claude-alfred 0.5.4 → 0.5.5

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 (46) hide show
  1. package/dist/cli.mjs +3 -3
  2. package/dist/{directives-DLIMozEm.mjs → directives-Dvhsj4fG.mjs} +1 -1
  3. package/dist/{dispatcher-DdpodHtR.mjs → dispatcher-DS5QWU4q.mjs} +4 -4
  4. package/dist/{post-tool-0hPkxEeL.mjs → post-tool-B0EQeqcE.mjs} +3 -3
  5. package/dist/{post-tool-CX9gx971.mjs → post-tool-yjM6Si0X.mjs} +60 -3
  6. package/dist/{pre-compact-DtSNYDqr.mjs → pre-compact-C6shzwMh.mjs} +1 -1
  7. package/dist/{server-DH1JBP9G.mjs → server-6hlWwBFI.mjs} +24 -3
  8. package/dist/{server-CDS36bqe.mjs → server-Dx1FDa8O.mjs} +0 -66
  9. package/dist/{session-start-H2v1gmUg.mjs → session-start-O9DZ1pA7.mjs} +2 -2
  10. package/dist/{user-prompt-pZkrTHTQ.mjs → user-prompt-BZDKtk1x.mjs} +2 -2
  11. package/package.json +1 -1
  12. package/web/dist/assets/activity-dp8rJMYT.js +1 -0
  13. package/web/dist/assets/{api-SvfW-eaA.js → api-CRsy1HGN.js} +31 -31
  14. package/web/dist/assets/{badge-DQiF8V-T.js → badge-VLFQLwyS.js} +1 -1
  15. package/web/dist/assets/butler-empty-0madVwGs.js +1 -0
  16. package/web/dist/assets/button-C0o0iF3L.js +1 -0
  17. package/web/dist/assets/{dist-CioCuCJo.js → dist-BRZlYS80.js} +1 -1
  18. package/web/dist/assets/dist-DDKeJCSx.js +5 -0
  19. package/web/dist/assets/{es2015-Ba4HP1JV.js → es2015-C0hu_2KU.js} +1 -1
  20. package/web/dist/assets/{format-yfPPmP4I.js → format-CAUAxhcS.js} +1 -2
  21. package/web/dist/assets/index-Cds6GNiu.css +1 -0
  22. package/web/dist/assets/index-DQUDXHAT.js +10 -0
  23. package/web/dist/assets/knowledge-DdY6l8K_.js +14 -0
  24. package/web/dist/assets/{lib-CAPAdKcl.js → lib-Be929RPj.js} +3 -3
  25. package/web/dist/assets/{link-BUI8NSjI.js → link-CuBkPZlr.js} +1 -1
  26. package/web/dist/assets/{preload-helper-DGQaynfd.js → preload-helper-BtHw-6WQ.js} +1 -1
  27. package/web/dist/assets/projects-CI90XuW9.js +1 -0
  28. package/web/dist/assets/routes-CvyTrL8Z.js +9 -0
  29. package/web/dist/assets/skeleton-B-QvmrGK.js +1 -0
  30. package/web/dist/assets/{status-badge-lw-4vLCz.js → status-badge-CtuiN7AA.js} +2 -2
  31. package/web/dist/assets/{tasks-Dsm1XJYf.js → tasks-Veg0jsHG.js} +1 -1
  32. package/web/dist/assets/tasks._slug-C5HpFeT8.js +51 -0
  33. package/web/dist/assets/{tooltip-x6PhARM5.js → tooltip-D6J-Vmoz.js} +1 -1
  34. package/web/dist/assets/{use-view-mode-dARkzdlU.js → use-view-mode-B07iN0hy.js} +1 -1
  35. package/web/dist/assets/{wave-timeline-DhKSaNPe.js → wave-timeline-pUSQwb_A.js} +1 -1
  36. package/web/dist/index.html +10 -8
  37. package/web/dist/assets/activity-DkLCJ-SB.js +0 -1
  38. package/web/dist/assets/butler-empty-DJDx_tIO.js +0 -1
  39. package/web/dist/assets/detail-drawer-Do5HDzQb.js +0 -1
  40. package/web/dist/assets/index-BBJYZWxd.css +0 -1
  41. package/web/dist/assets/index-COtBBKDa.js +0 -14
  42. package/web/dist/assets/knowledge-DsfI7R0j.js +0 -14
  43. package/web/dist/assets/projects-CnKo47ec.js +0 -1
  44. package/web/dist/assets/routes-BvudKljh.js +0 -1
  45. package/web/dist/assets/skeleton-DaiiWyRB.js +0 -9
  46. package/web/dist/assets/tasks._slug-CYp5o6TD.js +0 -51
