tribunal-kit 5.8.4 → 5.8.5
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 +3 -3
- package/.agent/history/integrity_manifest.json +75 -7
- package/.agent/history/memory/.memory.idx +1065 -1
- package/.agent/history/memory/MEMORY.md +71 -1
- package/.agent/rules/GEMINI.md +1 -1
- package/.agent/scripts/_utils.js +28 -7
- package/.agent/scripts/context_broker.js +0 -19
- package/.agent/scripts/guardrail_engine.js +1 -1
- package/.agent/scripts/integrity_manifest.js +10 -4
- package/.agent/scripts/marathon_harness.js +10 -1
- package/.agent/scripts/skill_evolution.js +36 -21
- package/.agent/scripts/swarm_dispatcher.js +65 -6
- package/.agent/skills/api-patterns/scripts/__pycache__/api_validator.cpython-311.pyc +0 -0
- package/.agent/skills/better-colors/SKILL.md +12 -4
- package/.agent/skills/database-design/scripts/__pycache__/schema_validator.cpython-311.pyc +0 -0
- package/.agent/skills/fixing-accessibility/SKILL.md +6 -4
- package/.agent/skills/frontend-design/SKILL.md +80 -81
- package/.agent/skills/frontend-design/scripts/__pycache__/accessibility_checker.cpython-311.pyc +0 -0
- package/.agent/skills/frontend-design/scripts/__pycache__/ux_audit.cpython-311.pyc +0 -0
- package/.agent/skills/geo-fundamentals/scripts/__pycache__/geo_checker.cpython-311.pyc +0 -0
- package/.agent/skills/i18n-localization/scripts/__pycache__/i18n_checker.cpython-311.pyc +0 -0
- package/.agent/skills/impeccable/SKILL.md +2 -0
- package/.agent/skills/lint-and-validate/scripts/__pycache__/lint_runner.cpython-311.pyc +0 -0
- package/.agent/skills/lint-and-validate/scripts/__pycache__/type_coverage.cpython-311.pyc +0 -0
- package/.agent/skills/mobile-design/scripts/__pycache__/mobile_audit.cpython-311.pyc +0 -0
- package/.agent/skills/motion-engineering/SKILL.md +66 -164
- package/.agent/skills/nextjs-react-expert/scripts/__pycache__/convert_rules.cpython-311.pyc +0 -0
- package/.agent/skills/nextjs-react-expert/scripts/__pycache__/react_performance_checker.cpython-311.pyc +0 -0
- package/.agent/skills/performance-profiling/scripts/__pycache__/lighthouse_audit.cpython-311.pyc +0 -0
- package/.agent/skills/seo-fundamentals/scripts/__pycache__/seo_checker.cpython-311.pyc +0 -0
- package/.agent/skills/testing-patterns/scripts/__pycache__/test_runner.cpython-311.pyc +0 -0
- package/.agent/skills/vulnerability-scanner/scripts/__pycache__/security_scan.cpython-311.pyc +0 -0
- package/.agent/skills/webapp-testing/scripts/__pycache__/playwright_runner.cpython-311.pyc +0 -0
- package/.agent/workflows/tribunal-full.md +5 -5
- package/CONTRIBUTING.md +1 -1
- package/README.md +4 -4
- package/bin/mcp-server.js +45 -45
- package/bin/wrapper.js +50 -25
- package/dist/cli.js +30 -0
- package/dist/commands/init.js +25 -1
- package/dist/commands/native.js +228 -0
- package/dist/commands/validate.js +67 -0
- package/dist/mcp/server.js +4 -138
- package/package.json +11 -10
- package/scripts/benchmark.js +42 -0
- package/scripts/sync-version.js +129 -76
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 🧠 Tribunal Memory Index
|
|
2
2
|
> Auto-generated by `tribunal-kit memory export`. Do not edit manually.
|
|
3
|
-
> Entries:
|
|
3
|
+
> Entries: 221 | Semantic: 177 | Procedural: 44 | Episodic: 0 | Working: 0
|
|
4
4
|
|
|
5
5
|
## SEMANTIC (Permanent Facts)
|
|
6
6
|
| ID | Content | Tags | Source | Created |
|
|
@@ -126,6 +126,62 @@
|
|
|
126
126
|
| 147 | [ ] Have I checked the environment for relevant existing implementations? | project-idiom, auto-learned | manual | 1784618632Z |
|
|
127
127
|
| 148 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1784618632Z |
|
|
128
128
|
| 149 | ✅ **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. | project-idiom, auto-learned | manual | 1784618632Z |
|
|
129
|
+
| 152 | ❌ Overriding project idioms without explicit justification -> ✅ Idioms represent team decisions; flag deviations with reasoning | project-idiom, auto-learned | manual | 1784705972Z |
|
|
130
|
+
| 153 | ❌ Applying idioms from one project to a different project -> ✅ Idioms are project-specific; verify they apply to the current codebase | project-idiom, auto-learned | manual | 1784705972Z |
|
|
131
|
+
| 154 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1784705972Z |
|
|
132
|
+
| 155 | ✅ **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. | project-idiom, auto-learned | manual | 1784705972Z |
|
|
133
|
+
| 156 | [ ] Have I reviewed the user's specific constraints and requests? | project-idiom, auto-learned | manual | 1784705972Z |
|
|
134
|
+
| 157 | [ ] Have I checked the environment for relevant existing implementations? | project-idiom, auto-learned | manual | 1784705972Z |
|
|
135
|
+
| 158 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1784705972Z |
|
|
136
|
+
| 159 | ✅ **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. | project-idiom, auto-learned | manual | 1784705972Z |
|
|
137
|
+
| 162 | ❌ Overriding project idioms without explicit justification -> ✅ Idioms represent team decisions; flag deviations with reasoning | project-idiom, auto-learned | manual | 1784706426Z |
|
|
138
|
+
| 163 | ❌ Applying idioms from one project to a different project -> ✅ Idioms are project-specific; verify they apply to the current codebase | project-idiom, auto-learned | manual | 1784706426Z |
|
|
139
|
+
| 164 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1784706426Z |
|
|
140
|
+
| 165 | ✅ **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. | project-idiom, auto-learned | manual | 1784706426Z |
|
|
141
|
+
| 166 | [ ] Have I reviewed the user's specific constraints and requests? | project-idiom, auto-learned | manual | 1784706426Z |
|
|
142
|
+
| 167 | [ ] Have I checked the environment for relevant existing implementations? | project-idiom, auto-learned | manual | 1784706426Z |
|
|
143
|
+
| 168 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1784706426Z |
|
|
144
|
+
| 169 | ✅ **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. | project-idiom, auto-learned | manual | 1784706426Z |
|
|
145
|
+
| 172 | ❌ Overriding project idioms without explicit justification -> ✅ Idioms represent team decisions; flag deviations with reasoning | project-idiom, auto-learned | manual | 1784706433Z |
|
|
146
|
+
| 173 | ❌ Applying idioms from one project to a different project -> ✅ Idioms are project-specific; verify they apply to the current codebase | project-idiom, auto-learned | manual | 1784706433Z |
|
|
147
|
+
| 174 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1784706433Z |
|
|
148
|
+
| 175 | ✅ **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. | project-idiom, auto-learned | manual | 1784706433Z |
|
|
149
|
+
| 176 | [ ] Have I reviewed the user's specific constraints and requests? | project-idiom, auto-learned | manual | 1784706433Z |
|
|
150
|
+
| 177 | [ ] Have I checked the environment for relevant existing implementations? | project-idiom, auto-learned | manual | 1784706433Z |
|
|
151
|
+
| 178 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1784706433Z |
|
|
152
|
+
| 179 | ✅ **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. | project-idiom, auto-learned | manual | 1784706433Z |
|
|
153
|
+
| 182 | ❌ Overriding project idioms without explicit justification -> ✅ Idioms represent team decisions; flag deviations with reasoning | project-idiom, auto-learned | manual | 1784706809Z |
|
|
154
|
+
| 183 | ❌ Applying idioms from one project to a different project -> ✅ Idioms are project-specific; verify they apply to the current codebase | project-idiom, auto-learned | manual | 1784706809Z |
|
|
155
|
+
| 184 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1784706809Z |
|
|
156
|
+
| 185 | ✅ **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. | project-idiom, auto-learned | manual | 1784706809Z |
|
|
157
|
+
| 186 | [ ] Have I reviewed the user's specific constraints and requests? | project-idiom, auto-learned | manual | 1784706809Z |
|
|
158
|
+
| 187 | [ ] Have I checked the environment for relevant existing implementations? | project-idiom, auto-learned | manual | 1784706809Z |
|
|
159
|
+
| 188 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1784706809Z |
|
|
160
|
+
| 189 | ✅ **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. | project-idiom, auto-learned | manual | 1784706809Z |
|
|
161
|
+
| 192 | ❌ Overriding project idioms without explicit justification -> ✅ Idioms represent team decisions; flag deviations with reasoning | project-idiom, auto-learned | manual | 1784706814Z |
|
|
162
|
+
| 193 | ❌ Applying idioms from one project to a different project -> ✅ Idioms are project-specific; verify they apply to the current codebase | project-idiom, auto-learned | manual | 1784706814Z |
|
|
163
|
+
| 194 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1784706814Z |
|
|
164
|
+
| 195 | ✅ **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. | project-idiom, auto-learned | manual | 1784706814Z |
|
|
165
|
+
| 196 | [ ] Have I reviewed the user's specific constraints and requests? | project-idiom, auto-learned | manual | 1784706814Z |
|
|
166
|
+
| 197 | [ ] Have I checked the environment for relevant existing implementations? | project-idiom, auto-learned | manual | 1784706814Z |
|
|
167
|
+
| 198 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1784706814Z |
|
|
168
|
+
| 199 | ✅ **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. | project-idiom, auto-learned | manual | 1784706814Z |
|
|
169
|
+
| 202 | ❌ Overriding project idioms without explicit justification -> ✅ Idioms represent team decisions; flag deviations with reasoning | project-idiom, auto-learned | manual | 1785138690Z |
|
|
170
|
+
| 203 | ❌ Applying idioms from one project to a different project -> ✅ Idioms are project-specific; verify they apply to the current codebase | project-idiom, auto-learned | manual | 1785138690Z |
|
|
171
|
+
| 204 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1785138690Z |
|
|
172
|
+
| 205 | ✅ **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. | project-idiom, auto-learned | manual | 1785138690Z |
|
|
173
|
+
| 206 | [ ] Have I reviewed the user's specific constraints and requests? | project-idiom, auto-learned | manual | 1785138690Z |
|
|
174
|
+
| 207 | [ ] Have I checked the environment for relevant existing implementations? | project-idiom, auto-learned | manual | 1785138690Z |
|
|
175
|
+
| 208 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1785138690Z |
|
|
176
|
+
| 209 | ✅ **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. | project-idiom, auto-learned | manual | 1785138690Z |
|
|
177
|
+
| 212 | ❌ Overriding project idioms without explicit justification -> ✅ Idioms represent team decisions; flag deviations with reasoning | project-idiom, auto-learned | manual | 1785138695Z |
|
|
178
|
+
| 213 | ❌ Applying idioms from one project to a different project -> ✅ Idioms are project-specific; verify they apply to the current codebase | project-idiom, auto-learned | manual | 1785138695Z |
|
|
179
|
+
| 214 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1785138695Z |
|
|
180
|
+
| 215 | ✅ **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. | project-idiom, auto-learned | manual | 1785138695Z |
|
|
181
|
+
| 216 | [ ] Have I reviewed the user's specific constraints and requests? | project-idiom, auto-learned | manual | 1785138695Z |
|
|
182
|
+
| 217 | [ ] Have I checked the environment for relevant existing implementations? | project-idiom, auto-learned | manual | 1785138695Z |
|
|
183
|
+
| 218 | ❌ **Forbidden:** Declaring a task complete because the output "looks correct." | project-idiom, auto-learned | manual | 1785138695Z |
|
|
184
|
+
| 219 | ✅ **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. | project-idiom, auto-learned | manual | 1785138696Z |
|
|
129
185
|
|
|
130
186
|
## PROCEDURAL (How-To Recipes)
|
|
131
187
|
| ID | Content | Tags | Source | Created |
|
|
@@ -160,4 +216,18 @@
|
|
|
160
216
|
| 141 | Run `npm run validate-payload && jest --coverage` to test the project | build-script, test, auto-learned | manual | 1784396209Z |
|
|
161
217
|
| 150 | Run `echo 'No build step required for this project'` to build the project | build-script, build, auto-learned | manual | 1784618632Z |
|
|
162
218
|
| 151 | Run `npm run validate-payload && jest --coverage` to test the project | build-script, test, auto-learned | manual | 1784618632Z |
|
|
219
|
+
| 160 | Run `echo 'No build step required for this project'` to build the project | build-script, build, auto-learned | manual | 1784705972Z |
|
|
220
|
+
| 161 | Run `npm run validate-payload && jest --coverage` to test the project | build-script, test, auto-learned | manual | 1784705972Z |
|
|
221
|
+
| 170 | Run `echo 'No build step required for this project'` to build the project | build-script, build, auto-learned | manual | 1784706426Z |
|
|
222
|
+
| 171 | Run `npm run validate-payload && jest --coverage` to test the project | build-script, test, auto-learned | manual | 1784706426Z |
|
|
223
|
+
| 180 | Run `echo 'No build step required for this project'` to build the project | build-script, build, auto-learned | manual | 1784706433Z |
|
|
224
|
+
| 181 | Run `npm run validate-payload && jest --coverage` to test the project | build-script, test, auto-learned | manual | 1784706433Z |
|
|
225
|
+
| 190 | Run `echo 'No build step required for this project'` to build the project | build-script, build, auto-learned | manual | 1784706809Z |
|
|
226
|
+
| 191 | Run `npm run validate-payload && jest --coverage` to test the project | build-script, test, auto-learned | manual | 1784706809Z |
|
|
227
|
+
| 200 | Run `echo 'No build step required for this project'` to build the project | build-script, build, auto-learned | manual | 1784706814Z |
|
|
228
|
+
| 201 | Run `npm run validate-payload && jest --coverage` to test the project | build-script, test, auto-learned | manual | 1784706814Z |
|
|
229
|
+
| 210 | Run `npm run build:rust` to build the project | build-script, build, auto-learned | manual | 1785138690Z |
|
|
230
|
+
| 211 | Run `npm run validate-payload && jest --coverage` to test the project | build-script, test, auto-learned | manual | 1785138690Z |
|
|
231
|
+
| 220 | Run `npm run build:rust` to build the project | build-script, build, auto-learned | manual | 1785138696Z |
|
|
232
|
+
| 221 | Run `npm run validate-payload && jest --coverage` to test the project | build-script, test, auto-learned | manual | 1785138696Z |
|
|
163
233
|
|
package/.agent/rules/GEMINI.md
CHANGED
|
@@ -222,7 +222,7 @@ The Human Gate is never skipped. No code is written to a file without explicit u
|
|
|
222
222
|
| Database/SQL | logic + security + sql + schema + complexity-reviewer |
|
|
223
223
|
| Mobile/Cross-platform | logic + security + mobile-reviewer + type-safety + complexity-reviewer |
|
|
224
224
|
| Any domain | + performance (if optimization) |
|
|
225
|
-
| Before merge | /tribunal-full (all
|
|
225
|
+
| Before merge | /tribunal-full (all 19 reviewers) |
|
|
226
226
|
|
|
227
227
|
---
|
|
228
228
|
|
package/.agent/scripts/_utils.js
CHANGED
|
@@ -226,9 +226,34 @@ function parseArgs(argv, schema = {}) {
|
|
|
226
226
|
|
|
227
227
|
// ── Command Runner ──────────────────────────────────────────────────────────
|
|
228
228
|
|
|
229
|
+
const WINDOWS_CMD_SHIMS = new Set(["npm", "npx", "pnpm", "yarn", "bun", "bunx"]);
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Select the executable that should be passed to spawnSync.
|
|
233
|
+
* Only package-manager shims need a .cmd suffix on Windows; native executables
|
|
234
|
+
* such as node, cargo, and git must retain their original names.
|
|
235
|
+
*
|
|
236
|
+
* @param {string} cmd - Command to run
|
|
237
|
+
* @param {string} [platform] - Platform override for deterministic testing
|
|
238
|
+
* @returns {string}
|
|
239
|
+
*/
|
|
240
|
+
function normalizeCommand(cmd, platform = process.platform) {
|
|
241
|
+
const lowerCaseCommand = cmd.toLowerCase();
|
|
242
|
+
const hasPath = cmd.includes("/") || cmd.includes("\\\\");
|
|
243
|
+
if (
|
|
244
|
+
platform === "win32" &&
|
|
245
|
+
!hasPath &&
|
|
246
|
+
!lowerCaseCommand.endsWith(".cmd") &&
|
|
247
|
+
WINDOWS_CMD_SHIMS.has(lowerCaseCommand)
|
|
248
|
+
) {
|
|
249
|
+
return `${cmd}.cmd`;
|
|
250
|
+
}
|
|
251
|
+
return cmd;
|
|
252
|
+
}
|
|
253
|
+
|
|
229
254
|
/**
|
|
230
255
|
* Run a command synchronously and return a structured result.
|
|
231
|
-
* Handles Windows
|
|
256
|
+
* Handles known Windows package-manager shims without rewriting native tools.
|
|
232
257
|
*
|
|
233
258
|
* @param {string} cmd - Command to run
|
|
234
259
|
* @param {string[]} args - Arguments
|
|
@@ -237,12 +262,7 @@ function parseArgs(argv, schema = {}) {
|
|
|
237
262
|
*/
|
|
238
263
|
function runCommand(cmd, args = [], opts = {}) {
|
|
239
264
|
const { spawnSync } = require("child_process");
|
|
240
|
-
const executable =
|
|
241
|
-
process.platform === "win32" &&
|
|
242
|
-
!cmd.endsWith(".cmd") &&
|
|
243
|
-
!cmd.includes(path.sep)
|
|
244
|
-
? `${cmd}.cmd`
|
|
245
|
-
: cmd;
|
|
265
|
+
const executable = normalizeCommand(cmd);
|
|
246
266
|
|
|
247
267
|
const result = spawnSync(executable, args, {
|
|
248
268
|
encoding: "utf8",
|
|
@@ -275,5 +295,6 @@ module.exports = {
|
|
|
275
295
|
// CLI
|
|
276
296
|
parseArgs,
|
|
277
297
|
// Commands
|
|
298
|
+
normalizeCommand,
|
|
278
299
|
runCommand,
|
|
279
300
|
};
|
|
@@ -355,25 +355,6 @@ const BASELINE_SKILLS = [
|
|
|
355
355
|
|
|
356
356
|
// ── Skill catalogue (loaded from disk) ───────────────────────────────────────
|
|
357
357
|
|
|
358
|
-
/**
|
|
359
|
-
* Find the .agent directory by walking up from cwd.
|
|
360
|
-
* @returns {string} path to .agent/
|
|
361
|
-
*/
|
|
362
|
-
function findAgentDir() {
|
|
363
|
-
let current = path.resolve(process.cwd());
|
|
364
|
-
const root = path.parse(current).root;
|
|
365
|
-
while (current !== root) {
|
|
366
|
-
const candidate = path.join(current, ".agent");
|
|
367
|
-
if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory())
|
|
368
|
-
return candidate;
|
|
369
|
-
current = path.dirname(current);
|
|
370
|
-
}
|
|
371
|
-
console.error(
|
|
372
|
-
`${RED}✖ .agent/ not found. Run: npx tribunal-kit init${RESET}`,
|
|
373
|
-
);
|
|
374
|
-
process.exit(1);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
358
|
/**
|
|
378
359
|
* Parse the YAML frontmatter from a SKILL.md file.
|
|
379
360
|
* Returns { name, description, ... } or null on parse failure.
|
|
@@ -104,7 +104,7 @@ function ruleReviewerCount(content, manifest, _ctx) {
|
|
|
104
104
|
const actualCount = manifest.agents ? manifest.agents.reviewer_count : null;
|
|
105
105
|
if (actualCount === null) return violations;
|
|
106
106
|
|
|
107
|
-
const countRegex = /(\d+)
|
|
107
|
+
const countRegex = /(\d+)\s*(?:-\s*)?(?:(?:parallel|domain(?:-specific)?|tribunal|code)\s+)*reviewers?\b/gi;
|
|
108
108
|
let match;
|
|
109
109
|
while ((match = countRegex.exec(content)) !== null) {
|
|
110
110
|
const claimed = parseInt(match[1], 10);
|
|
@@ -82,9 +82,10 @@ function crawlAgents(agentDir) {
|
|
|
82
82
|
const content = safeReadFile(path.join(agentsDir, file));
|
|
83
83
|
const fm = parseFrontmatter(content);
|
|
84
84
|
const isReviewer =
|
|
85
|
-
/reviewer|auditor|tester/i.test(name) ||
|
|
85
|
+
/reviewer|auditor|tester|throughput-optimizer/i.test(name) ||
|
|
86
86
|
(fm.role && /reviewer/i.test(fm.role));
|
|
87
87
|
|
|
88
|
+
|
|
88
89
|
if (isReviewer) {
|
|
89
90
|
reviewers.push(name);
|
|
90
91
|
} else {
|
|
@@ -239,7 +240,10 @@ function extractNumericClaims(filePath, content, agentDir, actualCounts) {
|
|
|
239
240
|
const lines = content.split(/\r?\n/);
|
|
240
241
|
|
|
241
242
|
const claimPatterns = [
|
|
242
|
-
{
|
|
243
|
+
{
|
|
244
|
+
regex: /(\d+)\s*(?:-\s*)?(?:(?:parallel|domain(?:-specific)?|tribunal|code)\s+)*reviewers?\b/gi,
|
|
245
|
+
entity: "reviewers",
|
|
246
|
+
},
|
|
243
247
|
{ regex: /(\d+)\s*(?:specialist\s+)?agents?\b/gi, entity: "agents" },
|
|
244
248
|
{ regex: /(\d+)\s*(?:modular\s+)?skills?\b/gi, entity: "skills" },
|
|
245
249
|
{ regex: /(\d+)\s*(?:slash\s+)?workflows?\b/gi, entity: "workflows" },
|
|
@@ -253,8 +257,10 @@ function extractNumericClaims(filePath, content, agentDir, actualCounts) {
|
|
|
253
257
|
let match;
|
|
254
258
|
while ((match = regex.exec(line)) !== null) {
|
|
255
259
|
const claimed = parseInt(match[1], 10);
|
|
256
|
-
//
|
|
257
|
-
|
|
260
|
+
// This manifest describes the full Tribunal payload, so small local
|
|
261
|
+
// counts (for example, "3 skills" in one skill group) are not global
|
|
262
|
+
// asset claims. Skip them along with implausibly large values.
|
|
263
|
+
if (claimed < 5 || claimed > 500) continue;
|
|
258
264
|
|
|
259
265
|
const actual = actualCounts[entity];
|
|
260
266
|
if (actual !== undefined) {
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
const fs = require("fs");
|
|
25
25
|
const path = require("path");
|
|
26
26
|
const { execSync } = require("child_process");
|
|
27
|
+
const { findAgentDir } = require("./_utils");
|
|
27
28
|
|
|
28
29
|
const {
|
|
29
30
|
GREEN,
|
|
@@ -42,7 +43,11 @@ const {
|
|
|
42
43
|
} = require("./_colors");
|
|
43
44
|
|
|
44
45
|
// ── Paths ────────────────────────────────────────────────────────────────────
|
|
45
|
-
|
|
46
|
+
function getMarathonDir(startDir = process.cwd()) {
|
|
47
|
+
return path.join(findAgentDir(startDir), "history", "marathon");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const MARATHON_DIR = getMarathonDir();
|
|
46
51
|
const FEATURE_LIST_FILE = path.join(MARATHON_DIR, "feature_list.json");
|
|
47
52
|
const PROGRESS_FILE = path.join(MARATHON_DIR, "progress.json");
|
|
48
53
|
const ARCHIVE_DIR = path.join(MARATHON_DIR, "archive");
|
|
@@ -1049,6 +1054,10 @@ function main() {
|
|
|
1049
1054
|
}
|
|
1050
1055
|
}
|
|
1051
1056
|
|
|
1057
|
+
module.exports = {
|
|
1058
|
+
getMarathonDir,
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1052
1061
|
if (require.main === module) {
|
|
1053
1062
|
main();
|
|
1054
1063
|
}
|
|
@@ -46,11 +46,18 @@ const {
|
|
|
46
46
|
const { findAgentDir } = require("./_utils");
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
|
|
49
|
+
function getPaths(startDir = process.cwd()) {
|
|
50
|
+
const agentDir = findAgentDir(startDir);
|
|
51
|
+
const skillDir = path.join(agentDir, "skills", "project-idioms");
|
|
52
|
+
const historyDir = path.join(agentDir, "history", "skill-evolution");
|
|
53
|
+
return {
|
|
54
|
+
agentDir,
|
|
55
|
+
skillDir,
|
|
56
|
+
skillFile: path.join(skillDir, "SKILL.md"),
|
|
57
|
+
historyDir,
|
|
58
|
+
logFile: path.join(historyDir, "digest-log.json"),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
54
61
|
|
|
55
62
|
// ── Architectural Weight Patterns ────────────────────────────────────────────
|
|
56
63
|
const HIGH_WEIGHT_PATTERNS = [
|
|
@@ -205,8 +212,9 @@ function countTokensEstimate(text) {
|
|
|
205
212
|
|
|
206
213
|
// ── Idiom management ──────────────────────────────────────────────────────────
|
|
207
214
|
function loadExistingIdioms() {
|
|
208
|
-
|
|
209
|
-
|
|
215
|
+
const { skillFile } = getPaths();
|
|
216
|
+
if (!fs.existsSync(skillFile)) return [];
|
|
217
|
+
const content = fs.readFileSync(skillFile, "utf8");
|
|
210
218
|
const idioms = [];
|
|
211
219
|
const pattern =
|
|
212
220
|
/\|\s*(\d+)\s*\|\s*`([^`]+)`\s*\|\s*([^|]+)\|\s*([^|]+)\|\s*([^|]+)\|/g;
|
|
@@ -346,10 +354,11 @@ function parseLlmYamlResponse(response) {
|
|
|
346
354
|
|
|
347
355
|
// ── Log helpers ────────────────────────────────────────────────────────────────
|
|
348
356
|
function loadLog() {
|
|
349
|
-
|
|
350
|
-
|
|
357
|
+
const { historyDir, logFile } = getPaths();
|
|
358
|
+
fs.mkdirSync(historyDir, { recursive: true });
|
|
359
|
+
if (fs.existsSync(logFile)) {
|
|
351
360
|
try {
|
|
352
|
-
return JSON.parse(fs.readFileSync(
|
|
361
|
+
return JSON.parse(fs.readFileSync(logFile, "utf8"));
|
|
353
362
|
} catch {
|
|
354
363
|
/* fallthrough */
|
|
355
364
|
}
|
|
@@ -358,8 +367,9 @@ function loadLog() {
|
|
|
358
367
|
}
|
|
359
368
|
|
|
360
369
|
function saveLog(log) {
|
|
361
|
-
|
|
362
|
-
fs.
|
|
370
|
+
const { historyDir, logFile } = getPaths();
|
|
371
|
+
fs.mkdirSync(historyDir, { recursive: true });
|
|
372
|
+
fs.writeFileSync(logFile, JSON.stringify(log, null, 2), "utf8");
|
|
363
373
|
}
|
|
364
374
|
|
|
365
375
|
// ── Auto-LLM API Integration ─────────────────────────────────────────────────
|
|
@@ -835,8 +845,9 @@ async function cmdDigest(args) {
|
|
|
835
845
|
if (added > 0) {
|
|
836
846
|
log.total_idioms = merged.length;
|
|
837
847
|
const skillMd = renderSkillMd(merged, (log.cycles || []).length + 1);
|
|
838
|
-
|
|
839
|
-
fs.
|
|
848
|
+
const { skillDir, skillFile } = getPaths();
|
|
849
|
+
fs.mkdirSync(skillDir, { recursive: true });
|
|
850
|
+
fs.writeFileSync(skillFile, skillMd, "utf8");
|
|
840
851
|
console.log(` ${GREEN}✔ ${added} new idiom(s) added to SKILL.md${RESET}`);
|
|
841
852
|
} else {
|
|
842
853
|
console.log(` ${DIM} No new unique idioms added to SKILL.md.${RESET}`);
|
|
@@ -932,22 +943,24 @@ async function cmdDigest(args) {
|
|
|
932
943
|
}
|
|
933
944
|
|
|
934
945
|
function cmdShow() {
|
|
935
|
-
|
|
946
|
+
const { skillFile } = getPaths();
|
|
947
|
+
if (!fs.existsSync(skillFile)) {
|
|
936
948
|
console.log(
|
|
937
949
|
`${YELLOW}No project-idioms skill found. Run 'digest' first.${RESET}`,
|
|
938
950
|
);
|
|
939
951
|
return;
|
|
940
952
|
}
|
|
941
|
-
console.log(fs.readFileSync(
|
|
953
|
+
console.log(fs.readFileSync(skillFile, "utf8"));
|
|
942
954
|
}
|
|
943
955
|
|
|
944
956
|
function cmdReset() {
|
|
945
|
-
|
|
946
|
-
|
|
957
|
+
const { skillFile, logFile } = getPaths();
|
|
958
|
+
if (fs.existsSync(skillFile)) {
|
|
959
|
+
fs.unlinkSync(skillFile);
|
|
947
960
|
console.log(`${GREEN}✔ project-idioms/SKILL.md deleted.${RESET}`);
|
|
948
961
|
}
|
|
949
|
-
if (fs.existsSync(
|
|
950
|
-
fs.unlinkSync(
|
|
962
|
+
if (fs.existsSync(logFile)) {
|
|
963
|
+
fs.unlinkSync(logFile);
|
|
951
964
|
console.log(`${GREEN}✔ Digest log cleared.${RESET}`);
|
|
952
965
|
}
|
|
953
966
|
console.log(`${DIM}Run 'digest' to start a fresh evolution cycle.${RESET}`);
|
|
@@ -958,7 +971,8 @@ function cmdStatus() {
|
|
|
958
971
|
const cycles = log.cycles || [];
|
|
959
972
|
const totalSaved = log.total_tokens_saved || 0;
|
|
960
973
|
const totalIdioms = log.total_idioms || 0;
|
|
961
|
-
const
|
|
974
|
+
const { skillFile } = getPaths();
|
|
975
|
+
const idiomsExist = fs.existsSync(skillFile);
|
|
962
976
|
|
|
963
977
|
console.log(
|
|
964
978
|
`\n${BOLD}${CYAN}━━━ Skill Evolution Status ━━━━━━━━━━━━━━━━━━━━━━━━${RESET}`,
|
|
@@ -1033,6 +1047,7 @@ module.exports = {
|
|
|
1033
1047
|
architecturalWeight,
|
|
1034
1048
|
parseLlmYamlResponse,
|
|
1035
1049
|
loadExistingIdioms,
|
|
1050
|
+
getPaths,
|
|
1036
1051
|
};
|
|
1037
1052
|
|
|
1038
1053
|
if (require.main === module) {
|
|
@@ -52,7 +52,7 @@ class SwarmDashboard {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
start() {
|
|
55
|
-
|
|
55
|
+
this.render();
|
|
56
56
|
this.timer = setInterval(() => this.render(), 80);
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -89,12 +89,63 @@ const MAX_GOAL_LENGTH = 200;
|
|
|
89
89
|
const MAX_CONTEXT_LENGTH = 800;
|
|
90
90
|
const MAX_WORKERS_PER_SWARM = 5;
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
function getBinaryPath() {
|
|
93
|
+
if (process.env.TRIBUNAL_FORCE_JS === "1") return null;
|
|
94
|
+
const isWindows = process.platform === "win32";
|
|
95
|
+
const ext = isWindows ? ".exe" : "";
|
|
96
|
+
const candidates = [
|
|
97
|
+
process.env.TRIBUNAL_CORE_PATH,
|
|
98
|
+
path.resolve(__dirname, "..", "..", "tribunal-kit", "target", "release", `tribunal-core${ext}`),
|
|
99
|
+
path.resolve(__dirname, "..", "..", "target", "release", `tribunal-core${ext}`),
|
|
100
|
+
path.resolve(process.cwd(), "target", "release", `tribunal-core${ext}`),
|
|
101
|
+
path.resolve(process.cwd(), "tribunal-kit", "target", "release", `tribunal-core${ext}`),
|
|
102
|
+
];
|
|
103
|
+
for (const c of candidates) {
|
|
104
|
+
if (c && fs.existsSync(c)) return c;
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
93
108
|
|
|
109
|
+
function nativeValidate(file, schemaType) {
|
|
110
|
+
const bin = getBinaryPath();
|
|
111
|
+
if (!bin || !file || !fs.existsSync(file)) return null;
|
|
112
|
+
try {
|
|
113
|
+
const { spawnSync } = require("child_process");
|
|
114
|
+
const res = spawnSync(bin, ["validate", "--file", file, "--schema", schemaType], {
|
|
115
|
+
encoding: "utf-8",
|
|
116
|
+
});
|
|
117
|
+
if (res.status === 0) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
} catch {
|
|
121
|
+
// fallback to JS engine
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function findAgentDir(startPath) {
|
|
127
|
+
let current = path.resolve(startPath);
|
|
128
|
+
const root = path.parse(current).root;
|
|
129
|
+
while (current !== root) {
|
|
130
|
+
const agentDir = path.join(current, ".agent");
|
|
131
|
+
if (fs.existsSync(agentDir) && fs.statSync(agentDir).isDirectory()) {
|
|
132
|
+
return agentDir;
|
|
133
|
+
}
|
|
134
|
+
current = path.dirname(current);
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
94
138
|
|
|
95
139
|
// ─── Legacy mode: validate orchestrator micro-worker payloads ──────────────────
|
|
96
140
|
|
|
97
|
-
function validatePayload(payloadData, workspaceRoot, agentsDir) {
|
|
141
|
+
function validatePayload(payloadData, workspaceRoot, agentsDir, payloadFile = null) {
|
|
142
|
+
if (payloadFile) {
|
|
143
|
+
const nativeResult = nativeValidate(payloadFile, "micro-worker");
|
|
144
|
+
if (nativeResult === true) {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
98
149
|
if (!payloadData.dispatch_micro_workers) {
|
|
99
150
|
console.error(
|
|
100
151
|
"ERROR: Payload missing required 'dispatch_micro_workers' array.",
|
|
@@ -301,7 +352,14 @@ function validateWorkerResult(res, index) {
|
|
|
301
352
|
return errors;
|
|
302
353
|
}
|
|
303
354
|
|
|
304
|
-
function validateSwarmPayload(payloadData, agentsDir) {
|
|
355
|
+
function validateSwarmPayload(payloadData, agentsDir, payloadFile = null) {
|
|
356
|
+
if (payloadFile) {
|
|
357
|
+
const nativeResult = nativeValidate(payloadFile, "swarm");
|
|
358
|
+
if (nativeResult === true) {
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
305
363
|
let items;
|
|
306
364
|
if (typeof payloadData === "object" && payloadData !== null) {
|
|
307
365
|
if (Array.isArray(payloadData)) {
|
|
@@ -417,7 +475,7 @@ function main() {
|
|
|
417
475
|
}
|
|
418
476
|
|
|
419
477
|
if (mode === "swarm") {
|
|
420
|
-
if (!validateSwarmPayload(payloadData, agentsDir)) {
|
|
478
|
+
if (!validateSwarmPayload(payloadData, agentsDir, file)) {
|
|
421
479
|
console.error("ERROR: Swarm payload validation failed.");
|
|
422
480
|
process.exit(1);
|
|
423
481
|
}
|
|
@@ -494,7 +552,7 @@ function main() {
|
|
|
494
552
|
}
|
|
495
553
|
}
|
|
496
554
|
} else {
|
|
497
|
-
if (!validatePayload(payloadData, workspaceRoot, agentsDir)) {
|
|
555
|
+
if (!validatePayload(payloadData, workspaceRoot, agentsDir, file)) {
|
|
498
556
|
console.error("ERROR: Payload validation failed.");
|
|
499
557
|
process.exit(1);
|
|
500
558
|
}
|
|
@@ -536,6 +594,7 @@ function main() {
|
|
|
536
594
|
}
|
|
537
595
|
|
|
538
596
|
module.exports = {
|
|
597
|
+
SwarmDashboard,
|
|
539
598
|
validateWorkerRequest,
|
|
540
599
|
validateWorkerResult,
|
|
541
600
|
validateSwarmPayload,
|
|
Binary file
|
|
@@ -40,15 +40,16 @@ $$\text{Format: } \text{oklch}(L \quad C \quad H [\quad / \quad A])$$
|
|
|
40
40
|
- `250`: Blue / Indigo
|
|
41
41
|
- `300`: Purple / Violet
|
|
42
42
|
|
|
43
|
-
### CSS Custom Properties
|
|
43
|
+
### CSS Custom Properties & Relative Color Syntax
|
|
44
44
|
|
|
45
45
|
```css
|
|
46
46
|
:root {
|
|
47
47
|
/* Brand Primary: Vibrant Indigo */
|
|
48
48
|
--color-primary: oklch(0.55 0.22 260);
|
|
49
|
-
|
|
50
|
-
--color-primary-
|
|
51
|
-
--color-primary-
|
|
49
|
+
/* Modern CSS Relative Color Syntax (Modifying Lightness/Chroma dynamically) */
|
|
50
|
+
--color-primary-hover: oklch(from var(--color-primary) calc(l - 0.08) c h);
|
|
51
|
+
--color-primary-active: oklch(from var(--color-primary) calc(l - 0.14) c h);
|
|
52
|
+
--color-primary-subtle: oklch(from var(--color-primary) 0.95 0.04 h);
|
|
52
53
|
|
|
53
54
|
/* Neutrals: Subtly Tinted (Chroma ~ 0.015) */
|
|
54
55
|
--bg-surface: oklch(0.99 0.005 260);
|
|
@@ -58,6 +59,13 @@ $$\text{Format: } \text{oklch}(L \quad C \quad H [\quad / \quad A])$$
|
|
|
58
59
|
--border-subtle: oklch(0.88 0.015 260);
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
/* Native CSS light-dark() declaration mode */
|
|
63
|
+
:root {
|
|
64
|
+
color-scheme: light dark;
|
|
65
|
+
--surface-adaptive: light-dark(oklch(0.99 0.005 260), oklch(0.14 0.015 260));
|
|
66
|
+
--text-adaptive: light-dark(oklch(0.20 0.02 260), oklch(0.96 0.01 260));
|
|
67
|
+
}
|
|
68
|
+
|
|
61
69
|
@media (prefers-color-scheme: dark) {
|
|
62
70
|
:root {
|
|
63
71
|
--bg-surface: oklch(0.14 0.015 260);
|
|
Binary file
|
|
@@ -19,15 +19,17 @@ Guidelines for detecting, prioritizing, and fixing accessibility defects across
|
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
## 1. Priority Priority Matrix
|
|
22
|
+
## 1. Priority Priority Matrix (WCAG 2.2 AA)
|
|
23
23
|
|
|
24
24
|
| Priority | Category | Critical Requirements |
|
|
25
25
|
| --- | --- | --- |
|
|
26
26
|
| **P1** | **Accessible Names** | Every icon button MUST have `aria-label` or `aria-labelledby`. Decorative icons MUST have `aria-hidden="true"`. |
|
|
27
27
|
| **P2** | **Keyboard Access** | All interactive controls MUST be reachable and operable via `Tab` / `Shift+Tab`, `Space`, `Enter`. NEVER use `<div>` or `<span>` as clickable elements without `role="button"`, `tabIndex={0}`, and key handlers. |
|
|
28
|
-
| **P3** | **Focus & Dialogs** | Modals/Dialogs MUST trap focus within the dialog container while open, return focus
|
|
29
|
-
| **P4** | **
|
|
30
|
-
| **P5** | **
|
|
28
|
+
| **P3** | **Focus & Dialogs (SC 2.4.11)** | Modals/Dialogs MUST trap focus within the dialog container while open, return focus on close, dismiss on `Escape`, and ensure focused items are **never fully obscured by sticky headers/footers**. |
|
|
29
|
+
| **P4** | **Focus Appearance (SC 2.4.13)** | Focus indicators MUST be clearly visible (`:focus-visible`), achieve at least **3:1 contrast** against adjacent background, and have a min **2px thickness**. |
|
|
30
|
+
| **P5** | **Target Size (SC 2.5.8)** | Interactive controls MUST measure at least **24x24 CSS pixels** (min **44x44px** recommended for mobile touch targets) or have sufficient non-intersecting spacing. |
|
|
31
|
+
| **P6** | **Color & Contrast** | Text MUST satisfy WCAG AA 4.5:1 ratio (3.0:1 for large text). Color alone MUST NOT be the only indicator of state or error. |
|
|
32
|
+
| **P7** | **Form Validation** | Inputs MUST have explicit `<label>` or `aria-labelledby`. Errors MUST use `aria-invalid="true"` and `aria-describedby` pointing to error text. |
|
|
31
33
|
|
|
32
34
|
---
|
|
33
35
|
|