issue-flow 0.10.0 → 0.11.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.
Files changed (103) hide show
  1. package/README.md +1 -1
  2. package/dist/{analyze-UZYJAWAP.js → analyze-XV3K25K3.js} +15 -9
  3. package/dist/analyze-XV3K25K3.js.map +1 -0
  4. package/dist/apply-WUJHDD7A.js +788 -0
  5. package/dist/apply-WUJHDD7A.js.map +1 -0
  6. package/dist/{chunk-2Z7OEZZT.js → chunk-34WNTK3K.js} +14 -9
  7. package/dist/chunk-34WNTK3K.js.map +1 -0
  8. package/dist/{chunk-UUY4PCWW.js → chunk-3BOHTH4V.js} +2 -2
  9. package/dist/chunk-3D4A4B46.js +2 -0
  10. package/dist/{policy-NP4ZAVF6.js → chunk-47VIN33V.js} +82 -112
  11. package/dist/chunk-47VIN33V.js.map +1 -0
  12. package/dist/{chunk-67ZO5ROQ.js → chunk-6N7LZZ5U.js} +19 -13
  13. package/dist/chunk-6N7LZZ5U.js.map +1 -0
  14. package/dist/{chunk-S67Q4I2O.js → chunk-AAY6KM7N.js} +6 -3
  15. package/dist/chunk-AAY6KM7N.js.map +1 -0
  16. package/dist/{chunk-2LNQL4XH.js → chunk-BXCPXRBR.js} +17 -12
  17. package/dist/chunk-BXCPXRBR.js.map +1 -0
  18. package/dist/{chunk-MXTGCD5C.js → chunk-EWDJENFW.js} +30 -9
  19. package/dist/chunk-EWDJENFW.js.map +1 -0
  20. package/dist/{chunk-SP7DD4ID.js → chunk-EY6WMHV2.js} +17 -12
  21. package/dist/chunk-EY6WMHV2.js.map +1 -0
  22. package/dist/{chunk-652DJBCN.js → chunk-GANSDJV7.js} +4 -4
  23. package/dist/{chunk-V5OHFSW4.js → chunk-HC2MT7BX.js} +23 -3
  24. package/dist/chunk-HC2MT7BX.js.map +1 -0
  25. package/dist/chunk-HQYXVIH6.js +110 -0
  26. package/dist/chunk-HQYXVIH6.js.map +1 -0
  27. package/dist/{chunk-UH4KAJBJ.js → chunk-IVHZEYAX.js} +17 -12
  28. package/dist/chunk-IVHZEYAX.js.map +1 -0
  29. package/dist/{chunk-EWA3OGCM.js → chunk-KQ4JQN7T.js} +14 -9
  30. package/dist/chunk-KQ4JQN7T.js.map +1 -0
  31. package/dist/{chunk-VOKNTBOO.js → chunk-LVKQ2AKT.js} +3 -3
  32. package/dist/chunk-OBLVLIUS.js +285 -0
  33. package/dist/chunk-OBLVLIUS.js.map +1 -0
  34. package/dist/chunk-RKTEV6EG.js +246 -0
  35. package/dist/chunk-RKTEV6EG.js.map +1 -0
  36. package/dist/{chunk-VYFKOUUR.js → chunk-VQ5VN7DF.js} +9 -5
  37. package/dist/chunk-VQ5VN7DF.js.map +1 -0
  38. package/dist/cli.js +26 -22
  39. package/dist/cli.js.map +1 -1
  40. package/dist/{config-YCF3HIKR.js → config-4THHOXNN.js} +3 -3
  41. package/dist/execute-5OEKLM5X.js +15 -0
  42. package/dist/{generate-TW6QKSW5.js → generate-TBVTLMOP.js} +101 -13
  43. package/dist/generate-TBVTLMOP.js.map +1 -0
  44. package/dist/init-PRMOTQ7N.js +9 -0
  45. package/dist/plan-Y2BYZD24.js +17 -0
  46. package/dist/policy-XQW5NUIE.js +117 -0
  47. package/dist/policy-XQW5NUIE.js.map +1 -0
  48. package/dist/pr-H6GLOSXF.js +21 -0
  49. package/dist/pr-review-CK5FR6WX.js +17 -0
  50. package/dist/prd-4PWLCGH5.js +17 -0
  51. package/dist/review-QGVAHEZF.js +15 -0
  52. package/dist/review-QGVAHEZF.js.map +1 -0
  53. package/dist/{run-DIBC3YKX.js → run-DBF2VWUN.js} +26 -25
  54. package/dist/{run-DIBC3YKX.js.map → run-DBF2VWUN.js.map} +1 -1
  55. package/dist/{web-O2FVOYZW.js → web-ANQQTTRD.js} +5 -5
  56. package/package.json +1 -1
  57. package/prompts/analyze.md +24 -0
  58. package/prompts/execute.md +29 -1
  59. package/prompts/generate.md +61 -7
  60. package/prompts/plan.md +24 -1
  61. package/prompts/pr-review.md +65 -4
  62. package/prompts/pr.md +37 -3
  63. package/prompts/prd.md +17 -0
  64. package/prompts/review.md +40 -0
  65. package/dist/analyze-UZYJAWAP.js.map +0 -1
  66. package/dist/chunk-2LNQL4XH.js.map +0 -1
  67. package/dist/chunk-2Z7OEZZT.js.map +0 -1
  68. package/dist/chunk-67ZO5ROQ.js.map +0 -1
  69. package/dist/chunk-EWA3OGCM.js.map +0 -1
  70. package/dist/chunk-EZMOEBLU.js +0 -135
  71. package/dist/chunk-EZMOEBLU.js.map +0 -1
  72. package/dist/chunk-MXTGCD5C.js.map +0 -1
  73. package/dist/chunk-PPLIXZI5.js +0 -101
  74. package/dist/chunk-PPLIXZI5.js.map +0 -1
  75. package/dist/chunk-S67Q4I2O.js.map +0 -1
  76. package/dist/chunk-SLHZPB3C.js +0 -50
  77. package/dist/chunk-SLHZPB3C.js.map +0 -1
  78. package/dist/chunk-SP7DD4ID.js.map +0 -1
  79. package/dist/chunk-UH4KAJBJ.js.map +0 -1
  80. package/dist/chunk-V5OHFSW4.js.map +0 -1
  81. package/dist/chunk-VYFKOUUR.js.map +0 -1
  82. package/dist/execute-QYXA225W.js +0 -14
  83. package/dist/generate-TW6QKSW5.js.map +0 -1
  84. package/dist/init-G57UXKDG.js +0 -9
  85. package/dist/plan-YJLGBYBQ.js +0 -16
  86. package/dist/policy-NP4ZAVF6.js.map +0 -1
  87. package/dist/pr-V5H65MRW.js +0 -20
  88. package/dist/pr-review-RCMXKXVP.js +0 -16
  89. package/dist/prd-3XR5KYJS.js +0 -16
  90. package/dist/review-ZZG3CSUO.js +0 -14
  91. /package/dist/{chunk-UUY4PCWW.js.map → chunk-3BOHTH4V.js.map} +0 -0
  92. /package/dist/{config-YCF3HIKR.js.map → chunk-3D4A4B46.js.map} +0 -0
  93. /package/dist/{chunk-652DJBCN.js.map → chunk-GANSDJV7.js.map} +0 -0
  94. /package/dist/{chunk-VOKNTBOO.js.map → chunk-LVKQ2AKT.js.map} +0 -0
  95. /package/dist/{execute-QYXA225W.js.map → config-4THHOXNN.js.map} +0 -0
  96. /package/dist/{init-G57UXKDG.js.map → execute-5OEKLM5X.js.map} +0 -0
  97. /package/dist/{plan-YJLGBYBQ.js.map → init-PRMOTQ7N.js.map} +0 -0
  98. /package/dist/{pr-V5H65MRW.js.map → plan-Y2BYZD24.js.map} +0 -0
  99. /package/dist/{pr-review-RCMXKXVP.js.map → pr-H6GLOSXF.js.map} +0 -0
  100. /package/dist/{prd-3XR5KYJS.js.map → pr-review-CK5FR6WX.js.map} +0 -0
  101. /package/dist/{review-ZZG3CSUO.js.map → prd-4PWLCGH5.js.map} +0 -0
  102. /package/dist/{web-O2FVOYZW.js.map → web-ANQQTTRD.js.map} +0 -0
  103. /package/web/{CLAUDE.md → AGENTS.md} +0 -0
package/dist/cli.js CHANGED
@@ -2,12 +2,12 @@
2
2
  import {
3
3
  setIssuesCliOverrides,
4
4
  setWebCliOverrides
5
- } from "./chunk-VYFKOUUR.js";
5
+ } from "./chunk-VQ5VN7DF.js";
6
6
  import {
7
7
  printError,
8
8
  setGlobalTimeout,
9
9
  setVerbose
10
- } from "./chunk-V5OHFSW4.js";
10
+ } from "./chunk-HC2MT7BX.js";
11
11
 
12
12
  // src/cli.ts
13
13
  import { createRequire } from "module";
@@ -191,15 +191,19 @@ program.hook("preAction", (_thisCommand, actionCommand) => {
191
191
  });
192
192
  withIssueOptions(
193
193
  withGlobalOptions(
194
- program.command("init").description("Verify that all prerequisites (claude, gh, git) are met")
194
+ program.command("init").description(
195
+ "Check prerequisites and report (or create) the conventions this repository is missing"
196
+ ).option("--apply", "Create the missing files instead of only reporting them").option("--json", "Emit the plan as JSON").option("--scope <dir>", "Resolve the conventions for a subdirectory (monorepo)").option("--check-only", "Only verify prerequisites, as earlier releases did")
195
197
  )
196
- ).action(async () => {
197
- const { loadIssuesConfig } = await import("./config-YCF3HIKR.js");
198
- const { runInit } = await import("./init-G57UXKDG.js");
199
- const { preferredProvider } = await loadIssuesConfig();
200
- const code = await runInit(preferredProvider);
201
- process.exit(code);
202
- });
198
+ ).action(
199
+ async (options) => {
200
+ const { loadIssuesConfig } = await import("./config-4THHOXNN.js");
201
+ const { runInit } = await import("./init-PRMOTQ7N.js");
202
+ const { preferredProvider } = await loadIssuesConfig();
203
+ const code = await runInit(preferredProvider, options);
204
+ process.exit(code);
205
+ }
206
+ );
203
207
  withGlobalOptions(
204
208
  program.command("generate").description("Draft an issue via Claude Code Headless and create it").requiredOption("--prompt <text>", "Issue description text").option("--github", "Create the issue on GitHub").option("--local", "Create the issue under issues/<n>/ only").option("--both", "Create the issue on GitHub and mirror it locally")
205
209
  ).action(async (options) => {
@@ -213,7 +217,7 @@ withGlobalOptions(
213
217
  }
214
218
  throw error;
215
219
  }
216
- const { runGenerate } = await import("./generate-TW6QKSW5.js");
220
+ const { runGenerate } = await import("./generate-TBVTLMOP.js");
217
221
  const code = await runGenerate(options.prompt, target);
218
222
  process.exit(code);
219
223
  });
