tribunal-kit 5.8.2 ā 5.8.4
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/.agent/ARCHITECTURE.md +12 -12
- package/.agent/agents/complexity-reviewer.md +53 -0
- package/.agent/agents/precedence-reviewer.md +12 -12
- package/.agent/agents/swarm-worker-registry.md +3 -3
- package/.agent/history/integrity_manifest.json +958 -0
- package/.agent/history/memory/.memory.idx +305 -1
- package/.agent/history/memory/MEMORY.md +21 -1
- package/.agent/rules/GEMINI.md +31 -28
- package/.agent/scripts/case_law_manager.js +3 -15
- package/.agent/scripts/context_broker.js +3 -1
- package/.agent/scripts/guardrail_engine.js +643 -0
- package/.agent/scripts/integrity_manifest.js +486 -0
- package/.agent/scripts/signal_detector.js +1 -1
- package/.agent/scripts/skill_evolution.js +3 -15
- package/.agent/scripts/skill_integrator.js +2 -12
- package/.agent/scripts/swarm_dispatcher.js +2 -12
- package/.agent/skills/12-principles-of-animation/SKILL.md +69 -0
- package/.agent/skills/60fps-animation/SKILL.md +78 -0
- package/.agent/skills/accessible-animation/SKILL.md +86 -0
- package/.agent/skills/adapt/SKILL.md +75 -0
- package/.agent/skills/animation-on-scroll/SKILL.md +110 -0
- package/.agent/skills/animation-systems/SKILL.md +69 -0
- package/.agent/skills/antfu-conventions/SKILL.md +74 -0
- package/.agent/skills/app-builder/SKILL.md +1 -1
- package/.agent/skills/apple-design/SKILL.md +108 -0
- package/.agent/skills/audit-and-fix/SKILL.md +83 -0
- package/.agent/skills/baseline-ui/SKILL.md +74 -0
- package/.agent/skills/better-colors/SKILL.md +124 -0
- package/.agent/skills/better-typography/SKILL.md +111 -0
- package/.agent/skills/better-ui/SKILL.md +102 -0
- package/.agent/skills/bolder/SKILL.md +68 -0
- package/.agent/skills/build-primitive/SKILL.md +70 -0
- package/.agent/skills/clarify/SKILL.md +75 -0
- package/.agent/skills/cobejs/SKILL.md +96 -0
- package/.agent/skills/codebase-design/SKILL.md +84 -0
- package/.agent/skills/colorize/SKILL.md +77 -0
- package/.agent/skills/compact-landing/SKILL.md +70 -0
- package/.agent/skills/company-logos/SKILL.md +73 -0
- package/.agent/skills/create-design-md/SKILL.md +104 -0
- package/.agent/skills/critique/SKILL.md +95 -0
- package/.agent/skills/delight/SKILL.md +65 -0
- package/.agent/skills/design-lab/SKILL.md +59 -0
- package/.agent/skills/diagnosing-bugs/SKILL.md +190 -0
- package/.agent/skills/distill/SKILL.md +65 -0
- package/.agent/skills/domain-modeling/SKILL.md +78 -0
- package/.agent/skills/fixing-accessibility/SKILL.md +98 -0
- package/.agent/skills/fixing-metadata/SKILL.md +97 -0
- package/.agent/skills/fixing-motion-performance/SKILL.md +96 -0
- package/.agent/skills/gpt-taste/SKILL.md +68 -0
- package/.agent/skills/harden/SKILL.md +74 -0
- package/.agent/skills/impeccable/SKILL.md +72 -0
- package/.agent/skills/improve-codebase-architecture/SKILL.md +67 -0
- package/.agent/skills/improve-ui/SKILL.md +83 -0
- package/.agent/skills/landing-page/SKILL.md +88 -0
- package/.agent/skills/lint-and-validate/SKILL.md +1 -2
- package/.agent/skills/local-first-architecture/SKILL.md +66 -0
- package/.agent/skills/lottie-animation/SKILL.md +82 -0
- package/.agent/skills/marquee-loop/SKILL.md +96 -0
- package/.agent/skills/masked-reveal/SKILL.md +88 -0
- package/.agent/skills/micro-interaction/SKILL.md +100 -0
- package/.agent/skills/morphing-icons/SKILL.md +85 -0
- package/.agent/skills/page-transition-animation/SKILL.md +108 -0
- package/.agent/skills/parallel-agents/SKILL.md +5 -5
- package/.agent/skills/polish/SKILL.md +63 -0
- package/.agent/skills/pricing-page/SKILL.md +68 -0
- package/.agent/skills/progressive-blur/SKILL.md +100 -0
- package/.agent/skills/project-idioms/SKILL.md +7 -7
- package/.agent/skills/quieter/SKILL.md +68 -0
- package/.agent/skills/react-doctor/SKILL.md +70 -0
- package/.agent/skills/redesign-skill/SKILL.md +65 -0
- package/.agent/skills/shape/SKILL.md +73 -0
- package/.agent/skills/soft-skill/SKILL.md +72 -0
- package/.agent/skills/sounds-on-the-web/SKILL.md +100 -0
- package/.agent/skills/svg-animation/SKILL.md +91 -0
- package/.agent/skills/swiss-design/SKILL.md +64 -0
- package/.agent/skills/taste-skill/SKILL.md +71 -0
- package/.agent/skills/tdd-workflow/SKILL.md +36 -165
- package/.agent/skills/test-result-analyzer/SKILL.md +1 -1
- package/.agent/skills/thermo-nuclear-code-quality-review/SKILL.md +82 -0
- package/.agent/skills/to-spring-or-not-to-spring/SKILL.md +66 -0
- package/.agent/skills/transitions-dev/SKILL.md +101 -0
- package/.agent/skills/typeset/SKILL.md +76 -0
- package/.agent/skills/ui-skills-root/SKILL.md +85 -0
- package/.agent/skills/web-quality-audit/SKILL.md +67 -0
- package/.agent/workflows/fix.md +2 -2
- package/.agent/workflows/preview.md +5 -5
- package/.agent/workflows/status.md +1 -1
- package/.agent/workflows/tribunal-full.md +3 -3
- package/.agent/workflows/tribunal-speed.md +2 -2
- package/README.md +348 -238
- package/bin/tribunal-kit.js +62 -1482
- package/dist/cli.js +13 -0
- package/dist/commands/align.js +1 -1
- package/dist/commands/compile.js +1 -1
- package/dist/commands/guardrail.js +275 -0
- package/dist/commands/init.js +10 -9
- package/dist/commands/optimize.js +318 -0
- package/dist/utils/version.js +1 -1
- package/package.json +10 -8
- package/scripts/fix-vbc.js +98 -0
- package/scripts/fix-vbc.ps1 +119 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.cmdOptimizeSkill = cmdOptimizeSkill;
|
|
7
|
+
|
|
8
|
+
const fs = __importDefault(require("fs"));
|
|
9
|
+
const path = __importDefault(require("path"));
|
|
10
|
+
const os = __importDefault(require("os"));
|
|
11
|
+
const https = __importDefault(require("https"));
|
|
12
|
+
const { execSync } = require("child_process");
|
|
13
|
+
const logger = require("../utils/logger");
|
|
14
|
+
const helpers = require("../utils/helpers");
|
|
15
|
+
|
|
16
|
+
// āā LLM Helpers āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
17
|
+
function detectLlmProvider() {
|
|
18
|
+
if (process.env.ANTHROPIC_API_KEY)
|
|
19
|
+
return { provider: "anthropic", key: process.env.ANTHROPIC_API_KEY };
|
|
20
|
+
if (process.env.OPENAI_API_KEY)
|
|
21
|
+
return { provider: "openai", key: process.env.OPENAI_API_KEY };
|
|
22
|
+
if (process.env.GEMINI_API_KEY)
|
|
23
|
+
return { provider: "gemini", key: process.env.GEMINI_API_KEY };
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function httpsPost(hostname, apiPath, headers, body) {
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
const data = JSON.stringify(body);
|
|
30
|
+
const req = https.request(
|
|
31
|
+
{
|
|
32
|
+
method: "POST",
|
|
33
|
+
hostname,
|
|
34
|
+
path: apiPath,
|
|
35
|
+
headers: { ...headers, "Content-Length": Buffer.byteLength(data) },
|
|
36
|
+
},
|
|
37
|
+
(res) => {
|
|
38
|
+
let raw = "";
|
|
39
|
+
res.on("data", (c) => { raw += c; });
|
|
40
|
+
res.on("end", () => resolve(raw));
|
|
41
|
+
res.on("error", reject);
|
|
42
|
+
},
|
|
43
|
+
);
|
|
44
|
+
req.on("error", reject);
|
|
45
|
+
req.setTimeout(30000, () => {
|
|
46
|
+
req.destroy(new Error("LLM API timeout"));
|
|
47
|
+
});
|
|
48
|
+
req.write(data);
|
|
49
|
+
req.end();
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function callLlmApi(prompt, provider, apiKey) {
|
|
54
|
+
try {
|
|
55
|
+
if (provider === "anthropic") {
|
|
56
|
+
const raw = await httpsPost(
|
|
57
|
+
"api.anthropic.com",
|
|
58
|
+
"/v1/messages",
|
|
59
|
+
{
|
|
60
|
+
"Content-Type": "application/json",
|
|
61
|
+
"x-api-key": apiKey,
|
|
62
|
+
"anthropic-version": "2023-06-01",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
model: "claude-3-5-sonnet-latest",
|
|
66
|
+
max_tokens: 1024,
|
|
67
|
+
messages: [{ role: "user", content: prompt }],
|
|
68
|
+
},
|
|
69
|
+
);
|
|
70
|
+
const json = JSON.parse(raw);
|
|
71
|
+
return json?.content?.[0]?.text ?? null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (provider === "openai") {
|
|
75
|
+
const raw = await httpsPost(
|
|
76
|
+
"api.openai.com",
|
|
77
|
+
"/v1/chat/completions",
|
|
78
|
+
{
|
|
79
|
+
"Content-Type": "application/json",
|
|
80
|
+
Authorization: `Bearer ${apiKey}`,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
model: "gpt-4o-mini",
|
|
84
|
+
max_tokens: 1024,
|
|
85
|
+
messages: [{ role: "user", content: prompt }],
|
|
86
|
+
temperature: 0.1,
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
const json = JSON.parse(raw);
|
|
90
|
+
return json?.choices?.[0]?.message?.content ?? null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (provider === "gemini") {
|
|
94
|
+
const raw = await httpsPost(
|
|
95
|
+
"generativelanguage.googleapis.com",
|
|
96
|
+
`/v1beta/models/gemini-1.5-flash:generateContent?key=${apiKey}`,
|
|
97
|
+
{ "Content-Type": "application/json" },
|
|
98
|
+
{
|
|
99
|
+
contents: [{ parts: [{ text: prompt }] }],
|
|
100
|
+
generationConfig: { maxOutputTokens: 1024, temperature: 0.1 },
|
|
101
|
+
},
|
|
102
|
+
);
|
|
103
|
+
const json = JSON.parse(raw);
|
|
104
|
+
return json?.candidates?.[0]?.content?.parts?.[0]?.text ?? null;
|
|
105
|
+
}
|
|
106
|
+
} catch (e) {
|
|
107
|
+
logger.err(`LLM API Call failed: ${e.message}`);
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// āā Core Binary Resolver āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
114
|
+
function getCoreBinaryPath(targetDir) {
|
|
115
|
+
const isWindows = os.default.platform() === "win32";
|
|
116
|
+
const ext = isWindows ? ".exe" : "";
|
|
117
|
+
|
|
118
|
+
// Dev build target checks
|
|
119
|
+
const devPath = path.default.resolve(targetDir, 'target', 'release', `tribunal-core${ext}`);
|
|
120
|
+
if (fs.default.existsSync(devPath)) return devPath;
|
|
121
|
+
|
|
122
|
+
const debugPath = path.default.resolve(targetDir, 'target', 'debug', `tribunal-core${ext}`);
|
|
123
|
+
if (fs.default.existsSync(debugPath)) return debugPath;
|
|
124
|
+
|
|
125
|
+
// Production npm package checks
|
|
126
|
+
const pkgName = `@tribunal-kit/core-${os.default.platform()}-${os.default.arch()}`;
|
|
127
|
+
try {
|
|
128
|
+
const pkgPath = require.resolve(`${pkgName}/package.json`);
|
|
129
|
+
const binPath = path.default.resolve(path.default.dirname(pkgPath), `bin/tribunal-core${ext}`);
|
|
130
|
+
if (fs.default.existsSync(binPath)) return binPath;
|
|
131
|
+
} catch {}
|
|
132
|
+
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// āā Main Optimizer Command āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
137
|
+
async function cmdOptimizeSkill(flags, processArgs, quiet = false) {
|
|
138
|
+
const targetDir = flags.path ? path.default.resolve(flags.path) : process.cwd();
|
|
139
|
+
const agentDest = path.default.join(targetDir, '.agent');
|
|
140
|
+
|
|
141
|
+
if (!fs.default.existsSync(agentDest)) {
|
|
142
|
+
logger.err('.agent/ not found. Run: npx tribunal-kit init');
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
helpers.banner(quiet);
|
|
147
|
+
|
|
148
|
+
// Detect LLM Credentials
|
|
149
|
+
const llm = detectLlmProvider();
|
|
150
|
+
if (!llm) {
|
|
151
|
+
logger.err("No LLM API Key detected in environment. Please set GEMINI_API_KEY, OPENAI_API_KEY, or ANTHROPIC_API_KEY.");
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Resolve Core Binary
|
|
156
|
+
const binPath = getCoreBinaryPath(targetDir);
|
|
157
|
+
if (!binPath) {
|
|
158
|
+
logger.err("tribunal-core binary not found. Run 'cargo build --release' or install the core package.");
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Parse loop parameters
|
|
163
|
+
const skillName = flags.target || 'project-idioms';
|
|
164
|
+
const skillPath = path.default.join(agentDest, 'skills', skillName, 'SKILL.md');
|
|
165
|
+
|
|
166
|
+
if (!fs.default.existsSync(skillPath)) {
|
|
167
|
+
logger.err(`Target skill file not found: ${skillPath}`);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Find the harness command
|
|
172
|
+
const positionalArgs = processArgs.slice(3).filter(arg => !arg.startsWith("--"));
|
|
173
|
+
if (positionalArgs.length === 0) {
|
|
174
|
+
logger.err("Harness command is required. Usage: tk optimize-skill --target <skill-name> \"<harness-command>\"");
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
177
|
+
const harnessCmd = positionalArgs[0];
|
|
178
|
+
|
|
179
|
+
const epochs = 4;
|
|
180
|
+
const editBudget = 4;
|
|
181
|
+
|
|
182
|
+
logger.log(` ${logger.c('cyan', 'ā')} Starting SkillOpt loop for skill: ${logger.bold(skillName)}`);
|
|
183
|
+
logger.log(` ${logger.c('cyan', 'ā')} Harness: "${logger.bold(harnessCmd)}"`);
|
|
184
|
+
logger.log(` ${logger.c('cyan', 'ā')} Provider: ${logger.bold(llm.provider)}`);
|
|
185
|
+
console.log();
|
|
186
|
+
|
|
187
|
+
let bestScore = 0.0;
|
|
188
|
+
let currentSkillText = fs.default.readFileSync(skillPath, 'utf8');
|
|
189
|
+
|
|
190
|
+
for (let epoch = 1; epoch <= epochs; epoch++) {
|
|
191
|
+
logger.log(` ${logger.c('cyan', 'ā¶')} ${logger.bold(`Epoch ${epoch}/${epochs}`)}`);
|
|
192
|
+
|
|
193
|
+
// 1. Run Rollout Harness
|
|
194
|
+
logger.log(` ${logger.c('gray', 'ā')} Running rollout batch execution...`);
|
|
195
|
+
let rolloutLogs = "";
|
|
196
|
+
let rolloutSuccess = true;
|
|
197
|
+
try {
|
|
198
|
+
rolloutLogs = execSync(harnessCmd, { encoding: 'utf8', cwd: targetDir, stdio: 'pipe' });
|
|
199
|
+
} catch (e) {
|
|
200
|
+
rolloutLogs = e.stdout + "\n" + e.stderr;
|
|
201
|
+
rolloutSuccess = false;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const _initialScore = rolloutSuccess ? 1.0 : 0.0;
|
|
205
|
+
logger.log(` ${logger.c('gray', 'ā')} Rollout score: ${rolloutSuccess ? logger.c('green', '1.0') : logger.c('red', '0.0')}`);
|
|
206
|
+
|
|
207
|
+
// 2. Call LLM for Patch Proposals
|
|
208
|
+
logger.log(` ${logger.c('gray', 'ā')} Requesting optimizer reflections from LLM...`);
|
|
209
|
+
const reflectionPrompt = `
|
|
210
|
+
You are a SkillOpt text-space optimizer coach.
|
|
211
|
+
Analyze the following rollout run logs and current skill document, then propose bounded add/delete/replace/insert_after edits.
|
|
212
|
+
The goal is to fix failure patterns and make the procedural memory rules clearer and more robust.
|
|
213
|
+
|
|
214
|
+
Current Skill Content:
|
|
215
|
+
"""
|
|
216
|
+
${currentSkillText}
|
|
217
|
+
"""
|
|
218
|
+
|
|
219
|
+
Rollout Logs:
|
|
220
|
+
${rolloutLogs.slice(-4000)}
|
|
221
|
+
|
|
222
|
+
Output ONLY a JSON array containing proposed edits. No markdown formatting, no explanation.
|
|
223
|
+
Each edit must follow this schema:
|
|
224
|
+
[
|
|
225
|
+
{
|
|
226
|
+
"op": "append" | "insert_after" | "replace" | "delete",
|
|
227
|
+
"target": "<exact text match to replace/insert_after/delete, leave null for append>",
|
|
228
|
+
"content": "<exact markdown/rules to add, replace, or insert>",
|
|
229
|
+
"support_count": 1,
|
|
230
|
+
"source_type": "${rolloutSuccess ? "success" : "failure"}"
|
|
231
|
+
}
|
|
232
|
+
]
|
|
233
|
+
`;
|
|
234
|
+
|
|
235
|
+
const llmResponse = await callLlmApi(reflectionPrompt, llm.provider, llm.key);
|
|
236
|
+
if (!llmResponse) {
|
|
237
|
+
logger.warn(" ā ļø LLM returned empty response. Skipping epoch step.");
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Clean LLM JSON response from markdown wrappers if present
|
|
242
|
+
let cleanedJson = llmResponse.trim();
|
|
243
|
+
if (cleanedJson.startsWith("```json")) {
|
|
244
|
+
cleanedJson = cleanedJson.replace(/^```json/, "").replace(/```$/, "").trim();
|
|
245
|
+
} else if (cleanedJson.startsWith("```")) {
|
|
246
|
+
cleanedJson = cleanedJson.replace(/^```/, "").replace(/```$/, "").trim();
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// 3. Invoke Rust binary for optimizing step
|
|
250
|
+
logger.log(` ${logger.c('gray', 'ā')} Merging and applying bounded edits via Rust Core...`);
|
|
251
|
+
let optResultStr = "";
|
|
252
|
+
try {
|
|
253
|
+
const tempFile = path.default.join(os.default.tmpdir(), `edits-${Date.now()}.json`);
|
|
254
|
+
fs.default.writeFileSync(tempFile, cleanedJson, 'utf8');
|
|
255
|
+
|
|
256
|
+
optResultStr = execSync(
|
|
257
|
+
`"${binPath}" optimize-step --skill-path "${skillPath}" --edits-json "${cleanedJson.replace(/"/g, '\\"')}" --budget ${editBudget}`,
|
|
258
|
+
{ encoding: 'utf8', cwd: targetDir, stdio: 'pipe' }
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
try { fs.default.unlinkSync(tempFile); } catch {}
|
|
262
|
+
} catch (e) {
|
|
263
|
+
logger.err(` ā Rust Core optimization failed: ${e.message}`);
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
let optReport;
|
|
268
|
+
try {
|
|
269
|
+
optReport = JSON.parse(optResultStr.trim());
|
|
270
|
+
} catch {
|
|
271
|
+
logger.err(" ā Failed to parse optimizer report from Rust Core.");
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (optReport.applied_count === 0) {
|
|
276
|
+
logger.log(` ${logger.c('yellow', 'ā')} No edits applied (deduplicated or target not found).`);
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
logger.log(` ${logger.c('green', 'ā')} Applied ${optReport.applied_count} edits to skill.`);
|
|
281
|
+
|
|
282
|
+
// 4. Run Validation Harness
|
|
283
|
+
logger.log(` ${logger.c('gray', 'ā')} Evaluating candidate skill against validation split...`);
|
|
284
|
+
let valSuccess = true;
|
|
285
|
+
try {
|
|
286
|
+
execSync(harnessCmd, { encoding: 'utf8', cwd: targetDir, stdio: 'pipe' });
|
|
287
|
+
} catch {
|
|
288
|
+
valSuccess = false;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const candidateScore = valSuccess ? 1.0 : 0.0;
|
|
292
|
+
|
|
293
|
+
// 5. Validation Gate
|
|
294
|
+
if (candidateScore > bestScore || (candidateScore === 1.0 && bestScore === 0.0)) {
|
|
295
|
+
logger.ok(` ā Gate Accepted! Score improved/stabilized to ${logger.c('green', String(candidateScore))}.`);
|
|
296
|
+
bestScore = candidateScore;
|
|
297
|
+
currentSkillText = fs.default.readFileSync(skillPath, 'utf8');
|
|
298
|
+
} else {
|
|
299
|
+
logger.warn(` ā ļø Gate Rejected. Score (${candidateScore}) <= Best (${bestScore}). Reverting edits.`);
|
|
300
|
+
fs.default.writeFileSync(skillPath, currentSkillText, 'utf8');
|
|
301
|
+
|
|
302
|
+
// Save to rejected-edit buffer history
|
|
303
|
+
const rejectedPath = path.default.join(agentDest, 'history', 'skill-optimization');
|
|
304
|
+
fs.default.mkdirSync(rejectedPath, { recursive: true });
|
|
305
|
+
const bufFile = path.default.join(rejectedPath, 'rejected-buffer.json');
|
|
306
|
+
let buffer = [];
|
|
307
|
+
if (fs.default.existsSync(bufFile)) {
|
|
308
|
+
try { buffer = JSON.parse(fs.default.readFileSync(bufFile, 'utf8')); } catch {}
|
|
309
|
+
}
|
|
310
|
+
buffer.push({ epoch, timestamp: new Date().toISOString(), edits: optReport.reports });
|
|
311
|
+
fs.default.writeFileSync(bufFile, JSON.stringify(buffer, null, 2), 'utf8');
|
|
312
|
+
}
|
|
313
|
+
console.log();
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
logger.ok(`š SkillOpt training complete. Best validation score: ${logger.c('green', String(bestScore))}`);
|
|
317
|
+
console.log();
|
|
318
|
+
}
|
package/dist/utils/version.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.compareSemver = compareSemver;
|
|
|
7
7
|
exports.fetchLatestVersion = fetchLatestVersion;
|
|
8
8
|
exports.autoUpdateCheck = autoUpdateCheck;
|
|
9
9
|
const https_1 = __importDefault(require("https"));
|
|
10
|
-
const
|
|
10
|
+
const _child_process_1 = require("child_process");
|
|
11
11
|
const fs_1 = __importDefault(require("fs"));
|
|
12
12
|
const path_1 = __importDefault(require("path"));
|
|
13
13
|
const os_1 = __importDefault(require("os"));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tribunal-kit",
|
|
3
|
-
"version": "5.8.
|
|
4
|
-
"description": "The operating system for AI software engineering ā governance, memory, review pipelines, and reusable skills for every coding agent.
|
|
3
|
+
"version": "5.8.4",
|
|
4
|
+
"description": "The operating system for AI software engineering ā governance, memory, review pipelines, and reusable skills for every coding agent. 44 specialist agents, 34 workflows, 20 parallel Tribunal code reviewers, MCP server, Rust core engine, and long-running autonomous agent harness for Cursor, VSCode, Windsurf, Claude Code, and Aider.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
7
7
|
"ai-agent",
|
|
@@ -91,6 +91,8 @@
|
|
|
91
91
|
"validate-payload": "node scripts/validate-payload.js",
|
|
92
92
|
"benchmark": "node scripts/benchmark.js",
|
|
93
93
|
"benchmark:rust": "cargo build --release && node scripts/benchmark.js",
|
|
94
|
+
"build:rust": "cargo build --release",
|
|
95
|
+
"test:rust": "cargo test --manifest-path crates/core/Cargo.toml",
|
|
94
96
|
"build": "echo 'No build step required for this project'"
|
|
95
97
|
},
|
|
96
98
|
"devDependencies": {
|
|
@@ -99,12 +101,12 @@
|
|
|
99
101
|
"typescript": "^5.4.5"
|
|
100
102
|
},
|
|
101
103
|
"optionalDependencies": {
|
|
102
|
-
"@tribunal-kit/core-darwin-arm64": "^5.8.
|
|
103
|
-
"@tribunal-kit/core-darwin-x64": "^5.8.
|
|
104
|
-
"@tribunal-kit/core-linux-arm64": "^5.8.
|
|
105
|
-
"@tribunal-kit/core-linux-x64": "^5.8.
|
|
106
|
-
"@tribunal-kit/core-win32-arm64": "^5.8.
|
|
107
|
-
"@tribunal-kit/core-win32-x64": "^5.8.
|
|
104
|
+
"@tribunal-kit/core-darwin-arm64": "^5.8.4",
|
|
105
|
+
"@tribunal-kit/core-darwin-x64": "^5.8.4",
|
|
106
|
+
"@tribunal-kit/core-linux-arm64": "^5.8.4",
|
|
107
|
+
"@tribunal-kit/core-linux-x64": "^5.8.4",
|
|
108
|
+
"@tribunal-kit/core-win32-arm64": "^5.8.4",
|
|
109
|
+
"@tribunal-kit/core-win32-x64": "^5.8.4"
|
|
108
110
|
},
|
|
109
111
|
"jest": {
|
|
110
112
|
"testMatch": [
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* fix-vbc.js ā Batch appends missing VBC Protocol and Pre-Flight sections
|
|
4
|
+
* to all SKILL.md files in .agent/skills/ that are failing validation.
|
|
5
|
+
*
|
|
6
|
+
* Run: node scripts/fix-vbc.js
|
|
7
|
+
* Dry-run: node scripts/fix-vbc.js --dry-run
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require("fs");
|
|
11
|
+
const path = require("path");
|
|
12
|
+
|
|
13
|
+
const ROOT = path.resolve(__dirname, "..");
|
|
14
|
+
const SKILLS_DIR = path.join(ROOT, ".agent", "skills");
|
|
15
|
+
const DRY_RUN = process.argv.includes("--dry-run");
|
|
16
|
+
|
|
17
|
+
const PRE_FLIGHT_BLOCK = `
|
|
18
|
+
### ā
Pre-Flight Self-Audit
|
|
19
|
+
|
|
20
|
+
\`\`\`
|
|
21
|
+
ā
Did I rely ONLY on real, verified tools and methods?
|
|
22
|
+
ā
Is this solution appropriately scoped to the user's constraints?
|
|
23
|
+
ā
Did I handle potential failure modes and edge cases?
|
|
24
|
+
ā
Have I avoided generic boilerplate that doesn't add value?
|
|
25
|
+
\`\`\`
|
|
26
|
+
`;
|
|
27
|
+
|
|
28
|
+
const VBC_BLOCK = `
|
|
29
|
+
### š Verification-Before-Completion (VBC) Protocol
|
|
30
|
+
|
|
31
|
+
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
|
|
32
|
+
|
|
33
|
+
- ā **Forbidden:** Declaring a task complete because the output "looks correct."
|
|
34
|
+
- ā
**Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
let fixedCount = 0;
|
|
38
|
+
let skippedCount = 0;
|
|
39
|
+
let errorCount = 0;
|
|
40
|
+
|
|
41
|
+
const skillDirs = fs.readdirSync(SKILLS_DIR).filter((d) => {
|
|
42
|
+
return fs.statSync(path.join(SKILLS_DIR, d)).isDirectory();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
for (const dir of skillDirs) {
|
|
46
|
+
const skillPath = path.join(SKILLS_DIR, dir, "SKILL.md");
|
|
47
|
+
if (!fs.existsSync(skillPath)) continue;
|
|
48
|
+
|
|
49
|
+
let content;
|
|
50
|
+
try {
|
|
51
|
+
content = fs.readFileSync(skillPath, "utf8");
|
|
52
|
+
} catch (e) {
|
|
53
|
+
console.error(` ā Failed to read: ${dir}/SKILL.md ā ${e.message}`);
|
|
54
|
+
errorCount++;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const hasPreFlight =
|
|
59
|
+
content.includes("Pre-Flight Checklist") || content.includes("Pre-Flight");
|
|
60
|
+
const hasVBC =
|
|
61
|
+
content.includes("VBC Protocol") || content.includes("VBC");
|
|
62
|
+
|
|
63
|
+
if (hasPreFlight && hasVBC) {
|
|
64
|
+
skippedCount++;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let appendText = "";
|
|
69
|
+
|
|
70
|
+
if (!hasPreFlight) {
|
|
71
|
+
appendText += PRE_FLIGHT_BLOCK;
|
|
72
|
+
console.log(` š§ ${dir}/SKILL.md ā appending Pre-Flight Self-Audit`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!hasVBC) {
|
|
76
|
+
appendText += VBC_BLOCK;
|
|
77
|
+
console.log(` š§ ${dir}/SKILL.md ā appending VBC Protocol`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (DRY_RUN) {
|
|
81
|
+
console.log(` [DRY-RUN] Would append to ${dir}/SKILL.md`);
|
|
82
|
+
} else {
|
|
83
|
+
try {
|
|
84
|
+
fs.appendFileSync(skillPath, appendText, "utf8");
|
|
85
|
+
fixedCount++;
|
|
86
|
+
} catch (e) {
|
|
87
|
+
console.error(` ā Failed to write: ${dir}/SKILL.md ā ${e.message}`);
|
|
88
|
+
errorCount++;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.log(`\nāāā VBC Fix Summary āāāāāāāāāāāāāāāāāāāāā`);
|
|
94
|
+
console.log(` Fixed: ${fixedCount}`);
|
|
95
|
+
console.log(` Skipped: ${skippedCount} (already compliant)`);
|
|
96
|
+
console.log(` Errors: ${errorCount}`);
|
|
97
|
+
console.log(` Mode: ${DRY_RUN ? "DRY-RUN (no changes)" : "LIVE"}`);
|
|
98
|
+
console.log();
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
$ErrorActionPreference = "Stop"
|
|
2
|
+
|
|
3
|
+
$skillsDir = "c:\Users\sunrise\Desktop\pfojects\cli project\tribunal-kit\.agent\skills"
|
|
4
|
+
|
|
5
|
+
$vbcBlock = @"
|
|
6
|
+
|
|
7
|
+
### `u{1F6D1} Verification-Before-Completion (VBC) Protocol
|
|
8
|
+
|
|
9
|
+
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
|
|
10
|
+
|
|
11
|
+
- `u{274C} **Forbidden:** Declaring a task complete because the output "looks correct."
|
|
12
|
+
- `u{2705} **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
13
|
+
"@
|
|
14
|
+
|
|
15
|
+
$preFlightBlock = @"
|
|
16
|
+
|
|
17
|
+
### `u{2705} Pre-Flight Self-Audit
|
|
18
|
+
|
|
19
|
+
``````
|
|
20
|
+
`u{2705} Did I rely ONLY on real, verified tools and methods?
|
|
21
|
+
`u{2705} Is this solution appropriately scoped to the user's constraints?
|
|
22
|
+
`u{2705} Did I handle potential failure modes and edge cases?
|
|
23
|
+
`u{2705} Have I avoided generic boilerplate that doesn't add value?
|
|
24
|
+
``````
|
|
25
|
+
"@
|
|
26
|
+
|
|
27
|
+
$failingSkills = @(
|
|
28
|
+
"12-principles-of-animation",
|
|
29
|
+
"60fps-animation",
|
|
30
|
+
"accessible-animation",
|
|
31
|
+
"adapt",
|
|
32
|
+
"animation-on-scroll",
|
|
33
|
+
"animation-systems",
|
|
34
|
+
"antfu-conventions",
|
|
35
|
+
"audit-and-fix",
|
|
36
|
+
"bolder",
|
|
37
|
+
"build-primitive",
|
|
38
|
+
"clarify",
|
|
39
|
+
"cobejs",
|
|
40
|
+
"codebase-design",
|
|
41
|
+
"colorize",
|
|
42
|
+
"compact-landing",
|
|
43
|
+
"company-logos",
|
|
44
|
+
"critique",
|
|
45
|
+
"delight",
|
|
46
|
+
"design-lab",
|
|
47
|
+
"diagnosing-bugs",
|
|
48
|
+
"distill",
|
|
49
|
+
"domain-modeling",
|
|
50
|
+
"fixing-metadata",
|
|
51
|
+
"gpt-taste",
|
|
52
|
+
"harden",
|
|
53
|
+
"impeccable",
|
|
54
|
+
"improve-codebase-architecture",
|
|
55
|
+
"landing-page",
|
|
56
|
+
"local-first-architecture",
|
|
57
|
+
"lottie-animation",
|
|
58
|
+
"marquee-loop",
|
|
59
|
+
"masked-reveal",
|
|
60
|
+
"micro-interaction",
|
|
61
|
+
"morphing-icons",
|
|
62
|
+
"page-transition-animation",
|
|
63
|
+
"polish",
|
|
64
|
+
"pricing-page",
|
|
65
|
+
"progressive-blur",
|
|
66
|
+
"quieter",
|
|
67
|
+
"react-doctor",
|
|
68
|
+
"redesign-skill",
|
|
69
|
+
"shape",
|
|
70
|
+
"soft-skill",
|
|
71
|
+
"sounds-on-the-web",
|
|
72
|
+
"svg-animation",
|
|
73
|
+
"swiss-design",
|
|
74
|
+
"taste-skill",
|
|
75
|
+
"tdd-workflow",
|
|
76
|
+
"thermo-nuclear-code-quality-review",
|
|
77
|
+
"to-spring-or-not-to-spring",
|
|
78
|
+
"transitions-dev",
|
|
79
|
+
"typeset",
|
|
80
|
+
"web-quality-audit"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
$fixedCount = 0
|
|
84
|
+
$errorCount = 0
|
|
85
|
+
|
|
86
|
+
foreach ($skill in $failingSkills) {
|
|
87
|
+
$filePath = Join-Path $skillsDir "$skill\SKILL.md"
|
|
88
|
+
|
|
89
|
+
if (-not (Test-Path $filePath)) {
|
|
90
|
+
Write-Host " SKIP: $skill/SKILL.md not found" -ForegroundColor Yellow
|
|
91
|
+
continue
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
$content = Get-Content $filePath -Raw
|
|
95
|
+
$appendText = ""
|
|
96
|
+
|
|
97
|
+
$hasPreFlight = ($content -match "Pre-Flight Checklist") -or ($content -match "Pre-Flight")
|
|
98
|
+
$hasVBC = ($content -match "VBC Protocol") -or ($content -match "VBC")
|
|
99
|
+
|
|
100
|
+
if (-not $hasPreFlight) {
|
|
101
|
+
$appendText += $preFlightBlock
|
|
102
|
+
Write-Host " FIX: $skill/SKILL.md - adding Pre-Flight" -ForegroundColor Cyan
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (-not $hasVBC) {
|
|
106
|
+
$appendText += $vbcBlock
|
|
107
|
+
Write-Host " FIX: $skill/SKILL.md - adding VBC Protocol" -ForegroundColor Cyan
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if ($appendText -ne "") {
|
|
111
|
+
Add-Content -Path $filePath -Value $appendText -NoNewline
|
|
112
|
+
$fixedCount++
|
|
113
|
+
Write-Host " DONE: $skill/SKILL.md" -ForegroundColor Green
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
Write-Host ""
|
|
118
|
+
Write-Host "Fixed: $fixedCount files" -ForegroundColor Green
|
|
119
|
+
Write-Host "Errors: $errorCount" -ForegroundColor Red
|