@iloom/cli 0.1.19 → 0.3.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/README.md +290 -30
- package/dist/BranchNamingService-3OQPRSWT.js +13 -0
- package/dist/ClaudeContextManager-MUQSDY2E.js +13 -0
- package/dist/ClaudeService-HG4VQ7AW.js +12 -0
- package/dist/GitHubService-EBOETDIW.js +11 -0
- package/dist/{LoomLauncher-UMMLPIZO.js → LoomLauncher-FLEMBCSQ.js} +64 -33
- package/dist/LoomLauncher-FLEMBCSQ.js.map +1 -0
- package/dist/ProjectCapabilityDetector-34LU7JJ4.js +9 -0
- package/dist/{PromptTemplateManager-WII75TKH.js → PromptTemplateManager-A52RUAMS.js} +2 -2
- package/dist/README.md +290 -30
- package/dist/{SettingsManager-SKLUVE3K.js → SettingsManager-WHHFGSL7.js} +12 -4
- package/dist/SettingsMigrationManager-AGIIIPDQ.js +10 -0
- package/dist/agents/iloom-issue-analyze-and-plan.md +125 -35
- package/dist/agents/iloom-issue-analyzer.md +284 -32
- package/dist/agents/iloom-issue-complexity-evaluator.md +40 -21
- package/dist/agents/iloom-issue-enhancer.md +69 -48
- package/dist/agents/iloom-issue-implementer.md +36 -25
- package/dist/agents/iloom-issue-planner.md +35 -24
- package/dist/agents/iloom-issue-reviewer.md +62 -9
- package/dist/chunk-3KATJIKO.js +55 -0
- package/dist/chunk-3KATJIKO.js.map +1 -0
- package/dist/{chunk-JXQXSC45.js → chunk-3RUPPQRG.js} +1 -18
- package/dist/chunk-3RUPPQRG.js.map +1 -0
- package/dist/{chunk-PR7FKQBG.js → chunk-47KSHUCR.js} +3 -3
- package/dist/chunk-47KSHUCR.js.map +1 -0
- package/dist/{chunk-IO4WFTL2.js → chunk-4HHRTA7Q.js} +3 -3
- package/dist/{chunk-IO4WFTL2.js.map → chunk-4HHRTA7Q.js.map} +1 -1
- package/dist/chunk-5EF7Z346.js +1987 -0
- package/dist/chunk-5EF7Z346.js.map +1 -0
- package/dist/{chunk-VVH3ANF2.js → chunk-AWOFAD5O.js} +12 -12
- package/dist/chunk-AWOFAD5O.js.map +1 -0
- package/dist/{chunk-DEPYQRRB.js → chunk-C5QCTEQK.js} +2 -2
- package/dist/{chunk-CWR2SANQ.js → chunk-EBISESAP.js} +1 -1
- package/dist/{chunk-ELFT36PV.js → chunk-FIAT22G7.js} +4 -16
- package/dist/chunk-FIAT22G7.js.map +1 -0
- package/dist/{chunk-ZWXJBSUW.js → chunk-G2IEYOLQ.js} +11 -38
- package/dist/chunk-G2IEYOLQ.js.map +1 -0
- package/dist/{chunk-ZMNQBJUI.js → chunk-IP7SMKIF.js} +61 -22
- package/dist/chunk-IP7SMKIF.js.map +1 -0
- package/dist/{chunk-JNKJ7NJV.js → chunk-JKXJ7BGL.js} +6 -2
- package/dist/{chunk-JNKJ7NJV.js.map → chunk-JKXJ7BGL.js.map} +1 -1
- package/dist/{chunk-LAPY6NAE.js → chunk-JQFO7QQN.js} +68 -12
- package/dist/{chunk-LAPY6NAE.js.map → chunk-JQFO7QQN.js.map} +1 -1
- package/dist/{SettingsMigrationManager-MTQIMI54.js → chunk-KLBYVHPK.js} +3 -2
- package/dist/{chunk-KOCQAD2E.js → chunk-MAVL6PJF.js} +26 -3
- package/dist/chunk-MAVL6PJF.js.map +1 -0
- package/dist/{chunk-USVVV3FP.js → chunk-MKWYLDFK.js} +5 -5
- package/dist/chunk-ML3NRPNB.js +396 -0
- package/dist/chunk-ML3NRPNB.js.map +1 -0
- package/dist/{chunk-FXV24OYZ.js → chunk-PA6Q6AWM.js} +24 -4
- package/dist/chunk-PA6Q6AWM.js.map +1 -0
- package/dist/chunk-RO26VS3W.js +444 -0
- package/dist/chunk-RO26VS3W.js.map +1 -0
- package/dist/{chunk-PV3GAXQO.js → chunk-VAYCCUXW.js} +72 -2
- package/dist/{chunk-PV3GAXQO.js.map → chunk-VAYCCUXW.js.map} +1 -1
- package/dist/{chunk-SPYPLHMK.js → chunk-VU3QMIP2.js} +34 -2
- package/dist/chunk-VU3QMIP2.js.map +1 -0
- package/dist/{chunk-PVAVNJKS.js → chunk-WEN5C5DM.js} +10 -1
- package/dist/chunk-WEN5C5DM.js.map +1 -0
- package/dist/{chunk-PXZBAC2M.js → chunk-XXV3UFZL.js} +4 -4
- package/dist/{chunk-PXZBAC2M.js.map → chunk-XXV3UFZL.js.map} +1 -1
- package/dist/{chunk-RSRO7564.js → chunk-ZE74H5BR.js} +28 -3
- package/dist/chunk-ZE74H5BR.js.map +1 -0
- package/dist/{chunk-GZP4UGGM.js → chunk-ZM3CFL5L.js} +2 -2
- package/dist/{chunk-BLCTGFZN.js → chunk-ZT3YZB4K.js} +3 -4
- package/dist/chunk-ZT3YZB4K.js.map +1 -0
- package/dist/{claude-7LUVDZZ4.js → claude-GOP6PFC7.js} +2 -2
- package/dist/{cleanup-ZHROIBSQ.js → cleanup-7RWLBSLE.js} +86 -25
- package/dist/cleanup-7RWLBSLE.js.map +1 -0
- package/dist/cli.js +2513 -64
- package/dist/cli.js.map +1 -1
- package/dist/{contribute-3MQJ3XAQ.js → contribute-BS2L4FZR.js} +9 -6
- package/dist/{contribute-3MQJ3XAQ.js.map → contribute-BS2L4FZR.js.map} +1 -1
- package/dist/{feedback-ZOUCCHN4.js → feedback-N4ECWIPF.js} +15 -14
- package/dist/{feedback-ZOUCCHN4.js.map → feedback-N4ECWIPF.js.map} +1 -1
- package/dist/{git-OUYMVYJX.js → git-TDXKRTXM.js} +4 -2
- package/dist/{ignite-HICLZEYU.js → ignite-VM64QO3J.js} +32 -27
- package/dist/ignite-VM64QO3J.js.map +1 -0
- package/dist/index.d.ts +379 -45
- package/dist/index.js +1241 -448
- package/dist/index.js.map +1 -1
- package/dist/{init-UMKNHNV5.js → init-G3T64SC4.js} +104 -40
- package/dist/init-G3T64SC4.js.map +1 -0
- package/dist/mcp/issue-management-server.js +934 -0
- package/dist/mcp/issue-management-server.js.map +1 -0
- package/dist/{neon-helpers-ZVIRPKCI.js → neon-helpers-WPUACUVC.js} +3 -3
- package/dist/{open-ETZUFSE4.js → open-KXDXEKRZ.js} +39 -36
- package/dist/open-KXDXEKRZ.js.map +1 -0
- package/dist/{prompt-ANTQWHUF.js → prompt-7INJ7YRU.js} +4 -2
- package/dist/prompt-7INJ7YRU.js.map +1 -0
- package/dist/prompts/init-prompt.txt +563 -91
- package/dist/prompts/issue-prompt.txt +27 -27
- package/dist/{rebase-KBWFDZCN.js → rebase-Q7GMM7EI.js} +6 -6
- package/dist/{remote-GJEZWRCC.js → remote-VUNCQZ6J.js} +5 -2
- package/dist/remote-VUNCQZ6J.js.map +1 -0
- package/dist/{run-4SVQ3WEU.js → run-PAWJJCSX.js} +39 -36
- package/dist/run-PAWJJCSX.js.map +1 -0
- package/dist/schema/settings.schema.json +74 -0
- package/dist/{terminal-3D6TUAKJ.js → terminal-BIRBZ4AZ.js} +2 -2
- package/dist/terminal-BIRBZ4AZ.js.map +1 -0
- package/dist/{test-git-MKZATGZN.js → test-git-3WDLNQCA.js} +3 -3
- package/dist/{test-prefix-ZNLWDI3K.js → test-prefix-EVGAWAJW.js} +3 -3
- package/dist/{test-tabs-JRKY3QMM.js → test-tabs-RXDBZ6J7.js} +2 -2
- package/dist/{test-webserver-M2I3EV4J.js → test-webserver-DAHONWCS.js} +4 -4
- package/dist/test-webserver-DAHONWCS.js.map +1 -0
- package/package.json +2 -1
- package/dist/ClaudeContextManager-JKR4WGNU.js +0 -13
- package/dist/ClaudeService-55DQGB7T.js +0 -12
- package/dist/GitHubService-LWP4GKGH.js +0 -11
- package/dist/LoomLauncher-UMMLPIZO.js.map +0 -1
- package/dist/add-issue-X56V3XPB.js +0 -69
- package/dist/add-issue-X56V3XPB.js.map +0 -1
- package/dist/chunk-BLCTGFZN.js.map +0 -1
- package/dist/chunk-ELFT36PV.js.map +0 -1
- package/dist/chunk-FXV24OYZ.js.map +0 -1
- package/dist/chunk-H4E4THUZ.js +0 -55
- package/dist/chunk-H4E4THUZ.js.map +0 -1
- package/dist/chunk-H5LDRGVK.js +0 -642
- package/dist/chunk-H5LDRGVK.js.map +0 -1
- package/dist/chunk-JXQXSC45.js.map +0 -1
- package/dist/chunk-KOCQAD2E.js.map +0 -1
- package/dist/chunk-PR7FKQBG.js.map +0 -1
- package/dist/chunk-PVAVNJKS.js.map +0 -1
- package/dist/chunk-Q2KYPAH2.js +0 -545
- package/dist/chunk-Q2KYPAH2.js.map +0 -1
- package/dist/chunk-RSRO7564.js.map +0 -1
- package/dist/chunk-SPYPLHMK.js.map +0 -1
- package/dist/chunk-VCMMAFXQ.js +0 -54
- package/dist/chunk-VCMMAFXQ.js.map +0 -1
- package/dist/chunk-VVH3ANF2.js.map +0 -1
- package/dist/chunk-VYQLLHZ7.js +0 -239
- package/dist/chunk-VYQLLHZ7.js.map +0 -1
- package/dist/chunk-ZMNQBJUI.js.map +0 -1
- package/dist/chunk-ZWXJBSUW.js.map +0 -1
- package/dist/cleanup-ZHROIBSQ.js.map +0 -1
- package/dist/enhance-VGWUX474.js +0 -176
- package/dist/enhance-VGWUX474.js.map +0 -1
- package/dist/finish-QJSK6Z7J.js +0 -1355
- package/dist/finish-QJSK6Z7J.js.map +0 -1
- package/dist/ignite-HICLZEYU.js.map +0 -1
- package/dist/init-UMKNHNV5.js.map +0 -1
- package/dist/mcp/chunk-6SDFJ42P.js +0 -62
- package/dist/mcp/chunk-6SDFJ42P.js.map +0 -1
- package/dist/mcp/claude-YHHHLSXH.js +0 -249
- package/dist/mcp/claude-YHHHLSXH.js.map +0 -1
- package/dist/mcp/color-QS5BFCNN.js +0 -168
- package/dist/mcp/color-QS5BFCNN.js.map +0 -1
- package/dist/mcp/github-comment-server.js +0 -168
- package/dist/mcp/github-comment-server.js.map +0 -1
- package/dist/mcp/terminal-SDCMDVD7.js +0 -202
- package/dist/mcp/terminal-SDCMDVD7.js.map +0 -1
- package/dist/open-ETZUFSE4.js.map +0 -1
- package/dist/run-4SVQ3WEU.js.map +0 -1
- package/dist/start-CT2ZEFP2.js +0 -983
- package/dist/start-CT2ZEFP2.js.map +0 -1
- package/dist/test-webserver-M2I3EV4J.js.map +0 -1
- /package/dist/{ClaudeContextManager-JKR4WGNU.js.map → BranchNamingService-3OQPRSWT.js.map} +0 -0
- /package/dist/{ClaudeService-55DQGB7T.js.map → ClaudeContextManager-MUQSDY2E.js.map} +0 -0
- /package/dist/{GitHubService-LWP4GKGH.js.map → ClaudeService-HG4VQ7AW.js.map} +0 -0
- /package/dist/{PromptTemplateManager-WII75TKH.js.map → GitHubService-EBOETDIW.js.map} +0 -0
- /package/dist/{SettingsManager-SKLUVE3K.js.map → ProjectCapabilityDetector-34LU7JJ4.js.map} +0 -0
- /package/dist/{claude-7LUVDZZ4.js.map → PromptTemplateManager-A52RUAMS.js.map} +0 -0
- /package/dist/{git-OUYMVYJX.js.map → SettingsManager-WHHFGSL7.js.map} +0 -0
- /package/dist/{neon-helpers-ZVIRPKCI.js.map → SettingsMigrationManager-AGIIIPDQ.js.map} +0 -0
- /package/dist/{chunk-DEPYQRRB.js.map → chunk-C5QCTEQK.js.map} +0 -0
- /package/dist/{chunk-CWR2SANQ.js.map → chunk-EBISESAP.js.map} +0 -0
- /package/dist/{SettingsMigrationManager-MTQIMI54.js.map → chunk-KLBYVHPK.js.map} +0 -0
- /package/dist/{chunk-USVVV3FP.js.map → chunk-MKWYLDFK.js.map} +0 -0
- /package/dist/{chunk-GZP4UGGM.js.map → chunk-ZM3CFL5L.js.map} +0 -0
- /package/dist/{prompt-ANTQWHUF.js.map → claude-GOP6PFC7.js.map} +0 -0
- /package/dist/{remote-GJEZWRCC.js.map → git-TDXKRTXM.js.map} +0 -0
- /package/dist/{terminal-3D6TUAKJ.js.map → neon-helpers-WPUACUVC.js.map} +0 -0
- /package/dist/{rebase-KBWFDZCN.js.map → rebase-Q7GMM7EI.js.map} +0 -0
- /package/dist/{test-git-MKZATGZN.js.map → test-git-3WDLNQCA.js.map} +0 -0
- /package/dist/{test-prefix-ZNLWDI3K.js.map → test-prefix-EVGAWAJW.js.map} +0 -0
- /package/dist/{test-tabs-JRKY3QMM.js.map → test-tabs-RXDBZ6J7.js.map} +0 -0
package/dist/enhance-VGWUX474.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
generateGitHubCommentMcpConfig
|
|
4
|
-
} from "./chunk-VCMMAFXQ.js";
|
|
5
|
-
import {
|
|
6
|
-
AgentManager
|
|
7
|
-
} from "./chunk-OC4H6HJD.js";
|
|
8
|
-
import {
|
|
9
|
-
openBrowser
|
|
10
|
-
} from "./chunk-YETJNRQM.js";
|
|
11
|
-
import {
|
|
12
|
-
getConfiguredRepoFromSettings,
|
|
13
|
-
hasMultipleRemotes
|
|
14
|
-
} from "./chunk-FXV24OYZ.js";
|
|
15
|
-
import {
|
|
16
|
-
GitHubService
|
|
17
|
-
} from "./chunk-ZWXJBSUW.js";
|
|
18
|
-
import "./chunk-JXQXSC45.js";
|
|
19
|
-
import {
|
|
20
|
-
launchClaude
|
|
21
|
-
} from "./chunk-PXZBAC2M.js";
|
|
22
|
-
import {
|
|
23
|
-
SettingsManager
|
|
24
|
-
} from "./chunk-VYQLLHZ7.js";
|
|
25
|
-
import {
|
|
26
|
-
waitForKeypress
|
|
27
|
-
} from "./chunk-JNKJ7NJV.js";
|
|
28
|
-
import {
|
|
29
|
-
logger
|
|
30
|
-
} from "./chunk-GEHQXLEI.js";
|
|
31
|
-
|
|
32
|
-
// src/commands/enhance.ts
|
|
33
|
-
var EnhanceCommand = class {
|
|
34
|
-
constructor(gitHubService, agentManager, settingsManager) {
|
|
35
|
-
this.gitHubService = gitHubService ?? new GitHubService();
|
|
36
|
-
this.agentManager = agentManager ?? new AgentManager();
|
|
37
|
-
this.settingsManager = settingsManager ?? new SettingsManager();
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Execute the enhance command workflow:
|
|
41
|
-
* 1. Validate issue number
|
|
42
|
-
* 2. Fetch issue to verify it exists
|
|
43
|
-
* 3. Load agent configurations
|
|
44
|
-
* 4. Invoke Claude CLI with enhancer agent
|
|
45
|
-
* 5. Parse response to determine outcome
|
|
46
|
-
* 6. Handle browser interaction based on outcome
|
|
47
|
-
*/
|
|
48
|
-
async execute(input) {
|
|
49
|
-
const { issueNumber, options } = input;
|
|
50
|
-
const { author } = options;
|
|
51
|
-
const settings = await this.settingsManager.loadSettings();
|
|
52
|
-
let repo;
|
|
53
|
-
const multipleRemotes = await hasMultipleRemotes();
|
|
54
|
-
if (multipleRemotes) {
|
|
55
|
-
repo = await getConfiguredRepoFromSettings(settings);
|
|
56
|
-
logger.info(`Using GitHub repository: ${repo}`);
|
|
57
|
-
}
|
|
58
|
-
this.validateIssueNumber(issueNumber);
|
|
59
|
-
logger.info(`Fetching issue #${issueNumber}...`);
|
|
60
|
-
const issue = await this.gitHubService.fetchIssue(issueNumber, repo);
|
|
61
|
-
logger.debug("Issue fetched successfully", { number: issue.number, title: issue.title });
|
|
62
|
-
logger.debug("Loading agent configurations...");
|
|
63
|
-
const loadedAgents = await this.agentManager.loadAgents(settings);
|
|
64
|
-
const agents = this.agentManager.formatForCli(loadedAgents);
|
|
65
|
-
let mcpConfig;
|
|
66
|
-
let allowedTools;
|
|
67
|
-
let disallowedTools;
|
|
68
|
-
try {
|
|
69
|
-
mcpConfig = await generateGitHubCommentMcpConfig("issue", repo);
|
|
70
|
-
logger.debug("Generated MCP configuration for GitHub comment broker");
|
|
71
|
-
allowedTools = [
|
|
72
|
-
"mcp__github_comment__create_comment",
|
|
73
|
-
"mcp__github_comment__update_comment"
|
|
74
|
-
];
|
|
75
|
-
disallowedTools = ["Bash(gh api:*)"];
|
|
76
|
-
logger.debug("Configured tool filtering for issue workflow", { allowedTools, disallowedTools });
|
|
77
|
-
} catch (error) {
|
|
78
|
-
logger.warn(`Failed to generate MCP config: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
79
|
-
}
|
|
80
|
-
logger.info("Invoking enhancer agent. This may take a moment...");
|
|
81
|
-
const prompt = this.constructPrompt(issueNumber, author);
|
|
82
|
-
const response = await launchClaude(prompt, {
|
|
83
|
-
headless: true,
|
|
84
|
-
model: "sonnet",
|
|
85
|
-
agents,
|
|
86
|
-
...mcpConfig && { mcpConfig },
|
|
87
|
-
...allowedTools && { allowedTools },
|
|
88
|
-
...disallowedTools && { disallowedTools }
|
|
89
|
-
});
|
|
90
|
-
const result = this.parseEnhancerResponse(response);
|
|
91
|
-
if (!result.enhanced) {
|
|
92
|
-
logger.success("Issue already has thorough description. No enhancement needed.");
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
logger.success(`Issue #${issueNumber} enhanced successfully!`);
|
|
96
|
-
logger.info(`Enhanced specification available at: ${result.url}`);
|
|
97
|
-
if (!options.noBrowser && result.url) {
|
|
98
|
-
await this.promptAndOpenBrowser(result.url);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Validate that issue number is a valid positive integer
|
|
103
|
-
*/
|
|
104
|
-
validateIssueNumber(issueNumber) {
|
|
105
|
-
if (issueNumber === void 0 || issueNumber === null) {
|
|
106
|
-
throw new Error("Issue number is required");
|
|
107
|
-
}
|
|
108
|
-
if (typeof issueNumber !== "number" || Number.isNaN(issueNumber) || issueNumber <= 0 || !Number.isInteger(issueNumber)) {
|
|
109
|
-
throw new Error("Issue number must be a valid positive integer");
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Construct the prompt for the orchestrating Claude instance.
|
|
114
|
-
* This prompt is very clear about expected output format to ensure reliable parsing.
|
|
115
|
-
*/
|
|
116
|
-
constructPrompt(issueNumber, author) {
|
|
117
|
-
const authorInstruction = author ? `
|
|
118
|
-
IMPORTANT: When you create your analysis comment, tag @${author} in the "Questions for Reporter" section if you have questions.
|
|
119
|
-
` : "";
|
|
120
|
-
return `Execute @agent-iloom-issue-enhancer ${issueNumber}${authorInstruction}
|
|
121
|
-
|
|
122
|
-
## OUTPUT REQUIREMENTS
|
|
123
|
-
* If the issue was not enhanced, return ONLY: "No enhancement needed"
|
|
124
|
-
* If the issue WAS enhanced, return ONLY: <FULL URL OF THE COMMENT INCLUDING COMMENT ID>
|
|
125
|
-
* If you encounter permission/authentication/access errors, return ONLY: "Permission denied: <specific error description>"
|
|
126
|
-
* IMPORTANT: Return ONLY one of the above - DO NOT include commentary such as "I created a comment at <URL>" or "I examined the issue and found no enhancement was necessary"
|
|
127
|
-
* CONTEXT: Your output is going to be parsed programmatically, so adherence to the output requirements is CRITICAL.`;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Parse the response from the enhancer agent.
|
|
131
|
-
* Returns either { enhanced: false } or { enhanced: true, url: "..." }
|
|
132
|
-
* Throws specific errors for permission issues.
|
|
133
|
-
*/
|
|
134
|
-
parseEnhancerResponse(response) {
|
|
135
|
-
if (!response || typeof response !== "string") {
|
|
136
|
-
throw new Error("No response from enhancer agent");
|
|
137
|
-
}
|
|
138
|
-
const trimmed = response.trim();
|
|
139
|
-
logger.debug(`RESPONSE FROM ENHANCER AGENT: '${trimmed}'`);
|
|
140
|
-
if (trimmed.toLowerCase().startsWith("permission denied:")) {
|
|
141
|
-
const errorMessage = trimmed.substring("permission denied:".length).trim();
|
|
142
|
-
throw new Error(`Permission denied: ${errorMessage}`);
|
|
143
|
-
}
|
|
144
|
-
if (trimmed.toLowerCase().includes("no enhancement needed")) {
|
|
145
|
-
return { enhanced: false };
|
|
146
|
-
}
|
|
147
|
-
const urlPattern = /https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/\d+#issuecomment-\d+/;
|
|
148
|
-
const match = trimmed.match(urlPattern);
|
|
149
|
-
if (match) {
|
|
150
|
-
return { enhanced: true, url: match[0] };
|
|
151
|
-
}
|
|
152
|
-
throw new Error(`Unexpected response from enhancer agent: ${trimmed}`);
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Prompt user and open browser to view enhanced issue.
|
|
156
|
-
* Matches the pattern from the issue specification.
|
|
157
|
-
*/
|
|
158
|
-
async promptAndOpenBrowser(commentUrl) {
|
|
159
|
-
try {
|
|
160
|
-
const key = await waitForKeypress(
|
|
161
|
-
"Press q to quit or any other key to view the enhanced issue in a web browser..."
|
|
162
|
-
);
|
|
163
|
-
if (key.toLowerCase() === "q") {
|
|
164
|
-
logger.info("Skipping browser opening");
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
await openBrowser(commentUrl);
|
|
168
|
-
} catch (error) {
|
|
169
|
-
logger.warn(`Failed to open browser: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
export {
|
|
174
|
-
EnhanceCommand
|
|
175
|
-
};
|
|
176
|
-
//# sourceMappingURL=enhance-VGWUX474.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/enhance.ts"],"sourcesContent":["import type { GitHubService } from '../lib/GitHubService.js'\nimport type { AgentManager } from '../lib/AgentManager.js'\nimport type { SettingsManager } from '../lib/SettingsManager.js'\nimport { launchClaude } from '../utils/claude.js'\nimport { openBrowser } from '../utils/browser.js'\nimport { waitForKeypress } from '../utils/prompt.js'\nimport { logger } from '../utils/logger.js'\nimport { generateGitHubCommentMcpConfig } from '../utils/mcp.js'\nimport { GitHubService as DefaultGitHubService } from '../lib/GitHubService.js'\nimport { AgentManager as DefaultAgentManager } from '../lib/AgentManager.js'\nimport { SettingsManager as DefaultSettingsManager } from '../lib/SettingsManager.js'\nimport { getConfiguredRepoFromSettings, hasMultipleRemotes } from '../utils/remote.js'\n\nexport interface EnhanceCommandInput {\n\tissueNumber: number\n\toptions: EnhanceOptions\n}\n\nexport interface EnhanceOptions {\n\tnoBrowser?: boolean // Skip browser opening prompt\n\tauthor?: string // GitHub username of issue author for tagging\n}\n\n/**\n * Command to enhance existing GitHub issues with AI assistance.\n * Applies the issue enhancer agent to an existing issue, respecting idempotency checks.\n */\nexport class EnhanceCommand {\n\tprivate gitHubService: GitHubService\n\tprivate agentManager: AgentManager\n\tprivate settingsManager: SettingsManager\n\n\tconstructor(\n\t\tgitHubService?: GitHubService,\n\t\tagentManager?: AgentManager,\n\t\tsettingsManager?: SettingsManager\n\t) {\n\t\t// Use provided services or create defaults\n\t\tthis.gitHubService = gitHubService ?? new DefaultGitHubService()\n\t\tthis.agentManager = agentManager ?? new DefaultAgentManager()\n\t\tthis.settingsManager = settingsManager ?? new DefaultSettingsManager()\n\t}\n\n\t/**\n\t * Execute the enhance command workflow:\n\t * 1. Validate issue number\n\t * 2. Fetch issue to verify it exists\n\t * 3. Load agent configurations\n\t * 4. Invoke Claude CLI with enhancer agent\n\t * 5. Parse response to determine outcome\n\t * 6. Handle browser interaction based on outcome\n\t */\n\tpublic async execute(input: EnhanceCommandInput): Promise<void> {\n\t\tconst { issueNumber, options } = input\n\t\tconst { author } = options\n\n\t\t// Step 0: Load settings and get configured repo for GitHub operations\n\t\tconst settings = await this.settingsManager.loadSettings()\n\t\tlet repo: string | undefined\n\n\t\tconst multipleRemotes = await hasMultipleRemotes()\n\t\tif (multipleRemotes) {\n\t\t\trepo = await getConfiguredRepoFromSettings(settings)\n\t\t\tlogger.info(`Using GitHub repository: ${repo}`)\n\t\t}\n\n\t\t// Step 1: Validate issue number\n\t\tthis.validateIssueNumber(issueNumber)\n\n\t\t// Step 2: Fetch issue to verify it exists\n\t\tlogger.info(`Fetching issue #${issueNumber}...`)\n\t\tconst issue = await this.gitHubService.fetchIssue(issueNumber, repo)\n\t\tlogger.debug('Issue fetched successfully', { number: issue.number, title: issue.title })\n\n\t\t// Step 3: Load agent configurations\n\t\tlogger.debug('Loading agent configurations...')\n\t\tconst loadedAgents = await this.agentManager.loadAgents(settings)\n\t\tconst agents = this.agentManager.formatForCli(loadedAgents)\n\n\t\t// Step 3.5: Generate MCP config and tool filtering for GitHub comment broker\n\t\tlet mcpConfig: Record<string, unknown>[] | undefined\n\t\tlet allowedTools: string[] | undefined\n\t\tlet disallowedTools: string[] | undefined\n\n\t\ttry {\n\t\t\tmcpConfig = await generateGitHubCommentMcpConfig('issue', repo)\n\t\t\tlogger.debug('Generated MCP configuration for GitHub comment broker')\n\n\t\t\t// Configure tool filtering for issue workflows\n\t\t\tallowedTools = [\n\t\t\t\t'mcp__github_comment__create_comment',\n\t\t\t\t'mcp__github_comment__update_comment',\n\t\t\t]\n\t\t\tdisallowedTools = ['Bash(gh api:*)']\n\n\t\t\tlogger.debug('Configured tool filtering for issue workflow', { allowedTools, disallowedTools })\n\t\t} catch (error) {\n\t\t\t// Log warning but continue without MCP\n\t\t\tlogger.warn(`Failed to generate MCP config: ${error instanceof Error ? error.message : 'Unknown error'}`)\n\t\t}\n\n\t\t// Step 4: Invoke Claude CLI with enhancer agent\n\t\tlogger.info('Invoking enhancer agent. This may take a moment...')\n\t\tconst prompt = this.constructPrompt(issueNumber, author)\n\t\tconst response = await launchClaude(prompt, {\n\t\t\theadless: true,\n\t\t\tmodel: 'sonnet',\n\t\t\tagents,\n\t\t\t...(mcpConfig && { mcpConfig }),\n\t\t\t...(allowedTools && { allowedTools }),\n\t\t\t...(disallowedTools && { disallowedTools }),\n\t\t})\n\n\t\t// Step 5: Parse response to determine outcome\n\t\tconst result = this.parseEnhancerResponse(response)\n\n\t\t// Step 6: Handle browser interaction based on outcome\n\t\tif (!result.enhanced) {\n\t\t\tlogger.success('Issue already has thorough description. No enhancement needed.')\n\t\t\treturn\n\t\t}\n\n\t\tlogger.success(`Issue #${issueNumber} enhanced successfully!`)\n\t\tlogger.info(`Enhanced specification available at: ${result.url}`)\n\n\t\t// Prompt to open browser (unless --no-browser flag is set)\n\t\tif (!options.noBrowser && result.url) {\n\t\t\tawait this.promptAndOpenBrowser(result.url)\n\t\t}\n\t}\n\n\t/**\n\t * Validate that issue number is a valid positive integer\n\t */\n\tprivate validateIssueNumber(issueNumber: number): void {\n\t\tif (issueNumber === undefined || issueNumber === null) {\n\t\t\tthrow new Error('Issue number is required')\n\t\t}\n\n\t\tif (typeof issueNumber !== 'number' || Number.isNaN(issueNumber) || issueNumber <= 0 || !Number.isInteger(issueNumber)) {\n\t\t\tthrow new Error('Issue number must be a valid positive integer')\n\t\t}\n\t}\n\n\t/**\n\t * Construct the prompt for the orchestrating Claude instance.\n\t * This prompt is very clear about expected output format to ensure reliable parsing.\n\t */\n\tprivate constructPrompt(issueNumber: number, author?: string): string {\n\t\tconst authorInstruction = author\n\t\t\t? `\\nIMPORTANT: When you create your analysis comment, tag @${author} in the \"Questions for Reporter\" section if you have questions.\\n`\n\t\t\t: ''\n\n\t\treturn `Execute @agent-iloom-issue-enhancer ${issueNumber}${authorInstruction}\n\n## OUTPUT REQUIREMENTS\n* If the issue was not enhanced, return ONLY: \"No enhancement needed\"\n* If the issue WAS enhanced, return ONLY: <FULL URL OF THE COMMENT INCLUDING COMMENT ID>\n* If you encounter permission/authentication/access errors, return ONLY: \"Permission denied: <specific error description>\"\n* IMPORTANT: Return ONLY one of the above - DO NOT include commentary such as \"I created a comment at <URL>\" or \"I examined the issue and found no enhancement was necessary\"\n* CONTEXT: Your output is going to be parsed programmatically, so adherence to the output requirements is CRITICAL.`\n\t}\n\n\t/**\n\t * Parse the response from the enhancer agent.\n\t * Returns either { enhanced: false } or { enhanced: true, url: \"...\" }\n\t * Throws specific errors for permission issues.\n\t */\n\tprivate parseEnhancerResponse(response: string | void): { enhanced: boolean; url?: string } {\n\t\t// Handle empty or void response\n\t\tif (!response || typeof response !== 'string') {\n\t\t\tthrow new Error('No response from enhancer agent')\n\t\t}\n\n\t\tconst trimmed = response.trim()\n\t\n\t\tlogger.debug(`RESPONSE FROM ENHANCER AGENT: '${trimmed}'`)\n\n\t\t// Check for permission denied errors (case-insensitive)\n\t\tif (trimmed.toLowerCase().startsWith('permission denied:')) {\n\t\t\tconst errorMessage = trimmed.substring('permission denied:'.length).trim()\n\t\t\tthrow new Error(`Permission denied: ${errorMessage}`)\n\t\t}\n\n\t\t// Check for \"No enhancement needed\" (case-insensitive)\n\t\tif (trimmed.toLowerCase().includes('no enhancement needed')) {\n\t\t\treturn { enhanced: false }\n\t\t}\n\n\t\t// Check if response looks like a GitHub comment URL\n\t\tconst urlPattern = /https:\\/\\/github\\.com\\/[^/]+\\/[^/]+\\/issues\\/\\d+#issuecomment-\\d+/\n\t\tconst match = trimmed.match(urlPattern)\n\n\t\tif (match) {\n\t\t\treturn { enhanced: true, url: match[0] }\n\t\t}\n\n\t\t// Unexpected response format\n\t\tthrow new Error(`Unexpected response from enhancer agent: ${trimmed}`)\n\t}\n\n\t/**\n\t * Prompt user and open browser to view enhanced issue.\n\t * Matches the pattern from the issue specification.\n\t */\n\tprivate async promptAndOpenBrowser(commentUrl: string): Promise<void> {\n\t\ttry {\n\t\t\t// Prompt user with custom message\n\t\t\tconst key = await waitForKeypress(\n\t\t\t\t'Press q to quit or any other key to view the enhanced issue in a web browser...'\n\t\t\t)\n\n\t\t\t// Check if user pressed 'q' to quit\n\t\t\tif (key.toLowerCase() === 'q') {\n\t\t\t\tlogger.info('Skipping browser opening')\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Open browser with comment URL\n\t\t\tawait openBrowser(commentUrl)\n\t\t} catch (error) {\n\t\t\t// Browser opening failures should not be fatal\n\t\t\tlogger.warn(`Failed to open browser: ${error instanceof Error ? error.message : 'Unknown error'}`)\n\t\t}\n\t}\n\n}\n"],"mappings":"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","names":[]}
|