devloom 1.0.0 → 1.2.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/.ai/core.dsl +44 -0
- package/.ai/skills.dsl +39 -0
- package/.ai/verify.dsl +97 -0
- package/.ai/workflow.dsl +81 -0
- package/.opencode/themes/devloom-night-owl.json +103 -0
- package/GUIDE.md +572 -115
- package/README.md +583 -109
- package/SECURITY.md +93 -0
- package/agents/devloom-developer-flash.md +31 -0
- package/agents/devloom-developer-senior.md +32 -0
- package/agents/devloom-developer.md +21 -55
- package/agents/devloom-documenter-flash.md +28 -0
- package/agents/devloom-documenter.md +17 -56
- package/agents/devloom-orchestrator.md +236 -356
- package/agents/devloom-planner-flash.md +34 -0
- package/agents/devloom-planner-senior.md +35 -0
- package/agents/devloom-planner.md +36 -0
- package/agents/devloom-qa-flash.md +32 -0
- package/agents/devloom-qa.md +21 -83
- package/agents/devloom-security-senior.md +35 -0
- package/agents/devloom-security.md +34 -0
- package/agents/devloom-verifier.md +33 -0
- package/agents/devloom-vision.md +113 -0
- package/agents/devloom-visual-critic.md +102 -0
- package/agents/devloom-visual-director.md +84 -0
- package/commands/devloom-agents.md +49 -0
- package/commands/devloom-auto.md +11 -0
- package/commands/devloom-context.md +82 -0
- package/commands/devloom-deepseek-mimo.md +11 -0
- package/commands/devloom-deepseek.md +11 -0
- package/commands/devloom-free.md +11 -0
- package/commands/devloom-go-economy.md +11 -0
- package/commands/devloom-go-flash.md +11 -0
- package/commands/devloom-go.md +11 -0
- package/commands/devloom-init.md +28 -50
- package/commands/devloom-loop-status.md +25 -0
- package/commands/devloom-loop.md +36 -0
- package/commands/devloom-mimo.md +11 -0
- package/commands/devloom-plan.md +13 -0
- package/commands/devloom-refresh.md +22 -0
- package/commands/devloom-resume.md +30 -49
- package/commands/devloom-save.md +69 -0
- package/commands/devloom-status.md +9 -18
- package/commands/devloom.md +99 -67
- package/dist/agents.d.ts +30 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +139 -0
- package/dist/agents.js.map +1 -0
- package/dist/bootstrap.d.ts +56 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +116 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/constraints.d.ts +5 -0
- package/dist/constraints.d.ts.map +1 -0
- package/dist/constraints.js +45 -0
- package/dist/constraints.js.map +1 -0
- package/dist/context.d.ts +42 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +636 -0
- package/dist/context.js.map +1 -0
- package/dist/guard.d.ts +19 -0
- package/dist/guard.d.ts.map +1 -0
- package/dist/guard.js +418 -0
- package/dist/guard.js.map +1 -0
- package/dist/loop.d.ts +64 -0
- package/dist/loop.d.ts.map +1 -0
- package/dist/loop.js +164 -0
- package/dist/loop.js.map +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +101 -1
- package/dist/plugin.js.map +1 -1
- package/dist/tui-agents.d.ts +61 -0
- package/dist/tui-agents.d.ts.map +1 -0
- package/dist/tui-agents.js +89 -0
- package/dist/tui-agents.js.map +1 -0
- package/dist/tui.d.ts +6 -0
- package/dist/tui.d.ts.map +1 -0
- package/dist/tui.js +92 -0
- package/dist/tui.js.map +1 -0
- package/dist/worktree.d.ts +46 -0
- package/dist/worktree.d.ts.map +1 -0
- package/dist/worktree.js +272 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +46 -6
- package/patterns/changelog-drafter.md +38 -0
- package/patterns/ci-sweeper.md +40 -0
- package/patterns/daily-triage.md +37 -0
- package/patterns/dependency-sweeper.md +40 -0
- package/patterns/design-audit.md +63 -0
- package/patterns/issue-triage.md +37 -0
- package/patterns/post-merge-cleanup.md +34 -0
- package/patterns/pr-babysitter.md +37 -0
- package/patterns/registry.yaml +52 -0
- package/postinstall.mjs +264 -64
- package/project/README.md +29 -0
- package/protocol/agent-contracts.md +27 -0
- package/protocol/artifact-system.md +53 -0
- package/protocol/model-routing.md +194 -0
- package/protocol/orchestrator-core.md +43 -0
- package/protocol/project-system.md +45 -0
- package/protocol/rules.md +18 -0
- package/protocol/verification-policy.md +48 -0
- package/scripts/briefing.mjs +192 -0
- package/scripts/loop-run.mjs +205 -0
- package/scripts/model-capabilities.mjs +194 -0
- package/scripts/plugin-cache.mjs +269 -0
- package/scripts/profile.mjs +755 -0
- package/scripts/visual-benchmark.mjs +149 -0
- package/scripts/worktree.mjs +445 -0
- package/skills/build/development.md +33 -0
- package/skills/build/live-docs.md +38 -0
- package/skills/build/simplify.md +50 -0
- package/skills/build/vision-analysis.md +98 -0
- package/skills/design/app-design.md +31 -0
- package/skills/design/design-grounding.md +30 -0
- package/skills/design/design-system.md +27 -0
- package/skills/design/game-design.md +35 -0
- package/skills/design/motion-design.md +34 -0
- package/skills/design/visual-direction.md +32 -0
- package/skills/design/web-design.md +33 -0
- package/skills/loop/changelog-drafter.md +32 -0
- package/skills/loop/ci-sweeper.md +24 -0
- package/skills/loop/constraints.md +21 -0
- package/skills/loop/dependency-sweeper.md +24 -0
- package/skills/loop/design-audit.md +67 -0
- package/skills/loop/issue-triage.md +27 -0
- package/skills/loop/post-merge-cleanup.md +24 -0
- package/skills/loop/pr-babysitter.md +26 -0
- package/skills/loop/triage.md +25 -0
- package/skills/loop/verifier.md +20 -0
- package/skills/meta/skill-discovery.md +23 -0
- package/skills/plan/planning.md +27 -0
- package/skills/plan/verification-planning.md +40 -0
- package/skills/review/security-review.md +63 -0
- package/skills/ship/documentation.md +11 -0
- package/skills/verify/app-verification.md +19 -0
- package/skills/verify/quality-assurance.md +17 -0
- package/skills/verify/visual-critique.md +30 -0
- package/skills/verify/visual-quality-gate.md +29 -0
- package/skills/verify/visual-regression.md +25 -0
- package/agents/devloom-analyst.md +0 -83
- package/agents/devloom-architect.md +0 -88
package/dist/worktree.js
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from "node:fs";
|
|
3
|
+
import { join, dirname } from "node:path";
|
|
4
|
+
const WORKTREE_DIR = ".devloom-worktrees";
|
|
5
|
+
const REGISTRY_PATH = join(WORKTREE_DIR, ".registry.json");
|
|
6
|
+
const GIT_TIMEOUT = 30_000;
|
|
7
|
+
const GIT_MAX_BUFFER = 10 * 1024 * 1024;
|
|
8
|
+
function git(rootDir, args, opts = {}) {
|
|
9
|
+
const timeout = opts.timeout ?? GIT_TIMEOUT;
|
|
10
|
+
try {
|
|
11
|
+
const out = execFileSync("git", args, {
|
|
12
|
+
cwd: rootDir,
|
|
13
|
+
encoding: "utf8",
|
|
14
|
+
timeout,
|
|
15
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
16
|
+
stdio: opts.stdio ?? ["pipe", "pipe", "pipe"],
|
|
17
|
+
});
|
|
18
|
+
return String(out).trim();
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
if (opts.throwOnError !== false) {
|
|
22
|
+
const stderr = err.stderr ? String(err.stderr).trim() : "";
|
|
23
|
+
throw new Error(`git ${args[0] || ""} failed: ${err.message}${stderr ? " | " + stderr : ""}`);
|
|
24
|
+
}
|
|
25
|
+
return "";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function gitOk(rootDir, args) {
|
|
29
|
+
try {
|
|
30
|
+
execFileSync("git", args, { cwd: rootDir, encoding: "utf8", timeout: GIT_TIMEOUT, maxBuffer: GIT_MAX_BUFFER, stdio: ["pipe", "pipe", "pipe"] });
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function readJson(path, fallback) {
|
|
38
|
+
try {
|
|
39
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return fallback;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function writeJson(path, data) {
|
|
46
|
+
const dir = dirname(path);
|
|
47
|
+
if (!existsSync(dir))
|
|
48
|
+
mkdirSync(dir, { recursive: true });
|
|
49
|
+
writeFileSync(path, JSON.stringify(data, null, 2) + "\n");
|
|
50
|
+
}
|
|
51
|
+
function isGitRepo(rootDir) {
|
|
52
|
+
return gitOk(rootDir, ["rev-parse", "--is-inside-work-tree"]);
|
|
53
|
+
}
|
|
54
|
+
export function getCurrentBranch(rootDir) {
|
|
55
|
+
return git(rootDir, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
56
|
+
}
|
|
57
|
+
export function isClean(rootDir) {
|
|
58
|
+
const status = git(rootDir, ["status", "--porcelain"]);
|
|
59
|
+
return status.length === 0;
|
|
60
|
+
}
|
|
61
|
+
function commitAll(rootDir, message) {
|
|
62
|
+
git(rootDir, ["add", "-A"]);
|
|
63
|
+
if (isClean(rootDir))
|
|
64
|
+
return null;
|
|
65
|
+
git(rootDir, ["commit", "-m", message]);
|
|
66
|
+
return git(rootDir, ["rev-parse", "HEAD"]);
|
|
67
|
+
}
|
|
68
|
+
function branchSlug(branchName) {
|
|
69
|
+
return branchName.replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
70
|
+
}
|
|
71
|
+
function worktreePath(rootDir, branchName) {
|
|
72
|
+
return join(rootDir, WORKTREE_DIR, branchSlug(branchName));
|
|
73
|
+
}
|
|
74
|
+
function readRegistry(rootDir) {
|
|
75
|
+
return readJson(join(rootDir, REGISTRY_PATH), { worktrees: [] });
|
|
76
|
+
}
|
|
77
|
+
function writeRegistry(rootDir, registry) {
|
|
78
|
+
writeJson(join(rootDir, REGISTRY_PATH), registry);
|
|
79
|
+
}
|
|
80
|
+
function addToRegistry(rootDir, entry) {
|
|
81
|
+
const reg = readRegistry(rootDir);
|
|
82
|
+
const idx = reg.worktrees.findIndex((w) => w.branch === entry.branch);
|
|
83
|
+
if (idx >= 0)
|
|
84
|
+
reg.worktrees[idx] = entry;
|
|
85
|
+
else
|
|
86
|
+
reg.worktrees.push(entry);
|
|
87
|
+
writeRegistry(rootDir, reg);
|
|
88
|
+
}
|
|
89
|
+
function removeFromRegistry(rootDir, branchName) {
|
|
90
|
+
const reg = readRegistry(rootDir);
|
|
91
|
+
reg.worktrees = reg.worktrees.filter((w) => w.branch !== branchName);
|
|
92
|
+
writeRegistry(rootDir, reg);
|
|
93
|
+
}
|
|
94
|
+
export function createWorktree(rootDir, branchName, baseRef) {
|
|
95
|
+
if (!isGitRepo(rootDir))
|
|
96
|
+
throw new Error("not a git repository");
|
|
97
|
+
const ref = baseRef || getCurrentBranch(rootDir);
|
|
98
|
+
const wtPath = worktreePath(rootDir, branchName);
|
|
99
|
+
if (existsSync(wtPath)) {
|
|
100
|
+
gitOk(rootDir, ["worktree", "remove", "--force", wtPath]);
|
|
101
|
+
rmSync(wtPath, { recursive: true, force: true });
|
|
102
|
+
}
|
|
103
|
+
// Exact match: a substring test makes a sibling branch (`feat/x-old`) look
|
|
104
|
+
// like a collision with `feat/x`, and the resulting `branch -D` then throws.
|
|
105
|
+
const existing = git(rootDir, ["branch", "--list", "--format=%(refname:short)"], { throwOnError: false })
|
|
106
|
+
.split("\n")
|
|
107
|
+
.map((b) => b.trim());
|
|
108
|
+
if (existing.includes(branchName)) {
|
|
109
|
+
git(rootDir, ["branch", "-D", branchName]);
|
|
110
|
+
}
|
|
111
|
+
ensureGitignore(rootDir);
|
|
112
|
+
if (!isClean(rootDir)) {
|
|
113
|
+
commitAll(rootDir, `devloom: auto-commit before worktree ${branchName}`);
|
|
114
|
+
}
|
|
115
|
+
git(rootDir, ["worktree", "add", "-b", branchName, wtPath, ref]);
|
|
116
|
+
const parts = branchName.split("/");
|
|
117
|
+
const entry = {
|
|
118
|
+
branch: branchName,
|
|
119
|
+
path: wtPath,
|
|
120
|
+
baseRef: ref,
|
|
121
|
+
createdAt: new Date().toISOString(),
|
|
122
|
+
ticket: parts[1] || branchName,
|
|
123
|
+
agent: parts[2] || "unknown",
|
|
124
|
+
};
|
|
125
|
+
addToRegistry(rootDir, entry);
|
|
126
|
+
return entry;
|
|
127
|
+
}
|
|
128
|
+
function ensureGitignore(rootDir) {
|
|
129
|
+
const gitignorePath = join(rootDir, ".gitignore");
|
|
130
|
+
const entry = ".devloom-worktrees/";
|
|
131
|
+
try {
|
|
132
|
+
const content = readFileSync(gitignorePath, "utf8");
|
|
133
|
+
if (!content.includes(entry)) {
|
|
134
|
+
writeFileSync(gitignorePath, content + (content.endsWith("\n") ? "" : "\n") + entry + "\n");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
writeFileSync(gitignorePath, entry + "\n");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
export function mergeWorktree(rootDir, branchName) {
|
|
142
|
+
if (!isGitRepo(rootDir))
|
|
143
|
+
throw new Error("not a git repository");
|
|
144
|
+
const wtPath = worktreePath(rootDir, branchName);
|
|
145
|
+
if (!existsSync(wtPath))
|
|
146
|
+
throw new Error(`worktree not found: ${branchName}`);
|
|
147
|
+
if (!isClean(wtPath)) {
|
|
148
|
+
commitAll(wtPath, `devloom: auto-commit in worktree ${branchName} before merge`);
|
|
149
|
+
}
|
|
150
|
+
const currentBranch = getCurrentBranch(rootDir);
|
|
151
|
+
if (!isClean(rootDir)) {
|
|
152
|
+
commitAll(rootDir, `devloom: auto-commit before merge of ${branchName}`);
|
|
153
|
+
}
|
|
154
|
+
const mergeOut = git(rootDir, ["merge", "--no-ff", branchName, "-m", `devloom: merge ${branchName}`], { throwOnError: false });
|
|
155
|
+
const hasMergeHead = gitOk(rootDir, ["rev-parse", "-q", "--verify", "MERGE_HEAD"]);
|
|
156
|
+
if (hasMergeHead) {
|
|
157
|
+
const conflictFiles = git(rootDir, ["diff", "--name-only", "--diff-filter=U"], { throwOnError: false });
|
|
158
|
+
const conflicts = conflictFiles ? conflictFiles.split("\n").filter(Boolean) : [];
|
|
159
|
+
if (conflicts.length > 0 || mergeOut.includes("CONFLICT") || mergeOut.includes("Automatic merge failed")) {
|
|
160
|
+
git(rootDir, ["merge", "--abort"]);
|
|
161
|
+
return {
|
|
162
|
+
success: false,
|
|
163
|
+
conflicts,
|
|
164
|
+
message: `merge conflict in ${conflicts.length} file(s): ${conflicts.join(", ")}`,
|
|
165
|
+
branch: branchName,
|
|
166
|
+
worktreePath: wtPath,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
git(rootDir, ["merge", "--abort"]);
|
|
170
|
+
return {
|
|
171
|
+
success: false,
|
|
172
|
+
conflicts: [],
|
|
173
|
+
message: "merge conflict detected (auto-aborted)",
|
|
174
|
+
branch: branchName,
|
|
175
|
+
worktreePath: wtPath,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
git(rootDir, ["worktree", "remove", wtPath]);
|
|
179
|
+
git(rootDir, ["branch", "-d", branchName], { throwOnError: false });
|
|
180
|
+
rmSync(wtPath, { recursive: true, force: true });
|
|
181
|
+
removeFromRegistry(rootDir, branchName);
|
|
182
|
+
return {
|
|
183
|
+
success: true,
|
|
184
|
+
conflicts: [],
|
|
185
|
+
message: `merged ${branchName} into ${currentBranch}`,
|
|
186
|
+
branch: branchName,
|
|
187
|
+
mergedInto: currentBranch,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
export function removeWorktree(rootDir, branchName, force = false) {
|
|
191
|
+
if (!isGitRepo(rootDir))
|
|
192
|
+
throw new Error("not a git repository");
|
|
193
|
+
const wtPath = worktreePath(rootDir, branchName);
|
|
194
|
+
if (!existsSync(wtPath)) {
|
|
195
|
+
removeFromRegistry(rootDir, branchName);
|
|
196
|
+
return { removed: false, message: `worktree not found: ${branchName}` };
|
|
197
|
+
}
|
|
198
|
+
if (!force && !isClean(wtPath)) {
|
|
199
|
+
const status = git(wtPath, ["status", "--porcelain"]);
|
|
200
|
+
throw new Error(`worktree ${branchName} has uncommitted changes. Use --force to discard.\nUncommitted:\n${status}`);
|
|
201
|
+
}
|
|
202
|
+
git(rootDir, ["worktree", "remove", "--force", wtPath]);
|
|
203
|
+
git(rootDir, ["branch", "-D", branchName], { throwOnError: false });
|
|
204
|
+
rmSync(wtPath, { recursive: true, force: true });
|
|
205
|
+
removeFromRegistry(rootDir, branchName);
|
|
206
|
+
return { removed: true, message: `removed worktree ${branchName}` };
|
|
207
|
+
}
|
|
208
|
+
export function listWorktrees(rootDir) {
|
|
209
|
+
if (!isGitRepo(rootDir))
|
|
210
|
+
return [];
|
|
211
|
+
const reg = readRegistry(rootDir);
|
|
212
|
+
return reg.worktrees.filter((w) => existsSync(w.path));
|
|
213
|
+
}
|
|
214
|
+
export function worktreeStatus(rootDir, branchName) {
|
|
215
|
+
if (!isGitRepo(rootDir))
|
|
216
|
+
throw new Error("not a git repository");
|
|
217
|
+
const reg = readRegistry(rootDir);
|
|
218
|
+
const entry = reg.worktrees.find((w) => w.branch === branchName);
|
|
219
|
+
if (!entry || !existsSync(entry.path)) {
|
|
220
|
+
return { branch: branchName, exists: false, clean: false, ahead: 0, behind: 0 };
|
|
221
|
+
}
|
|
222
|
+
const clean = isClean(entry.path);
|
|
223
|
+
const aheadStr = git(rootDir, ["rev-list", "--count", `${entry.baseRef}..${branchName}`], { throwOnError: false });
|
|
224
|
+
const behindStr = git(rootDir, ["rev-list", "--count", `${branchName}..${entry.baseRef}`], { throwOnError: false });
|
|
225
|
+
return {
|
|
226
|
+
branch: branchName,
|
|
227
|
+
exists: true,
|
|
228
|
+
path: entry.path,
|
|
229
|
+
clean,
|
|
230
|
+
ahead: parseInt(aheadStr) || 0,
|
|
231
|
+
behind: parseInt(behindStr) || 0,
|
|
232
|
+
createdAt: entry.createdAt,
|
|
233
|
+
ticket: entry.ticket,
|
|
234
|
+
agent: entry.agent,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
export function cleanWorktrees(rootDir, force = false) {
|
|
238
|
+
if (!isGitRepo(rootDir))
|
|
239
|
+
return [];
|
|
240
|
+
const reg = readRegistry(rootDir);
|
|
241
|
+
const results = [];
|
|
242
|
+
for (const w of reg.worktrees) {
|
|
243
|
+
try {
|
|
244
|
+
const aheadStr = git(rootDir, ["rev-list", "--count", `${w.baseRef}..${w.branch}`], { throwOnError: false });
|
|
245
|
+
const ahead = parseInt(aheadStr) || 0;
|
|
246
|
+
// `ahead > 0` is deliberate: a 0-commit worktree is one an agent is still
|
|
247
|
+
// working in, and reclaiming it would discard uncommitted work.
|
|
248
|
+
const isMerged = ahead > 0 && gitOk(rootDir, ["merge-base", "--is-ancestor", w.branch, "HEAD"]);
|
|
249
|
+
if (isMerged || force) {
|
|
250
|
+
removeWorktree(rootDir, w.branch, true);
|
|
251
|
+
results.push({ branch: w.branch, removed: true });
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
results.push({ branch: w.branch, removed: false, reason: "unmerged (use --force)" });
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
catch (err) {
|
|
258
|
+
results.push({ branch: w.branch, removed: false, reason: err.message });
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return results;
|
|
262
|
+
}
|
|
263
|
+
export function readWorktreeSummary(rootDir) {
|
|
264
|
+
const worktrees = listWorktrees(rootDir);
|
|
265
|
+
if (worktrees.length === 0)
|
|
266
|
+
return "worktrees=0";
|
|
267
|
+
const statuses = worktrees.map((w) => worktreeStatus(rootDir, w.branch));
|
|
268
|
+
const dirty = statuses.filter((s) => !s.clean).length;
|
|
269
|
+
const total = statuses.length;
|
|
270
|
+
return `worktrees=${total} dirty=${dirty}`;
|
|
271
|
+
}
|
|
272
|
+
//# sourceMappingURL=worktree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree.js","sourceRoot":"","sources":["../src/worktree.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,35 +1,72 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devloom",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "DevLoom – Autonomous Development Weaver for OpenCode. Transforms a single prompt into fully tested, documented software.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./server": {
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./tui": {
|
|
18
|
+
"import": "./dist/tui.js",
|
|
19
|
+
"types": "./dist/tui.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@opentui/solid": "0.4.5",
|
|
24
|
+
"solid-js": "1.9.12"
|
|
25
|
+
},
|
|
8
26
|
"files": [
|
|
27
|
+
".ai",
|
|
28
|
+
".opencode/themes",
|
|
9
29
|
"dist",
|
|
10
30
|
"agents",
|
|
11
31
|
"commands",
|
|
32
|
+
"skills",
|
|
33
|
+
"protocol",
|
|
34
|
+
"patterns",
|
|
35
|
+
"project",
|
|
36
|
+
"scripts",
|
|
12
37
|
"postinstall.mjs",
|
|
13
38
|
"README.md",
|
|
14
|
-
"GUIDE.md"
|
|
39
|
+
"GUIDE.md",
|
|
40
|
+
"SECURITY.md"
|
|
15
41
|
],
|
|
16
42
|
"scripts": {
|
|
17
43
|
"build": "tsc",
|
|
18
44
|
"dev": "tsc --watch",
|
|
19
|
-
"postinstall": "node postinstall.mjs"
|
|
45
|
+
"postinstall": "node postinstall.mjs",
|
|
46
|
+
"prepublishOnly": "npm run build && npm test",
|
|
47
|
+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
48
|
+
"test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
|
|
49
|
+
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
|
|
50
|
+
"visual-benchmark": "node scripts/visual-benchmark.mjs"
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=18.0.0",
|
|
54
|
+
"npm": ">=9.0.0"
|
|
20
55
|
},
|
|
21
56
|
"peerDependencies": {
|
|
22
|
-
"@opencode-ai/plugin": ">=0.6.0"
|
|
57
|
+
"@opencode-ai/plugin": ">=0.6.0 <2.0.0"
|
|
23
58
|
},
|
|
24
|
-
|
|
25
59
|
"devDependencies": {
|
|
26
60
|
"@opencode-ai/plugin": "^1.15.7",
|
|
61
|
+
"@types/jest": "^30.0.0",
|
|
27
62
|
"@types/node": "^25.9.1",
|
|
63
|
+
"jest": "^30.4.2",
|
|
64
|
+
"ts-jest": "^29.4.11",
|
|
28
65
|
"typescript": "^5.4.0"
|
|
29
66
|
},
|
|
30
67
|
"repository": {
|
|
31
68
|
"type": "git",
|
|
32
|
-
"url": "https://github.com/nsrau/devloom.git"
|
|
69
|
+
"url": "git+https://github.com/nsrau/devloom.git"
|
|
33
70
|
},
|
|
34
71
|
"bugs": {
|
|
35
72
|
"url": "https://github.com/nsrau/devloom/issues"
|
|
@@ -44,5 +81,8 @@
|
|
|
44
81
|
"weaver",
|
|
45
82
|
"code-generation"
|
|
46
83
|
],
|
|
84
|
+
"overrides": {
|
|
85
|
+
"js-yaml": "4.2.0"
|
|
86
|
+
},
|
|
47
87
|
"license": "MIT"
|
|
48
88
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: changelog-drafter
|
|
3
|
+
cadence: "0 8 * * *"
|
|
4
|
+
level: L1
|
|
5
|
+
agents: [documenter]
|
|
6
|
+
cost: 30000
|
|
7
|
+
description: "Draft release notes from recent commits"
|
|
8
|
+
---
|
|
9
|
+
# Changelog Drafter Pattern
|
|
10
|
+
|
|
11
|
+
## Purpose
|
|
12
|
+
Scan recent commits and draft release notes. Read-only (L1). Do not edit source code.
|
|
13
|
+
|
|
14
|
+
## State Schema
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"changelog": {
|
|
18
|
+
"since": "ISO string",
|
|
19
|
+
"until": "ISO string",
|
|
20
|
+
"commits": number,
|
|
21
|
+
"categories": {
|
|
22
|
+
"features": string[],
|
|
23
|
+
"fixes": string[],
|
|
24
|
+
"chores": string[]
|
|
25
|
+
},
|
|
26
|
+
"draftPath": string
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Agent Chain
|
|
32
|
+
1. documenter — read git log since last release, categorize commits, write draft
|
|
33
|
+
|
|
34
|
+
## Prompt Template
|
|
35
|
+
"Review commits from {since} to {until}. Categorize into features, fixes, and chores. Draft a changelog entry. L1: do not edit any source code."
|
|
36
|
+
|
|
37
|
+
## Token Cost Estimate
|
|
38
|
+
~30K tokens per tick.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ci-sweeper
|
|
3
|
+
cadence: "*/10 * * * *"
|
|
4
|
+
level: L2
|
|
5
|
+
agents: [developer, qa]
|
|
6
|
+
cost: 300000
|
|
7
|
+
description: "Detect and fix CI failures"
|
|
8
|
+
---
|
|
9
|
+
# CI Sweeper Pattern
|
|
10
|
+
|
|
11
|
+
## Purpose
|
|
12
|
+
Monitor CI pipeline results and automatically fix common failures. Operates in a worktree to contain changes.
|
|
13
|
+
|
|
14
|
+
## State Schema
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"ci": {
|
|
18
|
+
"lastRunId": string,
|
|
19
|
+
"status": "passing" | "failing" | "running",
|
|
20
|
+
"failureCount": number,
|
|
21
|
+
"failures": [
|
|
22
|
+
{
|
|
23
|
+
"job": string,
|
|
24
|
+
"type": "test" | "lint" | "build" | "typecheck",
|
|
25
|
+
"message": string,
|
|
26
|
+
"attempts": number
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Agent Chain
|
|
34
|
+
1. developer — inspect CI failure, create fix in worktree
|
|
35
|
+
2. qa — run tests, verify the fix doesn't break other things
|
|
36
|
+
|
|
37
|
+
## Safety
|
|
38
|
+
- L2: fix only in worktree, never on main branch directly
|
|
39
|
+
- Max 2 attempts per failure type per tick
|
|
40
|
+
- If fix is complex (>3 files), create a ticket instead
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: daily-triage
|
|
3
|
+
cadence: "0 6 * * *"
|
|
4
|
+
level: L1
|
|
5
|
+
agents: [verifier, documenter]
|
|
6
|
+
cost: 50000
|
|
7
|
+
description: "Report repo health every morning"
|
|
8
|
+
---
|
|
9
|
+
# Daily Triage Pattern
|
|
10
|
+
|
|
11
|
+
## Purpose
|
|
12
|
+
Generate a daily health report for the repository. Read-only (L1). Do not edit source code.
|
|
13
|
+
|
|
14
|
+
## State Schema
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"report": {
|
|
18
|
+
"date": "ISO string",
|
|
19
|
+
"openPRs": number,
|
|
20
|
+
"failingCI": boolean,
|
|
21
|
+
"staleBranches": number,
|
|
22
|
+
"unmergedWorktrees": number,
|
|
23
|
+
"tokenUsage": number,
|
|
24
|
+
"recommendations": string[]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Agent Chain
|
|
30
|
+
1. verifier (scope=explore) — check repo health, PR count, CI status, stale branches
|
|
31
|
+
2. documenter — write report to .opencode/devloom/reports/daily-YYYY-MM-DD.md
|
|
32
|
+
|
|
33
|
+
## Prompt Template
|
|
34
|
+
"Run daily triage on this repo. Check: (1) open PRs and their ages, (2) CI status from recent commits, (3) stale branches older than 7 days, (4) unmerged worktrees. Report findings. L1: do not edit any source code."
|
|
35
|
+
|
|
36
|
+
## Token Cost Estimate
|
|
37
|
+
~50K tokens per tick (verifier explore + documenter write).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: dependency-sweeper
|
|
3
|
+
cadence: "0 */6 * * *"
|
|
4
|
+
level: L2
|
|
5
|
+
agents: [verifier, developer]
|
|
6
|
+
cost: 100000
|
|
7
|
+
description: "Patch-only dependency updates"
|
|
8
|
+
---
|
|
9
|
+
# Dependency Sweeper Pattern
|
|
10
|
+
|
|
11
|
+
## Purpose
|
|
12
|
+
Check for outdated dependencies and apply patch-level updates only. Minor and major updates are reported but not auto-applied.
|
|
13
|
+
|
|
14
|
+
## State Schema
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"deps": {
|
|
18
|
+
"checked": "ISO string",
|
|
19
|
+
"updates": [
|
|
20
|
+
{
|
|
21
|
+
"name": string,
|
|
22
|
+
"current": string,
|
|
23
|
+
"latest": string,
|
|
24
|
+
"type": "patch" | "minor" | "major",
|
|
25
|
+
"autoApplied": boolean
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"vulnerabilities": number
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Agent Chain
|
|
34
|
+
1. verifier — scan package.json, check for outdated deps (npm outdated), check Snyk/GHSA for vulnerabilities
|
|
35
|
+
2. developer — apply patch updates only, run tests after each update
|
|
36
|
+
|
|
37
|
+
## Safety
|
|
38
|
+
- L2: patch-only (1.x.x → 1.x.y), never minor/major
|
|
39
|
+
- Run `npm test` after each update batch
|
|
40
|
+
- Log all changes to run-log.json
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: design-audit
|
|
3
|
+
cadence: "on-demand"
|
|
4
|
+
level: L1
|
|
5
|
+
agents: [verifier]
|
|
6
|
+
cost: 200000
|
|
7
|
+
description: "Comprehensive UI/UX + functional audit with automated fix loop — covers visual inconsistencies, broken actions, missing actions, dead-end flows, API mismatches"
|
|
8
|
+
---
|
|
9
|
+
# Design Audit Pattern
|
|
10
|
+
|
|
11
|
+
## Purpose
|
|
12
|
+
Run exhaustive UI/UX + FUNCTIONAL audits across target pages. Two modes: AUDIT (L1, report-only) catalogs both visual and functional issues; FIX (L2, worktree+verifier) applies unified design system + functional fixes, looping until all items verified.
|
|
13
|
+
|
|
14
|
+
## State Schema
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"audit": {
|
|
18
|
+
"urls": ["https://..."],
|
|
19
|
+
"reportPath": ".opencode/devloom/reports/design-audit-YYYY-MM-DD.md",
|
|
20
|
+
"issueCount": number,
|
|
21
|
+
"categories": { "ui": N, "functional": N, "missing-action": N, "broken-action": N, "api": N, "state": N },
|
|
22
|
+
"designSystemSpecPath": ".opencode/devloom/reports/design-system-spec.md"
|
|
23
|
+
},
|
|
24
|
+
"fix": {
|
|
25
|
+
"progress": {
|
|
26
|
+
"items": [{ "id": "...", "status": "...", "category": "ui|functional|missing-action|broken-action|api|state", "severity": "critical|high|medium|low" }],
|
|
27
|
+
"completionCondition": "All items verified against design system + functional contract",
|
|
28
|
+
"total": number, "done": number, "verified": number
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Modes
|
|
35
|
+
|
|
36
|
+
### AUDIT (L1 — report only)
|
|
37
|
+
Analyze every page exhaustively. Catalog BOTH:
|
|
38
|
+
- **UI**: buttons, modals, forms, tables, tabs, colors, spacing, typography, icons, loading/error/empty states, navigation, layout, responsiveness
|
|
39
|
+
- **Functional**: broken buttons, broken links, missing CRUD, missing validations, missing feedback, dead-end flows, API errors, state issues
|
|
40
|
+
|
|
41
|
+
Produce unified design system spec + functional contract. Tag each issue with category + severity. No source code edits.
|
|
42
|
+
|
|
43
|
+
### FIX (L2 — worktree + verifier, run-until-done)
|
|
44
|
+
Apply unified design system + functional fixes item-by-item in worktrees. Priority: critical → high → medium → low. Loop until all items verified.
|
|
45
|
+
|
|
46
|
+
## Agent Chain
|
|
47
|
+
- **AUDIT**: verifier (crawl + catalog + report)
|
|
48
|
+
- **FIX**: developer (implement per-item in worktree) → verifier (verify item matches spec + functional contract)
|
|
49
|
+
|
|
50
|
+
## Safety
|
|
51
|
+
- L1: no source files modified, no code edits
|
|
52
|
+
- L2: all changes in worktrees, each item verified before proceeding
|
|
53
|
+
- Max retries per item: 3
|
|
54
|
+
- Budget exhaustion → pause, logs partial progress
|
|
55
|
+
|
|
56
|
+
## Prompt Template (AUDIT)
|
|
57
|
+
"Run design-audit in audit mode. Analyze all pages at {URLs}. For each page: (1) catalog every UI element — buttons, links, inputs, modals, forms, tables, tabs, navigation, colors, spacing, typography, icons, loading/error/empty states; (2) test every functional action — click each button, submit each form, follow each link, switch each tab, verify each API call has error handling, check for missing CRUD/validations/feedback, find dead-end flows and state issues. Tag each issue with category (ui|functional|missing-action|broken-action|api|state) and severity (critical|high|medium|low). Write audit report to .opencode/devloom/reports/design-audit-{DATE}.md and unified spec to .opencode/devloom/reports/design-system-spec.md. L1: do not edit any source code."
|
|
58
|
+
|
|
59
|
+
## Prompt Template (FIX)
|
|
60
|
+
"Run design-audit in fix mode. Read progress from .opencode/devloom/loop/progress.json. Pick next un-verified item (ordered by severity). Apply the design system spec + functional contract from .opencode/devloom/reports/design-system-spec.md in a worktree (branch: devloom/design-audit/{PAGE}). Fix both UI inconsistencies and functional issues (broken actions, missing handlers, missing validations, dead-end flows, API errors, state problems). Verify the item matches spec + functional contract. If verified, mark progress. Repeat until all items verified or budget exhausted."
|
|
61
|
+
|
|
62
|
+
## Token Cost Estimate
|
|
63
|
+
~200K tokens per tick (verifier for audit; developer+verifier for fix).
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: issue-triage
|
|
3
|
+
cadence: "0 */2 * * *"
|
|
4
|
+
level: L1
|
|
5
|
+
agents: [planner]
|
|
6
|
+
cost: 60000
|
|
7
|
+
description: "Propose labels and priorities for new issues"
|
|
8
|
+
---
|
|
9
|
+
# Issue Triage Pattern
|
|
10
|
+
|
|
11
|
+
## Purpose
|
|
12
|
+
Scan for new GitHub Issues and propose labels, priorities, and assignment suggestions. Read-only (L1).
|
|
13
|
+
|
|
14
|
+
## State Schema
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"issues": [
|
|
18
|
+
{
|
|
19
|
+
"number": number,
|
|
20
|
+
"title": string,
|
|
21
|
+
"type": "bug" | "feature" | "question" | "docs",
|
|
22
|
+
"suggestedPriority": "high" | "medium" | "low",
|
|
23
|
+
"suggestedLabels": string[],
|
|
24
|
+
"suggestedAgent": string
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Agent Chain
|
|
31
|
+
1. planner — read open issues without labels, classify each, write triage report
|
|
32
|
+
|
|
33
|
+
## Prompt Template
|
|
34
|
+
"Review open issues without labels. For each: classify as bug/feature/question/docs, suggest priority (high/medium/low), and propose labels. Output to .opencode/devloom/reports/triage-YYYY-MM-DD.md. L1: do not edit any source code."
|
|
35
|
+
|
|
36
|
+
## Token Cost Estimate
|
|
37
|
+
~60K tokens per tick.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: post-merge-cleanup
|
|
3
|
+
cadence: "0 3 * * *"
|
|
4
|
+
level: L1
|
|
5
|
+
agents: [developer, qa]
|
|
6
|
+
cost: 40000
|
|
7
|
+
description: "Clean up stale branches and worktrees"
|
|
8
|
+
---
|
|
9
|
+
# Post-Merge Cleanup Pattern
|
|
10
|
+
|
|
11
|
+
## Purpose
|
|
12
|
+
Clean up stale branches and worktrees that have already been merged or are no longer needed. L1: reports only, no destructive actions without confirmation.
|
|
13
|
+
|
|
14
|
+
## State Schema
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"cleanup": {
|
|
18
|
+
"checked": "ISO string",
|
|
19
|
+
"staleBranches": number,
|
|
20
|
+
"mergedWorktrees": number,
|
|
21
|
+
"orphanedWorktrees": number,
|
|
22
|
+
"recommendedActions": string[]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Agent Chain
|
|
28
|
+
1. developer — list all worktrees, check merge status of each branch
|
|
29
|
+
2. qa — verify branches are safe to remove, report findings
|
|
30
|
+
|
|
31
|
+
## Safety
|
|
32
|
+
- L1: report-only, no automatic deletion
|
|
33
|
+
- Flag branches merged >7 days ago as cleanup candidates
|
|
34
|
+
- Never delete unmerged branches
|