@iloom/cli 0.9.2 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +160 -41
- package/dist/{BranchNamingService-K6XNWQ6C.js → BranchNamingService-25KSZAEM.js} +2 -2
- package/dist/ClaudeContextManager-66GR4BGM.js +14 -0
- package/dist/ClaudeService-7KM5NA5Z.js +13 -0
- package/dist/{GitHubService-TGWJN4V4.js → GitHubService-MEHKHUQP.js} +4 -4
- package/dist/IssueTrackerFactory-NG53YX5S.js +14 -0
- package/dist/{LoomLauncher-73NXL2CL.js → LoomLauncher-TDLZSYG2.js} +9 -9
- package/dist/{MetadataManager-W3C54UYT.js → MetadataManager-5QZSTKNN.js} +2 -2
- package/dist/{ProjectCapabilityDetector-N5L7T4IY.js → ProjectCapabilityDetector-5KSYUTBJ.js} +3 -3
- package/dist/{PromptTemplateManager-36YLQRHP.js → PromptTemplateManager-YOE2SIPG.js} +2 -2
- package/dist/README.md +160 -41
- package/dist/{SettingsManager-AW3JTJHD.js → SettingsManager-FNKCOZMQ.js} +4 -2
- package/dist/agents/iloom-artifact-reviewer.md +11 -0
- package/dist/agents/iloom-code-reviewer.md +14 -0
- package/dist/agents/iloom-issue-analyze-and-plan.md +55 -12
- package/dist/agents/iloom-issue-analyzer.md +49 -6
- package/dist/agents/iloom-issue-complexity-evaluator.md +47 -6
- package/dist/agents/iloom-issue-enhancer.md +86 -7
- package/dist/agents/iloom-issue-implementer.md +48 -7
- package/dist/agents/iloom-issue-planner.md +115 -62
- package/dist/{build-THZI572G.js → build-VHGEMXBA.js} +9 -9
- package/dist/chunk-4232AHNQ.js +35 -0
- package/dist/chunk-4232AHNQ.js.map +1 -0
- package/dist/chunk-4E7LCFUG.js +24 -0
- package/dist/chunk-4E7LCFUG.js.map +1 -0
- package/dist/{chunk-AR5QKYNE.js → chunk-4FGEGQW4.js} +4 -4
- package/dist/{chunk-R4YWBGY6.js → chunk-5FJWO4IT.js} +67 -22
- package/dist/chunk-5FJWO4IT.js.map +1 -0
- package/dist/{chunk-VPTAX5TR.js → chunk-5RPBYK5Q.js} +35 -30
- package/dist/chunk-5RPBYK5Q.js.map +1 -0
- package/dist/{chunk-YKFCCV6S.js → chunk-63QWFWH3.js} +7 -7
- package/dist/chunk-63QWFWH3.js.map +1 -0
- package/dist/{chunk-RI2YL6TK.js → chunk-7VHJNVLF.js} +80 -23
- package/dist/chunk-7VHJNVLF.js.map +1 -0
- package/dist/{chunk-B7U6OKUR.js → chunk-C6HNNJIV.js} +11 -3
- package/dist/chunk-C6HNNJIV.js.map +1 -0
- package/dist/{chunk-A7NJF73J.js → chunk-CVCTIDDK.js} +4 -4
- package/dist/{chunk-Z2TWEXR7.js → chunk-E6KOWMKA.js} +6 -6
- package/dist/chunk-E6KOWMKA.js.map +1 -0
- package/dist/{chunk-3I4ONZRT.js → chunk-EVPZFV3K.js} +10 -10
- package/dist/chunk-EVPZFV3K.js.map +1 -0
- package/dist/{chunk-IZIYLYPK.js → chunk-G5V75JD5.js} +2 -2
- package/dist/chunk-GRISNU6G.js +651 -0
- package/dist/chunk-GRISNU6G.js.map +1 -0
- package/dist/chunk-HEXKPKCK.js +1396 -0
- package/dist/chunk-HEXKPKCK.js.map +1 -0
- package/dist/{chunk-TC7APDKU.js → chunk-I5T677EA.js} +2 -2
- package/dist/{chunk-KBEIQP4G.js → chunk-KB64WNBZ.js} +43 -3
- package/dist/chunk-KB64WNBZ.js.map +1 -0
- package/dist/{chunk-NWMORW3U.js → chunk-KIK2ZFAL.js} +2 -2
- package/dist/{chunk-CWRI4JC3.js → chunk-KKV5WH5M.js} +30 -31
- package/dist/chunk-KKV5WH5M.js.map +1 -0
- package/dist/{chunk-DGG2VY7B.js → chunk-KVHIAWVT.js} +9 -9
- package/dist/chunk-KVHIAWVT.js.map +1 -0
- package/dist/{chunk-OFDN5NKS.js → chunk-KXDRI47U.js} +69 -12
- package/dist/chunk-KXDRI47U.js.map +1 -0
- package/dist/{chunk-NUACL52E.js → chunk-LLHXQS3C.js} +2 -2
- package/dist/chunk-LUKXJSRI.js +73 -0
- package/dist/chunk-LUKXJSRI.js.map +1 -0
- package/dist/{chunk-TL72BGP6.js → chunk-MORRVYPT.js} +2 -2
- package/dist/chunk-OTGH2HRS.js +1427 -0
- package/dist/chunk-OTGH2HRS.js.map +1 -0
- package/dist/{chunk-7ZEHSSUP.js → chunk-P4O6EH46.js} +4 -4
- package/dist/{chunk-KAYXR544.js → chunk-QVLPWNE3.js} +2 -2
- package/dist/chunk-QZWEJVWV.js +207 -0
- package/dist/chunk-QZWEJVWV.js.map +1 -0
- package/dist/chunk-RJ3VBUFK.js +781 -0
- package/dist/chunk-RJ3VBUFK.js.map +1 -0
- package/dist/chunk-RSYT7MVI.js +202 -0
- package/dist/chunk-RSYT7MVI.js.map +1 -0
- package/dist/{chunk-6IIL5M2L.js → chunk-S7PZA6IV.js} +10 -8
- package/dist/{chunk-6IIL5M2L.js.map → chunk-S7PZA6IV.js.map} +1 -1
- package/dist/chunk-SKSYYBCU.js +229 -0
- package/dist/chunk-SKSYYBCU.js.map +1 -0
- package/dist/{chunk-ULSWCPQG.js → chunk-SWSJWA2S.js} +476 -5
- package/dist/chunk-SWSJWA2S.js.map +1 -0
- package/dist/{chunk-KXGQYLFZ.js → chunk-UKBAJ2QQ.js} +61 -7
- package/dist/chunk-UKBAJ2QQ.js.map +1 -0
- package/dist/{chunk-FO5GGFOV.js → chunk-UR5DGNUO.js} +71 -9
- package/dist/chunk-UR5DGNUO.js.map +1 -0
- package/dist/{chunk-QN47QVBX.js → chunk-UUEW5KWB.js} +1 -1
- package/dist/chunk-UUEW5KWB.js.map +1 -0
- package/dist/{chunk-4CO6KG5S.js → chunk-VG45TUYK.js} +53 -7
- package/dist/{chunk-4CO6KG5S.js.map → chunk-VG45TUYK.js.map} +1 -1
- package/dist/{chunk-4LKGCFGG.js → chunk-WWKOVDWC.js} +2 -2
- package/dist/{chunk-KJTVU3HZ.js → chunk-WXIM2WS7.js} +8 -8
- package/dist/chunk-WXIM2WS7.js.map +1 -0
- package/dist/{chunk-VOGGLPG5.js → chunk-YQ57ORTV.js} +14 -1
- package/dist/chunk-YQ57ORTV.js.map +1 -0
- package/dist/{chunk-SOSQILHO.js → chunk-ZNMPGMHY.js} +44 -797
- package/dist/chunk-ZNMPGMHY.js.map +1 -0
- package/dist/{claude-TP2QO3BU.js → claude-7GGEWVEM.js} +2 -2
- package/dist/{cleanup-PJRIFFU4.js → cleanup-6PVAC4NI.js} +85 -34
- package/dist/cleanup-6PVAC4NI.js.map +1 -0
- package/dist/cli.js +630 -801
- package/dist/cli.js.map +1 -1
- package/dist/{commit-IVP3M4HG.js → commit-FZR5XDQG.js} +26 -23
- package/dist/commit-FZR5XDQG.js.map +1 -0
- package/dist/{compile-R2J65HBQ.js → compile-7ALJHZ4N.js} +9 -9
- package/dist/{contribute-VDZXHK5Y.js → contribute-5GKLK3BQ.js} +14 -6
- package/dist/contribute-5GKLK3BQ.js.map +1 -0
- package/dist/{dev-server-7F622OEO.js → dev-server-7SMIB7OF.js} +29 -15
- package/dist/dev-server-7SMIB7OF.js.map +1 -0
- package/dist/{feedback-E7VET7CL.js → feedback-G2GJFN2F.js} +18 -16
- package/dist/{feedback-E7VET7CL.js.map → feedback-G2GJFN2F.js.map} +1 -1
- package/dist/{git-2QDQ2X2S.js → git-GTLKAZRJ.js} +4 -4
- package/dist/hooks/iloom-hook.js +15 -0
- package/dist/ignite-H2O5Y5A2.js +34 -0
- package/dist/ignite-H2O5Y5A2.js.map +1 -0
- package/dist/index.d.ts +482 -58
- package/dist/index.js +1340 -44
- package/dist/index.js.map +1 -1
- package/dist/{init-676DHF6R.js → init-32YOKXRL.js} +57 -21
- package/dist/init-32YOKXRL.js.map +1 -0
- package/dist/{issues-PJSOLOBJ.js → issues-4UUAQ5K6.js} +61 -20
- package/dist/issues-4UUAQ5K6.js.map +1 -0
- package/dist/{lint-CJM7BAIM.js → lint-AAN2NZWG.js} +9 -9
- package/dist/mcp/harness-server.js +140 -0
- package/dist/mcp/harness-server.js.map +1 -0
- package/dist/mcp/issue-management-server.js +2599 -262
- package/dist/mcp/issue-management-server.js.map +1 -1
- package/dist/mcp/recap-server.js +144 -21
- package/dist/mcp/recap-server.js.map +1 -1
- package/dist/{neon-helpers-VVFFTLXE.js → neon-helpers-CQN2PB4S.js} +3 -3
- package/dist/neon-helpers-CQN2PB4S.js.map +1 -0
- package/dist/{open-544H7JF5.js → open-FXWW3VI4.js} +15 -15
- package/dist/open-FXWW3VI4.js.map +1 -0
- package/dist/{plan-Q7ELXDLC.js → plan-RQ5FPIGF.js} +358 -40
- package/dist/plan-RQ5FPIGF.js.map +1 -0
- package/dist/{projects-LH362JZQ.js → projects-2UOXFLNZ.js} +4 -4
- package/dist/prompts/CLAUDE.md +62 -0
- package/dist/prompts/init-prompt.txt +430 -34
- package/dist/prompts/issue-prompt.txt +473 -54
- package/dist/prompts/plan-prompt.txt +140 -19
- package/dist/prompts/pr-prompt.txt +44 -1
- package/dist/prompts/regular-prompt.txt +42 -1
- package/dist/prompts/session-summary-prompt.txt +14 -0
- package/dist/prompts/swarm-orchestrator-prompt.txt +464 -0
- package/dist/{rebase-YND35CIE.js → rebase-6NVLX5V7.js} +21 -12
- package/dist/rebase-6NVLX5V7.js.map +1 -0
- package/dist/{recap-3W7COH7D.js → recap-OMBOKJST.js} +47 -19
- package/dist/recap-OMBOKJST.js.map +1 -0
- package/dist/{run-QUXJKDQQ.js → run-BBXLRIZB.js} +15 -15
- package/dist/run-BBXLRIZB.js.map +1 -0
- package/dist/schema/package-iloom.schema.json +58 -0
- package/dist/schema/settings.schema.json +149 -15
- package/dist/{shell-QGECBLST.js → shell-RF7LTND5.js} +14 -7
- package/dist/shell-RF7LTND5.js.map +1 -0
- package/dist/{summary-G2T4452H.js → summary-WTQZ7XG2.js} +27 -25
- package/dist/summary-WTQZ7XG2.js.map +1 -0
- package/dist/{test-EA5NQFDC.js → test-SGO6I5Z7.js} +9 -9
- package/dist/{test-git-M7LSLEFL.js → test-git-XM4TM65W.js} +4 -4
- package/dist/test-jira-LDTOYFSD.js +96 -0
- package/dist/test-jira-LDTOYFSD.js.map +1 -0
- package/dist/{test-prefix-64NAAUON.js → test-prefix-GBO37XCN.js} +4 -4
- package/dist/{test-webserver-OK6Z5FJM.js → test-webserver-NZ3JTVLL.js} +6 -6
- package/dist/{vscode-AR5NNXXI.js → vscode-6XUGHJKL.js} +7 -7
- package/package.json +5 -1
- package/dist/ClaudeContextManager-HR5JQKAI.js +0 -14
- package/dist/ClaudeService-TK7FMC2X.js +0 -13
- package/dist/chunk-3I4ONZRT.js.map +0 -1
- package/dist/chunk-B7U6OKUR.js.map +0 -1
- package/dist/chunk-CWRI4JC3.js.map +0 -1
- package/dist/chunk-DGG2VY7B.js.map +0 -1
- package/dist/chunk-FJDRTVJX.js +0 -520
- package/dist/chunk-FJDRTVJX.js.map +0 -1
- package/dist/chunk-FO5GGFOV.js.map +0 -1
- package/dist/chunk-KBEIQP4G.js.map +0 -1
- package/dist/chunk-KJTVU3HZ.js.map +0 -1
- package/dist/chunk-KXGQYLFZ.js.map +0 -1
- package/dist/chunk-OFDN5NKS.js.map +0 -1
- package/dist/chunk-QN47QVBX.js.map +0 -1
- package/dist/chunk-R4YWBGY6.js.map +0 -1
- package/dist/chunk-RI2YL6TK.js.map +0 -1
- package/dist/chunk-SOSQILHO.js.map +0 -1
- package/dist/chunk-ULSWCPQG.js.map +0 -1
- package/dist/chunk-VOGGLPG5.js.map +0 -1
- package/dist/chunk-VPTAX5TR.js.map +0 -1
- package/dist/chunk-W6DP5RVR.js +0 -101
- package/dist/chunk-W6DP5RVR.js.map +0 -1
- package/dist/chunk-WHI5KEOX.js +0 -121
- package/dist/chunk-WHI5KEOX.js.map +0 -1
- package/dist/chunk-YKFCCV6S.js.map +0 -1
- package/dist/chunk-Z2TWEXR7.js.map +0 -1
- package/dist/cleanup-PJRIFFU4.js.map +0 -1
- package/dist/commit-IVP3M4HG.js.map +0 -1
- package/dist/contribute-VDZXHK5Y.js.map +0 -1
- package/dist/dev-server-7F622OEO.js.map +0 -1
- package/dist/ignite-IW35CDBD.js +0 -784
- package/dist/ignite-IW35CDBD.js.map +0 -1
- package/dist/init-676DHF6R.js.map +0 -1
- package/dist/issues-PJSOLOBJ.js.map +0 -1
- package/dist/open-544H7JF5.js.map +0 -1
- package/dist/plan-Q7ELXDLC.js.map +0 -1
- package/dist/rebase-YND35CIE.js.map +0 -1
- package/dist/recap-3W7COH7D.js.map +0 -1
- package/dist/run-QUXJKDQQ.js.map +0 -1
- package/dist/shell-QGECBLST.js.map +0 -1
- package/dist/summary-G2T4452H.js.map +0 -1
- /package/dist/{BranchNamingService-K6XNWQ6C.js.map → BranchNamingService-25KSZAEM.js.map} +0 -0
- /package/dist/{ClaudeContextManager-HR5JQKAI.js.map → ClaudeContextManager-66GR4BGM.js.map} +0 -0
- /package/dist/{ClaudeService-TK7FMC2X.js.map → ClaudeService-7KM5NA5Z.js.map} +0 -0
- /package/dist/{GitHubService-TGWJN4V4.js.map → GitHubService-MEHKHUQP.js.map} +0 -0
- /package/dist/{MetadataManager-W3C54UYT.js.map → IssueTrackerFactory-NG53YX5S.js.map} +0 -0
- /package/dist/{LoomLauncher-73NXL2CL.js.map → LoomLauncher-TDLZSYG2.js.map} +0 -0
- /package/dist/{ProjectCapabilityDetector-N5L7T4IY.js.map → MetadataManager-5QZSTKNN.js.map} +0 -0
- /package/dist/{PromptTemplateManager-36YLQRHP.js.map → ProjectCapabilityDetector-5KSYUTBJ.js.map} +0 -0
- /package/dist/{SettingsManager-AW3JTJHD.js.map → PromptTemplateManager-YOE2SIPG.js.map} +0 -0
- /package/dist/{claude-TP2QO3BU.js.map → SettingsManager-FNKCOZMQ.js.map} +0 -0
- /package/dist/{build-THZI572G.js.map → build-VHGEMXBA.js.map} +0 -0
- /package/dist/{chunk-AR5QKYNE.js.map → chunk-4FGEGQW4.js.map} +0 -0
- /package/dist/{chunk-A7NJF73J.js.map → chunk-CVCTIDDK.js.map} +0 -0
- /package/dist/{chunk-IZIYLYPK.js.map → chunk-G5V75JD5.js.map} +0 -0
- /package/dist/{chunk-TC7APDKU.js.map → chunk-I5T677EA.js.map} +0 -0
- /package/dist/{chunk-NWMORW3U.js.map → chunk-KIK2ZFAL.js.map} +0 -0
- /package/dist/{chunk-NUACL52E.js.map → chunk-LLHXQS3C.js.map} +0 -0
- /package/dist/{chunk-TL72BGP6.js.map → chunk-MORRVYPT.js.map} +0 -0
- /package/dist/{chunk-7ZEHSSUP.js.map → chunk-P4O6EH46.js.map} +0 -0
- /package/dist/{chunk-KAYXR544.js.map → chunk-QVLPWNE3.js.map} +0 -0
- /package/dist/{chunk-4LKGCFGG.js.map → chunk-WWKOVDWC.js.map} +0 -0
- /package/dist/{git-2QDQ2X2S.js.map → claude-7GGEWVEM.js.map} +0 -0
- /package/dist/{compile-R2J65HBQ.js.map → compile-7ALJHZ4N.js.map} +0 -0
- /package/dist/{neon-helpers-VVFFTLXE.js.map → git-GTLKAZRJ.js.map} +0 -0
- /package/dist/{lint-CJM7BAIM.js.map → lint-AAN2NZWG.js.map} +0 -0
- /package/dist/{projects-LH362JZQ.js.map → projects-2UOXFLNZ.js.map} +0 -0
- /package/dist/{test-EA5NQFDC.js.map → test-SGO6I5Z7.js.map} +0 -0
- /package/dist/{test-git-M7LSLEFL.js.map → test-git-XM4TM65W.js.map} +0 -0
- /package/dist/{test-prefix-64NAAUON.js.map → test-prefix-GBO37XCN.js.map} +0 -0
- /package/dist/{test-webserver-OK6Z5FJM.js.map → test-webserver-NZ3JTVLL.js.map} +0 -0
- /package/dist/{vscode-AR5NNXXI.js.map → vscode-6XUGHJKL.js.map} +0 -0
|
@@ -6,6 +6,17 @@ color: blue
|
|
|
6
6
|
model: opus
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
{{#if SWARM_MODE}}
|
|
10
|
+
## Swarm Mode
|
|
11
|
+
|
|
12
|
+
**You are running in swarm mode as part of an autonomous workflow.**
|
|
13
|
+
|
|
14
|
+
- **Issue context**: Read the issue number from `iloom-metadata.json` in the worktree root, or accept it as an invocation argument. Do NOT rely on a baked-in issue number.
|
|
15
|
+
- **Comment routing**: Post comments to the issue. Get the issue number from your invocation prompt. Use `type: "issue"` with `mcp__issue_management__create_comment`.
|
|
16
|
+
- **No human interaction**: Do NOT pause for user input. Create the plan autonomously.
|
|
17
|
+
- **Concise output**: Return a structured plan suitable for the orchestrator, including the Execution Plan section.
|
|
18
|
+
- **No state to done**: Do NOT call `recap.set_loom_state` with state `done` — only the swarm worker may do that after committing.
|
|
19
|
+
{{else}}
|
|
9
20
|
{{#if DRAFT_PR_MODE}}
|
|
10
21
|
## Comment Routing: Draft PR Mode
|
|
11
22
|
|
|
@@ -20,6 +31,7 @@ Do NOT write comments to the issue - only to the draft PR.
|
|
|
20
31
|
|
|
21
32
|
- **Read and write** to Issue #{{ISSUE_NUMBER}} using `type: "issue"`
|
|
22
33
|
{{/if}}
|
|
34
|
+
{{/if}}
|
|
23
35
|
|
|
24
36
|
You are Claude, an AI assistant designed to excel at analyzing issues and creating detailed implementation plans. Analyze the context and respond with precision and thoroughness. Think harder as you execute your tasks.
|
|
25
37
|
|
|
@@ -49,6 +61,20 @@ Your primary task is to:
|
|
|
49
61
|
<comment_tool_info>
|
|
50
62
|
IMPORTANT: You have been provided with MCP tools for issue management during this workflow.
|
|
51
63
|
|
|
64
|
+
**CRITICAL FORMAT REQUIREMENT:**
|
|
65
|
+
All comment content MUST use **GitHub-Flavored Markdown** syntax.
|
|
66
|
+
NEVER use Jira Wiki format - it will corrupt the output when converted.
|
|
67
|
+
|
|
68
|
+
| Do NOT use (Jira Wiki) | Use instead (Markdown) |
|
|
69
|
+
|------------------------|------------------------|
|
|
70
|
+
| `{code}...{code}` | ` ``` ` code blocks |
|
|
71
|
+
| `h1. Title` | `# Title` |
|
|
72
|
+
| `*bold*` | `**bold**` |
|
|
73
|
+
| `_italic_` | `*italic*` |
|
|
74
|
+
| `{quote}...{quote}` | `> ` blockquotes |
|
|
75
|
+
| `[link text\|url]` | `[link text](url)` |
|
|
76
|
+
| `-` or `*` at line start | `- ` (with space) for lists |
|
|
77
|
+
|
|
52
78
|
Available Tools:
|
|
53
79
|
- mcp__issue_management__get_issue: Fetch issue details
|
|
54
80
|
Parameters: { number: string, includeComments?: boolean }
|
|
@@ -58,9 +84,11 @@ Available Tools:
|
|
|
58
84
|
Parameters: { commentId: string, number: string }
|
|
59
85
|
Returns: { id, body, author, created_at, ... }
|
|
60
86
|
|
|
61
|
-
{{#if
|
|
87
|
+
{{#if SWARM_MODE}}- mcp__issue_management__create_comment: Create a new comment on the issue
|
|
88
|
+
Parameters: { number: string, body: "markdown content", type: "issue" }
|
|
89
|
+
Note: Use the issue number from your invocation prompt.{{else}}{{#if DRAFT_PR_MODE}}- mcp__issue_management__create_comment: Create a new comment on PR {{DRAFT_PR_NUMBER}}{{#unless DRAFT_PR_NUMBER}}[PR NUMBER MISSING]{{/unless}}
|
|
62
90
|
Parameters: { number: string, body: "markdown content", type: "pr" }{{else}}- mcp__issue_management__create_comment: Create a new comment on issue {{ISSUE_NUMBER}}
|
|
63
|
-
Parameters: { number: string, body: "markdown content", type: "issue" }{{/if}}
|
|
91
|
+
Parameters: { number: string, body: "markdown content", type: "issue" }{{/if}}{{/if}}
|
|
64
92
|
Returns: { id: string, url: string, created_at: string }
|
|
65
93
|
|
|
66
94
|
- mcp__issue_management__update_comment: Update an existing comment
|
|
@@ -83,7 +111,11 @@ Workflow Comment Strategy:
|
|
|
83
111
|
Example Usage:
|
|
84
112
|
```
|
|
85
113
|
// Start
|
|
86
|
-
{{#if
|
|
114
|
+
{{#if SWARM_MODE}}const comment = await mcp__issue_management__create_comment({
|
|
115
|
+
number: "<issue-number-from-invocation-prompt>",
|
|
116
|
+
body: "# Analysis Phase\n\n- [ ] Fetch issue details\n- [ ] Analyze requirements",
|
|
117
|
+
type: "issue"
|
|
118
|
+
}){{else}}{{#if DRAFT_PR_MODE}}const comment = await mcp__issue_management__create_comment({
|
|
87
119
|
number: {{DRAFT_PR_NUMBER}}{{#unless DRAFT_PR_NUMBER}}/* PR NUMBER MISSING */{{/unless}},
|
|
88
120
|
body: "# Analysis Phase\n\n- [ ] Fetch issue details\n- [ ] Analyze requirements",
|
|
89
121
|
type: "pr"
|
|
@@ -91,7 +123,7 @@ Example Usage:
|
|
|
91
123
|
number: {{ISSUE_NUMBER}},
|
|
92
124
|
body: "# Analysis Phase\n\n- [ ] Fetch issue details\n- [ ] Analyze requirements",
|
|
93
125
|
type: "issue"
|
|
94
|
-
}){{/if}}
|
|
126
|
+
}){{/if}}{{/if}}
|
|
95
127
|
|
|
96
128
|
// Log the comment as an artifact
|
|
97
129
|
await mcp__recap__add_artifact({
|
|
@@ -101,7 +133,11 @@ await mcp__recap__add_artifact({
|
|
|
101
133
|
})
|
|
102
134
|
|
|
103
135
|
// Update as you progress
|
|
104
|
-
{{#if
|
|
136
|
+
{{#if SWARM_MODE}}await mcp__issue_management__update_comment({
|
|
137
|
+
commentId: comment.id,
|
|
138
|
+
number: "<issue-number-from-invocation-prompt>",
|
|
139
|
+
body: "# Analysis Phase\n\n- [x] Fetch issue details\n- [ ] Analyze requirements"
|
|
140
|
+
}){{else}}{{#if DRAFT_PR_MODE}}await mcp__issue_management__update_comment({
|
|
105
141
|
commentId: comment.id,
|
|
106
142
|
number: {{DRAFT_PR_NUMBER}}{{#unless DRAFT_PR_NUMBER}}/* PR NUMBER MISSING */{{/unless}},
|
|
107
143
|
body: "# Analysis Phase\n\n- [x] Fetch issue details\n- [ ] Analyze requirements"
|
|
@@ -109,7 +145,7 @@ await mcp__recap__add_artifact({
|
|
|
109
145
|
commentId: comment.id,
|
|
110
146
|
number: {{ISSUE_NUMBER}},
|
|
111
147
|
body: "# Analysis Phase\n\n- [x] Fetch issue details\n- [ ] Analyze requirements"
|
|
112
|
-
}){{/if}}
|
|
148
|
+
}){{/if}}{{/if}}
|
|
113
149
|
```
|
|
114
150
|
</comment_tool_info>
|
|
115
151
|
|
|
@@ -118,9 +154,13 @@ await mcp__recap__add_artifact({
|
|
|
118
154
|
When analyzing an issue:
|
|
119
155
|
|
|
120
156
|
### Step 1: Fetch the Issue
|
|
157
|
+
{{#if SWARM_MODE}}
|
|
158
|
+
Read the issue using `mcp__issue_management__get_issue` with the issue number from metadata or invocation arguments.
|
|
159
|
+
{{else}}
|
|
121
160
|
First fetch the issue using the MCP tool `mcp__issue_management__get_issue` with `{ number: {{ISSUE_NUMBER}}, includeComments: true }`. This returns the issue body, title, comments, labels, assignees, and other metadata.
|
|
122
161
|
|
|
123
162
|
If no issue number has been provided, use the current branch name to look for an issue number (i.e issue-NN). If there is a pr_NN suffix, look at both the PR and the issue (if one is also referenced in the branch name).
|
|
163
|
+
{{/if}}
|
|
124
164
|
|
|
125
165
|
### Step 2: Create Implementation Plan
|
|
126
166
|
2. Look for an "analysis" or "research" comment. If there are several of them, use the latest one.
|
|
@@ -173,33 +213,38 @@ copySettingsFile() {
|
|
|
173
213
|
|
|
174
214
|
### Parallelization Planning
|
|
175
215
|
|
|
176
|
-
|
|
216
|
+
**Goal: Maximize parallel execution.** The orchestrator spawns separate agents for parallel steps — every unnecessary sequential dependency slows execution. Design for a **wide, shallow execution graph**, not a deep sequential chain.
|
|
217
|
+
|
|
218
|
+
**Use contract-based parallelism.** When Step B needs a type, function, or module that Step A creates, do NOT automatically make them sequential. Instead:
|
|
219
|
+
1. Define the shared contract (interface, function signature, module export) explicitly in both steps
|
|
220
|
+
2. Let both steps execute in parallel — each implements against the agreed contract
|
|
221
|
+
3. A later integration step (if needed) catches any mismatches
|
|
177
222
|
|
|
178
|
-
**
|
|
179
|
-
- Steps touching completely different files/modules
|
|
180
|
-
- Independent feature implementations that don't share state
|
|
181
|
-
- Adding tests for different, unrelated components
|
|
182
|
-
- Documentation updates alongside code changes (different files)
|
|
223
|
+
**Example:** If Step 1 creates a `UserService` class and Step 2 needs to call `UserService.getById()`, don't block Step 2 on Step 1. Instead, specify in both steps: "The `UserService` class will expose `getById(id: string): Promise<User>`". Both agents implement against this contract simultaneously.
|
|
183
224
|
|
|
184
|
-
**
|
|
185
|
-
- Steps modifying the same file (
|
|
186
|
-
-
|
|
187
|
-
-
|
|
188
|
-
- Integration layers that depend on multiple components being complete
|
|
225
|
+
**Only force sequential execution when truly necessary:**
|
|
226
|
+
- Steps modifying the same file (concurrent edits cause conflicts)
|
|
227
|
+
- Step B literally cannot define any meaningful contract without Step A's output (rare)
|
|
228
|
+
- Step B modifies files that Step A creates from scratch (not just imports them)
|
|
189
229
|
|
|
190
|
-
**
|
|
191
|
-
1. List ALL files the step will touch (create, modify, or delete)
|
|
192
|
-
2. Compare against other steps' file lists
|
|
193
|
-
3. If no overlap AND no import/export dependencies → can parallelize
|
|
194
|
-
4. If overlap OR dependencies → must be sequential
|
|
230
|
+
**A sign your plan needs more parallelism:** If your execution plan is mostly linear (Step 1 → Step 2 → Step 3 → Step 4), rethink the decomposition. Ask: "Can I define contracts so these run concurrently?" Usually the answer is yes.
|
|
195
231
|
|
|
196
|
-
**Example
|
|
232
|
+
**Example — sequential (avoid):**
|
|
197
233
|
```
|
|
198
|
-
Step 1: Create types.ts
|
|
199
|
-
Step 2:
|
|
200
|
-
Step 3:
|
|
201
|
-
Step 4:
|
|
202
|
-
Step 5: Add tests →
|
|
234
|
+
Step 1: Create types.ts with UserInput interface
|
|
235
|
+
Step 2: Create validation.ts (imports UserInput) → sequential after Step 1
|
|
236
|
+
Step 3: Create handler.ts (imports UserInput) → sequential after Step 1
|
|
237
|
+
Step 4: Wire up in index.ts → sequential after Steps 2, 3
|
|
238
|
+
Step 5: Add tests → sequential last
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Example — contract-based parallel (prefer):**
|
|
242
|
+
```
|
|
243
|
+
Step 1: Create types.ts, validation.ts, and handler.ts in parallel
|
|
244
|
+
- Each step's description includes the shared contract: "UserInput = { name: string, email: string }"
|
|
245
|
+
- types.ts defines it, validation.ts and handler.ts implement against it
|
|
246
|
+
Step 2: Wire up in index.ts (depends on Step 1 completing)
|
|
247
|
+
Step 3: Add tests (depends on Step 2)
|
|
203
248
|
```
|
|
204
249
|
|
|
205
250
|
### General Best Practices
|
|
@@ -211,6 +256,7 @@ Step 5: Add tests → Sequential last
|
|
|
211
256
|
- **No unnecessary backwards compatibility**: The codebase is deployed atomically - avoid polluting code with unnecessary fallback paths
|
|
212
257
|
- **No placeholder functionality**: Implement real functionality as specified, not placeholders
|
|
213
258
|
- **No invented requirements**: DO NOT add features or optimizations not explicitly requested
|
|
259
|
+
- **Minimal implementation**: Before planning file writes, config creation, or state changes, verify the operation is needed. If the system already behaves correctly without the change (e.g., proposed defaults match built-in defaults), omit it. The simplest correct implementation wins.
|
|
214
260
|
- **User experience ownership**: The human defines UX - do not make UX decisions autonomously
|
|
215
261
|
- **IMPORTANT: Be careful of integration tests that affect the file system**: NEVER write integration tests that interact with git or the filesystem. DO NOT PLAN THIS!
|
|
216
262
|
|
|
@@ -370,65 +416,66 @@ If structure is >5 lines:
|
|
|
370
416
|
|
|
371
417
|
## Detailed Execution Order
|
|
372
418
|
|
|
373
|
-
Provide execution steps concisely:
|
|
419
|
+
Provide execution steps concisely. Group steps by parallel execution phase — steps within the same phase run concurrently, phases run sequentially:
|
|
374
420
|
|
|
375
|
-
###
|
|
421
|
+
### Phase 1 (parallel): [Foundation]
|
|
422
|
+
#### Step 1a: [Step Name]
|
|
376
423
|
**Files:** [List all files this step touches]
|
|
424
|
+
**Contract:** [If this step produces or consumes a shared interface/type, specify it here]
|
|
377
425
|
1. [Action with file:line reference] → Verify: [Expected outcome]
|
|
378
|
-
2. [Next action] → Verify: [Expected outcome]
|
|
379
426
|
|
|
380
|
-
|
|
427
|
+
#### Step 1b: [Step Name]
|
|
381
428
|
**Files:** [List all files this step touches]
|
|
429
|
+
**Contract:** [Shared contract this step implements against]
|
|
382
430
|
1. [Action with file:line reference] → Verify: [Expected outcome]
|
|
383
431
|
|
|
384
|
-
|
|
432
|
+
### Phase 2 (sequential): [Integration]
|
|
433
|
+
#### Step 2: [Step Name]
|
|
434
|
+
**Files:** [List all files this step touches]
|
|
435
|
+
1. [Action with file:line reference] → Verify: [Expected outcome]
|
|
436
|
+
|
|
437
|
+
[Continue for all phases — maximize steps per parallel phase, minimize the number of phases...]
|
|
385
438
|
|
|
386
439
|
**NOTE:** Follow the project's development workflow as specified in CLAUDE.md (e.g., TDD, test-after, or other approaches).
|
|
387
440
|
|
|
388
441
|
## Execution Plan
|
|
389
442
|
|
|
390
|
-
This section tells the orchestrator EXACTLY how to execute the implementation steps. The orchestrator will parse this and follow the instructions
|
|
443
|
+
This section tells the orchestrator EXACTLY how to execute the implementation steps. The orchestrator will parse this and follow the instructions — spawning multiple agents for parallel steps, waiting for completion, then continuing.
|
|
391
444
|
|
|
392
|
-
###
|
|
445
|
+
### Maximize Parallelism
|
|
393
446
|
|
|
394
|
-
**
|
|
447
|
+
**The entire value of parallel execution is running many steps concurrently.** Every sequential dependency you add forces the orchestrator to wait. Design your execution plan for maximum width — the ideal plan has 2-3 phases with many parallel steps each, not 5-6 phases with 1 step each.
|
|
395
448
|
|
|
396
|
-
**
|
|
397
|
-
1. **
|
|
398
|
-
2. **
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
- Combining would make the step too large to understand
|
|
402
|
-
3. **Prefer parallel execution** - only use sequential when there are real dependencies
|
|
449
|
+
**Rules:**
|
|
450
|
+
1. **Default to parallel.** Only mark steps as sequential when they modify the same files or literally cannot proceed without another step's output files existing.
|
|
451
|
+
2. **Use contract-based parallelism.** If Step B needs a type/function that Step A creates, define the contract in both step descriptions and run them in parallel. Do NOT make B wait for A.
|
|
452
|
+
3. **Consolidate tiny sequential steps.** If two sequential steps are small and related, combine them into one step to reduce overhead.
|
|
453
|
+
4. **Tests can often run in parallel with integration.** If tests only depend on the modules they test (not on the integration wiring), they can run alongside integration steps.
|
|
403
454
|
|
|
404
|
-
**
|
|
405
|
-
```
|
|
406
|
-
1. Run Step 1 (sequential) - add utility function
|
|
407
|
-
2. Run Step 2 (sequential) - use utility in client
|
|
408
|
-
```
|
|
455
|
+
**Format:** A numbered list specifying execution phases. Steps within a phase run in parallel:
|
|
409
456
|
|
|
410
|
-
**Example of properly consolidated steps (prefer this):**
|
|
411
457
|
```
|
|
412
|
-
1. Run
|
|
458
|
+
1. Run Steps 1, 2, 3 in parallel (contract: SharedType = { ... })
|
|
459
|
+
2. Run Steps 4, 5 in parallel (integration + tests, different files)
|
|
413
460
|
```
|
|
414
461
|
|
|
415
|
-
**
|
|
416
|
-
|
|
462
|
+
**Example — over-sequential (avoid):**
|
|
417
463
|
```
|
|
418
|
-
1. Run Step 1 (sequential -
|
|
419
|
-
2. Run
|
|
420
|
-
3. Run Step
|
|
421
|
-
4. Run Step
|
|
464
|
+
1. Run Step 1 (sequential - create types)
|
|
465
|
+
2. Run Step 2 (sequential - create service using types)
|
|
466
|
+
3. Run Step 3 (sequential - create handler using types)
|
|
467
|
+
4. Run Step 4 (sequential - wire up index)
|
|
468
|
+
5. Run Step 5 (sequential - add tests)
|
|
422
469
|
```
|
|
423
470
|
|
|
424
|
-
**Example
|
|
471
|
+
**Example — parallel-first (prefer):**
|
|
425
472
|
```
|
|
426
|
-
1. Run
|
|
427
|
-
2. Run Steps
|
|
428
|
-
3. Run Step 4 (sequential - integration layer depends on Steps 2-3)
|
|
429
|
-
4. Run Step 5 (sequential - tests and validation)
|
|
473
|
+
1. Run Steps 1, 2, 3 in parallel (types, service, handler — shared contract: "UserInput = { name: string, email: string }")
|
|
474
|
+
2. Run Steps 4, 5 in parallel (index wiring + tests — different files)
|
|
430
475
|
```
|
|
431
476
|
|
|
477
|
+
**A sign your plan needs rework:** If most phases have only 1 step, you're effectively running sequentially. Rethink the step boundaries and apply contract-based parallelism.
|
|
478
|
+
|
|
432
479
|
## Dependencies and Configuration
|
|
433
480
|
|
|
434
481
|
- [Package name@version] - [Purpose]
|
|
@@ -462,7 +509,8 @@ This section tells the orchestrator EXACTLY how to execute the implementation st
|
|
|
462
509
|
## HOW TO UPDATE THE USER OF YOUR PROGRESS
|
|
463
510
|
* AS SOON AS YOU CAN, once you have formulated an initial plan/todo list for your task, you should create a comment as described in the <comment_tool_info> section above.
|
|
464
511
|
* AFTER YOU COMPLETE EACH ITEM ON YOUR TODO LIST - update the same comment with your progress as described in the <comment_tool_info> section above.
|
|
465
|
-
* When the whole task is complete, update the SAME comment with the results of your work including Section 1 and Section 2 above. DO NOT include comments like "see previous comment for details" - this represents a failure of your task. NEVER ATTEMPT CONCURRENT UPDATES OF THE COMMENT. DATA WILL BE LOST.
|
|
512
|
+
* When the whole task is complete, update the SAME comment with the results of your work including Section 1 and Section 2 above. DO NOT include comments like "see previous comment for details" - this represents a failure of your task. NEVER ATTEMPT CONCURRENT UPDATES OF THE COMMENT. DATA WILL BE LOST.
|
|
513
|
+
|
|
466
514
|
## Critical Reminders
|
|
467
515
|
|
|
468
516
|
- **READ the issue completely** including all comments before planning
|
|
@@ -472,10 +520,15 @@ This section tells the orchestrator EXACTLY how to execute the implementation st
|
|
|
472
520
|
- **NO EXECUTION** - you are planning only, not implementing
|
|
473
521
|
- **NO ASSUMPTIONS** - if something is unclear, note it in the plan
|
|
474
522
|
- **NO ENHANCEMENTS** - stick strictly to stated requirements
|
|
523
|
+
- **QUESTION NECESSITY** - if requirements describe writing values that already match the system's built-in defaults, the write may be unnecessary. Plan for the actual need, not the literal phrasing of the issue.
|
|
475
524
|
|
|
476
525
|
## Workflow
|
|
477
526
|
|
|
527
|
+
{{#if SWARM_MODE}}
|
|
528
|
+
1. Use `mcp__issue_management__get_issue` with the issue number from metadata or invocation arguments to get full context
|
|
529
|
+
{{else}}
|
|
478
530
|
1. Use the MCP issue management tool `mcp__issue_management__get_issue` with `{ number: {{ISSUE_NUMBER}}, includeComments: true }` to get full context (body, title, comments, labels, assignees, milestone)
|
|
531
|
+
{{/if}}
|
|
479
532
|
2. Search and read relevant files in the codebase
|
|
480
533
|
3. Create detailed implementation plan with exact locations (but, per instructions above, don't write the exact code)
|
|
481
534
|
4. Write plan to temporary file
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ScriptCommandBase
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-WXIM2WS7.js";
|
|
5
|
+
import "./chunk-WWKOVDWC.js";
|
|
6
|
+
import "./chunk-63QWFWH3.js";
|
|
7
|
+
import "./chunk-I5T677EA.js";
|
|
8
|
+
import "./chunk-YQ57ORTV.js";
|
|
9
|
+
import "./chunk-4FGEGQW4.js";
|
|
10
|
+
import "./chunk-7VHJNVLF.js";
|
|
11
|
+
import "./chunk-KB64WNBZ.js";
|
|
12
12
|
import "./chunk-6MLEBAYZ.js";
|
|
13
13
|
import "./chunk-VT4PDUYT.js";
|
|
14
14
|
|
|
@@ -24,4 +24,4 @@ var BuildCommand = class extends ScriptCommandBase {
|
|
|
24
24
|
export {
|
|
25
25
|
BuildCommand
|
|
26
26
|
};
|
|
27
|
-
//# sourceMappingURL=build-
|
|
27
|
+
//# sourceMappingURL=build-VHGEMXBA.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/utils/jira.ts
|
|
4
|
+
function escapeJql(value) {
|
|
5
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
6
|
+
}
|
|
7
|
+
async function fetchJiraIssueList(client, options) {
|
|
8
|
+
const { host, projectKey, doneStatuses = ["Done"], limit = 100, sprint, mine } = options;
|
|
9
|
+
const statusExclusions = doneStatuses.map((s) => `"${escapeJql(s)}"`).join(", ");
|
|
10
|
+
let jql = `project = "${escapeJql(projectKey)}" AND status NOT IN (${statusExclusions})`;
|
|
11
|
+
if (sprint === "current") {
|
|
12
|
+
jql += " AND sprint in openSprints()";
|
|
13
|
+
} else if (sprint) {
|
|
14
|
+
jql += ` AND sprint = "${escapeJql(sprint)}"`;
|
|
15
|
+
}
|
|
16
|
+
if (mine) {
|
|
17
|
+
jql += " AND assignee = currentUser()";
|
|
18
|
+
}
|
|
19
|
+
jql += " ORDER BY updated DESC";
|
|
20
|
+
const issues = await client.searchIssues(jql);
|
|
21
|
+
const baseUrl = host.replace(/\/$/, "");
|
|
22
|
+
return issues.slice(0, limit).map((issue) => ({
|
|
23
|
+
id: issue.key,
|
|
24
|
+
title: issue.fields.summary,
|
|
25
|
+
updatedAt: issue.fields.updated,
|
|
26
|
+
url: `${baseUrl}/browse/${issue.key}`,
|
|
27
|
+
state: issue.fields.status.name
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
escapeJql,
|
|
33
|
+
fetchJiraIssueList
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=chunk-4232AHNQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/jira.ts"],"sourcesContent":["/**\n * Jira utilities for the issues command\n * Follows the pattern of fetchGitHubIssueList and fetchLinearIssueList\n */\n\nimport type { JiraApiClient, JiraIssue } from '../lib/providers/jira/index.js'\n\n/**\n * Escape a string value for safe interpolation into JQL queries.\n * Prevents JQL injection by escaping backslashes and double quotes.\n */\nexport function escapeJql(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')\n}\n\nexport interface JiraIssueListItem {\n id: string // issue key e.g. \"PROJ-123\"\n title: string // fields.summary\n updatedAt: string // fields.updated (ISO string)\n url: string // {host}/browse/{key}\n state: string // fields.status.name\n}\n\n/**\n * Fetch a list of Jira issues for a project, excluding done statuses\n * @param client - Configured JiraApiClient instance\n * @param options - Fetch options\n * @returns Array of issues sorted by updated date\n */\nexport async function fetchJiraIssueList(\n client: JiraApiClient,\n options: {\n host: string\n projectKey: string\n doneStatuses?: string[]\n limit?: number\n sprint?: string | undefined\n mine?: boolean | undefined\n },\n): Promise<JiraIssueListItem[]> {\n const { host, projectKey, doneStatuses = ['Done'], limit = 100, sprint, mine } = options\n\n // Build JQL with status exclusion\n const statusExclusions = doneStatuses.map((s) => `\"${escapeJql(s)}\"`).join(', ')\n let jql = `project = \"${escapeJql(projectKey)}\" AND status NOT IN (${statusExclusions})`\n\n // Add sprint filter\n if (sprint === 'current') {\n jql += ' AND sprint in openSprints()'\n } else if (sprint) {\n jql += ` AND sprint = \"${escapeJql(sprint)}\"`\n }\n\n // Add assignee filter\n if (mine) {\n jql += ' AND assignee = currentUser()'\n }\n\n jql += ' ORDER BY updated DESC'\n\n const issues: JiraIssue[] = await client.searchIssues(jql)\n\n const baseUrl = host.replace(/\\/$/, '')\n\n return issues.slice(0, limit).map((issue) => ({\n id: issue.key,\n title: issue.fields.summary,\n updatedAt: issue.fields.updated,\n url: `${baseUrl}/browse/${issue.key}`,\n state: issue.fields.status.name,\n }))\n}\n"],"mappings":";;;AAWO,SAAS,UAAU,OAAuB;AAC/C,SAAO,MAAM,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK;AACzD;AAgBA,eAAsB,mBACpB,QACA,SAQ8B;AAC9B,QAAM,EAAE,MAAM,YAAY,eAAe,CAAC,MAAM,GAAG,QAAQ,KAAK,QAAQ,KAAK,IAAI;AAGjF,QAAM,mBAAmB,aAAa,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC,GAAG,EAAE,KAAK,IAAI;AAC/E,MAAI,MAAM,cAAc,UAAU,UAAU,CAAC,wBAAwB,gBAAgB;AAGrF,MAAI,WAAW,WAAW;AACxB,WAAO;AAAA,EACT,WAAW,QAAQ;AACjB,WAAO,kBAAkB,UAAU,MAAM,CAAC;AAAA,EAC5C;AAGA,MAAI,MAAM;AACR,WAAO;AAAA,EACT;AAEA,SAAO;AAEP,QAAM,SAAsB,MAAM,OAAO,aAAa,GAAG;AAEzD,QAAM,UAAU,KAAK,QAAQ,OAAO,EAAE;AAEtC,SAAO,OAAO,MAAM,GAAG,KAAK,EAAE,IAAI,CAAC,WAAW;AAAA,IAC5C,IAAI,MAAM;AAAA,IACV,OAAO,MAAM,OAAO;AAAA,IACpB,WAAW,MAAM,OAAO;AAAA,IACxB,KAAK,GAAG,OAAO,WAAW,MAAM,GAAG;AAAA,IACnC,OAAO,MAAM,OAAO,OAAO;AAAA,EAC7B,EAAE;AACJ;","names":[]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/utils/text.ts
|
|
4
|
+
function capitalizeFirstLetter(str) {
|
|
5
|
+
if (!str || str.length === 0) {
|
|
6
|
+
return str;
|
|
7
|
+
}
|
|
8
|
+
if (str.startsWith(" ")) {
|
|
9
|
+
return str.slice(1);
|
|
10
|
+
}
|
|
11
|
+
const firstChar = str.charAt(0);
|
|
12
|
+
const upperChar = firstChar.toUpperCase();
|
|
13
|
+
if (upperChar !== firstChar.toLowerCase() || new RegExp("\\p{L}", "u").test(firstChar)) {
|
|
14
|
+
if (upperChar !== firstChar) {
|
|
15
|
+
return upperChar + str.slice(1);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return str;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
capitalizeFirstLetter
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=chunk-4E7LCFUG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/text.ts"],"sourcesContent":["/**\n * Capitalizes the first letter of a string.\n *\n * Override behavior: If the string starts with a space, it signals the user\n * wants to opt-out of auto-capitalization. In this case, the leading space\n * is stripped and the first letter is NOT capitalized.\n *\n * @param str - The string to process\n * @returns The processed string with first letter capitalized (or original if override)\n */\nexport function capitalizeFirstLetter(str: string): string {\n\t// Handle empty or whitespace-only strings\n\tif (!str || str.length === 0) {\n\t\treturn str\n\t}\n\n\t// Check for space-prefix override: strip leading space and return as-is\n\tif (str.startsWith(' ')) {\n\t\treturn str.slice(1)\n\t}\n\n\t// Find the first character that could be capitalized (a letter)\n\tconst firstChar = str.charAt(0)\n\n\t// If first character is a letter (including unicode), capitalize it\n\t// Check if toUpperCase() produces a different result (indicates it's a letter with case)\n\tconst upperChar = firstChar.toUpperCase()\n\tif (upperChar !== firstChar.toLowerCase() || /\\p{L}/u.test(firstChar)) {\n\t\t// Only capitalize if it actually changes (avoids issues with non-cased scripts)\n\t\tif (upperChar !== firstChar) {\n\t\t\treturn upperChar + str.slice(1)\n\t\t}\n\t}\n\n\t// Non-letter first character or no case transformation available: return unchanged\n\treturn str\n}\n"],"mappings":";;;AAUO,SAAS,sBAAsB,KAAqB;AAE1D,MAAI,CAAC,OAAO,IAAI,WAAW,GAAG;AAC7B,WAAO;AAAA,EACR;AAGA,MAAI,IAAI,WAAW,GAAG,GAAG;AACxB,WAAO,IAAI,MAAM,CAAC;AAAA,EACnB;AAGA,QAAM,YAAY,IAAI,OAAO,CAAC;AAI9B,QAAM,YAAY,UAAU,YAAY;AACxC,MAAI,cAAc,UAAU,YAAY,KAAK,WAAC,UAAM,GAAC,EAAC,KAAK,SAAS,GAAG;AAEtE,QAAI,cAAc,WAAW;AAC5B,aAAO,YAAY,IAAI,MAAM,CAAC;AAAA,IAC/B;AAAA,EACD;AAGA,SAAO;AACR;","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SettingsManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7VHJNVLF.js";
|
|
5
5
|
import {
|
|
6
6
|
MetadataManager
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-KB64WNBZ.js";
|
|
8
8
|
import {
|
|
9
9
|
logger
|
|
10
10
|
} from "./chunk-VT4PDUYT.js";
|
|
@@ -375,7 +375,7 @@ async function getDefaultBranch(path2 = process.cwd()) {
|
|
|
375
375
|
}
|
|
376
376
|
async function findAllBranchesForIssue(issueNumber, path2 = process.cwd(), settingsManager) {
|
|
377
377
|
if (!settingsManager) {
|
|
378
|
-
const { SettingsManager: SM } = await import("./SettingsManager-
|
|
378
|
+
const { SettingsManager: SM } = await import("./SettingsManager-FNKCOZMQ.js");
|
|
379
379
|
settingsManager = new SM();
|
|
380
380
|
}
|
|
381
381
|
const protectedBranches = await settingsManager.getProtectedBranches(path2);
|
|
@@ -738,4 +738,4 @@ export {
|
|
|
738
738
|
removePlaceholderCommitFromHead,
|
|
739
739
|
removePlaceholderCommitFromHistory
|
|
740
740
|
};
|
|
741
|
-
//# sourceMappingURL=chunk-
|
|
741
|
+
//# sourceMappingURL=chunk-4FGEGQW4.js.map
|
|
@@ -2,31 +2,32 @@
|
|
|
2
2
|
import {
|
|
3
3
|
detectPackageManager,
|
|
4
4
|
runScript
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-WWKOVDWC.js";
|
|
6
6
|
import {
|
|
7
7
|
ProjectCapabilityDetector
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MORRVYPT.js";
|
|
9
9
|
import {
|
|
10
10
|
getPackageConfig,
|
|
11
11
|
hasScript
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-YQ57ORTV.js";
|
|
13
13
|
import {
|
|
14
|
+
detectClaudeCli,
|
|
15
|
+
launchClaude
|
|
16
|
+
} from "./chunk-UR5DGNUO.js";
|
|
17
|
+
import {
|
|
18
|
+
GitCommandError,
|
|
14
19
|
executeGitCommand,
|
|
15
20
|
fetchOrigin,
|
|
16
21
|
findMainWorktreePathWithSettings,
|
|
17
22
|
findWorktreeForBranch,
|
|
18
23
|
getMergeTargetBranch
|
|
19
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-4FGEGQW4.js";
|
|
20
25
|
import {
|
|
21
26
|
SettingsManager
|
|
22
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-7VHJNVLF.js";
|
|
23
28
|
import {
|
|
24
29
|
MetadataManager
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import {
|
|
27
|
-
detectClaudeCli,
|
|
28
|
-
launchClaude
|
|
29
|
-
} from "./chunk-FO5GGFOV.js";
|
|
30
|
+
} from "./chunk-KB64WNBZ.js";
|
|
30
31
|
import {
|
|
31
32
|
getLogger
|
|
32
33
|
} from "./chunk-6MLEBAYZ.js";
|
|
@@ -59,7 +60,8 @@ var MergeManager = class {
|
|
|
59
60
|
*/
|
|
60
61
|
async rebaseOnMain(worktreePath, options = {}) {
|
|
61
62
|
var _a;
|
|
62
|
-
const { dryRun = false, force = false } = options;
|
|
63
|
+
const { dryRun = false, force = false, jsonStream = false } = options;
|
|
64
|
+
await this.abortInProgressRebase(worktreePath);
|
|
63
65
|
const mainBranch = await this.getMainBranch(worktreePath);
|
|
64
66
|
const metadata = await this.metadataManager.readMetadata(worktreePath);
|
|
65
67
|
const isChildLoom = !!(metadata == null ? void 0 : metadata.parentLoom);
|
|
@@ -117,7 +119,7 @@ Ensure the branch exists locally.`
|
|
|
117
119
|
if (wipCommitHash) {
|
|
118
120
|
await this.restoreWipCommit(worktreePath, wipCommitHash);
|
|
119
121
|
}
|
|
120
|
-
return;
|
|
122
|
+
return { conflictsDetected: false, claudeLaunched: false, conflictsResolved: false };
|
|
121
123
|
}
|
|
122
124
|
const commitsOutput = await executeGitCommand(["log", "--oneline", `${targetBranch}..HEAD`], {
|
|
123
125
|
cwd: worktreePath
|
|
@@ -138,7 +140,7 @@ Ensure the branch exists locally.`
|
|
|
138
140
|
if (commitLines.length > 0) {
|
|
139
141
|
getLogger().info(`[DRY RUN] This would rebase ${commitLines.length} commit(s)`);
|
|
140
142
|
}
|
|
141
|
-
return;
|
|
143
|
+
return { conflictsDetected: false, claudeLaunched: false, conflictsResolved: false };
|
|
142
144
|
}
|
|
143
145
|
try {
|
|
144
146
|
await executeGitCommand(["-c", "core.hooksPath=/dev/null", "rebase", targetBranch], { cwd: worktreePath });
|
|
@@ -146,20 +148,22 @@ Ensure the branch exists locally.`
|
|
|
146
148
|
if (wipCommitHash) {
|
|
147
149
|
await this.restoreWipCommit(worktreePath, wipCommitHash);
|
|
148
150
|
}
|
|
151
|
+
return { conflictsDetected: false, claudeLaunched: false, conflictsResolved: false };
|
|
149
152
|
} catch (error) {
|
|
150
153
|
const conflictedFiles = await this.detectConflictedFiles(worktreePath);
|
|
151
154
|
if (conflictedFiles.length > 0) {
|
|
152
155
|
getLogger().info("Merge conflicts detected, attempting Claude-assisted resolution...");
|
|
153
156
|
const resolved = await this.attemptClaudeConflictResolution(
|
|
154
157
|
worktreePath,
|
|
155
|
-
conflictedFiles
|
|
158
|
+
conflictedFiles,
|
|
159
|
+
{ jsonStream }
|
|
156
160
|
);
|
|
157
161
|
if (resolved) {
|
|
158
162
|
getLogger().success("Conflicts resolved with Claude assistance, rebase completed");
|
|
159
163
|
if (wipCommitHash) {
|
|
160
164
|
await this.restoreWipCommit(worktreePath, wipCommitHash);
|
|
161
165
|
}
|
|
162
|
-
return;
|
|
166
|
+
return { conflictsDetected: true, claudeLaunched: true, conflictsResolved: true };
|
|
163
167
|
}
|
|
164
168
|
const conflictError = this.formatConflictError(conflictedFiles);
|
|
165
169
|
throw new Error(conflictError);
|
|
@@ -338,7 +342,7 @@ To recover:
|
|
|
338
342
|
* @returns true if conflicts resolved, false otherwise
|
|
339
343
|
* @private
|
|
340
344
|
*/
|
|
341
|
-
async attemptClaudeConflictResolution(worktreePath, conflictedFiles) {
|
|
345
|
+
async attemptClaudeConflictResolution(worktreePath, conflictedFiles, options = {}) {
|
|
342
346
|
const isClaudeAvailable = await detectClaudeCli();
|
|
343
347
|
if (!isClaudeAvailable) {
|
|
344
348
|
getLogger().debug("Claude CLI not available, skipping conflict resolution");
|
|
@@ -352,14 +356,18 @@ To recover:
|
|
|
352
356
|
"Bash(git diff:*)",
|
|
353
357
|
"Bash(git log:*)",
|
|
354
358
|
"Bash(git add:*)",
|
|
355
|
-
"Bash(git rebase:*)"
|
|
359
|
+
"Bash(git rebase:*)",
|
|
360
|
+
"Bash(GIT_EDITOR=true git rebase:*)"
|
|
356
361
|
];
|
|
357
362
|
try {
|
|
358
363
|
await launchClaude(prompt, {
|
|
359
364
|
appendSystemPrompt: systemPrompt,
|
|
360
365
|
addDir: worktreePath,
|
|
361
|
-
headless: false,
|
|
362
|
-
|
|
366
|
+
headless: options.jsonStream ? true : false,
|
|
367
|
+
...options.jsonStream && {
|
|
368
|
+
permissionMode: "bypassPermissions",
|
|
369
|
+
passthroughStdout: true
|
|
370
|
+
},
|
|
363
371
|
allowedTools: rebaseAllowedTools,
|
|
364
372
|
noSessionPersistence: true
|
|
365
373
|
// Utility operation - no session persistence needed
|
|
@@ -396,8 +404,12 @@ To recover:
|
|
|
396
404
|
async isRebaseInProgress(worktreePath) {
|
|
397
405
|
const fs = await import("fs/promises");
|
|
398
406
|
const path = await import("path");
|
|
399
|
-
const
|
|
400
|
-
|
|
407
|
+
const gitDir = (await executeGitCommand(
|
|
408
|
+
["rev-parse", "--absolute-git-dir"],
|
|
409
|
+
{ cwd: worktreePath }
|
|
410
|
+
)).trim();
|
|
411
|
+
const rebaseMergePath = path.join(gitDir, "rebase-merge");
|
|
412
|
+
const rebaseApplyPath = path.join(gitDir, "rebase-apply");
|
|
401
413
|
try {
|
|
402
414
|
await fs.access(rebaseMergePath);
|
|
403
415
|
return true;
|
|
@@ -410,6 +422,39 @@ To recover:
|
|
|
410
422
|
}
|
|
411
423
|
return false;
|
|
412
424
|
}
|
|
425
|
+
/**
|
|
426
|
+
* Abort an in-progress rebase if one is detected
|
|
427
|
+
* This handles cases where a previous rebase was interrupted (e.g., terminal closed,
|
|
428
|
+
* Claude session ended, user manually stopped) and the worktree is left in a dirty state.
|
|
429
|
+
* Since we're about to start a new rebase, the stale rebase state is irrelevant and safe to abort.
|
|
430
|
+
*
|
|
431
|
+
* @param worktreePath - Path to the worktree
|
|
432
|
+
* @private
|
|
433
|
+
*/
|
|
434
|
+
async abortInProgressRebase(worktreePath) {
|
|
435
|
+
const rebaseInProgress = await this.isRebaseInProgress(worktreePath);
|
|
436
|
+
if (!rebaseInProgress) {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
getLogger().warn("A rebase is already in progress. Aborting the stale rebase before proceeding...");
|
|
440
|
+
try {
|
|
441
|
+
await executeGitCommand(["rebase", "--abort"], { cwd: worktreePath });
|
|
442
|
+
getLogger().info("Stale rebase aborted successfully.");
|
|
443
|
+
} catch (error) {
|
|
444
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
445
|
+
if (errorMsg.includes("No rebase in progress")) {
|
|
446
|
+
getLogger().info("Rebase was already resolved by another process.");
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
if (error instanceof GitCommandError) {
|
|
450
|
+
throw new Error(
|
|
451
|
+
`Failed to abort in-progress rebase: ${error.message}
|
|
452
|
+
Manual recovery: run "git rebase --abort" in the worktree directory.`
|
|
453
|
+
);
|
|
454
|
+
}
|
|
455
|
+
throw error;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
413
458
|
};
|
|
414
459
|
|
|
415
460
|
// src/lib/BuildRunner.ts
|
|
@@ -494,4 +539,4 @@ export {
|
|
|
494
539
|
MergeManager,
|
|
495
540
|
BuildRunner
|
|
496
541
|
};
|
|
497
|
-
//# sourceMappingURL=chunk-
|
|
542
|
+
//# sourceMappingURL=chunk-5FJWO4IT.js.map
|