continuous-improvement 3.0.0 → 3.8.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 +78 -0
- package/CHANGELOG.md +210 -0
- package/LICENSE +21 -21
- package/QUICKSTART.md +101 -81
- package/README.md +224 -198
- package/SKILL.md +87 -9
- package/action.yml +33 -0
- package/bin/analyze.sh +161 -153
- package/bin/backfill.mjs +172 -0
- package/bin/check-docs-substrings.mjs +333 -0
- package/bin/check-everything-mirror.mjs +145 -0
- package/bin/check-routing-targets.mjs +151 -0
- package/bin/check-skill-law-tag.mjs +128 -0
- package/bin/check-skill-mirror.mjs +119 -0
- package/bin/check-skill-tiers.mjs +116 -0
- package/bin/check-third-party-shape.mjs +202 -0
- package/bin/generate-plugin-manifests.mjs +169 -0
- package/bin/harvest-friction.mjs +279 -0
- package/bin/hook-stats.mjs +258 -0
- package/bin/install.mjs +418 -456
- package/bin/lint-transcript.mjs +239 -0
- package/bin/mcp-server.mjs +842 -499
- package/bin/observe.mjs +148 -0
- package/bin/pre-commit-block-strays.sh +49 -0
- package/bin/refresh-third-party.mjs +416 -0
- package/bin/unified-cli.mjs +533 -0
- package/commands/continuous-improvement.md +115 -74
- package/commands/dashboard.md +56 -0
- package/commands/discipline.md +51 -0
- package/commands/harvest.md +76 -0
- package/commands/learn-eval.md +117 -0
- package/commands/planning-with-files.md +66 -0
- package/commands/proceed-with-the-recommendation.md +62 -0
- package/commands/ralph.md +103 -0
- package/commands/release-train.md +81 -0
- package/commands/seven-laws.md +16 -0
- package/commands/superpowers.md +153 -0
- package/commands/swarm.md +101 -0
- package/commands/workspace-surface-audit.md +77 -0
- package/hooks/observe.sh +172 -134
- package/hooks/session.sh +106 -106
- package/hooks/three-section-close.mjs +181 -0
- package/instinct-packs/go.json +58 -0
- package/instinct-packs/meta.json +16 -0
- package/instinct-packs/python.json +58 -0
- package/instinct-packs/react.json +58 -0
- package/lib/cli-anything.mjs +401 -0
- package/lib/compound-engineering.mjs +831 -0
- package/lib/observe-event.mjs +128 -0
- package/lib/plugin-metadata.mjs +432 -0
- package/lib/pm-marketplace.mjs +61 -0
- package/lib/pm-skills.mjs +1274 -0
- package/lib/resolve-home-dir.mjs +43 -0
- package/lib/skill-tiers.mjs +137 -0
- package/lib/unified-plugin.mjs +924 -0
- package/llms.txt +68 -0
- package/package.json +38 -15
- package/plugins/beginner.json +17 -6
- package/plugins/continuous-improvement/.claude-plugin/marketplace.json +20 -0
- package/plugins/continuous-improvement/.claude-plugin/plugin.json +26 -0
- package/plugins/continuous-improvement/LICENSE +21 -0
- package/plugins/continuous-improvement/README.md +56 -0
- package/plugins/continuous-improvement/bin/backfill.mjs +172 -0
- package/plugins/continuous-improvement/bin/mcp-server.mjs +886 -0
- package/plugins/continuous-improvement/bin/observe.mjs +148 -0
- package/plugins/continuous-improvement/commands/continuous-improvement.md +115 -0
- package/plugins/continuous-improvement/commands/dashboard.md +56 -0
- package/plugins/continuous-improvement/commands/discipline.md +51 -0
- package/plugins/continuous-improvement/commands/harvest.md +76 -0
- package/plugins/continuous-improvement/commands/learn-eval.md +117 -0
- package/plugins/continuous-improvement/commands/planning-with-files.md +66 -0
- package/plugins/continuous-improvement/commands/proceed-with-the-recommendation.md +62 -0
- package/plugins/continuous-improvement/commands/ralph.md +103 -0
- package/plugins/continuous-improvement/commands/release-train.md +81 -0
- package/plugins/continuous-improvement/commands/seven-laws.md +16 -0
- package/plugins/continuous-improvement/commands/superpowers.md +153 -0
- package/plugins/continuous-improvement/commands/swarm.md +101 -0
- package/plugins/continuous-improvement/commands/workspace-surface-audit.md +77 -0
- package/plugins/continuous-improvement/hooks/hooks.json +60 -0
- package/plugins/continuous-improvement/hooks/observe.sh +172 -0
- package/plugins/continuous-improvement/hooks/session.sh +106 -0
- package/plugins/continuous-improvement/hooks/three-section-close.mjs +181 -0
- package/plugins/continuous-improvement/instinct-packs/go.json +58 -0
- package/plugins/continuous-improvement/instinct-packs/meta.json +16 -0
- package/plugins/continuous-improvement/instinct-packs/python.json +58 -0
- package/plugins/continuous-improvement/instinct-packs/react.json +58 -0
- package/plugins/continuous-improvement/lib/observe-event.mjs +128 -0
- package/plugins/continuous-improvement/lib/plugin-metadata.mjs +432 -0
- package/plugins/continuous-improvement/lib/resolve-home-dir.mjs +43 -0
- package/plugins/continuous-improvement/skills/README.md +34 -0
- package/plugins/continuous-improvement/skills/continuous-improvement/SKILL.md +249 -0
- package/plugins/continuous-improvement/skills/deploy-receipt/SKILL.md +131 -0
- package/plugins/continuous-improvement/skills/gateguard/SKILL.md +155 -0
- package/plugins/continuous-improvement/skills/para-memory-files/SKILL.md +108 -0
- package/plugins/continuous-improvement/skills/proceed-with-the-recommendation/SKILL.md +454 -0
- package/plugins/continuous-improvement/skills/ralph/SKILL.md +221 -0
- package/plugins/continuous-improvement/skills/safety-guard/SKILL.md +76 -0
- package/plugins/continuous-improvement/skills/strategic-compact/SKILL.md +104 -0
- package/plugins/continuous-improvement/skills/superpowers/SKILL.md +212 -0
- package/plugins/continuous-improvement/skills/tdd-workflow/SKILL.md +411 -0
- package/plugins/continuous-improvement/skills/token-budget-advisor/SKILL.md +136 -0
- package/plugins/continuous-improvement/skills/verification-loop/SKILL.md +192 -0
- package/plugins/continuous-improvement/skills/wild-risa-balance/SKILL.md +191 -0
- package/plugins/continuous-improvement/skills/workspace-surface-audit/SKILL.md +147 -0
- package/plugins/continuous-improvement/templates/planning-with-files/findings.md +8 -0
- package/plugins/continuous-improvement/templates/planning-with-files/progress.md +7 -0
- package/plugins/continuous-improvement/templates/planning-with-files/task_plan.md +23 -0
- package/plugins/expert.json +34 -5
- package/skills/README.md +79 -0
- package/skills/deploy-receipt.md +131 -0
- package/skills/gateguard.md +155 -0
- package/skills/para-memory-files.md +108 -0
- package/skills/proceed-with-the-recommendation.md +454 -0
- package/skills/ralph.md +221 -0
- package/skills/safety-guard.md +76 -0
- package/skills/strategic-compact.md +104 -0
- package/skills/superpowers.md +212 -0
- package/skills/tdd-workflow.md +411 -0
- package/skills/token-budget-advisor.md +136 -0
- package/skills/verification-loop.md +192 -0
- package/skills/wild-risa-balance.md +191 -0
- package/skills/workspace-surface-audit.md +147 -0
- package/templates/planning-with-files/findings.md +8 -0
- package/templates/planning-with-files/progress.md +7 -0
- package/templates/planning-with-files/task_plan.md +23 -0
- package/templates/verify-ladder.example.json +47 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Agent Transcript Linter
|
|
4
|
+
*
|
|
5
|
+
* Analyzes AI agent transcripts/observations for compliance with
|
|
6
|
+
* the 7 Laws of AI Agent Discipline.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node bin/lint-transcript.mjs <file.jsonl> # Lint a transcript file
|
|
10
|
+
* cat observations.jsonl | node bin/lint-transcript.mjs --stdin # Pipe input
|
|
11
|
+
* node bin/lint-transcript.mjs --help
|
|
12
|
+
*
|
|
13
|
+
* Exit codes:
|
|
14
|
+
* 0 — no violations (or --strict not set)
|
|
15
|
+
* 1 — violations found (with --strict)
|
|
16
|
+
*/
|
|
17
|
+
import { readFileSync } from "node:fs";
|
|
18
|
+
import { createInterface } from "node:readline";
|
|
19
|
+
const LAWS = {
|
|
20
|
+
1: { name: "Research Before Executing", patterns: [] },
|
|
21
|
+
2: { name: "Plan Is Sacred", patterns: [] },
|
|
22
|
+
3: { name: "One Thing at a Time", patterns: [] },
|
|
23
|
+
4: { name: "Verify Before Reporting", patterns: [] },
|
|
24
|
+
5: { name: "Reflect After Sessions", patterns: [] },
|
|
25
|
+
6: { name: "Iterate One Change", patterns: [] },
|
|
26
|
+
7: { name: "Learn From Every Session", patterns: [] },
|
|
27
|
+
};
|
|
28
|
+
function analyzeTranscript(events, parseFailures) {
|
|
29
|
+
const violations = [];
|
|
30
|
+
const stats = {
|
|
31
|
+
totalEvents: events.length,
|
|
32
|
+
toolCalls: 0,
|
|
33
|
+
researchTools: 0,
|
|
34
|
+
writeTools: 0,
|
|
35
|
+
verifyTools: 0,
|
|
36
|
+
sessions: new Set(),
|
|
37
|
+
parseFailures,
|
|
38
|
+
};
|
|
39
|
+
for (const event of events) {
|
|
40
|
+
stats.toolCalls++;
|
|
41
|
+
if (event.session_id) {
|
|
42
|
+
stats.sessions.add(event.session_id);
|
|
43
|
+
}
|
|
44
|
+
const tool = event.tool || event.tool_name || "";
|
|
45
|
+
const input = event.tool_input || event.input || {};
|
|
46
|
+
const command = typeof input.command === "string" ? input.command : "";
|
|
47
|
+
if (["Grep", "Glob", "Read"].includes(tool)) {
|
|
48
|
+
stats.researchTools++;
|
|
49
|
+
}
|
|
50
|
+
if (["Write", "Edit"].includes(tool)) {
|
|
51
|
+
stats.writeTools++;
|
|
52
|
+
}
|
|
53
|
+
if (tool === "Bash" && /\b(test|build|npm run|jest|vitest|bun test|deno test|ava|tap|mocha|pytest|go test|cargo test|gradle test|mvn test)\b/.test(command)) {
|
|
54
|
+
stats.verifyTools++;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
let lastResearchIdx = -1;
|
|
58
|
+
for (let index = 0; index < events.length; index++) {
|
|
59
|
+
const tool = events[index]?.tool || events[index]?.tool_name || "";
|
|
60
|
+
if (["Grep", "Glob", "Read"].includes(tool)) {
|
|
61
|
+
lastResearchIdx = index;
|
|
62
|
+
}
|
|
63
|
+
if (["Write", "Edit"].includes(tool) && lastResearchIdx === -1) {
|
|
64
|
+
violations.push({
|
|
65
|
+
law: 1,
|
|
66
|
+
severity: "high",
|
|
67
|
+
message: `Write/Edit at event ${index} without any prior research (Grep/Glob/Read)`,
|
|
68
|
+
event: index,
|
|
69
|
+
});
|
|
70
|
+
// Continue checking for more violations
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (stats.writeTools > 0 && stats.researchTools === 0) {
|
|
74
|
+
violations.push({
|
|
75
|
+
law: 1,
|
|
76
|
+
severity: "high",
|
|
77
|
+
message: `${stats.writeTools} writes with 0 research operations. Agent likely skipped research.`,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
else if (stats.writeTools > stats.researchTools * 3) {
|
|
81
|
+
violations.push({
|
|
82
|
+
law: 1,
|
|
83
|
+
severity: "medium",
|
|
84
|
+
message: `Write-to-research ratio is ${stats.writeTools}:${stats.researchTools}. Consider more research.`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
let consecutiveEdits = 0;
|
|
88
|
+
const editedFiles = new Set();
|
|
89
|
+
for (const event of events) {
|
|
90
|
+
const tool = event.tool || event.tool_name || "";
|
|
91
|
+
const input = event.tool_input || event.input || {};
|
|
92
|
+
if (["Write", "Edit"].includes(tool)) {
|
|
93
|
+
consecutiveEdits++;
|
|
94
|
+
if (typeof input.file_path === "string") {
|
|
95
|
+
editedFiles.add(input.file_path);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// Reset on any non-write tool (verification, research, etc.)
|
|
100
|
+
consecutiveEdits = 0;
|
|
101
|
+
}
|
|
102
|
+
if (consecutiveEdits > 5) {
|
|
103
|
+
violations.push({
|
|
104
|
+
law: 3,
|
|
105
|
+
severity: "medium",
|
|
106
|
+
message: `${consecutiveEdits} consecutive edits without verification. Editing multiple files at once.`,
|
|
107
|
+
});
|
|
108
|
+
consecutiveEdits = 0;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (stats.writeTools > 0 && stats.verifyTools === 0) {
|
|
112
|
+
violations.push({
|
|
113
|
+
law: 4,
|
|
114
|
+
severity: "high",
|
|
115
|
+
message: `${stats.writeTools} code changes with 0 verification commands (test/build). Agent may have declared done without verifying.`,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
if (editedFiles.size > 8) {
|
|
119
|
+
violations.push({
|
|
120
|
+
law: 6,
|
|
121
|
+
severity: "medium",
|
|
122
|
+
message: `${editedFiles.size} different files modified. Consider smaller, focused iterations.`,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
const maxViolations = 7;
|
|
126
|
+
const violationWeight = violations.reduce((sum, violation) => {
|
|
127
|
+
return sum + (violation.severity === "high" ? 2 : 1);
|
|
128
|
+
}, 0);
|
|
129
|
+
const score = Math.max(0, Math.round(100 - (violationWeight / maxViolations) * 100));
|
|
130
|
+
return { violations, stats, score, parseFailures };
|
|
131
|
+
}
|
|
132
|
+
function formatReport(result) {
|
|
133
|
+
const { violations, stats, score, parseFailures } = result;
|
|
134
|
+
const lines = [];
|
|
135
|
+
lines.push("## Agent Discipline Report");
|
|
136
|
+
lines.push("");
|
|
137
|
+
lines.push(`**Score:** ${score}/100`);
|
|
138
|
+
lines.push(`**Events analyzed:** ${stats.totalEvents}`);
|
|
139
|
+
lines.push(`**Tool calls:** ${stats.toolCalls}`);
|
|
140
|
+
lines.push(`**Research ops:** ${stats.researchTools} | **Write ops:** ${stats.writeTools} | **Verify ops:** ${stats.verifyTools}`);
|
|
141
|
+
if (parseFailures > 0) {
|
|
142
|
+
lines.push(`**Parse failures:** ${parseFailures} (malformed JSON lines skipped)`);
|
|
143
|
+
}
|
|
144
|
+
lines.push("");
|
|
145
|
+
if (violations.length === 0) {
|
|
146
|
+
lines.push("No law violations detected. Good discipline!");
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
lines.push(`### Violations (${violations.length})`);
|
|
150
|
+
lines.push("");
|
|
151
|
+
for (const violation of violations) {
|
|
152
|
+
const severity = violation.severity === "high" ? "HIGH" : "MEDIUM";
|
|
153
|
+
lines.push(`- **[${severity}] Law ${violation.law}: ${LAWS[violation.law].name}**`);
|
|
154
|
+
lines.push(` ${violation.message}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
lines.push("");
|
|
158
|
+
lines.push("---");
|
|
159
|
+
lines.push("*Generated by [continuous-improvement](https://github.com/naimkatiman/continuous-improvement) transcript linter*");
|
|
160
|
+
return lines.join("\n");
|
|
161
|
+
}
|
|
162
|
+
const args = process.argv.slice(2);
|
|
163
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
164
|
+
console.log(`
|
|
165
|
+
Agent Transcript Linter — The 7 Laws of AI Agent Discipline
|
|
166
|
+
|
|
167
|
+
Usage:
|
|
168
|
+
node bin/lint-transcript.mjs <file.jsonl> Lint a transcript file
|
|
169
|
+
cat obs.jsonl | node bin/lint-transcript.mjs --stdin Pipe input
|
|
170
|
+
node bin/lint-transcript.mjs --help Show help
|
|
171
|
+
|
|
172
|
+
Options:
|
|
173
|
+
--stdin Read from stdin
|
|
174
|
+
--strict Exit 1 if violations found
|
|
175
|
+
--json Output as JSON instead of markdown
|
|
176
|
+
`);
|
|
177
|
+
process.exit(0);
|
|
178
|
+
}
|
|
179
|
+
const isStrict = args.includes("--strict");
|
|
180
|
+
const isJson = args.includes("--json");
|
|
181
|
+
const isStdin = args.includes("--stdin");
|
|
182
|
+
async function main() {
|
|
183
|
+
let lines = [];
|
|
184
|
+
if (isStdin) {
|
|
185
|
+
const rl = createInterface({ input: process.stdin, terminal: false });
|
|
186
|
+
for await (const line of rl) {
|
|
187
|
+
if (line.trim()) {
|
|
188
|
+
lines.push(line.trim());
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
const filePath = args.find((arg) => !arg.startsWith("--"));
|
|
194
|
+
if (!filePath) {
|
|
195
|
+
console.error("Error: provide a file path or use --stdin");
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
const content = readFileSync(filePath, "utf8");
|
|
199
|
+
lines = content.split("\n").filter((line) => line.trim().length > 0);
|
|
200
|
+
}
|
|
201
|
+
const events = [];
|
|
202
|
+
let parseFailures = 0;
|
|
203
|
+
for (const line of lines) {
|
|
204
|
+
try {
|
|
205
|
+
events.push(JSON.parse(line));
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
parseFailures++;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (events.length === 0) {
|
|
212
|
+
console.log("No events found to analyze.");
|
|
213
|
+
process.exit(0);
|
|
214
|
+
}
|
|
215
|
+
const result = analyzeTranscript(events, parseFailures);
|
|
216
|
+
if (isJson) {
|
|
217
|
+
console.log(JSON.stringify(result, null, 2));
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
console.log(formatReport(result));
|
|
221
|
+
}
|
|
222
|
+
if (process.env.GITHUB_OUTPUT) {
|
|
223
|
+
const outputLines = [
|
|
224
|
+
`violations=${result.violations.length}`,
|
|
225
|
+
`score=${result.score}`,
|
|
226
|
+
];
|
|
227
|
+
const { appendFileSync } = await import("node:fs");
|
|
228
|
+
for (const line of outputLines) {
|
|
229
|
+
appendFileSync(process.env.GITHUB_OUTPUT, line + "\n");
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (isStrict && result.violations.length > 0) {
|
|
233
|
+
process.exit(1);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
main().catch((error) => {
|
|
237
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
238
|
+
process.exit(1);
|
|
239
|
+
});
|