chati-dev 3.0.5 → 3.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chati-dev",
3
- "version": "3.0.5",
3
+ "version": "3.1.0",
4
4
  "description": "AI-Powered Multi-Agent Orchestration System — Structured vibe coding for Full Stack Development",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,210 @@
1
+ /**
2
+ * @fileoverview Framework file adapter for multi-CLI support.
3
+ *
4
+ * Transforms Claude Code-specific framework files (orchestrator, agents,
5
+ * constitution, context) into provider-native versions at install time.
6
+ * Each LLM reads instructions written for it — zero runtime translation.
7
+ *
8
+ * Constitution Article XIX — framework files are pre-adapted per provider.
9
+ */
10
+
11
+ import { PROVIDER_MODEL_MAPS } from '../installer/templates.js';
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Adaptable Files
15
+ // ---------------------------------------------------------------------------
16
+
17
+ /**
18
+ * Set of framework file paths (relative to chati.dev/) that need
19
+ * provider-specific adaptation when the selected provider is not Claude.
20
+ */
21
+ export const ADAPTABLE_FILES = new Set([
22
+ 'constitution.md',
23
+ 'orchestrator/chati.md',
24
+ 'agents/discover/greenfield-wu.md',
25
+ 'agents/discover/brownfield-wu.md',
26
+ 'agents/discover/brief.md',
27
+ 'agents/plan/detail.md',
28
+ 'agents/plan/architect.md',
29
+ 'agents/plan/ux.md',
30
+ 'agents/plan/phases.md',
31
+ 'agents/plan/tasks.md',
32
+ 'agents/quality/qa-planning.md',
33
+ 'agents/quality/qa-implementation.md',
34
+ 'agents/build/dev.md',
35
+ 'agents/deploy/devops.md',
36
+ 'context/governance.md',
37
+ 'context/root.md',
38
+ ]);
39
+
40
+ // ---------------------------------------------------------------------------
41
+ // Provider Metadata
42
+ // ---------------------------------------------------------------------------
43
+
44
+ const PROVIDER_META = {
45
+ claude: {
46
+ cliName: 'Claude Code',
47
+ contextFile: 'CLAUDE.md',
48
+ localFile: 'CLAUDE.local.md',
49
+ },
50
+ gemini: {
51
+ cliName: 'Gemini CLI',
52
+ contextFile: 'GEMINI.md',
53
+ localFile: '.chati/session.yaml',
54
+ },
55
+ codex: {
56
+ cliName: 'Codex CLI',
57
+ contextFile: 'AGENTS.md',
58
+ localFile: '.chati/session.yaml',
59
+ },
60
+ copilot: {
61
+ cliName: 'GitHub Copilot CLI',
62
+ contextFile: 'AGENTS.md',
63
+ localFile: '.chati/session.yaml',
64
+ },
65
+ };
66
+
67
+ // ---------------------------------------------------------------------------
68
+ // Replacement Configuration Builder
69
+ // ---------------------------------------------------------------------------
70
+
71
+ /**
72
+ * Build the complete replacement config for a given provider.
73
+ * Returns { strings, patterns } where:
74
+ * - strings: ordered [search, replace] pairs for replaceAll
75
+ * - patterns: { pattern, replacement } objects for regex replace
76
+ *
77
+ * Ordering: most-specific strings first to prevent partial matches.
78
+ */
79
+ function buildReplacementConfig(provider) {
80
+ const meta = PROVIDER_META[provider];
81
+ const modelMap = PROVIDER_MODEL_MAPS[provider];
82
+
83
+ if (!meta || !modelMap) {
84
+ throw new Error(`Unknown provider: ${provider}`);
85
+ }
86
+
87
+ const { cliName, contextFile, localFile } = meta;
88
+ const { deep, light, minimal } = modelMap;
89
+
90
+ // --- String replacements (ordered, most specific first) ---
91
+ const strings = [
92
+ // File references (most specific first)
93
+ ['CLAUDE.local.md', localFile],
94
+ ['CLAUDE.md', contextFile],
95
+ ['.claude/rules/chati/', 'chati.dev/context/'],
96
+
97
+ // Provider name (most specific first)
98
+ ['Claude Code processes', `${cliName} processes`],
99
+ ['Claude Code CLI', cliName],
100
+ ['Claude Code', cliName],
101
+
102
+ // Behavioral
103
+ ['NEVER act as generic Claude', 'NEVER act as generic AI assistant'],
104
+
105
+ // /model commands (specific model names)
106
+ ['/model opus', `/model ${deep}`],
107
+ ['/model sonnet', `/model ${light}`],
108
+ ['/model haiku', `/model ${minimal}`],
109
+ ];
110
+
111
+ // --- Regex patterns for model names in structured contexts ---
112
+ const patterns = [
113
+ // Identity section: **Model**: opus | ...
114
+ { pattern: /(\*\*Model\*\*:\s*)opus/g, replacement: `$1${deep}` },
115
+ { pattern: /(\*\*Model\*\*:\s*)sonnet/g, replacement: `$1${light}` },
116
+ { pattern: /(\*\*Model\*\*:\s*)haiku/g, replacement: `$1${minimal}` },
117
+
118
+ // YAML-like blocks: default: sonnet, upgrade_to: opus, etc.
119
+ { pattern: /(default:\s*)opus/g, replacement: `$1${deep}` },
120
+ { pattern: /(default:\s*)sonnet/g, replacement: `$1${light}` },
121
+ { pattern: /(default:\s*)haiku/g, replacement: `$1${minimal}` },
122
+ { pattern: /(upgrade_to:\s*)opus/g, replacement: `$1${deep}` },
123
+ { pattern: /(upgrade_to:\s*)sonnet/g, replacement: `$1${light}` },
124
+ { pattern: /(downgrade_to:\s*)haiku/g, replacement: `$1${minimal}` },
125
+ { pattern: /(downgrade_to:\s*)sonnet/g, replacement: `$1${light}` },
126
+ { pattern: /(recommended:\s*)opus/g, replacement: `$1${deep}` },
127
+ { pattern: /(recommended:\s*)sonnet/g, replacement: `$1${light}` },
128
+ { pattern: /(actual:\s*)opus/g, replacement: `$1${deep}` },
129
+ { pattern: /(actual:\s*)sonnet/g, replacement: `$1${light}` },
130
+ { pattern: /(model:\s*)opus/g, replacement: `$1${deep}` },
131
+ { pattern: /(model:\s*)sonnet/g, replacement: `$1${light}` },
132
+
133
+ // Table cells: | opus | or | sonnet | or | haiku |
134
+ { pattern: /(\|\s*)opus(\s*\|)/g, replacement: `$1${deep}$2` },
135
+ { pattern: /(\|\s*)sonnet(\s*\|)/g, replacement: `$1${light}$2` },
136
+ { pattern: /(\|\s*)haiku(\s*\|)/g, replacement: `$1${minimal}$2` },
137
+
138
+ // Upgrade/downgrade conditions in prose: "sonnet if ...", "opus if ..."
139
+ { pattern: /opus if /g, replacement: `${deep} if ` },
140
+ { pattern: /sonnet if /g, replacement: `${light} if ` },
141
+ { pattern: /haiku if /g, replacement: `${minimal} if ` },
142
+
143
+ // Constitution/governance model tier definitions
144
+ { pattern: /\*\*opus\*\*:/g, replacement: `**${deep}**:` },
145
+ { pattern: /\*\*sonnet\*\*:/g, replacement: `**${light}**:` },
146
+ { pattern: /\*\*haiku\*\*:/g, replacement: `**${minimal}**:` },
147
+ { pattern: /opus \(deep reasoning\)/g, replacement: `${deep} (deep reasoning)` },
148
+ { pattern: /sonnet \(structured\)/g, replacement: `${light} (structured)` },
149
+ { pattern: /haiku \(lightweight\)/g, replacement: `${minimal} (lightweight)` },
150
+
151
+ // Provider field in agent Identity: claude (default) with optional conditional
152
+ { pattern: /- \*\*Provider\*\*: claude \(default\)(?:\s*\|[^\n]*)?/g,
153
+ replacement: `- **Provider**: ${provider} (default)` },
154
+
155
+ // Provider in table rows: | claude (default) | or | claude (default) | gemini (...) |
156
+ { pattern: /(\|\s*)claude \(default\)(?:\s*\|[^|\n]*)?\s*(\|)/g,
157
+ replacement: `$1${provider} (default) $2` },
158
+
159
+ // "claude" as primary provider in prose
160
+ { pattern: /primary provider \(claude\)/g, replacement: `primary provider (${provider})` },
161
+ { pattern: /fallback_provider: claude/g, replacement: `fallback_provider: ${provider}` },
162
+ { pattern: /fall back to the primary provider \(claude\)/g,
163
+ replacement: `fall back to the primary provider (${provider})` },
164
+ { pattern: /primary provider: claude/g, replacement: `primary provider: ${provider}` },
165
+
166
+ // /chati providers display: swap PRIMARY designation
167
+ // Note: "Claude Code CLI" may already be replaced by string replacements, so match any trailing text
168
+ { pattern: /claude\s+PRIMARY\s+Enabled\s+.+/g,
169
+ replacement: `${provider} PRIMARY Enabled ${cliName}` },
170
+
171
+ // CLAUDE.md Update sections in agents
172
+ { pattern: /### CLAUDE\.md Update/g, replacement: `### ${contextFile} Update` },
173
+ { pattern: /### CLAUDE\.md Final Update/g, replacement: `### ${contextFile} Final Update` },
174
+ { pattern: /Update CLAUDE\.md/g, replacement: `Update ${contextFile}` },
175
+ ];
176
+
177
+ return { strings, patterns };
178
+ }
179
+
180
+ // ---------------------------------------------------------------------------
181
+ // Main Adapter Function
182
+ // ---------------------------------------------------------------------------
183
+
184
+ /**
185
+ * Adapt a single framework file for the target provider.
186
+ *
187
+ * @param {string} content - Original file content (Claude Code version)
188
+ * @param {string} filePath - Relative path within chati.dev/ (e.g. 'orchestrator/chati.md')
189
+ * @param {string} provider - Target provider: 'gemini', 'codex', 'copilot'
190
+ * @returns {string} Adapted content for the target provider
191
+ */
192
+ export function adaptFrameworkFile(content, filePath, provider) {
193
+ if (provider === 'claude') return content;
194
+ if (!content) return content;
195
+
196
+ const config = buildReplacementConfig(provider);
197
+ let result = content;
198
+
199
+ // 1. Apply ordered string replacements (most specific first)
200
+ for (const [search, replace] of config.strings) {
201
+ result = result.replaceAll(search, replace);
202
+ }
203
+
204
+ // 2. Apply regex patterns (model names + structured contexts)
205
+ for (const { pattern, replacement } of config.patterns) {
206
+ result = result.replace(pattern, replacement);
207
+ }
208
+
209
+ return result;
210
+ }
@@ -5,6 +5,7 @@ import { IDE_CONFIGS } from '../config/ide-configs.js';
5
5
  import { generateClaudeMCPConfig } from '../config/mcp-configs.js';
6
6
  import { generateSessionYaml, generateConfigYaml, generateClaudeMd, generateClaudeLocalMd, generateCodexSkill, generateGeminiRouter, generateCopilotAgent } from './templates.js';
7
7
  import { generateContextFiles } from '../config/context-file-generator.js';
8
+ import { adaptFrameworkFile, ADAPTABLE_FILES } from '../config/framework-adapter.js';
8
9
  import { verifyManifest } from './manifest.js';
9
10
 
10
11
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -86,8 +87,8 @@ export async function installFramework(config) {
86
87
  createDir(join(memoriesBase, dir));
87
88
  }
88
89
 
89
- // Copy framework files from source
90
- copyFrameworkFiles(frameworkDir);
90
+ // Copy framework files from source (adapted for non-Claude providers)
91
+ copyFrameworkFiles(frameworkDir, llmProvider || 'claude');
91
92
 
92
93
  // Write config.yaml
93
94
  writeFileSync(
@@ -132,7 +133,7 @@ export async function installFramework(config) {
132
133
  /**
133
134
  * Copy framework files from the Chati.dev source directory
134
135
  */
135
- function copyFrameworkFiles(destDir) {
136
+ function copyFrameworkFiles(destDir, provider = 'claude') {
136
137
  if (!existsSync(FRAMEWORK_SOURCE)) return;
137
138
 
138
139
  const filesToCopy = [
@@ -241,7 +242,15 @@ function copyFrameworkFiles(destDir) {
241
242
 
242
243
  if (existsSync(src)) {
243
244
  createDir(dirname(dest));
244
- copyFileSync(src, dest);
245
+
246
+ if (provider !== 'claude' && ADAPTABLE_FILES.has(file)) {
247
+ // Non-Claude provider: read, adapt, write
248
+ const content = readFileSync(src, 'utf-8');
249
+ writeFileSync(dest, adaptFrameworkFile(content, file, provider), 'utf-8');
250
+ } else {
251
+ // Claude or non-adaptable: direct copy
252
+ copyFileSync(src, dest);
253
+ }
245
254
  }
246
255
  }
247
256
  }
@@ -52,7 +52,7 @@ export function generateSessionYaml(config) {
52
52
  * Deep reasoning agents (architect, qa, dev, detail, brownfield-wu) get the top model.
53
53
  * Lightweight agents (brief, phases, ux, greenfield-wu, devops, orchestrator) get the fast model.
54
54
  */
55
- const PROVIDER_MODEL_MAPS = {
55
+ export const PROVIDER_MODEL_MAPS = {
56
56
  claude: {
57
57
  deep: 'opus', light: 'sonnet', minimal: 'haiku',
58
58
  agents: {
@@ -180,30 +180,18 @@ ALL responses MUST be in this language. This overrides any global setting.
180
180
 
181
181
  If session.yaml does not exist or has no language field, default to English.
182
182
 
183
- ## CRITICAL — Provider Context Mapping
184
-
185
- The orchestrator was written for Claude Code. You are running on **Codex CLI**.
186
- When the orchestrator references Claude-specific files, use these equivalents:
187
-
188
- | Orchestrator says | You use instead |
189
- |-------------------|-----------------|
190
- | \`CLAUDE.md\` | \`AGENTS.md\` |
191
- | \`CLAUDE.local.md\` | \`.chati/session.yaml\` (session state only) |
192
- | \`.claude/rules/chati/\` | \`chati.dev/context/\` |
193
- | \`.claude/commands/\` | \`.agents/skills/\` |
194
- | \`/chati\` | \`$chati\` |
195
-
196
- **NEVER create or reference CLAUDE.md, CLAUDE.local.md, or .claude/ directories.**
197
-
198
183
  ## Load
199
184
 
185
+ The orchestrator and all agent files are **pre-configured for Codex CLI**.
186
+ No translation needed — follow all instructions as written.
187
+
200
188
  Read and execute the full orchestrator at \`chati.dev/orchestrator/chati.md\`.
201
189
 
202
- Apply the Provider Context Mapping above when following the orchestrator instructions.
190
+ **NEVER create or reference CLAUDE.md, CLAUDE.local.md, or .claude/ directories.**
203
191
 
204
192
  **Context to pass:**
205
193
  - \`.chati/session.yaml\` (session state — includes language)
206
- - \`AGENTS.md\` (project context — auto-generated from base content)
194
+ - \`AGENTS.md\` (project context)
207
195
  - \`chati.dev/artifacts/handoffs/\` (latest handoff)
208
196
  - \`chati.dev/config.yaml\` (version info)
209
197
 
@@ -221,27 +209,21 @@ export function generateGeminiRouter() {
221
209
  return `description = "Activate Chati.dev orchestrator"
222
210
  prompt = """
223
211
  CRITICAL — Language Override:
224
- Read \`.chati/session.yaml\` field \`language\` BEFORE anything else.
212
+ Read .chati/session.yaml field "language" BEFORE anything else.
225
213
  ALL responses MUST be in this language (en, pt, es, fr).
226
214
  If session.yaml does not exist or has no language field, default to English.
227
215
 
228
- CRITICAL Provider Context Mapping:
229
- The orchestrator was written for Claude Code. You are running on Gemini CLI.
230
- When the orchestrator references Claude-specific files, use these equivalents:
231
- - CLAUDE.md -> GEMINI.md
232
- - CLAUDE.local.md -> .chati/session.yaml (session state only)
233
- - .claude/rules/chati/ -> chati.dev/context/
234
- - .claude/commands/ -> .gemini/commands/
235
- NEVER create or reference CLAUDE.md, CLAUDE.local.md, or .claude/ directories.
216
+ The orchestrator and all agent files are pre-configured for Gemini CLI.
217
+ No translation needed follow all instructions as written.
236
218
 
237
- Read and execute the full orchestrator at \`chati.dev/orchestrator/chati.md\`.
238
- Apply the Provider Context Mapping above when following instructions.
219
+ Read and execute the full orchestrator at chati.dev/orchestrator/chati.md.
220
+ NEVER create or reference CLAUDE.md, CLAUDE.local.md, or .claude/ directories.
239
221
 
240
222
  Context to load:
241
- - \`.chati/session.yaml\` (session state — includes language)
242
- - \`GEMINI.md\` (project context — auto-generated)
243
- - \`chati.dev/artifacts/handoffs/\` (latest handoff)
244
- - \`chati.dev/config.yaml\` (version info)
223
+ - .chati/session.yaml (session state — includes language)
224
+ - GEMINI.md (project context)
225
+ - chati.dev/artifacts/handoffs/ (latest handoff)
226
+ - chati.dev/config.yaml (version info)
245
227
 
246
228
  User input: {{args}}
247
229
  """
@@ -273,26 +255,14 @@ ALL responses MUST be in this language. This overrides any global setting.
273
255
 
274
256
  If session.yaml does not exist or has no language field, default to English.
275
257
 
276
- ## CRITICAL — Provider Context Mapping
277
-
278
- The orchestrator was written for Claude Code. You are running on **GitHub Copilot CLI**.
279
- When the orchestrator references Claude-specific files, use these equivalents:
280
-
281
- | Orchestrator says | You use instead |
282
- |-------------------|-----------------|
283
- | \`CLAUDE.md\` | \`AGENTS.md\` |
284
- | \`CLAUDE.local.md\` | \`.chati/session.yaml\` (session state only) |
285
- | \`.claude/rules/chati/\` | \`chati.dev/context/\` |
286
- | \`.claude/commands/\` | \`.github/agents/\` |
287
- | \`/chati\` | \`@chati\` |
288
-
289
- **NEVER create or reference CLAUDE.md, CLAUDE.local.md, or .claude/ directories.**
290
-
291
258
  ## Load
292
259
 
260
+ The orchestrator and all agent files are **pre-configured for GitHub Copilot CLI**.
261
+ No translation needed — follow all instructions as written.
262
+
293
263
  Read and execute the full orchestrator at \`chati.dev/orchestrator/chati.md\`.
294
264
 
295
- Apply the Provider Context Mapping above when following the orchestrator instructions.
265
+ **NEVER create or reference CLAUDE.md, CLAUDE.local.md, or .claude/ directories.**
296
266
 
297
267
  **Context to pass:**
298
268
  - \`.chati/session.yaml\` (session state — includes language)