cortex-agents 1.0.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/build.md +160 -0
- package/.opencode/agents/debug.md +141 -0
- package/.opencode/agents/devops.md +109 -0
- package/.opencode/agents/fullstack.md +84 -0
- package/.opencode/agents/plan.md +188 -0
- package/.opencode/agents/security.md +90 -0
- package/.opencode/agents/testing.md +89 -0
- package/.opencode/skills/code-quality/SKILL.md +251 -0
- package/.opencode/skills/deployment-automation/SKILL.md +258 -0
- package/.opencode/skills/git-workflow/SKILL.md +281 -0
- package/.opencode/skills/security-hardening/SKILL.md +209 -0
- package/.opencode/skills/testing-strategies/SKILL.md +159 -0
- package/.opencode/skills/web-development/SKILL.md +122 -0
- package/LICENSE +17 -0
- package/README.md +172 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +174 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/plugin.d.ts +1 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +3 -0
- package/dist/tools/branch.d.ts +35 -0
- package/dist/tools/branch.d.ts.map +1 -0
- package/dist/tools/branch.js +176 -0
- package/dist/tools/cortex.d.ts +11 -0
- package/dist/tools/cortex.d.ts.map +1 -0
- package/dist/tools/cortex.js +149 -0
- package/dist/tools/plan.d.ts +59 -0
- package/dist/tools/plan.d.ts.map +1 -0
- package/dist/tools/plan.js +177 -0
- package/dist/tools/session.d.ts +36 -0
- package/dist/tools/session.d.ts.map +1 -0
- package/dist/tools/session.js +175 -0
- package/dist/tools/worktree.d.ts +45 -0
- package/dist/tools/worktree.d.ts.map +1 -0
- package/dist/tools/worktree.js +198 -0
- package/package.json +55 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
const CORTEX_DIR = ".cortex";
|
|
5
|
+
const SESSIONS_DIR = "sessions";
|
|
6
|
+
function getDatePrefix() {
|
|
7
|
+
const now = new Date();
|
|
8
|
+
return now.toISOString().split("T")[0]; // YYYY-MM-DD
|
|
9
|
+
}
|
|
10
|
+
function ensureSessionsDir(worktree) {
|
|
11
|
+
const cortexPath = path.join(worktree, CORTEX_DIR);
|
|
12
|
+
const sessionsPath = path.join(cortexPath, SESSIONS_DIR);
|
|
13
|
+
if (!fs.existsSync(sessionsPath)) {
|
|
14
|
+
fs.mkdirSync(sessionsPath, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
return sessionsPath;
|
|
17
|
+
}
|
|
18
|
+
function generateSessionId() {
|
|
19
|
+
return Math.random().toString(36).substring(2, 10);
|
|
20
|
+
}
|
|
21
|
+
export const save = tool({
|
|
22
|
+
description: "Save a session summary with key decisions to .cortex/sessions/",
|
|
23
|
+
args: {
|
|
24
|
+
summary: tool.schema
|
|
25
|
+
.string()
|
|
26
|
+
.describe("Brief summary of what was accomplished in this session"),
|
|
27
|
+
decisions: tool.schema
|
|
28
|
+
.array(tool.schema.string())
|
|
29
|
+
.describe("List of key decisions made during the session"),
|
|
30
|
+
filesChanged: tool.schema
|
|
31
|
+
.array(tool.schema.string())
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Optional list of files that were modified"),
|
|
34
|
+
relatedPlan: tool.schema
|
|
35
|
+
.string()
|
|
36
|
+
.optional()
|
|
37
|
+
.describe("Optional filename of related plan"),
|
|
38
|
+
branch: tool.schema
|
|
39
|
+
.string()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe("Git branch this work was done on"),
|
|
42
|
+
},
|
|
43
|
+
async execute(args, context) {
|
|
44
|
+
const { summary, decisions, filesChanged, relatedPlan, branch } = args;
|
|
45
|
+
const sessionsPath = ensureSessionsDir(context.worktree);
|
|
46
|
+
const datePrefix = getDatePrefix();
|
|
47
|
+
const sessionId = generateSessionId();
|
|
48
|
+
const filename = `${datePrefix}-${sessionId}.md`;
|
|
49
|
+
const filepath = path.join(sessionsPath, filename);
|
|
50
|
+
// Get current branch if not provided
|
|
51
|
+
let currentBranch = branch;
|
|
52
|
+
if (!currentBranch) {
|
|
53
|
+
try {
|
|
54
|
+
currentBranch = (await Bun.$ `git branch --show-current`.cwd(context.worktree).text()).trim();
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
currentBranch = "unknown";
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Build content
|
|
61
|
+
let content = `---
|
|
62
|
+
date: ${new Date().toISOString()}
|
|
63
|
+
branch: ${currentBranch}
|
|
64
|
+
${relatedPlan ? `relatedPlan: ${relatedPlan}` : ""}
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
# Session Summary
|
|
68
|
+
|
|
69
|
+
${summary}
|
|
70
|
+
|
|
71
|
+
## Key Decisions
|
|
72
|
+
|
|
73
|
+
${decisions.map((d) => `- ${d}`).join("\n")}
|
|
74
|
+
`;
|
|
75
|
+
if (filesChanged && filesChanged.length > 0) {
|
|
76
|
+
content += `
|
|
77
|
+
## Files Changed
|
|
78
|
+
|
|
79
|
+
${filesChanged.map((f) => `- \`${f}\``).join("\n")}
|
|
80
|
+
`;
|
|
81
|
+
}
|
|
82
|
+
if (relatedPlan) {
|
|
83
|
+
content += `
|
|
84
|
+
## Related Plan
|
|
85
|
+
|
|
86
|
+
See: \`.cortex/plans/${relatedPlan}\`
|
|
87
|
+
`;
|
|
88
|
+
}
|
|
89
|
+
// Write file
|
|
90
|
+
fs.writeFileSync(filepath, content);
|
|
91
|
+
return `✓ Session summary saved
|
|
92
|
+
|
|
93
|
+
File: ${filename}
|
|
94
|
+
Branch: ${currentBranch}
|
|
95
|
+
Decisions recorded: ${decisions.length}
|
|
96
|
+
${filesChanged ? `Files tracked: ${filesChanged.length}` : ""}
|
|
97
|
+
|
|
98
|
+
Session summaries are stored in .cortex/sessions/ and gitignored by default.`;
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
export const list = tool({
|
|
102
|
+
description: "List recent session summaries from .cortex/sessions/",
|
|
103
|
+
args: {
|
|
104
|
+
limit: tool.schema
|
|
105
|
+
.number()
|
|
106
|
+
.optional()
|
|
107
|
+
.describe("Maximum number of sessions to return (default: 10)"),
|
|
108
|
+
},
|
|
109
|
+
async execute(args, context) {
|
|
110
|
+
const { limit = 10 } = args;
|
|
111
|
+
const sessionsPath = path.join(context.worktree, CORTEX_DIR, SESSIONS_DIR);
|
|
112
|
+
if (!fs.existsSync(sessionsPath)) {
|
|
113
|
+
return `No sessions found. The .cortex/sessions/ directory doesn't exist.
|
|
114
|
+
|
|
115
|
+
Sessions are created when you use session_save after completing work.`;
|
|
116
|
+
}
|
|
117
|
+
const files = fs
|
|
118
|
+
.readdirSync(sessionsPath)
|
|
119
|
+
.filter((f) => f.endsWith(".md"))
|
|
120
|
+
.sort()
|
|
121
|
+
.reverse()
|
|
122
|
+
.slice(0, limit);
|
|
123
|
+
if (files.length === 0) {
|
|
124
|
+
return "No session summaries found in .cortex/sessions/";
|
|
125
|
+
}
|
|
126
|
+
let output = `📝 Recent Sessions (showing ${files.length}):\n\n`;
|
|
127
|
+
for (const file of files) {
|
|
128
|
+
const filepath = path.join(sessionsPath, file);
|
|
129
|
+
const content = fs.readFileSync(filepath, "utf-8");
|
|
130
|
+
// Parse frontmatter
|
|
131
|
+
let date = file.substring(0, 10);
|
|
132
|
+
let branch = "unknown";
|
|
133
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
134
|
+
if (frontmatterMatch) {
|
|
135
|
+
const fm = frontmatterMatch[1];
|
|
136
|
+
const dateMatch = fm.match(/date:\s*(\S+)/);
|
|
137
|
+
const branchMatch = fm.match(/branch:\s*(\S+)/);
|
|
138
|
+
if (dateMatch)
|
|
139
|
+
date = dateMatch[1].split("T")[0];
|
|
140
|
+
if (branchMatch)
|
|
141
|
+
branch = branchMatch[1];
|
|
142
|
+
}
|
|
143
|
+
// Get first line of summary (after frontmatter and heading)
|
|
144
|
+
const summaryMatch = content.match(/# Session Summary\n\n([^\n]+)/);
|
|
145
|
+
const summaryPreview = summaryMatch
|
|
146
|
+
? summaryMatch[1].substring(0, 80) + (summaryMatch[1].length > 80 ? "..." : "")
|
|
147
|
+
: "(no summary)";
|
|
148
|
+
output += `• ${date} [${branch}]\n`;
|
|
149
|
+
output += ` ${summaryPreview}\n`;
|
|
150
|
+
output += ` File: ${file}\n\n`;
|
|
151
|
+
}
|
|
152
|
+
return output.trim();
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
export const load = tool({
|
|
156
|
+
description: "Load a session summary by filename",
|
|
157
|
+
args: {
|
|
158
|
+
filename: tool.schema.string().describe("Session filename"),
|
|
159
|
+
},
|
|
160
|
+
async execute(args, context) {
|
|
161
|
+
const { filename } = args;
|
|
162
|
+
const sessionsPath = path.join(context.worktree, CORTEX_DIR, SESSIONS_DIR);
|
|
163
|
+
const filepath = path.join(sessionsPath, filename);
|
|
164
|
+
if (!fs.existsSync(filepath)) {
|
|
165
|
+
return `✗ Session not found: ${filename}
|
|
166
|
+
|
|
167
|
+
Use session_list to see available sessions.`;
|
|
168
|
+
}
|
|
169
|
+
const content = fs.readFileSync(filepath, "utf-8");
|
|
170
|
+
return `📝 Session: ${filename}
|
|
171
|
+
${"=".repeat(50)}
|
|
172
|
+
|
|
173
|
+
${content}`;
|
|
174
|
+
},
|
|
175
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export declare const create: {
|
|
2
|
+
description: string;
|
|
3
|
+
args: {
|
|
4
|
+
name: import("zod").ZodString;
|
|
5
|
+
type: import("zod").ZodEnum<{
|
|
6
|
+
feature: "feature";
|
|
7
|
+
bugfix: "bugfix";
|
|
8
|
+
hotfix: "hotfix";
|
|
9
|
+
refactor: "refactor";
|
|
10
|
+
spike: "spike";
|
|
11
|
+
docs: "docs";
|
|
12
|
+
test: "test";
|
|
13
|
+
}>;
|
|
14
|
+
};
|
|
15
|
+
execute(args: {
|
|
16
|
+
name: string;
|
|
17
|
+
type: "feature" | "bugfix" | "hotfix" | "refactor" | "spike" | "docs" | "test";
|
|
18
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
19
|
+
};
|
|
20
|
+
export declare const list: {
|
|
21
|
+
description: string;
|
|
22
|
+
args: {};
|
|
23
|
+
execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
24
|
+
};
|
|
25
|
+
export declare const remove: {
|
|
26
|
+
description: string;
|
|
27
|
+
args: {
|
|
28
|
+
name: import("zod").ZodString;
|
|
29
|
+
deleteBranch: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
30
|
+
};
|
|
31
|
+
execute(args: {
|
|
32
|
+
name: string;
|
|
33
|
+
deleteBranch?: boolean | undefined;
|
|
34
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
35
|
+
};
|
|
36
|
+
export declare const open: {
|
|
37
|
+
description: string;
|
|
38
|
+
args: {
|
|
39
|
+
name: import("zod").ZodString;
|
|
40
|
+
};
|
|
41
|
+
execute(args: {
|
|
42
|
+
name: string;
|
|
43
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=worktree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/tools/worktree.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;CA8DjB,CAAC;AAEH,eAAO,MAAM,IAAI;;;;CAiCf,CAAC;AAEH,eAAO,MAAM,MAAM;;;;;;;;;;CA4DjB,CAAC;AAEH,eAAO,MAAM,IAAI;;;;;;;;CAgDf,CAAC"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
const WORKTREE_ROOT = "../.worktrees";
|
|
5
|
+
export const create = tool({
|
|
6
|
+
description: "Create a new git worktree for isolated development. Worktrees are created in ../.worktrees/",
|
|
7
|
+
args: {
|
|
8
|
+
name: tool.schema
|
|
9
|
+
.string()
|
|
10
|
+
.describe("Worktree name (e.g., 'auth-feature', 'login-bugfix')"),
|
|
11
|
+
type: tool.schema
|
|
12
|
+
.enum(["feature", "bugfix", "hotfix", "refactor", "spike", "docs", "test"])
|
|
13
|
+
.describe("Type of work - determines branch prefix"),
|
|
14
|
+
},
|
|
15
|
+
async execute(args, context) {
|
|
16
|
+
const { name, type } = args;
|
|
17
|
+
const branchName = `${type}/${name}`;
|
|
18
|
+
const worktreePath = path.join(context.worktree, WORKTREE_ROOT, name);
|
|
19
|
+
const absoluteWorktreePath = path.resolve(worktreePath);
|
|
20
|
+
// Check if we're in a git repository
|
|
21
|
+
try {
|
|
22
|
+
const gitCheck = await Bun.$ `git rev-parse --git-dir`.cwd(context.worktree).text();
|
|
23
|
+
if (!gitCheck.trim()) {
|
|
24
|
+
return "✗ Error: Not in a git repository";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return "✗ Error: Not in a git repository. Initialize git first.";
|
|
29
|
+
}
|
|
30
|
+
// Check if worktree already exists
|
|
31
|
+
if (fs.existsSync(absoluteWorktreePath)) {
|
|
32
|
+
return `✗ Error: Worktree already exists at ${absoluteWorktreePath}
|
|
33
|
+
|
|
34
|
+
Use worktree_list to see existing worktrees.`;
|
|
35
|
+
}
|
|
36
|
+
// Create parent directory if needed
|
|
37
|
+
const worktreeParent = path.dirname(absoluteWorktreePath);
|
|
38
|
+
if (!fs.existsSync(worktreeParent)) {
|
|
39
|
+
fs.mkdirSync(worktreeParent, { recursive: true });
|
|
40
|
+
}
|
|
41
|
+
// Create the worktree with a new branch
|
|
42
|
+
try {
|
|
43
|
+
await Bun.$ `git worktree add -b ${branchName} ${absoluteWorktreePath}`.cwd(context.worktree);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
// Branch might already exist, try without -b
|
|
47
|
+
try {
|
|
48
|
+
await Bun.$ `git worktree add ${absoluteWorktreePath} ${branchName}`.cwd(context.worktree);
|
|
49
|
+
}
|
|
50
|
+
catch (error2) {
|
|
51
|
+
return `✗ Error creating worktree: ${error2.message || error2}`;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return `✓ Created worktree successfully
|
|
55
|
+
|
|
56
|
+
Branch: ${branchName}
|
|
57
|
+
Path: ${absoluteWorktreePath}
|
|
58
|
+
|
|
59
|
+
To work in this worktree:
|
|
60
|
+
cd ${absoluteWorktreePath}
|
|
61
|
+
|
|
62
|
+
Or use worktree_open to get a command to open a new terminal there.`;
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
export const list = tool({
|
|
66
|
+
description: "List all git worktrees for this project",
|
|
67
|
+
args: {},
|
|
68
|
+
async execute(args, context) {
|
|
69
|
+
try {
|
|
70
|
+
const result = await Bun.$ `git worktree list`.cwd(context.worktree).text();
|
|
71
|
+
if (!result.trim()) {
|
|
72
|
+
return "No worktrees found.";
|
|
73
|
+
}
|
|
74
|
+
const lines = result.trim().split("\n");
|
|
75
|
+
let output = "Git Worktrees:\n\n";
|
|
76
|
+
for (const line of lines) {
|
|
77
|
+
const parts = line.split(/\s+/);
|
|
78
|
+
const worktreePath = parts[0];
|
|
79
|
+
const commit = parts[1];
|
|
80
|
+
const branch = parts[2]?.replace(/[\[\]]/g, "") || "detached";
|
|
81
|
+
const isMain = worktreePath === context.worktree;
|
|
82
|
+
const marker = isMain ? " (main)" : "";
|
|
83
|
+
output += `• ${branch}${marker}\n`;
|
|
84
|
+
output += ` Path: ${worktreePath}\n`;
|
|
85
|
+
output += ` Commit: ${commit}\n\n`;
|
|
86
|
+
}
|
|
87
|
+
return output.trim();
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
return `✗ Error listing worktrees: ${error.message || error}`;
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
export const remove = tool({
|
|
95
|
+
description: "Remove a git worktree (after merging). Optionally deletes the branch.",
|
|
96
|
+
args: {
|
|
97
|
+
name: tool.schema.string().describe("Worktree name to remove"),
|
|
98
|
+
deleteBranch: tool.schema
|
|
99
|
+
.boolean()
|
|
100
|
+
.optional()
|
|
101
|
+
.describe("Also delete the associated branch (default: false)"),
|
|
102
|
+
},
|
|
103
|
+
async execute(args, context) {
|
|
104
|
+
const { name, deleteBranch = false } = args;
|
|
105
|
+
const worktreePath = path.join(context.worktree, WORKTREE_ROOT, name);
|
|
106
|
+
const absoluteWorktreePath = path.resolve(worktreePath);
|
|
107
|
+
// Check if worktree exists
|
|
108
|
+
if (!fs.existsSync(absoluteWorktreePath)) {
|
|
109
|
+
return `✗ Error: Worktree not found at ${absoluteWorktreePath}
|
|
110
|
+
|
|
111
|
+
Use worktree_list to see existing worktrees.`;
|
|
112
|
+
}
|
|
113
|
+
// Get branch name before removing
|
|
114
|
+
let branchName = "";
|
|
115
|
+
try {
|
|
116
|
+
branchName = await Bun.$ `git -C ${absoluteWorktreePath} branch --show-current`.text();
|
|
117
|
+
branchName = branchName.trim();
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// Ignore error, branch detection is optional
|
|
121
|
+
}
|
|
122
|
+
// Remove the worktree
|
|
123
|
+
try {
|
|
124
|
+
await Bun.$ `git worktree remove ${absoluteWorktreePath}`.cwd(context.worktree);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
// Try force remove if there are changes
|
|
128
|
+
try {
|
|
129
|
+
await Bun.$ `git worktree remove --force ${absoluteWorktreePath}`.cwd(context.worktree);
|
|
130
|
+
}
|
|
131
|
+
catch (error2) {
|
|
132
|
+
return `✗ Error removing worktree: ${error2.message || error2}
|
|
133
|
+
|
|
134
|
+
The worktree may have uncommitted changes. Commit or stash them first.`;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
let output = `✓ Removed worktree at ${absoluteWorktreePath}`;
|
|
138
|
+
// Delete branch if requested
|
|
139
|
+
if (deleteBranch && branchName) {
|
|
140
|
+
try {
|
|
141
|
+
await Bun.$ `git branch -d ${branchName}`.cwd(context.worktree);
|
|
142
|
+
output += `\n✓ Deleted branch ${branchName}`;
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
output += `\n⚠ Could not delete branch ${branchName}: ${error.message || error}`;
|
|
146
|
+
output += "\n (Branch may not be fully merged. Use git branch -D to force delete.)";
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return output;
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
export const open = tool({
|
|
153
|
+
description: "Get the command to open a new terminal window in a worktree directory",
|
|
154
|
+
args: {
|
|
155
|
+
name: tool.schema.string().describe("Worktree name"),
|
|
156
|
+
},
|
|
157
|
+
async execute(args, context) {
|
|
158
|
+
const { name } = args;
|
|
159
|
+
const worktreePath = path.join(context.worktree, WORKTREE_ROOT, name);
|
|
160
|
+
const absoluteWorktreePath = path.resolve(worktreePath);
|
|
161
|
+
// Check if worktree exists
|
|
162
|
+
if (!fs.existsSync(absoluteWorktreePath)) {
|
|
163
|
+
return `✗ Error: Worktree not found at ${absoluteWorktreePath}
|
|
164
|
+
|
|
165
|
+
Use worktree_list to see existing worktrees.`;
|
|
166
|
+
}
|
|
167
|
+
// Detect OS and provide appropriate command
|
|
168
|
+
const platform = process.platform;
|
|
169
|
+
let command = "";
|
|
170
|
+
let instructions = "";
|
|
171
|
+
if (platform === "darwin") {
|
|
172
|
+
// macOS
|
|
173
|
+
command = `open -a Terminal "${absoluteWorktreePath}"`;
|
|
174
|
+
instructions = `Or with iTerm2: open -a iTerm "${absoluteWorktreePath}"`;
|
|
175
|
+
}
|
|
176
|
+
else if (platform === "linux") {
|
|
177
|
+
// Linux - try common terminals
|
|
178
|
+
command = `gnome-terminal --working-directory="${absoluteWorktreePath}" || xterm -e "cd '${absoluteWorktreePath}' && $SHELL" || konsole --workdir "${absoluteWorktreePath}"`;
|
|
179
|
+
instructions = "Command tries gnome-terminal, xterm, then konsole.";
|
|
180
|
+
}
|
|
181
|
+
else if (platform === "win32") {
|
|
182
|
+
// Windows
|
|
183
|
+
command = `start cmd /k "cd /d ${absoluteWorktreePath}"`;
|
|
184
|
+
instructions = `Or with PowerShell: Start-Process powershell -ArgumentList "-NoExit", "-Command", "cd '${absoluteWorktreePath}'"`;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
command = `cd "${absoluteWorktreePath}"`;
|
|
188
|
+
instructions = "Unknown platform. Use the cd command above.";
|
|
189
|
+
}
|
|
190
|
+
return `To open a new terminal in the worktree:
|
|
191
|
+
|
|
192
|
+
${command}
|
|
193
|
+
|
|
194
|
+
${instructions}
|
|
195
|
+
|
|
196
|
+
Worktree path: ${absoluteWorktreePath}`;
|
|
197
|
+
},
|
|
198
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cortex-agents",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Cortex agents for OpenCode - worktree workflow, plan persistence, and session management",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"cortex-agents": "dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
".opencode"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"prepare": "npm run build",
|
|
18
|
+
"postinstall": "echo 'Run: npx cortex-agents install'"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"opencode",
|
|
22
|
+
"plugin",
|
|
23
|
+
"cortex",
|
|
24
|
+
"agents",
|
|
25
|
+
"skills",
|
|
26
|
+
"ai",
|
|
27
|
+
"coding",
|
|
28
|
+
"worktree",
|
|
29
|
+
"git",
|
|
30
|
+
"planning"
|
|
31
|
+
],
|
|
32
|
+
"author": "",
|
|
33
|
+
"license": "Apache-2.0",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/your-org/cortex-agents"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/your-org/cortex-agents#readme",
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/your-org/cortex-agents/issues"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18.0.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@opencode-ai/plugin": "^1.0.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@opencode-ai/plugin": "^1.0.0",
|
|
50
|
+
"@types/bun": "^1.3.9",
|
|
51
|
+
"@types/node": "^20.0.0",
|
|
52
|
+
"bun-types": "^1.0.0",
|
|
53
|
+
"typescript": "^5.0.0"
|
|
54
|
+
}
|
|
55
|
+
}
|