package/dist/cli.mjs CHANGED
@@ -371,7 +371,7 @@ const main = defineCommand({
371
371
  async run() {
372
372
  const { Store } = await import("./store-BhCFm1Tb.mjs").then((n) => (n.t(), n.r));
373
373
  const { Embedder } = await import("./embedder-9lsjLVC6.mjs");
374
- const { serveMCP } = await import("./server-DH1JBP9G.mjs");
374
+ const { serveMCP } = await import("./server-6hlWwBFI.mjs");
375
375
  const store = Store.openDefault();
376
376
  let emb = null;
377
377
  try {
@@ -401,7 +401,7 @@ const main = defineCommand({
401
401
  const { join } = await import("node:path");
402
402
  const { Store } = await import("./store-BhCFm1Tb.mjs").then((n) => (n.t(), n.r));
403
403
  const { Embedder } = await import("./embedder-9lsjLVC6.mjs");
404
- const { startDashboard } = await import("./server-CDS36bqe.mjs");
404
+ const { startDashboard } = await import("./server-Dx1FDa8O.mjs");
405
405
  const { resolveOrRegisterProject } = await import("./project-DKLV_Zw3.mjs").then((n) => (n.n(), n.a));
406
406
  const { syncAllProjectSpecs } = await import("./spec-sync-BYLLyRG3.mjs");
407
407
  const cwd = process.cwd();
@@ -431,7 +431,7 @@ const main = defineCommand({
431
431
  description: "Event name"
432
432
  } },
433
433
  async run({ args }) {
434
- const { runHook } = await import("./dispatcher-DdpodHtR.mjs").then((n) => (n.i(), n.t));
434
+ const { runHook } = await import("./dispatcher-DS5QWU4q.mjs").then((n) => (n.i(), n.t));
435
435
  await runHook(args.event);
436
436
  }
437
437
  }),
@@ -3,7 +3,7 @@ import { n as __esmMin } from "./chunk-CAm0Jl7e.mjs";
3
3
  import { a as getKnowledgeByIDs, l as incrementHitCount, p as searchKnowledgeKeyword, u as init_knowledge } from "./knowledge-7gqtk8yz.mjs";
4
4
  import { r as vectorSearchKnowledge, t as init_vectors } from "./vectors-BVQ0dz9J.mjs";
5
5
  import { a as subTypeBoost, o as subTypeHalfLife, r as searchKnowledgeFTS, t as init_fts } from "./fts-CG3NjtDr.mjs";
6
- import { i as init_dispatcher, n as emitAdditionalContext } from "./dispatcher-DdpodHtR.mjs";
6
+ import { i as init_dispatcher, n as emitAdditionalContext } from "./dispatcher-DS5QWU4q.mjs";
7
7
  //#region src/mcp/helpers.ts
8
8
  function truncate(s, maxLen) {
9
9
  const runes = [...s];
@@ -89,19 +89,19 @@ async function runHook(event) {
89
89
  }
90
90
  }
91
91
  async function handleSessionStart(ev, signal) {
92
- const { sessionStart } = await import("./session-start-H2v1gmUg.mjs");
92
+ const { sessionStart } = await import("./session-start-O9DZ1pA7.mjs");
93
93
  await sessionStart(ev, signal);
94
94
  }
95
95
  async function handlePreCompact(ev, signal) {
96
- const { preCompact } = await import("./pre-compact-DtSNYDqr.mjs");
96
+ const { preCompact } = await import("./pre-compact-C6shzwMh.mjs");
97
97
  await preCompact(ev, signal);
98
98
  }
99
99
  async function handleUserPromptSubmit(ev, signal) {
100
- const { userPromptSubmit } = await import("./user-prompt-pZkrTHTQ.mjs");
100
+ const { userPromptSubmit } = await import("./user-prompt-BZDKtk1x.mjs");
101
101
  await userPromptSubmit(ev, signal);
102
102
  }
103
103
  async function handlePostToolUse(ev, signal) {
104
- const { postToolUse } = await import("./post-tool-0hPkxEeL.mjs");
104
+ const { postToolUse } = await import("./post-tool-B0EQeqcE.mjs");
105
105
  await postToolUse(ev, signal);
106
106
  }
107
107
  async function handlePreToolUse(ev, _signal) {
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import "./types-BucChDqv.mjs";
3
3
  import "./audit-tp3tpgzR.mjs";
4
- import "./dispatcher-DdpodHtR.mjs";
5
- import "./directives-DLIMozEm.mjs";
6
- import { a as postToolUse, n as init_post_tool } from "./post-tool-CX9gx971.mjs";
4
+ import "./dispatcher-DS5QWU4q.mjs";
5
+ import "./directives-Dvhsj4fG.mjs";
6
+ import { n as init_post_tool, o as postToolUse } from "./post-tool-yjM6Si0X.mjs";
7
7
  import "./store-BhCFm1Tb.mjs";
8
8
  import "./review-gate-PHUE_mEA.mjs";
9
9
  import "./state-7-p9AqA6.mjs";
@@ -6,8 +6,8 @@ import { f as promoteSubType, h as upsertKnowledge, i as getKnowledgeByID, o as
6
6
  import { o as subTypeHalfLife, r as searchKnowledgeFTS, t as init_fts } from "./fts-CG3NjtDr.mjs";
7
7
  import { n as init_project, s as resolveOrRegisterProject } from "./project-DKLV_Zw3.mjs";
8
8
  import { n as init_user, t as getGitUserName } from "./user-BRphWhLv.mjs";
9
- import { a as notifyUser, i as init_dispatcher } from "./dispatcher-DdpodHtR.mjs";
10
- import { a as trackHitCounts, i as searchPipeline, n as init_directives, o as truncate, r as init_helpers, t as emitDirectives } from "./directives-DLIMozEm.mjs";
9
+ import { a as notifyUser, i as init_dispatcher } from "./dispatcher-DS5QWU4q.mjs";
10
+ import { a as trackHitCounts, i as searchPipeline, n as init_directives, o as truncate, r as init_helpers, t as emitDirectives } from "./directives-Dvhsj4fG.mjs";
11
11
  import { n as openDefaultCached, t as init_store } from "./store-BhCFm1Tb.mjs";
12
12
  import { a as writeReviewGate, d as init_spec_guard, n as init_review_gate, p as isSpecFilePath } from "./review-gate-PHUE_mEA.mjs";
13
13
  import { a as readStateJSON, d as writeStateJSON, f as writeStateText, i as parseWaveProgress, o as readStateText, p as writeWaveProgress, r as init_state, s as readWaveProgress, t as addWorkedSlug } from "./state-7-p9AqA6.mjs";
@@ -655,6 +655,7 @@ var post_tool_exports = /* @__PURE__ */ __exportAll({
655
655
  detectWaveCompletion: () => detectWaveCompletion,
656
656
  isGitCommit: () => isGitCommit,
657
657
  isTestFailure: () => isTestFailure,
658
+ matchTaskDescription: () => matchTaskDescription,
658
659
  postToolUse: () => postToolUse
659
660
  });
660
661
  function readExploreCount(cwd) {
@@ -699,6 +700,7 @@ async function postToolUse(ev, signal) {
699
700
  if ((ev.tool_name === "Edit" || ev.tool_name === "Write") && ev.tool_input) {
700
701
  const input = ev.tool_input;
701
702
  const filePath = typeof input.file_path === "string" ? input.file_path : "";
703
+ if (filePath) autoCheckTasks(ev.cwd, filePath, items);
702
704
  try {
703
705
  const slug = readActive(ev.cwd);
704
706
  addWorkedSlug(ev.cwd, slug);
@@ -732,6 +734,8 @@ async function handleBashResult(ev, items, signal) {
732
734
  }
733
735
  if (response.exitCode === 0) {
734
736
  const stdout = response.stdout ?? "";
737
+ const commandStr = typeof ev.tool_input === "object" && ev.tool_input !== null ? ev.tool_input.command ?? "" : "";
738
+ autoCheckTasks(ev.cwd, `${stdout}\n${commandStr}`, items);
735
739
  if (isGitCommit(stdout) && !signal.aborted) {
736
740
  trackFirstCommit(ev.cwd, stdout);
737
741
  let appendedFiles = /* @__PURE__ */ new Set();
@@ -773,6 +777,59 @@ async function searchErrorContext(_projectPath, errorText, items) {
773
777
  } catch {}
774
778
  }
775
779
  /**
780
+ * Auto-check tasks.md checkboxes when implementation matches task descriptions.
781
+ * Uses file path matching for backtick-quoted paths + filename matching.
782
+ * NOTE: Does NOT emit unchecked count CONTEXT — that caused Claude to stall (#27).
783
+ */
784
+ function autoCheckTasks(projectPath, context, items) {
785
+ try {
786
+ const taskSlug = readActive(projectPath);
787
+ const sd = new SpecDir(projectPath, taskSlug);
788
+ let tasks;
789
+ try {
790
+ tasks = sd.readFile("tasks.md");
791
+ } catch {
792
+ return;
793
+ }
794
+ const lines = tasks.split("\n");
795
+ let changed = false;
796
+ for (let i = 0; i < lines.length; i++) {
797
+ const line = lines[i];
798
+ const match = line.match(/^- \[ \] (.+)$/);
799
+ if (!match) continue;
800
+ const description = match[1];
801
+ if (matchTaskDescription(description, context)) {
802
+ lines[i] = line.replace("- [ ]", "- [x]");
803
+ changed = true;
804
+ }
805
+ }
806
+ if (changed) {
807
+ const updatedContent = lines.join("\n");
808
+ sd.writeFile("tasks.md", updatedContent);
809
+ const waveItems = detectWaveCompletion(projectPath, taskSlug, updatedContent);
810
+ items.push(...waveItems);
811
+ }
812
+ } catch {}
813
+ }
814
+ /**
815
+ * Match a task description against context (stdout/file path).
816
+ * Strategies:
817
+ * 1. Backtick-quoted paths in description matched against context
818
+ * 2. Filename matching (extension-bearing words matched against context)
819
+ */
820
+ function matchTaskDescription(description, context) {
821
+ if (!context || !description) return false;
822
+ const lowerCtx = context.toLowerCase();
823
+ const backtickPaths = description.match(/`([^`]+\.[a-z]+)`/g);
824
+ if (backtickPaths) for (const quoted of backtickPaths) {
825
+ const path = quoted.slice(1, -1);
826
+ if (lowerCtx.includes(path.toLowerCase())) return true;
827
+ }
828
+ const filenames = [...description.matchAll(/\b([\w.-]+\.[a-z]{1,4})\b/gi)].map((m) => m[1].toLowerCase()).filter((f) => f.length > 4 && !f.startsWith("."));
829
+ for (const fname of filenames) if (lowerCtx.includes(fname)) return true;
830
+ return false;
831
+ }
832
+ /**
776
833
  * Detect wave completion after tasks.md update.
777
834
  * When all tasks in a wave are checked: emit DIRECTIVE + set review gate.
778
835
  */
@@ -936,4 +993,4 @@ var init_post_tool = __esmMin((() => {
936
993
  init_review_gate();
937
994
  }));
938
995
  //#endregion
939
- export { postToolUse as a, updateTaskStatus as c, isTestFailure as i, handleLedger as l, init_post_tool as n, post_tool_exports as o, isGitCommit as r, init_status as s, detectWaveCompletion as t, init_ledger as u };
996
+ export { matchTaskDescription as a, init_status as c, init_ledger as d, isTestFailure as i, updateTaskStatus as l, init_post_tool as n, postToolUse as o, isGitCommit as r, post_tool_exports as s, detectWaveCompletion as t, handleLedger as u };
@@ -4,7 +4,7 @@ import { c as readActive, d as reviewStatusFor, h as verifyReviewFile, l as read
4
4
  import { n as init_audit, t as appendAudit } from "./audit-tp3tpgzR.mjs";
5
5
  import { h as upsertKnowledge, u as init_knowledge } from "./knowledge-7gqtk8yz.mjs";
6
6
  import { n as init_project, s as resolveOrRegisterProject } from "./project-DKLV_Zw3.mjs";
7
- import { a as notifyUser, i as init_dispatcher } from "./dispatcher-DdpodHtR.mjs";
7
+ import { a as notifyUser, i as init_dispatcher } from "./dispatcher-DS5QWU4q.mjs";
8
8
  import { n as openDefaultCached, t as init_store } from "./store-BhCFm1Tb.mjs";
9
9
  import { readFileSync, writeFileSync } from "node:fs";
10
10
  import { join } from "node:path";
@@ -6,10 +6,10 @@ import { a as getKnowledgeByIDs, u as init_knowledge } from "./knowledge-7gqtk8y
6
6
  import { r as vectorSearchKnowledge, t as init_vectors } from "./vectors-BVQ0dz9J.mjs";
7
7
  import { a as subTypeBoost, r as searchKnowledgeFTS, t as init_fts } from "./fts-CG3NjtDr.mjs";
8
8
  import { n as init_user, t as getGitUserName } from "./user-BRphWhLv.mjs";
9
- import "./dispatcher-DdpodHtR.mjs";
9
+ import "./dispatcher-DS5QWU4q.mjs";
10
10
  import { n as shouldAutoAppend, t as init_lang_filter } from "./lang-filter--xQlqF9A.mjs";
11
- import { o as truncate, r as init_helpers } from "./directives-DLIMozEm.mjs";
12
- import { c as updateTaskStatus, l as handleLedger, n as init_post_tool, o as post_tool_exports, s as init_status, u as init_ledger } from "./post-tool-CX9gx971.mjs";
11
+ import { o as truncate, r as init_helpers } from "./directives-Dvhsj4fG.mjs";
12
+ import { c as init_status, d as init_ledger, l as updateTaskStatus, n as init_post_tool, s as post_tool_exports, u as handleLedger } from "./post-tool-yjM6Si0X.mjs";
13
13
  import "./store-BhCFm1Tb.mjs";
14
14
  import { a as writeReviewGate, i as readReviewGate, n as init_review_gate, t as clearReviewGate } from "./review-gate-PHUE_mEA.mjs";
15
15
  import { d as writeStateJSON, n as ensureStateDir, p as writeWaveProgress, r as init_state, s as readWaveProgress, u as stateDir } from "./state-7-p9AqA6.mjs";
@@ -19323,6 +19323,27 @@ function dossierCheck(projectPath, params) {
19323
19323
  }
19324
19324
  }
19325
19325
  if (!checked && closingIndex < nth) return errorResult(`task_id "${taskId}" not found: Closing Wave has only ${closingIndex} item(s)`);
19326
+ } else if (taskId.match(/^T-\d+\.R$/i)) {
19327
+ const headerPattern = new RegExp(`^###\\s+${taskId.replace(".", "\\.")}\\b`, "i");
19328
+ let foundHeader = false;
19329
+ for (let i = 0; i < lines.length; i++) {
19330
+ const line = lines[i];
19331
+ if (headerPattern.test(line)) {
19332
+ foundHeader = true;
19333
+ continue;
19334
+ }
19335
+ if (foundHeader && /^- \[ \] /.test(line)) {
19336
+ lines[i] = line.replace("- [ ]", "- [x]");
19337
+ checked = true;
19338
+ break;
19339
+ }
19340
+ if (foundHeader && /^- \[[xX]\] /.test(line)) return jsonResult({
19341
+ task_id: taskId,
19342
+ status: "already_checked"
19343
+ });
19344
+ if (foundHeader && /^##[# ]/.test(line)) break;
19345
+ }
19346
+ if (!checked && !foundHeader) return errorResult(`task_id "${taskId}" not found in tasks.md`);
19326
19347
  } else {
19327
19348
  for (let i = 0; i < lines.length; i++) {
19328
19349
  const line = lines[i];
@@ -2631,72 +2631,6 @@ function createApp(projectPath, store, _emb, version) {
2631
2631
  project_name: proj.name
2632
2632
  });
2633
2633
  });
2634
- app.get("/api/briefing", (c) => {
2635
- const filterProjectId = getProjectFilter(c.req.query("project"));
2636
- try {
2637
- const activeProjects = filterProjectId ? [getProject(store, filterProjectId)].filter(Boolean) : listActiveProjects(store);
2638
- const activeSpecs = [];
2639
- const recentCompletions = [];
2640
- const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2641
- for (const p of activeProjects) {
2642
- if (!p || !existsSync(p.path)) continue;
2643
- const result = collectProjectTasks(p.path, p.name, p.id);
2644
- for (const t of result.tasks) {
2645
- const status = t.status;
2646
- const waves = t.waves;
2647
- if (status === "completed" || status === "done") {
2648
- const completedAt = t.completed_at;
2649
- if (completedAt && completedAt.slice(0, 10) === today) recentCompletions.push({
2650
- slug: t.slug,
2651
- completedAt
2652
- });
2653
- continue;
2654
- }
2655
- if (status === "cancelled" || status === "deferred") continue;
2656
- if (waves && waves.length > 0) {
2657
- const nonClosing = waves.filter((w) => w.key !== "closing");
2658
- const currentIdx = nonClosing.findIndex((w) => w.isCurrent);
2659
- const currentWave = currentIdx >= 0 ? currentIdx + 1 : nonClosing.length;
2660
- const totalWaves = nonClosing.length;
2661
- const totalAll = waves.reduce((s, w) => s + w.total, 0);
2662
- const totalChecked = waves.reduce((s, w) => s + w.checked, 0);
2663
- activeSpecs.push({
2664
- slug: t.slug,
2665
- currentWave,
2666
- totalWaves,
2667
- remainingTasks: totalAll - totalChecked
2668
- });
2669
- } else activeSpecs.push({
2670
- slug: t.slug,
2671
- currentWave: 1,
2672
- totalWaves: 1,
2673
- remainingTasks: (t.total ?? 0) - (t.completed ?? 0)
2674
- });
2675
- }
2676
- }
2677
- const knowledgeTotal = getKnowledgeStats(store, filterProjectId).total;
2678
- const now = (/* @__PURE__ */ new Date()).toISOString();
2679
- const projectFilter = filterProjectId ? "AND ki.project_id = ?" : "";
2680
- const overdueParams = [now];
2681
- if (filterProjectId) overdueParams.push(filterProjectId);
2682
- const overdueVerifications = store.db.prepare(`SELECT COUNT(*) as cnt FROM knowledge_index ki WHERE ki.enabled = 1 AND ki.verification_due IS NOT NULL AND ki.verification_due < ? ${projectFilter}`).get(...overdueParams)?.cnt ?? 0;
2683
- return c.json({
2684
- activeSpecs,
2685
- completedToday: recentCompletions.length,
2686
- knowledgeTotal,
2687
- overdueVerifications,
2688
- recentCompletions
2689
- });
2690
- } catch {
2691
- return c.json({
2692
- activeSpecs: [],
2693
- completedToday: 0,
2694
- knowledgeTotal: 0,
2695
- overdueVerifications: 0,
2696
- recentCompletions: []
2697
- });
2698
- }
2699
- });
2700
2634
  app.get("/api/tasks/:slug/specs/:file", (c) => {
2701
2635
  const slug = c.req.param("slug");
2702
2636
  const file = c.req.param("file");
@@ -3,8 +3,8 @@ import { n as __esmMin } from "./chunk-CAm0Jl7e.mjs";
3
3
  import { c as readActive, l as readActiveState, s as init_types, t as SpecDir } from "./types-BucChDqv.mjs";
4
4
  import { c as getRecentDecisions, h as upsertKnowledge, n as countKnowledge, r as deleteOrphanKnowledge, u as init_knowledge } from "./knowledge-7gqtk8yz.mjs";
5
5
  import { n as init_project, s as resolveOrRegisterProject } from "./project-DKLV_Zw3.mjs";
6
- import { a as notifyUser, i as init_dispatcher, r as extractSection } from "./dispatcher-DdpodHtR.mjs";
7
- import { n as init_directives, o as truncate, r as init_helpers, t as emitDirectives } from "./directives-DLIMozEm.mjs";
6
+ import { a as notifyUser, i as init_dispatcher, r as extractSection } from "./dispatcher-DS5QWU4q.mjs";
7
+ import { n as init_directives, o as truncate, r as init_helpers, t as emitDirectives } from "./directives-Dvhsj4fG.mjs";
8
8
  import { n as openDefaultCached, t as init_store } from "./store-BhCFm1Tb.mjs";
9
9
  import { d as writeStateJSON, l as resetWorkedSlugs, r as init_state } from "./state-7-p9AqA6.mjs";
10
10
  import { existsSync, readFileSync, readdirSync } from "node:fs";
@@ -3,8 +3,8 @@ import { n as __esmMin } from "./chunk-CAm0Jl7e.mjs";
3
3
  import { l as readActiveState, s as init_types } from "./types-BucChDqv.mjs";
4
4
  import { a as subTypeBoost, t as init_fts } from "./fts-CG3NjtDr.mjs";
5
5
  import { Embedder, t as init_embedder } from "./embedder-9lsjLVC6.mjs";
6
- import "./dispatcher-DdpodHtR.mjs";
7
- import { a as trackHitCounts, i as searchPipeline, n as init_directives, o as truncate, r as init_helpers, t as emitDirectives } from "./directives-DLIMozEm.mjs";
6
+ import "./dispatcher-DS5QWU4q.mjs";
7
+ import { a as trackHitCounts, i as searchPipeline, n as init_directives, o as truncate, r as init_helpers, t as emitDirectives } from "./directives-Dvhsj4fG.mjs";
8
8
  import { n as openDefaultCached, t as init_store } from "./store-BhCFm1Tb.mjs";
9
9
  import { a as readStateJSON, c as readWorkedSlugs, d as writeStateJSON, n as ensureStateDir, r as init_state } from "./state-7-p9AqA6.mjs";
10
10
  import { appendFileSync, existsSync, readFileSync, writeFileSync } from "node:fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-alfred",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "alfred": "dist/cli.mjs"
@@ -0,0 +1 @@
1
+ import{Wt as e,_t as t,at as n,g as r,gt as i,n as a,r as o,rt as s,t as c,y as l}from"./api-CRsy1HGN.js";import{t as u}from"./link-CuBkPZlr.js";import{i as d,n as f,t as p}from"./tooltip-D6J-Vmoz.js";import"./es2015-C0hu_2KU.js";import{a as m,i as h,n as g,o as _,s as v,t as y}from"./dist-DDKeJCSx.js";var b=e(t(),1),x=i();function S({analytics:e}){let{t}=s(),n=e.reworkRates.filter(e=>!e.pending),r=n.length>0?n.reduce((e,t)=>e+t.reworkRate,0)/n.length:0,i=e.cycleTimeBreakdown.length>0?e.cycleTimeBreakdown.reduce((e,t)=>e+t.phases.total,0)/e.cycleTimeBreakdown.length:0,a=e.cycleTimeBreakdown.length;return(0,x.jsx)(`div`,{className:`grid gap-4 sm:grid-cols-3`,children:[{label:t(`activity.avgCycleTime`),value:`${i.toFixed(1)}`,unit:t(`activity.days`),color:`#628141`},{label:t(`activity.avgReworkRate`),value:`${(r*100).toFixed(0)}%`,unit:``,color:r>.15?`#c0392b`:`#2d8b7a`},{label:t(`activity.totalSpecs`),value:String(a),unit:``,color:`#40513b`}].map(e=>(0,x.jsxs)(`div`,{className:`rounded-organic border border-border/60 bg-card py-4 px-4`,children:[(0,x.jsx)(`p`,{className:`text-[11px] font-medium text-muted-foreground uppercase tracking-wider`,children:e.label}),(0,x.jsxs)(`p`,{className:`mt-1 text-2xl font-bold`,style:{fontFamily:`var(--font-display)`,color:e.color},children:[e.value,e.unit&&(0,x.jsx)(`span`,{className:`ml-1 text-sm font-normal text-muted-foreground`,children:e.unit})]})]},e.label))})}function C({analytics:e}){let{t}=s();if(e.reworkRates.length===0)return null;let n=Math.max(...e.reworkRates.map(e=>e.reworkRate),.01);return(0,x.jsxs)(`div`,{className:`rounded-organic border border-border/60 bg-card py-4 px-4`,children:[(0,x.jsx)(`h3`,{className:`text-sm font-semibold mb-3`,children:t(`activity.rework.title`)}),(0,x.jsx)(`div`,{className:`space-y-3`,children:e.reworkRates.map(e=>{let t=Math.round(e.reworkRate*100),r=Math.max(e.reworkRate/n*100,2);return(0,x.jsxs)(`div`,{children:[(0,x.jsxs)(`div`,{className:`flex items-baseline justify-between mb-1`,children:[(0,x.jsx)(`span`,{className:`text-[11px] font-mono text-foreground/80`,children:e.slug}),(0,x.jsxs)(`span`,{className:`text-[11px] font-mono text-muted-foreground`,children:[t,`%`]})]}),(0,x.jsx)(`div`,{className:`h-4 bg-muted/30 rounded overflow-hidden`,children:(0,x.jsx)(`div`,{className:`h-full rounded`,style:{width:`${r}%`,backgroundColor:e.pending?`#e67e22`:`#2d8b7a`,opacity:e.pending?.5:1}})})]},e.slug)})}),e.reworkRates.some(e=>e.pending)&&(0,x.jsx)(`p`,{className:`text-[10px] text-muted-foreground mt-2`,children:t(`activity.rework.pending`)})]})}var w={planning:`#628141`,approval:`#e67e22`,implementation:`#2d8b7a`};function T({analytics:e}){let{t}=s();if(e.cycleTimeBreakdown.length===0)return null;let n=Math.max(...e.cycleTimeBreakdown.map(e=>e.phases.total),.1);return(0,x.jsxs)(`div`,{className:`rounded-organic border border-border/60 bg-card py-4 px-4`,children:[(0,x.jsx)(`h3`,{className:`text-sm font-semibold mb-3`,children:t(`activity.cycleTime.title`)}),(0,x.jsx)(`div`,{className:`space-y-3`,children:e.cycleTimeBreakdown.map(e=>{let r=e.phases,i=(r.planning??0)/n*100,a=(r.approvalWait??0)/n*100,o=(r.implementation??0)/n*100;return(0,x.jsxs)(`div`,{children:[(0,x.jsxs)(`div`,{className:`flex items-baseline justify-between mb-1`,children:[(0,x.jsx)(`span`,{className:`text-[11px] font-mono text-foreground/80`,children:e.slug}),(0,x.jsxs)(`span`,{className:`text-[11px] font-mono text-muted-foreground`,children:[r.total.toFixed(1),`d`]})]}),(0,x.jsxs)(`div`,{className:`h-4 bg-muted/30 rounded overflow-hidden flex`,children:[i>0&&(0,x.jsx)(`div`,{className:`h-full`,style:{width:`${i}%`,backgroundColor:w.planning},title:`${t(`activity.cycleTime.planning`)}: ${r.planning?.toFixed(1)}d`}),a>0&&(0,x.jsx)(`div`,{className:`h-full`,style:{width:`${a}%`,backgroundColor:w.approval},title:`${t(`activity.cycleTime.approval`)}: ${r.approvalWait?.toFixed(1)}d`}),o>0&&(0,x.jsx)(`div`,{className:`h-full`,style:{width:`${o}%`,backgroundColor:w.implementation},title:`${t(`activity.cycleTime.implementation`)}: ${r.implementation?.toFixed(1)}d`})]})]},e.slug)})}),(0,x.jsx)(`div`,{className:`flex gap-4 mt-3`,children:[`planning`,`approval`,`implementation`].map(e=>(0,x.jsxs)(`span`,{className:`flex items-center gap-1 text-[10px] text-muted-foreground`,children:[(0,x.jsx)(`span`,{className:`size-2 rounded-sm`,style:{backgroundColor:w[e]}}),t(`activity.cycleTime.${e}`)]},e))})]})}var E=12,D=E+2,O=28,k=16,A=7,j=[`var(--color-card)`,`#c8c4b8`,`#a8c4a0`,`#628141`,`#40513b`];function M(e){return e===0?j[0]:e<=2?j[1]:e<=5?j[2]:e<=10?j[3]:j[4]}function N(e){let t=e.getDay(),n=e.getDate()-t+(t===0?-6:1);return new Date(e.getFullYear(),e.getMonth(),n)}function P({data:e,weeks:t=16}){let{t:n}=s(),r=new Map;for(let t of e)r.set(t.date,t.count);let i=new Date,a=N(new Date(i.getFullYear(),i.getMonth(),i.getDate()-(t-1)*7)),o=[],c=[],l=-1;for(let e=0;e<t;e++)for(let t=0;t<A;t++){let n=new Date(a);if(n.setDate(n.getDate()+e*7+t),n>i)continue;let s=n.toISOString().slice(0,10),u=r.get(s)??0;o.push({date:s,count:u,col:e,row:t}),t===0&&n.getMonth()!==l&&(l=n.getMonth(),c.push({label:n.toLocaleDateString(`en`,{month:`short`}),col:e}))}let u=O+t*D,m=k+A*D;return(0,x.jsxs)(`div`,{className:`rounded-organic border border-border/60 bg-card py-4 px-4`,children:[(0,x.jsx)(`h3`,{className:`text-sm font-semibold mb-3`,children:n(`heatmap.title`)}),(0,x.jsx)(`div`,{className:`overflow-x-auto`,children:(0,x.jsxs)(`svg`,{width:u,height:m,className:`block`,children:[c.map(e=>(0,x.jsx)(`text`,{x:O+e.col*D,y:k-4,className:`fill-muted-foreground`,fontSize:10,children:e.label},`month-${e.col}`)),[`Mon`,``,`Wed`,``,`Fri`,``,``].map((e,t)=>e?(0,x.jsx)(`text`,{x:0,y:k+t*D+E-2,className:`fill-muted-foreground`,fontSize:10,children:e},`day-${t}`):null),o.map(e=>(0,x.jsxs)(p,{children:[(0,x.jsx)(d,{asChild:!0,children:(0,x.jsx)(`rect`,{x:O+e.col*D,y:k+e.row*D,width:E,height:E,rx:2,fill:M(e.count),className:`outline-1 outline-border/20`,"aria-label":n(`heatmap.tooltip`,{date:e.date,count:e.count})})}),(0,x.jsx)(f,{children:n(`heatmap.tooltip`,{date:e.date,count:e.count})})]},e.date))]})}),(0,x.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-2 justify-end`,children:[(0,x.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:n(`heatmap.less`)}),j.map((e,t)=>(0,x.jsx)(`span`,{className:`inline-block size-3 rounded-sm border border-border/20`,style:{backgroundColor:e}},t)),(0,x.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:n(`heatmap.more`)})]})]})}function F({...e}){return(0,x.jsx)(_,{"data-slot":`sheet`,...e})}function I({...e}){return(0,x.jsx)(m,{"data-slot":`sheet-portal`,...e})}function L({className:e,...t}){return(0,x.jsx)(h,{"data-slot":`sheet-overlay`,className:r(`fixed inset-0 z-50 bg-black/20 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0`,e),...t})}function R({className:e,children:t,side:n=`right`,showCloseButton:i=!0,...a}){return(0,x.jsxs)(I,{children:[(0,x.jsx)(L,{}),(0,x.jsxs)(g,{"data-slot":`sheet-content`,className:r(`fixed z-50 flex flex-col gap-4 bg-background transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:animate-in data-[state=open]:duration-500`,n===`right`&&`inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm`,n===`left`&&`inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm`,n===`top`&&`inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top`,n===`bottom`&&`inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom`,e),...a,children:[t,i&&(0,x.jsxs)(y,{className:`absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary`,children:[(0,x.jsx)(l,{className:`size-4`}),(0,x.jsx)(`span`,{className:`sr-only`,children:`Close`})]})]})]})}function z({className:e,...t}){return(0,x.jsx)(`div`,{"data-slot":`sheet-header`,className:r(`flex flex-col gap-1.5 p-4`,e),...t})}function B({className:e,...t}){return(0,x.jsx)(v,{"data-slot":`sheet-title`,className:r(`font-semibold text-foreground`,e),...t})}function V({open:e,onClose:t,title:n,children:r}){return(0,x.jsx)(F,{open:e,onOpenChange:e=>{e||t()},children:(0,x.jsxs)(R,{side:`right`,className:`max-w-[480px] w-full overflow-y-auto`,children:[(0,x.jsx)(z,{children:(0,x.jsx)(B,{className:`text-base`,children:n})}),(0,x.jsx)(`div`,{className:`py-4 space-y-4`,children:r})]})})}function H(){let{t:e}=s(),{data:t}=n(a()),{data:r}=n(o()),[i,l]=(0,b.useState)(0),{data:d}=n(c(i)),[f,p]=(0,b.useState)(null),m=t&&((t.reworkRates?.length??0)>0||(t.cycleTimeBreakdown?.length??0)>0);return(0,x.jsxs)(`div`,{className:`flex flex-col gap-6 h-[calc(100vh-8rem)]`,children:[(0,x.jsx)(`h1`,{className:`text-2xl font-bold tracking-tight shrink-0`,style:{fontFamily:`var(--font-display)`},children:e(`activity.title`)}),m?(0,x.jsxs)(`div`,{className:`shrink-0 space-y-6`,children:[(0,x.jsx)(S,{analytics:t}),(0,x.jsxs)(`div`,{className:`grid gap-6 lg:grid-cols-2`,children:[(0,x.jsx)(C,{analytics:t}),(0,x.jsx)(T,{analytics:t})]})]}):(0,x.jsxs)(`div`,{className:`flex flex-col items-center justify-center py-12 text-center shrink-0`,children:[(0,x.jsx)(`p`,{className:`text-lg font-medium text-muted-foreground`,style:{fontFamily:`var(--font-display)`},children:e(`activity.empty.title`)}),(0,x.jsx)(`p`,{className:`mt-2 text-sm text-muted-foreground/70`,children:e(`activity.empty.description`)})]}),(0,x.jsx)(`div`,{className:`shrink-0`,children:(0,x.jsx)(P,{data:r?.data??[],weeks:r?.weeks??16})}),(0,x.jsx)(U,{entries:d?.entries??[],total:d?.total??0,page:i,onPageChange:l,onSelect:p}),(0,x.jsx)(V,{open:!!f,onClose:()=>p(null),title:f?f.target?`${f.action} — ${f.target}`:f.action:``,children:f&&(0,x.jsxs)(`div`,{className:`space-y-3 text-sm`,children:[(0,x.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,x.jsx)(G,{event:f.action})}),(0,x.jsxs)(`div`,{className:`space-y-2`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`p`,{className:`text-[11px] text-muted-foreground uppercase tracking-wide`,children:e(`activity.log.slug`)}),f.target?(0,x.jsx)(u,{to:`/tasks/$slug`,params:{slug:f.target},className:`font-mono text-sm hover:underline`,style:{color:`#40513b`},children:f.target}):(0,x.jsx)(`p`,{className:`text-muted-foreground`,children:`—`})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`p`,{className:`text-[11px] text-muted-foreground uppercase tracking-wide`,children:e(`activity.log.actor`)}),(0,x.jsx)(`p`,{children:f.actor||`—`})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`p`,{className:`text-[11px] text-muted-foreground uppercase tracking-wide`,children:e(`activity.log.time`)}),(0,x.jsx)(`p`,{className:`font-mono text-[11px]`,children:new Date(f.timestamp).toLocaleString()})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`p`,{className:`text-[11px] text-muted-foreground uppercase tracking-wide`,children:e(`activity.log.detail`)}),(0,x.jsx)(`p`,{className:`whitespace-pre-wrap break-all text-[12px] leading-relaxed`,children:f.detail||`—`})]})]})]})})]})}function U({entries:e,total:t,page:n,onPageChange:r,onSelect:i}){let{t:a}=s(),o=Math.ceil(t/50);return(0,x.jsxs)(`div`,{className:`rounded-organic border border-border/60 bg-card flex flex-col min-h-0 flex-1`,children:[(0,x.jsxs)(`div`,{className:`flex items-center justify-between py-3 px-4 border-b border-border/30 shrink-0`,children:[(0,x.jsx)(`h3`,{className:`text-sm font-semibold`,children:a(`activity.log.title`)}),o>1&&(0,x.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px] text-muted-foreground`,children:[(0,x.jsxs)(`span`,{children:[t,` `,a(`activity.log.entries`)]}),(0,x.jsx)(`button`,{type:`button`,disabled:n===0,onClick:()=>r(n-1),className:`px-2 py-0.5 rounded border border-border/40 disabled:opacity-30`,children:a(`activity.log.prev`)}),(0,x.jsxs)(`span`,{children:[n+1,`/`,o]}),(0,x.jsx)(`button`,{type:`button`,disabled:n>=o-1,onClick:()=>r(n+1),className:`px-2 py-0.5 rounded border border-border/40 disabled:opacity-30`,children:a(`activity.log.next`)})]})]}),e.length===0?(0,x.jsx)(`p`,{className:`text-sm text-muted-foreground py-8 text-center`,children:a(`activity.noMetrics`)}):(0,x.jsx)(`div`,{className:`overflow-auto flex-1 min-h-0`,children:(0,x.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,x.jsx)(`thead`,{className:`sticky top-0 bg-card z-10`,children:(0,x.jsxs)(`tr`,{className:`border-b border-border/40 text-left text-[11px] text-muted-foreground uppercase tracking-wider`,children:[(0,x.jsx)(`th`,{className:`py-2 px-4 whitespace-nowrap`,children:a(`activity.log.time`)}),(0,x.jsx)(`th`,{className:`py-2 pr-3 whitespace-nowrap`,children:a(`activity.log.event`)}),(0,x.jsx)(`th`,{className:`py-2 pr-3 whitespace-nowrap`,children:a(`activity.log.slug`)}),(0,x.jsx)(`th`,{className:`py-2 pr-3 whitespace-nowrap`,children:a(`activity.log.actor`)}),(0,x.jsx)(`th`,{className:`py-2 pr-4`,children:a(`activity.log.detail`)})]})}),(0,x.jsx)(`tbody`,{children:e.map((e,t)=>(0,x.jsx)(K,{entry:e,onSelect:()=>i(e)},t))})]})})]})}var W={"spec.init":{bg:`#40513b20`,text:`#40513b`},"spec.complete":{bg:`#62814120`,text:`#628141`},"review.submit":{bg:`#2d8b7a20`,text:`#2d8b7a`},"gate.set":{bg:`#e67e2220`,text:`#e67e22`},"gate.clear":{bg:`#62814120`,text:`#628141`},"gate.fix":{bg:`#e67e2220`,text:`#e67e22`},first_commit:{bg:`#7b6b8d20`,text:`#7b6b8d`},"task.status_change":{bg:`#44403c15`,text:`#44403c`},"living-spec.update":{bg:`#2d8b7a15`,text:`#2d8b7a`},"rework.checked":{bg:`#c0392b20`,text:`#c0392b`}};function G({event:e}){let t=W[e]??{bg:`#44403c10`,text:`#44403c`};return(0,x.jsx)(`span`,{className:`inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-medium font-mono whitespace-nowrap`,style:{backgroundColor:t.bg,color:t.text},children:e})}function K({entry:e,onSelect:t}){return(0,x.jsx)(x.Fragment,{children:(0,x.jsxs)(`tr`,{className:`border-b border-border/10 last:border-0 hover:bg-muted/20 cursor-pointer`,onClick:t,children:[(0,x.jsx)(`td`,{className:`py-1.5 px-4 text-[11px] text-muted-foreground font-mono whitespace-nowrap`,children:q(e.timestamp)}),(0,x.jsx)(`td`,{className:`py-1.5 pr-3`,children:(0,x.jsx)(G,{event:e.action})}),(0,x.jsx)(`td`,{className:`py-1.5 pr-3 font-mono text-[11px]`,children:e.target}),(0,x.jsx)(`td`,{className:`py-1.5 pr-3 text-[11px] text-muted-foreground`,children:e.actor}),(0,x.jsx)(`td`,{className:`py-1.5 pr-4 text-[11px] text-muted-foreground`,children:(0,x.jsx)(`span`,{className:`truncate max-w-[300px] inline-block align-bottom`,children:e.detail})})]})})}function q(e){let t=new Date(e);return`${String(t.getMonth()+1).padStart(2,`0`)}/${String(t.getDate()).padStart(2,`0`)} ${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}`}export{H as component};