tribunal-kit 4.0.1 → 4.3.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.
Files changed (196) hide show
  1. package/.agent/ARCHITECTURE.md +21 -14
  2. package/.agent/GEMINI.md +4 -2
  3. package/.agent/agents/api-architect.md +66 -0
  4. package/.agent/agents/db-latency-auditor.md +216 -0
  5. package/.agent/agents/precedence-reviewer.md +41 -4
  6. package/.agent/agents/resilience-reviewer.md +88 -0
  7. package/.agent/agents/schema-reviewer.md +67 -0
  8. package/.agent/agents/swarm-worker-contracts.md +5 -5
  9. package/.agent/agents/throughput-optimizer.md +299 -0
  10. package/.agent/agents/ui-ux-auditor.md +292 -0
  11. package/.agent/agents/vitals-reviewer.md +223 -0
  12. package/.agent/history/case-law/cases/case-0001.json +33 -0
  13. package/.agent/history/case-law/index.json +35 -0
  14. package/.agent/rules/GEMINI.md +28 -11
  15. package/.agent/scripts/__pycache__/_colors.cpython-311.pyc +0 -0
  16. package/.agent/scripts/__pycache__/_utils.cpython-311.pyc +0 -0
  17. package/.agent/scripts/__pycache__/case_law_manager.cpython-311.pyc +0 -0
  18. package/.agent/scripts/_colors.js +18 -0
  19. package/.agent/scripts/_utils.js +42 -0
  20. package/.agent/scripts/auto_preview.js +197 -0
  21. package/.agent/scripts/bundle_analyzer.js +290 -0
  22. package/.agent/scripts/case_law_manager.js +684 -0
  23. package/.agent/scripts/checklist.js +266 -0
  24. package/.agent/scripts/colors.js +17 -0
  25. package/.agent/scripts/compress_skills.js +141 -0
  26. package/.agent/scripts/consolidate_skills.js +149 -0
  27. package/.agent/scripts/context_broker.js +609 -0
  28. package/.agent/scripts/deep_compress.js +150 -0
  29. package/.agent/scripts/dependency_analyzer.js +272 -0
  30. package/.agent/scripts/inner_loop_validator.js +465 -0
  31. package/.agent/scripts/lint_runner.js +187 -0
  32. package/.agent/scripts/minify_context.js +100 -0
  33. package/.agent/scripts/patch_skills_meta.js +156 -0
  34. package/.agent/scripts/patch_skills_output.js +244 -0
  35. package/.agent/scripts/schema_validator.js +297 -0
  36. package/.agent/scripts/security_scan.js +303 -0
  37. package/.agent/scripts/session_manager.js +276 -0
  38. package/.agent/scripts/skill_evolution.js +644 -0
  39. package/.agent/scripts/skill_integrator.js +313 -0
  40. package/.agent/scripts/strengthen_skills.js +193 -0
  41. package/.agent/scripts/strip_tribunal.js +47 -0
  42. package/.agent/scripts/swarm_dispatcher.js +360 -0
  43. package/.agent/scripts/test_runner.js +193 -0
  44. package/.agent/scripts/utils.js +32 -0
  45. package/.agent/scripts/verify_all.js +256 -0
  46. package/.agent/skills/agent-organizer/SKILL.md +42 -0
  47. package/.agent/skills/agentic-patterns/SKILL.md +42 -0
  48. package/.agent/skills/ai-prompt-injection-defense/SKILL.md +42 -0
  49. package/.agent/skills/api-patterns/SKILL.md +42 -0
  50. package/.agent/skills/api-security-auditor/SKILL.md +42 -0
  51. package/.agent/skills/app-builder/SKILL.md +42 -0
  52. package/.agent/skills/app-builder/templates/SKILL.md +70 -0
  53. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +1 -1
  54. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +1 -1
  55. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +1 -1
  56. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +1 -1
  57. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +1 -1
  58. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +1 -1
  59. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +1 -1
  60. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +1 -1
  61. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +1 -1
  62. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +1 -1
  63. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +1 -1
  64. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +1 -1
  65. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +1 -1
  66. package/.agent/skills/appflow-wireframe/SKILL.md +42 -0
  67. package/.agent/skills/architecture/SKILL.md +42 -0
  68. package/.agent/skills/authentication-best-practices/SKILL.md +42 -0
  69. package/.agent/skills/bash-linux/SKILL.md +42 -0
  70. package/.agent/skills/behavioral-modes/SKILL.md +42 -0
  71. package/.agent/skills/brainstorming/SKILL.md +42 -0
  72. package/.agent/skills/building-native-ui/SKILL.md +42 -0
  73. package/.agent/skills/clean-code/SKILL.md +42 -0
  74. package/.agent/skills/code-review-checklist/SKILL.md +42 -0
  75. package/.agent/skills/config-validator/SKILL.md +42 -0
  76. package/.agent/skills/csharp-developer/SKILL.md +42 -0
  77. package/.agent/skills/data-validation-schemas/SKILL.md +320 -0
  78. package/.agent/skills/database-design/SKILL.md +42 -0
  79. package/.agent/skills/deployment-procedures/SKILL.md +42 -0
  80. package/.agent/skills/devops-engineer/SKILL.md +42 -0
  81. package/.agent/skills/devops-incident-responder/SKILL.md +42 -0
  82. package/.agent/skills/doc.md +1 -1
  83. package/.agent/skills/documentation-templates/SKILL.md +42 -0
  84. package/.agent/skills/edge-computing/SKILL.md +42 -0
  85. package/.agent/skills/error-resilience/SKILL.md +420 -0
  86. package/.agent/skills/extract-design-system/SKILL.md +42 -0
  87. package/.agent/skills/framer-motion-expert/SKILL.md +42 -1
  88. package/.agent/skills/frontend-design/SKILL.md +42 -0
  89. package/.agent/skills/game-design-expert/SKILL.md +42 -0
  90. package/.agent/skills/game-engineering-expert/SKILL.md +42 -0
  91. package/.agent/skills/geo-fundamentals/SKILL.md +42 -0
  92. package/.agent/skills/github-operations/SKILL.md +42 -0
  93. package/.agent/skills/gsap-core/SKILL.md +300 -0
  94. package/.agent/skills/gsap-frameworks/SKILL.md +199 -0
  95. package/.agent/skills/gsap-performance/SKILL.md +125 -0
  96. package/.agent/skills/gsap-plugins/SKILL.md +472 -0
  97. package/.agent/skills/gsap-react/SKILL.md +181 -0
  98. package/.agent/skills/gsap-scrolltrigger/SKILL.md +342 -0
  99. package/.agent/skills/gsap-timeline/SKILL.md +153 -0
  100. package/.agent/skills/gsap-utils/SKILL.md +330 -0
  101. package/.agent/skills/i18n-localization/SKILL.md +42 -0
  102. package/.agent/skills/intelligent-routing/SKILL.md +72 -1
  103. package/.agent/skills/lint-and-validate/SKILL.md +42 -0
  104. package/.agent/skills/llm-engineering/SKILL.md +42 -0
  105. package/.agent/skills/local-first/SKILL.md +42 -0
  106. package/.agent/skills/mcp-builder/SKILL.md +42 -0
  107. package/.agent/skills/mobile-design/SKILL.md +42 -0
  108. package/.agent/skills/monorepo-management/SKILL.md +326 -0
  109. package/.agent/skills/motion-engineering/SKILL.md +42 -0
  110. package/.agent/skills/nextjs-react-expert/SKILL.md +42 -0
  111. package/.agent/skills/nodejs-best-practices/SKILL.md +42 -0
  112. package/.agent/skills/observability/SKILL.md +42 -0
  113. package/.agent/skills/parallel-agents/SKILL.md +42 -0
  114. package/.agent/skills/performance-profiling/SKILL.md +42 -0
  115. package/.agent/skills/plan-writing/SKILL.md +42 -0
  116. package/.agent/skills/platform-engineer/SKILL.md +42 -0
  117. package/.agent/skills/playwright-best-practices/SKILL.md +42 -0
  118. package/.agent/skills/powershell-windows/SKILL.md +42 -0
  119. package/.agent/skills/project-idioms/SKILL.md +42 -0
  120. package/.agent/skills/python-patterns/SKILL.md +42 -0
  121. package/.agent/skills/python-pro/SKILL.md +42 -0
  122. package/.agent/skills/react-specialist/SKILL.md +42 -0
  123. package/.agent/skills/readme-builder/SKILL.md +42 -0
  124. package/.agent/skills/realtime-patterns/SKILL.md +42 -0
  125. package/.agent/skills/red-team-tactics/SKILL.md +42 -0
  126. package/.agent/skills/rust-pro/SKILL.md +42 -0
  127. package/.agent/skills/seo-fundamentals/SKILL.md +42 -0
  128. package/.agent/skills/server-management/SKILL.md +42 -0
  129. package/.agent/skills/shadcn-ui-expert/SKILL.md +42 -0
  130. package/.agent/skills/skill-creator/SKILL.md +42 -0
  131. package/.agent/skills/sql-pro/SKILL.md +42 -0
  132. package/.agent/skills/supabase-postgres-best-practices/SKILL.md +42 -0
  133. package/.agent/skills/swiftui-expert/SKILL.md +42 -0
  134. package/.agent/skills/systematic-debugging/SKILL.md +42 -0
  135. package/.agent/skills/tailwind-patterns/SKILL.md +42 -0
  136. package/.agent/skills/tdd-workflow/SKILL.md +42 -0
  137. package/.agent/skills/test-result-analyzer/SKILL.md +42 -0
  138. package/.agent/skills/testing-patterns/SKILL.md +42 -0
  139. package/.agent/skills/trend-researcher/SKILL.md +42 -0
  140. package/.agent/skills/typescript-advanced/SKILL.md +327 -0
  141. package/.agent/skills/ui-ux-pro-max/SKILL.md +42 -0
  142. package/.agent/skills/ui-ux-researcher/SKILL.md +42 -0
  143. package/.agent/skills/vue-expert/SKILL.md +42 -0
  144. package/.agent/skills/vulnerability-scanner/SKILL.md +42 -0
  145. package/.agent/skills/web-accessibility-auditor/SKILL.md +42 -0
  146. package/.agent/skills/web-design-guidelines/SKILL.md +42 -0
  147. package/.agent/skills/webapp-testing/SKILL.md +42 -0
  148. package/.agent/skills/whimsy-injector/SKILL.md +42 -0
  149. package/.agent/skills/workflow-optimizer/SKILL.md +42 -0
  150. package/.agent/workflows/audit.md +6 -6
  151. package/.agent/workflows/deploy.md +1 -1
  152. package/.agent/workflows/generate.md +23 -6
  153. package/.agent/workflows/session.md +5 -5
  154. package/.agent/workflows/swarm.md +2 -2
  155. package/.agent/workflows/tribunal-backend.md +13 -2
  156. package/.agent/workflows/tribunal-full.md +15 -8
  157. package/.agent/workflows/tribunal-speed.md +183 -0
  158. package/README.md +64 -8
  159. package/bin/tribunal-kit.js +281 -41
  160. package/package.json +9 -6
  161. package/scripts/changelog.js +167 -0
  162. package/scripts/sync-version.js +81 -0
  163. package/.agent/scripts/__pycache__/auto_preview.cpython-311.pyc +0 -0
  164. package/.agent/scripts/__pycache__/bundle_analyzer.cpython-311.pyc +0 -0
  165. package/.agent/scripts/__pycache__/checklist.cpython-311.pyc +0 -0
  166. package/.agent/scripts/__pycache__/dependency_analyzer.cpython-311.pyc +0 -0
  167. package/.agent/scripts/__pycache__/security_scan.cpython-311.pyc +0 -0
  168. package/.agent/scripts/__pycache__/session_manager.cpython-311.pyc +0 -0
  169. package/.agent/scripts/__pycache__/skill_integrator.cpython-311.pyc +0 -0
  170. package/.agent/scripts/__pycache__/swarm_dispatcher.cpython-311.pyc +0 -0
  171. package/.agent/scripts/__pycache__/test_runner.cpython-311.pyc +0 -0
  172. package/.agent/scripts/__pycache__/verify_all.cpython-311.pyc +0 -0
  173. package/.agent/scripts/auto_preview.py +0 -180
  174. package/.agent/scripts/bundle_analyzer.py +0 -259
  175. package/.agent/scripts/case_law_manager.py +0 -525
  176. package/.agent/scripts/checklist.py +0 -209
  177. package/.agent/scripts/compress_skills.py +0 -167
  178. package/.agent/scripts/consolidate_skills.py +0 -173
  179. package/.agent/scripts/deep_compress.py +0 -202
  180. package/.agent/scripts/dependency_analyzer.py +0 -247
  181. package/.agent/scripts/lint_runner.py +0 -188
  182. package/.agent/scripts/minify_context.py +0 -80
  183. package/.agent/scripts/patch_skills_meta.py +0 -177
  184. package/.agent/scripts/patch_skills_output.py +0 -285
  185. package/.agent/scripts/schema_validator.py +0 -279
  186. package/.agent/scripts/security_scan.py +0 -224
  187. package/.agent/scripts/session_manager.py +0 -261
  188. package/.agent/scripts/skill_evolution.py +0 -563
  189. package/.agent/scripts/skill_integrator.py +0 -234
  190. package/.agent/scripts/strengthen_skills.py +0 -220
  191. package/.agent/scripts/strip_tribunal.py +0 -41
  192. package/.agent/scripts/swarm_dispatcher.py +0 -350
  193. package/.agent/scripts/test_runner.py +0 -192
  194. package/.agent/scripts/test_swarm_dispatcher.py +0 -163
  195. package/.agent/scripts/verify_all.py +0 -195
  196. package/.agent/skills/gsap-expert/SKILL.md +0 -194
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * changelog.js — Auto-generate CHANGELOG from git history
4
+ *
5
+ * Categorizes commits by conventional commit type:
6
+ * feat: → ✨ Features
7
+ * fix: → 🐛 Bug Fixes
8
+ * perf: → ⚡ Performance
9
+ * docs: → 📝 Documentation
10
+ * test: → ✅ Tests
11
+ * refactor: → ♻️ Refactors
12
+ * chore: → 🔧 Chores
13
+ * BREAKING: → 💥 Breaking Changes
14
+ *
15
+ * Usage:
16
+ * node scripts/changelog.js → Generate full changelog
17
+ * node scripts/changelog.js --preview → Preview unreleased changes
18
+ * node scripts/changelog.js --since v4.1.0 → Changes since a specific tag
19
+ */
20
+
21
+ 'use strict';
22
+
23
+ const { execSync } = require('child_process');
24
+ const fs = require('fs');
25
+ const path = require('path');
26
+
27
+ const PKG = require(path.resolve(__dirname, '..', 'package.json'));
28
+ const CHANGELOG_PATH = path.resolve(__dirname, '..', 'CHANGELOG.md');
29
+
30
+ // ── Commit Categories ────────────────────────────────────
31
+ const CATEGORIES = {
32
+ feat: { emoji: '✨', title: 'Features' },
33
+ fix: { emoji: '🐛', title: 'Bug Fixes' },
34
+ perf: { emoji: '⚡', title: 'Performance' },
35
+ docs: { emoji: '📝', title: 'Documentation' },
36
+ test: { emoji: '✅', title: 'Tests' },
37
+ refactor: { emoji: '♻️', title: 'Refactors' },
38
+ chore: { emoji: '🔧', title: 'Chores' },
39
+ ci: { emoji: '🏗️', title: 'CI/CD' },
40
+ style: { emoji: '🎨', title: 'Style' },
41
+ breaking: { emoji: '💥', title: 'Breaking Changes' },
42
+ };
43
+
44
+ // ── Git Helpers ──────────────────────────────────────────
45
+ function git(cmd) {
46
+ try {
47
+ return execSync(`git ${cmd}`, { encoding: 'utf8', timeout: 10000 }).trim();
48
+ } catch {
49
+ return '';
50
+ }
51
+ }
52
+
53
+ function getLatestTag() {
54
+ return git('describe --tags --abbrev=0 2>nul') || git('describe --tags --abbrev=0 2>/dev/null') || '';
55
+ }
56
+
57
+ function getCommits(since) {
58
+ const range = since ? `${since}..HEAD` : 'HEAD';
59
+ const format = '--format="%H||%s||%an||%ai"';
60
+ const raw = git(`log ${range} ${format} --no-merges`);
61
+ if (!raw) return [];
62
+
63
+ return raw.split('\n').filter(Boolean).map(line => {
64
+ const [hash, subject, author, date] = line.split('||');
65
+ return { hash: hash?.slice(0, 7), subject, author, date: date?.slice(0, 10) };
66
+ });
67
+ }
68
+
69
+ function categorize(subject) {
70
+ const lower = subject.toLowerCase();
71
+
72
+ // Check for BREAKING CHANGE
73
+ if (lower.includes('breaking') || lower.includes('!:')) {
74
+ return 'breaking';
75
+ }
76
+
77
+ // Match conventional commit prefix
78
+ const match = subject.match(/^(\w+)(?:\(.+?\))?:\s*/);
79
+ if (match) {
80
+ const type = match[1].toLowerCase();
81
+ if (CATEGORIES[type]) return type;
82
+ }
83
+
84
+ // Heuristic fallback
85
+ if (lower.includes('fix') || lower.includes('bug')) return 'fix';
86
+ if (lower.includes('add') || lower.includes('new') || lower.includes('feat')) return 'feat';
87
+ if (lower.includes('doc') || lower.includes('readme')) return 'docs';
88
+ if (lower.includes('test')) return 'test';
89
+ if (lower.includes('refactor') || lower.includes('clean')) return 'refactor';
90
+ if (lower.includes('perf') || lower.includes('optim')) return 'perf';
91
+ if (lower.includes('ci') || lower.includes('workflow')) return 'ci';
92
+
93
+ return 'chore';
94
+ }
95
+
96
+ // ── Changelog Generation ─────────────────────────────────
97
+ function generateChangelog(commits, version, date) {
98
+ const grouped = {};
99
+ for (const commit of commits) {
100
+ const cat = categorize(commit.subject);
101
+ if (!grouped[cat]) grouped[cat] = [];
102
+ // Strip conventional prefix for cleaner display
103
+ const clean = commit.subject.replace(/^\w+(\(.+?\))?:\s*/, '');
104
+ grouped[cat].push({ ...commit, clean });
105
+ }
106
+
107
+ let md = `## [${version}] — ${date}\n\n`;
108
+
109
+ // Breaking changes first
110
+ const order = ['breaking', 'feat', 'fix', 'perf', 'refactor', 'docs', 'test', 'ci', 'style', 'chore'];
111
+ for (const cat of order) {
112
+ if (!grouped[cat] || grouped[cat].length === 0) continue;
113
+ const { emoji, title } = CATEGORIES[cat];
114
+ md += `### ${emoji} ${title}\n\n`;
115
+ for (const c of grouped[cat]) {
116
+ md += `- ${c.clean} (\`${c.hash}\`)\n`;
117
+ }
118
+ md += '\n';
119
+ }
120
+
121
+ return md;
122
+ }
123
+
124
+ // ── Main ─────────────────────────────────────────────────
125
+ function main() {
126
+ const args = process.argv.slice(2);
127
+ const isPreview = args.includes('--preview');
128
+ const sinceIdx = args.indexOf('--since');
129
+ const sinceTag = sinceIdx !== -1 ? args[sinceIdx + 1] : null;
130
+
131
+ const since = sinceTag || getLatestTag();
132
+ const commits = getCommits(since);
133
+
134
+ if (commits.length === 0) {
135
+ console.log(' ℹ️ No new commits found since', since || 'beginning');
136
+ process.exit(0);
137
+ }
138
+
139
+ const today = new Date().toISOString().slice(0, 10);
140
+ const version = isPreview ? 'Unreleased' : PKG.version;
141
+
142
+ const changelog = generateChangelog(commits, version, today);
143
+
144
+ if (isPreview) {
145
+ console.log('\n 📋 Changelog Preview\n ' + '─'.repeat(40) + '\n');
146
+ console.log(changelog);
147
+ console.log(` 📊 ${commits.length} commits since ${since || 'initial commit'}`);
148
+ return;
149
+ }
150
+
151
+ // Write or prepend to CHANGELOG.md
152
+ const header = `# Changelog\n\nAll notable changes to Tribunal Kit are documented here.\nFormat follows [Keep a Changelog](https://keepachangelog.com/).\n\n`;
153
+
154
+ let existing = '';
155
+ if (fs.existsSync(CHANGELOG_PATH)) {
156
+ existing = fs.readFileSync(CHANGELOG_PATH, 'utf8');
157
+ // Remove existing header
158
+ existing = existing.replace(/^# Changelog[\s\S]*?(?=## )/, '');
159
+ }
160
+
161
+ const full = header + changelog + existing;
162
+ fs.writeFileSync(CHANGELOG_PATH, full, 'utf8');
163
+
164
+ console.log(` ✔ CHANGELOG.md updated — v${version} (${commits.length} commits)`);
165
+ }
166
+
167
+ main();
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * sync-version.js — Version Sync for Tribunal Kit
4
+ *
5
+ * Reads the version and counts from package.json and the .agent/ directory,
6
+ * then updates all stale references across documentation files.
7
+ *
8
+ * Run manually or as a preversion npm script:
9
+ * node scripts/sync-version.js
10
+ */
11
+
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+
15
+ const ROOT = path.resolve(__dirname, '..');
16
+ const PKG = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8'));
17
+
18
+ // Count actual installed items
19
+ function countItems(dir) {
20
+ const fullPath = path.join(ROOT, '.agent', dir);
21
+ if (!fs.existsSync(fullPath)) return '?';
22
+ return fs.readdirSync(fullPath).filter(f => !f.startsWith('.')).length;
23
+ }
24
+
25
+ const version = PKG.version;
26
+ const agents = countItems('agents');
27
+ const skills = countItems('skills');
28
+ const workflows = countItems('workflows');
29
+ const scripts = countItems('scripts');
30
+
31
+ console.log(`\n 📊 Tribunal Kit v${version} — Actual Counts`);
32
+ console.log(` ──────────────────────────────────────`);
33
+ console.log(` Agents: ${agents}`);
34
+ console.log(` Skills: ${skills}`);
35
+ console.log(` Workflows: ${workflows}`);
36
+ console.log(` Scripts: ${scripts}`);
37
+ console.log();
38
+
39
+ // Files to check for stale numbers
40
+ const FILES_TO_CHECK = [
41
+ 'README.md',
42
+ 'AGENT_FLOW.md',
43
+ '.agent/ARCHITECTURE.md',
44
+ ];
45
+
46
+ let staleFound = 0;
47
+
48
+ for (const relPath of FILES_TO_CHECK) {
49
+ const filePath = path.join(ROOT, relPath);
50
+ if (!fs.existsSync(filePath)) continue;
51
+
52
+ const content = fs.readFileSync(filePath, 'utf8');
53
+
54
+ // Check for common stale patterns
55
+ const checks = [
56
+ { regex: /(\d+)\s*(specialist\s+)?agents/gi, expected: agents, label: 'agents' },
57
+ { regex: /(\d+)\s*skill\s*modules/gi, expected: skills, label: 'skills' },
58
+ { regex: /(\d+)\s*slash\s*command/gi, expected: workflows, label: 'workflows' },
59
+ ];
60
+
61
+ for (const check of checks) {
62
+ let match;
63
+ while ((match = check.regex.exec(content)) !== null) {
64
+ const found = parseInt(match[1]);
65
+ if (found !== check.expected && found > 5) { // ignore tiny numbers
66
+ staleFound++;
67
+ const line = content.substring(0, match.index).split('\n').length;
68
+ console.log(` ⚠️ ${relPath}:${line} — says ${found} ${check.label}, actual is ${check.expected}`);
69
+ }
70
+ }
71
+ }
72
+ }
73
+
74
+ if (staleFound === 0) {
75
+ console.log(` ✅ All counts are in sync across ${FILES_TO_CHECK.length} files.`);
76
+ } else {
77
+ console.log(`\n ❌ Found ${staleFound} stale reference(s). Update manually or run the sync tool.`);
78
+ process.exit(1);
79
+ }
80
+
81
+ console.log();
@@ -1,180 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- auto_preview.py — Start, stop, or check a local development server.
4
-
5
- Usage:
6
- python .agent/scripts/auto_preview.py start
7
- python .agent/scripts/auto_preview.py stop
8
- python .agent/scripts/auto_preview.py status
9
- python .agent/scripts/auto_preview.py restart
10
- """
11
-
12
- import os
13
- import sys
14
- import json
15
- import time
16
- import signal
17
- import socket
18
- import subprocess
19
- from pathlib import Path
20
-
21
- PID_FILE = ".preview.pid"
22
- DEFAULT_PORT = 3000
23
- TIMEOUT_SECONDS = 30
24
-
25
- GREEN = "\033[92m"
26
- RED = "\033[91m"
27
- YELLOW = "\033[93m"
28
- BOLD = "\033[1m"
29
- RESET = "\033[0m"
30
-
31
-
32
- def find_start_command() -> tuple[list[str], bool]:
33
- """
34
- Read package.json for a dev/start script.
35
- Returns (command, found) — found=False if no package.json or no scripts.
36
- """
37
- pkg_path = Path("package.json")
38
- if not pkg_path.exists():
39
- return [], False
40
-
41
- try:
42
- with open(pkg_path) as f:
43
- pkg = json.load(f)
44
- scripts = pkg.get("scripts", {})
45
- if "dev" in scripts:
46
- return ["npm", "run", "dev"], True
47
- elif "start" in scripts:
48
- return ["npm", "run", "start"], True
49
- else:
50
- return [], False
51
- except (json.JSONDecodeError, IOError):
52
- return [], False
53
-
54
-
55
- def get_port_from_env() -> int:
56
- env_path = Path(".env")
57
- if env_path.exists():
58
- try:
59
- with open(env_path) as f:
60
- for line in f:
61
- if line.startswith("PORT="):
62
- return int(line.split("=")[1].strip())
63
- except (ValueError, IOError):
64
- pass
65
- return DEFAULT_PORT
66
-
67
-
68
- def is_port_open(port: int) -> bool:
69
- with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
70
- s.settimeout(1)
71
- return s.connect_ex(("localhost", port)) == 0
72
-
73
-
74
- def read_pid() -> int | None:
75
- pid_file = Path(PID_FILE)
76
- if pid_file.exists():
77
- try:
78
- return int(pid_file.read_text().strip())
79
- except (ValueError, IOError):
80
- pass
81
- return None
82
-
83
-
84
- def write_pid(pid: int) -> None:
85
- Path(PID_FILE).write_text(str(pid))
86
-
87
-
88
- def clear_pid() -> None:
89
- pid_file = Path(PID_FILE)
90
- if pid_file.exists():
91
- pid_file.unlink()
92
-
93
-
94
- def start_server() -> None:
95
- port = get_port_from_env()
96
-
97
- if is_port_open(port):
98
- print(f"{YELLOW}⚠️ Port {port} is already in use.{RESET}")
99
- pid = read_pid()
100
- if pid:
101
- print(f" Known PID: {pid}")
102
- return
103
-
104
- cmd, found = find_start_command()
105
- if not found:
106
- print(f"{RED}❌ No dev/start script found.{RESET}")
107
- print(f" This project has no package.json, or its package.json has no 'dev' or 'start' script.")
108
- print(f" Add a script to package.json, or start your server manually.")
109
- return
110
-
111
- print(f"{BOLD}Starting: {' '.join(cmd)}{RESET}")
112
- proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
113
- write_pid(proc.pid)
114
-
115
- print(f"Waiting for port {port}…", end="", flush=True)
116
- for _ in range(TIMEOUT_SECONDS):
117
- if is_port_open(port):
118
- print()
119
- print(f"\n{GREEN}✅ Server started{RESET}")
120
- print(f" URL: http://localhost:{port}")
121
- print(f" PID: {proc.pid}")
122
- print(f" Command: {' '.join(cmd)}")
123
- print(f"\nStop with: python .agent/scripts/auto_preview.py stop")
124
- return
125
- print(".", end="", flush=True)
126
- time.sleep(1)
127
-
128
- print()
129
- print(f"{RED}❌ Server did not start within {TIMEOUT_SECONDS}s{RESET}")
130
- proc.terminate()
131
- clear_pid()
132
-
133
-
134
- def stop_server() -> None:
135
- pid = read_pid()
136
- if not pid:
137
- print(f"{YELLOW}⚠️ No stored server PID found{RESET}")
138
- return
139
- try:
140
- os.kill(pid, signal.SIGTERM)
141
- time.sleep(1)
142
- print(f"{GREEN}✅ Server stopped (PID {pid}){RESET}")
143
- except ProcessLookupError:
144
- print(f"{YELLOW}Process {pid} was not running{RESET}")
145
- finally:
146
- clear_pid()
147
-
148
-
149
- def show_status() -> None:
150
- port = get_port_from_env()
151
- pid = read_pid()
152
- if is_port_open(port):
153
- print(f"{GREEN}🟢 Running — http://localhost:{port}{RESET}")
154
- if pid:
155
- print(f" PID: {pid}")
156
- else:
157
- print(f"{RED}🔴 Not running on port {port}{RESET}")
158
-
159
-
160
- def main() -> None:
161
- actions = {"start", "stop", "status", "restart"}
162
- if len(sys.argv) < 2 or sys.argv[1] not in actions:
163
- print(f"Usage: auto_preview.py [start|stop|status|restart]")
164
- sys.exit(1)
165
-
166
- action = sys.argv[1]
167
- if action == "start":
168
- start_server()
169
- elif action == "stop":
170
- stop_server()
171
- elif action == "status":
172
- show_status()
173
- elif action == "restart":
174
- stop_server()
175
- time.sleep(1)
176
- start_server()
177
-
178
-
179
- if __name__ == "__main__":
180
- main()