claude-alfred 0.3.14 → 0.3.16

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 (51) hide show
  1. package/README.ja.md +1 -1
  2. package/README.md +1 -1
  3. package/content/hooks/hooks.json +5 -0
  4. package/dist/cli.mjs +2 -2
  5. package/dist/{directives-BWPf6KVs.mjs → directives-BtMZZnDe.mjs} +1 -1
  6. package/dist/{dispatcher-CLRAWyYx.mjs → dispatcher-Bl7px8hy.mjs} +6 -6
  7. package/dist/{post-tool-C0hkS1sJ.mjs → post-tool-BL5YKl-j.mjs} +4 -4
  8. package/dist/{post-tool-CsM0XliT.mjs → post-tool-BRoelm73.mjs} +5 -5
  9. package/dist/{pre-compact-B7PQb3TM.mjs → pre-compact-DEqTQ_7v.mjs} +1 -1
  10. package/dist/pre-tool-YJGmHuiU.mjs +65 -0
  11. package/dist/{review-gate-BQMnScje.mjs → review-gate-0cGEW7jx.mjs} +15 -2
  12. package/dist/{server-9V6cWIBd.mjs → server-D2-ootz-.mjs} +6 -6
  13. package/dist/{session-start-_MNVxux-.mjs → session-start-CrZszyvc.mjs} +3 -3
  14. package/dist/{state-Bw1XMJxp.mjs → state-XSGGyez_.mjs} +2 -25
  15. package/dist/{stop-_ovIig2U.mjs → stop-gh3SchT6.mjs} +2 -2
  16. package/dist/{user-prompt-CCU3XlOv.mjs → user-prompt-la6CpECb.mjs} +3 -5
  17. package/package.json +1 -1
  18. package/web/dist/assets/activity-D7DAt7pk.js +1 -0
  19. package/web/dist/assets/{api-DUW_x4Qc.js → api-Tgguux9h.js} +1 -1
  20. package/web/dist/assets/{badge-CasOf-Iy.js → badge-DTZEkDjH.js} +1 -1
  21. package/web/dist/assets/card-BGzSdSzz.js +1 -0
  22. package/web/dist/assets/circle-check-D9SSjQ_w.js +1 -0
  23. package/web/dist/assets/circle-dot-D-WVSx5v.js +1 -0
  24. package/web/dist/assets/{circle-x-BVT5qi-w.js → circle-x-BvmeoEcf.js} +1 -1
  25. package/web/dist/assets/{createLucideIcon-5rRvYiBC.js → createLucideIcon-BqPHTYUC.js} +1 -1
  26. package/web/dist/assets/dist-B0kJ1bYO.js +1 -0
  27. package/web/dist/assets/{dist-YKGTWb04.js → dist-BGKsNkBS.js} +1 -1
  28. package/web/dist/assets/index-BGVUuzaa.css +1 -0
  29. package/web/dist/assets/{index-DGyD_f9j.js → index-DvnkHott.js} +3 -3
  30. package/web/dist/assets/{knowledge-C0koz_R_.js → knowledge-BqxA4We-.js} +2 -3
  31. package/web/dist/assets/{link-BBv-Zwrr.js → link-q518SX3M.js} +1 -1
  32. package/web/dist/assets/pagination-DtCkbiSH.js +1 -0
  33. package/web/dist/assets/{progress-Q8H-LYzC.js → progress-DWm7GXJf.js} +1 -1
  34. package/web/dist/assets/{routes-j_NFYRTo.js → routes-Bttr0L8B.js} +1 -1
  35. package/web/dist/assets/{scroll-area-WifYJqwD.js → scroll-area-1RaN3xD9.js} +1 -1
  36. package/web/dist/assets/separator-DNBh2gSt.js +1 -0
  37. package/web/dist/assets/{skeleton-W0NNrTUC.js → skeleton-DB1q8YGJ.js} +1 -1
  38. package/web/dist/assets/tasks-B_eJ-hie.js +1 -0
  39. package/web/dist/assets/{tasks._slug-BhDNz4kh.js → tasks._slug-CUfsXH19.js} +4 -4
  40. package/web/dist/assets/{useParams-pNbbxrTn.js → useParams-BDmwgE4R.js} +1 -1
  41. package/web/dist/index.html +6 -6
  42. package/dist/pre-tool-ptD5st2b.mjs +0 -72
  43. package/web/dist/assets/activity-C1FTqhFl.js +0 -1
  44. package/web/dist/assets/card-CHfuGvSw.js +0 -1
  45. package/web/dist/assets/circle-check-Cz0Ne7EA.js +0 -1
  46. package/web/dist/assets/circle-dot-ClhowmeB.js +0 -1
  47. package/web/dist/assets/dist-DqB2i2il.js +0 -1
  48. package/web/dist/assets/index-DF1Om0oI.css +0 -1
  49. package/web/dist/assets/pagination-0vUA_BUN.js +0 -1
  50. package/web/dist/assets/separator-BI3E_x2g.js +0 -1
  51. package/web/dist/assets/tasks-DuhUxMDe.js +0 -1
package/README.ja.md CHANGED
@@ -123,7 +123,7 @@ JSON ファイルとして Git にコミットし、PR でレビューし、チ
123
123
  | サイズ | ファイル数 | 用途 |
