claude-alfred 0.3.1 → 0.3.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.
Files changed (38) hide show
  1. package/dist/{audit-BrTztz4z.mjs → audit-6NSlW0Ut.mjs} +1 -1
  2. package/dist/cli.mjs +3 -3
  3. package/dist/{directives-iFMV2Mmx.mjs → directives-ko2sX5BW.mjs} +1 -1
  4. package/dist/{dispatcher-xZAhoK7h.mjs → dispatcher-BnBtA4bo.mjs} +7 -7
  5. package/dist/{fts-CDEAxhSV.mjs → fts-QWdC_4Zv.mjs} +2 -2
  6. package/dist/{helpers-DVDJYnXA.mjs → helpers-BnPVn8Nv.mjs} +3 -3
  7. package/dist/{knowledge-DItYbraO.mjs → knowledge-B0fsJ9SI.mjs} +16 -2
  8. package/dist/{post-tool-G2PAotAa.mjs → post-tool-gG8qG5Ee.mjs} +5 -5
  9. package/dist/{pre-compact-CyNPLjSK.mjs → pre-compact-CwvBi5op.mjs} +3 -3
  10. package/dist/{pre-tool-B_CYjJPV.mjs → pre-tool-BMCYjtHT.mjs} +2 -2
  11. package/dist/{server-23A-5yhs.mjs → server-CHdcikXe.mjs} +6 -6
  12. package/dist/{server-Dfefx0Gm.mjs → server-Df8fib2F.mjs} +75 -57
  13. package/dist/{session-start-D177nOGO.mjs → session-start-dPl4lfZw.mjs} +13 -4
  14. package/dist/{spec-guard-YaW8olGC.mjs → spec-guard-BGwtCxgH.mjs} +1 -1
  15. package/dist/{stop-uQEMYJUS.mjs → stop-NL5GdPNy.mjs} +2 -2
  16. package/dist/{user-prompt-X18njRds.mjs → user-prompt-o9rlzB2I.mjs} +5 -5
  17. package/dist/{vectors-C_Yj-4sR.mjs → vectors-BDQP0gaa.mjs} +1 -1
  18. package/package.json +1 -1
  19. package/web/dist/assets/{activity-BEGGrVcS.js → activity-mXF0VmCt.js} +1 -1
  20. package/web/dist/assets/{button-DnlE4Vv_.js → button-CBPUE5Y6.js} +1 -1
  21. package/web/dist/assets/index-CNTBHHOa.js +10 -0
  22. package/web/dist/assets/{index-BeDDkww-.css → index-uhr7UtxX.css} +1 -1
  23. package/web/dist/assets/{knowledge-d1qgwDQ0.js → knowledge-wd_PIN8X.js} +1 -1
  24. package/web/dist/assets/routes-DUyvG12-.js +1 -0
  25. package/web/dist/assets/tasks-pPCS6lSa.js +1 -0
  26. package/web/dist/assets/{tasks._slug-GHRGy5XE.js → tasks._slug-C-Z_7eYZ.js} +2 -2
  27. package/web/dist/assets/useParams-CJl-SvaR.js +1 -0
  28. package/web/dist/index.html +3 -3
  29. package/web/dist/assets/circle-D8Rr9amD.js +0 -1
  30. package/web/dist/assets/index-DRPc84bA.js +0 -10
  31. package/web/dist/assets/matchContext-Dst1Emk1.js +0 -1
  32. package/web/dist/assets/routes-DuxHjsHU.js +0 -1
  33. package/web/dist/assets/tasks-BVHxHTf5.js +0 -1
  34. /package/web/dist/assets/{badge-CBVw5E1L.js → badge-CBFM8JtH.js} +0 -0
  35. /package/web/dist/assets/{dist--KR51Ecg.js → dist-7qozDZTq.js} +0 -0
  36. /package/web/dist/assets/{progress-CokWPQNM.js → progress-B0hcYV7D.js} +0 -0
  37. /package/web/dist/assets/{separator-DgaTFrP0.js → separator-0fdLqhBM.js} +0 -0
  38. /package/web/dist/assets/{skeleton-BjX-jJYO.js → skeleton-CLJEM3zd.js} +0 -0
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { E as require_dist, S as rootDir, m as VALID_SLUG } from "./knowledge-DItYbraO.mjs";
2
+ import { C as rootDir, D as require_dist, h as VALID_SLUG } from "./knowledge-B0fsJ9SI.mjs";
3
3
  import { appendFileSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  //#region src/epic/index.ts
package/dist/cli.mjs CHANGED
@@ -371,7 +371,7 @@ const main = defineCommand({
371
371
  async run() {
372
372
  const { Store } = await import("./store-CuN3_dWu.mjs");
373
373
  const { Embedder } = await import("./embedder-BRG2Xpr4.mjs");
374
- const { serveMCP } = await import("./server-23A-5yhs.mjs");
374
+ const { serveMCP } = await import("./server-CHdcikXe.mjs");
375
375
  const store = Store.openDefault();
376
376
  let emb = null;
377
377
  try {
@@ -399,7 +399,7 @@ const main = defineCommand({
399
399
  async run({ args }) {
400
400
  const { Store } = await import("./store-CuN3_dWu.mjs");
401
401
  const { Embedder } = await import("./embedder-BRG2Xpr4.mjs");
402
- const { startDashboard } = await import("./server-Dfefx0Gm.mjs");
402
+ const { startDashboard } = await import("./server-Df8fib2F.mjs");
403
403
  const projectPath = process.cwd();
404
404
  const store = Store.openDefault();
405
405
  let emb = null;
@@ -422,7 +422,7 @@ const main = defineCommand({
422
422
  description: "Event name"
423
423
  } },
424
424
  async run({ args }) {
425
- const { runHook } = await import("./dispatcher-xZAhoK7h.mjs").then((n) => n.t);
425
+ const { runHook } = await import("./dispatcher-BnBtA4bo.mjs").then((n) => n.t);
426
426
  await runHook(args.event);
427
427
  }
428
428
  }),
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as emitAdditionalContext } from "./dispatcher-xZAhoK7h.mjs";
2
+ import { n as emitAdditionalContext } from "./dispatcher-BnBtA4bo.mjs";
3
3
  //#region src/hooks/directives.ts
4
4
  const LEVEL_ORDER = {
5
5
  DIRECTIVE: 0,
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { O as __exportAll } from "./knowledge-DItYbraO.mjs";
2
+ import { k as __exportAll } from "./knowledge-B0fsJ9SI.mjs";
3
3
  import { resolve } from "node:path";
4
4
  //#region src/hooks/dispatcher.ts
5
5
  var dispatcher_exports = /* @__PURE__ */ __exportAll({
@@ -89,27 +89,27 @@ async function runHook(event) {
89
89
  }
90
90
  }
91
91
  async function handleSessionStart(ev, signal) {
92
- const { sessionStart } = await import("./session-start-D177nOGO.mjs");
92
+ const { sessionStart } = await import("./session-start-dPl4lfZw.mjs");
93
93
  await sessionStart(ev, signal);
94
94
  }
95
95
  async function handlePreCompact(ev, signal) {
96
- const { preCompact } = await import("./pre-compact-CyNPLjSK.mjs");
96
+ const { preCompact } = await import("./pre-compact-CwvBi5op.mjs");
97
97
  await preCompact(ev, signal);
98
98
  }
99
99
  async function handleUserPromptSubmit(ev, signal) {
100
- const { userPromptSubmit } = await import("./user-prompt-X18njRds.mjs");
100
+ const { userPromptSubmit } = await import("./user-prompt-o9rlzB2I.mjs");
101
101
  await userPromptSubmit(ev, signal);
102
102
  }
103
103
  async function handlePostToolUse(ev, signal) {
104
- const { postToolUse } = await import("./post-tool-G2PAotAa.mjs");
104
+ const { postToolUse } = await import("./post-tool-gG8qG5Ee.mjs");
105
105
  await postToolUse(ev, signal);
106
106
  }
107
107
  async function handlePreToolUse(ev, _signal) {
108
- const { preToolUse } = await import("./pre-tool-B_CYjJPV.mjs");
108
+ const { preToolUse } = await import("./pre-tool-BMCYjtHT.mjs");
109
109
  await preToolUse(ev);
110
110
  }
111
111
  async function handleStop(ev, _signal) {
112
- const { stop } = await import("./stop-uQEMYJUS.mjs");
112
+ const { stop } = await import("./stop-NL5GdPNy.mjs");
113
113
  await stop(ev);
114
114
  }
115
115
  //#endregion
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { c as mapRow, r as getKnowledgeByIDs, u as searchKnowledgeKeyword } from "./knowledge-DItYbraO.mjs";
3
- import { n as deserializeFloat32, t as cosineSimilarity } from "./vectors-C_Yj-4sR.mjs";
2
+ import { d as searchKnowledgeKeyword, i as getKnowledgeByIDs, l as mapRow } from "./knowledge-B0fsJ9SI.mjs";
3
+ import { n as deserializeFloat32, t as cosineSimilarity } from "./vectors-BDQP0gaa.mjs";
4
4
  //#region src/store/fts.ts
5
5
  function subTypeHalfLife(subType) {
6
6
  switch (subType) {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { r as getKnowledgeByIDs, s as incrementHitCount, u as searchKnowledgeKeyword } from "./knowledge-DItYbraO.mjs";
3
- import { r as vectorSearchKnowledge } from "./vectors-C_Yj-4sR.mjs";
4
- import { i as subTypeHalfLife, n as searchKnowledgeFTS, r as subTypeBoost } from "./fts-CDEAxhSV.mjs";
2
+ import { c as incrementHitCount, d as searchKnowledgeKeyword, i as getKnowledgeByIDs } from "./knowledge-B0fsJ9SI.mjs";
3
+ import { r as vectorSearchKnowledge } from "./vectors-BDQP0gaa.mjs";
4
+ import { i as subTypeHalfLife, n as searchKnowledgeFTS, r as subTypeBoost } from "./fts-QWdC_4Zv.mjs";
5
5
  //#region src/mcp/helpers.ts
6
6
  const RECENCY_FLOOR = .5;
7
7
  function truncate(s, maxLen) {
@@ -6753,7 +6753,7 @@ function readActiveState(projectPath) {
6753
6753
  }
6754
6754
  try {
6755
6755
  const state = (0, import_dist.parse)(data);
6756
- if (state?.primary) return state;
6756
+ if (state?.primary != null || state?.tasks) return state;
6757
6757
  } catch {}
6758
6758
  let slug = "", startedAt = "";
6759
6759
  for (const line of data.split("\n")) {
@@ -6999,6 +6999,20 @@ function getRecentDecisions(store, projectRemote, projectPath, sinceISO, limit)
6999
6999
  createdAt: r.created_at
7000
7000
  }));
7001
7001
  }
7002
+ function deleteOrphanKnowledge(store, projectRemote, projectPath, branch, validFilePaths) {
7003
+ const rows = store.db.prepare("SELECT id, file_path FROM knowledge_index WHERE project_remote = ? AND project_path = ? AND branch = ?").all(projectRemote, projectPath, branch);
7004
+ let deleted = 0;
7005
+ const delEmbed = store.db.prepare("DELETE FROM embeddings WHERE source = 'knowledge' AND source_id = ?");
7006
+ const delKnowledge = store.db.prepare("DELETE FROM knowledge_index WHERE id = ?");
7007
+ store.db.transaction(() => {
7008
+ for (const row of rows) if (!validFilePaths.has(row.file_path)) {
7009
+ delEmbed.run(row.id);
7010
+ delKnowledge.run(row.id);
7011
+ deleted++;
7012
+ }
7013
+ })();
7014
+ return deleted;
7015
+ }
7002
7016
  function countKnowledge(store, projectRemote, projectPath) {
7003
7017
  return store.db.prepare("SELECT COUNT(*) as cnt FROM knowledge_index WHERE project_remote = ? AND project_path = ? AND enabled = 1").get(projectRemote, projectPath).cnt;
7004
7018
  }
@@ -7028,4 +7042,4 @@ function mapRow(r) {
7028
7042
  };
7029
7043
  }
7030
7044
  //#endregion
7031
- export { switchActive as C, __commonJSMin as D, require_dist as E, __exportAll as O, rootDir as S, writeActiveState as T, filesForSize as _, getPromotionCandidates as a, removeTask as b, mapRow as c, setKnowledgeEnabled as d, upsertKnowledge as f, detectSize as g, completeTask as h, getKnowledgeStats as i, __toESM as k, promoteSubType as l, VALID_SLUG as m, getKnowledgeByID as n, getRecentDecisions as o, SpecDir as p, getKnowledgeByIDs as r, incrementHitCount as s, countKnowledge as t, searchKnowledgeKeyword as u, readActive as v, verifyReviewFile as w, reviewStatusFor as x, readActiveState as y };
7045
+ export { __toESM as A, rootDir as C, require_dist as D, writeActiveState as E, __commonJSMin as O, reviewStatusFor as S, verifyReviewFile as T, detectSize as _, getKnowledgeStats as a, readActiveState as b, incrementHitCount as c, searchKnowledgeKeyword as d, setKnowledgeEnabled as f, completeTask as g, VALID_SLUG as h, getKnowledgeByIDs as i, __exportAll as k, mapRow as l, SpecDir as m, deleteOrphanKnowledge as n, getPromotionCandidates as o, upsertKnowledge as p, getKnowledgeByID as r, getRecentDecisions as s, countKnowledge as t, promoteSubType as u, filesForSize as v, switchActive as w, removeTask as x, readActive as y };
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { a as getPromotionCandidates, f as upsertKnowledge, l as promoteSubType, p as SpecDir, v as readActive, y as readActiveState } from "./knowledge-DItYbraO.mjs";
3
- import { n as searchKnowledgeFTS, t as detectKnowledgeConflicts } from "./fts-CDEAxhSV.mjs";
2
+ import { b as readActiveState, m as SpecDir, o as getPromotionCandidates, p as upsertKnowledge, u as promoteSubType, y as readActive } from "./knowledge-B0fsJ9SI.mjs";
3
+ import { n as searchKnowledgeFTS, t as detectKnowledgeConflicts } from "./fts-QWdC_4Zv.mjs";
4
4
  import { t as detectProject } from "./project-Djp8-Djz.mjs";
5
- import { i as notifyUser, r as extractSection } from "./dispatcher-xZAhoK7h.mjs";
6
- import { r as truncate } from "./helpers-DVDJYnXA.mjs";
5
+ import { i as notifyUser, r as extractSection } from "./dispatcher-BnBtA4bo.mjs";
6
+ import { r as truncate } from "./helpers-BnPVn8Nv.mjs";
7
7
  import { openDefaultCached } from "./store-CuN3_dWu.mjs";
8
- import { t as emitDirectives } from "./directives-iFMV2Mmx.mjs";
8
+ import { t as emitDirectives } from "./directives-ko2sX5BW.mjs";
9
9
  import { i as writeStateText, n as readStateText } from "./state-CdHO66SV.mjs";
10
10
  //#region src/hooks/post-tool.ts
11
11
  function readExploreCount(cwd) {
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { f as upsertKnowledge, h as completeTask, p as SpecDir, v as readActive, w as verifyReviewFile, x as reviewStatusFor, y as readActiveState } from "./knowledge-DItYbraO.mjs";
3
- import { s as syncTaskStatus, t as appendAudit } from "./audit-BrTztz4z.mjs";
2
+ import { S as reviewStatusFor, T as verifyReviewFile, b as readActiveState, g as completeTask, m as SpecDir, p as upsertKnowledge, y as readActive } from "./knowledge-B0fsJ9SI.mjs";
3
+ import { s as syncTaskStatus, t as appendAudit } from "./audit-6NSlW0Ut.mjs";
4
4
  import { t as detectProject } from "./project-Djp8-Djz.mjs";
5
- import { i as notifyUser } from "./dispatcher-xZAhoK7h.mjs";
5
+ import { i as notifyUser } from "./dispatcher-BnBtA4bo.mjs";
6
6
  import { openDefaultCached } from "./store-CuN3_dWu.mjs";
7
7
  import { readFileSync, writeFileSync } from "node:fs";
8
8
  import { join } from "node:path";
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import "./dispatcher-xZAhoK7h.mjs";
3
- import { a as isSpecFilePath, o as tryReadActiveSpec, r as denyTool } from "./spec-guard-YaW8olGC.mjs";
2
+ import "./dispatcher-BnBtA4bo.mjs";
3
+ import { a as isSpecFilePath, o as tryReadActiveSpec, r as denyTool } from "./spec-guard-BGwtCxgH.mjs";
4
4
  //#region src/hooks/pre-tool.ts
5
5
  const BLOCKABLE_TOOLS = new Set(["Edit", "Write"]);
6
6
  /**
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { C as switchActive, D as __commonJSMin, T as writeActiveState, _ as filesForSize, a as getPromotionCandidates, b as removeTask, f as upsertKnowledge, g as detectSize, h as completeTask, i as getKnowledgeStats, k as __toESM, l as promoteSubType, m as VALID_SLUG, n as getKnowledgeByID, p as SpecDir, r as getKnowledgeByIDs, v as readActive, w as verifyReviewFile, x as reviewStatusFor, y as readActiveState } from "./knowledge-DItYbraO.mjs";
3
- import { a as nextActionable, c as topologicalOrder, i as listAllEpics, l as unlinkTaskFromAllEpics, n as EpicDir, o as removeEpic, r as initEpic, s as syncTaskStatus, t as appendAudit } from "./audit-BrTztz4z.mjs";
4
- import { r as vectorSearchKnowledge } from "./vectors-C_Yj-4sR.mjs";
5
- import { n as searchKnowledgeFTS, r as subTypeBoost, t as detectKnowledgeConflicts } from "./fts-CDEAxhSV.mjs";
2
+ import { A as __toESM, E as writeActiveState, O as __commonJSMin, S as reviewStatusFor, T as verifyReviewFile, _ as detectSize, a as getKnowledgeStats, b as readActiveState, g as completeTask, h as VALID_SLUG, i as getKnowledgeByIDs, m as SpecDir, o as getPromotionCandidates, p as upsertKnowledge, r as getKnowledgeByID, u as promoteSubType, v as filesForSize, w as switchActive, x as removeTask, y as readActive } from "./knowledge-B0fsJ9SI.mjs";
3
+ import { a as nextActionable, c as topologicalOrder, i as listAllEpics, l as unlinkTaskFromAllEpics, n as EpicDir, o as removeEpic, r as initEpic, s as syncTaskStatus, t as appendAudit } from "./audit-6NSlW0Ut.mjs";
4
+ import { r as vectorSearchKnowledge } from "./vectors-BDQP0gaa.mjs";
5
+ import { n as searchKnowledgeFTS, r as subTypeBoost, t as detectKnowledgeConflicts } from "./fts-QWdC_4Zv.mjs";
6
6
  import { t as detectProject } from "./project-Djp8-Djz.mjs";
7
- import { n as trackHitCounts, r as truncate, t as searchPipeline } from "./helpers-DVDJYnXA.mjs";
7
+ import { n as trackHitCounts, r as truncate, t as searchPipeline } from "./helpers-BnPVn8Nv.mjs";
8
8
  import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
9
9
  import { join, resolve } from "node:path";
10
10
  import { createHash } from "node:crypto";
@@ -18586,7 +18586,7 @@ async function ledgerSave(store, emb, params) {
18586
18586
  const model = emb.model;
18587
18587
  const embText = `${params.title} ${params.context_text ?? ""} ${params.decision ?? params.pattern ?? params.text ?? ""}`;
18588
18588
  emb.embedForStorage(embText).then(async (vec) => {
18589
- const { insertEmbedding } = await import("./vectors-C_Yj-4sR.mjs").then((n) => n.i);
18589
+ const { insertEmbedding } = await import("./vectors-BDQP0gaa.mjs").then((n) => n.i);
18590
18590
  insertEmbedding(store, "knowledge", dbId, model, vec);
18591
18591
  }).catch((err) => {
18592
18592
  console.error(`[alfred] embedding failed for ${dbId}: ${err}`);
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { T as writeActiveState, _ as filesForSize, d as setKnowledgeEnabled, h as completeTask, i as getKnowledgeStats, m as VALID_SLUG, p as SpecDir, w as verifyReviewFile, y as readActiveState } from "./knowledge-DItYbraO.mjs";
3
- import { i as listAllEpics, t as appendAudit } from "./audit-BrTztz4z.mjs";
4
- import { n as searchKnowledgeFTS } from "./fts-CDEAxhSV.mjs";
2
+ import { E as writeActiveState, T as verifyReviewFile, a as getKnowledgeStats, b as readActiveState, f as setKnowledgeEnabled, g as completeTask, h as VALID_SLUG, m as SpecDir, v as filesForSize } from "./knowledge-B0fsJ9SI.mjs";
3
+ import { i as listAllEpics, t as appendAudit } from "./audit-6NSlW0Ut.mjs";
4
+ import { n as searchKnowledgeFTS } from "./fts-QWdC_4Zv.mjs";
5
5
  import { t as detectProject } from "./project-Djp8-Djz.mjs";
6
6
  import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
7
7
  import { join } from "node:path";
@@ -2424,6 +2424,59 @@ function toKnowledgeEntry(r) {
2424
2424
  function createApp(projectPath, store, _emb, version) {
2425
2425
  const app = new Hono();
2426
2426
  const proj = detectProject(projectPath);
2427
+ function enrichTask(task, projPath, projectName) {
2428
+ const detail = {
2429
+ ...task,
2430
+ project_name: projectName
2431
+ };
2432
+ const sd = new SpecDir(projPath, task.slug);
2433
+ try {
2434
+ const lines = sd.readFile("session.md").split("\n");
2435
+ let inFocus = false;
2436
+ for (const line of lines) {
2437
+ if (line.startsWith("## Currently Working On")) {
2438
+ inFocus = true;
2439
+ continue;
2440
+ }
2441
+ if (inFocus) {
2442
+ if (line.startsWith("## ")) break;
2443
+ const trimmed = line.trim();
2444
+ if (trimmed && !trimmed.startsWith("<!--")) {
2445
+ detail.focus = trimmed;
2446
+ break;
2447
+ }
2448
+ }
2449
+ }
2450
+ let inNextSteps = false;
2451
+ const stepLines = [];
2452
+ for (const line of lines) {
2453
+ if (line.startsWith("## Next Steps")) {
2454
+ inNextSteps = true;
2455
+ continue;
2456
+ }
2457
+ if (inNextSteps) {
2458
+ if (line.startsWith("## ")) break;
2459
+ if (line.match(/^- \[[ x]\] /)) stepLines.push(line);
2460
+ }
2461
+ }
2462
+ if (stepLines.length > 0) {
2463
+ const nextSteps = stepLines.map((s) => ({
2464
+ text: s.replace(/^- \[[ x]\] /, ""),
2465
+ done: s.startsWith("- [x]")
2466
+ }));
2467
+ detail.next_steps = nextSteps;
2468
+ detail.completed = nextSteps.filter((s) => s.done).length;
2469
+ detail.total = nextSteps.length;
2470
+ } else {
2471
+ detail.completed = 0;
2472
+ detail.total = 0;
2473
+ }
2474
+ } catch {
2475
+ detail.completed = 0;
2476
+ detail.total = 0;
2477
+ }
2478
+ return detail;
2479
+ }
2427
2480
  app.get("/api/version", (c) => c.json({ version }));
2428
2481
  app.get("/api/project", (c) => c.json({
2429
2482
  path: projectPath,
@@ -2432,62 +2485,27 @@ function createApp(projectPath, store, _emb, version) {
2432
2485
  app.get("/api/tasks", (c) => {
2433
2486
  try {
2434
2487
  const state = readActiveState(projectPath);
2435
- const enriched = state.tasks.map((task) => {
2436
- const detail = {
2437
- ...task,
2438
- project_name: proj.name
2439
- };
2440
- const sd = new SpecDir(projectPath, task.slug);
2441
- try {
2442
- const lines = sd.readFile("session.md").split("\n");
2443
- let inFocus = false;
2444
- for (const line of lines) {
2445
- if (line.startsWith("## Currently Working On")) {
2446
- inFocus = true;
2447
- continue;
2448
- }
2449
- if (inFocus) {
2450
- if (line.startsWith("## ")) break;
2451
- const trimmed = line.trim();
2452
- if (trimmed && !trimmed.startsWith("<!--")) {
2453
- detail.focus = trimmed;
2454
- break;
2455
- }
2456
- }
2457
- }
2458
- let inNextSteps = false;
2459
- const stepLines = [];
2460
- for (const line of lines) {
2461
- if (line.startsWith("## Next Steps")) {
2462
- inNextSteps = true;
2463
- continue;
2464
- }
2465
- if (inNextSteps) {
2466
- if (line.startsWith("## ")) break;
2467
- if (line.match(/^- \[[ x]\] /)) stepLines.push(line);
2468
- }
2469
- }
2470
- if (stepLines.length > 0) {
2471
- const nextSteps = stepLines.map((s) => ({
2472
- text: s.replace(/^- \[[ x]\] /, ""),
2473
- done: s.startsWith("- [x]")
2474
- }));
2475
- detail.next_steps = nextSteps;
2476
- detail.completed = nextSteps.filter((s) => s.done).length;
2477
- detail.total = nextSteps.length;
2478
- } else {
2479
- detail.completed = 0;
2480
- detail.total = 0;
2488
+ const enriched = state.tasks.map((task) => enrichTask(task, projectPath, proj.name));
2489
+ const specsDir = join(projectPath, ".alfred", "specs");
2490
+ const activeSlugs = new Set(state.tasks.map((t) => t.slug));
2491
+ let archived = [];
2492
+ try {
2493
+ archived = readdirSync(specsDir).filter((d) => {
2494
+ if (d.startsWith("_") || !VALID_SLUG.test(d) || activeSlugs.has(d)) return false;
2495
+ try {
2496
+ return statSync(join(specsDir, d)).isDirectory();
2497
+ } catch {
2498
+ return false;
2481
2499
  }
2482
- } catch {
2483
- detail.completed = 0;
2484
- detail.total = 0;
2485
- }
2486
- return detail;
2487
- });
2500
+ }).map((slug) => enrichTask({
2501
+ slug,
2502
+ status: "completed",
2503
+ started_at: ""
2504
+ }, projectPath, proj.name));
2505
+ } catch {}
2488
2506
  return c.json({
2489
2507
  active: state.primary,
2490
- tasks: enriched,
2508
+ tasks: [...enriched, ...archived],
2491
2509
  project_name: proj.name
2492
2510
  });
2493
2511
  } catch {
@@ -2562,7 +2580,7 @@ function createApp(projectPath, store, _emb, version) {
2562
2580
  SELECT id, file_path, content_hash, title, content, sub_type,
2563
2581
  project_remote, project_path, project_name, branch,
2564
2582
  created_at, updated_at, hit_count, last_accessed, enabled
2565
- FROM knowledge_index ORDER BY updated_at DESC LIMIT ?
2583
+ FROM knowledge_index WHERE enabled = 1 ORDER BY updated_at DESC LIMIT ?
2566
2584
  `).all(limit).map((r) => ({
2567
2585
  id: r.id,
2568
2586
  label: r.title,
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { f as upsertKnowledge, o as getRecentDecisions, p as SpecDir, t as countKnowledge, v as readActive, y as readActiveState } from "./knowledge-DItYbraO.mjs";
2
+ import { b as readActiveState, m as SpecDir, n as deleteOrphanKnowledge, p as upsertKnowledge, s as getRecentDecisions, t as countKnowledge, y as readActive } from "./knowledge-B0fsJ9SI.mjs";
3
3
  import { t as detectProject } from "./project-Djp8-Djz.mjs";
4
- import { i as notifyUser, r as extractSection } from "./dispatcher-xZAhoK7h.mjs";
5
- import { r as truncate } from "./helpers-DVDJYnXA.mjs";
4
+ import { i as notifyUser, r as extractSection } from "./dispatcher-BnBtA4bo.mjs";
5
+ import { r as truncate } from "./helpers-BnPVn8Nv.mjs";
6
6
  import { openDefaultCached } from "./store-CuN3_dWu.mjs";
7
- import { t as emitDirectives } from "./directives-iFMV2Mmx.mjs";
7
+ import { t as emitDirectives } from "./directives-ko2sX5BW.mjs";
8
8
  import { existsSync, readFileSync, readdirSync } from "node:fs";
9
9
  import { join } from "node:path";
10
10
  //#region src/hooks/session-start.ts
@@ -36,6 +36,7 @@ function syncKnowledgeIndex(store, projectPath) {
36
36
  const knowledgeDir = join(projectPath, ".alfred", "knowledge");
37
37
  const proj = detectProject(projectPath);
38
38
  let synced = 0;
39
+ const validFilePaths = /* @__PURE__ */ new Set();
39
40
  for (const typeDir of [
40
41
  "decisions",
41
42
  "patterns",
@@ -52,6 +53,7 @@ function syncKnowledgeIndex(store, projectPath) {
52
53
  const raw = readFileSync(join(dir, file), "utf-8");
53
54
  const entry = JSON.parse(raw);
54
55
  const filePath = `${typeDir}/${file}`;
56
+ validFilePaths.add(filePath);
55
57
  const subType = typeDir === "decisions" ? "decision" : typeDir === "patterns" ? "pattern" : "rule";
56
58
  const { changed } = upsertKnowledge(store, {
57
59
  id: 0,
@@ -76,6 +78,7 @@ function syncKnowledgeIndex(store, projectPath) {
76
78
  try {
77
79
  const mdFiles = readdirSync(knowledgeDir).filter((f) => f.endsWith(".md"));
78
80
  for (const file of mdFiles) try {
81
+ validFilePaths.add(file);
79
82
  const { frontmatter, body } = parseFrontmatter(readFileSync(join(knowledgeDir, file), "utf-8"));
80
83
  const { changed } = upsertKnowledge(store, {
81
84
  id: 0,
@@ -97,6 +100,12 @@ function syncKnowledgeIndex(store, projectPath) {
97
100
  if (changed) synced++;
98
101
  } catch {}
99
102
  } catch {}
103
+ try {
104
+ const deleted = deleteOrphanKnowledge(store, proj.remote, proj.path, proj.branch, validFilePaths);
105
+ if (deleted > 0) notifyUser("cleaned %d orphan knowledge entries from index", deleted);
106
+ } catch (err) {
107
+ notifyUser("warning: orphan knowledge cleanup failed: %s", err);
108
+ }
100
109
  if (synced > 0) notifyUser("synced %d knowledge files to index", synced);
101
110
  }
102
111
  function parseFrontmatter(content) {
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { r as extractSection } from "./dispatcher-xZAhoK7h.mjs";
2
+ import { r as extractSection } from "./dispatcher-BnBtA4bo.mjs";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { join, resolve } from "node:path";
5
5
  //#region src/hooks/spec-guard.ts
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import "./dispatcher-xZAhoK7h.mjs";
3
- import { i as hasUncheckedSelfReview, n as countUncheckedNextSteps, o as tryReadActiveSpec, t as blockStop } from "./spec-guard-YaW8olGC.mjs";
2
+ import "./dispatcher-BnBtA4bo.mjs";
3
+ import { i as hasUncheckedSelfReview, n as countUncheckedNextSteps, o as tryReadActiveSpec, t as blockStop } from "./spec-guard-BGwtCxgH.mjs";
4
4
  //#region src/hooks/stop.ts
5
5
  /**
6
6
  * Stop handler: block Claude from stopping when active spec has incomplete items.
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { y as readActiveState } from "./knowledge-DItYbraO.mjs";
3
- import { r as subTypeBoost } from "./fts-CDEAxhSV.mjs";
2
+ import { b as readActiveState } from "./knowledge-B0fsJ9SI.mjs";
3
+ import { r as subTypeBoost } from "./fts-QWdC_4Zv.mjs";
4
4
  import { Embedder } from "./embedder-BRG2Xpr4.mjs";
5
- import "./dispatcher-xZAhoK7h.mjs";
6
- import { n as trackHitCounts, r as truncate, t as searchPipeline } from "./helpers-DVDJYnXA.mjs";
5
+ import "./dispatcher-BnBtA4bo.mjs";
6
+ import { n as trackHitCounts, r as truncate, t as searchPipeline } from "./helpers-BnPVn8Nv.mjs";
7
7
  import { openDefaultCached } from "./store-CuN3_dWu.mjs";
8
- import { t as emitDirectives } from "./directives-iFMV2Mmx.mjs";
8
+ import { t as emitDirectives } from "./directives-ko2sX5BW.mjs";
9
9
  import { r as writeStateJSON, t as readStateJSON } from "./state-CdHO66SV.mjs";
10
10
  import { existsSync } from "node:fs";
11
11
  import { join } from "node:path";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { O as __exportAll } from "./knowledge-DItYbraO.mjs";
2
+ import { k as __exportAll } from "./knowledge-B0fsJ9SI.mjs";
3
3
  //#region src/store/vectors.ts
4
4
  var vectors_exports = /* @__PURE__ */ __exportAll({
5
5
  cosineSimilarity: () => cosineSimilarity,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-alfred",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "alfred": "dist/cli.mjs"
@@ -1 +1 @@
1
- import{B as e,C as t,O as n,T as r,b as i,dt as a,g as o,i as s,t as c,y as l,z as u}from"./api-BpnabbKu.js";import{t as d}from"./dist--KR51Ecg.js";import{t as f}from"./progress-CokWPQNM.js";import{c as p,f as m,l as h,s as g,u as _}from"./index-DRPc84bA.js";import{n as v,t as y}from"./badge-CBVw5E1L.js";import{a as b,i as x,n as S,r as C,t as w}from"./skeleton-BjX-jJYO.js";var T=a(e(),1),E=u();function D(e){let n=e+`CollectionProvider`,[i,a]=l(n),[o,s]=i(n,{collectionRef:{current:null},itemMap:new Map}),c=e=>{let{scope:t,children:n}=e,r=T.useRef(null),i=T.useRef(new Map).current;return(0,E.jsx)(o,{scope:t,itemMap:i,collectionRef:r,children:n})};c.displayName=n;let u=e+`CollectionSlot`,d=t(u),f=T.forwardRef((e,t)=>{let{scope:n,children:i}=e;return(0,E.jsx)(d,{ref:r(t,s(u,n).collectionRef),children:i})});f.displayName=u;let p=e+`CollectionItemSlot`,m=`data-radix-collection-item`,h=t(p),g=T.forwardRef((e,t)=>{let{scope:n,children:i,...a}=e,o=T.useRef(null),c=r(t,o),l=s(p,n);return T.useEffect(()=>(l.itemMap.set(o,{ref:o,...a}),()=>void l.itemMap.delete(o))),(0,E.jsx)(h,{[m]:``,ref:c,children:i})});g.displayName=p;function _(t){let n=s(e+`CollectionConsumer`,t);return T.useCallback(()=>{let e=n.collectionRef.current;if(!e)return[];let t=Array.from(e.querySelectorAll(`[${m}]`));return Array.from(n.itemMap.values()).sort((e,n)=>t.indexOf(e.ref.current)-t.indexOf(n.ref.current))},[n.collectionRef,n.itemMap])}return[{Provider:c,Slot:f,ItemSlot:g},_,a]}var O=`rovingFocusGroup.onEntryFocus`,ee={bubbles:!1,cancelable:!0},k=`RovingFocusGroup`,[A,j,M]=D(k),[N,P]=l(k,[M]),[te,ne]=N(k),F=T.forwardRef((e,t)=>(0,E.jsx)(A.Provider,{scope:e.__scopeRovingFocusGroup,children:(0,E.jsx)(A.Slot,{scope:e.__scopeRovingFocusGroup,children:(0,E.jsx)(re,{...e,ref:t})})}));F.displayName=k;var re=T.forwardRef((e,t)=>{let{__scopeRovingFocusGroup:n,orientation:a,loop:o=!1,dir:s,currentTabStopId:c,defaultCurrentTabStopId:l,onCurrentTabStopIdChange:u,onEntryFocus:f,preventScrollOnEntryFocus:p=!1,...h}=e,v=T.useRef(null),y=r(t,v),b=d(s),[x,S]=_({prop:c,defaultProp:l??null,onChange:u,caller:k}),[C,w]=T.useState(!1),D=g(f),A=j(n),M=T.useRef(!1),[N,P]=T.useState(0);return T.useEffect(()=>{let e=v.current;if(e)return e.addEventListener(O,D),()=>e.removeEventListener(O,D)},[D]),(0,E.jsx)(te,{scope:n,orientation:a,dir:b,loop:o,currentTabStopId:x,onItemFocus:T.useCallback(e=>S(e),[S]),onItemShiftTab:T.useCallback(()=>w(!0),[]),onFocusableItemAdd:T.useCallback(()=>P(e=>e+1),[]),onFocusableItemRemove:T.useCallback(()=>P(e=>e-1),[]),children:(0,E.jsx)(i.div,{tabIndex:C||N===0?-1:0,"data-orientation":a,...h,ref:y,style:{outline:`none`,...e.style},onMouseDown:m(e.onMouseDown,()=>{M.current=!0}),onFocus:m(e.onFocus,e=>{let t=!M.current;if(e.target===e.currentTarget&&t&&!C){let t=new CustomEvent(O,ee);if(e.currentTarget.dispatchEvent(t),!t.defaultPrevented){let e=A().filter(e=>e.focusable);R([e.find(e=>e.active),e.find(e=>e.id===x),...e].filter(Boolean).map(e=>e.ref.current),p)}}M.current=!1}),onBlur:m(e.onBlur,()=>w(!1))})})}),I=`RovingFocusGroupItem`,L=T.forwardRef((e,t)=>{let{__scopeRovingFocusGroup:n,focusable:r=!0,active:a=!1,tabStopId:o,children:s,...c}=e,l=p(),u=o||l,d=ne(I,n),f=d.currentTabStopId===u,h=j(n),{onFocusableItemAdd:g,onFocusableItemRemove:_,currentTabStopId:v}=d;return T.useEffect(()=>{if(r)return g(),()=>_()},[r,g,_]),(0,E.jsx)(A.ItemSlot,{scope:n,id:u,focusable:r,active:a,children:(0,E.jsx)(i.span,{tabIndex:f?0:-1,"data-orientation":d.orientation,...c,ref:t,onMouseDown:m(e.onMouseDown,e=>{r?d.onItemFocus(u):e.preventDefault()}),onFocus:m(e.onFocus,()=>d.onItemFocus(u)),onKeyDown:m(e.onKeyDown,e=>{if(e.key===`Tab`&&e.shiftKey){d.onItemShiftTab();return}if(e.target!==e.currentTarget)return;let t=oe(e,d.orientation,d.dir);if(t!==void 0){if(e.metaKey||e.ctrlKey||e.altKey||e.shiftKey)return;e.preventDefault();let n=h().filter(e=>e.focusable).map(e=>e.ref.current);if(t===`last`)n.reverse();else if(t===`prev`||t===`next`){t===`prev`&&n.reverse();let r=n.indexOf(e.currentTarget);n=d.loop?se(n,r+1):n.slice(r+1)}setTimeout(()=>R(n))}}),children:typeof s==`function`?s({isCurrentTabStop:f,hasTabStop:v!=null}):s})})});L.displayName=I;var ie={ArrowLeft:`prev`,ArrowUp:`prev`,ArrowRight:`next`,ArrowDown:`next`,PageUp:`first`,Home:`first`,PageDown:`last`,End:`last`};function ae(e,t){return t===`rtl`?e===`ArrowLeft`?`ArrowRight`:e===`ArrowRight`?`ArrowLeft`:e:e}function oe(e,t,n){let r=ae(e.key,n);if(!(t===`vertical`&&[`ArrowLeft`,`ArrowRight`].includes(r))&&!(t===`horizontal`&&[`ArrowUp`,`ArrowDown`].includes(r)))return ie[r]}function R(e,t=!1){let n=document.activeElement;for(let r of e)if(r===n||(r.focus({preventScroll:t}),document.activeElement!==n))return}function se(e,t){return e.map((n,r)=>e[(t+r)%e.length])}var ce=F,le=L,z=`Tabs`,[ue,de]=l(z,[P]),B=P(),[fe,V]=ue(z),H=T.forwardRef((e,t)=>{let{__scopeTabs:n,value:r,onValueChange:a,defaultValue:o,orientation:s=`horizontal`,dir:c,activationMode:l=`automatic`,...u}=e,f=d(c),[m,h]=_({prop:r,onChange:a,defaultProp:o??``,caller:z});return(0,E.jsx)(fe,{scope:n,baseId:p(),value:m,onValueChange:h,orientation:s,dir:f,activationMode:l,children:(0,E.jsx)(i.div,{dir:f,"data-orientation":s,...u,ref:t})})});H.displayName=z;var U=`TabsList`,W=T.forwardRef((e,t)=>{let{__scopeTabs:n,loop:r=!0,...a}=e,o=V(U,n),s=B(n);return(0,E.jsx)(ce,{asChild:!0,...s,orientation:o.orientation,dir:o.dir,loop:r,children:(0,E.jsx)(i.div,{role:`tablist`,"aria-orientation":o.orientation,...a,ref:t})})});W.displayName=U;var G=`TabsTrigger`,K=T.forwardRef((e,t)=>{let{__scopeTabs:n,value:r,disabled:a=!1,...o}=e,s=V(G,n),c=B(n),l=J(s.baseId,r),u=Y(s.baseId,r),d=r===s.value;return(0,E.jsx)(le,{asChild:!0,...c,focusable:!a,active:d,children:(0,E.jsx)(i.button,{type:`button`,role:`tab`,"aria-selected":d,"aria-controls":u,"data-state":d?`active`:`inactive`,"data-disabled":a?``:void 0,disabled:a,id:l,...o,ref:t,onMouseDown:m(e.onMouseDown,e=>{!a&&e.button===0&&e.ctrlKey===!1?s.onValueChange(r):e.preventDefault()}),onKeyDown:m(e.onKeyDown,e=>{[` `,`Enter`].includes(e.key)&&s.onValueChange(r)}),onFocus:m(e.onFocus,()=>{let e=s.activationMode!==`manual`;!d&&!a&&e&&s.onValueChange(r)})})})});K.displayName=G;var q=`TabsContent`,pe=T.forwardRef((e,t)=>{let{__scopeTabs:n,value:r,forceMount:a,children:o,...s}=e,c=V(q,n),l=J(c.baseId,r),u=Y(c.baseId,r),d=r===c.value,f=T.useRef(d);return T.useEffect(()=>{let e=requestAnimationFrame(()=>f.current=!1);return()=>cancelAnimationFrame(e)},[]),(0,E.jsx)(h,{present:a||d,children:({present:n})=>(0,E.jsx)(i.div,{"data-state":d?`active`:`inactive`,"data-orientation":c.orientation,role:`tabpanel`,"aria-labelledby":l,hidden:!n,id:u,tabIndex:0,...s,ref:t,style:{...e.style,animationDuration:f.current?`0s`:void 0},children:n&&o})})});pe.displayName=q;function J(e,t){return`${e}-trigger-${t}`}function Y(e,t){return`${e}-content-${t}`}var me=H,he=W,ge=K;function _e({className:e,...t}){return(0,E.jsx)(`div`,{"data-slot":`table-container`,className:`relative w-full overflow-x-auto`,children:(0,E.jsx)(`table`,{"data-slot":`table`,className:o(`w-full caption-bottom text-sm`,e),...t})})}function ve({className:e,...t}){return(0,E.jsx)(`thead`,{"data-slot":`table-header`,className:o(`[&_tr]:border-b`,e),...t})}function ye({className:e,...t}){return(0,E.jsx)(`tbody`,{"data-slot":`table-body`,className:o(`[&_tr:last-child]:border-0`,e),...t})}function X({className:e,...t}){return(0,E.jsx)(`tr`,{"data-slot":`table-row`,className:o(`border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted`,e),...t})}function Z({className:e,...t}){return(0,E.jsx)(`th`,{"data-slot":`table-head`,className:o(`h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,e),...t})}function Q({className:e,...t}){return(0,E.jsx)(`td`,{"data-slot":`table-cell`,className:o(`p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,e),...t})}function be({className:e,orientation:t=`horizontal`,...n}){return(0,E.jsx)(me,{"data-slot":`tabs`,"data-orientation":t,orientation:t,className:o(`group/tabs flex gap-2 data-[orientation=horizontal]:flex-col`,e),...n})}var xe=v(`group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col data-[variant=line]:rounded-none`,{variants:{variant:{default:`bg-muted`,line:`gap-1 bg-transparent`}},defaultVariants:{variant:`default`}});function Se({className:e,variant:t=`default`,...n}){return(0,E.jsx)(he,{"data-slot":`tabs-list`,"data-variant":t,className:o(xe({variant:t}),e),...n})}function Ce({className:e,...t}){return(0,E.jsx)(ge,{"data-slot":`tabs-trigger`,className:o(`relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,`group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent`,`data-[state=active]:bg-background data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:data-[state=active]:text-foreground`,`after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100`,e),...t})}var $=[`all`,`spec.init`,`spec.complete`,`review.submit`];function we(){let[e,t]=(0,T.useState)(`all`),{data:r,isLoading:i}=n(c(100,e===`all`?void 0:e)),{data:a}=n(s()),o=r?.entries??[],l=(a?.epics??[]).filter(e=>e.status!==`completed`);return(0,E.jsxs)(`div`,{className:`space-y-6`,children:[(0,E.jsx)(be,{value:e,onValueChange:t,children:(0,E.jsx)(Se,{children:$.map(e=>(0,E.jsx)(Ce,{value:e,className:`text-xs`,children:e===`all`?`All`:e},e))})}),i?(0,E.jsx)(`div`,{className:`space-y-2`,children:Array.from({length:5}).map((e,t)=>(0,E.jsx)(w,{className:`h-10 w-full`},`skel-${t}`))}):(0,E.jsx)(Te,{entries:o}),l.length>0&&(0,E.jsx)(Oe,{epics:l})]})}function Te({entries:e}){let[t,n]=(0,T.useState)(null);return(0,E.jsxs)(_e,{children:[(0,E.jsx)(ve,{children:(0,E.jsxs)(X,{children:[(0,E.jsx)(Z,{className:`w-44`,children:`Timestamp`}),(0,E.jsx)(Z,{className:`w-32`,children:`Action`}),(0,E.jsx)(Z,{children:`Target`}),(0,E.jsx)(Z,{children:`Detail`})]})}),(0,E.jsxs)(ye,{children:[e.map((e,r)=>{let i=t===r,a=!!e.detail&&e.detail.length>40;return(0,E.jsxs)(X,{className:a?`cursor-pointer hover:bg-accent/50`:``,onClick:()=>a&&n(i?null:r),children:[(0,E.jsx)(Q,{className:`text-xs text-muted-foreground font-mono align-top`,children:ke(e.timestamp)}),(0,E.jsx)(Q,{className:`align-top`,children:(0,E.jsx)(De,{action:e.action})}),(0,E.jsx)(Q,{className:`text-sm align-top`,children:e.target}),(0,E.jsx)(Q,{className:`text-xs text-muted-foreground`,children:i?(0,E.jsx)(`div`,{className:`whitespace-pre-wrap break-words max-w-lg`,children:e.detail}):(0,E.jsx)(`div`,{className:`max-w-xs truncate`,children:e.detail})})]},`${e.timestamp}-${r}`)}),e.length===0&&(0,E.jsx)(X,{children:(0,E.jsx)(Q,{colSpan:4,className:`text-center text-sm text-muted-foreground`,children:`No activity found.`})})]})]})}var Ee={"spec.init":`#40513b`,"spec.complete":`#2d8b7a`,"spec.delete":`#c0392b`,"review.submit":`#628141`,"living-spec.update":`#7b6b8d`};function De({action:e}){let t=Ee[e]??`#6b7280`;return(0,E.jsx)(y,{variant:`outline`,className:`text-xs`,style:{borderColor:`${t}40`,color:t},children:e})}function Oe({epics:e}){return(0,E.jsxs)(`div`,{className:`space-y-3`,children:[(0,E.jsx)(`h3`,{className:`text-sm font-medium text-foreground`,children:`Epics`}),(0,E.jsx)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:e.map(e=>{let t=e.total>0?e.completed/e.total*100:0;return(0,E.jsxs)(S,{children:[(0,E.jsx)(x,{className:`pb-2`,children:(0,E.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,E.jsx)(b,{className:`text-sm`,children:e.name}),(0,E.jsx)(y,{variant:`outline`,className:`text-xs`,children:e.status})]})}),(0,E.jsxs)(C,{className:`space-y-2`,children:[(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(f,{value:t,className:`h-1.5 flex-1`}),(0,E.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[e.completed,`/`,e.total]})]}),e.tasks&&e.tasks.length>0&&(0,E.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:e.tasks.map(e=>(0,E.jsx)(y,{variant:`outline`,className:`text-[10px]`,style:{borderColor:e.status===`completed`?`rgba(45,139,122,0.3)`:`rgba(107,114,128,0.3)`,color:e.status===`completed`?`#2d8b7a`:`#6b7280`},children:e.slug},e.slug))})]})]},e.slug)})})]})}function ke(e){try{return new Date(e).toLocaleString(`ja-JP`,{month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`})}catch{return e}}export{we as component};
1
+ import{B as e,C as t,O as n,T as r,b as i,dt as a,g as o,i as s,t as c,y as l,z as u}from"./api-BpnabbKu.js";import{t as d}from"./dist-7qozDZTq.js";import{t as f}from"./progress-B0hcYV7D.js";import{c as p,f as m,l as h,s as g,u as _}from"./index-CNTBHHOa.js";import{n as v,t as y}from"./badge-CBFM8JtH.js";import{a as b,i as x,n as S,r as C,t as w}from"./skeleton-CLJEM3zd.js";var T=a(e(),1),E=u();function D(e){let n=e+`CollectionProvider`,[i,a]=l(n),[o,s]=i(n,{collectionRef:{current:null},itemMap:new Map}),c=e=>{let{scope:t,children:n}=e,r=T.useRef(null),i=T.useRef(new Map).current;return(0,E.jsx)(o,{scope:t,itemMap:i,collectionRef:r,children:n})};c.displayName=n;let u=e+`CollectionSlot`,d=t(u),f=T.forwardRef((e,t)=>{let{scope:n,children:i}=e;return(0,E.jsx)(d,{ref:r(t,s(u,n).collectionRef),children:i})});f.displayName=u;let p=e+`CollectionItemSlot`,m=`data-radix-collection-item`,h=t(p),g=T.forwardRef((e,t)=>{let{scope:n,children:i,...a}=e,o=T.useRef(null),c=r(t,o),l=s(p,n);return T.useEffect(()=>(l.itemMap.set(o,{ref:o,...a}),()=>void l.itemMap.delete(o))),(0,E.jsx)(h,{[m]:``,ref:c,children:i})});g.displayName=p;function _(t){let n=s(e+`CollectionConsumer`,t);return T.useCallback(()=>{let e=n.collectionRef.current;if(!e)return[];let t=Array.from(e.querySelectorAll(`[${m}]`));return Array.from(n.itemMap.values()).sort((e,n)=>t.indexOf(e.ref.current)-t.indexOf(n.ref.current))},[n.collectionRef,n.itemMap])}return[{Provider:c,Slot:f,ItemSlot:g},_,a]}var O=`rovingFocusGroup.onEntryFocus`,ee={bubbles:!1,cancelable:!0},k=`RovingFocusGroup`,[A,j,M]=D(k),[N,P]=l(k,[M]),[te,ne]=N(k),F=T.forwardRef((e,t)=>(0,E.jsx)(A.Provider,{scope:e.__scopeRovingFocusGroup,children:(0,E.jsx)(A.Slot,{scope:e.__scopeRovingFocusGroup,children:(0,E.jsx)(re,{...e,ref:t})})}));F.displayName=k;var re=T.forwardRef((e,t)=>{let{__scopeRovingFocusGroup:n,orientation:a,loop:o=!1,dir:s,currentTabStopId:c,defaultCurrentTabStopId:l,onCurrentTabStopIdChange:u,onEntryFocus:f,preventScrollOnEntryFocus:p=!1,...h}=e,v=T.useRef(null),y=r(t,v),b=d(s),[x,S]=_({prop:c,defaultProp:l??null,onChange:u,caller:k}),[C,w]=T.useState(!1),D=g(f),A=j(n),M=T.useRef(!1),[N,P]=T.useState(0);return T.useEffect(()=>{let e=v.current;if(e)return e.addEventListener(O,D),()=>e.removeEventListener(O,D)},[D]),(0,E.jsx)(te,{scope:n,orientation:a,dir:b,loop:o,currentTabStopId:x,onItemFocus:T.useCallback(e=>S(e),[S]),onItemShiftTab:T.useCallback(()=>w(!0),[]),onFocusableItemAdd:T.useCallback(()=>P(e=>e+1),[]),onFocusableItemRemove:T.useCallback(()=>P(e=>e-1),[]),children:(0,E.jsx)(i.div,{tabIndex:C||N===0?-1:0,"data-orientation":a,...h,ref:y,style:{outline:`none`,...e.style},onMouseDown:m(e.onMouseDown,()=>{M.current=!0}),onFocus:m(e.onFocus,e=>{let t=!M.current;if(e.target===e.currentTarget&&t&&!C){let t=new CustomEvent(O,ee);if(e.currentTarget.dispatchEvent(t),!t.defaultPrevented){let e=A().filter(e=>e.focusable);R([e.find(e=>e.active),e.find(e=>e.id===x),...e].filter(Boolean).map(e=>e.ref.current),p)}}M.current=!1}),onBlur:m(e.onBlur,()=>w(!1))})})}),I=`RovingFocusGroupItem`,L=T.forwardRef((e,t)=>{let{__scopeRovingFocusGroup:n,focusable:r=!0,active:a=!1,tabStopId:o,children:s,...c}=e,l=p(),u=o||l,d=ne(I,n),f=d.currentTabStopId===u,h=j(n),{onFocusableItemAdd:g,onFocusableItemRemove:_,currentTabStopId:v}=d;return T.useEffect(()=>{if(r)return g(),()=>_()},[r,g,_]),(0,E.jsx)(A.ItemSlot,{scope:n,id:u,focusable:r,active:a,children:(0,E.jsx)(i.span,{tabIndex:f?0:-1,"data-orientation":d.orientation,...c,ref:t,onMouseDown:m(e.onMouseDown,e=>{r?d.onItemFocus(u):e.preventDefault()}),onFocus:m(e.onFocus,()=>d.onItemFocus(u)),onKeyDown:m(e.onKeyDown,e=>{if(e.key===`Tab`&&e.shiftKey){d.onItemShiftTab();return}if(e.target!==e.currentTarget)return;let t=oe(e,d.orientation,d.dir);if(t!==void 0){if(e.metaKey||e.ctrlKey||e.altKey||e.shiftKey)return;e.preventDefault();let n=h().filter(e=>e.focusable).map(e=>e.ref.current);if(t===`last`)n.reverse();else if(t===`prev`||t===`next`){t===`prev`&&n.reverse();let r=n.indexOf(e.currentTarget);n=d.loop?se(n,r+1):n.slice(r+1)}setTimeout(()=>R(n))}}),children:typeof s==`function`?s({isCurrentTabStop:f,hasTabStop:v!=null}):s})})});L.displayName=I;var ie={ArrowLeft:`prev`,ArrowUp:`prev`,ArrowRight:`next`,ArrowDown:`next`,PageUp:`first`,Home:`first`,PageDown:`last`,End:`last`};function ae(e,t){return t===`rtl`?e===`ArrowLeft`?`ArrowRight`:e===`ArrowRight`?`ArrowLeft`:e:e}function oe(e,t,n){let r=ae(e.key,n);if(!(t===`vertical`&&[`ArrowLeft`,`ArrowRight`].includes(r))&&!(t===`horizontal`&&[`ArrowUp`,`ArrowDown`].includes(r)))return ie[r]}function R(e,t=!1){let n=document.activeElement;for(let r of e)if(r===n||(r.focus({preventScroll:t}),document.activeElement!==n))return}function se(e,t){return e.map((n,r)=>e[(t+r)%e.length])}var ce=F,le=L,z=`Tabs`,[ue,de]=l(z,[P]),B=P(),[fe,V]=ue(z),H=T.forwardRef((e,t)=>{let{__scopeTabs:n,value:r,onValueChange:a,defaultValue:o,orientation:s=`horizontal`,dir:c,activationMode:l=`automatic`,...u}=e,f=d(c),[m,h]=_({prop:r,onChange:a,defaultProp:o??``,caller:z});return(0,E.jsx)(fe,{scope:n,baseId:p(),value:m,onValueChange:h,orientation:s,dir:f,activationMode:l,children:(0,E.jsx)(i.div,{dir:f,"data-orientation":s,...u,ref:t})})});H.displayName=z;var U=`TabsList`,W=T.forwardRef((e,t)=>{let{__scopeTabs:n,loop:r=!0,...a}=e,o=V(U,n),s=B(n);return(0,E.jsx)(ce,{asChild:!0,...s,orientation:o.orientation,dir:o.dir,loop:r,children:(0,E.jsx)(i.div,{role:`tablist`,"aria-orientation":o.orientation,...a,ref:t})})});W.displayName=U;var G=`TabsTrigger`,K=T.forwardRef((e,t)=>{let{__scopeTabs:n,value:r,disabled:a=!1,...o}=e,s=V(G,n),c=B(n),l=J(s.baseId,r),u=Y(s.baseId,r),d=r===s.value;return(0,E.jsx)(le,{asChild:!0,...c,focusable:!a,active:d,children:(0,E.jsx)(i.button,{type:`button`,role:`tab`,"aria-selected":d,"aria-controls":u,"data-state":d?`active`:`inactive`,"data-disabled":a?``:void 0,disabled:a,id:l,...o,ref:t,onMouseDown:m(e.onMouseDown,e=>{!a&&e.button===0&&e.ctrlKey===!1?s.onValueChange(r):e.preventDefault()}),onKeyDown:m(e.onKeyDown,e=>{[` `,`Enter`].includes(e.key)&&s.onValueChange(r)}),onFocus:m(e.onFocus,()=>{let e=s.activationMode!==`manual`;!d&&!a&&e&&s.onValueChange(r)})})})});K.displayName=G;var q=`TabsContent`,pe=T.forwardRef((e,t)=>{let{__scopeTabs:n,value:r,forceMount:a,children:o,...s}=e,c=V(q,n),l=J(c.baseId,r),u=Y(c.baseId,r),d=r===c.value,f=T.useRef(d);return T.useEffect(()=>{let e=requestAnimationFrame(()=>f.current=!1);return()=>cancelAnimationFrame(e)},[]),(0,E.jsx)(h,{present:a||d,children:({present:n})=>(0,E.jsx)(i.div,{"data-state":d?`active`:`inactive`,"data-orientation":c.orientation,role:`tabpanel`,"aria-labelledby":l,hidden:!n,id:u,tabIndex:0,...s,ref:t,style:{...e.style,animationDuration:f.current?`0s`:void 0},children:n&&o})})});pe.displayName=q;function J(e,t){return`${e}-trigger-${t}`}function Y(e,t){return`${e}-content-${t}`}var me=H,he=W,ge=K;function _e({className:e,...t}){return(0,E.jsx)(`div`,{"data-slot":`table-container`,className:`relative w-full overflow-x-auto`,children:(0,E.jsx)(`table`,{"data-slot":`table`,className:o(`w-full caption-bottom text-sm`,e),...t})})}function ve({className:e,...t}){return(0,E.jsx)(`thead`,{"data-slot":`table-header`,className:o(`[&_tr]:border-b`,e),...t})}function ye({className:e,...t}){return(0,E.jsx)(`tbody`,{"data-slot":`table-body`,className:o(`[&_tr:last-child]:border-0`,e),...t})}function X({className:e,...t}){return(0,E.jsx)(`tr`,{"data-slot":`table-row`,className:o(`border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted`,e),...t})}function Z({className:e,...t}){return(0,E.jsx)(`th`,{"data-slot":`table-head`,className:o(`h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,e),...t})}function Q({className:e,...t}){return(0,E.jsx)(`td`,{"data-slot":`table-cell`,className:o(`p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,e),...t})}function be({className:e,orientation:t=`horizontal`,...n}){return(0,E.jsx)(me,{"data-slot":`tabs`,"data-orientation":t,orientation:t,className:o(`group/tabs flex gap-2 data-[orientation=horizontal]:flex-col`,e),...n})}var xe=v(`group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col data-[variant=line]:rounded-none`,{variants:{variant:{default:`bg-muted`,line:`gap-1 bg-transparent`}},defaultVariants:{variant:`default`}});function Se({className:e,variant:t=`default`,...n}){return(0,E.jsx)(he,{"data-slot":`tabs-list`,"data-variant":t,className:o(xe({variant:t}),e),...n})}function Ce({className:e,...t}){return(0,E.jsx)(ge,{"data-slot":`tabs-trigger`,className:o(`relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,`group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent`,`data-[state=active]:bg-background data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:data-[state=active]:text-foreground`,`after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100`,e),...t})}var $=[`all`,`spec.init`,`spec.complete`,`review.submit`];function we(){let[e,t]=(0,T.useState)(`all`),{data:r,isLoading:i}=n(c(100,e===`all`?void 0:e)),{data:a}=n(s()),o=r?.entries??[],l=(a?.epics??[]).filter(e=>e.status!==`completed`);return(0,E.jsxs)(`div`,{className:`space-y-6`,children:[(0,E.jsx)(be,{value:e,onValueChange:t,children:(0,E.jsx)(Se,{children:$.map(e=>(0,E.jsx)(Ce,{value:e,className:`text-xs`,children:e===`all`?`All`:e},e))})}),i?(0,E.jsx)(`div`,{className:`space-y-2`,children:Array.from({length:5}).map((e,t)=>(0,E.jsx)(w,{className:`h-10 w-full`},`skel-${t}`))}):(0,E.jsx)(Te,{entries:o}),l.length>0&&(0,E.jsx)(Oe,{epics:l})]})}function Te({entries:e}){let[t,n]=(0,T.useState)(null);return(0,E.jsxs)(_e,{children:[(0,E.jsx)(ve,{children:(0,E.jsxs)(X,{children:[(0,E.jsx)(Z,{className:`w-44`,children:`Timestamp`}),(0,E.jsx)(Z,{className:`w-32`,children:`Action`}),(0,E.jsx)(Z,{children:`Target`}),(0,E.jsx)(Z,{children:`Detail`})]})}),(0,E.jsxs)(ye,{children:[e.map((e,r)=>{let i=t===r,a=!!e.detail&&e.detail.length>40;return(0,E.jsxs)(X,{className:a?`cursor-pointer hover:bg-accent/50`:``,onClick:()=>a&&n(i?null:r),children:[(0,E.jsx)(Q,{className:`text-xs text-muted-foreground font-mono align-top`,children:ke(e.timestamp)}),(0,E.jsx)(Q,{className:`align-top`,children:(0,E.jsx)(De,{action:e.action})}),(0,E.jsx)(Q,{className:`text-sm align-top`,children:e.target}),(0,E.jsx)(Q,{className:`text-xs text-muted-foreground`,children:i?(0,E.jsx)(`div`,{className:`whitespace-pre-wrap break-words max-w-lg`,children:e.detail}):(0,E.jsx)(`div`,{className:`max-w-xs truncate`,children:e.detail})})]},`${e.timestamp}-${r}`)}),e.length===0&&(0,E.jsx)(X,{children:(0,E.jsx)(Q,{colSpan:4,className:`text-center text-sm text-muted-foreground`,children:`No activity found.`})})]})]})}var Ee={"spec.init":`#40513b`,"spec.complete":`#2d8b7a`,"spec.delete":`#c0392b`,"review.submit":`#628141`,"living-spec.update":`#7b6b8d`};function De({action:e}){let t=Ee[e]??`#6b7280`;return(0,E.jsx)(y,{variant:`outline`,className:`text-xs`,style:{borderColor:`${t}40`,color:t},children:e})}function Oe({epics:e}){return(0,E.jsxs)(`div`,{className:`space-y-3`,children:[(0,E.jsx)(`h3`,{className:`text-sm font-medium text-foreground`,children:`Epics`}),(0,E.jsx)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:e.map(e=>{let t=e.total>0?e.completed/e.total*100:0;return(0,E.jsxs)(S,{children:[(0,E.jsx)(x,{className:`pb-2`,children:(0,E.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,E.jsx)(b,{className:`text-sm`,children:e.name}),(0,E.jsx)(y,{variant:`outline`,className:`text-xs`,children:e.status})]})}),(0,E.jsxs)(C,{className:`space-y-2`,children:[(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(f,{value:t,className:`h-1.5 flex-1`}),(0,E.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[e.completed,`/`,e.total]})]}),e.tasks&&e.tasks.length>0&&(0,E.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:e.tasks.map(e=>(0,E.jsx)(y,{variant:`outline`,className:`text-[10px]`,style:{borderColor:e.status===`completed`?`rgba(45,139,122,0.3)`:`rgba(107,114,128,0.3)`,color:e.status===`completed`?`#2d8b7a`:`#6b7280`},children:e.slug},e.slug))})]})]},e.slug)})})]})}function ke(e){try{return new Date(e).toLocaleString(`ja-JP`,{month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`})}catch{return e}}export{we as component};