From 8d1f27e08557550b454c441cc55c36021ba5e43e Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 18 Jul 2026 01:13:06 +0000 Subject: [PATCH] fix(spec): resolve multi-line and .js imports in skill-reference resolver (#3139) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `extractLocalImports` in build-skill-references.ts under-reported a skill's transitive schema deps because of two blind spots in the import scan: - The regex `/^import\s+.*\s+from\s+.../` used `.`, which does not cross newlines, so any multi-line named import (`import {\n … \n} from './x'`) was silently dropped and never queued into the closure. - `.js`-suffixed ESM specifiers were mangled: the resolver appended `.ts` unconditionally, turning `./types.js` into a non-existent `./types.js.ts` that then failed the `fs.existsSync` check and was discarded. Replace the pattern with a multi-line-tolerant scan that excludes `;`, quotes, and `(` between `import` and `from` — this keeps the non-greedy span from bridging across statement boundaries, side-effect imports, or a dynamic `import(...)`. Normalize `.js` specifiers to `.ts` before resolving. Regenerated the indexes with the fix in place: the platform skill now surfaces `system/tenant.zod.ts`, reached through the previously-invisible `.js` import in `kernel/context.zod.ts`. The `check:skill-refs` gate added in #3138 passes with the regenerated output. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01YTjm38Bo2xUv1UUPWu4mC5 --- packages/spec/scripts/build-skill-references.ts | 17 ++++++++++++++--- .../objectstack-platform/references/_index.md | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/spec/scripts/build-skill-references.ts b/packages/spec/scripts/build-skill-references.ts index 658b6b02a..a039d149b 100644 --- a/packages/spec/scripts/build-skill-references.ts +++ b/packages/spec/scripts/build-skill-references.ts @@ -122,13 +122,24 @@ const SKILL_MAP: Record = { function extractLocalImports(filePath: string): string[] { const content = fs.readFileSync(filePath, 'utf-8'); const imports: string[] = []; - const re = /^import\s+.*\s+from\s+['"](\.[^'"]+)['"]/gm; + const dir = path.dirname(filePath); + // Match `import … from ''`, tolerating a multi-line import clause. + // The clause between `import` and `from` never contains a `;`, quote, or `(`, + // so excluding those keeps the non-greedy span from bridging across a + // statement boundary, a side-effect import (`import './x'`), or a dynamic + // `import(...)` into the wrong specifier. A plain `.` (the old pattern) does + // not cross newlines, so multi-line named imports were silently dropped. + const re = /^import\b[^;'"()]*?\bfrom\s*['"](\.[^'"]+)['"]/gm; let match: RegExpExecArray | null; while ((match = re.exec(content)) !== null) { const importSpec = match[1]; - const dir = path.dirname(filePath); let resolved = path.resolve(dir, importSpec); - if (!resolved.endsWith('.ts')) resolved += '.ts'; + // ESM specifiers may carry a `.js` extension that maps to a `.ts` source + // (`./types.js` → `./types.ts`); otherwise append `.ts` for an + // extensionless local specifier. Blindly appending `.ts` turned `.js` + // imports into a non-existent `foo.js.ts` that was then dropped. + if (resolved.endsWith('.js')) resolved = resolved.slice(0, -3) + '.ts'; + else if (!resolved.endsWith('.ts')) resolved += '.ts'; if (fs.existsSync(resolved)) { imports.push(path.relative(SPEC_SRC, resolved)); } diff --git a/skills/objectstack-platform/references/_index.md b/skills/objectstack-platform/references/_index.md index 14bdbb941..a200bdfbd 100644 --- a/skills/objectstack-platform/references/_index.md +++ b/skills/objectstack-platform/references/_index.md @@ -33,6 +33,7 @@ from `node_modules` — there is no local copy in the skill bundle. - `node_modules/@objectstack/spec/src/shared/identifiers.zod.ts` — System Identifier Schema - `node_modules/@objectstack/spec/src/shared/lazy-schema.ts` — Wrap a Zod schema constructor so its body is only evaluated on first use. - `node_modules/@objectstack/spec/src/shared/protection.zod.ts` — Package-level metadata protection (ADR-0010 §3.7 — Phase 4.3) +- `node_modules/@objectstack/spec/src/system/tenant.zod.ts` — Tenant Schema (Multi-Tenant Architecture) - `node_modules/@objectstack/spec/src/ui/action.zod.ts` — Action Parameter Schema - `node_modules/@objectstack/spec/src/ui/app.zod.ts` — Base Navigation Item Schema - `node_modules/@objectstack/spec/src/ui/i18n.zod.ts` — I18n Object Schema