@@ -246,7 +250,7 @@ withUserStoryNumberingOptions(
246
250
  }
247
251
  throw error;
248
252
  }
249
- const { runPipeline } = await import("./run-DIBC3YKX.js");
253
+ const { runPipeline } = await import("./run-DBF2VWUN.js");
250
254
  const code = await runPipeline(
251
255
  issues,
252
256
  options.mode,
@@ -268,7 +272,7 @@ withIssueOptions(
268
272
  program.command("analyze").description("Analyze an issue via Claude Code Headless").argument("<issue>", "Issue number")
269
273
  )
270
274
  ).action(async (issue) => {
271
- const { runAnalyze } = await import("./analyze-UZYJAWAP.js");
275
+ const { runAnalyze } = await import("./analyze-XV3K25K3.js");
272
276
  const code = await runAnalyze(issue);
273
277
  process.exit(code);
274
278
  });
@@ -277,7 +281,7 @@ withIssueOptions(
277
281
  program.command("prd").description("Generate a PRD from an analyzed issue via Claude Code Headless").argument("<issue>", "Issue number")
278
282
  )
279
283
  ).action(async (issue) => {
280
- const { runPrd } = await import("./prd-3XR5KYJS.js");
284
+ const { runPrd } = await import("./prd-4PWLCGH5.js");
281
285
  const code = await runPrd(issue);
282
286
  process.exit(code);
283
287
  });
@@ -298,7 +302,7 @@ withUserStoryNumberingOptions(
298
302
  }
299
303
  throw error;
300
304
  }
301
- const { runPlan } = await import("./plan-YJLGBYBQ.js");
305
+ const { runPlan } = await import("./plan-Y2BYZD24.js");
302
306
  const code = await runPlan(issue, void 0, numbering);
303
307
  process.exit(code);
304
308
  });
