chati-dev 4.3.1 → 4.4.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 (147) hide show
  1. package/README.md +18 -13
  2. package/bin/chati.js +12 -4
  3. package/framework/agents/build/dev.md +5 -1
  4. package/framework/agents/discover/greenfield-wu.md +16 -1
  5. package/framework/agents/plan/tasks.md +31 -0
  6. package/framework/agents/plan/ux-brand-architect.md +21 -2
  7. package/framework/agents/plan/ux-component-engineer.md +10 -0
  8. package/framework/agents/quality/qa-implementation.md +1 -1
  9. package/framework/agents/quality/qa-planning.md +1 -1
  10. package/framework/agents/quality/qa-visual.md +24 -21
  11. package/framework/config.yaml +5 -4
  12. package/framework/constitution.md +58 -11
  13. package/framework/context/governance.md +12 -10
  14. package/framework/context/root.md +2 -2
  15. package/framework/data/entity-registry.yaml +12 -4
  16. package/framework/data/qa-rubrics.yaml +335 -0
  17. package/framework/domains/constitution.yaml +3 -3
  18. package/framework/executors/json-validate.js +80 -0
  19. package/framework/executors/npm-script.js +72 -0
  20. package/framework/executors/path-check.js +67 -0
  21. package/framework/executors/registry.yaml +36 -0
  22. package/framework/hooks/advance-trigger.js +47 -3
  23. package/framework/hooks/constitution-guard.js +9 -4
  24. package/framework/hooks/git-push-authority.js +113 -0
  25. package/framework/hooks/license-guard.js +59 -9
  26. package/framework/hooks/model-governance.js +40 -17
  27. package/framework/hooks/prism-engine.js +78 -11
  28. package/framework/hooks/session-digest.js +12 -3
  29. package/framework/hooks/settings.json +7 -3
  30. package/framework/hooks/style-guard.js +52 -3
  31. package/framework/hooks/team-quality-gate.js +43 -5
  32. package/framework/i18n/en.yaml +3 -3
  33. package/framework/i18n/es.yaml +3 -3
  34. package/framework/i18n/fr.yaml +3 -3
  35. package/framework/i18n/pt.yaml +3 -3
  36. package/framework/intelligence/confidence.yaml +85 -6
  37. package/framework/intelligence/context-engine.md +9 -5
  38. package/framework/intelligence/decision-engine.md +1 -1
  39. package/framework/orchestrator/chati-router.js +1 -1
  40. package/framework/orchestrator/chati-update.md +19 -3
  41. package/framework/orchestrator/chati.md +19 -1
  42. package/framework/quality-gates/planning-gate.md +2 -0
  43. package/framework/scaffold/motion-premium/scaffold.yaml +2 -1
  44. package/framework/scaffold/motion-premium-3d/components/webgl/WebGLContext.tsx.template +1 -1
  45. package/framework/scaffold/saas-dashboard/README.md +58 -0
  46. package/framework/scaffold/saas-dashboard/app/dashboard/page.tsx.template +546 -0
  47. package/framework/scaffold/saas-dashboard/app/globals.css.template +746 -0
  48. package/framework/scaffold/saas-dashboard/app/layout.tsx.template +192 -0
  49. package/framework/scaffold/saas-dashboard/app/shell.css.template +1070 -0
  50. package/framework/scaffold/saas-dashboard/components/data/Chart.tsx.template +725 -0
  51. package/framework/scaffold/saas-dashboard/components/data/DataTable.tsx.template +623 -0
  52. package/framework/scaffold/saas-dashboard/components/data/DataTable.types.ts.template +104 -0
  53. package/framework/scaffold/saas-dashboard/components/data/DataTablePagination.tsx.template +234 -0
  54. package/framework/scaffold/saas-dashboard/components/data/SkeletonBlock.tsx.template +111 -0
  55. package/framework/scaffold/saas-dashboard/components/data/StatCard.tsx.template +393 -0
  56. package/framework/scaffold/saas-dashboard/components/data/StatCardGrid.tsx.template +121 -0
  57. package/framework/scaffold/saas-dashboard/components/feedback/EmptyState.tsx.template +281 -0
  58. package/framework/scaffold/saas-dashboard/components/interaction/CommandPalette.tsx.template +767 -0
  59. package/framework/scaffold/saas-dashboard/components/interaction/Field.tsx.template +351 -0
  60. package/framework/scaffold/saas-dashboard/components/interaction/Form.tsx.template +424 -0
  61. package/framework/scaffold/saas-dashboard/components/primitives/Badge.tsx.template +193 -0
  62. package/framework/scaffold/saas-dashboard/components/primitives/Button.tsx.template +261 -0
  63. package/framework/scaffold/saas-dashboard/components/primitives/Card.tsx.template +287 -0
  64. package/framework/scaffold/saas-dashboard/components/primitives/Input.tsx.template +310 -0
  65. package/framework/scaffold/saas-dashboard/components/primitives/Spinner.tsx.template +135 -0
  66. package/framework/scaffold/saas-dashboard/components/primitives/index.ts.template +60 -0
  67. package/framework/scaffold/saas-dashboard/components/shell/AppShell.tsx.template +174 -0
  68. package/framework/scaffold/saas-dashboard/components/shell/Breadcrumb.tsx.template +186 -0
  69. package/framework/scaffold/saas-dashboard/components/shell/Container.tsx.template +86 -0
  70. package/framework/scaffold/saas-dashboard/components/shell/NavItem.tsx.template +147 -0
  71. package/framework/scaffold/saas-dashboard/components/shell/Sidebar.tsx.template +378 -0
  72. package/framework/scaffold/saas-dashboard/components/shell/SidebarContext.tsx.template +169 -0
  73. package/framework/scaffold/saas-dashboard/components/shell/ThemeToggle.tsx.template +128 -0
  74. package/framework/scaffold/saas-dashboard/components/shell/Topbar.tsx.template +301 -0
  75. package/framework/scaffold/saas-dashboard/lib/brand.ts.template +324 -0
  76. package/framework/scaffold/saas-dashboard/scaffold.yaml +225 -0
  77. package/framework/schemas/session.schema.json +5 -0
  78. package/framework/schemas/task.schema.json +9 -0
  79. package/framework/scripts/visual-qa.js +87 -1
  80. package/framework/tasks/orchestrator-health.md +4 -4
  81. package/framework/tasks/qa-impl-verdict.md +11 -5
  82. package/framework/templates/qa-gate-tmpl.yaml +24 -11
  83. package/package.json +3 -3
  84. package/src/config/context-file-generator.js +0 -6
  85. package/src/dashboard/renderer.js +0 -36
  86. package/src/executors/runner.js +204 -0
  87. package/src/installer/core.js +2 -1
  88. package/src/installer/templates.js +5 -6
  89. package/src/intelligence/registry-manager.js +1 -1
  90. package/src/license/client.js +9 -3
  91. package/src/license/commands.js +12 -2
  92. package/src/license/machine-id.js +42 -1
  93. package/src/memory/gotchas.js +58 -40
  94. package/src/memory/magic-docs.js +1 -1
  95. package/src/memory/session-digest.js +9 -4
  96. package/src/orchestrator/cli.js +174 -14
  97. package/src/orchestrator/doctor.js +98 -16
  98. package/src/orchestrator/pipeline-manager.js +44 -22
  99. package/src/orchestrator/session-manager.js +56 -8
  100. package/src/telemetry/sender.js +7 -19
  101. package/src/terminal/run-team.js +3 -3
  102. package/src/upgrade/tracked-files-detector.js +34 -16
  103. package/src/utils/feature-flags.js +1 -1
  104. package/src/utils/flatten-entities.js +4 -40
  105. package/src/utils/schema-validator.js +0 -14
  106. package/src/wizard/i18n.js +3 -3
  107. package/src/api/index.js +0 -120
  108. package/src/autonomy/autonomous-gate.js +0 -294
  109. package/src/autonomy/build-loop.js +0 -281
  110. package/src/autonomy/build-state.js +0 -286
  111. package/src/autonomy/cause-analyzer.js +0 -177
  112. package/src/autonomy/escalation.js +0 -214
  113. package/src/autonomy/index.js +0 -51
  114. package/src/autonomy/mode-manager.js +0 -225
  115. package/src/autonomy/mode-suggester.js +0 -283
  116. package/src/autonomy/progress-reporter.js +0 -275
  117. package/src/autonomy/safety-net.js +0 -370
  118. package/src/config/agent-customizer.js +0 -231
  119. package/src/decision/analyzer.js +0 -291
  120. package/src/decision/engine.js +0 -250
  121. package/src/decision/index.js +0 -38
  122. package/src/decision/registry-healer.js +0 -468
  123. package/src/decision/registry-updater.js +0 -339
  124. package/src/extensions/loader.js +0 -145
  125. package/src/extensions/registry.js +0 -134
  126. package/src/gates/circuit-breaker.js +0 -151
  127. package/src/gates/g1-planning-complete.js +0 -154
  128. package/src/gates/g2-qa-planning.js +0 -156
  129. package/src/gates/g3-implementation.js +0 -215
  130. package/src/gates/g4-qa-implementation.js +0 -240
  131. package/src/gates/g5-deploy-ready.js +0 -181
  132. package/src/gates/gate-base.js +0 -185
  133. package/src/gates/index.js +0 -46
  134. package/src/health/auto-fix.js +0 -216
  135. package/src/health/engine.js +0 -246
  136. package/src/merger/semantic-merger.js +0 -292
  137. package/src/preview/detector.js +0 -238
  138. package/src/preview/index.js +0 -20
  139. package/src/preview/launcher.js +0 -235
  140. package/src/preview/log-buffer.js +0 -103
  141. package/src/quality/metrics-collector.js +0 -281
  142. package/src/quality/test-runner.js +0 -366
  143. package/src/tasks/executor.js +0 -195
  144. package/src/tasks/index.js +0 -4
  145. package/src/tasks/loader.js +0 -210
  146. package/src/tasks/router.js +0 -182
  147. package/src/utils/event-bus.js +0 -126
