@snappedly-tools/shipyard 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,8 +33,9 @@ npx shipyard init
33
33
  cp .shipyard/.env.example .shipyard/.env
34
34
  ```
35
35
 
36
- `init` asks which agent, sandbox provider, issue tracker, and starter template
37
- to use. Start with the `blank` template. Put the requested credentials in
36
+ `init` asks which agent, sandbox provider, and starter template to use. Its
37
+ issue-based templates use GitHub Issues. Start with the `blank` template. Put
38
+ the requested credentials in
38
39
  `.shipyard/.env`, then write one concrete task in `.shipyard/prompt.md`.
39
40
 
40
41
  Run it:
package/dist/main.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { CODEX_MODELS, withFriendlyErrors } from './chunk-VDHZO5PP.js';
3
3
  import { buildImage, removeImage } from './chunk-OCJKONZ7.js';
4
- import { CONFIG_DIR, SANDBOX_REPO_DIR, Display, InitError, PRODUCT_NAME, CLI_NAME, ClackDisplay, defaultImageName, ExecHostError, LOCKS_DIR, ConfigDirError } from './chunk-2GT3OPO5.js';
4
+ import { SANDBOX_REPO_DIR, Display, InitError, PRODUCT_NAME, CONFIG_DIR, CLI_NAME, ClackDisplay, defaultImageName, ExecHostError, LOCKS_DIR, ConfigDirError } from './chunk-2GT3OPO5.js';
5
5
  import './chunk-KMGNFXKN.js';
6
6
  import './chunk-WA7QPAXO.js';
7
7
  import { NodeContext, NodeRuntime } from '@effect/platform-node';
@@ -54,8 +54,6 @@ logs/
54
54
  worktrees/
55
55
  ${LOCKS_DIR}/
56
56
  `;
57
- var SETUP_ISSUE_TRACKER_DOC = "SETUP_ISSUE_TRACKER.md";
58
- var SETUP_ISSUE_TRACKER_PATH = `${CONFIG_DIR}/${SETUP_ISSUE_TRACKER_DOC}`;
59
57
  var DEFAULT_AGENT_NAME = "codex";
60
58
  var TEMPLATE_AGENT_FACTORY = "codex";
61
59
  var CODEX_CHATGPT_ENV_EXAMPLE = `# Codex ChatGPT subscription authentication
@@ -236,8 +234,7 @@ var AGENT_REGISTRY = [
236
234
  factoryImport: "codex",
237
235
  dockerfileTemplate: CODEX_DOCKERFILE,
238
236
  envExample: `# OpenAI API key
239
- OPENAI_API_KEY=`,
240
- setupCommand: `codex "$(cat ${SETUP_ISSUE_TRACKER_PATH})"`
237
+ OPENAI_API_KEY=`
241
238
  },
242
239
  {
243
240
  name: "claude-code",
@@ -249,8 +246,7 @@ OPENAI_API_KEY=`,
249
246
  # Lets the agent use your Claude subscription instead of an API key.
250
247
  CLAUDE_CODE_OAUTH_TOKEN=
251
248
  # Or use an Anthropic API key instead \u2014 uncomment and fill in:
252
- # ANTHROPIC_API_KEY=`,
253
- setupCommand: `claude "$(cat ${SETUP_ISSUE_TRACKER_PATH})"`
249
+ # ANTHROPIC_API_KEY=`
254
250
  }
255
251
  ];
256
252
  var listAgents = () => AGENT_REGISTRY;
@@ -261,25 +257,6 @@ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \\
261
257
  | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \\
262
258
  && apt-get update && apt-get install -y gh \\
