issue-flow 0.6.0 → 0.7.0
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/dist/{analyze-VVG7UABS.js → analyze-WRFFG2R5.js} +10 -6
- package/dist/analyze-WRFFG2R5.js.map +1 -0
- package/dist/{chunk-WZDCTAWZ.js → chunk-2Y3UO7H2.js} +27 -2
- package/dist/chunk-2Y3UO7H2.js.map +1 -0
- package/dist/{chunk-FPGHTTVV.js → chunk-75K5IKAC.js} +12 -7
- package/dist/chunk-75K5IKAC.js.map +1 -0
- package/dist/{chunk-EHX4J5G5.js → chunk-BTBSVBE3.js} +12 -7
- package/dist/chunk-BTBSVBE3.js.map +1 -0
- package/dist/chunk-CW6UE3NW.js +72 -0
- package/dist/chunk-CW6UE3NW.js.map +1 -0
- package/dist/chunk-EWMSQQL2.js +725 -0
- package/dist/chunk-EWMSQQL2.js.map +1 -0
- package/dist/{chunk-SVOWWZQJ.js → chunk-HS4QWZAO.js} +5 -280
- package/dist/chunk-HS4QWZAO.js.map +1 -0
- package/dist/{chunk-2CSHLHYP.js → chunk-JV7P6UGG.js} +2 -2
- package/dist/chunk-KUDAY57D.js +283 -0
- package/dist/chunk-KUDAY57D.js.map +1 -0
- package/dist/{chunk-4HT4EVYV.js → chunk-OVFYJLOH.js} +56 -13
- package/dist/chunk-OVFYJLOH.js.map +1 -0
- package/dist/{chunk-KWGRBNUG.js → chunk-UX6YAVLT.js} +26 -7
- package/dist/chunk-UX6YAVLT.js.map +1 -0
- package/dist/{chunk-YM3G5BLR.js → chunk-VLSZFMLZ.js} +2 -2
- package/dist/{chunk-7W5VGYXW.js → chunk-YXJPKBPV.js} +39 -64
- package/dist/chunk-YXJPKBPV.js.map +1 -0
- package/dist/{chunk-JTSAL3TI.js → chunk-Z3UIGLZG.js} +10 -5
- package/dist/chunk-Z3UIGLZG.js.map +1 -0
- package/dist/cli.js +65 -20
- package/dist/cli.js.map +1 -1
- package/dist/{config-B564P45C.js → config-UHQ6XXX2.js} +5 -3
- package/dist/execute-K5B4UMUT.js +13 -0
- package/dist/{generate-IN62ARBS.js → generate-DUKQCADD.js} +7 -5
- package/dist/{generate-IN62ARBS.js.map → generate-DUKQCADD.js.map} +1 -1
- package/dist/init-W4HBLW7R.js +9 -0
- package/dist/plan-NKPU45NP.js +15 -0
- package/dist/pr-JYGLLIEF.js +15 -0
- package/dist/pr-review-6H6F4XUY.js +15 -0
- package/dist/prd-FC2ZCEOX.js +15 -0
- package/dist/review-X4NGDZZI.js +13 -0
- package/dist/review-X4NGDZZI.js.map +1 -0
- package/dist/{run-GPBICAD6.js → run-VC647DQI.js} +150 -55
- package/dist/run-VC647DQI.js.map +1 -0
- package/package.json +1 -1
- package/prompts/pr-review.md +144 -0
- package/dist/analyze-VVG7UABS.js.map +0 -1
- package/dist/chunk-4HT4EVYV.js.map +0 -1
- package/dist/chunk-7W5VGYXW.js.map +0 -1
- package/dist/chunk-EHX4J5G5.js.map +0 -1
- package/dist/chunk-FPGHTTVV.js.map +0 -1
- package/dist/chunk-JTSAL3TI.js.map +0 -1
- package/dist/chunk-KWGRBNUG.js.map +0 -1
- package/dist/chunk-SVOWWZQJ.js.map +0 -1
- package/dist/chunk-WZDCTAWZ.js.map +0 -1
- package/dist/execute-PNOFNLZG.js +0 -12
- package/dist/init-5242XSYC.js +0 -9
- package/dist/plan-6KLONWPR.js +0 -14
- package/dist/pr-JLJLMFN3.js +0 -14
- package/dist/prd-TVJDYZXH.js +0 -14
- package/dist/review-FRV4ZMS2.js +0 -12
- package/dist/run-GPBICAD6.js.map +0 -1
- /package/dist/{chunk-2CSHLHYP.js.map → chunk-JV7P6UGG.js.map} +0 -0
- /package/dist/{chunk-YM3G5BLR.js.map → chunk-VLSZFMLZ.js.map} +0 -0
- /package/dist/{config-B564P45C.js.map → config-UHQ6XXX2.js.map} +0 -0
- /package/dist/{execute-PNOFNLZG.js.map → execute-K5B4UMUT.js.map} +0 -0
- /package/dist/{init-5242XSYC.js.map → init-W4HBLW7R.js.map} +0 -0
- /package/dist/{plan-6KLONWPR.js.map → plan-NKPU45NP.js.map} +0 -0
- /package/dist/{pr-JLJLMFN3.js.map → pr-JYGLLIEF.js.map} +0 -0
- /package/dist/{prd-TVJDYZXH.js.map → pr-review-6H6F4XUY.js.map} +0 -0
- /package/dist/{review-FRV4ZMS2.js.map → prd-FC2ZCEOX.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/issues/draft.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 return { title, body, labels: parseLabels(extractTag(block, 'labels')) };\n}\n","import { loadIssuesConfig } from '../config.js';\nimport { runHeadless } from '../core/headless.js';\nimport { applyPlaceholders, loadPrompt } from '../core/prompt-resolver.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 { getProvider } from '../issues/registry.js';\nimport type { Issue, IssueDraft, IssueGenerateTarget } from '../issues/types.js';\nimport { printError, printSuccess } 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 const template = await loadPrompt('generate');\n const prompt = applyPlaceholders(template, {\n __USER_PROMPT__: promptText,\n });\n\n const result = await runHeadless({\n prompt,\n maxTurns: 15,\n timeout: getGlobalTimeout() ?? 300_000,\n outputFormat: 'text',\n allowedTools: ['Bash', 'Read', 'Glob', 'Grep'],\n statusMessage: 'Drafting issue...',\n });\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\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 let created: Issue[];\n try {\n created = await createIssues(destination, draft);\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":"
|
|
1
|
+
{"version":3,"sources":["../src/issues/draft.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 return { title, body, labels: parseLabels(extractTag(block, 'labels')) };\n}\n","import { loadIssuesConfig } from '../config.js';\nimport { runHeadless } from '../core/headless.js';\nimport { applyPlaceholders, loadPrompt } from '../core/prompt-resolver.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 { getProvider } from '../issues/registry.js';\nimport type { Issue, IssueDraft, IssueGenerateTarget } from '../issues/types.js';\nimport { printError, printSuccess } 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 const template = await loadPrompt('generate');\n const prompt = applyPlaceholders(template, {\n __USER_PROMPT__: promptText,\n });\n\n const result = await runHeadless({\n prompt,\n maxTurns: 15,\n timeout: getGlobalTimeout() ?? 300_000,\n outputFormat: 'text',\n allowedTools: ['Bash', 'Read', 'Glob', 'Grep'],\n statusMessage: 'Drafting issue...',\n });\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\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 let created: Issue[];\n try {\n created = await createIssues(destination, draft);\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,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
runPlan
|
|
4
|
+
} from "./chunk-75K5IKAC.js";
|
|
5
|
+
import "./chunk-JV7P6UGG.js";
|
|
6
|
+
import "./chunk-HS4QWZAO.js";
|
|
7
|
+
import "./chunk-HDV3YDTG.js";
|
|
8
|
+
import "./chunk-KUDAY57D.js";
|
|
9
|
+
import "./chunk-SLHZPB3C.js";
|
|
10
|
+
import "./chunk-OVFYJLOH.js";
|
|
11
|
+
import "./chunk-2Y3UO7H2.js";
|
|
12
|
+
export {
|
|
13
|
+
runPlan
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=plan-NKPU45NP.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
runPr
|
|
4
|
+
} from "./chunk-UX6YAVLT.js";
|
|
5
|
+
import "./chunk-JV7P6UGG.js";
|
|
6
|
+
import "./chunk-HS4QWZAO.js";
|
|
7
|
+
import "./chunk-HDV3YDTG.js";
|
|
8
|
+
import "./chunk-KUDAY57D.js";
|
|
9
|
+
import "./chunk-SLHZPB3C.js";
|
|
10
|
+
import "./chunk-OVFYJLOH.js";
|
|
11
|
+
import "./chunk-2Y3UO7H2.js";
|
|
12
|
+
export {
|
|
13
|
+
runPr
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=pr-JYGLLIEF.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
exitCodeFor,
|
|
4
|
+
runPrReview
|
|
5
|
+
} from "./chunk-EWMSQQL2.js";
|
|
6
|
+
import "./chunk-CW6UE3NW.js";
|
|
7
|
+
import "./chunk-KUDAY57D.js";
|
|
8
|
+
import "./chunk-SLHZPB3C.js";
|
|
9
|
+
import "./chunk-OVFYJLOH.js";
|
|
10
|
+
import "./chunk-2Y3UO7H2.js";
|
|
11
|
+
export {
|
|
12
|
+
exitCodeFor,
|
|
13
|
+
runPrReview
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=pr-review-6H6F4XUY.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
runPrd
|
|
4
|
+
} from "./chunk-BTBSVBE3.js";
|
|
5
|
+
import "./chunk-JV7P6UGG.js";
|
|
6
|
+
import "./chunk-HS4QWZAO.js";
|
|
7
|
+
import "./chunk-HDV3YDTG.js";
|
|
8
|
+
import "./chunk-KUDAY57D.js";
|
|
9
|
+
import "./chunk-SLHZPB3C.js";
|
|
10
|
+
import "./chunk-OVFYJLOH.js";
|
|
11
|
+
import "./chunk-2Y3UO7H2.js";
|
|
12
|
+
export {
|
|
13
|
+
runPrd
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=prd-FC2ZCEOX.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
runReview
|
|
4
|
+
} from "./chunk-Z3UIGLZG.js";
|
|
5
|
+
import "./chunk-HS4QWZAO.js";
|
|
6
|
+
import "./chunk-KUDAY57D.js";
|
|
7
|
+
import "./chunk-SLHZPB3C.js";
|
|
8
|
+
import "./chunk-OVFYJLOH.js";
|
|
9
|
+
import "./chunk-2Y3UO7H2.js";
|
|
10
|
+
export {
|
|
11
|
+
runReview
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=review-X4NGDZZI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,52 +1,62 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
runPrd
|
|
4
|
+
} from "./chunk-BTBSVBE3.js";
|
|
2
5
|
import {
|
|
3
6
|
runReview
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-Z3UIGLZG.js";
|
|
5
8
|
import {
|
|
6
9
|
runInit
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-VLSZFMLZ.js";
|
|
8
11
|
import {
|
|
9
|
-
|
|
12
|
+
printRunSummary,
|
|
10
13
|
runExecute
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-YXJPKBPV.js";
|
|
12
15
|
import {
|
|
13
16
|
runPlan
|
|
14
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-75K5IKAC.js";
|
|
15
18
|
import {
|
|
16
19
|
runPr
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import
|
|
19
|
-
runPrd
|
|
20
|
-
} from "./chunk-EHX4J5G5.js";
|
|
21
|
-
import "./chunk-2CSHLHYP.js";
|
|
20
|
+
} from "./chunk-UX6YAVLT.js";
|
|
21
|
+
import "./chunk-JV7P6UGG.js";
|
|
22
22
|
import {
|
|
23
23
|
getProvider,
|
|
24
24
|
resolveCommandIssue
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-HS4QWZAO.js";
|
|
26
26
|
import "./chunk-HDV3YDTG.js";
|
|
27
|
+
import {
|
|
28
|
+
mostRecent,
|
|
29
|
+
prReviewDir,
|
|
30
|
+
readPrReviewIndex,
|
|
31
|
+
runPrReview
|
|
32
|
+
} from "./chunk-EWMSQQL2.js";
|
|
33
|
+
import {
|
|
34
|
+
listPullRequests,
|
|
35
|
+
publishGitState
|
|
36
|
+
} from "./chunk-CW6UE3NW.js";
|
|
37
|
+
import "./chunk-KUDAY57D.js";
|
|
27
38
|
import {
|
|
28
39
|
resolvePackageDir
|
|
29
40
|
} from "./chunk-SLHZPB3C.js";
|
|
30
41
|
import {
|
|
42
|
+
getIssueDir,
|
|
31
43
|
loadIssuesConfig,
|
|
32
44
|
loadWebConfig
|
|
33
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-OVFYJLOH.js";
|
|
34
46
|
import {
|
|
35
47
|
FilePublisher,
|
|
36
48
|
NullPublisher,
|
|
37
|
-
formatDuration,
|
|
38
49
|
isVerbose,
|
|
39
50
|
isoNow,
|
|
40
51
|
loadTaskPlan,
|
|
41
52
|
printError,
|
|
42
53
|
printInfo,
|
|
43
|
-
printSuccess,
|
|
44
54
|
printWarning,
|
|
45
55
|
saveTaskPlan,
|
|
46
56
|
setOutputCallback,
|
|
47
57
|
setSessionPublisher,
|
|
48
58
|
setStoryUpdateCallback
|
|
49
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-2Y3UO7H2.js";
|
|
50
60
|
|
|
51
61
|
// src/commands/run.ts
|
|
52
62
|
import { randomUUID } from "crypto";
|
|
@@ -55,6 +65,7 @@ import { execa } from "execa";
|
|
|
55
65
|
|
|
56
66
|
// src/core/pipeline.ts
|
|
57
67
|
var PIPELINE_PHASES = ["init", "prd", "plan", "execute", "review", "pr"];
|
|
68
|
+
var PIPELINE_PHASES_WITH_PR_REVIEW = [...PIPELINE_PHASES, "pr-review"];
|
|
58
69
|
var PIPELINE_PHASES_NO_BRANCH = PIPELINE_PHASES.filter(
|
|
59
70
|
(p) => p !== "pr"
|
|
60
71
|
);
|
|
@@ -64,7 +75,8 @@ var PHASE_TO_FIELD = {
|
|
|
64
75
|
plan: "jsonCompleted",
|
|
65
76
|
execute: "executionCompleted",
|
|
66
77
|
review: "reviewCompleted",
|
|
67
|
-
pr: "prCreated"
|
|
78
|
+
pr: "prCreated",
|
|
79
|
+
"pr-review": "prReviewCompleted"
|
|
68
80
|
};
|
|
69
81
|
var PipelineManager = class {
|
|
70
82
|
tasksJsonPath;
|
|
@@ -151,8 +163,12 @@ var PHASE_LABELS = {
|
|
|
151
163
|
plan: "Plan",
|
|
152
164
|
execute: "Execute",
|
|
153
165
|
review: "Review",
|
|
154
|
-
pr: "PR"
|
|
166
|
+
pr: "PR",
|
|
167
|
+
"pr-review": "PR Review"
|
|
155
168
|
};
|
|
169
|
+
function phaseLabel(phase) {
|
|
170
|
+
return PHASE_LABELS[phase] ?? phase.charAt(0).toUpperCase() + phase.slice(1);
|
|
171
|
+
}
|
|
156
172
|
function selectRenderer(verbose) {
|
|
157
173
|
const isTTY = !!process.stdout.isTTY;
|
|
158
174
|
const isCI = !!process.env.CI;
|
|
@@ -231,7 +247,7 @@ function buildExecutePhaseTask(runner, tasksPath, verbose) {
|
|
|
231
247
|
};
|
|
232
248
|
return task.newListr([engineSubtask, ...subtaskDefs], {
|
|
233
249
|
concurrent: true,
|
|
234
|
-
exitOnError:
|
|
250
|
+
exitOnError: true,
|
|
235
251
|
rendererOptions: {
|
|
236
252
|
timer: PRESET_TIMER,
|
|
237
253
|
collapseSkips: false
|
|
@@ -247,7 +263,7 @@ async function runPipelineWithRenderer(options) {
|
|
|
247
263
|
const isSimple = renderer === "simple";
|
|
248
264
|
const tasks = new Listr(
|
|
249
265
|
phases.map((phase, index) => {
|
|
250
|
-
const label =
|
|
266
|
+
const label = phaseLabel(phase);
|
|
251
267
|
const isExecutePhase = phase === "execute" && tasksPath;
|
|
252
268
|
return {
|
|
253
269
|
title: label,
|
|
@@ -489,9 +505,32 @@ function toIssueNumber(id) {
|
|
|
489
505
|
}
|
|
490
506
|
var RUNNABLE_PHASES = ["prd", "plan", "execute", "review", "pr"];
|
|
491
507
|
var RUNNABLE_PHASES_NO_BRANCH = ["prd", "plan", "execute", "review"];
|
|
492
|
-
|
|
508
|
+
var RUNNABLE_PHASES_WITH_PR_REVIEW = [...RUNNABLE_PHASES, "pr-review"];
|
|
509
|
+
async function readPrReviewOutcome(issue, tasksPath, requestedChanges) {
|
|
510
|
+
const outcome = { requestedChanges, recommendation: null, reportPath: null };
|
|
511
|
+
try {
|
|
512
|
+
const plan = await loadTaskPlan(tasksPath);
|
|
513
|
+
outcome.recommendation = plan.prReview?.lastRecommendation ?? null;
|
|
514
|
+
const pullRequest = plan.prReview?.pullRequestNumber;
|
|
515
|
+
if (pullRequest !== void 0) {
|
|
516
|
+
const dir = await prReviewDir({ issue, pullRequest });
|
|
517
|
+
const index = await readPrReviewIndex(dir);
|
|
518
|
+
const last = index?.rounds.reduce(
|
|
519
|
+
(latest, entry) => latest === null || entry.round > latest.round ? entry : latest,
|
|
520
|
+
null
|
|
521
|
+
);
|
|
522
|
+
if (last) {
|
|
523
|
+
outcome.reportPath = join2(dir, last.reportPath);
|
|
524
|
+
outcome.recommendation ??= last.recommendation;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
} catch {
|
|
528
|
+
}
|
|
529
|
+
return outcome;
|
|
530
|
+
}
|
|
531
|
+
async function runPipeline(issue, mode, from, noBranch, prReview) {
|
|
493
532
|
const issueNumber = issue.replace(/^#/, "");
|
|
494
|
-
const issueDir =
|
|
533
|
+
const issueDir = await getIssueDir(issueNumber);
|
|
495
534
|
const webConfig = await loadWebConfig();
|
|
496
535
|
const publisher = webConfig.enabled ? new FilePublisher(join2(issueDir, "session.json"), {
|
|
497
536
|
logLimit: webConfig.logLimit,
|
|
@@ -509,7 +548,15 @@ async function runPipeline(issue, mode, from, noBranch) {
|
|
|
509
548
|
}
|
|
510
549
|
let exitCode = 1;
|
|
511
550
|
try {
|
|
512
|
-
exitCode = await runPipelinePhases(
|
|
551
|
+
exitCode = await runPipelinePhases(
|
|
552
|
+
issueNumber,
|
|
553
|
+
issueDir,
|
|
554
|
+
mode,
|
|
555
|
+
publisher,
|
|
556
|
+
from,
|
|
557
|
+
noBranch,
|
|
558
|
+
prReview
|
|
559
|
+
);
|
|
513
560
|
return exitCode;
|
|
514
561
|
} finally {
|
|
515
562
|
publisher.publish({
|
|
@@ -522,7 +569,7 @@ async function runPipeline(issue, mode, from, noBranch) {
|
|
|
522
569
|
setSessionPublisher(void 0);
|
|
523
570
|
}
|
|
524
571
|
}
|
|
525
|
-
async function runPipelinePhases(issueNumber, issueDir, mode, publisher, from, noBranch) {
|
|
572
|
+
async function runPipelinePhases(issueNumber, issueDir, mode, publisher, from, noBranch, prReview) {
|
|
526
573
|
const tasksPath = join2(issueDir, "tasks.json");
|
|
527
574
|
const sessionId = randomUUID();
|
|
528
575
|
let publishedIssueNumber = toIssueNumber(issueNumber);
|
|
@@ -563,6 +610,7 @@ async function runPipelinePhases(issueNumber, issueDir, mode, publisher, from, n
|
|
|
563
610
|
const resolvedIssue = resolution.resolved;
|
|
564
611
|
publishedIssueNumber = resolvedIssue.issue.number;
|
|
565
612
|
let effectiveNoBranch = noBranch ?? false;
|
|
613
|
+
let effectivePrReview = prReview ?? false;
|
|
566
614
|
let planIssueUrl;
|
|
567
615
|
let planBranch;
|
|
568
616
|
try {
|
|
@@ -570,6 +618,7 @@ async function runPipelinePhases(issueNumber, issueDir, mode, publisher, from, n
|
|
|
570
618
|
const persistedNoBranch = existingPlan.noBranch ?? false;
|
|
571
619
|
planIssueUrl = existingPlan.issueUrl || void 0;
|
|
572
620
|
planBranch = existingPlan.branchName || void 0;
|
|
621
|
+
effectivePrReview = prReview ?? existingPlan.prReview?.enabled ?? false;
|
|
573
622
|
if (noBranch !== void 0 && noBranch !== persistedNoBranch) {
|
|
574
623
|
if (persistedNoBranch) {
|
|
575
624
|
printWarning(
|
|
@@ -584,8 +633,24 @@ async function runPipelinePhases(issueNumber, issueDir, mode, publisher, from, n
|
|
|
584
633
|
effectiveNoBranch = persistedNoBranch;
|
|
585
634
|
} catch {
|
|
586
635
|
}
|
|
587
|
-
|
|
588
|
-
|
|
636
|
+
if (effectiveNoBranch && effectivePrReview) {
|
|
637
|
+
printWarning(
|
|
638
|
+
"This pipeline runs with --no-branch and opens no PR. Skipping the pr-review phase."
|
|
639
|
+
);
|
|
640
|
+
effectivePrReview = false;
|
|
641
|
+
}
|
|
642
|
+
if (effectivePrReview) {
|
|
643
|
+
try {
|
|
644
|
+
const plan = await loadTaskPlan(tasksPath);
|
|
645
|
+
if (plan.prReview?.enabled !== true) {
|
|
646
|
+
plan.prReview = { ...plan.prReview, enabled: true, rounds: plan.prReview?.rounds ?? 0 };
|
|
647
|
+
await saveTaskPlan(tasksPath, plan);
|
|
648
|
+
}
|
|
649
|
+
} catch {
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
const activePhases = effectiveNoBranch ? PIPELINE_PHASES_NO_BRANCH : effectivePrReview ? PIPELINE_PHASES_WITH_PR_REVIEW : PIPELINE_PHASES;
|
|
653
|
+
const phaseOrder = effectiveNoBranch ? RUNNABLE_PHASES_NO_BRANCH : effectivePrReview ? RUNNABLE_PHASES_WITH_PR_REVIEW : RUNNABLE_PHASES;
|
|
589
654
|
publishSessionStart(activePhases, sessionStartedAt, {
|
|
590
655
|
issueUrl: planIssueUrl ?? resolvedIssue.issue.remoteRef ?? void 0,
|
|
591
656
|
branch: planBranch
|
|
@@ -645,10 +710,15 @@ async function runPipelinePhases(issueNumber, issueDir, mode, publisher, from, n
|
|
|
645
710
|
prd: makeRunner(() => runPrd(issueNumber, resolvedIssue), "prd"),
|
|
646
711
|
plan: async () => {
|
|
647
712
|
await makeRunner(() => runPlan(issueNumber, resolvedIssue), "plan")();
|
|
648
|
-
if (effectiveNoBranch) {
|
|
713
|
+
if (effectiveNoBranch || effectivePrReview) {
|
|
649
714
|
try {
|
|
650
715
|
const plan = await loadTaskPlan(tasksPath);
|
|
651
|
-
|
|
716
|
+
if (effectiveNoBranch) {
|
|
717
|
+
plan.noBranch = true;
|
|
718
|
+
}
|
|
719
|
+
if (effectivePrReview) {
|
|
720
|
+
plan.prReview = { ...plan.prReview, enabled: true, rounds: plan.prReview?.rounds ?? 0 };
|
|
721
|
+
}
|
|
652
722
|
await saveTaskPlan(tasksPath, plan);
|
|
653
723
|
} catch {
|
|
654
724
|
}
|
|
@@ -686,6 +756,16 @@ async function runPipelinePhases(issueNumber, issueDir, mode, publisher, from, n
|
|
|
686
756
|
},
|
|
687
757
|
pr: makeRunner(() => runPr(issueNumber, resolvedIssue), "pr")
|
|
688
758
|
};
|
|
759
|
+
const reviewBox = { outcome: null };
|
|
760
|
+
if (effectivePrReview) {
|
|
761
|
+
runners["pr-review"] = async () => {
|
|
762
|
+
const code = await runPrReview(void 0, { issue: issueNumber, yes: true });
|
|
763
|
+
if (code === 1) {
|
|
764
|
+
throw new Error("Phase pr-review failed with exit code 1");
|
|
765
|
+
}
|
|
766
|
+
reviewBox.outcome = await readPrReviewOutcome(issueNumber, tasksPath, code === 2);
|
|
767
|
+
};
|
|
768
|
+
}
|
|
689
769
|
const instrumentedRunners = Object.fromEntries(
|
|
690
770
|
Object.entries(runners).map(([phase, fn]) => [
|
|
691
771
|
phase,
|
|
@@ -720,28 +800,25 @@ async function runPipelinePhases(issueNumber, issueDir, mode, publisher, from, n
|
|
|
720
800
|
printError(`Phase ${result.failedPhase} failed`);
|
|
721
801
|
return 1;
|
|
722
802
|
}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
803
|
+
const review = reviewBox.outcome;
|
|
804
|
+
if (review?.requestedChanges) {
|
|
805
|
+
console.log("");
|
|
806
|
+
printWarning("PR review requested changes \u2014 the Pull Request is not ready to merge.");
|
|
807
|
+
if (review.reportPath !== null) {
|
|
808
|
+
console.log(` Report: ${review.reportPath}`);
|
|
728
809
|
}
|
|
729
|
-
} catch {
|
|
730
|
-
printWarning("Failed to close issue automatically");
|
|
731
810
|
}
|
|
732
|
-
|
|
733
|
-
|
|
811
|
+
if (review?.requestedChanges) {
|
|
812
|
+
printInfo("Issue left open until the review blockers are addressed.");
|
|
813
|
+
} else {
|
|
734
814
|
try {
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
);
|
|
740
|
-
const parsed = JSON.parse(proc.stdout?.toString() ?? "[]");
|
|
741
|
-
if (parsed[0]?.url) {
|
|
742
|
-
prUrl = parsed[0].url;
|
|
815
|
+
const provider = getProvider(resolvedIssue.source);
|
|
816
|
+
if (provider.close !== void 0) {
|
|
817
|
+
printInfo("Closing issue...");
|
|
818
|
+
await provider.close(issueNumber);
|
|
743
819
|
}
|
|
744
820
|
} catch {
|
|
821
|
+
printWarning("Failed to close issue automatically");
|
|
745
822
|
}
|
|
746
823
|
}
|
|
747
824
|
let branchName = "unknown";
|
|
@@ -751,27 +828,45 @@ async function runPipelinePhases(issueNumber, issueDir, mode, publisher, from, n
|
|
|
751
828
|
} catch {
|
|
752
829
|
}
|
|
753
830
|
let storyCount = 0;
|
|
831
|
+
let planPrUrl = null;
|
|
754
832
|
try {
|
|
755
833
|
const plan = await loadTaskPlan(tasksPath);
|
|
756
834
|
storyCount = plan.userStories.length;
|
|
757
|
-
plan.
|
|
758
|
-
plan.completedAt = isoNow();
|
|
835
|
+
planPrUrl = plan.pullRequest?.url ?? null;
|
|
759
836
|
plan.lastAttemptAt = isoNow();
|
|
837
|
+
if (!review?.requestedChanges) {
|
|
838
|
+
plan.issueStatus = "completed";
|
|
839
|
+
plan.completedAt = isoNow();
|
|
840
|
+
}
|
|
760
841
|
await saveTaskPlan(tasksPath, plan);
|
|
761
842
|
} catch {
|
|
762
843
|
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
844
|
+
let prUrl = "unknown";
|
|
845
|
+
if (!effectiveNoBranch && resolvedIssue.source === "github") {
|
|
846
|
+
if (planPrUrl !== null) {
|
|
847
|
+
prUrl = planPrUrl;
|
|
848
|
+
} else if (branchName !== "unknown" && branchName !== "") {
|
|
849
|
+
try {
|
|
850
|
+
const latest = mostRecent(await listPullRequests(branchName));
|
|
851
|
+
if (latest !== null) {
|
|
852
|
+
prUrl = latest.url;
|
|
853
|
+
}
|
|
854
|
+
} catch {
|
|
855
|
+
}
|
|
856
|
+
}
|
|
771
857
|
}
|
|
858
|
+
printRunSummary({
|
|
859
|
+
issueNumber,
|
|
860
|
+
branchName,
|
|
861
|
+
noBranch: effectiveNoBranch,
|
|
862
|
+
storyCount,
|
|
863
|
+
elapsedSeconds: result.overallElapsedSeconds,
|
|
864
|
+
prUrl,
|
|
865
|
+
prReview: review
|
|
866
|
+
});
|
|
772
867
|
return 0;
|
|
773
868
|
}
|
|
774
869
|
export {
|
|
775
870
|
runPipeline
|
|
776
871
|
};
|
|
777
|
-
//# sourceMappingURL=run-
|
|
872
|
+
//# sourceMappingURL=run-VC647DQI.js.map
|