continuous-improvement 3.1.0 → 3.9.1
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 +66 -0
- package/CHANGELOG.md +216 -0
- package/QUICKSTART.md +79 -12
- package/README.md +229 -349
- package/SKILL.md +87 -9
- package/action.yml +1 -1
- package/bin/analyze.sh +9 -1
- package/bin/backfill.mjs +172 -0
- package/bin/check-doc-runtime-claims.mjs +120 -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 +171 -0
- package/bin/harvest-friction.mjs +279 -0
- package/bin/hook-stats.mjs +258 -0
- package/bin/install.mjs +407 -499
- package/bin/lint-transcript.mjs +182 -210
- package/bin/mcp-server.mjs +834 -608
- 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 +43 -2
- package/commands/discipline.md +14 -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 +180 -0
- package/commands/swarm.md +101 -0
- package/commands/workspace-surface-audit.md +77 -0
- package/hooks/gateguard.mjs +172 -0
- package/hooks/observe.sh +42 -4
- package/hooks/session.sh +3 -3
- package/hooks/three-section-close.mjs +181 -0
- package/instinct-packs/meta.json +16 -0
- package/lib/cli-anything.mjs +401 -0
- package/lib/compound-engineering.mjs +831 -0
- package/lib/gateguard-state.mjs +85 -0
- package/lib/observe-event.mjs +128 -0
- package/lib/plugin-metadata.mjs +435 -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 +32 -7
- package/package.json +29 -19
- 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 +57 -0
- package/plugins/continuous-improvement/agents/README.md +120 -0
- package/plugins/continuous-improvement/agents/code-reviewer.md +97 -0
- package/plugins/continuous-improvement/agents/security-auditor.md +101 -0
- package/plugins/continuous-improvement/agents/test-engineer.md +95 -0
- package/plugins/continuous-improvement/bin/backfill.mjs +172 -0
- package/plugins/continuous-improvement/bin/mcp-server.mjs +889 -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 +180 -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/gateguard.mjs +172 -0
- package/plugins/continuous-improvement/hooks/hooks.json +65 -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 +435 -0
- package/plugins/continuous-improvement/lib/resolve-home-dir.mjs +43 -0
- package/plugins/continuous-improvement/skills/README.md +37 -0
- package/plugins/continuous-improvement/skills/continuous-improvement/SKILL.md +249 -0
- package/plugins/continuous-improvement/skills/deploy-receipt/SKILL.md +178 -0
- package/plugins/continuous-improvement/skills/gateguard/SKILL.md +163 -0
- package/plugins/continuous-improvement/skills/para-memory-files/SKILL.md +108 -0
- package/plugins/continuous-improvement/skills/proceed-with-the-recommendation/SKILL.md +447 -0
- package/plugins/continuous-improvement/skills/ralph/SKILL.md +221 -0
- package/plugins/continuous-improvement/skills/recovery-classification/SKILL.md +73 -0
- package/plugins/continuous-improvement/skills/safety-guard/SKILL.md +76 -0
- package/plugins/continuous-improvement/skills/state-reconciliation/SKILL.md +63 -0
- package/plugins/continuous-improvement/skills/strategic-compact/SKILL.md +104 -0
- package/plugins/continuous-improvement/skills/superpowers/SKILL.md +219 -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 +224 -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/skills/worktree-safety/SKILL.md +66 -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 +26 -5
- package/skills/README.md +79 -0
- package/skills/deploy-receipt.md +178 -0
- package/skills/gateguard.md +163 -0
- package/skills/para-memory-files.md +108 -0
- package/skills/proceed-with-the-recommendation.md +447 -0
- package/skills/ralph.md +221 -0
- package/skills/recovery-classification.md +73 -0
- package/skills/safety-guard.md +76 -0
- package/skills/state-reconciliation.md +63 -0
- package/skills/strategic-compact.md +104 -0
- package/skills/superpowers.md +219 -0
- package/skills/tdd-workflow.md +411 -0
- package/skills/token-budget-advisor.md +136 -0
- package/skills/verification-loop.md +224 -0
- package/skills/wild-risa-balance.md +191 -0
- package/skills/workspace-surface-audit.md +147 -0
- package/skills/worktree-safety.md +66 -0
- package/templates/insights-claude-md.md +91 -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 +60 -0
package/bin/lint-transcript.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
2
|
/**
|
|
4
3
|
* Agent Transcript Linter
|
|
5
4
|
*
|
|
@@ -15,175 +14,154 @@
|
|
|
15
14
|
* 0 — no violations (or --strict not set)
|
|
16
15
|
* 1 — violations found (with --strict)
|
|
17
16
|
*/
|
|
18
|
-
|
|
19
17
|
import { readFileSync } from "node:fs";
|
|
20
18
|
import { createInterface } from "node:readline";
|
|
21
|
-
|
|
22
19
|
const LAWS = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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: [] },
|
|
30
27
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
+
}
|
|
54
56
|
}
|
|
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
|
+
}
|
|
57
72
|
}
|
|
58
|
-
if (
|
|
59
|
-
|
|
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
|
+
});
|
|
60
79
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const tool = events[i].tool || events[i].tool_name || "";
|
|
68
|
-
if (["Grep", "Glob", "Read"].includes(tool)) {
|
|
69
|
-
lastResearchIdx = i;
|
|
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
|
+
});
|
|
70
86
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
+
}
|
|
79
110
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
severity: "high",
|
|
87
|
-
message: `${stats.writeTools} writes with 0 research operations. Agent likely skipped research.`,
|
|
88
|
-
});
|
|
89
|
-
} else if (stats.writeTools > stats.researchTools * 3) {
|
|
90
|
-
violations.push({
|
|
91
|
-
law: 1,
|
|
92
|
-
severity: "medium",
|
|
93
|
-
message: `Write-to-research ratio is ${stats.writeTools}:${stats.researchTools}. Consider more research.`,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Law 3: One Thing at a Time
|
|
98
|
-
// Detect rapid context switching (different files edited in quick succession without verification)
|
|
99
|
-
let consecutiveEdits = 0;
|
|
100
|
-
const editedFiles = new Set();
|
|
101
|
-
for (const event of events) {
|
|
102
|
-
const tool = event.tool || event.tool_name || "";
|
|
103
|
-
const input = event.tool_input || event.input || {};
|
|
104
|
-
|
|
105
|
-
if (["Write", "Edit"].includes(tool)) {
|
|
106
|
-
consecutiveEdits++;
|
|
107
|
-
if (input.file_path) editedFiles.add(input.file_path);
|
|
108
|
-
} else if (tool === "Bash") {
|
|
109
|
-
consecutiveEdits = 0; // Reset on verification
|
|
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
|
+
});
|
|
110
117
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
});
|
|
118
|
-
consecutiveEdits = 0;
|
|
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
|
+
});
|
|
119
124
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
severity: "high",
|
|
127
|
-
message: `${stats.writeTools} code changes with 0 verification commands (test/build). Agent may have declared done without verifying.`,
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Law 6: Iterate One Change
|
|
132
|
-
if (editedFiles.size > 8) {
|
|
133
|
-
violations.push({
|
|
134
|
-
law: 6,
|
|
135
|
-
severity: "medium",
|
|
136
|
-
message: `${editedFiles.size} different files modified. Consider smaller, focused iterations.`,
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Calculate discipline score
|
|
141
|
-
const maxViolations = 7; // One per law
|
|
142
|
-
const violationWeight = violations.reduce((sum, v) => {
|
|
143
|
-
return sum + (v.severity === "high" ? 2 : 1);
|
|
144
|
-
}, 0);
|
|
145
|
-
const score = Math.max(0, Math.round(100 - (violationWeight / maxViolations) * 100));
|
|
146
|
-
|
|
147
|
-
return { violations, stats, score };
|
|
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 };
|
|
148
131
|
}
|
|
149
|
-
|
|
150
132
|
function formatReport(result) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
lines.push("## Agent Discipline Report");
|
|
155
|
-
lines.push("");
|
|
156
|
-
lines.push(`**Score:** ${score}/100`);
|
|
157
|
-
lines.push(`**Events analyzed:** ${stats.totalEvents}`);
|
|
158
|
-
lines.push(`**Tool calls:** ${stats.toolCalls}`);
|
|
159
|
-
lines.push(`**Research ops:** ${stats.researchTools} | **Write ops:** ${stats.writeTools} | **Verify ops:** ${stats.verifyTools}`);
|
|
160
|
-
lines.push("");
|
|
161
|
-
|
|
162
|
-
if (violations.length === 0) {
|
|
163
|
-
lines.push("No law violations detected. Good discipline!");
|
|
164
|
-
} else {
|
|
165
|
-
lines.push(`### Violations (${violations.length})`);
|
|
133
|
+
const { violations, stats, score, parseFailures } = result;
|
|
134
|
+
const lines = [];
|
|
135
|
+
lines.push("## Agent Discipline Report");
|
|
166
136
|
lines.push("");
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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)`);
|
|
171
143
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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");
|
|
179
161
|
}
|
|
180
|
-
|
|
181
|
-
// --- Main ---
|
|
182
|
-
|
|
183
162
|
const args = process.argv.slice(2);
|
|
184
|
-
|
|
185
163
|
if (args.includes("--help") || args.includes("-h")) {
|
|
186
|
-
|
|
164
|
+
console.log(`
|
|
187
165
|
Agent Transcript Linter — The 7 Laws of AI Agent Discipline
|
|
188
166
|
|
|
189
167
|
Usage:
|
|
@@ -196,72 +174,66 @@ Options:
|
|
|
196
174
|
--strict Exit 1 if violations found
|
|
197
175
|
--json Output as JSON instead of markdown
|
|
198
176
|
`);
|
|
199
|
-
|
|
177
|
+
process.exit(0);
|
|
200
178
|
}
|
|
201
|
-
|
|
202
179
|
const isStrict = args.includes("--strict");
|
|
203
180
|
const isJson = args.includes("--json");
|
|
204
181
|
const isStdin = args.includes("--stdin");
|
|
205
|
-
|
|
206
182
|
async function main() {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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
|
+
}
|
|
214
191
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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);
|
|
220
200
|
}
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
// skip non-JSON lines
|
|
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
|
+
}
|
|
231
210
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
appendFileSync(process.env.GITHUB_OUTPUT, line + "\n");
|
|
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);
|
|
256
234
|
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (isStrict && result.violations.length > 0) {
|
|
260
|
-
process.exit(1);
|
|
261
|
-
}
|
|
262
235
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
process.exit(1);
|
|
236
|
+
main().catch((error) => {
|
|
237
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
238
|
+
process.exit(1);
|
|
267
239
|
});
|