124
124
  |--------|-----------|------|
125
125
  | **S** | 2 | バグ修正、設定変更 |
126
- | **M** | 4 | 新エンドポイント、リファクタ |
126
+ | **M** | 3-4 | 新エンドポイント、リファクタ |
127
127
  | **L/XL** | 5 | アーキテクチャ変更、新サブシステム |
128
128
  | **D** | 1 | 既存コードへの差分変更 |
129
129
 
package/README.md CHANGED
@@ -123,7 +123,7 @@ Search pipeline: Voyage AI vectors with reranking > FTS5 with fuzzy matching > k
123
123
  | Size | Files | Good for |
124
124
  |------|-------|----------|
125
125
  | **S** | 2 | Bug fix, config tweak |
126
- | **M** | 4 | New endpoint, moderate refactor |
126
+ | **M** | 3-4 | New endpoint, moderate refactor |
127
127
  | **L/XL** | 5 | Architecture change, new subsystem |
128
128
  | **D** | 1 | Brownfield delta change |
129
129
 
@@ -58,6 +58,11 @@
58
58
  "statusMessage": "alfred: checking spec approval...",
59
59
  "timeout": 5,
60
60
  "type": "command"
61
+ },
62
+ {
63
+ "type": "prompt",
64
+ "prompt": "You are a spec-driven development gatekeeper. An Edit/Write tool is about to execute. The command handler already passed deterministic checks (review-gate, approval-gate).\n\nCheck the conversation context:\n1. If an active spec ALREADY EXISTS (dossier init was called, or spec context is visible in the conversation), respond {\"ok\": true} — the spec requirement is satisfied.\n2. If NO spec exists and this is a TRIVIAL change (typo fix, documentation update, config tweak, comment edit, style fix, renaming, version bump), respond {\"ok\": true} — no spec needed.\n3. If NO spec exists and this is SUBSTANTIAL work (new feature, bug fix requiring investigation, refactoring, architecture change), respond {\"ok\": false, \"reason\": \"This change requires a spec. Create one with: dossier action=init (use size=S for small changes, size=D for delta changes)\"}.\n\nWhen in doubt, allow it — false blocks are worse than missing specs.",
65
+ "timeout": 10
61
66
  }
62
67
  ]
63
68
  }