@@ -6,11 +6,24 @@
6
6
  */
7
7
 
8
8
  import yaml from 'js-yaml';
9
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
9
+ import { existsSync, readFileSync, writeFileSync, renameSync, mkdirSync } from 'fs';
10
10
  import { join, dirname } from 'path';
11
11
 
12
12
  const SESSION_FILE = '.chati/session.yaml';
13
13
 
14
+ /**
15
+ * Atomic write helper. Writes `content` to a sibling `.tmp` file and then
16
+ * renames it into place. If the process is killed mid-write the original
17
+ * remains intact. Same-FS rename on POSIX is atomic; on Windows it's
18
+ * best-effort. Mirrors the pattern used by `chati.dev/hooks/prism-engine.js`
19
+ * `writeBackSession` to keep both hook and CLI write paths consistent.
20
+ */
21
+ function writeFileAtomic(path, content, encoding = 'utf-8') {
22
+ const tmp = `${path}.tmp`;
23
+ writeFileSync(tmp, content, encoding);
24
+ renameSync(tmp, path);
25
+ }
26
+
14
27
  /**
15
28
  * Default session template.
16
29
  */
@@ -26,6 +39,12 @@ const DEFAULT_SESSION = {
26
39
  started_at: null,
27
40
  current_agent: '',
28
41
  pipeline_position: 0,
42
+ // execution_mode is a string enum ('interactive' | 'autonomous') per
43
+ // session.schema.json. Article XVIII deprecation (2026-04-18) collapsed
44
+ // the old 4-value execution_profile enum into this binary form. Per-
45
+ // transition metadata (setAt, reason) lives in mode_transitions[] below,
46
+ // not on this field. mode-manager.js was historically reading it as an
47
+ // object — that path was normalized to read the string in 2026-05.
29
48
  execution_mode: 'interactive',
30
49
  user_level: 'auto',
31
50
  user_level_confidence: 0.0,
@@ -135,7 +154,7 @@ export function initSession(projectDir, options = {}) {
135
154
  noRefs: true,
136
155
  });
