sinapse-ai 1.25.0 → 1.25.2
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/.claude/settings.json +170 -0
- package/.codex/catalog.json +1 -1
- package/.codex/scripts/sinapse-codex.js +0 -5
- package/.codex/scripts/sync-codex-native.js +4 -37
- package/.codex/scripts/validate-codex-native.js +13 -23
- package/.codex/tasks/onboard-sinapse-codex.md +1 -1
- package/.sinapse-ai/data/entity-registry.yaml +44 -18
- package/.sinapse-ai/install-manifest.yaml +3 -3
- package/CHANGELOG.md +8 -14
- package/README.en.md +38 -30
- package/README.md +33 -25
- package/bin/cli.js +8 -1
- package/bin/commands/help.js +3 -2
- package/bin/commands/install.js +25 -14
- package/bin/commands/status.js +4 -3
- package/bin/commands/uninstall.js +216 -51
- package/bin/commands/update.js +8 -4
- package/bin/lib/global-provider-adapters.js +73 -10
- package/bin/lib/provider-parity.js +22 -0
- package/bin/postinstall.js +11 -11
- package/docs/framework/codex-parity/codex-integration-process.md +6 -7
- package/docs/framework/codex-parity/codex-native-runtime-v2.md +8 -8
- package/docs/framework/codex-parity/codex-parity-program.md +4 -4
- package/docs/framework/codex-parity/codex-total-parity-orchestration-plan.md +1 -1
- package/docs/getting-started.md +13 -5
- package/docs/guides/codex-config.md +35 -51
- package/docs/guides/development-setup.md +1 -2
- package/docs/guides/ide-integration.md +28 -29
- package/docs/guides/project-status-feature.md +35 -55
- package/docs/guides/quality-gates.md +2 -2
- package/docs/guides/user-guide.md +21 -10
- package/docs/ide-integration.md +2 -2
- package/docs/installation/README.md +4 -4
- package/docs/installation/faq.md +84 -70
- package/docs/installation/linux.md +11 -14
- package/docs/installation/macos.md +10 -4
- package/docs/installation/troubleshooting.md +11 -5
- package/docs/installation/v4-quick-start.md +14 -14
- package/docs/installation/windows.md +11 -15
- package/docs/pt/contributing.md +1 -1
- package/docs/pt/guides/development-setup.md +1 -2
- package/docs/pt/guides/project-status-feature.md +35 -55
- package/docs/pt/guides/quality-gates.md +2 -2
- package/docs/pt/guides/user-guide.md +21 -11
- package/docs/pt/ide-integration.md +6 -6
- package/docs/pt/installation/README.md +2 -4
- package/docs/pt/installation/faq.md +54 -89
- package/docs/pt/installation/linux.md +9 -27
- package/docs/pt/installation/macos.md +8 -12
- package/docs/pt/installation/troubleshooting.md +11 -10
- package/docs/pt/installation/v4-quick-start.md +17 -18
- package/docs/pt/installation/windows.md +8 -21
- package/docs/pt/platforms/claude-code.md +4 -4
- package/docs/sinapse-agent-flows/analyst-system.md +1 -1
- package/docs/sinapse-agent-flows/architect-system.md +1 -1
- package/docs/sinapse-agent-flows/data-engineer-system.md +1 -1
- package/docs/sinapse-agent-flows/dev-system.md +1 -1
- package/docs/sinapse-agent-flows/pm-system.md +1 -1
- package/docs/sinapse-agent-flows/qa-system.md +1 -1
- package/docs/sinapse-agent-flows/sm-system.md +1 -1
- package/docs/sinapse-agent-flows/snps-orqx-system.md +1 -1
- package/docs/sinapse-agent-flows/squad-creator-system.md +2 -2
- package/docs/sinapse-agent-flows/ux-design-expert-system.md +1 -1
- package/docs/troubleshooting.md +9 -7
- package/package.json +21 -16
- package/packages/installer/src/config/ide-configs.js +1 -1
- package/packages/installer/src/installer/sinapse-ai-installer.js +282 -10
- package/packages/installer/src/migrations/legacy-claude-agent-command-hashes.json +36 -0
- package/packages/installer/src/migrations/legacy-codex-native-skill-hashes.json +42 -0
- package/packages/installer/src/updater/index.js +24 -7
- package/packages/installer/src/wizard/ide-config-generator.js +4 -0
- package/packages/installer/src/wizard/index.js +6 -2
- package/scripts/validate-article-vii.js +305 -20
- package/scripts/validate-codex-command-registry.js +101 -0
- package/scripts/validate-install-docs.js +87 -3
- package/scripts/validate-provider-adapters.js +117 -1
- package/squads/claude-code-mastery/agents/skill-craftsman.md +2 -2
- package/squads/claude-code-mastery/knowledge-base/skill-creation-patterns.md +1 -1
- package/squads/squad-design/agents/ux-designer.md +1 -1
- package/.codex/skills/sinapse/SKILL.md +0 -10
- package/.codex/skills/sinapse-agent/SKILL.md +0 -22
- package/.codex/skills/sinapse-analyst/SKILL.md +0 -29
- package/.codex/skills/sinapse-animations/SKILL.md +0 -28
- package/.codex/skills/sinapse-architect/SKILL.md +0 -31
- package/.codex/skills/sinapse-brand/SKILL.md +0 -28
- package/.codex/skills/sinapse-claude/SKILL.md +0 -28
- package/.codex/skills/sinapse-cloning/SKILL.md +0 -28
- package/.codex/skills/sinapse-commercial/SKILL.md +0 -28
- package/.codex/skills/sinapse-content/SKILL.md +0 -28
- package/.codex/skills/sinapse-copy/SKILL.md +0 -28
- package/.codex/skills/sinapse-council/SKILL.md +0 -28
- package/.codex/skills/sinapse-courses/SKILL.md +0 -28
- package/.codex/skills/sinapse-cyber/SKILL.md +0 -28
- package/.codex/skills/sinapse-data-engineer/SKILL.md +0 -31
- package/.codex/skills/sinapse-design/SKILL.md +0 -28
- package/.codex/skills/sinapse-dev/SKILL.md +0 -31
- package/.codex/skills/sinapse-devops/SKILL.md +0 -31
- package/.codex/skills/sinapse-finance/SKILL.md +0 -28
- package/.codex/skills/sinapse-growth/SKILL.md +0 -28
- package/.codex/skills/sinapse-loop/SKILL.md +0 -35
- package/.codex/skills/sinapse-orqx/SKILL.md +0 -44
- package/.codex/skills/sinapse-paidmedia/SKILL.md +0 -28
- package/.codex/skills/sinapse-pm/SKILL.md +0 -31
- package/.codex/skills/sinapse-po/SKILL.md +0 -31
- package/.codex/skills/sinapse-product/SKILL.md +0 -28
- package/.codex/skills/sinapse-qa/SKILL.md +0 -31
- package/.codex/skills/sinapse-research/SKILL.md +0 -28
- package/.codex/skills/sinapse-sm/SKILL.md +0 -27
- package/.codex/skills/sinapse-spec-driven/SKILL.md +0 -35
- package/.codex/skills/sinapse-squad-creator/SKILL.md +0 -31
- package/.codex/skills/sinapse-storytelling/SKILL.md +0 -28
- package/.codex/skills/sinapse-swarm/SKILL.md +0 -28
- package/.codex/skills/sinapse-ux-design-expert/SKILL.md +0 -24
- package/.codex/skills/snps/SKILL.md +0 -10
- package/.codex/skills/snps-orqx/SKILL.md +0 -10
- /package/{.codex → .agents}/skills/react-bits-frontend/SKILL.md +0 -0
- /package/{.codex → .agents}/skills/react-bits-frontend/agents/openai.yaml +0 -0
- /package/{.codex → .agents}/skills/react-bits-frontend/references/corpus-map.md +0 -0
|
@@ -9,10 +9,29 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const fs = require('fs-extra');
|
|
12
|
+
const nativeFs = require('fs');
|
|
12
13
|
const path = require('path');
|
|
14
|
+
const crypto = require('crypto');
|
|
13
15
|
const ora = require('ora');
|
|
14
16
|
const { hashFile } = require('./file-hasher');
|
|
15
17
|
|
|
18
|
+
const NOFOLLOW_READ_FLAGS = nativeFs.constants.O_RDONLY | (nativeFs.constants.O_NOFOLLOW || 0);
|
|
19
|
+
|
|
20
|
+
async function readRegularFileNoFollow(filePath) {
|
|
21
|
+
let handle;
|
|
22
|
+
try {
|
|
23
|
+
handle = await nativeFs.promises.open(filePath, NOFOLLOW_READ_FLAGS);
|
|
24
|
+
const stat = await handle.stat();
|
|
25
|
+
if (!stat.isFile()) return null;
|
|
26
|
+
return await handle.readFile();
|
|
27
|
+
} catch (error) {
|
|
28
|
+
if (['ENOENT', 'ELOOP', 'EISDIR'].includes(error.code)) return null;
|
|
29
|
+
throw error;
|
|
30
|
+
} finally {
|
|
31
|
+
if (handle) await handle.close();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
16
35
|
/**
|
|
17
36
|
* Get the path to the source .sinapse-ai directory in the package
|
|
18
37
|
* @returns {string} Absolute path to .sinapse-ai source
|
|
@@ -62,6 +81,82 @@ const ROOT_FILES_TO_COPY = [
|
|
|
62
81
|
const CODEX_TOP_LEVEL_DIRS = ['.agents', '.codex'];
|
|
63
82
|
const CLAUDE_SUPPORT_DIRS = ['.claude/hooks', '.claude/rules'];
|
|
64
83
|
|
|
84
|
+
function getClaudeHookName(command) {
|
|
85
|
+
const match = String(command || '').replace(/\\/g, '/').match(/\.claude\/hooks\/([^"'\s]+)/);
|
|
86
|
+
return match ? match[1] : null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function getClaudeHookRegistrationKey(event, matcher, hookName) {
|
|
90
|
+
return JSON.stringify([event, matcher ?? null, hookName]);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Merge shipped SINAPSE hook registrations without replacing user settings. */
|
|
94
|
+
async function reconcileClaudeHookSettings(packageRoot, targetDir) {
|
|
95
|
+
const sourcePath = path.join(packageRoot, '.claude', 'settings.json');
|
|
96
|
+
if (!await fs.pathExists(sourcePath)) return null;
|
|
97
|
+
|
|
98
|
+
const targetPath = path.join(targetDir, '.claude', 'settings.local.json');
|
|
99
|
+
const source = await fs.readJson(sourcePath);
|
|
100
|
+
let target = {};
|
|
101
|
+
if (await fs.pathExists(targetPath)) {
|
|
102
|
+
try {
|
|
103
|
+
target = await fs.readJson(targetPath);
|
|
104
|
+
} catch (_error) {
|
|
105
|
+
// Preserve malformed user settings verbatim. The installer must not turn
|
|
106
|
+
// a recoverable configuration problem into data loss or a failed install.
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (!target || typeof target !== 'object' || Array.isArray(target)) return null;
|
|
111
|
+
if (!target.hooks || typeof target.hooks !== 'object' || Array.isArray(target.hooks)) {
|
|
112
|
+
target.hooks = {};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const existingSettings = [target];
|
|
116
|
+
const projectSettingsPath = path.join(targetDir, '.claude', 'settings.json');
|
|
117
|
+
if (await fs.pathExists(projectSettingsPath)) {
|
|
118
|
+
try {
|
|
119
|
+
const projectSettings = await fs.readJson(projectSettingsPath);
|
|
120
|
+
if (projectSettings && typeof projectSettings === 'object' && !Array.isArray(projectSettings)) {
|
|
121
|
+
existingSettings.push(projectSettings);
|
|
122
|
+
}
|
|
123
|
+
} catch (_error) {
|
|
124
|
+
// An invalid sibling settings file cannot provide reliable registrations;
|
|
125
|
+
// ignore it while retaining its contents and merge into settings.local.
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const registered = new Set();
|
|
129
|
+
for (const settings of existingSettings) {
|
|
130
|
+
for (const [event, groups] of Object.entries(settings.hooks || {})) {
|
|
131
|
+
for (const group of Array.isArray(groups) ? groups : []) {
|
|
132
|
+
for (const hook of Array.isArray(group.hooks) ? group.hooks : []) {
|
|
133
|
+
const hookName = getClaudeHookName(hook.command);
|
|
134
|
+
if (hookName) registered.add(getClaudeHookRegistrationKey(event, group.matcher, hookName));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
for (const [event, groups] of Object.entries(source.hooks || {})) {
|
|
141
|
+
if (!Array.isArray(target.hooks[event])) target.hooks[event] = [];
|
|
142
|
+
for (const group of groups || []) {
|
|
143
|
+
for (const hook of group.hooks || []) {
|
|
144
|
+
const hookName = getClaudeHookName(hook.command);
|
|
145
|
+
const registrationKey = getClaudeHookRegistrationKey(event, group.matcher, hookName);
|
|
146
|
+
if (!hookName || registered.has(registrationKey)) continue;
|
|
147
|
+
const registration = { hooks: [hook] };
|
|
148
|
+
if (group.matcher) registration.matcher = group.matcher;
|
|
149
|
+
target.hooks[event].push(registration);
|
|
150
|
+
registered.add(registrationKey);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
await fs.ensureDir(path.dirname(targetPath));
|
|
156
|
+
await fs.writeJson(targetPath, target, { spaces: 2 });
|
|
157
|
+
return path.join('.claude', 'settings.local.json');
|
|
158
|
+
}
|
|
159
|
+
|
|
65
160
|
/**
|
|
66
161
|
* Replace {root} placeholder in file content
|
|
67
162
|
* @param {string} content - File content
|
|
@@ -121,9 +216,22 @@ async function generateVersionJson(options) {
|
|
|
121
216
|
installedFiles,
|
|
122
217
|
mode = 'project-development',
|
|
123
218
|
providers = [],
|
|
219
|
+
targetDir = path.dirname(targetSinapseCore),
|
|
220
|
+
providerFiles = [],
|
|
221
|
+
providerSourceRoot = targetDir,
|
|
124
222
|
} = options;
|
|
125
223
|
|
|
126
224
|
const fileHashes = await generateFileHashes(targetSinapseCore, installedFiles);
|
|
225
|
+
const providerFileHashes = {};
|
|
226
|
+
for (const relativePath of providerFiles) {
|
|
227
|
+
const sourcePath = path.join(providerSourceRoot, relativePath);
|
|
228
|
+
const sourceContent = await readRegularFileNoFollow(sourcePath);
|
|
229
|
+
if (sourceContent !== null) {
|
|
230
|
+
const installedContent = replaceRootPlaceholder(sourceContent.toString('utf8'));
|
|
231
|
+
const digest = crypto.createHash('sha256').update(installedContent).digest('hex');
|
|
232
|
+
providerFileHashes[relativePath.replace(/\\/g, '/')] = `sha256:${digest}`;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
127
235
|
|
|
128
236
|
const versionJson = {
|
|
129
237
|
version,
|
|
@@ -131,6 +239,7 @@ async function generateVersionJson(options) {
|
|
|
131
239
|
mode,
|
|
132
240
|
providers: [...new Set(providers)].sort(),
|
|
133
241
|
fileHashes,
|
|
242
|
+
providerFileHashes,
|
|
134
243
|
customized: [],
|
|
135
244
|
};
|
|
136
245
|
|
|
@@ -162,17 +271,158 @@ function isUserOwnedL3(destPath) {
|
|
|
162
271
|
return false;
|
|
163
272
|
}
|
|
164
273
|
|
|
165
|
-
function
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
274
|
+
function getManagedCodexSkillPaths(packageRoot) {
|
|
275
|
+
const catalog = fs.readJsonSync(path.join(packageRoot, '.codex', 'catalog.json'));
|
|
276
|
+
return [...new Set([
|
|
277
|
+
...(catalog.expectedSkillIds || []),
|
|
278
|
+
...(catalog.publicAliasSkillIds || []),
|
|
279
|
+
catalog.genericAgentSkillId,
|
|
280
|
+
].filter(Boolean))]
|
|
281
|
+
.sort()
|
|
282
|
+
.map((skillId) => path.posix.join('.agents', 'skills', skillId, 'SKILL.md'));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function createCodexPreservePredicate(targetDir, packageRoot, previousProviderHashes = {}) {
|
|
286
|
+
const legacyRegistry = fs.readJsonSync(path.join(
|
|
287
|
+
packageRoot,
|
|
288
|
+
'packages',
|
|
289
|
+
'installer',
|
|
290
|
+
'src',
|
|
291
|
+
'migrations',
|
|
292
|
+
'legacy-codex-native-skill-hashes.json',
|
|
293
|
+
));
|
|
294
|
+
return (destPath) => {
|
|
295
|
+
const normalized = String(destPath).replace(/\\/g, '/');
|
|
296
|
+
if (normalized.endsWith('/.codex/config.toml') || normalized.endsWith('/.codex/hooks.json')) return true;
|
|
297
|
+
if (!/\/(?:\.codex|\.agents)\/skills\/[^/]+\/SKILL\.md$/.test(normalized)) return false;
|
|
298
|
+
if (!fs.existsSync(destPath)) return false;
|
|
299
|
+
const relativePath = path.relative(targetDir, destPath).replace(/\\/g, '/');
|
|
300
|
+
const digest = hashFile(destPath);
|
|
301
|
+
const previous = String(previousProviderHashes[relativePath] || '').replace(/^sha256:/, '');
|
|
302
|
+
const legacyHashes = legacyRegistry.files[relativePath] || [];
|
|
303
|
+
return digest !== previous && !legacyHashes.includes(digest);
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
async function reconcileLegacyCodexSkills(targetDir, packageRoot) {
|
|
308
|
+
const catalogPath = path.join(packageRoot, '.codex', 'catalog.json');
|
|
309
|
+
if (!await fs.pathExists(catalogPath)) return { removed: 0, migrated: 0, quarantined: 0, ambiguous: [] };
|
|
310
|
+
|
|
311
|
+
const catalog = await fs.readJson(catalogPath);
|
|
312
|
+
const managedIds = [...new Set([
|
|
313
|
+
...(catalog.expectedSkillIds || []),
|
|
314
|
+
...(catalog.publicAliasSkillIds || []),
|
|
315
|
+
catalog.genericAgentSkillId,
|
|
316
|
+
].filter((id) => /^[a-z0-9][a-z0-9-]*$/.test(String(id))))].sort();
|
|
317
|
+
const result = { removed: 0, migrated: 0, quarantined: 0, ambiguous: [] };
|
|
318
|
+
|
|
319
|
+
for (const skillId of managedIds) {
|
|
320
|
+
const legacyPath = path.join(targetDir, '.codex', 'skills', skillId, 'SKILL.md');
|
|
321
|
+
if (!await fs.pathExists(legacyPath)) continue;
|
|
322
|
+
const legacyContent = await readRegularFileNoFollow(legacyPath);
|
|
323
|
+
if (legacyContent === null) {
|
|
324
|
+
result.ambiguous.push(path.relative(targetDir, legacyPath));
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const nativePath = path.join(targetDir, '.agents', 'skills', skillId, 'SKILL.md');
|
|
329
|
+
if (!await fs.pathExists(nativePath)) {
|
|
330
|
+
await fs.ensureDir(path.dirname(nativePath));
|
|
331
|
+
try {
|
|
332
|
+
await fs.writeFile(nativePath, legacyContent, { flag: 'wx' });
|
|
333
|
+
} catch (error) {
|
|
334
|
+
if (error.code === 'EEXIST') {
|
|
335
|
+
result.ambiguous.push(path.relative(targetDir, legacyPath));
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
throw error;
|
|
339
|
+
}
|
|
340
|
+
await fs.remove(legacyPath);
|
|
341
|
+
if ((await fs.readdir(path.dirname(legacyPath))).length === 0) {
|
|
342
|
+
await fs.remove(path.dirname(legacyPath));
|
|
343
|
+
}
|
|
344
|
+
result.migrated += 1;
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const nativeContent = await readRegularFileNoFollow(nativePath);
|
|
349
|
+
if (nativeContent === null) {
|
|
350
|
+
result.ambiguous.push(path.relative(targetDir, legacyPath));
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
if (legacyContent.equals(nativeContent)) {
|
|
354
|
+
await fs.remove(legacyPath);
|
|
355
|
+
if ((await fs.readdir(path.dirname(legacyPath))).length === 0) {
|
|
356
|
+
await fs.remove(path.dirname(legacyPath));
|
|
357
|
+
}
|
|
358
|
+
result.removed += 1;
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const digest = crypto.createHash('sha256').update(legacyContent).digest('hex').slice(0, 12);
|
|
363
|
+
const quarantinePath = path.join(
|
|
364
|
+
targetDir,
|
|
365
|
+
'.sinapse-ai',
|
|
366
|
+
'migrations',
|
|
367
|
+
'codex-skills',
|
|
368
|
+
`${skillId}.${digest}.legacy.md`,
|
|
172
369
|
);
|
|
173
|
-
|
|
370
|
+
await fs.ensureDir(path.dirname(quarantinePath));
|
|
371
|
+
try {
|
|
372
|
+
await fs.writeFile(quarantinePath, legacyContent, { flag: 'wx' });
|
|
373
|
+
} catch (error) {
|
|
374
|
+
if (error.code !== 'EEXIST') throw error;
|
|
375
|
+
const quarantinedContent = await readRegularFileNoFollow(quarantinePath);
|
|
376
|
+
if (quarantinedContent === null || !quarantinedContent.equals(legacyContent)) {
|
|
377
|
+
result.ambiguous.push(path.relative(targetDir, legacyPath));
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
await fs.remove(legacyPath);
|
|
382
|
+
if ((await fs.readdir(path.dirname(legacyPath))).length === 0) {
|
|
383
|
+
await fs.remove(path.dirname(legacyPath));
|
|
384
|
+
}
|
|
385
|
+
result.quarantined += 1;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
return result;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
async function reconcileLegacyClaudeAgentCommands(targetDir, packageRoot = path.join(__dirname, '..', '..', '..', '..')) {
|
|
392
|
+
const legacyDir = path.join(targetDir, '.claude', 'commands', 'SINAPSE', 'agents');
|
|
393
|
+
const result = { removed: 0, preserved: 0, ambiguous: [] };
|
|
394
|
+
if (!await fs.pathExists(legacyDir)) return result;
|
|
395
|
+
|
|
396
|
+
const registryPath = path.join(
|
|
397
|
+
packageRoot,
|
|
398
|
+
'packages',
|
|
399
|
+
'installer',
|
|
400
|
+
'src',
|
|
401
|
+
'migrations',
|
|
402
|
+
'legacy-claude-agent-command-hashes.json',
|
|
403
|
+
);
|
|
404
|
+
const registry = await fs.readJson(registryPath);
|
|
405
|
+
for (const entry of await fs.readdir(legacyDir, { withFileTypes: true })) {
|
|
406
|
+
const filePath = path.join(legacyDir, entry.name);
|
|
407
|
+
if (!entry.isFile()) {
|
|
408
|
+
result.preserved += 1;
|
|
409
|
+
result.ambiguous.push(path.relative(targetDir, filePath));
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
const content = await fs.readFile(filePath);
|
|
413
|
+
const digest = crypto.createHash('sha256').update(content).digest('hex');
|
|
414
|
+
const knownHashes = registry.files[entry.name] || [];
|
|
415
|
+
const isMarked = content.includes(Buffer.from('SINAPSE-MANAGED:claude-command'));
|
|
416
|
+
if (knownHashes.includes(digest) || isMarked) {
|
|
417
|
+
await fs.remove(filePath);
|
|
418
|
+
result.removed += 1;
|
|
419
|
+
} else {
|
|
420
|
+
result.preserved += 1;
|
|
421
|
+
result.ambiguous.push(path.relative(targetDir, filePath));
|
|
422
|
+
}
|
|
174
423
|
}
|
|
175
|
-
|
|
424
|
+
if ((await fs.readdir(legacyDir)).length === 0) await fs.remove(legacyDir);
|
|
425
|
+
return result;
|
|
176
426
|
}
|
|
177
427
|
|
|
178
428
|
async function copyFileWithRootReplacement(sourcePath, destPath, replaceRoot = true, preserveExisting = null) {
|
|
@@ -350,6 +600,15 @@ async function installSinapseCore(options = {}) {
|
|
|
350
600
|
try {
|
|
351
601
|
const sourceDir = getSinapseCoreSourcePath();
|
|
352
602
|
const targetSinapseCore = path.join(targetDir, '.sinapse-ai');
|
|
603
|
+
const previousVersionPath = path.join(targetSinapseCore, 'version.json');
|
|
604
|
+
let previousProviderHashes = {};
|
|
605
|
+
if (await fs.pathExists(previousVersionPath)) {
|
|
606
|
+
try {
|
|
607
|
+
previousProviderHashes = (await fs.readJson(previousVersionPath)).providerFileHashes || {};
|
|
608
|
+
} catch (_error) {
|
|
609
|
+
previousProviderHashes = {};
|
|
610
|
+
}
|
|
611
|
+
}
|
|
353
612
|
|
|
354
613
|
// Check if source exists
|
|
355
614
|
if (!await fs.pathExists(sourceDir)) {
|
|
@@ -415,7 +674,7 @@ async function installSinapseCore(options = {}) {
|
|
|
415
674
|
if (await fs.pathExists(src)) {
|
|
416
675
|
spinner.text = `Copying ${dirName}...`;
|
|
417
676
|
const preserveExisting = dirName === '.codex' || dirName === '.agents'
|
|
418
|
-
?
|
|
677
|
+
? createCodexPreservePredicate(targetDir, pkgRoot, previousProviderHashes)
|
|
419
678
|
: null;
|
|
420
679
|
const copied = await copyDirectoryWithRootReplacement(
|
|
421
680
|
src,
|
|
@@ -431,6 +690,7 @@ async function installSinapseCore(options = {}) {
|
|
|
431
690
|
}
|
|
432
691
|
|
|
433
692
|
if (includeClaude) {
|
|
693
|
+
result.claudeLegacyAgentCommandReconciliation = await reconcileLegacyClaudeAgentCommands(targetDir, pkgRoot);
|
|
434
694
|
const claude = await deliverClaudeNativeAdapters(pkgRoot, targetDir, { overwriteManaged: overwriteManagedAdapters });
|
|
435
695
|
result.claudeNativeAgentFiles = claude.agents.length;
|
|
436
696
|
result.claudeNativeSkillFiles = claude.skills.length;
|
|
@@ -441,6 +701,8 @@ async function installSinapseCore(options = {}) {
|
|
|
441
701
|
if (await fs.pathExists(claudeContextSource) && await copyFileWithRootReplacement(claudeContextSource, claudeContextDest, true)) {
|
|
442
702
|
result.installedFiles.push(path.join('.claude', 'CLAUDE.md'));
|
|
443
703
|
}
|
|
704
|
+
const claudeSettings = await reconcileClaudeHookSettings(pkgRoot, targetDir);
|
|
705
|
+
if (claudeSettings) result.installedFiles.push(claudeSettings);
|
|
444
706
|
}
|
|
445
707
|
|
|
446
708
|
// AGENTS.md is the Codex CLI's default context file (Imperator greeting +
|
|
@@ -455,6 +717,7 @@ async function installSinapseCore(options = {}) {
|
|
|
455
717
|
result.installedFiles.push('AGENTS.md');
|
|
456
718
|
result.agentsMdInstalled = true;
|
|
457
719
|
}
|
|
720
|
+
result.codexLegacySkillReconciliation = await reconcileLegacyCodexSkills(targetDir, pkgRoot);
|
|
458
721
|
}
|
|
459
722
|
|
|
460
723
|
// Create install manifest
|
|
@@ -481,6 +744,9 @@ async function installSinapseCore(options = {}) {
|
|
|
481
744
|
installedFiles: result.installedFiles,
|
|
482
745
|
mode: 'project-development',
|
|
483
746
|
providers: [includeClaude && 'claude-code', includeCodex && 'codex'].filter(Boolean),
|
|
747
|
+
targetDir,
|
|
748
|
+
providerFiles: includeCodex ? getManagedCodexSkillPaths(pkgRoot) : [],
|
|
749
|
+
providerSourceRoot: pkgRoot,
|
|
484
750
|
});
|
|
485
751
|
result.versionInfo = versionInfo;
|
|
486
752
|
|
|
@@ -602,10 +868,16 @@ module.exports = {
|
|
|
602
868
|
copyFileWithRootReplacement,
|
|
603
869
|
copyDirectoryWithRootReplacement,
|
|
604
870
|
isUserOwnedL3,
|
|
871
|
+
createCodexPreservePredicate,
|
|
872
|
+
getManagedCodexSkillPaths,
|
|
873
|
+
reconcileLegacyCodexSkills,
|
|
874
|
+
reconcileLegacyClaudeAgentCommands,
|
|
605
875
|
generateVersionJson,
|
|
606
876
|
generateFileHashes,
|
|
607
877
|
deliverCodexRootFiles,
|
|
608
878
|
deliverClaudeNativeAdapters,
|
|
879
|
+
getClaudeHookName,
|
|
880
|
+
reconcileClaudeHookSettings,
|
|
609
881
|
FOLDERS_TO_COPY,
|
|
610
882
|
ROOT_FILES_TO_COPY,
|
|
611
883
|
CODEX_ROOT_FILES,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"algorithm": "sha256",
|
|
4
|
+
"files": {
|
|
5
|
+
"analyst.md": ["795b9209e7bc5bd31a736bb67ee5c0eeb1a95590afd47fb630c81de0dd87c126"],
|
|
6
|
+
"animations-orqx.md": ["f3cce5c6d75a6a872171593dba8bafeae657488950fad63c89f17e7e193e92e0"],
|
|
7
|
+
"architect.md": ["d2e8a9b7b4c7582870f08561f482fa6c51a0b347fdcc066bd88bda5575a2052f"],
|
|
8
|
+
"brand-orqx.md": ["a4afdbd9dc8fd118939be2e07377967a86748310b89c7f59b14818d84fbb10ad"],
|
|
9
|
+
"cloning-orqx.md": ["134d10224635b9898469d7bb3992f636ecdba375272e3ad1c24eb0215c1a85c0"],
|
|
10
|
+
"commercial-orqx.md": ["170288942d7c85c28fece5eef0256101eee0699a76a8f28b3e7ec5878d2f0b79"],
|
|
11
|
+
"content-orqx.md": ["f93bf397c8da352d10b884600ae339979a0c6c5190fb3b21daa1de6d3e7a2e45"],
|
|
12
|
+
"copy-orqx.md": ["86f70db676af7475d13face6468da78ee05e5c257b506fe484b62c0d1ca9439c"],
|
|
13
|
+
"council-orqx.md": ["d2ab7fcd71e71677d6fd15ae1565c35fb241e4b9558e79da0e030fc70a81efe4"],
|
|
14
|
+
"courses-orqx.md": ["236e69533c0155a42dfc762f563455244b71f127ae6459b70ffabad8ba081654"],
|
|
15
|
+
"cyber-orqx.md": ["8efff68f6e1441df8719b3d743dc27f9e6d0ce6d9f6e7128284a144d5c74ac63"],
|
|
16
|
+
"data-engineer.md": ["9c9faba56ad0bb8816e76117e0392e0727d8f4aba46413fa053c97d5aaf086bf"],
|
|
17
|
+
"design-orqx.md": ["e3b10fb943a64916826a11d13e0e57f61cc5e27e8966ea15924cae4e055aad64"],
|
|
18
|
+
"developer.md": ["b996b501f752b4f049367182d0c2c5a99019fddeab343c840a7da2f8ca1d70a4"],
|
|
19
|
+
"devops.md": ["18354e8a0e8b39786d48a5d9f8a7e532698e6fe49a65f3243be6a96eb6c73c42"],
|
|
20
|
+
"finance-orqx.md": ["f4ebeb70b7a0890c491608a00feedd31b9b4a9b872ed02d489b39a99fa01c537"],
|
|
21
|
+
"growth-orqx.md": ["b0f74d98f40fe384c81a22ab705007e4e40ab9f82bc6c23d2282a05aed17cbdf"],
|
|
22
|
+
"paidmedia-orqx.md": ["b68b91bc647fa6290c9109d621d98f6567b28967acb9e474cbf399442711c530"],
|
|
23
|
+
"product-lead.md": ["a62d2f6079b7deabe22d24cd66943375e82fbe9ea389e23bf9a7a9ea2fa55e08"],
|
|
24
|
+
"product-orqx.md": ["5df3d89096efdc1cabdcfaaf82b14571689d258a495981520ae0a0ea8fa04a92"],
|
|
25
|
+
"project-lead.md": ["0dd16d04f28c7614c025dadb557aa4b3eeb56c96fda8874afec40b8044db6e2b"],
|
|
26
|
+
"quality-gate.md": ["ed735180b28c51df2803933009f9b9bc6f5f497ac2b528919a4eed83e0ba1682"],
|
|
27
|
+
"research-orqx.md": ["9cf3c189b670ee4565329abec1a2c7d208a3013a9dba695208cbe617b4b0984b"],
|
|
28
|
+
"sinapse-orqx.md": ["36e704406c594a72cbf72eac52bb9ce22a636965a8c86a45c6560e4cc4fb67d6"],
|
|
29
|
+
"snps-orqx.md": ["0452d5291fd27239c0e6f79064d214c9755234e444daabbcea7cdd5e0f5a544d"],
|
|
30
|
+
"sprint-lead.md": ["3abfcccefb0e15765549cc54fabb8e398de135532c76f9ef8b16a57220dcac69"],
|
|
31
|
+
"squad-creator.md": ["1a92aeabebee66782dd906a75844451d3cb0fc0af59f7df266ab4106026ef657"],
|
|
32
|
+
"storytelling-orqx.md": ["45889421752caaecaff3ccc92d22e333235d675f65710f435b3b7224bbc0e022"],
|
|
33
|
+
"swarm-orqx.md": ["9eb519069dc7b9a10fd2ca677f4dfbed9ad3f966d0d65b2a73daf67b000b81c0"],
|
|
34
|
+
"ux-design-expert.md": ["f26f6935b95bd3c5d051a0b0a70394571f47fb1992e26ad17b25033b04f81048"]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"algorithm": "sha256",
|
|
4
|
+
"files": {
|
|
5
|
+
".agents/skills/sinapse-agent/SKILL.md": ["122ddfefe2fc23579c54513953f2f8cb7e872708c3c2078aac1a72a5e8a55959"],
|
|
6
|
+
".agents/skills/sinapse-analyst/SKILL.md": ["3ff8b42481e23e847ebac3c255ff4437b984c715046e16fb61d0605fa1a5b677"],
|
|
7
|
+
".agents/skills/sinapse-animations/SKILL.md": ["78666bb951ea083f1df13d9960ed7cecaef304024cea4392b2fc3022251fdab5"],
|
|
8
|
+
".agents/skills/sinapse-architect/SKILL.md": ["05bbbaf7d493918cf4856feddd611b8f2e1f88924e7bba0f6ab9ce83ab7b6718"],
|
|
9
|
+
".agents/skills/sinapse-brand/SKILL.md": ["bfbdebaa0e3c9e2668025af01df88841646ea450e4b1e6cb5008ca02258206db"],
|
|
10
|
+
".agents/skills/sinapse-claude/SKILL.md": ["85f25d07838fa259cf48338ab526eeb6391c47ddbf10dba44aa6cc35421a90bf"],
|
|
11
|
+
".agents/skills/sinapse-cloning/SKILL.md": ["b9e6d9e6c87cb79f261c46b6f6e83fc1d10506bcb920ece4012b07020334dc2a"],
|
|
12
|
+
".agents/skills/sinapse-commercial/SKILL.md": ["b26cb18661293ffee078bd555677b7fa201718f1cdedf859dd358ae33b901e1e"],
|
|
13
|
+
".agents/skills/sinapse-content/SKILL.md": ["61f4cbb9b9a5de4dde5fbf7b3027898be20fb127a287b19d5955e34a832b3ba3"],
|
|
14
|
+
".agents/skills/sinapse-copy/SKILL.md": ["dddf3da31fe8807eb60450ad0dcdd73288ba32470b142d4d1c994277282dd1a2"],
|
|
15
|
+
".agents/skills/sinapse-council/SKILL.md": ["6692021c2578524513a5462b7271aa7eda7335961cea5d9d015f7b75f3dfd2a1"],
|
|
16
|
+
".agents/skills/sinapse-courses/SKILL.md": ["653a21c66dd78904b53b8924601778f1682db8b879ab5d50320d06452236687d"],
|
|
17
|
+
".agents/skills/sinapse-cyber/SKILL.md": ["55c12f9a6f35970b3bf0d6d6ab8208b6348a9390040df1d8d01df108a369b429"],
|
|
18
|
+
".agents/skills/sinapse-data-engineer/SKILL.md": ["5c8e31f9cba46f89fffbb5c83fe831725d951f75275b085b51ea48beab0291fa"],
|
|
19
|
+
".agents/skills/sinapse-design/SKILL.md": ["3c35efa3e905d636352f5f046d494665ebf9e33f4c896fddcfa112103877a00d"],
|
|
20
|
+
".agents/skills/sinapse-dev/SKILL.md": ["a2ff86c33e61efb1085e9388c8f1f6a58389b9dc8b74ecbe83c096b920f114db"],
|
|
21
|
+
".agents/skills/sinapse-devops/SKILL.md": ["9cf5ef12999568e292f4e5d302bd61831872a783d6ed9caaca7a1ac247c63c01"],
|
|
22
|
+
".agents/skills/sinapse-finance/SKILL.md": ["4b596578bbb950e8513eb96ea62200880c9184989bdfc91c7ecd1370f47b07ab"],
|
|
23
|
+
".agents/skills/sinapse-growth/SKILL.md": ["53d32adb439098528925425d4ff86458e8fb2efb3c8fd6b62e8c42de4f06873c"],
|
|
24
|
+
".agents/skills/sinapse-loop/SKILL.md": ["e5a33f9235c66e554e67d7668ac5e3255e1b6f9ed026f7bf3be666c169bf396a"],
|
|
25
|
+
".agents/skills/sinapse-orqx/SKILL.md": ["b522b867768f4f6cf9151978734611b1482ec6f35cbe8552e9e324c4bb16de50"],
|
|
26
|
+
".agents/skills/sinapse-paidmedia/SKILL.md": ["81ae19dae135dcd001703446131989ac51da1a299d8fab59ddc21596b1d462e2"],
|
|
27
|
+
".agents/skills/sinapse-pm/SKILL.md": ["ecf406f3a94c48defff97c9ef55410cdf82cfa445b3d1244df0c6dd66543b910"],
|
|
28
|
+
".agents/skills/sinapse-po/SKILL.md": ["56693d11a13cf51eb600883d26f232adfb6c0275015a1dfa0fd467387700667f"],
|
|
29
|
+
".agents/skills/sinapse-product/SKILL.md": ["50bae9a40dca95287b864a873fe578953b5f361239a3e6c2b70ae2cd38197eb7"],
|
|
30
|
+
".agents/skills/sinapse-qa/SKILL.md": ["54ac75619ae2cd28fa820e224abc5fc82163198652ce200d0706aa0734e98509"],
|
|
31
|
+
".agents/skills/sinapse-research/SKILL.md": ["ac98bc465c1c975d95d93ffc6a665c41ab679e1885882ab7a91c86501a34d181"],
|
|
32
|
+
".agents/skills/sinapse-sm/SKILL.md": ["408556e7cff08d5b84c724e55a3d35e7624e155984edfe697c7a9fe61e60a72f"],
|
|
33
|
+
".agents/skills/sinapse-spec-driven/SKILL.md": ["5216b2f651f88263323a07cabec78259036bb4ec23689d312c770cef216b26a1"],
|
|
34
|
+
".agents/skills/sinapse-squad-creator/SKILL.md": ["779a93754fb121d8f405667f2d3852faeb8945302129aec74c0d1f6b51f62ed3"],
|
|
35
|
+
".agents/skills/sinapse-storytelling/SKILL.md": ["65e2d8719eee6d0221bcfe758144c24575cf00c0aa988b785f98c69fc4982025"],
|
|
36
|
+
".agents/skills/sinapse-swarm/SKILL.md": ["8c98e9b1da2cb279ef7fa10ca4e81cb0a230ecdbfda4f890b0b94f1604626f00"],
|
|
37
|
+
".agents/skills/sinapse-ux-design-expert/SKILL.md": ["5a1c747c030113b50d98a431bfffc4418e38355cae72f7e5a088ee5bee8bc530"],
|
|
38
|
+
".agents/skills/sinapse/SKILL.md": ["fe017c091d1308eb937762ffe25f83518f778a266303cc3f028d0f468df0747f"],
|
|
39
|
+
".agents/skills/snps-orqx/SKILL.md": ["24f66470a5721fc086a52eca9907958d091d68c2de0a0b56a42e07e83fe00342"],
|
|
40
|
+
".agents/skills/snps/SKILL.md": ["9f9a0972a184a07234948f4e5dd8f7032835be3283608a00c8cbf8bbf68064a3"]
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -26,6 +26,24 @@ const { PostInstallValidator, formatReport: formatValidationReport } = require('
|
|
|
26
26
|
const { _testing: { installGlobalAgents } } = require('../wizard/index');
|
|
27
27
|
const { installSinapseCore } = require('../installer/sinapse-ai-installer');
|
|
28
28
|
|
|
29
|
+
function detectInstalledProviders(projectRoot, recordedProviders = []) {
|
|
30
|
+
if (recordedProviders.length > 0) {
|
|
31
|
+
return {
|
|
32
|
+
includeClaude: recordedProviders.includes('claude-code'),
|
|
33
|
+
includeCodex: recordedProviders.includes('codex'),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const includeClaude = fs.existsSync(path.join(projectRoot, '.claude', 'skill-manifest.json'));
|
|
37
|
+
const hasCodexCatalog = fs.existsSync(path.join(projectRoot, '.codex', 'catalog.json'));
|
|
38
|
+
const hasNativeActivator = fs.existsSync(
|
|
39
|
+
path.join(projectRoot, '.agents', 'skills', 'sinapse-agent', 'SKILL.md'),
|
|
40
|
+
);
|
|
41
|
+
const hasLegacyActivator = fs.existsSync(
|
|
42
|
+
path.join(projectRoot, '.codex', 'skills', 'sinapse-agent', 'SKILL.md'),
|
|
43
|
+
);
|
|
44
|
+
return { includeClaude, includeCodex: hasCodexCatalog && (hasNativeActivator || hasLegacyActivator) };
|
|
45
|
+
}
|
|
46
|
+
|
|
29
47
|
/**
|
|
30
48
|
* Update status types
|
|
31
49
|
* @enum {string}
|
|
@@ -614,13 +632,10 @@ class SINAPSEUpdater {
|
|
|
614
632
|
const recordedProviders = Array.isArray(this.versionInfo?.providers)
|
|
615
633
|
? this.versionInfo.providers
|
|
616
634
|
: [];
|
|
617
|
-
const includeClaude
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
? recordedProviders.includes('codex')
|
|
622
|
-
: fs.existsSync(path.join(this.projectRoot, '.codex', 'catalog.json'))
|
|
623
|
-
&& fs.existsSync(path.join(this.projectRoot, '.agents', 'skills', 'sinapse-agent', 'SKILL.md'));
|
|
635
|
+
const { includeClaude, includeCodex } = detectInstalledProviders(
|
|
636
|
+
this.projectRoot,
|
|
637
|
+
recordedProviders,
|
|
638
|
+
);
|
|
624
639
|
const delivery = await installSinapseCore({
|
|
625
640
|
targetDir: this.projectRoot,
|
|
626
641
|
includeClaude,
|
|
@@ -631,6 +646,7 @@ class SINAPSEUpdater {
|
|
|
631
646
|
|
|
632
647
|
result.success = true;
|
|
633
648
|
result.filesUpdated = 1 + delivery.installedFiles.length;
|
|
649
|
+
result.codexLegacySkillReconciliation = delivery.codexLegacySkillReconciliation || null;
|
|
634
650
|
|
|
635
651
|
return result;
|
|
636
652
|
} catch (error) {
|
|
@@ -942,4 +958,5 @@ module.exports = {
|
|
|
942
958
|
formatCheckResult,
|
|
943
959
|
formatUpdateResult,
|
|
944
960
|
sanitizeLogText,
|
|
961
|
+
detectInstalledProviders,
|
|
945
962
|
};
|
|
@@ -18,6 +18,7 @@ const crossSpawn = require('cross-spawn');
|
|
|
18
18
|
const { getIDEConfig } = require('../config/ide-configs');
|
|
19
19
|
const { validateProjectName } = require('./validators');
|
|
20
20
|
const { getMergeStrategy, hasMergeStrategy } = require('../merger/index.js');
|
|
21
|
+
const { reconcileLegacyClaudeAgentCommands } = require('../installer/sinapse-ai-installer');
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Render template with variables
|
|
@@ -373,6 +374,9 @@ async function generateIDEConfigs(selectedIDEs, wizardState, options = {}) {
|
|
|
373
374
|
|
|
374
375
|
// Copy agent files to IDE-specific agent folder
|
|
375
376
|
if (ide.agentFolder) {
|
|
377
|
+
if (ideKey === 'claude-code') {
|
|
378
|
+
await reconcileLegacyClaudeAgentCommands(projectRoot);
|
|
379
|
+
}
|
|
376
380
|
spinner.start(`Copying agents to ${ide.agentFolder}...`);
|
|
377
381
|
const agentFiles = await copyAgentFiles(projectRoot, ide.agentFolder, ide);
|
|
378
382
|
createdFiles.push(...agentFiles);
|
|
@@ -536,6 +536,10 @@ async function runWizard(options = {}) {
|
|
|
536
536
|
const installed = pillars.filter(p => sinapseCoreResult.installedFolders.includes(p));
|
|
537
537
|
const aux = sinapseCoreResult.installedFolders.filter(f => !pillars.includes(f));
|
|
538
538
|
console.log(`✅ SINAPSE core: ${sinapseCoreResult.installedFiles.length} files (${installed.length} pillars, ${aux.length} modules)`);
|
|
539
|
+
const cleanup = sinapseCoreResult.codexLegacySkillReconciliation;
|
|
540
|
+
if (cleanup && (cleanup.removed || cleanup.migrated || cleanup.quarantined || cleanup.ambiguous.length)) {
|
|
541
|
+
console.log(`SINAPSE Codex skill cleanup: ${cleanup.removed} removed, ${cleanup.migrated} migrated, ${cleanup.quarantined} quarantined, ${cleanup.ambiguous.length} ambiguous`);
|
|
542
|
+
}
|
|
539
543
|
}
|
|
540
544
|
answers.sinapseCoreInstalled = true;
|
|
541
545
|
answers.sinapseCoreResult = sinapseCoreResult;
|
|
@@ -806,7 +810,7 @@ async function runWizard(options = {}) {
|
|
|
806
810
|
}
|
|
807
811
|
|
|
808
812
|
// Codex local-first sync: the ide-sync above drives claude-code only now,
|
|
809
|
-
// so .codex/agents + .
|
|
813
|
+
// so .codex/agents + .agents/skills are regenerated here from the canonical
|
|
810
814
|
// source (the static .codex payload — scripts/tasks/JSONs — was already
|
|
811
815
|
// copied by installSinapseCore when Codex was selected). Codex installs only.
|
|
812
816
|
if (shouldConfigureCodex(selectedLLM)) {
|
|
@@ -822,7 +826,7 @@ async function runWizard(options = {}) {
|
|
|
822
826
|
: { total: 0 };
|
|
823
827
|
answers.codexSyncStatus = codexResult.ok ? 'synced' : 'failed';
|
|
824
828
|
const m = codexResult.metrics || {};
|
|
825
|
-
console.log(`✅ Codex sync: ${codexResult.ok ? 'synced' : 'issues'} (${m.codexAgents || 0} adapters, ${nativeResult.total || 0} native agents, ${m.codexSkills || 0}
|
|
829
|
+
console.log(`✅ Codex sync: ${codexResult.ok ? 'synced' : 'issues'} (${m.codexAgents || 0} adapters, ${nativeResult.total || 0} native agents, ${m.codexSkills || 0} native skills)`);
|
|
826
830
|
} catch (codexErr) {
|
|
827
831
|
console.warn(`⚠️ Codex sync failed: ${codexErr.message} — run 'npm run sync:ide:codex' post-install`);
|
|
828
832
|
answers.codexSyncStatus = 'failed';
|