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 CHANGED
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import { i as e, n as t, r as n, s as r, t as i } from "./uninstall-DO2YpTSz.js";
3
- import { existsSync as a, mkdirSync as o, readFileSync as s, readdirSync as c, rmSync as l, unlinkSync as u, writeFileSync as d } from "node:fs";
4
- import { dirname as f, join as p, resolve as m } from "node:path";
5
- import { fileURLToPath as h } from "node:url";
6
- import { homedir as g } from "node:os";
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 _ = /^---\n([\s\S]*?)\n---(?:\n|$)/;
9
- function v(e) {
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 y(e) {
13
- let t = v(e).match(_);
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 b(e, t, n) {
25
- let r = v(e), i = r.match(_);
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 x(e, t) {
35
- let n = r(e), i = p(e, n.paths.prds, `${t}.md`), c = p(e, n.paths.plans, `${t}.md`), f = p(e, n.paths.archives, t), m = a(i);
36
- if (!a(c)) throw Error(`Plan "${t}" not found at ${c}`);
37
- if (a(f)) throw Error(`Archive "${t}" already exists at ${f}`);
38
- o(f, { recursive: !0 });
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(), r = [];
41
- if (m) {
42
- let t = s(i, "utf8");
43
- t = b(t, "status", "done"), t = b(t, "completed", e), d(p(f, "prd.md"), t);
44
- } else r.push(`Warning: PRD "${t}" missing, archiving plan only`);
45
- let a = s(c, "utf8");
46
- return a += `\n## Archived\n\nArchived on ${e.slice(0, 10)}.\n`, d(p(f, "plan.md"), a), m && u(i), u(c), r.push(`Archived "${t}" to ${n.paths.archives}/${t}/`), m && r.push(` prd.md — status: done, completed: ${e}`), r.push(" plan.md — archived block appended"), r;
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(f, {
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 S = /^## (Phase \d+\s*.*)$/, C = /^- \[x\] /i, w = /^- \[ \] /;
57
- function T(e) {
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(S);
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 && (C.test(t) ? (r.checked++, r.total++) : w.test(t) && r.total++);
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 E = /^- \[ \] (.+)/;
76
- function D(e, t) {
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 O(e) {
82
+ function k(e) {
83
83
  for (let t of e.split("\n")) {
84
- let e = t.trimStart().match(E);
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 k(e, t = /* @__PURE__ */ new Date()) {
90
- let n = r(e), i = p(e, n.paths.prds);
91
- if (!a(i)) return ["No features found — run `/tk:prd` to start one."];
92
- let o = c(i).filter((e) => e.endsWith(".md")).sort();
93
- if (o.length === 0) return ["No features found — run `/tk:prd` to start one."];
94
- let l = p(e, n.paths.plans), u = [];
95
- for (let e of o) {
96
- let t = e.replace(/\.md$/, ""), n = y(s(p(i, e), "utf8"));
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", o = n.created || "", c = o && !isNaN(new Date(o).getTime()) ? o : "", d = "—", f = "—", m = p(l, `${t}.md`);
99
- if (a(m)) {
100
- let e = s(m, "utf8"), { phases: t } = T(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 = O(e);
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: c,
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 n = e.created ? D(e.created, t) : "";
115
- return `| ${e.slug} | ${e.status} | ${n} | ${e.progress} | ${e.next} |`;
116
- }), f = u.filter((e) => e.status === "in_progress"), m = f.length === 1 ? f[0] : f[0] ?? u[0];
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 → ${m.slug}**`
122
+ `**Focus → ${p.slug}**`
123
123
  ];
124
124
  }
125
125
  //#endregion
126
126
  //#region src/commands/progress.ts
127
- function A(e, t) {
128
- let n = p(e, r(e).paths.plans, `${t}.md`);
129
- if (!a(n)) throw Error(`Plan "${t}" not found at ${n}`);
130
- let { phases: i } = T(s(n, "utf8"));
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 o = [], c = 0, l = 0;
133
- for (let e of i) c += e.checked, l += e.total, o.push(` ${e.title}: ${e.checked}/${e.total}`);
134
- return o.push(""), o.push(`Total: ${c}/${l}`), o;
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: j } = JSON.parse(s(m(f(h(import.meta.url)), "..", "package.json"), "utf8")), M = Math.max(...e.map((e) => `${e.name} ${e.args}`.length)), N = [
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
- ...e.map((e) => ` ${`${e.name} ${e.args}`.padEnd(M + 2)}${e.desc}`),
142
+ ...t.map((e) => ` ${`${e.name} ${e.args}`.padEnd(N + 2)}${e.desc}`),
143
143
  "",
144
144
  "Options:",
145
- " --force Overwrite modified files during update",
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 P(e, t = g()) {
151
+ function F(e, t = _()) {
152
152
  let n = e.find((e) => !e.startsWith("-"));
153
- return n ? m(n) : t;
153
+ return n ? h(n) : t;
154
154
  }
155
- function F(e, t) {
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
- ...N
160
+ ...P
161
161
  ];
162
162
  let r = e[n], i = e.filter((e, t) => t !== n);
163
163
  try {
164
- return t(P(i, process.cwd()), r);
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 I(e) {
170
- if (e.includes("--help") || e.includes("-h")) return N;
171
- if (e.includes("--version") || e.includes("-v")) return [`tracerkit/${j}`];
172
- let r = e[0], a = e.slice(1);
173
- switch (r) {
174
- case "brief": return k(P(a, process.cwd()));
175
- case "init": return n(P(a));
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 = a.includes("--force"), n = t(P(a.filter((e) => e !== "--force")), { force: e });
178
- return n.push("", "Updated to the latest TracerKit."), n.push("If using Claude Code, restart your session to load changes."), n;
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 i(P(a));
181
- case "progress": return F(a, A);
182
- case "archive": return F(a, x);
183
- default: return N;
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 L = I(process.argv.slice(2));
189
- for (let e of L) console.log(e);
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, o as r, r as i, t as a } from "./uninstall-DO2YpTSz.js";
2
- export { t as COMMANDS, e as DEPRECATED_SKILLS, r as SKILL_NAMES, i as init, a as uninstall, n as update };
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
- ], h = s(o(l(import.meta.url)), "..", "templates");
64
- function g(e, t = "") {
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(...g(s(e, r.name), n)) : i.push(n);
72
+ r.isDirectory() ? i.push(..._(s(e, r.name), n)) : i.push(n);
69
73
  }
70
74
  return i.sort();
71
75
  }
72
- function _(e, t) {
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 v(e, r, i) {
76
- let c = i ?? g(h);
79
+ function y(e, r, i) {
80
+ let c = i ?? _(g);
77
81
  for (let i of c) {
78
- let c = s(h, i), l = s(e, i);
79
- t(o(l), { recursive: !0 }), a(l, _(n(c, "utf8"), r));
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 y(e) {
87
+ function b(e) {
84
88
  return c("sha256").update(e).digest("hex");
85
89
  }
86
- function b(t, r) {
87
- let i = g(h), a = [], o = [], c = [];
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 = _(n(s(h, l), "utf8"), r);
93
- y(Buffer.from(e)) === y(n(i)) ? a.push(l) : o.push(l);
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 x(t) {
105
- for (let n of f) if (e(s(t, ".claude", "skills", n))) throw Error(`.claude/skills/${n}/ already exists — aborting`);
106
- let { copied: n } = v(t, d(t));
107
- return n.map((e) => `✓ ${e}`);
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 S(t, n) {
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 } = b(t, r), l = [];
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
- v(t, r, m);
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 C(t) {
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, m as i, S as n, f as o, x as r, d as s, C as t };
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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tracerkit",
3
- "version": "1.8.2",
3
+ "version": "1.9.0",
4
4
  "description": "Spec-driven workflow for Claude Code: replace ad-hoc prompts with PRD → plan → verify.",
5
5
  "license": "MIT",
6
6
  "author": {