@kienntpixon/dieu-phoi 0.5.2 → 0.6.0
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/CHANGELOG.md +73 -0
- package/README.md +9 -3
- package/agents/dp-exec.md +2 -0
- package/agents/dp-scout.md +2 -0
- package/agents/dp-verify.md +2 -0
- package/bin/dieu-phoi.cjs +21 -3
- package/hook.cjs +907 -19
- package/lib/args.cjs +19 -2
- package/lib/commands.cjs +109 -22
- package/lib/knowledge.cjs +1002 -0
- package/lib/profile.cjs +204 -0
- package/lib/prune.cjs +57 -20
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,78 @@
|
|
|
1
1
|
# Changelog — @kienntpixon/dieu-phoi
|
|
2
2
|
|
|
3
|
+
## 0.6.0 (2026-10-22)
|
|
4
|
+
|
|
5
|
+
`CORE_VERSION` 0.6.0; đi cùng skill 1.5.0. Gộp nhánh `s5-parallel-safety` và `knowledge` (kế hoạch 464k2t30). `sheet/` không đổi, không cần deploy lại `Code.gs`.
|
|
6
|
+
|
|
7
|
+
An toàn khi chạy nhiều phiên dieu-phoi song song (contract 464k2t30, bước s5).
|
|
8
|
+
|
|
9
|
+
- **`prune --yes` không còn làm mất event:** `appendEvent` giờ giữ `data/events.lock` (tạo `wx`, ~0,3 ms/lần; chờ tối đa 1,5 s < timeout hook 5 s) và `prune` đọc → ghi tmp → rename `events.jsonl` dưới đúng khoá đó, nên dòng ghi giữa lúc đọc và rename (khe cũ ở `prune.cjs`) không còn bị đè. Trên Windows rename gặp fd của hook đang mở từng ném EPERM; nay hook phải chờ khoá nên không xảy ra. Quá 1,5 s thì `appendEvent` vẫn ghi (không bỏ telemetry), còn `prune` bỏ cuộc và để nguyên `events.jsonl` (exit 1). Khoá bỏ dở > 30 s (prune: 60 s) bị chiếm lại; chủ cũ không xoá nhầm khoá đã bị chiếm. Offset sync được đọc lại dưới khoá.
|
|
10
|
+
- **`prune --yes` từ chối khi phiên khác đang chạy:** nếu có event (có `session`) của phiên khác trong 15 phút gần nhất thì exit 1, không đổi gì. Phiên của bạn = `--session <id>` hoặc `$CLAUDE_CODE_SESSION_ID`; không biết thì mọi phiên đều tính. `--force` bỏ qua. Dry-run luôn chạy được; event không gắn phiên (verdict/steer/discard) không tính. `--lock-timeout-ms` chỉnh thời gian chờ khoá (mặc định 15 s).
|
|
11
|
+
- **`ctx-warn.json` ghi dưới `ctx-warn.lock`:** `ctxWarnOnce` đọc-sửa-ghi trong khoá; hai phiên cùng cảnh báo không còn đè mục của nhau (cảnh báo lặp). Hết thời gian chờ thì chạy không khoá (trạng thái chỉ để tham khảo).
|
|
12
|
+
- Helper mới `acquireFileLock` / `withFileLock` trong `hook.cjs`. Test mới `test/parallel-safety.test.cjs` (ghi đồng thời + prune không mất dòng nào — trên code cũ test này fail; từ chối khi phiên khác chạy; ctx-warn song song; khoá).
|
|
13
|
+
|
|
14
|
+
Kế hoạch 464k2t30, bước s1 (nhánh `knowledge`): khoá project cho kho knowledge dùng chung.
|
|
15
|
+
|
|
16
|
+
- **Khoá project cho đường dẫn bất kỳ** (`resolveProject`, `hook.cjs`): `remote:<host>/<path>` từ `remote.origin.url` đã chuẩn hoá (bỏ scheme, credential, cổng ssh, `.git`; host viết thường — ssh và https của một repo ra cùng khoá, fork khác URL thì khác khoá), repo không có remote thì `git:<realpath git-common-dir>`. Worktree (`.git` là file `gitdir:` + `commondir`), subdir và clone cùng remote ra cùng khoá; ngoài git → null. Kho đặt ở `~/.dieu-phoi/projects/<tên>-<sha8(khoá)>` (env `DIEU_PHOI_PROJECTS_DIR`); chưa tạo thư mục nào ở bước này.
|
|
17
|
+
- **Chỉ đọc file, không spawn git** (đường nóng của hook): tìm `.git`, `commondir`, `config`; `readHead` đọc `HEAD` → loose ref → `packed-refs` (đúng với worktree, detached, unborn; repo reftable trả `unsupported: 'reftable'` để CLI tự rơi về `git rev-parse`). Đo trên repo thật: 1–3 ms/lần đầu, ~0,6 ms/lần với `projectFields`; HEAD trùng `git rev-parse` ở cả 6 repo họ fast-forward.
|
|
18
|
+
- **`dieu-phoi knowledge path [--json]` và `knowledge rekey [--from <kho>]`**: `path` in thư mục kho (`--json`: khoá, loại, tên, HEAD, alias, gợi ý rekey). `rekey`: repo vừa thêm remote nên khoá đổi → ghi khoá mới thành alias của kho cũ trong `projects/aliases.json` (dưới khoá `aliases.lock`, ghi tmp+rename; không đổi tên/di chuyển thư mục; từ chối khi hai kho cùng tồn tại hoặc `--from` không nằm trong kho).
|
|
19
|
+
- **`--repo <đường dẫn>` cho mọi lệnh**: kiểm thư mục tồn tại ngay ở bin (lỗi → exit 1); `repoOf(opts)` trong `args.cjs` (mặc định cwd, chấp nhận `/d/x` của git-bash). `start --json` thêm `project` (null ngoài repo; bản chữ không đổi).
|
|
20
|
+
- **Event `dispatch` có `project` + `project_src`**: đích của việc là dòng `repo: <đường dẫn>` đầu tiên trỏ tới thư mục có thật trong brief (phiên ở repo cha giao việc cho repo con), không có thì `cwd` của payload; ngoài repo không ghi gì. Chỉ cục bộ — sink không thêm cột (Code.gs bỏ trường lạ). Test mới `test/project-key.test.cjs` (18 ca: chuẩn hoá URL, worktree thật + fixture `<repo>-wt/*`, hai clone, fork, ngoài git, HEAD, không spawn, alias rekey, `--repo`).
|
|
21
|
+
|
|
22
|
+
Bước s2 (cùng nhánh): kho knowledge theo mục.
|
|
23
|
+
|
|
24
|
+
- **Kho `<projects>/<tên>-<sha8>/`**: `index.json` `{schema, key, name, related, sections: [{id, title, tags, paths, sha, rev, updated, lines}]}`, `sections/<id>.md` (chỉ thân mục, ≤ 40 dòng, LF), `history/<id>/r<rev>-<sha7>-<giờ>.md` (bản bị thay, dòng đầu là entry cũ dạng JSON), `meta.json` (`keys`, `created`). Đọc không bao giờ tạo kho; `index.json` hỏng → merge từ chối, không ghi đè.
|
|
25
|
+
- **`knowledge get <id|từ khoá>... [--path f[,f]] [--follow] [--json]`**: id khớp đúng, hoặc mọi từ khoá khớp đầu một từ trong id/tag/tiêu đề ("ui" không khớp "build"); `--path` trả các mục có glob `paths` khớp file (đường dẫn trong repo; tuyệt đối và `./` tính từ cwd/`--repo`; `**`, `*`, `?`, thư mục trần); có cả hai thì lấy giao. Mỗi mục in `base: <sha>#<rev>` để chép vào delta. `--follow` tra thêm kho cha qua `related`. `children`/`upstream` chưa lưu thì dựng từ `related`. Không mục nào khớp → exit 1 (khớp một phần: in thêm "không khớp: ...").
|
|
26
|
+
- **`knowledge list [--follow] [--json]`**: id, số dòng, `sha#rev`, ngày, tiêu đề, tags, paths, related (và kho cha với `--follow`).
|
|
27
|
+
- **`knowledge merge --run <id|thư mục> [--dry-run] [--json]`**: gộp mọi `knowledge-delta*.md` của run (theo số `-r<n>`). Header `repo:` chọn kho (phiên ở repo cha ghi được vào kho repo con); đường dẫn đã mất (worktree xoá) thì cần `--repo`. `sha` = HEAD đọc từ file của repo đó (reftable → `git rev-parse`) hoặc dòng `head:`. `## +id` thêm (bắt buộc `paths:`; id đã có với nội dung khác → xung đột), `## id` thay (kế thừa title/tags/paths nếu bỏ trống; bắt buộc `base:` khớp sha — và rev nếu ghi `#rev` — của mục hiện tại, không thì xung đột và giữ nguyên mục). Nội dung trùng bản đang có → "không đổi" (chạy lại merge vô hại). Mục > 40 dòng, thân rỗng, id sai, thay mục chưa có → từ chối; các mục khác vẫn gộp. Có xung đột/từ chối/file lỗi → exit 2. Cả lượt đọc–sửa–ghi index nằm trong `knowledge.lock` (chờ tối đa 10 s, lock cũ > 5 phút tự bỏ); `## ` trong khối code không tách mục.
|
|
28
|
+
- **`knowledge link <repo> --rel child|parent [--remove]`**: ghi liên kết hai chiều vào `related` của cả hai kho (`{key, name, path, rel}`), idempotent, không đụng mục.
|
|
29
|
+
- Test mới `test/knowledge-store.test.cjs` (10 ca): glob, parse delta, thêm/get/list/`--path` (cả từ worktree), thay + history + xung đột theo sha và theo rev + thiếu base + chạy lại, từ chối, **2 tiến trình merge đồng thời** (mở rộng cửa sổ đọc–ghi 300 ms bằng env test `DIEU_PHOI_TEST_KNOWLEDGE_LOCK_DELAY_MS`: 24/24 mục mới còn đủ, mục chung thay đúng một lần, bên kia xung đột; bỏ khoá thì test hỏng), header `repo:`/`head:`/dry-run, index hỏng, link + `--follow`. Mọi kho/run nằm trong thư mục tạm.
|
|
30
|
+
|
|
31
|
+
Bước s3 (cùng nhánh): độ tươi của mục knowledge.
|
|
32
|
+
|
|
33
|
+
- **Độ tươi theo mục** (`computeFreshness` trong `hook.cjs` — hook phải tự chứa nên logic nằm ở đó, `knowledge.cjs` dùng lại; `globMatch` chuyển sang hook): mục `stale` khi có file khớp `paths` đổi giữa `sha` của mục và HEAD (diff ròng, kể cả sha trên nhánh chưa merge). MỘT tiến trình `git --no-optional-locks diff-tree --stdin --always -r --name-only --no-renames -z -- <pathspec>` cho mọi sha khác nhau (pathspec `:(glob)`, win32 thêm `icase`; glob có `**` đầu/`..`/tuyệt đối/quá dài → cả repo rồi lọc bằng JS; pathspec bị từ chối → chạy lại không pathspec). sha == HEAD → tươi, không spawn. sha rỗng/rút gọn/không có trong repo → `unknown` (không chặn). Git lỗi hoặc quá thời gian → mọi mục `unknown` + `error`, không cache.
|
|
34
|
+
- **Cache `<kho>/cache/freshness.json`**: khoá HEAD + mtime/size của `index.json`, giữ ≤ 12 HEAD, ghi tmp+rename best-effort. HEAD không đổi → 0 tiến trình git.
|
|
35
|
+
- **Dòng `project_knowledge:` trong khối start** (hook `UserPromptSubmit` và `dieu-phoi start`): `<kho> — N mục, k stale (ids)[, u không xác định (ids)] · HEAD abc1234 · …`. Hook chỉ làm tươi repo hiện tại (tối đa một `diff-tree`, timeout `HOOK_DIFF_TIMEOUT_MS` = 1500 ms; quá → dòng ghi "git lỗi (quá 1500 ms)", start vẫn chạy, exit 0), không bao giờ `git status`; repo `related` chỉ đọc cache ("độ tươi chưa kiểm" nếu chưa có). Ngoài repo / chưa có kho → không có dòng.
|
|
36
|
+
- **`knowledge get`/`list`** gắn độ tươi (`get`: dòng "STALE — n file đổi…"/"độ tươi: tươi"/"không xác định — …", JSON `fresh`/`stale`/`stale_count`/`fresh_why`; `list`: cột `ok/STALE/?` + HEAD). `get --follow` làm tươi kho cha qua `related.path`.
|
|
37
|
+
- **Lệnh mới `knowledge status [--follow] [--dirty] [--no-cache] [--json]`**: tóm tắt độ tươi; `--dirty` thêm file chưa commit khớp `paths` (`git status --porcelain=v1 -z -uno --no-renames`, timeout 2 s → "chưa kiểm"); `--no-cache` bỏ qua cache.
|
|
38
|
+
- Test mới `test/knowledge-fresh.test.cjs` (8 ca: stale đúng mục từ worktree/subdir, nhiều sha một diff-tree, sha ma/rút gọn/null, nhánh chưa merge, không có git, cache không spawn, `--dirty` + timeout, pathspec, khối start). `test/_fixtures.cjs` mặc định `DIEU_PHOI_PROJECTS_DIR` tạm. Benchmark chỉ đọc `scripts/bench-knowledge.cjs <repo>... [--json]` (không publish; kiểm `.git/index` + HEAD không đổi). Đo 22/10 (30 mục): pff-dressmaker (625 commit, 22,7k file) lạnh 205–330 ms, cache 1,4 ms, hook có kho + cache hit +0 ms so với ngoài repo, cache miss 146–620 ms wall (mặc định), tiêm git chậm 5 s → hook trả sau ~1,57 s với 30 mục "không xác định", exit 0; pff-rotate-rings lạnh ~50 ms, hook miss +48 ms.
|
|
39
|
+
- Ngoài phạm vi s3: TTL cho mục chung (contract E).
|
|
40
|
+
|
|
41
|
+
Bước s4 (cùng nhánh): knowledge đi vào luồng 4 cổng + retro không ghi đè.
|
|
42
|
+
|
|
43
|
+
- **`verdict … accept` tự gộp knowledge** (`commands.cjs`: `rootOfTask`, `knowledgeOnAccept`): `--task T accept` gộp `knowledge-delta-T*.md` của run gốc (tìm plan có bước T); `--root R accept` gộp delta của R + các bước vừa accept + file không mang task_id. Reject không gộp; `--no-knowledge` bỏ qua. Xung đột/từ chối không đổi verdict (vẫn exit 0): output in `XUNG ĐỘT`/`TỪ CHỐI` + lệnh `dieu-phoi knowledge merge --run … --task …` để chạy lại; `--json` đẩy báo cáo knowledge ra stderr.
|
|
44
|
+
- **`knowledge merge --task a,b [--untagged]`**: chỉ gộp delta của các task đó. Quy ước tên delta: `knowledge-delta-<task_id>[-r<n>].md`; file không mang task_id = "untagged". `deltaFiles`/`deltaTaskOf` export.
|
|
45
|
+
- **`knowledge bootstrap [--repo R] [--children <mẫu>] [--json]`**: chỉ đọc, không tạo kho — nguồn để seed (docs gốc + 1 cấp, bỏ node_modules/Assets…; ≤ 15 file run cũ có nhắc repo), repo anh em khớp mẫu (cho mục `children`, không link), mục đã có/nên có, mẫu delta.
|
|
46
|
+
- **Lệnh mới `profile base --save <dir>` / `profile apply --base <dir> [--lessons F] [--profile F] [--dry-run] [--json]`** (`lib/profile.cjs`): retro dựng đề xuất từ bản chụp, apply dưới `profile/profile.lock`: không đổi → ghi; lessons chỉ thêm dòng → gộp (chèn sau dòng neo, neo mất → cuối file); dòng cũ sửa/xoá hoặc `profile.json` đổi → exit 2, không ghi file nào; kiểm lại file sống ngay trước rename, lệch → làm lại (≤ 5 lần). Còn khe < 1 ms giữa lần đọc cuối và rename (người `>>` không lấy khoá) — ghi ở đầu `profile.cjs`.
|
|
47
|
+
- `args.cjs`: cờ boolean `untagged`, `no-knowledge`. Help: verdict, `knowledge …|status|bootstrap`, `profile`.
|
|
48
|
+
- **Agent `dp-scout`/`dp-exec`/`dp-verify`** (`agents/`): `repo:` của brief là repo đích; tra `knowledge list/get --repo` trước khi đọc code; codebase-memory-mcp khi repo đã có index; worktree + cổng riêng, chỉ kill tiến trình của mình; exec/scout ghi `knowledge-delta-<task_id>.md`, không tự merge. Cần `dieu-phoi setup` lại để cài bản mới.
|
|
49
|
+
- Test mới `test/knowledge-s4.test.cjs` (12 ca): merge `--task`; verdict accept/reject/`--no-knowledge`; xung đột giữ verdict; `--root` gộp root + bước + untagged; bootstrap chỉ đọc; profile: không đổi, append trong lúc retro, chèn theo neo, sửa dòng → dừng, `profile.json` đổi → dừng, base thiếu/sửa/JSON hỏng, `>>` trong lúc apply → làm lại. `ctx-cap` test theo skill 1.5.0. Benchmark `knowledge-fresh` lấy min của 5 lần cache hit (start: 3 lần) thay một mẫu — một mẫu đơn từng 93 ms khi chạy chung suite (GC/lịch CPU), ngưỡng 50 ms/150 ms giữ nguyên.
|
|
50
|
+
|
|
51
|
+
Sửa 3 lỗi nhỏ của s4 (task 9f33dy5p, kết quả verify byicfcgy), cùng nhánh `knowledge`:
|
|
52
|
+
|
|
53
|
+
- **`verdict --root R accept` không còn bước chờ vẫn gộp delta của root + delta không thẻ** (`commands.cjs`: `verdictRoot` trả danh sách rỗng thay vì ném lỗi, `cmdVerdict` gộp `[R]` + untagged): trước đây mọi bước đã accept riêng bằng `--task` thì exit 1 trước bước gộp, delta của root/untagged không bao giờ được gộp. Giờ in "Không còn bước nào … chờ nghiệm thu", exit theo kết quả gộp (0 gộp xong hoặc không có gì mới — chạy lại idempotent; 2 xung đột/từ chối; 1 lỗi). Không có bước chờ **và** không có delta nào → vẫn lỗi cũ exit 1. `--json` in `[]`.
|
|
54
|
+
- **Output `knowledge bootstrap` khớp brief G**: bỏ câu "rồi dieu-phoi knowledge merge …"; thay bằng "Agent KHÔNG tự chạy knowledge merge: kho chỉ đổi khi người dùng accept" + lệnh kiểm `merge … --dry-run`.
|
|
55
|
+
- **Số dòng một luật duy nhất** (`countLines` trong `knowledge.cjs`: CRLF, CR hoặc LF ngắt dòng; dòng trống cuối không tính): giới hạn ≤ 40 của merge, `lines` lưu trong index, `knowledge get` (`lines`), bootstrap (số dòng tài liệu) đếm cùng cách. `knowledge list` (và `list --json`) lấy số dòng thật từ `sections/<id>.md`, chỉ dùng giá trị index khi không đọc được file, nên không thể lệch với thân mà `get` in. Lưu ý: `get` in thêm 3–4 dòng đầu (tiêu đề, meta, base, độ tươi) trước thân; cột `NNd` chỉ đếm thân.
|
|
56
|
+
- Test: 3 ca mới + 1 assert thêm trong `test/knowledge-s4.test.cjs` (root không còn bước: gộp / idempotent / `--json` / lỗi cũ khi không có delta / xung đột exit 2; bootstrap không gợi ý merge; list/get đếm CRLF, CR lẻ, dòng trống giữa thân, index lệch; 41 dòng CR bị từ chối, 40 qua).
|
|
57
|
+
|
|
58
|
+
Bước s4b (cùng nhánh, task 7wytvsez): `knowledge merge` idempotent.
|
|
59
|
+
|
|
60
|
+
- **Lỗi**: `merge --task <id>` và auto-merge của `verdict … accept` gộp lại các file delta đã gộp trước đó trong run dir; `## +id` của delta cũ gặp mục đã lên rev 2 → XUNG ĐỘT, exit 2 (task foq5o6jv).
|
|
61
|
+
- **Sổ delta đã áp**: mỗi file delta gộp xong (có thêm/thay mục, không xung đột/từ chối) được ghi `{sha256, file, run, at}` vào `meta.json` → `applied` của kho (trong `knowledge.lock`, tối đa 300 mục). Lần sau file cùng nội dung (hash sau khi bỏ BOM, CRLF → LF) bị bỏ qua: mọi mục "không đổi: file delta đã gộp trước đó", exit 0. File đã sửa sau khi áp hash khác → gộp như delta mới. `--dry-run` đọc sổ nhưng không ghi.
|
|
62
|
+
- **Nhận diện kho đã seed (không có sổ)**: mục `## +id` (hoặc `## id` với base cũ) mà nội dung (thân + title + tags + paths) trùng một rev cũ còn trong `history/<id>/` được coi là "không đổi: khớp rev N cũ, đã gộp trước đó" thay vì xung đột. Không ghi gì vào kho (kể cả sổ). `## id` có base đúng hiện tại vẫn là thay thế bình thường (kể cả quay về nội dung cũ có chủ ý); nội dung chưa từng thấy vẫn xung đột, exit 2.
|
|
63
|
+
- Test mới `test/knowledge-idem.test.cjs` (6 ca): merge hai lần liên tiếp (lần 2 no-op exit 0, kho giống từng byte), file sửa sau khi áp + bản CRLF, delta cũ sau khi mục đã lên rev, kho seed không có sổ, xung đột thật vẫn exit 2 và không vào sổ + revert có chủ ý, dry-run.
|
|
64
|
+
|
|
65
|
+
## 0.5.3 (2026-10-22)
|
|
66
|
+
|
|
67
|
+
Đề xuất core 1–3 của retro 2026-10-22 (`~/.dieu-phoi/runs/258ajcrr/retro-2026-10-22.md`). `CORE_VERSION` 0.5.3; đi cùng skill 1.4.3. Không cần deploy lại `sheet/Code.gs`.
|
|
68
|
+
|
|
69
|
+
- **Thẻ sai được gắn cờ thay vì mất task_id:** 76 dp-exec ($407, 25% chi phí 10-19..21) mất `task_id` vì brief đặt id vào ô loại (`[dp:<id>|…]`, thiếu `task=`). Hook mới có `resolveTag` (`parseTag` giữ nguyên, gate gen-2 vẫn dùng bản chặt): `dispatch`/`complete` mang `tag_issue` = `type-is-id|bad-type|missing-task|no-tag` (nối `+`); thiếu `task=` mà ô loại là id (đúng định dạng, không phải loại đã biết, có chữ số hoặc được nhắc trong `dp-out-<id>`/`handoff-<id>`/`task=<id>` của brief) → `task_id` = id đó + `task_id_inferred: true`, loại lấy từ phần khác của thẻ nếu có. Id bắt đầu bằng chữ số (trước đây `parseTag` trả null, agent thành `untagged` và không có watchdog) giờ cũng được nhận. Loại hợp lệ = 12 loại cố định + `art-gen` + `extra_task_types` của profile.
|
|
70
|
+
- **Cảnh báo trả về điều phối viên:** PostToolUse(Agent) in `additionalContext` khi thẻ bị gắn cờ (nêu lỗi, id đã suy hoặc "không vào stats", mẫu thẻ đúng, danh sách loại). Agent không phải `dp-*` và không có thẻ: không cờ, không in.
|
|
71
|
+
- **Dispatch ghi tier `choose` đã đề xuất:** `choose --task` và `plan-table --approve` để lại `data/suggest/<task>-<role>.json`; dispatch kế tiếp của task + role đó ghi `suggested_tier` (tier choose tự chọn, trước override), `choose_tier` (tier choose trả về), `suggested_source`, `dispatched_tier`, `tier_mismatch`. Bản ghi > 14 ngày bị bỏ qua.
|
|
72
|
+
- **Trần chuỗi handoff:** dispatch exec ghi `task_handoffs` (số agent đã handoff của task); từ handoff thứ 3 hook cảnh báo dừng tiếp nối và giao planner chia phần còn lại (retro: 15/63 task feature-impl handoff ≥ 2 lần; cq7yn1ws 10 handoff, $70, fail).
|
|
73
|
+
- **Sửa hai lỗi nhỏ của cảnh báo thẻ:** `bad-type` nêu đúng token sai (trường `bad_type`) kể cả khi thẻ có thêm một loại hợp lệ (`[dp:foo|review|…]` báo "foo", không phải "review"); watchdog (`readHeadTag`) nay truyền `extra_task_types` của profile nên loại của profile không bị coi là `bad-type`.
|
|
74
|
+
- Sink không thêm cột (các trường mới là chẩn đoán cục bộ; `suggested_tier` trùng tên cột sẵn có của `override`). Test mới `test/retro-1022.test.cjs`.
|
|
75
|
+
|
|
3
76
|
## 0.5.2
|
|
4
77
|
|
|
5
78
|
- **`dieu-phoi prune --after-retro <file> [--yes]`:** dọn sau retro, dry-run mặc định. Run dir của task đã có verdict người dùng và mọi sự kiện ≤ mốc cắt (dòng `cutoff:` trong file retro, không có thì mtime) chỉ còn `retro-*.md` + dp-out exec/verify cuối (giữ = try cao nhất VÀ file mới nhất theo mtime cho mỗi task+role; file legacy không phân loại được và kết quả inline cuối cũng giữ); xoá file plan hỏng (tên không phải task id hoặc không đọc được); task còn mở không đụng. Event của task đã dọn chuyển vào `data/archive/events-<ngày>.jsonl.gz` (ghi + xác minh archive trước, rồi ghi lại `events.jsonl` qua file tạm + rename, giữ khoá sync); `readEvents` đọc cả archive (chống trùng nếu prune chết giữa chừng) nên retro/stats/choose/state không đổi số; sync chỉ đọc `events.jsonl`, offset được dịch theo phần đã bỏ, event chưa đẩy lên sink (khi có sink) không bị chuyển. Run dir có file mới hơn mốc cắt (việc đang chạy chưa vào log) không bị dọn. Từ chối gốc ổ đĩa, không đi theo symlink/junction, chỉ đụng runs dir + data dir.
|
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ Khởi động lại Claude Code sau khi cài. Kiểm tra bằng `dieu-phoi doct
|
|
|
43
43
|
| `doctor [--net] [--json]` | kiểm node, hook, settings (+ `prompt-hook`), config, profile, sink (từ bộ nhớ đệm 24 giờ; `--net` kiểm trực tiếp); context phiên điều phối hiện tại nếu đo được (`orch-ctx`); thư mục `~/.dieu-phoi/runs` + quyền của nó, không còn luật cũ (`run-permissions`); `--json` có `runs_dir` |
|
|
44
44
|
| `verdict <agent_id\|last> <pass\|fail\|timeout\|aborted> [--verify tests\|lint\|review\|judgment\|none] [--reason short-kebab]` | nghiệm thu tầng agent (`by=agent`). `aborted` (0.4.0) = dừng vì usage limit/quota: không pass/fail, không leo thang; hook tự ghi khi bắt được. `last` = agent hoàn thành gần nhất; từ chối (liệt kê ứng viên) nếu trong 30 phút qua có > 1 agent xong mà chưa có verdict. Được viết tắt agent_id nếu không trùng |
|
|
45
45
|
| `verdict --task <task_id> <accept\|reject> [--cause quality\|scope] [--round n] [--reason R]` | nghiệm thu của **người dùng** (`by=user`). `reject` bắt buộc `--cause`: `quality` = làm sai (tính là fail), `scope` = yêu cầu đổi/thiếu (không tính cho model). `--round` mặc định tự tăng |
|
|
46
|
-
| `verdict --root <root_task_id> accept [--steps a,b]` | (0.4.0) người dùng nhận một lúc mọi bước đã giao exec của kế hoạch đã duyệt mà chưa có verdict người dùng |
|
|
46
|
+
| `verdict --root <root_task_id> accept [--steps a,b]` | (0.4.0) người dùng nhận một lúc mọi bước đã giao exec của kế hoạch đã duyệt mà chưa có verdict người dùng. (0.6.0) `accept` tự gộp knowledge: `--task T` gộp `knowledge-delta-T*.md` của run gốc; `--root R` gộp delta của R + các bước vừa accept + file không mang task_id. Xung đột/từ chối không đổi verdict (exit 0): output in `XUNG ĐỘT` + lệnh `knowledge merge` để chạy lại. `--root` mà mọi bước đã có verdict người dùng: vẫn gộp delta của R + file không thẻ, exit theo kết quả gộp (không có delta nào → lỗi "không có bước nào cần nghiệm thu"). `reject` không gộp; `--no-knowledge` bỏ qua |
|
|
47
47
|
| `discard --task <task_id> [--reason R]` | (0.4.0) rút một task nhầm khỏi stats/choose/state/sink bằng sự kiện `discard` — không bao giờ sửa tay `events.jsonl` |
|
|
48
48
|
| `steer <agent_id> \| --task <task_id> --kind minor\|plan\|redirect [--reason R]` | ghi **một** lần người dùng lái giữa chừng (một `steer_id`). `--task` chỉ đánh dấu agent đang chạy của task; không có agent nào đang chạy → bản ghi cấp task. `plan`/`redirect` trước verdict loại lượt đó khỏi tỉ lệ của tier (chi phí vẫn tính); steer không xoá fail đã ghi |
|
|
49
49
|
| `stats [--type T] [--json]` | các ô `task_type × model/effort` theo "Thước đo" của `CONTRACT.md`: n, n_excluded, accept_rate, agent_pass_rate, chi phí/thời gian mỗi task (TB, p50, p75); bảng steer theo task_type; tóm tắt điều phối (`orchestration`: số phiên, context p50/max, chi phí điều phối vs subagent, `orch_share`) |
|
|
@@ -54,7 +54,13 @@ Khởi động lại Claude Code sau khi cài. Kiểm tra bằng `dieu-phoi doct
|
|
|
54
54
|
| `start [--json]` | khởi động cổng 1 trong một lệnh, không gọi mạng: kiểm cục bộ, `root_task_id` + `step_ids`, tạo run dir, đường dẫn brief scout. Thường không cần: hook `UserPromptSubmit` làm sẵn việc này khi prompt có "điều phối" hoặc bắt đầu bằng `/dieu-phoi` |
|
|
55
55
|
| `new-id [--count n] [--json]` | in task_id mới hợp lệ (đúng 8 ký tự `a-z0-9`), mỗi dòng một id (mặc định 1, tối đa 1000; `--json`: mảng). Lấy mọi `task_id` / `root_task_id` từ đây — không tự bịa. `choose/verdict/steer --task` và `plan-table --approve` từ chối id sai định dạng (kèm gợi ý id mới); hook vẫn ghi id cũ nhưng gắn `task_id_invalid: true`, `doctor` cảnh báo |
|
|
56
56
|
| `sync [--json]` | đẩy bản ghi chưa đồng bộ lên sink, lô ≤ 200, có thử lại. Bản ghi sink từ chối → `data/sync-rejected.jsonl`, `doctor` báo số lượng |
|
|
57
|
-
| `prune --after-retro <file> [--yes]` | dọn sau retro (dry-run mặc định): run dir đã nghiệm thu, plan hỏng, event cũ → `data/archive/*.jsonl.gz` |
|
|
57
|
+
| `prune --after-retro <file> [--yes] [--session <id>] [--force]` | dọn sau retro (dry-run mặc định): run dir đã nghiệm thu, plan hỏng, event cũ → `data/archive/*.jsonl.gz`. `--yes` từ chối khi phiên khác có sự kiện trong 15 phút gần nhất (phiên của bạn = `--session` hoặc `$CLAUDE_CODE_SESSION_ID`; `--force` bỏ qua) và ghi lại `events.jsonl` dưới `events.lock` — cùng khoá mà hook dùng khi ghi event |
|
|
58
|
+
| `knowledge path [--json]` / `knowledge rekey [--from <kho>]` | (0.6.0) khoá project và thư mục kho knowledge của repo (`--repo` hoặc cwd; mọi worktree/clone của một repo ra cùng thư mục `~/.dieu-phoi/projects/<tên>-<sha8>`; env `DIEU_PHOI_PROJECTS_DIR` để đổi). Khoá = `remote.origin.url` đã chuẩn hoá (bỏ scheme/credential/`.git`, host viết thường; ssh và https của một repo trùng khoá), repo không remote thì realpath của `git-common-dir`. Chỉ đọc file, không spawn git. `rekey`: repo vừa thêm remote nên khoá đổi, ghi khoá mới thành alias của kho cũ (`projects/aliases.json`) thay vì đổi tên thư mục. Tuỳ chọn chung `--repo <đường dẫn>` hợp lệ cho mọi lệnh (kiểm tra thư mục tồn tại) |
|
|
59
|
+
| `knowledge list [--follow]` / `knowledge get <id\|từ khoá>... [--path f] [--follow]` / `knowledge merge --run <id> [--dry-run]` / `knowledge link <repo> --rel child\|parent [--remove]` | (0.6.0) kho knowledge theo mục: `index.json` (`related` + `sections: [{id, title, tags, paths, sha, rev, updated, lines}]`), `sections/<id>.md` (≤ 40 dòng), `history/`. `get` in đúng mục cần (id, từ khoá theo đầu từ trong id/tag/tiêu đề, hoặc `--path` = các mục có glob khớp file; cả hai = giao), kèm dòng `base: <sha>#<rev>`; `--follow` tra thêm kho cha; `children`/`upstream` chưa lưu thì dựng từ `related`. Chỉ `merge` ghi: đọc `knowledge-delta*.md` của run, header `repo:` chọn kho (thiếu thì `--repo`/cwd), `## +id` thêm (bắt buộc `paths:`), `## id` thay (bắt buộc `base:`; base cũ → xung đột, không ghi đè), giữ `knowledge.lock`, tmp+rename, bản cũ vào `history/`, `sha` = HEAD của repo đó (hoặc `head:`). Có xung đột/từ chối → exit 2. `link` ghi liên kết cha–con vào `related` của cả hai kho. `get`/`list` gắn độ tươi mỗi mục (`STALE` khi file khớp `paths` đổi từ `sha` của mục tới HEAD; `?` = không xác định) |
|
|
60
|
+
| `knowledge status [--follow] [--dirty] [--no-cache] [--json]` | (0.6.0) độ tươi của kho: một `git diff-tree --stdin` cho mọi sha, cache `<kho>/cache/freshness.json` theo HEAD (HEAD không đổi → không spawn git). `--follow` cả kho cha, `--dirty` thêm file chưa commit khớp `paths` (timeout 2 s), `--no-cache` tính lại. Khối start (hook và `dieu-phoi start`) có dòng `project_knowledge: <kho> — N mục, k stale (ids) · HEAD …` khi repo có kho; hook chỉ diff repo hiện tại, tối đa 1500 ms, quá thì ghi "không xác định" và không chặn |
|
|
61
|
+
| `knowledge merge --run <id> --task a,b [--untagged]` | (0.6.0) chỉ gộp `knowledge-delta-<task_id>[-r<n>].md` của các task đó (`--untagged`: thêm file không mang task_id) — bước `verdict … accept` tự gọi |
|
|
62
|
+
| `knowledge bootstrap [--repo R] [--children "pff-*,fff-*"] [--json]` | (0.6.0) **chỉ đọc**, không tạo kho: liệt kê nguồn để seed (CLAUDE.md/AGENTS.md/README/CONTRACT ở gốc + 1 cấp, ≤ 15 context-r/contract/handoff cũ có nhắc repo), repo anh em khớp mẫu cho mục `children` (không link — link sẽ tạo kho cho con), mục đã có, mục nên có, mẫu delta. Agent seed theo brief G của skill |
|
|
63
|
+
| `profile base --save <dir>` / `profile apply --base <dir> [--lessons F] [--profile F] [--dry-run]` | (0.6.0) retro không ghi đè bài học mới: `base` chụp `profile/lessons.md` + `profile.json` vào `<dir>/profile-base/` (kèm sha256); `apply` dưới `profile/profile.lock`: file sống chưa đổi → ghi đề xuất; lessons chỉ có dòng thêm mới → tự gộp (chèn sau dòng neo); dòng cũ bị sửa/xoá hoặc `profile.json` đổi → exit 2, không ghi gì; kiểm lại ngay trước rename, lệch thì làm lại (≤ 5 lần) |
|
|
58
64
|
| `retro [--json]` | tóm tắt cho vòng retro: số liệu từng ô, đếm `reason_code`, danh sách loại task, tóm tắt điều phối (`orchestration`) |
|
|
59
65
|
| `uninstall [--purge]` | gỡ hook và đúng các quyền thư mục `runs` đã thêm khỏi settings (có sao lưu); `--purge` xoá cả `hook.cjs`. Dữ liệu giữ lại |
|
|
60
66
|
|
|
@@ -93,7 +99,7 @@ Kết quả `--json`: `{"action":"dispatch","model":"sonnet","model_id":"claude-
|
|
|
93
99
|
|
|
94
100
|
## Dữ liệu
|
|
95
101
|
|
|
96
|
-
- Sự kiện: `~/.claude/dieu-phoi/data/events.jsonl` (`dispatch`, `complete`, `verdict`, `steer`, `override`, `discard`; `schema: 1`), xem `CONTRACT.md`. File chỉ ghi nối (append-only), không bao giờ viết lại. Tiến độ đẩy lên sink nằm ở `data/sync-offset.json` (byte offset sau dòng cuối đã đẩy); trạng thái segment từng agent ở `data/segments/<agent_id>.json`.
|
|
102
|
+
- Sự kiện: `~/.claude/dieu-phoi/data/events.jsonl` (`dispatch`, `complete`, `verdict`, `steer`, `override`, `discard`; `schema: 1`), xem `CONTRACT.md`. `dispatch` có thêm `project` (tên thư mục kho: `<tên>-<sha8 khoá>`, không phải đường dẫn) + `project_src` (`repo` = dòng `repo: <đường dẫn>` trong brief, `cwd` = cwd của phiên) khi đích nằm trong một repo git; chỉ cục bộ, sink không có cột này. File chỉ ghi nối (append-only), không bao giờ viết lại. Tiến độ đẩy lên sink nằm ở `data/sync-offset.json` (byte offset sau dòng cuối đã đẩy); trạng thái segment từng agent ở `data/segments/<agent_id>.json`.
|
|
97
103
|
- Lỗi của hook: `~/.claude/dieu-phoi/hook-errors.log`.
|
|
98
104
|
- Subagent nội bộ của Claude Code (không có transcript, không qua Agent tool) không được ghi; số lần bỏ qua ở `data/skipped-internal.json`. Log cũ của 0.1.0 có các `complete` rỗng loại này — `stats`/`retro` tự bỏ qua, không cần sửa file (từ 0.1.1).
|
|
99
105
|
- Người dùng chỉ lưu dạng sha256 rút gọn 8 ký tự (`git config user.email`, không có thì tên tài khoản máy). Phiên: `session` = sha256-8; từ 0.2.0 `dispatch` có thêm `session_id` thô (mã phiên, không phải nội dung) để nối với `dieu-phoi ctx`.
|
package/agents/dp-exec.md
CHANGED
|
@@ -28,6 +28,8 @@ Bạn là agent thực thi (exec) của dieu-phoi. Brief ở tin nhắn đầu (
|
|
|
28
28
|
|
|
29
29
|
Bàn giao qua file: ghi TOÀN BỘ kết quả vào `dp-out-<task_id>-exec-try<n>.md` trong run dir (đường dẫn brief chỉ định), rồi chỉ trả: đường dẫn file đó, dòng `STATUS:`, và ≤ 3 dòng ý chính. Không đặt tên file `report*` / `summary*` / `findings*` / `analysis*.md` — Claude Code chặn cứng Write các tên đó trong subagent. File dp-out/handoff mà brief trỏ tới là báo cáo chính thức: đọc thẳng, không cần xin thêm quyền.
|
|
30
30
|
|
|
31
|
+
Repo đích và knowledge: dòng `repo:` của brief là repo ĐÍCH (có thể là repo con, khác cwd). Trước khi đọc code: `dieu-phoi knowledge list --repo <repo>` rồi `knowledge get <id|từ khoá> --repo <repo>` (ít nhất `build-test ports-resources` nếu có); mục STALE chỉ là gợi ý. Cấu trúc code: dùng codebase-memory-mcp khi repo đã có index (`list_projects`), không thì Grep/Glob — không tự index. Brief có `worktree:` → chỉ sửa và chạy lệnh trong worktree đó, dùng cổng/tài nguyên riêng brief ghi, chỉ kill tiến trình do chính mình mở. Học được điều không suy ra từ code (lệnh test thật, cổng, bẫy) → ghi `<run>/knowledge-delta-<task_id>.md` (header `repo:`; `## +id` + `paths:` cho mục mới; sửa mục cũ `## id` + dòng `base:` chép từ `get`; ≤ 40 dòng/mục; không ghi giá trị secret); không tự `knowledge merge`.
|
|
32
|
+
|
|
31
33
|
Helper thế hệ 2 (tuỳ chọn, chỉ khi giúp giữ ngữ cảnh nhỏ): tối đa 4 agent `subagent_type: dp-helper`, `model` đặt rõ `haiku` hoặc `sonnet`, cho đúng hai loại việc — (a) đọc/quét code hoặc tài liệu rồi trả tóm tắt ≤ 15 dòng, (b) chạy test / Unity smoke rồi tóm tắt log. Dòng đầu prompt helper: `[dp:<type>|s<n>|<urgency>|try1|task=<id mới từ dieu-phoi new-id>|role=helper|parent=<task của bạn>]`. Hook từ chối mọi lần giao sai luật. Không giao helper sửa code.
|
|
32
34
|
|
|
33
35
|
Giữ ngữ cảnh nhỏ (mỗi lượt gửi lại toàn bộ ngữ cảnh — số lượt mới là thứ làm phình):
|
package/agents/dp-scout.md
CHANGED
|
@@ -19,6 +19,8 @@ Bạn là scout/planner của dieu-phoi: khảo sát (code, tài liệu, dữ li
|
|
|
19
19
|
|
|
20
20
|
Bàn giao qua file: ghi TOÀN BỘ kết quả vào `dp-out-<task_id>-plan-try<n>.md` trong run dir (đường dẫn brief chỉ định), rồi chỉ trả: đường dẫn file đó, dòng `STATUS:`, và ≤ 3 dòng ý chính. Không đặt tên file `report*` / `summary*` / `findings*` / `analysis*.md` — Claude Code chặn cứng Write các tên đó trong subagent. File dp-out/handoff mà brief trỏ tới là báo cáo chính thức: đọc thẳng, không cần xin thêm quyền.
|
|
21
21
|
|
|
22
|
+
Repo đích và knowledge: `repo:` trong prompt là repo ĐÍCH (phiên ở repo cha làm việc trên repo con → repo con). Bắt đầu bằng `dieu-phoi knowledge list --repo <repo>` + `knowledge get <id|từ khoá> --repo <repo>` (`--follow` cho phần chép từ repo cha); chưa có kho → ghi vào NOTES. Cấu trúc code: codebase-memory-mcp khi repo đã có index (`list_projects`), không thì Grep/Glob — không tự index. Bước sửa code chạy song song cùng repo → ghi cần worktree + cổng riêng. Điều không suy ra từ code → `<run>/knowledge-delta-<task_id>.md` (header `repo:`, `## +id` + `paths:`), không tự merge.
|
|
23
|
+
|
|
22
24
|
Giữ ngữ cảnh nhỏ (mỗi lượt gửi lại toàn bộ ngữ cảnh — số lượt mới là thứ làm phình):
|
|
23
25
|
- Grep/Glob trước, rồi Read đúng đoạn cần bằng offset/limit; không cat/sed -n cả file qua Bash.
|
|
24
26
|
- Không đọc lại file đã đọc — ghi chú điều cần nhớ ngay khi đọc.
|
package/agents/dp-verify.md
CHANGED
|
@@ -19,6 +19,8 @@ Bạn là agent kiểm chứng (verify) của dieu-phoi: kiểm tra độc lập
|
|
|
19
19
|
|
|
20
20
|
Bàn giao qua file: ghi TOÀN BỘ kết quả vào `dp-out-<task_id>-verify-try<n>.md` trong run dir (đường dẫn brief chỉ định), rồi chỉ trả: đường dẫn file đó, dòng `STATUS:`/`VERDICT:`, và ≤ 3 dòng ý chính. Không đặt tên file `report*` / `summary*` / `findings*` / `analysis*.md` — Claude Code chặn cứng Write các tên đó trong subagent. File dp-out/handoff mà brief trỏ tới là báo cáo chính thức: đọc thẳng, không cần xin thêm quyền.
|
|
21
21
|
|
|
22
|
+
Repo đích và knowledge: chạy lệnh trong `worktree:` của bước nếu brief có, không thì trong `repo:` đích; chỉ xem diff trong thư mục đó. Cách build/test, cổng/DB test: `dieu-phoi knowledge get build-test ports-resources --repo <repo>` nếu kho có; chỉ dừng tiến trình do chính mình mở. Không ghi delta knowledge trừ khi phát hiện mục sai.
|
|
23
|
+
|
|
22
24
|
Giữ ngữ cảnh nhỏ (mỗi lượt gửi lại toàn bộ ngữ cảnh — số lượt mới là thứ làm phình):
|
|
23
25
|
- Grep/Glob trước, rồi Read đúng đoạn cần bằng offset/limit; không cat/sed -n cả file qua Bash.
|
|
24
26
|
- Không đọc lại file đã đọc — ghi chú điều cần nhớ ngay khi đọc.
|
package/bin/dieu-phoi.cjs
CHANGED
|
@@ -19,6 +19,7 @@ Cách dùng: dieu-phoi <lệnh> [tuỳ chọn]
|
|
|
19
19
|
nghiệm thu của người dùng (by=user); reject bắt buộc --cause
|
|
20
20
|
verdict --root <root_task_id> accept [--steps a,b]
|
|
21
21
|
người dùng nhận mọi bước đã giao exec của kế hoạch đã duyệt chưa có verdict người dùng
|
|
22
|
+
accept (--task/--root) tự gộp knowledge-delta-<task_id>*.md của run vào kho (--no-knowledge: bỏ)
|
|
22
23
|
discard --task <task_id> [--reason R]
|
|
23
24
|
loại một task nhầm khỏi thống kê/choose/state (ghi sự kiện discard, không sửa log)
|
|
24
25
|
steer <agent_id> --kind minor|plan|redirect [--reason R]
|
|
@@ -40,13 +41,21 @@ Cách dùng: dieu-phoi <lệnh> [tuỳ chọn]
|
|
|
40
41
|
in task_id mới hợp lệ (8 ký tự a-z0-9), mỗi dòng một id — không tự bịa id
|
|
41
42
|
sync đẩy bản ghi chưa đồng bộ lên sink
|
|
42
43
|
retro [--json] tóm tắt cho vòng retro (không chứa nội dung)
|
|
43
|
-
prune --after-retro <file retro> [--yes]
|
|
44
|
+
prune --after-retro <file retro> [--yes] [--session <id>] [--force]
|
|
44
45
|
dọn sau retro: run dir đã nghiệm thu (giữ retro-*.md + dp-out exec/verify cuối), plan hỏng,
|
|
45
46
|
events cũ → data/archive/*.jsonl.gz (không xoá event). Mặc định dry-run; --yes mới thực hiện
|
|
47
|
+
(từ chối nếu phiên khác có event trong 15 phút gần nhất, trừ khi --force)
|
|
48
|
+
knowledge path|rekey|list|get|merge|link|status|bootstrap
|
|
49
|
+
kho knowledge theo project (mọi worktree/clone của một repo dùng chung): tra mục bằng get/list,
|
|
50
|
+
ghi chỉ qua merge --run <id> (delta của agent); knowledge --help
|
|
51
|
+
profile base --save <dir> | apply --base <dir> [--lessons F] [--profile F] [--dry-run]
|
|
52
|
+
áp retro lên profile/ không ghi đè phiên khác: chụp base trước khi retro đọc, apply dưới khoá;
|
|
53
|
+
lessons chỉ thêm dòng → tự gộp, sửa/xoá dòng cũ hoặc profile.json đổi → dừng (exit 2); profile --help
|
|
46
54
|
uninstall [--purge] gỡ hook khỏi settings.json (--purge xoá cả hook.cjs; dữ liệu giữ lại)
|
|
47
55
|
hook (nội bộ) đọc payload hook từ stdin
|
|
48
56
|
|
|
49
|
-
Tuỳ chọn chung: --claude-dir <dir> (mặc định $CLAUDE_CONFIG_DIR hoặc ~/.claude), --json, --help, --version
|
|
57
|
+
Tuỳ chọn chung: --claude-dir <dir> (mặc định $CLAUDE_CONFIG_DIR hoặc ~/.claude), --json, --help, --version,
|
|
58
|
+
--repo <đường dẫn> (repo đích của lệnh, mặc định thư mục hiện tại; một đường dẫn bất kỳ trong repo hoặc worktree của nó)
|
|
50
59
|
`;
|
|
51
60
|
|
|
52
61
|
async function main(argv) {
|
|
@@ -56,7 +65,7 @@ async function main(argv) {
|
|
|
56
65
|
process.stdout.write(`${core.CORE_VERSION}\n`);
|
|
57
66
|
return 0;
|
|
58
67
|
}
|
|
59
|
-
if (!cmd || opts.help || opts.h || cmd === 'help') {
|
|
68
|
+
if (!cmd || ((opts.help || opts.h) && cmd !== 'knowledge' && cmd !== 'profile') || cmd === 'help') {
|
|
60
69
|
process.stdout.write(HELP);
|
|
61
70
|
return cmd || opts.help || opts.h ? 0 : 1;
|
|
62
71
|
}
|
|
@@ -68,6 +77,13 @@ async function main(argv) {
|
|
|
68
77
|
} catch (e) { core.logError(null, e, 'cli-hook'); }
|
|
69
78
|
return 0;
|
|
70
79
|
}
|
|
80
|
+
if (opts.repo !== undefined) {
|
|
81
|
+
try { require('../lib/args.cjs').repoOf(opts); } catch (e) {
|
|
82
|
+
process.stderr.write(`dieu-phoi: ${e.message}
|
|
83
|
+
`);
|
|
84
|
+
return 1;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
71
87
|
const c = require('../lib/commands.cjs');
|
|
72
88
|
const table = {
|
|
73
89
|
setup: c.cmdSetup,
|
|
@@ -85,6 +101,8 @@ async function main(argv) {
|
|
|
85
101
|
sync: c.cmdSync,
|
|
86
102
|
retro: c.cmdRetro,
|
|
87
103
|
prune: c.cmdPrune,
|
|
104
|
+
knowledge: require('../lib/knowledge.cjs').cmdKnowledge,
|
|
105
|
+
profile: (o) => require('../lib/profile.cjs').cmdProfile(o),
|
|
88
106
|
uninstall: c.cmdUninstall,
|
|
89
107
|
};
|
|
90
108
|
const fn = table[cmd];
|