137
156
 
138
- writeFileSync(sessionPath, yamlContent, 'utf-8');
157
+ writeFileAtomic(sessionPath, yamlContent);
139
158
 
140
159
  return {
141
160
  created: true,
@@ -216,6 +235,14 @@ export function migrateSession(session) {
216
235
  };
217
236
  }
218
237
 
238
+ // Defensive seed: ensure execution_mode is always present after migration.
239
+ // An unrecognized execution_profile (e.g. a hand-edited 'custom') or no
240
+ // profile at all used to leave the field absent, so validateSession could
241
+ // not catch it and every subsequent load re-migrated the same session. The
242
+ // profile mapping below can still promote this to 'autonomous'. Guarded so
243
+ // an existing 'autonomous' value is preserved.
244
+ if (!session.execution_mode) session.execution_mode = 'interactive';
245
+
219
246
  // Article XVIII deprecation (2026-04-18): collapse execution_profile into
220
247
  // execution_mode per the migration table. Runs LAST so it overrides any
221
248
  // default seeded above. See constitution Article XVIII for rationale.
@@ -232,6 +259,20 @@ export function migrateSession(session) {
232
259
  delete session.profile_transitions;
233
260
  }
234
261
 
262
+ // execution_mode normalization (2026-05): the schema declares this field
263
+ // as a string enum ('interactive' | 'autonomous'), and all CLI/dashboard/
264
+ // hook consumers treat it as a string. Earlier `setExecutionMode` writes
265
+ // accidentally produced an object shape `{ mode, setAt, reason }` that
266
+ // only `mode-manager.js#getCurrentMode` understood. Sessions that ran
267
+ // through that path stored the object form; flatten them back to a string
268
+ // here so subsequent reads from cli.js / dashboard / templates work.
269
+ // Per-transition metadata lives in mode_transitions[] (already present).
270
+ if (session.execution_mode && typeof session.execution_mode === 'object' && !Array.isArray(session.execution_mode)) {
271
+ const inner = session.execution_mode.mode;
272
+ const map = { 'human-in-the-loop': 'interactive', interactive: 'interactive', autonomous: 'autonomous' };
273
+ session.execution_mode = map[inner] || 'interactive';
274
+ }
275
+
235
276
  return { migrated: true, fromVersion, toVersion: CURRENT_SCHEMA_VERSION };
