claude-alfred 0.3.0 → 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.
- package/README.ja.md +3 -2
- package/README.md +4 -3
- package/dist/{audit-DMxi6YnF.mjs → audit-6NSlW0Ut.mjs} +5 -7
- package/dist/cli.mjs +10 -12
- package/dist/{directives-B23lVUGt.mjs → directives-ko2sX5BW.mjs} +5 -5
- package/dist/{dispatcher-bW4qDAhl.mjs → dispatcher-BnBtA4bo.mjs} +9 -9
- package/dist/{embedder-qPO74Ar-.mjs → embedder-BRG2Xpr4.mjs} +4 -5
- package/dist/{fts-DInh3bOQ.mjs → fts-QWdC_4Zv.mjs} +2 -2
- package/dist/{helpers-C6av-rsB.mjs → helpers-BnPVn8Nv.mjs} +6 -6
- package/dist/{knowledge-CicKSdup.mjs → knowledge-B0fsJ9SI.mjs} +19 -5
- package/dist/{post-tool-CFyBxFlB.mjs → post-tool-gG8qG5Ee.mjs} +19 -28
- package/dist/postinstall.mjs +1 -1
- package/dist/{pre-compact-CUPQ3Qj-.mjs → pre-compact-CwvBi5op.mjs} +5 -5
- package/dist/{pre-tool-BcdaDusF.mjs → pre-tool-BMCYjtHT.mjs} +2 -2
- package/dist/{server-B0gr3On1.mjs → server-CHdcikXe.mjs} +41 -41
- package/dist/{server-DhEN_dME.mjs → server-Df8fib2F.mjs} +2473 -2346
- package/dist/{session-start-l9fkYqD5.mjs → session-start-dPl4lfZw.mjs} +20 -70
- package/dist/{spec-guard-ntNzlw8B.mjs → spec-guard-BGwtCxgH.mjs} +4 -4
- package/dist/state-CdHO66SV.mjs +53 -0
- package/dist/{stop-BEMycnn1.mjs → stop-NL5GdPNy.mjs} +2 -2
- package/dist/{user-prompt-COyVgW_-.mjs → user-prompt-o9rlzB2I.mjs} +17 -30
- package/dist/{vectors-B5WOzF-3.mjs → vectors-BDQP0gaa.mjs} +2 -2
- package/package.json +4 -1
- package/web/dist/assets/activity-mXF0VmCt.js +1 -0
- package/web/dist/assets/api-BpnabbKu.js +1 -0
- package/web/dist/assets/badge-CBFM8JtH.js +1 -0
- package/web/dist/assets/button-CBPUE5Y6.js +14 -0
- package/web/dist/assets/checkbox-B_KjCpy7.js +1 -0
- package/web/dist/assets/{circle-dot-BPxCviEE.js → circle-dot-BMf8wYDE.js} +1 -1
- package/web/dist/assets/createLucideIcon-MCX4k61-.js +1 -0
- package/web/dist/assets/dist-7qozDZTq.js +1 -0
- package/web/dist/assets/index-CNTBHHOa.js +10 -0
- package/web/dist/assets/index-uhr7UtxX.css +1 -0
- package/web/dist/assets/knowledge-wd_PIN8X.js +59 -0
- package/web/dist/assets/{link-DqICqa6t.js → link-D7DRVryP.js} +1 -1
- package/web/dist/assets/progress-B0hcYV7D.js +6 -0
- package/web/dist/assets/routes-DUyvG12-.js +1 -0
- package/web/dist/assets/separator-0fdLqhBM.js +1 -0
- package/web/dist/assets/skeleton-CLJEM3zd.js +1 -0
- package/web/dist/assets/tasks-pPCS6lSa.js +1 -0
- package/web/dist/assets/tasks._slug-C-Z_7eYZ.js +35 -0
- package/web/dist/assets/useParams-CJl-SvaR.js +1 -0
- package/web/dist/index.html +6 -6
- package/web/dist/assets/activity-QgmI9mew.js +0 -1
- package/web/dist/assets/api-Cq0fYMlI.js +0 -1
- package/web/dist/assets/card-BcSoTIRX.js +0 -1
- package/web/dist/assets/circle-BL_hGKys.js +0 -1
- package/web/dist/assets/createLucideIcon-BsT1VhJi.js +0 -1
- package/web/dist/assets/dist-BoQ-HzPG.js +0 -1
- package/web/dist/assets/index-BBgUhwsZ.js +0 -10
- package/web/dist/assets/index-D3MHfJUi.css +0 -1
- package/web/dist/assets/knowledge-hAa3Wi3j.js +0 -15
- package/web/dist/assets/lib-B4Vj6fDL.js +0 -58
- package/web/dist/assets/matchContext-Djmy2MvT.js +0 -1
- package/web/dist/assets/progress-Dq-nvFJj.js +0 -6
- package/web/dist/assets/routes-mB72Gd2i.js +0 -1
- package/web/dist/assets/separator-CMQXCJRe.js +0 -1
- package/web/dist/assets/skeleton-CG9s_VrV.js +0 -1
- package/web/dist/assets/tasks-Dm4Gt0QY.js +0 -1
- package/web/dist/assets/tasks._slug-Cjjewclt.js +0 -42
- package/web/dist/assets/utils-muoz4bGA.js +0 -1
- /package/dist/{store-D-S-ZKaA.mjs → store-CuN3_dWu.mjs} +0 -0
package/README.ja.md
CHANGED
|
@@ -131,7 +131,7 @@ npm update -g claude-alfred # CLI、hooks、MCP サーバー、ダッシ
|
|
|
131
131
|
|
|
132
132
|
| イベント | 動作 |
|
|
133
133
|
|----------|------|
|
|
134
|
-
| SessionStart | 仕様コンテキスト復元 +
|
|
134
|
+
| SessionStart | 仕様コンテキスト復元 + ナレッジ同期 + 1%ルール(スキル発動促進)+ 成熟度適応 |
|
|
135
135
|
| PreCompact | スナップショット保存 + 決定抽出 + エピック進捗同期 + 調査パターン検出 |
|
|
136
136
|
| UserPromptSubmit | セマンティック検索 + スキルナッジ + **spec承認ゲート**(未承認 M/L/XL に DIRECTIVE) |
|
|
137
137
|
| PostToolUse | エラー検出 + Next Steps 自動チェック + ドリフト検出 + コミット時決定保存 |
|
|
@@ -149,7 +149,7 @@ alfred dashboard --url-only # URLだけ出力
|
|
|
149
149
|
| タブ | 表示内容 |
|
|
150
150
|
|------|----------|
|
|
151
151
|
| **Overview** | プロジェクトの健康状態 — タスク進捗とバリデーション結果、メモリ健康度(陳腐化数・矛盾数)、仕様の信頼度分布、エピック進捗、最近の意思決定 |
|
|
152
|
-
| **Tasks** |
|
|
152
|
+
| **Tasks** | Active/Completed セクション分離。タスクをクリックで2カラム詳細ビュー: 左にメタデータ、右に折りたたみ可能なspecセクション(色分け付き)。Review タブでインラインコメント |
|
|
153
153
|
| **Knowledge** | メモリ一覧(サブタイプ別タグ付き)。セマンティック検索(Voyage AI、300msデバウンス)。ローカルテキストフィルタ。メモリの有効/無効切り替え |
|
|
154
154
|
| **Activity** | 操作タイムライン。イベントタイプ別フィルタ(init/complete/review)。エピックドリルダウン |
|
|
155
155
|
|
|
@@ -281,6 +281,7 @@ Hook(見えない)
|
|
|
281
281
|
| `.alfred/epics/` | 最初のエピック作成時 | `roster action=init` |
|
|
282
282
|
| `.alfred/steering/` | `/alfred:init` 実行時 | プロジェクト初期化スキル |
|
|
283
283
|
| `.alfred/templates/` | ユーザーが仕様・Steeringテンプレートをカスタマイズする時 | テンプレートオーバーライド用に手動作成 |
|
|
284
|
+
| `.alfred/.state/` | 最初のセッションローカル状態保存時 | ナッジ抑制カウント、探索カウンター(gitignore対象) |
|
|
284
285
|
| `.alfred/audit.jsonl` | 最初の仕様操作時またはコミット後ドリフト検出時 | `dossier init`、レビュー送信、PostToolUse ドリフト |
|
|
285
286
|
|
|
286
287
|
## トラブルシューティング
|
package/README.md
CHANGED
|
@@ -131,7 +131,7 @@ Run automatically. You don't touch these.
|
|
|
131
131
|
|
|
132
132
|
| Event | What happens |
|
|
133
133
|
|-------|-------------|
|
|
134
|
-
| SessionStart | Restores spec context,
|
|
134
|
+
| SessionStart | Restores spec context, syncs knowledge index, adapts injection depth to project maturity, 1% rule skill activation |
|
|
135
135
|
| PreCompact | Extracts decisions, saves chapter snapshots, syncs epic progress, detects research patterns |
|
|
136
136
|
| UserPromptSubmit | Semantic search + file context boost + **skill nudge** + **spec approval gate** (blocks implement intent on unapproved M/L/XL specs) |
|
|
137
137
|
| PostToolUse | Detects Bash errors + searches memory. After commits: spec drift detection + auto-save decisions. Edit/Write: auto-check Next Steps progress |
|
|
@@ -149,7 +149,7 @@ alfred dashboard --url-only # print URL only
|
|
|
149
149
|
| Tab | What you see |
|
|
150
150
|
|-----|-------------|
|
|
151
151
|
| **Overview** | Project health at a glance — task progress with validation badges, memory health (stale count, conflicts), confidence distribution across specs, epic progress, recent decisions |
|
|
152
|
-
| **Tasks** |
|
|
152
|
+
| **Tasks** | Active/Completed sections. Drill into any task for a 2-column detail view: metadata on the left, collapsible spec sections (color-coded) on the right. Switch to Review tab for inline comments |
|
|
153
153
|
| **Knowledge** | Browse all memories with sub-type tags. Semantic search (Voyage AI) with 300ms debounce. Local text filter. Toggle any memory on/off |
|
|
154
154
|
| **Activity** | Timeline of all operations. Filter by event type (init/complete/review). Epic drill-down with task status badges |
|
|
155
155
|
|
|
@@ -252,7 +252,7 @@ You
|
|
|
252
252
|
|
|
|
253
253
|
v
|
|
254
254
|
Hooks (invisible)
|
|
255
|
-
|-- SessionStart -> restore context, 1% rule, adapt to project maturity
|
|
255
|
+
|-- SessionStart -> restore context, sync knowledge, 1% rule, adapt to project maturity
|
|
256
256
|
|-- PreCompact -> save snapshots, extract decisions, epic progress
|
|
257
257
|
|-- UserPromptSubmit -> vector search + FTS5 + skill nudge + spec approval check
|
|
258
258
|
|-- PostToolUse -> detect errors, auto-check Next Steps, drift detection
|
|
@@ -281,6 +281,7 @@ Nothing is generated at install time. Files appear as you use alfred:
|
|
|
281
281
|
| `.alfred/epics/` | First epic is created | `roster action=init` |
|
|
282
282
|
| `.alfred/steering/` | Running `/alfred:init` | Project initialization skill |
|
|
283
283
|
| `.alfred/templates/` | User customizes spec or steering templates | Manual creation for template override |
|
|
284
|
+
| `.alfred/.state/` | First hook that needs session-local state | Nudge dismissals, exploration counter (gitignored) |
|
|
284
285
|
| `.alfred/audit.jsonl` | First spec operation or commit drift detection | `dossier init`, `dossier delete`, review submission, PostToolUse drift |
|
|
285
286
|
|
|
286
287
|
## Troubleshooting
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
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
|
|
@@ -39,7 +39,7 @@ var EpicDir = class {
|
|
|
39
39
|
}
|
|
40
40
|
save(ep) {
|
|
41
41
|
const data = (0, import_dist.stringify)(ep);
|
|
42
|
-
const tmp = this.epicPath()
|
|
42
|
+
const tmp = `${this.epicPath()}.tmp`;
|
|
43
43
|
writeFileSync(tmp, data);
|
|
44
44
|
renameSync(tmp, this.epicPath());
|
|
45
45
|
}
|
|
@@ -161,9 +161,7 @@ function listAllEpics(projectPath) {
|
|
|
161
161
|
total: tasks.length,
|
|
162
162
|
tasks
|
|
163
163
|
});
|
|
164
|
-
} catch {
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
164
|
+
} catch {}
|
|
167
165
|
}
|
|
168
166
|
return summaries;
|
|
169
167
|
}
|
|
@@ -219,7 +217,7 @@ function writeActiveEpics(projectPath, state) {
|
|
|
219
217
|
mkdirSync(epicsDir(projectPath), { recursive: true });
|
|
220
218
|
const data = (0, import_dist.stringify)(state);
|
|
221
219
|
const path = epicActivePath(projectPath);
|
|
222
|
-
const tmp = path
|
|
220
|
+
const tmp = `${path}.tmp`;
|
|
223
221
|
writeFileSync(tmp, data);
|
|
224
222
|
renameSync(tmp, path);
|
|
225
223
|
}
|
|
@@ -233,7 +231,7 @@ function appendAudit(projectPath, entry) {
|
|
|
233
231
|
...entry,
|
|
234
232
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
235
233
|
});
|
|
236
|
-
appendFileSync(join(dir, "audit.jsonl"), line
|
|
234
|
+
appendFileSync(join(dir, "audit.jsonl"), `${line}\n`);
|
|
237
235
|
} catch {}
|
|
238
236
|
}
|
|
239
237
|
//#endregion
|
package/dist/cli.mjs
CHANGED
|
@@ -369,9 +369,9 @@ const main = defineCommand({
|
|
|
369
369
|
serve: defineCommand({
|
|
370
370
|
meta: { description: "Start MCP server (stdio)" },
|
|
371
371
|
async run() {
|
|
372
|
-
const { Store } = await import("./store-
|
|
373
|
-
const { Embedder } = await import("./embedder-
|
|
374
|
-
const { serveMCP } = await import("./server-
|
|
372
|
+
const { Store } = await import("./store-CuN3_dWu.mjs");
|
|
373
|
+
const { Embedder } = await import("./embedder-BRG2Xpr4.mjs");
|
|
374
|
+
const { serveMCP } = await import("./server-CHdcikXe.mjs");
|
|
375
375
|
const store = Store.openDefault();
|
|
376
376
|
let emb = null;
|
|
377
377
|
try {
|
|
@@ -397,9 +397,9 @@ const main = defineCommand({
|
|
|
397
397
|
}
|
|
398
398
|
},
|
|
399
399
|
async run({ args }) {
|
|
400
|
-
const { Store } = await import("./store-
|
|
401
|
-
const { Embedder } = await import("./embedder-
|
|
402
|
-
const { startDashboard } = await import("./server-
|
|
400
|
+
const { Store } = await import("./store-CuN3_dWu.mjs");
|
|
401
|
+
const { Embedder } = await import("./embedder-BRG2Xpr4.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-
|
|
425
|
+
const { runHook } = await import("./dispatcher-BnBtA4bo.mjs").then((n) => n.t);
|
|
426
426
|
await runHook(args.event);
|
|
427
427
|
}
|
|
428
428
|
}),
|
|
@@ -456,8 +456,8 @@ const main = defineCommand({
|
|
|
456
456
|
}
|
|
457
457
|
const dbPath = join(home, ".claude-alfred", "alfred.db");
|
|
458
458
|
check(existsSync(dbPath), `DB: ${dbPath}`, "not found — run: alfred (any command) to create");
|
|
459
|
-
check(!!process.env
|
|
460
|
-
const lang = process.env
|
|
459
|
+
check(!!process.env.VOYAGE_API_KEY, "VOYAGE_API_KEY set", "not set — semantic search disabled, FTS5 fallback active");
|
|
460
|
+
const lang = process.env.ALFRED_LANG;
|
|
461
461
|
check(true, `ALFRED_LANG: ${lang || "(not set, default: en)"}`);
|
|
462
462
|
const rulesDir = join(home, ".claude", "rules");
|
|
463
463
|
try {
|
|
@@ -498,9 +498,7 @@ async function resolveVersion() {
|
|
|
498
498
|
for (const rel of ["..", "../.."]) try {
|
|
499
499
|
const pkg = JSON.parse(readFileSync(join(thisDir, rel, "package.json"), "utf-8"));
|
|
500
500
|
if (pkg.version) return pkg.version;
|
|
501
|
-
} catch {
|
|
502
|
-
continue;
|
|
503
|
-
}
|
|
501
|
+
} catch {}
|
|
504
502
|
} catch {}
|
|
505
503
|
return "dev";
|
|
506
504
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as emitAdditionalContext } from "./dispatcher-
|
|
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,
|
|
@@ -30,16 +30,16 @@ function buildDirectiveOutput(items) {
|
|
|
30
30
|
let block = `[${item.level}] ${item.message}`;
|
|
31
31
|
if (item.level === "DIRECTIVE") {
|
|
32
32
|
const rats = (item.rationalizations ?? []).slice();
|
|
33
|
-
const suffix = item.spiritVsLetter ?
|
|
33
|
+
const suffix = item.spiritVsLetter ? `\n${SPIRIT_VS_LETTER}` : "";
|
|
34
34
|
while (rats.length > 0) {
|
|
35
|
-
if (
|
|
35
|
+
if (`${block}\n${rats.map((r) => `- ${r}`).join("\n")}${suffix}`.length <= MAX_DIRECTIVE_BLOCK_CHARS) break;
|
|
36
36
|
rats.pop();
|
|
37
37
|
}
|
|
38
|
-
if (rats.length > 0) block +=
|
|
38
|
+
if (rats.length > 0) block += `\n${rats.map((r) => `- ${r}`).join("\n")}`;
|
|
39
39
|
block += suffix;
|
|
40
40
|
if (block.length > MAX_DIRECTIVE_BLOCK_CHARS) {
|
|
41
41
|
const messageOnly = `[${item.level}] ${item.message}`;
|
|
42
|
-
if (messageOnly.length > MAX_DIRECTIVE_BLOCK_CHARS) block = messageOnly.slice(0, MAX_DIRECTIVE_BLOCK_CHARS - 3)
|
|
42
|
+
if (messageOnly.length > MAX_DIRECTIVE_BLOCK_CHARS) block = `${messageOnly.slice(0, MAX_DIRECTIVE_BLOCK_CHARS - 3)}...`;
|
|
43
43
|
else block = messageOnly;
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
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({
|
|
@@ -19,7 +19,7 @@ function emitAdditionalContext(eventName, context) {
|
|
|
19
19
|
additionalContext: context
|
|
20
20
|
} };
|
|
21
21
|
try {
|
|
22
|
-
process.stdout.write(JSON.stringify(out)
|
|
22
|
+
process.stdout.write(`${JSON.stringify(out)}\n`);
|
|
23
23
|
} catch {}
|
|
24
24
|
}
|
|
25
25
|
function extractSection(content, heading) {
|
|
@@ -27,7 +27,7 @@ function extractSection(content, heading) {
|
|
|
27
27
|
const result = [];
|
|
28
28
|
let inSection = false;
|
|
29
29
|
for (const line of lines) {
|
|
30
|
-
if (line === heading || line.startsWith(heading
|
|
30
|
+
if (line === heading || line.startsWith(`${heading} `)) {
|
|
31
31
|
inSection = true;
|
|
32
32
|
continue;
|
|
33
33
|
}
|
|
@@ -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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
112
|
+
const { stop } = await import("./stop-NL5GdPNy.mjs");
|
|
113
113
|
await stop(ev);
|
|
114
114
|
}
|
|
115
115
|
//#endregion
|
|
@@ -12,7 +12,7 @@ function envIntOr(key, fallback) {
|
|
|
12
12
|
const v = process.env[key];
|
|
13
13
|
if (v) {
|
|
14
14
|
const n = parseInt(v, 10);
|
|
15
|
-
if (!isNaN(n) && n > 0) return n;
|
|
15
|
+
if (!Number.isNaN(n) && n > 0) return n;
|
|
16
16
|
}
|
|
17
17
|
return fallback;
|
|
18
18
|
}
|
|
@@ -82,7 +82,6 @@ async function retryVoyage(fn, signal) {
|
|
|
82
82
|
if (err.status === 400 && (isVoyageTransient(err.detail) || isVoyageTransientStructured(err.errResp))) continue;
|
|
83
83
|
throw err;
|
|
84
84
|
}
|
|
85
|
-
continue;
|
|
86
85
|
}
|
|
87
86
|
}
|
|
88
87
|
throw lastErr;
|
|
@@ -116,7 +115,7 @@ var VoyageClient = class {
|
|
|
116
115
|
method: "POST",
|
|
117
116
|
headers: {
|
|
118
117
|
"Content-Type": "application/json",
|
|
119
|
-
|
|
118
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
120
119
|
},
|
|
121
120
|
body: JSON.stringify(payload),
|
|
122
121
|
signal: signal ?? AbortSignal.timeout(3e4)
|
|
@@ -157,7 +156,7 @@ var VoyageClient = class {
|
|
|
157
156
|
method: "POST",
|
|
158
157
|
headers: {
|
|
159
158
|
"Content-Type": "application/json",
|
|
160
|
-
|
|
159
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
161
160
|
},
|
|
162
161
|
body: JSON.stringify(payload),
|
|
163
162
|
signal: signal ?? AbortSignal.timeout(3e4)
|
|
@@ -185,7 +184,7 @@ var Embedder = class Embedder {
|
|
|
185
184
|
this.client = client;
|
|
186
185
|
}
|
|
187
186
|
static create() {
|
|
188
|
-
const apiKey = process.env
|
|
187
|
+
const apiKey = process.env.VOYAGE_API_KEY;
|
|
189
188
|
if (!apiKey) throw new Error("VOYAGE_API_KEY is required but not set (get a key at https://dash.voyageai.com/)");
|
|
190
189
|
return new Embedder(new VoyageClient(apiKey));
|
|
191
190
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { n as deserializeFloat32, t as cosineSimilarity } from "./vectors-
|
|
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,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { r as vectorSearchKnowledge } from "./vectors-
|
|
4
|
-
import { i as subTypeHalfLife, n as searchKnowledgeFTS, r as subTypeBoost } from "./fts-
|
|
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) {
|
|
8
8
|
const runes = [...s];
|
|
9
9
|
if (runes.length <= maxLen) return s;
|
|
10
|
-
return runes.slice(0, maxLen).join("")
|
|
10
|
+
return `${runes.slice(0, maxLen).join("")}...`;
|
|
11
11
|
}
|
|
12
12
|
function recencyFactor(createdAt, subType, now) {
|
|
13
13
|
const halfLife = subTypeHalfLife(subType);
|
|
14
14
|
if (halfLife <= 0) return 1;
|
|
15
15
|
const parsed = Date.parse(createdAt);
|
|
16
|
-
if (isNaN(parsed)) return 1;
|
|
16
|
+
if (Number.isNaN(parsed)) return 1;
|
|
17
17
|
const ageDays = (now.getTime() - parsed) / (1e3 * 60 * 60 * 24);
|
|
18
18
|
if (ageDays <= 0) return 1;
|
|
19
19
|
const factor = Math.exp(-Math.LN2 * ageDays / halfLife);
|
|
@@ -55,7 +55,7 @@ async function searchPipeline(store, emb, query, limit, overRetrieve, precompute
|
|
|
55
55
|
rawDocs = ordered;
|
|
56
56
|
res.searchMethod = "vector";
|
|
57
57
|
if (rawDocs.length > limit) try {
|
|
58
|
-
const contents = rawDocs.map((d) => d.title
|
|
58
|
+
const contents = rawDocs.map((d) => `${d.title}\n${d.content}`);
|
|
59
59
|
const reranked = await emb.rerank(query, contents, limit);
|
|
60
60
|
if (reranked.length > 0) {
|
|
61
61
|
const reorderedDocs = [];
|
|
@@ -6606,7 +6606,7 @@ var require_dist = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
6606
6606
|
//#endregion
|
|
6607
6607
|
//#region src/spec/types.ts
|
|
6608
6608
|
var import_dist = require_dist();
|
|
6609
|
-
const VALID_SLUG = /^[a-z0-9][a-z0-9
|
|
6609
|
+
const VALID_SLUG = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
6610
6610
|
function detectSize(description) {
|
|
6611
6611
|
const n = [...description].length;
|
|
6612
6612
|
if (n < 100) return "S";
|
|
@@ -6692,7 +6692,7 @@ var SpecDir = class {
|
|
|
6692
6692
|
}
|
|
6693
6693
|
writeFileRaw(f, content) {
|
|
6694
6694
|
const path = this.filePath(f);
|
|
6695
|
-
const tmp = path
|
|
6695
|
+
const tmp = `${path}.tmp`;
|
|
6696
6696
|
writeFileSync(tmp, content);
|
|
6697
6697
|
renameSync(tmp, path);
|
|
6698
6698
|
}
|
|
@@ -6703,7 +6703,7 @@ var SpecDir = class {
|
|
|
6703
6703
|
const histDir = join(this.dir(), ".history");
|
|
6704
6704
|
mkdirSync(histDir, { recursive: true });
|
|
6705
6705
|
writeFileSync(join(histDir, `${f}.${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").slice(0, 15)}`), readFileSync(path, "utf-8"));
|
|
6706
|
-
const entries = readdirSync(histDir).filter((e) => e.startsWith(f
|
|
6706
|
+
const entries = readdirSync(histDir).filter((e) => e.startsWith(`${f}.`)).sort();
|
|
6707
6707
|
while (entries.length > 20) {
|
|
6708
6708
|
const old = entries.shift();
|
|
6709
6709
|
try {
|
|
@@ -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 {
|
|
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,34 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { n as searchKnowledgeFTS, t as detectKnowledgeConflicts } from "./fts-
|
|
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-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { t as emitDirectives } from "./directives-
|
|
9
|
-
import {
|
|
10
|
-
import { join } from "node:path";
|
|
11
|
-
import { tmpdir } from "node:os";
|
|
5
|
+
import { i as notifyUser, r as extractSection } from "./dispatcher-BnBtA4bo.mjs";
|
|
6
|
+
import { r as truncate } from "./helpers-BnPVn8Nv.mjs";
|
|
7
|
+
import { openDefaultCached } from "./store-CuN3_dWu.mjs";
|
|
8
|
+
import { t as emitDirectives } from "./directives-ko2sX5BW.mjs";
|
|
9
|
+
import { i as writeStateText, n as readStateText } from "./state-CdHO66SV.mjs";
|
|
12
10
|
//#region src/hooks/post-tool.ts
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
return parseInt(readFileSync(EXPLORE_COUNTER_PATH, "utf-8"), 10) || 0;
|
|
17
|
-
} catch {
|
|
18
|
-
return 0;
|
|
19
|
-
}
|
|
11
|
+
function readExploreCount(cwd) {
|
|
12
|
+
return parseInt(readStateText(cwd, "explore-count", "0"), 10) || 0;
|
|
20
13
|
}
|
|
21
|
-
function writeExploreCount(n) {
|
|
22
|
-
|
|
23
|
-
writeFileSync(EXPLORE_COUNTER_PATH, String(n));
|
|
24
|
-
} catch {}
|
|
14
|
+
function writeExploreCount(cwd, n) {
|
|
15
|
+
writeStateText(cwd, "explore-count", String(n));
|
|
25
16
|
}
|
|
26
17
|
async function postToolUse(ev, signal) {
|
|
27
18
|
if (!ev.cwd || !ev.tool_name) return;
|
|
28
19
|
const items = [];
|
|
29
20
|
if (ev.tool_name === "Read" || ev.tool_name === "Grep" || ev.tool_name === "Glob") {
|
|
30
|
-
const count = readExploreCount() + 1;
|
|
31
|
-
writeExploreCount(count);
|
|
21
|
+
const count = readExploreCount(ev.cwd) + 1;
|
|
22
|
+
writeExploreCount(ev.cwd, count);
|
|
32
23
|
if (count >= 5) try {
|
|
33
24
|
readActive(ev.cwd);
|
|
34
25
|
} catch {
|
|
@@ -36,12 +27,12 @@ async function postToolUse(ev, signal) {
|
|
|
36
27
|
level: "WARNING",
|
|
37
28
|
message: `5+ consecutive ${ev.tool_name} calls without a spec. Consider \`/alfred:survey\` to reverse-engineer a spec from the code.`
|
|
38
29
|
});
|
|
39
|
-
writeExploreCount(0);
|
|
30
|
+
writeExploreCount(ev.cwd, 0);
|
|
40
31
|
}
|
|
41
32
|
emitDirectives("PostToolUse", items);
|
|
42
33
|
return;
|
|
43
34
|
}
|
|
44
|
-
writeExploreCount(0);
|
|
35
|
+
writeExploreCount(ev.cwd, 0);
|
|
45
36
|
if (ev.tool_name === "Bash" && !signal.aborted) await handleBashResult(ev, items, signal);
|
|
46
37
|
if ((ev.tool_name === "Edit" || ev.tool_name === "Write") && ev.tool_input) {
|
|
47
38
|
const input = ev.tool_input;
|
|
@@ -62,7 +53,7 @@ async function handleBashResult(ev, items, signal) {
|
|
|
62
53
|
const errorText = typeof response.stderr === "string" ? response.stderr : "";
|
|
63
54
|
const stdout = response.stdout ?? "";
|
|
64
55
|
if (errorText.length > 10) await searchErrorContext(ev.cwd, errorText, items);
|
|
65
|
-
if (isTestFailure(stdout
|
|
56
|
+
if (isTestFailure(`${stdout}\n${errorText}`)) items.push({
|
|
66
57
|
level: "WARNING",
|
|
67
58
|
message: "Test failure detected. Investigate the root cause before continuing implementation. Consider reverting recent changes with `git stash` or `git diff` to isolate the issue."
|
|
68
59
|
});
|
|
@@ -70,14 +61,14 @@ async function handleBashResult(ev, items, signal) {
|
|
|
70
61
|
if (response.exitCode === 0) {
|
|
71
62
|
const stdout = response.stdout ?? "";
|
|
72
63
|
const commandStr = typeof ev.tool_input === "object" && ev.tool_input !== null ? ev.tool_input.command ?? "" : "";
|
|
73
|
-
autoCheckNextSteps(ev.cwd, stdout
|
|
64
|
+
autoCheckNextSteps(ev.cwd, `${stdout}\n${commandStr}`);
|
|
74
65
|
if (isGitCommit(stdout) && !signal.aborted) {
|
|
75
66
|
await checkKnowledgeConflicts(items);
|
|
76
67
|
saveKnowledgeOnCommit(ev.cwd);
|
|
77
68
|
}
|
|
78
69
|
}
|
|
79
70
|
}
|
|
80
|
-
async function searchErrorContext(
|
|
71
|
+
async function searchErrorContext(_projectPath, errorText, items) {
|
|
81
72
|
let store;
|
|
82
73
|
try {
|
|
83
74
|
store = openDefaultCached();
|
|
@@ -143,7 +134,7 @@ function updateCurrentlyWorkingOn(session, newFocus) {
|
|
|
143
134
|
return session.slice(0, afterMarker + 1) + lines.join("\n");
|
|
144
135
|
}
|
|
145
136
|
}
|
|
146
|
-
return session.slice(0, afterMarker + 1)
|
|
137
|
+
return `${session.slice(0, afterMarker + 1)}\n${newFocus}\n${session.slice(afterMarker + 1)}`;
|
|
147
138
|
}
|
|
148
139
|
/**
|
|
149
140
|
* FR-4: Detect test failure patterns in command output.
|
package/dist/postinstall.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { s as syncTaskStatus, t as appendAudit } from "./audit-
|
|
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-
|
|
6
|
-
import { openDefaultCached } from "./store-
|
|
5
|
+
import { i as notifyUser } from "./dispatcher-BnBtA4bo.mjs";
|
|
6
|
+
import { openDefaultCached } from "./store-CuN3_dWu.mjs";
|
|
7
7
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
//#region src/hooks/pre-compact.ts
|
|
@@ -71,7 +71,7 @@ async function preCompact(ev, _signal) {
|
|
|
71
71
|
};
|
|
72
72
|
upsertKnowledge(store, row);
|
|
73
73
|
const breadcrumb = {
|
|
74
|
-
claude_session_id: process.env
|
|
74
|
+
claude_session_id: process.env.CLAUDE_SESSION_ID ?? "",
|
|
75
75
|
task_slug: taskSlug,
|
|
76
76
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
77
77
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./dispatcher-
|
|
3
|
-
import { a as isSpecFilePath, o as tryReadActiveSpec, r as denyTool } from "./spec-guard-
|
|
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
|
/**
|