From 4c33642e3cdf80ca08a43c0faa64c43cfaae08f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=82CHES?= Date: Sat, 14 Mar 2026 07:27:32 -0600 Subject: [PATCH] fix: normalize .ts import extensions to .js for Node 22.22+ compatibility (#354) Node 22.22.0's --experimental-strip-types handles .ts import specifiers differently, causing ERR_INVALID_TYPESCRIPT_SYNTAX in CI. The project convention uses .js specifiers with a custom resolve hook that rewrites them to .ts at test time. Co-authored-by: Claude Opus 4.6 (1M context) --- src/resources/extensions/gsd/auto.ts | 8 ++++---- src/resources/extensions/gsd/dispatch-guard.ts | 2 +- src/resources/extensions/gsd/files.ts | 8 ++++---- src/resources/extensions/gsd/git-service.ts | 2 +- src/resources/extensions/gsd/migrate/index.ts | 16 ++++++++-------- src/resources/extensions/gsd/migrate/parser.ts | 6 +++--- src/resources/extensions/gsd/migrate/parsers.ts | 4 ++-- src/resources/extensions/gsd/migrate/preview.ts | 4 ++-- .../extensions/gsd/migrate/transformer.ts | 2 +- .../extensions/gsd/migrate/validator.ts | 2 +- src/resources/extensions/gsd/migrate/writer.ts | 4 ++-- .../extensions/gsd/native-parser-bridge.ts | 2 +- src/resources/extensions/gsd/preferences.ts | 4 ++-- src/resources/extensions/gsd/roadmap-slices.ts | 2 +- src/resources/extensions/gsd/state.ts | 8 ++++---- src/resources/extensions/gsd/unit-runtime.ts | 4 ++-- src/resources/extensions/gsd/workspace-index.ts | 10 +++++----- src/resources/extensions/gsd/worktree.ts | 8 ++++---- 18 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/resources/extensions/gsd/auto.ts b/src/resources/extensions/gsd/auto.ts index e430e211f..03ae26ec8 100644 --- a/src/resources/extensions/gsd/auto.ts +++ b/src/resources/extensions/gsd/auto.ts @@ -69,10 +69,10 @@ import { setActiveMilestoneId, switchToMain, mergeSliceToMain, -} from "./worktree.ts"; -import { GitServiceImpl, runGit } from "./git-service.ts"; -import { getPriorSliceCompletionBlocker } from "./dispatch-guard.ts"; -import type { GitPreferences } from "./git-service.ts"; +} from "./worktree.js"; +import { GitServiceImpl, runGit } from "./git-service.js"; +import { getPriorSliceCompletionBlocker } from "./dispatch-guard.js"; +import type { GitPreferences } from "./git-service.js"; import { truncateToWidth, visibleWidth } from "@gsd/pi-tui"; import { makeUI, GLYPH, INDENT } from "../shared/ui.js"; import { showNextAction } from "../shared/next-action-ui.js"; diff --git a/src/resources/extensions/gsd/dispatch-guard.ts b/src/resources/extensions/gsd/dispatch-guard.ts index 6d49e35d3..2509a7c9b 100644 --- a/src/resources/extensions/gsd/dispatch-guard.ts +++ b/src/resources/extensions/gsd/dispatch-guard.ts @@ -1,7 +1,7 @@ import { execSync } from "node:child_process"; import { readdirSync } from "node:fs"; import { relMilestoneFile, milestonesDir } from "./paths.js"; -import { parseRoadmapSlices } from "./roadmap-slices.ts"; +import { parseRoadmapSlices } from "./roadmap-slices.js"; import { extractMilestoneSeq, milestoneIdSort } from "./guided-flow.js"; const SLICE_DISPATCH_TYPES = new Set([ diff --git a/src/resources/extensions/gsd/files.ts b/src/resources/extensions/gsd/files.ts index 3d027d992..c575b6e06 100644 --- a/src/resources/extensions/gsd/files.ts +++ b/src/resources/extensions/gsd/files.ts @@ -16,11 +16,11 @@ import type { RequirementCounts, SecretsManifest, SecretsManifestEntry, SecretsManifestEntryStatus, ManifestStatus, -} from './types.ts'; +} from './types.js'; -import { checkExistingEnvKeys } from '../get-secrets-from-user.ts'; -import { parseRoadmapSlices } from './roadmap-slices.ts'; -import { nativeParseRoadmap, nativeExtractSection, NATIVE_UNAVAILABLE } from './native-parser-bridge.ts'; +import { checkExistingEnvKeys } from '../get-secrets-from-user.js'; +import { parseRoadmapSlices } from './roadmap-slices.js'; +import { nativeParseRoadmap, nativeExtractSection, NATIVE_UNAVAILABLE } from './native-parser-bridge.js'; // ─── Helpers ─────────────────────────────────────────────────────────────── diff --git a/src/resources/extensions/gsd/git-service.ts b/src/resources/extensions/gsd/git-service.ts index de6ed624d..a690e2641 100644 --- a/src/resources/extensions/gsd/git-service.ts +++ b/src/resources/extensions/gsd/git-service.ts @@ -16,7 +16,7 @@ import { detectWorktreeName, getSliceBranchName, SLICE_BRANCH_RE, -} from "./worktree.ts"; +} from "./worktree.js"; // ─── Types ───────────────────────────────────────────────────────────────── diff --git a/src/resources/extensions/gsd/migrate/index.ts b/src/resources/extensions/gsd/migrate/index.ts index 68d77cb80..fa1e1e494 100644 --- a/src/resources/extensions/gsd/migrate/index.ts +++ b/src/resources/extensions/gsd/migrate/index.ts @@ -1,12 +1,12 @@ // Barrel export for old .planning migration module -export { handleMigrate } from './command.ts'; -export { parsePlanningDirectory } from './parser.ts'; -export { validatePlanningDirectory } from './validator.ts'; -export { transformToGSD } from './transformer.ts'; -export { writeGSDDirectory } from './writer.ts'; -export type { WrittenFiles, MigrationPreview } from './writer.ts'; -export { generatePreview } from './preview.ts'; +export { handleMigrate } from './command.js'; +export { parsePlanningDirectory } from './parser.js'; +export { validatePlanningDirectory } from './validator.js'; +export { transformToGSD } from './transformer.js'; +export { writeGSDDirectory } from './writer.js'; +export type { WrittenFiles, MigrationPreview } from './writer.js'; +export { generatePreview } from './preview.js'; export type { // Input types (old .planning format) PlanningProject, @@ -39,4 +39,4 @@ export type { GSDSliceSummaryData, GSDTaskSummaryData, GSDBoundaryEntry, -} from './types.ts'; +} from './types.js'; diff --git a/src/resources/extensions/gsd/migrate/parser.ts b/src/resources/extensions/gsd/migrate/parser.ts index 36a762a82..937464aaf 100644 --- a/src/resources/extensions/gsd/migrate/parser.ts +++ b/src/resources/extensions/gsd/migrate/parser.ts @@ -14,8 +14,8 @@ import { parseOldProject, parseOldState, parseOldConfig, -} from './parsers.ts'; -import { validatePlanningDirectory } from './validator.ts'; +} from './parsers.js'; +import { validatePlanningDirectory } from './validator.js'; import type { PlanningProject, @@ -24,7 +24,7 @@ import type { PlanningMilestone, PlanningResearch, PlanningPhaseFile, -} from './types.ts'; +} from './types.js'; // ─── Helpers ─────────────────────────────────────────────────────────────── diff --git a/src/resources/extensions/gsd/migrate/parsers.ts b/src/resources/extensions/gsd/migrate/parsers.ts index 6ba0eb480..5de6514c6 100644 --- a/src/resources/extensions/gsd/migrate/parsers.ts +++ b/src/resources/extensions/gsd/migrate/parsers.ts @@ -2,7 +2,7 @@ // Pure functions that take file content (string) and return typed data. // Zero Pi dependencies — uses only exported helpers from files.ts. -import { splitFrontmatter, parseFrontmatterMap, extractBoldField } from '../files.ts'; +import { splitFrontmatter, parseFrontmatterMap, extractBoldField } from '../files.js'; import type { PlanningRoadmap, @@ -17,7 +17,7 @@ import type { PlanningRequirement, PlanningState, PlanningConfig, -} from './types.ts'; +} from './types.js'; // Re-export PlanningProjectMeta — not in types.ts yet, use string for project field // Actually PlanningProjectMeta isn't in types.ts — project is stored as string | null. diff --git a/src/resources/extensions/gsd/migrate/preview.ts b/src/resources/extensions/gsd/migrate/preview.ts index 933771448..28be74e25 100644 --- a/src/resources/extensions/gsd/migrate/preview.ts +++ b/src/resources/extensions/gsd/migrate/preview.ts @@ -1,8 +1,8 @@ // GSD Migration Preview — Pre-write statistics // Pure function, no I/O. Computes counts from a GSDProject. -import type { GSDProject } from './types.ts'; -import type { MigrationPreview } from './writer.ts'; +import type { GSDProject } from './types.js'; +import type { MigrationPreview } from './writer.js'; /** * Compute pre-write statistics from a GSDProject without performing I/O. diff --git a/src/resources/extensions/gsd/migrate/transformer.ts b/src/resources/extensions/gsd/migrate/transformer.ts index 2bb059665..b1661c0e0 100644 --- a/src/resources/extensions/gsd/migrate/transformer.ts +++ b/src/resources/extensions/gsd/migrate/transformer.ts @@ -18,7 +18,7 @@ import type { GSDSliceSummaryData, GSDTaskSummaryData, GSDBoundaryEntry, -} from './types.ts'; +} from './types.js'; // ─── Helpers ─────────────────────────────────────────────────────────────── diff --git a/src/resources/extensions/gsd/migrate/validator.ts b/src/resources/extensions/gsd/migrate/validator.ts index 2bbf44dfb..82be20054 100644 --- a/src/resources/extensions/gsd/migrate/validator.ts +++ b/src/resources/extensions/gsd/migrate/validator.ts @@ -5,7 +5,7 @@ import { existsSync, statSync } from 'node:fs'; import { join } from 'node:path'; -import type { ValidationResult, ValidationIssue, ValidationSeverity } from './types.ts'; +import type { ValidationResult, ValidationIssue, ValidationSeverity } from './types.js'; function issue(file: string, severity: ValidationSeverity, message: string): ValidationIssue { return { file, severity, message }; diff --git a/src/resources/extensions/gsd/migrate/writer.ts b/src/resources/extensions/gsd/migrate/writer.ts index 79006a415..27b627ba9 100644 --- a/src/resources/extensions/gsd/migrate/writer.ts +++ b/src/resources/extensions/gsd/migrate/writer.ts @@ -4,7 +4,7 @@ // writeGSDDirectory: orchestrator that writes a complete .gsd directory tree from a GSDProject. import { join } from 'node:path'; -import { saveFile } from '../files.ts'; +import { saveFile } from '../files.js'; import type { GSDMilestone, @@ -12,7 +12,7 @@ import type { GSDTask, GSDRequirement, GSDProject, -} from './types.ts'; +} from './types.js'; // ─── Types ───────────────────────────────────────────────────────────────── diff --git a/src/resources/extensions/gsd/native-parser-bridge.ts b/src/resources/extensions/gsd/native-parser-bridge.ts index 8b791335c..d56f9a3aa 100644 --- a/src/resources/extensions/gsd/native-parser-bridge.ts +++ b/src/resources/extensions/gsd/native-parser-bridge.ts @@ -4,7 +4,7 @@ // // Functions fall back to JS implementations if the native module is unavailable. -import type { Roadmap, BoundaryMapEntry, RoadmapSliceEntry, RiskLevel } from './types.ts'; +import type { Roadmap, BoundaryMapEntry, RoadmapSliceEntry, RiskLevel } from './types.js'; let nativeModule: { parseFrontmatter: (content: string) => { metadata: string; body: string }; diff --git a/src/resources/extensions/gsd/preferences.ts b/src/resources/extensions/gsd/preferences.ts index 86846065e..e1862850d 100644 --- a/src/resources/extensions/gsd/preferences.ts +++ b/src/resources/extensions/gsd/preferences.ts @@ -2,8 +2,8 @@ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs"; import { homedir } from "node:os"; import { isAbsolute, join } from "node:path"; import { getAgentDir } from "@gsd/pi-coding-agent"; -import type { GitPreferences } from "./git-service.ts"; -import { VALID_BRANCH_NAME } from "./git-service.ts"; +import type { GitPreferences } from "./git-service.js"; +import { VALID_BRANCH_NAME } from "./git-service.js"; const GLOBAL_PREFERENCES_PATH = join(homedir(), ".gsd", "preferences.md"); const LEGACY_GLOBAL_PREFERENCES_PATH = join(homedir(), ".pi", "agent", "gsd-preferences.md"); diff --git a/src/resources/extensions/gsd/roadmap-slices.ts b/src/resources/extensions/gsd/roadmap-slices.ts index a454adcf6..e03e9d72c 100644 --- a/src/resources/extensions/gsd/roadmap-slices.ts +++ b/src/resources/extensions/gsd/roadmap-slices.ts @@ -1,4 +1,4 @@ -import type { RoadmapSliceEntry, RiskLevel } from "./types.ts"; +import type { RoadmapSliceEntry, RiskLevel } from "./types.js"; function extractSlicesSection(content: string): string { const headingMatch = /^## Slices\s*$/m.exec(content); diff --git a/src/resources/extensions/gsd/state.ts b/src/resources/extensions/gsd/state.ts index 3a26202ad..fd9a905c9 100644 --- a/src/resources/extensions/gsd/state.ts +++ b/src/resources/extensions/gsd/state.ts @@ -9,7 +9,7 @@ import type { RoadmapSliceEntry, SlicePlan, MilestoneRegistryEntry, -} from './types.ts'; +} from './types.js'; import { parseRoadmap, @@ -18,7 +18,7 @@ import { loadFile, parseRequirementCounts, parseContextDependsOn, -} from './files.ts'; +} from './files.js'; import { milestonesDir, @@ -28,8 +28,8 @@ import { resolveSliceFile, resolveTaskFile, resolveGsdRootFile, -} from './paths.ts'; -import { getActiveSliceBranch } from './worktree.ts'; +} from './paths.js'; +import { getActiveSliceBranch } from './worktree.js'; import { milestoneIdSort } from './guided-flow.js'; import { readdirSync } from 'fs'; diff --git a/src/resources/extensions/gsd/unit-runtime.ts b/src/resources/extensions/gsd/unit-runtime.ts index 6b17c5f35..6a44fca77 100644 --- a/src/resources/extensions/gsd/unit-runtime.ts +++ b/src/resources/extensions/gsd/unit-runtime.ts @@ -6,8 +6,8 @@ import { relTaskFile, resolveSliceFile, resolveTaskFile, -} from "./paths.ts"; -import { loadFile, parseTaskPlanMustHaves, countMustHavesMentionedInSummary } from "./files.ts"; +} from "./paths.js"; +import { loadFile, parseTaskPlanMustHaves, countMustHavesMentionedInSummary } from "./files.js"; export type UnitRuntimePhase = | "dispatched" diff --git a/src/resources/extensions/gsd/workspace-index.ts b/src/resources/extensions/gsd/workspace-index.ts index e8161e4f9..a21de212d 100644 --- a/src/resources/extensions/gsd/workspace-index.ts +++ b/src/resources/extensions/gsd/workspace-index.ts @@ -1,7 +1,7 @@ import { readdirSync } from "node:fs"; import { join } from "node:path"; -import { loadFile, parsePlan, parseRoadmap } from "./files.ts"; +import { loadFile, parsePlan, parseRoadmap } from "./files.js"; import { milestonesDir, resolveMilestoneFile, @@ -9,11 +9,11 @@ import { resolveSlicePath, resolveTaskFile, resolveTasksDir, -} from "./paths.ts"; -import { deriveState } from "./state.ts"; +} from "./paths.js"; +import { deriveState } from "./state.js"; import { milestoneIdSort } from "./guided-flow.js"; -import { type ValidationIssue, validateCompleteBoundary, validatePlanBoundary } from "./observability-validator.ts"; -import { getSliceBranchName, detectWorktreeName } from "./worktree.ts"; +import { type ValidationIssue, validateCompleteBoundary, validatePlanBoundary } from "./observability-validator.js"; +import { getSliceBranchName, detectWorktreeName } from "./worktree.js"; export interface WorkspaceTaskTarget { id: string; diff --git a/src/resources/extensions/gsd/worktree.ts b/src/resources/extensions/gsd/worktree.ts index 0b337ab47..38f450c7f 100644 --- a/src/resources/extensions/gsd/worktree.ts +++ b/src/resources/extensions/gsd/worktree.ts @@ -17,12 +17,12 @@ import { sep } from "node:path"; -import { GitServiceImpl, writeIntegrationBranch } from "./git-service.ts"; -import { loadEffectiveGSDPreferences } from "./preferences.ts"; +import { GitServiceImpl, writeIntegrationBranch } from "./git-service.js"; +import { loadEffectiveGSDPreferences } from "./preferences.js"; // Re-export MergeSliceResult from the canonical source (D014 — type-only re-export) -export type { MergeSliceResult } from "./git-service.ts"; -export { MergeConflictError } from "./git-service.ts"; +export type { MergeSliceResult } from "./git-service.js"; +export { MergeConflictError } from "./git-service.js"; // ─── Lazy GitServiceImpl Cache ─────────────────────────────────────────────