agentln 0.1.1 → 0.1.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/README.md +25 -6
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +5 -3
- package/dist/args.js.map +1 -1
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +47 -31
- package/dist/executor.js.map +1 -1
- package/dist/planner.d.ts.map +1 -1
- package/dist/planner.js +96 -55
- package/dist/planner.js.map +1 -1
- package/dist/scanner.d.ts +15 -6
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.js +61 -21
- package/dist/scanner.js.map +1 -1
- package/dist/types.d.ts +16 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# agentln
|
|
2
2
|
|
|
3
|
-
Cross-platform CLI that keeps `CLAUDE.md` and `AGENTS.md`
|
|
4
|
-
|
|
3
|
+
Cross-platform CLI that keeps `CLAUDE.md` and `AGENTS.md` (and
|
|
4
|
+
`.claude/skills/` and `.agents/skills/`) in sync across an entire repository
|
|
5
|
+
by managing **relative symlinks** between them.
|
|
5
6
|
|
|
6
7
|
You make **one decision at the repository root** — which filename is the source
|
|
7
8
|
of truth — and `agentln` applies that decision recursively to every directory
|
|
8
|
-
in the repo.
|
|
9
|
+
in the repo, for both the markdown pair and the skills directory pair.
|
|
9
10
|
|
|
10
11
|
- Works on macOS, Linux, and Windows (PowerShell, Git Bash, WSL).
|
|
11
12
|
- Uses Node's native `fs` symlink APIs. Never shells out to `ln`, `bash`, or
|
|
@@ -50,10 +51,27 @@ that contains either file is reconciled to the same convention:
|
|
|
50
51
|
|
|
51
52
|
`agentln` is idempotent. Running it twice in a row will say "already in sync."
|
|
52
53
|
|
|
54
|
+
### Skills directories
|
|
55
|
+
|
|
56
|
+
The same source-of-truth decision is applied to `.claude/skills/` and
|
|
57
|
+
`.agents/skills/` if either exists in a directory. With `CLAUDE.md` chosen as
|
|
58
|
+
source, `.claude/skills/` becomes the source-of-truth directory and
|
|
59
|
+
`.agents/skills/` is reconciled to a symlink pointing at `../.claude/skills`
|
|
60
|
+
(and vice versa). The parent `.claude/` or `.agents/` directory is created
|
|
61
|
+
automatically when needed.
|
|
62
|
+
|
|
63
|
+
Replacing a non-empty skills directory with a symlink requires `--force`, so
|
|
64
|
+
agentln will not silently delete a populated skills tree.
|
|
65
|
+
|
|
66
|
+
Only the `skills/` subdirectory is managed — other things under `.claude/` or
|
|
67
|
+
`.agents/` (e.g. `commands/`, `hooks/`, `settings.json`) are left alone
|
|
68
|
+
because they don't share a portable convention across agents.
|
|
69
|
+
|
|
53
70
|
### Symlink format
|
|
54
71
|
|
|
55
|
-
Symlinks are always **relative** (`AGENTS.md → CLAUDE.md
|
|
56
|
-
|
|
72
|
+
Symlinks are always **relative** (`AGENTS.md → CLAUDE.md`,
|
|
73
|
+
`.agents/skills → ../.claude/skills`), never absolute. This keeps the repo
|
|
74
|
+
portable across machines and clones.
|
|
57
75
|
|
|
58
76
|
### Ignored directories
|
|
59
77
|
|
|
@@ -72,7 +90,8 @@ agentln [options]
|
|
|
72
90
|
--source <name> Use CLAUDE.md or AGENTS.md as source of truth (skips prompt).
|
|
73
91
|
-y, --yes Non-interactive mode. Accepts defaults for every prompt.
|
|
74
92
|
--dry-run Show planned changes without writing anything.
|
|
75
|
-
--force Overwrite divergent regular files
|
|
93
|
+
--force Overwrite divergent regular files or non-empty skills directories
|
|
94
|
+
when replacing with a symlink.
|
|
76
95
|
--copy-fallback On Windows, copy the file instead of failing when symlink
|
|
77
96
|
creation is denied.
|
|
78
97
|
--no-copy-fallback Disable the copy fallback (default).
|
package/dist/args.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,UAAU,EAEhB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,UAAU,EAEhB,MAAM,YAAY,CAAC;AAuBpB,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAoEpD;AAsBD,wBAAgB,QAAQ,IAAI,MAAM,CAEjC"}
|
package/dist/args.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { AGENTS_FILE, CLAUDE_FILE, } from "./types.js";
|
|
3
|
-
const HELP_TEXT = `agentln — manage CLAUDE.md ⇄ AGENTS.md symlinks across a repo
|
|
3
|
+
const HELP_TEXT = `agentln — manage CLAUDE.md ⇄ AGENTS.md and .claude/skills ⇄ .agents/skills symlinks across a repo
|
|
4
4
|
|
|
5
5
|
Usage:
|
|
6
6
|
npx agentln [options]
|
|
@@ -9,10 +9,12 @@ Usage:
|
|
|
9
9
|
Options:
|
|
10
10
|
--root <path> Repository root (default: current working directory).
|
|
11
11
|
--source <name> Use CLAUDE.md or AGENTS.md as source of truth (skips prompt).
|
|
12
|
+
Also drives .claude/skills vs .agents/skills as the source-of-truth dir.
|
|
12
13
|
-y, --yes Non-interactive mode (assume defaults for every prompt).
|
|
13
14
|
--dry-run Show planned changes without writing anything.
|
|
14
|
-
--force Overwrite divergent regular files
|
|
15
|
-
|
|
15
|
+
--force Overwrite divergent regular files or non-empty skills directories
|
|
16
|
+
when replacing with a symlink.
|
|
17
|
+
--copy-fallback On Windows, fall back to a recursive copy if symlink creation is denied.
|
|
16
18
|
--no-copy-fallback Disable the copy fallback (default).
|
|
17
19
|
--verbose Print debug-level information.
|
|
18
20
|
-h, --help Show this help.
|
package/dist/args.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,WAAW,EACX,WAAW,GAGZ,MAAM,YAAY,CAAC;AAEpB,MAAM,SAAS,GAAG
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
|
package/dist/executor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE9D,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,0EAA0E;IAC1E,YAAY,EAAE,OAAO,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE9D,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,0EAA0E;IAC1E,YAAY,EAAE,OAAO,CAAC;CACvB;AA4CD,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,YAAY,CAAC,CAsIvB;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
package/dist/executor.js
CHANGED
|
@@ -3,27 +3,29 @@ import os from "node:os";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
const IS_WINDOWS = process.platform === "win32";
|
|
5
5
|
/**
|
|
6
|
-
* On Windows, `fs.symlink` needs an explicit type hint
|
|
7
|
-
*
|
|
8
|
-
* ignored.
|
|
6
|
+
* On Windows, `fs.symlink` needs an explicit type hint ("file" or "dir").
|
|
7
|
+
* On POSIX systems the type arg is ignored.
|
|
9
8
|
*/
|
|
10
|
-
async function createRelativeSymlink(linkPath, sourcePath) {
|
|
9
|
+
async function createRelativeSymlink(linkPath, sourcePath, isDirectory) {
|
|
11
10
|
const target = path.relative(path.dirname(linkPath), sourcePath);
|
|
12
|
-
|
|
11
|
+
const winType = isDirectory ? "dir" : "file";
|
|
12
|
+
await fs.symlink(target, linkPath, IS_WINDOWS ? winType : undefined);
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
/** Remove a file, symlink, or directory tree. No-op if the path is missing. */
|
|
15
|
+
async function safeRemove(p) {
|
|
16
|
+
await fs.rm(p, { recursive: true, force: true });
|
|
17
|
+
}
|
|
18
|
+
async function ensureParentDir(p) {
|
|
19
|
+
await fs.mkdir(path.dirname(p), { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
async function copyEntry(sourcePath, destPath, isDirectory) {
|
|
22
|
+
if (isDirectory) {
|
|
23
|
+
await fs.cp(sourcePath, destPath, { recursive: true });
|
|
17
24
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (code !== "ENOENT")
|
|
21
|
-
throw err;
|
|
25
|
+
else {
|
|
26
|
+
await fs.copyFile(sourcePath, destPath);
|
|
22
27
|
}
|
|
23
28
|
}
|
|
24
|
-
async function copyFile(sourcePath, destPath) {
|
|
25
|
-
await fs.copyFile(sourcePath, destPath);
|
|
26
|
-
}
|
|
27
29
|
function isSymlinkPermissionError(err) {
|
|
28
30
|
const code = err?.code;
|
|
29
31
|
return code === "EPERM" || code === "EACCES" || code === "ENOSYS";
|
|
@@ -50,25 +52,37 @@ export async function executeAction(action, options) {
|
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
case "create-symlink": {
|
|
55
|
+
const noun = action.isDirectory ? "directory symlink" : "symlink";
|
|
53
56
|
if (options.dryRun) {
|
|
54
57
|
const verb = action.replacesExisting ? "replace" : "create";
|
|
55
|
-
return { action, ok: true, message: `would ${verb}
|
|
58
|
+
return { action, ok: true, message: `would ${verb} ${noun}` };
|
|
59
|
+
}
|
|
60
|
+
// Guard real-content replacement (real file or real directory) behind --force.
|
|
61
|
+
if (action.replacesExisting && action.replacesRegularFile && action.isDirectory) {
|
|
62
|
+
return {
|
|
63
|
+
action,
|
|
64
|
+
ok: false,
|
|
65
|
+
message: `${action.linkPath} is a non-empty directory; refusing to replace it ` +
|
|
66
|
+
"with a symlink without --force (this would delete its contents).",
|
|
67
|
+
};
|
|
56
68
|
}
|
|
57
69
|
try {
|
|
58
70
|
if (action.replacesExisting)
|
|
59
|
-
await
|
|
60
|
-
await
|
|
61
|
-
|
|
71
|
+
await safeRemove(action.linkPath);
|
|
72
|
+
await ensureParentDir(action.linkPath);
|
|
73
|
+
await createRelativeSymlink(action.linkPath, action.sourcePath, action.isDirectory);
|
|
74
|
+
return { action, ok: true, message: `${noun} created` };
|
|
62
75
|
}
|
|
63
76
|
catch (err) {
|
|
64
77
|
if (IS_WINDOWS && isSymlinkPermissionError(err) && options.copyFallback) {
|
|
65
78
|
try {
|
|
66
|
-
await
|
|
67
|
-
await
|
|
79
|
+
await safeRemove(action.linkPath);
|
|
80
|
+
await ensureParentDir(action.linkPath);
|
|
81
|
+
await copyEntry(action.sourcePath, action.linkPath, action.isDirectory);
|
|
68
82
|
return {
|
|
69
83
|
action,
|
|
70
84
|
ok: true,
|
|
71
|
-
message:
|
|
85
|
+
message: `${noun} not permitted on this system; wrote a ${action.isDirectory ? "recursive copy" : "file copy"} instead. ` +
|
|
72
86
|
"Re-run after enabling Developer Mode or with admin privileges " +
|
|
73
87
|
"to use real symlinks.",
|
|
74
88
|
fellBackToCopy: true,
|
|
@@ -82,20 +96,21 @@ export async function executeAction(action, options) {
|
|
|
82
96
|
return {
|
|
83
97
|
action,
|
|
84
98
|
ok: false,
|
|
85
|
-
message:
|
|
99
|
+
message: `creating a ${noun} was denied by the OS. On Windows, enable ` +
|
|
86
100
|
"Developer Mode or run an elevated shell, or re-run with " +
|
|
87
|
-
|
|
101
|
+
`--copy-fallback to write a ${action.isDirectory ? "recursive copy" : "regular file copy"} instead.`,
|
|
88
102
|
};
|
|
89
103
|
}
|
|
90
104
|
return { action, ok: false, message: errorMessage(err) };
|
|
91
105
|
}
|
|
92
106
|
}
|
|
93
107
|
case "promote-to-source": {
|
|
108
|
+
const noun = action.isDirectory ? "directory" : "file";
|
|
94
109
|
if (options.dryRun) {
|
|
95
110
|
return {
|
|
96
111
|
action,
|
|
97
112
|
ok: true,
|
|
98
|
-
message: `would rename ${path.basename(action.fromPath)} → ${path.basename(action.toPath)} and link back`,
|
|
113
|
+
message: `would rename ${noun} ${path.basename(action.fromPath)} → ${path.basename(action.toPath)} and link back`,
|
|
99
114
|
};
|
|
100
115
|
}
|
|
101
116
|
try {
|
|
@@ -117,24 +132,25 @@ export async function executeAction(action, options) {
|
|
|
117
132
|
};
|
|
118
133
|
}
|
|
119
134
|
if (targetExists)
|
|
120
|
-
await
|
|
135
|
+
await safeRemove(action.toPath);
|
|
136
|
+
await ensureParentDir(action.toPath);
|
|
121
137
|
await fs.rename(action.fromPath, action.toPath);
|
|
122
|
-
await createRelativeSymlink(action.fromPath, action.toPath);
|
|
138
|
+
await createRelativeSymlink(action.fromPath, action.toPath, action.isDirectory);
|
|
123
139
|
return {
|
|
124
140
|
action,
|
|
125
141
|
ok: true,
|
|
126
|
-
message:
|
|
142
|
+
message: `promoted ${noun} to source and linked back`,
|
|
127
143
|
};
|
|
128
144
|
}
|
|
129
145
|
catch (err) {
|
|
130
146
|
if (IS_WINDOWS && isSymlinkPermissionError(err) && options.copyFallback) {
|
|
131
147
|
try {
|
|
132
|
-
await
|
|
148
|
+
await copyEntry(action.toPath, action.fromPath, action.isDirectory);
|
|
133
149
|
return {
|
|
134
150
|
action,
|
|
135
151
|
ok: true,
|
|
136
|
-
message:
|
|
137
|
-
"two
|
|
152
|
+
message: `symlink not permitted; wrote a ${action.isDirectory ? "recursive copy" : "file copy"} as fallback. ` +
|
|
153
|
+
"The two paths will diverge on subsequent edits.",
|
|
138
154
|
fellBackToCopy: true,
|
|
139
155
|
};
|
|
140
156
|
}
|
package/dist/executor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAW7B,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAEhD
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
|
package/dist/planner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"AAEA,OAAO,EAOL,KAAK,QAAQ,EAEb,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,IAAI;IACnB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC;CACpB;AAiBD,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAmDhD;AAwID,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAuB5D"}
|
package/dist/planner.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { AGENTS_FILE, CLAUDE_FILE, } from "./types.js";
|
|
2
|
+
import { AGENTS_DIR, AGENTS_FILE, CLAUDE_DIR, CLAUDE_FILE, SKILLS_SUBDIR, sourceDirFor, } from "./types.js";
|
|
3
3
|
function linkName(source) {
|
|
4
4
|
return source === CLAUDE_FILE ? AGENTS_FILE : CLAUDE_FILE;
|
|
5
5
|
}
|
|
@@ -12,6 +12,8 @@ export function buildPlan(input) {
|
|
|
12
12
|
let cleanCount = 0;
|
|
13
13
|
let emptyCount = 0;
|
|
14
14
|
const otherName = linkName(source);
|
|
15
|
+
const sourceDir = sourceDirFor(source);
|
|
16
|
+
const otherDir = sourceDir === CLAUDE_DIR ? AGENTS_DIR : CLAUDE_DIR;
|
|
15
17
|
if (bootstrapRoot) {
|
|
16
18
|
actions.push({
|
|
17
19
|
type: "create-root-source",
|
|
@@ -20,62 +22,92 @@ export function buildPlan(input) {
|
|
|
20
22
|
}
|
|
21
23
|
for (const dir of dirs) {
|
|
22
24
|
const isRootDir = dir.dir === root;
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
(
|
|
27
|
-
|
|
28
|
-
(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
// --- File pair: CLAUDE.md <-> AGENTS.md ---
|
|
26
|
+
const fileOutcome = reconcilePair({
|
|
27
|
+
sourceEntry: entryFor(dir, source),
|
|
28
|
+
linkEntry: entryFor(dir, otherName),
|
|
29
|
+
sourcePath: path.join(dir.dir, source),
|
|
30
|
+
linkPath: path.join(dir.dir, otherName),
|
|
31
|
+
isDirectory: false,
|
|
32
|
+
// The root source is bootstrapped earlier, so treat it as present at planning time.
|
|
33
|
+
sourceConsideredPresent: isRootDir && bootstrapRoot,
|
|
34
|
+
force,
|
|
35
|
+
});
|
|
36
|
+
// --- Directory pair: .claude/skills <-> .agents/skills ---
|
|
37
|
+
const skillsOutcome = reconcilePair({
|
|
38
|
+
sourceEntry: skillsEntryFor(dir, sourceDir),
|
|
39
|
+
linkEntry: skillsEntryFor(dir, otherDir),
|
|
40
|
+
sourcePath: path.join(dir.dir, sourceDir, SKILLS_SUBDIR),
|
|
41
|
+
linkPath: path.join(dir.dir, otherDir, SKILLS_SUBDIR),
|
|
42
|
+
isDirectory: true,
|
|
43
|
+
sourceConsideredPresent: false,
|
|
44
|
+
force,
|
|
45
|
+
});
|
|
46
|
+
actions.push(...fileOutcome.actions, ...skillsOutcome.actions);
|
|
47
|
+
const combined = combineStatus(fileOutcome.status, skillsOutcome.status);
|
|
48
|
+
if (combined === "clean")
|
|
49
|
+
cleanCount++;
|
|
50
|
+
else if (combined === "empty")
|
|
32
51
|
emptyCount++;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
actions
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
52
|
+
}
|
|
53
|
+
return { actions, cleanCount, emptyCount };
|
|
54
|
+
}
|
|
55
|
+
function combineStatus(a, b) {
|
|
56
|
+
if (a === "changed" || b === "changed")
|
|
57
|
+
return "changed";
|
|
58
|
+
if (a === "clean" || b === "clean")
|
|
59
|
+
return "clean";
|
|
60
|
+
return "empty";
|
|
61
|
+
}
|
|
62
|
+
function skillsEntryFor(dir, which) {
|
|
63
|
+
return which === CLAUDE_DIR ? dir.claudeSkills : dir.agentsSkills;
|
|
64
|
+
}
|
|
65
|
+
function reconcilePair(args) {
|
|
66
|
+
const { sourceEntry, linkEntry, sourcePath, linkPath, isDirectory, force } = args;
|
|
67
|
+
const sourcePresent = args.sourceConsideredPresent ||
|
|
68
|
+
sourceEntry.kind === "regular-file" ||
|
|
69
|
+
sourceEntry.kind === "correct-symlink";
|
|
70
|
+
const linkPresent = linkEntry.kind !== "missing";
|
|
71
|
+
if (!sourcePresent && !linkPresent) {
|
|
72
|
+
return { actions: [], status: "empty" };
|
|
73
|
+
}
|
|
74
|
+
if (sourcePresent) {
|
|
75
|
+
const desired = ensureLink({ linkEntry, sourcePath, linkPath, isDirectory, force });
|
|
76
|
+
if (desired === "ok")
|
|
77
|
+
return { actions: [], status: "clean" };
|
|
78
|
+
return { actions: [desired], status: "changed" };
|
|
79
|
+
}
|
|
80
|
+
// No source present in this directory; promote the link if it has real
|
|
81
|
+
// content (or even just a salvageable stale symlink target).
|
|
82
|
+
if (linkEntry.kind === "regular-file" ||
|
|
83
|
+
linkEntry.kind === "incorrect-symlink" ||
|
|
84
|
+
linkEntry.kind === "broken-symlink") {
|
|
85
|
+
return {
|
|
86
|
+
actions: [
|
|
87
|
+
{
|
|
88
|
+
type: "promote-to-source",
|
|
89
|
+
fromPath: linkEntry.path,
|
|
90
|
+
toPath: sourcePath,
|
|
91
|
+
linkBack: true,
|
|
92
|
+
isDirectory,
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
status: "changed",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
actions: [
|
|
100
|
+
{
|
|
67
101
|
type: "skip",
|
|
68
102
|
path: linkEntry.path,
|
|
69
103
|
reason: `unexpected entry kind: ${linkEntry.kind}`,
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
status: "changed",
|
|
107
|
+
};
|
|
74
108
|
}
|
|
75
109
|
function ensureLink(args) {
|
|
76
|
-
const {
|
|
77
|
-
const sourcePath = path.join(dir, sourceName);
|
|
78
|
-
const linkPath = linkEntry.path;
|
|
110
|
+
const { linkEntry, sourcePath, linkPath, isDirectory, force } = args;
|
|
79
111
|
if (linkEntry.kind === "correct-symlink")
|
|
80
112
|
return "ok";
|
|
81
113
|
if (linkEntry.kind === "missing") {
|
|
@@ -85,6 +117,7 @@ function ensureLink(args) {
|
|
|
85
117
|
sourcePath,
|
|
86
118
|
replacesExisting: false,
|
|
87
119
|
replacesRegularFile: false,
|
|
120
|
+
isDirectory,
|
|
88
121
|
};
|
|
89
122
|
}
|
|
90
123
|
if (linkEntry.kind === "incorrect-symlink" ||
|
|
@@ -95,15 +128,20 @@ function ensureLink(args) {
|
|
|
95
128
|
sourcePath,
|
|
96
129
|
replacesExisting: true,
|
|
97
130
|
replacesRegularFile: false,
|
|
131
|
+
isDirectory,
|
|
98
132
|
};
|
|
99
133
|
}
|
|
100
134
|
if (linkEntry.kind === "regular-file") {
|
|
135
|
+
// "regular-file" here means real content of the expected kind (real file
|
|
136
|
+
// for the MD pair, real directory for the skills pair). Replacing real
|
|
137
|
+
// content requires --force so we don't silently destroy data.
|
|
101
138
|
return {
|
|
102
139
|
type: "create-symlink",
|
|
103
140
|
linkPath,
|
|
104
141
|
sourcePath,
|
|
105
142
|
replacesExisting: true,
|
|
106
143
|
replacesRegularFile: !force,
|
|
144
|
+
isDirectory,
|
|
107
145
|
};
|
|
108
146
|
}
|
|
109
147
|
return {
|
|
@@ -118,16 +156,19 @@ export function describeAction(action) {
|
|
|
118
156
|
return `create empty source file → ${action.sourcePath}`;
|
|
119
157
|
case "create-symlink": {
|
|
120
158
|
const rel = path.relative(path.dirname(action.linkPath), action.sourcePath);
|
|
159
|
+
const noun = action.isDirectory ? "directory symlink" : "symlink";
|
|
160
|
+
const realNoun = action.isDirectory ? "directory" : "regular file";
|
|
121
161
|
const verb = action.replacesExisting
|
|
122
162
|
? action.replacesRegularFile
|
|
123
|
-
?
|
|
124
|
-
:
|
|
125
|
-
:
|
|
163
|
+
? `replace ${realNoun}`
|
|
164
|
+
: `replace stale ${noun}`
|
|
165
|
+
: `create ${noun}`;
|
|
126
166
|
return `${verb} ${action.linkPath} → ${rel}`;
|
|
127
167
|
}
|
|
128
168
|
case "promote-to-source": {
|
|
129
169
|
const rel = path.relative(path.dirname(action.fromPath), action.toPath);
|
|
130
|
-
|
|
170
|
+
const noun = action.isDirectory ? "directory" : "file";
|
|
171
|
+
return `rename ${noun} ${action.fromPath} → ${action.toPath}, then link ${path.basename(action.fromPath)} → ${rel}`;
|
|
131
172
|
}
|
|
132
173
|
case "skip":
|
|
133
174
|
return `skip ${action.path} (${action.reason})`;
|
package/dist/planner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner.js","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,WAAW,EACX,WAAW,
|
|
1
|
+
{"version":3,"file":"planner.js","sourceRoot":"","sources":["../src/planner.ts"],"names":[],"mappings":"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"}
|
package/dist/scanner.d.ts
CHANGED
|
@@ -5,14 +5,23 @@ export interface ScanOptions {
|
|
|
5
5
|
followHiddenDirs?: boolean;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* Classify a single CLAUDE.md/AGENTS.md candidate path
|
|
9
|
-
*
|
|
10
|
-
* its sibling
|
|
8
|
+
* Classify a single CLAUDE.md/AGENTS.md candidate path, or a managed
|
|
9
|
+
* directory path (e.g. .claude/skills). Resolves the symlink target without
|
|
10
|
+
* following it, so we can decide whether it already points at its sibling
|
|
11
|
+
* source. `expectedKind` determines whether a "real" entry should be a file
|
|
12
|
+
* or a directory; the returned EntryKind reuses `regular-file` to mean
|
|
13
|
+
* "real content at this path" in either mode.
|
|
14
|
+
*
|
|
15
|
+
* For directories, `expectedSiblingTarget` is the relative path that a
|
|
16
|
+
* correctly-shaped symlink should point to (e.g. `../.claude/skills`).
|
|
11
17
|
*/
|
|
12
|
-
export declare function classifyEntry(filePath: string,
|
|
18
|
+
export declare function classifyEntry(filePath: string, expectedSiblingTarget: string | null, options?: {
|
|
19
|
+
expectedKind?: "file" | "directory";
|
|
20
|
+
}): Promise<EntryState>;
|
|
13
21
|
/**
|
|
14
|
-
* Build the per-directory state for the two managed files
|
|
15
|
-
* repository-wide source-of-truth
|
|
22
|
+
* Build the per-directory state for the two managed files and the two
|
|
23
|
+
* managed skills directories. `source` is the repository-wide source-of-truth
|
|
24
|
+
* name; the other file (and corresponding skills dir) is the link.
|
|
16
25
|
*/
|
|
17
26
|
export declare function readDirState(dir: string, source: SourceName): Promise<DirState>;
|
|
18
27
|
/**
|
package/dist/scanner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAGA,OAAO,EAOL,KAAK,QAAQ,EAEb,KAAK,UAAU,EACf,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,oBAAoB,aAiB/B,CAAC;AAEH,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,qBAAqB,EAAE,MAAM,GAAG,IAAI,EACpC,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;CAAO,GACpD,OAAO,CAAC,UAAU,CAAC,CA4DrB;AAOD;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,QAAQ,CAAC,CA8BnB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAkDrB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAmBvD"}
|
package/dist/scanner.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { promises as fs } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { AGENTS_FILE, CLAUDE_FILE, } from "./types.js";
|
|
3
|
+
import { AGENTS_DIR, AGENTS_FILE, CLAUDE_DIR, CLAUDE_FILE, SKILLS_SUBDIR, sourceDirFor, } from "./types.js";
|
|
4
4
|
export const DEFAULT_IGNORED_DIRS = new Set([
|
|
5
5
|
"node_modules",
|
|
6
6
|
".git",
|
|
@@ -20,11 +20,18 @@ export const DEFAULT_IGNORED_DIRS = new Set([
|
|
|
20
20
|
".vscode",
|
|
21
21
|
]);
|
|
22
22
|
/**
|
|
23
|
-
* Classify a single CLAUDE.md/AGENTS.md candidate path
|
|
24
|
-
*
|
|
25
|
-
* its sibling
|
|
23
|
+
* Classify a single CLAUDE.md/AGENTS.md candidate path, or a managed
|
|
24
|
+
* directory path (e.g. .claude/skills). Resolves the symlink target without
|
|
25
|
+
* following it, so we can decide whether it already points at its sibling
|
|
26
|
+
* source. `expectedKind` determines whether a "real" entry should be a file
|
|
27
|
+
* or a directory; the returned EntryKind reuses `regular-file` to mean
|
|
28
|
+
* "real content at this path" in either mode.
|
|
29
|
+
*
|
|
30
|
+
* For directories, `expectedSiblingTarget` is the relative path that a
|
|
31
|
+
* correctly-shaped symlink should point to (e.g. `../.claude/skills`).
|
|
26
32
|
*/
|
|
27
|
-
export async function classifyEntry(filePath,
|
|
33
|
+
export async function classifyEntry(filePath, expectedSiblingTarget, options = {}) {
|
|
34
|
+
const expectedKind = options.expectedKind ?? "file";
|
|
28
35
|
let lstat;
|
|
29
36
|
try {
|
|
30
37
|
lstat = await fs.lstat(filePath);
|
|
@@ -32,9 +39,6 @@ export async function classifyEntry(filePath, expectedSiblingSource) {
|
|
|
32
39
|
catch {
|
|
33
40
|
return { path: filePath, kind: "missing" };
|
|
34
41
|
}
|
|
35
|
-
if (lstat.isDirectory()) {
|
|
36
|
-
return { path: filePath, kind: "directory" };
|
|
37
|
-
}
|
|
38
42
|
if (lstat.isSymbolicLink()) {
|
|
39
43
|
let target;
|
|
40
44
|
try {
|
|
@@ -50,35 +54,59 @@ export async function classifyEntry(filePath, expectedSiblingSource) {
|
|
|
50
54
|
catch {
|
|
51
55
|
return { path: filePath, kind: "broken-symlink", linkTarget: target };
|
|
52
56
|
}
|
|
53
|
-
|
|
57
|
+
const targetMatchesKind = expectedKind === "file" ? stat.isFile() : stat.isDirectory();
|
|
58
|
+
if (!targetMatchesKind) {
|
|
54
59
|
return { path: filePath, kind: "incorrect-symlink", linkTarget: target };
|
|
55
60
|
}
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (normalised === expectedSiblingSource) {
|
|
61
|
+
if (expectedSiblingTarget) {
|
|
62
|
+
const normalised = normaliseLinkTarget(target);
|
|
63
|
+
if (normalised === normaliseLinkTarget(expectedSiblingTarget)) {
|
|
60
64
|
return { path: filePath, kind: "correct-symlink", linkTarget: target };
|
|
61
65
|
}
|
|
62
66
|
return { path: filePath, kind: "incorrect-symlink", linkTarget: target };
|
|
63
67
|
}
|
|
64
68
|
return { path: filePath, kind: "incorrect-symlink", linkTarget: target };
|
|
65
69
|
}
|
|
70
|
+
if (expectedKind === "directory") {
|
|
71
|
+
if (lstat.isDirectory()) {
|
|
72
|
+
return { path: filePath, kind: "regular-file" };
|
|
73
|
+
}
|
|
74
|
+
if (lstat.isFile()) {
|
|
75
|
+
return { path: filePath, kind: "other" };
|
|
76
|
+
}
|
|
77
|
+
return { path: filePath, kind: "other" };
|
|
78
|
+
}
|
|
79
|
+
if (lstat.isDirectory()) {
|
|
80
|
+
return { path: filePath, kind: "directory" };
|
|
81
|
+
}
|
|
66
82
|
if (lstat.isFile()) {
|
|
67
83
|
return { path: filePath, kind: "regular-file" };
|
|
68
84
|
}
|
|
69
85
|
return { path: filePath, kind: "other" };
|
|
70
86
|
}
|
|
87
|
+
function normaliseLinkTarget(target) {
|
|
88
|
+
// Accept both POSIX and Windows separators; strip a leading "./".
|
|
89
|
+
return target.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
90
|
+
}
|
|
71
91
|
/**
|
|
72
|
-
* Build the per-directory state for the two managed files
|
|
73
|
-
* repository-wide source-of-truth
|
|
92
|
+
* Build the per-directory state for the two managed files and the two
|
|
93
|
+
* managed skills directories. `source` is the repository-wide source-of-truth
|
|
94
|
+
* name; the other file (and corresponding skills dir) is the link.
|
|
74
95
|
*/
|
|
75
96
|
export async function readDirState(dir, source) {
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
97
|
+
const sourceDir = sourceDirFor(source);
|
|
98
|
+
const linkFile = source === CLAUDE_FILE ? AGENTS_FILE : CLAUDE_FILE;
|
|
99
|
+
const linkDir = sourceDir === CLAUDE_DIR ? AGENTS_DIR : CLAUDE_DIR;
|
|
100
|
+
// For the file pair, a correct link points at the bare source filename.
|
|
101
|
+
// For the skills pair, a correct link points at "../<source-dir>/skills".
|
|
102
|
+
const skillsLinkTarget = `../${sourceDir}/${SKILLS_SUBDIR}`;
|
|
103
|
+
const [claude, agents, claudeSkills, agentsSkills] = await Promise.all([
|
|
104
|
+
classifyEntry(path.join(dir, CLAUDE_FILE), source === CLAUDE_FILE ? null : linkFile === CLAUDE_FILE ? source : null),
|
|
105
|
+
classifyEntry(path.join(dir, AGENTS_FILE), source === AGENTS_FILE ? null : linkFile === AGENTS_FILE ? source : null),
|
|
106
|
+
classifyEntry(path.join(dir, CLAUDE_DIR, SKILLS_SUBDIR), sourceDir === CLAUDE_DIR ? null : linkDir === CLAUDE_DIR ? skillsLinkTarget : null, { expectedKind: "directory" }),
|
|
107
|
+
classifyEntry(path.join(dir, AGENTS_DIR, SKILLS_SUBDIR), sourceDir === AGENTS_DIR ? null : linkDir === AGENTS_DIR ? skillsLinkTarget : null, { expectedKind: "directory" }),
|
|
80
108
|
]);
|
|
81
|
-
return { dir, claude, agents };
|
|
109
|
+
return { dir, claude, agents, claudeSkills, agentsSkills };
|
|
82
110
|
}
|
|
83
111
|
/**
|
|
84
112
|
* Walk the repo recursively and yield every directory that contains at least
|
|
@@ -98,8 +126,16 @@ export async function scanRepository(root, source, options = {}) {
|
|
|
98
126
|
}
|
|
99
127
|
let hasClaude = false;
|
|
100
128
|
let hasAgents = false;
|
|
129
|
+
let hasClaudeManagedDir = false;
|
|
130
|
+
let hasAgentsManagedDir = false;
|
|
101
131
|
const childDirs = [];
|
|
102
132
|
for (const entry of entries) {
|
|
133
|
+
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
134
|
+
if (entry.name === CLAUDE_DIR)
|
|
135
|
+
hasClaudeManagedDir = true;
|
|
136
|
+
else if (entry.name === AGENTS_DIR)
|
|
137
|
+
hasAgentsManagedDir = true;
|
|
138
|
+
}
|
|
103
139
|
if (entry.isDirectory()) {
|
|
104
140
|
if (ignored.has(entry.name))
|
|
105
141
|
continue;
|
|
@@ -114,7 +150,11 @@ export async function scanRepository(root, source, options = {}) {
|
|
|
114
150
|
hasAgents = true;
|
|
115
151
|
}
|
|
116
152
|
}
|
|
117
|
-
if (isRoot ||
|
|
153
|
+
if (isRoot ||
|
|
154
|
+
hasClaude ||
|
|
155
|
+
hasAgents ||
|
|
156
|
+
hasClaudeManagedDir ||
|
|
157
|
+
hasAgentsManagedDir) {
|
|
118
158
|
results.push(await readDirState(dir, source));
|
|
119
159
|
}
|
|
120
160
|
for (const child of childDirs) {
|
package/dist/scanner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,WAAW,EACX,WAAW,
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,aAAa,EACb,YAAY,GAKb,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IAC1C,cAAc;IACd,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,eAAe;IACf,aAAa;IACb,OAAO;IACP,SAAS;IACT,SAAS;IACT,OAAO;IACP,SAAS;CACV,CAAC,CAAC;AAOH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,qBAAoC,EACpC,UAAmD,EAAE;IAErD,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,MAAM,CAAC;IACpD,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7C,CAAC;IAED,IAAI,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC;QAC3B,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;QACpD,CAAC;QAED,IAAI,IAAI,CAAC;QACT,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QACxE,CAAC;QAED,MAAM,iBAAiB,GACrB,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/D,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAC3E,CAAC;QAED,IAAI,qBAAqB,EAAE,CAAC;YAC1B,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC/C,IAAI,UAAU,KAAK,mBAAmB,CAAC,qBAAqB,CAAC,EAAE,CAAC;gBAC9D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;YACzE,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAC3E,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAC3E,CAAC;IAED,IAAI,YAAY,KAAK,WAAW,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;QAClD,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACnB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC3C,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;QACxB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC/C,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;IAClD,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3C,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc;IACzC,kEAAkE;IAClE,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAW,EACX,MAAkB;IAElB,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;IACpE,MAAM,OAAO,GAAG,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;IAEnE,wEAAwE;IACxE,0EAA0E;IAC1E,MAAM,gBAAgB,GAAG,MAAM,SAAS,IAAI,aAAa,EAAE,CAAC;IAE5D,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACrE,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,EAC3B,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CACzE;QACD,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,EAC3B,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CACzE;QACD,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,aAAa,CAAC,EACzC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,EAClF,EAAE,YAAY,EAAE,WAAW,EAAE,CAC9B;QACD,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,aAAa,CAAC,EACzC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,EAClF,EAAE,YAAY,EAAE,WAAW,EAAE,CAC9B;KACF,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,MAAkB,EAClB,UAAuB,EAAE;IAEzB,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,IAAI,oBAAoB,CAAC;IAC5D,MAAM,OAAO,GAAe,EAAE,CAAC;IAE/B,KAAK,UAAU,IAAI,CAAC,GAAW,EAAE,MAAe;QAC9C,IAAI,OAAO,CAAC;QACZ,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QAED,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,IAAI,mBAAmB,GAAG,KAAK,CAAC;QAChC,IAAI,mBAAmB,GAAG,KAAK,CAAC;QAChC,MAAM,SAAS,GAAa,EAAE,CAAC;QAE/B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC;gBAClD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;oBAAE,mBAAmB,GAAG,IAAI,CAAC;qBACrD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;oBAAE,mBAAmB,GAAG,IAAI,CAAC;YACjE,CAAC;YACD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACtC,IAAI,CAAC,OAAO,CAAC,gBAAgB,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,SAAS;gBACtE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7C,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC;gBACpD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;oBAAE,SAAS,GAAG,IAAI,CAAC;qBAC5C,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;oBAAE,SAAS,GAAG,IAAI,CAAC;YACxD,CAAC;QACH,CAAC;QAED,IACE,MAAM;YACN,SAAS;YACT,SAAS;YACT,mBAAmB;YACnB,mBAAmB,EACnB,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,MAAM,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;QAChD,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;YAC9B,MAAM,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACvB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAiB;IAC7C,QAAQ,KAAK,CAAC,IAAiB,EAAE,CAAC;QAChC,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,cAAc;YACjB,OAAO,cAAc,CAAC;QACxB,KAAK,iBAAiB;YACpB,OAAO,aAAa,KAAK,CAAC,UAAU,IAAI,GAAG,YAAY,CAAC;QAC1D,KAAK,mBAAmB;YACtB,OAAO,aAAa,KAAK,CAAC,UAAU,IAAI,GAAG,UAAU,CAAC;QACxD,KAAK,gBAAgB;YACnB,OAAO,oBAAoB,KAAK,CAAC,UAAU,IAAI,GAAG,EAAE,CAAC;QACvD,KAAK,WAAW;YACd,OAAO,wBAAwB,CAAC;QAClC,KAAK,OAAO;YACV,OAAO,+BAA+B,CAAC;QACzC;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
export declare const CLAUDE_FILE = "CLAUDE.md";
|
|
2
2
|
export declare const AGENTS_FILE = "AGENTS.md";
|
|
3
|
+
export declare const CLAUDE_DIR = ".claude";
|
|
4
|
+
export declare const AGENTS_DIR = ".agents";
|
|
5
|
+
export declare const SKILLS_SUBDIR = "skills";
|
|
3
6
|
export type SourceName = typeof CLAUDE_FILE | typeof AGENTS_FILE;
|
|
7
|
+
export type SourceDirName = typeof CLAUDE_DIR | typeof AGENTS_DIR;
|
|
8
|
+
export declare function sourceDirFor(source: SourceName): SourceDirName;
|
|
4
9
|
export interface CliOptions {
|
|
5
10
|
root: string;
|
|
6
11
|
yes: boolean;
|
|
@@ -26,6 +31,10 @@ export interface DirState {
|
|
|
26
31
|
dir: string;
|
|
27
32
|
claude: EntryState;
|
|
28
33
|
agents: EntryState;
|
|
34
|
+
/** State of <dir>/.claude/skills (directory, symlink, or missing). */
|
|
35
|
+
claudeSkills: EntryState;
|
|
36
|
+
/** State of <dir>/.agents/skills (directory, symlink, or missing). */
|
|
37
|
+
agentsSkills: EntryState;
|
|
29
38
|
}
|
|
30
39
|
export type PlannedAction = {
|
|
31
40
|
type: "create-symlink";
|
|
@@ -35,16 +44,20 @@ export type PlannedAction = {
|
|
|
35
44
|
sourcePath: string;
|
|
36
45
|
/** Whether the link file currently exists and must be removed first. */
|
|
37
46
|
replacesExisting: boolean;
|
|
38
|
-
/** Whether existing entry is
|
|
47
|
+
/** Whether existing entry is real content (regular file or real directory) vs a stale symlink. */
|
|
39
48
|
replacesRegularFile: boolean;
|
|
49
|
+
/** True when linking a directory (e.g. skills/), false for a single file. */
|
|
50
|
+
isDirectory: boolean;
|
|
40
51
|
} | {
|
|
41
52
|
type: "promote-to-source";
|
|
42
|
-
/** Existing
|
|
53
|
+
/** Existing entry that will be renamed (e.g. AGENTS.md in a folder where CLAUDE.md is source). */
|
|
43
54
|
fromPath: string;
|
|
44
|
-
/** New name for that
|
|
55
|
+
/** New name for that entry (e.g. CLAUDE.md). */
|
|
45
56
|
toPath: string;
|
|
46
57
|
/** Then create symlink at fromPath -> toPath. */
|
|
47
58
|
linkBack: true;
|
|
59
|
+
/** True when promoting a directory (e.g. skills/), false for a single file. */
|
|
60
|
+
isDirectory: boolean;
|
|
48
61
|
} | {
|
|
49
62
|
type: "create-root-source";
|
|
50
63
|
/** Create an empty source file at the repository root. */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,cAAc,CAAC;AACvC,eAAO,MAAM,WAAW,cAAc,CAAC;AAEvC,MAAM,MAAM,UAAU,GAAG,OAAO,WAAW,GAAG,OAAO,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,cAAc,CAAC;AACvC,eAAO,MAAM,WAAW,cAAc,CAAC;AAEvC,eAAO,MAAM,UAAU,YAAY,CAAC;AACpC,eAAO,MAAM,UAAU,YAAY,CAAC;AACpC,eAAO,MAAM,aAAa,WAAW,CAAC;AAEtC,MAAM,MAAM,UAAU,GAAG,OAAO,WAAW,GAAG,OAAO,WAAW,CAAC;AACjE,MAAM,MAAM,aAAa,GAAG,OAAO,UAAU,GAAG,OAAO,UAAU,CAAC;AAElE,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,CAE9D;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,cAAc,GACd,iBAAiB,GACjB,mBAAmB,GACnB,gBAAgB,GAChB,WAAW,GACX,OAAO,CAAC;AAEZ,MAAM,WAAW,UAAU;IACzB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,+BAA+B;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB,sEAAsE;IACtE,YAAY,EAAE,UAAU,CAAC;IACzB,sEAAsE;IACtE,YAAY,EAAE,UAAU,CAAC;CAC1B;AAED,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,gBAAgB,CAAC;IACvB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kGAAkG;IAClG,mBAAmB,EAAE,OAAO,CAAC;IAC7B,6EAA6E;IAC7E,WAAW,EAAE,OAAO,CAAC;CACtB,GACD;IACE,IAAI,EAAE,mBAAmB,CAAC;IAC1B,kGAAkG;IAClG,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,QAAQ,EAAE,IAAI,CAAC;IACf,+EAA+E;IAC/E,WAAW,EAAE,OAAO,CAAC;CACtB,GACD;IACE,IAAI,EAAE,oBAAoB,CAAC;IAC3B,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B"}
|
package/dist/types.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
export const CLAUDE_FILE = "CLAUDE.md";
|
|
2
2
|
export const AGENTS_FILE = "AGENTS.md";
|
|
3
|
+
export const CLAUDE_DIR = ".claude";
|
|
4
|
+
export const AGENTS_DIR = ".agents";
|
|
5
|
+
export const SKILLS_SUBDIR = "skills";
|
|
6
|
+
export function sourceDirFor(source) {
|
|
7
|
+
return source === CLAUDE_FILE ? CLAUDE_DIR : AGENTS_DIR;
|
|
8
|
+
}
|
|
3
9
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AACvC,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AACvC,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AAEvC,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC;AACpC,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC;AACpC,MAAM,CAAC,MAAM,aAAa,GAAG,QAAQ,CAAC;AAKtC,MAAM,UAAU,YAAY,CAAC,MAAkB;IAC7C,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;AAC1D,CAAC"}
|