kenaz 0.3.17 → 0.3.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/core/.claude/commands/agent-worker.md +1 -1
  2. package/core/.claude/commands/architect.md +1 -2
  3. package/core/.claude/commands/spec.md +1 -1
  4. package/core/.claude/commands//347/224/242/345/223/201.md +1 -1
  5. package/core/.claude/hooks/__tests__/task-1977-dedupe-guard.test.js +8 -8
  6. package/core/.claude/hooks/synapse-first-investigation.js +15 -0
  7. package/core/.claude/skills/architect_agent/SKILL.md +11 -92
  8. package/core/.claude/skills/assessment_agent/SKILL.md +0 -1
  9. package/core/.claude/skills/backend_engineer/SKILL.md +3 -6
  10. package/core/.claude/skills/code_reviewer/SKILL.md +1 -1
  11. package/core/.claude/skills/code_reviewer/patterns.yaml +1 -1
  12. package/core/.claude/skills/designer/SKILL.md +3 -6
  13. package/core/.claude/skills/dev_agent/SKILL.md +30 -491
  14. package/core/.claude/skills/developer/SKILL.md +3 -6
  15. package/core/.claude/skills/feature_agent/SKILL.md +3 -17
  16. package/core/.claude/skills/product_manager/SKILL.md +29 -1064
  17. package/core/.claude/skills/qa_engineer/SKILL.md +12 -17
  18. package/core/.claude/skills/spec_optimizer/SKILL.md +25 -275
  19. package/core/.claude/skills/sre_agent/SKILL.md +3 -6
  20. package/core/.collaboration/README.md +2 -3
  21. package/core/.collaboration/core/task-api.js +5 -138
  22. package/core/.collaboration/docs/CLI.md +0 -2
  23. package/core/.failure/INDEX.yaml +6 -40
  24. package/core/.failure/agent-execution/FAIL-013-search-cwd-drift-and-case-mismatch.yaml +1 -1
  25. package/core/.failure/tools/README.md +9 -227
  26. package/core/.formation/bifrost/exec.js +29 -4
  27. package/core/.formation/bifrost/launch.js +1 -6
  28. package/core/.formation/bifrost/launch.test.js +1 -1
  29. package/core/.formation/bifrost/provider-launch.js +18 -11
  30. package/core/.formation/bifrost/provider-launch.test.js +26 -2
  31. package/core/.formation/bifrost/shared/ansuz-boot-policy.js +3 -3
  32. package/core/.formation/bifrost/shared/ansuz-boot-policy.test.js +1 -2
  33. package/core/.formation/tools/__tests__/dispatch-cwd-project.test.js +42 -0
  34. package/core/.formation/tools/__tests__/m1-hmap-convid.test.js +1 -124
  35. package/core/.formation/tools/__tests__/subagent-executor.test.js +3 -2
  36. package/core/.formation/tools/dispatch.js +15 -2
  37. package/core/.formation/tools/loader.js +17 -140
  38. package/core/.formation/tools/post-complete.js +0 -31
  39. package/core/.rule/INDEX.yaml +0 -18
  40. package/core/.rule/general/agent-workflow.yaml +14 -164
  41. package/core/.rule/general/project-self-containment.yaml +8 -19
  42. package/core/.rule/general/rust-verify-target.yaml +6 -5
  43. package/core/.rule/general/synapse-code-intelligence.yaml +3 -3
  44. package/core/.specialist/Amelia/capability.yaml +12 -12
  45. package/core/.specialist/Amelia/workflow.yaml +2 -2
  46. package/core/.specialist/Ansuz/SYSTEM_DOC.md +20 -578
  47. package/core/.specialist/Ansuz/cognitive_principles.yaml +2 -3
  48. package/core/.specialist/Ansuz/concepts/boot_rules_summary.yaml +0 -1
  49. package/core/.specialist/Ansuz/concepts/deep_knowledge_pointers.yaml +1 -2
  50. package/core/.specialist/Ansuz/core.yaml +6 -108
  51. package/core/.specialist/Ansuz/guards/lesson_guards.yaml +0 -3
  52. package/core/.specialist/Ansuz/identity_contract.yaml +0 -1
  53. package/core/.specialist/Ansuz/knowledge.yaml +0 -4
  54. package/core/.specialist/Ansuz/rule.yaml +0 -1
  55. package/core/.specialist/Ansuz/tools/handoff-session-identity.test.js +6 -150
  56. package/core/.specialist/tests/runtime-discovery/README.md +1 -1
  57. package/core/.specialist/tools/__tests__/task-2374-usage-counter.test.js +1 -12
  58. package/core/.specialist/tools/prompt-files.test.js +1 -0
  59. package/core/.specialist/tools/task-bridge.js +1 -66
  60. package/core/.system/README.md +11 -552
  61. package/core/.system/collaboration/README.md +10 -174
  62. package/core/CLAUDE.md +1 -6
  63. package/core/KENAZ_CORE_VERSION +1 -1
  64. package/core/dev/scripts/js-yaml-resolution.test.js +1 -1
  65. package/core/dev/scripts/run-rust-tests.js +30 -46
  66. package/core/dev/scripts/run-rust-tests.test.js +17 -0
  67. package/core/dev/scripts/rust-verify-worktree.js +4 -4
  68. package/core/dev/scripts/verify-target-dir.js +6 -6
  69. package/core/plugins/kenaz/INVENTORY.md +8 -8
  70. package/core/plugins/kenaz/commands/architect.md +1 -2
  71. package/core/plugins/kenaz/commands/spec.md +1 -1
  72. package/core/plugins/kenaz/commands//347/224/242/345/223/201.md +1 -1
  73. package/core/plugins/kenaz/guidance.md +1 -1
  74. package/core/plugins/kenaz/scripts/sync.js +1 -1
  75. package/core/plugins/kenaz/scripts/ygg.js +6 -0
  76. package/core/plugins/kenaz/skills/architect_agent/SKILL.md +11 -92
  77. package/core/plugins/kenaz/skills/assessment_agent/SKILL.md +0 -1
  78. package/core/plugins/kenaz/skills/backend_engineer/SKILL.md +3 -6
  79. package/core/plugins/kenaz/skills/code_reviewer/SKILL.md +1 -1
  80. package/core/plugins/kenaz/skills/code_reviewer/patterns.yaml +1 -1
  81. package/core/plugins/kenaz/skills/designer/SKILL.md +3 -6
  82. package/core/plugins/kenaz/skills/dev_agent/SKILL.md +30 -491
  83. package/core/plugins/kenaz/skills/developer/SKILL.md +3 -6
  84. package/core/plugins/kenaz/skills/feature_agent/SKILL.md +3 -17
  85. package/core/plugins/kenaz/skills/product_manager/SKILL.md +29 -1064
  86. package/core/plugins/kenaz/skills/qa_engineer/SKILL.md +12 -17
  87. package/core/plugins/kenaz/skills/spec_optimizer/SKILL.md +25 -275
  88. package/core/plugins/kenaz/skills/sre_agent/SKILL.md +3 -6
  89. package/package.json +6 -6
  90. package/core/.claude/commands/archive.md +0 -24
  91. package/core/.claude/commands/init.md +0 -112
  92. package/core/.claude/commands/legacy_dev.md +0 -18
  93. package/core/.claude/commands/product-review.md +0 -131
  94. package/core/.claude/commands/strategy.md +0 -141
  95. package/core/.claude/commands/sunny.md +0 -1
  96. package/core/.claude/commands//347/224/242/345/223/201/346/252/242/350/246/226.md +0 -129
  97. package/core/.claude/commands//351/200/262/345/272/246.md +0 -15
  98. package/core/.claude/hooks/__tests__/substrate.test.js +0 -122
  99. package/core/.claude/hooks/_substrate-paths.js +0 -95
  100. package/core/.claude/hooks/context-check.js +0 -51
  101. package/core/.claude/hooks/fatigue-check.js +0 -52
  102. package/core/.claude/hooks/handoff-snapshot-on-commit.js +0 -154
  103. package/core/.claude/hooks/handoff-snapshot-on-question.js +0 -158
  104. package/core/.claude/hooks/handoff-staleness.js +0 -197
  105. package/core/.claude/hooks/jev-thalamus-context.js +0 -17
  106. package/core/.claude/hooks/jev-thalamus-context.test.js +0 -41
  107. package/core/.claude/hooks/lease-release.js +0 -119
  108. package/core/.claude/hooks/lease-touch.js +0 -96
  109. package/core/.claude/hooks/reflex-feedback.js +0 -5
  110. package/core/.claude/hooks/session-init.ps1 +0 -49
  111. package/core/.claude/hooks/sound-event.js +0 -70
  112. package/core/.claude/hooks/sound-event.sh +0 -37
  113. package/core/.claude/hooks/stream-delta.js +0 -169
  114. package/core/.claude/no-hooks.settings.json +0 -3
  115. package/core/.claude/skills/legacy_dev/SKILL.md +0 -202
  116. package/core/.claude/skills/sunny/SKILL.md +0 -74
  117. package/core/.collaboration/cli/commands/assign.js +0 -39
  118. package/core/.collaboration/cli/commands/claim.js +0 -33
  119. package/core/.collaboration/cli/commands/complete.js +0 -44
  120. package/core/.collaboration/cli/commands/create.js +0 -110
  121. package/core/.collaboration/cli/commands/get.js +0 -83
  122. package/core/.collaboration/cli/commands/index.js +0 -52
  123. package/core/.collaboration/cli/commands/list.js +0 -51
  124. package/core/.collaboration/cli/commands/lock.js +0 -45
  125. package/core/.collaboration/cli/commands/rebuild.js +0 -39
  126. package/core/.collaboration/cli/commands/search.js +0 -61
  127. package/core/.collaboration/cli/commands/stats.js +0 -61
  128. package/core/.collaboration/cli/commands/transfer.js +0 -41
  129. package/core/.collaboration/cli/commands/unlock.js +0 -48
  130. package/core/.collaboration/cli/formatters/help-formatter.js +0 -70
  131. package/core/.collaboration/cli/formatters/index.js +0 -7
  132. package/core/.collaboration/cli/task-cli.js +0 -46
  133. package/core/.collaboration/cli/utils/arg-parser.js +0 -74
  134. package/core/.collaboration/cli/utils/git-user.js +0 -25
  135. package/core/.collaboration/cli/utils/index.js +0 -9
  136. package/core/.collaboration/cli/utils/output.js +0 -10
  137. package/core/.collaboration/config/default.yaml +0 -189
  138. package/core/.collaboration/core/conflict-resolver.js +0 -461
  139. package/core/.collaboration/core/conflict-resolver.test.js +0 -389
  140. package/core/.collaboration/core/migrate-legacy.js +0 -260
  141. package/core/.collaboration/docs/API.md +0 -787
  142. package/core/.collaboration/docs/ARCHITECTURE.md +0 -596
  143. package/core/.collaboration/docs/FAQ.md +0 -695
  144. package/core/.collaboration/docs/MIGRATION.md +0 -804
  145. package/core/.collaboration/docs/examples/README.md +0 -320
  146. package/core/.collaboration/docs/examples/advanced-queries.js +0 -261
  147. package/core/.collaboration/docs/examples/basic-usage.js +0 -184
  148. package/core/.collaboration/docs/examples/team-workflow.js +0 -352
  149. package/core/.failure/agent-execution/FAIL-001-agent-no-output.yaml +0 -391
  150. package/core/.failure/agent-execution/FAIL-007-pm-lead-wrong-team-invocation.yaml +0 -0
  151. package/core/.failure/agent-execution/FAIL-010-phase0-poem-format-skipped.yaml +0 -28
  152. package/core/.failure/agent-execution/FAIL-010-skipping-cognitive-checkpoint-after-verification.yaml +0 -59
  153. package/core/.failure/agent-execution/FAIL-012-grep-shortcut-during-investigation.yaml +0 -85
  154. package/core/.failure/architecture/FAIL-006-python-version-compatibility.yaml +0 -445
  155. package/core/.failure/pipeline/FAIL-003-queue-pollution.yaml +0 -335
  156. package/core/.failure/pipeline/README.md +0 -95
  157. package/core/.failure/retired/FAIL-009-skipping-synapse-pulse-before-code-change.yaml +0 -49
  158. package/core/.failure/tools/USAGE_GUIDE.md +0 -323
  159. package/core/.failure/tools/check_failures.ps1 +0 -387
  160. package/core/.failure/tools/log_failure.ps1 +0 -474
  161. package/core/.formation/.episode-input.json +0 -10
  162. package/core/.formation/.merge-lock +0 -1
  163. package/core/.formation/lead.yaml +0 -118
  164. package/core/.formation/legacy.bak/designer.yaml +0 -57
  165. package/core/.formation/legacy.bak/pm.yaml +0 -57
  166. package/core/.formation/legacy.bak/qa.yaml +0 -57
  167. package/core/.formation/legacy.bak/review.yaml +0 -62
  168. package/core/.formation/legacy.bak/scheduler.yaml +0 -129
  169. package/core/.formation/legacy.bak/sre.yaml +0 -57
  170. package/core/.formation/role-map.yaml +0 -274
  171. package/core/.formation/roles/_shared/modules/code_review.yaml +0 -98
  172. package/core/.formation/roles/_shared/modules/security.yaml +0 -103
  173. package/core/.formation/roles/_shared/modules/testing.yaml +0 -14
  174. package/core/.formation/roles/backend/role.yaml +0 -93
  175. package/core/.formation/roles/code_reviewer/role.yaml +0 -102
  176. package/core/.formation/roles/database_optimizer/role.yaml +0 -107
  177. package/core/.formation/roles/designer/role.yaml +0 -66
  178. package/core/.formation/roles/developer/role.yaml +0 -75
  179. package/core/.formation/roles/frontend/role.yaml +0 -134
  180. package/core/.formation/roles/incident_response/role.yaml +0 -89
  181. package/core/.formation/roles/qa/role.yaml +0 -89
  182. package/core/.formation/roles/security/role.yaml +0 -87
  183. package/core/.formation/roles/sre/role.yaml +0 -66
  184. package/core/.formation/skills/coordinator.yaml +0 -52
  185. package/core/.formation/solo/diagnosis.yaml +0 -78
  186. package/core/.formation/solo/strategy.yaml +0 -121
  187. package/core/.formation/tests/hello.txt +0 -2
  188. package/core/.formation/tools/coordinator.js +0 -350
  189. package/core/.formation/tools/jev-correction.js +0 -214
  190. package/core/.formation/tools/jev-correction.test.js +0 -178
  191. package/core/.formation/tools/log-reader.js +0 -232
  192. package/core/.formation/tools/revert-daemon-state.js +0 -162
  193. package/core/.formation/tools/test-drift.js +0 -148
  194. package/core/.formation/unit/heimdall.yaml +0 -96
  195. package/core/.formation/unit/plan.yaml +0 -67
  196. package/core/.formation/unit/think.yaml +0 -58
  197. package/core/.kenaz/MUNINN_SNAPSHOT9_EPISODE.json +0 -32
  198. package/core/.kenaz/MUNINN_SNAPSHOT9_RUNE.json +0 -23
  199. package/core/.kenaz/MUNINN_SNAPSHOT9_SUMMARY.md +0 -89
  200. package/core/.kenaz/ash_TASK_1428-20260507.json +0 -14
  201. package/core/.kenaz/muninn_episode_write.ps1 +0 -17
  202. package/core/.kenaz/muninn_snapshot11_rune_candidates.md +0 -63
  203. package/core/.kenaz/muninn_snapshot1_rune_candidates.md +0 -49
  204. package/core/.kenaz/runes_TASK_1428.json +0 -57
  205. package/core/.kenaz/tmp_heimdall_proposal_8d3e392.json +0 -13
  206. package/core/.kenaz/tmp_props.json +0 -1
  207. package/core/.kenaz/tmp_sounddrop_t1_prompt.txt +0 -371
  208. package/core/.rule/MECHANIZED.md +0 -61
  209. package/core/.rule/general/cortex-memory-recall.yaml +0 -446
  210. package/core/.rule/general/pipeline.yaml +0 -246
  211. package/core/.rule/general/sunny-access-control.yaml +0 -60
  212. package/core/.rule/general/system-invariants.yaml +0 -231
  213. package/core/.rule/pipeline/PPL-002-completed-task-archival.yaml +0 -528
  214. package/core/.rule/pipeline/auto-update.yaml +0 -282
  215. package/core/.rule/pipeline/task-execution.yaml +0 -365
  216. package/core/.specialist/Ansuz/concepts/phase_protocol.yaml +0 -65
  217. package/core/.specialist/Ansuz/experiments/boot_ablation_replay.js +0 -197
  218. package/core/.specialist/Ansuz/tools/bootstrap-anchors.js +0 -289
  219. package/core/.specialist/Ansuz/workflow.yaml +0 -1225
  220. package/core/.specialist/experiments/rg_benchmark.js +0 -523
  221. package/core/.specialist/experiments/rg_benchmark_results.json +0 -27
  222. package/core/.specialist/tools/jev-optional-context.js +0 -107
  223. package/core/.specialist/tools/jev-optional-context.test.js +0 -152
  224. package/core/.specialist/tools/memory-action-log.js +0 -839
  225. package/core/.specialist/tools/phase-gate.js +0 -3534
  226. package/core/.specialist/tools/phase-gate.test.js +0 -85
  227. package/core/.specialist/tools/precompute-runner.js +0 -444
  228. package/core/.specialist/tools/rule-engine.js +0 -621
  229. package/core/.specialist/tools/task-bridge-jev.test.js +0 -170
  230. package/core/.synapse/memory-shared.json.sync +0 -1
  231. package/core/.system/agent-skills/README.md +0 -724
  232. package/core/.system/cli-tools/README.md +0 -724
  233. package/core/.system/cortex/MODULES.md +0 -1046
  234. package/core/.system/dashboard/FRONTEND.md +0 -812
  235. package/core/.system/dashboard/README.md +0 -737
  236. package/core/.system/failure/README.md +0 -723
  237. package/core/.system/formation/LEGACY_SKILLS.md +0 -974
  238. package/core/.system/formation/POST_COMPLETE.md +0 -602
  239. package/core/.system/formation/README.md +0 -1094
  240. package/core/.system/formation/TOOLS_REFERENCE.md +0 -1145
  241. package/core/.system/kenaz/README.md +0 -787
  242. package/core/.system/memory/README.md +0 -719
  243. package/core/.system/pipeline/README.md +0 -712
  244. package/core/.system/rule/README.md +0 -794
  245. package/core/.system/sunny/README.md +0 -476
  246. package/core/.system/sunny/RULES.json +0 -89
  247. package/core/.system/sunny/knowledge/INDEX.md +0 -37
  248. package/core/.system/sunny/knowledge/agent-teams-api.md +0 -0
  249. package/core/.system/sunny/knowledge/ansuz-specialist.md +0 -500
  250. package/core/.system/sunny/knowledge/claude-cli-spawn.md +0 -177
  251. package/core/.system/sunny/knowledge/collaboration-api.md +0 -925
  252. package/core/.system/sunny/teammates/README.md +0 -107
  253. package/core/.system/sunny/teammates/how_to_use.yaml +0 -101
  254. package/core/.system/sunny/teammates/tools/headless/launcher.js +0 -318
  255. package/core/.system/sunny/teammates/tools/powershell/launcher.js +0 -241
  256. package/core/.system/sunny/teammates/tools/powershell/start.bat +0 -50
  257. package/core/.system/sunny/teammates/tools/utils/env.js +0 -96
  258. package/core/.system/sunny/teammates/tools/utils/format-output.js +0 -329
  259. package/core/.system/sunny/tools.json +0 -101
  260. package/core/dev/scripts/cleanup-queue.js +0 -184
  261. package/core/dev/scripts/cleanup_queue.js +0 -86
  262. package/core/dev/scripts/legacy/README.md +0 -39
  263. package/core/dev/scripts/legacy/dev_agent_scheduler.ps1.bak +0 -536
  264. package/core/dev/scripts/legacy/multi_agent_scheduler.ps1.bak +0 -1978
  265. package/core/dev/scripts/matrix/CLI_README.md +0 -214
  266. package/core/dev/scripts/matrix/README.md +0 -310
  267. package/core/dev/scripts/matrix/package-lock.json +0 -4266
  268. package/core/dev/scripts/matrix/package.json +0 -55
  269. package/core/dev/scripts/matrix/src/abbreviations.ts +0 -295
  270. package/core/dev/scripts/matrix/src/cli/commands/convert.ts +0 -211
  271. package/core/dev/scripts/matrix/src/cli/commands/create.ts +0 -95
  272. package/core/dev/scripts/matrix/src/cli/commands/delete.ts +0 -102
  273. package/core/dev/scripts/matrix/src/cli/commands/list-tags.ts.wip +0 -140
  274. package/core/dev/scripts/matrix/src/cli/commands/manage-tags.ts.wip +0 -173
  275. package/core/dev/scripts/matrix/src/cli/commands/query.ts +0 -261
  276. package/core/dev/scripts/matrix/src/cli/commands/read.ts +0 -77
  277. package/core/dev/scripts/matrix/src/cli/commands/stats.ts.wip +0 -168
  278. package/core/dev/scripts/matrix/src/cli/commands/tokens.ts.wip +0 -126
  279. package/core/dev/scripts/matrix/src/cli/commands/update.ts +0 -147
  280. package/core/dev/scripts/matrix/src/cli/commands/validate.ts +0 -275
  281. package/core/dev/scripts/matrix/src/cli/index.ts +0 -350
  282. package/core/dev/scripts/matrix/src/cli/utils/file-handler.ts +0 -72
  283. package/core/dev/scripts/matrix/src/cli/utils/logger.ts +0 -65
  284. package/core/dev/scripts/matrix/src/index.ts +0 -62
  285. package/core/dev/scripts/matrix/src/indexer/tag-indexer.ts +0 -165
  286. package/core/dev/scripts/matrix/src/parser.ts +0 -281
  287. package/core/dev/scripts/matrix/src/serializer.ts +0 -151
  288. package/core/dev/scripts/matrix/src/validator.ts +0 -301
  289. package/core/dev/scripts/matrix/tests/abbreviations.test.ts +0 -122
  290. package/core/dev/scripts/matrix/tests/cli.test.ts +0 -177
  291. package/core/dev/scripts/matrix/tests/convert.test.ts +0 -143
  292. package/core/dev/scripts/matrix/tests/parser.test.ts +0 -203
  293. package/core/dev/scripts/matrix/tests/query.test.ts +0 -85
  294. package/core/dev/scripts/matrix/tests/serializer.test.ts +0 -197
  295. package/core/dev/scripts/matrix/tests/validate.test.ts +0 -141
  296. package/core/dev/scripts/matrix/tests/validator.test.ts +0 -167
  297. package/core/dev/scripts/matrix/tsconfig.json +0 -20
  298. package/core/dev/scripts/matrix/types/index.d.ts +0 -111
  299. package/core/dev/scripts/matrix/types/index.d.ts.map +0 -1
  300. package/core/dev/scripts/matrix/types/index.js +0 -8
  301. package/core/dev/scripts/matrix/types/index.js.map +0 -1
  302. package/core/dev/scripts/matrix/types/index.ts +0 -124
  303. package/core/dev/scripts/memory-usage-report.js +0 -152
  304. package/core/dev/scripts/probe/ansuz-scaffold-ablation.js +0 -579
  305. package/core/dev/scripts/probe/ansuz-scaffold-ablation.test.js +0 -244
  306. package/core/dev/scripts/probe/hook-latency-probe.js +0 -315
  307. package/core/dev/scripts/probe/hook-latency-probe.test.js +0 -105
  308. package/core/dev/scripts/probe/prediction-signal-auc.js +0 -483
  309. package/core/dev/scripts/probe/prediction-signal-auc.test.js +0 -200
  310. package/core/dev/scripts/test-pty-ws-tunnel.js +0 -229
  311. package/core/dev/scripts/validate_pipeline.js +0 -197
  312. package/core/dev/spikes/task2145-evidence-20261004/backend-log-excerpt.txt +0 -56
  313. package/core/dev/spikes/task2145-evidence-20261004/graph.shadow +0 -0
  314. package/core/dev/spikes/task2145-evidence-20261004/graph.wal +0 -0
  315. package/core/dev/spikes/task2145-evidence-20261004/graph_corrupt_suspect.marker +0 -1
  316. package/core/plugins/kenaz/commands/strategy.md +0 -141