@@ -317,7 +321,7 @@ withWebOptions(
317
321
  ).action(
318
322
  async (positionalMaxIter, options) => {
319
323
  try {
320
- const { runExecute } = await import("./execute-QYXA225W.js");
324
+ const { runExecute } = await import("./execute-5OEKLM5X.js");
321
325
  const code = await runExecute(positionalMaxIter, options);
322
326
  process.exit(code);
323
327
  } catch (error) {
@@ -331,7 +335,7 @@ withIssueOptions(
331
335
  program.command("review").description("Validate an issue resolution via Claude Code Headless").argument("<issue>", "Issue number")
332
336
  )
333
337
  ).action(async (issue) => {
334
- const { runReview } = await import("./review-ZZG3CSUO.js");
338
+ const { runReview } = await import("./review-QGVAHEZF.js");
335
339
  const code = await runReview(issue);
336
340
  process.exit(code);
337
341
  });
@@ -340,7 +344,7 @@ withIssueOptions(
340
344
  program.command("pr").description("Create a pull request via Claude Code Headless").argument("<issue>", "Issue number")
341
345
  )
342
346
  ).action(async (issue) => {
343
- const { runPr } = await import("./pr-V5H65MRW.js");
347
+ const { runPr } = await import("./pr-H6GLOSXF.js");
344
348
  const code = await runPr(issue);
345
349
  process.exit(code);
346
350
  });
@@ -348,21 +352,21 @@ var webCommand = program.command("web").description("Manage the web monitoring s
348
352
  webCommand.command("serve").description(
349
353
  "Run the web monitor server in the foreground (internal \u2014 spawned detached by --web)"
350
354
  ).option("--port <n>", "Web server port (default: 3737)", parseInteger).option("--host <h>", "Web server host (default: 0.0.0.0)").option("--refresh <s>", "Suggested UI polling interval in seconds", parseInteger).action(async (options) => {
351
- const { runWebServe } = await import("./web-O2FVOYZW.js");
355
+ const { runWebServe } = await import("./web-ANQQTTRD.js");
352
356
  const code = await runWebServe(options);
353
357
  if (code !== 0) {
354
358
  process.exit(code);
355
359
  }
356
360
  });
357
361
  webCommand.command("stop").description("Stop the running web monitor server").action(async () => {
358
- const { runWebStop } = await import("./web-O2FVOYZW.js");
362
+ const { runWebStop } = await import("./web-ANQQTTRD.js");
359
363
  const code = await runWebStop();
360
364
  process.exit(code);
361
365
  });
362
366
  withGlobalOptions(
363
367
  program.command("policy").description("Inspect the policies discovered in this repository and their provenance").option("--scope <dir>", "Resolve the policy for a subdirectory (monorepo)").option("--json", "Emit the resolved policy as JSON")
364
368
  ).action(async (options) => {
365
- const { runPolicy } = await import("./policy-NP4ZAVF6.js");
369
+ const { runPolicy } = await import("./policy-XQW5NUIE.js");
366
370
  const code = await runPolicy(options);
367
371
  process.exit(code);
368
372
  });
@@ -373,7 +377,7 @@ withGlobalOptions(
373
377
  )
374
378
  ).action(
375
379
  async (pr, options) => {
376
- const { runPrReview } = await import("./pr-review-RCMXKXVP.js");
380
+ const { runPrReview } = await import("./pr-review-CK5FR6WX.js");
377
381
  const code = await runPrReview(pr, options);
378
382
  process.exit(code);
379
383
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/cli-options.ts","../src/issues/cli-flags.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { Command, InvalidArgumentError } from 'commander';\nimport {\n CliFlagError,\n resolveQueueScopeFlags,\n resolveRunPhaseFlags,\n resolveUserStoryNumberingFlags,\n} from './cli-options.js';\nimport { setIssuesCliOverrides, setWebCliOverrides } from './config.js';\nimport { setGlobalTimeout, setVerbose } from './core/verbose.js';\nimport {\n IssueFlagError,\n resolveGenerateTarget,\n resolveIssuesOverrides,\n} from './issues/cli-flags.js';\nimport type { IssueGenerateTarget } from './issues/types.js';\nimport type { WebConfig } from './schemas.js';\nimport { printError } from './ui/logger.js';\n\nconst require = createRequire(import.meta.url);\nconst { version } = require('../package.json') as { version: string };\n\n/**\n * Parse a numeric string, throwing InvalidArgumentError if not a valid number.\n */\nfunction parseInteger(value: string): number {\n const parsed = parseInt(value, 10);\n if (Number.isNaN(parsed) || parsed < 0) {\n throw new InvalidArgumentError('Must be a non-negative integer.');\n }\n return parsed;\n}\n\n/**\n * Parse `--start-us <n>`: a User Story number is 1-based, so 0 is rejected\n * along with everything `parseInteger` already rejects.\n */\nfunction parseStartUs(value: string): number {\n const parsed = parseInteger(value);\n if (parsed < 1) {\n throw new InvalidArgumentError('Must be a positive integer (US-001 is the first story).');\n }\n return parsed;\n}\n\n/**\n * Add the User Story numbering override options to a subcommand that\n * triggers `plan` (`run` and `plan` itself) — see issue #36.\n */\nfunction withUserStoryNumberingOptions(cmd: Command): Command {\n return cmd\n .option('--continue', 'Continue User Story numbering from the last used in this project')\n .option(\n '--start-us <n>',\n 'Force User Story numbering to start at a specific number, ignoring history',\n parseStartUs,\n );\n}\n\n/**\n * Add shared options (--verbose) to a subcommand.\n */\nfunction withGlobalOptions(cmd: Command): Command {\n return cmd\n .option('-v, --verbose', 'Show Claude progress output in real time')\n .option(\n '-t, --timeout <seconds>',\n 'Override headless timeout in seconds (0 = no limit)',\n parseInteger,\n );\n}\n\n/**\n * Add web monitoring options to a subcommand (run and execute only).\n * The values are resolved into CLI overrides by the preAction hook below;\n * loadWebConfig() applies the flag > env > file > defaults precedence.\n */\nfunction withWebOptions(cmd: Command): Command {\n return cmd\n .option('--web', 'Enable the web monitoring server')\n .option('--serve', 'Alias for --web')\n .option('--port <n>', 'Web server port (default: 3737)', parseInteger)\n .option('--host <h>', 'Web server host (default: 0.0.0.0)')\n .option('--refresh <s>', 'Suggested UI polling interval in seconds', parseInteger)\n .option('--web-log-limit <n>', 'Max log entries kept in the snapshot', parseInteger)\n .option('--web-no-logs', 'Exclude logs from the published snapshot');\n}\n\n/**\n * Add the Issue provider options to a subcommand.\n *\n * Declared once here (like withWebOptions) so no command repeats the flag\n * list; the preAction hook below turns them into config overrides, and\n * loadIssuesConfig() applies the flag > .issue-flow.json > defaults precedence.\n */\nfunction withIssueOptions(cmd: Command): Command {\n return cmd\n .option('--local', 'Prefer the local file Issue provider')\n .option('--github', 'Prefer the GitHub Issue provider')\n .option('--prefer-local', 'On divergence, use the local version without asking')\n .option('--prefer-github', 'On divergence, use the GitHub version without asking')\n .option('--ask', 'On divergence, ask which version to use (interactive only)');\n}\n\n/**\n * Extract the web-related CLI flags from a command's options, keeping only\n * the ones the user actually set.\n */\nfunction resolveWebOverrides(opts: Record<string, unknown>): Partial<WebConfig> {\n const overrides: Partial<WebConfig> = {};\n if (opts.web === true || opts.serve === true) {\n overrides.enabled = true;\n }\n if (opts.port !== undefined) {\n overrides.port = opts.port as number;\n }\n if (opts.host !== undefined) {\n overrides.host = opts.host as string;\n }\n if (opts.refresh !== undefined) {\n overrides.refreshSeconds = opts.refresh as number;\n }\n if (opts.webLogLimit !== undefined) {\n overrides.logLimit = opts.webLogLimit as number;\n }\n if (opts.webNoLogs === true) {\n overrides.includeLogs = false;\n }\n return overrides;\n}\n\nconst program = new Command();\n\nprogram\n .name('issue-flow')\n .description(\n 'Unified CLI for orchestrating the full issue-flow pipeline via Claude Code Headless.',\n )\n .version(version);\n\nprogram.hook('preAction', (_thisCommand, actionCommand) => {\n const opts = actionCommand.opts();\n if (opts.verbose) {\n setVerbose(true);\n }\n if (opts.timeout !== undefined) {\n setGlobalTimeout(opts.timeout * 1000);\n }\n setWebCliOverrides(resolveWebOverrides(opts));\n try {\n setIssuesCliOverrides(resolveIssuesOverrides(opts));\n } catch (error) {\n if (error instanceof IssueFlagError) {\n printError(error.message);\n process.exit(1);\n }\n throw error;\n }\n});\n\n// ── init ────────────────────────────────────────────────────────────────────\nwithIssueOptions(\n withGlobalOptions(\n program.command('init').description('Verify that all prerequisites (claude, gh, git) are met'),\n ),\n).action(async () => {\n const { loadIssuesConfig } = await import('./config.js');\n const { runInit } = await import('./commands/init.js');\n const { preferredProvider } = await loadIssuesConfig();\n const code = await runInit(preferredProvider);\n process.exit(code);\n});\n\n// ── generate ────────────────────────────────────────────────────────────────\nwithGlobalOptions(\n program\n .command('generate')\n .description('Draft an issue via Claude Code Headless and create it')\n .requiredOption('--prompt <text>', 'Issue description text')\n .option('--github', 'Create the issue on GitHub')\n .option('--local', 'Create the issue under issues/<n>/ only')\n .option('--both', 'Create the issue on GitHub and mirror it locally'),\n).action(async (options: { prompt: string; github?: boolean; local?: boolean; both?: boolean }) => {\n let target: IssueGenerateTarget | undefined;\n try {\n target = resolveGenerateTarget(options);\n } catch (error) {\n if (error instanceof IssueFlagError) {\n printError(error.message);\n process.exit(1);\n }\n throw error;\n }\n\n const { runGenerate } = await import('./commands/generate.js');\n const code = await runGenerate(options.prompt, target);\n process.exit(code);\n});\n\n// ── run ─────────────────────────────────────────────────────────────────────\nwithUserStoryNumberingOptions(\n withWebOptions(\n withIssueOptions(\n withGlobalOptions(\n program\n .command('run')\n .description(\n 'Execute the full pipeline: prd → plan → execute → review → pr (→ pr-review, optional)',\n )\n .argument('<issues...>', 'Issue number(s): 42, \"42,43\" or 42 43')\n .option('--mode <mode>', 'Execution mode: auto | manual', 'auto')\n .option('--from <phase>', 'Resume from a specific phase')\n .option(\n '--no-branch',\n 'Run pipeline on current branch without creating a new branch or PR',\n )\n .option('--pr-review', 'Review the created Pull Request after the pr phase')\n .option('-y, --yes', 'Run the whole discovered hierarchy without confirmation')\n .option('--only', 'Run just the issues informed, without their hierarchy'),\n ),\n ),\n ),\n).action(\n async (\n issues: string[],\n options: {\n mode: string;\n from?: string;\n branch?: boolean;\n prReview?: boolean;\n yes?: boolean;\n only?: boolean;\n continue?: boolean;\n startUs?: number;\n },\n ) => {\n let phases: ReturnType<typeof resolveRunPhaseFlags>;\n let scope: ReturnType<typeof resolveQueueScopeFlags>;\n let numbering: ReturnType<typeof resolveUserStoryNumberingFlags>;\n try {\n phases = resolveRunPhaseFlags(options);\n scope = resolveQueueScopeFlags(options);\n numbering = resolveUserStoryNumberingFlags(options);\n } catch (error) {\n if (error instanceof CliFlagError) {\n printError(error.message);\n process.exit(1);\n }\n throw error;\n }\n\n const { runPipeline } = await import('./commands/run.js');\n const code = await runPipeline(\n issues,\n options.mode,\n options.from,\n phases.noBranch,\n phases.prReview,\n {\n yes: scope.yes,\n only: scope.only,\n continueNumbering: numbering.continueFlag,\n startUs: numbering.startUs,\n },\n );\n process.exit(code);\n },\n);\n\n// ── analyze ─────────────────────────────────────────────────────────────────\nwithIssueOptions(\n withGlobalOptions(\n program\n .command('analyze')\n .description('Analyze an issue via Claude Code Headless')\n .argument('<issue>', 'Issue number'),\n ),\n).action(async (issue: string) => {\n const { runAnalyze } = await import('./commands/analyze.js');\n const code = await runAnalyze(issue);\n process.exit(code);\n});\n\n// ── prd ─────────────────────────────────────────────────────────────────────\nwithIssueOptions(\n withGlobalOptions(\n program\n .command('prd')\n .description('Generate a PRD from an analyzed issue via Claude Code Headless')\n .argument('<issue>', 'Issue number'),\n ),\n).action(async (issue: string) => {\n const { runPrd } = await import('./commands/prd.js');\n const code = await runPrd(issue);\n process.exit(code);\n});\n\n// ── plan ────────────────────────────────────────────────────────────────────\nwithUserStoryNumberingOptions(\n withIssueOptions(\n withGlobalOptions(\n program\n .command('plan')\n .description('Convert a PRD to a tasks.json task plan via Claude Code Headless')\n .argument('<issue>', 'Issue number'),\n ),\n ),\n).action(async (issue: string, options: { continue?: boolean; startUs?: number }) => {\n let numbering: ReturnType<typeof resolveUserStoryNumberingFlags>;\n try {\n numbering = resolveUserStoryNumberingFlags(options);\n } catch (error) {\n if (error instanceof CliFlagError) {\n printError(error.message);\n process.exit(1);\n }\n throw error;\n }\n\n const { runPlan } = await import('./commands/plan.js');\n const code = await runPlan(issue, undefined, numbering);\n process.exit(code);\n});\n\n// ── execute ─────────────────────────────────────────────────────────────────\nwithWebOptions(\n withGlobalOptions(\n program\n .command('execute')\n .description('Run the iterative story execution loop (issue-flow engine)')\n .option('--issue <number>', 'Issue number — reads artifacts from issues/N/')\n .option('--max-iterations <number>', 'Stop after N iterations', parseInteger)\n .option(\n '--retry-limit <number>',\n 'Retry transient Claude failures up to N consecutive times',\n parseInteger,\n )\n .option('--retry-forever', 'Retry transient Claude failures indefinitely')\n .argument(\n '[max-iterations]',\n 'Backward-compatible alias for --max-iterations N',\n parseInteger,\n ),\n ),\n).action(\n async (\n positionalMaxIter: number | undefined,\n options: {\n issue?: string;\n maxIterations?: number;\n retryLimit?: number;\n retryForever?: boolean;\n },\n ) => {\n try {\n const { runExecute } = await import('./commands/execute.js');\n const code = await runExecute(positionalMaxIter, options);\n process.exit(code);\n } catch (error) {\n printError(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n },\n);\n\n// ── review ──────────────────────────────────────────────────────────────────\nwithIssueOptions(\n withGlobalOptions(\n program\n .command('review')\n .description('Validate an issue resolution via Claude Code Headless')\n .argument('<issue>', 'Issue number'),\n ),\n).action(async (issue: string) => {\n const { runReview } = await import('./commands/review.js');\n const code = await runReview(issue);\n process.exit(code);\n});\n\n// ── pr ──────────────────────────────────────────────────────────────────────\nwithIssueOptions(\n withGlobalOptions(\n program\n .command('pr')\n .description('Create a pull request via Claude Code Headless')\n .argument('<issue>', 'Issue number'),\n ),\n).action(async (issue: string) => {\n const { runPr } = await import('./commands/pr.js');\n const code = await runPr(issue);\n process.exit(code);\n});\n\n// ── web ─────────────────────────────────────────────────────────────────────\nconst webCommand = program.command('web').description('Manage the web monitoring server');\n\nwebCommand\n .command('serve')\n .description(\n 'Run the web monitor server in the foreground (internal — spawned detached by --web)',\n )\n .option('--port <n>', 'Web server port (default: 3737)', parseInteger)\n .option('--host <h>', 'Web server host (default: 0.0.0.0)')\n .option('--refresh <s>', 'Suggested UI polling interval in seconds', parseInteger)\n .action(async (options: { port?: number; host?: string; refresh?: number }) => {\n const { runWebServe } = await import('./commands/web.js');\n const code = await runWebServe(options);\n // On success this process stays alive for as long as the server is bound\n // (server.ts binds it with unref: false) — only a failure exits here.\n if (code !== 0) {\n process.exit(code);\n }\n });\n\nwebCommand\n .command('stop')\n .description('Stop the running web monitor server')\n .action(async () => {\n const { runWebStop } = await import('./commands/web.js');\n const code = await runWebStop();\n process.exit(code);\n });\n\n// ── policy ──────────────────────────────────────────────────────────────\nwithGlobalOptions(\n program\n .command('policy')\n .description('Inspect the policies discovered in this repository and their provenance')\n .option('--scope <dir>', 'Resolve the policy for a subdirectory (monorepo)')\n .option('--json', 'Emit the resolved policy as JSON'),\n).action(async (options: { scope?: string; json?: boolean }) => {\n const { runPolicy } = await import('./commands/policy.js');\n const code = await runPolicy(options);\n process.exit(code);\n});\n\n// ── pr-review ───────────────────────────────────────────────────────────────\nwithGlobalOptions(\n program\n .command('pr-review')\n .description('Review a Pull Request as a whole via Claude Code Headless')\n .argument('[pr]', 'Pull Request number (discovered from the session when omitted)')\n .option('--issue <n>', 'Issue the Pull Request belongs to')\n .option('--round <n>', 'Rewrite a specific review round instead of appending a new one')\n .option('--yes', 'Skip the confirmation of the discovered Pull Request')\n .option(\n '--fail-on <level>',\n 'Verdict that fails the command: request-changes | suggestions | none',\n ),\n).action(\n async (\n pr: string | undefined,\n options: { issue?: string; round?: string; yes?: boolean; failOn?: string },\n ) => {\n const { runPrReview } = await import('./commands/pr-review.js');\n const code = await runPrReview(pr, options);\n process.exit(code);\n },\n);\n\nprogram.parse();\n","/**\n * Pure mappings from parsed CLI options to command arguments.\n *\n * They live outside cli.ts because that module runs `program.parse()` on\n * import, so anything defined there is untestable.\n */\n\n/** Shape commander produces for a negated boolean option (`--no-branch`). */\nexport interface BranchFlagOptions {\n branch?: boolean;\n}\n\n/**\n * Translate commander's `--no-branch` into the tri-state `runPipeline` expects.\n *\n * Commander stores a negated option under its positive name: `--no-branch`\n * yields `{ branch: false }` and never a `noBranch` key. Reading `noBranch`\n * silently dropped the flag, so the pipeline always created a branch and opened\n * a PR.\n *\n * `undefined` (flag absent) is preserved on purpose: `runPipeline` uses it to\n * tell \"the user said nothing, keep the mode persisted in tasks.json\" apart\n * from an explicit choice.\n */\nexport function resolveNoBranch(options: BranchFlagOptions): boolean | undefined {\n return options.branch === false ? true : undefined;\n}\n\n/** Invalid flag combination on a command, reported as a CLI error. */\nexport class CliFlagError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CliFlagError';\n }\n}\n\n/** Options `run` accepts that select which phases the pipeline executes. */\nexport interface RunPhaseFlagOptions extends BranchFlagOptions {\n prReview?: boolean;\n}\n\n/** Phase selection `runPipeline` expects, both entries tri-state. */\nexport interface RunPhaseFlags {\n noBranch: boolean | undefined;\n prReview: boolean | undefined;\n}\n\n/** Scope flags of `run`, deciding what a discovered hierarchy does. */\nexport interface QueueScopeFlagOptions {\n yes?: boolean;\n only?: boolean;\n}\n\n/** Resolved scope answer; both absent means \"ask, when the terminal allows it\". */\nexport interface QueueScopeFlags {\n yes: boolean | undefined;\n only: boolean | undefined;\n}\n\n/**\n * Resolve `--yes` / `--only`, rejecting the combination that has no meaning.\n *\n * They answer the same question in opposite ways — run everything that was\n * discovered, or run only what was asked for — so passing both is a mistake\n * worth naming rather than silently resolving by precedence.\n *\n * @throws CliFlagError when both are present.\n */\nexport function resolveQueueScopeFlags(options: QueueScopeFlagOptions): QueueScopeFlags {\n if (options.yes === true && options.only === true) {\n throw new CliFlagError(\n '--yes cannot be combined with --only: --yes runs the whole discovered hierarchy, ' +\n '--only runs just the issues you informed.',\n );\n }\n\n return {\n yes: options.yes === true ? true : undefined,\n only: options.only === true ? true : undefined,\n };\n}\n\n/**\n * Resolve the phase-selection flags of `run`, rejecting the one combination\n * that cannot work.\n *\n * `--no-branch` skips the `pr` phase, so there is no Pull Request for\n * `--pr-review` to review. Failing here — before any phase runs — beats\n * discovering it at the end of a full pipeline.\n *\n * Both values stay `undefined` when the user passed nothing: `runPipeline`\n * uses that to tell \"no opinion, keep what tasks.json persisted\" apart from an\n * explicit choice.\n *\n * @throws CliFlagError when `--pr-review` is combined with `--no-branch`.\n */\nexport function resolveRunPhaseFlags(options: RunPhaseFlagOptions): RunPhaseFlags {\n const noBranch = resolveNoBranch(options);\n const prReview = options.prReview === true ? true : undefined;\n\n if (prReview === true && noBranch === true) {\n throw new CliFlagError(\n '--pr-review cannot be combined with --no-branch: --no-branch skips the pr phase, ' +\n 'so there is no Pull Request to review.',\n );\n }\n\n return { noBranch, prReview };\n}\n\n/** Options `run` and `plan` accept to override User Story numbering (issue #36). */\nexport interface UserStoryNumberingFlagOptions {\n continue?: boolean;\n startUs?: number;\n}\n\n/** Resolved User Story numbering override, ready for `determineUserStoryNumbering()`. */\nexport interface UserStoryNumberingFlags {\n continueFlag: boolean;\n startUs: number | undefined;\n}\n\n/**\n * Resolve the `--continue` / `--start-us <n>` override of the User Story\n * numbering cascade (issue #36), rejecting the one combination that cannot\n * work: the two disagree about whether history should be consulted at all.\n *\n * @throws CliFlagError when both flags are passed together.\n */\nexport function resolveUserStoryNumberingFlags(\n options: UserStoryNumberingFlagOptions,\n): UserStoryNumberingFlags {\n const continueFlag = options.continue === true;\n const startUs = options.startUs;\n\n if (continueFlag && startUs !== undefined) {\n throw new CliFlagError(\n '--continue and --start-us cannot be combined: choose either the last known numbering ' +\n '(--continue) or an explicit override (--start-us).',\n );\n }\n\n return { continueFlag, startUs };\n}\n","import type { IssueGenerateTarget, IssuesConfig } from './types.js';\n\n/**\n * Mapping from the Issue provider CLI flags to configuration overrides.\n *\n * Kept out of cli.ts (which runs `program.parse()` on import) so the\n * precedence rules stay unit-testable. Only the keys the user actually passed\n * are returned: a key present with `undefined` would override .issue-flow.json\n * when the layers are merged.\n */\n\nexport interface IssueCliFlags {\n local?: boolean;\n github?: boolean;\n preferLocal?: boolean;\n preferGithub?: boolean;\n ask?: boolean;\n}\n\n/** Invalid flag combination, reported to the user as a CLI error. */\nexport class IssueFlagError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'IssueFlagError';\n }\n}\n\n/**\n * Translate the parsed options of a command into `IssuesConfig` overrides.\n *\n * @throws IssueFlagError when mutually exclusive flags are combined.\n */\nexport function resolveIssuesOverrides(opts: IssueCliFlags): Partial<IssuesConfig> {\n const overrides: Partial<IssuesConfig> = {};\n\n if (opts.local === true && opts.github === true) {\n throw new IssueFlagError('--local and --github are mutually exclusive; pass only one.');\n }\n if (opts.local === true) {\n overrides.preferredProvider = 'local';\n }\n if (opts.github === true) {\n overrides.preferredProvider = 'github';\n }\n\n const conflictFlags = [\n opts.preferLocal === true ? '--prefer-local' : null,\n opts.preferGithub === true ? '--prefer-github' : null,\n opts.ask === true ? '--ask' : null,\n ].filter((flag): flag is string => flag !== null);\n\n if (conflictFlags.length > 1) {\n throw new IssueFlagError(\n `${conflictFlags.join(', ')} are mutually exclusive; pass only one conflict policy.`,\n );\n }\n if (opts.preferLocal === true) {\n overrides.conflictPolicy = 'prefer-local';\n }\n if (opts.preferGithub === true) {\n overrides.conflictPolicy = 'prefer-github';\n }\n if (opts.ask === true) {\n overrides.conflictPolicy = 'ask';\n }\n\n return overrides;\n}\n\n/** Destination flags accepted by `generate`. */\nexport interface GenerateTargetFlags {\n github?: boolean;\n local?: boolean;\n both?: boolean;\n}\n\n/**\n * Destination the generated Issue is created in, or `undefined` when the user\n * passed no flag (the caller then falls back to `defaultGenerateTarget`).\n *\n * @throws IssueFlagError when more than one destination is requested.\n */\nexport function resolveGenerateTarget(opts: GenerateTargetFlags): IssueGenerateTarget | undefined {\n const selected: IssueGenerateTarget[] = [];\n if (opts.github === true) selected.push('github');\n if (opts.local === true) selected.push('local');\n if (opts.both === true) selected.push('both');\n\n if (selected.length > 1) {\n throw new IssueFlagError(\n `${selected.map((target) => `--${target}`).join(', ')} are mutually exclusive; ` +\n 'pass only one destination.',\n );\n }\n\n return selected[0];\n}\n"],"mappings":"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","names":["require"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/cli-options.ts","../src/issues/cli-flags.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { Command, InvalidArgumentError } from 'commander';\nimport {\n CliFlagError,\n resolveQueueScopeFlags,\n resolveRunPhaseFlags,\n resolveUserStoryNumberingFlags,\n} from './cli-options.js';\nimport { setIssuesCliOverrides, setWebCliOverrides } from './config.js';\nimport { setGlobalTimeout, setVerbose } from './core/verbose.js';\nimport {\n IssueFlagError,\n resolveGenerateTarget,\n resolveIssuesOverrides,\n} from './issues/cli-flags.js';\nimport type { IssueGenerateTarget } from './issues/types.js';\nimport type { WebConfig } from './schemas.js';\nimport { printError } from './ui/logger.js';\n\nconst require = createRequire(import.meta.url);\nconst { version } = require('../package.json') as { version: string };\n\n/**\n * Parse a numeric string, throwing InvalidArgumentError if not a valid number.\n */\nfunction parseInteger(value: string): number {\n const parsed = parseInt(value, 10);\n if (Number.isNaN(parsed) || parsed < 0) {\n throw new InvalidArgumentError('Must be a non-negative integer.');\n }\n return parsed;\n}\n\n/**\n * Parse `--start-us <n>`: a User Story number is 1-based, so 0 is rejected\n * along with everything `parseInteger` already rejects.\n */\nfunction parseStartUs(value: string): number {\n const parsed = parseInteger(value);\n if (parsed < 1) {\n throw new InvalidArgumentError('Must be a positive integer (US-001 is the first story).');\n }\n return parsed;\n}\n\n/**\n * Add the User Story numbering override options to a subcommand that\n * triggers `plan` (`run` and `plan` itself) — see issue #36.\n */\nfunction withUserStoryNumberingOptions(cmd: Command): Command {\n return cmd\n .option('--continue', 'Continue User Story numbering from the last used in this project')\n .option(\n '--start-us <n>',\n 'Force User Story numbering to start at a specific number, ignoring history',\n parseStartUs,\n );\n}\n\n/**\n * Add shared options (--verbose) to a subcommand.\n */\nfunction withGlobalOptions(cmd: Command): Command {\n return cmd\n .option('-v, --verbose', 'Show Claude progress output in real time')\n .option(\n '-t, --timeout <seconds>',\n 'Override headless timeout in seconds (0 = no limit)',\n parseInteger,\n );\n}\n\n/**\n * Add web monitoring options to a subcommand (run and execute only).\n * The values are resolved into CLI overrides by the preAction hook below;\n * loadWebConfig() applies the flag > env > file > defaults precedence.\n */\nfunction withWebOptions(cmd: Command): Command {\n return cmd\n .option('--web', 'Enable the web monitoring server')\n .option('--serve', 'Alias for --web')\n .option('--port <n>', 'Web server port (default: 3737)', parseInteger)\n .option('--host <h>', 'Web server host (default: 0.0.0.0)')\n .option('--refresh <s>', 'Suggested UI polling interval in seconds', parseInteger)\n .option('--web-log-limit <n>', 'Max log entries kept in the snapshot', parseInteger)\n .option('--web-no-logs', 'Exclude logs from the published snapshot');\n}\n\n/**\n * Add the Issue provider options to a subcommand.\n *\n * Declared once here (like withWebOptions) so no command repeats the flag\n * list; the preAction hook below turns them into config overrides, and\n * loadIssuesConfig() applies the flag > .issue-flow.json > defaults precedence.\n */\nfunction withIssueOptions(cmd: Command): Command {\n return cmd\n .option('--local', 'Prefer the local file Issue provider')\n .option('--github', 'Prefer the GitHub Issue provider')\n .option('--prefer-local', 'On divergence, use the local version without asking')\n .option('--prefer-github', 'On divergence, use the GitHub version without asking')\n .option('--ask', 'On divergence, ask which version to use (interactive only)');\n}\n\n/**\n * Extract the web-related CLI flags from a command's options, keeping only\n * the ones the user actually set.\n */\nfunction resolveWebOverrides(opts: Record<string, unknown>): Partial<WebConfig> {\n const overrides: Partial<WebConfig> = {};\n if (opts.web === true || opts.serve === true) {\n overrides.enabled = true;\n }\n if (opts.port !== undefined) {\n overrides.port = opts.port as number;\n }\n if (opts.host !== undefined) {\n overrides.host = opts.host as string;\n }\n if (opts.refresh !== undefined) {\n overrides.refreshSeconds = opts.refresh as number;\n }\n if (opts.webLogLimit !== undefined) {\n overrides.logLimit = opts.webLogLimit as number;\n }\n if (opts.webNoLogs === true) {\n overrides.includeLogs = false;\n }\n return overrides;\n}\n\nconst program = new Command();\n\nprogram\n .name('issue-flow')\n .description(\n 'Unified CLI for orchestrating the full issue-flow pipeline via Claude Code Headless.',\n )\n .version(version);\n\nprogram.hook('preAction', (_thisCommand, actionCommand) => {\n const opts = actionCommand.opts();\n if (opts.verbose) {\n setVerbose(true);\n }\n if (opts.timeout !== undefined) {\n setGlobalTimeout(opts.timeout * 1000);\n }\n setWebCliOverrides(resolveWebOverrides(opts));\n try {\n setIssuesCliOverrides(resolveIssuesOverrides(opts));\n } catch (error) {\n if (error instanceof IssueFlagError) {\n printError(error.message);\n process.exit(1);\n }\n throw error;\n }\n});\n\n// ── init ────────────────────────────────────────────────────────────────────\nwithIssueOptions(\n withGlobalOptions(\n program\n .command('init')\n .description(\n 'Check prerequisites and report (or create) the conventions this repository is missing',\n )\n .option('--apply', 'Create the missing files instead of only reporting them')\n .option('--json', 'Emit the plan as JSON')\n .option('--scope <dir>', 'Resolve the conventions for a subdirectory (monorepo)')\n .option('--check-only', 'Only verify prerequisites, as earlier releases did'),\n ),\n).action(\n async (options: { apply?: boolean; json?: boolean; scope?: string; checkOnly?: boolean }) => {\n const { loadIssuesConfig } = await import('./config.js');\n const { runInit } = await import('./commands/init.js');\n const { preferredProvider } = await loadIssuesConfig();\n const code = await runInit(preferredProvider, options);\n process.exit(code);\n },\n);\n\n// ── generate ────────────────────────────────────────────────────────────────\nwithGlobalOptions(\n program\n .command('generate')\n .description('Draft an issue via Claude Code Headless and create it')\n .requiredOption('--prompt <text>', 'Issue description text')\n .option('--github', 'Create the issue on GitHub')\n .option('--local', 'Create the issue under issues/<n>/ only')\n .option('--both', 'Create the issue on GitHub and mirror it locally'),\n).action(async (options: { prompt: string; github?: boolean; local?: boolean; both?: boolean }) => {\n let target: IssueGenerateTarget | undefined;\n try {\n target = resolveGenerateTarget(options);\n } catch (error) {\n if (error instanceof IssueFlagError) {\n printError(error.message);\n process.exit(1);\n }\n throw error;\n }\n\n const { runGenerate } = await import('./commands/generate.js');\n const code = await runGenerate(options.prompt, target);\n process.exit(code);\n});\n\n// ── run ─────────────────────────────────────────────────────────────────────\nwithUserStoryNumberingOptions(\n withWebOptions(\n withIssueOptions(\n withGlobalOptions(\n program\n .command('run')\n .description(\n 'Execute the full pipeline: prd → plan → execute → review → pr (→ pr-review, optional)',\n )\n .argument('<issues...>', 'Issue number(s): 42, \"42,43\" or 42 43')\n .option('--mode <mode>', 'Execution mode: auto | manual', 'auto')\n .option('--from <phase>', 'Resume from a specific phase')\n .option(\n '--no-branch',\n 'Run pipeline on current branch without creating a new branch or PR',\n )\n .option('--pr-review', 'Review the created Pull Request after the pr phase')\n .option('-y, --yes', 'Run the whole discovered hierarchy without confirmation')\n .option('--only', 'Run just the issues informed, without their hierarchy'),\n ),\n ),\n ),\n).action(\n async (\n issues: string[],\n options: {\n mode: string;\n from?: string;\n branch?: boolean;\n prReview?: boolean;\n yes?: boolean;\n only?: boolean;\n continue?: boolean;\n startUs?: number;\n },\n ) => {\n let phases: ReturnType<typeof resolveRunPhaseFlags>;\n let scope: ReturnType<typeof resolveQueueScopeFlags>;\n let numbering: ReturnType<typeof resolveUserStoryNumberingFlags>;\n try {\n phases = resolveRunPhaseFlags(options);\n scope = resolveQueueScopeFlags(options);\n numbering = resolveUserStoryNumberingFlags(options);\n } catch (error) {\n if (error instanceof CliFlagError) {\n printError(error.message);\n process.exit(1);\n }\n throw error;\n }\n\n const { runPipeline } = await import('./commands/run.js');\n const code = await runPipeline(\n issues,\n options.mode,\n options.from,\n phases.noBranch,\n phases.prReview,\n {\n yes: scope.yes,\n only: scope.only,\n continueNumbering: numbering.continueFlag,\n startUs: numbering.startUs,\n },\n );\n process.exit(code);\n },\n);\n\n// ── analyze ─────────────────────────────────────────────────────────────────\nwithIssueOptions(\n withGlobalOptions(\n program\n .command('analyze')\n .description('Analyze an issue via Claude Code Headless')\n .argument('<issue>', 'Issue number'),\n ),\n).action(async (issue: string) => {\n const { runAnalyze } = await import('./commands/analyze.js');\n const code = await runAnalyze(issue);\n process.exit(code);\n});\n\n// ── prd ─────────────────────────────────────────────────────────────────────\nwithIssueOptions(\n withGlobalOptions(\n program\n .command('prd')\n .description('Generate a PRD from an analyzed issue via Claude Code Headless')\n .argument('<issue>', 'Issue number'),\n ),\n).action(async (issue: string) => {\n const { runPrd } = await import('./commands/prd.js');\n const code = await runPrd(issue);\n process.exit(code);\n});\n\n// ── plan ────────────────────────────────────────────────────────────────────\nwithUserStoryNumberingOptions(\n withIssueOptions(\n withGlobalOptions(\n program\n .command('plan')\n .description('Convert a PRD to a tasks.json task plan via Claude Code Headless')\n .argument('<issue>', 'Issue number'),\n ),\n ),\n).action(async (issue: string, options: { continue?: boolean; startUs?: number }) => {\n let numbering: ReturnType<typeof resolveUserStoryNumberingFlags>;\n try {\n numbering = resolveUserStoryNumberingFlags(options);\n } catch (error) {\n if (error instanceof CliFlagError) {\n printError(error.message);\n process.exit(1);\n }\n throw error;\n }\n\n const { runPlan } = await import('./commands/plan.js');\n const code = await runPlan(issue, undefined, numbering);\n process.exit(code);\n});\n\n// ── execute ─────────────────────────────────────────────────────────────────\nwithWebOptions(\n withGlobalOptions(\n program\n .command('execute')\n .description('Run the iterative story execution loop (issue-flow engine)')\n .option('--issue <number>', 'Issue number — reads artifacts from issues/N/')\n .option('--max-iterations <number>', 'Stop after N iterations', parseInteger)\n .option(\n '--retry-limit <number>',\n 'Retry transient Claude failures up to N consecutive times',\n parseInteger,\n )\n .option('--retry-forever', 'Retry transient Claude failures indefinitely')\n .argument(\n '[max-iterations]',\n 'Backward-compatible alias for --max-iterations N',\n parseInteger,\n ),\n ),\n).action(\n async (\n positionalMaxIter: number | undefined,\n options: {\n issue?: string;\n maxIterations?: number;\n retryLimit?: number;\n retryForever?: boolean;\n },\n ) => {\n try {\n const { runExecute } = await import('./commands/execute.js');\n const code = await runExecute(positionalMaxIter, options);\n process.exit(code);\n } catch (error) {\n printError(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n },\n);\n\n// ── review ──────────────────────────────────────────────────────────────────\nwithIssueOptions(\n withGlobalOptions(\n program\n .command('review')\n .description('Validate an issue resolution via Claude Code Headless')\n .argument('<issue>', 'Issue number'),\n ),\n).action(async (issue: string) => {\n const { runReview } = await import('./commands/review.js');\n const code = await runReview(issue);\n process.exit(code);\n});\n\n// ── pr ──────────────────────────────────────────────────────────────────────\nwithIssueOptions(\n withGlobalOptions(\n program\n .command('pr')\n .description('Create a pull request via Claude Code Headless')\n .argument('<issue>', 'Issue number'),\n ),\n).action(async (issue: string) => {\n const { runPr } = await import('./commands/pr.js');\n const code = await runPr(issue);\n process.exit(code);\n});\n\n// ── web ─────────────────────────────────────────────────────────────────────\nconst webCommand = program.command('web').description('Manage the web monitoring server');\n\nwebCommand\n .command('serve')\n .description(\n 'Run the web monitor server in the foreground (internal — spawned detached by --web)',\n )\n .option('--port <n>', 'Web server port (default: 3737)', parseInteger)\n .option('--host <h>', 'Web server host (default: 0.0.0.0)')\n .option('--refresh <s>', 'Suggested UI polling interval in seconds', parseInteger)\n .action(async (options: { port?: number; host?: string; refresh?: number }) => {\n const { runWebServe } = await import('./commands/web.js');\n const code = await runWebServe(options);\n // On success this process stays alive for as long as the server is bound\n // (server.ts binds it with unref: false) — only a failure exits here.\n if (code !== 0) {\n process.exit(code);\n }\n });\n\nwebCommand\n .command('stop')\n .description('Stop the running web monitor server')\n .action(async () => {\n const { runWebStop } = await import('./commands/web.js');\n const code = await runWebStop();\n process.exit(code);\n });\n\n// ── policy ──────────────────────────────────────────────────────────────\nwithGlobalOptions(\n program\n .command('policy')\n .description('Inspect the policies discovered in this repository and their provenance')\n .option('--scope <dir>', 'Resolve the policy for a subdirectory (monorepo)')\n .option('--json', 'Emit the resolved policy as JSON'),\n).action(async (options: { scope?: string; json?: boolean }) => {\n const { runPolicy } = await import('./commands/policy.js');\n const code = await runPolicy(options);\n process.exit(code);\n});\n\n// ── pr-review ───────────────────────────────────────────────────────────────\nwithGlobalOptions(\n program\n .command('pr-review')\n .description('Review a Pull Request as a whole via Claude Code Headless')\n .argument('[pr]', 'Pull Request number (discovered from the session when omitted)')\n .option('--issue <n>', 'Issue the Pull Request belongs to')\n .option('--round <n>', 'Rewrite a specific review round instead of appending a new one')\n .option('--yes', 'Skip the confirmation of the discovered Pull Request')\n .option(\n '--fail-on <level>',\n 'Verdict that fails the command: request-changes | suggestions | none',\n ),\n).action(\n async (\n pr: string | undefined,\n options: { issue?: string; round?: string; yes?: boolean; failOn?: string },\n ) => {\n const { runPrReview } = await import('./commands/pr-review.js');\n const code = await runPrReview(pr, options);\n process.exit(code);\n },\n);\n\nprogram.parse();\n","/**\n * Pure mappings from parsed CLI options to command arguments.\n *\n * They live outside cli.ts because that module runs `program.parse()` on\n * import, so anything defined there is untestable.\n */\n\n/** Shape commander produces for a negated boolean option (`--no-branch`). */\nexport interface BranchFlagOptions {\n branch?: boolean;\n}\n\n/**\n * Translate commander's `--no-branch` into the tri-state `runPipeline` expects.\n *\n * Commander stores a negated option under its positive name: `--no-branch`\n * yields `{ branch: false }` and never a `noBranch` key. Reading `noBranch`\n * silently dropped the flag, so the pipeline always created a branch and opened\n * a PR.\n *\n * `undefined` (flag absent) is preserved on purpose: `runPipeline` uses it to\n * tell \"the user said nothing, keep the mode persisted in tasks.json\" apart\n * from an explicit choice.\n */\nexport function resolveNoBranch(options: BranchFlagOptions): boolean | undefined {\n return options.branch === false ? true : undefined;\n}\n\n/** Invalid flag combination on a command, reported as a CLI error. */\nexport class CliFlagError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CliFlagError';\n }\n}\n\n/** Options `run` accepts that select which phases the pipeline executes. */\nexport interface RunPhaseFlagOptions extends BranchFlagOptions {\n prReview?: boolean;\n}\n\n/** Phase selection `runPipeline` expects, both entries tri-state. */\nexport interface RunPhaseFlags {\n noBranch: boolean | undefined;\n prReview: boolean | undefined;\n}\n\n/** Scope flags of `run`, deciding what a discovered hierarchy does. */\nexport interface QueueScopeFlagOptions {\n yes?: boolean;\n only?: boolean;\n}\n\n/** Resolved scope answer; both absent means \"ask, when the terminal allows it\". */\nexport interface QueueScopeFlags {\n yes: boolean | undefined;\n only: boolean | undefined;\n}\n\n/**\n * Resolve `--yes` / `--only`, rejecting the combination that has no meaning.\n *\n * They answer the same question in opposite ways — run everything that was\n * discovered, or run only what was asked for — so passing both is a mistake\n * worth naming rather than silently resolving by precedence.\n *\n * @throws CliFlagError when both are present.\n */\nexport function resolveQueueScopeFlags(options: QueueScopeFlagOptions): QueueScopeFlags {\n if (options.yes === true && options.only === true) {\n throw new CliFlagError(\n '--yes cannot be combined with --only: --yes runs the whole discovered hierarchy, ' +\n '--only runs just the issues you informed.',\n );\n }\n\n return {\n yes: options.yes === true ? true : undefined,\n only: options.only === true ? true : undefined,\n };\n}\n\n/**\n * Resolve the phase-selection flags of `run`, rejecting the one combination\n * that cannot work.\n *\n * `--no-branch` skips the `pr` phase, so there is no Pull Request for\n * `--pr-review` to review. Failing here — before any phase runs — beats\n * discovering it at the end of a full pipeline.\n *\n * Both values stay `undefined` when the user passed nothing: `runPipeline`\n * uses that to tell \"no opinion, keep what tasks.json persisted\" apart from an\n * explicit choice.\n *\n * @throws CliFlagError when `--pr-review` is combined with `--no-branch`.\n */\nexport function resolveRunPhaseFlags(options: RunPhaseFlagOptions): RunPhaseFlags {\n const noBranch = resolveNoBranch(options);\n const prReview = options.prReview === true ? true : undefined;\n\n if (prReview === true && noBranch === true) {\n throw new CliFlagError(\n '--pr-review cannot be combined with --no-branch: --no-branch skips the pr phase, ' +\n 'so there is no Pull Request to review.',\n );\n }\n\n return { noBranch, prReview };\n}\n\n/** Options `run` and `plan` accept to override User Story numbering (issue #36). */\nexport interface UserStoryNumberingFlagOptions {\n continue?: boolean;\n startUs?: number;\n}\n\n/** Resolved User Story numbering override, ready for `determineUserStoryNumbering()`. */\nexport interface UserStoryNumberingFlags {\n continueFlag: boolean;\n startUs: number | undefined;\n}\n\n/**\n * Resolve the `--continue` / `--start-us <n>` override of the User Story\n * numbering cascade (issue #36), rejecting the one combination that cannot\n * work: the two disagree about whether history should be consulted at all.\n *\n * @throws CliFlagError when both flags are passed together.\n */\nexport function resolveUserStoryNumberingFlags(\n options: UserStoryNumberingFlagOptions,\n): UserStoryNumberingFlags {\n const continueFlag = options.continue === true;\n const startUs = options.startUs;\n\n if (continueFlag && startUs !== undefined) {\n throw new CliFlagError(\n '--continue and --start-us cannot be combined: choose either the last known numbering ' +\n '(--continue) or an explicit override (--start-us).',\n );\n }\n\n return { continueFlag, startUs };\n}\n","import type { IssueGenerateTarget, IssuesConfig } from './types.js';\n\n/**\n * Mapping from the Issue provider CLI flags to configuration overrides.\n *\n * Kept out of cli.ts (which runs `program.parse()` on import) so the\n * precedence rules stay unit-testable. Only the keys the user actually passed\n * are returned: a key present with `undefined` would override .issue-flow.json\n * when the layers are merged.\n */\n\nexport interface IssueCliFlags {\n local?: boolean;\n github?: boolean;\n preferLocal?: boolean;\n preferGithub?: boolean;\n ask?: boolean;\n}\n\n/** Invalid flag combination, reported to the user as a CLI error. */\nexport class IssueFlagError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'IssueFlagError';\n }\n}\n\n/**\n * Translate the parsed options of a command into `IssuesConfig` overrides.\n *\n * @throws IssueFlagError when mutually exclusive flags are combined.\n */\nexport function resolveIssuesOverrides(opts: IssueCliFlags): Partial<IssuesConfig> {\n const overrides: Partial<IssuesConfig> = {};\n\n if (opts.local === true && opts.github === true) {\n throw new IssueFlagError('--local and --github are mutually exclusive; pass only one.');\n }\n if (opts.local === true) {\n overrides.preferredProvider = 'local';\n }\n if (opts.github === true) {\n overrides.preferredProvider = 'github';\n }\n\n const conflictFlags = [\n opts.preferLocal === true ? '--prefer-local' : null,\n opts.preferGithub === true ? '--prefer-github' : null,\n opts.ask === true ? '--ask' : null,\n ].filter((flag): flag is string => flag !== null);\n\n if (conflictFlags.length > 1) {\n throw new IssueFlagError(\n `${conflictFlags.join(', ')} are mutually exclusive; pass only one conflict policy.`,\n );\n }\n if (opts.preferLocal === true) {\n overrides.conflictPolicy = 'prefer-local';\n }\n if (opts.preferGithub === true) {\n overrides.conflictPolicy = 'prefer-github';\n }\n if (opts.ask === true) {\n overrides.conflictPolicy = 'ask';\n }\n\n return overrides;\n}\n\n/** Destination flags accepted by `generate`. */\nexport interface GenerateTargetFlags {\n github?: boolean;\n local?: boolean;\n both?: boolean;\n}\n\n/**\n * Destination the generated Issue is created in, or `undefined` when the user\n * passed no flag (the caller then falls back to `defaultGenerateTarget`).\n *\n * @throws IssueFlagError when more than one destination is requested.\n */\nexport function resolveGenerateTarget(opts: GenerateTargetFlags): IssueGenerateTarget | undefined {\n const selected: IssueGenerateTarget[] = [];\n if (opts.github === true) selected.push('github');\n if (opts.local === true) selected.push('local');\n if (opts.both === true) selected.push('both');\n\n if (selected.length > 1) {\n throw new IssueFlagError(\n `${selected.map((target) => `--${target}`).join(', ')} are mutually exclusive; ` +\n 'pass only one destination.',\n );\n }\n\n return selected[0];\n}\n"],"mappings":"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","names":["require"]}
@@ -17,8 +17,8 @@ import {
17
17
  setPolicyCliOverrides,
18
18
  setWebCliOverrides,
19
19
  validateDependencies
20
- } from "./chunk-VYFKOUUR.js";
21
- import "./chunk-V5OHFSW4.js";
20
+ } from "./chunk-VQ5VN7DF.js";
21
+ import "./chunk-HC2MT7BX.js";
22
22
  export {
23
23
  DEFAULTS,
24
24
  GLOBAL_CONFIG_FILENAME,
@@ -38,4 +38,4 @@ export {
38
38
  setWebCliOverrides,
39
39
  validateDependencies
40
40
  };
41
- //# sourceMappingURL=config-YCF3HIKR.js.map
41
+ //# sourceMappingURL=config-4THHOXNN.js.map
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ runExecute
4
+ } from "./chunk-6N7LZZ5U.js";
5
+ import "./chunk-LVKQ2AKT.js";
6
+ import "./chunk-HDV3YDTG.js";
7
+ import "./chunk-OBLVLIUS.js";
8
+ import "./chunk-HQYXVIH6.js";
9
+ import "./chunk-47VIN33V.js";
10
+ import "./chunk-VQ5VN7DF.js";
11
+ import "./chunk-HC2MT7BX.js";
12
+ export {
13
+ runExecute
14
+ };
15
+ //# sourceMappingURL=execute-5OEKLM5X.js.map
@@ -1,29 +1,39 @@
1
1
  #!/usr/bin/env node
2
+ import "./chunk-3D4A4B46.js";
2
3
  import {
3
4
  ensureProvidersRegistered,
4
5
  getProvider,
5
6
  localIssueRef
6
- } from "./chunk-S67Q4I2O.js";
7
+ } from "./chunk-AAY6KM7N.js";
7
8
  import {
9
+ DEFAULT_HEADLESS_TIMEOUT_MS,
8
10
  runHeadless
9
- } from "./chunk-MXTGCD5C.js";
11
+ } from "./chunk-EWDJENFW.js";
10
12
  import {
11
- publishPhaseMetrics
12
- } from "./chunk-PPLIXZI5.js";
13
+ publishPhaseMetrics,
14
+ resolvePolicyPlaceholders
15
+ } from "./chunk-OBLVLIUS.js";
13
16
  import {
14
17
  applyPlaceholders,
15
18
  loadPrompt
16
- } from "./chunk-SLHZPB3C.js";
19
+ } from "./chunk-HQYXVIH6.js";
20
+ import {
21
+ loadRepositoryPolicy
22
+ } from "./chunk-47VIN33V.js";
17
23
  import {
18
24
  loadIssuesConfig,
19
- resolveProjectPaths
20
- } from "./chunk-VYFKOUUR.js";
25
+ loadPolicyConfig,
26
+ resolveProjectPaths,
27
+ run
28
+ } from "./chunk-VQ5VN7DF.js";
21
29
  import {
22
30
  getGlobalTimeout,
23
31
  isoNow,
24
32
  printError,
25
- printSuccess
26
- } from "./chunk-V5OHFSW4.js";
33
+ printInfo,
34
+ printSuccess,
35
+ printWarning
36
+ } from "./chunk-HC2MT7BX.js";
27
37
 