package/dist/cli.mjs CHANGED
@@ -371,7 +371,7 @@ const main = defineCommand({
371
371
  async run() {
372
372
  const { Store } = await import("./store-BffM-bi-.mjs").then((n) => (n.t(), n.r));
373
373
  const { Embedder } = await import("./embedder-D3hJoryD.mjs");
374
- const { serveMCP } = await import("./server-9V6cWIBd.mjs");
374
+ const { serveMCP } = await import("./server-D2-ootz-.mjs");
375
375
  const store = Store.openDefault();
376
376
  let emb = null;
377
377
  try {
@@ -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-CLRAWyYx.mjs").then((n) => (n.i(), n.t));
425
+ const { runHook } = await import("./dispatcher-Bl7px8hy.mjs").then((n) => (n.i(), n.t));
426
426
  await runHook(args.event);
427
427
  }
428
428
  }),
@@ -3,7 +3,7 @@ import { n as __esmMin } from "./chunk-CAm0Jl7e.mjs";
3
3
  import { c as incrementHitCount, f as searchKnowledgeKeyword, i as getKnowledgeByIDs, l as init_knowledge } from "./knowledge-C7rEfFSX.mjs";
4
4
  import { r as vectorSearchKnowledge, t as init_vectors } from "./vectors-DHZGQ096.mjs";
5
5
  import { a as subTypeBoost, i as searchKnowledgeFTS, o as subTypeHalfLife, r as init_fts } from "./fts-DICqcpG_.mjs";
6
- import { i as init_dispatcher, n as emitAdditionalContext } from "./dispatcher-CLRAWyYx.mjs";
6
+ import { i as init_dispatcher, n as emitAdditionalContext } from "./dispatcher-Bl7px8hy.mjs";
7
7
  //#region src/mcp/helpers.ts
8
8
  function truncate(s, maxLen) {
9
9
  const runes = [...s];
@@ -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-_MNVxux-.mjs");
92
+ const { sessionStart } = await import("./session-start-CrZszyvc.mjs");
93
93
  await sessionStart(ev, signal);
94
94
  }
95
95
  async function handlePreCompact(ev, signal) {
96
- const { preCompact } = await import("./pre-compact-B7PQb3TM.mjs");
96
+ const { preCompact } = await import("./pre-compact-DEqTQ_7v.mjs");
97
97
  await preCompact(ev, signal);
98
98
  }
99
99
  async function handleUserPromptSubmit(ev, signal) {
100
- const { userPromptSubmit } = await import("./user-prompt-CCU3XlOv.mjs");
100
+ const { userPromptSubmit } = await import("./user-prompt-la6CpECb.mjs");
101
101
  await userPromptSubmit(ev, signal);
102
102
  }
103
103
  async function handlePostToolUse(ev, signal) {
104
- const { postToolUse } = await import("./post-tool-CsM0XliT.mjs");
104
+ const { postToolUse } = await import("./post-tool-BRoelm73.mjs");
105
105
  await postToolUse(ev, signal);
106
106
  }
107
107
  async function handlePreToolUse(ev, _signal) {
108
- const { preToolUse } = await import("./pre-tool-ptD5st2b.mjs");
108
+ const { preToolUse } = await import("./pre-tool-YJGmHuiU.mjs");
109
109
  await preToolUse(ev);
110
110
  }
111
111
  async function handleStop(ev, _signal) {
112
- const { stop } = await import("./stop-_ovIig2U.mjs");
112
+ const { stop } = await import("./stop-gh3SchT6.mjs");
113
113
  await stop(ev);
114
114
  }
115
115
  var init_dispatcher = __esmMin((() => {}));
@@ -5,11 +5,11 @@ import { n as init_audit, t as appendAudit } from "./audit-e13xK9Fr.mjs";
5
5
  import { a as getKnowledgeStats, d as promoteSubType, l as init_knowledge, m as upsertKnowledge, o as getPromotionCandidates, r as getKnowledgeByID } from "./knowledge-C7rEfFSX.mjs";
6
6
  import { i as searchKnowledgeFTS, r as init_fts, t as detectKnowledgeConflicts } from "./fts-DICqcpG_.mjs";
7
7
  import { n as init_project, t as detectProject } from "./project-DCKke4_Q.mjs";
8
- import { a as notifyUser, i as init_dispatcher } from "./dispatcher-CLRAWyYx.mjs";
9
- import { a as trackHitCounts, i as searchPipeline, n as init_directives, o as truncate, r as init_helpers, t as emitDirectives } from "./directives-BWPf6KVs.mjs";
8
+ import { a as notifyUser, i as init_dispatcher } from "./dispatcher-Bl7px8hy.mjs";
9
+ import { a as trackHitCounts, i as searchPipeline, n as init_directives, o as truncate, r as init_helpers, t as emitDirectives } from "./directives-BtMZZnDe.mjs";
10
10
  import { n as openDefaultCached, t as init_store } from "./store-BffM-bi-.mjs";
11
- import { a as writeReviewGate, f as isSpecFilePath, n as init_review_gate, u as init_spec_guard } from "./review-gate-BQMnScje.mjs";
12
- import { c as readWaveProgress, i as parseWaveProgress, m as writeWaveProgress, n as addWorkedSlug, p as writeStateText, r as init_state, s as readStateText } from "./state-Bw1XMJxp.mjs";
11
+ import { a as writeReviewGate, d as init_spec_guard, n as init_review_gate, p as isSpecFilePath } from "./review-gate-0cGEW7jx.mjs";
12
+ import { a as readStateText, d as writeWaveProgress, n as init_state, o as readWaveProgress, r as parseWaveProgress, t as addWorkedSlug, u as writeStateText } from "./state-XSGGyez_.mjs";
13
13
  import { mkdirSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
14
14
  import { join } from "node:path";
15
15
  import { createHash } from "node:crypto";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import "./types-K2jxpWyU.mjs";
3
3
  import "./audit-e13xK9Fr.mjs";
4
- import "./dispatcher-CLRAWyYx.mjs";
5
- import "./directives-BWPf6KVs.mjs";
6
- import { a as postToolUse, n as init_post_tool } from "./post-tool-C0hkS1sJ.mjs";
4
+ import "./dispatcher-Bl7px8hy.mjs";
5
+ import "./directives-BtMZZnDe.mjs";
6
+ import { a as postToolUse, n as init_post_tool } from "./post-tool-BL5YKl-j.mjs";
7
7
  import "./store-BffM-bi-.mjs";
8
- import "./review-gate-BQMnScje.mjs";
9
- import "./state-Bw1XMJxp.mjs";
8
+ import "./review-gate-0cGEW7jx.mjs";
9
+ import "./state-XSGGyez_.mjs";
10
10
  init_post_tool();
11
11
  export { postToolUse };
@@ -5,7 +5,7 @@ import { r as init_epic, s as syncTaskStatus } from "./epic-CfxJ13zy.mjs";
5
5
  import { n as init_audit, t as appendAudit } from "./audit-e13xK9Fr.mjs";
6
6
  import { l as init_knowledge, m as upsertKnowledge } from "./knowledge-C7rEfFSX.mjs";
7
7
  import { n as init_project, t as detectProject } from "./project-DCKke4_Q.mjs";
8
- import { a as notifyUser, i as init_dispatcher } from "./dispatcher-CLRAWyYx.mjs";
8
+ import { a as notifyUser, i as init_dispatcher } from "./dispatcher-Bl7px8hy.mjs";
9
9
  import { n as openDefaultCached, t as init_store } from "./store-BffM-bi-.mjs";
10
10
  import { readFileSync, writeFileSync } from "node:fs";
11
11
  import { join } from "node:path";
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+ import { n as __esmMin } from "./chunk-CAm0Jl7e.mjs";
3
+ import { a as effectiveStatus, s as init_types } from "./types-K2jxpWyU.mjs";
4
+ import { d as init_spec_guard, f as isActiveSpecMalformed, l as denyTool, m as tryReadActiveSpec, n as init_review_gate, o as allowTool, p as isSpecFilePath, r as isGateActive } from "./review-gate-0cGEW7jx.mjs";
5
+ import "./state-XSGGyez_.mjs";
6
+ //#region src/hooks/pre-tool.ts
7
+ /**
8
+ * PreToolUse handler: block Edit/Write on review-gate or unapproved spec.
9
+ * Enforcement order: .alfred/ exempt → malformed check → review-gate → approval gate.
10
+ * Only uses allowTool() for definitively exempt edits (.alfred/ files, deferred/cancelled).
11
+ * For all other cases, returns silently so the prompt hook (LLM judge) can evaluate.
12
+ */
13
+ async function preToolUse(ev) {
14
+ const toolName = ev.tool_name ?? "";
15
+ if (!BLOCKABLE_TOOLS.has(toolName)) return;
16
+ const toolInput = ev.tool_input ?? {};
17
+ const filePath = typeof toolInput.file_path === "string" ? toolInput.file_path : "";
18
+ if (filePath && isSpecFilePath(ev.cwd, filePath)) {
19
+ allowTool("Spec file edit");
20
+ return;
21
+ }
22
+ if (isActiveSpecMalformed(ev.cwd)) {
23
+ denyTool("Failed to read spec state (_active.md exists but could not be parsed). Fix or delete .alfred/specs/_active.md before editing source files.");
24
+ return;
25
+ }
26
+ const spec = tryReadActiveSpec(ev.cwd);
27
+ if (spec) {
28
+ const status = effectiveStatus(spec.status);
29
+ if (status === "deferred" || status === "cancelled") {
30
+ allowTool("Deferred/cancelled spec");
31
+ return;
32
+ }
33
+ }
34
+ const gate = isGateActive(ev.cwd);
35
+ if (gate) {
36
+ denyTool([
37
+ `${gate.gate === "wave-review" ? `Wave ${gate.wave ?? "?"} review` : "Spec self-review"} required for spec '${gate.slug}'. Complete review, then run: dossier action=gate sub_action=clear reason="<review summary>"`,
38
+ `- Gate reason: ${gate.reason}`,
39
+ "- \"I already reviewed mentally\" → Run actual review (3-agent or /alfred:inspect), then clear the gate"
40
+ ].join("\n"));
41
+ return;
42
+ }
43
+ if (!spec) return;
44
+ if ([
45
+ "M",
46
+ "L",
47
+ "XL"
48
+ ].includes(spec.size) && spec.reviewStatus !== "approved") {
49
+ denyTool([
50
+ `Spec '${spec.slug}' (size ${spec.size}) is not approved. Submit review via \`alfred dashboard\` or run self-review before implementation.`,
51
+ "- \"I'll get the review after implementation\" → The Stop hook will block you from finishing anyway",
52
+ "- \"This edit is trivial\" → All M/L/XL edits are gated. Use dossier init size=S for trivial changes"
53
+ ].join("\n"));
54
+ return;
55
+ }
56
+ }
57
+ var BLOCKABLE_TOOLS;
58
+ //#endregion
59
+ __esmMin((() => {
60
+ init_types();
61
+ init_review_gate();
62
+ init_spec_guard();
63
+ BLOCKABLE_TOOLS = new Set(["Edit", "Write"]);
64
+ }))();
65
+ export { preToolUse };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as __esmMin } from "./chunk-CAm0Jl7e.mjs";
3
3
  import { l as readActiveState, s as init_types } from "./types-K2jxpWyU.mjs";
4
- import { f as writeStateJSON, o as readStateJSON, r as init_state } from "./state-Bw1XMJxp.mjs";
4
+ import { i as readStateJSON, l as writeStateJSON, n as init_state } from "./state-XSGGyez_.mjs";
5
5
  import { existsSync, readFileSync } from "node:fs";
6
6
  import { join, resolve } from "node:path";
7
7
  //#region src/hooks/spec-guard.ts
@@ -82,6 +82,19 @@ function hasUncheckedSelfReview(cwd, slug) {
82
82
  }
83
83
  }
