tracerkit 1.13.1 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -7
- package/dist/bin.js +45 -44
- package/dist/index.js +2 -2
- package/dist/uninstall-k_ZGY-Mk.js +518 -0
- package/package.json +1 -1
- package/dist/uninstall-9tiXr-15.js +0 -205
package/README.md
CHANGED
|
@@ -103,6 +103,14 @@ tracerkit config github.repo org/repo # set target repo
|
|
|
103
103
|
|
|
104
104
|
PRDs and plans become GitHub Issues with `tk:prd` and `tk:plan` labels. On `/tk:check` pass, issues are closed instead of archived locally. Each project can use a different backend; local is the default. See [Configuration](docs/configuration.md) for details.
|
|
105
105
|
|
|
106
|
+
To migrate existing artifacts between backends:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
tracerkit migrate-storage # local→github or github→local (auto-detected)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Direction is inferred from the current `storage` config. All artifacts are migrated, existing duplicates are skipped, and the config is flipped to the target backend. Source artifacts are left intact as backup. For archived features migrating to GitHub, merged PRs matching the slug are linked automatically.
|
|
113
|
+
|
|
106
114
|
</details>
|
|
107
115
|
|
|
108
116
|
## Skills
|
|
@@ -137,13 +145,13 @@ Without arguments, shows a feature dashboard with status and progress before ask
|
|
|
137
145
|
|
|
138
146
|
## Docs
|
|
139
147
|
|
|
140
|
-
| Document | Description
|
|
141
|
-
| ------------------------------------------------ |
|
|
142
|
-
| [Examples](docs/examples.md) | Walk through end-to-end usage scenarios
|
|
143
|
-
| [CLI Reference](docs/cli-reference.md) | Commands: init, update, config, uninstall
|
|
144
|
-
| [Configuration](docs/configuration.md) | Storage backends, GitHub options, custom paths
|
|
145
|
-
| [Metadata Lifecycle](docs/metadata-lifecycle.md) | Understand YAML frontmatter states and transitions
|
|
146
|
-
| [Comparison](docs/comparison.md) | Compare TracerKit to Spec Kit, Kiro, and OpenSpec
|
|
148
|
+
| Document | Description |
|
|
149
|
+
| ------------------------------------------------ | ---------------------------------------------------------- |
|
|
150
|
+
| [Examples](docs/examples.md) | Walk through end-to-end usage scenarios |
|
|
151
|
+
| [CLI Reference](docs/cli-reference.md) | Commands: init, update, config, migrate-storage, uninstall |
|
|
152
|
+
| [Configuration](docs/configuration.md) | Storage backends, GitHub options, custom paths |
|
|
153
|
+
| [Metadata Lifecycle](docs/metadata-lifecycle.md) | Understand YAML frontmatter states and transitions |
|
|
154
|
+
| [Comparison](docs/comparison.md) | Compare TracerKit to Spec Kit, Kiro, and OpenSpec |
|
|
147
155
|
|
|
148
156
|
## Contributing
|
|
149
157
|
|
package/dist/bin.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as e,
|
|
3
|
-
import { existsSync as
|
|
4
|
-
import { dirname as
|
|
5
|
-
import { fileURLToPath as
|
|
6
|
-
import { homedir as
|
|
2
|
+
import { a as e, f as t, i as n, l as r, n as i, o as a, p as o, r as s, s as c, t as l, u } from "./uninstall-k_ZGY-Mk.js";
|
|
3
|
+
import { existsSync as d, readFileSync as f, statSync as p } from "node:fs";
|
|
4
|
+
import { dirname as m, join as h, resolve as g } from "node:path";
|
|
5
|
+
import { fileURLToPath as _ } from "node:url";
|
|
6
|
+
import { homedir as v } from "node:os";
|
|
7
7
|
//#region src/commands/config.ts
|
|
8
|
-
function
|
|
8
|
+
function y(e, t) {
|
|
9
9
|
let [n, r] = t;
|
|
10
|
-
return n ? r ?
|
|
10
|
+
return n ? r ? S(e, n, r) : x(e, n) : b(e);
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
let
|
|
14
|
-
storage:
|
|
15
|
-
paths:
|
|
16
|
-
} :
|
|
12
|
+
function b(e) {
|
|
13
|
+
let n = t(e), r = n.storage === "local" ? {
|
|
14
|
+
storage: n.storage,
|
|
15
|
+
paths: n.paths
|
|
16
|
+
} : n;
|
|
17
17
|
return JSON.stringify(r, null, 2).split("\n");
|
|
18
18
|
}
|
|
19
|
-
function
|
|
20
|
-
let r =
|
|
21
|
-
return r === void 0 ? [`Unknown key: ${
|
|
19
|
+
function x(e, n) {
|
|
20
|
+
let r = w(t(e), n);
|
|
21
|
+
return r === void 0 ? [`Unknown key: ${n}`] : typeof r == "object" ? [JSON.stringify(r, null, 2)] : [String(r)];
|
|
22
22
|
}
|
|
23
|
-
function
|
|
24
|
-
|
|
25
|
-
let
|
|
26
|
-
return
|
|
23
|
+
function S(e, t, n) {
|
|
24
|
+
o(e, T(t, n));
|
|
25
|
+
let r = [`✓ Set ${t} = ${n}`];
|
|
26
|
+
return C(e, r), r;
|
|
27
27
|
}
|
|
28
|
-
function
|
|
29
|
-
|
|
28
|
+
function C(n, r) {
|
|
29
|
+
u.some((e) => d(h(n, ".claude", "skills", e))) && (e(n, t(n)), r.push("✓ Skills re-rendered"));
|
|
30
30
|
}
|
|
31
|
-
function
|
|
31
|
+
function w(e, t) {
|
|
32
32
|
let n = t.split("."), r = e;
|
|
33
33
|
for (let e of n) {
|
|
34
34
|
if (typeof r != "object" || !r) return;
|
|
@@ -36,7 +36,7 @@ function C(e, t) {
|
|
|
36
36
|
}
|
|
37
37
|
return r;
|
|
38
38
|
}
|
|
39
|
-
function
|
|
39
|
+
function T(e, t) {
|
|
40
40
|
let n = e.split("."), r = {}, i = r;
|
|
41
41
|
for (let e = 0; e < n.length - 1; e++) {
|
|
42
42
|
let t = {};
|
|
@@ -46,11 +46,11 @@ function w(e, t) {
|
|
|
46
46
|
}
|
|
47
47
|
//#endregion
|
|
48
48
|
//#region src/cli.ts
|
|
49
|
-
var { version:
|
|
49
|
+
var { version: E } = JSON.parse(f(g(m(_(import.meta.url)), "..", "package.json"), "utf8")), D = Math.max(...a.map((e) => `${e.name} ${e.args}`.length)), O = [
|
|
50
50
|
"Usage: tracerkit <command> [path]",
|
|
51
51
|
"",
|
|
52
52
|
"Commands:",
|
|
53
|
-
...
|
|
53
|
+
...a.map((e) => ` ${`${e.name} ${e.args}`.padEnd(D + 2)}${e.desc}`),
|
|
54
54
|
"",
|
|
55
55
|
"Options:",
|
|
56
56
|
" --force Overwrite modified files during update",
|
|
@@ -60,39 +60,40 @@ var { version: T } = JSON.parse(d(h(p(g(import.meta.url)), "..", "package.json")
|
|
|
60
60
|
"init/update/uninstall default to the home directory when no path is given.",
|
|
61
61
|
"config defaults to the current working directory."
|
|
62
62
|
];
|
|
63
|
-
function
|
|
63
|
+
function k(e) {
|
|
64
64
|
if (!e) return !1;
|
|
65
65
|
try {
|
|
66
|
-
return
|
|
66
|
+
return p(g(e)).isDirectory();
|
|
67
67
|
} catch {
|
|
68
68
|
return !1;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
function
|
|
71
|
+
function A(e, t = v()) {
|
|
72
72
|
let n = e.find((e) => !e.startsWith("-"));
|
|
73
|
-
return n ?
|
|
73
|
+
return n ? g(n) : t;
|
|
74
74
|
}
|
|
75
|
-
function
|
|
76
|
-
if (e.includes(
|
|
77
|
-
if (e.includes(
|
|
78
|
-
let
|
|
79
|
-
if (
|
|
80
|
-
switch (
|
|
81
|
-
case "init": return
|
|
75
|
+
function j(e) {
|
|
76
|
+
if (e.includes(r.help) || e.includes("-h")) return O;
|
|
77
|
+
if (e.includes(r.version) || e.includes("-v")) return [`tracerkit/${E}`];
|
|
78
|
+
let t = e[0], a = e.slice(1);
|
|
79
|
+
if (c.includes(t)) return [`"${t}" has been removed — skills handle this now.`, "Run `tracerkit update` to get the latest skills."];
|
|
80
|
+
switch (t) {
|
|
81
|
+
case "init": return s(A(a));
|
|
82
82
|
case "update": {
|
|
83
|
-
let e =
|
|
84
|
-
return
|
|
83
|
+
let e = a.includes(r.force), t = n(A(a.filter((e) => e !== r.force)), { force: e });
|
|
84
|
+
return t.push("", "Updated to the latest TracerKit."), t.push("If using Claude Code, restart your session to load changes."), t;
|
|
85
85
|
}
|
|
86
86
|
case "config": {
|
|
87
|
-
let e =
|
|
88
|
-
return
|
|
87
|
+
let e = k(a[0]);
|
|
88
|
+
return y(e ? g(a[0]) : process.cwd(), e ? a.slice(1) : a);
|
|
89
89
|
}
|
|
90
|
-
case "uninstall": return l(
|
|
91
|
-
|
|
90
|
+
case "uninstall": return l(A(a));
|
|
91
|
+
case "migrate-storage": return i(k(a[0]) ? g(a[0]) : process.cwd());
|
|
92
|
+
default: return O;
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
//#endregion
|
|
95
96
|
//#region src/bin.ts
|
|
96
|
-
var
|
|
97
|
-
for (let e of
|
|
97
|
+
var M = j(process.argv.slice(2));
|
|
98
|
+
for (let e of M) console.log(e);
|
|
98
99
|
//#endregion
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { c as e, i as t, n, o as r, r as i, t as a, u as o } from "./uninstall-k_ZGY-Mk.js";
|
|
2
|
+
export { r as COMMANDS, e as DEPRECATED_SKILLS, o as SKILL_NAMES, i as init, n as migrateStorage, a as uninstall, t as update };
|
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
import { existsSync as e, mkdirSync as t, readFileSync as n, readdirSync as r, rmSync as i, writeFileSync as a } from "node:fs";
|
|
2
|
+
import { basename as o, dirname as s, join as c } from "node:path";
|
|
3
|
+
import { createHash as l } from "node:crypto";
|
|
4
|
+
import { fileURLToPath as u } from "node:url";
|
|
5
|
+
import { execSync as d } from "node:child_process";
|
|
6
|
+
//#region src/config.ts
|
|
7
|
+
var f = "local", p = "github", m = [f, p], h = {
|
|
8
|
+
prds: ".tracerkit/prds",
|
|
9
|
+
plans: ".tracerkit/plans",
|
|
10
|
+
archives: ".tracerkit/archives"
|
|
11
|
+
}, g = { labels: {
|
|
12
|
+
prd: "tk:prd",
|
|
13
|
+
plan: "tk:plan"
|
|
14
|
+
} };
|
|
15
|
+
function _(t) {
|
|
16
|
+
let r = c(t, ".tracerkit", "config.json");
|
|
17
|
+
if (!e(r)) return {
|
|
18
|
+
storage: f,
|
|
19
|
+
paths: { ...h },
|
|
20
|
+
github: { ...g }
|
|
21
|
+
};
|
|
22
|
+
let i;
|
|
23
|
+
try {
|
|
24
|
+
i = JSON.parse(n(r, "utf8"));
|
|
25
|
+
} catch {
|
|
26
|
+
throw Error("Invalid .tracerkit/config.json — expected valid JSON");
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
storage: ee(i.storage),
|
|
30
|
+
paths: v(i.paths),
|
|
31
|
+
github: y(i.github)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function ee(e) {
|
|
35
|
+
return typeof e == "string" && m.includes(e) ? e : f;
|
|
36
|
+
}
|
|
37
|
+
function v(e) {
|
|
38
|
+
let t = S(e) ? e : {};
|
|
39
|
+
return {
|
|
40
|
+
prds: typeof t.prds == "string" ? t.prds : h.prds,
|
|
41
|
+
plans: typeof t.plans == "string" ? t.plans : h.plans,
|
|
42
|
+
archives: typeof t.archives == "string" ? t.archives : h.archives
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function y(e) {
|
|
46
|
+
let t = S(e) ? e : {}, n = S(t.labels) ? t.labels : {};
|
|
47
|
+
return {
|
|
48
|
+
...typeof t.repo == "string" ? { repo: t.repo } : {},
|
|
49
|
+
labels: {
|
|
50
|
+
prd: typeof n.prd == "string" ? n.prd : g.labels.prd,
|
|
51
|
+
plan: typeof n.plan == "string" ? n.plan : g.labels.plan
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function b(r, i) {
|
|
56
|
+
let o = c(r, ".tracerkit", "config.json");
|
|
57
|
+
t(s(o), { recursive: !0 });
|
|
58
|
+
let l = {};
|
|
59
|
+
if (e(o)) try {
|
|
60
|
+
l = JSON.parse(n(o, "utf8"));
|
|
61
|
+
} catch {
|
|
62
|
+
l = {};
|
|
63
|
+
}
|
|
64
|
+
let u = x(l, i);
|
|
65
|
+
a(o, JSON.stringify(u, null, 2) + "\n");
|
|
66
|
+
}
|
|
67
|
+
function x(e, t) {
|
|
68
|
+
let n = { ...e };
|
|
69
|
+
for (let e of Object.keys(t)) S(n[e]) && S(t[e]) ? n[e] = x(n[e], t[e]) : n[e] = t[e];
|
|
70
|
+
return n;
|
|
71
|
+
}
|
|
72
|
+
function S(e) {
|
|
73
|
+
return typeof e == "object" && !!e && !Array.isArray(e);
|
|
74
|
+
}
|
|
75
|
+
var C = [
|
|
76
|
+
"tk:brief",
|
|
77
|
+
"tk:prd",
|
|
78
|
+
"tk:plan",
|
|
79
|
+
"tk:check"
|
|
80
|
+
], w = ["tk:verify"], T = {
|
|
81
|
+
force: "--force",
|
|
82
|
+
help: "--help",
|
|
83
|
+
version: "--version"
|
|
84
|
+
}, E = [
|
|
85
|
+
"brief",
|
|
86
|
+
"progress",
|
|
87
|
+
"archive"
|
|
88
|
+
], D = [
|
|
89
|
+
{
|
|
90
|
+
name: "init",
|
|
91
|
+
args: "[path]",
|
|
92
|
+
desc: "Install skills to ~/.claude/skills/ (or [path] if given)"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: "update",
|
|
96
|
+
args: "[path]",
|
|
97
|
+
desc: "Refresh unchanged files from latest version, skip modified"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "config",
|
|
101
|
+
args: "[path] [key] [value]",
|
|
102
|
+
desc: "Get or set TracerKit configuration"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "uninstall",
|
|
106
|
+
args: "[path]",
|
|
107
|
+
desc: "Remove TracerKit skill directories, keep .tracerkit/ artifacts"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: "migrate-storage",
|
|
111
|
+
args: "[path]",
|
|
112
|
+
desc: "Migrate artifacts between local and GitHub storage backends"
|
|
113
|
+
}
|
|
114
|
+
], O = c(s(u(import.meta.url)), "..", "skills");
|
|
115
|
+
function k(e, t = "") {
|
|
116
|
+
let n = r(e, { withFileTypes: !0 }), i = [];
|
|
117
|
+
for (let r of n) {
|
|
118
|
+
let n = t ? `${t}/${r.name}` : r.name;
|
|
119
|
+
r.isDirectory() ? i.push(...k(c(e, r.name), n)) : i.push(n);
|
|
120
|
+
}
|
|
121
|
+
return i.sort();
|
|
122
|
+
}
|
|
123
|
+
function A(e) {
|
|
124
|
+
return `.claude/skills/tk:${e}`;
|
|
125
|
+
}
|
|
126
|
+
function j(e) {
|
|
127
|
+
return e.slice(18);
|
|
128
|
+
}
|
|
129
|
+
function M(e, t) {
|
|
130
|
+
let n = e;
|
|
131
|
+
return t.paths.prds !== h.prds && (n = n.replaceAll(h.prds, t.paths.prds)), t.paths.plans !== h.plans && (n = n.replaceAll(h.plans, t.paths.plans)), t.paths.archives !== h.archives && (n = n.replaceAll(h.archives, t.paths.archives)), t.github?.repo && (n = n.replaceAll("{{github.repo}}", t.github.repo)), t.github?.labels?.prd && (n = n.replaceAll("{{github.labels.prd}}", t.github.labels.prd)), t.github?.labels?.plan && (n = n.replaceAll("{{github.labels.plan}}", t.github.labels.plan)), n;
|
|
132
|
+
}
|
|
133
|
+
function N(e, r, i) {
|
|
134
|
+
let o = i ?? k(O).map(A);
|
|
135
|
+
for (let i of o) {
|
|
136
|
+
let o = c(O, j(i)), l = c(e, i);
|
|
137
|
+
t(s(l), { recursive: !0 }), a(l, M(n(o, "utf8"), r));
|
|
138
|
+
}
|
|
139
|
+
return { copied: o };
|
|
140
|
+
}
|
|
141
|
+
function P(e) {
|
|
142
|
+
return l("sha256").update(e).digest("hex");
|
|
143
|
+
}
|
|
144
|
+
function F(t, r) {
|
|
145
|
+
let i = k(O).map(A), a = [], o = [], s = [];
|
|
146
|
+
for (let l of i) {
|
|
147
|
+
let i = c(t, l);
|
|
148
|
+
if (!e(i)) s.push(l);
|
|
149
|
+
else {
|
|
150
|
+
let e = M(n(c(O, j(l)), "utf8"), r);
|
|
151
|
+
P(Buffer.from(e)) === P(n(i)) ? a.push(l) : o.push(l);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
unchanged: a,
|
|
156
|
+
modified: o,
|
|
157
|
+
missing: s
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region src/commands/update.ts
|
|
162
|
+
function I(t, n) {
|
|
163
|
+
if (!C.some((n) => e(c(t, ".claude", "skills", n)))) throw Error("TracerKit not initialized — run `tracerkit init` first");
|
|
164
|
+
let r = _(t), { unchanged: a, modified: o, missing: s } = F(t, r), l = [];
|
|
165
|
+
for (let n of w) {
|
|
166
|
+
let r = c(t, ".claude", "skills", n);
|
|
167
|
+
e(r) && (i(r, {
|
|
168
|
+
recursive: !0,
|
|
169
|
+
force: !0
|
|
170
|
+
}), l.push(`✗ .claude/skills/${n}/ removed (deprecated)`));
|
|
171
|
+
}
|
|
172
|
+
let u = n?.force ?? !1, d = [
|
|
173
|
+
...a,
|
|
174
|
+
...s,
|
|
175
|
+
...u ? o : []
|
|
176
|
+
];
|
|
177
|
+
if (d.length > 0) {
|
|
178
|
+
N(t, r, d);
|
|
179
|
+
for (let e of a) l.push(`✓ ${e}`);
|
|
180
|
+
for (let e of s) l.push(`✓ ${e} (added)`);
|
|
181
|
+
if (u) for (let e of o) l.push(`✓ ${e} (replaced)`);
|
|
182
|
+
}
|
|
183
|
+
if (!u && o.length > 0) {
|
|
184
|
+
for (let e of o) l.push(`⚠ ${e} (skipped — modified)`);
|
|
185
|
+
l.push("", "Run `tracerkit update --force` to replace modified files with latest versions.");
|
|
186
|
+
}
|
|
187
|
+
return l;
|
|
188
|
+
}
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/commands/init.ts
|
|
191
|
+
function te(t) {
|
|
192
|
+
if (C.some((n) => e(c(t, ".claude", "skills", n)))) return I(t, { force: !1 });
|
|
193
|
+
let { copied: n } = N(t, _(t));
|
|
194
|
+
return n.map((e) => `✓ ${e}`);
|
|
195
|
+
}
|
|
196
|
+
//#endregion
|
|
197
|
+
//#region src/commands/migrate-storage.ts
|
|
198
|
+
var L = {
|
|
199
|
+
created: "tk:created",
|
|
200
|
+
in_progress: "tk:in-progress",
|
|
201
|
+
done: "tk:done"
|
|
202
|
+
}, R = {
|
|
203
|
+
"tk:created": "created",
|
|
204
|
+
"tk:in-progress": "in_progress",
|
|
205
|
+
"tk:done": "done"
|
|
206
|
+
};
|
|
207
|
+
function z(e) {
|
|
208
|
+
let t = e.match(/^---\n([\s\S]*?)---\n([\s\S]*)$/);
|
|
209
|
+
if (!t) return {
|
|
210
|
+
metadata: {},
|
|
211
|
+
body: e
|
|
212
|
+
};
|
|
213
|
+
let n = {};
|
|
214
|
+
for (let e of t[1].split("\n")) {
|
|
215
|
+
let t = e.indexOf(":");
|
|
216
|
+
if (t === -1) continue;
|
|
217
|
+
let r = e.slice(0, t).trim(), i = e.slice(t + 1).trim();
|
|
218
|
+
r && (n[r] = i);
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
metadata: n,
|
|
222
|
+
body: t[2]
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function B(e) {
|
|
226
|
+
let t = Object.entries(e);
|
|
227
|
+
return t.length === 0 ? "<!-- tk:metadata\n-->" : `<!-- tk:metadata\n${t.map(([e, t]) => `${e}: ${t}`).join("\n")}\n-->`;
|
|
228
|
+
}
|
|
229
|
+
function V(e) {
|
|
230
|
+
return L[e] ?? "tk:created";
|
|
231
|
+
}
|
|
232
|
+
function H(e) {
|
|
233
|
+
let t = e.match(/<!--\s*tk:metadata\n([\s\S]*?)-->\n*([\s\S]*)$/);
|
|
234
|
+
if (!t) return {
|
|
235
|
+
metadata: {},
|
|
236
|
+
body: e
|
|
237
|
+
};
|
|
238
|
+
let n = {};
|
|
239
|
+
for (let e of t[1].split("\n")) {
|
|
240
|
+
let t = e.indexOf(":");
|
|
241
|
+
if (t === -1) continue;
|
|
242
|
+
let r = e.slice(0, t).trim(), i = e.slice(t + 1).trim();
|
|
243
|
+
r && (n[r] = i);
|
|
244
|
+
}
|
|
245
|
+
return {
|
|
246
|
+
metadata: n,
|
|
247
|
+
body: t[2]
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function U(e) {
|
|
251
|
+
let t = Object.entries(e);
|
|
252
|
+
return t.length === 0 ? "---\n---\n" : `---\n${t.map(([e, t]) => `${e}: ${t}`).join("\n")}\n---\n`;
|
|
253
|
+
}
|
|
254
|
+
function W(e) {
|
|
255
|
+
let t = e.match(/\[[^\]]+\]\s+([^:]+):/);
|
|
256
|
+
return t ? t[1].trim() : null;
|
|
257
|
+
}
|
|
258
|
+
function G(e) {
|
|
259
|
+
let t = e.match(/^#\s+(.+)$/m);
|
|
260
|
+
return t ? t[1].trim() : "Untitled";
|
|
261
|
+
}
|
|
262
|
+
function K(t, i) {
|
|
263
|
+
let a = [], s = c(t, i.paths.prds);
|
|
264
|
+
if (e(s)) for (let e of r(s)) {
|
|
265
|
+
if (!e.endsWith(".md")) continue;
|
|
266
|
+
let t = o(e, ".md"), { metadata: r, body: i } = z(n(c(s, e), "utf8"));
|
|
267
|
+
a.push({
|
|
268
|
+
slug: t,
|
|
269
|
+
type: "prd",
|
|
270
|
+
metadata: r,
|
|
271
|
+
body: i,
|
|
272
|
+
title: G(i),
|
|
273
|
+
archived: !1
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
let l = c(t, i.paths.plans);
|
|
277
|
+
if (e(l)) for (let e of r(l)) {
|
|
278
|
+
if (!e.endsWith(".md")) continue;
|
|
279
|
+
let t = o(e, ".md"), r = n(c(l, e), "utf8");
|
|
280
|
+
a.push({
|
|
281
|
+
slug: t,
|
|
282
|
+
type: "plan",
|
|
283
|
+
metadata: {},
|
|
284
|
+
body: r,
|
|
285
|
+
title: G(r),
|
|
286
|
+
archived: !1
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
let u = c(t, i.paths.archives);
|
|
290
|
+
if (e(u)) for (let t of r(u, { withFileTypes: !0 })) {
|
|
291
|
+
if (!t.isDirectory()) continue;
|
|
292
|
+
let r = t.name, i = c(u, r, "prd.md"), o = c(u, r, "plan.md");
|
|
293
|
+
if (e(i)) {
|
|
294
|
+
let { metadata: e, body: t } = z(n(i, "utf8"));
|
|
295
|
+
a.push({
|
|
296
|
+
slug: r,
|
|
297
|
+
type: "prd",
|
|
298
|
+
metadata: {
|
|
299
|
+
...e,
|
|
300
|
+
status: "done"
|
|
301
|
+
},
|
|
302
|
+
body: t,
|
|
303
|
+
title: G(t),
|
|
304
|
+
archived: !0
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
if (e(o)) {
|
|
308
|
+
let e = n(o, "utf8");
|
|
309
|
+
a.push({
|
|
310
|
+
slug: r,
|
|
311
|
+
type: "plan",
|
|
312
|
+
metadata: { status: "done" },
|
|
313
|
+
body: e,
|
|
314
|
+
title: G(e),
|
|
315
|
+
archived: !0
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return a;
|
|
320
|
+
}
|
|
321
|
+
function q(e) {
|
|
322
|
+
return d(`gh ${e.map((e) => `'${e.replace(/'/g, "'\\''")}'`).join(" ")}`, {
|
|
323
|
+
encoding: "utf8",
|
|
324
|
+
stdio: [
|
|
325
|
+
"pipe",
|
|
326
|
+
"pipe",
|
|
327
|
+
"pipe"
|
|
328
|
+
]
|
|
329
|
+
}).trim();
|
|
330
|
+
}
|
|
331
|
+
function J(e, t) {
|
|
332
|
+
return e.github.repo ? e.github.repo : t([
|
|
333
|
+
"repo",
|
|
334
|
+
"view",
|
|
335
|
+
"--json",
|
|
336
|
+
"nameWithOwner",
|
|
337
|
+
"-q",
|
|
338
|
+
".nameWithOwner"
|
|
339
|
+
]);
|
|
340
|
+
}
|
|
341
|
+
function Y(e, t, n) {
|
|
342
|
+
let r = n([
|
|
343
|
+
"issue",
|
|
344
|
+
"list",
|
|
345
|
+
"--repo",
|
|
346
|
+
e,
|
|
347
|
+
"--label",
|
|
348
|
+
t,
|
|
349
|
+
"--state",
|
|
350
|
+
"all",
|
|
351
|
+
"--json",
|
|
352
|
+
"number,title,body,labels,state",
|
|
353
|
+
"--limit",
|
|
354
|
+
"1000"
|
|
355
|
+
]);
|
|
356
|
+
return JSON.parse(r || "[]");
|
|
357
|
+
}
|
|
358
|
+
function X(e, t) {
|
|
359
|
+
return t.some((t) => W(t.title) === e);
|
|
360
|
+
}
|
|
361
|
+
function Z(e, t, n) {
|
|
362
|
+
for (let r of t) n([
|
|
363
|
+
"label",
|
|
364
|
+
"create",
|
|
365
|
+
r,
|
|
366
|
+
"--repo",
|
|
367
|
+
e,
|
|
368
|
+
"--force"
|
|
369
|
+
]);
|
|
370
|
+
}
|
|
371
|
+
function ne(e, t, n) {
|
|
372
|
+
let r = [
|
|
373
|
+
"issue",
|
|
374
|
+
"create",
|
|
375
|
+
"--repo",
|
|
376
|
+
e,
|
|
377
|
+
"--title",
|
|
378
|
+
t.title,
|
|
379
|
+
"--body",
|
|
380
|
+
t.body
|
|
381
|
+
];
|
|
382
|
+
for (let e of t.labels) r.push("--label", e);
|
|
383
|
+
let i = n(r).match(/\/(\d+)\s*$/);
|
|
384
|
+
return i ? parseInt(i[1], 10) : 0;
|
|
385
|
+
}
|
|
386
|
+
function re(e, t, n) {
|
|
387
|
+
n([
|
|
388
|
+
"issue",
|
|
389
|
+
"close",
|
|
390
|
+
String(t),
|
|
391
|
+
"--repo",
|
|
392
|
+
e
|
|
393
|
+
]);
|
|
394
|
+
}
|
|
395
|
+
function ie(e, t, n) {
|
|
396
|
+
let r = n([
|
|
397
|
+
"pr",
|
|
398
|
+
"list",
|
|
399
|
+
"--repo",
|
|
400
|
+
e,
|
|
401
|
+
"--search",
|
|
402
|
+
t,
|
|
403
|
+
"--state",
|
|
404
|
+
"merged",
|
|
405
|
+
"--json",
|
|
406
|
+
"number,title",
|
|
407
|
+
"--limit",
|
|
408
|
+
"5"
|
|
409
|
+
]);
|
|
410
|
+
return JSON.parse(r || "[]");
|
|
411
|
+
}
|
|
412
|
+
function ae(e, t, n, r) {
|
|
413
|
+
r([
|
|
414
|
+
"issue",
|
|
415
|
+
"comment",
|
|
416
|
+
String(t),
|
|
417
|
+
"--repo",
|
|
418
|
+
e,
|
|
419
|
+
"--body",
|
|
420
|
+
n
|
|
421
|
+
]);
|
|
422
|
+
}
|
|
423
|
+
function oe(e) {
|
|
424
|
+
for (let t of e) {
|
|
425
|
+
let e = R[t];
|
|
426
|
+
if (e) return e;
|
|
427
|
+
}
|
|
428
|
+
return "created";
|
|
429
|
+
}
|
|
430
|
+
function Q(e, n) {
|
|
431
|
+
t(s(e), { recursive: !0 }), a(e, n);
|
|
432
|
+
}
|
|
433
|
+
function $(e, t) {
|
|
434
|
+
let n = t?.runGh ?? q, r = _(e);
|
|
435
|
+
return r.storage === "local" ? se(e, r, n) : le(e, r, n);
|
|
436
|
+
}
|
|
437
|
+
function se(e, t, n) {
|
|
438
|
+
let r = [], i = J(t, n), a = K(e, t);
|
|
439
|
+
if (a.length === 0) return b(e, { storage: p }), r.push("No artifacts found — nothing to migrate."), r.push(`✓ Storage switched to "${p}".`), r;
|
|
440
|
+
let o = t.github.labels?.prd ?? "tk:prd", s = t.github.labels?.plan ?? "tk:plan";
|
|
441
|
+
Z(i, [
|
|
442
|
+
o,
|
|
443
|
+
s,
|
|
444
|
+
...[...new Set(a.map((e) => V(e.metadata.status ?? "created")))]
|
|
445
|
+
], n);
|
|
446
|
+
let c = Y(i, o, n), l = Y(i, s, n);
|
|
447
|
+
for (let e of a) {
|
|
448
|
+
let t = e.type === "prd" ? o : s, a = e.type === "prd" ? c : l;
|
|
449
|
+
if (X(e.slug, a)) {
|
|
450
|
+
r.push(`⚠ skip ${e.type} "${e.slug}" — already exists on GitHub`);
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
let u = V(e.metadata.status ?? "created"), d = `${B(e.metadata)}\n\n${e.body.replace(/^\n/, "")}`, f = ne(i, {
|
|
454
|
+
title: `[${t}] ${e.slug}: ${e.title}`,
|
|
455
|
+
body: d,
|
|
456
|
+
labels: [t, u]
|
|
457
|
+
}, n);
|
|
458
|
+
e.archived ? (re(i, f, n), ce(i, e.slug, f, n), r.push(`✓ ${e.type} "${e.slug}" → issue #${f} (closed)`)) : r.push(`✓ ${e.type} "${e.slug}" → issue #${f}`);
|
|
459
|
+
}
|
|
460
|
+
return b(e, { storage: p }), r.push(`✓ Storage switched to "${p}".`), r;
|
|
461
|
+
}
|
|
462
|
+
function ce(e, t, n, r) {
|
|
463
|
+
let i = ie(e, t, r);
|
|
464
|
+
i.length !== 0 && ae(e, n, `Linked PR: ${i.map((e) => `#${e.number}`).join(", ")}`, r);
|
|
465
|
+
}
|
|
466
|
+
function le(t, n, r) {
|
|
467
|
+
let i = [], a = J(n, r), o = n.github.labels?.prd ?? "tk:prd", s = n.github.labels?.plan ?? "tk:plan", l = Y(a, o, r), u = Y(a, s, r), d = [...l.map((e) => ({
|
|
468
|
+
...e,
|
|
469
|
+
type: "prd"
|
|
470
|
+
})), ...u.map((e) => ({
|
|
471
|
+
...e,
|
|
472
|
+
type: "plan"
|
|
473
|
+
}))];
|
|
474
|
+
if (d.length === 0) return b(t, { storage: f }), i.push("No GitHub issues found — nothing to migrate."), i.push(`✓ Storage switched to "${f}".`), i;
|
|
475
|
+
for (let r of d) {
|
|
476
|
+
let a = W(r.title);
|
|
477
|
+
if (!a) continue;
|
|
478
|
+
let o = r.labels.map((e) => e.name), s = o.includes("tk:done") && r.state === "CLOSED", { metadata: l, body: u } = H(r.body ?? ""), d = l.status ?? oe(o);
|
|
479
|
+
if (s) {
|
|
480
|
+
let o = c(t, n.paths.archives, a), s = c(o, "prd.md"), f = c(o, "plan.md"), p = r.type === "prd" ? s : f;
|
|
481
|
+
if (e(p)) {
|
|
482
|
+
i.push(`⚠ skip ${r.type} "${a}" — local file already exists`);
|
|
483
|
+
continue;
|
|
484
|
+
}
|
|
485
|
+
r.type === "prd" ? Q(p, `${U({
|
|
486
|
+
...l,
|
|
487
|
+
status: d
|
|
488
|
+
})}\n${u}`) : Q(p, u), i.push(`✓ ${r.type} "${a}" → ${p} (archived)`);
|
|
489
|
+
} else {
|
|
490
|
+
let o = c(t, r.type === "prd" ? n.paths.prds : n.paths.plans, `${a}.md`);
|
|
491
|
+
if (e(o)) {
|
|
492
|
+
i.push(`⚠ skip ${r.type} "${a}" — local file already exists`);
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
r.type === "prd" ? Q(o, `${U({
|
|
496
|
+
...l,
|
|
497
|
+
status: d
|
|
498
|
+
})}\n${u}`) : Q(o, u), i.push(`✓ ${r.type} "${a}" → ${o}`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return b(t, { storage: f }), i.push(`✓ Storage switched to "${f}".`), i;
|
|
502
|
+
}
|
|
503
|
+
//#endregion
|
|
504
|
+
//#region src/commands/uninstall.ts
|
|
505
|
+
function ue(t) {
|
|
506
|
+
if (!C.some((n) => e(c(t, ".claude", "skills", n)))) throw Error("TracerKit not initialized — nothing to uninstall");
|
|
507
|
+
let n = [];
|
|
508
|
+
for (let r of C) {
|
|
509
|
+
let a = c(t, ".claude", "skills", r);
|
|
510
|
+
e(a) && (i(a, {
|
|
511
|
+
recursive: !0,
|
|
512
|
+
force: !0
|
|
513
|
+
}), n.push(`✗ .claude/skills/${r}/ removed`));
|
|
514
|
+
}
|
|
515
|
+
return n;
|
|
516
|
+
}
|
|
517
|
+
//#endregion
|
|
518
|
+
export { N as a, w as c, f as d, _ as f, I as i, T as l, $ as n, D as o, b as p, te as r, E as s, ue as t, C as u };
|
package/package.json
CHANGED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import { existsSync as e, mkdirSync as t, readFileSync as n, readdirSync as r, rmSync as i, writeFileSync as a } from "node:fs";
|
|
2
|
-
import { dirname as o, join as s } from "node:path";
|
|
3
|
-
import { createHash as c } from "node:crypto";
|
|
4
|
-
import { fileURLToPath as l } from "node:url";
|
|
5
|
-
//#region src/config.ts
|
|
6
|
-
var u = "local", d = [u, "github"], f = {
|
|
7
|
-
prds: ".tracerkit/prds",
|
|
8
|
-
plans: ".tracerkit/plans",
|
|
9
|
-
archives: ".tracerkit/archives"
|
|
10
|
-
}, p = { labels: {
|
|
11
|
-
prd: "tk:prd",
|
|
12
|
-
plan: "tk:plan"
|
|
13
|
-
} };
|
|
14
|
-
function m(t) {
|
|
15
|
-
let r = s(t, ".tracerkit", "config.json");
|
|
16
|
-
if (!e(r)) return {
|
|
17
|
-
storage: u,
|
|
18
|
-
paths: { ...f },
|
|
19
|
-
github: { ...p }
|
|
20
|
-
};
|
|
21
|
-
let i;
|
|
22
|
-
try {
|
|
23
|
-
i = JSON.parse(n(r, "utf8"));
|
|
24
|
-
} catch {
|
|
25
|
-
throw Error("Invalid .tracerkit/config.json — expected valid JSON");
|
|
26
|
-
}
|
|
27
|
-
return {
|
|
28
|
-
storage: h(i.storage),
|
|
29
|
-
paths: g(i.paths),
|
|
30
|
-
github: _(i.github)
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
function h(e) {
|
|
34
|
-
return typeof e == "string" && d.includes(e) ? e : u;
|
|
35
|
-
}
|
|
36
|
-
function g(e) {
|
|
37
|
-
let t = b(e) ? e : {};
|
|
38
|
-
return {
|
|
39
|
-
prds: typeof t.prds == "string" ? t.prds : f.prds,
|
|
40
|
-
plans: typeof t.plans == "string" ? t.plans : f.plans,
|
|
41
|
-
archives: typeof t.archives == "string" ? t.archives : f.archives
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
function _(e) {
|
|
45
|
-
let t = b(e) ? e : {}, n = b(t.labels) ? t.labels : {};
|
|
46
|
-
return {
|
|
47
|
-
...typeof t.repo == "string" ? { repo: t.repo } : {},
|
|
48
|
-
labels: {
|
|
49
|
-
prd: typeof n.prd == "string" ? n.prd : p.labels.prd,
|
|
50
|
-
plan: typeof n.plan == "string" ? n.plan : p.labels.plan
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
function v(r, i) {
|
|
55
|
-
let c = s(r, ".tracerkit", "config.json");
|
|
56
|
-
t(o(c), { recursive: !0 });
|
|
57
|
-
let l = {};
|
|
58
|
-
if (e(c)) try {
|
|
59
|
-
l = JSON.parse(n(c, "utf8"));
|
|
60
|
-
} catch {
|
|
61
|
-
l = {};
|
|
62
|
-
}
|
|
63
|
-
let u = y(l, i);
|
|
64
|
-
a(c, JSON.stringify(u, null, 2) + "\n");
|
|
65
|
-
}
|
|
66
|
-
function y(e, t) {
|
|
67
|
-
let n = { ...e };
|
|
68
|
-
for (let e of Object.keys(t)) b(n[e]) && b(t[e]) ? n[e] = y(n[e], t[e]) : n[e] = t[e];
|
|
69
|
-
return n;
|
|
70
|
-
}
|
|
71
|
-
function b(e) {
|
|
72
|
-
return typeof e == "object" && !!e && !Array.isArray(e);
|
|
73
|
-
}
|
|
74
|
-
var x = [
|
|
75
|
-
"tk:brief",
|
|
76
|
-
"tk:prd",
|
|
77
|
-
"tk:plan",
|
|
78
|
-
"tk:check"
|
|
79
|
-
], S = ["tk:verify"], C = {
|
|
80
|
-
force: "--force",
|
|
81
|
-
help: "--help",
|
|
82
|
-
version: "--version"
|
|
83
|
-
}, w = [
|
|
84
|
-
"brief",
|
|
85
|
-
"progress",
|
|
86
|
-
"archive"
|
|
87
|
-
], T = [
|
|
88
|
-
{
|
|
89
|
-
name: "init",
|
|
90
|
-
args: "[path]",
|
|
91
|
-
desc: "Install skills to ~/.claude/skills/ (or [path] if given)"
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
name: "update",
|
|
95
|
-
args: "[path]",
|
|
96
|
-
desc: "Refresh unchanged files from latest version, skip modified"
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: "config",
|
|
100
|
-
args: "[path] [key] [value]",
|
|
101
|
-
desc: "Get or set TracerKit configuration"
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
name: "uninstall",
|
|
105
|
-
args: "[path]",
|
|
106
|
-
desc: "Remove TracerKit skill directories, keep .tracerkit/ artifacts"
|
|
107
|
-
}
|
|
108
|
-
], E = s(o(l(import.meta.url)), "..", "skills");
|
|
109
|
-
function D(e, t = "") {
|
|
110
|
-
let n = r(e, { withFileTypes: !0 }), i = [];
|
|
111
|
-
for (let r of n) {
|
|
112
|
-
let n = t ? `${t}/${r.name}` : r.name;
|
|
113
|
-
r.isDirectory() ? i.push(...D(s(e, r.name), n)) : i.push(n);
|
|
114
|
-
}
|
|
115
|
-
return i.sort();
|
|
116
|
-
}
|
|
117
|
-
function O(e) {
|
|
118
|
-
return `.claude/skills/tk:${e}`;
|
|
119
|
-
}
|
|
120
|
-
function k(e) {
|
|
121
|
-
return e.slice(18);
|
|
122
|
-
}
|
|
123
|
-
function A(e, t) {
|
|
124
|
-
let n = e;
|
|
125
|
-
return t.paths.prds !== f.prds && (n = n.replaceAll(f.prds, t.paths.prds)), t.paths.plans !== f.plans && (n = n.replaceAll(f.plans, t.paths.plans)), t.paths.archives !== f.archives && (n = n.replaceAll(f.archives, t.paths.archives)), t.github?.repo && (n = n.replaceAll("{{github.repo}}", t.github.repo)), t.github?.labels?.prd && (n = n.replaceAll("{{github.labels.prd}}", t.github.labels.prd)), t.github?.labels?.plan && (n = n.replaceAll("{{github.labels.plan}}", t.github.labels.plan)), n;
|
|
126
|
-
}
|
|
127
|
-
function j(e, r, i) {
|
|
128
|
-
let c = i ?? D(E).map(O);
|
|
129
|
-
for (let i of c) {
|
|
130
|
-
let c = s(E, k(i)), l = s(e, i);
|
|
131
|
-
t(o(l), { recursive: !0 }), a(l, A(n(c, "utf8"), r));
|
|
132
|
-
}
|
|
133
|
-
return { copied: c };
|
|
134
|
-
}
|
|
135
|
-
function M(e) {
|
|
136
|
-
return c("sha256").update(e).digest("hex");
|
|
137
|
-
}
|
|
138
|
-
function N(t, r) {
|
|
139
|
-
let i = D(E).map(O), a = [], o = [], c = [];
|
|
140
|
-
for (let l of i) {
|
|
141
|
-
let i = s(t, l);
|
|
142
|
-
if (!e(i)) c.push(l);
|
|
143
|
-
else {
|
|
144
|
-
let e = A(n(s(E, k(l)), "utf8"), r);
|
|
145
|
-
M(Buffer.from(e)) === M(n(i)) ? a.push(l) : o.push(l);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return {
|
|
149
|
-
unchanged: a,
|
|
150
|
-
modified: o,
|
|
151
|
-
missing: c
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
//#endregion
|
|
155
|
-
//#region src/commands/update.ts
|
|
156
|
-
function P(t, n) {
|
|
157
|
-
if (!x.some((n) => e(s(t, ".claude", "skills", n)))) throw Error("TracerKit not initialized — run `tracerkit init` first");
|
|
158
|
-
let r = m(t), { unchanged: a, modified: o, missing: c } = N(t, r), l = [];
|
|
159
|
-
for (let n of S) {
|
|
160
|
-
let r = s(t, ".claude", "skills", n);
|
|
161
|
-
e(r) && (i(r, {
|
|
162
|
-
recursive: !0,
|
|
163
|
-
force: !0
|
|
164
|
-
}), l.push(`✗ .claude/skills/${n}/ removed (deprecated)`));
|
|
165
|
-
}
|
|
166
|
-
let u = n?.force ?? !1, d = [
|
|
167
|
-
...a,
|
|
168
|
-
...c,
|
|
169
|
-
...u ? o : []
|
|
170
|
-
];
|
|
171
|
-
if (d.length > 0) {
|
|
172
|
-
j(t, r, d);
|
|
173
|
-
for (let e of a) l.push(`✓ ${e}`);
|
|
174
|
-
for (let e of c) l.push(`✓ ${e} (added)`);
|
|
175
|
-
if (u) for (let e of o) l.push(`✓ ${e} (replaced)`);
|
|
176
|
-
}
|
|
177
|
-
if (!u && o.length > 0) {
|
|
178
|
-
for (let e of o) l.push(`⚠ ${e} (skipped — modified)`);
|
|
179
|
-
l.push("", "Run `tracerkit update --force` to replace modified files with latest versions.");
|
|
180
|
-
}
|
|
181
|
-
return l;
|
|
182
|
-
}
|
|
183
|
-
//#endregion
|
|
184
|
-
//#region src/commands/init.ts
|
|
185
|
-
function F(t) {
|
|
186
|
-
if (x.some((n) => e(s(t, ".claude", "skills", n)))) return P(t, { force: !1 });
|
|
187
|
-
let { copied: n } = j(t, m(t));
|
|
188
|
-
return n.map((e) => `✓ ${e}`);
|
|
189
|
-
}
|
|
190
|
-
//#endregion
|
|
191
|
-
//#region src/commands/uninstall.ts
|
|
192
|
-
function I(t) {
|
|
193
|
-
if (!x.some((n) => e(s(t, ".claude", "skills", n)))) throw Error("TracerKit not initialized — nothing to uninstall");
|
|
194
|
-
let n = [];
|
|
195
|
-
for (let r of x) {
|
|
196
|
-
let a = s(t, ".claude", "skills", r);
|
|
197
|
-
e(a) && (i(a, {
|
|
198
|
-
recursive: !0,
|
|
199
|
-
force: !0
|
|
200
|
-
}), n.push(`✗ .claude/skills/${r}/ removed`));
|
|
201
|
-
}
|
|
202
|
-
return n;
|
|
203
|
-
}
|
|
204
|
-
//#endregion
|
|
205
|
-
export { T as a, C as c, m as d, v as f, j as i, x as l, F as n, w as o, P as r, S as s, I as t, u };
|