236
277
  }
237
278
 
@@ -260,9 +301,16 @@ export function loadSession(projectDir) {
260
301
  if (migration.migrated) {
261
302
  try {
262
303
  const yamlContent = yaml.dump(session, { lineWidth: -1, noRefs: true });
263
- writeFileSync(sessionPath, yamlContent, 'utf-8');
264
- } catch { /* expected: operation may fail gracefully */
265
- // Migration write failed continue with migrated in-memory session
304
+ writeFileAtomic(sessionPath, yamlContent);
305
+ } catch (writeErr) {
306
+ // Migration write-back failed (read-only filesystem, EACCES). The
307
+ // session continues with the migrated in-memory copy, but disk stays
308
+ // on the old schema and re-migrates on every load. Surface it so the
309
+ // user can fix the cause (make .chati/ writable) instead of it failing
310
+ // silently. The production path (writable FS) never reaches here.
311
+ process.stderr.write(
312
+ `[chati] warning: session migrated in memory but could not be written back to ${sessionPath} (${writeErr.code || writeErr.message}); it will re-migrate on every load until the directory is writable\n`
313
+ );
266
314
  }
267
315
  }
268
316
 
@@ -329,7 +377,7 @@ export function updateSession(projectDir, updates) {
329
377
  noRefs: true,
330
378
  });
331
379
 
332
- writeFileSync(sessionPath, yamlContent, 'utf-8');
380
+ writeFileAtomic(sessionPath, yamlContent);
333
381
 
