chati-dev 4.2.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 (222) hide show
  1. package/README.md +80 -53
  2. package/bin/chati.js +150 -5
  3. package/framework/agents/build/dev.md +509 -76
  4. package/framework/agents/deploy/devops.md +40 -25
  5. package/framework/agents/discover/brief.md +156 -22
  6. package/framework/agents/discover/brownfield-wu.md +24 -14
  7. package/framework/agents/discover/greenfield-wu.md +100 -14
  8. package/framework/agents/plan/architect-data-engineer.md +6 -6
  9. package/framework/agents/plan/architect-system.md +46 -12
  10. package/framework/agents/plan/architect.md +40 -20
  11. package/framework/agents/plan/detail.md +36 -24
  12. package/framework/agents/plan/phases.md +36 -26
  13. package/framework/agents/plan/tasks.md +114 -33
  14. package/framework/agents/plan/ux-brand-architect.md +240 -8
  15. package/framework/agents/plan/ux-component-engineer.md +28 -13
  16. package/framework/agents/plan/ux-researcher.md +7 -6
  17. package/framework/agents/plan/ux.md +55 -22
  18. package/framework/agents/quality/qa-implementation.md +143 -74
  19. package/framework/agents/quality/qa-planning.md +115 -42
  20. package/framework/agents/quality/qa-visual.md +439 -0
  21. package/framework/agents/shared/visualizer.md +128 -0
  22. package/framework/config.yaml +8 -7
  23. package/framework/constitution.md +127 -43
  24. package/framework/context/governance.md +12 -7
  25. package/framework/context/quality.md +6 -5
  26. package/framework/context/root.md +6 -6
  27. package/framework/data/entity-registry.yaml +377 -4
  28. package/framework/data/model-limits.json +19 -0
  29. package/framework/domains/agents/qa-visual.yaml +74 -0
  30. package/framework/domains/constitution.yaml +46 -2
  31. package/framework/domains/workflows/greenfield-fullstack.yaml +2 -2
  32. package/framework/hooks/advance-trigger.js +131 -0
  33. package/framework/hooks/brief-validator.js +83 -0
  34. package/framework/hooks/constitution-guard.js +91 -36
  35. package/framework/hooks/license-guard.js +129 -190
  36. package/framework/hooks/mode-governance.js +68 -16
  37. package/framework/hooks/model-governance.js +19 -8
  38. package/framework/hooks/package.json +3 -0
  39. package/framework/hooks/post-dev.js +207 -0
  40. package/framework/hooks/prism-engine.js +288 -105
  41. package/framework/hooks/read-protection.js +37 -9
  42. package/framework/hooks/reasoning-escalator.js +371 -0
  43. package/framework/hooks/reference-trigger.js +117 -0
  44. package/framework/hooks/session-digest.js +94 -20
  45. package/framework/hooks/settings.json +32 -1
  46. package/framework/hooks/style-guard.js +52 -13
  47. package/framework/hooks/team-quality-gate.js +58 -25
  48. package/framework/hooks/undercover-guard.js +34 -13
  49. package/framework/i18n/en.yaml +3 -3
  50. package/framework/i18n/es.yaml +3 -3
  51. package/framework/i18n/fr.yaml +3 -3
  52. package/framework/i18n/pt.yaml +3 -3
  53. package/framework/intelligence/context-engine.md +4 -5
  54. package/framework/intelligence/decision-engine.md +1 -1
  55. package/framework/intelligence/hooks-performance.md +3 -3
  56. package/framework/migrations/v1.0-to-v1.1.yaml +1 -1
  57. package/framework/migrations/v1.4-to-v2.0.yaml +11 -11
  58. package/framework/migrations/v4.0-to-v4.1.yaml +2 -2
  59. package/framework/migrations/v4.2-to-v4.3.yaml +29 -0
  60. package/framework/orchestrator/chati-router.js +387 -0
  61. package/framework/orchestrator/chati-update.md +40 -40
  62. package/framework/orchestrator/chati.md +318 -115
  63. package/framework/scaffold/motion-premium/README.md +89 -0
  64. package/framework/scaffold/motion-premium/app/globals.css.template +400 -0
  65. package/framework/scaffold/motion-premium/app/layout.tsx.template +110 -0
  66. package/framework/scaffold/motion-premium/components/animation/BackgroundCrossfadeProvider.tsx.template +170 -0
  67. package/framework/scaffold/motion-premium/components/animation/LenisProvider.tsx.template +49 -0
  68. package/framework/scaffold/motion-premium/components/animation/PageTransitionWrapper.tsx.template +83 -0
  69. package/framework/scaffold/motion-premium/components/animation/Preloader.tsx.template +171 -0
  70. package/framework/scaffold/motion-premium/components/ui/Container.tsx.template +69 -0
  71. package/framework/scaffold/motion-premium/components/ui/PageSection.tsx.template +74 -0
  72. package/framework/scaffold/motion-premium/lib/animations/gsap.ts.template +112 -0
  73. package/framework/scaffold/motion-premium/lib/animations/refreshCoordinator.ts.template +75 -0
  74. package/framework/scaffold/motion-premium/lib/animations/tokens.ts.template +119 -0
  75. package/framework/scaffold/motion-premium/lib/animations/useGsapContext.ts.template +92 -0
  76. package/framework/scaffold/motion-premium/lib/animations/useScrollSnapStepper.ts.template +265 -0
  77. package/framework/scaffold/motion-premium/lib/animations/useSmoothScroll.ts.template +67 -0
  78. package/framework/scaffold/motion-premium/lib/brand.ts.template +43 -0
  79. package/framework/scaffold/motion-premium/scaffold.yaml +174 -0
  80. package/framework/scaffold/motion-premium-3d/README.md +80 -0
  81. package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/ScrollDemoCanvas.tsx.template +81 -0
  82. package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/ScrollDemoClient.tsx.template +75 -0
  83. package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/page.tsx.template +26 -0
  84. package/framework/scaffold/motion-premium-3d/components/3d/CameraRig.tsx.template +100 -0
  85. package/framework/scaffold/motion-premium-3d/components/3d/CanvasProvider.tsx.template +85 -0
  86. package/framework/scaffold/motion-premium-3d/components/3d/InvalidateOnScroll.tsx.template +51 -0
  87. package/framework/scaffold/motion-premium-3d/components/3d/MeshCrossfade.tsx.template +79 -0
  88. package/framework/scaffold/motion-premium-3d/components/3d/ScrollCrossfade.tsx.template +88 -0
  89. package/framework/scaffold/motion-premium-3d/components/3d/ScrollScene.tsx.template +121 -0
  90. package/framework/scaffold/motion-premium-3d/components/webgl/SceneFallback.tsx.template +65 -0
  91. package/framework/scaffold/motion-premium-3d/components/webgl/WebGLContext.tsx.template +68 -0
  92. package/framework/scaffold/motion-premium-3d/lib/webgl/detect.ts.template +69 -0
  93. package/framework/scaffold/motion-premium-3d/scaffold.yaml +133 -0
  94. package/framework/schemas/session.schema.json +109 -21
  95. package/framework/scripts/reference-capture.js +430 -0
  96. package/framework/scripts/visual-qa.js +674 -0
  97. package/framework/tasks/orchestrator-handoff.md +1 -1
  98. package/framework/tasks/orchestrator-resume.md +1 -1
  99. package/framework/tasks/orchestrator-route.md +1 -1
  100. package/framework/tasks/orchestrator-status.md +3 -3
  101. package/framework/tasks/qa-planning-gate-define.md +1 -1
  102. package/framework/templates/brandbook-html-tmpl.md +1 -1
  103. package/framework/templates/brandbook-tmpl.yaml +1 -1
  104. package/framework/templates/component-spec-tmpl.yaml +1 -1
  105. package/framework/templates/design-token-tmpl.yaml +1 -1
  106. package/framework/templates/icon-system-tmpl.yaml +1 -1
  107. package/framework/templates/team-planning-tasks.yaml +6 -5
  108. package/framework/workflows/brownfield-discovery.yaml +2 -2
  109. package/framework/workflows/brownfield-fullstack.yaml +15 -11
  110. package/framework/workflows/brownfield-service.yaml +14 -10
  111. package/framework/workflows/brownfield-ui.yaml +15 -11
  112. package/framework/workflows/greenfield-fullstack.yaml +16 -13
  113. package/framework/workflows/quick-flow.yaml +3 -3
  114. package/framework/workflows/standard-flow.yaml +12 -9
  115. package/package.json +10 -5
  116. package/src/autonomy/autonomous-gate.js +1 -0
  117. package/src/autonomy/build-state.js +1 -2
  118. package/src/autonomy/progress-reporter.js +1 -1
  119. package/src/config/agent-customizer.js +11 -3
  120. package/src/config/claude-settings-generator.js +226 -0
  121. package/src/config/context-file-generator.js +41 -21
  122. package/src/config/framework-adapter.js +1 -0
  123. package/src/config/gemini-hooks-generator.js +76 -6
  124. package/src/config/mcp-configs.js +1 -0
  125. package/src/context/layers/l1-global.js +2 -1
  126. package/src/dashboard/data-reader.js +4 -3
  127. package/src/dashboard/layout.js +2 -1
  128. package/src/decision/analyzer.js +6 -30
  129. package/src/decision/engine.js +4 -28
  130. package/src/decision/registry-healer.js +3 -2
  131. package/src/decision/registry-updater.js +23 -14
  132. package/src/extensions/loader.js +2 -8
  133. package/src/gates/g1-planning-complete.js +2 -1
  134. package/src/gates/g2-qa-planning.js +2 -1
  135. package/src/gates/g3-implementation.js +2 -1
  136. package/src/gates/g4-qa-implementation.js +3 -2
  137. package/src/gates/g5-deploy-ready.js +2 -1
  138. package/src/health/engine.js +4 -3
  139. package/src/installer/core.js +557 -81
  140. package/src/installer/preflight.js +131 -0
  141. package/src/installer/provider-overlay.js +3 -3
  142. package/src/installer/scaffold-applier.js +358 -0
  143. package/src/installer/templates.js +52 -31
  144. package/src/installer/validator.js +17 -12
  145. package/src/intelligence/registry-manager.js +22 -29
  146. package/src/intelligence/timeline.js +11 -6
  147. package/src/license/commands.js +1 -1
  148. package/src/license/wait.js +102 -0
  149. package/src/memory/agent-memory.js +81 -0
  150. package/src/memory/dream.js +32 -1
  151. package/src/merger/replace-merger.js +28 -15
  152. package/src/orchestrator/agent-selector.js +2 -1
  153. package/src/orchestrator/cli.js +1908 -80
  154. package/src/orchestrator/doctor.js +270 -0
  155. package/src/orchestrator/handoff-engine.js +4 -3
  156. package/src/orchestrator/index.js +2 -0
  157. package/src/orchestrator/pipeline-manager.js +306 -15
  158. package/src/orchestrator/session-manager.js +331 -6
  159. package/src/tasks/handoff.js +3 -2
  160. package/src/telemetry/config.js +4 -3
  161. package/src/telemetry/schema.js +1 -0
  162. package/src/terminal/collector.js +3 -2
  163. package/src/terminal/index.js +1 -2
  164. package/src/terminal/isolation.js +52 -18
  165. package/src/terminal/prompt-builder.js +42 -25
  166. package/src/terminal/run-parallel.js +1 -1
  167. package/src/terminal/run-team.js +3 -3
  168. package/src/terminal/team-task-list.js +43 -4
  169. package/src/upgrade/backup.js +3 -2
  170. package/src/upgrade/checker.js +3 -2
  171. package/src/upgrade/migrator.js +65 -7
  172. package/src/upgrade/tracked-files-detector.js +86 -0
  173. package/src/upgrade/user-messages.js +94 -0
  174. package/src/utils/config-parser.js +2 -1
  175. package/src/utils/feature-flags.js +2 -1
  176. package/src/utils/flatten-entities.js +69 -0
  177. package/src/utils/framework-dir.js +16 -0
  178. package/src/utils/model-id.js +85 -0
  179. package/src/utils/provider-limits.js +84 -23
  180. package/src/utils/schema-validator.js +1 -1
  181. package/src/wizard/i18n.js +5 -4
  182. package/src/wizard/index.js +14 -0
  183. package/assets/logo - c/303/263pia.png +0 -0
  184. package/assets/logo.svg +0 -42
  185. package/assets/logo2.png +0 -0
  186. package/assets/social-preview.png +0 -0
  187. package/scripts/bundle-framework.js +0 -69
  188. package/scripts/changelog-generator.js +0 -222
  189. package/scripts/codebase-mapper.js +0 -728
  190. package/scripts/commit-message-generator.js +0 -167
  191. package/scripts/coverage-analyzer.js +0 -260
  192. package/scripts/dependency-analyzer.js +0 -280
  193. package/scripts/doctor/checks/agents.js +0 -77
  194. package/scripts/doctor/checks/constitution.js +0 -41
  195. package/scripts/doctor/checks/domain-alignment.js +0 -58
  196. package/scripts/doctor/checks/prism-layers.js +0 -84
  197. package/scripts/doctor/checks/registry.js +0 -55
  198. package/scripts/doctor/checks/schemas.js +0 -61
  199. package/scripts/doctor/fixes/reference-fix.js +0 -100
  200. package/scripts/doctor/fixes/registry-fix.js +0 -56
  201. package/scripts/doctor/index.js +0 -212
  202. package/scripts/framework-analyzer.js +0 -308
  203. package/scripts/generate-constitution-domain.js +0 -253
  204. package/scripts/generate-signing-key.js +0 -33
  205. package/scripts/health-check.js +0 -481
  206. package/scripts/ide-sync.js +0 -326
  207. package/scripts/performance-analyzer.js +0 -325
  208. package/scripts/plan-tracker.js +0 -278
  209. package/scripts/populate-entity-registry.js +0 -481
  210. package/scripts/pr-review.js +0 -317
  211. package/scripts/rollback-manager.js +0 -310
  212. package/scripts/semantic-lint.js +0 -328
  213. package/scripts/sign-manifest.js +0 -53
  214. package/scripts/stuck-detector.js +0 -343
  215. package/scripts/test-quality-assessment.js +0 -257
  216. package/scripts/validate-agents.js +0 -368
  217. package/scripts/validate-package.js +0 -367
  218. package/scripts/validate-tasks.js +0 -465
  219. package/src/autonomy/worktree-manager.js +0 -250
  220. package/src/intelligence/decision-engine.js +0 -256
  221. package/src/intelligence/document-sharder.js +0 -221
  222. package/src/intelligence/elicitation.js +0 -265
