tracerkit 1.8.2 → 1.9.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/dist/bin.js +82 -79
- package/dist/index.js +2 -2
- package/dist/{uninstall-DO2YpTSz.js → uninstall-BP2pCnBW.js} +30 -23
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { existsSync as
|
|
4
|
-
import { dirname as
|
|
5
|
-
import { fileURLToPath as
|
|
6
|
-
import { homedir as
|
|
2
|
+
import { c as e, i as t, n, o as r, r as i, t as a } from "./uninstall-BP2pCnBW.js";
|
|
3
|
+
import { existsSync as o, mkdirSync as s, readFileSync as c, readdirSync as l, rmSync as u, unlinkSync as d, writeFileSync as f } from "node:fs";
|
|
4
|
+
import { dirname as p, join as m, resolve as h } from "node:path";
|
|
5
|
+
import { fileURLToPath as g } from "node:url";
|
|
6
|
+
import { homedir as _ } from "node:os";
|
|
7
7
|
//#region src/frontmatter.ts
|
|
8
|
-
var
|
|
9
|
-
function
|
|
8
|
+
var v = /^---\n([\s\S]*?)\n---(?:\n|$)/;
|
|
9
|
+
function y(e) {
|
|
10
10
|
return e.replace(/\r\n/g, "\n");
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
let t =
|
|
12
|
+
function b(e) {
|
|
13
|
+
let t = y(e).match(v);
|
|
14
14
|
if (!t) return {};
|
|
15
15
|
let n = {};
|
|
16
16
|
for (let e of t[1].split("\n")) {
|
|
@@ -21,8 +21,8 @@ function y(e) {
|
|
|
21
21
|
}
|
|
22
22
|
return n;
|
|
23
23
|
}
|
|
24
|
-
function
|
|
25
|
-
let r =
|
|
24
|
+
function x(e, t, n) {
|
|
25
|
+
let r = y(e), i = r.match(v);
|
|
26
26
|
if (!i) return `---\n${t}: ${n}\n---\n${r}`;
|
|
27
27
|
let a = i[1].split("\n"), o = RegExp(`^${t}\\s*:`), s = a.findIndex((e) => o.test(e));
|
|
28
28
|
s === -1 ? a.push(`${t}: ${n}`) : a[s] = `${t}: ${n}`;
|
|
@@ -31,21 +31,21 @@ function b(e, t, n) {
|
|
|
31
31
|
}
|
|
32
32
|
//#endregion
|
|
33
33
|
//#region src/commands/archive.ts
|
|
34
|
-
function
|
|
35
|
-
let
|
|
36
|
-
if (!a
|
|
37
|
-
if (
|
|
38
|
-
|
|
34
|
+
function S(t, n) {
|
|
35
|
+
let r = e(t), i = m(t, r.paths.prds, `${n}.md`), a = m(t, r.paths.plans, `${n}.md`), l = m(t, r.paths.archives, n), p = o(i);
|
|
36
|
+
if (!o(a)) throw Error(`Plan "${n}" not found at ${a}`);
|
|
37
|
+
if (o(l)) throw Error(`Archive "${n}" already exists at ${l}`);
|
|
38
|
+
s(l, { recursive: !0 });
|
|
39
39
|
try {
|
|
40
|
-
let e = (/* @__PURE__ */ new Date()).toISOString(),
|
|
41
|
-
if (
|
|
42
|
-
let t =
|
|
43
|
-
t =
|
|
44
|
-
} else
|
|
45
|
-
let
|
|
46
|
-
return
|
|
40
|
+
let e = (/* @__PURE__ */ new Date()).toISOString(), t = [];
|
|
41
|
+
if (p) {
|
|
42
|
+
let t = c(i, "utf8");
|
|
43
|
+
t = x(t, "status", "done"), t = x(t, "completed", e), f(m(l, "prd.md"), t);
|
|
44
|
+
} else t.push(`Warning: PRD "${n}" missing, archiving plan only`);
|
|
45
|
+
let o = c(a, "utf8");
|
|
46
|
+
return o += `\n## Archived\n\nArchived on ${e.slice(0, 10)}.\n`, f(m(l, "plan.md"), o), p && d(i), d(a), t.push(`Archived "${n}" to ${r.paths.archives}/${n}/`), p && t.push(` prd.md — status: done, completed: ${e}`), t.push(" plan.md — archived block appended"), t;
|
|
47
47
|
} catch (e) {
|
|
48
|
-
throw l
|
|
48
|
+
throw u(l, {
|
|
49
49
|
recursive: !0,
|
|
50
50
|
force: !0
|
|
51
51
|
}), e;
|
|
@@ -53,11 +53,11 @@ function x(e, t) {
|
|
|
53
53
|
}
|
|
54
54
|
//#endregion
|
|
55
55
|
//#region src/plan.ts
|
|
56
|
-
var
|
|
57
|
-
function
|
|
56
|
+
var C = /^## (Phase \d+\s*.*)$/, w = /^- \[x\] /i, T = /^- \[ \] /;
|
|
57
|
+
function E(e) {
|
|
58
58
|
let t = e.replace(/\r\n/g, "\n").split("\n"), n = [], r = null;
|
|
59
59
|
for (let e of t) {
|
|
60
|
-
let t = e.trimStart(), i = t.match(
|
|
60
|
+
let t = e.trimStart(), i = t.match(C);
|
|
61
61
|
if (t.startsWith("## ")) {
|
|
62
62
|
i ? (r = {
|
|
63
63
|
title: i[1].trim(),
|
|
@@ -66,44 +66,44 @@ function T(e) {
|
|
|
66
66
|
}, n.push(r)) : r = null;
|
|
67
67
|
continue;
|
|
68
68
|
}
|
|
69
|
-
r && (
|
|
69
|
+
r && (w.test(t) ? (r.checked++, r.total++) : T.test(t) && r.total++);
|
|
70
70
|
}
|
|
71
71
|
return { phases: n };
|
|
72
72
|
}
|
|
73
73
|
//#endregion
|
|
74
74
|
//#region src/commands/brief.ts
|
|
75
|
-
var
|
|
76
|
-
function
|
|
75
|
+
var D = /^- \[ \] (.+)/;
|
|
76
|
+
function O(e, t) {
|
|
77
77
|
let n = new Date(e);
|
|
78
78
|
if (isNaN(n.getTime())) return "";
|
|
79
79
|
let r = Math.floor((t.getTime() - n.getTime()) / 864e5);
|
|
80
80
|
return r < 0 ? "" : r < 7 ? `${r}d` : r < 30 ? `${Math.floor(r / 7)}w` : `${Math.floor(r / 30)}mo`;
|
|
81
81
|
}
|
|
82
|
-
function
|
|
82
|
+
function k(e) {
|
|
83
83
|
for (let t of e.split("\n")) {
|
|
84
|
-
let e = t.trimStart().match(
|
|
84
|
+
let e = t.trimStart().match(D);
|
|
85
85
|
if (e) return e[1].replace(/\s*\[.*?\]\s*$/, "").trim();
|
|
86
86
|
}
|
|
87
87
|
return "—";
|
|
88
88
|
}
|
|
89
|
-
function
|
|
90
|
-
let
|
|
91
|
-
if (!
|
|
92
|
-
let
|
|
93
|
-
if (
|
|
94
|
-
let
|
|
95
|
-
for (let e of
|
|
96
|
-
let t = e.replace(/\.md$/, ""), n =
|
|
89
|
+
function A(t, n = /* @__PURE__ */ new Date()) {
|
|
90
|
+
let r = e(t), i = m(t, r.paths.prds);
|
|
91
|
+
if (!o(i)) return ["No features found — run `/tk:prd` to start one."];
|
|
92
|
+
let a = l(i).filter((e) => e.endsWith(".md")).sort();
|
|
93
|
+
if (a.length === 0) return ["No features found — run `/tk:prd` to start one."];
|
|
94
|
+
let s = m(t, r.paths.plans), u = [];
|
|
95
|
+
for (let e of a) {
|
|
96
|
+
let t = e.replace(/\.md$/, ""), n = b(c(m(i, e), "utf8"));
|
|
97
97
|
if (n.status === "done") continue;
|
|
98
|
-
let r = n.status || "unknown",
|
|
99
|
-
if (
|
|
100
|
-
let e =
|
|
101
|
-
r > 0 && (d = `${n}/${r}`), f =
|
|
98
|
+
let r = n.status || "unknown", a = n.created || "", l = a && !isNaN(new Date(a).getTime()) ? a : "", d = "—", f = "—", p = m(s, `${t}.md`);
|
|
99
|
+
if (o(p)) {
|
|
100
|
+
let e = c(p, "utf8"), { phases: t } = E(e), n = t.reduce((e, t) => e + t.checked, 0), r = t.reduce((e, t) => e + t.total, 0);
|
|
101
|
+
r > 0 && (d = `${n}/${r}`), f = k(e);
|
|
102
102
|
}
|
|
103
103
|
u.push({
|
|
104
104
|
slug: t,
|
|
105
105
|
status: r,
|
|
106
|
-
created:
|
|
106
|
+
created: l,
|
|
107
107
|
progress: d,
|
|
108
108
|
next: f
|
|
109
109
|
});
|
|
@@ -111,80 +111,83 @@ function k(e, t = /* @__PURE__ */ new Date()) {
|
|
|
111
111
|
if (u.length === 0) return ["No features found — run `/tk:prd` to start one."];
|
|
112
112
|
u.sort((e, t) => e.created && t.created ? new Date(e.created).getTime() - new Date(t.created).getTime() : e.created ? -1 : t.created ? 1 : 0);
|
|
113
113
|
let d = u.map((e) => {
|
|
114
|
-
let
|
|
115
|
-
return `| ${e.slug} | ${e.status} | ${
|
|
116
|
-
}), f = u.filter((e) => e.status === "in_progress"),
|
|
114
|
+
let t = e.created ? O(e.created, n) : "";
|
|
115
|
+
return `| ${e.slug} | ${e.status} | ${t} | ${e.progress} | ${e.next} |`;
|
|
116
|
+
}), f = u.filter((e) => e.status === "in_progress"), p = f.length === 1 ? f[0] : f[0] ?? u[0];
|
|
117
117
|
return [
|
|
118
118
|
"| Feature | Status | Age | Progress | Next |",
|
|
119
119
|
"|---------|--------|-----|----------|------|",
|
|
120
120
|
...d,
|
|
121
121
|
"",
|
|
122
|
-
`**Focus → ${
|
|
122
|
+
`**Focus → ${p.slug}**`
|
|
123
123
|
];
|
|
124
124
|
}
|
|
125
125
|
//#endregion
|
|
126
126
|
//#region src/commands/progress.ts
|
|
127
|
-
function
|
|
128
|
-
let
|
|
129
|
-
if (!
|
|
130
|
-
let { phases: i } =
|
|
127
|
+
function j(t, n) {
|
|
128
|
+
let r = m(t, e(t).paths.plans, `${n}.md`);
|
|
129
|
+
if (!o(r)) throw Error(`Plan "${n}" not found at ${r}`);
|
|
130
|
+
let { phases: i } = E(c(r, "utf8"));
|
|
131
131
|
if (i.length === 0) return ["No phases found in plan.", "Total: 0/0"];
|
|
132
|
-
let
|
|
133
|
-
for (let e of i)
|
|
134
|
-
return
|
|
132
|
+
let a = [], s = 0, l = 0;
|
|
133
|
+
for (let e of i) s += e.checked, l += e.total, a.push(` ${e.title}: ${e.checked}/${e.total}`);
|
|
134
|
+
return a.push(""), a.push(`Total: ${s}/${l}`), a;
|
|
135
135
|
}
|
|
136
136
|
//#endregion
|
|
137
137
|
//#region src/cli.ts
|
|
138
|
-
var { version:
|
|
138
|
+
var { version: M } = JSON.parse(c(h(p(g(import.meta.url)), "..", "package.json"), "utf8")), N = Math.max(...t.map((e) => `${e.name} ${e.args}`.length)), P = [
|
|
139
139
|
"Usage: tracerkit <command> [path]",
|
|
140
140
|
"",
|
|
141
141
|
"Commands:",
|
|
142
|
-
...
|
|
142
|
+
...t.map((e) => ` ${`${e.name} ${e.args}`.padEnd(N + 2)}${e.desc}`),
|
|
143
143
|
"",
|
|
144
144
|
"Options:",
|
|
145
|
-
" --force
|
|
145
|
+
" --force init: replace all skills; update: overwrite modified files",
|
|
146
146
|
" --help, -h Show this help message",
|
|
147
147
|
" --version, -v Print version",
|
|
148
148
|
"",
|
|
149
149
|
"All commands default to the home directory when no path is given."
|
|
150
150
|
];
|
|
151
|
-
function
|
|
151
|
+
function F(e, t = _()) {
|
|
152
152
|
let n = e.find((e) => !e.startsWith("-"));
|
|
153
|
-
return n ?
|
|
153
|
+
return n ? h(n) : t;
|
|
154
154
|
}
|
|
155
|
-
function
|
|
155
|
+
function I(e, t) {
|
|
156
156
|
let n = e.findIndex((e) => !e.startsWith("-"));
|
|
157
157
|
if (n === -1) return [
|
|
158
158
|
"Error: missing <slug> argument",
|
|
159
159
|
"",
|
|
160
|
-
...
|
|
160
|
+
...P
|
|
161
161
|
];
|
|
162
162
|
let r = e[n], i = e.filter((e, t) => t !== n);
|
|
163
163
|
try {
|
|
164
|
-
return t(
|
|
164
|
+
return t(F(i, process.cwd()), r);
|
|
165
165
|
} catch (e) {
|
|
166
166
|
return [`Error: ${e instanceof Error ? e.message : String(e)}`];
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
|
-
function
|
|
170
|
-
if (e.includes(
|
|
171
|
-
if (e.includes(
|
|
172
|
-
let
|
|
173
|
-
switch (
|
|
174
|
-
case "brief": return
|
|
175
|
-
case "init":
|
|
169
|
+
function L(e) {
|
|
170
|
+
if (e.includes(r.help) || e.includes("-h")) return P;
|
|
171
|
+
if (e.includes(r.version) || e.includes("-v")) return [`tracerkit/${M}`];
|
|
172
|
+
let t = e[0], o = e.slice(1);
|
|
173
|
+
switch (t) {
|
|
174
|
+
case "brief": return A(F(o, process.cwd()));
|
|
175
|
+
case "init": {
|
|
176
|
+
let e = o.includes(r.force);
|
|
177
|
+
return i(F(o.filter((e) => e !== r.force)), { force: e });
|
|
178
|
+
}
|
|
176
179
|
case "update": {
|
|
177
|
-
let e =
|
|
178
|
-
return
|
|
180
|
+
let e = o.includes(r.force), t = n(F(o.filter((e) => e !== r.force)), { force: e });
|
|
181
|
+
return t.push("", "Updated to the latest TracerKit."), t.push("If using Claude Code, restart your session to load changes."), t;
|
|
179
182
|
}
|
|
180
|
-
case "uninstall": return
|
|
181
|
-
case "progress": return
|
|
182
|
-
case "archive": return
|
|
183
|
-
default: return
|
|
183
|
+
case "uninstall": return a(F(o));
|
|
184
|
+
case "progress": return I(o, j);
|
|
185
|
+
case "archive": return I(o, S);
|
|
186
|
+
default: return P;
|
|
184
187
|
}
|
|
185
188
|
}
|
|
186
189
|
//#endregion
|
|
187
190
|
//#region src/bin.ts
|
|
188
|
-
var
|
|
189
|
-
for (let e of
|
|
191
|
+
var R = L(process.argv.slice(2));
|
|
192
|
+
for (let e of R) console.log(e);
|
|
190
193
|
//#endregion
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, i as t, n,
|
|
2
|
-
export { t as COMMANDS, e as DEPRECATED_SKILLS,
|
|
1
|
+
import { a as e, i as t, n, r, s as i, t as a } from "./uninstall-BP2pCnBW.js";
|
|
2
|
+
export { t as COMMANDS, e as DEPRECATED_SKILLS, i as SKILL_NAMES, r as init, a as uninstall, n as update };
|
|
@@ -29,7 +29,11 @@ var f = [
|
|
|
29
29
|
"tk:prd",
|
|
30
30
|
"tk:plan",
|
|
31
31
|
"tk:check"
|
|
32
|
-
], p = ["tk:verify"], m =
|
|
32
|
+
], p = ["tk:verify"], m = {
|
|
33
|
+
force: "--force",
|
|
34
|
+
help: "--help",
|
|
35
|
+
version: "--version"
|
|
36
|
+
}, h = [
|
|
33
37
|
{
|
|
34
38
|
name: "init",
|
|
35
39
|
args: "[path]",
|
|
@@ -60,37 +64,37 @@ var f = [
|
|
|
60
64
|
args: "<slug>",
|
|
61
65
|
desc: "Archive a completed feature (PRD + plan)"
|
|
62
66
|
}
|
|
63
|
-
],
|
|
64
|
-
function
|
|
67
|
+
], g = s(o(l(import.meta.url)), "..", "templates");
|
|
68
|
+
function _(e, t = "") {
|
|
65
69
|
let n = r(e, { withFileTypes: !0 }), i = [];
|
|
66
70
|
for (let r of n) {
|
|
67
71
|
let n = t ? `${t}/${r.name}` : r.name;
|
|
68
|
-
r.isDirectory() ? i.push(...
|
|
72
|
+
r.isDirectory() ? i.push(..._(s(e, r.name), n)) : i.push(n);
|
|
69
73
|
}
|
|
70
74
|
return i.sort();
|
|
71
75
|
}
|
|
72
|
-
function
|
|
76
|
+
function v(e, t) {
|
|
73
77
|
return e.replaceAll("{{paths.prds}}", t.paths.prds).replaceAll("{{paths.plans}}", t.paths.plans).replaceAll("{{paths.archives}}", t.paths.archives);
|
|
74
78
|
}
|
|
75
|
-
function
|
|
76
|
-
let c = i ?? g
|
|
79
|
+
function y(e, r, i) {
|
|
80
|
+
let c = i ?? _(g);
|
|
77
81
|
for (let i of c) {
|
|
78
|
-
let c = s(
|
|
79
|
-
t(o(l), { recursive: !0 }), a(l,
|
|
82
|
+
let c = s(g, i), l = s(e, i);
|
|
83
|
+
t(o(l), { recursive: !0 }), a(l, v(n(c, "utf8"), r));
|
|
80
84
|
}
|
|
81
85
|
return { copied: c };
|
|
82
86
|
}
|
|
83
|
-
function
|
|
87
|
+
function b(e) {
|
|
84
88
|
return c("sha256").update(e).digest("hex");
|
|
85
89
|
}
|
|
86
|
-
function
|
|
87
|
-
let i = g
|
|
90
|
+
function x(t, r) {
|
|
91
|
+
let i = _(g), a = [], o = [], c = [];
|
|
88
92
|
for (let l of i) {
|
|
89
93
|
let i = s(t, l);
|
|
90
94
|
if (!e(i)) c.push(l);
|
|
91
95
|
else {
|
|
92
|
-
let e =
|
|
93
|
-
|
|
96
|
+
let e = v(n(s(g, l), "utf8"), r);
|
|
97
|
+
b(Buffer.from(e)) === b(n(i)) ? a.push(l) : o.push(l);
|
|
94
98
|
}
|
|
95
99
|
}
|
|
96
100
|
return {
|
|
@@ -101,16 +105,19 @@ function b(t, r) {
|
|
|
101
105
|
}
|
|
102
106
|
//#endregion
|
|
103
107
|
//#region src/commands/init.ts
|
|
104
|
-
function
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
function S(t, n) {
|
|
109
|
+
let r = n?.force ?? !1;
|
|
110
|
+
if (!r) {
|
|
111
|
+
for (let n of f) if (e(s(t, ".claude", "skills", n))) throw Error(`.claude/skills/${n}/ already exists — run \`tracerkit update\` to add new skills, or \`tracerkit init --force\` to replace all skills`);
|
|
112
|
+
}
|
|
113
|
+
let { copied: i } = y(t, d(t));
|
|
114
|
+
return i.map((e) => `✓ ${e}${r ? " (replaced)" : ""}`);
|
|
108
115
|
}
|
|
109
116
|
//#endregion
|
|
110
117
|
//#region src/commands/update.ts
|
|
111
|
-
function
|
|
118
|
+
function C(t, n) {
|
|
112
119
|
if (!f.some((n) => e(s(t, ".claude", "skills", n)))) throw Error("TracerKit not initialized — run `tracerkit init` first");
|
|
113
|
-
let r = d(t), { unchanged: a, modified: o, missing: c } =
|
|
120
|
+
let r = d(t), { unchanged: a, modified: o, missing: c } = x(t, r), l = [];
|
|
114
121
|
for (let n of p) {
|
|
115
122
|
let r = s(t, ".claude", "skills", n);
|
|
116
123
|
e(r) && (i(r, {
|
|
@@ -124,7 +131,7 @@ function S(t, n) {
|
|
|
124
131
|
...u ? o : []
|
|
125
132
|
];
|
|
126
133
|
if (m.length > 0) {
|
|
127
|
-
|
|
134
|
+
y(t, r, m);
|
|
128
135
|
for (let e of a) l.push(`✓ ${e}`);
|
|
129
136
|
for (let e of c) l.push(`✓ ${e} (added)`);
|
|
130
137
|
if (u) for (let e of o) l.push(`✓ ${e} (replaced)`);
|
|
@@ -137,7 +144,7 @@ function S(t, n) {
|
|
|
137
144
|
}
|
|
138
145
|
//#endregion
|
|
139
146
|
//#region src/commands/uninstall.ts
|
|
140
|
-
function
|
|
147
|
+
function w(t) {
|
|
141
148
|
if (!f.some((n) => e(s(t, ".claude", "skills", n)))) throw Error("TracerKit not initialized — nothing to uninstall");
|
|
142
149
|
let n = [];
|
|
143
150
|
for (let r of f) {
|
|
@@ -150,4 +157,4 @@ function C(t) {
|
|
|
150
157
|
return n;
|
|
151
158
|
}
|
|
152
159
|
//#endregion
|
|
153
|
-
export { p as a,
|
|
160
|
+
export { p as a, d as c, h as i, C as n, m as o, S as r, f as s, w as t };
|