263
259
  && rm -rf /var/lib/apt/lists/*`;
264
- var BEADS_TOOLS = `# Install system dependencies for Beads
265
- RUN apt-get update && apt-get install -y \\
266
- dpkg-dev \\
267
- libicu72 \\
268
- && rm -rf /var/lib/apt/lists/* \\
269
- && ARCH_DIR=$(dpkg-architecture -qDEB_HOST_MULTIARCH) \\
270
- && for lib in /usr/lib/$ARCH_DIR/libicu*.so.72; do \\
271
- ln -s "$lib" "\${lib%.72}.74"; \\
272
- done
273
-
274
- RUN curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
275
-
276
- RUN corepack enable`;
277
- var CUSTOM_LIST_TASKS_SENTINEL = `echo 'No issue tracker configured \u2014 run ${SETUP_ISSUE_TRACKER_PATH} through your coding agent.' >&2; exit 1`;
278
- var CUSTOM_VIEW_TASK_MARKER = `<view command \u2014 see ${SETUP_ISSUE_TRACKER_PATH}>`;
279
- var CUSTOM_CLOSE_TASK_MARKER = `<close command \u2014 see ${SETUP_ISSUE_TRACKER_PATH}>`;
280
- var CUSTOM_TRACKER_TOOLS = `# TODO: install your issue tracker's CLI here. See ${SETUP_ISSUE_TRACKER_PATH}`;
281
- var CUSTOM_ENV_EXAMPLE = `# TODO: add any env vars your issue tracker needs (e.g. an API token).
282
- # See ${SETUP_ISSUE_TRACKER_PATH}`;
283
260
  var ISSUE_TRACKER_REGISTRY = [
284
261
  {
285
262
  name: "github-issues",
@@ -294,32 +271,6 @@ var ISSUE_TRACKER_REGISTRY = [
294
271
  # Create a fine-grained token: https://github.com/settings/personal-access-tokens/new
295
272
  # Required repository permissions: Issues (Read and write) and Metadata (Read)
296
273
  GH_TOKEN=`
297
- },
298
- {
299
- name: "beads",
300
- label: "Beads",
301
- templateArgs: {
302
- LIST_TASKS_COMMAND: "bd ready --json",
303
- VIEW_TASK_COMMAND: "bd show <ID>",
304
- CLOSE_TASK_COMMAND: `bd close <ID> --reason="Completed by ${PRODUCT_NAME}"`,
305
- ISSUE_TRACKER_TOOLS: BEADS_TOOLS
306
- },
307
- envExample: ""
308
- },
309
- {
310
- name: "custom",
311
- label: "Custom",
312
- templateArgs: {
313
- // The only real shell expression: PromptPreprocessor fails the run on a
314
- // non-zero exit and surfaces stderr, so this is the single enforcement
315
- // point that keeps the scaffold broken until the user configures it.
316
- LIST_TASKS_COMMAND: CUSTOM_LIST_TASKS_SENTINEL,
317
- // Inline text markers — replaced by the setup agent, never executed.
318
- VIEW_TASK_COMMAND: CUSTOM_VIEW_TASK_MARKER,
319
- CLOSE_TASK_COMMAND: CUSTOM_CLOSE_TASK_MARKER,
320
- ISSUE_TRACKER_TOOLS: CUSTOM_TRACKER_TOOLS
321
- },
322
- envExample: CUSTOM_ENV_EXAMPLE
323
274
  }
324
275
  ];
325
276
  var listIssueTrackers = () => ISSUE_TRACKER_REGISTRY;
@@ -335,7 +286,7 @@ var SANDBOX_PROVIDER_REGISTRY = [
335
286
  ];
336
287
  var listSandboxProviders = () => SANDBOX_PROVIDER_REGISTRY;
337
288
  var getSandboxProvider = (name) => SANDBOX_PROVIDER_REGISTRY.find((p) => p.name === name);
338
- function getNextStepsLines(template, mainFilename, issueTracker, agent, packageManager, codexAuth = "api-key") {
289
+ function getNextStepsLines(template, mainFilename, agent, packageManager, codexAuth = "api-key") {
339
290
  const getAuthLines = (step) => {
340
291
  if (agent.name === "codex") {
341
292
  if (codexAuth === "chatgpt") {
@@ -364,19 +315,6 @@ function getNextStepsLines(template, mainFilename, issueTracker, agent, packageM
364
315
  `${step}. Set the required env vars in ${CONFIG_DIR}/.env (see ${CONFIG_DIR}/.env.example)`
365
316
  ];
366
317
  };
367
- if (issueTracker.name === "custom") {
368
- const authLines = agent.name === "codex" && codexAuth === "chatgpt" ? getAuthLines(1) : [];
369
- const setupStep = authLines.length > 0 ? 2 : 1;
370
- return [
371
- "Next steps:",
372
- ...authLines,
373
- `${setupStep}. Your custom issue tracker isn't wired up yet \u2014 runs hard-fail until you configure it.`,
374
- `${setupStep + 1}. Feed the setup prompt to ${agent.label} on your host to finish wiring it up:`,
375
- ` ${agent.setupCommand}`,
376
- ` (Runs on the host \u2014 you need the ${agent.label} CLI installed locally, since the sandbox image isn't built yet.)`,
377
- `${setupStep + 2}. Follow ${CONFIG_DIR}/${SETUP_ISSUE_TRACKER_DOC} to edit the scaffolded files in place, build the image, and verify.`
378
- ];
379
- }
380
318
  if (template === "blank") {
381
319
  const lines = ["Next steps:", ...getAuthLines(1)];
382
320
  lines.push(
@@ -548,61 +486,6 @@ var substituteTemplateArgs = (configDir, issueTracker) => Effect.gen(function* (
548
486
  { concurrency: "unbounded" }
549
487
  );
550
488
  });
551
- var buildSetupIssueTrackerDoc = (cliNamespace) => `# Set up your custom issue tracker
552
-
553
- You are a coding agent. Finish wiring up the **custom issue tracker** for this Shipyard project. It was scaffolded in a deliberately broken-until-configured state: until you complete the steps below, every Shipyard run hard-fails with a pointer back to this file.
554
-
555
- ## Goal
556
-
557
- Wire up the issue tracker so the scaffolded prompts can **list**, **view**, and **close** tasks. There is no runtime abstraction to implement \u2014 the tracker commands are baked into the scaffolded files, so you edit those files **in place**.
558
-
559
- ## 1. Interview the user
560
-
561
- Ask the user:
562
-
563
- - Which issue tracker do they use (e.g. Jira, Linear, a GitHub repo other than this one, an internal API)?
564
- - How should the sandbox authenticate \u2014 a CLI that is already logged in, or an API token? If a token, what is the environment variable name?
565
-
566
- ## 2. Produce three commands
567
-
568
- Work out, together with the user, the shell commands for:
569
-
570
- - **list** \u2014 print all open tasks **as JSON** (match the shape the built-in trackers emit: an array of objects, each with at least an id/number, title, and body). This is what the agent reads at the start of every iteration.
571
- - **view** \`<ID>\` \u2014 show a single task by id.
572
- - **close** \`<ID>\` \u2014 close a single task by id.
573
-
574
- ## 3. Edit the scaffolded files in place
575
-
576
- - **Dockerfile / Containerfile** \u2014 replace the line
577
-
578
- \`\`\`
579
- ${CUSTOM_TRACKER_TOOLS}
580
- \`\`\`
581
-
582
- with the install steps for your tracker's CLI (if it needs one).
583
-
584
- - **Prompt files (\`${CONFIG_DIR}/*.md\`)** \u2014 replace the sentinel
585
-
586
- \`\`\`
587
- ${CUSTOM_LIST_TASKS_SENTINEL}
588
- \`\`\`
589
-
590
- with your **list** command. In the prompt file the sentinel sits inside a Shipyard **shell expression** \u2014 a leading \`!\` followed by the command in backticks \u2014 whose output is injected into the prompt before each run. Keep that \`!\` and the surrounding backticks; replace only the command between them, and **remove the \`exit 1\`** (leaving it keeps every run hard-failing). Then replace the \`${CUSTOM_VIEW_TASK_MARKER}\` and \`${CUSTOM_CLOSE_TASK_MARKER}\` markers with your **view** and **close** commands.
591
-
592
- - **\`.env.example\`** \u2014 replace the \`# TODO\` block with the real env var(s) your tracker needs, then tell the user to set them in \`${CONFIG_DIR}/.env\`.
593
-
594
- ## 4. Build the image
595
-
596
- Once the files are wired up, build the sandbox image:
597
-
598
- \`\`\`
599
- ${CLI_NAME} ${cliNamespace} build-image
600
- \`\`\`
601
-
602
- ## 5. Verify
603
-
604
- Run your **list** command inside the built image and confirm it returns the open tasks as JSON. If it errors, fix the command or the auth and rebuild.
605
- `;
606
489
  var detectMainFilename = (repoDir) => Effect.gen(function* () {
607
490
  const fs = yield* FileSystem.FileSystem;
608
491
  const pkgPath = join(repoDir, "package.json");
@@ -672,12 +555,6 @@ var scaffold = (repoDir, options) => Effect.gen(function* () {
672
555
  if (!createLabel) {
673
556
  yield* rewritePromptFiles(configDir);
674
557
  }
675
- if (issueTracker.name === "custom") {
676
- yield* fs.writeFileString(
677
- join(configDir, SETUP_ISSUE_TRACKER_DOC),
678
- buildSetupIssueTrackerDoc(sandboxProvider.cliNamespace)
679
- ).pipe(Effect.mapError((e) => new Error(e.message)));
680
- }
681
558
  return { mainFilename };
682
559
  });
683
560
  var codexAuthFilePath = (authHome = join(homedir(), ".codex")) => join(authHome, "auth.json");
@@ -733,7 +610,7 @@ var ensureCodexChatGptAuth = (options) => {
733
610
  });
734
611
  }
735
612
  };
736
- var VERSION = "0.3.1" ;
613
+ var VERSION = "0.4.1" ;
737
614
 
738
615
  // src/cli.ts
739
616
  var imageNameOption = Options.text("image-name").pipe(
@@ -907,9 +784,7 @@ var sandboxOption = Options.text("sandbox").pipe(
907
784
  Options.optional
908
785
  );
909
786
  var issueTrackerOption = Options.text("issue-tracker").pipe(
910
- Options.withDescription(
911
- "Issue tracker to use (e.g. github-issues, beads, custom)"
912
- ),
787
+ Options.withDescription("Issue tracker to use (github-issues)"),
913
788
  Options.optional
914
789
  );
915
790
  var createLabelOption = Options.choice("create-label", [
@@ -922,9 +797,7 @@ var createLabelOption = Options.choice("create-label", [
922
797
  Options.optional
923
798
  );
924
799
  var buildImageOption = Options.choice("build-image", ["true", "false"]).pipe(
925
- Options.withDescription(
926
- "Whether to build the sandbox image now (ignored when --issue-tracker custom is selected)"
927
- ),
800
+ Options.withDescription("Whether to build the sandbox image now"),
928
801
  Options.optional
929
802
  );
930
803
  var installTemplateDepsOption = Options.choice("install-template-deps", [
@@ -1226,41 +1099,30 @@ var initCommand = Command.make(
1226
1099
  }
1227
1100
  }
1228
1101
  const providerLabel = selectedSandboxProvider.label;
1229
- if (selectedIssueTracker.name === "custom") {
1102
+ const shouldBuild = yield* resolveConfirmFlag({
1103
+ choice: buildImageChoice,
1104
+ flag: "--build-image",
1105
+ promptMessage: `Build the default ${providerLabel} image now?`,
1106
+ cancelMessage: "Build-image selection cancelled."
1107
+ });
1108
+ if (shouldBuild) {
1109
+ const containerfileDir = join(cwd, CONFIG_DIR);
1110
+ yield* d.spinner(
1111
+ `Building ${providerLabel} image '${imageName}'...`,
1112
+ buildImage(imageName, containerfileDir, {
1113
+ buildArgs: defaultUidBuildArgs()
1114
+ })
1115
+ );
1116
+ yield* d.status("Init complete! Image built successfully.", "success");
1117
+ } else {
1230
1118
  yield* d.status(
1231
- "Init complete! Your custom issue tracker isn't configured yet \u2014 see the steps below before building.",
1119
+ `Init complete! Run \`${CLI_NAME} ${selectedSandboxProvider.cliNamespace} build-image\` to build the ${providerLabel} image later.`,
1232
1120
  "success"
1233
1121
  );
1234
- } else {
1235
- const shouldBuild = yield* resolveConfirmFlag({
1236
- choice: buildImageChoice,
1237
- flag: "--build-image",
1238
- promptMessage: `Build the default ${providerLabel} image now?`,
1239
- cancelMessage: "Build-image selection cancelled."
1240
- });
1241
- if (shouldBuild) {
1242
- const containerfileDir = join(cwd, CONFIG_DIR);
1243
- yield* d.spinner(
1244
- `Building ${providerLabel} image '${imageName}'...`,
1245
- buildImage(imageName, containerfileDir, {
1246
- buildArgs: defaultUidBuildArgs()
1247
- })
1248
- );
1249
- yield* d.status(
1250
- "Init complete! Image built successfully.",
1251
- "success"
1252
- );
1253
- } else {
1254
- yield* d.status(
1255
- `Init complete! Run \`${CLI_NAME} ${selectedSandboxProvider.cliNamespace} build-image\` to build the ${providerLabel} image later.`,
1256
- "success"
1257
- );
1258
- }
1259
1122
  }
1260
1123
  const nextSteps = getNextStepsLines(
1261
1124
  selectedTemplate,
1262
1125
  scaffoldResult.mainFilename,
1263
- selectedIssueTracker,
1264
1126
  selectedAgent,
1265
1127
  packageManager,
1266
1128
  selectedCodexAuth
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtimeConfig.ts","../src/InitService.ts","../src/CodexAuth.ts","../src/version.ts","../src/cli.ts","../src/terminalCleanup.ts","../src/main.ts"],"names":["Effect","FileSystem","join"],"mappings":"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","file":"main.js","sourcesContent":["import { FileSystem } from \"@effect/platform\";\nimport { Effect } from \"effect\";\nimport { join } from \"node:path\";\n\nimport { ConfigDirError } from \"./errors.js\";\nimport { CONFIG_DIR, CLI_NAME } from \"./runtimeNames.js\";\n\nexport type ConfigDirState = \"missing\" | \"canonical\";\n\nconst pathExists = (\n path: string,\n): Effect.Effect<boolean, never, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n return yield* fs\n .exists(path)\n .pipe(Effect.catchAll(() => Effect.succeed(false)));\n });\n\nexport const getConfigDirState = (\n repoDir: string,\n): Effect.Effect<ConfigDirState, never, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const canonicalExists = yield* pathExists(join(repoDir, CONFIG_DIR));\n if (canonicalExists) return \"canonical\";\n return \"missing\";\n });\n\nexport const requireCanonicalConfigDir = (\n repoDir: string,\n): Effect.Effect<string, ConfigDirError, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const state = yield* getConfigDirState(repoDir);\n if (state === \"missing\") {\n return yield* Effect.fail(\n new ConfigDirError({\n message: `No ${CONFIG_DIR}/ found. Run \\`${CLI_NAME} init\\` first.`,\n }),\n );\n }\n return join(repoDir, CONFIG_DIR);\n });\n\n/** Fail before initialization can overwrite an existing configuration directory. */\nexport const assertConfigDirAvailable = (\n repoDir: string,\n): Effect.Effect<void, ConfigDirError, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const state = yield* getConfigDirState(repoDir);\n if (state === \"canonical\") {\n return yield* Effect.fail(\n new ConfigDirError({\n message: `${CONFIG_DIR}/ directory already exists. ${CLI_NAME} did not modify it. Use the existing configuration or remove it deliberately after preserving any active worktrees before re-initializing.`,\n }),\n );\n }\n });\n","import { FileSystem } from \"@effect/platform\";\nimport { Effect } from \"effect\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { SANDBOX_REPO_DIR } from \"./SandboxFactory.js\";\nimport { assertConfigDirAvailable } from \"./runtimeConfig.js\";\nimport {\n CONFIG_DIR,\n PRODUCT_NAME,\n CLI_NAME,\n LOCKS_DIR,\n} from \"./runtimeNames.js\";\nimport { CODEX_MODELS } from \"./modelConfig.js\";\n\nconst GITIGNORE = `.env\nlogs/\nworktrees/\n${LOCKS_DIR}/\n`;\n\n/**\n * Filename of the setup prompt scaffolded for the `custom` issue tracker.\n * Both the per-agent `setupCommand` and the in-scaffold sentinels point at it,\n * so it is defined once here.\n */\nconst SETUP_ISSUE_TRACKER_DOC = \"SETUP_ISSUE_TRACKER.md\";\nconst SETUP_ISSUE_TRACKER_PATH = `${CONFIG_DIR}/${SETUP_ISSUE_TRACKER_DOC}`;\nexport const DEFAULT_AGENT_NAME = \"codex\";\nconst TEMPLATE_AGENT_FACTORY = \"codex\";\n\nexport type CodexAuthMode = \"api-key\" | \"chatgpt\";\n\nconst CODEX_CHATGPT_ENV_EXAMPLE = `# Codex ChatGPT subscription authentication\n# On the host, run \\`codex login\\` and make sure \\`~/.codex/auth.json\\` exists.\n# Shipyard mounts that file read-only into the sandbox.\n# Do not add OPENAI_API_KEY here: that selects API-key billing instead.`;\n\nconst CODEX_CHATGPT_AUTH_OPTIONS = `{\n mounts: [\n {\n hostPath: \"~/.codex/auth.json\",\n sandboxPath: \"~/.codex/auth.json\",\n readonly: true,\n },\n ],\n}`;\n\nexport interface TemplateMetadata {\n name: string;\n description: string;\n /**\n * Host-side npm packages the template's `main` file imports directly (e.g.\n * the planner templates import `zod` for their `<plan>` output schema). Init\n * offers to install these with the detected package manager so that\n * `npx tsx ${CONFIG_DIR}/main.ts` doesn't crash with ERR_MODULE_NOT_FOUND.\n */\n dependencies?: readonly string[];\n}\n\nconst TEMPLATES: TemplateMetadata[] = [\n {\n name: \"blank\",\n description: \"Bare scaffold — write your own prompt and orchestration\",\n },\n {\n name: \"simple-loop\",\n description: \"Picks issues one by one and closes them\",\n },\n {\n name: \"sequential-reviewer\",\n description:\n \"Implements issues one by one, with a code review step after each\",\n },\n {\n name: \"parallel-planner\",\n description:\n \"Plans parallelizable issues, executes on separate branches, merges\",\n dependencies: [\"zod\"],\n },\n {\n name: \"parallel-planner-with-review\",\n description:\n \"Plans parallelizable issues, executes with per-branch review, merges\",\n dependencies: [\"zod\"],\n },\n];\n\nexport const listTemplates = (): TemplateMetadata[] => TEMPLATES;\n\n/**\n * Host-side npm packages the given template imports directly. Empty when the\n * template name is unknown or the template declares no extra dependencies.\n */\nexport const getTemplateDependencies = (\n templateName: string,\n): readonly string[] =>\n TEMPLATES.find((t) => t.name === templateName)?.dependencies ?? [];\n\n// ---------------------------------------------------------------------------\n// Package manager detection (internal — not part of public API)\n// ---------------------------------------------------------------------------\n\nconst PACKAGE_MANAGERS = [\"npm\", \"pnpm\", \"yarn\", \"bun\"] as const;\n\n/** A package manager Shipyard can detect on the host and build install commands for. */\nexport type PackageManager = (typeof PACKAGE_MANAGERS)[number];\n\n// Lockfiles checked in priority order. bun.lock / bun.lockb are both valid bun\n// lockfiles (text vs binary), so both map to bun.\nconst LOCKFILES: ReadonlyArray<readonly [string, PackageManager]> = [\n [\"bun.lockb\", \"bun\"],\n [\"bun.lock\", \"bun\"],\n [\"pnpm-lock.yaml\", \"pnpm\"],\n [\"yarn.lock\", \"yarn\"],\n [\"package-lock.json\", \"npm\"],\n];\n\n/**\n * Detect the host project's package manager. An explicit corepack-style\n * `packageManager` field in package.json wins; otherwise the first matching\n * lockfile decides. Defaults to npm when nothing matches.\n */\nexport const detectPackageManager = (\n repoDir: string,\n): Effect.Effect<PackageManager, never, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n\n const pkgPath = join(repoDir, \"package.json\");\n const pkgExists = yield* fs\n .exists(pkgPath)\n .pipe(Effect.orElseSucceed(() => false));\n if (pkgExists) {\n const content = yield* fs\n .readFileString(pkgPath)\n .pipe(Effect.orElseSucceed(() => \"\"));\n try {\n const pkg = JSON.parse(content) as Record<string, unknown>;\n const field = pkg[\"packageManager\"];\n if (typeof field === \"string\") {\n const name = field.split(\"@\")[0];\n const match = PACKAGE_MANAGERS.find((pm) => pm === name);\n if (match) return match;\n }\n } catch {\n // Malformed package.json — fall through to lockfile detection.\n }\n }\n\n for (const [file, pm] of LOCKFILES) {\n const exists = yield* fs\n .exists(join(repoDir, file))\n .pipe(Effect.orElseSucceed(() => false));\n if (exists) return pm;\n }\n\n return \"npm\";\n });\n\n/** Build the command that adds a runtime dependency for the given package manager. */\nexport const addDependencyCommand = (\n packageManager: PackageManager,\n pkg: string,\n): string => {\n switch (packageManager) {\n case \"pnpm\":\n return `pnpm add ${pkg}`;\n case \"yarn\":\n return `yarn add ${pkg}`;\n case \"bun\":\n return `bun add ${pkg}`;\n case \"npm\":\n return `npm install ${pkg}`;\n }\n};\n\n/**\n * Whether the host package.json already declares `pkg` in any of its dependency\n * maps. Used so init doesn't offer to install something already present.\n */\nexport const hostHasDependency = (\n repoDir: string,\n pkg: string,\n): Effect.Effect<boolean, never, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const pkgPath = join(repoDir, \"package.json\");\n const exists = yield* fs\n .exists(pkgPath)\n .pipe(Effect.orElseSucceed(() => false));\n if (!exists) return false;\n const content = yield* fs\n .readFileString(pkgPath)\n .pipe(Effect.orElseSucceed(() => \"\"));\n try {\n const parsed = JSON.parse(content) as Record<string, unknown>;\n const depMaps = [\n \"dependencies\",\n \"devDependencies\",\n \"peerDependencies\",\n \"optionalDependencies\",\n ];\n return depMaps.some((key) => {\n const deps = parsed[key];\n return (\n typeof deps === \"object\" && deps !== null && pkg in (deps as object)\n );\n });\n } catch {\n return false;\n }\n });\n\n// ---------------------------------------------------------------------------\n// Agent registry (internal — not part of public API)\n// ---------------------------------------------------------------------------\n\nexport interface AgentEntry {\n readonly name: string;\n readonly label: string;\n readonly defaultModel: string;\n readonly factoryImport: string;\n readonly dockerfileTemplate: string;\n /** Lines to include in the generated `.env.example` for this agent's API key. */\n readonly envExample: string;\n /**\n * Copy-pasteable interactive command that feeds the custom-issue-tracker\n * setup prompt to this agent's CLI on the host. Printed in init's next steps\n * when the `custom` issue tracker is selected. Runs on the host (the\n * sandbox image isn't built yet), so the user must have the CLI installed.\n */\n readonly setupCommand: string;\n}\n\nconst CLAUDE_CODE_DOCKERFILE = `FROM node:22-bookworm\n\n# Install system dependencies\nRUN apt-get update && apt-get install -y \\\\\n git \\\\\n curl \\\\\n jq \\\\\n && rm -rf /var/lib/apt/lists/*\n\n{{ISSUE_TRACKER_TOOLS}}\n\n# Build-args for UID/GID alignment: shipyard docker build-image\n# defaults these to the host user's UID/GID so image-built files\n# and bind-mounted files share an owner without runtime chown.\nARG AGENT_UID=1000\nARG AGENT_GID=1000\n\n# Rename the base image's \"node\" user to \"agent\" and align UID/GID.\nRUN groupmod -o -g $AGENT_GID node && usermod -o -u $AGENT_UID -g $AGENT_GID -d /home/agent -m -l agent node\nUSER \\${AGENT_UID}:\\${AGENT_GID}\n\n# Install Claude Code CLI\nRUN curl -fsSL https://claude.ai/install.sh | bash\n\n# Add Claude to PATH\nENV PATH=\"/home/agent/.local/bin:$PATH\"\n\nWORKDIR /home/agent\n\n# In worktree sandbox mode, Shipyard bind-mounts the git worktree at ${SANDBOX_REPO_DIR}\n# and overrides the working directory to ${SANDBOX_REPO_DIR} at container start.\n# Structure your Dockerfile so that ${SANDBOX_REPO_DIR} can serve as the project root.\nENTRYPOINT [\"sleep\", \"infinity\"]\n`;\n\nconst CODEX_DOCKERFILE = `FROM node:22-bookworm\n\n# Install system dependencies\nRUN apt-get update && apt-get install -y \\\\\n git \\\\\n curl \\\\\n jq \\\\\n && rm -rf /var/lib/apt/lists/*\n\n{{ISSUE_TRACKER_TOOLS}}\n\n# Build-args for UID/GID alignment: shipyard docker build-image\n# defaults these to the host user's UID/GID so image-built files\n# and bind-mounted files share an owner without runtime chown.\nARG AGENT_UID=1000\nARG AGENT_GID=1000\n\n# Rename the base image's \"node\" user to \"agent\" and align UID/GID.\nRUN groupmod -o -g $AGENT_GID node && usermod -o -u $AGENT_UID -g $AGENT_GID -d /home/agent -m -l agent node\n\n# Install Codex CLI (run as root before USER agent)\nRUN npm install -g @openai/codex\n\nUSER \\${AGENT_UID}:\\${AGENT_GID}\n\nWORKDIR /home/agent\n\n# In worktree sandbox mode, Shipyard bind-mounts the git worktree at ${SANDBOX_REPO_DIR}\n# and overrides the working directory to ${SANDBOX_REPO_DIR} at container start.\n# Structure your Dockerfile so that ${SANDBOX_REPO_DIR} can serve as the project root.\nENTRYPOINT [\"sleep\", \"infinity\"]\n`;\n\nconst AGENT_REGISTRY: AgentEntry[] = [\n {\n name: \"codex\",\n label: \"Codex\",\n defaultModel: CODEX_MODELS.routine.model,\n factoryImport: \"codex\",\n dockerfileTemplate: CODEX_DOCKERFILE,\n envExample: `# OpenAI API key\nOPENAI_API_KEY=`,\n setupCommand: `codex \"$(cat ${SETUP_ISSUE_TRACKER_PATH})\"`,\n },\n {\n name: \"claude-code\",\n label: \"Claude Code\",\n defaultModel: \"claude-opus-4-8\",\n factoryImport: \"claudeCode\",\n dockerfileTemplate: CLAUDE_CODE_DOCKERFILE,\n envExample: `# Claude Code OAuth token — get one by running \\`claude setup-token\\` on your host.\n# Lets the agent use your Claude subscription instead of an API key.\nCLAUDE_CODE_OAUTH_TOKEN=\n# Or use an Anthropic API key instead — uncomment and fill in:\n# ANTHROPIC_API_KEY=`,\n setupCommand: `claude \"$(cat ${SETUP_ISSUE_TRACKER_PATH})\"`,\n },\n];\n\nexport const listAgents = (): AgentEntry[] => AGENT_REGISTRY;\n\n// ---------------------------------------------------------------------------\n// Issue tracker registry (internal — not part of public API)\n// ---------------------------------------------------------------------------\n\nexport interface IssueTrackerEntry {\n readonly name: string;\n readonly label: string;\n readonly templateArgs: {\n readonly LIST_TASKS_COMMAND: string;\n readonly VIEW_TASK_COMMAND: string;\n readonly CLOSE_TASK_COMMAND: string;\n readonly ISSUE_TRACKER_TOOLS: string;\n };\n /** Lines to append to `.env.example` for this issue tracker, or empty string if none needed. */\n readonly envExample: string;\n}\n\nconst GITHUB_CLI_TOOLS = `# Install GitHub CLI\nRUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \\\\\n | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \\\\\n && echo \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" \\\\\n | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \\\\\n && apt-get update && apt-get install -y gh \\\\\n && rm -rf /var/lib/apt/lists/*`;\n\nconst BEADS_TOOLS = `# Install system dependencies for Beads\nRUN apt-get update && apt-get install -y \\\\\n dpkg-dev \\\\\n libicu72 \\\\\n && rm -rf /var/lib/apt/lists/* \\\\\n && ARCH_DIR=$(dpkg-architecture -qDEB_HOST_MULTIARCH) \\\\\n && for lib in /usr/lib/$ARCH_DIR/libicu*.so.72; do \\\\\n ln -s \"$lib\" \"\\${lib%.72}.74\"; \\\\\n done\n\nRUN curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash\n\nRUN corepack enable`;\n\n// Sentinels baked into the scaffold for the `custom` issue tracker. The\n// project ships deliberately broken-until-configured; the setup agent finds\n// and replaces these markers in place (see SETUP_ISSUE_TRACKER.md). Defined as\n// shared constants so the registry entry and the setup doc stay in sync.\nconst CUSTOM_LIST_TASKS_SENTINEL = `echo 'No issue tracker configured — run ${SETUP_ISSUE_TRACKER_PATH} through your coding agent.' >&2; exit 1`;\nconst CUSTOM_VIEW_TASK_MARKER = `<view command — see ${SETUP_ISSUE_TRACKER_PATH}>`;\nconst CUSTOM_CLOSE_TASK_MARKER = `<close command — see ${SETUP_ISSUE_TRACKER_PATH}>`;\nconst CUSTOM_TRACKER_TOOLS = `# TODO: install your issue tracker's CLI here. See ${SETUP_ISSUE_TRACKER_PATH}`;\nconst CUSTOM_ENV_EXAMPLE = `# TODO: add any env vars your issue tracker needs (e.g. an API token).\n# See ${SETUP_ISSUE_TRACKER_PATH}`;\n\nconst ISSUE_TRACKER_REGISTRY: IssueTrackerEntry[] = [\n {\n name: \"github-issues\",\n label: \"GitHub Issues\",\n templateArgs: {\n LIST_TASKS_COMMAND: `gh issue list --state open --label ${PRODUCT_NAME} --limit 100 --json number,title,body,labels,comments --jq '[.[] | {number, title, body, labels: [.labels[].name], comments: [.comments[].body]}]'`,\n VIEW_TASK_COMMAND: \"gh issue view <ID>\",\n CLOSE_TASK_COMMAND: `gh issue close <ID> --comment \"Completed by ${PRODUCT_NAME}\"`,\n ISSUE_TRACKER_TOOLS: GITHUB_CLI_TOOLS,\n },\n envExample: `# GitHub personal access token — the agent uses it to read and manage GitHub Issues\n# Create a fine-grained token: https://github.com/settings/personal-access-tokens/new\n# Required repository permissions: Issues (Read and write) and Metadata (Read)\nGH_TOKEN=`,\n },\n {\n name: \"beads\",\n label: \"Beads\",\n templateArgs: {\n LIST_TASKS_COMMAND: \"bd ready --json\",\n VIEW_TASK_COMMAND: \"bd show <ID>\",\n CLOSE_TASK_COMMAND: `bd close <ID> --reason=\"Completed by ${PRODUCT_NAME}\"`,\n ISSUE_TRACKER_TOOLS: BEADS_TOOLS,\n },\n envExample: \"\",\n },\n {\n name: \"custom\",\n label: \"Custom\",\n templateArgs: {\n // The only real shell expression: PromptPreprocessor fails the run on a\n // non-zero exit and surfaces stderr, so this is the single enforcement\n // point that keeps the scaffold broken until the user configures it.\n LIST_TASKS_COMMAND: CUSTOM_LIST_TASKS_SENTINEL,\n // Inline text markers — replaced by the setup agent, never executed.\n VIEW_TASK_COMMAND: CUSTOM_VIEW_TASK_MARKER,\n CLOSE_TASK_COMMAND: CUSTOM_CLOSE_TASK_MARKER,\n ISSUE_TRACKER_TOOLS: CUSTOM_TRACKER_TOOLS,\n },\n envExample: CUSTOM_ENV_EXAMPLE,\n },\n];\n\nexport const listIssueTrackers = (): IssueTrackerEntry[] =>\n ISSUE_TRACKER_REGISTRY;\n\nexport const getIssueTracker = (name: string): IssueTrackerEntry | undefined =>\n ISSUE_TRACKER_REGISTRY.find((b) => b.name === name);\n\nexport const getAgent = (name: string): AgentEntry | undefined =>\n AGENT_REGISTRY.find((a) => a.name === name);\n\n// ---------------------------------------------------------------------------\n// Sandbox provider registry (internal — not part of public API)\n// ---------------------------------------------------------------------------\n\nexport interface SandboxProviderEntry {\n readonly name: string;\n readonly label: string;\n /** Filename written to .shipyard/. */\n readonly containerfileName: string;\n /** CLI namespace for build/remove commands. */\n readonly cliNamespace: string;\n}\n\nconst SANDBOX_PROVIDER_REGISTRY: SandboxProviderEntry[] = [\n {\n name: \"docker\",\n label: \"Docker\",\n containerfileName: \"Dockerfile\",\n cliNamespace: \"docker\",\n },\n];\n\nexport const listSandboxProviders = (): SandboxProviderEntry[] =>\n SANDBOX_PROVIDER_REGISTRY;\n\nexport const getSandboxProvider = (\n name: string,\n): SandboxProviderEntry | undefined =>\n SANDBOX_PROVIDER_REGISTRY.find((p) => p.name === name);\n\n// ---------------------------------------------------------------------------\n// Next steps\n// ---------------------------------------------------------------------------\n\nexport function getNextStepsLines(\n template: string,\n mainFilename: string,\n issueTracker: IssueTrackerEntry,\n agent: AgentEntry,\n packageManager: PackageManager,\n codexAuth: CodexAuthMode = \"api-key\",\n): string[] {\n const getAuthLines = (step: number): string[] => {\n if (agent.name === \"codex\") {\n if (codexAuth === \"chatgpt\") {\n return [\n `${step}. Use your ChatGPT subscription with Codex: run \\`codex login\\` on the host and make sure \\`~/.codex/auth.json\\` exists`,\n ' If it does not exist, set `cli_auth_credentials_store = \"file\"` in `~/.codex/config.toml`, then run the login again',\n \" Shipyard mounts this credential read-only; use this mode only with trusted repositories.\",\n ` If subscription auth does not work, rerun init with \\`--codex-auth api-key\\` and set \\`OPENAI_API_KEY\\` in ${CONFIG_DIR}/.env instead.`,\n ` Also set any issue-tracker variables shown in ${CONFIG_DIR}/.env.example.`,\n ];\n }\n return [\n `${step}. Use your ChatGPT subscription with Codex (recommended): run \\`codex login\\` on the host, then initialize with \\`--codex-auth chatgpt\\` so Shipyard can mount \\`~/.codex/auth.json\\` read-only`,\n ` If subscription auth does not work, use API-key billing instead by setting \\`OPENAI_API_KEY\\` in ${CONFIG_DIR}/.env (see ${CONFIG_DIR}/.env.example).`,\n ` Also set any issue-tracker variables shown in ${CONFIG_DIR}/.env.example.`,\n ];\n }\n\n if (agent.name === \"claude-code\") {\n return [\n `${step}. Use your Claude subscription (recommended): run \\`claude setup-token\\` on the host and paste the result into \\`CLAUDE_CODE_OAUTH_TOKEN\\` in ${CONFIG_DIR}/.env`,\n ` If subscription auth does not work, use API-key billing instead by uncommenting \\`ANTHROPIC_API_KEY\\` in ${CONFIG_DIR}/.env and setting it to your key.`,\n ` Also set any issue-tracker variables shown in ${CONFIG_DIR}/.env.example.`,\n ];\n }\n\n return [\n `${step}. Set the required env vars in ${CONFIG_DIR}/.env (see ${CONFIG_DIR}/.env.example)`,\n ];\n };\n\n // The custom issue tracker scaffolds a broken-until-configured project, so\n // its next steps are about running the setup prompt — not the template's\n // normal \"set env vars and go\" flow. This branch wins over template-specific\n // steps regardless of the chosen template.\n if (issueTracker.name === \"custom\") {\n const authLines =\n agent.name === \"codex\" && codexAuth === \"chatgpt\" ? getAuthLines(1) : [];\n const setupStep = authLines.length > 0 ? 2 : 1;\n return [\n \"Next steps:\",\n ...authLines,\n `${setupStep}. Your custom issue tracker isn't wired up yet — runs hard-fail until you configure it.`,\n `${setupStep + 1}. Feed the setup prompt to ${agent.label} on your host to finish wiring it up:`,\n ` ${agent.setupCommand}`,\n ` (Runs on the host — you need the ${agent.label} CLI installed locally, since the sandbox image isn't built yet.)`,\n `${setupStep + 2}. Follow ${CONFIG_DIR}/${SETUP_ISSUE_TRACKER_DOC} to edit the scaffolded files in place, build the image, and verify.`,\n ];\n }\n if (template === \"blank\") {\n const lines = [\"Next steps:\", ...getAuthLines(1)];\n lines.push(\n `2. Read and customize ${CONFIG_DIR}/prompt.md to describe what you want the agent to do`,\n `3. Customize ${CONFIG_DIR}/${mainFilename} — it uses the JS API (\\`run()\\`) to control how the agent runs`,\n `4. Run \\`npx ${CLI_NAME} run\\` to build the sandbox image and start the agent`,\n );\n return lines;\n } else {\n const hasReviewer = template.includes(\"review\");\n const usesPlanSchema = getTemplateDependencies(template).includes(\"zod\");\n let step = 1;\n const lines: string[] = [\"Next steps:\", ...getAuthLines(step++)];\n lines.push(\n `${step++}. Templates use \\`copyToWorktree: [\"node_modules\"]\\` to copy your host node_modules into the sandbox for fast startup — the \\`npm install\\` in the onSandboxReady hook is a safety net for platform-specific binaries. Adjust both if you use a different package manager`,\n );\n if (usesPlanSchema) {\n lines.push(\n `${step++}. Install a schema validator for the planner's \\`<plan>\\` output — the template uses Zod (\\`${addDependencyCommand(packageManager, \"zod\")}\\`), but Valibot, ArkType, or any Standard Schema library works (https://standardschema.dev)`,\n );\n }\n lines.push(\n `${step++}. Read and customize the prompt files in ${CONFIG_DIR}/ — they shape what the agent does`,\n );\n if (hasReviewer) {\n lines.push(\n `${step++}. Customize ${CONFIG_DIR}/CODING_STANDARDS.md with your project's standards — the reviewer agent loads it during review`,\n );\n }\n lines.push(\n `${step++}. Run \\`npx ${CLI_NAME} run\\` to build the sandbox image and start the workflow`,\n );\n return lines;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Scaffolding helpers\n// ---------------------------------------------------------------------------\n\nfunction getTemplatesDir(): string {\n const thisFile = fileURLToPath(import.meta.url);\n return join(dirname(thisFile), \"templates\");\n}\n\nconst getTemplateDir = (\n templateName: string,\n): Effect.Effect<string, Error, never> =>\n Effect.gen(function* () {\n const template = TEMPLATES.find((t) => t.name === templateName);\n if (!template) {\n const names = TEMPLATES.map((t) => t.name).join(\", \");\n yield* Effect.fail(\n new Error(`Unknown template: \"${templateName}\". Available: ${names}`),\n );\n }\n return join(getTemplatesDir(), templateName);\n });\n\nconst COMPILED_FILE_EXTENSIONS = [\n \".js\",\n \".js.map\",\n \".d.ts\",\n \".d.ts.map\",\n \".mjs\",\n \".mjs.map\",\n \".d.mts\",\n \".d.mts.map\",\n];\n\nconst copyTemplateFiles = (\n templateDir: string,\n destDir: string,\n mainFilename: string,\n): Effect.Effect<void, Error, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const files = yield* fs\n .readDirectory(templateDir)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n yield* Effect.all(\n files\n .filter(\n (f) =>\n f !== \"template.json\" &&\n f !== \".env.example\" &&\n !COMPILED_FILE_EXTENSIONS.some((ext) => f.endsWith(ext)),\n )\n .map((f) => {\n const destName = f === \"main.mts\" ? mainFilename : f;\n return fs\n .copyFile(join(templateDir, f), join(destDir, destName))\n .pipe(Effect.mapError((e) => new Error(e.message)));\n }),\n { concurrency: \"unbounded\" },\n );\n });\n\n/**\n * Replace the agent factory and sandbox provider in a scaffolded main.ts.\n *\n * Templates use `codex` as the default agent factory and `docker` as the\n * default sandbox provider. When a different agent, model, or sandbox provider\n * is selected, this function rewrites the imports and factory calls.\n */\nconst rewriteMainTs = (\n configDir: string,\n agent: AgentEntry,\n model: string,\n sandboxProvider: SandboxProviderEntry,\n mainFilename: string,\n codexAuth: CodexAuthMode,\n): Effect.Effect<void, Error, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const mainTsPath = join(configDir, mainFilename);\n\n const exists = yield* fs\n .exists(mainTsPath)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n if (!exists) return;\n\n let content = yield* fs\n .readFileString(mainTsPath)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n\n // Templates use main.mts as the canonical filename in comments.\n // When the target is main.ts, rewrite those references.\n if (mainFilename === \"main.ts\") {\n content = content.replace(/main\\.mts/g, \"main.ts\");\n }\n\n // Replace the default factory function name in imports.\n // and all factory calls with the correct model.\n // Templates always use Codex as the placeholder factory.\n content = content.replace(\n new RegExp(`\\\\b${TEMPLATE_AGENT_FACTORY}\\\\b`, \"g\"),\n agent.factoryImport,\n );\n // Replace model arguments in factory calls. The built-in Codex templates\n // use CODEX_MODELS references so the central model configuration remains\n // live in a default Codex scaffold.\n const factoryCallRe = new RegExp(\n `${agent.factoryImport}\\\\(([^)\\\\n]*)\\\\)`,\n \"g\",\n );\n content = content.replace(\n factoryCallRe,\n (match, modelExpression: string) => {\n const keepsConfiguredModel =\n agent.name === \"codex\" &&\n model === CODEX_MODELS.routine.model &&\n /^(?:[A-Za-z_$][\\w$]*\\.)*CODEX_MODELS\\.[A-Za-z_$][\\w$]*$/.test(\n modelExpression.trim(),\n );\n return keepsConfiguredModel\n ? match\n : `${agent.factoryImport}(\"${model}\")`;\n },\n );\n\n // CODEX_MODELS is only needed when the generated file continues using\n // the central Codex configuration. Remove it from named imports when a\n // custom model or another provider has replaced every reference.\n if (agent.name !== \"codex\" || model !== CODEX_MODELS.routine.model) {\n content = content.replace(/\\bCODEX_MODELS,\\s*/g, \"\");\n }\n\n // ChatGPT subscription auth is stored by the host Codex CLI. Mount the\n // file into the sandbox read-only so Codex can use it without exposing an\n // API key through the generated .env file.\n if (agent.name === \"codex\" && codexAuth === \"chatgpt\") {\n content = content.replace(\n /\\bdocker\\(\\)/g,\n `docker(${CODEX_CHATGPT_AUTH_OPTIONS})`,\n );\n }\n\n // Replace the sandbox provider. Templates always use `docker` as the\n // placeholder, where the registry name doubles as both the factory function\n // name and the `/sandboxes/<name>` import subpath segment. A single\n // case-sensitive word-boundary replace therefore rewrites the named import,\n // the import subpath, and every factory call site — and is a no-op when\n // docker is selected.\n content = content.replace(/\\bdocker\\b/g, sandboxProvider.name);\n\n yield* fs\n .writeFileString(mainTsPath, content)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n });\n\n/**\n * When the user opted out of the Shipyard label, strip the corresponding label\n * from all `.md` files in the scaffolded config directory so that `gh issue list`\n * commands work without a label filter.\n */\nconst rewritePromptFiles = (\n configDir: string,\n): Effect.Effect<void, Error, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const files = yield* fs\n .readDirectory(configDir)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n const mdFiles = files.filter((f) => f.endsWith(\".md\"));\n yield* Effect.all(\n mdFiles.map((f) =>\n Effect.gen(function* () {\n const filePath = join(configDir, f);\n const content = yield* fs\n .readFileString(filePath)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n const updated = content.replace(\n new RegExp(` --label ${PRODUCT_NAME}`, \"g\"),\n \"\",\n );\n if (updated !== content) {\n yield* fs\n .writeFileString(filePath, updated)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n }\n }),\n ),\n { concurrency: \"unbounded\" },\n );\n });\n\n/** Text file extensions eligible for `{{KEY}}` template argument substitution. */\nconst TEXT_FILE_EXTENSIONS = new Set([\n \".md\",\n \".txt\",\n \".env\",\n \".example\",\n // Dockerfile / Containerfile have no extension — handled by name check below\n]);\n\nconst isTextFile = (filename: string): boolean => {\n if (\n filename === \"Dockerfile\" ||\n filename === \"Containerfile\" ||\n filename === \".gitignore\"\n )\n return true;\n const dotIdx = filename.lastIndexOf(\".\");\n if (dotIdx === -1) return false;\n return TEXT_FILE_EXTENSIONS.has(filename.slice(dotIdx));\n};\n\n/**\n * Replace `{{KEY}}` template arguments from the issue tracker's\n * `templateArgs` map in all text files in the scaffolded config directory.\n */\nconst substituteTemplateArgs = (\n configDir: string,\n issueTracker: IssueTrackerEntry,\n): Effect.Effect<void, Error, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const files = yield* fs\n .readDirectory(configDir)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n const textFiles = files.filter(isTextFile);\n yield* Effect.all(\n textFiles.map((f) =>\n Effect.gen(function* () {\n const filePath = join(configDir, f);\n let content = yield* fs\n .readFileString(filePath)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n const original = content;\n for (const [key, value] of Object.entries(\n issueTracker.templateArgs,\n )) {\n content = content.replace(\n new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, \"g\"),\n value,\n );\n }\n if (content !== original) {\n yield* fs\n .writeFileString(filePath, content)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n }\n }),\n ),\n { concurrency: \"unbounded\" },\n );\n });\n\n/**\n * Build the `SETUP_ISSUE_TRACKER.md` prompt scaffolded for the `custom` issue\n * tracker. It addresses the user's coding agent and walks it through wiring up\n * the tracker by editing the scaffolded files in place. The build command is\n * provider-parameterized so it names the selected CLI namespace.\n */\nconst buildSetupIssueTrackerDoc = (cliNamespace: string): string =>\n `# Set up your custom issue tracker\n\nYou are a coding agent. Finish wiring up the **custom issue tracker** for this Shipyard project. It was scaffolded in a deliberately broken-until-configured state: until you complete the steps below, every Shipyard run hard-fails with a pointer back to this file.\n\n## Goal\n\nWire up the issue tracker so the scaffolded prompts can **list**, **view**, and **close** tasks. There is no runtime abstraction to implement — the tracker commands are baked into the scaffolded files, so you edit those files **in place**.\n\n## 1. Interview the user\n\nAsk the user:\n\n- Which issue tracker do they use (e.g. Jira, Linear, a GitHub repo other than this one, an internal API)?\n- How should the sandbox authenticate — a CLI that is already logged in, or an API token? If a token, what is the environment variable name?\n\n## 2. Produce three commands\n\nWork out, together with the user, the shell commands for:\n\n- **list** — print all open tasks **as JSON** (match the shape the built-in trackers emit: an array of objects, each with at least an id/number, title, and body). This is what the agent reads at the start of every iteration.\n- **view** \\`<ID>\\` — show a single task by id.\n- **close** \\`<ID>\\` — close a single task by id.\n\n## 3. Edit the scaffolded files in place\n\n- **Dockerfile / Containerfile** — replace the line\n\n \\`\\`\\`\n ${CUSTOM_TRACKER_TOOLS}\n \\`\\`\\`\n\n with the install steps for your tracker's CLI (if it needs one).\n\n- **Prompt files (\\`${CONFIG_DIR}/*.md\\`)** — replace the sentinel\n\n \\`\\`\\`\n ${CUSTOM_LIST_TASKS_SENTINEL}\n \\`\\`\\`\n\n with your **list** command. In the prompt file the sentinel sits inside a Shipyard **shell expression** — a leading \\`!\\` followed by the command in backticks — whose output is injected into the prompt before each run. Keep that \\`!\\` and the surrounding backticks; replace only the command between them, and **remove the \\`exit 1\\`** (leaving it keeps every run hard-failing). Then replace the \\`${CUSTOM_VIEW_TASK_MARKER}\\` and \\`${CUSTOM_CLOSE_TASK_MARKER}\\` markers with your **view** and **close** commands.\n\n- **\\`.env.example\\`** — replace the \\`# TODO\\` block with the real env var(s) your tracker needs, then tell the user to set them in \\`${CONFIG_DIR}/.env\\`.\n\n## 4. Build the image\n\nOnce the files are wired up, build the sandbox image:\n\n\\`\\`\\`\n${CLI_NAME} ${cliNamespace} build-image\n\\`\\`\\`\n\n## 5. Verify\n\nRun your **list** command inside the built image and confirm it returns the open tasks as JSON. If it errors, fix the command or the auth and rebuild.\n`;\n\n// ---------------------------------------------------------------------------\n// Main scaffold function\n// ---------------------------------------------------------------------------\n\nexport interface ScaffoldOptions {\n agent: AgentEntry;\n model: string;\n templateName?: string;\n createLabel?: boolean;\n issueTracker?: IssueTrackerEntry;\n sandboxProvider?: SandboxProviderEntry;\n codexAuth?: CodexAuthMode;\n}\n\nexport interface ScaffoldResult {\n mainFilename: string;\n}\n\n/**\n * Detect whether the project's package.json has `\"type\": \"module\"`.\n * If so, we can use plain `.ts`; otherwise we use `.mts` to ensure ESM.\n */\nconst detectMainFilename = (\n repoDir: string,\n): Effect.Effect<string, never, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const pkgPath = join(repoDir, \"package.json\");\n const exists = yield* fs\n .exists(pkgPath)\n .pipe(Effect.orElseSucceed(() => false));\n if (!exists) return \"main.mts\";\n const content = yield* fs\n .readFileString(pkgPath)\n .pipe(Effect.orElseSucceed(() => \"\"));\n try {\n const pkg = JSON.parse(content) as Record<string, unknown>;\n return pkg[\"type\"] === \"module\" ? \"main.ts\" : \"main.mts\";\n } catch {\n return \"main.mts\";\n }\n });\n\nexport const scaffold = (\n repoDir: string,\n options: ScaffoldOptions,\n): Effect.Effect<ScaffoldResult, Error, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const {\n agent,\n model,\n templateName = \"blank\",\n createLabel = true,\n issueTracker = ISSUE_TRACKER_REGISTRY[0]!, // default: github-issues\n sandboxProvider = SANDBOX_PROVIDER_REGISTRY[0]!, // default: docker\n codexAuth = \"api-key\",\n } = options;\n if (codexAuth === \"chatgpt\" && agent.name !== \"codex\") {\n return yield* Effect.fail(\n new Error(\n \"ChatGPT subscription authentication is only supported for Codex.\",\n ),\n );\n }\n const fs = yield* FileSystem.FileSystem;\n yield* assertConfigDirAvailable(repoDir);\n const configDir = join(repoDir, CONFIG_DIR);\n\n const mainFilename = yield* detectMainFilename(repoDir);\n\n yield* fs\n .makeDirectory(configDir, { recursive: false })\n .pipe(Effect.mapError((e) => new Error(e.message)));\n\n const templateDir = yield* getTemplateDir(templateName);\n\n // Build .env.example from agent + issue tracker env blocks\n const envExampleParts = [\n agent.name === \"codex\" && codexAuth === \"chatgpt\"\n ? CODEX_CHATGPT_ENV_EXAMPLE\n : agent.envExample,\n ];\n if (issueTracker.envExample) {\n envExampleParts.push(issueTracker.envExample);\n }\n const envExampleContent = envExampleParts.join(\"\\n\") + \"\\n\";\n\n yield* Effect.all(\n [\n fs\n .writeFileString(\n join(configDir, sandboxProvider.containerfileName),\n agent.dockerfileTemplate,\n )\n .pipe(Effect.mapError((e) => new Error(e.message))),\n fs\n .writeFileString(join(configDir, \".gitignore\"), GITIGNORE)\n .pipe(Effect.mapError((e) => new Error(e.message))),\n fs\n .writeFileString(join(configDir, \".env.example\"), envExampleContent)\n .pipe(Effect.mapError((e) => new Error(e.message))),\n copyTemplateFiles(templateDir, configDir, mainFilename),\n ],\n { concurrency: \"unbounded\" },\n );\n\n // Rewrite main file with the selected agent factory, model, and sandbox provider\n yield* rewriteMainTs(\n configDir,\n agent,\n model,\n sandboxProvider,\n mainFilename,\n codexAuth,\n );\n\n // Replace issue tracker template arguments in all text files (must run before label stripping)\n yield* substituteTemplateArgs(configDir, issueTracker);\n\n // Strip the Shipyard label from prompt files when the user declined label creation\n if (!createLabel) {\n yield* rewritePromptFiles(configDir);\n }\n\n // For the custom issue tracker, drop the setup prompt the user feeds to\n // their coding agent. Written after substituteTemplateArgs so it isn't\n // clobbered and references the resolved sentinel markers the agent finds\n // (not the {{KEY}} names, which are gone by now).\n if (issueTracker.name === \"custom\") {\n yield* fs\n .writeFileString(\n join(configDir, SETUP_ISSUE_TRACKER_DOC),\n buildSetupIssueTrackerDoc(sandboxProvider.cliNamespace),\n )\n .pipe(Effect.mapError((e) => new Error(e.message)));\n }\n\n return { mainFilename };\n });\n","import { execFileSync } from \"node:child_process\";\nimport { statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { InitError } from \"./errors.js\";\n\nexport interface CodexAuthPreflightOptions {\n readonly cwd: string;\n readonly interactive: boolean;\n /** Test seam; production uses the user's default ~/.codex directory. */\n readonly authHome?: string;\n /** Test seam; production runs `codex login` in the user's terminal. */\n readonly login?: (cwd: string) => void;\n}\n\nexport const codexAuthFilePath = (\n authHome = join(homedir(), \".codex\"),\n): string => join(authHome, \"auth.json\");\n\nconst isRegularFile = (path: string): boolean => {\n try {\n return statSync(path).isFile();\n } catch {\n return false;\n }\n};\n\nconst isMissingCodexCli = (error: unknown): boolean =>\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === \"ENOENT\";\n\n// Shipyard mounts auth.json into the sandbox, so make this login use the file\n// store without changing the user's permanent Codex configuration.\nconst codexLoginArgs = [\n \"--config\",\n 'cli_auth_credentials_store=\"file\"',\n \"login\",\n];\n\nconst runCodexLogin = (cwd: string): void => {\n try {\n execFileSync(\"codex\", codexLoginArgs, { cwd, stdio: \"inherit\" });\n } catch (error) {\n if (!isMissingCodexCli(error)) throw error;\n // Shipyard already requires npm. Use npx as a no-global-install fallback\n // when the user has not installed the Codex CLI on the host yet.\n execFileSync(\n process.platform === \"win32\" ? \"npx.cmd\" : \"npx\",\n [\"--yes\", \"@openai/codex\", ...codexLoginArgs],\n { cwd, stdio: \"inherit\" },\n );\n }\n};\n\n/**\n * Ensure the host has a file-backed Codex ChatGPT login for the generated\n * sandbox mount. The browser/device login remains user-driven; init only\n * starts it when an interactive terminal is available.\n */\nexport const ensureCodexChatGptAuth = (\n options: CodexAuthPreflightOptions,\n): void => {\n const authFile = codexAuthFilePath(options.authHome);\n if (isRegularFile(authFile)) return;\n\n if (!options.interactive) {\n throw new InitError({\n message:\n \"Codex ChatGPT authentication is not ready: ~/.codex/auth.json was not found. Run `codex login` in an interactive terminal, then rerun `shipyard init --codex-auth chatgpt` (non-interactive mode cannot open the login flow).\",\n });\n }\n\n try {\n (options.login ?? runCodexLogin)(options.cwd);\n } catch (error) {\n if (error instanceof InitError) throw error;\n if (isMissingCodexCli(error)) {\n throw new InitError({\n message:\n \"The Codex CLI is not installed. Install it with `npm install --global @openai/codex`, run `codex login`, and rerun Shipyard init.\",\n });\n }\n throw new InitError({\n message:\n \"Codex login failed. Complete `codex login` successfully, then rerun Shipyard init.\",\n });\n }\n\n if (!isRegularFile(authFile)) {\n throw new InitError({\n message:\n 'Codex login finished, but ~/.codex/auth.json was not created. Codex may be using an OS keyring or a managed configuration. Set `cli_auth_credentials_store = \"file\"` in `~/.codex/config.toml`, run `codex login` again, and rerun Shipyard init.',\n });\n }\n};\n","import { createRequire } from \"node:module\";\n\ndeclare const __SHIPYARD_VERSION__: string | undefined;\n\nconst fallbackVersion = (): string => {\n const require = createRequire(import.meta.url);\n const pkg = require(\"../package.json\") as { version: string };\n return pkg.version;\n};\n\n/**\n * The package version. Injected at build time by tsup via `define`. When\n * the source is loaded directly (e.g. via `tsx` during tests) the constant\n * is undefined, so we fall back to reading `package.json` at runtime.\n */\nexport const VERSION: string =\n typeof __SHIPYARD_VERSION__ !== \"undefined\"\n ? __SHIPYARD_VERSION__\n : fallbackVersion();\n","import { Command, Options } from \"@effect/cli\";\nimport { Effect, Option } from \"effect\";\nimport * as clack from \"@clack/prompts\";\nimport { execSync, spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { styleText } from \"node:util\";\n\nimport { Display } from \"./Display.js\";\nimport { buildImage, removeImage } from \"./DockerLifecycle.js\";\nimport {\n scaffold,\n listTemplates,\n listAgents,\n getAgent,\n listIssueTrackers,\n getIssueTracker,\n listSandboxProviders,\n getSandboxProvider,\n DEFAULT_AGENT_NAME,\n getNextStepsLines,\n detectPackageManager,\n addDependencyCommand,\n hostHasDependency,\n getTemplateDependencies,\n} from \"./InitService.js\";\nimport { defaultImageName } from \"./sandboxes/docker.js\";\nimport type {\n AgentEntry,\n CodexAuthMode,\n IssueTrackerEntry,\n SandboxProviderEntry,\n} from \"./InitService.js\";\nimport { ExecHostError, InitError } from \"./errors.js\";\nimport { ensureCodexChatGptAuth } from \"./CodexAuth.js\";\nimport { requireCanonicalConfigDir } from \"./runtimeConfig.js\";\nimport { CONFIG_DIR, CLI_NAME, PRODUCT_NAME } from \"./runtimeNames.js\";\nimport { VERSION } from \"./version.js\";\n\n// --- Shared options ---\n\nconst imageNameOption = Options.text(\"image-name\").pipe(\n Options.withDescription(\"Docker image name\"),\n Options.optional,\n);\n\nconst resolveImageName = (\n cliFlag: Option.Option<string>,\n cwd: string,\n): string => (cliFlag._tag === \"Some\" ? cliFlag.value : defaultImageName(cwd));\n\n// --- UID build-args ---\n\n/** Build-args that align the image UID/GID to the host (Linux/macOS). No-op on Windows. */\nconst defaultUidBuildArgs = (): Record<string, string> => {\n const args: Record<string, string> = {};\n const uid = process.getuid?.();\n const gid = process.getgid?.();\n if (uid !== undefined) args.AGENT_UID = String(uid);\n if (gid !== undefined) args.AGENT_GID = String(gid);\n return args;\n};\n\n// --- Config directory check ---\n\nconst requireConfigDir = (\n cwd: string,\n): ReturnType<typeof requireCanonicalConfigDir> =>\n requireCanonicalConfigDir(cwd);\n\n// --- Run command ---\n\nconst runSandboxOption = Options.choice(\"sandbox\", [\"docker\"] as const).pipe(\n Options.withDescription(\n \"Sandbox provider to build (inferred from Dockerfile)\",\n ),\n Options.optional,\n);\n\nconst skipBuildOption = Options.boolean(\"skip-build\").pipe(\n Options.withDescription(\"Skip rebuilding the sandbox image\"),\n);\n\nconst entrypointOption = Options.text(\"entrypoint\").pipe(\n Options.withDescription(\n \"TypeScript entrypoint (defaults to .shipyard/main.ts or main.mts)\",\n ),\n Options.optional,\n);\n\ntype RunSandbox = \"docker\";\n\nconst resolveRunEntrypoint = (\n cwd: string,\n configDir: string,\n entrypoint: Option.Option<string>,\n): string | InitError => {\n if (entrypoint._tag === \"Some\") {\n const path = resolve(cwd, entrypoint.value);\n return existsSync(path)\n ? path\n : new InitError({ message: `Entrypoint not found: ${entrypoint.value}` });\n }\n\n for (const filename of [\"main.ts\", \"main.mts\"]) {\n const path = join(configDir, filename);\n if (existsSync(path)) return path;\n }\n\n return new InitError({\n message:\n \"No Shipyard entrypoint found. Expected .shipyard/main.ts or .shipyard/main.mts; run `shipyard init` first or pass `--entrypoint <path>.\",\n });\n};\n\nconst resolveRunSandbox = (\n configDir: string,\n sandbox: Option.Option<RunSandbox>,\n): RunSandbox | InitError => {\n if (sandbox._tag === \"Some\") {\n const filename = \"Dockerfile\";\n if (!existsSync(join(configDir, filename))) {\n return new InitError({\n message: `No .shipyard/${filename} found for the selected ${sandbox.value} sandbox provider.`,\n });\n }\n return sandbox.value;\n }\n\n const hasDockerfile = existsSync(join(configDir, \"Dockerfile\"));\n if (hasDockerfile) return \"docker\";\n return new InitError({\n message:\n \"No .shipyard/Dockerfile found. Run `shipyard init` first, or pass `--skip-build` for a programmatically configured sandbox.\",\n });\n};\n\nconst executeEntrypoint = (\n cwd: string,\n entrypoint: string,\n): Effect.Effect<void, ExecHostError> =>\n Effect.async((resume, signal) => {\n const command = process.platform === \"win32\" ? \"npx.cmd\" : \"npx\";\n const args = [\"--no-install\", \"tsx\", entrypoint];\n const child = spawn(command, args, {\n cwd,\n env: process.env,\n stdio: \"inherit\",\n });\n const commandText = `${command} ${args.join(\" \")}`;\n let settled = false;\n\n const finish = (effect: Effect.Effect<void, ExecHostError>) => {\n if (settled) return;\n settled = true;\n signal.removeEventListener(\"abort\", onAbort);\n resume(effect);\n };\n const onAbort = () => child.kill(\"SIGTERM\");\n signal.addEventListener(\"abort\", onAbort, { once: true });\n\n child.once(\"error\", (error) => {\n finish(\n Effect.fail(\n new ExecHostError({\n command: commandText,\n message: error.message,\n }),\n ),\n );\n });\n child.once(\"close\", (code, closeSignal) => {\n if (code === 0) {\n finish(Effect.succeed(undefined));\n return;\n }\n finish(\n Effect.fail(\n new ExecHostError({\n command: commandText,\n message:\n closeSignal === null\n ? `Process exited with code ${code ?? \"unknown\"}.`\n : `Process terminated by ${closeSignal}.`,\n }),\n ),\n );\n });\n });\n\nconst runCommand = Command.make(\n \"run\",\n {\n imageName: imageNameOption,\n sandbox: runSandboxOption,\n skipBuild: skipBuildOption,\n entrypoint: entrypointOption,\n },\n ({ imageName: imageNameFlag, sandbox, skipBuild, entrypoint }) =>\n Effect.gen(function* () {\n const d = yield* Display;\n const cwd = process.cwd();\n const configDir = yield* requireConfigDir(cwd);\n const resolvedEntrypoint = resolveRunEntrypoint(\n cwd,\n configDir,\n entrypoint,\n );\n if (resolvedEntrypoint instanceof InitError) {\n return yield* Effect.fail(resolvedEntrypoint);\n }\n\n if (!skipBuild) {\n const selectedSandbox = resolveRunSandbox(configDir, sandbox);\n if (selectedSandbox instanceof InitError) {\n return yield* Effect.fail(selectedSandbox);\n }\n const imageName = resolveImageName(imageNameFlag, cwd);\n yield* d.spinner(\n `Building Docker image '${imageName}'...`,\n buildImage(imageName, configDir, {\n buildArgs: defaultUidBuildArgs(),\n }),\n );\n }\n\n yield* d.status(\n `Running ${entrypoint._tag === \"Some\" ? entrypoint.value : \".shipyard/\" + resolvedEntrypoint.split(/[\\\\/]/).pop()}.`,\n \"info\",\n );\n yield* executeEntrypoint(cwd, resolvedEntrypoint);\n }),\n);\n\n// --- Init command ---\n\nconst templateOption = Options.text(\"template\").pipe(\n Options.withDescription(\n \"Template to scaffold (e.g. blank, simple-loop, parallel-planner)\",\n ),\n Options.optional,\n);\n\nconst agentOption = Options.text(\"agent\").pipe(\n Options.withDescription(\"Agent to use (e.g. codex)\"),\n Options.optional,\n);\n\nconst codexAuthOption = Options.choice(\"codex-auth\", [\n \"api-key\",\n \"chatgpt\",\n]).pipe(\n Options.withDescription(\n \"How Codex should authenticate: API key or ChatGPT subscription\",\n ),\n Options.optional,\n);\n\nconst initModelOption = Options.text(\"model\").pipe(\n Options.withDescription(\n \"Model to use for the agent. Defaults to the agent's configured default model\",\n ),\n Options.optional,\n);\n\nconst sandboxOption = Options.text(\"sandbox\").pipe(\n Options.withDescription(\"Sandbox provider to use (docker)\"),\n Options.optional,\n);\n\nconst issueTrackerOption = Options.text(\"issue-tracker\").pipe(\n Options.withDescription(\n \"Issue tracker to use (e.g. github-issues, beads, custom)\",\n ),\n Options.optional,\n);\n\n// Tri-state booleans (Some(true) / Some(false) / None) so we can tell \"user\n// chose false\" from \"user didn't pass the flag at all\" — only the latter\n// triggers the interactive prompt.\nconst createLabelOption = Options.choice(\"create-label\", [\n \"true\",\n \"false\",\n]).pipe(\n Options.withDescription(\n `Whether to create the \"${PRODUCT_NAME}\" GitHub label (only meaningful with --issue-tracker github-issues)`,\n ),\n Options.optional,\n);\n\nconst buildImageOption = Options.choice(\"build-image\", [\"true\", \"false\"]).pipe(\n Options.withDescription(\n \"Whether to build the sandbox image now (ignored when --issue-tracker custom is selected)\",\n ),\n Options.optional,\n);\n\nconst installTemplateDepsOption = Options.choice(\"install-template-deps\", [\n \"true\",\n \"false\",\n]).pipe(\n Options.withDescription(\n \"Whether to install the template's host dependencies (e.g. zod for the planner templates)\",\n ),\n Options.optional,\n);\n\n/**\n * Translate an `Options.choice(\"flag\", [\"true\", \"false\"]).optional` value into\n * a tri-state boolean. None when the flag was absent; otherwise the parsed bool.\n */\nconst choiceToTriBool = (\n opt: Option.Option<\"true\" | \"false\">,\n): Option.Option<boolean> =>\n opt._tag === \"Some\" ? Option.some(opt.value === \"true\") : Option.none();\n\nconst initCommand = Command.make(\n \"init\",\n {\n imageName: imageNameOption,\n template: templateOption,\n agent: agentOption,\n codexAuth: codexAuthOption,\n model: initModelOption,\n sandbox: sandboxOption,\n issueTracker: issueTrackerOption,\n createLabel: createLabelOption,\n buildImage: buildImageOption,\n installTemplateDeps: installTemplateDepsOption,\n },\n ({\n imageName: imageNameFlag,\n template,\n agent: agentFlag,\n codexAuth: codexAuthFlag,\n model: modelFlag,\n sandbox: sandboxFlag,\n issueTracker: issueTrackerFlag,\n createLabel: createLabelFlag,\n buildImage: buildImageFlag,\n installTemplateDeps: installTemplateDepsFlag,\n }) =>\n Effect.gen(function* () {\n const d = yield* Display;\n const cwd = process.cwd();\n const imageName = resolveImageName(imageNameFlag, cwd);\n\n // Early validation of CLI flags before interactive prompts\n const templates = listTemplates();\n if (template._tag === \"Some\") {\n const valid = templates.find((tmpl) => tmpl.name === template.value);\n if (!valid) {\n const names = templates.map((tmpl) => tmpl.name).join(\", \");\n yield* Effect.fail(\n new InitError({\n message: `Unknown template \"${template.value}\". Available: ${names}`,\n }),\n );\n }\n }\n\n if (sandboxFlag._tag === \"Some\") {\n const valid = getSandboxProvider(sandboxFlag.value);\n if (!valid) {\n const names = listSandboxProviders()\n .map((p) => p.name)\n .join(\", \");\n yield* Effect.fail(\n new InitError({\n message: `Unknown sandbox provider \"${sandboxFlag.value}\". Available: ${names}`,\n }),\n );\n }\n }\n\n if (issueTrackerFlag._tag === \"Some\") {\n const valid = getIssueTracker(issueTrackerFlag.value);\n if (!valid) {\n const names = listIssueTrackers()\n .map((t) => t.name)\n .join(\", \");\n yield* Effect.fail(\n new InitError({\n message: `Unknown issue tracker \"${issueTrackerFlag.value}\". Available: ${names}`,\n }),\n );\n }\n }\n\n const createLabelChoice = choiceToTriBool(createLabelFlag);\n const buildImageChoice = choiceToTriBool(buildImageFlag);\n const installTemplateDepsChoice = choiceToTriBool(\n installTemplateDepsFlag,\n );\n\n const isInteractive = process.stdin.isTTY === true;\n const failIfNonInteractive = (flag: string) =>\n Effect.fail(\n new InitError({\n message: `${flag} is required in non-interactive mode (no TTY detected).`,\n }),\n );\n\n // Tri-state confirm: CLI flag wins; otherwise prompt interactively (or\n // fail fast in non-interactive mode naming the missing flag). Cancelling\n // the prompt is treated as abort — same shape as the select prompts above.\n const resolveConfirmFlag = (params: {\n choice: Option.Option<boolean>;\n flag: string;\n promptMessage: string;\n cancelMessage: string;\n }): Effect.Effect<boolean, InitError> =>\n Effect.gen(function* () {\n if (params.choice._tag === \"Some\") return params.choice.value;\n if (!isInteractive) {\n yield* failIfNonInteractive(params.flag);\n }\n const confirmed = yield* Effect.promise(() =>\n clack.confirm({\n message: params.promptMessage,\n initialValue: true,\n }),\n );\n if (clack.isCancel(confirmed)) {\n yield* Effect.fail(\n new InitError({ message: params.cancelMessage }),\n );\n }\n return confirmed === true;\n });\n\n // Resolve agent: CLI flag > interactive select\n const agents = listAgents();\n let selectedAgent: AgentEntry;\n if (agentFlag._tag === \"Some\") {\n const entry = getAgent(agentFlag.value);\n if (!entry) {\n const names = agents.map((a) => a.name).join(\", \");\n yield* Effect.fail(\n new InitError({\n message: `Unknown agent \"${agentFlag.value}\". Available: ${names}`,\n }),\n );\n }\n selectedAgent = entry!;\n } else {\n if (!isInteractive) {\n yield* failIfNonInteractive(\"--agent\");\n }\n const selected = yield* Effect.promise(() =>\n clack.select({\n message: \"Select an agent:\",\n initialValue: DEFAULT_AGENT_NAME,\n options: agents.map((a) => ({\n value: a.name,\n label: a.label,\n hint: `Default model: ${a.defaultModel}`,\n })),\n }),\n );\n if (clack.isCancel(selected)) {\n yield* Effect.fail(\n new InitError({ message: \"Agent selection cancelled.\" }),\n );\n }\n selectedAgent = getAgent(selected as string)!;\n }\n\n // Resolve model: CLI flag > agent default\n const selectedModel =\n modelFlag._tag === \"Some\"\n ? modelFlag.value\n : selectedAgent.defaultModel;\n\n const selectedCodexAuth: CodexAuthMode =\n codexAuthFlag._tag === \"Some\" ? codexAuthFlag.value : \"api-key\";\n if (selectedCodexAuth === \"chatgpt\" && selectedAgent.name !== \"codex\") {\n yield* Effect.fail(\n new InitError({\n message:\n \"--codex-auth chatgpt can only be used with --agent codex.\",\n }),\n );\n }\n\n if (selectedCodexAuth === \"chatgpt\") {\n yield* Effect.try({\n try: () =>\n ensureCodexChatGptAuth({\n cwd,\n interactive: isInteractive,\n }),\n catch: (error) =>\n error instanceof InitError\n ? error\n : new InitError({\n message: `Codex authentication setup failed: ${String(error)}`,\n }),\n });\n }\n\n // Resolve sandbox provider: CLI flag > interactive select (no default — user must choose)\n const sandboxProviders = listSandboxProviders();\n let selectedSandboxProvider: SandboxProviderEntry;\n if (sandboxFlag._tag === \"Some\") {\n selectedSandboxProvider = getSandboxProvider(sandboxFlag.value)!;\n } else {\n if (!isInteractive) {\n yield* failIfNonInteractive(\"--sandbox\");\n }\n const selected = yield* Effect.promise(() =>\n clack.select({\n message: \"Select a sandbox provider:\",\n options: sandboxProviders.map((p) => ({\n value: p.name,\n label: p.label,\n })),\n }),\n );\n if (clack.isCancel(selected)) {\n yield* Effect.fail(\n new InitError({\n message: \"Sandbox provider selection cancelled.\",\n }),\n );\n }\n selectedSandboxProvider = getSandboxProvider(selected as string)!;\n }\n\n // Resolve issue tracker: CLI flag > interactive select (already validated above)\n const issueTrackers = listIssueTrackers();\n let selectedIssueTracker: IssueTrackerEntry;\n if (issueTrackerFlag._tag === \"Some\") {\n selectedIssueTracker = getIssueTracker(issueTrackerFlag.value)!;\n } else {\n if (!isInteractive) {\n yield* failIfNonInteractive(\"--issue-tracker\");\n }\n const selected = yield* Effect.promise(() =>\n clack.select({\n message: \"Select an issue tracker:\",\n initialValue: \"github-issues\",\n options: issueTrackers.map((b) => ({\n value: b.name,\n label: b.label,\n })),\n }),\n );\n if (clack.isCancel(selected)) {\n yield* Effect.fail(\n new InitError({\n message: \"Issue tracker selection cancelled.\",\n }),\n );\n }\n selectedIssueTracker = getIssueTracker(selected as string)!;\n }\n\n // Resolve template: CLI flag > interactive select (already validated above)\n let selectedTemplate: string;\n if (template._tag === \"Some\") {\n selectedTemplate = template.value;\n } else {\n if (!isInteractive) {\n yield* failIfNonInteractive(\"--template\");\n }\n const selected = yield* Effect.promise(() =>\n clack.select({\n message: \"Select a template:\",\n initialValue: \"blank\",\n options: templates.map((tmpl) => ({\n value: tmpl.name,\n label: tmpl.name,\n hint: tmpl.description,\n })),\n }),\n );\n if (clack.isCancel(selected)) {\n yield* Effect.fail(\n new InitError({ message: \"Template selection cancelled.\" }),\n );\n }\n selectedTemplate = selected as string;\n }\n\n // Offer to create the \"Shipyard\" label on the repo (skip for non-GitHub issue trackers).\n // CLI flag > interactive confirm. The flag is only meaningful for the github-issues tracker.\n let shouldCreateLabel = false;\n if (selectedIssueTracker.name === \"github-issues\") {\n shouldCreateLabel = yield* resolveConfirmFlag({\n choice: createLabelChoice,\n flag: \"--create-label\",\n promptMessage: `Create a \"${PRODUCT_NAME}\" GitHub label? (Templates filter issues by this label)`,\n cancelMessage: \"Label selection cancelled.\",\n });\n\n if (shouldCreateLabel) {\n yield* Effect.try({\n try: () =>\n execSync(\n `gh label create \"${PRODUCT_NAME}\" --description \"Issues for ${PRODUCT_NAME} to work on\" --color \"F9A825\" 2>/dev/null`,\n { cwd, stdio: \"ignore\" },\n ),\n catch: () => undefined,\n }).pipe(Effect.ignore);\n }\n }\n\n const scaffoldResult = yield* d.spinner(\n `Scaffolding ${CONFIG_DIR}/ config directory...`,\n scaffold(cwd, {\n agent: selectedAgent,\n model: selectedModel,\n templateName: selectedTemplate,\n createLabel: shouldCreateLabel,\n issueTracker: selectedIssueTracker,\n sandboxProvider: selectedSandboxProvider,\n codexAuth: selectedCodexAuth,\n }).pipe(\n Effect.mapError(\n (e) =>\n new InitError({\n message: `${e instanceof Error ? e.message : e}`,\n }),\n ),\n ),\n );\n\n // Detect the host package manager so the zod offer below and the next\n // steps below both use the right install command.\n const packageManager = yield* detectPackageManager(cwd);\n\n // If the chosen template imports zod on the host (the planner templates\n // build their <plan> output schema with it) and the host doesn't already\n // declare it, offer to install it. Without this, the very first\n // `npx tsx .shipyard/main.ts` crashes with ERR_MODULE_NOT_FOUND.\n if (getTemplateDependencies(selectedTemplate).includes(\"zod\")) {\n const alreadyInstalled = yield* hostHasDependency(cwd, \"zod\");\n if (!alreadyInstalled) {\n const installCmd = addDependencyCommand(packageManager, \"zod\");\n const shouldInstall = yield* resolveConfirmFlag({\n choice: installTemplateDepsChoice,\n flag: \"--install-template-deps\",\n promptMessage: `The ${selectedTemplate} template needs a schema validator. Install zod now (\\`${installCmd}\\`)?`,\n cancelMessage: \"Install-template-deps selection cancelled.\",\n });\n if (shouldInstall) {\n const installed = yield* Effect.sync(() => {\n try {\n execSync(installCmd, { cwd, stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n });\n yield* installed\n ? d.status(`Installed zod with ${packageManager}.`, \"success\")\n : d.status(\n `Couldn't install zod automatically. Run \\`${installCmd}\\` before running the agent.`,\n \"warn\",\n );\n }\n }\n }\n\n // Prompt user before building image. The custom issue tracker scaffolds\n // an intentionally unfinished Dockerfile (the install block is a TODO),\n // so there is nothing valid to build yet — skip the build prompt entirely\n // (and silently ignore --build-image) and let the next steps point the\n // user at the setup doc.\n const providerLabel = selectedSandboxProvider.label;\n if (selectedIssueTracker.name === \"custom\") {\n yield* d.status(\n \"Init complete! Your custom issue tracker isn't configured yet — see the steps below before building.\",\n \"success\",\n );\n } else {\n const shouldBuild = yield* resolveConfirmFlag({\n choice: buildImageChoice,\n flag: \"--build-image\",\n promptMessage: `Build the default ${providerLabel} image now?`,\n cancelMessage: \"Build-image selection cancelled.\",\n });\n\n if (shouldBuild) {\n const containerfileDir = join(cwd, CONFIG_DIR);\n yield* d.spinner(\n `Building ${providerLabel} image '${imageName}'...`,\n buildImage(imageName, containerfileDir, {\n buildArgs: defaultUidBuildArgs(),\n }),\n );\n yield* d.status(\n \"Init complete! Image built successfully.\",\n \"success\",\n );\n } else {\n yield* d.status(\n `Init complete! Run \\`${CLI_NAME} ${selectedSandboxProvider.cliNamespace} build-image\\` to build the ${providerLabel} image later.`,\n \"success\",\n );\n }\n }\n\n // Show template-specific next steps\n const nextSteps = getNextStepsLines(\n selectedTemplate,\n scaffoldResult.mainFilename,\n selectedIssueTracker,\n selectedAgent,\n packageManager,\n selectedCodexAuth,\n );\n for (const [i, line] of nextSteps.entries()) {\n yield* d.text(i === 0 ? line : styleText(\"dim\", line));\n }\n }),\n);\n\n// --- Build-image command ---\n\nconst dockerfileOption = Options.file(\"dockerfile\").pipe(\n Options.withDescription(\n \"Path to a custom Dockerfile (build context will be the current working directory)\",\n ),\n Options.optional,\n);\n\nconst buildImageCommand = Command.make(\n \"build-image\",\n {\n imageName: imageNameOption,\n dockerfile: dockerfileOption,\n },\n ({ imageName: imageNameFlag, dockerfile }) =>\n Effect.gen(function* () {\n const d = yield* Display;\n const cwd = process.cwd();\n yield* requireConfigDir(cwd);\n\n const imageName = resolveImageName(imageNameFlag, cwd);\n\n const dockerfileDir = join(cwd, CONFIG_DIR);\n const dockerfilePath =\n dockerfile._tag === \"Some\" ? dockerfile.value : undefined;\n\n yield* d.spinner(\n `Building Docker image '${imageName}'...`,\n buildImage(imageName, dockerfileDir, {\n dockerfile: dockerfilePath,\n buildArgs: defaultUidBuildArgs(),\n }),\n );\n\n yield* d.status(\"Build complete!\", \"success\");\n }),\n);\n\n// --- Remove-image command ---\n\nconst removeImageCommand = Command.make(\n \"remove-image\",\n {\n imageName: imageNameOption,\n },\n ({ imageName: imageNameFlag }) =>\n Effect.gen(function* () {\n const d = yield* Display;\n const cwd = process.cwd();\n\n const imageName = resolveImageName(imageNameFlag, cwd);\n\n yield* d.spinner(\n `Removing Docker image '${imageName}'...`,\n removeImage(imageName),\n );\n yield* d.status(\"Image removed.\", \"success\");\n }),\n);\n\n// --- Docker namespace command ---\n\nconst dockerCommand = Command.make(\"docker\", {}, () =>\n Effect.gen(function* () {\n const d = yield* Display;\n yield* d.status(\n \"Docker sandbox commands. Use --help to see available subcommands.\",\n \"info\",\n );\n }),\n).pipe(Command.withSubcommands([buildImageCommand, removeImageCommand]));\n\n// --- Root command ---\n\nconst rootCommand = Command.make(CLI_NAME, {}, () =>\n Effect.gen(function* () {\n const d = yield* Display;\n yield* d.status(`${PRODUCT_NAME} v${VERSION}`, \"info\");\n yield* d.status(\"Use --help to see available commands.\", \"info\");\n }),\n);\n\nexport const shipyard = rootCommand.pipe(\n Command.withSubcommands([initCommand, runCommand, dockerCommand]),\n);\n\nexport const cli = Command.run(shipyard, {\n name: CLI_NAME,\n version: VERSION,\n});\n","/**\n * Terminal cleanup for abrupt exits.\n *\n * @clack/prompts' spinner and taskLog call stdin.setRawMode(true) and hide\n * the cursor via escape sequences. When the process is killed by a signal\n * handler that calls process.exit() directly (e.g. during Ctrl-C cleanup in\n * SandboxFactory), clack's own cleanup is bypassed and the terminal is left\n * in raw mode with the cursor hidden.\n *\n * Registering a process 'exit' listener that restores these guarantees the\n * terminal is always left in a usable state.\n */\n\n/** Escape sequence to show the cursor (DECTCEM). */\nexport const SHOW_CURSOR = \"\\x1b[?25h\";\n\n/**\n * Creates a synchronous exit handler that restores terminal state.\n * Extracted as a pure function so it can be unit-tested without side effects.\n */\nexport const makeTerminalCleanupHandler =\n (\n stdin: { isTTY?: boolean; setRawMode?: (raw: boolean) => void },\n stdout: { write: (data: string) => boolean },\n ) =>\n (): void => {\n if (stdin.isTTY && stdin.setRawMode) {\n try {\n stdin.setRawMode(false);\n } catch {\n // Best-effort — may fail if stdin is already closed\n }\n }\n stdout.write(SHOW_CURSOR);\n };\n\n/**\n * Registers the terminal cleanup handler on process 'exit'.\n * Call once at program startup (main.ts).\n */\nexport const setupTerminalCleanup = (): void => {\n process.on(\"exit\", makeTerminalCleanupHandler(process.stdin, process.stdout));\n};\n","#!/usr/bin/env node\nimport { NodeContext, NodeRuntime } from \"@effect/platform-node\";\nimport { Effect, Layer } from \"effect\";\nimport { cli } from \"./cli.js\";\nimport { ClackDisplay } from \"./Display.js\";\nimport { withFriendlyErrors } from \"./ErrorHandler.js\";\nimport { setupTerminalCleanup } from \"./terminalCleanup.js\";\n\n// Restore terminal state on any exit.\n// @clack/prompts' spinner/taskLog set stdin to raw mode and hide the cursor.\n// If the process exits via a signal handler that calls process.exit() directly\n// (e.g. the Ctrl-C handler in SandboxFactory), clack's own cleanup is\n// bypassed, leaving the terminal broken. This exit hook fixes that.\nsetupTerminalCleanup();\n\nconst mainLayer = Layer.merge(NodeContext.layer, ClackDisplay.layer);\n\ncli(process.argv).pipe(\n withFriendlyErrors,\n Effect.provide(mainLayer),\n NodeRuntime.runMain,\n);\n"]}
1
+ {"version":3,"sources":["../src/runtimeConfig.ts","../src/InitService.ts","../src/CodexAuth.ts","../src/version.ts","../src/cli.ts","../src/terminalCleanup.ts","../src/main.ts"],"names":["Effect","FileSystem","join"],"mappings":"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","file":"main.js","sourcesContent":["import { FileSystem } from \"@effect/platform\";\nimport { Effect } from \"effect\";\nimport { join } from \"node:path\";\n\nimport { ConfigDirError } from \"./errors.js\";\nimport { CONFIG_DIR, CLI_NAME } from \"./runtimeNames.js\";\n\nexport type ConfigDirState = \"missing\" | \"canonical\";\n\nconst pathExists = (\n path: string,\n): Effect.Effect<boolean, never, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n return yield* fs\n .exists(path)\n .pipe(Effect.catchAll(() => Effect.succeed(false)));\n });\n\nexport const getConfigDirState = (\n repoDir: string,\n): Effect.Effect<ConfigDirState, never, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const canonicalExists = yield* pathExists(join(repoDir, CONFIG_DIR));\n if (canonicalExists) return \"canonical\";\n return \"missing\";\n });\n\nexport const requireCanonicalConfigDir = (\n repoDir: string,\n): Effect.Effect<string, ConfigDirError, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const state = yield* getConfigDirState(repoDir);\n if (state === \"missing\") {\n return yield* Effect.fail(\n new ConfigDirError({\n message: `No ${CONFIG_DIR}/ found. Run \\`${CLI_NAME} init\\` first.`,\n }),\n );\n }\n return join(repoDir, CONFIG_DIR);\n });\n\n/** Fail before initialization can overwrite an existing configuration directory. */\nexport const assertConfigDirAvailable = (\n repoDir: string,\n): Effect.Effect<void, ConfigDirError, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const state = yield* getConfigDirState(repoDir);\n if (state === \"canonical\") {\n return yield* Effect.fail(\n new ConfigDirError({\n message: `${CONFIG_DIR}/ directory already exists. ${CLI_NAME} did not modify it. Use the existing configuration or remove it deliberately after preserving any active worktrees before re-initializing.`,\n }),\n );\n }\n });\n","import { FileSystem } from \"@effect/platform\";\nimport { Effect } from \"effect\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { SANDBOX_REPO_DIR } from \"./SandboxFactory.js\";\nimport { assertConfigDirAvailable } from \"./runtimeConfig.js\";\nimport {\n CONFIG_DIR,\n PRODUCT_NAME,\n CLI_NAME,\n LOCKS_DIR,\n} from \"./runtimeNames.js\";\nimport { CODEX_MODELS } from \"./modelConfig.js\";\n\nconst GITIGNORE = `.env\nlogs/\nworktrees/\n${LOCKS_DIR}/\n`;\n\nexport const DEFAULT_AGENT_NAME = \"codex\";\nconst TEMPLATE_AGENT_FACTORY = \"codex\";\n\nexport type CodexAuthMode = \"api-key\" | \"chatgpt\";\n\nconst CODEX_CHATGPT_ENV_EXAMPLE = `# Codex ChatGPT subscription authentication\n# On the host, run \\`codex login\\` and make sure \\`~/.codex/auth.json\\` exists.\n# Shipyard mounts that file read-only into the sandbox.\n# Do not add OPENAI_API_KEY here: that selects API-key billing instead.`;\n\nconst CODEX_CHATGPT_AUTH_OPTIONS = `{\n mounts: [\n {\n hostPath: \"~/.codex/auth.json\",\n sandboxPath: \"~/.codex/auth.json\",\n readonly: true,\n },\n ],\n}`;\n\nexport interface TemplateMetadata {\n name: string;\n description: string;\n /**\n * Host-side npm packages the template's `main` file imports directly (e.g.\n * the planner templates import `zod` for their `<plan>` output schema). Init\n * offers to install these with the detected package manager so that\n * `npx tsx ${CONFIG_DIR}/main.ts` doesn't crash with ERR_MODULE_NOT_FOUND.\n */\n dependencies?: readonly string[];\n}\n\nconst TEMPLATES: TemplateMetadata[] = [\n {\n name: \"blank\",\n description: \"Bare scaffold — write your own prompt and orchestration\",\n },\n {\n name: \"simple-loop\",\n description: \"Picks issues one by one and closes them\",\n },\n {\n name: \"sequential-reviewer\",\n description:\n \"Implements issues one by one, with a code review step after each\",\n },\n {\n name: \"parallel-planner\",\n description:\n \"Plans parallelizable issues, executes on separate branches, merges\",\n dependencies: [\"zod\"],\n },\n {\n name: \"parallel-planner-with-review\",\n description:\n \"Plans parallelizable issues, executes with per-branch review, merges\",\n dependencies: [\"zod\"],\n },\n];\n\nexport const listTemplates = (): TemplateMetadata[] => TEMPLATES;\n\n/**\n * Host-side npm packages the given template imports directly. Empty when the\n * template name is unknown or the template declares no extra dependencies.\n */\nexport const getTemplateDependencies = (\n templateName: string,\n): readonly string[] =>\n TEMPLATES.find((t) => t.name === templateName)?.dependencies ?? [];\n\n// ---------------------------------------------------------------------------\n// Package manager detection (internal — not part of public API)\n// ---------------------------------------------------------------------------\n\nconst PACKAGE_MANAGERS = [\"npm\", \"pnpm\", \"yarn\", \"bun\"] as const;\n\n/** A package manager Shipyard can detect on the host and build install commands for. */\nexport type PackageManager = (typeof PACKAGE_MANAGERS)[number];\n\n// Lockfiles checked in priority order. bun.lock / bun.lockb are both valid bun\n// lockfiles (text vs binary), so both map to bun.\nconst LOCKFILES: ReadonlyArray<readonly [string, PackageManager]> = [\n [\"bun.lockb\", \"bun\"],\n [\"bun.lock\", \"bun\"],\n [\"pnpm-lock.yaml\", \"pnpm\"],\n [\"yarn.lock\", \"yarn\"],\n [\"package-lock.json\", \"npm\"],\n];\n\n/**\n * Detect the host project's package manager. An explicit corepack-style\n * `packageManager` field in package.json wins; otherwise the first matching\n * lockfile decides. Defaults to npm when nothing matches.\n */\nexport const detectPackageManager = (\n repoDir: string,\n): Effect.Effect<PackageManager, never, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n\n const pkgPath = join(repoDir, \"package.json\");\n const pkgExists = yield* fs\n .exists(pkgPath)\n .pipe(Effect.orElseSucceed(() => false));\n if (pkgExists) {\n const content = yield* fs\n .readFileString(pkgPath)\n .pipe(Effect.orElseSucceed(() => \"\"));\n try {\n const pkg = JSON.parse(content) as Record<string, unknown>;\n const field = pkg[\"packageManager\"];\n if (typeof field === \"string\") {\n const name = field.split(\"@\")[0];\n const match = PACKAGE_MANAGERS.find((pm) => pm === name);\n if (match) return match;\n }\n } catch {\n // Malformed package.json — fall through to lockfile detection.\n }\n }\n\n for (const [file, pm] of LOCKFILES) {\n const exists = yield* fs\n .exists(join(repoDir, file))\n .pipe(Effect.orElseSucceed(() => false));\n if (exists) return pm;\n }\n\n return \"npm\";\n });\n\n/** Build the command that adds a runtime dependency for the given package manager. */\nexport const addDependencyCommand = (\n packageManager: PackageManager,\n pkg: string,\n): string => {\n switch (packageManager) {\n case \"pnpm\":\n return `pnpm add ${pkg}`;\n case \"yarn\":\n return `yarn add ${pkg}`;\n case \"bun\":\n return `bun add ${pkg}`;\n case \"npm\":\n return `npm install ${pkg}`;\n }\n};\n\n/**\n * Whether the host package.json already declares `pkg` in any of its dependency\n * maps. Used so init doesn't offer to install something already present.\n */\nexport const hostHasDependency = (\n repoDir: string,\n pkg: string,\n): Effect.Effect<boolean, never, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const pkgPath = join(repoDir, \"package.json\");\n const exists = yield* fs\n .exists(pkgPath)\n .pipe(Effect.orElseSucceed(() => false));\n if (!exists) return false;\n const content = yield* fs\n .readFileString(pkgPath)\n .pipe(Effect.orElseSucceed(() => \"\"));\n try {\n const parsed = JSON.parse(content) as Record<string, unknown>;\n const depMaps = [\n \"dependencies\",\n \"devDependencies\",\n \"peerDependencies\",\n \"optionalDependencies\",\n ];\n return depMaps.some((key) => {\n const deps = parsed[key];\n return (\n typeof deps === \"object\" && deps !== null && pkg in (deps as object)\n );\n });\n } catch {\n return false;\n }\n });\n\n// ---------------------------------------------------------------------------\n// Agent registry (internal — not part of public API)\n// ---------------------------------------------------------------------------\n\nexport interface AgentEntry {\n readonly name: string;\n readonly label: string;\n readonly defaultModel: string;\n readonly factoryImport: string;\n readonly dockerfileTemplate: string;\n /** Lines to include in the generated `.env.example` for this agent's API key. */\n readonly envExample: string;\n}\n\nconst CLAUDE_CODE_DOCKERFILE = `FROM node:22-bookworm\n\n# Install system dependencies\nRUN apt-get update && apt-get install -y \\\\\n git \\\\\n curl \\\\\n jq \\\\\n && rm -rf /var/lib/apt/lists/*\n\n{{ISSUE_TRACKER_TOOLS}}\n\n# Build-args for UID/GID alignment: shipyard docker build-image\n# defaults these to the host user's UID/GID so image-built files\n# and bind-mounted files share an owner without runtime chown.\nARG AGENT_UID=1000\nARG AGENT_GID=1000\n\n# Rename the base image's \"node\" user to \"agent\" and align UID/GID.\nRUN groupmod -o -g $AGENT_GID node && usermod -o -u $AGENT_UID -g $AGENT_GID -d /home/agent -m -l agent node\nUSER \\${AGENT_UID}:\\${AGENT_GID}\n\n# Install Claude Code CLI\nRUN curl -fsSL https://claude.ai/install.sh | bash\n\n# Add Claude to PATH\nENV PATH=\"/home/agent/.local/bin:$PATH\"\n\nWORKDIR /home/agent\n\n# In worktree sandbox mode, Shipyard bind-mounts the git worktree at ${SANDBOX_REPO_DIR}\n# and overrides the working directory to ${SANDBOX_REPO_DIR} at container start.\n# Structure your Dockerfile so that ${SANDBOX_REPO_DIR} can serve as the project root.\nENTRYPOINT [\"sleep\", \"infinity\"]\n`;\n\nconst CODEX_DOCKERFILE = `FROM node:22-bookworm\n\n# Install system dependencies\nRUN apt-get update && apt-get install -y \\\\\n git \\\\\n curl \\\\\n jq \\\\\n && rm -rf /var/lib/apt/lists/*\n\n{{ISSUE_TRACKER_TOOLS}}\n\n# Build-args for UID/GID alignment: shipyard docker build-image\n# defaults these to the host user's UID/GID so image-built files\n# and bind-mounted files share an owner without runtime chown.\nARG AGENT_UID=1000\nARG AGENT_GID=1000\n\n# Rename the base image's \"node\" user to \"agent\" and align UID/GID.\nRUN groupmod -o -g $AGENT_GID node && usermod -o -u $AGENT_UID -g $AGENT_GID -d /home/agent -m -l agent node\n\n# Install Codex CLI (run as root before USER agent)\nRUN npm install -g @openai/codex\n\nUSER \\${AGENT_UID}:\\${AGENT_GID}\n\nWORKDIR /home/agent\n\n# In worktree sandbox mode, Shipyard bind-mounts the git worktree at ${SANDBOX_REPO_DIR}\n# and overrides the working directory to ${SANDBOX_REPO_DIR} at container start.\n# Structure your Dockerfile so that ${SANDBOX_REPO_DIR} can serve as the project root.\nENTRYPOINT [\"sleep\", \"infinity\"]\n`;\n\nconst AGENT_REGISTRY: AgentEntry[] = [\n {\n name: \"codex\",\n label: \"Codex\",\n defaultModel: CODEX_MODELS.routine.model,\n factoryImport: \"codex\",\n dockerfileTemplate: CODEX_DOCKERFILE,\n envExample: `# OpenAI API key\nOPENAI_API_KEY=`,\n },\n {\n name: \"claude-code\",\n label: \"Claude Code\",\n defaultModel: \"claude-opus-4-8\",\n factoryImport: \"claudeCode\",\n dockerfileTemplate: CLAUDE_CODE_DOCKERFILE,\n envExample: `# Claude Code OAuth token — get one by running \\`claude setup-token\\` on your host.\n# Lets the agent use your Claude subscription instead of an API key.\nCLAUDE_CODE_OAUTH_TOKEN=\n# Or use an Anthropic API key instead — uncomment and fill in:\n# ANTHROPIC_API_KEY=`,\n },\n];\n\nexport const listAgents = (): AgentEntry[] => AGENT_REGISTRY;\n\n// ---------------------------------------------------------------------------\n// Issue tracker registry (internal — not part of public API)\n// ---------------------------------------------------------------------------\n\nexport interface IssueTrackerEntry {\n readonly name: string;\n readonly label: string;\n readonly templateArgs: {\n readonly LIST_TASKS_COMMAND: string;\n readonly VIEW_TASK_COMMAND: string;\n readonly CLOSE_TASK_COMMAND: string;\n readonly ISSUE_TRACKER_TOOLS: string;\n };\n /** Lines to append to `.env.example` for this issue tracker, or empty string if none needed. */\n readonly envExample: string;\n}\n\nconst GITHUB_CLI_TOOLS = `# Install GitHub CLI\nRUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \\\\\n | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \\\\\n && echo \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" \\\\\n | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \\\\\n && apt-get update && apt-get install -y gh \\\\\n && rm -rf /var/lib/apt/lists/*`;\n\nconst ISSUE_TRACKER_REGISTRY: IssueTrackerEntry[] = [\n {\n name: \"github-issues\",\n label: \"GitHub Issues\",\n templateArgs: {\n LIST_TASKS_COMMAND: `gh issue list --state open --label ${PRODUCT_NAME} --limit 100 --json number,title,body,labels,comments --jq '[.[] | {number, title, body, labels: [.labels[].name], comments: [.comments[].body]}]'`,\n VIEW_TASK_COMMAND: \"gh issue view <ID>\",\n CLOSE_TASK_COMMAND: `gh issue close <ID> --comment \"Completed by ${PRODUCT_NAME}\"`,\n ISSUE_TRACKER_TOOLS: GITHUB_CLI_TOOLS,\n },\n envExample: `# GitHub personal access token — the agent uses it to read and manage GitHub Issues\n# Create a fine-grained token: https://github.com/settings/personal-access-tokens/new\n# Required repository permissions: Issues (Read and write) and Metadata (Read)\nGH_TOKEN=`,\n },\n];\n\nexport const listIssueTrackers = (): IssueTrackerEntry[] =>\n ISSUE_TRACKER_REGISTRY;\n\nexport const getIssueTracker = (name: string): IssueTrackerEntry | undefined =>\n ISSUE_TRACKER_REGISTRY.find((b) => b.name === name);\n\nexport const getAgent = (name: string): AgentEntry | undefined =>\n AGENT_REGISTRY.find((a) => a.name === name);\n\n// ---------------------------------------------------------------------------\n// Sandbox provider registry (internal — not part of public API)\n// ---------------------------------------------------------------------------\n\nexport interface SandboxProviderEntry {\n readonly name: string;\n readonly label: string;\n /** Filename written to .shipyard/. */\n readonly containerfileName: string;\n /** CLI namespace for build/remove commands. */\n readonly cliNamespace: string;\n}\n\nconst SANDBOX_PROVIDER_REGISTRY: SandboxProviderEntry[] = [\n {\n name: \"docker\",\n label: \"Docker\",\n containerfileName: \"Dockerfile\",\n cliNamespace: \"docker\",\n },\n];\n\nexport const listSandboxProviders = (): SandboxProviderEntry[] =>\n SANDBOX_PROVIDER_REGISTRY;\n\nexport const getSandboxProvider = (\n name: string,\n): SandboxProviderEntry | undefined =>\n SANDBOX_PROVIDER_REGISTRY.find((p) => p.name === name);\n\n// ---------------------------------------------------------------------------\n// Next steps\n// ---------------------------------------------------------------------------\n\nexport function getNextStepsLines(\n template: string,\n mainFilename: string,\n agent: AgentEntry,\n packageManager: PackageManager,\n codexAuth: CodexAuthMode = \"api-key\",\n): string[] {\n const getAuthLines = (step: number): string[] => {\n if (agent.name === \"codex\") {\n if (codexAuth === \"chatgpt\") {\n return [\n `${step}. Use your ChatGPT subscription with Codex: run \\`codex login\\` on the host and make sure \\`~/.codex/auth.json\\` exists`,\n ' If it does not exist, set `cli_auth_credentials_store = \"file\"` in `~/.codex/config.toml`, then run the login again',\n \" Shipyard mounts this credential read-only; use this mode only with trusted repositories.\",\n ` If subscription auth does not work, rerun init with \\`--codex-auth api-key\\` and set \\`OPENAI_API_KEY\\` in ${CONFIG_DIR}/.env instead.`,\n ` Also set any issue-tracker variables shown in ${CONFIG_DIR}/.env.example.`,\n ];\n }\n return [\n `${step}. Use your ChatGPT subscription with Codex (recommended): run \\`codex login\\` on the host, then initialize with \\`--codex-auth chatgpt\\` so Shipyard can mount \\`~/.codex/auth.json\\` read-only`,\n ` If subscription auth does not work, use API-key billing instead by setting \\`OPENAI_API_KEY\\` in ${CONFIG_DIR}/.env (see ${CONFIG_DIR}/.env.example).`,\n ` Also set any issue-tracker variables shown in ${CONFIG_DIR}/.env.example.`,\n ];\n }\n\n if (agent.name === \"claude-code\") {\n return [\n `${step}. Use your Claude subscription (recommended): run \\`claude setup-token\\` on the host and paste the result into \\`CLAUDE_CODE_OAUTH_TOKEN\\` in ${CONFIG_DIR}/.env`,\n ` If subscription auth does not work, use API-key billing instead by uncommenting \\`ANTHROPIC_API_KEY\\` in ${CONFIG_DIR}/.env and setting it to your key.`,\n ` Also set any issue-tracker variables shown in ${CONFIG_DIR}/.env.example.`,\n ];\n }\n\n return [\n `${step}. Set the required env vars in ${CONFIG_DIR}/.env (see ${CONFIG_DIR}/.env.example)`,\n ];\n };\n\n if (template === \"blank\") {\n const lines = [\"Next steps:\", ...getAuthLines(1)];\n lines.push(\n `2. Read and customize ${CONFIG_DIR}/prompt.md to describe what you want the agent to do`,\n `3. Customize ${CONFIG_DIR}/${mainFilename} — it uses the JS API (\\`run()\\`) to control how the agent runs`,\n `4. Run \\`npx ${CLI_NAME} run\\` to build the sandbox image and start the agent`,\n );\n return lines;\n } else {\n const hasReviewer = template.includes(\"review\");\n const usesPlanSchema = getTemplateDependencies(template).includes(\"zod\");\n let step = 1;\n const lines: string[] = [\"Next steps:\", ...getAuthLines(step++)];\n lines.push(\n `${step++}. Templates use \\`copyToWorktree: [\"node_modules\"]\\` to copy your host node_modules into the sandbox for fast startup — the \\`npm install\\` in the onSandboxReady hook is a safety net for platform-specific binaries. Adjust both if you use a different package manager`,\n );\n if (usesPlanSchema) {\n lines.push(\n `${step++}. Install a schema validator for the planner's \\`<plan>\\` output — the template uses Zod (\\`${addDependencyCommand(packageManager, \"zod\")}\\`), but Valibot, ArkType, or any Standard Schema library works (https://standardschema.dev)`,\n );\n }\n lines.push(\n `${step++}. Read and customize the prompt files in ${CONFIG_DIR}/ — they shape what the agent does`,\n );\n if (hasReviewer) {\n lines.push(\n `${step++}. Customize ${CONFIG_DIR}/CODING_STANDARDS.md with your project's standards — the reviewer agent loads it during review`,\n );\n }\n lines.push(\n `${step++}. Run \\`npx ${CLI_NAME} run\\` to build the sandbox image and start the workflow`,\n );\n return lines;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Scaffolding helpers\n// ---------------------------------------------------------------------------\n\nfunction getTemplatesDir(): string {\n const thisFile = fileURLToPath(import.meta.url);\n return join(dirname(thisFile), \"templates\");\n}\n\nconst getTemplateDir = (\n templateName: string,\n): Effect.Effect<string, Error, never> =>\n Effect.gen(function* () {\n const template = TEMPLATES.find((t) => t.name === templateName);\n if (!template) {\n const names = TEMPLATES.map((t) => t.name).join(\", \");\n yield* Effect.fail(\n new Error(`Unknown template: \"${templateName}\". Available: ${names}`),\n );\n }\n return join(getTemplatesDir(), templateName);\n });\n\nconst COMPILED_FILE_EXTENSIONS = [\n \".js\",\n \".js.map\",\n \".d.ts\",\n \".d.ts.map\",\n \".mjs\",\n \".mjs.map\",\n \".d.mts\",\n \".d.mts.map\",\n];\n\nconst copyTemplateFiles = (\n templateDir: string,\n destDir: string,\n mainFilename: string,\n): Effect.Effect<void, Error, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const files = yield* fs\n .readDirectory(templateDir)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n yield* Effect.all(\n files\n .filter(\n (f) =>\n f !== \"template.json\" &&\n f !== \".env.example\" &&\n !COMPILED_FILE_EXTENSIONS.some((ext) => f.endsWith(ext)),\n )\n .map((f) => {\n const destName = f === \"main.mts\" ? mainFilename : f;\n return fs\n .copyFile(join(templateDir, f), join(destDir, destName))\n .pipe(Effect.mapError((e) => new Error(e.message)));\n }),\n { concurrency: \"unbounded\" },\n );\n });\n\n/**\n * Replace the agent factory and sandbox provider in a scaffolded main.ts.\n *\n * Templates use `codex` as the default agent factory and `docker` as the\n * default sandbox provider. When a different agent, model, or sandbox provider\n * is selected, this function rewrites the imports and factory calls.\n */\nconst rewriteMainTs = (\n configDir: string,\n agent: AgentEntry,\n model: string,\n sandboxProvider: SandboxProviderEntry,\n mainFilename: string,\n codexAuth: CodexAuthMode,\n): Effect.Effect<void, Error, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const mainTsPath = join(configDir, mainFilename);\n\n const exists = yield* fs\n .exists(mainTsPath)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n if (!exists) return;\n\n let content = yield* fs\n .readFileString(mainTsPath)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n\n // Templates use main.mts as the canonical filename in comments.\n // When the target is main.ts, rewrite those references.\n if (mainFilename === \"main.ts\") {\n content = content.replace(/main\\.mts/g, \"main.ts\");\n }\n\n // Replace the default factory function name in imports.\n // and all factory calls with the correct model.\n // Templates always use Codex as the placeholder factory.\n content = content.replace(\n new RegExp(`\\\\b${TEMPLATE_AGENT_FACTORY}\\\\b`, \"g\"),\n agent.factoryImport,\n );\n // Replace model arguments in factory calls. The built-in Codex templates\n // use CODEX_MODELS references so the central model configuration remains\n // live in a default Codex scaffold.\n const factoryCallRe = new RegExp(\n `${agent.factoryImport}\\\\(([^)\\\\n]*)\\\\)`,\n \"g\",\n );\n content = content.replace(\n factoryCallRe,\n (match, modelExpression: string) => {\n const keepsConfiguredModel =\n agent.name === \"codex\" &&\n model === CODEX_MODELS.routine.model &&\n /^(?:[A-Za-z_$][\\w$]*\\.)*CODEX_MODELS\\.[A-Za-z_$][\\w$]*$/.test(\n modelExpression.trim(),\n );\n return keepsConfiguredModel\n ? match\n : `${agent.factoryImport}(\"${model}\")`;\n },\n );\n\n // CODEX_MODELS is only needed when the generated file continues using\n // the central Codex configuration. Remove it from named imports when a\n // custom model or another provider has replaced every reference.\n if (agent.name !== \"codex\" || model !== CODEX_MODELS.routine.model) {\n content = content.replace(/\\bCODEX_MODELS,\\s*/g, \"\");\n }\n\n // ChatGPT subscription auth is stored by the host Codex CLI. Mount the\n // file into the sandbox read-only so Codex can use it without exposing an\n // API key through the generated .env file.\n if (agent.name === \"codex\" && codexAuth === \"chatgpt\") {\n content = content.replace(\n /\\bdocker\\(\\)/g,\n `docker(${CODEX_CHATGPT_AUTH_OPTIONS})`,\n );\n }\n\n // Replace the sandbox provider. Templates always use `docker` as the\n // placeholder, where the registry name doubles as both the factory function\n // name and the `/sandboxes/<name>` import subpath segment. A single\n // case-sensitive word-boundary replace therefore rewrites the named import,\n // the import subpath, and every factory call site — and is a no-op when\n // docker is selected.\n content = content.replace(/\\bdocker\\b/g, sandboxProvider.name);\n\n yield* fs\n .writeFileString(mainTsPath, content)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n });\n\n/**\n * When the user opted out of the Shipyard label, strip the corresponding label\n * from all `.md` files in the scaffolded config directory so that `gh issue list`\n * commands work without a label filter.\n */\nconst rewritePromptFiles = (\n configDir: string,\n): Effect.Effect<void, Error, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const files = yield* fs\n .readDirectory(configDir)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n const mdFiles = files.filter((f) => f.endsWith(\".md\"));\n yield* Effect.all(\n mdFiles.map((f) =>\n Effect.gen(function* () {\n const filePath = join(configDir, f);\n const content = yield* fs\n .readFileString(filePath)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n const updated = content.replace(\n new RegExp(` --label ${PRODUCT_NAME}`, \"g\"),\n \"\",\n );\n if (updated !== content) {\n yield* fs\n .writeFileString(filePath, updated)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n }\n }),\n ),\n { concurrency: \"unbounded\" },\n );\n });\n\n/** Text file extensions eligible for `{{KEY}}` template argument substitution. */\nconst TEXT_FILE_EXTENSIONS = new Set([\n \".md\",\n \".txt\",\n \".env\",\n \".example\",\n // Dockerfile / Containerfile have no extension — handled by name check below\n]);\n\nconst isTextFile = (filename: string): boolean => {\n if (\n filename === \"Dockerfile\" ||\n filename === \"Containerfile\" ||\n filename === \".gitignore\"\n )\n return true;\n const dotIdx = filename.lastIndexOf(\".\");\n if (dotIdx === -1) return false;\n return TEXT_FILE_EXTENSIONS.has(filename.slice(dotIdx));\n};\n\n/**\n * Replace `{{KEY}}` template arguments from the issue tracker's\n * `templateArgs` map in all text files in the scaffolded config directory.\n */\nconst substituteTemplateArgs = (\n configDir: string,\n issueTracker: IssueTrackerEntry,\n): Effect.Effect<void, Error, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const files = yield* fs\n .readDirectory(configDir)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n const textFiles = files.filter(isTextFile);\n yield* Effect.all(\n textFiles.map((f) =>\n Effect.gen(function* () {\n const filePath = join(configDir, f);\n let content = yield* fs\n .readFileString(filePath)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n const original = content;\n for (const [key, value] of Object.entries(\n issueTracker.templateArgs,\n )) {\n content = content.replace(\n new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, \"g\"),\n value,\n );\n }\n if (content !== original) {\n yield* fs\n .writeFileString(filePath, content)\n .pipe(Effect.mapError((e) => new Error(e.message)));\n }\n }),\n ),\n { concurrency: \"unbounded\" },\n );\n });\n\n// ---------------------------------------------------------------------------\n// Main scaffold function\n// ---------------------------------------------------------------------------\n\nexport interface ScaffoldOptions {\n agent: AgentEntry;\n model: string;\n templateName?: string;\n createLabel?: boolean;\n issueTracker?: IssueTrackerEntry;\n sandboxProvider?: SandboxProviderEntry;\n codexAuth?: CodexAuthMode;\n}\n\nexport interface ScaffoldResult {\n mainFilename: string;\n}\n\n/**\n * Detect whether the project's package.json has `\"type\": \"module\"`.\n * If so, we can use plain `.ts`; otherwise we use `.mts` to ensure ESM.\n */\nconst detectMainFilename = (\n repoDir: string,\n): Effect.Effect<string, never, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const pkgPath = join(repoDir, \"package.json\");\n const exists = yield* fs\n .exists(pkgPath)\n .pipe(Effect.orElseSucceed(() => false));\n if (!exists) return \"main.mts\";\n const content = yield* fs\n .readFileString(pkgPath)\n .pipe(Effect.orElseSucceed(() => \"\"));\n try {\n const pkg = JSON.parse(content) as Record<string, unknown>;\n return pkg[\"type\"] === \"module\" ? \"main.ts\" : \"main.mts\";\n } catch {\n return \"main.mts\";\n }\n });\n\nexport const scaffold = (\n repoDir: string,\n options: ScaffoldOptions,\n): Effect.Effect<ScaffoldResult, Error, FileSystem.FileSystem> =>\n Effect.gen(function* () {\n const {\n agent,\n model,\n templateName = \"blank\",\n createLabel = true,\n issueTracker = ISSUE_TRACKER_REGISTRY[0]!, // default: github-issues\n sandboxProvider = SANDBOX_PROVIDER_REGISTRY[0]!, // default: docker\n codexAuth = \"api-key\",\n } = options;\n if (codexAuth === \"chatgpt\" && agent.name !== \"codex\") {\n return yield* Effect.fail(\n new Error(\n \"ChatGPT subscription authentication is only supported for Codex.\",\n ),\n );\n }\n const fs = yield* FileSystem.FileSystem;\n yield* assertConfigDirAvailable(repoDir);\n const configDir = join(repoDir, CONFIG_DIR);\n\n const mainFilename = yield* detectMainFilename(repoDir);\n\n yield* fs\n .makeDirectory(configDir, { recursive: false })\n .pipe(Effect.mapError((e) => new Error(e.message)));\n\n const templateDir = yield* getTemplateDir(templateName);\n\n // Build .env.example from agent + issue tracker env blocks\n const envExampleParts = [\n agent.name === \"codex\" && codexAuth === \"chatgpt\"\n ? CODEX_CHATGPT_ENV_EXAMPLE\n : agent.envExample,\n ];\n if (issueTracker.envExample) {\n envExampleParts.push(issueTracker.envExample);\n }\n const envExampleContent = envExampleParts.join(\"\\n\") + \"\\n\";\n\n yield* Effect.all(\n [\n fs\n .writeFileString(\n join(configDir, sandboxProvider.containerfileName),\n agent.dockerfileTemplate,\n )\n .pipe(Effect.mapError((e) => new Error(e.message))),\n fs\n .writeFileString(join(configDir, \".gitignore\"), GITIGNORE)\n .pipe(Effect.mapError((e) => new Error(e.message))),\n fs\n .writeFileString(join(configDir, \".env.example\"), envExampleContent)\n .pipe(Effect.mapError((e) => new Error(e.message))),\n copyTemplateFiles(templateDir, configDir, mainFilename),\n ],\n { concurrency: \"unbounded\" },\n );\n\n // Rewrite main file with the selected agent factory, model, and sandbox provider\n yield* rewriteMainTs(\n configDir,\n agent,\n model,\n sandboxProvider,\n mainFilename,\n codexAuth,\n );\n\n // Replace issue tracker template arguments in all text files (must run before label stripping)\n yield* substituteTemplateArgs(configDir, issueTracker);\n\n // Strip the Shipyard label from prompt files when the user declined label creation\n if (!createLabel) {\n yield* rewritePromptFiles(configDir);\n }\n\n return { mainFilename };\n });\n","import { execFileSync } from \"node:child_process\";\nimport { statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { InitError } from \"./errors.js\";\n\nexport interface CodexAuthPreflightOptions {\n readonly cwd: string;\n readonly interactive: boolean;\n /** Test seam; production uses the user's default ~/.codex directory. */\n readonly authHome?: string;\n /** Test seam; production runs `codex login` in the user's terminal. */\n readonly login?: (cwd: string) => void;\n}\n\nexport const codexAuthFilePath = (\n authHome = join(homedir(), \".codex\"),\n): string => join(authHome, \"auth.json\");\n\nconst isRegularFile = (path: string): boolean => {\n try {\n return statSync(path).isFile();\n } catch {\n return false;\n }\n};\n\nconst isMissingCodexCli = (error: unknown): boolean =>\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === \"ENOENT\";\n\n// Shipyard mounts auth.json into the sandbox, so make this login use the file\n// store without changing the user's permanent Codex configuration.\nconst codexLoginArgs = [\n \"--config\",\n 'cli_auth_credentials_store=\"file\"',\n \"login\",\n];\n\nconst runCodexLogin = (cwd: string): void => {\n try {\n execFileSync(\"codex\", codexLoginArgs, { cwd, stdio: \"inherit\" });\n } catch (error) {\n if (!isMissingCodexCli(error)) throw error;\n // Shipyard already requires npm. Use npx as a no-global-install fallback\n // when the user has not installed the Codex CLI on the host yet.\n execFileSync(\n process.platform === \"win32\" ? \"npx.cmd\" : \"npx\",\n [\"--yes\", \"@openai/codex\", ...codexLoginArgs],\n { cwd, stdio: \"inherit\" },\n );\n }\n};\n\n/**\n * Ensure the host has a file-backed Codex ChatGPT login for the generated\n * sandbox mount. The browser/device login remains user-driven; init only\n * starts it when an interactive terminal is available.\n */\nexport const ensureCodexChatGptAuth = (\n options: CodexAuthPreflightOptions,\n): void => {\n const authFile = codexAuthFilePath(options.authHome);\n if (isRegularFile(authFile)) return;\n\n if (!options.interactive) {\n throw new InitError({\n message:\n \"Codex ChatGPT authentication is not ready: ~/.codex/auth.json was not found. Run `codex login` in an interactive terminal, then rerun `shipyard init --codex-auth chatgpt` (non-interactive mode cannot open the login flow).\",\n });\n }\n\n try {\n (options.login ?? runCodexLogin)(options.cwd);\n } catch (error) {\n if (error instanceof InitError) throw error;\n if (isMissingCodexCli(error)) {\n throw new InitError({\n message:\n \"The Codex CLI is not installed. Install it with `npm install --global @openai/codex`, run `codex login`, and rerun Shipyard init.\",\n });\n }\n throw new InitError({\n message:\n \"Codex login failed. Complete `codex login` successfully, then rerun Shipyard init.\",\n });\n }\n\n if (!isRegularFile(authFile)) {\n throw new InitError({\n message:\n 'Codex login finished, but ~/.codex/auth.json was not created. Codex may be using an OS keyring or a managed configuration. Set `cli_auth_credentials_store = \"file\"` in `~/.codex/config.toml`, run `codex login` again, and rerun Shipyard init.',\n });\n }\n};\n","import { createRequire } from \"node:module\";\n\ndeclare const __SHIPYARD_VERSION__: string | undefined;\n\nconst fallbackVersion = (): string => {\n const require = createRequire(import.meta.url);\n const pkg = require(\"../package.json\") as { version: string };\n return pkg.version;\n};\n\n/**\n * The package version. Injected at build time by tsup via `define`. When\n * the source is loaded directly (e.g. via `tsx` during tests) the constant\n * is undefined, so we fall back to reading `package.json` at runtime.\n */\nexport const VERSION: string =\n typeof __SHIPYARD_VERSION__ !== \"undefined\"\n ? __SHIPYARD_VERSION__\n : fallbackVersion();\n","import { Command, Options } from \"@effect/cli\";\nimport { Effect, Option } from \"effect\";\nimport * as clack from \"@clack/prompts\";\nimport { execSync, spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { styleText } from \"node:util\";\n\nimport { Display } from \"./Display.js\";\nimport { buildImage, removeImage } from \"./DockerLifecycle.js\";\nimport {\n scaffold,\n listTemplates,\n listAgents,\n getAgent,\n listIssueTrackers,\n getIssueTracker,\n listSandboxProviders,\n getSandboxProvider,\n DEFAULT_AGENT_NAME,\n getNextStepsLines,\n detectPackageManager,\n addDependencyCommand,\n hostHasDependency,\n getTemplateDependencies,\n} from \"./InitService.js\";\nimport { defaultImageName } from \"./sandboxes/docker.js\";\nimport type {\n AgentEntry,\n CodexAuthMode,\n IssueTrackerEntry,\n SandboxProviderEntry,\n} from \"./InitService.js\";\nimport { ExecHostError, InitError } from \"./errors.js\";\nimport { ensureCodexChatGptAuth } from \"./CodexAuth.js\";\nimport { requireCanonicalConfigDir } from \"./runtimeConfig.js\";\nimport { CONFIG_DIR, CLI_NAME, PRODUCT_NAME } from \"./runtimeNames.js\";\nimport { VERSION } from \"./version.js\";\n\n// --- Shared options ---\n\nconst imageNameOption = Options.text(\"image-name\").pipe(\n Options.withDescription(\"Docker image name\"),\n Options.optional,\n);\n\nconst resolveImageName = (\n cliFlag: Option.Option<string>,\n cwd: string,\n): string => (cliFlag._tag === \"Some\" ? cliFlag.value : defaultImageName(cwd));\n\n// --- UID build-args ---\n\n/** Build-args that align the image UID/GID to the host (Linux/macOS). No-op on Windows. */\nconst defaultUidBuildArgs = (): Record<string, string> => {\n const args: Record<string, string> = {};\n const uid = process.getuid?.();\n const gid = process.getgid?.();\n if (uid !== undefined) args.AGENT_UID = String(uid);\n if (gid !== undefined) args.AGENT_GID = String(gid);\n return args;\n};\n\n// --- Config directory check ---\n\nconst requireConfigDir = (\n cwd: string,\n): ReturnType<typeof requireCanonicalConfigDir> =>\n requireCanonicalConfigDir(cwd);\n\n// --- Run command ---\n\nconst runSandboxOption = Options.choice(\"sandbox\", [\"docker\"] as const).pipe(\n Options.withDescription(\n \"Sandbox provider to build (inferred from Dockerfile)\",\n ),\n Options.optional,\n);\n\nconst skipBuildOption = Options.boolean(\"skip-build\").pipe(\n Options.withDescription(\"Skip rebuilding the sandbox image\"),\n);\n\nconst entrypointOption = Options.text(\"entrypoint\").pipe(\n Options.withDescription(\n \"TypeScript entrypoint (defaults to .shipyard/main.ts or main.mts)\",\n ),\n Options.optional,\n);\n\ntype RunSandbox = \"docker\";\n\nconst resolveRunEntrypoint = (\n cwd: string,\n configDir: string,\n entrypoint: Option.Option<string>,\n): string | InitError => {\n if (entrypoint._tag === \"Some\") {\n const path = resolve(cwd, entrypoint.value);\n return existsSync(path)\n ? path\n : new InitError({ message: `Entrypoint not found: ${entrypoint.value}` });\n }\n\n for (const filename of [\"main.ts\", \"main.mts\"]) {\n const path = join(configDir, filename);\n if (existsSync(path)) return path;\n }\n\n return new InitError({\n message:\n \"No Shipyard entrypoint found. Expected .shipyard/main.ts or .shipyard/main.mts; run `shipyard init` first or pass `--entrypoint <path>.\",\n });\n};\n\nconst resolveRunSandbox = (\n configDir: string,\n sandbox: Option.Option<RunSandbox>,\n): RunSandbox | InitError => {\n if (sandbox._tag === \"Some\") {\n const filename = \"Dockerfile\";\n if (!existsSync(join(configDir, filename))) {\n return new InitError({\n message: `No .shipyard/${filename} found for the selected ${sandbox.value} sandbox provider.`,\n });\n }\n return sandbox.value;\n }\n\n const hasDockerfile = existsSync(join(configDir, \"Dockerfile\"));\n if (hasDockerfile) return \"docker\";\n return new InitError({\n message:\n \"No .shipyard/Dockerfile found. Run `shipyard init` first, or pass `--skip-build` for a programmatically configured sandbox.\",\n });\n};\n\nconst executeEntrypoint = (\n cwd: string,\n entrypoint: string,\n): Effect.Effect<void, ExecHostError> =>\n Effect.async((resume, signal) => {\n const command = process.platform === \"win32\" ? \"npx.cmd\" : \"npx\";\n const args = [\"--no-install\", \"tsx\", entrypoint];\n const child = spawn(command, args, {\n cwd,\n env: process.env,\n stdio: \"inherit\",\n });\n const commandText = `${command} ${args.join(\" \")}`;\n let settled = false;\n\n const finish = (effect: Effect.Effect<void, ExecHostError>) => {\n if (settled) return;\n settled = true;\n signal.removeEventListener(\"abort\", onAbort);\n resume(effect);\n };\n const onAbort = () => child.kill(\"SIGTERM\");\n signal.addEventListener(\"abort\", onAbort, { once: true });\n\n child.once(\"error\", (error) => {\n finish(\n Effect.fail(\n new ExecHostError({\n command: commandText,\n message: error.message,\n }),\n ),\n );\n });\n child.once(\"close\", (code, closeSignal) => {\n if (code === 0) {\n finish(Effect.succeed(undefined));\n return;\n }\n finish(\n Effect.fail(\n new ExecHostError({\n command: commandText,\n message:\n closeSignal === null\n ? `Process exited with code ${code ?? \"unknown\"}.`\n : `Process terminated by ${closeSignal}.`,\n }),\n ),\n );\n });\n });\n\nconst runCommand = Command.make(\n \"run\",\n {\n imageName: imageNameOption,\n sandbox: runSandboxOption,\n skipBuild: skipBuildOption,\n entrypoint: entrypointOption,\n },\n ({ imageName: imageNameFlag, sandbox, skipBuild, entrypoint }) =>\n Effect.gen(function* () {\n const d = yield* Display;\n const cwd = process.cwd();\n const configDir = yield* requireConfigDir(cwd);\n const resolvedEntrypoint = resolveRunEntrypoint(\n cwd,\n configDir,\n entrypoint,\n );\n if (resolvedEntrypoint instanceof InitError) {\n return yield* Effect.fail(resolvedEntrypoint);\n }\n\n if (!skipBuild) {\n const selectedSandbox = resolveRunSandbox(configDir, sandbox);\n if (selectedSandbox instanceof InitError) {\n return yield* Effect.fail(selectedSandbox);\n }\n const imageName = resolveImageName(imageNameFlag, cwd);\n yield* d.spinner(\n `Building Docker image '${imageName}'...`,\n buildImage(imageName, configDir, {\n buildArgs: defaultUidBuildArgs(),\n }),\n );\n }\n\n yield* d.status(\n `Running ${entrypoint._tag === \"Some\" ? entrypoint.value : \".shipyard/\" + resolvedEntrypoint.split(/[\\\\/]/).pop()}.`,\n \"info\",\n );\n yield* executeEntrypoint(cwd, resolvedEntrypoint);\n }),\n);\n\n// --- Init command ---\n\nconst templateOption = Options.text(\"template\").pipe(\n Options.withDescription(\n \"Template to scaffold (e.g. blank, simple-loop, parallel-planner)\",\n ),\n Options.optional,\n);\n\nconst agentOption = Options.text(\"agent\").pipe(\n Options.withDescription(\"Agent to use (e.g. codex)\"),\n Options.optional,\n);\n\nconst codexAuthOption = Options.choice(\"codex-auth\", [\n \"api-key\",\n \"chatgpt\",\n]).pipe(\n Options.withDescription(\n \"How Codex should authenticate: API key or ChatGPT subscription\",\n ),\n Options.optional,\n);\n\nconst initModelOption = Options.text(\"model\").pipe(\n Options.withDescription(\n \"Model to use for the agent. Defaults to the agent's configured default model\",\n ),\n Options.optional,\n);\n\nconst sandboxOption = Options.text(\"sandbox\").pipe(\n Options.withDescription(\"Sandbox provider to use (docker)\"),\n Options.optional,\n);\n\nconst issueTrackerOption = Options.text(\"issue-tracker\").pipe(\n Options.withDescription(\"Issue tracker to use (github-issues)\"),\n Options.optional,\n);\n\n// Tri-state booleans (Some(true) / Some(false) / None) so we can tell \"user\n// chose false\" from \"user didn't pass the flag at all\" — only the latter\n// triggers the interactive prompt.\nconst createLabelOption = Options.choice(\"create-label\", [\n \"true\",\n \"false\",\n]).pipe(\n Options.withDescription(\n `Whether to create the \"${PRODUCT_NAME}\" GitHub label (only meaningful with --issue-tracker github-issues)`,\n ),\n Options.optional,\n);\n\nconst buildImageOption = Options.choice(\"build-image\", [\"true\", \"false\"]).pipe(\n Options.withDescription(\"Whether to build the sandbox image now\"),\n Options.optional,\n);\n\nconst installTemplateDepsOption = Options.choice(\"install-template-deps\", [\n \"true\",\n \"false\",\n]).pipe(\n Options.withDescription(\n \"Whether to install the template's host dependencies (e.g. zod for the planner templates)\",\n ),\n Options.optional,\n);\n\n/**\n * Translate an `Options.choice(\"flag\", [\"true\", \"false\"]).optional` value into\n * a tri-state boolean. None when the flag was absent; otherwise the parsed bool.\n */\nconst choiceToTriBool = (\n opt: Option.Option<\"true\" | \"false\">,\n): Option.Option<boolean> =>\n opt._tag === \"Some\" ? Option.some(opt.value === \"true\") : Option.none();\n\nconst initCommand = Command.make(\n \"init\",\n {\n imageName: imageNameOption,\n template: templateOption,\n agent: agentOption,\n codexAuth: codexAuthOption,\n model: initModelOption,\n sandbox: sandboxOption,\n issueTracker: issueTrackerOption,\n createLabel: createLabelOption,\n buildImage: buildImageOption,\n installTemplateDeps: installTemplateDepsOption,\n },\n ({\n imageName: imageNameFlag,\n template,\n agent: agentFlag,\n codexAuth: codexAuthFlag,\n model: modelFlag,\n sandbox: sandboxFlag,\n issueTracker: issueTrackerFlag,\n createLabel: createLabelFlag,\n buildImage: buildImageFlag,\n installTemplateDeps: installTemplateDepsFlag,\n }) =>\n Effect.gen(function* () {\n const d = yield* Display;\n const cwd = process.cwd();\n const imageName = resolveImageName(imageNameFlag, cwd);\n\n // Early validation of CLI flags before interactive prompts\n const templates = listTemplates();\n if (template._tag === \"Some\") {\n const valid = templates.find((tmpl) => tmpl.name === template.value);\n if (!valid) {\n const names = templates.map((tmpl) => tmpl.name).join(\", \");\n yield* Effect.fail(\n new InitError({\n message: `Unknown template \"${template.value}\". Available: ${names}`,\n }),\n );\n }\n }\n\n if (sandboxFlag._tag === \"Some\") {\n const valid = getSandboxProvider(sandboxFlag.value);\n if (!valid) {\n const names = listSandboxProviders()\n .map((p) => p.name)\n .join(\", \");\n yield* Effect.fail(\n new InitError({\n message: `Unknown sandbox provider \"${sandboxFlag.value}\". Available: ${names}`,\n }),\n );\n }\n }\n\n if (issueTrackerFlag._tag === \"Some\") {\n const valid = getIssueTracker(issueTrackerFlag.value);\n if (!valid) {\n const names = listIssueTrackers()\n .map((t) => t.name)\n .join(\", \");\n yield* Effect.fail(\n new InitError({\n message: `Unknown issue tracker \"${issueTrackerFlag.value}\". Available: ${names}`,\n }),\n );\n }\n }\n\n const createLabelChoice = choiceToTriBool(createLabelFlag);\n const buildImageChoice = choiceToTriBool(buildImageFlag);\n const installTemplateDepsChoice = choiceToTriBool(\n installTemplateDepsFlag,\n );\n\n const isInteractive = process.stdin.isTTY === true;\n const failIfNonInteractive = (flag: string) =>\n Effect.fail(\n new InitError({\n message: `${flag} is required in non-interactive mode (no TTY detected).`,\n }),\n );\n\n // Tri-state confirm: CLI flag wins; otherwise prompt interactively (or\n // fail fast in non-interactive mode naming the missing flag). Cancelling\n // the prompt is treated as abort — same shape as the select prompts above.\n const resolveConfirmFlag = (params: {\n choice: Option.Option<boolean>;\n flag: string;\n promptMessage: string;\n cancelMessage: string;\n }): Effect.Effect<boolean, InitError> =>\n Effect.gen(function* () {\n if (params.choice._tag === \"Some\") return params.choice.value;\n if (!isInteractive) {\n yield* failIfNonInteractive(params.flag);\n }\n const confirmed = yield* Effect.promise(() =>\n clack.confirm({\n message: params.promptMessage,\n initialValue: true,\n }),\n );\n if (clack.isCancel(confirmed)) {\n yield* Effect.fail(\n new InitError({ message: params.cancelMessage }),\n );\n }\n return confirmed === true;\n });\n\n // Resolve agent: CLI flag > interactive select\n const agents = listAgents();\n let selectedAgent: AgentEntry;\n if (agentFlag._tag === \"Some\") {\n const entry = getAgent(agentFlag.value);\n if (!entry) {\n const names = agents.map((a) => a.name).join(\", \");\n yield* Effect.fail(\n new InitError({\n message: `Unknown agent \"${agentFlag.value}\". Available: ${names}`,\n }),\n );\n }\n selectedAgent = entry!;\n } else {\n if (!isInteractive) {\n yield* failIfNonInteractive(\"--agent\");\n }\n const selected = yield* Effect.promise(() =>\n clack.select({\n message: \"Select an agent:\",\n initialValue: DEFAULT_AGENT_NAME,\n options: agents.map((a) => ({\n value: a.name,\n label: a.label,\n hint: `Default model: ${a.defaultModel}`,\n })),\n }),\n );\n if (clack.isCancel(selected)) {\n yield* Effect.fail(\n new InitError({ message: \"Agent selection cancelled.\" }),\n );\n }\n selectedAgent = getAgent(selected as string)!;\n }\n\n // Resolve model: CLI flag > agent default\n const selectedModel =\n modelFlag._tag === \"Some\"\n ? modelFlag.value\n : selectedAgent.defaultModel;\n\n const selectedCodexAuth: CodexAuthMode =\n codexAuthFlag._tag === \"Some\" ? codexAuthFlag.value : \"api-key\";\n if (selectedCodexAuth === \"chatgpt\" && selectedAgent.name !== \"codex\") {\n yield* Effect.fail(\n new InitError({\n message:\n \"--codex-auth chatgpt can only be used with --agent codex.\",\n }),\n );\n }\n\n if (selectedCodexAuth === \"chatgpt\") {\n yield* Effect.try({\n try: () =>\n ensureCodexChatGptAuth({\n cwd,\n interactive: isInteractive,\n }),\n catch: (error) =>\n error instanceof InitError\n ? error\n : new InitError({\n message: `Codex authentication setup failed: ${String(error)}`,\n }),\n });\n }\n\n // Resolve sandbox provider: CLI flag > interactive select (no default — user must choose)\n const sandboxProviders = listSandboxProviders();\n let selectedSandboxProvider: SandboxProviderEntry;\n if (sandboxFlag._tag === \"Some\") {\n selectedSandboxProvider = getSandboxProvider(sandboxFlag.value)!;\n } else {\n if (!isInteractive) {\n yield* failIfNonInteractive(\"--sandbox\");\n }\n const selected = yield* Effect.promise(() =>\n clack.select({\n message: \"Select a sandbox provider:\",\n options: sandboxProviders.map((p) => ({\n value: p.name,\n label: p.label,\n })),\n }),\n );\n if (clack.isCancel(selected)) {\n yield* Effect.fail(\n new InitError({\n message: \"Sandbox provider selection cancelled.\",\n }),\n );\n }\n selectedSandboxProvider = getSandboxProvider(selected as string)!;\n }\n\n // Resolve issue tracker: CLI flag > interactive select (already validated above)\n const issueTrackers = listIssueTrackers();\n let selectedIssueTracker: IssueTrackerEntry;\n if (issueTrackerFlag._tag === \"Some\") {\n selectedIssueTracker = getIssueTracker(issueTrackerFlag.value)!;\n } else {\n if (!isInteractive) {\n yield* failIfNonInteractive(\"--issue-tracker\");\n }\n const selected = yield* Effect.promise(() =>\n clack.select({\n message: \"Select an issue tracker:\",\n initialValue: \"github-issues\",\n options: issueTrackers.map((b) => ({\n value: b.name,\n label: b.label,\n })),\n }),\n );\n if (clack.isCancel(selected)) {\n yield* Effect.fail(\n new InitError({\n message: \"Issue tracker selection cancelled.\",\n }),\n );\n }\n selectedIssueTracker = getIssueTracker(selected as string)!;\n }\n\n // Resolve template: CLI flag > interactive select (already validated above)\n let selectedTemplate: string;\n if (template._tag === \"Some\") {\n selectedTemplate = template.value;\n } else {\n if (!isInteractive) {\n yield* failIfNonInteractive(\"--template\");\n }\n const selected = yield* Effect.promise(() =>\n clack.select({\n message: \"Select a template:\",\n initialValue: \"blank\",\n options: templates.map((tmpl) => ({\n value: tmpl.name,\n label: tmpl.name,\n hint: tmpl.description,\n })),\n }),\n );\n if (clack.isCancel(selected)) {\n yield* Effect.fail(\n new InitError({ message: \"Template selection cancelled.\" }),\n );\n }\n selectedTemplate = selected as string;\n }\n\n // Offer to create the \"Shipyard\" label on the repo (skip for non-GitHub issue trackers).\n // CLI flag > interactive confirm. The flag is only meaningful for the github-issues tracker.\n let shouldCreateLabel = false;\n if (selectedIssueTracker.name === \"github-issues\") {\n shouldCreateLabel = yield* resolveConfirmFlag({\n choice: createLabelChoice,\n flag: \"--create-label\",\n promptMessage: `Create a \"${PRODUCT_NAME}\" GitHub label? (Templates filter issues by this label)`,\n cancelMessage: \"Label selection cancelled.\",\n });\n\n if (shouldCreateLabel) {\n yield* Effect.try({\n try: () =>\n execSync(\n `gh label create \"${PRODUCT_NAME}\" --description \"Issues for ${PRODUCT_NAME} to work on\" --color \"F9A825\" 2>/dev/null`,\n { cwd, stdio: \"ignore\" },\n ),\n catch: () => undefined,\n }).pipe(Effect.ignore);\n }\n }\n\n const scaffoldResult = yield* d.spinner(\n `Scaffolding ${CONFIG_DIR}/ config directory...`,\n scaffold(cwd, {\n agent: selectedAgent,\n model: selectedModel,\n templateName: selectedTemplate,\n createLabel: shouldCreateLabel,\n issueTracker: selectedIssueTracker,\n sandboxProvider: selectedSandboxProvider,\n codexAuth: selectedCodexAuth,\n }).pipe(\n Effect.mapError(\n (e) =>\n new InitError({\n message: `${e instanceof Error ? e.message : e}`,\n }),\n ),\n ),\n );\n\n // Detect the host package manager so the zod offer below and the next\n // steps below both use the right install command.\n const packageManager = yield* detectPackageManager(cwd);\n\n // If the chosen template imports zod on the host (the planner templates\n // build their <plan> output schema with it) and the host doesn't already\n // declare it, offer to install it. Without this, the very first\n // `npx tsx .shipyard/main.ts` crashes with ERR_MODULE_NOT_FOUND.\n if (getTemplateDependencies(selectedTemplate).includes(\"zod\")) {\n const alreadyInstalled = yield* hostHasDependency(cwd, \"zod\");\n if (!alreadyInstalled) {\n const installCmd = addDependencyCommand(packageManager, \"zod\");\n const shouldInstall = yield* resolveConfirmFlag({\n choice: installTemplateDepsChoice,\n flag: \"--install-template-deps\",\n promptMessage: `The ${selectedTemplate} template needs a schema validator. Install zod now (\\`${installCmd}\\`)?`,\n cancelMessage: \"Install-template-deps selection cancelled.\",\n });\n if (shouldInstall) {\n const installed = yield* Effect.sync(() => {\n try {\n execSync(installCmd, { cwd, stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n });\n yield* installed\n ? d.status(`Installed zod with ${packageManager}.`, \"success\")\n : d.status(\n `Couldn't install zod automatically. Run \\`${installCmd}\\` before running the agent.`,\n \"warn\",\n );\n }\n }\n }\n\n const providerLabel = selectedSandboxProvider.label;\n const shouldBuild = yield* resolveConfirmFlag({\n choice: buildImageChoice,\n flag: \"--build-image\",\n promptMessage: `Build the default ${providerLabel} image now?`,\n cancelMessage: \"Build-image selection cancelled.\",\n });\n\n if (shouldBuild) {\n const containerfileDir = join(cwd, CONFIG_DIR);\n yield* d.spinner(\n `Building ${providerLabel} image '${imageName}'...`,\n buildImage(imageName, containerfileDir, {\n buildArgs: defaultUidBuildArgs(),\n }),\n );\n yield* d.status(\"Init complete! Image built successfully.\", \"success\");\n } else {\n yield* d.status(\n `Init complete! Run \\`${CLI_NAME} ${selectedSandboxProvider.cliNamespace} build-image\\` to build the ${providerLabel} image later.`,\n \"success\",\n );\n }\n\n // Show template-specific next steps\n const nextSteps = getNextStepsLines(\n selectedTemplate,\n scaffoldResult.mainFilename,\n selectedAgent,\n packageManager,\n selectedCodexAuth,\n );\n for (const [i, line] of nextSteps.entries()) {\n yield* d.text(i === 0 ? line : styleText(\"dim\", line));\n }\n }),\n);\n\n// --- Build-image command ---\n\nconst dockerfileOption = Options.file(\"dockerfile\").pipe(\n Options.withDescription(\n \"Path to a custom Dockerfile (build context will be the current working directory)\",\n ),\n Options.optional,\n);\n\nconst buildImageCommand = Command.make(\n \"build-image\",\n {\n imageName: imageNameOption,\n dockerfile: dockerfileOption,\n },\n ({ imageName: imageNameFlag, dockerfile }) =>\n Effect.gen(function* () {\n const d = yield* Display;\n const cwd = process.cwd();\n yield* requireConfigDir(cwd);\n\n const imageName = resolveImageName(imageNameFlag, cwd);\n\n const dockerfileDir = join(cwd, CONFIG_DIR);\n const dockerfilePath =\n dockerfile._tag === \"Some\" ? dockerfile.value : undefined;\n\n yield* d.spinner(\n `Building Docker image '${imageName}'...`,\n buildImage(imageName, dockerfileDir, {\n dockerfile: dockerfilePath,\n buildArgs: defaultUidBuildArgs(),\n }),\n );\n\n yield* d.status(\"Build complete!\", \"success\");\n }),\n);\n\n// --- Remove-image command ---\n\nconst removeImageCommand = Command.make(\n \"remove-image\",\n {\n imageName: imageNameOption,\n },\n ({ imageName: imageNameFlag }) =>\n Effect.gen(function* () {\n const d = yield* Display;\n const cwd = process.cwd();\n\n const imageName = resolveImageName(imageNameFlag, cwd);\n\n yield* d.spinner(\n `Removing Docker image '${imageName}'...`,\n removeImage(imageName),\n );\n yield* d.status(\"Image removed.\", \"success\");\n }),\n);\n\n// --- Docker namespace command ---\n\nconst dockerCommand = Command.make(\"docker\", {}, () =>\n Effect.gen(function* () {\n const d = yield* Display;\n yield* d.status(\n \"Docker sandbox commands. Use --help to see available subcommands.\",\n \"info\",\n );\n }),\n).pipe(Command.withSubcommands([buildImageCommand, removeImageCommand]));\n\n// --- Root command ---\n\nconst rootCommand = Command.make(CLI_NAME, {}, () =>\n Effect.gen(function* () {\n const d = yield* Display;\n yield* d.status(`${PRODUCT_NAME} v${VERSION}`, \"info\");\n yield* d.status(\"Use --help to see available commands.\", \"info\");\n }),\n);\n\nexport const shipyard = rootCommand.pipe(\n Command.withSubcommands([initCommand, runCommand, dockerCommand]),\n);\n\nexport const cli = Command.run(shipyard, {\n name: CLI_NAME,\n version: VERSION,\n});\n","/**\n * Terminal cleanup for abrupt exits.\n *\n * @clack/prompts' spinner and taskLog call stdin.setRawMode(true) and hide\n * the cursor via escape sequences. When the process is killed by a signal\n * handler that calls process.exit() directly (e.g. during Ctrl-C cleanup in\n * SandboxFactory), clack's own cleanup is bypassed and the terminal is left\n * in raw mode with the cursor hidden.\n *\n * Registering a process 'exit' listener that restores these guarantees the\n * terminal is always left in a usable state.\n */\n\n/** Escape sequence to show the cursor (DECTCEM). */\nexport const SHOW_CURSOR = \"\\x1b[?25h\";\n\n/**\n * Creates a synchronous exit handler that restores terminal state.\n * Extracted as a pure function so it can be unit-tested without side effects.\n */\nexport const makeTerminalCleanupHandler =\n (\n stdin: { isTTY?: boolean; setRawMode?: (raw: boolean) => void },\n stdout: { write: (data: string) => boolean },\n ) =>\n (): void => {\n if (stdin.isTTY && stdin.setRawMode) {\n try {\n stdin.setRawMode(false);\n } catch {\n // Best-effort — may fail if stdin is already closed\n }\n }\n stdout.write(SHOW_CURSOR);\n };\n\n/**\n * Registers the terminal cleanup handler on process 'exit'.\n * Call once at program startup (main.ts).\n */\nexport const setupTerminalCleanup = (): void => {\n process.on(\"exit\", makeTerminalCleanupHandler(process.stdin, process.stdout));\n};\n","#!/usr/bin/env node\nimport { NodeContext, NodeRuntime } from \"@effect/platform-node\";\nimport { Effect, Layer } from \"effect\";\nimport { cli } from \"./cli.js\";\nimport { ClackDisplay } from \"./Display.js\";\nimport { withFriendlyErrors } from \"./ErrorHandler.js\";\nimport { setupTerminalCleanup } from \"./terminalCleanup.js\";\n\n// Restore terminal state on any exit.\n// @clack/prompts' spinner/taskLog set stdin to raw mode and hide the cursor.\n// If the process exits via a signal handler that calls process.exit() directly\n// (e.g. the Ctrl-C handler in SandboxFactory), clack's own cleanup is\n// bypassed, leaving the terminal broken. This exit hook fixes that.\nsetupTerminalCleanup();\n\nconst mainLayer = Layer.merge(NodeContext.layer, ClackDisplay.layer);\n\ncli(process.argv).pipe(\n withFriendlyErrors,\n Effect.provide(mainLayer),\n NodeRuntime.runMain,\n);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snappedly-tools/shipyard",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "Run AI coding agents in isolated sandboxes",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",