@@ -1,253 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Generate Constitution Domain — Extracts governance rules from constitution.md
5
- * and generates a structured YAML domain file.
6
- *
7
- * Exports:
8
- * generateConstitutionDomain(frameworkDir) → writes domains/constitution.yaml
9
- */
10
-
11
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
12
- import { join } from 'path';
13
- import yaml from 'js-yaml';
14
-
15
- /**
16
- * Map Roman numerals to integers.
17
- * @param {string} roman - Roman numeral string.
18
- * @returns {number} Integer value.
19
- */
20
- function romanToInt(roman) {
21
- const values = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 };
22
- let result = 0;
23
- for (let i = 0; i < roman.length; i++) {
24
- const current = values[roman[i]] || 0;
25
- const next = values[roman[i + 1]] || 0;
26
- result += current < next ? -current : current;
27
- }
28
- return result;
29
- }
30
-
31
- /**
32
- * Extract articles from constitution.md content.
33
- * @param {string} content - Full constitution markdown.
34
- * @returns {object[]} Array of { id, numeral, title, rules, enforcement }.
35
- */
36
- function extractArticles(content) {
37
- const articles = [];
38
-
39
- // Split by article headers
40
- const articleRegex = /^## Article ([IVXLCDM]+):\s*(.+)/gm;
41
- let match;
42
- const articlePositions = [];
43
-
44
- while ((match = articleRegex.exec(content)) !== null) {
45
- articlePositions.push({
46
- numeral: match[1],
47
- title: match[2].trim(),
48
- start: match.index,
49
- });
50
- }
51
-
52
- for (let i = 0; i < articlePositions.length; i++) {
53
- const pos = articlePositions[i];
54
- const end = i + 1 < articlePositions.length ? articlePositions[i + 1].start : content.length;
55
- const section = content.slice(pos.start, end);
56
-
57
- // Extract enforcement
58
- const enforcementMatch = section.match(/\*\*Enforcement:\s*(BLOCK|GUIDE|WARN)\*\*/);
59
- const enforcement = enforcementMatch ? enforcementMatch[1].toLowerCase() : 'unknown';
60
-
61
- // Extract numbered rules (lines starting with number followed by period)
62
- const rules = [];
63
- const ruleLines = section.match(/^\d+\.\s+.+/gm) || [];
64
- for (const line of ruleLines) {
65
- const ruleText = line.replace(/^\d+\.\s+/, '').replace(/\*\*/g, '').trim();
66
- if (ruleText.length > 10) {
67
- rules.push(ruleText);
68
- }
69
- }
70
-
71
- articles.push({
72
- id: pos.numeral,
73
- number: romanToInt(pos.numeral),
74
- title: pos.title,
75
- rules,
76
- enforcement,
77
- });
78
- }
79
-
80
- return articles;
81
- }
82
-
83
- /**
84
- * Extract mode definitions from Article XI.
85
- * @param {string} content - Full constitution markdown.
86
- * @returns {object|null} Mode definitions.
87
- */
88
- function extractModes(content) {
89
- // Find Article XI section
90
- const xiMatch = content.match(/## Article XI[\s\S]*?(?=## Article [IVXLCDM]+:|$)/);
91
- if (!xiMatch) return null;
92
-
93
- const section = xiMatch[0];
94
-
95
- const modes = {};
96
-
97
- // Extract from the table
98
- const tableRegex = /\|\s*\*\*(\w+)\*\*\s*\|([^|]*)\|([^|]*)\|([^|]*)\|/g;
99
- let tableMatch;
100
-
101
- while ((tableMatch = tableRegex.exec(section)) !== null) {
102
- const modeName = tableMatch[1].toLowerCase();
103
- const states = tableMatch[2].trim();
104
- const reads = tableMatch[3].trim();
105
- const writes = tableMatch[4].trim();
106
-
107
- modes[modeName] = {
108
- states: states.split(',').map(s => s.trim()).filter(Boolean),
109
- reads: reads || 'Entire project',
110
- writes: writes || 'unknown',
111
- };
112
- }
113
-
114
- return Object.keys(modes).length > 0 ? modes : null;
115
- }
116
-
117
- /**
118
- * Extract blocker codes from constitution content.
119
- * @param {string} content - Full constitution markdown.
120
- * @returns {{ critical: string[], general: string[] }}
121
- */
122
- function extractBlockers(content) {
123
- const critical = [];
124
- const general = [];
125
-
126
- // Look for C01-C99 pattern (critical blockers)
127
- const criticalMatches = content.match(/C\d{2}/g) || [];
128
- for (const c of [...new Set(criticalMatches)]) {
129
- critical.push(c);
130
- }
131
-
132
- // Look for G01-G99 pattern (general blockers)
133
- const generalMatches = content.match(/G\d{2}/g) || [];
134
- for (const g of [...new Set(generalMatches)]) {
135
- general.push(g);
136
- }
137
-
138
- return { critical: critical.sort(), general: general.sort() };
139
- }
140
-
141
- /**
142
- * Extract quality thresholds from constitution content.
143
- * @param {string} content - Full constitution markdown.
144
- * @returns {object} Quality thresholds.
145
- */
146
- function extractQualityThresholds(content) {
147
- const thresholds = {};
148
-
149
- // Look for percentage thresholds
150
- const selfValidation = content.match(/>= (\d+)%.*(?:self|validation|criteria|quality)/i);
151
- if (selfValidation) {
152
- thresholds.selfValidation = parseInt(selfValidation[1], 10);
153
- }
154
-
155
- const testCoverage = content.match(/test coverage.*?>= (\d+)%/i) || content.match(/>= (\d+)%.*?test coverage/i);
156
- if (testCoverage) {
157
- thresholds.testCoverage = parseInt(testCoverage[1], 10);
158
- }
159
-
160
- const maxCorrections = content.match(/(?:max|maximum)\s+(\d+)\s+correction/i);
161
- if (maxCorrections) {
162
- thresholds.maxCorrectionLoops = parseInt(maxCorrections[1], 10);
163
- }
164
-
165
- return thresholds;
166
- }
167
-
168
- /**
169
- * Generate a constitution domain YAML file from constitution.md.
170
- * @param {string} frameworkDir - Path to the framework directory.
171
- * @returns {{ path: string, domain: object }} The generated domain object and file path.
172
- */
173
- export function generateConstitutionDomain(frameworkDir) {
174
- const constPath = join(frameworkDir, 'constitution.md');
175
- if (!existsSync(constPath)) {
176
- throw new Error(`constitution.md not found at: ${constPath}`);
177
- }
178
-
179
- const content = readFileSync(constPath, 'utf8');
180
-
181
- const articles = extractArticles(content);
182
- const modes = extractModes(content);
183
- const blockers = extractBlockers(content);
184
- const thresholds = extractQualityThresholds(content);
185
-
186
- const domain = {
187
- constitution: {
188
- version: '1.0',
189
- source: 'constitution.md',
190
- generatedAt: new Date().toISOString(),
191
- articleCount: articles.length,
192
- articles: articles.map(a => ({
193
- id: a.id,
194
- title: a.title,
195
- enforcement: a.enforcement,
196
- rules: a.rules,
197
- })),
198
- },
199
- };
200
-
201
- if (modes) {
202
- domain.constitution.modes = modes;
203
- }
204
-
205
- if (blockers.critical.length > 0 || blockers.general.length > 0) {
206
- domain.constitution.blockers = blockers;
207
- }
208
-
209
- if (Object.keys(thresholds).length > 0) {
210
- domain.constitution.qualityThresholds = thresholds;
211
- }
212
-
213
- // Write the domain file
214
- const domainsDir = join(frameworkDir, 'domains');
215
- mkdirSync(domainsDir, { recursive: true });
216
-
217
- const outputPath = join(domainsDir, 'constitution.yaml');
218
- const yamlContent = yaml.dump(domain, {
219
- lineWidth: 120,
220
- noRefs: true,
221
- sortKeys: false,
222
- });
223
-
224
- writeFileSync(outputPath, `# Constitution Domain — Auto-generated from constitution.md\n# Do not edit manually. Regenerate with: node scripts/generate-constitution-domain.js\n\n${yamlContent}`, 'utf8');
225
-
226
- return { path: outputPath, domain };
227
- }
228
-
229
- // ---------------------------------------------------------------------------
230
- // CLI entrypoint
231
- // ---------------------------------------------------------------------------
232
-
233
- const isMainModule = process.argv[1] && (
234
- process.argv[1].endsWith('generate-constitution-domain.js') ||
235
- process.argv[1].endsWith('generate-constitution-domain')
236
- );
237
-
238
- if (isMainModule) {
239
- const frameworkDir = process.argv[2] || join(process.cwd(), 'chati.dev');
240
-
241
- console.log(`Generating constitution domain from: ${frameworkDir}`);
242
-
243
- try {
244
- const { path, domain } = generateConstitutionDomain(frameworkDir);
245
- console.log(`Articles extracted: ${domain.constitution.articleCount}`);
246
- console.log(`Modes: ${domain.constitution.modes ? Object.keys(domain.constitution.modes).join(', ') : 'none'}`);
247
- console.log(`Blockers: critical=${domain.constitution.blockers?.critical?.length || 0}, general=${domain.constitution.blockers?.general?.length || 0}`);
248
- console.log(`Written to: ${path}`);
249
- } catch (err) {
250
- console.error(`Error: ${err.message}`);
251
- process.exit(1);
252
- }
253
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * One-time keypair generation for Ed25519 manifest signing.
3
- * Run: node scripts/generate-signing-key.js
4
- *
5
- * Private key: .signing-key.pem (GITIGNORED — never commit)
6
- * Public key: src/installer/signing-public-key.pem (committed — distributed with package)
7
- */
8
- import { generateKeyPairSync } from 'crypto';
9
- import { writeFileSync, existsSync } from 'fs';
10
- import { join, dirname } from 'path';
11
- import { fileURLToPath } from 'url';
12
-
13
- const __dirname = dirname(fileURLToPath(import.meta.url));
14
- const privateKeyPath = join(__dirname, '..', '.signing-key.pem');
15
- const publicKeyPath = join(__dirname, '..', 'src', 'installer', 'signing-public-key.pem');
16
-
17
- if (existsSync(privateKeyPath)) {
18
- console.error('Private key already exists at .signing-key.pem');
19
- console.error('Delete it first if you want to regenerate.');
20
- process.exit(1);
21
- }
22
-
23
- const { publicKey, privateKey } = generateKeyPairSync('ed25519', {
24
- publicKeyEncoding: { type: 'spki', format: 'pem' },
25
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' },
26
- });
27
-
28
- writeFileSync(privateKeyPath, privateKey);
29
- writeFileSync(publicKeyPath, publicKey);
30
-
31
- console.log('Ed25519 keypair generated.');
32
- console.log(` Private: .signing-key.pem (GITIGNORED)`);
33
- console.log(` Public: src/installer/signing-public-key.pem`);