From 5de5fee659f64f14855a0e8998a0ac48fb941cc6 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Thu, 16 Apr 2026 21:43:34 -0400 Subject: [PATCH] refactor: unwrap Question namespace in question/index.ts + fix script - question/index.ts: unwrap `export namespace Question { ... }` into flat top-level exports + self-reexport `export * as Question from "."`. Public API preserved; consumers that write `import { Question } from "@/question"` continue to work unchanged. - script/unwrap-and-self-reexport.ts: when the target file is literally named `index.ts`, emit `from "."` instead of `from "./index"`. The former matches the existing convention in the codebase (pty/index.ts, file/index.ts, snapshot/index.ts, etc.) and avoids referencing "index" literally. Before this fix, running the script on a file named index.ts would have produced `export * as Foo from "./index"` which, while valid, is stylistically wrong. Verified: tsgo --noEmit 0 errors, SDK generate no drift, test/question/ 14/14 pass, test/tool/question.test.ts + test/session/{prompt-effect,message-v2,snapshot-tool-race}.test.ts 75/75 pass. --- .../script/unwrap-and-self-reexport.ts | 11 +- packages/opencode/src/question/index.ts | 388 +++++++++--------- 2 files changed, 202 insertions(+), 197 deletions(-) diff --git a/packages/opencode/script/unwrap-and-self-reexport.ts b/packages/opencode/script/unwrap-and-self-reexport.ts index 5ae703182e19..09256f3a5196 100644 --- a/packages/opencode/script/unwrap-and-self-reexport.ts +++ b/packages/opencode/script/unwrap-and-self-reexport.ts @@ -207,10 +207,15 @@ const rewrittenBody = dedented.map(rewriteLine) // Assemble the new file. Collapse multiple trailing blank lines so the // self-reexport sits cleanly at the end. +// +// When the file is itself `index.ts`, prefer `"."` over `"./index"` — both are +// valid but `"."` matches the existing convention in the codebase (e.g. +// pty/index.ts, file/index.ts, etc.) and avoids referencing "index" literally. const basename = path.basename(absPath, ".ts") +const reexportSource = basename === "index" ? "." : `./${basename}` const assembled = [...before, ...rewrittenBody, ...after].join("\n") const trimmed = assembled.replace(/\s+$/g, "") -const output = `${trimmed}\n\nexport * as ${nsName} from "./${basename}"\n` +const output = `${trimmed}\n\nexport * as ${nsName} from "${reexportSource}"\n` if (dryRun) { console.log(`--- dry run: ${path.relative(process.cwd(), absPath)} ---`) @@ -218,7 +223,7 @@ if (dryRun) { console.log(`body lines: ${body.length}`) console.log(`declared names: ${Array.from(declaredNames).join(", ") || "(none)"}`) console.log(`self-refs rewr: ${rewriteCount}`) - console.log(`self-reexport: export * as ${nsName} from "./${basename}"`) + console.log(`self-reexport: export * as ${nsName} from "${reexportSource}"`) console.log(`output preview (last 10 lines):`) const outputLines = output.split("\n") for (const l of outputLines.slice(Math.max(0, outputLines.length - 10))) { @@ -231,7 +236,7 @@ fs.writeFileSync(absPath, output) console.log(`unwrapped ${path.relative(process.cwd(), absPath)} → ${nsName}`) console.log(` body lines: ${body.length}`) console.log(` self-refs rewr: ${rewriteCount}`) -console.log(` self-reexport: export * as ${nsName} from "./${basename}"`) +console.log(` self-reexport: export * as ${nsName} from "${reexportSource}"`) console.log("") console.log("Next: verify with") console.log(" bunx --bun tsgo --noEmit") diff --git a/packages/opencode/src/question/index.ts b/packages/opencode/src/question/index.ts index 627d04564d0d..3b377c9827ae 100644 --- a/packages/opencode/src/question/index.ts +++ b/packages/opencode/src/question/index.ts @@ -8,222 +8,222 @@ import { Log } from "@/util" import { withStatics } from "@/util/schema" import { QuestionID } from "./schema" -export namespace Question { - const log = Log.create({ service: "question" }) - - // Schemas - - export class Option extends Schema.Class