cortex-agents 2.3.1 → 3.4.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/.opencode/agents/{plan.md → architect.md} +69 -15
- package/.opencode/agents/{fullstack.md → crosslayer.md} +2 -2
- package/.opencode/agents/{debug.md → fix.md} +11 -9
- package/.opencode/agents/{security.md → guard.md} +1 -1
- package/.opencode/agents/{build.md → implement.md} +121 -22
- package/.opencode/agents/{testing.md → qa.md} +1 -1
- package/.opencode/agents/{devops.md → ship.md} +1 -1
- package/README.md +107 -31
- package/dist/cli.js +87 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -7
- package/dist/registry.d.ts +8 -3
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +16 -2
- package/dist/tools/cortex.d.ts +2 -2
- package/dist/tools/cortex.js +7 -7
- package/dist/tools/environment.d.ts +31 -0
- package/dist/tools/environment.d.ts.map +1 -0
- package/dist/tools/environment.js +93 -0
- package/dist/tools/github.d.ts +42 -0
- package/dist/tools/github.d.ts.map +1 -0
- package/dist/tools/github.js +200 -0
- package/dist/tools/repl.d.ts +50 -0
- package/dist/tools/repl.d.ts.map +1 -0
- package/dist/tools/repl.js +240 -0
- package/dist/tools/task.d.ts +2 -0
- package/dist/tools/task.d.ts.map +1 -1
- package/dist/tools/task.js +25 -30
- package/dist/tools/worktree.d.ts.map +1 -1
- package/dist/tools/worktree.js +22 -11
- package/dist/utils/github.d.ts +104 -0
- package/dist/utils/github.d.ts.map +1 -0
- package/dist/utils/github.js +243 -0
- package/dist/utils/ide.d.ts +76 -0
- package/dist/utils/ide.d.ts.map +1 -0
- package/dist/utils/ide.js +307 -0
- package/dist/utils/plan-extract.d.ts +7 -0
- package/dist/utils/plan-extract.d.ts.map +1 -1
- package/dist/utils/plan-extract.js +25 -1
- package/dist/utils/repl.d.ts +114 -0
- package/dist/utils/repl.d.ts.map +1 -0
- package/dist/utils/repl.js +434 -0
- package/dist/utils/terminal.d.ts +53 -1
- package/dist/utils/terminal.d.ts.map +1 -1
- package/dist/utils/terminal.js +642 -5
- package/package.json +1 -1
- package/dist/plugin.d.ts +0 -1
- package/dist/plugin.d.ts.map +0 -1
- package/dist/plugin.js +0 -4
- /package/.opencode/agents/{review.md → audit.md} +0 -0
package/dist/tools/cortex.js
CHANGED
|
@@ -151,13 +151,13 @@ Plans: ${planCount}`;
|
|
|
151
151
|
/**
|
|
152
152
|
* cortex_configure — Write per-project model configuration to ./opencode.json.
|
|
153
153
|
*
|
|
154
|
-
* Accepts a primary model (for
|
|
155
|
-
* (for
|
|
154
|
+
* Accepts a primary model (for implement/architect/fix/audit) and a subagent model
|
|
155
|
+
* (for crosslayer/qa/guard/ship). Merges into any existing
|
|
156
156
|
* opencode.json at the project root, preserving other settings.
|
|
157
157
|
*/
|
|
158
158
|
export const configure = tool({
|
|
159
159
|
description: "Save per-project model configuration to ./opencode.json. " +
|
|
160
|
-
"Sets the model for primary agents (
|
|
160
|
+
"Sets the model for primary agents (implement, architect, fix, audit) and subagents (crosslayer, qa, guard, ship). " +
|
|
161
161
|
"Available models — Premium: " +
|
|
162
162
|
MODEL_REGISTRY.filter((m) => m.tier === "premium")
|
|
163
163
|
.map((m) => `${m.name} (${m.id})`)
|
|
@@ -174,10 +174,10 @@ export const configure = tool({
|
|
|
174
174
|
args: {
|
|
175
175
|
primaryModel: z
|
|
176
176
|
.string()
|
|
177
|
-
.describe("Model ID for primary agents (
|
|
177
|
+
.describe("Model ID for primary agents (implement, architect, fix, audit). Format: provider/model-name"),
|
|
178
178
|
subagentModel: z
|
|
179
179
|
.string()
|
|
180
|
-
.describe("Model ID for subagents (
|
|
180
|
+
.describe("Model ID for subagents (crosslayer, qa, guard, ship). Format: provider/model-name"),
|
|
181
181
|
},
|
|
182
182
|
async execute(args, context) {
|
|
183
183
|
const configPath = path.join(context.worktree, "opencode.json");
|
|
@@ -246,10 +246,10 @@ export const configure = tool({
|
|
|
246
246
|
return `✓ Model configuration saved to:
|
|
247
247
|
${savedTo}
|
|
248
248
|
|
|
249
|
-
Primary agents (
|
|
249
|
+
Primary agents (implement, architect, fix, audit):
|
|
250
250
|
→ ${primaryDisplay} (${args.primaryModel})
|
|
251
251
|
|
|
252
|
-
Subagents (
|
|
252
|
+
Subagents (crosslayer, qa, guard, ship):
|
|
253
253
|
→ ${subagentDisplay} (${args.subagentModel})
|
|
254
254
|
|
|
255
255
|
Restart OpenCode to apply changes.`;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment Detection Tool
|
|
3
|
+
*
|
|
4
|
+
* Provides agents with information about the current development environment
|
|
5
|
+
* (IDE, terminal, editor) to offer contextually appropriate worktree launch options.
|
|
6
|
+
*
|
|
7
|
+
* Uses two detection systems:
|
|
8
|
+
* - IDE detection (ide.ts) — for "Open in IDE" options
|
|
9
|
+
* - Terminal detection (terminal.ts) — for "Open in terminal tab" options
|
|
10
|
+
*
|
|
11
|
+
* The terminal detection uses a multi-strategy chain:
|
|
12
|
+
* 1. Environment variables (fast, synchronous)
|
|
13
|
+
* 2. Process-tree walk (finds terminal in parent processes)
|
|
14
|
+
* 3. Frontmost app detection (macOS only)
|
|
15
|
+
* 4. User preference (.cortex/config.json)
|
|
16
|
+
*/
|
|
17
|
+
export declare const detectEnvironment: {
|
|
18
|
+
description: string;
|
|
19
|
+
args: {};
|
|
20
|
+
execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Quick environment check tool for agents.
|
|
24
|
+
* Returns a simplified response for quick decision-making.
|
|
25
|
+
*/
|
|
26
|
+
export declare const getEnvironmentInfo: {
|
|
27
|
+
description: string;
|
|
28
|
+
args: {};
|
|
29
|
+
execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/tools/environment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,eAAO,MAAM,iBAAiB;;;;CAgD5B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;CA4B7B,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment Detection Tool
|
|
3
|
+
*
|
|
4
|
+
* Provides agents with information about the current development environment
|
|
5
|
+
* (IDE, terminal, editor) to offer contextually appropriate worktree launch options.
|
|
6
|
+
*
|
|
7
|
+
* Uses two detection systems:
|
|
8
|
+
* - IDE detection (ide.ts) — for "Open in IDE" options
|
|
9
|
+
* - Terminal detection (terminal.ts) — for "Open in terminal tab" options
|
|
10
|
+
*
|
|
11
|
+
* The terminal detection uses a multi-strategy chain:
|
|
12
|
+
* 1. Environment variables (fast, synchronous)
|
|
13
|
+
* 2. Process-tree walk (finds terminal in parent processes)
|
|
14
|
+
* 3. Frontmost app detection (macOS only)
|
|
15
|
+
* 4. User preference (.cortex/config.json)
|
|
16
|
+
*/
|
|
17
|
+
import { tool } from "@opencode-ai/plugin";
|
|
18
|
+
import { detectIDEWithCLICheck, formatEnvironmentReport, generateEnvironmentRecommendations } from "../utils/ide.js";
|
|
19
|
+
import { detectDriver, detectTerminalDriver } from "../utils/terminal.js";
|
|
20
|
+
export const detectEnvironment = tool({
|
|
21
|
+
description: "Detect the current development environment (IDE, terminal, editor) " +
|
|
22
|
+
"to offer contextually appropriate worktree launch options. " +
|
|
23
|
+
"Returns environment info and recommended launch options.",
|
|
24
|
+
args: {},
|
|
25
|
+
async execute(args, context) {
|
|
26
|
+
// Use async detection that verifies CLI availability in PATH
|
|
27
|
+
const ide = await detectIDEWithCLICheck();
|
|
28
|
+
const ideDriver = detectDriver();
|
|
29
|
+
// Multi-strategy terminal detection (the one used for "Open in terminal tab")
|
|
30
|
+
const terminalDetection = await detectTerminalDriver(context.worktree);
|
|
31
|
+
// Format the report (now includes CLI availability status)
|
|
32
|
+
const report = formatEnvironmentReport(ide, terminalDetection.driver.name);
|
|
33
|
+
// Add CLI status section
|
|
34
|
+
const additionalInfo = [];
|
|
35
|
+
additionalInfo.push(``, `### CLI Status`, ``);
|
|
36
|
+
additionalInfo.push(`- IDE: ${ide.name}`);
|
|
37
|
+
additionalInfo.push(`- IDE Driver: ${ideDriver.name}`);
|
|
38
|
+
additionalInfo.push(`- Terminal Emulator: **${terminalDetection.driver.name}**`);
|
|
39
|
+
additionalInfo.push(`- Platform: ${process.platform}`);
|
|
40
|
+
if (ide.cliBinary) {
|
|
41
|
+
if (ide.cliAvailable) {
|
|
42
|
+
additionalInfo.push(`- CLI: \`${ide.cliBinary}\` available in PATH`);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
additionalInfo.push(`- CLI: \`${ide.cliBinary}\` **NOT found** in PATH`);
|
|
46
|
+
if (ide.cliInstallHint) {
|
|
47
|
+
additionalInfo.push(`- Fix: ${ide.cliInstallHint}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Terminal detection details
|
|
52
|
+
additionalInfo.push(``, `### Terminal Detection`, ``);
|
|
53
|
+
additionalInfo.push(`- Strategy: **${terminalDetection.strategy}**`);
|
|
54
|
+
if (terminalDetection.detail) {
|
|
55
|
+
additionalInfo.push(`- Detail: ${terminalDetection.detail}`);
|
|
56
|
+
}
|
|
57
|
+
additionalInfo.push(`- Driver: ${terminalDetection.driver.name}`);
|
|
58
|
+
additionalInfo.push(``);
|
|
59
|
+
additionalInfo.push(`When "Open in terminal tab" is selected, a new tab will open in **${terminalDetection.driver.name}**.`);
|
|
60
|
+
return report + additionalInfo.join("\n");
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
/**
|
|
64
|
+
* Quick environment check tool for agents.
|
|
65
|
+
* Returns a simplified response for quick decision-making.
|
|
66
|
+
*/
|
|
67
|
+
export const getEnvironmentInfo = tool({
|
|
68
|
+
description: "Get quick environment info for deciding worktree launch options. " +
|
|
69
|
+
"Returns IDE type, terminal name, and whether to offer IDE-specific options.",
|
|
70
|
+
args: {},
|
|
71
|
+
async execute(args, context) {
|
|
72
|
+
const ide = await detectIDEWithCLICheck();
|
|
73
|
+
const terminalDetection = await detectTerminalDriver(context.worktree);
|
|
74
|
+
return JSON.stringify({
|
|
75
|
+
ide: {
|
|
76
|
+
type: ide.type,
|
|
77
|
+
name: ide.name,
|
|
78
|
+
hasIntegratedTerminal: ide.hasIntegratedTerminal,
|
|
79
|
+
canOpenInWindow: ide.canOpenInWindow,
|
|
80
|
+
cliAvailable: ide.cliAvailable,
|
|
81
|
+
cliBinary: ide.cliBinary,
|
|
82
|
+
cliInstallHint: ide.cliInstallHint,
|
|
83
|
+
},
|
|
84
|
+
terminal: {
|
|
85
|
+
name: terminalDetection.driver.name,
|
|
86
|
+
detectionStrategy: terminalDetection.strategy,
|
|
87
|
+
detectionDetail: terminalDetection.detail,
|
|
88
|
+
},
|
|
89
|
+
platform: process.platform,
|
|
90
|
+
recommendations: generateEnvironmentRecommendations(ide),
|
|
91
|
+
}, null, 2);
|
|
92
|
+
},
|
|
93
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export declare const status: {
|
|
2
|
+
description: string;
|
|
3
|
+
args: {};
|
|
4
|
+
execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
5
|
+
};
|
|
6
|
+
export declare const issues: {
|
|
7
|
+
description: string;
|
|
8
|
+
args: {
|
|
9
|
+
state: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
10
|
+
closed: "closed";
|
|
11
|
+
open: "open";
|
|
12
|
+
all: "all";
|
|
13
|
+
}>>;
|
|
14
|
+
labels: import("zod").ZodOptional<import("zod").ZodString>;
|
|
15
|
+
milestone: import("zod").ZodOptional<import("zod").ZodString>;
|
|
16
|
+
assignee: import("zod").ZodOptional<import("zod").ZodString>;
|
|
17
|
+
limit: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
18
|
+
detailed: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
19
|
+
};
|
|
20
|
+
execute(args: {
|
|
21
|
+
state?: "closed" | "open" | "all" | undefined;
|
|
22
|
+
labels?: string | undefined;
|
|
23
|
+
milestone?: string | undefined;
|
|
24
|
+
assignee?: string | undefined;
|
|
25
|
+
limit?: number | undefined;
|
|
26
|
+
detailed?: boolean | undefined;
|
|
27
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
28
|
+
};
|
|
29
|
+
export declare const projects: {
|
|
30
|
+
description: string;
|
|
31
|
+
args: {
|
|
32
|
+
projectNumber: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
33
|
+
status: import("zod").ZodOptional<import("zod").ZodString>;
|
|
34
|
+
limit: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
35
|
+
};
|
|
36
|
+
execute(args: {
|
|
37
|
+
projectNumber?: number | undefined;
|
|
38
|
+
status?: string | undefined;
|
|
39
|
+
limit?: number | undefined;
|
|
40
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/tools/github.ts"],"names":[],"mappings":"AAwCA,eAAO,MAAM,MAAM;;;;CAgDjB,CAAC;AAIH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;CAsEjB,CAAC;AAIH,eAAO,MAAM,QAAQ;;;;;;;;;;;;CA0EnB,CAAC"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin";
|
|
2
|
+
import { checkGhAvailability, fetchIssues, fetchProjects, fetchProjectItems, formatIssueList, formatIssueForPlan, formatProjectItemList, } from "../utils/github.js";
|
|
3
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
4
|
+
/**
|
|
5
|
+
* Validate GitHub CLI availability and return status.
|
|
6
|
+
* Returns a formatted error string if not available, or the status object.
|
|
7
|
+
*/
|
|
8
|
+
async function requireGh(cwd) {
|
|
9
|
+
const status = await checkGhAvailability(cwd);
|
|
10
|
+
if (!status.installed) {
|
|
11
|
+
return {
|
|
12
|
+
ok: false,
|
|
13
|
+
error: "✗ GitHub CLI (gh) is not installed.\n\nInstall it from https://cli.github.com/ and run `gh auth login`.",
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
if (!status.authenticated) {
|
|
17
|
+
return {
|
|
18
|
+
ok: false,
|
|
19
|
+
error: "✗ GitHub CLI is not authenticated.\n\nRun `gh auth login` to authenticate.",
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return { ok: true, status };
|
|
23
|
+
}
|
|
24
|
+
// ─── Tool: github_status ─────────────────────────────────────────────────────
|
|
25
|
+
export const status = tool({
|
|
26
|
+
description: "Check GitHub CLI availability, authentication, and detect GitHub Projects for the current repository. " +
|
|
27
|
+
"Use this first to verify the repo is connected before listing issues or projects.",
|
|
28
|
+
args: {},
|
|
29
|
+
async execute(_args, context) {
|
|
30
|
+
const status = await checkGhAvailability(context.worktree);
|
|
31
|
+
const lines = [];
|
|
32
|
+
// Installation
|
|
33
|
+
lines.push(status.installed ? "✓ GitHub CLI installed" : "✗ GitHub CLI not installed");
|
|
34
|
+
if (!status.installed) {
|
|
35
|
+
lines.push(" Install from https://cli.github.com/");
|
|
36
|
+
return lines.join("\n");
|
|
37
|
+
}
|
|
38
|
+
// Authentication
|
|
39
|
+
lines.push(status.authenticated ? "✓ Authenticated" : "✗ Not authenticated");
|
|
40
|
+
if (!status.authenticated) {
|
|
41
|
+
lines.push(" Run: gh auth login");
|
|
42
|
+
return lines.join("\n");
|
|
43
|
+
}
|
|
44
|
+
// Remote
|
|
45
|
+
if (status.hasRemote && status.repoOwner && status.repoName) {
|
|
46
|
+
lines.push(`✓ Repository: ${status.repoOwner}/${status.repoName}`);
|
|
47
|
+
// Fetch projects
|
|
48
|
+
const projects = await fetchProjects(context.worktree, status.repoOwner);
|
|
49
|
+
status.projects = projects;
|
|
50
|
+
if (projects.length > 0) {
|
|
51
|
+
lines.push("");
|
|
52
|
+
lines.push(`GitHub Projects (${projects.length}):`);
|
|
53
|
+
for (const p of projects) {
|
|
54
|
+
lines.push(` #${p.number}: ${p.title}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
lines.push(" No GitHub Projects found for this repository owner.");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
lines.push("✗ No GitHub remote (origin) configured");
|
|
63
|
+
lines.push(" Add one with: git remote add origin <url>");
|
|
64
|
+
}
|
|
65
|
+
return lines.join("\n");
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
// ─── Tool: github_issues ─────────────────────────────────────────────────────
|
|
69
|
+
export const issues = tool({
|
|
70
|
+
description: "List GitHub issues for the current repository, filterable by state, labels, milestone, and assignee. " +
|
|
71
|
+
"Returns a formatted list suitable for selecting issues to plan. " +
|
|
72
|
+
"Set `detailed` to true to get full issue descriptions for plan seeding.",
|
|
73
|
+
args: {
|
|
74
|
+
state: tool.schema
|
|
75
|
+
.enum(["open", "closed", "all"])
|
|
76
|
+
.optional()
|
|
77
|
+
.describe("Filter by issue state (default: open)"),
|
|
78
|
+
labels: tool.schema
|
|
79
|
+
.string()
|
|
80
|
+
.optional()
|
|
81
|
+
.describe("Filter by labels (comma-separated, e.g., 'bug,priority:high')"),
|
|
82
|
+
milestone: tool.schema
|
|
83
|
+
.string()
|
|
84
|
+
.optional()
|
|
85
|
+
.describe("Filter by milestone name"),
|
|
86
|
+
assignee: tool.schema
|
|
87
|
+
.string()
|
|
88
|
+
.optional()
|
|
89
|
+
.describe("Filter by assignee username"),
|
|
90
|
+
limit: tool.schema
|
|
91
|
+
.number()
|
|
92
|
+
.optional()
|
|
93
|
+
.describe("Maximum number of issues to return (default: 20, max: 100)"),
|
|
94
|
+
detailed: tool.schema
|
|
95
|
+
.boolean()
|
|
96
|
+
.optional()
|
|
97
|
+
.describe("If true, return full issue details formatted for plan seeding (default: false)"),
|
|
98
|
+
},
|
|
99
|
+
async execute(args, context) {
|
|
100
|
+
const check = await requireGh(context.worktree);
|
|
101
|
+
if (!check.ok)
|
|
102
|
+
return check.error;
|
|
103
|
+
const limit = Math.min(Math.max(args.limit ?? 20, 1), 100);
|
|
104
|
+
try {
|
|
105
|
+
const issueList = await fetchIssues(context.worktree, {
|
|
106
|
+
state: args.state ?? "open",
|
|
107
|
+
labels: args.labels,
|
|
108
|
+
milestone: args.milestone,
|
|
109
|
+
assignee: args.assignee,
|
|
110
|
+
limit,
|
|
111
|
+
});
|
|
112
|
+
if (issueList.length === 0) {
|
|
113
|
+
const filters = [];
|
|
114
|
+
if (args.state)
|
|
115
|
+
filters.push(`state: ${args.state}`);
|
|
116
|
+
if (args.labels)
|
|
117
|
+
filters.push(`labels: ${args.labels}`);
|
|
118
|
+
if (args.milestone)
|
|
119
|
+
filters.push(`milestone: ${args.milestone}`);
|
|
120
|
+
if (args.assignee)
|
|
121
|
+
filters.push(`assignee: ${args.assignee}`);
|
|
122
|
+
const filterStr = filters.length > 0 ? ` (filters: ${filters.join(", ")})` : "";
|
|
123
|
+
return `No issues found${filterStr}.`;
|
|
124
|
+
}
|
|
125
|
+
const header = `Found ${issueList.length} issue(s):\n\n`;
|
|
126
|
+
if (args.detailed) {
|
|
127
|
+
// Full detail mode for plan seeding
|
|
128
|
+
const formatted = issueList.map((issue) => formatIssueForPlan(issue)).join("\n\n---\n\n");
|
|
129
|
+
return header + formatted;
|
|
130
|
+
}
|
|
131
|
+
// Compact list mode for selection
|
|
132
|
+
return header + formatIssueList(issueList);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
return `✗ Error fetching issues: ${error.message || error}`;
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
// ─── Tool: github_projects ───────────────────────────────────────────────────
|
|
140
|
+
export const projects = tool({
|
|
141
|
+
description: "List GitHub Project boards and their work items for the current repository. " +
|
|
142
|
+
"Without a projectNumber, lists all projects. " +
|
|
143
|
+
"With a projectNumber, lists items from that specific project board.",
|
|
144
|
+
args: {
|
|
145
|
+
projectNumber: tool.schema
|
|
146
|
+
.number()
|
|
147
|
+
.optional()
|
|
148
|
+
.describe("Specific project number to list items from (omit to list all projects)"),
|
|
149
|
+
status: tool.schema
|
|
150
|
+
.string()
|
|
151
|
+
.optional()
|
|
152
|
+
.describe("Filter project items by status column (e.g., 'Todo', 'In Progress')"),
|
|
153
|
+
limit: tool.schema
|
|
154
|
+
.number()
|
|
155
|
+
.optional()
|
|
156
|
+
.describe("Maximum number of items to return (default: 30)"),
|
|
157
|
+
},
|
|
158
|
+
async execute(args, context) {
|
|
159
|
+
const check = await requireGh(context.worktree);
|
|
160
|
+
if (!check.ok)
|
|
161
|
+
return check.error;
|
|
162
|
+
const { status: ghStatus } = check;
|
|
163
|
+
if (!ghStatus.hasRemote || !ghStatus.repoOwner) {
|
|
164
|
+
return "✗ No GitHub remote (origin) configured. Cannot fetch projects.";
|
|
165
|
+
}
|
|
166
|
+
const owner = ghStatus.repoOwner;
|
|
167
|
+
try {
|
|
168
|
+
// If no project number specified, list all projects
|
|
169
|
+
if (args.projectNumber === undefined) {
|
|
170
|
+
const projectList = await fetchProjects(context.worktree, owner);
|
|
171
|
+
if (projectList.length === 0) {
|
|
172
|
+
return `No GitHub Projects found for ${owner}.`;
|
|
173
|
+
}
|
|
174
|
+
const lines = [`GitHub Projects for ${owner} (${projectList.length}):\n`];
|
|
175
|
+
for (const p of projectList) {
|
|
176
|
+
lines.push(` #${p.number}: ${p.title}`);
|
|
177
|
+
}
|
|
178
|
+
lines.push("");
|
|
179
|
+
lines.push("Use github_projects with a projectNumber to list items from a specific project.");
|
|
180
|
+
return lines.join("\n");
|
|
181
|
+
}
|
|
182
|
+
// Fetch items from a specific project (cap limit for safety)
|
|
183
|
+
const limit = Math.min(Math.max(args.limit ?? 30, 1), 100);
|
|
184
|
+
const items = await fetchProjectItems(context.worktree, owner, args.projectNumber, {
|
|
185
|
+
status: args.status,
|
|
186
|
+
limit,
|
|
187
|
+
});
|
|
188
|
+
if (items.length === 0) {
|
|
189
|
+
const statusFilter = args.status ? ` with status "${args.status}"` : "";
|
|
190
|
+
return `No items found in project #${args.projectNumber}${statusFilter}.`;
|
|
191
|
+
}
|
|
192
|
+
const statusFilter = args.status ? ` (status: ${args.status})` : "";
|
|
193
|
+
const header = `Project #${args.projectNumber} — ${items.length} item(s)${statusFilter}:\n\n`;
|
|
194
|
+
return header + formatProjectItemList(items);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
return `✗ Error fetching projects: ${error.message || error}`;
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REPL Loop Tools
|
|
3
|
+
*
|
|
4
|
+
* Four tools for the implement agent's iterative task-by-task development loop:
|
|
5
|
+
* - repl_init — Initialize a loop from a plan
|
|
6
|
+
* - repl_status — Get current progress and next task
|
|
7
|
+
* - repl_report — Report task outcome (pass/fail/skip)
|
|
8
|
+
* - repl_summary — Generate markdown summary for PR body
|
|
9
|
+
*/
|
|
10
|
+
export declare const init: {
|
|
11
|
+
description: string;
|
|
12
|
+
args: {
|
|
13
|
+
planFilename: import("zod").ZodString;
|
|
14
|
+
buildCommand: import("zod").ZodOptional<import("zod").ZodString>;
|
|
15
|
+
testCommand: import("zod").ZodOptional<import("zod").ZodString>;
|
|
16
|
+
maxRetries: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
17
|
+
};
|
|
18
|
+
execute(args: {
|
|
19
|
+
planFilename: string;
|
|
20
|
+
buildCommand?: string | undefined;
|
|
21
|
+
testCommand?: string | undefined;
|
|
22
|
+
maxRetries?: number | undefined;
|
|
23
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
24
|
+
};
|
|
25
|
+
export declare const status: {
|
|
26
|
+
description: string;
|
|
27
|
+
args: {};
|
|
28
|
+
execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
29
|
+
};
|
|
30
|
+
export declare const report: {
|
|
31
|
+
description: string;
|
|
32
|
+
args: {
|
|
33
|
+
result: import("zod").ZodEnum<{
|
|
34
|
+
pass: "pass";
|
|
35
|
+
fail: "fail";
|
|
36
|
+
skip: "skip";
|
|
37
|
+
}>;
|
|
38
|
+
detail: import("zod").ZodString;
|
|
39
|
+
};
|
|
40
|
+
execute(args: {
|
|
41
|
+
result: "pass" | "fail" | "skip";
|
|
42
|
+
detail: string;
|
|
43
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
44
|
+
};
|
|
45
|
+
export declare const summary: {
|
|
46
|
+
description: string;
|
|
47
|
+
args: {};
|
|
48
|
+
execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=repl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repl.d.ts","sourceRoot":"","sources":["../../src/tools/repl.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAwBH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;CAqGf,CAAC;AAIH,eAAO,MAAM,MAAM;;;;CAyBjB,CAAC;AAIH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;CAwCjB,CAAC;AA8EH,eAAO,MAAM,OAAO;;;;CAclB,CAAC"}
|