28
38
  // src/issues/draft.ts
29
39
  var DRAFT_TAG = "issue-draft";
@@ -62,7 +72,51 @@ function parseIssueDraft(output) {
62
72
  if (body.length === 0) {
63
73
  throw new IssueDraftParseError(`The <${DRAFT_TAG}> block has no <body>.`);
64
74
  }
65
- return { title, body, labels: parseLabels(extractTag(block, "labels")) };
75
+ const type = (extractTag(block, "type") ?? "").trim();
76
+ const template = (extractTag(block, "template") ?? "").trim();
77
+ return {
78
+ title,
79
+ body,
80
+ labels: parseLabels(extractTag(block, "labels")),
81
+ ...type === "" || type.toLowerCase() === "(none)" ? {} : { type },
82
+ ...template === "" || template.toLowerCase() === "(none)" ? {} : { template }
83
+ };
84
+ }
85
+
86
+ // src/issues/label-policy.ts
87
+ function reconcileLabels(suggested, known) {
88
+ if (known.length === 0) {
89
+ return { labels: [...suggested], missing: [] };
90
+ }
91
+ const canonical = new Map(known.map((label) => [label.name.toLowerCase(), label.name]));
92
+ const labels = [];
93
+ const missing = [];
94
+ for (const suggestion of suggested) {
95
+ const match = canonical.get(suggestion.trim().toLowerCase());
96
+ if (match === void 0) {
97
+ if (!missing.includes(suggestion)) missing.push(suggestion);
98
+ continue;
99
+ }
100
+ if (!labels.includes(match)) labels.push(match);
101
+ }
102
+ return { labels, missing };
103
+ }
104
+ async function createMissingLabels(names, warn) {
105
+ const created = [];
106
+ for (const name of names) {
107
+ const result = await run("gh", ["label", "create", name]);
108
+ if (result.exitCode === 0) {
109
+ created.push(name);
110
+ continue;
111
+ }
112
+ const detail = (result.stderr || result.stdout).trim();
113
+ if (/already exists/i.test(detail)) {
114
+ created.push(name);
115
+ continue;
116
+ }
117
+ warn(`Could not create label "${name}": ${detail || "gh label create failed"}`);
118
+ }
119
+ return created;
66
120
  }
