kenaz 0.3.18 → 0.3.20
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/core/.claude/commands/agent-worker.md +1 -1
- package/core/.claude/commands/architect.md +1 -2
- package/core/.claude/commands/spec.md +1 -1
- package/core/.claude/commands//347/224/242/345/223/201.md +1 -1
- package/core/.claude/hooks/__tests__/task-1977-dedupe-guard.test.js +8 -8
- package/core/.claude/skills/architect_agent/SKILL.md +11 -92
- package/core/.claude/skills/assessment_agent/SKILL.md +0 -1
- package/core/.claude/skills/backend_engineer/SKILL.md +3 -6
- package/core/.claude/skills/code_reviewer/SKILL.md +1 -1
- package/core/.claude/skills/code_reviewer/patterns.yaml +1 -1
- package/core/.claude/skills/designer/SKILL.md +3 -6
- package/core/.claude/skills/dev_agent/SKILL.md +30 -491
- package/core/.claude/skills/developer/SKILL.md +3 -6
- package/core/.claude/skills/feature_agent/SKILL.md +3 -17
- package/core/.claude/skills/product_manager/SKILL.md +29 -1064
- package/core/.claude/skills/qa_engineer/SKILL.md +12 -17
- package/core/.claude/skills/spec_optimizer/SKILL.md +25 -275
- package/core/.claude/skills/sre_agent/SKILL.md +3 -6
- package/core/.collaboration/README.md +2 -3
- package/core/.collaboration/core/task-api.js +5 -138
- package/core/.collaboration/docs/CLI.md +0 -2
- package/core/.failure/INDEX.yaml +6 -40
- package/core/.failure/agent-execution/FAIL-013-search-cwd-drift-and-case-mismatch.yaml +1 -1
- package/core/.failure/tools/README.md +9 -227
- package/core/.formation/bifrost/launch.js +1 -6
- package/core/.formation/bifrost/launch.test.js +1 -1
- package/core/.formation/bifrost/shared/ansuz-boot-policy.js +3 -3
- package/core/.formation/bifrost/shared/ansuz-boot-policy.test.js +1 -2
- package/core/.formation/tools/__tests__/arms.test.js +41 -0
- package/core/.formation/tools/__tests__/diagnose-bug.test.js +10 -0
- package/core/.formation/tools/__tests__/m1-hmap-convid.test.js +1 -124
- package/core/.formation/tools/arms.js +48 -0
- package/core/.formation/tools/dispatch.js +24 -15
- package/core/.formation/tools/kenaz-stats.js +32 -8
- package/core/.formation/tools/kenaz-stats.test.js +15 -2
- package/core/.formation/tools/loader.js +17 -140
- package/core/.formation/tools/post-complete.js +0 -31
- package/core/.formation/tools/prompt.js +16 -1
- package/core/.formation/tools/prompt.test.js +20 -0
- package/core/.rule/INDEX.yaml +0 -18
- package/core/.rule/general/agent-workflow.yaml +14 -164
- package/core/.rule/general/project-self-containment.yaml +8 -19
- package/core/.rule/general/rust-verify-target.yaml +6 -5
- package/core/.rule/general/synapse-code-intelligence.yaml +3 -3
- package/core/.specialist/Amelia/capability.yaml +12 -12
- package/core/.specialist/Amelia/workflow.yaml +2 -2
- package/core/.specialist/Ansuz/SYSTEM_DOC.md +20 -578
- package/core/.specialist/Ansuz/cognitive_principles.yaml +2 -3
- package/core/.specialist/Ansuz/concepts/boot_rules_summary.yaml +0 -1
- package/core/.specialist/Ansuz/concepts/deep_knowledge_pointers.yaml +1 -2
- package/core/.specialist/Ansuz/core.yaml +6 -108
- package/core/.specialist/Ansuz/guards/lesson_guards.yaml +0 -3
- package/core/.specialist/Ansuz/identity_contract.yaml +0 -1
- package/core/.specialist/Ansuz/knowledge.yaml +0 -4
- package/core/.specialist/Ansuz/rule.yaml +0 -1
- package/core/.specialist/Ansuz/tools/handoff-session-identity.test.js +6 -150
- package/core/.specialist/tests/runtime-discovery/README.md +1 -1
- package/core/.specialist/tools/__tests__/task-2374-usage-counter.test.js +1 -12
- package/core/.specialist/tools/ansuz-boot-fast.js +7 -4
- package/core/.specialist/tools/ansuz-boot-fast.test.js +10 -3
- package/core/.specialist/tools/prompt-files.test.js +1 -0
- package/core/.specialist/tools/task-bridge.js +1 -66
- package/core/.system/README.md +11 -552
- package/core/.system/collaboration/README.md +10 -174
- package/core/CLAUDE.md +1 -6
- package/core/KENAZ_CORE_VERSION +1 -1
- package/core/dev/scripts/js-yaml-resolution.test.js +1 -1
- package/core/dev/scripts/peer-identity-e2e.js +402 -0
- package/core/dev/scripts/peer-identity-e2e.md +47 -0
- package/core/dev/scripts/relay-admin.js +94 -0
- package/core/dev/scripts/relay-admin.test.js +131 -0
- package/core/dev/scripts/run-rust-tests.js +9 -45
- package/core/dev/scripts/rust-verify-worktree.js +4 -4
- package/core/dev/scripts/verify-target-dir.js +6 -6
- package/core/plugins/kenaz/INVENTORY.md +8 -8
- package/core/plugins/kenaz/README.md +10 -0
- package/core/plugins/kenaz/commands/architect.md +1 -2
- package/core/plugins/kenaz/commands/spec.md +1 -1
- package/core/plugins/kenaz/commands//347/224/242/345/223/201.md +1 -1
- package/core/plugins/kenaz/guidance.md +1 -1
- package/core/plugins/kenaz/hooks/kenaz-hook.js +2 -1
- package/core/plugins/kenaz/hooks/sdk-gate.js +9 -0
- package/core/plugins/kenaz/scripts/kenaz.test.js +15 -3
- package/core/plugins/kenaz/scripts/sync.js +1 -1
- package/core/plugins/kenaz/scripts/ygg.js +8 -0
- package/core/plugins/kenaz/scripts/ygg.test.js +72 -0
- package/core/plugins/kenaz/skills/architect_agent/SKILL.md +11 -92
- package/core/plugins/kenaz/skills/assessment_agent/SKILL.md +0 -1
- package/core/plugins/kenaz/skills/backend_engineer/SKILL.md +3 -6
- package/core/plugins/kenaz/skills/code_reviewer/SKILL.md +1 -1
- package/core/plugins/kenaz/skills/code_reviewer/patterns.yaml +1 -1
- package/core/plugins/kenaz/skills/designer/SKILL.md +3 -6
- package/core/plugins/kenaz/skills/dev_agent/SKILL.md +30 -491
- package/core/plugins/kenaz/skills/developer/SKILL.md +3 -6
- package/core/plugins/kenaz/skills/feature_agent/SKILL.md +3 -17
- package/core/plugins/kenaz/skills/product_manager/SKILL.md +29 -1064
- package/core/plugins/kenaz/skills/qa_engineer/SKILL.md +12 -17
- package/core/plugins/kenaz/skills/spec_optimizer/SKILL.md +25 -275
- package/core/plugins/kenaz/skills/sre_agent/SKILL.md +3 -6
- package/core/plugins/kenaz-peer/hooks/register.test.ts +32 -0
- package/core/plugins/kenaz-peer/hooks/register.ts +9 -0
- package/package.json +6 -6
- package/core/.claude/commands/archive.md +0 -24
- package/core/.claude/commands/init.md +0 -112
- package/core/.claude/commands/legacy_dev.md +0 -18
- package/core/.claude/commands/product-review.md +0 -131
- package/core/.claude/commands/strategy.md +0 -141
- package/core/.claude/commands/sunny.md +0 -1
- package/core/.claude/commands//347/224/242/345/223/201/346/252/242/350/246/226.md +0 -129
- package/core/.claude/commands//351/200/262/345/272/246.md +0 -15
- package/core/.claude/hooks/__tests__/substrate.test.js +0 -122
- package/core/.claude/hooks/_substrate-paths.js +0 -95
- package/core/.claude/hooks/context-check.js +0 -51
- package/core/.claude/hooks/fatigue-check.js +0 -52
- package/core/.claude/hooks/handoff-snapshot-on-commit.js +0 -154
- package/core/.claude/hooks/handoff-snapshot-on-question.js +0 -158
- package/core/.claude/hooks/handoff-staleness.js +0 -197
- package/core/.claude/hooks/jev-thalamus-context.js +0 -17
- package/core/.claude/hooks/jev-thalamus-context.test.js +0 -41
- package/core/.claude/hooks/lease-release.js +0 -119
- package/core/.claude/hooks/lease-touch.js +0 -96
- package/core/.claude/hooks/reflex-feedback.js +0 -5
- package/core/.claude/hooks/session-init.ps1 +0 -49
- package/core/.claude/hooks/sound-event.js +0 -70
- package/core/.claude/hooks/sound-event.sh +0 -37
- package/core/.claude/hooks/stream-delta.js +0 -169
- package/core/.claude/no-hooks.settings.json +0 -3
- package/core/.claude/skills/legacy_dev/SKILL.md +0 -202
- package/core/.claude/skills/sunny/SKILL.md +0 -74
- package/core/.collaboration/cli/commands/assign.js +0 -39
- package/core/.collaboration/cli/commands/claim.js +0 -33
- package/core/.collaboration/cli/commands/complete.js +0 -44
- package/core/.collaboration/cli/commands/create.js +0 -110
- package/core/.collaboration/cli/commands/get.js +0 -83
- package/core/.collaboration/cli/commands/index.js +0 -52
- package/core/.collaboration/cli/commands/list.js +0 -51
- package/core/.collaboration/cli/commands/lock.js +0 -45
- package/core/.collaboration/cli/commands/rebuild.js +0 -39
- package/core/.collaboration/cli/commands/search.js +0 -61
- package/core/.collaboration/cli/commands/stats.js +0 -61
- package/core/.collaboration/cli/commands/transfer.js +0 -41
- package/core/.collaboration/cli/commands/unlock.js +0 -48
- package/core/.collaboration/cli/formatters/help-formatter.js +0 -70
- package/core/.collaboration/cli/formatters/index.js +0 -7
- package/core/.collaboration/cli/task-cli.js +0 -46
- package/core/.collaboration/cli/utils/arg-parser.js +0 -74
- package/core/.collaboration/cli/utils/git-user.js +0 -25
- package/core/.collaboration/cli/utils/index.js +0 -9
- package/core/.collaboration/cli/utils/output.js +0 -10
- package/core/.collaboration/config/default.yaml +0 -189
- package/core/.collaboration/core/conflict-resolver.js +0 -461
- package/core/.collaboration/core/conflict-resolver.test.js +0 -389
- package/core/.collaboration/core/migrate-legacy.js +0 -260
- package/core/.collaboration/docs/API.md +0 -787
- package/core/.collaboration/docs/ARCHITECTURE.md +0 -596
- package/core/.collaboration/docs/FAQ.md +0 -695
- package/core/.collaboration/docs/MIGRATION.md +0 -804
- package/core/.collaboration/docs/examples/README.md +0 -320
- package/core/.collaboration/docs/examples/advanced-queries.js +0 -261
- package/core/.collaboration/docs/examples/basic-usage.js +0 -184
- package/core/.collaboration/docs/examples/team-workflow.js +0 -352
- package/core/.failure/agent-execution/FAIL-001-agent-no-output.yaml +0 -391
- package/core/.failure/agent-execution/FAIL-007-pm-lead-wrong-team-invocation.yaml +0 -0
- package/core/.failure/agent-execution/FAIL-010-phase0-poem-format-skipped.yaml +0 -28
- package/core/.failure/agent-execution/FAIL-010-skipping-cognitive-checkpoint-after-verification.yaml +0 -59
- package/core/.failure/agent-execution/FAIL-012-grep-shortcut-during-investigation.yaml +0 -85
- package/core/.failure/architecture/FAIL-006-python-version-compatibility.yaml +0 -445
- package/core/.failure/pipeline/FAIL-003-queue-pollution.yaml +0 -335
- package/core/.failure/pipeline/README.md +0 -95
- package/core/.failure/retired/FAIL-009-skipping-synapse-pulse-before-code-change.yaml +0 -49
- package/core/.failure/tools/USAGE_GUIDE.md +0 -323
- package/core/.failure/tools/check_failures.ps1 +0 -387
- package/core/.failure/tools/log_failure.ps1 +0 -474
- package/core/.formation/.episode-input.json +0 -10
- package/core/.formation/.merge-lock +0 -1
- package/core/.formation/lead.yaml +0 -118
- package/core/.formation/legacy.bak/designer.yaml +0 -57
- package/core/.formation/legacy.bak/pm.yaml +0 -57
- package/core/.formation/legacy.bak/qa.yaml +0 -57
- package/core/.formation/legacy.bak/review.yaml +0 -62
- package/core/.formation/legacy.bak/scheduler.yaml +0 -129
- package/core/.formation/legacy.bak/sre.yaml +0 -57
- package/core/.formation/role-map.yaml +0 -274
- package/core/.formation/roles/_shared/modules/code_review.yaml +0 -98
- package/core/.formation/roles/_shared/modules/security.yaml +0 -103
- package/core/.formation/roles/_shared/modules/testing.yaml +0 -14
- package/core/.formation/roles/backend/role.yaml +0 -93
- package/core/.formation/roles/code_reviewer/role.yaml +0 -102
- package/core/.formation/roles/database_optimizer/role.yaml +0 -107
- package/core/.formation/roles/designer/role.yaml +0 -66
- package/core/.formation/roles/developer/role.yaml +0 -75
- package/core/.formation/roles/frontend/role.yaml +0 -134
- package/core/.formation/roles/incident_response/role.yaml +0 -89
- package/core/.formation/roles/qa/role.yaml +0 -89
- package/core/.formation/roles/security/role.yaml +0 -87
- package/core/.formation/roles/sre/role.yaml +0 -66
- package/core/.formation/skills/coordinator.yaml +0 -52
- package/core/.formation/solo/diagnosis.yaml +0 -78
- package/core/.formation/solo/strategy.yaml +0 -121
- package/core/.formation/tests/hello.txt +0 -2
- package/core/.formation/tools/coordinator.js +0 -350
- package/core/.formation/tools/jev-correction.js +0 -214
- package/core/.formation/tools/jev-correction.test.js +0 -178
- package/core/.formation/tools/log-reader.js +0 -232
- package/core/.formation/tools/revert-daemon-state.js +0 -162
- package/core/.formation/tools/test-drift.js +0 -148
- package/core/.formation/unit/heimdall.yaml +0 -96
- package/core/.formation/unit/plan.yaml +0 -67
- package/core/.formation/unit/think.yaml +0 -58
- package/core/.kenaz/MUNINN_SNAPSHOT9_EPISODE.json +0 -32
- package/core/.kenaz/MUNINN_SNAPSHOT9_RUNE.json +0 -23
- package/core/.kenaz/MUNINN_SNAPSHOT9_SUMMARY.md +0 -89
- package/core/.kenaz/ash_TASK_1428-20260507.json +0 -14
- package/core/.kenaz/muninn_episode_write.ps1 +0 -17
- package/core/.kenaz/muninn_snapshot11_rune_candidates.md +0 -63
- package/core/.kenaz/muninn_snapshot1_rune_candidates.md +0 -49
- package/core/.kenaz/runes_TASK_1428.json +0 -57
- package/core/.kenaz/tmp_heimdall_proposal_8d3e392.json +0 -13
- package/core/.kenaz/tmp_props.json +0 -1
- package/core/.kenaz/tmp_sounddrop_t1_prompt.txt +0 -371
- package/core/.rule/MECHANIZED.md +0 -61
- package/core/.rule/general/cortex-memory-recall.yaml +0 -446
- package/core/.rule/general/pipeline.yaml +0 -246
- package/core/.rule/general/sunny-access-control.yaml +0 -60
- package/core/.rule/general/system-invariants.yaml +0 -231
- package/core/.rule/pipeline/PPL-002-completed-task-archival.yaml +0 -528
- package/core/.rule/pipeline/auto-update.yaml +0 -282
- package/core/.rule/pipeline/task-execution.yaml +0 -365
- package/core/.specialist/Ansuz/concepts/phase_protocol.yaml +0 -65
- package/core/.specialist/Ansuz/experiments/boot_ablation_replay.js +0 -197
- package/core/.specialist/Ansuz/tools/bootstrap-anchors.js +0 -289
- package/core/.specialist/Ansuz/workflow.yaml +0 -1225
- package/core/.specialist/experiments/rg_benchmark.js +0 -523
- package/core/.specialist/experiments/rg_benchmark_results.json +0 -27
- package/core/.specialist/tools/jev-optional-context.js +0 -107
- package/core/.specialist/tools/jev-optional-context.test.js +0 -152
- package/core/.specialist/tools/memory-action-log.js +0 -839
- package/core/.specialist/tools/phase-gate.js +0 -3534
- package/core/.specialist/tools/phase-gate.test.js +0 -85
- package/core/.specialist/tools/precompute-runner.js +0 -444
- package/core/.specialist/tools/rule-engine.js +0 -621
- package/core/.specialist/tools/task-bridge-jev.test.js +0 -170
- package/core/.synapse/memory-shared.json.sync +0 -1
- package/core/.system/agent-skills/README.md +0 -724
- package/core/.system/cli-tools/README.md +0 -724
- package/core/.system/cortex/MODULES.md +0 -1046
- package/core/.system/dashboard/FRONTEND.md +0 -812
- package/core/.system/dashboard/README.md +0 -737
- package/core/.system/failure/README.md +0 -723
- package/core/.system/formation/LEGACY_SKILLS.md +0 -974
- package/core/.system/formation/POST_COMPLETE.md +0 -602
- package/core/.system/formation/README.md +0 -1094
- package/core/.system/formation/TOOLS_REFERENCE.md +0 -1145
- package/core/.system/kenaz/README.md +0 -787
- package/core/.system/memory/README.md +0 -719
- package/core/.system/pipeline/README.md +0 -712
- package/core/.system/rule/README.md +0 -794
- package/core/.system/sunny/README.md +0 -476
- package/core/.system/sunny/RULES.json +0 -89
- package/core/.system/sunny/knowledge/INDEX.md +0 -37
- package/core/.system/sunny/knowledge/agent-teams-api.md +0 -0
- package/core/.system/sunny/knowledge/ansuz-specialist.md +0 -500
- package/core/.system/sunny/knowledge/claude-cli-spawn.md +0 -177
- package/core/.system/sunny/knowledge/collaboration-api.md +0 -925
- package/core/.system/sunny/teammates/README.md +0 -107
- package/core/.system/sunny/teammates/how_to_use.yaml +0 -101
- package/core/.system/sunny/teammates/tools/headless/launcher.js +0 -318
- package/core/.system/sunny/teammates/tools/powershell/launcher.js +0 -241
- package/core/.system/sunny/teammates/tools/powershell/start.bat +0 -50
- package/core/.system/sunny/teammates/tools/utils/env.js +0 -96
- package/core/.system/sunny/teammates/tools/utils/format-output.js +0 -329
- package/core/.system/sunny/tools.json +0 -101
- package/core/dev/scripts/cleanup-queue.js +0 -184
- package/core/dev/scripts/cleanup_queue.js +0 -86
- package/core/dev/scripts/legacy/README.md +0 -39
- package/core/dev/scripts/legacy/dev_agent_scheduler.ps1.bak +0 -536
- package/core/dev/scripts/legacy/multi_agent_scheduler.ps1.bak +0 -1978
- package/core/dev/scripts/matrix/CLI_README.md +0 -214
- package/core/dev/scripts/matrix/README.md +0 -310
- package/core/dev/scripts/matrix/package-lock.json +0 -4266
- package/core/dev/scripts/matrix/package.json +0 -55
- package/core/dev/scripts/matrix/src/abbreviations.ts +0 -295
- package/core/dev/scripts/matrix/src/cli/commands/convert.ts +0 -211
- package/core/dev/scripts/matrix/src/cli/commands/create.ts +0 -95
- package/core/dev/scripts/matrix/src/cli/commands/delete.ts +0 -102
- package/core/dev/scripts/matrix/src/cli/commands/list-tags.ts.wip +0 -140
- package/core/dev/scripts/matrix/src/cli/commands/manage-tags.ts.wip +0 -173
- package/core/dev/scripts/matrix/src/cli/commands/query.ts +0 -261
- package/core/dev/scripts/matrix/src/cli/commands/read.ts +0 -77
- package/core/dev/scripts/matrix/src/cli/commands/stats.ts.wip +0 -168
- package/core/dev/scripts/matrix/src/cli/commands/tokens.ts.wip +0 -126
- package/core/dev/scripts/matrix/src/cli/commands/update.ts +0 -147
- package/core/dev/scripts/matrix/src/cli/commands/validate.ts +0 -275
- package/core/dev/scripts/matrix/src/cli/index.ts +0 -350
- package/core/dev/scripts/matrix/src/cli/utils/file-handler.ts +0 -72
- package/core/dev/scripts/matrix/src/cli/utils/logger.ts +0 -65
- package/core/dev/scripts/matrix/src/index.ts +0 -62
- package/core/dev/scripts/matrix/src/indexer/tag-indexer.ts +0 -165
- package/core/dev/scripts/matrix/src/parser.ts +0 -281
- package/core/dev/scripts/matrix/src/serializer.ts +0 -151
- package/core/dev/scripts/matrix/src/validator.ts +0 -301
- package/core/dev/scripts/matrix/tests/abbreviations.test.ts +0 -122
- package/core/dev/scripts/matrix/tests/cli.test.ts +0 -177
- package/core/dev/scripts/matrix/tests/convert.test.ts +0 -143
- package/core/dev/scripts/matrix/tests/parser.test.ts +0 -203
- package/core/dev/scripts/matrix/tests/query.test.ts +0 -85
- package/core/dev/scripts/matrix/tests/serializer.test.ts +0 -197
- package/core/dev/scripts/matrix/tests/validate.test.ts +0 -141
- package/core/dev/scripts/matrix/tests/validator.test.ts +0 -167
- package/core/dev/scripts/matrix/tsconfig.json +0 -20
- package/core/dev/scripts/matrix/types/index.d.ts +0 -111
- package/core/dev/scripts/matrix/types/index.d.ts.map +0 -1
- package/core/dev/scripts/matrix/types/index.js +0 -8
- package/core/dev/scripts/matrix/types/index.js.map +0 -1
- package/core/dev/scripts/matrix/types/index.ts +0 -124
- package/core/dev/scripts/memory-usage-report.js +0 -152
- package/core/dev/scripts/probe/ansuz-scaffold-ablation.js +0 -579
- package/core/dev/scripts/probe/ansuz-scaffold-ablation.test.js +0 -244
- package/core/dev/scripts/probe/hook-latency-probe.js +0 -315
- package/core/dev/scripts/probe/hook-latency-probe.test.js +0 -105
- package/core/dev/scripts/probe/prediction-signal-auc.js +0 -483
- package/core/dev/scripts/probe/prediction-signal-auc.test.js +0 -200
- package/core/dev/scripts/test-pty-ws-tunnel.js +0 -229
- package/core/dev/scripts/validate_pipeline.js +0 -197
- package/core/dev/spikes/task2145-evidence-20261004/backend-log-excerpt.txt +0 -56
- package/core/dev/spikes/task2145-evidence-20261004/graph.shadow +0 -0
- package/core/dev/spikes/task2145-evidence-20261004/graph.wal +0 -0
- package/core/dev/spikes/task2145-evidence-20261004/graph_corrupt_suspect.marker +0 -1
- package/core/plugins/kenaz/commands/strategy.md +0 -141
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validate command - 驗證 .matrix 文件語法並提供修復建議
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import * as fs from 'fs';
|
|
6
|
-
import { MatrixValidator } from '../../validator';
|
|
7
|
-
import { MatrixParser } from '../../parser';
|
|
8
|
-
import { MatrixSerializer } from '../../serializer';
|
|
9
|
-
import { log, error as logError, success } from '../utils/logger';
|
|
10
|
-
import type { ParseError } from '../../../types';
|
|
11
|
-
|
|
12
|
-
interface ValidateOptions {
|
|
13
|
-
fix?: boolean;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Validate command handler
|
|
18
|
-
*/
|
|
19
|
-
export async function validateCommand(file: string, options: ValidateOptions): Promise<void> {
|
|
20
|
-
try {
|
|
21
|
-
// 確保文件有 .matrix 擴展名
|
|
22
|
-
const filePath = file.endsWith('.matrix') ? file : `${file}.matrix`;
|
|
23
|
-
|
|
24
|
-
// 檢查文件是否存在
|
|
25
|
-
if (!fs.existsSync(filePath)) {
|
|
26
|
-
throw new Error(`File not found: ${filePath}`);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// 讀取文件
|
|
30
|
-
const content = fs.readFileSync(filePath, 'utf-8');
|
|
31
|
-
|
|
32
|
-
// 執行驗證
|
|
33
|
-
const validator = new MatrixValidator();
|
|
34
|
-
const result = validator.validate(content);
|
|
35
|
-
|
|
36
|
-
// 顯示結果
|
|
37
|
-
displayValidationResults(result.errors, result.warnings, filePath);
|
|
38
|
-
|
|
39
|
-
// 如果有錯誤,提供修復建議
|
|
40
|
-
if (!result.valid && result.errors.length > 0) {
|
|
41
|
-
log('\n💡 Fix Suggestions:\n');
|
|
42
|
-
provideFixSuggestions(result.errors, content, filePath);
|
|
43
|
-
|
|
44
|
-
// 如果啟用了 --fix 選項,嘗試自動修復
|
|
45
|
-
if (options.fix) {
|
|
46
|
-
log('\n🔧 Attempting auto-fix...\n');
|
|
47
|
-
const fixed = attemptAutoFix(content, result.errors, filePath);
|
|
48
|
-
if (fixed) {
|
|
49
|
-
success(`✅ File fixed successfully: ${filePath}`);
|
|
50
|
-
} else {
|
|
51
|
-
logError('⚠️ Some errors could not be auto-fixed. Please fix manually.');
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
} else if (result.warnings.length > 0) {
|
|
55
|
-
log('\n⚠️ File is valid but has warnings. Consider addressing them.\n');
|
|
56
|
-
} else {
|
|
57
|
-
success(`\n✅ File is valid: ${filePath}\n`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
} catch (err) {
|
|
61
|
-
logError((err as Error).message);
|
|
62
|
-
throw err;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* 顯示驗證結果
|
|
68
|
-
*/
|
|
69
|
-
function displayValidationResults(errors: ParseError[], warnings: ParseError[], filePath: string): void {
|
|
70
|
-
log(`\n📋 Validation Report for: ${filePath}\n`);
|
|
71
|
-
log('─'.repeat(80));
|
|
72
|
-
|
|
73
|
-
// 顯示錯誤
|
|
74
|
-
if (errors.length > 0) {
|
|
75
|
-
log(`\n❌ Errors (${errors.length}):\n`);
|
|
76
|
-
for (const error of errors) {
|
|
77
|
-
const location = error.line ? ` at line ${error.line}` : '';
|
|
78
|
-
log(` [${error.code}] ${error.message}${location}`);
|
|
79
|
-
if (error.expected) {
|
|
80
|
-
log(` Expected: ${error.expected}`);
|
|
81
|
-
}
|
|
82
|
-
if (error.got) {
|
|
83
|
-
log(` Got: ${error.got}`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// 顯示警告
|
|
89
|
-
if (warnings.length > 0) {
|
|
90
|
-
log(`\n⚠️ Warnings (${warnings.length}):\n`);
|
|
91
|
-
for (const warning of warnings) {
|
|
92
|
-
const location = warning.line ? ` at line ${warning.line}` : '';
|
|
93
|
-
log(` [${warning.code}] ${warning.message}${location}`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
log('\n' + '─'.repeat(80));
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* 提供修復建議
|
|
102
|
-
*/
|
|
103
|
-
function provideFixSuggestions(errors: ParseError[], content: string, filePath: string): void {
|
|
104
|
-
const lines = content.split(/\r?\n/);
|
|
105
|
-
const suggestions: string[] = [];
|
|
106
|
-
|
|
107
|
-
for (const error of errors) {
|
|
108
|
-
const suggestion = getSuggestionForError(error, lines);
|
|
109
|
-
if (suggestion && !suggestions.includes(suggestion)) {
|
|
110
|
-
suggestions.push(suggestion);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
for (let i = 0; i < suggestions.length; i++) {
|
|
115
|
-
log(` ${i + 1}. ${suggestions[i]}`);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
log('');
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* 根據錯誤代碼生成具體的修復建議
|
|
123
|
-
*/
|
|
124
|
-
function getSuggestionForError(error: ParseError, lines: string[]): string {
|
|
125
|
-
switch (error.code) {
|
|
126
|
-
case 'E000':
|
|
127
|
-
return '文件為空。請添加至少包含 @meta 和 @index 的內容。\n 範例:\n # .matrix v1.0\n @meta |v=1.0|c=T|\n @index |tot=0|';
|
|
128
|
-
|
|
129
|
-
case 'E001':
|
|
130
|
-
if (error.message.includes('@meta')) {
|
|
131
|
-
return '缺少 @meta 層。請在文件開頭加入:\n @meta |v=1.0|c=T| (v=版本號, c=分類)';
|
|
132
|
-
}
|
|
133
|
-
if (error.message.includes('@index')) {
|
|
134
|
-
return '缺少 @index 層。請在 @meta 之後加入:\n @index |tot=0| (tot=總數)';
|
|
135
|
-
}
|
|
136
|
-
return '缺少必要的層級。請確保文件包含 @meta 和 @index。';
|
|
137
|
-
|
|
138
|
-
case 'E002':
|
|
139
|
-
if (error.message.includes('Duplicate')) {
|
|
140
|
-
return `刪除重複的 ${error.message.includes('@meta') ? '@meta' : '@index'} 層,每個文件只能有一個。`;
|
|
141
|
-
}
|
|
142
|
-
if (error.message.includes('order')) {
|
|
143
|
-
return '調整層級順序:@meta 必須在最前面,接著是 @index,最後是 @data(可選)。';
|
|
144
|
-
}
|
|
145
|
-
return '檢查層級順序和重複性。';
|
|
146
|
-
|
|
147
|
-
case 'E003':
|
|
148
|
-
if (error.line && lines[error.line - 1]) {
|
|
149
|
-
const line = lines[error.line - 1].trim();
|
|
150
|
-
return `第 ${error.line} 行格式錯誤。正確格式應為:\n ${error.expected || '|field=value|...|}'}`;
|
|
151
|
-
}
|
|
152
|
-
return '檢查分隔符 | 是否正確。每行應以 | 開始和結束。';
|
|
153
|
-
|
|
154
|
-
case 'E004':
|
|
155
|
-
return '欄位格式錯誤。每個欄位應為 key=value 格式,使用 | 分隔。\n 範例:|field1=value1|field2=value2|';
|
|
156
|
-
|
|
157
|
-
case 'E005':
|
|
158
|
-
if (error.message.includes('v')) {
|
|
159
|
-
return '@meta 必須包含 v (version) 欄位。請加入:v=1.0';
|
|
160
|
-
}
|
|
161
|
-
if (error.message.includes('c')) {
|
|
162
|
-
return '@meta 必須包含 c (category) 欄位。請加入:c=T (T/M/R/P 或自訂)';
|
|
163
|
-
}
|
|
164
|
-
return '@meta 必須包含 v (version) 和 c (category) 欄位。';
|
|
165
|
-
|
|
166
|
-
case 'E006':
|
|
167
|
-
return '時間戳格式錯誤。應使用 YYMMDD-HHMM 格式,例如:260207-1430';
|
|
168
|
-
|
|
169
|
-
case 'E007':
|
|
170
|
-
return '偵測到重複的記錄 ID。每個記錄的 ID 必須唯一。請檢查 @data 層的 ID。';
|
|
171
|
-
|
|
172
|
-
case 'E008':
|
|
173
|
-
return '未知的欄位鍵名。請確認欄位名稱是否正確或是否為自訂欄位。';
|
|
174
|
-
|
|
175
|
-
case 'E009':
|
|
176
|
-
return '值類型錯誤。請檢查欄位值是否符合預期類型(數字、布林、字串等)。';
|
|
177
|
-
|
|
178
|
-
case 'E010':
|
|
179
|
-
return '版本號格式錯誤。應使用語意化版本號,例如:1.0.0 或 2.1.3';
|
|
180
|
-
|
|
181
|
-
default:
|
|
182
|
-
return `錯誤代碼 ${error.code}: ${error.message}`;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* 嘗試自動修復常見錯誤
|
|
188
|
-
*/
|
|
189
|
-
function attemptAutoFix(content: string, errors: ParseError[], filePath: string): boolean {
|
|
190
|
-
let fixedContent = content;
|
|
191
|
-
let hasChanges = false;
|
|
192
|
-
|
|
193
|
-
// 修復 E000: 空文件
|
|
194
|
-
if (errors.some(e => e.code === 'E000')) {
|
|
195
|
-
fixedContent = `# .matrix v1.0\n@meta |v=1.0|c=T|\n@index |tot=0|\n@data\n`;
|
|
196
|
-
hasChanges = true;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// 修復 E001: 缺少 @meta
|
|
200
|
-
if (errors.some(e => e.code === 'E001' && e.message.includes('@meta'))) {
|
|
201
|
-
const lines = fixedContent.split(/\r?\n/);
|
|
202
|
-
// 在第一個非註釋行之前插入 @meta
|
|
203
|
-
let insertIndex = 0;
|
|
204
|
-
while (insertIndex < lines.length && lines[insertIndex].trim().startsWith('#')) {
|
|
205
|
-
insertIndex++;
|
|
206
|
-
}
|
|
207
|
-
lines.splice(insertIndex, 0, '@meta |v=1.0|c=T|');
|
|
208
|
-
fixedContent = lines.join('\n');
|
|
209
|
-
hasChanges = true;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// 修復 E001: 缺少 @index
|
|
213
|
-
if (errors.some(e => e.code === 'E001' && e.message.includes('@index'))) {
|
|
214
|
-
const lines = fixedContent.split(/\r?\n/);
|
|
215
|
-
// 在 @meta 之後插入 @index
|
|
216
|
-
const metaIndex = lines.findIndex(l => l.trim().startsWith('@meta'));
|
|
217
|
-
if (metaIndex >= 0) {
|
|
218
|
-
lines.splice(metaIndex + 1, 0, '@index |tot=0|');
|
|
219
|
-
fixedContent = lines.join('\n');
|
|
220
|
-
hasChanges = true;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// 修復 E003: 分隔符錯誤(簡單情況)
|
|
225
|
-
const delimiterErrors = errors.filter(e => e.code === 'E003');
|
|
226
|
-
if (delimiterErrors.length > 0) {
|
|
227
|
-
const lines = fixedContent.split(/\r?\n/);
|
|
228
|
-
for (const error of delimiterErrors) {
|
|
229
|
-
if (error.line && error.line <= lines.length) {
|
|
230
|
-
const lineIndex = error.line - 1;
|
|
231
|
-
let line = lines[lineIndex].trim();
|
|
232
|
-
|
|
233
|
-
// 如果缺少開頭或結尾的 |
|
|
234
|
-
if (line.startsWith('@meta') || line.startsWith('@index')) {
|
|
235
|
-
const match = line.match(/^(@\w+)\s+(.+)$/);
|
|
236
|
-
if (match) {
|
|
237
|
-
const section = match[1];
|
|
238
|
-
let content = match[2];
|
|
239
|
-
if (!content.startsWith('|')) content = '|' + content;
|
|
240
|
-
if (!content.endsWith('|')) content = content + '|';
|
|
241
|
-
lines[lineIndex] = `${section} ${content}`;
|
|
242
|
-
hasChanges = true;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
fixedContent = lines.join('\n');
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// 如果有修改,保存文件
|
|
251
|
-
if (hasChanges) {
|
|
252
|
-
// 備份原文件
|
|
253
|
-
const backupPath = `${filePath}.backup`;
|
|
254
|
-
fs.writeFileSync(backupPath, content, 'utf-8');
|
|
255
|
-
log(` 📦 Original file backed up to: ${backupPath}`);
|
|
256
|
-
|
|
257
|
-
// 寫入修復後的內容
|
|
258
|
-
fs.writeFileSync(filePath, fixedContent, 'utf-8');
|
|
259
|
-
log(` ✅ Fixed ${errors.length} error(s)`);
|
|
260
|
-
|
|
261
|
-
// 重新驗證
|
|
262
|
-
const validator = new MatrixValidator();
|
|
263
|
-
const revalidateResult = validator.validate(fixedContent);
|
|
264
|
-
|
|
265
|
-
if (revalidateResult.valid) {
|
|
266
|
-
log(` ✅ File is now valid!`);
|
|
267
|
-
return true;
|
|
268
|
-
} else {
|
|
269
|
-
log(` ⚠️ Some errors remain (${revalidateResult.errors.length}). Manual fix may be required.`);
|
|
270
|
-
return false;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return false;
|
|
275
|
-
}
|
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* matrix CLI - Command line tool for .matrix file operations
|
|
4
|
-
* @version 1.0.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { Command } from 'commander';
|
|
8
|
-
import { createCommand } from './commands/create';
|
|
9
|
-
import { readCommand } from './commands/read';
|
|
10
|
-
import { updateCommand } from './commands/update';
|
|
11
|
-
import { deleteCommand } from './commands/delete';
|
|
12
|
-
import { queryCommand } from './commands/query';
|
|
13
|
-
import { convertCommand } from './commands/convert';
|
|
14
|
-
import { validateCommand } from './commands/validate';
|
|
15
|
-
// TODO: Import new commands after fixing parser adaptation
|
|
16
|
-
// import { statsCommand } from './commands/stats';
|
|
17
|
-
// import { tokensCommand } from './commands/tokens';
|
|
18
|
-
// import { listTagsCommand } from './commands/list-tags';
|
|
19
|
-
// import { addTagCommand, removeTagCommand, showRuleTagsCommand } from './commands/manage-tags';
|
|
20
|
-
|
|
21
|
-
const program = new Command();
|
|
22
|
-
|
|
23
|
-
program
|
|
24
|
-
.name('matrix')
|
|
25
|
-
.description('CLI tool for managing .matrix format files')
|
|
26
|
-
.version('1.1.0');
|
|
27
|
-
|
|
28
|
-
// CREATE command
|
|
29
|
-
program
|
|
30
|
-
.command('create <file>')
|
|
31
|
-
.description('Create a new .matrix file')
|
|
32
|
-
.option('-v, --version <version>', 'Version number (e.g., 1.0.0)')
|
|
33
|
-
.option('-c, --category <category>', 'Category (T/M/R/P or custom)')
|
|
34
|
-
.option('-i, --interactive', 'Use interactive mode', false)
|
|
35
|
-
.action(async (file, options) => {
|
|
36
|
-
try {
|
|
37
|
-
await createCommand(file, options);
|
|
38
|
-
} catch (error) {
|
|
39
|
-
console.error('Error:', (error as Error).message);
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
})
|
|
43
|
-
.addHelpText(
|
|
44
|
-
'after',
|
|
45
|
-
`
|
|
46
|
-
Examples:
|
|
47
|
-
$ matrix create tasks.matrix -v 1.0.0 -c T
|
|
48
|
-
$ matrix create memory -i
|
|
49
|
-
$ matrix create project_status --version 2.0.0 --category P
|
|
50
|
-
`
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
// READ command
|
|
54
|
-
program
|
|
55
|
-
.command('read <file>')
|
|
56
|
-
.description('Read and display .matrix file content')
|
|
57
|
-
.option('-l, --level <level>', 'Display level (1=overview, 2=recent 10, 3=all)', '3')
|
|
58
|
-
.action((file, options) => {
|
|
59
|
-
try {
|
|
60
|
-
const level = parseInt(options.level, 10);
|
|
61
|
-
if (isNaN(level) || level < 1 || level > 3) {
|
|
62
|
-
console.error('Error: Level must be 1, 2, or 3');
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
readCommand(file, { level });
|
|
66
|
-
} catch (error) {
|
|
67
|
-
console.error('Error:', (error as Error).message);
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
70
|
-
})
|
|
71
|
-
.addHelpText(
|
|
72
|
-
'after',
|
|
73
|
-
`
|
|
74
|
-
Examples:
|
|
75
|
-
$ matrix read tasks.matrix
|
|
76
|
-
$ matrix read tasks.matrix --level 1
|
|
77
|
-
$ matrix read memory.matrix -l 2
|
|
78
|
-
`
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
// UPDATE command
|
|
82
|
-
program
|
|
83
|
-
.command('update <file> <rule-id>')
|
|
84
|
-
.description('Update a specific rule in .matrix file')
|
|
85
|
-
.option('-f, --field <field>', 'Field name to update')
|
|
86
|
-
.option('-v, --value <value>', 'New value for the field')
|
|
87
|
-
.option('-i, --interactive', 'Use interactive mode', false)
|
|
88
|
-
.action(async (file, ruleId, options) => {
|
|
89
|
-
try {
|
|
90
|
-
await updateCommand(file, ruleId, options);
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.error('Error:', (error as Error).message);
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
})
|
|
96
|
-
.addHelpText(
|
|
97
|
-
'after',
|
|
98
|
-
`
|
|
99
|
-
Examples:
|
|
100
|
-
$ matrix update tasks.matrix TASK_001 -f status -v completed
|
|
101
|
-
$ matrix update tasks.matrix TASK_002 -i
|
|
102
|
-
$ matrix update memory.matrix MEM_005 --field priority --value high
|
|
103
|
-
`
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
// DELETE command
|
|
107
|
-
program
|
|
108
|
-
.command('delete <file> <rule-id>')
|
|
109
|
-
.description('Delete a rule from .matrix file')
|
|
110
|
-
.option('-f, --force', 'Skip confirmation prompt', false)
|
|
111
|
-
.action(async (file, ruleId, options) => {
|
|
112
|
-
try {
|
|
113
|
-
await deleteCommand(file, ruleId, options);
|
|
114
|
-
} catch (error) {
|
|
115
|
-
console.error('Error:', (error as Error).message);
|
|
116
|
-
process.exit(1);
|
|
117
|
-
}
|
|
118
|
-
})
|
|
119
|
-
.addHelpText(
|
|
120
|
-
'after',
|
|
121
|
-
`
|
|
122
|
-
Examples:
|
|
123
|
-
$ matrix delete tasks.matrix TASK_001
|
|
124
|
-
$ matrix delete tasks.matrix TASK_002 -f
|
|
125
|
-
$ matrix delete memory.matrix MEM_OLD --force
|
|
126
|
-
`
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
// QUERY command
|
|
130
|
-
program
|
|
131
|
-
.command('query <file>')
|
|
132
|
-
.description('Query .matrix file with filters')
|
|
133
|
-
.option('-t, --tag <tag>', 'Filter by tag')
|
|
134
|
-
.option('-p, --priority <priority>', 'Filter by priority (P0/P1/P2/P3)')
|
|
135
|
-
.option('-s, --status <status>', 'Filter by status (pending/in_progress/completed/blocked)')
|
|
136
|
-
.option('-k, --keyword <keyword>', 'Search by keyword (in all fields)')
|
|
137
|
-
.option('-f, --format <format>', 'Output format (table/json/compact)', 'table')
|
|
138
|
-
.action(async (file, options) => {
|
|
139
|
-
try {
|
|
140
|
-
await queryCommand(file, options);
|
|
141
|
-
} catch (error) {
|
|
142
|
-
console.error('Error:', (error as Error).message);
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
.addHelpText(
|
|
147
|
-
'after',
|
|
148
|
-
`
|
|
149
|
-
Examples:
|
|
150
|
-
$ matrix query tasks.matrix --status pending
|
|
151
|
-
$ matrix query tasks.matrix -s completed -p P0
|
|
152
|
-
$ matrix query tasks.matrix --tag feature --format json
|
|
153
|
-
$ matrix query tasks.matrix -k "authentication" -f compact
|
|
154
|
-
`
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
// CONVERT command
|
|
158
|
-
program
|
|
159
|
-
.command('convert <input> <output>')
|
|
160
|
-
.description('Convert between .matrix and JSON formats')
|
|
161
|
-
.option('--from <format>', 'Input format (json/matrix, auto-detected if not specified)')
|
|
162
|
-
.option('--to <format>', 'Output format (json/matrix, auto-detected if not specified)')
|
|
163
|
-
.action(async (input, output, options) => {
|
|
164
|
-
try {
|
|
165
|
-
await convertCommand(input, output, options);
|
|
166
|
-
} catch (error) {
|
|
167
|
-
console.error('Error:', (error as Error).message);
|
|
168
|
-
process.exit(1);
|
|
169
|
-
}
|
|
170
|
-
})
|
|
171
|
-
.addHelpText(
|
|
172
|
-
'after',
|
|
173
|
-
`
|
|
174
|
-
Examples:
|
|
175
|
-
$ matrix convert tasks.matrix tasks.json
|
|
176
|
-
$ matrix convert tasks.json tasks.matrix
|
|
177
|
-
$ matrix convert input.matrix output.json --from matrix --to json
|
|
178
|
-
`
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
// VALIDATE command
|
|
182
|
-
program
|
|
183
|
-
.command('validate <file>')
|
|
184
|
-
.description('Validate .matrix file syntax and provide fix suggestions')
|
|
185
|
-
.option('--fix', 'Attempt to auto-fix simple errors', false)
|
|
186
|
-
.action(async (file, options) => {
|
|
187
|
-
try {
|
|
188
|
-
await validateCommand(file, options);
|
|
189
|
-
} catch (error) {
|
|
190
|
-
console.error('Error:', (error as Error).message);
|
|
191
|
-
process.exit(1);
|
|
192
|
-
}
|
|
193
|
-
})
|
|
194
|
-
.addHelpText(
|
|
195
|
-
'after',
|
|
196
|
-
`
|
|
197
|
-
Examples:
|
|
198
|
-
$ matrix validate tasks.matrix
|
|
199
|
-
$ matrix validate tasks.matrix --fix
|
|
200
|
-
$ matrix validate memory.matrix
|
|
201
|
-
`
|
|
202
|
-
);
|
|
203
|
-
|
|
204
|
-
// TODO: New commands (WIP - parser adaptation needed)
|
|
205
|
-
/*
|
|
206
|
-
// STATS command
|
|
207
|
-
program
|
|
208
|
-
.command('stats <file>')
|
|
209
|
-
.description('Display statistics about .matrix file')
|
|
210
|
-
.option('-v, --verbose', 'Show detailed statistics', false)
|
|
211
|
-
.action(async (file, options) => {
|
|
212
|
-
try {
|
|
213
|
-
await statsCommand(file, options);
|
|
214
|
-
} catch (error) {
|
|
215
|
-
console.error('Error:', (error as Error).message);
|
|
216
|
-
process.exit(1);
|
|
217
|
-
}
|
|
218
|
-
})
|
|
219
|
-
.addHelpText(
|
|
220
|
-
'after',
|
|
221
|
-
`
|
|
222
|
-
Examples:
|
|
223
|
-
$ matrix stats tasks.matrix
|
|
224
|
-
$ matrix stats tasks.matrix --verbose
|
|
225
|
-
$ matrix stats .rule/INDEX.matrix -v
|
|
226
|
-
`
|
|
227
|
-
);
|
|
228
|
-
|
|
229
|
-
// TOKENS command
|
|
230
|
-
program
|
|
231
|
-
.command('tokens <file>')
|
|
232
|
-
.description('Calculate token count and compression ratio')
|
|
233
|
-
.option('-v, --verbose', 'Show detailed token analysis', false)
|
|
234
|
-
.action(async (file, options) => {
|
|
235
|
-
try {
|
|
236
|
-
await tokensCommand(file, options);
|
|
237
|
-
} catch (error) {
|
|
238
|
-
console.error('Error:', (error as Error).message);
|
|
239
|
-
process.exit(1);
|
|
240
|
-
}
|
|
241
|
-
})
|
|
242
|
-
.addHelpText(
|
|
243
|
-
'after',
|
|
244
|
-
`
|
|
245
|
-
Examples:
|
|
246
|
-
$ matrix tokens tasks.matrix
|
|
247
|
-
$ matrix tokens tasks.matrix --verbose
|
|
248
|
-
$ matrix tokens .rule/INDEX.matrix
|
|
249
|
-
`
|
|
250
|
-
);
|
|
251
|
-
|
|
252
|
-
// LIST-TAGS command
|
|
253
|
-
program
|
|
254
|
-
.command('list-tags <file>')
|
|
255
|
-
.description('List all tags and their usage counts')
|
|
256
|
-
.option('-t, --type <type>', 'Filter by tag type (source/category/priority/domain/custom)')
|
|
257
|
-
.option('-s, --sort <sort>', 'Sort by name or count (default: count)', 'count')
|
|
258
|
-
.action(async (file, options) => {
|
|
259
|
-
try {
|
|
260
|
-
await listTagsCommand(file, options);
|
|
261
|
-
} catch (error) {
|
|
262
|
-
console.error('Error:', (error as Error).message);
|
|
263
|
-
process.exit(1);
|
|
264
|
-
}
|
|
265
|
-
})
|
|
266
|
-
.addHelpText(
|
|
267
|
-
'after',
|
|
268
|
-
`
|
|
269
|
-
Examples:
|
|
270
|
-
$ matrix list-tags tasks.matrix
|
|
271
|
-
$ matrix list-tags tasks.matrix --type priority
|
|
272
|
-
$ matrix list-tags tasks.matrix -t custom --sort name
|
|
273
|
-
`
|
|
274
|
-
);
|
|
275
|
-
|
|
276
|
-
// ADD-TAG command
|
|
277
|
-
program
|
|
278
|
-
.command('add-tag <file> <rule-id> <tag>')
|
|
279
|
-
.description('Add a tag to a rule')
|
|
280
|
-
.option('-f, --force', 'Skip confirmation', false)
|
|
281
|
-
.action(async (file, ruleId, tag, options) => {
|
|
282
|
-
try {
|
|
283
|
-
await addTagCommand(file, ruleId, tag, options);
|
|
284
|
-
} catch (error) {
|
|
285
|
-
console.error('Error:', (error as Error).message);
|
|
286
|
-
process.exit(1);
|
|
287
|
-
}
|
|
288
|
-
})
|
|
289
|
-
.addHelpText(
|
|
290
|
-
'after',
|
|
291
|
-
`
|
|
292
|
-
Examples:
|
|
293
|
-
$ matrix add-tag tasks.matrix TASK_001 feature
|
|
294
|
-
$ matrix add-tag tasks.matrix TASK_002 "#urgent"
|
|
295
|
-
$ matrix add-tag memory.matrix MEM_005 archived -f
|
|
296
|
-
`
|
|
297
|
-
);
|
|
298
|
-
|
|
299
|
-
// REMOVE-TAG command
|
|
300
|
-
program
|
|
301
|
-
.command('remove-tag <file> <rule-id> <tag>')
|
|
302
|
-
.description('Remove a tag from a rule')
|
|
303
|
-
.option('-f, --force', 'Skip confirmation', false)
|
|
304
|
-
.action(async (file, ruleId, tag, options) => {
|
|
305
|
-
try {
|
|
306
|
-
await removeTagCommand(file, ruleId, tag, options);
|
|
307
|
-
} catch (error) {
|
|
308
|
-
console.error('Error:', (error as Error).message);
|
|
309
|
-
process.exit(1);
|
|
310
|
-
}
|
|
311
|
-
})
|
|
312
|
-
.addHelpText(
|
|
313
|
-
'after',
|
|
314
|
-
`
|
|
315
|
-
Examples:
|
|
316
|
-
$ matrix remove-tag tasks.matrix TASK_001 feature
|
|
317
|
-
$ matrix remove-tag tasks.matrix TASK_002 "#urgent"
|
|
318
|
-
$ matrix remove-tag memory.matrix MEM_005 archived -f
|
|
319
|
-
`
|
|
320
|
-
);
|
|
321
|
-
|
|
322
|
-
// SHOW-RULE-TAGS command
|
|
323
|
-
program
|
|
324
|
-
.command('show-tags <file> <rule-id>')
|
|
325
|
-
.description('Show all tags for a specific rule')
|
|
326
|
-
.action(async (file, ruleId) => {
|
|
327
|
-
try {
|
|
328
|
-
await showRuleTagsCommand(file, ruleId);
|
|
329
|
-
} catch (error) {
|
|
330
|
-
console.error('Error:', (error as Error).message);
|
|
331
|
-
process.exit(1);
|
|
332
|
-
}
|
|
333
|
-
})
|
|
334
|
-
.addHelpText(
|
|
335
|
-
'after',
|
|
336
|
-
`
|
|
337
|
-
Examples:
|
|
338
|
-
$ matrix show-tags tasks.matrix TASK_001
|
|
339
|
-
$ matrix show-tags memory.matrix MEM_005
|
|
340
|
-
`
|
|
341
|
-
);
|
|
342
|
-
*/
|
|
343
|
-
|
|
344
|
-
// Parse arguments
|
|
345
|
-
program.parse(process.argv);
|
|
346
|
-
|
|
347
|
-
// Show help if no command provided
|
|
348
|
-
if (!process.argv.slice(2).length) {
|
|
349
|
-
program.outputHelp();
|
|
350
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* File Handler Utility
|
|
3
|
-
* Handles file I/O operations with error handling
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import * as fs from 'fs';
|
|
7
|
-
import * as path from 'path';
|
|
8
|
-
import { Logger } from './logger';
|
|
9
|
-
|
|
10
|
-
export class FileHandler {
|
|
11
|
-
/**
|
|
12
|
-
* Read .matrix file content
|
|
13
|
-
* @param filePath Path to .matrix file
|
|
14
|
-
* @returns File content or null if error
|
|
15
|
-
*/
|
|
16
|
-
static read(filePath: string): string | null {
|
|
17
|
-
try {
|
|
18
|
-
if (!fs.existsSync(filePath)) {
|
|
19
|
-
Logger.error(`File not found: ${filePath}`);
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return fs.readFileSync(filePath, 'utf-8');
|
|
24
|
-
} catch (error) {
|
|
25
|
-
Logger.error(`Failed to read file: ${(error as Error).message}`);
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Write content to .matrix file
|
|
32
|
-
* @param filePath Path to .matrix file
|
|
33
|
-
* @param content File content
|
|
34
|
-
* @returns Success status
|
|
35
|
-
*/
|
|
36
|
-
static write(filePath: string, content: string): boolean {
|
|
37
|
-
try {
|
|
38
|
-
// Ensure directory exists
|
|
39
|
-
const dir = path.dirname(filePath);
|
|
40
|
-
if (!fs.existsSync(dir)) {
|
|
41
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
fs.writeFileSync(filePath, content, 'utf-8');
|
|
45
|
-
return true;
|
|
46
|
-
} catch (error) {
|
|
47
|
-
Logger.error(`Failed to write file: ${(error as Error).message}`);
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Check if file exists
|
|
54
|
-
* @param filePath Path to file
|
|
55
|
-
* @returns True if exists
|
|
56
|
-
*/
|
|
57
|
-
static exists(filePath: string): boolean {
|
|
58
|
-
return fs.existsSync(filePath);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Ensure file has .matrix extension
|
|
63
|
-
* @param filePath Original file path
|
|
64
|
-
* @returns File path with .matrix extension
|
|
65
|
-
*/
|
|
66
|
-
static ensureExtension(filePath: string): string {
|
|
67
|
-
if (!filePath.endsWith('.matrix')) {
|
|
68
|
-
return `${filePath}.matrix`;
|
|
69
|
-
}
|
|
70
|
-
return filePath;
|
|
71
|
-
}
|
|
72
|
-
}
|