@@ -1,102 +0,0 @@
1
- /**
2
- * matrix delete command
3
- * Deletes a rule from .matrix file and auto-updates @index statistics
4
- */
5
-
6
- import inquirer from 'inquirer';
7
- import { MatrixParser } from '../../parser';
8
- import { MatrixSerializer } from '../../serializer';
9
- import { Logger } from '../utils/logger';
10
- import { FileHandler } from '../utils/file-handler';
11
-
12
- interface DeleteOptions {
13
- force?: boolean;
14
- }
15
-
16
- export async function deleteCommand(
17
- filePath: string,
18
- ruleId: string,
19
- options: DeleteOptions
20
- ): Promise<void> {
21
- Logger.header('Delete .matrix Rule');
22
-
23
- // Ensure .matrix extension
24
- const targetPath = FileHandler.ensureExtension(filePath);
25
-
26
- // Read and parse file
27
- const content = FileHandler.read(targetPath);
28
- if (!content) {
29
- process.exit(1);
30
- }
31
-
32
- const parser = new MatrixParser();
33
- const result = parser.parse(content);
34
-
35
- if (!result.success) {
36
- Logger.error('Failed to parse file');
37
- if (result.error) {
38
- Logger.error(` ${result.error.message}`);
39
- }
40
- process.exit(1);
41
- }
42
-
43
- const matrixFile = result.data!;
44
-
45
- // Find rule by ID
46
- if (!matrixFile.data) {
47
- Logger.error('No data records found in file');
48
- process.exit(1);
49
- }
50
-
51
- const recordIndex = matrixFile.data.records.findIndex(r => r.id === ruleId);
52
- if (recordIndex === -1) {
53
- Logger.error(`Rule not found: ${ruleId}`);
54
- Logger.info('Use "matrix read" to list available rules');
55
- process.exit(1);
56
- }
57
-
58
- const record = matrixFile.data.records[recordIndex];
59
-
60
- Logger.info(`Found rule: ${ruleId}`);
61
- Logger.record(ruleId, record.fields);
62
-
63
- // Confirm deletion
64
- if (!options.force) {
65
- const answers = await inquirer.prompt([
66
- {
67
- type: 'confirm',
68
- name: 'confirm',
69
- message: `Are you sure you want to delete rule "${ruleId}"?`,
70
- default: false,
71
- },
72
- ]);
73
-
74
- if (!answers.confirm) {
75
- Logger.info('Deletion cancelled');
76
- return;
77
- }
78
- }
79
-
80
- // Delete record
81
- matrixFile.data.records.splice(recordIndex, 1);
82
-
83
- // Auto-update @index statistics
84
- if (matrixFile.index.n !== undefined) {
85
- matrixFile.index.n = matrixFile.data.records.length;
86
- }
87
-
88
- if (matrixFile.index.upd !== undefined) {
89
- matrixFile.index.upd = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '');
90
- }
91
-
92
- // Serialize and write
93
- const serializer = new MatrixSerializer();
94
- const newContent = serializer.serialize(matrixFile);
95
-
96
- if (FileHandler.write(targetPath, newContent)) {
97
- Logger.success(`Deleted rule: ${ruleId}`);
98
- Logger.field('Remaining rules', matrixFile.data.records.length);
99
- } else {
100
- process.exit(1);
101
- }
102
- }
@@ -1,140 +0,0 @@
1
- /**
2
- * list-tags command - List all tags and their usage counts
3
- */
4
-
5
- import chalk from 'chalk';
6
- import { resolveFilePath } from '../utils/file-handler';
7
- import { parseMatrixFile } from '../../parser';
8
- import { TagIndexer } from '../../indexer/tag-indexer';
9
-
10
- interface ListTagsOptions {
11
- type?: string; // Filter by tag type: source, category, priority, domain, custom
12
- sort?: 'name' | 'count'; // Sort by name or count
13
- }
14
-
15
- export async function listTagsCommand(
16
- file: string,
17
- options: ListTagsOptions = {}
18
- ): Promise<void> {
19
- const filePath = resolveFilePath(file);
20
-
21
- // Parse file
22
- const matrixFile = parseMatrixFile(filePath);
23
-
24
- // Build tag index
25
- const indexer = new TagIndexer();
26
- indexer.buildIndex(matrixFile);
27
-
28
- // Get tag statistics
29
- let tagStats = indexer.getTagStats();
30
-
31
- // Filter by type if specified
32
- if (options.type) {
33
- const typePrefix = options.type.toLowerCase();
34
- tagStats = tagStats.filter((stat) => {
35
- if (typePrefix === 'custom') {
36
- return stat.tag.startsWith('#');
37
- }
38
- return stat.tag.startsWith(`${typePrefix}:`);
39
- });
40
- }
41
-
42
- // Sort by name if specified
43
- if (options.sort === 'name') {
44
- tagStats.sort((a, b) => a.tag.localeCompare(b.tag));
45
- }
46
- // Default: already sorted by count descending
47
-
48
- console.log(chalk.bold.cyan('\n🏷️ Tags\n'));
49
- console.log(chalk.gray(`File: ${filePath}\n`));
50
-
51
- if (tagStats.length === 0) {
52
- console.log(chalk.yellow('No tags found.'));
53
- console.log();
54
- return;
55
- }
56
-
57
- // Group tags by type
58
- const groupedTags = groupTagsByType(tagStats);
59
-
60
- // Display each group
61
- for (const [type, tags] of Object.entries(groupedTags)) {
62
- if (!options.type || options.type.toLowerCase() === type.toLowerCase()) {
63
- console.log(chalk.bold(`${getTypeEmoji(type)} ${type}:`));
64
-
65
- for (const stat of tags) {
66
- const tagDisplay = stat.tag.replace(`${type.toLowerCase()}:`, '');
67
- const bar = '█'.repeat(Math.min(stat.count, 20));
68
- console.log(
69
- ` ${chalk.cyan(tagDisplay.padEnd(20))} ${chalk.green(bar)} ${chalk.yellow(stat.count)}`
70
- );
71
- }
72
-
73
- console.log();
74
- }
75
- }
76
-
77
- // Summary
78
- console.log(chalk.bold('Summary:'));
79
- console.log(` Total tags: ${chalk.cyan(tagStats.length)}`);
80
- console.log(` Total tag types: ${chalk.cyan(Object.keys(groupedTags).length)}`);
81
- console.log();
82
- }
83
-
84
- /**
85
- * Group tags by type
86
- */
87
- function groupTagsByType(
88
- tagStats: { tag: string; count: number; ruleIds: string[] }[]
89
- ): Record<string, typeof tagStats> {
90
- const grouped: Record<string, typeof tagStats> = {
91
- Source: [],
92
- Category: [],
93
- Priority: [],
94
- Domain: [],
95
- Custom: [],
96
- };
97
-
98
- for (const stat of tagStats) {
99
- if (stat.tag.startsWith('source:')) {
100
- grouped.Source.push(stat);
101
- } else if (stat.tag.startsWith('category:')) {
102
- grouped.Category.push(stat);
103
- } else if (stat.tag.startsWith('priority:')) {
104
- grouped.Priority.push(stat);
105
- } else if (stat.tag.startsWith('domain:')) {
106
- grouped.Domain.push(stat);
107
- } else {
108
- grouped.Custom.push(stat);
109
- }
110
- }
111
-
112
- // Remove empty groups
113
- for (const key of Object.keys(grouped)) {
114
- if (grouped[key].length === 0) {
115
- delete grouped[key];
116
- }
117
- }
118
-
119
- return grouped;
120
- }
121
-
122
- /**
123
- * Get emoji for tag type
124
- */
125
- function getTypeEmoji(type: string): string {
126
- switch (type.toLowerCase()) {
127
- case 'source':
128
- return '📦';
129
- case 'category':
130
- return '📂';
131
- case 'priority':
132
- return '⚡';
133
- case 'domain':
134
- return '🌐';
135
- case 'custom':
136
- return '🏷️';
137
- default:
138
- return '•';
139
- }
140
- }
@@ -1,173 +0,0 @@
1
- /**
2
- * add-tag / remove-tag commands - Manage rule tags
3
- */
4
-
5
- import chalk from 'chalk';
6
- import * as fs from 'fs';
7
- import { resolveFilePath } from '../utils/file-handler';
8
- import { parseMatrixFile } from '../../parser';
9
- import { serializeMatrixFile } from '../../serializer';
10
- import { TagIndexer, buildTagIndex } from '../../indexer/tag-indexer';
11
-
12
- interface ManageTagsOptions {
13
- force?: boolean;
14
- }
15
-
16
- /**
17
- * Add tag to a rule
18
- */
19
- export async function addTagCommand(
20
- file: string,
21
- ruleId: string,
22
- tag: string,
23
- options: ManageTagsOptions = {}
24
- ): Promise<void> {
25
- const filePath = resolveFilePath(file);
26
-
27
- // Parse file
28
- const matrixFile = parseMatrixFile(filePath);
29
-
30
- // Find rule
31
- const rule = matrixFile.rules.find((r) => r.id === ruleId);
32
- if (!rule) {
33
- throw new Error(`Rule not found: ${ruleId}`);
34
- }
35
-
36
- // Ensure tag starts with # (for custom tags)
37
- const normalizedTag = tag.startsWith('#') ? tag : `#${tag}`;
38
-
39
- // Initialize tags array if not exists
40
- if (!rule.tags) {
41
- rule.tags = [];
42
- }
43
-
44
- // Check if tag already exists
45
- if (Array.isArray(rule.tags) && rule.tags.includes(normalizedTag)) {
46
- console.log(chalk.yellow(`Tag already exists: ${normalizedTag}`));
47
- return;
48
- }
49
-
50
- // Add tag
51
- if (Array.isArray(rule.tags)) {
52
- rule.tags.push(normalizedTag);
53
- } else {
54
- rule.tags = [normalizedTag];
55
- }
56
-
57
- // Save file
58
- const serialized = serializeMatrixFile(matrixFile);
59
- fs.writeFileSync(filePath, serialized, 'utf-8');
60
-
61
- // Rebuild tag index
62
- const indexPath = filePath.replace('.matrix', '.tags.json');
63
- buildTagIndex(matrixFile, indexPath);
64
-
65
- console.log(chalk.green(`✓ Tag added: ${normalizedTag} to ${ruleId}`));
66
- console.log(chalk.gray(` Index updated: ${indexPath}`));
67
- }
68
-
69
- /**
70
- * Remove tag from a rule
71
- */
72
- export async function removeTagCommand(
73
- file: string,
74
- ruleId: string,
75
- tag: string,
76
- options: ManageTagsOptions = {}
77
- ): Promise<void> {
78
- const filePath = resolveFilePath(file);
79
-
80
- // Parse file
81
- const matrixFile = parseMatrixFile(filePath);
82
-
83
- // Find rule
84
- const rule = matrixFile.rules.find((r) => r.id === ruleId);
85
- if (!rule) {
86
- throw new Error(`Rule not found: ${ruleId}`);
87
- }
88
-
89
- // Ensure tag starts with # (for custom tags)
90
- const normalizedTag = tag.startsWith('#') ? tag : `#${tag}`;
91
-
92
- // Check if rule has tags
93
- if (!rule.tags || !Array.isArray(rule.tags)) {
94
- console.log(chalk.yellow(`Rule has no tags: ${ruleId}`));
95
- return;
96
- }
97
-
98
- // Find tag index
99
- const tagIndex = rule.tags.indexOf(normalizedTag);
100
- if (tagIndex === -1) {
101
- console.log(chalk.yellow(`Tag not found: ${normalizedTag}`));
102
- return;
103
- }
104
-
105
- // Remove tag
106
- rule.tags.splice(tagIndex, 1);
107
-
108
- // Save file
109
- const serialized = serializeMatrixFile(matrixFile);
110
- fs.writeFileSync(filePath, serialized, 'utf-8');
111
-
112
- // Rebuild tag index
113
- const indexPath = filePath.replace('.matrix', '.tags.json');
114
- buildTagIndex(matrixFile, indexPath);
115
-
116
- console.log(chalk.green(`✓ Tag removed: ${normalizedTag} from ${ruleId}`));
117
- console.log(chalk.gray(` Index updated: ${indexPath}`));
118
- }
119
-
120
- /**
121
- * List tags for a specific rule
122
- */
123
- export async function showRuleTagsCommand(
124
- file: string,
125
- ruleId: string
126
- ): Promise<void> {
127
- const filePath = resolveFilePath(file);
128
-
129
- // Parse file
130
- const matrixFile = parseMatrixFile(filePath);
131
-
132
- // Find rule
133
- const rule = matrixFile.rules.find((r) => r.id === ruleId);
134
- if (!rule) {
135
- throw new Error(`Rule not found: ${ruleId}`);
136
- }
137
-
138
- console.log(chalk.bold.cyan(`\n🏷️ Tags for ${ruleId}\n`));
139
-
140
- // Collect all tags
141
- const allTags: string[] = [];
142
-
143
- if (rule.source) allTags.push(`source:${rule.source}`);
144
- if (rule.category) allTags.push(`category:${rule.category}`);
145
- if (rule.priority) allTags.push(`priority:${rule.priority}`);
146
- if (rule.domain) allTags.push(`domain:${rule.domain}`);
147
- if (rule.tags && Array.isArray(rule.tags)) {
148
- allTags.push(...rule.tags);
149
- }
150
-
151
- if (allTags.length === 0) {
152
- console.log(chalk.yellow('No tags found.'));
153
- } else {
154
- for (const tag of allTags) {
155
- const emoji = getTagEmoji(tag);
156
- console.log(` ${emoji} ${chalk.cyan(tag)}`);
157
- }
158
- }
159
-
160
- console.log();
161
- }
162
-
163
- /**
164
- * Get emoji for tag
165
- */
166
- function getTagEmoji(tag: string): string {
167
- if (tag.startsWith('source:')) return '📦';
168
- if (tag.startsWith('category:')) return '📂';
169
- if (tag.startsWith('priority:')) return '⚡';
170
- if (tag.startsWith('domain:')) return '🌐';
171
- if (tag.startsWith('#')) return '🏷️';
172
- return '•';
173
- }
@@ -1,261 +0,0 @@
1
- /**
2
- * Query command - 查詢 .matrix 文件
3
- * 支援標籤過濾、優先級過濾、狀態過濾、關鍵字搜尋
4
- */
5
-
6
- import * as fs from 'fs';
7
- import { MatrixParser } from '../../parser';
8
- import { log, error as logError } from '../utils/logger';
9
- import type { MatrixFile, DataRecord } from '../../../types';
10
-
11
- interface QueryOptions {
12
- tag?: string;
13
- priority?: string;
14
- status?: string;
15
- keyword?: string;
16
- format?: 'table' | 'json' | 'compact';
17
- }
18
-
19
- interface QueryResult {
20
- records: DataRecord[];
21
- total: number;
22
- }
23
-
24
- /**
25
- * Query command handler
26
- */
27
- export async function queryCommand(file: string, options: QueryOptions): Promise<void> {
28
- try {
29
- // 確保文件有 .matrix 擴展名
30
- const filePath = file.endsWith('.matrix') ? file : `${file}.matrix`;
31
-
32
- // 檢查文件是否存在
33
- if (!fs.existsSync(filePath)) {
34
- throw new Error(`File not found: ${filePath}`);
35
- }
36
-
37
- // 讀取並解析文件
38
- const content = fs.readFileSync(filePath, 'utf-8');
39
- const parser = new MatrixParser();
40
- const parseResult = parser.parse(content);
41
-
42
- if (!parseResult.success || !parseResult.data) {
43
- throw new Error(`Failed to parse file: ${parseResult.error?.message || 'Unknown error'}`);
44
- }
45
-
46
- const matrixFile = parseResult.data;
47
-
48
- // 執行查詢
49
- const result = executeQuery(matrixFile, options);
50
-
51
- // 輸出結果
52
- displayResults(result, options.format || 'table', matrixFile);
53
-
54
- } catch (err) {
55
- logError((err as Error).message);
56
- throw err;
57
- }
58
- }
59
-
60
- /**
61
- * 執行查詢邏輯(支援索引優化)
62
- */
63
- function executeQuery(matrixFile: MatrixFile, options: QueryOptions): QueryResult {
64
- // 如果沒有 data section,返回空結果
65
- if (!matrixFile.data || !matrixFile.data.records) {
66
- return { records: [], total: 0 };
67
- }
68
-
69
- let filteredRecords = matrixFile.data.records;
70
-
71
- // 索引優化:先檢查 @index 層是否有快速過濾機會
72
- // 例如:如果查詢 status=completed,先查看 index 的 completed 計數
73
- if (options.status && matrixFile.index) {
74
- const statusKey = getStatusKey(options.status);
75
- const countInIndex = matrixFile.index[statusKey];
76
-
77
- // 如果 index 顯示該狀態為 0,直接返回空結果
78
- if (countInIndex === 0) {
79
- return { records: [], total: 0 };
80
- }
81
- }
82
-
83
- // 過濾:tag
84
- if (options.tag) {
85
- filteredRecords = filteredRecords.filter(record => {
86
- const tags = record.fields.tags || record.fields.tag;
87
- if (Array.isArray(tags)) {
88
- return tags.includes(options.tag);
89
- }
90
- if (typeof tags === 'string') {
91
- return tags.split(',').map(t => t.trim()).includes(options.tag);
92
- }
93
- return false;
94
- });
95
- }
96
-
97
- // 過濾:priority
98
- if (options.priority) {
99
- filteredRecords = filteredRecords.filter(record => {
100
- const priority = record.fields.priority || record.fields.pri || record.fields.p;
101
- return priority === options.priority || priority === options.priority.toUpperCase();
102
- });
103
- }
104
-
105
- // 過濾:status
106
- if (options.status) {
107
- filteredRecords = filteredRecords.filter(record => {
108
- const status = record.fields.status || record.fields.st;
109
- return matchStatus(status, options.status!);
110
- });
111
- }
112
-
113
- // 關鍵字搜尋(在所有字段中搜尋)
114
- if (options.keyword) {
115
- const keyword = options.keyword.toLowerCase();
116
- filteredRecords = filteredRecords.filter(record => {
117
- // 搜尋 ID
118
- if (record.id.toLowerCase().includes(keyword)) {
119
- return true;
120
- }
121
-
122
- // 搜尋所有欄位值
123
- for (const value of Object.values(record.fields)) {
124
- const valueStr = String(value).toLowerCase();
125
- if (valueStr.includes(keyword)) {
126
- return true;
127
- }
128
- }
129
-
130
- return false;
131
- });
132
- }
133
-
134
- return {
135
- records: filteredRecords,
136
- total: filteredRecords.length,
137
- };
138
- }
139
-
140
- /**
141
- * 狀態匹配(支援縮寫)
142
- */
143
- function matchStatus(recordStatus: any, queryStatus: string): boolean {
144
- const status = String(recordStatus).toLowerCase();
145
- const query = queryStatus.toLowerCase();
146
-
147
- // 完全匹配
148
- if (status === query) return true;
149
-
150
- // 縮寫匹配
151
- const statusMap: Record<string, string[]> = {
152
- 'p': ['pending', 'p'],
153
- 'pending': ['pending', 'p'],
154
- 'i': ['in_progress', 'i', 'inprogress'],
155
- 'in_progress': ['in_progress', 'i', 'inprogress'],
156
- 'c': ['completed', 'c', 'done'],
157
- 'completed': ['completed', 'c', 'done'],
158
- 'b': ['blocked', 'b'],
159
- 'blocked': ['blocked', 'b'],
160
- };
161
-
162
- return statusMap[query]?.includes(status) || statusMap[status]?.includes(query) || false;
163
- }
164
-
165
- /**
166
- * 取得狀態在 index 中的鍵名
167
- */
168
- function getStatusKey(status: string): string {
169
- const query = status.toLowerCase();
170
-
171
- const keyMap: Record<string, string> = {
172
- 'p': 'pending',
173
- 'pending': 'pending',
174
- 'i': 'inprogress',
175
- 'in_progress': 'inprogress',
176
- 'inprogress': 'inprogress',
177
- 'c': 'completed',
178
- 'completed': 'completed',
179
- 'done': 'completed',
180
- 'b': 'blocked',
181
- 'blocked': 'blocked',
182
- };
183
-
184
- return keyMap[query] || query;
185
- }
186
-
187
- /**
188
- * 顯示查詢結果
189
- */
190
- function displayResults(result: QueryResult, format: 'table' | 'json' | 'compact', matrixFile: MatrixFile): void {
191
- if (result.total === 0) {
192
- log('No records found matching the query.');
193
- return;
194
- }
195
-
196
- switch (format) {
197
- case 'json':
198
- displayJSON(result);
199
- break;
200
- case 'compact':
201
- displayCompact(result);
202
- break;
203
- case 'table':
204
- default:
205
- displayTable(result, matrixFile);
206
- break;
207
- }
208
- }
209
-
210
- /**
211
- * 表格格式顯示
212
- */
213
- function displayTable(result: QueryResult, matrixFile: MatrixFile): void {
214
- log(`\n📊 Query Results (${result.total} records found)\n`);
215
- log('─'.repeat(80));
216
-
217
- // 表頭
218
- const headerRow = ['ID', 'Status', 'Priority', 'Title/Description'];
219
- const colWidths = [15, 12, 10, 40];
220
-
221
- const header = headerRow.map((h, i) => h.padEnd(colWidths[i])).join(' | ');
222
- log(header);
223
- log('─'.repeat(80));
224
-
225
- // 數據行
226
- for (const record of result.records) {
227
- const id = record.id.padEnd(colWidths[0]);
228
- const status = (record.fields.status || record.fields.st || '-').toString().padEnd(colWidths[1]);
229
- const priority = (record.fields.priority || record.fields.pri || record.fields.p || '-').toString().padEnd(colWidths[2]);
230
- const title = (record.fields.title || record.fields.desc || record.fields.description || '-').toString().substring(0, colWidths[3]).padEnd(colWidths[3]);
231
-
232
- log(`${id} | ${status} | ${priority} | ${title}`);
233
- }
234
-
235
- log('─'.repeat(80));
236
- log(`Total: ${result.total} record(s)\n`);
237
- }
238
-
239
- /**
240
- * JSON 格式顯示
241
- */
242
- function displayJSON(result: QueryResult): void {
243
- console.log(JSON.stringify(result.records, null, 2));
244
- }
245
-
246
- /**
247
- * 精簡格式顯示
248
- */
249
- function displayCompact(result: QueryResult): void {
250
- log(`Found ${result.total} record(s):\n`);
251
-
252
- for (const record of result.records) {
253
- const status = record.fields.status || record.fields.st || '-';
254
- const priority = record.fields.priority || record.fields.pri || record.fields.p || '-';
255
- const title = record.fields.title || record.fields.desc || '-';
256
-
257
- log(` • ${record.id} [${status}] [P${priority}] ${title}`);
258
- }
259
-
260
- log('');
261
- }