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.
- package/README.md +18 -13
- package/bin/chati.js +12 -4
- package/framework/agents/build/dev.md +5 -1
- package/framework/agents/discover/greenfield-wu.md +16 -1
- package/framework/agents/plan/tasks.md +31 -0
- package/framework/agents/plan/ux-brand-architect.md +21 -2
- package/framework/agents/plan/ux-component-engineer.md +10 -0
- package/framework/agents/quality/qa-implementation.md +1 -1
- package/framework/agents/quality/qa-planning.md +1 -1
- package/framework/agents/quality/qa-visual.md +24 -21
- package/framework/config.yaml +5 -4
- package/framework/constitution.md +58 -11
- package/framework/context/governance.md +12 -10
- package/framework/context/root.md +2 -2
- package/framework/data/entity-registry.yaml +12 -4
- package/framework/data/qa-rubrics.yaml +335 -0
- package/framework/domains/constitution.yaml +3 -3
- package/framework/executors/json-validate.js +80 -0
- package/framework/executors/npm-script.js +72 -0
- package/framework/executors/path-check.js +67 -0
- package/framework/executors/registry.yaml +36 -0
- package/framework/hooks/advance-trigger.js +47 -3
- package/framework/hooks/constitution-guard.js +9 -4
- package/framework/hooks/git-push-authority.js +113 -0
- package/framework/hooks/license-guard.js +59 -9
- package/framework/hooks/model-governance.js +40 -17
- package/framework/hooks/prism-engine.js +78 -11
- package/framework/hooks/session-digest.js +12 -3
- package/framework/hooks/settings.json +7 -3
- package/framework/hooks/style-guard.js +52 -3
- package/framework/hooks/team-quality-gate.js +43 -5
- package/framework/i18n/en.yaml +3 -3
- package/framework/i18n/es.yaml +3 -3
- package/framework/i18n/fr.yaml +3 -3
- package/framework/i18n/pt.yaml +3 -3
- package/framework/intelligence/confidence.yaml +85 -6
- package/framework/intelligence/context-engine.md +9 -5
- package/framework/intelligence/decision-engine.md +1 -1
- package/framework/orchestrator/chati-router.js +1 -1
- package/framework/orchestrator/chati-update.md +19 -3
- package/framework/orchestrator/chati.md +19 -1
- package/framework/quality-gates/planning-gate.md +2 -0
- package/framework/scaffold/motion-premium/scaffold.yaml +2 -1
- package/framework/scaffold/motion-premium-3d/components/webgl/WebGLContext.tsx.template +1 -1
- package/framework/scaffold/saas-dashboard/README.md +58 -0
- package/framework/scaffold/saas-dashboard/app/dashboard/page.tsx.template +546 -0
- package/framework/scaffold/saas-dashboard/app/globals.css.template +746 -0
- package/framework/scaffold/saas-dashboard/app/layout.tsx.template +192 -0
- package/framework/scaffold/saas-dashboard/app/shell.css.template +1070 -0
- package/framework/scaffold/saas-dashboard/components/data/Chart.tsx.template +725 -0
- package/framework/scaffold/saas-dashboard/components/data/DataTable.tsx.template +623 -0
- package/framework/scaffold/saas-dashboard/components/data/DataTable.types.ts.template +104 -0
- package/framework/scaffold/saas-dashboard/components/data/DataTablePagination.tsx.template +234 -0
- package/framework/scaffold/saas-dashboard/components/data/SkeletonBlock.tsx.template +111 -0
- package/framework/scaffold/saas-dashboard/components/data/StatCard.tsx.template +393 -0
- package/framework/scaffold/saas-dashboard/components/data/StatCardGrid.tsx.template +121 -0
- package/framework/scaffold/saas-dashboard/components/feedback/EmptyState.tsx.template +281 -0
- package/framework/scaffold/saas-dashboard/components/interaction/CommandPalette.tsx.template +767 -0
- package/framework/scaffold/saas-dashboard/components/interaction/Field.tsx.template +351 -0
- package/framework/scaffold/saas-dashboard/components/interaction/Form.tsx.template +424 -0
- package/framework/scaffold/saas-dashboard/components/primitives/Badge.tsx.template +193 -0
- package/framework/scaffold/saas-dashboard/components/primitives/Button.tsx.template +261 -0
- package/framework/scaffold/saas-dashboard/components/primitives/Card.tsx.template +287 -0
- package/framework/scaffold/saas-dashboard/components/primitives/Input.tsx.template +310 -0
- package/framework/scaffold/saas-dashboard/components/primitives/Spinner.tsx.template +135 -0
- package/framework/scaffold/saas-dashboard/components/primitives/index.ts.template +60 -0
- package/framework/scaffold/saas-dashboard/components/shell/AppShell.tsx.template +174 -0
- package/framework/scaffold/saas-dashboard/components/shell/Breadcrumb.tsx.template +186 -0
- package/framework/scaffold/saas-dashboard/components/shell/Container.tsx.template +86 -0
- package/framework/scaffold/saas-dashboard/components/shell/NavItem.tsx.template +147 -0
- package/framework/scaffold/saas-dashboard/components/shell/Sidebar.tsx.template +378 -0
- package/framework/scaffold/saas-dashboard/components/shell/SidebarContext.tsx.template +169 -0
- package/framework/scaffold/saas-dashboard/components/shell/ThemeToggle.tsx.template +128 -0
- package/framework/scaffold/saas-dashboard/components/shell/Topbar.tsx.template +301 -0
- package/framework/scaffold/saas-dashboard/lib/brand.ts.template +324 -0
- package/framework/scaffold/saas-dashboard/scaffold.yaml +225 -0
- package/framework/schemas/session.schema.json +5 -0
- package/framework/schemas/task.schema.json +9 -0
- package/framework/scripts/visual-qa.js +87 -1
- package/framework/tasks/orchestrator-health.md +4 -4
- package/framework/tasks/qa-impl-verdict.md +11 -5
- package/framework/templates/qa-gate-tmpl.yaml +24 -11
- package/package.json +3 -3
- package/src/config/context-file-generator.js +0 -6
- package/src/dashboard/renderer.js +0 -36
- package/src/executors/runner.js +204 -0
- package/src/installer/core.js +2 -1
- package/src/installer/templates.js +5 -6
- package/src/intelligence/registry-manager.js +1 -1
- package/src/license/client.js +9 -3
- package/src/license/commands.js +12 -2
- package/src/license/machine-id.js +42 -1
- package/src/memory/gotchas.js +58 -40
- package/src/memory/magic-docs.js +1 -1
- package/src/memory/session-digest.js +9 -4
- package/src/orchestrator/cli.js +174 -14
- package/src/orchestrator/doctor.js +98 -16
- package/src/orchestrator/pipeline-manager.js +44 -22
- package/src/orchestrator/session-manager.js +56 -8
- package/src/telemetry/sender.js +7 -19
- package/src/terminal/run-team.js +3 -3
- package/src/upgrade/tracked-files-detector.js +34 -16
- package/src/utils/feature-flags.js +1 -1
- package/src/utils/flatten-entities.js +4 -40
- package/src/utils/schema-validator.js +0 -14
- package/src/wizard/i18n.js +3 -3
- package/src/api/index.js +0 -120
- package/src/autonomy/autonomous-gate.js +0 -294
- package/src/autonomy/build-loop.js +0 -281
- package/src/autonomy/build-state.js +0 -286
- package/src/autonomy/cause-analyzer.js +0 -177
- package/src/autonomy/escalation.js +0 -214
- package/src/autonomy/index.js +0 -51
- package/src/autonomy/mode-manager.js +0 -225
- package/src/autonomy/mode-suggester.js +0 -283
- package/src/autonomy/progress-reporter.js +0 -275
- package/src/autonomy/safety-net.js +0 -370
- package/src/config/agent-customizer.js +0 -231
- package/src/decision/analyzer.js +0 -291
- package/src/decision/engine.js +0 -250
- package/src/decision/index.js +0 -38
- package/src/decision/registry-healer.js +0 -468
- package/src/decision/registry-updater.js +0 -339
- package/src/extensions/loader.js +0 -145
- package/src/extensions/registry.js +0 -134
- package/src/gates/circuit-breaker.js +0 -151
- package/src/gates/g1-planning-complete.js +0 -154
- package/src/gates/g2-qa-planning.js +0 -156
- package/src/gates/g3-implementation.js +0 -215
- package/src/gates/g4-qa-implementation.js +0 -240
- package/src/gates/g5-deploy-ready.js +0 -181
- package/src/gates/gate-base.js +0 -185
- package/src/gates/index.js +0 -46
- package/src/health/auto-fix.js +0 -216
- package/src/health/engine.js +0 -246
- package/src/merger/semantic-merger.js +0 -292
- package/src/preview/detector.js +0 -238
- package/src/preview/index.js +0 -20
- package/src/preview/launcher.js +0 -235
- package/src/preview/log-buffer.js +0 -103
- package/src/quality/metrics-collector.js +0 -281
- package/src/quality/test-runner.js +0 -366
- package/src/tasks/executor.js +0 -195
- package/src/tasks/index.js +0 -4
- package/src/tasks/loader.js +0 -210
- package/src/tasks/router.js +0 -182
- 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
|
-
|
|
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
|
-
|
|
264
|
-
} catch {
|
|
265
|
-
// Migration write failed
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
package/src/telemetry/sender.js
CHANGED
|
@@ -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
|
-
//
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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,
|
package/src/terminal/run-team.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
65
|
-
|
|
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
|
-
|
|
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
|
|
2
|
+
* @fileoverview Shared entity-flattening utility.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
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
|
*/
|
package/src/wizard/i18n.js
CHANGED
|
@@ -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 (
|
|
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-
|
|
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:
|
|
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
|
-
}
|