@dealdeploy/skl 1.7.0 → 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/index.ts CHANGED
@@ -101,13 +101,17 @@ const renderer = await createCliRenderer({
101
101
  const allSkills = getCatalogSkills();
102
102
  const lock = readLock();
103
103
  const skillRepos = new Map<string, string | null>();
104
+ const skillDates = new Map<string, string | null>();
104
105
  for (const name of allSkills) {
105
- skillRepos.set(name, lock.skills[name]?.source || null);
106
+ const entry = lock.skills[name];
107
+ skillRepos.set(name, entry?.source || null);
108
+ skillDates.set(name, entry?.updatedAt || entry?.addedAt || null);
106
109
  }
107
110
 
108
111
  tui = createTui(renderer, {
109
112
  allSkills,
110
113
  skillRepos,
114
+ skillDates,
111
115
  globalInstalled,
112
116
  localInstalled,
113
117
  catalogPath: CATALOG,
package/lib.ts CHANGED
@@ -20,6 +20,7 @@ export type LockEntry = {
20
20
  skillPath: string;
21
21
  treeSHA: string;
22
22
  addedAt: string;
23
+ updatedAt?: string;
23
24
  };
24
25
 
25
26
  export type LockFile = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dealdeploy/skl",
3
- "version": "1.7.0",
3
+ "version": "1.9.0",
4
4
  "description": "TUI skill manager for Claude Code agents",
5
5
  "module": "index.ts",
6
6
  "bin": {
package/tui.test.ts CHANGED
@@ -16,6 +16,7 @@ function setup(opts?: {
16
16
  }) {
17
17
  const skills = opts?.skills ?? ["alpha", "beta", "gamma"];
18
18
  const skillRepos = opts?.skillRepos ?? new Map(skills.map((s) => [s, null]));
19
+ const skillDates = new Map<string, string | null>(skills.map((s) => [s, null]));
19
20
  const globalInstalled = new Set(opts?.globalInstalled ?? []);
20
21
  const localInstalled = new Set(opts?.localInstalled ?? []);
21
22
 
@@ -43,6 +44,7 @@ function setup(opts?: {
43
44
  return {
44
45
  allSkills: skills,
45
46
  skillRepos,
47
+ skillDates,
46
48
  globalInstalled,
47
49
  localInstalled,
48
50
  catalogPath: "/tmp/test-catalog",
@@ -68,6 +70,7 @@ function setup(opts?: {
68
70
  return {
69
71
  allSkills: skills,
70
72
  skillRepos,
73
+ skillDates,
71
74
  globalInstalled,
72
75
  localInstalled,
73
76
  catalogPath: "/tmp/test-catalog",
package/tui.ts CHANGED
@@ -15,6 +15,7 @@ export type ColId = "global" | "local";
15
15
  export type TuiDeps = {
16
16
  allSkills: string[];
17
17
  skillRepos: Map<string, string | null>;
18
+ skillDates: Map<string, string | null>;
18
19
  globalInstalled: Set<string>;
19
20
  localInstalled: Set<string>;
20
21
  catalogPath: string;
@@ -49,6 +50,21 @@ export function createTui(renderer: CliRenderer, deps: TuiDeps) {
49
50
  return `${text.slice(0, max - 1)}\u2026`;
50
51
  }
51
52
 
53
+ function relativeDate(iso: string): string {
54
+ const ms = Date.now() - new Date(iso).getTime();
55
+ if (ms < 0) return "just now";
56
+ const mins = Math.floor(ms / 60000);
57
+ if (mins < 1) return "just now";
58
+ if (mins < 60) return `${mins}m ago`;
59
+ const hrs = Math.floor(mins / 60);
60
+ if (hrs < 24) return `${hrs}h ago`;
61
+ const days = Math.floor(hrs / 24);
62
+ if (days < 30) return `${days}d ago`;
63
+ const months = Math.floor(days / 30);
64
+ if (months < 12) return `${months}mo ago`;
65
+ return `${Math.floor(months / 12)}y ago`;
66
+ }
67
+
52
68
  // ── Build display list ─────────────────────────────────────────────
53
69
 
54
70
  const displayItems: DisplayItem[] = [];
@@ -178,12 +194,14 @@ export function createTui(renderer: CliRenderer, deps: TuiDeps) {
178
194
  });
179
195
 
180
196
  let COL_W = 14;
197
+ let DATE_W = 10;
181
198
  let NAME_W = 34;
182
199
 
183
200
  function calcWidths() {
184
201
  const w = (renderer as any).width ?? process.stdout.columns ?? 80;
185
202
  COL_W = Math.max(5, Math.min(14, Math.floor((w - 20) / 2)));
186
- NAME_W = Math.min(40, Math.max(15, w - COL_W * 2 - 1));
203
+ DATE_W = 10;
204
+ NAME_W = Math.min(40, Math.max(15, w - COL_W * 2 - DATE_W - 1));
187
205
  }
188
206
  calcWidths();
189
207
 
@@ -208,10 +226,18 @@ export function createTui(renderer: CliRenderer, deps: TuiDeps) {
208
226
  attributes: TextAttributes.BOLD,
209
227
  width: COL_W,
210
228
  });
229
+ const colUpdated = new TextRenderable(renderer, {
230
+ id: "col-updated",
231
+ content: "Updated",
232
+ fg: C.fgDim,
233
+ attributes: TextAttributes.BOLD,
234
+ width: DATE_W,
235
+ });
211
236
 
212
237
  colHeaderRow.add(colName);
213
238
  colHeaderRow.add(colGlobal);
214
239
  colHeaderRow.add(colLocal);
240
+ colHeaderRow.add(colUpdated);
215
241
 
216
242
  const sep = new TextRenderable(renderer, {
217
243
  id: "sep",
@@ -235,6 +261,7 @@ export function createTui(renderer: CliRenderer, deps: TuiDeps) {
235
261
  nameText: TextRenderable;
236
262
  globalText: TextRenderable;
237
263
  localText: TextRenderable;
264
+ dateText: TextRenderable;
238
265
  };
239
266
  const rows: RowRefs[] = new Array(allSkills.length);
240
267
 
@@ -262,7 +289,7 @@ export function createTui(renderer: CliRenderer, deps: TuiDeps) {
262
289
  id: `header-text-${di}`,
263
290
  content: ` ${item.repo}`,
264
291
  fg: C.fgDim,
265
- width: NAME_W + COL_W * 2,
292
+ width: NAME_W + COL_W * 2 + DATE_W,
266
293
  });
267
294
  hRow.add(hText);
268
295
  scrollBox.add(hRow);
@@ -301,11 +328,20 @@ export function createTui(renderer: CliRenderer, deps: TuiDeps) {
301
328
  width: COL_W,
302
329
  });
303
330
 
331
+ const dateStr = deps.skillDates.get(skill);
332
+ const dateText = new TextRenderable(renderer, {
333
+ id: `date-${i}`,
334
+ content: dateStr ? relativeDate(dateStr) : "",
335
+ fg: C.fgDim,
336
+ width: DATE_W,
337
+ });
338
+
304
339
  row.add(nameText);
305
340
  row.add(globalText);
306
341
  row.add(localText);
342
+ row.add(dateText);
307
343
  scrollBox.add(row);
308
- rows[i] = { row, nameText, globalText, localText };
344
+ rows[i] = { row, nameText, globalText, localText, dateText };
309
345
  }
310
346
  }
311
347
 
@@ -445,14 +481,16 @@ export function createTui(renderer: CliRenderer, deps: TuiDeps) {
445
481
  colName.width = NAME_W;
446
482
  colGlobal.width = COL_W;
447
483
  colLocal.width = COL_W;
484
+ colUpdated.width = DATE_W;
448
485
  for (let i = 0; i < allSkills.length; i++) {
449
486
  const r = rows[i]!;
450
487
  r.nameText.width = NAME_W;
451
488
  r.globalText.width = COL_W;
452
489
  r.localText.width = COL_W;
490
+ r.dateText.width = DATE_W;
453
491
  }
454
492
  for (const [, ref] of headerRefs) {
455
- ref.text.width = NAME_W + COL_W * 2;
493
+ ref.text.width = NAME_W + COL_W * 2 + DATE_W;
456
494
  }
457
495
  }
458
496
 
package/update.ts CHANGED
@@ -89,6 +89,7 @@ for (const [repo, skills] of byRepo) {
89
89
  const fileCount = await downloadSkillFiles(repo, branch, skill.skillPath, skillDir, tree);
90
90
 
91
91
  lock.skills[skill.name]!.treeSHA = skill.newSHA;
92
+ lock.skills[skill.name]!.updatedAt = new Date().toISOString();
92
93
  console.log(` updated (${fileCount} files)`);
93
94
  totalUpdated++;
94
95
  }