67
121
 
68
122
  // src/commands/generate.ts
@@ -73,6 +127,9 @@ async function draftIssue(promptText) {
73
127
  const { issuesDir } = await resolveProjectPaths();
74
128
  const template = await loadPrompt("generate");
75
129
  const prompt = applyPlaceholders(template, {
130
+ // The repository's own conventions. Empty when it declares none, which is
131
+ // what keeps the rendered prompt identical to the pre-policy one.
132
+ ...await resolvePolicyPlaceholders(),
76
133
  __USER_PROMPT__: promptText,
77
134
  __LOCAL_ISSUES_DIR__: issuesDir
78
135
  });
@@ -80,7 +137,7 @@ async function draftIssue(promptText) {
80
137
  const result = await runHeadless({
81
138
  prompt,
82
139
  maxTurns: 15,
83
- timeout: getGlobalTimeout() ?? 3e5,
140
+ timeout: getGlobalTimeout() ?? DEFAULT_HEADLESS_TIMEOUT_MS,
84
141
  // json (not text) so the CLI reports usage: the envelope's `result` field
85
142
  // carries the same assistant text parseIssueDraft() already consumed.
86
143
  outputFormat: "json",
@@ -123,6 +180,30 @@ async function createIssues(target, draft) {
123
180
  }
124
181
  return [await getProvider(target).create(draft)];
125
182
  }
183
+ async function applyLabelPolicy(draft) {
184
+ let known;
185
+ let allowCreation;
186
+ try {
187
+ const policy = await loadRepositoryPolicy();
188
+ known = policy.issues.labels;
189
+ const config = await loadPolicyConfig({ projectRoot: policy.root });
190
+ allowCreation = config.issues.allowLabelCreation ?? false;
191
+ } catch {
192
+ return draft;
193
+ }
194
+ const { labels, missing } = reconcileLabels(draft.labels, known);
195
+ if (missing.length === 0) {
196
+ return { ...draft, labels };
197
+ }
198
+ if (!allowCreation) {
199
+ printWarning(
200
+ `Dropping ${missing.length} label(s) this repository does not have: ${missing.join(", ")}. Issue Flow does not create labels; set policy.issues.allowLabelCreation to change that.`
201
+ );
202
+ return { ...draft, labels };
203
+ }
204
+ const created = await createMissingLabels(missing, printWarning);
205
+ return { ...draft, labels: [...labels, ...created] };
206
+ }
126
207
  async function runGenerate(promptText, target) {
127
208
  const config = await loadIssuesConfig();
128
209
  const destination = target ?? config.defaultGenerateTarget;
@@ -138,9 +219,16 @@ async function runGenerate(promptText, target) {
138
219
  }
139
220
  return 1;
140
221
  }
222
+ const finalDraft = await applyLabelPolicy(draft);
223
+ if (finalDraft.template !== void 0) {
224
+ printInfo(`Following the repository's Issue Template: ${finalDraft.template}`);
225
+ }
226
+ if (finalDraft.type !== void 0) {
227
+ printInfo(`Issue Type: ${finalDraft.type}`);
228
+ }
141
229
  let created;
142
230
  try {
143
- created = await createIssues(destination, draft);
231
+ created = await createIssues(destination, finalDraft);
144
232
  } catch (err) {
145
233
  printError(err instanceof Error ? err.message : String(err));
146
234
  return 1;
@@ -153,4 +241,4 @@ async function runGenerate(promptText, target) {
153
241
  export {
154
242
  runGenerate
155
243
  };
156
- //# sourceMappingURL=generate-TW6QKSW5.js.map
244
+ //# sourceMappingURL=generate-TBVTLMOP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/issues/draft.ts","../src/issues/label-policy.ts","../src/commands/generate.ts"],"sourcesContent":["import type { IssueDraft } from './types.js';\n\n/**\n * Structured Issue draft emitted by the `generate` prompt.\n *\n * The agent no longer creates the Issue itself: it returns the content and the\n * providers persist it, so the same draft can reach GitHub, the local files, or\n * both. Capturing the result therefore has to be exact — the old approach of\n * fishing an issue URL out of free-form prose only ever worked for GitHub.\n *\n * The block mirrors the `<issue-body>` convention already used by the phase\n * templates, which keeps a multi-line markdown body readable and free of the\n * escaping a JSON payload would demand.\n */\n\n/** Wrapper the agent must emit around the draft. */\nexport const DRAFT_TAG = 'issue-draft';\n\n/** Failure to capture a draft from the agent output. */\nexport class IssueDraftParseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'IssueDraftParseError';\n }\n}\n\n/**\n * Last occurrence of `<tag>...</tag>` in `source`, or `null`.\n *\n * The last one wins: an agent that shows the format before filling it in (or\n * restates the draft after a correction) would otherwise have its first,\n * throwaway attempt captured. The closing tag is searched from the end for the\n * same reason a body may legitimately quote one.\n */\nfunction extractTag(source: string, tag: string): string | null {\n const open = `<${tag}>`;\n const close = `</${tag}>`;\n\n const start = source.lastIndexOf(open);\n if (start === -1) return null;\n\n const end = source.lastIndexOf(close);\n if (end === -1 || end < start) return null;\n\n return source.slice(start + open.length, end);\n}\n\nfunction parseLabels(raw: string | null): string[] {\n if (raw === null) return [];\n return raw\n .split(',')\n .map((label) => label.trim())\n .filter((label) => label.length > 0 && label.toLowerCase() !== '(none)');\n}\n\n/**\n * Read the draft the agent produced.\n *\n * @throws IssueDraftParseError when the block is absent or has no usable\n * title/body, so a malformed answer fails loudly instead of creating an empty\n * Issue.\n */\nexport function parseIssueDraft(output: string): IssueDraft {\n const normalized = output.replace(/\\r\\n?/g, '\\n');\n const block = extractTag(normalized, DRAFT_TAG);\n\n if (block === null) {\n throw new IssueDraftParseError(\n `The agent did not emit an <${DRAFT_TAG}> block, so there is no Issue to create. ` +\n `Output was: ${normalized.trim().slice(0, 300) || '(empty)'}`,\n );\n }\n\n const title = (extractTag(block, 'title') ?? '').trim();\n const body = (extractTag(block, 'body') ?? '').trim();\n\n if (title.length === 0) {\n throw new IssueDraftParseError(`The <${DRAFT_TAG}> block has no <title>.`);\n }\n if (body.length === 0) {\n throw new IssueDraftParseError(`The <${DRAFT_TAG}> block has no <body>.`);\n }\n\n // Optional, and deliberately so: a repository with no Issue Types and no\n // templates emits neither, and the draft is exactly what it was before.\n const type = (extractTag(block, 'type') ?? '').trim();\n const template = (extractTag(block, 'template') ?? '').trim();\n\n return {\n title,\n body,\n labels: parseLabels(extractTag(block, 'labels')),\n ...(type === '' || type.toLowerCase() === '(none)' ? {} : { type }),\n ...(template === '' || template.toLowerCase() === '(none)' ? {} : { template }),\n };\n}\n","import type { LabelDefinition } from '../policy/types.js';\nimport { run } from '../utils/shell.js';\n\n/**\n * Reconciling the labels an agent suggested with the ones the repository\n * actually has.\n *\n * A workflow tool has no business changing a repository's taxonomy. Labels are\n * governance: a team that deleted `high`/`medium`/`low` in favour of a native\n * priority field, or `bug`/`enhancement` in favour of Issue Types, made a\n * decision — and a generator that silently recreates them undoes it, quietly and\n * repository-wide.\n *\n * So the default is to **validate, never create**. `policy.issues.allowLabelCreation`\n * restores the old behaviour for repositories that want it.\n */\n\nexport interface LabelReconciliation {\n /** Labels to apply, in the repository's own casing. */\n labels: string[];\n /** Suggested labels the repository does not have. */\n missing: string[];\n}\n\n/**\n * Intersect the suggested labels with the repository's real ones.\n *\n * Matching is case-insensitive and the result carries the **repository's**\n * casing: `gh issue create --label Bug` fails on a repository whose label is\n * `bug`, and an agent has no way to know which one it is.\n *\n * An empty `known` means the labels could not be read at all — no policy, no\n * `gh`, no network. That is not evidence the labels do not exist, so the\n * suggestions pass through untouched and the behaviour is the one that shipped\n * before this layer. Refusing to label an issue because discovery was offline\n * would be the wrong failure.\n */\nexport function reconcileLabels(\n suggested: string[],\n known: LabelDefinition[],\n): LabelReconciliation {\n if (known.length === 0) {\n return { labels: [...suggested], missing: [] };\n }\n\n const canonical = new Map(known.map((label) => [label.name.toLowerCase(), label.name]));\n\n const labels: string[] = [];\n const missing: string[] = [];\n for (const suggestion of suggested) {\n const match = canonical.get(suggestion.trim().toLowerCase());\n if (match === undefined) {\n if (!missing.includes(suggestion)) missing.push(suggestion);\n continue;\n }\n if (!labels.includes(match)) labels.push(match);\n }\n\n return { labels, missing };\n}\n\n/**\n * Create the labels the repository is missing, for\n * `policy.issues.allowLabelCreation: true`.\n *\n * Best-effort per label: one that cannot be created is reported and skipped, so\n * a single failure does not cost the Issue. Returns the labels that now exist.\n */\nexport async function createMissingLabels(\n names: string[],\n warn: (message: string) => void,\n): Promise<string[]> {\n const created: string[] = [];\n\n for (const name of names) {\n const result = await run('gh', ['label', 'create', name]);\n if (result.exitCode === 0) {\n created.push(name);\n continue;\n }\n // gh answers \"already exists\" when a label was created between the\n // discovery and now, which is a success for our purposes.\n const detail = (result.stderr || result.stdout).trim();\n if (/already exists/i.test(detail)) {\n created.push(name);\n continue;\n }\n warn(`Could not create label \"${name}\": ${detail || 'gh label create failed'}`);\n }\n\n return created;\n}\n","import { loadIssuesConfig, loadPolicyConfig } from '../config.js';\nimport { DEFAULT_HEADLESS_TIMEOUT_MS, runHeadless } from '../core/headless.js';\nimport { applyPlaceholders, loadPrompt } from '../core/prompt-resolver.js';\nimport { publishPhaseMetrics } from '../core/session-metrics.js';\nimport { isoNow } from '../core/state-manager.js';\nimport { getGlobalTimeout } from '../core/verbose.js';\nimport { ensureProvidersRegistered } from '../issues/bootstrap.js';\nimport { localIssueRef } from '../issues/context.js';\nimport { IssueDraftParseError, parseIssueDraft } from '../issues/draft.js';\nimport { createMissingLabels, reconcileLabels } from '../issues/label-policy.js';\nimport { getProvider } from '../issues/registry.js';\nimport type { Issue, IssueDraft, IssueGenerateTarget } from '../issues/types.js';\nimport { loadRepositoryPolicy } from '../policy/index.js';\nimport { resolvePolicyPlaceholders } from '../policy/placeholders.js';\nimport { resolveProjectPaths } from '../storage/resolve.js';\nimport { printError, printInfo, printSuccess, printWarning } from '../ui/logger.js';\n\n/** Human-readable pointer to a created Issue. */\nfunction issueLocation(issue: Issue): string {\n return issue.remoteRef ?? localIssueRef(issue.id);\n}\n\n/**\n * Ask the agent for the Issue content.\n *\n * The agent only drafts: creation belongs to the providers, so the same draft\n * can be persisted to GitHub, to the local files, or to both.\n */\nasync function draftIssue(promptText: string): Promise<IssueDraft> {\n // The duplicate check reads the local issues, which live in the global\n // storage: the path has to be handed over (and allowed) explicitly, since it\n // is outside the working directory the agent is started in.\n const { issuesDir } = await resolveProjectPaths();\n\n const template = await loadPrompt('generate');\n const prompt = applyPlaceholders(template, {\n // The repository's own conventions. Empty when it declares none, which is\n // what keeps the rendered prompt identical to the pre-policy one.\n ...(await resolvePolicyPlaceholders()),\n __USER_PROMPT__: promptText,\n __LOCAL_ISSUES_DIR__: issuesDir,\n });\n\n const startedAtMs = Date.now();\n const result = await runHeadless({\n prompt,\n maxTurns: 15,\n timeout: getGlobalTimeout() ?? DEFAULT_HEADLESS_TIMEOUT_MS,\n // json (not text) so the CLI reports usage: the envelope's `result` field\n // carries the same assistant text parseIssueDraft() already consumed.\n outputFormat: 'json',\n allowedTools: ['Bash', 'Read', 'Glob', 'Grep'],\n addDirs: [issuesDir],\n statusMessage: 'Drafting issue...',\n });\n // Before the success check: the tokens were spent either way.\n publishPhaseMetrics('generate', result.cost, startedAtMs);\n\n if (!result.success) {\n throw new Error(`Issue creation failed: ${result.error}`);\n }\n\n return parseIssueDraft(result.result);\n}\n\n/**\n * Create the GitHub Issue and mirror it locally.\n *\n * The remote comes first on purpose: it owns the identifier, and the mirror has\n * to reuse it so both copies describe one demand. A remote failure therefore\n * leaves nothing behind, and a mirror failure is reported with the remote\n * reference that already exists.\n */\nasync function createBoth(draft: IssueDraft): Promise<Issue[]> {\n const remote = await getProvider('github').create(draft);\n\n try {\n const mirror = await getProvider('local').create({\n ...draft,\n id: remote.id,\n ...(remote.remoteRef\n ? {\n remote: {\n provider: 'github' as const,\n ref: remote.remoteRef,\n syncedAt: isoNow(),\n syncedContentHash: remote.contentHash,\n },\n }\n : {}),\n });\n return [remote, mirror];\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(\n `GitHub issue created at ${issueLocation(remote)}, but the local mirror was not written: ` +\n `${message}. Nothing else was persisted; re-run with --local to create the mirror.`,\n );\n }\n}\n\nasync function createIssues(target: IssueGenerateTarget, draft: IssueDraft): Promise<Issue[]> {\n if (target === 'both') {\n return createBoth(draft);\n }\n return [await getProvider(target).create(draft)];\n}\n\n/**\n * Reconcile the draft's labels with the ones the repository really has.\n *\n * Two failures are being prevented here, and only one of them is cosmetic.\n * GitHub rejects an issue whose label does not exist, so an invented label costs\n * the whole Issue. And a tool that creates the label instead rewrites a taxonomy\n * the team may have curated deliberately — which is worse, because it succeeds.\n *\n * Never throws: a policy that could not be resolved leaves the draft untouched.\n */\nasync function applyLabelPolicy(draft: IssueDraft): Promise<IssueDraft> {\n let known: Awaited<ReturnType<typeof loadRepositoryPolicy>>['issues']['labels'];\n let allowCreation: boolean;\n try {\n const policy = await loadRepositoryPolicy();\n known = policy.issues.labels;\n const config = await loadPolicyConfig({ projectRoot: policy.root });\n allowCreation = config.issues.allowLabelCreation ?? false;\n } catch {\n return draft;\n }\n\n const { labels, missing } = reconcileLabels(draft.labels, known);\n if (missing.length === 0) {\n return { ...draft, labels };\n }\n\n if (!allowCreation) {\n printWarning(\n `Dropping ${missing.length} label(s) this repository does not have: ${missing.join(', ')}. ` +\n 'Issue Flow does not create labels; set policy.issues.allowLabelCreation to change that.',\n );\n return { ...draft, labels };\n }\n\n const created = await createMissingLabels(missing, printWarning);\n return { ...draft, labels: [...labels, ...created] };\n}\n\nexport async function runGenerate(\n promptText: string,\n target?: IssueGenerateTarget,\n): Promise<number> {\n const config = await loadIssuesConfig();\n const destination = target ?? config.defaultGenerateTarget;\n\n ensureProvidersRegistered();\n\n let draft: IssueDraft;\n try {\n draft = await draftIssue(promptText);\n } catch (err) {\n if (err instanceof IssueDraftParseError) {\n printError(`Could not read the generated Issue draft: ${err.message}`);\n } else {\n printError(err instanceof Error ? err.message : String(err));\n }\n return 1;\n }\n\n const finalDraft = await applyLabelPolicy(draft);\n if (finalDraft.template !== undefined) {\n printInfo(`Following the repository's Issue Template: ${finalDraft.template}`);\n }\n if (finalDraft.type !== undefined) {\n printInfo(`Issue Type: ${finalDraft.type}`);\n }\n\n let created: Issue[];\n try {\n created = await createIssues(destination, finalDraft);\n } catch (err) {\n printError(err instanceof Error ? err.message : String(err));\n return 1;\n }\n\n for (const issue of created) {\n printSuccess(`Issue created (${issue.source}): ${issueLocation(issue)}`);\n }\n return 0;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ runInit
4
+ } from "./chunk-RKTEV6EG.js";
5
+ import "./chunk-HC2MT7BX.js";
6
+ export {
7
+ runInit
8
+ };
9
+ //# sourceMappingURL=init-PRMOTQ7N.js.map
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ runPlan
4
+ } from "./chunk-EY6WMHV2.js";
5
+ import "./chunk-3BOHTH4V.js";
6
+ import "./chunk-AAY6KM7N.js";
7
+ import "./chunk-EWDJENFW.js";
8
+ import "./chunk-HDV3YDTG.js";
9
+ import "./chunk-OBLVLIUS.js";
10
+ import "./chunk-HQYXVIH6.js";
11
+ import "./chunk-47VIN33V.js";
12
+ import "./chunk-VQ5VN7DF.js";
13
+ import "./chunk-HC2MT7BX.js";
14
+ export {
15
+ runPlan
16
+ };
17
+ //# sourceMappingURL=plan-Y2BYZD24.js.map