@iloom/cli 0.7.3 → 0.7.5
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 +6 -4
- package/dist/{BranchNamingService-FLPUUFOB.js → BranchNamingService-AO7BPIUJ.js} +2 -2
- package/dist/{ClaudeContextManager-KE5TBZVZ.js → ClaudeContextManager-Y2YJC6BU.js} +4 -4
- package/dist/{ClaudeService-CRSETT3A.js → ClaudeService-NDVFQRKC.js} +3 -3
- package/dist/{LoomLauncher-NL65LSKP.js → LoomLauncher-U2B3VHPC.js} +4 -4
- package/dist/{PRManager-2ABCWXHW.js → PRManager-6ZJZRG5Z.js} +4 -4
- package/dist/README.md +6 -4
- package/dist/agents/iloom-issue-analyze-and-plan.md +1 -1
- package/dist/agents/iloom-issue-analyzer.md +1 -1
- package/dist/agents/iloom-issue-complexity-evaluator.md +1 -1
- package/dist/agents/iloom-issue-enhancer.md +1 -1
- package/dist/agents/iloom-issue-implementer.md +1 -1
- package/dist/agents/iloom-issue-planner.md +1 -1
- package/dist/agents/iloom-issue-reviewer.md +1 -1
- package/dist/{chunk-FM4KBPVA.js → chunk-3K3WY3BN.js} +2 -118
- package/dist/chunk-3K3WY3BN.js.map +1 -0
- package/dist/{chunk-6TL3BYH6.js → chunk-64HCHVJM.js} +2 -2
- package/dist/{chunk-QQFBMCAH.js → chunk-77VLG2KP.js} +20 -17
- package/dist/chunk-77VLG2KP.js.map +1 -0
- package/dist/{chunk-FEAJR6PN.js → chunk-C7YW5IMS.js} +2 -2
- package/dist/{chunk-DAOS6EC3.js → chunk-CAXFWFV6.js} +5 -3
- package/dist/{chunk-DAOS6EC3.js.map → chunk-CAXFWFV6.js.map} +1 -1
- package/dist/chunk-CFQVOTHO.js +111 -0
- package/dist/chunk-CFQVOTHO.js.map +1 -0
- package/dist/{chunk-AFRICMSW.js → chunk-ENMTWE74.js} +2 -2
- package/dist/{chunk-FP7G7DG3.js → chunk-IGKPPACU.js} +8 -3
- package/dist/chunk-IGKPPACU.js.map +1 -0
- package/dist/{chunk-CNSTXBJ3.js → chunk-KSXA2NOJ.js} +9 -5
- package/dist/chunk-KSXA2NOJ.js.map +1 -0
- package/dist/{chunk-GJMEKEI5.js → chunk-LZBSLO6S.js} +76 -1
- package/dist/chunk-LZBSLO6S.js.map +1 -0
- package/dist/{chunk-YQNSZKKT.js → chunk-NEPH2O4C.js} +8 -4
- package/dist/chunk-NEPH2O4C.js.map +1 -0
- package/dist/{chunk-KVS4XGBQ.js → chunk-O36JLYNW.js} +2 -2
- package/dist/{chunk-C3AKFAIR.js → chunk-Q457PKGH.js} +2 -2
- package/dist/{chunk-EPPPDVHD.js → chunk-TB6475EW.js} +6 -4
- package/dist/chunk-TB6475EW.js.map +1 -0
- package/dist/{chunk-HVQNVRAF.js → chunk-VYKKWU36.js} +96 -3
- package/dist/chunk-VYKKWU36.js.map +1 -0
- package/dist/{chunk-453NC377.js → chunk-WZYBHD7P.js} +3 -106
- package/dist/chunk-WZYBHD7P.js.map +1 -0
- package/dist/chunk-XAMBIVXE.js +121 -0
- package/dist/chunk-XAMBIVXE.js.map +1 -0
- package/dist/{claude-6H36IBHO.js → claude-V4HRPR4Z.js} +2 -2
- package/dist/{cleanup-77U5ATYI.js → cleanup-DB7EFBF3.js} +9 -6
- package/dist/{cleanup-77U5ATYI.js.map → cleanup-DB7EFBF3.js.map} +1 -1
- package/dist/cli.js +104 -156
- package/dist/cli.js.map +1 -1
- package/dist/{commit-ONRXU67O.js → commit-NGMDWWAP.js} +4 -4
- package/dist/{dev-server-UKAPBGUR.js → dev-server-OAP3RZC6.js} +4 -3
- package/dist/{dev-server-UKAPBGUR.js.map → dev-server-OAP3RZC6.js.map} +1 -1
- package/dist/{feedback-K3A4QUSG.js → feedback-ZLAX3BVL.js} +4 -3
- package/dist/{feedback-K3A4QUSG.js.map → feedback-ZLAX3BVL.js.map} +1 -1
- package/dist/{ignite-YUAOJ5PP.js → ignite-HA2OJF6Z.js} +26 -40
- package/dist/ignite-HA2OJF6Z.js.map +1 -0
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/{init-XQQMFDM6.js → init-S6IEGRSX.js} +3 -3
- package/dist/mcp/issue-management-server.js +157 -9
- package/dist/mcp/issue-management-server.js.map +1 -1
- package/dist/{open-QI63XQ4F.js → open-IN3LUZXX.js} +4 -3
- package/dist/{open-QI63XQ4F.js.map → open-IN3LUZXX.js.map} +1 -1
- package/dist/{projects-TWY4RT2Z.js → projects-CTRTTMSK.js} +25 -9
- package/dist/projects-CTRTTMSK.js.map +1 -0
- package/dist/prompts/issue-prompt.txt +16 -0
- package/dist/prompts/pr-prompt.txt +33 -13
- package/dist/prompts/regular-prompt.txt +7 -0
- package/dist/{rebase-QYCRF7JG.js → rebase-RLEVFHWN.js} +3 -3
- package/dist/{run-YDVYORT2.js → run-QEIS2EH2.js} +4 -3
- package/dist/{run-YDVYORT2.js.map → run-QEIS2EH2.js.map} +1 -1
- package/dist/{summary-G6L3VAKK.js → summary-2KLNHVTN.js} +4 -4
- package/dist/{test-webserver-NRMGT2HB.js → test-webserver-J6SMNLU2.js} +3 -2
- package/dist/{test-webserver-NRMGT2HB.js.map → test-webserver-J6SMNLU2.js.map} +1 -1
- package/package.json +1 -1
- package/dist/chunk-453NC377.js.map +0 -1
- package/dist/chunk-CNSTXBJ3.js.map +0 -1
- package/dist/chunk-EPPPDVHD.js.map +0 -1
- package/dist/chunk-FM4KBPVA.js.map +0 -1
- package/dist/chunk-FP7G7DG3.js.map +0 -1
- package/dist/chunk-GJMEKEI5.js.map +0 -1
- package/dist/chunk-HVQNVRAF.js.map +0 -1
- package/dist/chunk-QQFBMCAH.js.map +0 -1
- package/dist/chunk-YQNSZKKT.js.map +0 -1
- package/dist/ignite-YUAOJ5PP.js.map +0 -1
- package/dist/projects-TWY4RT2Z.js.map +0 -1
- /package/dist/{BranchNamingService-FLPUUFOB.js.map → BranchNamingService-AO7BPIUJ.js.map} +0 -0
- /package/dist/{ClaudeContextManager-KE5TBZVZ.js.map → ClaudeContextManager-Y2YJC6BU.js.map} +0 -0
- /package/dist/{ClaudeService-CRSETT3A.js.map → ClaudeService-NDVFQRKC.js.map} +0 -0
- /package/dist/{LoomLauncher-NL65LSKP.js.map → LoomLauncher-U2B3VHPC.js.map} +0 -0
- /package/dist/{PRManager-2ABCWXHW.js.map → PRManager-6ZJZRG5Z.js.map} +0 -0
- /package/dist/{chunk-6TL3BYH6.js.map → chunk-64HCHVJM.js.map} +0 -0
- /package/dist/{chunk-FEAJR6PN.js.map → chunk-C7YW5IMS.js.map} +0 -0
- /package/dist/{chunk-AFRICMSW.js.map → chunk-ENMTWE74.js.map} +0 -0
- /package/dist/{chunk-KVS4XGBQ.js.map → chunk-O36JLYNW.js.map} +0 -0
- /package/dist/{chunk-C3AKFAIR.js.map → chunk-Q457PKGH.js.map} +0 -0
- /package/dist/{claude-6H36IBHO.js.map → claude-V4HRPR4Z.js.map} +0 -0
- /package/dist/{commit-ONRXU67O.js.map → commit-NGMDWWAP.js.map} +0 -0
- /package/dist/{init-XQQMFDM6.js.map → init-S6IEGRSX.js.map} +0 -0
- /package/dist/{rebase-QYCRF7JG.js.map → rebase-RLEVFHWN.js.map} +0 -0
- /package/dist/{summary-G6L3VAKK.js.map → summary-2KLNHVTN.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SessionSummaryService
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KSXA2NOJ.js";
|
|
5
5
|
import "./chunk-NXMDEL3F.js";
|
|
6
6
|
import {
|
|
7
7
|
CLIIsolationManager,
|
|
@@ -9,18 +9,18 @@ import {
|
|
|
9
9
|
EnvironmentManager,
|
|
10
10
|
LoomManager,
|
|
11
11
|
ResourceCleanup
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-77VLG2KP.js";
|
|
13
13
|
import {
|
|
14
14
|
BuildRunner,
|
|
15
15
|
MergeManager
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CAXFWFV6.js";
|
|
17
17
|
import {
|
|
18
|
-
IssueTrackerFactory
|
|
19
|
-
|
|
20
|
-
} from "./chunk-FM4KBPVA.js";
|
|
18
|
+
IssueTrackerFactory
|
|
19
|
+
} from "./chunk-3K3WY3BN.js";
|
|
21
20
|
import {
|
|
22
21
|
ProcessManager
|
|
23
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-WZYBHD7P.js";
|
|
23
|
+
import "./chunk-CFQVOTHO.js";
|
|
24
24
|
import {
|
|
25
25
|
IdentifierParser
|
|
26
26
|
} from "./chunk-5V74K5ZA.js";
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
import {
|
|
31
31
|
InitCommand,
|
|
32
32
|
ShellCompletion
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-C7YW5IMS.js";
|
|
34
34
|
import {
|
|
35
35
|
FirstRunManager
|
|
36
36
|
} from "./chunk-Q7POFB5Q.js";
|
|
@@ -38,7 +38,8 @@ import "./chunk-F2PWIRV4.js";
|
|
|
38
38
|
import {
|
|
39
39
|
IssueEnhancementService,
|
|
40
40
|
capitalizeFirstLetter
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-VYKKWU36.js";
|
|
42
|
+
import "./chunk-XAMBIVXE.js";
|
|
42
43
|
import {
|
|
43
44
|
ProjectCapabilityDetector
|
|
44
45
|
} from "./chunk-7GLZVDPQ.js";
|
|
@@ -49,7 +50,7 @@ import {
|
|
|
49
50
|
CommitManager,
|
|
50
51
|
UserAbortedCommitError,
|
|
51
52
|
ValidationRunner
|
|
52
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-NEPH2O4C.js";
|
|
53
54
|
import {
|
|
54
55
|
installDependencies
|
|
55
56
|
} from "./chunk-RD7I2Q2F.js";
|
|
@@ -59,13 +60,13 @@ import {
|
|
|
59
60
|
import "./chunk-XPKN3QWY.js";
|
|
60
61
|
import {
|
|
61
62
|
PRManager
|
|
62
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-TB6475EW.js";
|
|
63
64
|
import {
|
|
64
65
|
openBrowser
|
|
65
66
|
} from "./chunk-YETJNRQM.js";
|
|
66
67
|
import {
|
|
67
68
|
IssueManagementProviderFactory
|
|
68
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-LZBSLO6S.js";
|
|
69
70
|
import "./chunk-HBJITKSZ.js";
|
|
70
71
|
import {
|
|
71
72
|
getConfiguredRepoFromSettings,
|
|
@@ -78,15 +79,15 @@ import {
|
|
|
78
79
|
} from "./chunk-O7VL5N6S.js";
|
|
79
80
|
import {
|
|
80
81
|
ClaudeContextManager
|
|
81
|
-
} from "./chunk-
|
|
82
|
-
import "./chunk-
|
|
82
|
+
} from "./chunk-64HCHVJM.js";
|
|
83
|
+
import "./chunk-O36JLYNW.js";
|
|
83
84
|
import "./chunk-TIYJEEVO.js";
|
|
84
85
|
import {
|
|
85
86
|
extractSettingsOverrides
|
|
86
87
|
} from "./chunk-GYCR2LOU.js";
|
|
87
88
|
import {
|
|
88
89
|
DefaultBranchNamingService
|
|
89
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-Q457PKGH.js";
|
|
90
91
|
import {
|
|
91
92
|
GitCommandError,
|
|
92
93
|
executeGitCommand,
|
|
@@ -116,9 +117,7 @@ import {
|
|
|
116
117
|
waitForKeypress
|
|
117
118
|
} from "./chunk-ZX3GTM7O.js";
|
|
118
119
|
import "./chunk-433MOLAU.js";
|
|
119
|
-
import
|
|
120
|
-
launchClaude
|
|
121
|
-
} from "./chunk-FP7G7DG3.js";
|
|
120
|
+
import "./chunk-IGKPPACU.js";
|
|
122
121
|
import {
|
|
123
122
|
getLogger,
|
|
124
123
|
withLogger
|
|
@@ -195,6 +194,7 @@ async function launchFirstRunSetup() {
|
|
|
195
194
|
var StartCommand = class {
|
|
196
195
|
constructor(issueTracker, loomManager, _agentManager, settingsManager) {
|
|
197
196
|
this.loomManager = null;
|
|
197
|
+
this.githubService = null;
|
|
198
198
|
this.issueTracker = issueTracker;
|
|
199
199
|
this.settingsManager = settingsManager ?? new SettingsManager();
|
|
200
200
|
this.providedLoomManager = loomManager;
|
|
@@ -206,6 +206,14 @@ var StartCommand = class {
|
|
|
206
206
|
getLogger().debug(`Loaded ${Object.keys(envResult.parsed).length} environment variables`);
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Get or create a GitHubService instance for PR operations
|
|
211
|
+
* Used when the configured issue tracker doesn't support PRs (e.g., Linear)
|
|
212
|
+
*/
|
|
213
|
+
getGitHubService() {
|
|
214
|
+
this.githubService ??= new GitHubService();
|
|
215
|
+
return this.githubService;
|
|
216
|
+
}
|
|
209
217
|
/**
|
|
210
218
|
* Initialize LoomManager with the main worktree path
|
|
211
219
|
* Uses lazy initialization to ensure we have the correct path
|
|
@@ -400,7 +408,7 @@ var StartCommand = class {
|
|
|
400
408
|
throw new Error("Missing required argument: identifier");
|
|
401
409
|
}
|
|
402
410
|
const spaceCount = (trimmedIdentifier.match(/ /g) ?? []).length;
|
|
403
|
-
if (trimmedIdentifier.length > 25 && spaceCount
|
|
411
|
+
if (trimmedIdentifier.length > 25 && spaceCount >= 1) {
|
|
404
412
|
return {
|
|
405
413
|
type: "description",
|
|
406
414
|
originalInput: hasLeadingSpace ? " " + trimmedIdentifier : trimmedIdentifier
|
|
@@ -438,24 +446,42 @@ var StartCommand = class {
|
|
|
438
446
|
const numericMatch = trimmedIdentifier.match(numericPattern);
|
|
439
447
|
if (numericMatch == null ? void 0 : numericMatch[1]) {
|
|
440
448
|
const number = parseInt(numericMatch[1], 10);
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
449
|
+
if (this.issueTracker.supportsPullRequests) {
|
|
450
|
+
const detection = await this.issueTracker.detectInputType(
|
|
451
|
+
trimmedIdentifier,
|
|
452
|
+
repo
|
|
453
|
+
);
|
|
454
|
+
if (detection.type === "pr") {
|
|
455
|
+
return {
|
|
456
|
+
type: "pr",
|
|
457
|
+
number: detection.identifier ? parseInt(detection.identifier, 10) : number,
|
|
458
|
+
originalInput: trimmedIdentifier
|
|
459
|
+
};
|
|
460
|
+
} else if (detection.type === "issue") {
|
|
461
|
+
return {
|
|
462
|
+
type: "issue",
|
|
463
|
+
number: detection.identifier ? parseInt(detection.identifier, 10) : number,
|
|
464
|
+
originalInput: trimmedIdentifier
|
|
465
|
+
};
|
|
466
|
+
} else {
|
|
467
|
+
throw new Error(`Could not find issue or PR #${number}`);
|
|
468
|
+
}
|
|
457
469
|
} else {
|
|
458
|
-
|
|
470
|
+
const githubService = this.getGitHubService();
|
|
471
|
+
const detection = await githubService.detectInputType(trimmedIdentifier, repo);
|
|
472
|
+
if (detection.type === "pr") {
|
|
473
|
+
return {
|
|
474
|
+
type: "pr",
|
|
475
|
+
number: detection.identifier ? parseInt(detection.identifier, 10) : number,
|
|
476
|
+
originalInput: trimmedIdentifier
|
|
477
|
+
};
|
|
478
|
+
} else {
|
|
479
|
+
return {
|
|
480
|
+
type: "issue",
|
|
481
|
+
number,
|
|
482
|
+
originalInput: trimmedIdentifier
|
|
483
|
+
};
|
|
484
|
+
}
|
|
459
485
|
}
|
|
460
486
|
}
|
|
461
487
|
return {
|
|
@@ -473,11 +499,14 @@ var StartCommand = class {
|
|
|
473
499
|
if (!parsed.number) {
|
|
474
500
|
throw new Error("Invalid PR number");
|
|
475
501
|
}
|
|
476
|
-
if (
|
|
477
|
-
|
|
502
|
+
if (this.issueTracker.supportsPullRequests && this.issueTracker.fetchPR && this.issueTracker.validatePRState) {
|
|
503
|
+
const pr = await this.issueTracker.fetchPR(parsed.number, repo);
|
|
504
|
+
await this.issueTracker.validatePRState(pr);
|
|
505
|
+
} else {
|
|
506
|
+
const githubService = this.getGitHubService();
|
|
507
|
+
const pr = await githubService.fetchPR(parsed.number, repo);
|
|
508
|
+
await githubService.validatePRState(pr);
|
|
478
509
|
}
|
|
479
|
-
const pr = await this.issueTracker.fetchPR(parsed.number, repo);
|
|
480
|
-
await this.issueTracker.validatePRState(pr);
|
|
481
510
|
getLogger().debug(`Validated PR #${parsed.number}`);
|
|
482
511
|
break;
|
|
483
512
|
}
|
|
@@ -641,20 +670,18 @@ var AddIssueCommand = class {
|
|
|
641
670
|
|
|
642
671
|
// src/commands/enhance.ts
|
|
643
672
|
var EnhanceCommand = class {
|
|
644
|
-
constructor(issueTracker,
|
|
673
|
+
constructor(issueTracker, enhancementService, settingsManager) {
|
|
645
674
|
this.issueTracker = issueTracker;
|
|
646
|
-
this.
|
|
675
|
+
this.enhancementService = enhancementService;
|
|
647
676
|
this.settingsManager = settingsManager ?? new SettingsManager();
|
|
648
677
|
}
|
|
649
678
|
/**
|
|
650
679
|
* Execute the enhance command workflow:
|
|
651
680
|
* 1. Validate issue number
|
|
652
681
|
* 2. Fetch issue to verify it exists
|
|
653
|
-
* 3.
|
|
654
|
-
* 4.
|
|
655
|
-
* 5.
|
|
656
|
-
* 6. Handle browser interaction based on outcome (unless --json mode)
|
|
657
|
-
* 7. Return result object when --json mode
|
|
682
|
+
* 3. Invoke enhancement service
|
|
683
|
+
* 4. Handle browser interaction based on outcome (unless --json mode)
|
|
684
|
+
* 5. Return result object when --json mode
|
|
658
685
|
*/
|
|
659
686
|
async execute(input) {
|
|
660
687
|
const { issueNumber, options } = input;
|
|
@@ -677,41 +704,13 @@ var EnhanceCommand = class {
|
|
|
677
704
|
}
|
|
678
705
|
const issue = await this.issueTracker.fetchIssue(issueNumber, repo);
|
|
679
706
|
getLogger().debug("Issue fetched successfully", { number: issue.number, title: issue.title });
|
|
680
|
-
getLogger().debug("Loading agent configurations...");
|
|
681
|
-
const loadedAgents = await this.agentManager.loadAgents(settings);
|
|
682
|
-
const agents = this.agentManager.formatForCli(loadedAgents);
|
|
683
|
-
let mcpConfig;
|
|
684
|
-
let allowedTools;
|
|
685
|
-
let disallowedTools;
|
|
686
|
-
try {
|
|
687
|
-
const provider = this.issueTracker.providerName;
|
|
688
|
-
mcpConfig = await generateIssueManagementMcpConfig("issue", repo, provider, settings);
|
|
689
|
-
getLogger().debug("Generated MCP configuration for issue management:", { mcpConfig });
|
|
690
|
-
allowedTools = [
|
|
691
|
-
"mcp__issue_management__get_issue",
|
|
692
|
-
"mcp__issue_management__get_comment",
|
|
693
|
-
"mcp__issue_management__create_comment",
|
|
694
|
-
"mcp__issue_management__update_comment",
|
|
695
|
-
"mcp__issue_management__create_issue"
|
|
696
|
-
];
|
|
697
|
-
disallowedTools = ["Bash(gh api:*)"];
|
|
698
|
-
getLogger().debug("Configured tool filtering for issue workflow", { allowedTools, disallowedTools });
|
|
699
|
-
} catch (error) {
|
|
700
|
-
getLogger().warn(`Failed to generate MCP config: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
701
|
-
}
|
|
702
707
|
if (!isJsonMode) {
|
|
703
708
|
getLogger().info("Invoking enhancer agent. This may take a moment...");
|
|
704
709
|
}
|
|
705
|
-
const
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
agents,
|
|
710
|
-
...mcpConfig && { mcpConfig },
|
|
711
|
-
...allowedTools && { allowedTools },
|
|
712
|
-
...disallowedTools && { disallowedTools }
|
|
713
|
-
});
|
|
714
|
-
const result = this.parseEnhancerResponse(response);
|
|
710
|
+
const enhanceOptions = {};
|
|
711
|
+
if (author !== void 0) enhanceOptions.author = author;
|
|
712
|
+
if (repo !== void 0) enhanceOptions.repo = repo;
|
|
713
|
+
const result = await this.enhancementService.enhanceExistingIssue(issueNumber, enhanceOptions);
|
|
715
714
|
if (isJsonMode) {
|
|
716
715
|
const commentId = result.url ? this.extractCommentId(result.url) : 0;
|
|
717
716
|
const resultData = {
|
|
@@ -758,48 +757,6 @@ var EnhanceCommand = class {
|
|
|
758
757
|
throw new Error("Issue identifier cannot be empty");
|
|
759
758
|
}
|
|
760
759
|
}
|
|
761
|
-
/**
|
|
762
|
-
* Construct the prompt for the orchestrating Claude instance.
|
|
763
|
-
* This prompt is very clear about expected output format to ensure reliable parsing.
|
|
764
|
-
*/
|
|
765
|
-
constructPrompt(issueNumber, author) {
|
|
766
|
-
const authorInstruction = author ? `
|
|
767
|
-
IMPORTANT: When you create your analysis comment, tag @${author} in the "Questions for Reporter" section if you have questions.
|
|
768
|
-
` : "";
|
|
769
|
-
return `Execute @agent-iloom-issue-enhancer ${issueNumber}${authorInstruction}
|
|
770
|
-
|
|
771
|
-
## OUTPUT REQUIREMENTS
|
|
772
|
-
* If the issue was not enhanced, return ONLY: "No enhancement needed"
|
|
773
|
-
* If the issue WAS enhanced, return ONLY: <FULL URL OF THE COMMENT INCLUDING COMMENT ID>
|
|
774
|
-
* If you encounter permission/authentication/access errors, return ONLY: "Permission denied: <specific error description>"
|
|
775
|
-
* 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"
|
|
776
|
-
* CONTEXT: Your output is going to be parsed programmatically, so adherence to the output requirements is CRITICAL.`;
|
|
777
|
-
}
|
|
778
|
-
/**
|
|
779
|
-
* Parse the response from the enhancer agent.
|
|
780
|
-
* Returns either { enhanced: false } or { enhanced: true, url: "..." }
|
|
781
|
-
* Throws specific errors for permission issues.
|
|
782
|
-
*/
|
|
783
|
-
parseEnhancerResponse(response) {
|
|
784
|
-
if (!response || typeof response !== "string") {
|
|
785
|
-
throw new Error("No response from enhancer agent");
|
|
786
|
-
}
|
|
787
|
-
const trimmed = response.trim();
|
|
788
|
-
getLogger().debug(`RESPONSE FROM ENHANCER AGENT: '${trimmed}'`);
|
|
789
|
-
if (trimmed.toLowerCase().startsWith("permission denied:")) {
|
|
790
|
-
const errorMessage = trimmed.substring("permission denied:".length).trim();
|
|
791
|
-
throw new Error(`Permission denied: ${errorMessage}`);
|
|
792
|
-
}
|
|
793
|
-
if (trimmed.toLowerCase().includes("no enhancement needed")) {
|
|
794
|
-
return { enhanced: false };
|
|
795
|
-
}
|
|
796
|
-
const urlPattern = /https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/\d+#issuecomment-\d+/;
|
|
797
|
-
const match = trimmed.match(urlPattern);
|
|
798
|
-
if (match) {
|
|
799
|
-
return { enhanced: true, url: match[0] };
|
|
800
|
-
}
|
|
801
|
-
throw new Error(`Unexpected response from enhancer agent: ${trimmed}`);
|
|
802
|
-
}
|
|
803
760
|
/**
|
|
804
761
|
* Prompt user and open browser to view enhanced issue.
|
|
805
762
|
* Matches the pattern from the issue specification.
|
|
@@ -860,7 +817,7 @@ var FinishCommand = class {
|
|
|
860
817
|
const neonProvider = createNeonProviderFromSettings(settings);
|
|
861
818
|
const databaseManager = new DatabaseManager(neonProvider, environmentManager, databaseUrlEnvVarName);
|
|
862
819
|
const cliIsolationManager = new CLIIsolationManager();
|
|
863
|
-
const { DefaultBranchNamingService: DefaultBranchNamingService2 } = await import("./BranchNamingService-
|
|
820
|
+
const { DefaultBranchNamingService: DefaultBranchNamingService2 } = await import("./BranchNamingService-AO7BPIUJ.js");
|
|
864
821
|
this.loomManager ??= new LoomManager(
|
|
865
822
|
this.gitWorktreeManager,
|
|
866
823
|
this.issueTracker,
|
|
@@ -1283,20 +1240,10 @@ var FinishCommand = class {
|
|
|
1283
1240
|
const settings = await this.settingsManager.loadSettings(worktree.path);
|
|
1284
1241
|
const mergeBehavior = settings.mergeBehavior ?? { mode: "local" };
|
|
1285
1242
|
if (mergeBehavior.mode === "github-pr") {
|
|
1286
|
-
if (!this.issueTracker.supportsPullRequests) {
|
|
1287
|
-
throw new Error(
|
|
1288
|
-
`The 'github-pr' merge mode requires a GitHub-compatible issue tracker. Your current provider (${this.issueTracker.providerName}) does not support pull requests. Either change mergeBehavior.mode to 'local' in your settings, or use GitHub as your issue tracker.`
|
|
1289
|
-
);
|
|
1290
|
-
}
|
|
1291
1243
|
await this.executeGitHubPRWorkflow(parsed, options, worktree, settings, result);
|
|
1292
1244
|
return;
|
|
1293
1245
|
}
|
|
1294
1246
|
if (mergeBehavior.mode === "github-draft-pr") {
|
|
1295
|
-
if (!this.issueTracker.supportsPullRequests) {
|
|
1296
|
-
throw new Error(
|
|
1297
|
-
`The 'github-draft-pr' merge mode requires a GitHub-compatible issue tracker. Your provider (${this.issueTracker.providerName}) does not support pull requests.`
|
|
1298
|
-
);
|
|
1299
|
-
}
|
|
1300
1247
|
const { MetadataManager: MetadataManager3 } = await import("./MetadataManager-XJ2YB762.js");
|
|
1301
1248
|
const metadataManager2 = new MetadataManager3();
|
|
1302
1249
|
const metadata = await metadataManager2.readMetadata(worktree.path);
|
|
@@ -2229,7 +2176,7 @@ function parseIssueIdentifier(value) {
|
|
|
2229
2176
|
const parsed = parseInt(value, 10);
|
|
2230
2177
|
return !isNaN(parsed) && String(parsed) === value ? parsed : value;
|
|
2231
2178
|
}
|
|
2232
|
-
program.name("iloom").description(packageJson.description).version(packageJson.version).option("--debug", "Enable debug output (default: based on ILOOM_DEBUG env var)").option("--completion", "Output shell completion script for current shell").option("--set <key=value>", "Override any setting using dot notation (repeatable, e.g., --set workflows.issue.startIde=false)").allowUnknownOption().hook("preAction", async (thisCommand, actionCommand) => {
|
|
2179
|
+
program.name("iloom").description(packageJson.description).version(packageJson.version).option("--debug", "Enable debug output (default: based on ILOOM_DEBUG env var)").option("--completion", "Output shell completion script for current shell").option("--set <key=value>", "Override any setting using dot notation (repeatable, e.g., --set workflows.issue.startIde=false)").allowUnknownOption().addHelpText("afterAll", "\nBy using iloom, you agree to our Terms of Service: https://iloom.ai/terms").hook("preAction", async (thisCommand, actionCommand) => {
|
|
2233
2180
|
const options = thisCommand.opts();
|
|
2234
2181
|
const envDebug = process.env.ILOOM_DEBUG === "true";
|
|
2235
2182
|
const debugEnabled = options.debug !== void 0 ? options.debug : envDebug;
|
|
@@ -2262,7 +2209,7 @@ program.name("iloom").description(packageJson.description).version(packageJson.v
|
|
|
2262
2209
|
}
|
|
2263
2210
|
await validateSettingsForCommand(actionCommand);
|
|
2264
2211
|
await validateGhCliForCommand(actionCommand);
|
|
2265
|
-
await validateIdeForStartCommand(
|
|
2212
|
+
await validateIdeForStartCommand(actionCommand);
|
|
2266
2213
|
});
|
|
2267
2214
|
async function validateSettingsForCommand(command) {
|
|
2268
2215
|
var _a, _b;
|
|
@@ -2345,7 +2292,7 @@ async function validateGhCliForCommand(command) {
|
|
|
2345
2292
|
}
|
|
2346
2293
|
async function validateIdeForStartCommand(command) {
|
|
2347
2294
|
var _a, _b;
|
|
2348
|
-
const commandName = command.
|
|
2295
|
+
const commandName = command.name();
|
|
2349
2296
|
if (commandName !== "start") {
|
|
2350
2297
|
return;
|
|
2351
2298
|
}
|
|
@@ -2389,7 +2336,7 @@ async function autoLaunchInitForMultipleRemotes() {
|
|
|
2389
2336
|
await waitForKeypress2("Press any key to start configuration...");
|
|
2390
2337
|
logger.info("");
|
|
2391
2338
|
try {
|
|
2392
|
-
const { InitCommand: InitCommand2 } = await import("./init-
|
|
2339
|
+
const { InitCommand: InitCommand2 } = await import("./init-S6IEGRSX.js");
|
|
2393
2340
|
const initCommand = new InitCommand2();
|
|
2394
2341
|
const customInitialMessage = "Help me configure which git remote iloom should use for GitHub operations. I have multiple remotes and need to select the correct one.";
|
|
2395
2342
|
await initCommand.execute(customInitialMessage);
|
|
@@ -2490,7 +2437,7 @@ program.command("add-issue").alias("a").description("Create and enhance GitHub i
|
|
|
2490
2437
|
});
|
|
2491
2438
|
program.command("feedback").alias("f").description("Submit feedback/bug report to iloom-cli repository").argument("<description>", "Feedback title (>30 chars, >2 spaces; or any non-empty text when --body provided)").option("--body <text>", "Body text for feedback (added after diagnostics)").action(async (description, options) => {
|
|
2492
2439
|
try {
|
|
2493
|
-
const { FeedbackCommand } = await import("./feedback-
|
|
2440
|
+
const { FeedbackCommand } = await import("./feedback-ZLAX3BVL.js");
|
|
2494
2441
|
const command = new FeedbackCommand();
|
|
2495
2442
|
const feedbackOptions = {};
|
|
2496
2443
|
if (options.body !== void 0) {
|
|
@@ -2513,7 +2460,8 @@ program.command("enhance").description("Apply enhancement agent to existing GitH
|
|
|
2513
2460
|
const settingsManager = new SettingsManager();
|
|
2514
2461
|
const settings = await settingsManager.loadSettings();
|
|
2515
2462
|
const issueTracker = IssueTrackerFactory.create(settings);
|
|
2516
|
-
const
|
|
2463
|
+
const enhancementService = new IssueEnhancementService(issueTracker, new AgentManager(), settingsManager);
|
|
2464
|
+
const command = new EnhanceCommand(issueTracker, enhancementService, settingsManager);
|
|
2517
2465
|
const result = await command.execute({
|
|
2518
2466
|
issueNumber,
|
|
2519
2467
|
options: {
|
|
@@ -2574,7 +2522,7 @@ program.command("finish").alias("dn").description("Merge work and cleanup worksp
|
|
|
2574
2522
|
program.command("commit").alias("c").description("Commit all uncommitted files with issue reference").option("-m, --message <text>", "Custom commit message (skip Claude generation)").option("--fixes", 'Use "Fixes #N" trailer instead of "Refs #N" (closes issue)').option("--no-review", "Skip commit message review prompt").option("--json", "Output result as JSON (implies --no-review)").option("--wip-commit", "Quick WIP commit: skip validations and pre-commit hooks").action(async (options) => {
|
|
2575
2523
|
const executeAction = async () => {
|
|
2576
2524
|
try {
|
|
2577
|
-
const { CommitCommand } = await import("./commit-
|
|
2525
|
+
const { CommitCommand } = await import("./commit-NGMDWWAP.js");
|
|
2578
2526
|
const command = new CommitCommand();
|
|
2579
2527
|
const noReview = options.review === false || options.json === true;
|
|
2580
2528
|
const result = await command.execute({
|
|
@@ -2609,7 +2557,7 @@ program.command("commit").alias("c").description("Commit all uncommitted files w
|
|
|
2609
2557
|
});
|
|
2610
2558
|
program.command("rebase").description("Rebase current branch on main with Claude-assisted conflict resolution").option("-f, --force", "Skip confirmation prompts").option("-n, --dry-run", "Preview actions without executing").action(async (options) => {
|
|
2611
2559
|
try {
|
|
2612
|
-
const { RebaseCommand } = await import("./rebase-
|
|
2560
|
+
const { RebaseCommand } = await import("./rebase-RLEVFHWN.js");
|
|
2613
2561
|
const command = new RebaseCommand();
|
|
2614
2562
|
await command.execute(options);
|
|
2615
2563
|
} catch (error) {
|
|
@@ -2621,7 +2569,7 @@ program.command("spin").alias("ignite").description("Launch Claude with auto-det
|
|
|
2621
2569
|
new Option("--one-shot <mode>", "One-shot automation mode").choices(["default", "noReview", "bypassPermissions"]).default("default")
|
|
2622
2570
|
).action(async (options) => {
|
|
2623
2571
|
try {
|
|
2624
|
-
const { IgniteCommand } = await import("./ignite-
|
|
2572
|
+
const { IgniteCommand } = await import("./ignite-HA2OJF6Z.js");
|
|
2625
2573
|
const command = new IgniteCommand();
|
|
2626
2574
|
await command.execute(options.oneShot ?? "default");
|
|
2627
2575
|
} catch (error) {
|
|
@@ -2632,7 +2580,7 @@ program.command("spin").alias("ignite").description("Launch Claude with auto-det
|
|
|
2632
2580
|
program.command("open").description("Open workspace in browser or run CLI tool").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").allowUnknownOption().action(async (identifier, _options, command) => {
|
|
2633
2581
|
try {
|
|
2634
2582
|
const args = (command == null ? void 0 : command.args) ? command.args.slice(identifier ? 1 : 0) : [];
|
|
2635
|
-
const { OpenCommand } = await import("./open-
|
|
2583
|
+
const { OpenCommand } = await import("./open-IN3LUZXX.js");
|
|
2636
2584
|
const cmd = new OpenCommand();
|
|
2637
2585
|
const input = identifier ? { identifier, args } : { args };
|
|
2638
2586
|
await cmd.execute(input);
|
|
@@ -2644,7 +2592,7 @@ program.command("open").description("Open workspace in browser or run CLI tool")
|
|
|
2644
2592
|
program.command("run").description("Run CLI tool or open workspace in browser").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").allowUnknownOption().action(async (identifier, _options, command) => {
|
|
2645
2593
|
try {
|
|
2646
2594
|
const args = (command == null ? void 0 : command.args) ? command.args.slice(identifier ? 1 : 0) : [];
|
|
2647
|
-
const { RunCommand } = await import("./run-
|
|
2595
|
+
const { RunCommand } = await import("./run-QEIS2EH2.js");
|
|
2648
2596
|
const cmd = new RunCommand();
|
|
2649
2597
|
const input = identifier ? { identifier, args } : { args };
|
|
2650
2598
|
await cmd.execute(input);
|
|
@@ -2655,7 +2603,7 @@ program.command("run").description("Run CLI tool or open workspace in browser").
|
|
|
2655
2603
|
});
|
|
2656
2604
|
program.command("dev-server").alias("dev").description("Start dev server for workspace (foreground)").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").option("--json", "Output as JSON").action(async (identifier, options) => {
|
|
2657
2605
|
try {
|
|
2658
|
-
const { DevServerCommand } = await import("./dev-server-
|
|
2606
|
+
const { DevServerCommand } = await import("./dev-server-OAP3RZC6.js");
|
|
2659
2607
|
const cmd = new DevServerCommand();
|
|
2660
2608
|
await cmd.execute({ identifier, json: options == null ? void 0 : options.json });
|
|
2661
2609
|
} catch (error) {
|
|
@@ -2716,7 +2664,7 @@ program.command("compile").alias("typecheck").description("Run the compile or ty
|
|
|
2716
2664
|
program.command("cleanup").alias("remove").alias("clean").description("Remove workspaces").argument("[identifier]", "Branch name or issue number to cleanup (auto-detected)").option("-l, --list", "List all worktrees").option("-a, --all", "Remove all worktrees (interactive confirmation)").option("-i, --issue <number>", "Cleanup by issue number", parseInt).option("-f, --force", "Skip confirmations and force removal").option("--dry-run", "Show what would be done without doing it").option("--json", "Output result as JSON").option("--defer <ms>", "Wait specified milliseconds before cleanup", parseInt).action(async (identifier, options) => {
|
|
2717
2665
|
const executeAction = async () => {
|
|
2718
2666
|
try {
|
|
2719
|
-
const { CleanupCommand } = await import("./cleanup-
|
|
2667
|
+
const { CleanupCommand } = await import("./cleanup-DB7EFBF3.js");
|
|
2720
2668
|
const command = new CleanupCommand();
|
|
2721
2669
|
const input = {
|
|
2722
2670
|
options: options ?? {}
|
|
@@ -2939,7 +2887,7 @@ program.command("list").description("Show active workspaces").option("--json", "
|
|
|
2939
2887
|
});
|
|
2940
2888
|
program.command("projects").description("List configured iloom projects").option("--json", "Output as JSON (default behavior)").action(async (options) => {
|
|
2941
2889
|
try {
|
|
2942
|
-
const { ProjectsCommand } = await import("./projects-
|
|
2890
|
+
const { ProjectsCommand } = await import("./projects-CTRTTMSK.js");
|
|
2943
2891
|
const command = new ProjectsCommand();
|
|
2944
2892
|
const result = await command.execute(options);
|
|
2945
2893
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -2950,7 +2898,7 @@ program.command("projects").description("List configured iloom projects").option
|
|
|
2950
2898
|
});
|
|
2951
2899
|
program.command("init").alias("config").description("Initialize iloom configuration").argument("[prompt]", 'Custom initial message to send to Claude (defaults to "Help me configure iloom settings.")').action(async (prompt) => {
|
|
2952
2900
|
try {
|
|
2953
|
-
const { InitCommand: InitCommand2 } = await import("./init-
|
|
2901
|
+
const { InitCommand: InitCommand2 } = await import("./init-S6IEGRSX.js");
|
|
2954
2902
|
const command = new InitCommand2();
|
|
2955
2903
|
const trimmedPrompt = prompt == null ? void 0 : prompt.trim();
|
|
2956
2904
|
const customPrompt = trimmedPrompt && trimmedPrompt.length > 0 ? trimmedPrompt : void 0;
|
|
@@ -2983,7 +2931,7 @@ program.command("update").description("Update iloom-cli to the latest version").
|
|
|
2983
2931
|
program.command("test-github").description("Test GitHub integration (Issue #3)").argument("<identifier>", "Issue number or PR number").option("--no-claude", "Skip Claude for branch name generation").action(async (identifier, options) => {
|
|
2984
2932
|
try {
|
|
2985
2933
|
const { GitHubService: GitHubService2 } = await import("./GitHubService-O7U4UQ7N.js");
|
|
2986
|
-
const { DefaultBranchNamingService: DefaultBranchNamingService2 } = await import("./BranchNamingService-
|
|
2934
|
+
const { DefaultBranchNamingService: DefaultBranchNamingService2 } = await import("./BranchNamingService-AO7BPIUJ.js");
|
|
2987
2935
|
logger.info("Testing GitHub Integration\n");
|
|
2988
2936
|
const service = new GitHubService2();
|
|
2989
2937
|
const branchNaming = new DefaultBranchNamingService2({ useClaude: options.claude !== false });
|
|
@@ -3041,10 +2989,10 @@ program.command("test-github").description("Test GitHub integration (Issue #3)")
|
|
|
3041
2989
|
});
|
|
3042
2990
|
program.command("test-claude").description("Test Claude integration (Issue #10)").option("--detect", "Test Claude CLI detection").option("--version", "Get Claude CLI version").option("--branch <title>", "Test branch name generation with given title").option("--issue <number>", "Issue number for branch generation", "123").option("--launch <prompt>", "Launch Claude with a prompt (headless)").option("--interactive", "Launch Claude interactively (requires --launch)").option("--template <name>", "Test template loading").action(async (options) => {
|
|
3043
2991
|
try {
|
|
3044
|
-
const { detectClaudeCli, getClaudeVersion, generateBranchName, launchClaude
|
|
2992
|
+
const { detectClaudeCli, getClaudeVersion, generateBranchName, launchClaude } = await import("./claude-V4HRPR4Z.js");
|
|
3045
2993
|
const { PromptTemplateManager } = await import("./PromptTemplateManager-7L3HJQQU.js");
|
|
3046
|
-
const { ClaudeService } = await import("./ClaudeService-
|
|
3047
|
-
const { ClaudeContextManager: ClaudeContextManager2 } = await import("./ClaudeContextManager-
|
|
2994
|
+
const { ClaudeService } = await import("./ClaudeService-NDVFQRKC.js");
|
|
2995
|
+
const { ClaudeContextManager: ClaudeContextManager2 } = await import("./ClaudeContextManager-Y2YJC6BU.js");
|
|
3048
2996
|
logger.info("Testing Claude Integration\n");
|
|
3049
2997
|
if (options.detect) {
|
|
3050
2998
|
logger.info("Detecting Claude CLI...");
|
|
@@ -3077,11 +3025,11 @@ program.command("test-claude").description("Test Claude integration (Issue #10)"
|
|
|
3077
3025
|
logger.info(` Mode: ${options.interactive ? "Interactive" : "Headless"}`);
|
|
3078
3026
|
if (options.interactive) {
|
|
3079
3027
|
logger.info(" Launching Claude in new terminal...");
|
|
3080
|
-
await
|
|
3028
|
+
await launchClaude(options.launch, { headless: false });
|
|
3081
3029
|
logger.info(" (Claude should open in a separate process)");
|
|
3082
3030
|
} else {
|
|
3083
3031
|
logger.info(" Waiting for response...");
|
|
3084
|
-
const result = await
|
|
3032
|
+
const result = await launchClaude(options.launch, { headless: true });
|
|
3085
3033
|
if (result) {
|
|
3086
3034
|
logger.success(" Response:");
|
|
3087
3035
|
logger.info(` ${result.split("\n").join("\n ")}`);
|
|
@@ -3155,7 +3103,7 @@ program.command("test-claude").description("Test Claude integration (Issue #10)"
|
|
|
3155
3103
|
logger.info("\n7. Testing Claude launch (headless)...");
|
|
3156
3104
|
logger.info(' Sending test prompt: "Say hello"');
|
|
3157
3105
|
try {
|
|
3158
|
-
const result = await
|
|
3106
|
+
const result = await launchClaude("Say hello", { headless: true });
|
|
3159
3107
|
if (result) {
|
|
3160
3108
|
logger.success(" Claude responded successfully");
|
|
3161
3109
|
logger.info(` Response preview: ${result.substring(0, 100)}...`);
|
|
@@ -3179,7 +3127,7 @@ program.command("test-claude").description("Test Claude integration (Issue #10)"
|
|
|
3179
3127
|
});
|
|
3180
3128
|
program.command("test-webserver").description("Test if a web server is running on a workspace port").argument("<issue-number>", "Issue number (port will be calculated as 3000 + issue number)", parseInt).option("--kill", "Kill the web server if detected").action(async (issueNumber, options) => {
|
|
3181
3129
|
try {
|
|
3182
|
-
const { TestWebserverCommand } = await import("./test-webserver-
|
|
3130
|
+
const { TestWebserverCommand } = await import("./test-webserver-J6SMNLU2.js");
|
|
3183
3131
|
const command = new TestWebserverCommand();
|
|
3184
3132
|
await command.execute({ issueNumber, options });
|
|
3185
3133
|
} catch (error) {
|
|
@@ -3232,7 +3180,7 @@ program.command("test-prefix").description("Test worktree prefix configuration -
|
|
|
3232
3180
|
program.command("summary").description("Generate Claude session summary for a loom").argument("[identifier]", "Issue number, PR number (pr/123), or branch name (auto-detected if omitted)").option("--with-comment", "Post summary as a comment to the issue/PR").option("--json", "Output result as JSON").action(async (identifier, options) => {
|
|
3233
3181
|
const executeAction = async () => {
|
|
3234
3182
|
try {
|
|
3235
|
-
const { SummaryCommand } = await import("./summary-
|
|
3183
|
+
const { SummaryCommand } = await import("./summary-2KLNHVTN.js");
|
|
3236
3184
|
const command = new SummaryCommand();
|
|
3237
3185
|
const result = await command.execute({ identifier, options });
|
|
3238
3186
|
if (options.json && result) {
|