84
84
  /**
85
+ * PreToolUse: explicitly allow tool via permissionDecision JSON (exit 0).
86
+ * Signals to Claude Code that this edit is permitted, so subsequent hooks
87
+ * (e.g. prompt-based spec-first judge) can be skipped.
88
+ */
89
+ function allowTool(reason) {
90
+ const out = { hookSpecificOutput: {
91
+ hookEventName: "PreToolUse",
92
+ permissionDecision: "allow",
93
+ permissionDecisionReason: reason
94
+ } };
95
+ process.stdout.write(`${JSON.stringify(out)}\n`);
96
+ }
97
+ /**
85
98
  * PreToolUse: deny tool via permissionDecision JSON (exit 0).
86
99
  */
87
100
  function denyTool(reason) {
@@ -169,4 +182,4 @@ var init_review_gate = __esmMin((() => {
169
182
  GATE_FILE = "review-gate.json";
170
183
  }));
171
184
  //#endregion
172
- export { writeReviewGate as a, denyTool as c, isActiveSpecMalformed as d, isSpecFilePath as f, readReviewGate as i, hasUncheckedSelfReview as l, init_review_gate as n, blockStop as o, tryReadActiveSpec as p, isGateActive as r, countUncheckedTasks as s, clearReviewGate as t, init_spec_guard as u };
185
+ export { writeReviewGate as a, countUncheckedTasks as c, init_spec_guard as d, isActiveSpecMalformed as f, readReviewGate as i, denyTool as l, tryReadActiveSpec as m, init_review_gate as n, allowTool as o, isSpecFilePath as p, isGateActive as r, blockStop as s, clearReviewGate as t, hasUncheckedSelfReview as u };
@@ -6,12 +6,12 @@ import { n as init_audit, t as appendAudit } from "./audit-e13xK9Fr.mjs";
6
6
  import { i as getKnowledgeByIDs, l as init_knowledge } from "./knowledge-C7rEfFSX.mjs";
7
7
  import { r as vectorSearchKnowledge, t as init_vectors } from "./vectors-DHZGQ096.mjs";
8
8
  import { a as subTypeBoost, i as searchKnowledgeFTS, r as init_fts } from "./fts-DICqcpG_.mjs";
9
- import "./dispatcher-CLRAWyYx.mjs";
10
- import { o as truncate, r as init_helpers } from "./directives-BWPf6KVs.mjs";
11
- 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-C0hkS1sJ.mjs";
9
+ import "./dispatcher-Bl7px8hy.mjs";
10
+ import { o as truncate, r as init_helpers } from "./directives-BtMZZnDe.mjs";
11
+ 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-BL5YKl-j.mjs";
12
12
  import "./store-BffM-bi-.mjs";
13
- import { a as writeReviewGate, i as readReviewGate, n as init_review_gate, t as clearReviewGate } from "./review-gate-BQMnScje.mjs";
14
- import { c as readWaveProgress, m as writeWaveProgress, r as init_state } from "./state-Bw1XMJxp.mjs";
13
+ import { a as writeReviewGate, i as readReviewGate, n as init_review_gate, t as clearReviewGate } from "./review-gate-0cGEW7jx.mjs";
14
+ import { d as writeWaveProgress, n as init_state, o as readWaveProgress } from "./state-XSGGyez_.mjs";
15
15
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
16
16
  import { join, resolve } from "node:path";
17
17
  import process$1 from "node:process";
@@ -19517,7 +19517,7 @@ function createMCPServer(store, emb, version) {
19517
19517
  Actions: status (read-only), init, update, switch, complete, delete (2-phase: preview then confirm=true), history, rollback, review, validate (read-only), gate (review gate management), check (mark task completed), defer (toggle deferred/resume), cancel.
19518
19518
 
19519
19519
  task_slug format: lowercase alphanumeric with hyphens (e.g. "my-feature", max 64 chars).
19520
- Size-based scaling: init accepts size (S/M/L/XL) and spec_type (feature/bugfix). S=3 files, M=4-5 files, L/XL=7 files.`, {
19520
+ Size-based scaling: init accepts size (S/M/L/XL) and spec_type (feature/bugfix). S=2 files, M=3-4 files, L/XL=5 files.`, {
19521
19521
  action: enumType([
19522
19522
  "init",
19523
19523
  "update",
@@ -3,10 +3,10 @@ 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-K2jxpWyU.mjs";
4
4
  import { l as init_knowledge, m as upsertKnowledge, n as deleteOrphanKnowledge, s as getRecentDecisions, t as countKnowledge } from "./knowledge-C7rEfFSX.mjs";
5
5
  import { n as init_project, t as detectProject } from "./project-DCKke4_Q.mjs";
6
- import { a as notifyUser, i as init_dispatcher, r as extractSection } from "./dispatcher-CLRAWyYx.mjs";
7
- import { n as init_directives, o as truncate, r as init_helpers, t as emitDirectives } from "./directives-BWPf6KVs.mjs";
6
+ import { a as notifyUser, i as init_dispatcher, r as extractSection } from "./dispatcher-Bl7px8hy.mjs";
7
+ import { n as init_directives, o as truncate, r as init_helpers, t as emitDirectives } from "./directives-BtMZZnDe.mjs";
8
8
  import { n as openDefaultCached, t as init_store } from "./store-BffM-bi-.mjs";
9
- import { r as init_state, u as resetWorkedSlugs } from "./state-Bw1XMJxp.mjs";
9
+ import { c as resetWorkedSlugs, n as init_state } from "./state-XSGGyez_.mjs";
10
10
  import { existsSync, readFileSync, readdirSync } from "node:fs";
11
11
  import { join } from "node:path";
12
12
  //#region src/hooks/session-start.ts
@@ -50,22 +50,6 @@ function writeStateText(cwd, name, data) {
50
50
  writeFileSync(join(stateDir(cwd), name), data);
51
51
  } catch {}
52
52
  }
53
- function writeLastIntent(cwd, intent) {
54
- if (!intent) {
55
- writeStateJSON(cwd, INTENT_FILE, null);
56
- return;
57
- }
58
- writeStateJSON(cwd, INTENT_FILE, {
59
- intent,
60
- timestamp: Date.now()
61
- });
62
- }
63
- function readLastIntent(cwd) {
64
- const data = readStateJSON(cwd, INTENT_FILE, null);
65
- if (!data || !data.intent || !data.timestamp) return null;
66
- if (Date.now() - data.timestamp > INTENT_EXPIRY_MS) return null;
67
- return data.intent;
68
- }
69
53
  /** Read the list of spec slugs worked on in this session. */
70
54
  function readWorkedSlugs(cwd) {
71
55
  const data = readStateJSON(cwd, WORKED_SLUGS_FILE, []);
@@ -138,17 +122,10 @@ function parseWaveProgress(tasksContent, slug) {
138
122
  waves
139
123
  };
140
124
  }
141
- var IMPLEMENT_INTENTS, INTENT_FILE, INTENT_EXPIRY_MS, WORKED_SLUGS_FILE, WAVE_PROGRESS_FILE;
125
+ var WORKED_SLUGS_FILE, WAVE_PROGRESS_FILE;
142
126
  var init_state = __esmMin((() => {
143
- IMPLEMENT_INTENTS = new Set([
144
- "implement",
145
- "bugfix",
146
- "tdd"
147
- ]);
148
- INTENT_FILE = "last-intent.json";
149
- INTENT_EXPIRY_MS = 1800 * 1e3;
150
127
  WORKED_SLUGS_FILE = "worked-slugs.json";
151
128
  WAVE_PROGRESS_FILE = "wave-progress.json";
152
129
  }));
153
130
  //#endregion
154
- export { readLastIntent as a, readWaveProgress as c, writeLastIntent as d, writeStateJSON as f, parseWaveProgress as i, readWorkedSlugs as l, writeWaveProgress as m, addWorkedSlug as n, readStateJSON as o, writeStateText as p, init_state as r, readStateText as s, IMPLEMENT_INTENTS as t, resetWorkedSlugs as u };
131
+ export { readStateText as a, resetWorkedSlugs as c, writeWaveProgress as d, readStateJSON as i, writeStateJSON as l, init_state as n, readWaveProgress as o, parseWaveProgress as r, readWorkedSlugs as s, addWorkedSlug as t, writeStateText as u };
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as __esmMin } from "./chunk-CAm0Jl7e.mjs";
3
3
  import "./types-K2jxpWyU.mjs";
4
- import { l as hasUncheckedSelfReview, n as init_review_gate, o as blockStop, p as tryReadActiveSpec, r as isGateActive, s as countUncheckedTasks, u as init_spec_guard } from "./review-gate-BQMnScje.mjs";
5
- import { l as readWorkedSlugs, r as init_state } from "./state-Bw1XMJxp.mjs";
4
+ import { c as countUncheckedTasks, d as init_spec_guard, m as tryReadActiveSpec, n as init_review_gate, r as isGateActive, s as blockStop, u as hasUncheckedSelfReview } from "./review-gate-0cGEW7jx.mjs";
5
+ import { n as init_state, s as readWorkedSlugs } from "./state-XSGGyez_.mjs";
6
6
  //#region src/hooks/stop.ts
7
7
  /**
8
8
  * Stop handler:
@@ -3,10 +3,10 @@ import { n as __esmMin } from "./chunk-CAm0Jl7e.mjs";
3
3
  import { l as readActiveState, s as init_types } from "./types-K2jxpWyU.mjs";
4
4
  import { a as subTypeBoost, r as init_fts } from "./fts-DICqcpG_.mjs";
5
5
  import { Embedder, t as init_embedder } from "./embedder-D3hJoryD.mjs";
6
- import "./dispatcher-CLRAWyYx.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-BWPf6KVs.mjs";
6
+ import "./dispatcher-Bl7px8hy.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-BtMZZnDe.mjs";
8
8
  import { n as openDefaultCached, t as init_store } from "./store-BffM-bi-.mjs";
9
- import { d as writeLastIntent, f as writeStateJSON, l as readWorkedSlugs, o as readStateJSON, r as init_state, t as IMPLEMENT_INTENTS } from "./state-Bw1XMJxp.mjs";
9
+ import { i as readStateJSON, l as writeStateJSON, n as init_state, s as readWorkedSlugs } from "./state-XSGGyez_.mjs";
10
10
  import { existsSync } from "node:fs";
11
11
  import { join } from "node:path";
12
12
  //#region src/hooks/user-prompt.ts
@@ -30,8 +30,6 @@ async function userPromptSubmit(ev, signal) {
30
30
  let intent = null;
31
31
  if (emb && promptVec) intent = await classifyIntentSemantic(emb, promptVec, signal);
32
32
  if (!intent) intent = classifyIntent(prompt);
33
- if (ev.cwd && existsSync(join(ev.cwd, ".alfred"))) if (intent && IMPLEMENT_INTENTS.has(intent)) writeLastIntent(ev.cwd, intent);
34
- else writeLastIntent(ev.cwd, null);
35
33
  const specDirective = checkSpecRequired(ev.cwd, intent);
36
34
  if (specDirective) {
37
35
  items.push(specDirective);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-alfred",
3
- "version": "0.3.14",
3
+ "version": "0.3.16",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "alfred": "dist/cli.mjs"
@@ -0,0 +1 @@
1
+ import{A as e,C as t,G as n,K as r,P as i,S as a,_t as o,i as s,j as c,t as l,y as u}from"./api-Tgguux9h.js";import{n as d,r as f,t as p}from"./dist-BGKsNkBS.js";import{t as m}from"./dist-B0kJ1bYO.js";import{t as h}from"./progress-DWm7GXJf.js";import{c as g,f as _,l as v,u as y}from"./index-DvnkHott.js";import{n as b,t as x}from"./badge-DTZEkDjH.js";import{a as S,i as C,n as w,r as T,t as E}from"./card-BGzSdSzz.js";import{t as D}from"./skeleton-DB1q8YGJ.js";var O=o(r(),1),k=n(),A=`Tabs`,[j,ee]=a(A,[f]),M=f(),[N,P]=j(A),F=O.forwardRef((e,n)=>{let{__scopeTabs:r,value:i,onValueChange:a,defaultValue:o,orientation:s=`horizontal`,dir:c,activationMode:l=`automatic`,...u}=e,d=m(c),[f,p]=y({prop:i,onChange:a,defaultProp:o??``,caller:A});return(0,k.jsx)(N,{scope:r,baseId:g(),value:f,onValueChange:p,orientation:s,dir:d,activationMode:l,children:(0,k.jsx)(t.div,{dir:d,"data-orientation":s,...u,ref:n})})});F.displayName=A;var I=`TabsList`,L=O.forwardRef((e,n)=>{let{__scopeTabs:r,loop:i=!0,...a}=e,o=P(I,r),s=M(r);return(0,k.jsx)(d,{asChild:!0,...s,orientation:o.orientation,dir:o.dir,loop:i,children:(0,k.jsx)(t.div,{role:`tablist`,"aria-orientation":o.orientation,...a,ref:n})})});L.displayName=I;var R=`TabsTrigger`,z=O.forwardRef((e,n)=>{let{__scopeTabs:r,value:i,disabled:a=!1,...o}=e,s=P(R,r),c=M(r),l=H(s.baseId,i),u=U(s.baseId,i),d=i===s.value;return(0,k.jsx)(p,{asChild:!0,...c,focusable:!a,active:d,children:(0,k.jsx)(t.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:n,onMouseDown:_(e.onMouseDown,e=>{!a&&e.button===0&&e.ctrlKey===!1?s.onValueChange(i):e.preventDefault()}),onKeyDown:_(e.onKeyDown,e=>{[` `,`Enter`].includes(e.key)&&s.onValueChange(i)}),onFocus:_(e.onFocus,()=>{let e=s.activationMode!==`manual`;!d&&!a&&e&&s.onValueChange(i)})})})});z.displayName=R;var B=`TabsContent`,V=O.forwardRef((e,n)=>{let{__scopeTabs:r,value:i,forceMount:a,children:o,...s}=e,c=P(B,r),l=H(c.baseId,i),u=U(c.baseId,i),d=i===c.value,f=O.useRef(d);return O.useEffect(()=>{let e=requestAnimationFrame(()=>f.current=!1);return()=>cancelAnimationFrame(e)},[]),(0,k.jsx)(v,{present:a||d,children:({present:r})=>(0,k.jsx)(t.div,{"data-state":d?`active`:`inactive`,"data-orientation":c.orientation,role:`tabpanel`,"aria-labelledby":l,hidden:!r,id:u,tabIndex:0,...s,ref:n,style:{...e.style,animationDuration:f.current?`0s`:void 0},children:r&&o})})});V.displayName=B;function H(e,t){return`${e}-trigger-${t}`}function U(e,t){return`${e}-content-${t}`}var W=F,G=L,K=z;function q({className:e,...t}){return(0,k.jsx)(`div`,{"data-slot":`table-container`,className:`relative w-full overflow-x-auto`,children:(0,k.jsx)(`table`,{"data-slot":`table`,className:u(`w-full caption-bottom text-sm`,e),...t})})}function J({className:e,...t}){return(0,k.jsx)(`thead`,{"data-slot":`table-header`,className:u(`[&_tr]:border-b`,e),...t})}function Y({className:e,...t}){return(0,k.jsx)(`tbody`,{"data-slot":`table-body`,className:u(`[&_tr:last-child]:border-0`,e),...t})}function X({className:e,...t}){return(0,k.jsx)(`tr`,{"data-slot":`table-row`,className:u(`border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted`,e),...t})}function Z({className:e,...t}){return(0,k.jsx)(`th`,{"data-slot":`table-head`,className:u(`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,k.jsx)(`td`,{"data-slot":`table-cell`,className:u(`p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,e),...t})}function $({className:e,orientation:t=`horizontal`,...n}){return(0,k.jsx)(W,{"data-slot":`tabs`,"data-orientation":t,orientation:t,className:u(`group/tabs flex gap-2 data-[orientation=horizontal]:flex-col`,e),...n})}var te=b(`group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-8 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 ne({className:e,variant:t=`default`,...n}){return(0,k.jsx)(G,{"data-slot":`tabs-list`,"data-variant":t,className:u(te({variant:t}),e),...n})}function re({className:e,...t}){return(0,k.jsx)(K,{"data-slot":`tabs-trigger`,className:u(`relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-lg border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-colors 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=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 ie=[`all`,`spec.init`,`spec.complete`,`review.submit`],ae=10080*60*1e3;function oe(){let{t:e}=c(),[t,n]=(0,O.useState)(`all`),[r,a]=(0,O.useState)(!1),{data:o,isLoading:u}=i(l(100,t===`all`?void 0:t)),{data:d}=i(s()),f=o?.entries??[],p=(0,O.useMemo)(()=>{if(r)return f;let e=Date.now()-ae;return f.filter(t=>{try{return new Date(t.timestamp).getTime()>=e}catch{return!0}})},[f,r]),m=!r&&p.length<f.length,h=(d?.epics??[]).filter(e=>e.status!==`completed`&&e.status!==`done`);return(0,k.jsxs)(`div`,{className:`space-y-6`,children:[(0,k.jsx)(`div`,{className:`sticky top-0 z-10 bg-background pb-3`,children:(0,k.jsx)($,{value:t,onValueChange:n,children:(0,k.jsx)(ne,{children:ie.map(t=>(0,k.jsx)(re,{value:t,className:`text-xs`,children:t===`all`?e(`activity.all`):t},t))})})}),u?(0,k.jsx)(`div`,{className:`space-y-2`,children:Array.from({length:5}).map((e,t)=>(0,k.jsx)(D,{className:`h-10 w-full`},`skel-${t}`))}):(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(se,{entries:p}),m&&(0,k.jsx)(`div`,{className:`flex justify-center`,children:(0,k.jsx)(S,{variant:`outline`,size:`sm`,onClick:()=>a(!0),children:e(`activity.showOlder`)})})]}),h.length>0&&(0,k.jsx)(ue,{epics:h})]})}function se({entries:e}){let{t,locale:n}=c(),[r,i]=(0,O.useState)(null);return(0,k.jsxs)(q,{children:[(0,k.jsx)(J,{children:(0,k.jsxs)(X,{children:[(0,k.jsx)(Z,{className:`w-44`,children:t(`activity.timestamp`)}),(0,k.jsx)(Z,{className:`w-32`,children:t(`activity.action`)}),(0,k.jsx)(Z,{children:t(`activity.target`)}),(0,k.jsx)(Z,{children:t(`activity.detail`)})]})}),(0,k.jsxs)(Y,{children:[e.map((e,t)=>{let a=r===t,o=!!e.detail&&e.detail.length>40;return(0,k.jsxs)(X,{className:o?`cursor-pointer hover:bg-accent/50`:``,onClick:()=>o&&i(a?null:t),children:[(0,k.jsx)(Q,{className:`text-xs text-muted-foreground font-mono align-top`,children:de(e.timestamp,n)}),(0,k.jsx)(Q,{className:`align-top`,children:(0,k.jsx)(le,{action:e.action})}),(0,k.jsx)(Q,{className:`text-sm align-top`,children:e.target}),(0,k.jsx)(Q,{className:`text-xs text-muted-foreground`,children:a?(0,k.jsx)(`div`,{className:`whitespace-pre-wrap break-words max-w-lg`,children:e.detail}):(0,k.jsx)(`div`,{className:`max-w-xs truncate`,children:e.detail})})]},`${e.timestamp}-${t}`)}),e.length===0&&(0,k.jsx)(X,{children:(0,k.jsx)(Q,{colSpan:4,className:`text-center text-sm text-muted-foreground`,children:t(`activity.noActivity`)})})]})]})}var ce={"spec.init":`#40513b`,"spec.complete":`#2d8b7a`,"spec.delete":`#c0392b`,"review.submit":`#628141`,"living-spec.update":`#7b6b8d`};function le({action:e}){let t=ce[e]??`#6b7280`;return(0,k.jsx)(x,{variant:`outline`,className:`text-xs`,style:{borderColor:`${t}40`,color:t},children:e})}function ue({epics:e}){let{t}=c();return(0,k.jsxs)(`div`,{className:`space-y-3`,children:[(0,k.jsx)(`h3`,{className:`text-sm font-medium text-foreground`,children:t(`activity.epics`)}),(0,k.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,k.jsxs)(E,{children:[(0,k.jsx)(T,{className:`pb-2`,children:(0,k.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,k.jsx)(C,{className:`text-sm`,children:e.name}),(0,k.jsx)(x,{variant:`outline`,className:`text-xs`,children:e.status})]})}),(0,k.jsxs)(w,{className:`space-y-2`,children:[(0,k.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,k.jsx)(h,{value:t,className:`flex-1`}),(0,k.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[e.completed,`/`,e.total]})]}),e.tasks&&e.tasks.length>0&&(0,k.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:e.tasks.map(e=>(0,k.jsx)(x,{variant:`outline`,className:`text-[10px]`,style:{borderColor:e.status===`completed`||e.status===`done`?`rgba(45,139,122,0.3)`:`rgba(107,114,128,0.3)`,color:e.status===`completed`||e.status===`done`?`#2d8b7a`:`#6b7280`},children:e.slug},e.slug))})]})]},e.slug)})})]})}function de(t,n=`en`){try{return new Date(t).toLocaleString(e(n),{month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`})}catch{return t}}export{oe as component};