334
382
  return {
335
383
  saved: true,
@@ -392,7 +440,7 @@ function writeSessionToDisk(projectDir, session) {
392
440
  const sessionPath = join(projectDir, SESSION_FILE);
393
441
  try {
394
442
  const yamlContent = yaml.dump(session, { lineWidth: -1, noRefs: true });
395
- writeFileSync(sessionPath, yamlContent, 'utf-8');
443
+ writeFileAtomic(sessionPath, yamlContent);
396
444
  return { saved: true, session };
397
445
  } catch (err) {
398
446
  return { saved: false, error: `Failed to write session: ${err.message}` };
@@ -875,7 +923,7 @@ export function validateSession(projectDir) {
875
923
  const session = loadResult.session;
876
924
 
877
925
  // Validate required fields
878
- const requiredFields = ['schema_version', 'version', 'mode', 'language', 'project_type', 'agents'];
926
+ const requiredFields = ['schema_version', 'version', 'mode', 'execution_mode', 'language', 'project_type', 'agents'];
879
927
  for (const field of requiredFields) {
880
928
  if (!session[field]) {
881
929
  return {
@@ -5,30 +5,19 @@
5
5
  * Fire-and-forget: never blocks the user workflow, fails silently.
6
6
  */
7
7
 
8
- import { existsSync, readFileSync } from 'fs';
9
- import { join } from 'path';
10
- import { homedir } from 'os';
11
-
12
8
  // ---------------------------------------------------------------------------
13
9
  // Default Endpoint
14
10
  // ---------------------------------------------------------------------------
15
11
 
16
12
  export const DEFAULT_ENDPOINT = 'https://chati.dev/api/telemetry';
17
13
 
18
- // ---------------------------------------------------------------------------
19
- // Helpers
20
- // ---------------------------------------------------------------------------
21
-
22
- function readGlobalLicenseKey() {
23
- try {
24
- const p = join(homedir(), '.chati-dev', 'license.yaml');
25
- if (!existsSync(p)) return null;
26
- const content = readFileSync(p, 'utf-8');
27
- const match = content.match(/^key:\s*(.+)$/m);
28
- const key = match?.[1]?.trim();
29
- return key && key !== 'null' ? key : null;
30
- } catch { return null; }
31
- }
14
+ // Note: the prior implementation read the local license key from
15
+ // `~/.chati-dev/license.yaml` and shipped it inside every telemetry POST as
16
+ // `license_key`. That sent a paying user's credential to the analytics
17
+ // endpoint on every install/pipeline event — outside the per-event PII
18
+ // scrubber. Removed (2026-05). Server-side attribution should be derived
19
+ // from the validated license session correlated to `anonymousId`, never from
20
+ // the raw key over the wire.
32
21
 
33
22
  // ---------------------------------------------------------------------------
34
23
  // Sender
@@ -50,7 +39,6 @@ export async function sendEvents(events, config) {
50
39
 
51
40
  const payload = {
52
41
  anonymousId: config.anonymousId,
53
- license_key: readGlobalLicenseKey(),
54
42
  project_name: config.projectName ?? null,
55
43
  chatiVersion: config.version || 'unknown',
56
44
  nodeVersion: process.version,
@@ -21,7 +21,7 @@ import { fileURLToPath } from 'url';
21
21
  import { existsSync, readFileSync } from 'fs';
22
22
  import { join } from 'path';
23
23
  import { buildAgentPrompt } from './prompt-builder.js';
24
- import { spawnParallelGroup, spawnTerminal } from './spawner.js';
24
+ import { spawnParallelGroup } from './spawner.js';
25
25
  import { TerminalMonitor } from './monitor.js';
26
26
  import { collectResults, mergeHandoffs, buildConsolidatedHandoff } from './collector.js';
27
27
  import { parseAgentOutput } from './handoff-parser.js';
@@ -107,7 +107,7 @@ async function main() {
107
107
  const taskListPath = join(teamDir, 'tasks.yaml');
108
108
 
109
109
  // Load session state (minimal parse)
110
- let sessionState = {};
110
+ const sessionState = {};
111
111
  try {
112
112
  const sessionPath = join(projectDir, '.chati', 'session.yaml');
113
113
  if (existsSync(sessionPath)) {
@@ -166,7 +166,7 @@ async function main() {
166
166
 
167
167
  // Spawn team members
168
168
  let group;
169
- let fallbackUsed = false;
169
+ const fallbackUsed = false;
170
170
  const echoEvents = [];
171
171
 
172
172
  try {
@@ -41,6 +41,11 @@ function isGitRepo(targetDir) {
41
41
  * Detect which framework-owned paths are currently tracked by git.
42
42
  * Does NOT modify git state — read-only operation.
43
43
  *
44
+ * Runs a single `git ls-files -z -- <pattern1> <pattern2> …` invocation and
45
+ * partitions the result locally. The prior implementation spawned one
46
+ * `git ls-files` per pattern (19 processes per call) which added several
47
+ * hundred ms of overhead on a slow disk during every upgrade check.
48
+ *
44
49
  * @param {string} targetDir - absolute path to the project root
45
50
  * @returns {string[]} array of tracked framework file paths (relative to targetDir)
46
51
  */
@@ -49,28 +54,41 @@ export function detectTrackedFrameworkFiles(targetDir) {
49
54
  return [];
50
55
  }
51
56
 
52
- const tracked = [];
57
+ let stdout;
58
+ try {
59
+ // -z: NUL-separated output (safe for paths with spaces/newlines).
60
+ // Pass all patterns as positional args after `--` so they're treated as
61
+ // pathspecs, not options. Quoting is handled by execFile-style argv if
62
+ // available; we use execSync with a builtin pattern array escape.
63
+ const args = FRAMEWORK_PATTERNS.map(p => JSON.stringify(p)).join(' ');
64
+ stdout = execSync(`git ls-files -z -- ${args}`, {
65
+ cwd: targetDir,
66
+ stdio: ['ignore', 'pipe', 'ignore'],
67
+ timeout: 5000,
68
+ }).toString();
69
+ } catch {
70
+ // git ls-files failed entirely (not a repo, repo corrupt, etc.) → none tracked
71
+ return [];
72
+ }
53
73
 
54
- for (const pattern of FRAMEWORK_PATTERNS) {
55
- try {
56
- const result = execSync(`git ls-files -- "${pattern}"`, {
57
- cwd: targetDir,
58
- stdio: ['ignore', 'pipe', 'ignore'],
59
- timeout: 5000,
60
- })
61
- .toString()
62
- .trim();
74
+ if (!stdout) return [];
63
75
 
64
- if (result.length > 0) {
65
- tracked.push(pattern);
76
+ // Split on NUL. For each tracked path returned by git, find which of our
77
+ // FRAMEWORK_PATTERNS it belongs under (directory prefixes use trailing
78
+ // slash; exact-file patterns match equality).
79
+ const trackedPaths = stdout.split('\0').filter(Boolean);
80
+ const tracked = new Set();
81
+ for (const path of trackedPaths) {
82
+ for (const pattern of FRAMEWORK_PATTERNS) {
83
+ if (pattern.endsWith('/')) {
84
+ if (path.startsWith(pattern)) { tracked.add(pattern); break; }
85
+ } else if (path === pattern) {
86
+ tracked.add(pattern); break;
66
87
  }
67
- } catch {
68
- // git ls-files failure means path is not tracked — skip
69
88
  }
70
89
  }
71
90
 
72
- // Deduplicate in case patterns overlap
73
- return [...new Set(tracked)];
91
+ return [...tracked];
74
92
  }
75
93
 
76
94
  /**
@@ -22,13 +22,13 @@ const DEFAULTS = {
22
22
  rate_limiter_integration: false,
23
23
  l5_keywords: false,
24
24
  prompt_size_guard: false,
25
- ids_decision_engine: false,
26
25
  surface_criteria: false,
27
26
  parallel_fallback: false,
28
27
  tool_mesh: false,
29
28
  tech_presets: false,
30
29
  doctor_autofix: false,
31
30
  brandbook: false,
31
+ execution_kinds: false,
32
32
  };
33
33
 
34
34
  /**
@@ -1,46 +1,10 @@
1
1
  /**
2
- * @fileoverview Shared entity-flattening utilities.
2
+ * @fileoverview Shared entity-flattening utility.
3
3
  *
4
- * Two variants exist because the registry YAML stores entities in two different
5
- * shapes depending on who reads it:
6
- *
7
- * - flattenEntitiesFromRegistry: receives the full registry object
8
- * (i.e. the result of yaml.load()), where each category's value is an Array.
9
- * Used by decision/analyzer.js and decision/engine.js.
10
- *
11
- * - flattenEntitiesMap: receives only the `registry.entities` map,
12
- * where each category's value is a nested object keyed by entity name.
13
- * Used by intelligence/registry-manager.js.
14
- *
15
- * Keep both functions here so there is a single canonical implementation.
16
- */
17
-
18
- /**
19
- * Flatten a full entity registry (as returned by yaml.load) into a flat array.
20
- *
21
- * Each category value must be an Array of entity objects.
22
- * The `type` field is inferred from the category key.
23
- *
24
- * @param {object} registry - Full registry object with a top-level `entities` key.
25
- * @returns {object[]} Flat array of entity objects, each with a `type` field added.
4
+ * flattenEntitiesMap receives the `registry.entities` map, where each category's
5
+ * value is a nested object keyed by entity name. Used by
6
+ * intelligence/registry-manager.js.
26
7
  */
27
- export function flattenEntitiesFromRegistry(registry) {
28
- const entities = [];
29
-
30
- if (!registry || !registry.entities) {
31
- return entities;
32
- }
33
-
34
- Object.entries(registry.entities).forEach(([type, typeEntities]) => {
35
- if (Array.isArray(typeEntities)) {
36
- typeEntities.forEach(entity => {
37
- entities.push({ ...entity, type });
38
- });
39
- }
40
- });
41
-
42
- return entities;
43
- }
44
8
 
45
9
  /**
46
10
  * Flatten the `entities` section of the registry (a nested object map) into a flat array.
@@ -177,20 +177,6 @@ export const SESSION_SCHEMA = {
177
177
  },
178
178
  };
179
179
 
180
- /**
181
- * Build state schema (build-state.json).
182
- */
183
- export const BUILD_STATE_SCHEMA = {
184
- required: ['sessionId', 'status', 'checkpoints'],
185
- properties: {
186
- sessionId: { type: 'string', required: true },
187
- status: { type: 'string', required: true, enum: ['idle', 'running', 'completed', 'failed', 'abandoned'] },
188
- checkpoints: { type: 'array', required: true },
189
- startedAt: { type: 'string' },
190
- totalAttempts: { type: 'number', min: 0 },
191
- },
192
- };
193
-
194
180
  /**
195
181
  * Config schema (config.yaml).
196
182
  */
@@ -39,7 +39,7 @@ const FALLBACK_EN = {
39
39
  agents_count: 'Specialized agent definitions across DISCOVER, PLAN, BUILD, DEPLOY phases',
40
40
  workflows_count: '6 workflow blueprints',
41
41
  templates_count: '6 templates (PRD, Brownfield PRD, Architecture, Task, QA Gate, Quick Brief)',
42
- constitution: 'Constitution (23 Articles + Preamble)',
42
+ constitution: 'Constitution (25 Articles + Preamble)',
43
43
  session_mgmt: 'Session management system',
44
44
  quality_gates: 'Quality gates (3-tier verdicts)',
45
45
  proceed: 'Proceed with installation?',
@@ -47,7 +47,7 @@ const FALLBACK_EN = {
47
47
  created_chati: 'Created .chati/ session directory',
48
48
  created_framework: 'Created chati.dev/ system directory (agents, templates, workflows)',
49
49
  created_commands: 'Created .claude/commands/ (thin router)',
50
- installed_constitution: 'Installed Constitution (Articles I-XXIII)',
50
+ installed_constitution: 'Installed Constitution (Articles I-XXV)',
51
51
  created_session: 'Created session.yaml schema',
52
52
  created_claude_md: 'Created CLAUDE.md',
53
53
  configured_mcps: 'Configured MCPs:',
@@ -55,7 +55,7 @@ const FALLBACK_EN = {
55
55
  agents_valid: 'All agents implement 8 protocols',
56
56
  handoff_ok: 'Handoff protocol: OK',
57
57
  validation_ok: 'Self-validation criteria: OK',
58
- constitution_ok: 'Constitution: 23 articles verified',
58
+ constitution_ok: 'Constitution: 25 articles verified',
59
59
  created_memories: 'Created .chati/memories/ (Memory Layer)',
60
60
  installed_intelligence: 'Installed Intelligence Layer (Context Engine, Memory, Registry)',
61
61
  intelligence_valid: 'Intelligence: 6 spec files verified',
package/src/api/index.js DELETED
@@ -1,120 +0,0 @@
1
- /**
2
- * @fileoverview Public API surface for chati-dev.
3
- *
4
- * Re-exports stable functions from core modules, providing
5
- * a clean entry point for programmatic usage.
6
- *
7
- * @example
8
- * import { createSession, runHealthChecks, classifyIntent } from 'chati-dev/api';
9
- */
10
-
11
- // ---------------------------------------------------------------------------
12
- // Health & Diagnostics
13
- // ---------------------------------------------------------------------------
14
-
15
- export { runHealthChecks } from '../health/engine.js';
16
-
17
- // ---------------------------------------------------------------------------
18
- // Context Engine (PRISM)
19
- // ---------------------------------------------------------------------------
20
-
21
- export { runPrism } from '../context/engine.js';
22
-
23
- // ---------------------------------------------------------------------------
24
- // Orchestrator
25
- // ---------------------------------------------------------------------------
26
-
27
- export { classifyIntent, INTENT_TYPES } from '../orchestrator/intent-classifier.js';
28
- export {
29
- initPipeline,
30
- advancePipeline,
31
- initQuickFlowPipeline,
32
- initStandardFlowPipeline,
33
- } from '../orchestrator/pipeline-manager.js';
34
- export { selectAgent } from '../orchestrator/agent-selector.js';
35
-
36
- // ---------------------------------------------------------------------------
37
- // Session Management
38
- // ---------------------------------------------------------------------------
39
-
40
- import { initSession as _initSession } from '../orchestrator/session-manager.js';
41
-
42
- export {
43
- initSession,
44
- loadSession,
45
- updateSession,
46
- validateSession,
47
- getSessionSummary,
48
- claimSession,
49
- releaseSession,
50
- getSessionOwner,
51
- } from '../orchestrator/session-manager.js';
52
-
53
- // ---------------------------------------------------------------------------
54
- // Autonomy
55
- // ---------------------------------------------------------------------------
56
-
57
- export { runBuildLoop } from '../autonomy/build-loop.js';
58
- export { checkSafety, SAFETY_TRIGGERS } from '../autonomy/safety-net.js';
59
-
60
- // ---------------------------------------------------------------------------
61
- // Memory
62
- // ---------------------------------------------------------------------------
63
-
64
- export { recordError, getGotchas } from '../memory/gotchas.js';
65
-
66
- // ---------------------------------------------------------------------------
67
- // Quality
68
- // ---------------------------------------------------------------------------
69
-
70
- export { getMetricsHistory, getQualityDashboard, recordMetric } from '../quality/metrics-collector.js';
71
-
72
- // ---------------------------------------------------------------------------
73
- // Extensions
74
- // ---------------------------------------------------------------------------
75
-
76
- export {
77
- registerExtension,
78
- getExtensions,
79
- executeExtensions,
80
- clearExtensions,
81
- EXTENSION_POINTS,
82
- } from '../extensions/registry.js';
83
- export { loadProjectExtensions, validateExtension } from '../extensions/loader.js';
84
-
85
- // ---------------------------------------------------------------------------
86
- // Configuration
87
- // ---------------------------------------------------------------------------
88
-
89
- export { loadCustomization, applyCustomization, validateCustomization } from '../config/agent-customizer.js';
90
- export { IDE_CONFIGS, getIDEChoices } from '../config/ide-configs.js';
91
-
92
- // ---------------------------------------------------------------------------
93
- // Convenience Wrapper
94
- // ---------------------------------------------------------------------------
95
-
96
- /**
97
- * Create and initialize a new chati.dev session.
98
- *
99
- * Convenience wrapper that initializes session state.
100
- *
101
- * @param {string} projectDir - Project root directory
102
- * @param {object} [options]
103
- * @param {string} [options.mode='discover'] - Initial pipeline mode
104
- * @param {boolean} [options.isGreenfield=true] - Project type
105
- * @param {string} [options.language='en'] - Interaction language
106
- * @param {string} [options.projectName=''] - Project name
107
- * @param {string[]} [options.ides=[]] - Selected IDEs
108
- * @param {string[]} [options.mcps=[]] - Selected MCPs
109
- * @returns {{ created: boolean, session: object, path: string }}
110
- */
111
- export function createSession(projectDir, options = {}) {
112
- return _initSession(projectDir, {
113
- mode: options.mode || 'discover',
114
- isGreenfield: options.isGreenfield !== false,
115
- language: options.language || 'en',
116
- projectName: options.projectName || '',
117
- ides: options.ides || [],
118
- mcps: options.mcps || [],
119
- });
120
- }