panopticon-cli 0.4.5 → 0.4.7
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/README.md +84 -2695
- package/dist/{agents-B5NRTVHK.js → agents-54LDKMHR.js} +8 -3
- package/dist/chunk-44EOY2ZL.js +58 -0
- package/dist/chunk-44EOY2ZL.js.map +1 -0
- package/dist/chunk-BWGFN44T.js +224 -0
- package/dist/chunk-BWGFN44T.js.map +1 -0
- package/dist/chunk-F7NQZD6H.js +49 -0
- package/dist/chunk-F7NQZD6H.js.map +1 -0
- package/dist/chunk-HCTJFIJJ.js +159 -0
- package/dist/chunk-HCTJFIJJ.js.map +1 -0
- package/dist/chunk-JM6V62LT.js +650 -0
- package/dist/chunk-JM6V62LT.js.map +1 -0
- package/dist/chunk-K45YD6A3.js +254 -0
- package/dist/chunk-K45YD6A3.js.map +1 -0
- package/dist/chunk-KGPRXDMX.js +137 -0
- package/dist/chunk-KGPRXDMX.js.map +1 -0
- package/dist/chunk-KQAEUOML.js +278 -0
- package/dist/chunk-KQAEUOML.js.map +1 -0
- package/dist/chunk-NYVQC3D7.js +90 -0
- package/dist/chunk-NYVQC3D7.js.map +1 -0
- package/dist/chunk-PUR532O7.js +1556 -0
- package/dist/chunk-PUR532O7.js.map +1 -0
- package/dist/chunk-VTDDVLCK.js +1977 -0
- package/dist/chunk-VTDDVLCK.js.map +1 -0
- package/dist/chunk-Z24TY3XN.js +916 -0
- package/dist/chunk-Z24TY3XN.js.map +1 -0
- package/dist/chunk-ZHC57RCV.js +44 -0
- package/dist/chunk-ZHC57RCV.js.map +1 -0
- package/dist/{chunk-ITI4IC5A.js → chunk-ZZ3477GY.js} +69 -100
- package/dist/chunk-ZZ3477GY.js.map +1 -0
- package/dist/cli/index.js +4664 -2912
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/public/assets/index-CRqsEkmn.css +32 -0
- package/dist/dashboard/public/assets/index-DPSUbu4A.js +645 -0
- package/dist/dashboard/public/index.html +15 -3
- package/dist/dashboard/server.js +45663 -17860
- package/dist/dns-L3L2BB27.js +30 -0
- package/dist/dns-L3L2BB27.js.map +1 -0
- package/dist/index.d.ts +63 -3
- package/dist/index.js +42 -18
- package/dist/index.js.map +1 -1
- package/dist/projects-ESIB34QQ.js +43 -0
- package/dist/projects-ESIB34QQ.js.map +1 -0
- package/dist/remote-agents-Z3R2A5BN.js +25 -0
- package/dist/remote-agents-Z3R2A5BN.js.map +1 -0
- package/dist/remote-workspace-HI4VML6H.js +179 -0
- package/dist/remote-workspace-HI4VML6H.js.map +1 -0
- package/dist/specialist-context-SNCJ7O7G.js +256 -0
- package/dist/specialist-context-SNCJ7O7G.js.map +1 -0
- package/dist/specialist-logs-A7ODEK2T.js +43 -0
- package/dist/specialist-logs-A7ODEK2T.js.map +1 -0
- package/dist/specialists-C7XLNSXQ.js +121 -0
- package/dist/specialists-C7XLNSXQ.js.map +1 -0
- package/dist/traefik-WI3KSRGG.js +12 -0
- package/dist/traefik-WI3KSRGG.js.map +1 -0
- package/package.json +2 -1
- package/skills/beads/README.md +120 -0
- package/skills/beads/SKILL.md +214 -0
- package/skills/beads/adr/0001-bd-prime-as-source-of-truth.md +59 -0
- package/skills/beads/resources/AGENTS.md +62 -0
- package/skills/beads/resources/ASYNC_GATES.md +168 -0
- package/skills/beads/resources/BOUNDARIES.md +469 -0
- package/skills/beads/resources/CHEMISTRY_PATTERNS.md +197 -0
- package/skills/beads/resources/CLI_REFERENCE.md +558 -0
- package/skills/beads/resources/DEPENDENCIES.md +747 -0
- package/skills/beads/resources/INTEGRATION_PATTERNS.md +407 -0
- package/skills/beads/resources/ISSUE_CREATION.md +139 -0
- package/skills/beads/resources/MOLECULES.md +354 -0
- package/skills/beads/resources/PATTERNS.md +341 -0
- package/skills/beads/resources/RESUMABILITY.md +207 -0
- package/skills/beads/resources/STATIC_DATA.md +54 -0
- package/skills/beads/resources/TROUBLESHOOTING.md +489 -0
- package/skills/beads/resources/WORKFLOWS.md +623 -0
- package/skills/beads/resources/WORKTREES.md +94 -0
- package/skills/beads-completion-check/SKILL.md +90 -0
- package/skills/beads-panopticon-guide/SKILL.md +171 -0
- package/skills/bug-fix/SKILL.md +32 -0
- package/skills/clear-writing/SKILL.md +105 -0
- package/skills/clear-writing/references/elements-of-style/01-introductory.md +3 -0
- package/skills/clear-writing/references/elements-of-style/02-elementary-rules-of-usage.md +214 -0
- package/skills/clear-writing/references/elements-of-style/03-elementary-principles-of-composition.md +398 -0
- package/skills/clear-writing/references/elements-of-style/04-a-few-matters-of-form.md +89 -0
- package/skills/clear-writing/references/elements-of-style/05-words-and-expressions-commonly-misused.md +342 -0
- package/skills/clear-writing/references/signs-of-ai-writing.md +901 -0
- package/skills/code-review/SKILL.md +37 -0
- package/skills/code-review-performance/SKILL.md +53 -0
- package/skills/code-review-security/SKILL.md +35 -0
- package/skills/dependency-update/SKILL.md +30 -0
- package/skills/feature-work/SKILL.md +39 -0
- package/skills/incident-response/SKILL.md +32 -0
- package/skills/knowledge-capture/SKILL.md +463 -0
- package/skills/onboard-codebase/SKILL.md +34 -0
- package/skills/opus-plan/SKILL.md +400 -0
- package/skills/pan-approve/SKILL.md +136 -0
- package/skills/pan-code-review/SKILL.md +249 -0
- package/skills/pan-config/SKILL.md +164 -0
- package/skills/pan-convoy-synthesis/SKILL.md +249 -0
- package/skills/pan-diagnose/SKILL.md +360 -0
- package/skills/pan-docker/SKILL.md +279 -0
- package/skills/pan-docs/SKILL.md +113 -0
- package/skills/pan-down/SKILL.md +434 -0
- package/skills/pan-health/SKILL.md +240 -0
- package/skills/pan-help/SKILL.md +237 -0
- package/skills/pan-install/SKILL.md +339 -0
- package/skills/pan-issue/SKILL.md +596 -0
- package/skills/pan-kill/SKILL.md +172 -0
- package/skills/pan-logs/SKILL.md +255 -0
- package/skills/pan-network/SKILL.md +320 -0
- package/skills/pan-oversee/SKILL.md +290 -0
- package/skills/pan-plan/SKILL.md +521 -0
- package/skills/pan-projects/SKILL.md +239 -0
- package/skills/pan-quickstart/SKILL.md +440 -0
- package/skills/pan-reload/SKILL.md +44 -0
- package/skills/pan-rescue/SKILL.md +271 -0
- package/skills/pan-restart/SKILL.md +53 -0
- package/skills/pan-setup/SKILL.md +478 -0
- package/skills/pan-skill-creator/SKILL.md +168 -0
- package/skills/pan-skill-creator/references/output-patterns.md +141 -0
- package/skills/pan-skill-creator/references/workflows.md +90 -0
- package/skills/pan-skill-creator/scripts/init_skill.py +176 -0
- package/skills/pan-status/SKILL.md +493 -0
- package/skills/pan-subagent-creator/SKILL.md +295 -0
- package/skills/pan-subagent-creator/assets/validate-readonly-query.sh +35 -0
- package/skills/pan-subagent-creator/references/example-agents.md +308 -0
- package/skills/pan-subagent-creator/scripts/init_agent.py +126 -0
- package/skills/pan-sync/SKILL.md +272 -0
- package/skills/pan-tell/SKILL.md +157 -0
- package/skills/pan-test-config/SKILL.md +208 -0
- package/skills/pan-tracker/SKILL.md +288 -0
- package/skills/pan-up/SKILL.md +458 -0
- package/skills/pan-workspace-config/SKILL.md +303 -0
- package/skills/refactor/SKILL.md +30 -0
- package/skills/refactor-radar/SKILL.md +475 -0
- package/skills/release/SKILL.md +25 -0
- package/skills/send-feedback-to-agent/SKILL.md +98 -0
- package/skills/session-health/SKILL.md +76 -0
- package/skills/session-health/scripts/check_sessions.py +166 -0
- package/skills/skill-creator/SKILL.md +92 -0
- package/skills/skill-creator/scripts/init_skill.py +152 -0
- package/skills/skill-creator/scripts/package_skill.py +123 -0
- package/skills/stitch-design-md/README.md +34 -0
- package/skills/stitch-design-md/SKILL.md +172 -0
- package/skills/stitch-design-md/examples/DESIGN.md +154 -0
- package/skills/stitch-react-components/README.md +36 -0
- package/skills/stitch-react-components/SKILL.md +47 -0
- package/skills/stitch-react-components/examples/gold-standard-card.tsx +80 -0
- package/skills/stitch-react-components/package-lock.json +231 -0
- package/skills/stitch-react-components/package.json +16 -0
- package/skills/stitch-react-components/resources/architecture-checklist.md +15 -0
- package/skills/stitch-react-components/resources/component-template.tsx +37 -0
- package/skills/stitch-react-components/resources/stitch-api-reference.md +14 -0
- package/skills/stitch-react-components/resources/style-guide.json +27 -0
- package/skills/stitch-react-components/scripts/fetch-stitch.sh +30 -0
- package/skills/stitch-react-components/scripts/validate.js +68 -0
- package/skills/stitch-setup/SKILL.md +94 -0
- package/skills/web-design-guidelines/SKILL.md +39 -0
- package/skills/work-complete/SKILL.md +79 -0
- package/templates/traefik/docker-compose.yml +1 -1
- package/templates/traefik/dynamic/panopticon.yml.template +41 -0
- package/templates/traefik/traefik.yml +8 -0
- package/dist/chunk-7HHDVXBM.js +0 -349
- package/dist/chunk-7HHDVXBM.js.map +0 -1
- package/dist/chunk-H45CLB7E.js +0 -2044
- package/dist/chunk-H45CLB7E.js.map +0 -1
- package/dist/chunk-ITI4IC5A.js.map +0 -1
- package/dist/dashboard/public/assets/index-BDd8hGYb.css +0 -32
- package/dist/dashboard/public/assets/index-sFwLPko-.js +0 -556
- package/templates/traefik/dynamic/panopticon.yml +0 -51
- /package/dist/{agents-B5NRTVHK.js.map → agents-54LDKMHR.js.map} +0 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getRecentRunLogs,
|
|
3
|
+
init_specialist_logs
|
|
4
|
+
} from "./chunk-VTDDVLCK.js";
|
|
5
|
+
import {
|
|
6
|
+
getModelId,
|
|
7
|
+
init_work_type_router
|
|
8
|
+
} from "./chunk-PUR532O7.js";
|
|
9
|
+
import {
|
|
10
|
+
getProject,
|
|
11
|
+
init_projects
|
|
12
|
+
} from "./chunk-K45YD6A3.js";
|
|
13
|
+
import {
|
|
14
|
+
PANOPTICON_HOME,
|
|
15
|
+
init_paths
|
|
16
|
+
} from "./chunk-KGPRXDMX.js";
|
|
17
|
+
import {
|
|
18
|
+
__esm,
|
|
19
|
+
__require,
|
|
20
|
+
init_esm_shims
|
|
21
|
+
} from "./chunk-ZHC57RCV.js";
|
|
22
|
+
|
|
23
|
+
// src/lib/cloister/specialist-context.ts
|
|
24
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
25
|
+
import { join } from "path";
|
|
26
|
+
import { exec } from "child_process";
|
|
27
|
+
import { promisify } from "util";
|
|
28
|
+
function getContextDirectory(projectKey, specialistType) {
|
|
29
|
+
return join(SPECIALISTS_DIR, projectKey, specialistType, "context");
|
|
30
|
+
}
|
|
31
|
+
function getContextDigestPath(projectKey, specialistType) {
|
|
32
|
+
const contextDir = getContextDirectory(projectKey, specialistType);
|
|
33
|
+
return join(contextDir, "latest-digest.md");
|
|
34
|
+
}
|
|
35
|
+
function ensureContextDirectory(projectKey, specialistType) {
|
|
36
|
+
const contextDir = getContextDirectory(projectKey, specialistType);
|
|
37
|
+
if (!existsSync(contextDir)) {
|
|
38
|
+
mkdirSync(contextDir, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function loadContextDigest(projectKey, specialistType) {
|
|
42
|
+
const digestPath = getContextDigestPath(projectKey, specialistType);
|
|
43
|
+
if (!existsSync(digestPath)) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
return readFileSync(digestPath, "utf-8");
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error(`[specialist-context] Failed to load digest for ${projectKey}/${specialistType}:`, error);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function getContextRunsCount(projectKey) {
|
|
54
|
+
const project = getProject(projectKey);
|
|
55
|
+
return project?.specialists?.context_runs ?? 5;
|
|
56
|
+
}
|
|
57
|
+
function getDigestModel(projectKey, specialistType) {
|
|
58
|
+
const project = getProject(projectKey);
|
|
59
|
+
if (project?.specialists?.digest_model) {
|
|
60
|
+
return project.specialists.digest_model;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const workTypeId = `specialist-${specialistType}`;
|
|
64
|
+
return getModelId(workTypeId);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
return "claude-sonnet-4-5";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function generateContextDigest(projectKey, specialistType, options = {}) {
|
|
70
|
+
ensureContextDirectory(projectKey, specialistType);
|
|
71
|
+
const runCount = options.runCount ?? getContextRunsCount(projectKey);
|
|
72
|
+
const recentRuns = getRecentRunLogs(projectKey, specialistType, runCount);
|
|
73
|
+
if (recentRuns.length === 0 && !options.force) {
|
|
74
|
+
console.log(`[specialist-context] No recent runs for ${projectKey}/${specialistType}, skipping digest generation`);
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const prompt = buildDigestPrompt(projectKey, specialistType, recentRuns);
|
|
78
|
+
const model = options.model ?? getDigestModel(projectKey, specialistType);
|
|
79
|
+
try {
|
|
80
|
+
console.log(`[specialist-context] Generating digest for ${projectKey}/${specialistType} using ${model}...`);
|
|
81
|
+
const tempDir = join(PANOPTICON_HOME, "tmp");
|
|
82
|
+
if (!existsSync(tempDir)) {
|
|
83
|
+
mkdirSync(tempDir, { recursive: true });
|
|
84
|
+
}
|
|
85
|
+
const promptFile = join(tempDir, `digest-prompt-${Date.now()}.md`);
|
|
86
|
+
writeFileSync(promptFile, prompt, "utf-8");
|
|
87
|
+
const { stdout, stderr } = await execAsync(
|
|
88
|
+
`claude --dangerously-skip-permissions --model ${model} "$(cat '${promptFile}')"`,
|
|
89
|
+
{
|
|
90
|
+
encoding: "utf-8",
|
|
91
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
92
|
+
// 10MB buffer
|
|
93
|
+
timeout: 6e4
|
|
94
|
+
// 60 second timeout
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
try {
|
|
98
|
+
const { unlinkSync } = await import("fs");
|
|
99
|
+
unlinkSync(promptFile);
|
|
100
|
+
} catch {
|
|
101
|
+
}
|
|
102
|
+
if (stderr && !stderr.includes("warning")) {
|
|
103
|
+
console.error(`[specialist-context] Claude stderr:`, stderr);
|
|
104
|
+
}
|
|
105
|
+
const digest = stdout.trim();
|
|
106
|
+
if (!digest) {
|
|
107
|
+
console.error(`[specialist-context] Empty digest generated`);
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const digestPath = getContextDigestPath(projectKey, specialistType);
|
|
111
|
+
writeFileSync(digestPath, digest, "utf-8");
|
|
112
|
+
console.log(`[specialist-context] Generated digest (${digest.length} chars)`);
|
|
113
|
+
return digest;
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error(`[specialist-context] Failed to generate digest:`, error.message);
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function buildDigestPrompt(projectKey, specialistType, recentRuns) {
|
|
120
|
+
const project = getProject(projectKey);
|
|
121
|
+
const projectName = project?.name || projectKey;
|
|
122
|
+
let prompt = `You are analyzing the recent history of a ${specialistType} specialist for the ${projectName} project.
|
|
123
|
+
|
|
124
|
+
Your task is to generate a concise context digest that will be provided to the specialist at the start of their next run. This digest should help them understand:
|
|
125
|
+
- Common patterns and practices observed in recent runs
|
|
126
|
+
- Recurring issues or failure modes
|
|
127
|
+
- Successful approaches and best practices
|
|
128
|
+
- Any project-specific context that would be helpful
|
|
129
|
+
|
|
130
|
+
Generate a digest in markdown format. Keep it focused and actionable - aim for 200-400 words total.
|
|
131
|
+
|
|
132
|
+
## Recent Runs
|
|
133
|
+
|
|
134
|
+
`;
|
|
135
|
+
if (recentRuns.length === 0) {
|
|
136
|
+
prompt += `No recent runs available yet. This is the specialist's first run.
|
|
137
|
+
|
|
138
|
+
`;
|
|
139
|
+
prompt += `Generate a brief introduction for the specialist explaining their role and what to expect.
|
|
140
|
+
`;
|
|
141
|
+
} else {
|
|
142
|
+
recentRuns.forEach((run, index) => {
|
|
143
|
+
prompt += `### Run ${index + 1}: ${run.metadata.issueId} (${run.metadata.status || "unknown"})
|
|
144
|
+
`;
|
|
145
|
+
prompt += `Started: ${run.metadata.startedAt}
|
|
146
|
+
`;
|
|
147
|
+
if (run.metadata.finishedAt) {
|
|
148
|
+
prompt += `Finished: ${run.metadata.finishedAt}
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
if (run.metadata.duration) {
|
|
152
|
+
const durationSec = Math.floor(run.metadata.duration / 1e3);
|
|
153
|
+
const minutes = Math.floor(durationSec / 60);
|
|
154
|
+
const seconds = durationSec % 60;
|
|
155
|
+
prompt += `Duration: ${minutes}m ${seconds}s
|
|
156
|
+
`;
|
|
157
|
+
}
|
|
158
|
+
if (run.metadata.notes) {
|
|
159
|
+
prompt += `Notes: ${run.metadata.notes}
|
|
160
|
+
`;
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
const logContent = readFileSync(run.filePath, "utf-8");
|
|
164
|
+
const maxChars = 500;
|
|
165
|
+
const transcriptMatch = logContent.match(/## Session Transcript\n([\s\S]+?)(?=\n## |$)/);
|
|
166
|
+
if (transcriptMatch) {
|
|
167
|
+
let transcript = transcriptMatch[1].trim();
|
|
168
|
+
if (transcript.length > maxChars) {
|
|
169
|
+
transcript = transcript.substring(0, maxChars) + "... [truncated]";
|
|
170
|
+
}
|
|
171
|
+
prompt += `
|
|
172
|
+
Transcript excerpt:
|
|
173
|
+
${transcript}
|
|
174
|
+
`;
|
|
175
|
+
}
|
|
176
|
+
} catch (error) {
|
|
177
|
+
}
|
|
178
|
+
prompt += `
|
|
179
|
+
`;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
prompt += `
|
|
183
|
+
## Your Task
|
|
184
|
+
|
|
185
|
+
Generate a context digest that summarizes the key insights from these runs. Format it as:
|
|
186
|
+
|
|
187
|
+
# Recent ${specialistType} History for ${projectName}
|
|
188
|
+
|
|
189
|
+
## Summary
|
|
190
|
+
[2-3 sentence overview of patterns and trends]
|
|
191
|
+
|
|
192
|
+
## Common Patterns
|
|
193
|
+
[Bulleted list of observed patterns]
|
|
194
|
+
|
|
195
|
+
## Recent Notable Runs
|
|
196
|
+
[Brief highlights of 2-3 most interesting runs]
|
|
197
|
+
|
|
198
|
+
## Recommendations
|
|
199
|
+
[Specific guidance for the next run based on this history]
|
|
200
|
+
|
|
201
|
+
Keep it concise, actionable, and focused on helping the specialist be more effective.`;
|
|
202
|
+
return prompt;
|
|
203
|
+
}
|
|
204
|
+
async function regenerateContextDigest(projectKey, specialistType) {
|
|
205
|
+
return generateContextDigest(projectKey, specialistType, { force: true });
|
|
206
|
+
}
|
|
207
|
+
function scheduleDigestGeneration(projectKey, specialistType) {
|
|
208
|
+
generateContextDigest(projectKey, specialistType).catch((error) => {
|
|
209
|
+
console.error(
|
|
210
|
+
`[specialist-context] Background digest generation failed for ${projectKey}/${specialistType}:`,
|
|
211
|
+
error
|
|
212
|
+
);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function hasContextDigest(projectKey, specialistType) {
|
|
216
|
+
const digestPath = getContextDigestPath(projectKey, specialistType);
|
|
217
|
+
return existsSync(digestPath);
|
|
218
|
+
}
|
|
219
|
+
function deleteContextDigest(projectKey, specialistType) {
|
|
220
|
+
const digestPath = getContextDigestPath(projectKey, specialistType);
|
|
221
|
+
if (!existsSync(digestPath)) {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
const { unlinkSync } = __require("fs");
|
|
226
|
+
unlinkSync(digestPath);
|
|
227
|
+
return true;
|
|
228
|
+
} catch (error) {
|
|
229
|
+
console.error(`[specialist-context] Failed to delete digest:`, error);
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
var execAsync, SPECIALISTS_DIR;
|
|
234
|
+
var init_specialist_context = __esm({
|
|
235
|
+
"src/lib/cloister/specialist-context.ts"() {
|
|
236
|
+
init_esm_shims();
|
|
237
|
+
init_paths();
|
|
238
|
+
init_specialist_logs();
|
|
239
|
+
init_projects();
|
|
240
|
+
init_work_type_router();
|
|
241
|
+
execAsync = promisify(exec);
|
|
242
|
+
SPECIALISTS_DIR = join(PANOPTICON_HOME, "specialists");
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
init_specialist_context();
|
|
246
|
+
export {
|
|
247
|
+
deleteContextDigest,
|
|
248
|
+
generateContextDigest,
|
|
249
|
+
getContextDigestPath,
|
|
250
|
+
getContextDirectory,
|
|
251
|
+
hasContextDigest,
|
|
252
|
+
loadContextDigest,
|
|
253
|
+
regenerateContextDigest,
|
|
254
|
+
scheduleDigestGeneration
|
|
255
|
+
};
|
|
256
|
+
//# sourceMappingURL=specialist-context-SNCJ7O7G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/cloister/specialist-context.ts"],"sourcesContent":["/**\n * Specialist Context Management\n *\n * Generates and manages AI-powered context digests from recent specialist runs.\n * These digests seed new specialist sessions with learned patterns and expertise.\n *\n * Directory structure:\n * ~/.panopticon/specialists/{projectKey}/{specialistType}/context/latest-digest.md\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { PANOPTICON_HOME } from '../paths.js';\nimport { getRecentRunLogs, type RunLogEntry } from './specialist-logs.js';\nimport { getProject } from '../projects.js';\nimport { getModelId } from '../work-type-router.js';\n\nconst execAsync = promisify(exec);\n\nconst SPECIALISTS_DIR = join(PANOPTICON_HOME, 'specialists');\n\n/**\n * Get the context directory for a project's specialist\n */\nexport function getContextDirectory(projectKey: string, specialistType: string): string {\n return join(SPECIALISTS_DIR, projectKey, specialistType, 'context');\n}\n\n/**\n * Get the path to the latest context digest file\n */\nexport function getContextDigestPath(projectKey: string, specialistType: string): string {\n const contextDir = getContextDirectory(projectKey, specialistType);\n return join(contextDir, 'latest-digest.md');\n}\n\n/**\n * Ensure context directory exists for a project's specialist\n */\nfunction ensureContextDirectory(projectKey: string, specialistType: string): void {\n const contextDir = getContextDirectory(projectKey, specialistType);\n if (!existsSync(contextDir)) {\n mkdirSync(contextDir, { recursive: true });\n }\n}\n\n/**\n * Load the context digest for a specialist\n *\n * @param projectKey - Project identifier\n * @param specialistType - Specialist type\n * @returns Context digest content or null if not found\n */\nexport function loadContextDigest(projectKey: string, specialistType: string): string | null {\n const digestPath = getContextDigestPath(projectKey, specialistType);\n\n if (!existsSync(digestPath)) {\n return null;\n }\n\n try {\n return readFileSync(digestPath, 'utf-8');\n } catch (error) {\n console.error(`[specialist-context] Failed to load digest for ${projectKey}/${specialistType}:`, error);\n return null;\n }\n}\n\n/**\n * Get the number of recent runs to include in context\n *\n * Reads from project config or uses default.\n *\n * @param projectKey - Project identifier\n * @returns Number of runs to include (default: 5)\n */\nfunction getContextRunsCount(projectKey: string): number {\n const project = getProject(projectKey);\n return project?.specialists?.context_runs ?? 5;\n}\n\n/**\n * Get the model to use for digest generation\n *\n * Reads from project config or uses the same model as the specialist.\n *\n * @param projectKey - Project identifier\n * @param specialistType - Specialist type\n * @returns Model ID to use\n */\nfunction getDigestModel(projectKey: string, specialistType: string): string {\n const project = getProject(projectKey);\n\n // Check for explicit digest model in project config\n if (project?.specialists?.digest_model) {\n return project.specialists.digest_model;\n }\n\n // Fall back to specialist's model\n try {\n const workTypeId = `specialist-${specialistType}` as any;\n return getModelId(workTypeId);\n } catch (error) {\n // Default to Sonnet if can't resolve\n return 'claude-sonnet-4-5';\n }\n}\n\n/**\n * Generate a context digest from recent runs using AI\n *\n * Creates an AI-generated summary of recent specialist runs to provide\n * context for the next run. This includes patterns, learnings, and common issues.\n *\n * @param projectKey - Project identifier\n * @param specialistType - Specialist type\n * @param options - Generation options\n * @returns Generated digest or null if generation failed\n */\nexport async function generateContextDigest(\n projectKey: string,\n specialistType: string,\n options: {\n runCount?: number;\n model?: string;\n force?: boolean; // Generate even if no recent runs\n } = {}\n): Promise<string | null> {\n ensureContextDirectory(projectKey, specialistType);\n\n // Get recent runs\n const runCount = options.runCount ?? getContextRunsCount(projectKey);\n const recentRuns = getRecentRunLogs(projectKey, specialistType, runCount);\n\n if (recentRuns.length === 0 && !options.force) {\n console.log(`[specialist-context] No recent runs for ${projectKey}/${specialistType}, skipping digest generation`);\n return null;\n }\n\n // Build prompt for digest generation\n const prompt = buildDigestPrompt(projectKey, specialistType, recentRuns);\n const model = options.model ?? getDigestModel(projectKey, specialistType);\n\n try {\n console.log(`[specialist-context] Generating digest for ${projectKey}/${specialistType} using ${model}...`);\n\n // Use Claude Code CLI to generate digest\n // Write prompt to temp file to avoid shell escaping issues\n const tempDir = join(PANOPTICON_HOME, 'tmp');\n if (!existsSync(tempDir)) {\n mkdirSync(tempDir, { recursive: true });\n }\n\n const promptFile = join(tempDir, `digest-prompt-${Date.now()}.md`);\n writeFileSync(promptFile, prompt, 'utf-8');\n\n // Run Claude Code with the prompt\n const { stdout, stderr } = await execAsync(\n `claude --dangerously-skip-permissions --model ${model} \"$(cat '${promptFile}')\"`,\n {\n encoding: 'utf-8',\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer\n timeout: 60000, // 60 second timeout\n }\n );\n\n // Clean up temp file\n try {\n const { unlinkSync } = await import('fs');\n unlinkSync(promptFile);\n } catch {\n // Ignore cleanup errors\n }\n\n if (stderr && !stderr.includes('warning')) {\n console.error(`[specialist-context] Claude stderr:`, stderr);\n }\n\n const digest = stdout.trim();\n\n if (!digest) {\n console.error(`[specialist-context] Empty digest generated`);\n return null;\n }\n\n // Save digest\n const digestPath = getContextDigestPath(projectKey, specialistType);\n writeFileSync(digestPath, digest, 'utf-8');\n\n console.log(`[specialist-context] Generated digest (${digest.length} chars)`);\n return digest;\n } catch (error: any) {\n console.error(`[specialist-context] Failed to generate digest:`, error.message);\n // Degrade gracefully - return null so specialist can continue without context\n return null;\n }\n}\n\n/**\n * Build the prompt for digest generation\n *\n * @param projectKey - Project identifier\n * @param specialistType - Specialist type\n * @param recentRuns - Recent run logs\n * @returns Prompt for Claude\n */\nfunction buildDigestPrompt(\n projectKey: string,\n specialistType: string,\n recentRuns: RunLogEntry[]\n): string {\n const project = getProject(projectKey);\n const projectName = project?.name || projectKey;\n\n let prompt = `You are analyzing the recent history of a ${specialistType} specialist for the ${projectName} project.\n\nYour task is to generate a concise context digest that will be provided to the specialist at the start of their next run. This digest should help them understand:\n- Common patterns and practices observed in recent runs\n- Recurring issues or failure modes\n- Successful approaches and best practices\n- Any project-specific context that would be helpful\n\nGenerate a digest in markdown format. Keep it focused and actionable - aim for 200-400 words total.\n\n## Recent Runs\n\n`;\n\n if (recentRuns.length === 0) {\n prompt += `No recent runs available yet. This is the specialist's first run.\\n\\n`;\n prompt += `Generate a brief introduction for the specialist explaining their role and what to expect.\\n`;\n } else {\n recentRuns.forEach((run, index) => {\n prompt += `### Run ${index + 1}: ${run.metadata.issueId} (${run.metadata.status || 'unknown'})\\n`;\n prompt += `Started: ${run.metadata.startedAt}\\n`;\n if (run.metadata.finishedAt) {\n prompt += `Finished: ${run.metadata.finishedAt}\\n`;\n }\n if (run.metadata.duration) {\n const durationSec = Math.floor(run.metadata.duration / 1000);\n const minutes = Math.floor(durationSec / 60);\n const seconds = durationSec % 60;\n prompt += `Duration: ${minutes}m ${seconds}s\\n`;\n }\n if (run.metadata.notes) {\n prompt += `Notes: ${run.metadata.notes}\\n`;\n }\n\n // Include snippets from the log if available\n try {\n const logContent = readFileSync(run.filePath, 'utf-8');\n // Extract key sections (limit to avoid overwhelming the prompt)\n const maxChars = 500;\n const transcriptMatch = logContent.match(/## Session Transcript\\n([\\s\\S]+?)(?=\\n## |$)/);\n if (transcriptMatch) {\n let transcript = transcriptMatch[1].trim();\n if (transcript.length > maxChars) {\n transcript = transcript.substring(0, maxChars) + '... [truncated]';\n }\n prompt += `\\nTranscript excerpt:\\n${transcript}\\n`;\n }\n } catch (error) {\n // If we can't read the log, skip the excerpt\n }\n\n prompt += `\\n`;\n });\n }\n\n prompt += `\\n## Your Task\n\nGenerate a context digest that summarizes the key insights from these runs. Format it as:\n\n# Recent ${specialistType} History for ${projectName}\n\n## Summary\n[2-3 sentence overview of patterns and trends]\n\n## Common Patterns\n[Bulleted list of observed patterns]\n\n## Recent Notable Runs\n[Brief highlights of 2-3 most interesting runs]\n\n## Recommendations\n[Specific guidance for the next run based on this history]\n\nKeep it concise, actionable, and focused on helping the specialist be more effective.`;\n\n return prompt;\n}\n\n/**\n * Regenerate the context digest\n *\n * Forces regeneration even if a digest already exists.\n *\n * @param projectKey - Project identifier\n * @param specialistType - Specialist type\n * @returns Generated digest or null if generation failed\n */\nexport async function regenerateContextDigest(\n projectKey: string,\n specialistType: string\n): Promise<string | null> {\n return generateContextDigest(projectKey, specialistType, { force: true });\n}\n\n/**\n * Generate digest after a run completes (async, fire-and-forget)\n *\n * This is called after a specialist finishes a run to update the context\n * for the next run. It runs asynchronously and failures are logged but not thrown.\n *\n * @param projectKey - Project identifier\n * @param specialistType - Specialist type\n */\nexport function scheduleDigestGeneration(projectKey: string, specialistType: string): void {\n // Run async without awaiting\n generateContextDigest(projectKey, specialistType).catch((error) => {\n console.error(\n `[specialist-context] Background digest generation failed for ${projectKey}/${specialistType}:`,\n error\n );\n });\n}\n\n/**\n * Check if a context digest exists\n *\n * @param projectKey - Project identifier\n * @param specialistType - Specialist type\n * @returns True if digest file exists\n */\nexport function hasContextDigest(projectKey: string, specialistType: string): boolean {\n const digestPath = getContextDigestPath(projectKey, specialistType);\n return existsSync(digestPath);\n}\n\n/**\n * Delete the context digest\n *\n * Useful for forcing a fresh start or clearing stale context.\n *\n * @param projectKey - Project identifier\n * @param specialistType - Specialist type\n * @returns True if digest was deleted, false if it didn't exist\n */\nexport function deleteContextDigest(projectKey: string, specialistType: string): boolean {\n const digestPath = getContextDigestPath(projectKey, specialistType);\n\n if (!existsSync(digestPath)) {\n return false;\n }\n\n try {\n const { unlinkSync } = require('fs');\n unlinkSync(digestPath);\n return true;\n } catch (error) {\n console.error(`[specialist-context] Failed to delete digest:`, error);\n return false;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAX_LOG_SIZE,
|
|
3
|
+
appendToRunLog,
|
|
4
|
+
checkLogSizeLimit,
|
|
5
|
+
cleanupAllLogs,
|
|
6
|
+
cleanupOldLogs,
|
|
7
|
+
createRunLog,
|
|
8
|
+
finalizeRunLog,
|
|
9
|
+
generateRunId,
|
|
10
|
+
getRecentRunLogs,
|
|
11
|
+
getRunLog,
|
|
12
|
+
getRunLogPath,
|
|
13
|
+
getRunLogSize,
|
|
14
|
+
getRunsDirectory,
|
|
15
|
+
init_specialist_logs,
|
|
16
|
+
isRunLogActive,
|
|
17
|
+
listRunLogs,
|
|
18
|
+
parseLogMetadata
|
|
19
|
+
} from "./chunk-VTDDVLCK.js";
|
|
20
|
+
import "./chunk-PUR532O7.js";
|
|
21
|
+
import "./chunk-K45YD6A3.js";
|
|
22
|
+
import "./chunk-KGPRXDMX.js";
|
|
23
|
+
import "./chunk-ZHC57RCV.js";
|
|
24
|
+
init_specialist_logs();
|
|
25
|
+
export {
|
|
26
|
+
MAX_LOG_SIZE,
|
|
27
|
+
appendToRunLog,
|
|
28
|
+
checkLogSizeLimit,
|
|
29
|
+
cleanupAllLogs,
|
|
30
|
+
cleanupOldLogs,
|
|
31
|
+
createRunLog,
|
|
32
|
+
finalizeRunLog,
|
|
33
|
+
generateRunId,
|
|
34
|
+
getRecentRunLogs,
|
|
35
|
+
getRunLog,
|
|
36
|
+
getRunLogPath,
|
|
37
|
+
getRunLogSize,
|
|
38
|
+
getRunsDirectory,
|
|
39
|
+
isRunLogActive,
|
|
40
|
+
listRunLogs,
|
|
41
|
+
parseLogMetadata
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=specialist-logs-A7ODEK2T.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkSpecialistQueue,
|
|
3
|
+
clearSessionId,
|
|
4
|
+
completeSpecialistTask,
|
|
5
|
+
countContextTokens,
|
|
6
|
+
disableSpecialist,
|
|
7
|
+
enableSpecialist,
|
|
8
|
+
ensureProjectSpecialistDir,
|
|
9
|
+
exitGracePeriod,
|
|
10
|
+
findSessionFile,
|
|
11
|
+
getAllProjectSpecialistStatuses,
|
|
12
|
+
getAllSpecialistStatus,
|
|
13
|
+
getAllSpecialists,
|
|
14
|
+
getEnabledSpecialists,
|
|
15
|
+
getFeedbackStats,
|
|
16
|
+
getGracePeriodState,
|
|
17
|
+
getNextSpecialistTask,
|
|
18
|
+
getPendingFeedback,
|
|
19
|
+
getProjectSpecialistDir,
|
|
20
|
+
getProjectSpecialistMetadata,
|
|
21
|
+
getSessionFilePath,
|
|
22
|
+
getSessionId,
|
|
23
|
+
getSpecialistMetadata,
|
|
24
|
+
getSpecialistState,
|
|
25
|
+
getSpecialistStatus,
|
|
26
|
+
getTmuxSessionName,
|
|
27
|
+
incrementProjectRunCount,
|
|
28
|
+
initSpecialistsDirectory,
|
|
29
|
+
init_specialists,
|
|
30
|
+
initializeEnabledSpecialists,
|
|
31
|
+
initializeSpecialist,
|
|
32
|
+
isEnabled,
|
|
33
|
+
isInitialized,
|
|
34
|
+
isRunning,
|
|
35
|
+
listProjectsWithSpecialists,
|
|
36
|
+
listSessionFiles,
|
|
37
|
+
listSpecialistsForProject,
|
|
38
|
+
loadRegistry,
|
|
39
|
+
pauseGracePeriod,
|
|
40
|
+
recordWake,
|
|
41
|
+
resumeGracePeriod,
|
|
42
|
+
saveRegistry,
|
|
43
|
+
sendFeedbackToAgent,
|
|
44
|
+
setCurrentRun,
|
|
45
|
+
setSessionId,
|
|
46
|
+
signalSpecialistCompletion,
|
|
47
|
+
spawnEphemeralSpecialist,
|
|
48
|
+
startGracePeriod,
|
|
49
|
+
submitToSpecialistQueue,
|
|
50
|
+
terminateSpecialist,
|
|
51
|
+
updateContextTokens,
|
|
52
|
+
updateProjectSpecialistMetadata,
|
|
53
|
+
updateRunStatus,
|
|
54
|
+
updateSpecialistMetadata,
|
|
55
|
+
wakeSpecialist,
|
|
56
|
+
wakeSpecialistOrQueue,
|
|
57
|
+
wakeSpecialistWithTask
|
|
58
|
+
} from "./chunk-VTDDVLCK.js";
|
|
59
|
+
import "./chunk-PUR532O7.js";
|
|
60
|
+
import "./chunk-K45YD6A3.js";
|
|
61
|
+
import "./chunk-KGPRXDMX.js";
|
|
62
|
+
import "./chunk-ZHC57RCV.js";
|
|
63
|
+
init_specialists();
|
|
64
|
+
export {
|
|
65
|
+
checkSpecialistQueue,
|
|
66
|
+
clearSessionId,
|
|
67
|
+
completeSpecialistTask,
|
|
68
|
+
countContextTokens,
|
|
69
|
+
disableSpecialist,
|
|
70
|
+
enableSpecialist,
|
|
71
|
+
ensureProjectSpecialistDir,
|
|
72
|
+
exitGracePeriod,
|
|
73
|
+
findSessionFile,
|
|
74
|
+
getAllProjectSpecialistStatuses,
|
|
75
|
+
getAllSpecialistStatus,
|
|
76
|
+
getAllSpecialists,
|
|
77
|
+
getEnabledSpecialists,
|
|
78
|
+
getFeedbackStats,
|
|
79
|
+
getGracePeriodState,
|
|
80
|
+
getNextSpecialistTask,
|
|
81
|
+
getPendingFeedback,
|
|
82
|
+
getProjectSpecialistDir,
|
|
83
|
+
getProjectSpecialistMetadata,
|
|
84
|
+
getSessionFilePath,
|
|
85
|
+
getSessionId,
|
|
86
|
+
getSpecialistMetadata,
|
|
87
|
+
getSpecialistState,
|
|
88
|
+
getSpecialistStatus,
|
|
89
|
+
getTmuxSessionName,
|
|
90
|
+
incrementProjectRunCount,
|
|
91
|
+
initSpecialistsDirectory,
|
|
92
|
+
initializeEnabledSpecialists,
|
|
93
|
+
initializeSpecialist,
|
|
94
|
+
isEnabled,
|
|
95
|
+
isInitialized,
|
|
96
|
+
isRunning,
|
|
97
|
+
listProjectsWithSpecialists,
|
|
98
|
+
listSessionFiles,
|
|
99
|
+
listSpecialistsForProject,
|
|
100
|
+
loadRegistry,
|
|
101
|
+
pauseGracePeriod,
|
|
102
|
+
recordWake,
|
|
103
|
+
resumeGracePeriod,
|
|
104
|
+
saveRegistry,
|
|
105
|
+
sendFeedbackToAgent,
|
|
106
|
+
setCurrentRun,
|
|
107
|
+
setSessionId,
|
|
108
|
+
signalSpecialistCompletion,
|
|
109
|
+
spawnEphemeralSpecialist,
|
|
110
|
+
startGracePeriod,
|
|
111
|
+
submitToSpecialistQueue,
|
|
112
|
+
terminateSpecialist,
|
|
113
|
+
updateContextTokens,
|
|
114
|
+
updateProjectSpecialistMetadata,
|
|
115
|
+
updateRunStatus,
|
|
116
|
+
updateSpecialistMetadata,
|
|
117
|
+
wakeSpecialist,
|
|
118
|
+
wakeSpecialistOrQueue,
|
|
119
|
+
wakeSpecialistWithTask
|
|
120
|
+
};
|
|
121
|
+
//# sourceMappingURL=specialists-C7XLNSXQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cleanupTemplateFiles,
|
|
3
|
+
generatePanopticonTraefikConfig
|
|
4
|
+
} from "./chunk-F7NQZD6H.js";
|
|
5
|
+
import "./chunk-NYVQC3D7.js";
|
|
6
|
+
import "./chunk-KGPRXDMX.js";
|
|
7
|
+
import "./chunk-ZHC57RCV.js";
|
|
8
|
+
export {
|
|
9
|
+
cleanupTemplateFiles,
|
|
10
|
+
generatePanopticonTraefikConfig
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=traefik-WI3KSRGG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "panopticon-cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7",
|
|
4
4
|
"description": "Multi-agent orchestration for AI coding assistants (Claude Code, Codex, Cursor, Gemini CLI)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agents",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"files": [
|
|
39
39
|
"dist",
|
|
40
40
|
"templates",
|
|
41
|
+
"skills",
|
|
41
42
|
"scripts/git-hooks",
|
|
42
43
|
"README.md",
|
|
43
44
|
"LICENSE"
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Beads Skill for Claude Code
|
|
2
|
+
|
|
3
|
+
A comprehensive skill for using [beads](https://github.com/steveyegge/beads) (bd) issue tracking with Claude Code.
|
|
4
|
+
|
|
5
|
+
## What This Skill Does
|
|
6
|
+
|
|
7
|
+
This skill teaches Claude Code how to use bd effectively for:
|
|
8
|
+
- **Multi-session work tracking** - Persistent memory across conversation compactions
|
|
9
|
+
- **Dependency management** - Graph-based issue relationships
|
|
10
|
+
- **Session handoff** - Writing notes that survive context resets
|
|
11
|
+
- **Molecules and wisps** (v0.34.0+) - Reusable work templates and ephemeral workflows
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
Copy the `beads/` directory to your Claude Code skills location:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Global installation
|
|
19
|
+
cp -r beads ~/.claude/skills/
|
|
20
|
+
|
|
21
|
+
# Or project-local
|
|
22
|
+
cp -r beads .claude/skills/
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## When Claude Uses This Skill
|
|
26
|
+
|
|
27
|
+
The skill activates when conversations involve:
|
|
28
|
+
- "multi-session", "complex dependencies", "resume after weeks"
|
|
29
|
+
- "project memory", "persistent context", "side quest tracking"
|
|
30
|
+
- Work that spans multiple days or compaction cycles
|
|
31
|
+
- Tasks too complex for simple TodoWrite lists
|
|
32
|
+
|
|
33
|
+
## File Structure
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
beads/
|
|
37
|
+
├── SKILL.md # Main skill file (Claude reads this first)
|
|
38
|
+
├── CLAUDE.md # Maintenance guide for updating the skill
|
|
39
|
+
├── README.md # This file (for humans)
|
|
40
|
+
├── adr/ # Architectural Decision Records
|
|
41
|
+
│ └── 0001-bd-prime-as-source-of-truth.md
|
|
42
|
+
└── resources/ # Detailed documentation (loaded on demand)
|
|
43
|
+
├── BOUNDARIES.md # When to use bd vs TodoWrite
|
|
44
|
+
├── CLI_REFERENCE.md # CLI command reference
|
|
45
|
+
├── DEPENDENCIES.md # Dependency semantics (A blocks B vs B blocks A)
|
|
46
|
+
├── INTEGRATION_PATTERNS.md # TodoWrite and other tool integration
|
|
47
|
+
├── ISSUE_CREATION.md # When and how to create issues
|
|
48
|
+
├── MOLECULES.md # Protos, mols, wisps (v0.34.0+)
|
|
49
|
+
├── PATTERNS.md # Common usage patterns
|
|
50
|
+
├── RESUMABILITY.md # Writing notes for post-compaction recovery
|
|
51
|
+
├── STATIC_DATA.md # Using bd for reference databases
|
|
52
|
+
├── TROUBLESHOOTING.md # Common issues and fixes
|
|
53
|
+
├── WORKFLOWS.md # Step-by-step workflow guides
|
|
54
|
+
├── AGENTS.md # Agent bead tracking (v0.40+)
|
|
55
|
+
├── ASYNC_GATES.md # Human-in-the-loop gates
|
|
56
|
+
├── CHEMISTRY_PATTERNS.md # Mol vs Wisp decision tree
|
|
57
|
+
└── WORKTREES.md # Parallel development patterns
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Key Concepts
|
|
61
|
+
|
|
62
|
+
### bd vs TodoWrite
|
|
63
|
+
|
|
64
|
+
| Use bd when... | Use TodoWrite when... |
|
|
65
|
+
|----------------|----------------------|
|
|
66
|
+
| Work spans multiple sessions | Single-session tasks |
|
|
67
|
+
| Complex dependencies exist | Linear step-by-step work |
|
|
68
|
+
| Need to resume after weeks | Just need a quick checklist |
|
|
69
|
+
| Knowledge work with fuzzy boundaries | Clear, immediate tasks |
|
|
70
|
+
|
|
71
|
+
### The Dependency Direction Trap
|
|
72
|
+
|
|
73
|
+
`bd dep add A B` means **"A depends on B"** (B must complete before A can start).
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Want: "Setup must complete before Implementation"
|
|
77
|
+
bd dep add implementation setup # ✓ CORRECT
|
|
78
|
+
# NOT: bd dep add setup implementation # ✗ WRONG
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Surviving Compaction
|
|
82
|
+
|
|
83
|
+
When Claude's context gets compacted, conversation history is lost but bd state survives. Write notes as if explaining to a future Claude with zero context:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
bd update issue-123 --notes "COMPLETED: JWT auth with RS256
|
|
87
|
+
KEY DECISION: RS256 over HS256 for key rotation
|
|
88
|
+
IN PROGRESS: Password reset flow
|
|
89
|
+
NEXT: Implement rate limiting"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Requirements
|
|
93
|
+
|
|
94
|
+
- [bd CLI](https://github.com/steveyegge/beads) installed (`brew install steveyegge/beads/bd`)
|
|
95
|
+
- A git repository (bd requires git for sync)
|
|
96
|
+
- Initialized database (`bd init` in project root)
|
|
97
|
+
|
|
98
|
+
## Version Compatibility
|
|
99
|
+
|
|
100
|
+
| Version | Features |
|
|
101
|
+
|---------|----------|
|
|
102
|
+
| v0.43.0+ | Full support: agents, gates, worktrees, chemistry patterns |
|
|
103
|
+
| v0.40.0+ | Agent beads, async gates, worktree management |
|
|
104
|
+
| v0.34.0+ | Molecules, wisps, cross-project dependencies |
|
|
105
|
+
| v0.15.0+ | Core: dependencies, notes, status tracking |
|
|
106
|
+
| Earlier | Basic functionality, some features missing |
|
|
107
|
+
|
|
108
|
+
## Contributing
|
|
109
|
+
|
|
110
|
+
This skill is maintained at [github.com/steveyegge/beads](https://github.com/steveyegge/beads) in the `skills/beads/` directory.
|
|
111
|
+
|
|
112
|
+
Issues and PRs welcome for:
|
|
113
|
+
- Documentation improvements
|
|
114
|
+
- New workflow patterns
|
|
115
|
+
- Bug fixes in examples
|
|
116
|
+
- Additional troubleshooting scenarios
|
|
117
|
+
|
|
118
|
+
## License
|
|
119
|
+
|
|
120
|
+
MIT (same as beads)
|