sequant 2.0.0 โ 2.1.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +7 -6
- package/dist/bin/cli.js +2 -1
- package/dist/marketplace/external_plugins/sequant/.claude-plugin/plugin.json +1 -1
- package/dist/marketplace/external_plugins/sequant/.mcp.json +6 -0
- package/dist/marketplace/external_plugins/sequant/README.md +58 -8
- package/dist/marketplace/external_plugins/sequant/hooks/post-tool.sh +19 -8
- package/dist/marketplace/external_plugins/sequant/hooks/pre-tool.sh +36 -49
- package/dist/marketplace/external_plugins/sequant/skills/_shared/references/subagent-types.md +158 -48
- package/dist/marketplace/external_plugins/sequant/skills/assess/SKILL.md +354 -352
- package/dist/marketplace/external_plugins/sequant/skills/exec/SKILL.md +1155 -33
- package/dist/marketplace/external_plugins/sequant/skills/fullsolve/SKILL.md +35 -4
- package/dist/marketplace/external_plugins/sequant/skills/qa/SKILL.md +2157 -104
- package/dist/marketplace/external_plugins/sequant/skills/qa/scripts/quality-checks.sh +1 -1
- package/dist/marketplace/external_plugins/sequant/skills/setup/SKILL.md +386 -0
- package/dist/marketplace/external_plugins/sequant/skills/solve/SKILL.md +38 -664
- package/dist/marketplace/external_plugins/sequant/skills/spec/SKILL.md +505 -120
- package/dist/marketplace/external_plugins/sequant/skills/test/SKILL.md +246 -1
- package/dist/marketplace/external_plugins/sequant/skills/testgen/SKILL.md +138 -1
- package/dist/src/commands/dashboard.js +1 -1
- package/dist/src/commands/doctor.js +1 -1
- package/dist/src/commands/init.js +10 -10
- package/dist/src/commands/logs.js +1 -1
- package/dist/src/commands/run.js +49 -39
- package/dist/src/commands/state.js +3 -3
- package/dist/src/commands/status.js +5 -5
- package/dist/src/commands/sync.js +8 -8
- package/dist/src/commands/update.js +16 -16
- package/dist/src/lib/cli-ui.js +20 -19
- package/dist/src/lib/merge-check/index.js +2 -2
- package/dist/src/lib/settings.d.ts +8 -0
- package/dist/src/lib/settings.js +1 -0
- package/dist/src/lib/shutdown.js +1 -1
- package/dist/src/lib/templates.js +2 -0
- package/dist/src/lib/wizard.js +6 -4
- package/dist/src/lib/workflow/batch-executor.d.ts +9 -1
- package/dist/src/lib/workflow/batch-executor.js +39 -2
- package/dist/src/lib/workflow/log-writer.js +6 -6
- package/dist/src/lib/workflow/metrics-writer.js +5 -3
- package/dist/src/lib/workflow/phase-executor.d.ts +1 -1
- package/dist/src/lib/workflow/phase-executor.js +52 -22
- package/dist/src/lib/workflow/platforms/github.js +5 -1
- package/dist/src/lib/workflow/state-cleanup.js +1 -1
- package/dist/src/lib/workflow/state-manager.js +15 -13
- package/dist/src/lib/workflow/state-rebuild.js +2 -2
- package/dist/src/lib/workflow/types.d.ts +27 -0
- package/dist/src/lib/workflow/worktree-manager.js +40 -41
- package/dist/src/lib/worktree-isolation.d.ts +130 -0
- package/dist/src/lib/worktree-isolation.js +310 -0
- package/package.json +24 -14
- package/templates/agents/sequant-explorer.md +23 -0
- package/templates/agents/sequant-implementer.md +18 -0
- package/templates/agents/sequant-qa-checker.md +24 -0
- package/templates/agents/sequant-testgen.md +25 -0
- package/templates/scripts/cleanup-worktree.sh +18 -0
- package/templates/skills/_shared/references/subagent-types.md +158 -48
- package/templates/skills/exec/SKILL.md +72 -6
- package/templates/skills/qa/SKILL.md +8 -217
- package/templates/skills/spec/SKILL.md +446 -120
- package/templates/skills/testgen/SKILL.md +138 -1
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worktree isolation for parallel /exec agent groups.
|
|
3
|
+
*
|
|
4
|
+
* Provides sub-worktree creation, merge-back, and cleanup for
|
|
5
|
+
* parallel agent execution, eliminating file conflicts structurally.
|
|
6
|
+
*
|
|
7
|
+
* @see https://github.com/sequant-io/sequant/issues/485
|
|
8
|
+
*/
|
|
9
|
+
import { execSync } from "child_process";
|
|
10
|
+
import { existsSync, mkdirSync, symlinkSync, copyFileSync, readFileSync, readdirSync, rmdirSync, } from "fs";
|
|
11
|
+
import { join, basename, dirname } from "path";
|
|
12
|
+
/**
|
|
13
|
+
* Directory name for sub-worktrees inside the issue worktree.
|
|
14
|
+
* This directory is nested inside the issue worktree for locality.
|
|
15
|
+
*/
|
|
16
|
+
export const SUB_WORKTREE_DIR = ".exec-agents";
|
|
17
|
+
/**
|
|
18
|
+
* Default files to copy into sub-worktrees when no .worktreeinclude exists.
|
|
19
|
+
* Matches the pattern in scripts/dev/new-feature.sh.
|
|
20
|
+
*/
|
|
21
|
+
const DEFAULT_INCLUDE_FILES = [
|
|
22
|
+
".env",
|
|
23
|
+
".env.local",
|
|
24
|
+
".env.development",
|
|
25
|
+
".claude/settings.local.json",
|
|
26
|
+
];
|
|
27
|
+
/** Name of the worktree include file */
|
|
28
|
+
export const WORKTREE_INCLUDE_FILE = ".worktreeinclude";
|
|
29
|
+
/**
|
|
30
|
+
* Read the list of files to copy into sub-worktrees.
|
|
31
|
+
*
|
|
32
|
+
* Reads from .worktreeinclude if it exists (one path per line, # comments),
|
|
33
|
+
* otherwise returns the hardcoded default list.
|
|
34
|
+
*/
|
|
35
|
+
export function getIncludeFiles(worktreePath) {
|
|
36
|
+
const includeFile = join(worktreePath, WORKTREE_INCLUDE_FILE);
|
|
37
|
+
if (!existsSync(includeFile)) {
|
|
38
|
+
return DEFAULT_INCLUDE_FILES;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
return readFileSync(includeFile, "utf-8")
|
|
42
|
+
.split("\n")
|
|
43
|
+
.map((line) => line.trim())
|
|
44
|
+
.filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return DEFAULT_INCLUDE_FILES;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Run a git command and return stdout, trimmed.
|
|
52
|
+
* Throws on non-zero exit code.
|
|
53
|
+
*/
|
|
54
|
+
function git(args, cwd) {
|
|
55
|
+
return execSync(`git ${args}`, {
|
|
56
|
+
cwd,
|
|
57
|
+
encoding: "utf-8",
|
|
58
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
59
|
+
}).trim();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Run a git command and return success/failure without throwing.
|
|
63
|
+
*/
|
|
64
|
+
function gitSafe(args, cwd) {
|
|
65
|
+
try {
|
|
66
|
+
const stdout = execSync(`git ${args}`, {
|
|
67
|
+
cwd,
|
|
68
|
+
encoding: "utf-8",
|
|
69
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
70
|
+
}).trim();
|
|
71
|
+
return { success: true, stdout, stderr: "" };
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
const error = err;
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
stdout: error.stdout ?? "",
|
|
78
|
+
stderr: error.stderr ?? "",
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Generate a branch name for a sub-worktree agent.
|
|
84
|
+
*
|
|
85
|
+
* @param issueWorktreePath - Path to the issue worktree
|
|
86
|
+
* @param agentIndex - Zero-based agent index
|
|
87
|
+
* @returns Branch name like `exec-agent-485-0`
|
|
88
|
+
*/
|
|
89
|
+
export function agentBranchName(issueWorktreePath, agentIndex) {
|
|
90
|
+
// Extract issue number from worktree path
|
|
91
|
+
const dirName = basename(issueWorktreePath);
|
|
92
|
+
const issueMatch = dirName.match(/^(\d+)-/);
|
|
93
|
+
const issueNum = issueMatch ? issueMatch[1] : dirName.slice(0, 10);
|
|
94
|
+
return `exec-agent-${issueNum}-${agentIndex}`;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Create a sub-worktree for a parallel agent.
|
|
98
|
+
*
|
|
99
|
+
* The sub-worktree is created inside the issue worktree at
|
|
100
|
+
* `.exec-agents/agent-<N>/` and branches from the issue branch HEAD.
|
|
101
|
+
*
|
|
102
|
+
* node_modules is symlinked from the issue worktree for speed.
|
|
103
|
+
* Environment files are copied per new-feature.sh convention.
|
|
104
|
+
*
|
|
105
|
+
* @param issueWorktreePath - Absolute path to the issue worktree
|
|
106
|
+
* @param agentIndex - Zero-based agent index
|
|
107
|
+
* @returns Sub-worktree info, or null if creation failed
|
|
108
|
+
*/
|
|
109
|
+
export function createSubWorktree(issueWorktreePath, agentIndex) {
|
|
110
|
+
const branch = agentBranchName(issueWorktreePath, agentIndex);
|
|
111
|
+
const subDir = join(issueWorktreePath, SUB_WORKTREE_DIR);
|
|
112
|
+
const agentPath = join(subDir, `agent-${agentIndex}`);
|
|
113
|
+
try {
|
|
114
|
+
// Ensure .exec-agents directory exists
|
|
115
|
+
if (!existsSync(subDir)) {
|
|
116
|
+
mkdirSync(subDir, { recursive: true });
|
|
117
|
+
}
|
|
118
|
+
// Create worktree branching from current HEAD
|
|
119
|
+
git(`worktree add "${agentPath}" -b ${branch}`, issueWorktreePath);
|
|
120
|
+
// Symlink node_modules from issue worktree (fast: ~13ms)
|
|
121
|
+
const issueNodeModules = join(issueWorktreePath, "node_modules");
|
|
122
|
+
const agentNodeModules = join(agentPath, "node_modules");
|
|
123
|
+
if (existsSync(issueNodeModules) && !existsSync(agentNodeModules)) {
|
|
124
|
+
symlinkSync(issueNodeModules, agentNodeModules);
|
|
125
|
+
}
|
|
126
|
+
// Copy files listed in .worktreeinclude (AC-7)
|
|
127
|
+
const includeFiles = getIncludeFiles(issueWorktreePath);
|
|
128
|
+
for (const filePath of includeFiles) {
|
|
129
|
+
const src = join(issueWorktreePath, filePath);
|
|
130
|
+
if (existsSync(src)) {
|
|
131
|
+
const dest = join(agentPath, filePath);
|
|
132
|
+
const destDir = dirname(dest);
|
|
133
|
+
if (!existsSync(destDir)) {
|
|
134
|
+
mkdirSync(destDir, { recursive: true });
|
|
135
|
+
}
|
|
136
|
+
copyFileSync(src, dest);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return { path: agentPath, branch, agentIndex };
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
143
|
+
console.error(`Failed to create sub-worktree for agent ${agentIndex}: ${message}`);
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Merge a single sub-worktree's changes back into the issue worktree.
|
|
149
|
+
*
|
|
150
|
+
* Uses `git merge --no-ff` for built-in conflict detection.
|
|
151
|
+
*
|
|
152
|
+
* @param issueWorktreePath - Absolute path to the issue worktree
|
|
153
|
+
* @param subWorktree - Sub-worktree info
|
|
154
|
+
* @returns Merge result with conflict details if any
|
|
155
|
+
*/
|
|
156
|
+
export function mergeBackSubWorktree(issueWorktreePath, subWorktree) {
|
|
157
|
+
const { branch, agentIndex } = subWorktree;
|
|
158
|
+
// Check if the agent branch has any commits beyond the base
|
|
159
|
+
const hasChanges = gitSafe(`log ${branch} --not HEAD --oneline`, issueWorktreePath);
|
|
160
|
+
if (hasChanges.success && hasChanges.stdout.length === 0) {
|
|
161
|
+
return { success: true, branch, agentIndex, conflictFiles: [] };
|
|
162
|
+
}
|
|
163
|
+
// Attempt merge
|
|
164
|
+
const mergeResult = gitSafe(`merge --no-ff ${branch} -m "Merge exec-agent-${agentIndex}"`, issueWorktreePath);
|
|
165
|
+
if (mergeResult.success) {
|
|
166
|
+
return { success: true, branch, agentIndex, conflictFiles: [] };
|
|
167
|
+
}
|
|
168
|
+
// Merge failed โ detect conflict files
|
|
169
|
+
const conflictResult = gitSafe("diff --name-only --diff-filter=U", issueWorktreePath);
|
|
170
|
+
const conflictFiles = conflictResult.stdout
|
|
171
|
+
.split("\n")
|
|
172
|
+
.filter((f) => f.length > 0);
|
|
173
|
+
// Abort the failed merge to leave clean state
|
|
174
|
+
gitSafe("merge --abort", issueWorktreePath);
|
|
175
|
+
return {
|
|
176
|
+
success: false,
|
|
177
|
+
branch,
|
|
178
|
+
agentIndex,
|
|
179
|
+
conflictFiles,
|
|
180
|
+
error: `Merge conflict in ${conflictFiles.length} file(s): ${conflictFiles.join(", ")}`,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Merge all sub-worktrees back into the issue worktree.
|
|
185
|
+
*
|
|
186
|
+
* Merges are attempted sequentially. If one conflicts, the merge is
|
|
187
|
+
* aborted and subsequent agents are still attempted. Non-conflicting
|
|
188
|
+
* changes are preserved in the issue worktree.
|
|
189
|
+
*
|
|
190
|
+
* @param issueWorktreePath - Absolute path to the issue worktree
|
|
191
|
+
* @param subWorktrees - Array of sub-worktree info
|
|
192
|
+
* @returns Aggregate merge result
|
|
193
|
+
*/
|
|
194
|
+
export function mergeAllSubWorktrees(issueWorktreePath, subWorktrees) {
|
|
195
|
+
const results = [];
|
|
196
|
+
let merged = 0;
|
|
197
|
+
let conflicts = 0;
|
|
198
|
+
for (const sub of subWorktrees) {
|
|
199
|
+
const result = mergeBackSubWorktree(issueWorktreePath, sub);
|
|
200
|
+
results.push(result);
|
|
201
|
+
if (result.success) {
|
|
202
|
+
merged++;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
conflicts++;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return { merged, conflicts, results };
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Remove a single sub-worktree and its branch.
|
|
212
|
+
*
|
|
213
|
+
* @param issueWorktreePath - Absolute path to the issue worktree
|
|
214
|
+
* @param subWorktree - Sub-worktree info to clean up
|
|
215
|
+
*/
|
|
216
|
+
export function cleanupSubWorktree(issueWorktreePath, subWorktree) {
|
|
217
|
+
const { path: subPath, branch } = subWorktree;
|
|
218
|
+
// Remove worktree
|
|
219
|
+
if (existsSync(subPath)) {
|
|
220
|
+
gitSafe(`worktree remove "${subPath}" --force`, issueWorktreePath);
|
|
221
|
+
}
|
|
222
|
+
// Delete branch
|
|
223
|
+
gitSafe(`branch -D ${branch}`, issueWorktreePath);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Clean up all sub-worktrees for an issue worktree.
|
|
227
|
+
*
|
|
228
|
+
* Handles both successful cleanup and orphaned worktrees from
|
|
229
|
+
* interrupted sessions.
|
|
230
|
+
*
|
|
231
|
+
* @param issueWorktreePath - Absolute path to the issue worktree
|
|
232
|
+
* @param subWorktrees - Known sub-worktrees to clean (if provided)
|
|
233
|
+
*/
|
|
234
|
+
export function cleanupAllSubWorktrees(issueWorktreePath, subWorktrees) {
|
|
235
|
+
if (subWorktrees) {
|
|
236
|
+
for (const sub of subWorktrees) {
|
|
237
|
+
cleanupSubWorktree(issueWorktreePath, sub);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// Also clean any orphaned sub-worktrees from interrupted sessions
|
|
241
|
+
cleanupOrphanedSubWorktrees(issueWorktreePath);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Detect and clean up orphaned sub-worktrees from interrupted sessions.
|
|
245
|
+
*
|
|
246
|
+
* Scans the `.exec-agents/` directory for any remaining worktrees and
|
|
247
|
+
* removes them. Also prunes stale worktree entries from git.
|
|
248
|
+
*
|
|
249
|
+
* @param issueWorktreePath - Absolute path to the issue worktree
|
|
250
|
+
*/
|
|
251
|
+
export function cleanupOrphanedSubWorktrees(issueWorktreePath) {
|
|
252
|
+
const subDir = join(issueWorktreePath, SUB_WORKTREE_DIR);
|
|
253
|
+
if (!existsSync(subDir)) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
// Prune stale worktree entries
|
|
257
|
+
gitSafe("worktree prune", issueWorktreePath);
|
|
258
|
+
// List worktrees to find any still pointing to .exec-agents/
|
|
259
|
+
const listResult = gitSafe("worktree list --porcelain", issueWorktreePath);
|
|
260
|
+
if (!listResult.success)
|
|
261
|
+
return;
|
|
262
|
+
const lines = listResult.stdout.split("\n");
|
|
263
|
+
for (const line of lines) {
|
|
264
|
+
if (line.startsWith("worktree ") && line.includes(SUB_WORKTREE_DIR)) {
|
|
265
|
+
const worktreePath = line.replace("worktree ", "");
|
|
266
|
+
gitSafe(`worktree remove "${worktreePath}" --force`, issueWorktreePath);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// Clean up orphaned exec-agent branches
|
|
270
|
+
const branchResult = gitSafe("branch --list exec-agent-*", issueWorktreePath);
|
|
271
|
+
if (branchResult.success && branchResult.stdout.length > 0) {
|
|
272
|
+
const branches = branchResult.stdout
|
|
273
|
+
.split("\n")
|
|
274
|
+
.map((b) => b.trim())
|
|
275
|
+
.filter((b) => b.length > 0);
|
|
276
|
+
for (const branch of branches) {
|
|
277
|
+
gitSafe(`branch -D ${branch}`, issueWorktreePath);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// Remove the .exec-agents directory if empty
|
|
281
|
+
try {
|
|
282
|
+
const entries = readdirSync(subDir);
|
|
283
|
+
if (entries.length === 0) {
|
|
284
|
+
rmdirSync(subDir);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
// Ignore errors during directory cleanup
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Format merge-back results for logging.
|
|
293
|
+
*
|
|
294
|
+
* @param result - Aggregate merge result
|
|
295
|
+
* @returns Human-readable summary
|
|
296
|
+
*/
|
|
297
|
+
export function formatMergeResult(result) {
|
|
298
|
+
const lines = [];
|
|
299
|
+
const total = result.merged + result.conflicts;
|
|
300
|
+
lines.push(`Merge-back: ${result.merged}/${total} agents merged successfully`);
|
|
301
|
+
if (result.conflicts > 0) {
|
|
302
|
+
lines.push(`Conflicts: ${result.conflicts} agent(s) had merge conflicts`);
|
|
303
|
+
for (const r of result.results) {
|
|
304
|
+
if (!r.success) {
|
|
305
|
+
lines.push(` Agent ${r.agentIndex}: ${r.error}`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return lines.join("\n");
|
|
310
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sequant",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Quantize your development workflow - Sequential AI phases with quality gates",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -32,16 +32,26 @@
|
|
|
32
32
|
"prepublishOnly": "npm run build"
|
|
33
33
|
},
|
|
34
34
|
"keywords": [
|
|
35
|
+
"ai",
|
|
35
36
|
"claude",
|
|
36
37
|
"claude-code",
|
|
38
|
+
"aider",
|
|
39
|
+
"mcp",
|
|
40
|
+
"cli",
|
|
37
41
|
"workflow",
|
|
38
|
-
"ai",
|
|
39
42
|
"automation",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
43
|
+
"coding-agent",
|
|
44
|
+
"agent",
|
|
45
|
+
"github",
|
|
46
|
+
"github-issues",
|
|
47
|
+
"quality-gates",
|
|
48
|
+
"code-quality",
|
|
49
|
+
"orchestrator",
|
|
50
|
+
"developer-tools",
|
|
51
|
+
"anthropic",
|
|
52
|
+
"llm",
|
|
53
|
+
"ai-coding",
|
|
54
|
+
"copilot"
|
|
45
55
|
],
|
|
46
56
|
"author": "Sequant Contributors",
|
|
47
57
|
"license": "MIT",
|
|
@@ -54,7 +64,7 @@
|
|
|
54
64
|
},
|
|
55
65
|
"homepage": "https://sequant.io",
|
|
56
66
|
"engines": {
|
|
57
|
-
"node": ">=20.
|
|
67
|
+
"node": ">=20.19.0"
|
|
58
68
|
},
|
|
59
69
|
"peerDependencies": {
|
|
60
70
|
"@modelcontextprotocol/sdk": "^1.27.1"
|
|
@@ -83,17 +93,17 @@
|
|
|
83
93
|
"zod": "^4.3.5"
|
|
84
94
|
},
|
|
85
95
|
"devDependencies": {
|
|
86
|
-
"@eslint/js": "^
|
|
96
|
+
"@eslint/js": "^10.0.1",
|
|
87
97
|
"@types/gradient-string": "^1.1.6",
|
|
88
98
|
"@types/inquirer": "^9.0.7",
|
|
89
99
|
"@types/node": "^25.4.0",
|
|
90
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
91
|
-
"@typescript-eslint/parser": "^8.
|
|
92
|
-
"eslint": "^
|
|
100
|
+
"@typescript-eslint/eslint-plugin": "^8.58.0",
|
|
101
|
+
"@typescript-eslint/parser": "^8.58.0",
|
|
102
|
+
"eslint": "^10.1.0",
|
|
93
103
|
"globals": "^17.0.0",
|
|
94
104
|
"tsx": "^4.19.2",
|
|
95
|
-
"typescript": "^
|
|
96
|
-
"typescript-eslint": "^8.
|
|
105
|
+
"typescript": "^6.0.2",
|
|
106
|
+
"typescript-eslint": "^8.58.0",
|
|
97
107
|
"vitest": "^4.1.0"
|
|
98
108
|
}
|
|
99
109
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sequant-explorer
|
|
3
|
+
description: Codebase exploration agent for sequant /spec phase. Searches for existing patterns, components, database schemas, and file structures. Use when gathering context before planning a feature implementation.
|
|
4
|
+
model: haiku
|
|
5
|
+
maxTurns: 15
|
|
6
|
+
tools:
|
|
7
|
+
- Read
|
|
8
|
+
- Grep
|
|
9
|
+
- Glob
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
You are an exploration agent for the sequant development workflow.
|
|
13
|
+
|
|
14
|
+
Your job is to search the codebase for existing patterns, components, and structures relevant to a planned feature.
|
|
15
|
+
|
|
16
|
+
Rules:
|
|
17
|
+
- Search thoroughly across relevant directories
|
|
18
|
+
- Report findings in structured format: file paths, patterns discovered, recommendations
|
|
19
|
+
- Do NOT modify any files
|
|
20
|
+
- Do NOT run shell commands
|
|
21
|
+
- Send results back via SendMessage when complete
|
|
22
|
+
- All grep commands must use `|| true` to prevent exit code 1 on zero matches
|
|
23
|
+
- Focus on actionable findings that inform implementation decisions
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sequant-implementer
|
|
3
|
+
description: Implementation agent for sequant /exec parallel groups. Handles component creation, type definitions, CLI scripts, and refactoring tasks. Use when spawned by the /exec skill to implement a specific subtask in a feature worktree.
|
|
4
|
+
permissionMode: bypassPermissions
|
|
5
|
+
maxTurns: 25
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are an implementation agent for the sequant development workflow.
|
|
9
|
+
|
|
10
|
+
Your job is to implement a specific subtask as described in your prompt, working within a feature worktree.
|
|
11
|
+
|
|
12
|
+
Rules:
|
|
13
|
+
- Work ONLY in the worktree path specified in your prompt
|
|
14
|
+
- Do NOT create test files unless explicitly asked
|
|
15
|
+
- Do NOT push to remote or create PRs
|
|
16
|
+
- Report what files were created/modified when complete via SendMessage
|
|
17
|
+
- Follow existing codebase patterns and conventions
|
|
18
|
+
- All grep commands must use `|| true` to prevent exit code 1 on zero matches
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sequant-qa-checker
|
|
3
|
+
description: Quality check agent for sequant /qa phase. Runs type safety, scope/size, security, and documentation checks on diffs. Use when spawned by the /qa skill to perform parallel or sequential quality checks.
|
|
4
|
+
model: haiku
|
|
5
|
+
permissionMode: bypassPermissions
|
|
6
|
+
effort: low
|
|
7
|
+
maxTurns: 15
|
|
8
|
+
tools:
|
|
9
|
+
- Read
|
|
10
|
+
- Grep
|
|
11
|
+
- Glob
|
|
12
|
+
- Bash
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
You are a quality check agent for the sequant development workflow.
|
|
16
|
+
|
|
17
|
+
Your job is to run a specific quality check on a code diff and report results concisely.
|
|
18
|
+
|
|
19
|
+
Rules:
|
|
20
|
+
- Run only the check described in your prompt
|
|
21
|
+
- Report results in structured format: check name, pass/fail, issue count, details
|
|
22
|
+
- Send results back via SendMessage when complete
|
|
23
|
+
- Do not modify any files
|
|
24
|
+
- All grep commands must use `|| true` to prevent exit code 1 on zero matches
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sequant-testgen
|
|
3
|
+
description: Test stub generator for sequant /testgen phase. Parses verification criteria from /spec comments and generates Jest/Vitest test stubs with Given/When/Then structure. Use when spawned by the /testgen skill.
|
|
4
|
+
model: haiku
|
|
5
|
+
maxTurns: 25
|
|
6
|
+
tools:
|
|
7
|
+
- Read
|
|
8
|
+
- Grep
|
|
9
|
+
- Glob
|
|
10
|
+
- Write
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
You are a test stub generation agent for the sequant development workflow.
|
|
14
|
+
|
|
15
|
+
Your job is to parse verification criteria and generate test stubs following project conventions.
|
|
16
|
+
|
|
17
|
+
Rules:
|
|
18
|
+
- Generate test stubs using the project's test framework (Jest or Vitest)
|
|
19
|
+
- Include Given/When/Then comments in each test
|
|
20
|
+
- Add TODO markers where implementation is needed
|
|
21
|
+
- Use `throw new Error('Test stub - implement this test')` for unimplemented tests
|
|
22
|
+
- Include failure path stubs based on the action verb
|
|
23
|
+
- Do NOT run shell commands
|
|
24
|
+
- Send results back via SendMessage when complete
|
|
25
|
+
- Return ONLY the test code, no explanation
|
|
@@ -53,6 +53,24 @@ if [ "$PR_STATUS" != "MERGED" ]; then
|
|
|
53
53
|
fi
|
|
54
54
|
fi
|
|
55
55
|
|
|
56
|
+
# Clean up any exec-agent sub-worktrees first (from parallel isolation)
|
|
57
|
+
EXEC_AGENTS_DIR="$WORKTREE_PATH/.exec-agents"
|
|
58
|
+
if [ -d "$EXEC_AGENTS_DIR" ]; then
|
|
59
|
+
echo -e "${BLUE}๐งน Cleaning up exec-agent sub-worktrees...${NC}"
|
|
60
|
+
for agent_dir in "$EXEC_AGENTS_DIR"/agent-*; do
|
|
61
|
+
if [ -d "$agent_dir" ]; then
|
|
62
|
+
echo -e "${BLUE} Removing: $(basename "$agent_dir")${NC}"
|
|
63
|
+
git worktree remove "$agent_dir" --force 2>/dev/null || true
|
|
64
|
+
fi
|
|
65
|
+
done
|
|
66
|
+
# Clean up orphaned exec-agent branches
|
|
67
|
+
git branch --list 'exec-agent-*' 2>/dev/null | while read -r branch; do
|
|
68
|
+
branch=$(echo "$branch" | tr -d ' *')
|
|
69
|
+
git branch -D "$branch" 2>/dev/null || true
|
|
70
|
+
done
|
|
71
|
+
rmdir "$EXEC_AGENTS_DIR" 2>/dev/null || true
|
|
72
|
+
fi
|
|
73
|
+
|
|
56
74
|
# Remove worktree
|
|
57
75
|
echo -e "${BLUE}๐ Removing worktree...${NC}"
|
|
58
76
|
git worktree remove "$WORKTREE_PATH" --force
|