chati-dev 4.5.13 → 4.5.15
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/framework/agents/build/dev.md +4 -5
- package/framework/agents/deploy/devops.md +9 -10
- package/framework/agents/discover/brief.md +7 -13
- package/framework/agents/discover/brownfield-wu.md +5 -11
- package/framework/agents/discover/greenfield-wu.md +7 -12
- package/framework/agents/plan/architect.md +1 -1
- package/framework/agents/plan/detail.md +5 -5
- package/framework/agents/plan/phases.md +4 -5
- package/framework/agents/plan/tasks.md +4 -5
- package/framework/agents/plan/ux-brand-architect.md +1 -1
- package/framework/agents/plan/ux.md +1 -1
- package/framework/agents/quality/qa-implementation.md +4 -5
- package/framework/agents/quality/qa-planning.md +4 -5
- package/framework/agents/quality/qa-visual.md +4 -4
- package/framework/agents/shared/visualizer.md +1 -1
- package/framework/config.yaml +5 -5
- package/framework/constitution.md +24 -26
- package/framework/context/governance.md +6 -6
- package/framework/context/root.md +4 -3
- package/framework/data/entity-registry.yaml +3 -3
- package/framework/data/model-limits.json +5 -2
- package/framework/hooks/model-governance.js +3 -2
- package/framework/hooks/prism-engine.js +1 -1
- package/framework/i18n/en.yaml +6 -2
- package/framework/i18n/es.yaml +6 -2
- package/framework/i18n/fr.yaml +6 -2
- package/framework/i18n/pt.yaml +6 -2
- package/framework/intelligence/context-engine.md +12 -16
- package/framework/manifest.json +63 -63
- package/framework/manifest.sig +1 -1
- package/framework/orchestrator/chati-router.js +40 -6
- package/framework/orchestrator/chati.md +12 -13
- package/framework/schemas/session.schema.json +1 -1
- package/package.json +1 -1
- package/src/config/context-file-generator.js +54 -246
- package/src/config/framework-adapter.js +45 -208
- package/src/context/bracket-tracker.js +3 -3
- package/src/context/engine.js +1 -1
- package/src/installer/core.js +190 -66
- package/src/installer/provider-overlay.js +1 -1
- package/src/installer/templates.js +55 -65
- package/src/installer-v2/index.js +2 -0
- package/src/memory/magic-docs.js +45 -26
- package/src/orchestrator/cli.js +50 -45
- package/src/orchestrator/handoff-engine.js +7 -5
- package/src/orchestrator/session-manager.js +24 -3
- package/src/terminal/cli-registry.js +5 -5
- package/src/terminal/prompt-builder.js +14 -10
- package/src/terminal/run-agent.js +10 -6
- package/src/terminal/run-parallel.js +6 -2
- package/src/terminal/run-team.js +7 -2
- package/src/terminal/spawner.js +34 -42
- package/src/utils/config-parser.js +2 -2
- package/src/utils/provider-limits.js +3 -1
- package/src/wizard/feedback.js +11 -0
- package/src/wizard/i18n.js +6 -2
- package/src/wizard/index.js +17 -7
|
@@ -38,13 +38,13 @@ After EVERY agent completes and the user approves:
|
|
|
38
38
|
|
|
39
39
|
## On Activation
|
|
40
40
|
|
|
41
|
-
When the user invokes
|
|
41
|
+
When the user invokes the provider-native Chati entry point, execute this sequence:
|
|
42
42
|
|
|
43
43
|
### Step 1: Load Context
|
|
44
44
|
|
|
45
45
|
```
|
|
46
46
|
1. Read .chati/session.yaml (session state)
|
|
47
|
-
2. Read
|
|
47
|
+
2. Read .chati/project-context.md (provider-neutral project context)
|
|
48
48
|
3. Read chati.dev/constitution.md (if first run or FRESH bracket - governance rules)
|
|
49
49
|
4. Read chati.dev/config.yaml (version info, provider overrides)
|
|
50
50
|
5. Detect language from session.yaml → respond in that language
|
|
@@ -275,7 +275,7 @@ only what executes it, and it is invisible when the feature is off.
|
|
|
275
275
|
|
|
276
276
|
## Action: Autonomous Agent
|
|
277
277
|
|
|
278
|
-
These agents run in separate
|
|
278
|
+
These agents run in separate processes using the exact provider and model binding returned by the router.
|
|
279
279
|
|
|
280
280
|
1. Track context bracket internally - do NOT display it.
|
|
281
281
|
2. Check `handoff_status.valid` from JSON:
|
|
@@ -309,10 +309,9 @@ If terminal spawning fails (CLI not found, system error), fall back **silently**
|
|
|
309
309
|
6. Continue pipeline normally — the user should not notice any difference
|
|
310
310
|
```
|
|
311
311
|
|
|
312
|
-
**NOTE:** A
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
advance call is the sole forward trigger.
|
|
312
|
+
**NOTE:** A provider-native post-tool hook may also fire on handoff write when
|
|
313
|
+
supported. In interactive mode, the explicit router advance call remains the
|
|
314
|
+
portable source of truth.
|
|
316
315
|
|
|
317
316
|
If the advance response contains `"already_advanced": true`, the hook or a
|
|
318
317
|
prior call already committed the transition — proceed silently using the
|
|
@@ -350,7 +349,7 @@ Planning phase agents (detail, architect, ux) run simultaneously.
|
|
|
350
349
|
|
|
351
350
|
## Action: Spawn Team (Article XXI)
|
|
352
351
|
|
|
353
|
-
Agent Teams enable
|
|
352
|
+
Agent Teams enable peer communication through a shared task list and filesystem mailbox. A harness profile may use native sub-agents when available; otherwise the same team contract runs through Chati's provider-neutral parallel process runner.
|
|
354
353
|
|
|
355
354
|
### Step 1: Register Team in Session
|
|
356
355
|
|
|
@@ -553,7 +552,7 @@ Agent tool call:
|
|
|
553
552
|
description: "QA-Visual - visual quality validation"
|
|
554
553
|
prompt: [Read and follow .chati.dev/agents/quality/qa-visual.md.
|
|
555
554
|
Phase 1: Run visual-qa.js script on all pages.
|
|
556
|
-
Phase 2: Spawn the Visualizer sub-agent
|
|
555
|
+
Phase 2: Spawn the Visualizer sub-agent using its router-provided binding to analyze build screenshots and compare with references.
|
|
557
556
|
Phase 3-4: Verify animation libraries and brandbook compliance from report.json.
|
|
558
557
|
Scoring: Run qa-visual-score CLI for deterministic score.
|
|
559
558
|
Write your handoff to artifacts/handoffs/qa-visual-handoff.md when done.]
|
|
@@ -675,7 +674,7 @@ review, bounded rework, ClickUp projection and the Release Lane.
|
|
|
675
674
|
1. Read the immutable handoff id returned in `rail_execute`.
|
|
676
675
|
2. Run:
|
|
677
676
|
```
|
|
678
|
-
node .chati.dev/
|
|
677
|
+
node .chati.dev/orchestrator/chati-router.js rail-next --handoff-id {handoff_id}
|
|
679
678
|
```
|
|
680
679
|
3. Execute only a dependency-ready task. Use its selected provider and model
|
|
681
680
|
binding from `.chati/v2/installation.json`. Never substitute an unselected
|
|
@@ -770,7 +769,7 @@ Session lock is written by `orchestrate init` and removed by `orchestrate exit`.
|
|
|
770
769
|
1. Read `chati.dev/orchestrator/chati.md` and follow its routing logic for EVERY message
|
|
771
770
|
2. Route ALL user messages through the current agent
|
|
772
771
|
3. NEVER respond outside of the Chati.dev system - you ARE the orchestrator
|
|
773
|
-
4. NEVER act as generic
|
|
772
|
+
4. NEVER act as a generic assistant while session is locked
|
|
774
773
|
5. Off-scope requests go to Deviation Protocol, NOT outside the system
|
|
775
774
|
6. The ONLY way to exit is via explicit exit commands
|
|
776
775
|
|
|
@@ -959,7 +958,7 @@ When the independent RAIL reviewer classifies a fault:
|
|
|
959
958
|
### ALLOWED
|
|
960
959
|
- Read any file in the project (for state detection)
|
|
961
960
|
- Write to .chati/session.yaml (session state)
|
|
962
|
-
-
|
|
961
|
+
- Reconcile every enabled harness's native session-lock file
|
|
963
962
|
- Present status dashboards
|
|
964
963
|
- Generate session digests
|
|
965
964
|
|
|
@@ -996,7 +995,7 @@ Level 2 - Escalate:
|
|
|
996
995
|
3. Return to previous agent
|
|
997
996
|
|
|
998
997
|
Level 3 - Session Recovery:
|
|
999
|
-
session.yaml corrupted → attempt reconstruction from
|
|
998
|
+
session.yaml corrupted → attempt reconstruction from .chati/project-context.md + artifacts
|
|
1000
999
|
If reconstruction fails → suggest re-init preserving artifacts
|
|
1001
1000
|
|
|
1002
1001
|
Level 4 - Graceful Degradation:
|
package/package.json
CHANGED
|
@@ -1,93 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview
|
|
2
|
+
* @fileoverview Provider-native context generation from a neutral Chati core.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* context
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* Provider conventions (verified Feb 2026):
|
|
9
|
-
* - Gemini CLI: auto-loads GEMINI.md, uses .gemini/commands/*.toml, no rules/
|
|
10
|
-
* - Codex CLI: auto-loads AGENTS.md, uses .agents/skills/chati/SKILL.md for $chati
|
|
4
|
+
* The canonical project context lives at .chati/project-context.md. Harness
|
|
5
|
+
* files consume that context through their native loading mechanisms. No
|
|
6
|
+
* provider file is derived from another provider's file.
|
|
11
7
|
*/
|
|
12
8
|
|
|
13
9
|
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
14
10
|
import { join } from 'path';
|
|
15
|
-
import {
|
|
11
|
+
import { parseProviderConfig } from '../utils/config-parser.js';
|
|
16
12
|
import { resolveFrameworkDir } from '../utils/framework-dir.js';
|
|
13
|
+
import { HARNESS_PROFILES } from './framework-adapter.js';
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
// Replacement Maps
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Text replacements for Gemini CLI context file.
|
|
24
|
-
* Transforms Claude Code-specific references into Gemini CLI equivalents.
|
|
25
|
-
* Note: Gemini has no rules/ directory — references point to chati.dev/context/.
|
|
26
|
-
*/
|
|
27
|
-
const GEMINI_REPLACEMENTS = [
|
|
28
|
-
['Claude Code', 'Gemini CLI'],
|
|
29
|
-
['claude code', 'Gemini CLI'],
|
|
30
|
-
['CLAUDE.md', 'GEMINI.md'],
|
|
31
|
-
['Claude.md', 'GEMINI.md'],
|
|
32
|
-
['.claude/commands/', '.gemini/commands/'],
|
|
33
|
-
['.claude/rules/chati/', '.gemini/context/'],
|
|
34
|
-
['.claude/rules/', '.gemini/context/'],
|
|
35
|
-
['.mcp.json', '.gemini/settings.json'],
|
|
36
|
-
['claude --print', 'gemini --prompt'],
|
|
37
|
-
['claude -p', 'gemini --prompt'],
|
|
38
|
-
['CLAUDE.local.md', '.gemini/session-lock.md'],
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Sections to strip from Codex CLI context file.
|
|
43
|
-
* Codex does not support hooks, so hook-related content is removed.
|
|
44
|
-
*/
|
|
45
|
-
const CODEX_STRIP_PATTERNS = [
|
|
46
|
-
/## (?:Hooks?|Hook System)[\s\S]*?(?=\n## |\n---|\n$)/gi,
|
|
47
|
-
/- \*\*Hooks?\*\*:.*\n/gi,
|
|
48
|
-
/hook[s]? \(.*?\)/gi,
|
|
49
|
-
];
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Build text replacements for Codex CLI context file.
|
|
53
|
-
* Note: Codex has no commands/ or rules/ directories — references point to the framework dir.
|
|
54
|
-
*
|
|
55
|
-
* @param {string} [frameworkDir='chati.dev'] - Resolved framework directory name (e.g. 'chati.dev' or '.chati.dev')
|
|
56
|
-
* @returns {Array<[string, string]>} Replacement pairs
|
|
57
|
-
*/
|
|
58
|
-
function buildCodexReplacements(frameworkDir = 'chati.dev') {
|
|
59
|
-
return [
|
|
60
|
-
['Claude Code', 'Codex CLI'],
|
|
61
|
-
['claude code', 'Codex CLI'],
|
|
62
|
-
['CLAUDE.md', 'AGENTS.md'],
|
|
63
|
-
['Claude.md', 'AGENTS.md'],
|
|
64
|
-
['.claude/commands/', `${frameworkDir}/orchestrator/`],
|
|
65
|
-
['.claude/rules/chati/', `${frameworkDir}/context/`],
|
|
66
|
-
['.claude/rules/', `${frameworkDir}/context/`],
|
|
67
|
-
['.mcp.json', '.codex/config.toml'],
|
|
68
|
-
['claude --print', 'codex exec'],
|
|
69
|
-
['claude -p', 'codex exec'],
|
|
70
|
-
['CLAUDE.local.md', 'AGENTS.override.md'],
|
|
71
|
-
];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Convert the interactive slash command without touching filesystem paths such
|
|
76
|
-
* as `.chati.dev/orchestrator/chati.md`.
|
|
77
|
-
*/
|
|
78
|
-
function adaptCodexInvocation(content) {
|
|
79
|
-
return content.replace(/(?<![\w/])\/chati(?=\s|$|[`'".,;:!?)]|\b)/gm, '$chati');
|
|
80
|
-
}
|
|
15
|
+
export const PROJECT_CONTEXT_PATH = join('.chati', 'project-context.md');
|
|
81
16
|
|
|
82
|
-
|
|
83
|
-
// Generators
|
|
84
|
-
// ---------------------------------------------------------------------------
|
|
17
|
+
const CONTEXT_FILES = ['root.md', 'governance.md', 'protocols.md', 'quality.md'];
|
|
85
18
|
|
|
86
|
-
/**
|
|
87
|
-
* @import directives appended to GEMINI.md.
|
|
88
|
-
* Gemini CLI resolves @import automatically, loading the full governance
|
|
89
|
-
* context chain + session lock — equivalent to Claude Code's rules/ + CLAUDE.local.md.
|
|
90
|
-
*/
|
|
91
19
|
const GEMINI_IMPORTS = [
|
|
92
20
|
'@import .gemini/context/root.md',
|
|
93
21
|
'@import .gemini/context/governance.md',
|
|
@@ -96,207 +24,87 @@ const GEMINI_IMPORTS = [
|
|
|
96
24
|
'@import .gemini/session-lock.md',
|
|
97
25
|
];
|
|
98
26
|
|
|
99
|
-
/**
|
|
100
|
-
* Generate GEMINI.md content from CLAUDE.md content.
|
|
101
|
-
*
|
|
102
|
-
* Adapts the content by replacing Claude Code-specific references with
|
|
103
|
-
* Gemini CLI equivalents, then appends @import directives so Gemini CLI
|
|
104
|
-
* auto-loads governance rules and session lock (context parity with Claude).
|
|
105
|
-
*
|
|
106
|
-
* @param {string} content - Raw CLAUDE.md content
|
|
107
|
-
* @returns {string} Adapted content for GEMINI.md
|
|
108
|
-
*/
|
|
27
|
+
/** Generate Gemini's native root context from the neutral Chati context. */
|
|
109
28
|
export function generateGeminiMd(content) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// Prepend a header noting this file is auto-generated
|
|
117
|
-
const header = [
|
|
118
|
-
'<!-- Auto-generated by chati.dev from CLAUDE.md — do not edit manually -->',
|
|
29
|
+
return [
|
|
30
|
+
'<!-- Auto-generated by chati.dev from .chati/project-context.md. -->',
|
|
31
|
+
'',
|
|
32
|
+
content.trim(),
|
|
33
|
+
'',
|
|
34
|
+
...GEMINI_IMPORTS,
|
|
119
35
|
'',
|
|
120
36
|
].join('\n');
|
|
121
|
-
|
|
122
|
-
// Append @import directives for context parity
|
|
123
|
-
const imports = '\n' + GEMINI_IMPORTS.join('\n') + '\n';
|
|
124
|
-
|
|
125
|
-
return header + result + imports;
|
|
126
37
|
}
|
|
127
38
|
|
|
128
39
|
/**
|
|
129
|
-
* Generate AGENTS.md
|
|
130
|
-
*
|
|
131
|
-
* Simplifies the content for Codex CLI: strips hook references,
|
|
132
|
-
* replaces CLI-specific paths, and produces a leaner context file
|
|
133
|
-
* focused on code execution. When contextFiles are provided, inlines
|
|
134
|
-
* governance/protocols/quality for full context parity with Claude Code.
|
|
135
|
-
*
|
|
136
|
-
* @param {string} content - Raw CLAUDE.md content
|
|
137
|
-
* @param {object} [contextFiles] - Optional inline context { root, governance, protocols, quality }
|
|
138
|
-
* @param {string} [frameworkDir='chati.dev'] - Resolved framework directory name
|
|
139
|
-
* @returns {string} Adapted content for AGENTS.md
|
|
40
|
+
* Generate the shared AGENTS.md consumed by Codex and Grok. Governance is
|
|
41
|
+
* inlined because these harnesses do not share Gemini's import mechanism.
|
|
140
42
|
*/
|
|
141
|
-
export function generateAgentsMd(content, contextFiles = null,
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
// Strip hook-related sections (Codex has no hooks support)
|
|
146
|
-
for (const pattern of CODEX_STRIP_PATTERNS) {
|
|
147
|
-
result = result.replace(pattern, '');
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Apply text replacements
|
|
151
|
-
for (const [search, replace] of replacements) {
|
|
152
|
-
result = result.replaceAll(search, replace);
|
|
153
|
-
}
|
|
154
|
-
result = adaptCodexInvocation(result);
|
|
155
|
-
|
|
156
|
-
// Clean up any double blank lines left by stripping
|
|
157
|
-
result = result.replace(/\n{3,}/g, '\n\n');
|
|
158
|
-
|
|
159
|
-
// Prepend a header noting this file is auto-generated
|
|
160
|
-
const header = [
|
|
161
|
-
'<!-- Auto-generated by chati.dev from CLAUDE.md — do not edit manually -->',
|
|
43
|
+
export function generateAgentsMd(content, contextFiles = null, enabledProviders = []) {
|
|
44
|
+
const sections = [
|
|
45
|
+
'<!-- Auto-generated by chati.dev from .chati/project-context.md. -->',
|
|
162
46
|
'',
|
|
163
|
-
|
|
47
|
+
content.trim(),
|
|
48
|
+
];
|
|
164
49
|
|
|
165
|
-
|
|
50
|
+
const runtimePointers = enabledProviders
|
|
51
|
+
.filter((provider) => provider === 'codex' || provider === 'grok')
|
|
52
|
+
.map((provider) => `- **${provider === 'codex' ? 'Codex' : 'Grok'} runtime lock**: \`${HARNESS_PROFILES[provider].sessionLockFile}\``);
|
|
53
|
+
if (runtimePointers.length > 0) {
|
|
54
|
+
sections.push('', '## Native Runtime State', '', ...runtimePointers);
|
|
55
|
+
}
|
|
166
56
|
|
|
167
|
-
// Inline context files for full governance parity (Codex has no @import)
|
|
168
57
|
if (contextFiles) {
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
if (fileContent) {
|
|
172
|
-
// Adapt context for Codex (replace Claude-specific refs)
|
|
173
|
-
let adapted = fileContent;
|
|
174
|
-
for (const [search, replace] of replacements) {
|
|
175
|
-
adapted = adapted.replaceAll(search, replace);
|
|
176
|
-
}
|
|
177
|
-
adapted = adaptCodexInvocation(adapted);
|
|
178
|
-
sections.push(adapted.trim());
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
if (sections.length > 0) {
|
|
182
|
-
result += '\n---\n\n' + sections.join('\n\n---\n\n') + '\n';
|
|
58
|
+
for (const fileContent of Object.values(contextFiles)) {
|
|
59
|
+
if (fileContent) sections.push('', '---', '', fileContent.trim());
|
|
183
60
|
}
|
|
184
61
|
}
|
|
185
62
|
|
|
186
|
-
return
|
|
63
|
+
return sections.join('\n').replace(/\n{3,}/g, '\n\n').trimEnd() + '\n';
|
|
187
64
|
}
|
|
188
65
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
// ---------------------------------------------------------------------------
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Context file names that provide governance parity across CLIs.
|
|
195
|
-
* These are read from chati.dev/context/ and inlined into AGENTS.md for Codex.
|
|
196
|
-
*/
|
|
197
|
-
const CONTEXT_FILES = ['root.md', 'governance.md', 'protocols.md', 'quality.md'];
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Generate context files for all enabled alternative providers.
|
|
201
|
-
*
|
|
202
|
-
* Reads config.yaml to determine which providers are enabled, reads
|
|
203
|
-
* CLAUDE.md from the project root, and writes the appropriate context
|
|
204
|
-
* files (GEMINI.md, AGENTS.md) when their providers are active.
|
|
205
|
-
*
|
|
206
|
-
* For Codex, governance context files are inlined into AGENTS.md to provide
|
|
207
|
-
* the same rules awareness that Claude gets from .claude/rules/chati/.
|
|
208
|
-
*
|
|
209
|
-
* @param {string} projectDir - Project root directory
|
|
210
|
-
* @param {string} [baseContent] - Optional base content (used when CLAUDE.md doesn't exist on disk)
|
|
211
|
-
* @returns {{ generated: string[], skipped: string[], warning: string|null }}
|
|
212
|
-
*/
|
|
213
|
-
export function generateContextFiles(projectDir, baseContent = null) {
|
|
66
|
+
/** Regenerate every enabled harness context from the neutral canonical file. */
|
|
67
|
+
export function generateContextFiles(projectDir, neutralContent = null) {
|
|
214
68
|
const result = { generated: [], skipped: [], warning: null };
|
|
69
|
+
const canonicalPath = join(projectDir, PROJECT_CONTEXT_PATH);
|
|
215
70
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (!existsSync(claudeMdPath)) {
|
|
221
|
-
result.warning = 'CLAUDE.md not found and no base content provided — skipping context file generation';
|
|
71
|
+
let content = neutralContent;
|
|
72
|
+
if (!content) {
|
|
73
|
+
if (!existsSync(canonicalPath)) {
|
|
74
|
+
result.warning = `${PROJECT_CONTEXT_PATH} not found and no neutral content provided`;
|
|
222
75
|
return result;
|
|
223
76
|
}
|
|
224
|
-
|
|
77
|
+
content = readFileSync(canonicalPath, 'utf-8');
|
|
225
78
|
}
|
|
226
79
|
|
|
227
|
-
|
|
228
|
-
const enabledProviders = resolveEnabledProviders(projectDir);
|
|
229
|
-
|
|
230
|
-
// Read context files for inline injection (Codex)
|
|
80
|
+
const { enabled } = parseProviderConfig(projectDir);
|
|
231
81
|
const contextFiles = readContextFilesFromDisk(projectDir);
|
|
232
82
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
filename: 'GEMINI.md',
|
|
240
|
-
generate: (content) => generateGeminiMd(content),
|
|
241
|
-
},
|
|
242
|
-
codex: {
|
|
243
|
-
filename: 'AGENTS.md',
|
|
244
|
-
generate: (content) => generateAgentsMd(content, contextFiles, fwDir),
|
|
245
|
-
},
|
|
246
|
-
};
|
|
83
|
+
if (enabled.includes('gemini')) {
|
|
84
|
+
writeFileSync(join(projectDir, 'GEMINI.md'), generateGeminiMd(content), 'utf-8');
|
|
85
|
+
result.generated.push('GEMINI.md');
|
|
86
|
+
} else {
|
|
87
|
+
result.skipped.push('GEMINI.md');
|
|
88
|
+
}
|
|
247
89
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
result.generated.push(config.filename);
|
|
254
|
-
} else {
|
|
255
|
-
result.skipped.push(config.filename);
|
|
256
|
-
}
|
|
90
|
+
if (enabled.includes('codex') || enabled.includes('grok')) {
|
|
91
|
+
writeFileSync(join(projectDir, 'AGENTS.md'), generateAgentsMd(content, contextFiles, enabled), 'utf-8');
|
|
92
|
+
result.generated.push('AGENTS.md');
|
|
93
|
+
} else {
|
|
94
|
+
result.skipped.push('AGENTS.md');
|
|
257
95
|
}
|
|
258
96
|
|
|
259
97
|
return result;
|
|
260
98
|
}
|
|
261
99
|
|
|
262
|
-
/**
|
|
263
|
-
* Read context files from chati.dev/context/ for inline injection.
|
|
264
|
-
* Returns null if no context files found (backward compat).
|
|
265
|
-
*
|
|
266
|
-
* @param {string} projectDir - Project root directory
|
|
267
|
-
* @returns {object|null} { root, governance, protocols, quality } or null
|
|
268
|
-
*/
|
|
269
100
|
function readContextFilesFromDisk(projectDir) {
|
|
270
|
-
|
|
271
|
-
const newDir = join(projectDir, '.chati.dev', 'context');
|
|
272
|
-
const legacyDir = join(projectDir, 'chati.dev', 'context');
|
|
273
|
-
const contextDir = existsSync(newDir) ? newDir : legacyDir;
|
|
101
|
+
const contextDir = join(projectDir, resolveFrameworkDir(projectDir), 'context');
|
|
274
102
|
if (!existsSync(contextDir)) return null;
|
|
275
103
|
|
|
276
104
|
const files = {};
|
|
277
|
-
let found = false;
|
|
278
105
|
for (const file of CONTEXT_FILES) {
|
|
279
106
|
const filePath = join(contextDir, file);
|
|
280
|
-
if (existsSync(filePath))
|
|
281
|
-
const key = file.replace('.md', '');
|
|
282
|
-
files[key] = readFileSync(filePath, 'utf-8');
|
|
283
|
-
found = true;
|
|
284
|
-
}
|
|
107
|
+
if (existsSync(filePath)) files[file.replace('.md', '')] = readFileSync(filePath, 'utf-8');
|
|
285
108
|
}
|
|
286
|
-
return
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// ---------------------------------------------------------------------------
|
|
290
|
-
// Helpers
|
|
291
|
-
// ---------------------------------------------------------------------------
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* Resolve which alternative providers are enabled from config.yaml.
|
|
295
|
-
* Delegates to shared config parser utility.
|
|
296
|
-
*
|
|
297
|
-
* @param {string} projectDir - Project root directory
|
|
298
|
-
* @returns {string[]} List of enabled non-Claude provider names
|
|
299
|
-
*/
|
|
300
|
-
function resolveEnabledProviders(projectDir) {
|
|
301
|
-
return getEnabledNonClaudeProviders(projectDir);
|
|
109
|
+
return Object.keys(files).length > 0 ? files : null;
|
|
302
110
|
}
|