@monoes/monomindcli 2.16.5 → 2.16.7
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/commands/agents/agent-capabilities.md +2 -5
- package/.claude/commands/coordination/task-orchestrate.md +0 -1
- package/.claude/commands/hooks/post-edit.md +1 -1
- package/.claude/commands/hooks/post-task.md +2 -3
- package/.claude/commands/hooks/pre-edit.md +0 -2
- package/.claude/commands/hooks/session-end.md +4 -4
- package/.claude/commands/monoswarm/consensus.md +1 -1
- package/.claude/commands/monoswarm/memory.md +1 -1
- package/.claude/commands/monoswarm/monoswarm.md +1 -1
- package/.claude/commands/monoswarm/spawn.md +1 -1
- package/.claude/commands/optimization/auto-topology.md +6 -9
- package/.claude/commands/optimization/performance-optimize.md +23 -39
- package/.claude/helpers/pick-rank.cjs +118 -9
- package/dist/src/catalog/projection.d.ts.map +1 -1
- package/dist/src/catalog/projection.js +2 -1
- package/dist/src/catalog/projection.js.map +1 -1
- package/dist/src/commands/agent-exec.d.ts.map +1 -1
- package/dist/src/commands/agent-exec.js +10 -1
- package/dist/src/commands/agent-exec.js.map +1 -1
- package/dist/src/commands/cleanup-plan.d.ts +3 -2
- package/dist/src/commands/cleanup-plan.d.ts.map +1 -1
- package/dist/src/commands/cleanup-plan.js +25 -5
- package/dist/src/commands/cleanup-plan.js.map +1 -1
- package/dist/src/commands/doctor.js +1 -1
- package/dist/src/commands/doctor.js.map +1 -1
- package/dist/src/commands/hooks-core-commands.d.ts.map +1 -1
- package/dist/src/commands/hooks-core-commands.js +10 -42
- package/dist/src/commands/hooks-core-commands.js.map +1 -1
- package/dist/src/commands/hooks-extended-commands.d.ts.map +1 -1
- package/dist/src/commands/hooks-extended-commands.js +3 -4
- package/dist/src/commands/hooks-extended-commands.js.map +1 -1
- package/dist/src/commands/hooks-routing-commands.d.ts.map +1 -1
- package/dist/src/commands/hooks-routing-commands.js +13 -24
- package/dist/src/commands/hooks-routing-commands.js.map +1 -1
- package/dist/src/commands/hooks-workers.d.ts.map +1 -1
- package/dist/src/commands/hooks-workers.js +0 -5
- package/dist/src/commands/hooks-workers.js.map +1 -1
- package/dist/src/commands/hooks.d.ts.map +1 -1
- package/dist/src/commands/hooks.js +9 -16
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/monograph.d.ts.map +1 -1
- package/dist/src/commands/monograph.js +24 -2
- package/dist/src/commands/monograph.js.map +1 -1
- package/dist/src/commands/org.d.ts.map +1 -1
- package/dist/src/commands/org.js +29 -1
- package/dist/src/commands/org.js.map +1 -1
- package/dist/src/commands/platforms.js +2 -1
- package/dist/src/commands/platforms.js.map +1 -1
- package/dist/src/init/asset-maps.d.ts +46 -0
- package/dist/src/init/asset-maps.d.ts.map +1 -0
- package/dist/src/init/asset-maps.js +177 -0
- package/dist/src/init/asset-maps.js.map +1 -0
- package/dist/src/init/copy-assets.d.ts.map +1 -1
- package/dist/src/init/copy-assets.js +4 -1
- package/dist/src/init/copy-assets.js.map +1 -1
- package/dist/src/init/executor.d.ts.map +1 -1
- package/dist/src/init/executor.js +6 -3
- package/dist/src/init/executor.js.map +1 -1
- package/dist/src/init/file-guard.d.ts +6 -0
- package/dist/src/init/file-guard.d.ts.map +1 -1
- package/dist/src/init/file-guard.js +27 -11
- package/dist/src/init/file-guard.js.map +1 -1
- package/dist/src/init/fs-helpers.d.ts +63 -0
- package/dist/src/init/fs-helpers.d.ts.map +1 -0
- package/dist/src/init/fs-helpers.js +198 -0
- package/dist/src/init/fs-helpers.js.map +1 -0
- package/dist/src/init/init-manifest.d.ts +106 -0
- package/dist/src/init/init-manifest.d.ts.map +1 -0
- package/dist/src/init/init-manifest.js +222 -0
- package/dist/src/init/init-manifest.js.map +1 -0
- package/dist/src/init/shared.d.ts +3 -201
- package/dist/src/init/shared.d.ts.map +1 -1
- package/dist/src/init/shared.js +7 -573
- package/dist/src/init/shared.js.map +1 -1
- package/dist/src/init/upgrade.d.ts.map +1 -1
- package/dist/src/init/upgrade.js +4 -2
- package/dist/src/init/upgrade.js.map +1 -1
- package/dist/src/init/write-antigravity.d.ts.map +1 -1
- package/dist/src/init/write-antigravity.js +2 -1
- package/dist/src/init/write-antigravity.js.map +1 -1
- package/dist/src/init/write-capabilities.js +2 -1
- package/dist/src/init/write-capabilities.js.map +1 -1
- package/dist/src/init/write-claude.d.ts +3 -5
- package/dist/src/init/write-claude.d.ts.map +1 -1
- package/dist/src/init/write-claude.js +6 -210
- package/dist/src/init/write-claude.js.map +1 -1
- package/dist/src/init/write-codex.js +1 -1
- package/dist/src/init/write-codex.js.map +1 -1
- package/dist/src/init/write-kimicode.d.ts.map +1 -1
- package/dist/src/init/write-kimicode.js +6 -2
- package/dist/src/init/write-kimicode.js.map +1 -1
- package/dist/src/init/write-opencode.d.ts.map +1 -1
- package/dist/src/init/write-opencode.js +5 -4
- package/dist/src/init/write-opencode.js.map +1 -1
- package/dist/src/init/write-runtime-config.d.ts.map +1 -1
- package/dist/src/init/write-runtime-config.js +2 -1
- package/dist/src/init/write-runtime-config.js.map +1 -1
- package/dist/src/init/write-settings.d.ts +9 -0
- package/dist/src/init/write-settings.d.ts.map +1 -0
- package/dist/src/init/write-settings.js +217 -0
- package/dist/src/init/write-settings.js.map +1 -0
- package/dist/src/mcp-tools/hooks-intelligence.d.ts.map +1 -1
- package/dist/src/mcp-tools/hooks-intelligence.js +2 -1
- package/dist/src/mcp-tools/hooks-intelligence.js.map +1 -1
- package/dist/src/mcp-tools/hooks-routing.d.ts.map +1 -1
- package/dist/src/mcp-tools/hooks-routing.js +11 -11
- package/dist/src/mcp-tools/hooks-routing.js.map +1 -1
- package/dist/src/mcp-tools/platforms-tools.js +1 -1
- package/dist/src/mcp-tools/platforms-tools.js.map +1 -1
- package/dist/src/monovector/command-outcomes.d.ts +2 -1
- package/dist/src/monovector/command-outcomes.d.ts.map +1 -1
- package/dist/src/monovector/command-outcomes.js +2 -2
- package/dist/src/monovector/command-outcomes.js.map +1 -1
- package/dist/src/orgrt/approvals.d.ts +25 -0
- package/dist/src/orgrt/approvals.d.ts.map +1 -1
- package/dist/src/orgrt/approvals.js +51 -2
- package/dist/src/orgrt/approvals.js.map +1 -1
- package/dist/src/orgrt/budget-closure.d.ts +27 -0
- package/dist/src/orgrt/budget-closure.d.ts.map +1 -0
- package/dist/src/orgrt/budget-closure.js +179 -0
- package/dist/src/orgrt/budget-closure.js.map +1 -0
- package/dist/src/orgrt/daemon.d.ts +14 -2
- package/dist/src/orgrt/daemon.d.ts.map +1 -1
- package/dist/src/orgrt/daemon.js +37 -2
- package/dist/src/orgrt/daemon.js.map +1 -1
- package/dist/src/orgrt/decisions.d.ts +8 -0
- package/dist/src/orgrt/decisions.d.ts.map +1 -1
- package/dist/src/orgrt/decisions.js +7 -1
- package/dist/src/orgrt/decisions.js.map +1 -1
- package/dist/src/orgrt/policy.d.ts +6 -0
- package/dist/src/orgrt/policy.d.ts.map +1 -1
- package/dist/src/orgrt/policy.js +5 -0
- package/dist/src/orgrt/policy.js.map +1 -1
- package/dist/src/orgrt/runner-registry.d.ts +11 -2
- package/dist/src/orgrt/runner-registry.d.ts.map +1 -1
- package/dist/src/orgrt/runner-registry.js +11 -34
- package/dist/src/orgrt/runner-registry.js.map +1 -1
- package/dist/src/orgrt/task-dag.d.ts +13 -0
- package/dist/src/orgrt/task-dag.d.ts.map +1 -1
- package/dist/src/orgrt/task-dag.js +29 -0
- package/dist/src/orgrt/task-dag.js.map +1 -1
- package/dist/src/orgrt/version-probe.d.ts +43 -0
- package/dist/src/orgrt/version-probe.d.ts.map +1 -0
- package/dist/src/orgrt/version-probe.js +136 -0
- package/dist/src/orgrt/version-probe.js.map +1 -0
- package/dist/src/platform-adapters/locations.d.ts +12 -0
- package/dist/src/platform-adapters/locations.d.ts.map +1 -0
- package/dist/src/platform-adapters/locations.js +57 -0
- package/dist/src/platform-adapters/locations.js.map +1 -0
- package/dist/src/platform-adapters/merge.d.ts +13 -0
- package/dist/src/platform-adapters/merge.d.ts.map +1 -1
- package/dist/src/platform-adapters/merge.js +33 -1
- package/dist/src/platform-adapters/merge.js.map +1 -1
- package/dist/src/platform-adapters/migration.d.ts.map +1 -1
- package/dist/src/platform-adapters/migration.js +10 -5
- package/dist/src/platform-adapters/migration.js.map +1 -1
- package/dist/src/platform-adapters/mutation.js +1 -1
- package/dist/src/platform-adapters/mutation.js.map +1 -1
- package/dist/src/platform-adapters/operations.d.ts +3 -16
- package/dist/src/platform-adapters/operations.d.ts.map +1 -1
- package/dist/src/platform-adapters/operations.js +43 -167
- package/dist/src/platform-adapters/operations.js.map +1 -1
- package/dist/src/platform-adapters/owned-files.d.ts +23 -0
- package/dist/src/platform-adapters/owned-files.d.ts.map +1 -0
- package/dist/src/platform-adapters/owned-files.js +64 -0
- package/dist/src/platform-adapters/owned-files.js.map +1 -0
- package/dist/src/platform-adapters/platform-doctor.d.ts +9 -0
- package/dist/src/platform-adapters/platform-doctor.d.ts.map +1 -0
- package/dist/src/platform-adapters/platform-doctor.js +117 -0
- package/dist/src/platform-adapters/platform-doctor.js.map +1 -0
- package/dist/src/platform-adapters/renderers/skills.d.ts.map +1 -1
- package/dist/src/platform-adapters/renderers/skills.js +5 -2
- package/dist/src/platform-adapters/renderers/skills.js.map +1 -1
- package/dist/src/platform-adapters/shared-surface.d.ts +7 -4
- package/dist/src/platform-adapters/shared-surface.d.ts.map +1 -1
- package/dist/src/platform-adapters/shared-surface.js +9 -5
- package/dist/src/platform-adapters/shared-surface.js.map +1 -1
- package/dist/src/platform-adapters/types.d.ts +24 -1
- package/dist/src/platform-adapters/types.d.ts.map +1 -1
- package/dist/src/protocol-capabilities.d.ts +4 -1
- package/dist/src/protocol-capabilities.d.ts.map +1 -1
- package/dist/src/protocol-capabilities.js +4 -0
- package/dist/src/protocol-capabilities.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem helpers shared by the init write-* modules: atomic and
|
|
3
|
+
* timestamp-stable writes, the conversion-target guard, and tree walkers.
|
|
4
|
+
*/
|
|
5
|
+
import type { InitResult } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Atomic write helper — writes to a sibling .tmp file then renames into place.
|
|
8
|
+
* SIGINT or crash during a partial write would otherwise corrupt user-critical
|
|
9
|
+
* files (.claude/settings.json, .mcp.json, helper scripts that Claude Code
|
|
10
|
+
* executes on every hook). Without atomicity a half-written settings.json or
|
|
11
|
+
* a zero-byte hook-handler.cjs disables Claude Code's protections silently.
|
|
12
|
+
*/
|
|
13
|
+
export declare function atomicWriteFile(target: string, content: string | Buffer, encoding?: BufferEncoding): void;
|
|
14
|
+
/**
|
|
15
|
+
* Write a generated file that embeds a `Generated: <ISO timestamp>` line,
|
|
16
|
+
* skipping the write entirely when that stamp is the only thing that would
|
|
17
|
+
* change. Otherwise every `init --force` rewrote these files with a fresh
|
|
18
|
+
* timestamp and left the repository dirty by exactly two files, for
|
|
19
|
+
* information nobody can act on. Skipping the write (rather than reusing the
|
|
20
|
+
* old stamp) keeps the mtime stable too, and the stamp keeps its meaning:
|
|
21
|
+
* when this content was generated.
|
|
22
|
+
*/
|
|
23
|
+
export declare function writeGeneratedFile(target: string, content: string): void;
|
|
24
|
+
/**
|
|
25
|
+
* Guard for the write-opencode.ts / write-kimicode.ts converters, which read
|
|
26
|
+
* `.claude/{agents,commands,skills}` and write the converted result into what
|
|
27
|
+
* is expected to be a separate platform directory (`.opencode/...`,
|
|
28
|
+
* `.kimi-code/...`). If that destination has been symlinked back into
|
|
29
|
+
* `.claude/` (observed live: a committed `.opencode/command -> ../.claude/commands`
|
|
30
|
+
* symlink), the atomic write-then-rename in `atomicWriteFile` resolves through
|
|
31
|
+
* the symlink and lands the converted, flattened, field-injected output
|
|
32
|
+
* straight back in the Claude source tree it was just read from — silently
|
|
33
|
+
* corrupting hand-authored agent/skill/command files and resurrecting
|
|
34
|
+
* "deleted" flattened command duplicates on every `--force` run.
|
|
35
|
+
*
|
|
36
|
+
* Checked once per destination directory (not per file) before its copy loop.
|
|
37
|
+
* Returns false and records one `result.errors` entry when `destDir` resolves
|
|
38
|
+
* inside `claudeDir`; the caller should skip the whole loop rather than write
|
|
39
|
+
* file-by-file into the wrong place. A `destDir` that is itself a symlink to
|
|
40
|
+
* `claudeDir/<mirrorOf>` is a deliberate mirror (this repo links
|
|
41
|
+
* `.opencode/agent -> ../.claude/agents`), so it is skipped without the error.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isSafeConversionTarget(destDir: string, claudeDir: string, result: InitResult, label: string, mirrorOf?: string): boolean;
|
|
44
|
+
/** Relative file paths under `dir` (files only). Used by every o-38 mirror
|
|
45
|
+
* sweep (copySkills's `.gemini`/`.agents`, writeOpencodeFiles's
|
|
46
|
+
* `.opencode/skills`) to tell "content the source regenerated" from "a file
|
|
47
|
+
* someone added directly inside the mirror" (o-38 §2·0b). */
|
|
48
|
+
export declare function listFilesRecursive(dir: string): Set<string>;
|
|
49
|
+
/**
|
|
50
|
+
* Copy directory recursively
|
|
51
|
+
*/
|
|
52
|
+
export declare function copyDirRecursive(src: string, dest: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Count files with extension in directory
|
|
55
|
+
*/
|
|
56
|
+
export declare function countFiles(dir: string, ext: string): number;
|
|
57
|
+
/** Recursively collect .md files under dir, returned relative to dir. */
|
|
58
|
+
export declare function walkMdFiles(dir: string): string[];
|
|
59
|
+
/** Skip READMEs and other non-definition markdown. */
|
|
60
|
+
export declare function isLikelyUserFile(rel: string): boolean;
|
|
61
|
+
/** Pull the `name:` scalar from a frontmatter block (best-effort). */
|
|
62
|
+
export declare function extractFmName(md: string): string | null;
|
|
63
|
+
//# sourceMappingURL=fs-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-helpers.d.ts","sourceRoot":"","sources":["../../../src/init/fs-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,QAAQ,CAAC,EAAE,cAAc,GACxB,IAAI,CAUN;AAaD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAQxE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CA4BT;AAED;;;8DAG8D;AAC9D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAY3D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAmBhE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAgB3D;AAED,yEAAyE;AACzE,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBjD;AAED,sDAAsD;AACtD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAIrD;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMvD"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem helpers shared by the init write-* modules: atomic and
|
|
3
|
+
* timestamp-stable writes, the conversion-target guard, and tree walkers.
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'node:fs';
|
|
6
|
+
import * as path from 'node:path';
|
|
7
|
+
/**
|
|
8
|
+
* Atomic write helper — writes to a sibling .tmp file then renames into place.
|
|
9
|
+
* SIGINT or crash during a partial write would otherwise corrupt user-critical
|
|
10
|
+
* files (.claude/settings.json, .mcp.json, helper scripts that Claude Code
|
|
11
|
+
* executes on every hook). Without atomicity a half-written settings.json or
|
|
12
|
+
* a zero-byte hook-handler.cjs disables Claude Code's protections silently.
|
|
13
|
+
*/
|
|
14
|
+
export function atomicWriteFile(target, content, encoding) {
|
|
15
|
+
const tmp = `${target}.${process.pid}.tmp`;
|
|
16
|
+
if (encoding && typeof content === 'string') {
|
|
17
|
+
fs.writeFileSync(tmp, content, encoding);
|
|
18
|
+
}
|
|
19
|
+
else if (typeof content === 'string') {
|
|
20
|
+
fs.writeFileSync(tmp, content, 'utf-8');
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
fs.writeFileSync(tmp, content);
|
|
24
|
+
}
|
|
25
|
+
fs.renameSync(tmp, target);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The `Generated: <ISO timestamp>` stamp that .monomind/config.yaml and
|
|
29
|
+
* .monomind/CAPABILITIES.md carry, in whatever comment syntax their format
|
|
30
|
+
* uses (`# Generated: …`, `> Generated: …`).
|
|
31
|
+
*/
|
|
32
|
+
const GENERATED_TIMESTAMP = /(Generated:[^\S\r\n]*)\d{4}-\d{2}-\d{2}T[\d:.]+Z/g;
|
|
33
|
+
function withoutGeneratedTimestamp(content) {
|
|
34
|
+
return content.replace(GENERATED_TIMESTAMP, '$1<generated>');
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Write a generated file that embeds a `Generated: <ISO timestamp>` line,
|
|
38
|
+
* skipping the write entirely when that stamp is the only thing that would
|
|
39
|
+
* change. Otherwise every `init --force` rewrote these files with a fresh
|
|
40
|
+
* timestamp and left the repository dirty by exactly two files, for
|
|
41
|
+
* information nobody can act on. Skipping the write (rather than reusing the
|
|
42
|
+
* old stamp) keeps the mtime stable too, and the stamp keeps its meaning:
|
|
43
|
+
* when this content was generated.
|
|
44
|
+
*/
|
|
45
|
+
export function writeGeneratedFile(target, content) {
|
|
46
|
+
try {
|
|
47
|
+
const existing = fs.readFileSync(target, 'utf-8');
|
|
48
|
+
if (withoutGeneratedTimestamp(existing) === withoutGeneratedTimestamp(content))
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// No readable file on disk — fall through and write it.
|
|
53
|
+
}
|
|
54
|
+
atomicWriteFile(target, content);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Guard for the write-opencode.ts / write-kimicode.ts converters, which read
|
|
58
|
+
* `.claude/{agents,commands,skills}` and write the converted result into what
|
|
59
|
+
* is expected to be a separate platform directory (`.opencode/...`,
|
|
60
|
+
* `.kimi-code/...`). If that destination has been symlinked back into
|
|
61
|
+
* `.claude/` (observed live: a committed `.opencode/command -> ../.claude/commands`
|
|
62
|
+
* symlink), the atomic write-then-rename in `atomicWriteFile` resolves through
|
|
63
|
+
* the symlink and lands the converted, flattened, field-injected output
|
|
64
|
+
* straight back in the Claude source tree it was just read from — silently
|
|
65
|
+
* corrupting hand-authored agent/skill/command files and resurrecting
|
|
66
|
+
* "deleted" flattened command duplicates on every `--force` run.
|
|
67
|
+
*
|
|
68
|
+
* Checked once per destination directory (not per file) before its copy loop.
|
|
69
|
+
* Returns false and records one `result.errors` entry when `destDir` resolves
|
|
70
|
+
* inside `claudeDir`; the caller should skip the whole loop rather than write
|
|
71
|
+
* file-by-file into the wrong place. A `destDir` that is itself a symlink to
|
|
72
|
+
* `claudeDir/<mirrorOf>` is a deliberate mirror (this repo links
|
|
73
|
+
* `.opencode/agent -> ../.claude/agents`), so it is skipped without the error.
|
|
74
|
+
*/
|
|
75
|
+
export function isSafeConversionTarget(destDir, claudeDir, result, label, mirrorOf) {
|
|
76
|
+
let realDest;
|
|
77
|
+
try {
|
|
78
|
+
realDest = fs.realpathSync(destDir);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return true; // doesn't exist yet — mkdirSync will create a real directory
|
|
82
|
+
}
|
|
83
|
+
let realClaude;
|
|
84
|
+
try {
|
|
85
|
+
realClaude = fs.realpathSync(claudeDir);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return true; // no .claude/ to collide with
|
|
89
|
+
}
|
|
90
|
+
if (realDest === realClaude || realDest.startsWith(`${realClaude}${path.sep}`)) {
|
|
91
|
+
if (mirrorOf !== undefined &&
|
|
92
|
+
fs.lstatSync(destDir).isSymbolicLink() &&
|
|
93
|
+
realDest === path.join(realClaude, mirrorOf)) {
|
|
94
|
+
result.skipped.push(`${label} (symlink to .claude/${mirrorOf})`);
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
result.errors.push(`${label} resolves inside .claude/ (likely a symlink) — skipping to avoid writing converted files back into the Claude source tree. Remove or repoint the symlink and re-run.`);
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
/** Relative file paths under `dir` (files only). Used by every o-38 mirror
|
|
103
|
+
* sweep (copySkills's `.gemini`/`.agents`, writeOpencodeFiles's
|
|
104
|
+
* `.opencode/skills`) to tell "content the source regenerated" from "a file
|
|
105
|
+
* someone added directly inside the mirror" (o-38 §2·0b). */
|
|
106
|
+
export function listFilesRecursive(dir) {
|
|
107
|
+
const out = new Set();
|
|
108
|
+
if (!fs.existsSync(dir))
|
|
109
|
+
return out;
|
|
110
|
+
const walk = (d) => {
|
|
111
|
+
for (const entry of fs.readdirSync(d, { withFileTypes: true })) {
|
|
112
|
+
const full = path.join(d, entry.name);
|
|
113
|
+
if (entry.isDirectory())
|
|
114
|
+
walk(full);
|
|
115
|
+
else
|
|
116
|
+
out.add(path.relative(dir, full));
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
walk(dir);
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Copy directory recursively
|
|
124
|
+
*/
|
|
125
|
+
export function copyDirRecursive(src, dest) {
|
|
126
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
127
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
128
|
+
for (const entry of entries) {
|
|
129
|
+
// Skip exFAT/macOS AppleDouble junk files (e.g. "._foo.js") so they don't
|
|
130
|
+
// get perpetuated into every newly-initialized project.
|
|
131
|
+
if (entry.name.startsWith('._'))
|
|
132
|
+
continue;
|
|
133
|
+
const srcPath = path.join(src, entry.name);
|
|
134
|
+
const destPath = path.join(dest, entry.name);
|
|
135
|
+
if (entry.isDirectory()) {
|
|
136
|
+
copyDirRecursive(srcPath, destPath);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
fs.copyFileSync(srcPath, destPath);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Count files with extension in directory
|
|
145
|
+
*/
|
|
146
|
+
export function countFiles(dir, ext) {
|
|
147
|
+
let count = 0;
|
|
148
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
149
|
+
for (const entry of entries) {
|
|
150
|
+
const fullPath = path.join(dir, entry.name);
|
|
151
|
+
if (entry.isDirectory()) {
|
|
152
|
+
count += countFiles(fullPath, ext);
|
|
153
|
+
}
|
|
154
|
+
else if (entry.name.endsWith(ext)) {
|
|
155
|
+
count++;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return count;
|
|
159
|
+
}
|
|
160
|
+
/** Recursively collect .md files under dir, returned relative to dir. */
|
|
161
|
+
export function walkMdFiles(dir) {
|
|
162
|
+
const out = [];
|
|
163
|
+
const visit = (d, prefix) => {
|
|
164
|
+
let entries;
|
|
165
|
+
try {
|
|
166
|
+
entries = fs.readdirSync(d, { withFileTypes: true });
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
for (const e of entries) {
|
|
172
|
+
const rel = prefix ? `${prefix}${path.sep}${e.name}` : e.name;
|
|
173
|
+
if (e.isDirectory())
|
|
174
|
+
visit(path.join(d, e.name), rel);
|
|
175
|
+
else if (e.isFile() && /\.md$/i.test(e.name))
|
|
176
|
+
out.push(rel);
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
visit(dir, '');
|
|
180
|
+
return out;
|
|
181
|
+
}
|
|
182
|
+
/** Skip READMEs and other non-definition markdown. */
|
|
183
|
+
export function isLikelyUserFile(rel) {
|
|
184
|
+
const base = path.basename(rel).toLowerCase();
|
|
185
|
+
if (base === 'readme.md' || base === 'readme')
|
|
186
|
+
return false;
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
/** Pull the `name:` scalar from a frontmatter block (best-effort). */
|
|
190
|
+
export function extractFmName(md) {
|
|
191
|
+
const m = md.match(/^---\r?\n[\s\S]*?\r?\n---/);
|
|
192
|
+
if (!m)
|
|
193
|
+
return null;
|
|
194
|
+
const fm = m[0];
|
|
195
|
+
const nm = fm.match(/^name\s*:\s*(.+?)\s*$/m);
|
|
196
|
+
return nm ? nm[1].replace(/^["']|["']$/g, '') : null;
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=fs-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-helpers.js","sourceRoot":"","sources":["../../../src/init/fs-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { InitResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Provenance manifest for generated .claude content.
|
|
4
|
+
*
|
|
5
|
+
* init used to "clean stale" entries by deleting every name under
|
|
6
|
+
* .claude/{skills,commands,agents} that was absent from the current version's
|
|
7
|
+
* SKILLS_MAP/COMMANDS_MAP/AGENTS_MAP. Every user-authored command and skill is
|
|
8
|
+
* absent from those maps, so that pass deleted user content on the very first
|
|
9
|
+
* run — unrecoverable data loss.
|
|
10
|
+
*
|
|
11
|
+
* The manifest records exactly which entries *this tool* wrote, so the stale
|
|
12
|
+
* sweep can be restricted to those. Anything init did not write is never
|
|
13
|
+
* removed. Projects initialised by an older version have no manifest, so their
|
|
14
|
+
* first run under the fix deletes nothing and seeds the manifest instead;
|
|
15
|
+
* stale generated content may survive one extra run, which is the correct
|
|
16
|
+
* trade (preserving stale generated content is recoverable, deleting user
|
|
17
|
+
* content is not).
|
|
18
|
+
*/
|
|
19
|
+
export declare const INIT_MANIFEST_REL: string;
|
|
20
|
+
/**
|
|
21
|
+
* One retired entry's provenance (o-38): a name the manifest recorded that
|
|
22
|
+
* this version no longer ships, moved to `movedTo` instead of deleted.
|
|
23
|
+
* Appended-only — a later run's `recordGenerated` never drops this array, so
|
|
24
|
+
* the run after next can still tell a user what was retired and where it went.
|
|
25
|
+
*/
|
|
26
|
+
export interface RetiredEntry {
|
|
27
|
+
/** The manifest section for a `.claude`/`.kimi-code` entry (an
|
|
28
|
+
* `InitManifestSection` value), or a descriptive label for a mirror
|
|
29
|
+
* retirement (e.g. `gemini-skills`) — mirrors have no manifest section
|
|
30
|
+
* of their own, so this is an audit-trail label, not a lookup key. */
|
|
31
|
+
section: string;
|
|
32
|
+
name: string;
|
|
33
|
+
/** Path (relative to targetDir) the entry was moved to. */
|
|
34
|
+
movedTo: string;
|
|
35
|
+
/** ISO timestamp of the retirement. */
|
|
36
|
+
at: string;
|
|
37
|
+
}
|
|
38
|
+
export interface InitManifest {
|
|
39
|
+
version: number;
|
|
40
|
+
/** Entry names directly under .claude/skills that init generated. */
|
|
41
|
+
skills: string[];
|
|
42
|
+
/** Entry names directly under .claude/commands that init generated. */
|
|
43
|
+
commands: string[];
|
|
44
|
+
/** Entry names (category dirs) directly under .claude/agents that init generated. */
|
|
45
|
+
agents: string[];
|
|
46
|
+
/** Directory names directly under .kimi-code/skills that init generated. */
|
|
47
|
+
kimiSkills: string[];
|
|
48
|
+
/** File names directly under .kimi-code/plugin/commands that init generated. */
|
|
49
|
+
kimiPluginCommands: string[];
|
|
50
|
+
/** Directory names directly under .opencode/skills that init generated.
|
|
51
|
+
* Absent in manifests written before this field existed; normalised to
|
|
52
|
+
* an empty list on read, which the sweep treats as "delete nothing". */
|
|
53
|
+
opencodeSkills: string[];
|
|
54
|
+
/** Every entry ever retired (o-38) — see `RetiredEntry`. Absent on a
|
|
55
|
+
* manifest written before this field existed; treated as empty. */
|
|
56
|
+
retired?: RetiredEntry[];
|
|
57
|
+
/** sha256 of each shipped file as init last left it, keyed by its
|
|
58
|
+
* project-relative path — how a later run tells a user edit from an
|
|
59
|
+
* untouched install (see file-guard.ts). */
|
|
60
|
+
files?: Record<string, string>;
|
|
61
|
+
/** sha256 of each managed block's body as init last wrote it, keyed
|
|
62
|
+
* `<file>#<marker>` (see file-guard.ts). */
|
|
63
|
+
blocks?: Record<string, string>;
|
|
64
|
+
}
|
|
65
|
+
export type InitManifestSection = 'skills' | 'commands' | 'agents' | 'kimiSkills' | 'kimiPluginCommands' | 'opencodeSkills';
|
|
66
|
+
/**
|
|
67
|
+
* Read the provenance manifest. Returns null when absent or unreadable —
|
|
68
|
+
* callers must treat that as "provenance unknown", i.e. delete nothing.
|
|
69
|
+
*/
|
|
70
|
+
export declare function readInitManifest(targetDir: string): InitManifest | null;
|
|
71
|
+
/** Replace the manifest's `files` or `blocks` hash map, keeping every other
|
|
72
|
+
* field (see file-guard.ts). */
|
|
73
|
+
export declare function recordManifestHashes(targetDir: string, field: 'files' | 'blocks', hashes: Record<string, string>): void;
|
|
74
|
+
/**
|
|
75
|
+
* Names init previously generated in one section. Empty set when no manifest
|
|
76
|
+
* exists — which makes the stale sweep a no-op rather than a delete-everything.
|
|
77
|
+
*/
|
|
78
|
+
export declare function previouslyGenerated(targetDir: string, section: InitManifestSection): Set<string>;
|
|
79
|
+
/**
|
|
80
|
+
* Record the entries init just wrote for one section, merging into any
|
|
81
|
+
* existing manifest so a partial run (e.g. --only-claude, or a section whose
|
|
82
|
+
* source dir was missing) never drops provenance for the other sections.
|
|
83
|
+
*/
|
|
84
|
+
export declare function recordGenerated(targetDir: string, section: InitManifestSection, entries: string[]): void;
|
|
85
|
+
/**
|
|
86
|
+
* Retire a generated entry instead of deleting it (o-38): a name the
|
|
87
|
+
* manifest recorded that this version no longer ships anywhere is moved to
|
|
88
|
+
* `.monomind/backups/<run-timestamp>-<pid>/retired/<label>/` rather than
|
|
89
|
+
* `rmSync`-ed. The manifest's granularity is per-top-level-entry — "did init
|
|
90
|
+
* ever generate this name" — not per-file, so a stale-sweep candidate can
|
|
91
|
+
* still hold user files added since (a note beside a retired skill, e.g.)
|
|
92
|
+
* that must survive byte-identical.
|
|
93
|
+
*
|
|
94
|
+
* `label` doubles as the retirement's section plus display name, e.g.
|
|
95
|
+
* `skills/my-retired-skill` — the first path segment is an
|
|
96
|
+
* `InitManifestSection` value for the five real call sites, or a
|
|
97
|
+
* descriptive mirror label (`gemini-skills`, `agents-skills`,
|
|
98
|
+
* `opencode-skills`) for a mirror copy that turned out to hold user-added
|
|
99
|
+
* content (see `copySkills` / `writeOpencodeFiles`).
|
|
100
|
+
*
|
|
101
|
+
* On any failure, the entry is LEFT IN PLACE and a warning is recorded in
|
|
102
|
+
* `result.errors` — this must never fall back to deleting; a fix that
|
|
103
|
+
* deletes when the move fails is the original bug with extra steps.
|
|
104
|
+
*/
|
|
105
|
+
export declare function retireGeneratedEntry(targetDir: string, label: string, stalePath: string, result: InitResult): void;
|
|
106
|
+
//# sourceMappingURL=init-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-manifest.d.ts","sourceRoot":"","sources":["../../../src/init/init-manifest.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,QAA+C,CAAC;AAE9E;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B;;;2EAGuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,uEAAuE;IACvE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,qFAAqF;IACrF,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gFAAgF;IAChF,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B;;6EAEyE;IACzE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB;wEACoE;IACpE,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB;;iDAE6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B;iDAC6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,MAAM,mBAAmB,GAC3B,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,YAAY,GACZ,oBAAoB,GACpB,gBAAgB,CAAC;AAErB;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CA2CvE;AAWD;iCACiC;AACjC,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,GAAG,QAAQ,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,IAAI,CAoBN;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,GAAG,CAAC,MAAM,CAAC,CAEhG;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,mBAAmB,EAC5B,OAAO,EAAE,MAAM,EAAE,GAChB,IAAI,CAoBN;AAmDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,UAAU,GACjB,IAAI,CAsBN"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { atomicWriteFile } from './fs-helpers.js';
|
|
4
|
+
/**
|
|
5
|
+
* Provenance manifest for generated .claude content.
|
|
6
|
+
*
|
|
7
|
+
* init used to "clean stale" entries by deleting every name under
|
|
8
|
+
* .claude/{skills,commands,agents} that was absent from the current version's
|
|
9
|
+
* SKILLS_MAP/COMMANDS_MAP/AGENTS_MAP. Every user-authored command and skill is
|
|
10
|
+
* absent from those maps, so that pass deleted user content on the very first
|
|
11
|
+
* run — unrecoverable data loss.
|
|
12
|
+
*
|
|
13
|
+
* The manifest records exactly which entries *this tool* wrote, so the stale
|
|
14
|
+
* sweep can be restricted to those. Anything init did not write is never
|
|
15
|
+
* removed. Projects initialised by an older version have no manifest, so their
|
|
16
|
+
* first run under the fix deletes nothing and seeds the manifest instead;
|
|
17
|
+
* stale generated content may survive one extra run, which is the correct
|
|
18
|
+
* trade (preserving stale generated content is recoverable, deleting user
|
|
19
|
+
* content is not).
|
|
20
|
+
*/
|
|
21
|
+
export const INIT_MANIFEST_REL = path.join('.monomind', 'init-manifest.json');
|
|
22
|
+
/**
|
|
23
|
+
* Read the provenance manifest. Returns null when absent or unreadable —
|
|
24
|
+
* callers must treat that as "provenance unknown", i.e. delete nothing.
|
|
25
|
+
*/
|
|
26
|
+
export function readInitManifest(targetDir) {
|
|
27
|
+
const manifestPath = path.join(targetDir, INIT_MANIFEST_REL);
|
|
28
|
+
try {
|
|
29
|
+
if (!fs.existsSync(manifestPath))
|
|
30
|
+
return null;
|
|
31
|
+
const parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
32
|
+
if (!parsed || typeof parsed !== 'object')
|
|
33
|
+
return null;
|
|
34
|
+
return {
|
|
35
|
+
version: typeof parsed.version === 'number' ? parsed.version : 1,
|
|
36
|
+
skills: Array.isArray(parsed.skills)
|
|
37
|
+
? parsed.skills.filter((s) => typeof s === 'string')
|
|
38
|
+
: [],
|
|
39
|
+
commands: Array.isArray(parsed.commands)
|
|
40
|
+
? parsed.commands.filter((s) => typeof s === 'string')
|
|
41
|
+
: [],
|
|
42
|
+
agents: Array.isArray(parsed.agents)
|
|
43
|
+
? parsed.agents.filter((s) => typeof s === 'string')
|
|
44
|
+
: [],
|
|
45
|
+
kimiSkills: Array.isArray(parsed.kimiSkills)
|
|
46
|
+
? parsed.kimiSkills.filter((s) => typeof s === 'string')
|
|
47
|
+
: [],
|
|
48
|
+
kimiPluginCommands: Array.isArray(parsed.kimiPluginCommands)
|
|
49
|
+
? parsed.kimiPluginCommands.filter((s) => typeof s === 'string')
|
|
50
|
+
: [],
|
|
51
|
+
opencodeSkills: Array.isArray(parsed.opencodeSkills)
|
|
52
|
+
? parsed.opencodeSkills.filter((s) => typeof s === 'string')
|
|
53
|
+
: [],
|
|
54
|
+
retired: Array.isArray(parsed.retired)
|
|
55
|
+
? parsed.retired.filter((r) => !!r &&
|
|
56
|
+
typeof r === 'object' &&
|
|
57
|
+
typeof r.section === 'string' &&
|
|
58
|
+
typeof r.name === 'string' &&
|
|
59
|
+
typeof r.movedTo === 'string' &&
|
|
60
|
+
typeof r.at === 'string')
|
|
61
|
+
: [],
|
|
62
|
+
files: stringRecord(parsed.files),
|
|
63
|
+
blocks: stringRecord(parsed.blocks),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function stringRecord(value) {
|
|
71
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
72
|
+
return {};
|
|
73
|
+
return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === 'string'));
|
|
74
|
+
}
|
|
75
|
+
/** Replace the manifest's `files` or `blocks` hash map, keeping every other
|
|
76
|
+
* field (see file-guard.ts). */
|
|
77
|
+
export function recordManifestHashes(targetDir, field, hashes) {
|
|
78
|
+
const manifestPath = path.join(targetDir, INIT_MANIFEST_REL);
|
|
79
|
+
const manifest = readInitManifest(targetDir) ?? {
|
|
80
|
+
version: 1,
|
|
81
|
+
skills: [],
|
|
82
|
+
commands: [],
|
|
83
|
+
agents: [],
|
|
84
|
+
kimiSkills: [],
|
|
85
|
+
kimiPluginCommands: [],
|
|
86
|
+
opencodeSkills: [],
|
|
87
|
+
};
|
|
88
|
+
manifest[field] = Object.fromEntries(Object.entries(hashes).sort(([a], [b]) => a.localeCompare(b)));
|
|
89
|
+
try {
|
|
90
|
+
fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
|
|
91
|
+
atomicWriteFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Non-fatal: without hashes the next run treats these files as unrecorded.
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Names init previously generated in one section. Empty set when no manifest
|
|
99
|
+
* exists — which makes the stale sweep a no-op rather than a delete-everything.
|
|
100
|
+
*/
|
|
101
|
+
export function previouslyGenerated(targetDir, section) {
|
|
102
|
+
return new Set(readInitManifest(targetDir)?.[section] ?? []);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Record the entries init just wrote for one section, merging into any
|
|
106
|
+
* existing manifest so a partial run (e.g. --only-claude, or a section whose
|
|
107
|
+
* source dir was missing) never drops provenance for the other sections.
|
|
108
|
+
*/
|
|
109
|
+
export function recordGenerated(targetDir, section, entries) {
|
|
110
|
+
const manifestPath = path.join(targetDir, INIT_MANIFEST_REL);
|
|
111
|
+
const existing = readInitManifest(targetDir);
|
|
112
|
+
const manifest = existing ?? {
|
|
113
|
+
version: 1,
|
|
114
|
+
skills: [],
|
|
115
|
+
commands: [],
|
|
116
|
+
agents: [],
|
|
117
|
+
kimiSkills: [],
|
|
118
|
+
kimiPluginCommands: [],
|
|
119
|
+
opencodeSkills: [],
|
|
120
|
+
};
|
|
121
|
+
manifest.version = 1;
|
|
122
|
+
manifest[section] = [...new Set(entries)].sort();
|
|
123
|
+
try {
|
|
124
|
+
fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
|
|
125
|
+
atomicWriteFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Non-fatal: without a manifest the next run simply deletes nothing.
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Append one retirement to the manifest's `retired` array (o-38). A separate
|
|
133
|
+
* read-modify-write from `recordGenerated`'s, deliberately: `recordGenerated`
|
|
134
|
+
* REPLACES one section's active-entry list, and calling it after every single
|
|
135
|
+
* retirement (the stale-sweep loop can retire several names) would be wrong.
|
|
136
|
+
* This only ever appends, and appending here happens before the sweep's
|
|
137
|
+
* `recordGenerated` call, so `retired` survives that call's read of the
|
|
138
|
+
* manifest — `recordGenerated` never touches this field.
|
|
139
|
+
*/
|
|
140
|
+
function appendRetiredProvenance(targetDir, entry) {
|
|
141
|
+
const manifestPath = path.join(targetDir, INIT_MANIFEST_REL);
|
|
142
|
+
const existing = readInitManifest(targetDir);
|
|
143
|
+
const manifest = existing ?? {
|
|
144
|
+
version: 1,
|
|
145
|
+
skills: [],
|
|
146
|
+
commands: [],
|
|
147
|
+
agents: [],
|
|
148
|
+
kimiSkills: [],
|
|
149
|
+
kimiPluginCommands: [],
|
|
150
|
+
opencodeSkills: [],
|
|
151
|
+
retired: [],
|
|
152
|
+
};
|
|
153
|
+
manifest.retired = [...(manifest.retired ?? []), entry];
|
|
154
|
+
try {
|
|
155
|
+
fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
|
|
156
|
+
atomicWriteFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Non-fatal, same as recordGenerated: the retire itself already
|
|
160
|
+
// succeeded (the file is safe); only the audit trail entry is lost.
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// One shared retire-destination root per init run, keyed by the run's own
|
|
164
|
+
// InitResult object (created once per `executeInit` call) rather than
|
|
165
|
+
// targetDir — safe under concurrent/sequential runs against different
|
|
166
|
+
// targetDirs in the same process (e.g. a test suite), and lets every
|
|
167
|
+
// retirement in a run land under one timestamped directory instead of a
|
|
168
|
+
// different one per call.
|
|
169
|
+
const retireRoots = new WeakMap();
|
|
170
|
+
function getRetireRoot(targetDir, result) {
|
|
171
|
+
let root = retireRoots.get(result);
|
|
172
|
+
if (!root) {
|
|
173
|
+
root = path.join(targetDir, '.monomind', 'backups', `${Date.now()}-${process.pid}`, 'retired');
|
|
174
|
+
retireRoots.set(result, root);
|
|
175
|
+
}
|
|
176
|
+
return root;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Retire a generated entry instead of deleting it (o-38): a name the
|
|
180
|
+
* manifest recorded that this version no longer ships anywhere is moved to
|
|
181
|
+
* `.monomind/backups/<run-timestamp>-<pid>/retired/<label>/` rather than
|
|
182
|
+
* `rmSync`-ed. The manifest's granularity is per-top-level-entry — "did init
|
|
183
|
+
* ever generate this name" — not per-file, so a stale-sweep candidate can
|
|
184
|
+
* still hold user files added since (a note beside a retired skill, e.g.)
|
|
185
|
+
* that must survive byte-identical.
|
|
186
|
+
*
|
|
187
|
+
* `label` doubles as the retirement's section plus display name, e.g.
|
|
188
|
+
* `skills/my-retired-skill` — the first path segment is an
|
|
189
|
+
* `InitManifestSection` value for the five real call sites, or a
|
|
190
|
+
* descriptive mirror label (`gemini-skills`, `agents-skills`,
|
|
191
|
+
* `opencode-skills`) for a mirror copy that turned out to hold user-added
|
|
192
|
+
* content (see `copySkills` / `writeOpencodeFiles`).
|
|
193
|
+
*
|
|
194
|
+
* On any failure, the entry is LEFT IN PLACE and a warning is recorded in
|
|
195
|
+
* `result.errors` — this must never fall back to deleting; a fix that
|
|
196
|
+
* deletes when the move fails is the original bug with extra steps.
|
|
197
|
+
*/
|
|
198
|
+
export function retireGeneratedEntry(targetDir, label, stalePath, result) {
|
|
199
|
+
const sepIndex = label.indexOf('/');
|
|
200
|
+
const section = sepIndex === -1 ? label : label.slice(0, sepIndex);
|
|
201
|
+
const name = sepIndex === -1 ? label : label.slice(sepIndex + 1);
|
|
202
|
+
const dest = path.join(getRetireRoot(targetDir, result), label);
|
|
203
|
+
try {
|
|
204
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
205
|
+
try {
|
|
206
|
+
fs.renameSync(stalePath, dest);
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
if (error.code !== 'EXDEV')
|
|
210
|
+
throw error;
|
|
211
|
+
fs.cpSync(stalePath, dest, { recursive: true });
|
|
212
|
+
fs.rmSync(stalePath, { recursive: true, force: true });
|
|
213
|
+
}
|
|
214
|
+
const movedTo = path.relative(targetDir, dest);
|
|
215
|
+
result.removed.push(`[retired] ${label} → ${movedTo}`);
|
|
216
|
+
appendRetiredProvenance(targetDir, { section, name, movedTo, at: new Date().toISOString() });
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
result.errors.push(`Could not retire ${label} (left in place): ${error instanceof Error ? error.message : String(error)}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=init-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-manifest.js","sourceRoot":"","sources":["../../../src/init/init-manifest.ts"],"names":[],"mappings":"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"}
|