claude-alfred 0.5.1 → 0.5.3
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 +5 -10
- package/README.md +5 -10
- package/dist/{audit-D8rTYtFw.mjs → audit-CmbBNEzT.mjs} +108 -1
- package/dist/{audit-BUfNnVyn.mjs → audit-tp3tpgzR.mjs} +1 -1
- package/dist/cli.mjs +14 -87
- package/dist/{directives-CONWKEcF.mjs → directives-BM9nkHZV.mjs} +9 -6
- package/dist/{dispatcher-B0mX7vIg.mjs → dispatcher-us-cOlZZ.mjs} +6 -6
- package/dist/{drift-Bzx6WLIh.mjs → drift-CyqSWmja.mjs} +4 -3
- package/dist/{fts-Bjh2ei-P.mjs → fts-CG3NjtDr.mjs} +2 -54
- package/dist/{knowledge-Dy5uM1Hn.mjs → knowledge-7gqtk8yz.mjs} +4 -1
- package/dist/{knowledge-io-D5yibPl3.mjs → knowledge-io-CII6K2EO.mjs} +2 -2
- package/dist/lang-filter--xQlqF9A.mjs +137 -0
- package/dist/{living-spec-BlkJjzMM.mjs → living-spec-DEmgB4Gw.mjs} +5 -137
- package/dist/{post-tool-B2I0YXfx.mjs → post-tool-CPUtuUxb.mjs} +155 -90
- package/dist/post-tool-DK48fw3G.mjs +11 -0
- package/dist/postinstall.mjs +1 -1
- package/dist/{pre-compact--oc_lXQL.mjs → pre-compact-DBnEMJwf.mjs} +8 -15
- package/dist/{pre-tool-3--r3A9s.mjs → pre-tool-6dYu2xfd.mjs} +3 -3
- package/dist/{review-gate-D_ru0z05.mjs → review-gate-PHUE_mEA.mjs} +11 -2
- package/dist/{schema-B_MIRZ5z.mjs → schema-BEv7jNnr.mjs} +15 -2
- package/dist/{server-BS-doEbJ.mjs → server-BVV-C9mF.mjs} +54 -207
- package/dist/{server-DWewjXMB.mjs → server-Ciof8e8X.mjs} +172 -307
- package/dist/{session-start-xADH3wLU.mjs → session-start-vtNhjJdP.mjs} +23 -10
- package/dist/{spec-sync-lML0Vh52.mjs → spec-sync-BYLLyRG3.mjs} +3 -3
- package/dist/{state-DSwLaF87.mjs → state-7-p9AqA6.mjs} +2 -2
- package/dist/{stop-xSK4TR_W.mjs → stop-DhNxcAvM.mjs} +3 -3
- package/dist/{store-Bys48i5B.mjs → store-BhCFm1Tb.mjs} +15 -2
- package/dist/{types-zr3tpkx_.mjs → types-BucChDqv.mjs} +1 -1
- package/dist/user-BRphWhLv.mjs +20 -0
- package/dist/{user-prompt-BesJG141.mjs → user-prompt-n5VcQmRT.mjs} +57 -9
- package/dist/{vectors-sMr3EQ8X.mjs → vectors-BVQ0dz9J.mjs} +2 -39
- package/package.json +1 -1
- package/web/dist/assets/activity-DS8gsAtD.js +1 -0
- package/web/dist/assets/api-CVUS-Ce3.js +3 -0
- package/web/dist/assets/badge-D8mApPpI.js +1 -0
- package/web/dist/assets/butler-empty-C3mWnDYa.js +1 -0
- package/web/dist/assets/dist-lzHifHMP.js +1 -0
- package/web/dist/assets/format-CY2ohS0a.js +2 -0
- package/web/dist/assets/index-DgRGKS9D.js +14 -0
- package/web/dist/assets/index-DvBh5daN.css +1 -0
- package/web/dist/assets/knowledge-Cu6MXPyf.js +14 -0
- package/web/dist/assets/lib-BDTjEd1Q.js +14 -0
- package/web/dist/assets/link-ahHmGL6O.js +1 -0
- package/web/dist/assets/preload-helper-BIScuso2.js +1 -0
- package/web/dist/assets/projects-9xEJb6MC.js +1 -0
- package/web/dist/assets/routes-C8fI2lxb.js +1 -0
- package/web/dist/assets/skeleton-CEUF44ae.js +9 -0
- package/web/dist/assets/status-badge-BcYaeEpe.js +6 -0
- package/web/dist/assets/tasks-auOZy7oP.js +1 -0
- package/web/dist/assets/tasks._slug-B48aNnrZ.js +51 -0
- package/web/dist/assets/tooltip-B_wZunY1.js +41 -0
- package/web/dist/assets/{api-bRDenTw5.js → utils-CXfoJANe.js} +1934 -1936
- package/web/dist/index.html +8 -10
- package/dist/config-Bo-RmOvR.mjs +0 -111
- package/dist/conflicts-DyAF51Cq.mjs +0 -78
- package/dist/epic-BHZ71Dpf.mjs +0 -233
- package/dist/init-D3Dj4iLX.mjs +0 -119
- package/dist/merge-driver-C-G0Syhj.mjs +0 -96
- package/dist/pattern-mining-CFngSfIv.mjs +0 -95
- package/dist/post-tool-G6vgH6L5.mjs +0 -11
- package/web/dist/assets/activity-G4L7p822.js +0 -1
- package/web/dist/assets/alert-dialog-95k_kiC9.js +0 -20
- package/web/dist/assets/badge-CnG7YBFb.js +0 -1
- package/web/dist/assets/butler-empty-uFY3olOm.js +0 -1
- package/web/dist/assets/button-CMQ3RNqS.js +0 -1
- package/web/dist/assets/card-o3eB3PWI.js +0 -1
- package/web/dist/assets/es2015-YDNOmm3L.js +0 -41
- package/web/dist/assets/index-3eR8NKmm.css +0 -1
- package/web/dist/assets/index-DHfbawKi.js +0 -10
- package/web/dist/assets/input-BKTK7oI_.js +0 -1
- package/web/dist/assets/knowledge-Bk6JY9Ae.js +0 -53
- package/web/dist/assets/link-DyKnnhOQ.js +0 -1
- package/web/dist/assets/motion-eqXv38ND.js +0 -1
- package/web/dist/assets/popover-Co-pTDfK.js +0 -1
- package/web/dist/assets/preload-helper-BdM6cKcW.js +0 -1
- package/web/dist/assets/progress-Cip2oR_a.js +0 -6
- package/web/dist/assets/projects-CqU08rS3.js +0 -1
- package/web/dist/assets/routes-R71feDjA.js +0 -1
- package/web/dist/assets/separator-BVNBZ4_p.js +0 -5
- package/web/dist/assets/skeleton-XOOCQsrO.js +0 -1
- package/web/dist/assets/stagger-container-CJO3QRbz.js +0 -9
- package/web/dist/assets/tasks-6O3fGgmS.js +0 -1
- package/web/dist/assets/tasks._slug-Bd4l7O_B.js +0 -44
- package/web/dist/assets/tooltip-CVVBJsKJ.js +0 -1
- package/web/dist/assets/types-D2X1vSUs.js +0 -2
- /package/dist/{embedder-D3hJoryD.mjs → embedder-9lsjLVC6.mjs} +0 -0
- /package/dist/{project-BPGWTiJo.mjs → project-DKLV_Zw3.mjs} +0 -0
package/README.ja.md
CHANGED
|
@@ -46,19 +46,19 @@ Claude Code で:
|
|
|
46
46
|
|
|
47
47
|
**提案ではなく強制。** 3層のゲートがコード編集を制御する。spec なしの実装を防ぐインテントガード。前の Wave をレビューするまで次を止めるレビューゲート。ダッシュボードで人間が承認するまで M/L の実装を止める承認ゲート。YAML を手で書き換えてもダメ — 署名済みレビューファイルまで検証する。
|
|
48
48
|
|
|
49
|
-
**記憶が育つ。** 「あの時なぜこう決めた」「このパターンは前もうまくいった」「X は試してダメだった」— `.alfred/knowledge/` に JSON で残る。15回以上検索ヒットしたパターンはルールに自動昇格。知識タイプごとに半減期が違う — ルールは120日、仮定は30
|
|
49
|
+
**記憶が育つ。** 「あの時なぜこう決めた」「このパターンは前もうまくいった」「X は試してダメだった」— `.alfred/knowledge/` に JSON で残る。15回以上検索ヒットしたパターンはルールに自動昇格。知識タイプごとに半減期が違う — ルールは120日、仮定は30日で鮮度が落ちる。Git に入れてチームで共有できる。次に似た状況が来たら、聞く前に出てくる。
|
|
50
50
|
|
|
51
51
|
**仕様がズレたら教えてくれる。** コミットの度に変更を設計ドキュメントと照合。spec にないコンポーネントを触ったら警告が飛ぶ。新しいソースファイルは該当コンポーネントのセクションに自動追記 — 手動で spec を更新する必要はない。
|
|
52
52
|
|
|
53
53
|
**コンテキストが適応する。** プロジェクトの成熟度に応じて注入量を調整する。新しいプロジェクトにはセッション開始時に spec 全体を注入。20件以上のナレッジがあるプロジェクトには現在のタスクとゴールだけ — コンテキストを膨らませない。
|
|
54
54
|
|
|
55
|
-
**スキルが勝手に出てくる。** 調べものしてたら `/brief` を提案。バグ直してたら `/mend
|
|
55
|
+
**スキルが勝手に出てくる。** 調べものしてたら `/brief` を提案。バグ直してたら `/mend`。覚えなくていい — 意図をセマンティック or キーワードで分類(日英バイリンガル)して、適切なスキルを出す。
|
|
56
56
|
|
|
57
57
|
**ダッシュボードが使える。** `alfred dashboard` で `localhost:7575` が開く。タスク進捗、行レベルコメント付きレビュー、ファイル単位の承認、ナレッジの健全性、操作履歴。プロジェクト横断ビュー + `Cmd+K` グローバル検索。日英ワンクリック切替。
|
|
58
58
|
|
|
59
59
|
**プロジェクト横断インテリジェンス。** alfred は全プロジェクトを横断して見る。プロジェクト間の矛盾する設計判断?自動検出。新しい認証機能を始める?他プロジェクトの過去の判断が聞く前に出てくる。3つ以上のプロジェクトに共通するパターンは自動的に検出・昇格。
|
|
60
60
|
|
|
61
|
-
**git でチーム共有。** ナレッジは構造化 JSON — コミットして PR
|
|
61
|
+
**git でチーム共有。** ナレッジは構造化 JSON — コミットして PR でレビューしてチームで共有。サーバー不要 — git がトランスポート。
|
|
62
62
|
|
|
63
63
|
## 2026年に alfred が必要な理由
|
|
64
64
|
|
|
@@ -97,7 +97,6 @@ Opus 4.6 の 1M context で compact は稀になったが、発火時の破壊
|
|
|
97
97
|
| `/alfred:inspect` | 6プロファイル並列レビュー。スコア付き |
|
|
98
98
|
| `/alfred:survey` | 既存コードから spec をリバースエンジニアリング。信頼度スコア付き |
|
|
99
99
|
| `/alfred:salon` | ブレスト。3人の専門家が並列で出して、トレードオフを議論 |
|
|
100
|
-
| `/alfred:harvest` | PR レビューコメントからナレッジを抽出して永続化 |
|
|
101
100
|
| `/alfred:archive` | 参照資料(PDF, CSV, 大きなテキスト)を検索可能なナレッジに変換 |
|
|
102
101
|
| `/alfred:init` | プロジェクト初期化。マルチエージェントで探索 → ステアリングドキュメント生成 |
|
|
103
102
|
|
|
@@ -114,15 +113,13 @@ Hook(見えない)
|
|
|
114
113
|
|-- UserPromptSubmit -> セマンティック検索 + スキル提案 + spec enforcement
|
|
115
114
|
|-- PreToolUse -> review gate + intent guard + approval gate(3層)
|
|
116
115
|
|-- PostToolUse -> 進捗自動更新、ステータス自動遷移、ドリフト検出
|
|
117
|
-
|-- PreCompact ->
|
|
116
|
+
|-- PreCompact -> タスクスナップショット、決定抽出
|
|
118
117
|
|-- Stop -> review gate ブロック + リマインド
|
|
119
118
|
v
|
|
120
119
|
ストレージ
|
|
121
120
|
|-- .alfred/knowledge/ -> JSON(decisions/, patterns/, rules/)— ソースオブトゥルース
|
|
122
121
|
|-- .alfred/specs/ -> spec ファイル + バージョン履歴 + レビュー
|
|
123
|
-
|-- .alfred/epics/ -> エピック YAML + 依存関係
|
|
124
122
|
|-- .alfred/steering/ -> プロジェクトコンテキスト(product, structure, tech)
|
|
125
|
-
|-- .alfred/team.yaml -> チーム設定(レビュー人数、spec 管理、横断検索)
|
|
126
123
|
+-- ~/.claude-alfred/ -> SQLite 検索インデックス + 監査ログ(再構築可能)
|
|
127
124
|
```
|
|
128
125
|
|
|
@@ -131,7 +128,6 @@ Hook(見えない)
|
|
|
131
128
|
| ツール | 管理対象 |
|
|
132
129
|
|--------|----------|
|
|
133
130
|
| `dossier` | spec ライフサイクル — init, update, complete, defer, cancel, review, gate など |
|
|
134
|
-
| `roster` | エピック — タスクのグループ化、依存関係、spec 横断の進捗追跡 |
|
|
135
131
|
| `ledger` | ナレッジ — 検索、保存、パターン → ルール昇格、ヘルスレポート |
|
|
136
132
|
|
|
137
133
|
## ナレッジ
|
|
@@ -145,7 +141,7 @@ JSON ファイルとして Git にコミットし、PR でレビューし、チ
|
|
|
145
141
|
rules/ # 「常に X する。優先度: P0。根拠: Y」
|
|
146
142
|
```
|
|
147
143
|
|
|
148
|
-
15
|
|
144
|
+
15回以上検索ヒットしたパターンはルールに自動昇格。
|
|
149
145
|
|
|
150
146
|
各エントリに作成者(`git user.name`)を自動記録。`alfred knowledge export/import` でプロジェクト間のナレッジ移動も可能。
|
|
151
147
|
|
|
@@ -179,7 +175,6 @@ npm install -g claude-alfred # CLI、hooks、MCP サーバー、ダッシ
|
|
|
179
175
|
| 意図しない言語 | `export ALFRED_LANG=ja` を `~/.zshrc` に追加 |
|
|
180
176
|
| Hook が動かない | `/plugin install alfred` して Claude Code を再起動 |
|
|
181
177
|
| ダッシュボードが空 | `.alfred/specs/` があるディレクトリで実行。任意ディレクトリでも横断ビューで起動可 |
|
|
182
|
-
| ナレッジの merge が衝突する | `alfred team init` で merge driver をセットアップ |
|
|
183
178
|
|
|
184
179
|
## アンインストール
|
|
185
180
|
|
package/README.md
CHANGED
|
@@ -46,19 +46,19 @@ Most spec tools give you slash commands that say "you should write a spec first.
|
|
|
46
46
|
|
|
47
47
|
**Enforcement, not suggestions.** Three layers gate your code edits. An intent guard blocks implementation without a spec. A review gate blocks the next wave until you've reviewed the last one. An approval gate blocks M/L specs until a human signs off in the dashboard. You can't YAML-edit your way past it — the signed review file gets checked too.
|
|
48
48
|
|
|
49
|
-
**Knowledge that grows up.** Every decision, pattern, and hard-won lesson goes to `.alfred/knowledge/` as structured JSON. Patterns auto-promote to rules after 15+ search hits. Each knowledge type has its own half-life — rules stay relevant for 120 days, assumptions fade after 30.
|
|
49
|
+
**Knowledge that grows up.** Every decision, pattern, and hard-won lesson goes to `.alfred/knowledge/` as structured JSON. Patterns auto-promote to rules after 15+ search hits. Each knowledge type has its own half-life — rules stay relevant for 120 days, assumptions fade after 30. Git-friendly, team-shareable, and alfred surfaces relevant experience before you ask.
|
|
50
50
|
|
|
51
51
|
**Specs that stay honest.** After every commit, alfred diffs your changes against the design doc. Touched a component not in the spec? You'll hear about it. New source files get auto-appended to the right component section — your spec stays in sync without manual updates.
|
|
52
52
|
|
|
53
53
|
**Context that adapts.** alfred adjusts how much it injects based on project maturity. A new project gets full spec context on session start. A mature one with 20+ knowledge entries gets just the current task and goal — no context bloat.
|
|
54
54
|
|
|
55
|
-
**Skills that show up on their own.** Researching? alfred suggests `/brief`. Fixing a bug? `/mend`.
|
|
55
|
+
**Skills that show up on their own.** Researching? alfred suggests `/brief`. Fixing a bug? `/mend`. No memorization needed — it classifies your intent (semantic or keyword, bilingual) and nudges the right skill.
|
|
56
56
|
|
|
57
57
|
**A dashboard that's actually useful.** `alfred dashboard` opens `localhost:7575` with live task progress, spec review with line-level comments, file-by-file approval, knowledge health, and activity timeline. Cross-project view with `Cmd+K` global search. English/Japanese toggle.
|
|
58
58
|
|
|
59
59
|
**Cross-project intelligence.** alfred sees across all your projects. Contradictory design decisions between projects? Flagged automatically. Starting a new auth feature? Past decisions from your other projects surface before you ask. Common patterns across 3+ projects get detected and promoted.
|
|
60
60
|
|
|
61
|
-
**Team sharing via git.** Knowledge files are structured JSON — commit, review in PRs, share with your team.
|
|
61
|
+
**Team sharing via git.** Knowledge files are structured JSON — commit, review in PRs, share with your team. No server needed — git is the transport.
|
|
62
62
|
|
|
63
63
|
## Why alfred in 2026
|
|
64
64
|
|
|
@@ -97,7 +97,6 @@ With Opus 4.6's 1M context window, compaction is rarer but more destructive when
|
|
|
97
97
|
| `/alfred:inspect` | 6-profile quality review. Parallel agents, scored findings |
|
|
98
98
|
| `/alfred:survey` | Reverse-engineer specs from existing code, with confidence scores |
|
|
99
99
|
| `/alfred:salon` | Brainstorm. 3 specialists ideate in parallel, then debate tradeoffs |
|
|
100
|
-
| `/alfred:harvest` | Extract knowledge from PR review comments into permanent memory |
|
|
101
100
|
| `/alfred:archive` | Ingest reference docs (PDF, CSV, big text) into searchable knowledge |
|
|
102
101
|
| `/alfred:init` | Project onboarding. Multi-agent codebase exploration + steering docs |
|
|
103
102
|
|
|
@@ -114,15 +113,13 @@ Hooks (invisible)
|
|
|
114
113
|
|-- UserPromptSubmit -> semantic search + skill nudge + spec enforcement
|
|
115
114
|
|-- PreToolUse -> review gate + intent guard + approval gate (3-layer)
|
|
116
115
|
|-- PostToolUse -> auto-update progress, auto-transition status, drift detection
|
|
117
|
-
|-- PreCompact -> snapshot tasks, extract decisions
|
|
116
|
+
|-- PreCompact -> snapshot tasks, extract decisions
|
|
118
117
|
|-- Stop -> review gate block + reminders
|
|
119
118
|
v
|
|
120
119
|
Storage
|
|
121
120
|
|-- .alfred/knowledge/ -> JSON (decisions/, patterns/, rules/) — source of truth
|
|
122
121
|
|-- .alfred/specs/ -> spec files + version history + reviews
|
|
123
|
-
|-- .alfred/epics/ -> epic YAML + task dependencies
|
|
124
122
|
|-- .alfred/steering/ -> project context (product, structure, tech)
|
|
125
|
-
|-- .alfred/team.yaml -> team config (review count, spec tracking, cross-project)
|
|
126
123
|
+-- ~/.claude-alfred/ -> SQLite search index + audit log (rebuildable)
|
|
127
124
|
```
|
|
128
125
|
|
|
@@ -131,7 +128,6 @@ Storage
|
|
|
131
128
|
| Tool | What it manages |
|
|
132
129
|
|------|----------------|
|
|
133
130
|
| `dossier` | Spec lifecycle — init, update, complete, defer, cancel, review, gate, and more |
|
|
134
|
-
| `roster` | Epics — group tasks with dependencies, track progress across specs |
|
|
135
131
|
| `ledger` | Knowledge — search, save, promote patterns to rules, health reports |
|
|
136
132
|
|
|
137
133
|
## Knowledge
|
|
@@ -145,7 +141,7 @@ Knowledge lives as JSON files you can commit, review in PRs, and share with your
|
|
|
145
141
|
rules/ # "Always do X. Priority: P0. Because: Y."
|
|
146
142
|
```
|
|
147
143
|
|
|
148
|
-
Patterns auto-promote to rules after 15+ search hits.
|
|
144
|
+
Patterns auto-promote to rules after 15+ search hits.
|
|
149
145
|
|
|
150
146
|
Search pipeline: Voyage AI vectors with reranking > FTS5 with fuzzy matching > keyword fallback. "auth" finds "authentication", "login", and more.
|
|
151
147
|
|
|
@@ -179,7 +175,6 @@ npm install -g claude-alfred # CLI, hooks, MCP server, dashboard
|
|
|
179
175
|
| Wrong language | `export ALFRED_LANG=ja` in `~/.zshrc` |
|
|
180
176
|
| Hook not firing | `/plugin install alfred` + restart Claude Code |
|
|
181
177
|
| Dashboard empty | Run from a directory with `.alfred/specs/`, or any directory for cross-project view |
|
|
182
|
-
| Merge conflicts in knowledge | Run `alfred team init` to set up the merge driver |
|
|
183
178
|
|
|
184
179
|
## Uninstalling
|
|
185
180
|
|
|
@@ -95,6 +95,113 @@ async function syncAuditJsonl(store, projectId, projectPath) {
|
|
|
95
95
|
skipped
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Read rework rates from audit_log (SQL only, no git).
|
|
100
|
+
* - Confirmed: rework.checked events (21+ days past completion)
|
|
101
|
+
* - Pending: spec.complete with changed_files but no rework.checked yet
|
|
102
|
+
*/
|
|
103
|
+
function getReworkRates(store, opts) {
|
|
104
|
+
const results = [];
|
|
105
|
+
const projectFilter = opts?.projectId ? "AND project_id = ?" : "";
|
|
106
|
+
const params = opts?.projectId ? [opts.projectId] : [];
|
|
107
|
+
const checkedRows = store.db.prepare(`
|
|
108
|
+
SELECT slug, detail FROM audit_log
|
|
109
|
+
WHERE event = 'rework.checked' ${projectFilter}
|
|
110
|
+
`).all(...params);
|
|
111
|
+
const checkedSlugs = /* @__PURE__ */ new Set();
|
|
112
|
+
for (const r of checkedRows) try {
|
|
113
|
+
const d = JSON.parse(r.detail);
|
|
114
|
+
checkedSlugs.add(r.slug);
|
|
115
|
+
results.push({
|
|
116
|
+
slug: r.slug,
|
|
117
|
+
size: d.size ?? "M",
|
|
118
|
+
completedAt: d.completed_at ?? "",
|
|
119
|
+
reworkRate: d.rework_rate ?? 0,
|
|
120
|
+
reworkedCount: d.reworked_count ?? 0,
|
|
121
|
+
totalCount: d.total_count ?? 0,
|
|
122
|
+
pending: false
|
|
123
|
+
});
|
|
124
|
+
} catch {}
|
|
125
|
+
const completedRows = store.db.prepare(`
|
|
126
|
+
SELECT slug, timestamp, detail FROM audit_log
|
|
127
|
+
WHERE event = 'spec.complete' ${projectFilter}
|
|
128
|
+
ORDER BY timestamp DESC
|
|
129
|
+
`).all(...params);
|
|
130
|
+
const now = Date.now();
|
|
131
|
+
const TWENTY_ONE_DAYS = 504 * 60 * 60 * 1e3;
|
|
132
|
+
for (const r of completedRows) {
|
|
133
|
+
if (checkedSlugs.has(r.slug)) continue;
|
|
134
|
+
try {
|
|
135
|
+
const d = JSON.parse(r.detail);
|
|
136
|
+
if (!d.changed_files || d.changed_files.length === 0) continue;
|
|
137
|
+
if (!(now - new Date(r.timestamp).getTime() < TWENTY_ONE_DAYS)) continue;
|
|
138
|
+
results.push({
|
|
139
|
+
slug: r.slug,
|
|
140
|
+
size: d.size ?? "M",
|
|
141
|
+
completedAt: r.timestamp,
|
|
142
|
+
reworkRate: 0,
|
|
143
|
+
reworkedCount: 0,
|
|
144
|
+
totalCount: d.changed_files.length,
|
|
145
|
+
pending: true
|
|
146
|
+
});
|
|
147
|
+
} catch {}
|
|
148
|
+
}
|
|
149
|
+
return results;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Compute cycle time breakdown from audit_log (SQL only).
|
|
153
|
+
* Phases: init → approved → first_commit → complete
|
|
154
|
+
*/
|
|
155
|
+
function getCycleTimeBreakdown(store, opts) {
|
|
156
|
+
const projectFilter = opts?.projectId ? "AND project_id = ?" : "";
|
|
157
|
+
const params = opts?.projectId ? [opts.projectId] : [];
|
|
158
|
+
return store.db.prepare(`
|
|
159
|
+
SELECT
|
|
160
|
+
slug,
|
|
161
|
+
MIN(CASE WHEN event = 'spec.init' THEN timestamp END) as init_ts,
|
|
162
|
+
MIN(CASE WHEN event = 'spec.complete' THEN timestamp END) as complete_ts,
|
|
163
|
+
MIN(CASE WHEN event = 'spec.complete' THEN detail END) as complete_detail,
|
|
164
|
+
MIN(CASE WHEN event = 'first_commit' THEN timestamp END) as first_commit_ts,
|
|
165
|
+
MIN(CASE WHEN event = 'review.submit' AND detail LIKE '%"approved"%' THEN timestamp END) as approved_ts
|
|
166
|
+
FROM audit_log
|
|
167
|
+
WHERE event IN ('spec.init', 'spec.complete', 'first_commit', 'review.submit')
|
|
168
|
+
${projectFilter}
|
|
169
|
+
GROUP BY slug
|
|
170
|
+
HAVING init_ts IS NOT NULL AND complete_ts IS NOT NULL
|
|
171
|
+
`).all(...params).map((r) => {
|
|
172
|
+
const initMs = new Date(r.init_ts).getTime();
|
|
173
|
+
const completeMs = new Date(r.complete_ts).getTime();
|
|
174
|
+
const firstCommitMs = r.first_commit_ts ? new Date(r.first_commit_ts).getTime() : null;
|
|
175
|
+
const approvedMs = r.approved_ts ? new Date(r.approved_ts).getTime() : null;
|
|
176
|
+
const daysDiff = (a, b) => Math.round((b - a) / (1e3 * 60 * 60 * 24) * 10) / 10;
|
|
177
|
+
let size = "M";
|
|
178
|
+
try {
|
|
179
|
+
const d = JSON.parse(r.complete_detail ?? "{}");
|
|
180
|
+
if (d.size) size = d.size;
|
|
181
|
+
} catch {}
|
|
182
|
+
let planning = null;
|
|
183
|
+
let approvalWait = null;
|
|
184
|
+
let implementation = null;
|
|
185
|
+
if (approvedMs && firstCommitMs) {
|
|
186
|
+
planning = daysDiff(initMs, approvedMs);
|
|
187
|
+
approvalWait = daysDiff(approvedMs, firstCommitMs);
|
|
188
|
+
implementation = daysDiff(firstCommitMs, completeMs);
|
|
189
|
+
} else if (firstCommitMs) {
|
|
190
|
+
planning = daysDiff(initMs, firstCommitMs);
|
|
191
|
+
implementation = daysDiff(firstCommitMs, completeMs);
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
slug: r.slug,
|
|
195
|
+
size,
|
|
196
|
+
phases: {
|
|
197
|
+
planning,
|
|
198
|
+
approvalWait,
|
|
199
|
+
implementation,
|
|
200
|
+
total: daysDiff(initMs, completeMs)
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
});
|
|
204
|
+
}
|
|
98
205
|
function getKnowledgeHitRanking(store, opts) {
|
|
99
206
|
const limit = opts?.limit ?? 10;
|
|
100
207
|
const projectFilter = opts?.projectId ? "AND ki.project_id = ?" : "";
|
|
@@ -151,4 +258,4 @@ function getSpecCompletionStats(store, opts) {
|
|
|
151
258
|
}));
|
|
152
259
|
}
|
|
153
260
|
//#endregion
|
|
154
|
-
export { getKnowledgeHitRanking, getSpecCompletionStats, queryAuditLog, syncAuditJsonl };
|
|
261
|
+
export { getCycleTimeBreakdown, getKnowledgeHitRanking, getReworkRates, getSpecCompletionStats, queryAuditLog, syncAuditJsonl };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { n as __esmMin } from "./chunk-CAm0Jl7e.mjs";
|
|
3
|
-
import { f as rootDir, s as init_types } from "./types-
|
|
3
|
+
import { f as rootDir, s as init_types } from "./types-BucChDqv.mjs";
|
|
4
4
|
import { appendFileSync, mkdirSync } from "node:fs";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
//#region src/spec/audit.ts
|
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-BhCFm1Tb.mjs").then((n) => (n.t(), n.r));
|
|
373
|
+
const { Embedder } = await import("./embedder-9lsjLVC6.mjs");
|
|
374
|
+
const { serveMCP } = await import("./server-Ciof8e8X.mjs");
|
|
375
375
|
const store = Store.openDefault();
|
|
376
376
|
let emb = null;
|
|
377
377
|
try {
|
|
@@ -399,11 +399,11 @@ const main = defineCommand({
|
|
|
399
399
|
async run({ args }) {
|
|
400
400
|
const { existsSync } = await import("node:fs");
|
|
401
401
|
const { join } = await import("node:path");
|
|
402
|
-
const { Store } = await import("./store-
|
|
403
|
-
const { Embedder } = await import("./embedder-
|
|
404
|
-
const { startDashboard } = await import("./server-
|
|
405
|
-
const { resolveOrRegisterProject } = await import("./project-
|
|
406
|
-
const { syncAllProjectSpecs } = await import("./spec-sync-
|
|
402
|
+
const { Store } = await import("./store-BhCFm1Tb.mjs").then((n) => (n.t(), n.r));
|
|
403
|
+
const { Embedder } = await import("./embedder-9lsjLVC6.mjs");
|
|
404
|
+
const { startDashboard } = await import("./server-BVV-C9mF.mjs");
|
|
405
|
+
const { resolveOrRegisterProject } = await import("./project-DKLV_Zw3.mjs").then((n) => (n.n(), n.a));
|
|
406
|
+
const { syncAllProjectSpecs } = await import("./spec-sync-BYLLyRG3.mjs");
|
|
407
407
|
const cwd = process.cwd();
|
|
408
408
|
const store = Store.openDefault();
|
|
409
409
|
let emb = null;
|
|
@@ -413,8 +413,8 @@ const main = defineCommand({
|
|
|
413
413
|
if (emb) store.expectedDims = emb.dims;
|
|
414
414
|
if (existsSync(join(cwd, ".alfred"))) resolveOrRegisterProject(store, cwd);
|
|
415
415
|
await syncAllProjectSpecs(store, emb);
|
|
416
|
-
const { syncAuditJsonl } = await import("./audit-
|
|
417
|
-
const { listActiveProjects } = await import("./project-
|
|
416
|
+
const { syncAuditJsonl } = await import("./audit-CmbBNEzT.mjs");
|
|
417
|
+
const { listActiveProjects } = await import("./project-DKLV_Zw3.mjs").then((n) => (n.n(), n.a));
|
|
418
418
|
for (const p of listActiveProjects(store)) if (existsSync(join(p.path, ".alfred"))) await syncAuditJsonl(store, p.id, p.path);
|
|
419
419
|
const version = await resolveVersion();
|
|
420
420
|
await startDashboard(cwd, store, emb, {
|
|
@@ -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-
|
|
434
|
+
const { runHook } = await import("./dispatcher-us-cOlZZ.mjs").then((n) => (n.i(), n.t));
|
|
435
435
|
await runHook(args.event);
|
|
436
436
|
}
|
|
437
437
|
}),
|
|
@@ -477,57 +477,6 @@ const main = defineCommand({
|
|
|
477
477
|
}
|
|
478
478
|
const cwd = process.cwd();
|
|
479
479
|
check(existsSync(join(cwd, ".alfred")), `Project: .alfred/ exists in ${cwd}`, "not initialized — run /alfred:init in Claude Code");
|
|
480
|
-
const { loadTeamConfig, getGitUserName } = await import("./config-Bo-RmOvR.mjs").then((n) => (n.i(), n.t));
|
|
481
|
-
check(!!loadTeamConfig(cwd), "Team: .alfred/team.yaml", "not found — run 'alfred team init' for team features");
|
|
482
|
-
const gitUser = getGitUserName(cwd);
|
|
483
|
-
check(gitUser !== "unknown", `Git user.name: ${gitUser}`, "not set — run: git config --global user.name 'Your Name'");
|
|
484
|
-
try {
|
|
485
|
-
const { execFileSync: exec } = await import("node:child_process");
|
|
486
|
-
check(!!exec("git", ["config", "merge.alfred-knowledge.driver"], {
|
|
487
|
-
cwd,
|
|
488
|
-
encoding: "utf-8",
|
|
489
|
-
timeout: 3e3
|
|
490
|
-
}).trim(), "Merge driver: configured");
|
|
491
|
-
} catch {
|
|
492
|
-
check(false, "Merge driver", "not registered — run 'alfred team init'");
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
}),
|
|
496
|
-
team: defineCommand({
|
|
497
|
-
meta: { description: "Team collaboration management" },
|
|
498
|
-
subCommands: {
|
|
499
|
-
init: defineCommand({
|
|
500
|
-
meta: { description: "Initialize team configuration" },
|
|
501
|
-
args: { name: {
|
|
502
|
-
type: "string",
|
|
503
|
-
default: "",
|
|
504
|
-
description: "Team name"
|
|
505
|
-
} },
|
|
506
|
-
async run({ args }) {
|
|
507
|
-
const { teamInit } = await import("./init-D3Dj4iLX.mjs");
|
|
508
|
-
const result = teamInit(process.cwd(), { name: args.name });
|
|
509
|
-
if (result.teamYaml) console.log(" ✓ Created .alfred/team.yaml");
|
|
510
|
-
if (result.gitattributes) console.log(" ✓ Added merge driver to .gitattributes");
|
|
511
|
-
if (result.mergeDriver) console.log(" ✓ Registered git merge driver");
|
|
512
|
-
if (result.gitignore) console.log(" ✓ Adjusted .gitignore for spec tracking");
|
|
513
|
-
if (result.templatesDir) console.log(" ✓ Created .alfred/templates/specs/");
|
|
514
|
-
console.log("\nTeam init complete. Share this repo and run 'alfred team join' on other machines.");
|
|
515
|
-
}
|
|
516
|
-
}),
|
|
517
|
-
join: defineCommand({
|
|
518
|
-
meta: { description: "Join an existing team" },
|
|
519
|
-
async run() {
|
|
520
|
-
const { teamJoin } = await import("./init-D3Dj4iLX.mjs");
|
|
521
|
-
try {
|
|
522
|
-
const result = teamJoin(process.cwd());
|
|
523
|
-
console.log("Team join complete:\n");
|
|
524
|
-
console.log(result.summary);
|
|
525
|
-
} catch (err) {
|
|
526
|
-
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
527
|
-
process.exit(1);
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
})
|
|
531
480
|
}
|
|
532
481
|
}),
|
|
533
482
|
knowledge: defineCommand({
|
|
@@ -536,7 +485,7 @@ const main = defineCommand({
|
|
|
536
485
|
export: defineCommand({
|
|
537
486
|
meta: { description: "Export knowledge as JSON" },
|
|
538
487
|
async run() {
|
|
539
|
-
const { exportKnowledge } = await import("./knowledge-io-
|
|
488
|
+
const { exportKnowledge } = await import("./knowledge-io-CII6K2EO.mjs");
|
|
540
489
|
const result = exportKnowledge(process.cwd());
|
|
541
490
|
process.stdout.write(JSON.stringify(result.entries, null, 2) + "\n");
|
|
542
491
|
process.stderr.write(`Exported ${result.count} entries\n`);
|
|
@@ -545,7 +494,7 @@ const main = defineCommand({
|
|
|
545
494
|
import: defineCommand({
|
|
546
495
|
meta: { description: "Import knowledge from JSON (stdin)" },
|
|
547
496
|
async run() {
|
|
548
|
-
const { importKnowledge } = await import("./knowledge-io-
|
|
497
|
+
const { importKnowledge } = await import("./knowledge-io-CII6K2EO.mjs");
|
|
549
498
|
const chunks = [];
|
|
550
499
|
const MAX_SIZE = 50 * 1024 * 1024;
|
|
551
500
|
let totalSize = 0;
|
|
@@ -573,7 +522,7 @@ const main = defineCommand({
|
|
|
573
522
|
diff: defineCommand({
|
|
574
523
|
meta: { description: "Show uncommitted knowledge changes" },
|
|
575
524
|
async run() {
|
|
576
|
-
const { showKnowledgeDiff } = await import("./knowledge-io-
|
|
525
|
+
const { showKnowledgeDiff } = await import("./knowledge-io-CII6K2EO.mjs");
|
|
577
526
|
const result = showKnowledgeDiff(process.cwd());
|
|
578
527
|
if (result.added.length === 0 && result.modified.length === 0 && result.deleted.length === 0) {
|
|
579
528
|
console.log("変更なし");
|
|
@@ -589,28 +538,6 @@ const main = defineCommand({
|
|
|
589
538
|
})
|
|
590
539
|
}
|
|
591
540
|
}),
|
|
592
|
-
"merge-driver": defineCommand({
|
|
593
|
-
meta: { description: "Git merge driver for knowledge files (internal)" },
|
|
594
|
-
args: {
|
|
595
|
-
base: {
|
|
596
|
-
type: "positional",
|
|
597
|
-
description: "Base (ancestor) file"
|
|
598
|
-
},
|
|
599
|
-
ours: {
|
|
600
|
-
type: "positional",
|
|
601
|
-
description: "Current (ours) file"
|
|
602
|
-
},
|
|
603
|
-
theirs: {
|
|
604
|
-
type: "positional",
|
|
605
|
-
description: "Other (theirs) file"
|
|
606
|
-
}
|
|
607
|
-
},
|
|
608
|
-
async run({ args }) {
|
|
609
|
-
const { mergeKnowledgeFiles } = await import("./merge-driver-C-G0Syhj.mjs");
|
|
610
|
-
const exitCode = mergeKnowledgeFiles(args.base, args.ours, args.theirs);
|
|
611
|
-
process.exit(exitCode);
|
|
612
|
-
}
|
|
613
|
-
}),
|
|
614
541
|
version: defineCommand({
|
|
615
542
|
meta: { description: "Show version" },
|
|
616
543
|
args: { short: {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { n as __esmMin } from "./chunk-CAm0Jl7e.mjs";
|
|
3
|
-
import { a as getKnowledgeByIDs, l as incrementHitCount, p as searchKnowledgeKeyword, u as init_knowledge } from "./knowledge-
|
|
4
|
-
import {
|
|
5
|
-
import { a as
|
|
6
|
-
import { i as init_dispatcher, n as emitAdditionalContext } from "./dispatcher-
|
|
3
|
+
import { a as getKnowledgeByIDs, l as incrementHitCount, p as searchKnowledgeKeyword, u as init_knowledge } from "./knowledge-7gqtk8yz.mjs";
|
|
4
|
+
import { r as vectorSearchKnowledge, t as init_vectors } from "./vectors-BVQ0dz9J.mjs";
|
|
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-us-cOlZZ.mjs";
|
|
7
7
|
//#region src/mcp/helpers.ts
|
|
8
8
|
function truncate(s, maxLen) {
|
|
9
9
|
const runes = [...s];
|
|
@@ -92,14 +92,17 @@ async function searchPipeline(store, emb, query, limit, overRetrieve, precompute
|
|
|
92
92
|
}
|
|
93
93
|
function trackHitCounts(store, scoredDocs) {
|
|
94
94
|
if (scoredDocs.length === 0) return;
|
|
95
|
-
|
|
95
|
+
const ids = scoredDocs.filter((sd) => sd.doc.id > 0 && sd.score >= MIN_HIT_SCORE).map((sd) => sd.doc.id);
|
|
96
|
+
if (ids.length === 0) return;
|
|
97
|
+
incrementHitCount(store, ids);
|
|
96
98
|
}
|
|
97
|
-
var RECENCY_FLOOR;
|
|
99
|
+
var RECENCY_FLOOR, MIN_HIT_SCORE;
|
|
98
100
|
var init_helpers = __esmMin((() => {
|
|
99
101
|
init_fts();
|
|
100
102
|
init_knowledge();
|
|
101
103
|
init_vectors();
|
|
102
104
|
RECENCY_FLOOR = .5;
|
|
105
|
+
MIN_HIT_SCORE = .6;
|
|
103
106
|
}));
|
|
104
107
|
//#endregion
|
|
105
108
|
//#region src/hooks/directives.ts
|
|
@@ -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-vtNhjJdP.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-DBnEMJwf.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-n5VcQmRT.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-DK48fw3G.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-6dYu2xfd.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-DhNxcAvM.mjs");
|
|
113
113
|
await stop(ev);
|
|
114
114
|
}
|
|
115
115
|
var init_dispatcher = __esmMin((() => {}));
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { n as __esmMin } from "./chunk-CAm0Jl7e.mjs";
|
|
3
|
-
import { c as readActive, s as init_types, t as SpecDir } from "./types-
|
|
4
|
-
import { n as init_audit, t as appendAudit } from "./audit-
|
|
5
|
-
import {
|
|
3
|
+
import { c as readActive, s as init_types, t as SpecDir } from "./types-BucChDqv.mjs";
|
|
4
|
+
import { n as init_audit, t as appendAudit } from "./audit-tp3tpgzR.mjs";
|
|
5
|
+
import { n as shouldAutoAppend, t as init_lang_filter } from "./lang-filter--xQlqF9A.mjs";
|
|
6
|
+
import { extractChangedFiles, parseDesignFileRefs, t as init_living_spec } from "./living-spec-DEmgB4Gw.mjs";
|
|
6
7
|
//#region src/hooks/drift.ts
|
|
7
8
|
/**
|
|
8
9
|
* Detect source files changed in the last commit that are not referenced in the active spec.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { n as __esmMin } from "./chunk-CAm0Jl7e.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import { r as pairwiseSimilarity, t as init_vectors } from "./vectors-sMr3EQ8X.mjs";
|
|
3
|
+
import { d as mapRow, p as searchKnowledgeKeyword, u as init_knowledge } from "./knowledge-7gqtk8yz.mjs";
|
|
5
4
|
//#region src/store/fts.ts
|
|
6
5
|
function subTypeHalfLife(subType) {
|
|
7
6
|
switch (subType) {
|
|
@@ -180,32 +179,6 @@ function fuzzySearchKnowledge(store, queryWords, limit, exclude) {
|
|
|
180
179
|
}
|
|
181
180
|
return docs;
|
|
182
181
|
}
|
|
183
|
-
function detectKnowledgeConflicts(store, threshold = .7, limit = 1e3) {
|
|
184
|
-
const pairs = pairwiseSimilarity(store, {
|
|
185
|
-
limit,
|
|
186
|
-
minScore: threshold
|
|
187
|
-
});
|
|
188
|
-
const conflicts = [];
|
|
189
|
-
for (const pair of pairs) if (pair.score >= threshold) conflicts.push({
|
|
190
|
-
a: { id: pair.idA },
|
|
191
|
-
b: { id: pair.idB },
|
|
192
|
-
similarity: pair.score,
|
|
193
|
-
type: "potential_duplicate"
|
|
194
|
-
});
|
|
195
|
-
if (conflicts.length > 0) {
|
|
196
|
-
const hydrated = getKnowledgeByIDs(store, conflicts.flatMap((c) => [c.a.id, c.b.id]));
|
|
197
|
-
const docMap = new Map(hydrated.map((d) => [d.id, d]));
|
|
198
|
-
for (const conflict of conflicts) {
|
|
199
|
-
const a = docMap.get(conflict.a.id);
|
|
200
|
-
const b = docMap.get(conflict.b.id);
|
|
201
|
-
if (a) conflict.a = a;
|
|
202
|
-
if (b) conflict.b = b;
|
|
203
|
-
conflict.type = classifyConflict(conflict.a.content, conflict.b.content);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
conflicts.sort((a, b) => b.similarity - a.similarity);
|
|
207
|
-
return conflicts;
|
|
208
|
-
}
|
|
209
182
|
function expandAliases(store, terms) {
|
|
210
183
|
if (terms.length === 0) return [];
|
|
211
184
|
const seen = new Set(terms.map((t) => t.toLowerCase()));
|
|
@@ -221,18 +194,6 @@ function expandAliases(store, terms) {
|
|
|
221
194
|
function sanitizeFTSTerm(term) {
|
|
222
195
|
return term.replace(/["*^{}]/g, "");
|
|
223
196
|
}
|
|
224
|
-
function classifyConflict(contentA, contentB) {
|
|
225
|
-
const lowerA = contentA.toLowerCase();
|
|
226
|
-
const lowerB = contentB.toLowerCase();
|
|
227
|
-
for (const [w0, w1] of CONTRADICTION_PAIRS) {
|
|
228
|
-
const aHas0 = lowerA.includes(w0);
|
|
229
|
-
const aHas1 = lowerA.includes(w1);
|
|
230
|
-
const bHas0 = lowerB.includes(w0);
|
|
231
|
-
const bHas1 = lowerB.includes(w1);
|
|
232
|
-
if (aHas0 && bHas1 && !aHas1 || aHas1 && bHas0 && !bHas1) return "potential_contradiction";
|
|
233
|
-
}
|
|
234
|
-
return "potential_duplicate";
|
|
235
|
-
}
|
|
236
197
|
function levenshtein(a, b) {
|
|
237
198
|
const ra = [...a];
|
|
238
199
|
const rb = [...b];
|
|
@@ -259,21 +220,8 @@ function fuzzyMatch(query, target) {
|
|
|
259
220
|
if (maxDist === 0) maxDist = 1;
|
|
260
221
|
return levenshtein(query.toLowerCase(), target.toLowerCase()) <= maxDist;
|
|
261
222
|
}
|
|
262
|
-
var CONTRADICTION_PAIRS;
|
|
263
223
|
var init_fts = __esmMin((() => {
|
|
264
224
|
init_knowledge();
|
|
265
|
-
init_vectors();
|
|
266
|
-
CONTRADICTION_PAIRS = [
|
|
267
|
-
["always", "never"],
|
|
268
|
-
["must", "must not"],
|
|
269
|
-
["use", "avoid"],
|
|
270
|
-
["enable", "disable"],
|
|
271
|
-
["allow", "deny"],
|
|
272
|
-
["required", "optional"],
|
|
273
|
-
["do", "don't"],
|
|
274
|
-
["add", "remove"],
|
|
275
|
-
["include", "exclude"]
|
|
276
|
-
];
|
|
277
225
|
}));
|
|
278
226
|
//#endregion
|
|
279
|
-
export {
|
|
227
|
+
export { subTypeBoost as a, searchUnified as i, levenshtein as n, subTypeHalfLife as o, searchKnowledgeFTS as r, init_fts as t };
|
|
@@ -160,7 +160,10 @@ function mapRow(r) {
|
|
|
160
160
|
updatedAt: r.updated_at,
|
|
161
161
|
hitCount: r.hit_count,
|
|
162
162
|
lastAccessed: r.last_accessed,
|
|
163
|
-
enabled: r.enabled === 1
|
|
163
|
+
enabled: r.enabled === 1,
|
|
164
|
+
verificationDue: r.verification_due ?? null,
|
|
165
|
+
lastVerified: r.last_verified ?? null,
|
|
166
|
+
verificationCount: r.verification_count ?? 0
|
|
164
167
|
};
|
|
165
168
|
}
|
|
166
169
|
var init_knowledge = __esmMin((() => {}));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as contentHash, u as init_knowledge } from "./knowledge-
|
|
3
|
-
import {
|
|
2
|
+
import { t as contentHash, u as init_knowledge } from "./knowledge-7gqtk8yz.mjs";
|
|
3
|
+
import { n as levenshtein, t as init_fts } from "./fts-CG3NjtDr.mjs";
|
|
4
4
|
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { join, relative } from "node:path";
|
|
6
6
|
import { execFileSync, execSync } from "node:child_process";
|