@cleocode/core 2026.3.47 → 2026.3.49
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/dist/bootstrap.d.ts.map +1 -1
- package/dist/index.js +19 -37
- package/dist/index.js.map +3 -3
- package/dist/init.d.ts +1 -3
- package/dist/init.d.ts.map +1 -1
- package/dist/project-info.d.ts +5 -0
- package/dist/project-info.d.ts.map +1 -1
- package/dist/upgrade.d.ts +6 -0
- package/dist/upgrade.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/injection-chain.test.ts +3 -2
- package/src/bootstrap.ts +18 -9
- package/src/init.ts +12 -12
- package/src/injection.ts +6 -6
- package/src/project-info.ts +16 -1
- package/src/upgrade.ts +49 -2
- package/src/validation/doctor/checks.ts +4 -4
package/dist/init.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* 9. Core skill installation via CAAMP
|
|
17
17
|
* 10. NEXUS project registration
|
|
18
18
|
* 11. Project type detection (--detect)
|
|
19
|
-
* 12. Injection refresh
|
|
19
|
+
* 12. Injection refresh
|
|
20
20
|
* 13. Git hook installation (commit-msg, pre-commit)
|
|
21
21
|
* 14. GitHub issue/PR templates (.github/ directory)
|
|
22
22
|
*
|
|
@@ -39,8 +39,6 @@ export interface InitOptions {
|
|
|
39
39
|
force?: boolean;
|
|
40
40
|
/** Auto-detect project configuration. */
|
|
41
41
|
detect?: boolean;
|
|
42
|
-
/** Update agent documentation injections only. */
|
|
43
|
-
updateDocs?: boolean;
|
|
44
42
|
/** Run codebase analysis and store findings to brain.db. */
|
|
45
43
|
mapCodebase?: boolean;
|
|
46
44
|
}
|
package/dist/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AA8BH,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yCAAyC;IACzC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AA8BH,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yCAAyC;IACzC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,oCAAoC;AACpC,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAaD;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqE9F;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,IAAI,CAAC,CA0Cf;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+FzF;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,IAAI,CAAC,CAuBf;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC,CAiDf;AAID;;;;;GAKG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAwBtD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,WAAW,CAAC,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CA2R7E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,WAAW,EAAE,OAAO,CAAA;CAAE,CAAC,CAiB/F;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAyBnF"}
|
package/dist/project-info.d.ts
CHANGED
|
@@ -32,4 +32,9 @@ export declare function getProjectInfo(cwd?: string): Promise<ProjectInfo>;
|
|
|
32
32
|
* Returns null if the file is missing or unparseable.
|
|
33
33
|
*/
|
|
34
34
|
export declare function getProjectInfoSync(cwd?: string): ProjectInfo | null;
|
|
35
|
+
/**
|
|
36
|
+
* Update the project name in project-info.json.
|
|
37
|
+
* Used by `cleo upgrade --name` and programmatic consumers.
|
|
38
|
+
*/
|
|
39
|
+
export declare function updateProjectName(cwd: string, name: string): void;
|
|
35
40
|
//# sourceMappingURL=project-info.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-info.d.ts","sourceRoot":"","sources":["../src/project-info.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,qEAAqE;AACrE,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;CACrB;AAID;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAqBvE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CA2BnE"}
|
|
1
|
+
{"version":3,"file":"project-info.d.ts","sourceRoot":"","sources":["../src/project-info.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,qEAAqE;AACrE,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;CACrB;AAID;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAqBvE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CA2BnE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CASjE"}
|
package/dist/upgrade.d.ts
CHANGED
|
@@ -48,12 +48,18 @@ export interface UpgradeResult {
|
|
|
48
48
|
* @param options.dryRun Preview changes without applying
|
|
49
49
|
* @param options.includeGlobal Also check global ~/.cleo
|
|
50
50
|
* @param options.autoMigrate Auto-migrate storage if needed (default: true)
|
|
51
|
+
* @param options.forceDetect Force re-detection of project type (ignore staleness)
|
|
52
|
+
* @param options.mapCodebase Run full codebase analysis and store to brain.db
|
|
53
|
+
* @param options.projectName Update project name in project-info and nexus
|
|
51
54
|
* @param options.cwd Project directory override
|
|
52
55
|
*/
|
|
53
56
|
export declare function runUpgrade(options?: {
|
|
54
57
|
dryRun?: boolean;
|
|
55
58
|
includeGlobal?: boolean;
|
|
56
59
|
autoMigrate?: boolean;
|
|
60
|
+
forceDetect?: boolean;
|
|
61
|
+
mapCodebase?: boolean;
|
|
62
|
+
projectName?: string;
|
|
57
63
|
cwd?: string;
|
|
58
64
|
}): Promise<UpgradeResult>;
|
|
59
65
|
//# sourceMappingURL=upgrade.d.ts.map
|
package/dist/upgrade.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAoCH,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,2BAA2B;AAC3B,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,iEAAiE;IACjE,gBAAgB,CAAC,EAAE;QACjB,QAAQ,EAAE,OAAO,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH;AAED
|
|
1
|
+
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAoCH,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,2BAA2B;AAC3B,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,iEAAiE;IACjE,gBAAgB,CAAC,EAAE;QACjB,QAAQ,EAAE,OAAO,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,UAAU,CAC9B,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACT,GACL,OAAO,CAAC,aAAa,CAAC,CAg4BxB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cleocode/core",
|
|
3
|
-
"version": "2026.3.
|
|
3
|
+
"version": "2026.3.49",
|
|
4
4
|
"description": "CLEO core business logic kernel — tasks, sessions, memory, orchestration, lifecycle, with bundled SQLite store",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"write-file-atomic": "^6.0.0",
|
|
37
37
|
"yaml": "^2.8.2",
|
|
38
38
|
"zod": "^3.25.76",
|
|
39
|
-
"@cleocode/
|
|
40
|
-
"@cleocode/
|
|
41
|
-
"@cleocode/
|
|
42
|
-
"@cleocode/
|
|
39
|
+
"@cleocode/contracts": "2026.3.49",
|
|
40
|
+
"@cleocode/adapters": "2026.3.49",
|
|
41
|
+
"@cleocode/agents": "2026.3.49",
|
|
42
|
+
"@cleocode/skills": "2026.3.49"
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
|
45
45
|
"node": ">=24.0.0"
|
|
@@ -257,8 +257,9 @@ describe('E2E: injection chain validation (T4694)', () => {
|
|
|
257
257
|
expect(existsSync(join(testDir, 'CLAUDE.md'))).toBe(true);
|
|
258
258
|
expect(existsSync(join(testDir, 'AGENTS.md'))).toBe(true);
|
|
259
259
|
|
|
260
|
-
// Run updateDocs
|
|
261
|
-
const
|
|
260
|
+
// Run updateDocs directly (no longer available via initProject flag — use upgrade path)
|
|
261
|
+
const { updateDocs } = await import('../init.js');
|
|
262
|
+
const result = await updateDocs();
|
|
262
263
|
expect(result.updateDocsOnly).toBe(true);
|
|
263
264
|
expect(result.initialized).toBe(true);
|
|
264
265
|
});
|
package/src/bootstrap.ts
CHANGED
|
@@ -53,6 +53,14 @@ export async function bootstrapGlobalCleo(options?: BootstrapOptions): Promise<B
|
|
|
53
53
|
isDryRun: options?.dryRun ?? false,
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
+
// Step 0: Ensure global home structure and clean stale artifacts
|
|
57
|
+
try {
|
|
58
|
+
const { ensureGlobalHome } = await import('./scaffold.js');
|
|
59
|
+
await ensureGlobalHome();
|
|
60
|
+
} catch {
|
|
61
|
+
// Best-effort — don't fail bootstrap if cleanup fails
|
|
62
|
+
}
|
|
63
|
+
|
|
56
64
|
// Step 1: Ensure global templates
|
|
57
65
|
await ensureGlobalTemplatesBootstrap(ctx, options?.packageRoot);
|
|
58
66
|
|
|
@@ -135,19 +143,20 @@ async function injectAgentsHub(ctx: BootstrapContext): Promise<void> {
|
|
|
135
143
|
if (!ctx.isDryRun) {
|
|
136
144
|
await mkdir(globalAgentsDir, { recursive: true });
|
|
137
145
|
|
|
138
|
-
//
|
|
146
|
+
// Consolidate: strip ALL legacy CLEO blocks AND duplicate CAAMP blocks,
|
|
147
|
+
// then inject a single clean block. CAAMP 1.8.0 idempotency doesn't
|
|
148
|
+
// consolidate pre-existing duplicates — it only prevents new ones.
|
|
139
149
|
if (existsSync(globalAgentsMd)) {
|
|
140
150
|
const content = await readFile(globalAgentsMd, 'utf8');
|
|
141
|
-
const stripped = content
|
|
142
|
-
/\n?<!-- CLEO:START[^>]*-->[\s\S]*?<!-- CLEO:END -->\n?/g,
|
|
143
|
-
''
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
151
|
+
const stripped = content
|
|
152
|
+
.replace(/\n?<!-- CLEO:START[^>]*-->[\s\S]*?<!-- CLEO:END -->\n?/g, '')
|
|
153
|
+
.replace(/\n?<!-- CAAMP:START -->[\s\S]*?<!-- CAAMP:END -->\n?/g, '')
|
|
154
|
+
.trim();
|
|
155
|
+
// Write clean file (empty or user content only)
|
|
156
|
+
await writeFile(globalAgentsMd, stripped ? `${stripped}\n` : '', 'utf8');
|
|
148
157
|
}
|
|
149
158
|
|
|
150
|
-
//
|
|
159
|
+
// Single inject call on a clean file — no duplicates possible
|
|
151
160
|
const expectedContent = '@~/.cleo/templates/CLEO-INJECTION.md';
|
|
152
161
|
const action = await inject(globalAgentsMd, expectedContent);
|
|
153
162
|
ctx.created.push(`~/.agents/AGENTS.md (${action})`);
|
package/src/init.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* 9. Core skill installation via CAAMP
|
|
17
17
|
* 10. NEXUS project registration
|
|
18
18
|
* 11. Project type detection (--detect)
|
|
19
|
-
* 12. Injection refresh
|
|
19
|
+
* 12. Injection refresh
|
|
20
20
|
* 13. Git hook installation (commit-msg, pre-commit)
|
|
21
21
|
* 14. GitHub issue/PR templates (.github/ directory)
|
|
22
22
|
*
|
|
@@ -68,8 +68,6 @@ export interface InitOptions {
|
|
|
68
68
|
force?: boolean;
|
|
69
69
|
/** Auto-detect project configuration. */
|
|
70
70
|
detect?: boolean;
|
|
71
|
-
/** Update agent documentation injections only. */
|
|
72
|
-
updateDocs?: boolean;
|
|
73
71
|
/** Run codebase analysis and store findings to brain.db. */
|
|
74
72
|
mapCodebase?: boolean;
|
|
75
73
|
}
|
|
@@ -132,12 +130,19 @@ export async function initAgentDefinition(created: string[], warnings: string[])
|
|
|
132
130
|
await mkdir(dirname(globalAgentsDir), { recursive: true });
|
|
133
131
|
|
|
134
132
|
try {
|
|
135
|
-
// Check if symlink already exists
|
|
133
|
+
// Check if symlink already exists and points to correct target
|
|
136
134
|
try {
|
|
137
135
|
const stat = await lstat(globalAgentsDir);
|
|
138
|
-
if (stat.isSymbolicLink()
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
if (stat.isSymbolicLink()) {
|
|
137
|
+
const { readlink } = await import('node:fs/promises');
|
|
138
|
+
const currentTarget = await readlink(globalAgentsDir);
|
|
139
|
+
if (currentTarget === agentSourceDir) {
|
|
140
|
+
return; // Symlink intact and pointing to correct location
|
|
141
|
+
}
|
|
142
|
+
// Stale symlink — remove and recreate
|
|
143
|
+
await unlink(globalAgentsDir);
|
|
144
|
+
} else if (stat.isDirectory()) {
|
|
145
|
+
return; // Copied dir, leave as-is
|
|
141
146
|
}
|
|
142
147
|
} catch {
|
|
143
148
|
// Doesn't exist, proceed to create
|
|
@@ -472,11 +477,6 @@ export async function updateDocs(): Promise<InitResult> {
|
|
|
472
477
|
* @task T4707
|
|
473
478
|
*/
|
|
474
479
|
export async function initProject(opts: InitOptions = {}): Promise<InitResult> {
|
|
475
|
-
// Handle --update-docs (T4686)
|
|
476
|
-
if (opts.updateDocs) {
|
|
477
|
-
return updateDocs();
|
|
478
|
-
}
|
|
479
|
-
|
|
480
480
|
const cleoDir = getCleoDirAbsolute();
|
|
481
481
|
const projRoot = getProjectRoot();
|
|
482
482
|
|
package/src/injection.ts
CHANGED
|
@@ -281,7 +281,7 @@ export function checkInjection(projectRoot: string): InjectionCheckResult {
|
|
|
281
281
|
status: 'warning',
|
|
282
282
|
message: 'AGENTS.md not found in project root',
|
|
283
283
|
details: { path: agentsMdPath, exists: false },
|
|
284
|
-
fix: 'cleo
|
|
284
|
+
fix: 'cleo upgrade',
|
|
285
285
|
};
|
|
286
286
|
}
|
|
287
287
|
|
|
@@ -311,7 +311,7 @@ export function checkInjection(projectRoot: string): InjectionCheckResult {
|
|
|
311
311
|
status: 'warning',
|
|
312
312
|
message: 'AGENTS.md exists but has no CAAMP markers',
|
|
313
313
|
details: { path: agentsMdPath, hasCaampMarker: false },
|
|
314
|
-
fix: 'cleo
|
|
314
|
+
fix: 'cleo upgrade',
|
|
315
315
|
};
|
|
316
316
|
}
|
|
317
317
|
|
|
@@ -323,7 +323,7 @@ export function checkInjection(projectRoot: string): InjectionCheckResult {
|
|
|
323
323
|
status: 'warning',
|
|
324
324
|
message: `CAAMP markers unbalanced: ${startCount} START vs ${endCount} END`,
|
|
325
325
|
details: { path: agentsMdPath, startCount, endCount },
|
|
326
|
-
fix: 'cleo
|
|
326
|
+
fix: 'cleo upgrade',
|
|
327
327
|
};
|
|
328
328
|
}
|
|
329
329
|
|
|
@@ -352,7 +352,7 @@ export function checkInjection(projectRoot: string): InjectionCheckResult {
|
|
|
352
352
|
status: 'warning',
|
|
353
353
|
message: `Missing @ reference targets: ${missing.join(', ')}`,
|
|
354
354
|
details: { path: agentsMdPath, missing, totalRefs: refs.length },
|
|
355
|
-
fix: 'cleo
|
|
355
|
+
fix: 'cleo upgrade',
|
|
356
356
|
};
|
|
357
357
|
}
|
|
358
358
|
}
|
|
@@ -372,7 +372,7 @@ export function checkInjection(projectRoot: string): InjectionCheckResult {
|
|
|
372
372
|
status: 'warning',
|
|
373
373
|
message: `CLAUDE.md CAAMP markers unbalanced: ${cStartCount} START vs ${cEndCount} END`,
|
|
374
374
|
details: { file: 'CLAUDE.md', startCount: cStartCount, endCount: cEndCount },
|
|
375
|
-
fix: 'cleo
|
|
375
|
+
fix: 'cleo upgrade',
|
|
376
376
|
};
|
|
377
377
|
}
|
|
378
378
|
|
|
@@ -383,7 +383,7 @@ export function checkInjection(projectRoot: string): InjectionCheckResult {
|
|
|
383
383
|
status: 'warning',
|
|
384
384
|
message: 'CLAUDE.md has no CAAMP markers',
|
|
385
385
|
details: { file: 'CLAUDE.md', hasCaampMarker: false },
|
|
386
|
-
fix: 'cleo
|
|
386
|
+
fix: 'cleo upgrade',
|
|
387
387
|
};
|
|
388
388
|
}
|
|
389
389
|
} catch {
|
package/src/project-info.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @task T5333
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
11
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
12
12
|
import { readFile } from 'node:fs/promises';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
import { getCleoDirAbsolute } from './paths.js';
|
|
@@ -92,3 +92,18 @@ export function getProjectInfoSync(cwd?: string): ProjectInfo | null {
|
|
|
92
92
|
return null;
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Update the project name in project-info.json.
|
|
98
|
+
* Used by `cleo upgrade --name` and programmatic consumers.
|
|
99
|
+
*/
|
|
100
|
+
export function updateProjectName(cwd: string, name: string): void {
|
|
101
|
+
const cleoDir = getCleoDirAbsolute(cwd);
|
|
102
|
+
const infoPath = join(cleoDir, 'project-info.json');
|
|
103
|
+
if (!existsSync(infoPath)) return;
|
|
104
|
+
|
|
105
|
+
const data = JSON.parse(readFileSync(infoPath, 'utf-8')) as Record<string, string>;
|
|
106
|
+
data.projectName = name;
|
|
107
|
+
data.lastUpdated = new Date().toISOString();
|
|
108
|
+
writeFileSync(infoPath, `${JSON.stringify(data, null, 2)}\n`);
|
|
109
|
+
}
|
package/src/upgrade.ts
CHANGED
|
@@ -85,10 +85,21 @@ export interface UpgradeResult {
|
|
|
85
85
|
* @param options.dryRun Preview changes without applying
|
|
86
86
|
* @param options.includeGlobal Also check global ~/.cleo
|
|
87
87
|
* @param options.autoMigrate Auto-migrate storage if needed (default: true)
|
|
88
|
+
* @param options.forceDetect Force re-detection of project type (ignore staleness)
|
|
89
|
+
* @param options.mapCodebase Run full codebase analysis and store to brain.db
|
|
90
|
+
* @param options.projectName Update project name in project-info and nexus
|
|
88
91
|
* @param options.cwd Project directory override
|
|
89
92
|
*/
|
|
90
93
|
export async function runUpgrade(
|
|
91
|
-
options: {
|
|
94
|
+
options: {
|
|
95
|
+
dryRun?: boolean;
|
|
96
|
+
includeGlobal?: boolean;
|
|
97
|
+
autoMigrate?: boolean;
|
|
98
|
+
forceDetect?: boolean;
|
|
99
|
+
mapCodebase?: boolean;
|
|
100
|
+
projectName?: string;
|
|
101
|
+
cwd?: string;
|
|
102
|
+
} = {},
|
|
92
103
|
): Promise<UpgradeResult> {
|
|
93
104
|
const isDryRun = options.dryRun ?? false;
|
|
94
105
|
const autoMigrate = options.autoMigrate ?? true;
|
|
@@ -635,7 +646,9 @@ export async function runUpgrade(
|
|
|
635
646
|
}
|
|
636
647
|
}
|
|
637
648
|
} else {
|
|
638
|
-
const contextResult = await ensureProjectContext(projectRootForContext, {
|
|
649
|
+
const contextResult = await ensureProjectContext(projectRootForContext, {
|
|
650
|
+
staleDays: options.forceDetect ? 0 : 30,
|
|
651
|
+
});
|
|
639
652
|
actions.push({
|
|
640
653
|
action: 'project_context_detection',
|
|
641
654
|
status: contextResult.action === 'skipped' ? 'skipped' : 'applied',
|
|
@@ -886,6 +899,40 @@ export async function runUpgrade(
|
|
|
886
899
|
/* best-effort */
|
|
887
900
|
}
|
|
888
901
|
|
|
902
|
+
// Run codebase mapping if requested (delegates to core mapCodebase)
|
|
903
|
+
if (options.mapCodebase) {
|
|
904
|
+
try {
|
|
905
|
+
const { mapCodebase } = await import('./codebase-map/index.js');
|
|
906
|
+
const mapResult = await mapCodebase(projectRootForMaint, { storeToBrain: true });
|
|
907
|
+
actions.push({
|
|
908
|
+
action: 'codebase_map',
|
|
909
|
+
status: 'applied',
|
|
910
|
+
details: `Analyzed: ${mapResult.stack?.languages?.length ?? 0} languages, ${mapResult.concerns?.todos?.length ?? 0} TODOs found`,
|
|
911
|
+
});
|
|
912
|
+
} catch (err) {
|
|
913
|
+
actions.push({
|
|
914
|
+
action: 'codebase_map',
|
|
915
|
+
status: 'error',
|
|
916
|
+
details: `Codebase mapping failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
// Update project name if requested (delegates to core updateProjectName)
|
|
922
|
+
if (options.projectName) {
|
|
923
|
+
try {
|
|
924
|
+
const { updateProjectName } = await import('./project-info.js');
|
|
925
|
+
await updateProjectName(projectRootForMaint, options.projectName);
|
|
926
|
+
actions.push({
|
|
927
|
+
action: 'project_name_update',
|
|
928
|
+
status: 'applied',
|
|
929
|
+
details: `Project name set to "${options.projectName}"`,
|
|
930
|
+
});
|
|
931
|
+
} catch {
|
|
932
|
+
/* best-effort */
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
889
936
|
// GitHub issue/PR templates — install missing ones, warn if absent
|
|
890
937
|
try {
|
|
891
938
|
const { existsSync: fsExistsSync } = await import('node:fs');
|
|
@@ -211,7 +211,7 @@ export function checkAgentsMdHub(projectRoot?: string): CheckResult {
|
|
|
211
211
|
status: 'warning',
|
|
212
212
|
message: 'AGENTS.md not found in project root',
|
|
213
213
|
details: { path: agentsMdPath, exists: false },
|
|
214
|
-
fix: 'cleo
|
|
214
|
+
fix: 'cleo upgrade',
|
|
215
215
|
};
|
|
216
216
|
}
|
|
217
217
|
|
|
@@ -236,7 +236,7 @@ export function checkAgentsMdHub(projectRoot?: string): CheckResult {
|
|
|
236
236
|
status: 'warning',
|
|
237
237
|
message: 'AGENTS.md exists but has no CAAMP:START marker',
|
|
238
238
|
details: { path: agentsMdPath, hasCaampMarker: false },
|
|
239
|
-
fix: 'cleo
|
|
239
|
+
fix: 'cleo upgrade',
|
|
240
240
|
};
|
|
241
241
|
}
|
|
242
242
|
|
|
@@ -709,7 +709,7 @@ export function checkCaampMarkerIntegrity(projectRoot?: string): CheckResult {
|
|
|
709
709
|
status: 'warning',
|
|
710
710
|
message: `CAAMP marker issues: ${issues.join('; ')}`,
|
|
711
711
|
details: { issues },
|
|
712
|
-
fix: 'cleo
|
|
712
|
+
fix: 'cleo upgrade',
|
|
713
713
|
};
|
|
714
714
|
}
|
|
715
715
|
|
|
@@ -797,7 +797,7 @@ export function checkAtReferenceTargetExists(projectRoot?: string): CheckResult
|
|
|
797
797
|
status: 'warning',
|
|
798
798
|
message: `Missing @ reference targets: ${missing.join(', ')}`,
|
|
799
799
|
details: { missing, totalRefs: refs.length },
|
|
800
|
-
fix: 'cleo
|
|
800
|
+
fix: 'cleo upgrade',
|
|
801
801
|
};
|
|
802
802
|
}
|
|
803
803
|
|