cognitive-core 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.json +111 -2
- package/.sessionlog/settings.json +4 -0
- package/dist/atlas.d.ts +10 -0
- package/dist/atlas.d.ts.map +1 -1
- package/dist/atlas.js +65 -0
- package/dist/atlas.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/learning/index.d.ts +1 -1
- package/dist/learning/index.d.ts.map +1 -1
- package/dist/learning/index.js.map +1 -1
- package/dist/learning/pipeline.d.ts +4 -31
- package/dist/learning/pipeline.d.ts.map +1 -1
- package/dist/learning/pipeline.js +12 -64
- package/dist/learning/pipeline.js.map +1 -1
- package/dist/learning/unified-pipeline.d.ts +30 -0
- package/dist/learning/unified-pipeline.d.ts.map +1 -1
- package/dist/learning/unified-pipeline.js +207 -0
- package/dist/learning/unified-pipeline.js.map +1 -1
- package/dist/memory/candidate-retrieval.d.ts.map +1 -1
- package/dist/memory/candidate-retrieval.js +3 -1
- package/dist/memory/candidate-retrieval.js.map +1 -1
- package/dist/memory/curated-loader.d.ts +21 -4
- package/dist/memory/curated-loader.d.ts.map +1 -1
- package/dist/memory/curated-loader.js +53 -16
- package/dist/memory/curated-loader.js.map +1 -1
- package/dist/memory/index.d.ts +2 -1
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +3 -1
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/playbook.d.ts +6 -0
- package/dist/memory/playbook.d.ts.map +1 -1
- package/dist/memory/playbook.js +15 -0
- package/dist/memory/playbook.js.map +1 -1
- package/dist/memory/source-resolver.d.ts +120 -0
- package/dist/memory/source-resolver.d.ts.map +1 -0
- package/dist/memory/source-resolver.js +300 -0
- package/dist/memory/source-resolver.js.map +1 -0
- package/dist/types/config.d.ts +141 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +40 -0
- package/dist/types/config.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/error-classifier.js +8 -8
- package/dist/utils/error-classifier.js.map +1 -1
- package/dist/workspace/efficacy-toolkit.d.ts +164 -0
- package/dist/workspace/efficacy-toolkit.d.ts.map +1 -0
- package/dist/workspace/efficacy-toolkit.js +281 -0
- package/dist/workspace/efficacy-toolkit.js.map +1 -0
- package/dist/workspace/index.d.ts +2 -1
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/index.js +3 -1
- package/dist/workspace/index.js.map +1 -1
- package/dist/workspace/templates/index.d.ts +3 -0
- package/dist/workspace/templates/index.d.ts.map +1 -1
- package/dist/workspace/templates/index.js +6 -0
- package/dist/workspace/templates/index.js.map +1 -1
- package/dist/workspace/templates/playbook-decay-detection.d.ts +46 -0
- package/dist/workspace/templates/playbook-decay-detection.d.ts.map +1 -0
- package/dist/workspace/templates/playbook-decay-detection.js +197 -0
- package/dist/workspace/templates/playbook-decay-detection.js.map +1 -0
- package/dist/workspace/templates/playbook-efficacy-audit.d.ts +46 -0
- package/dist/workspace/templates/playbook-efficacy-audit.d.ts.map +1 -0
- package/dist/workspace/templates/playbook-efficacy-audit.js +160 -0
- package/dist/workspace/templates/playbook-efficacy-audit.js.map +1 -0
- package/dist/workspace/templates/playbook-lifecycle-review.d.ts +51 -0
- package/dist/workspace/templates/playbook-lifecycle-review.d.ts.map +1 -0
- package/dist/workspace/templates/playbook-lifecycle-review.js +187 -0
- package/dist/workspace/templates/playbook-lifecycle-review.js.map +1 -0
- package/dist/workspace/types.d.ts +12 -54
- package/dist/workspace/types.d.ts.map +1 -1
- package/dist/workspace/types.js.map +1 -1
- package/package.json +8 -2
- package/playbooks/compound-engineering/adversarial-review.json +51 -0
- package/playbooks/compound-engineering/agent-native-architecture.json +59 -0
- package/playbooks/compound-engineering/agent-native-review.json +54 -0
- package/playbooks/compound-engineering/api-contract-review.json +52 -0
- package/playbooks/compound-engineering/brainstorm-requirements.json +55 -0
- package/playbooks/compound-engineering/bug-reproduction.json +62 -0
- package/playbooks/compound-engineering/confidence-calibration.json +49 -0
- package/playbooks/compound-engineering/correctness-review.json +49 -0
- package/playbooks/compound-engineering/data-migration-safety.json +59 -0
- package/playbooks/compound-engineering/deployment-verification.json +63 -0
- package/playbooks/compound-engineering/error-recovery-patterns.json +53 -0
- package/playbooks/compound-engineering/implementation-planning.json +64 -0
- package/playbooks/compound-engineering/issue-pattern-analysis.json +53 -0
- package/playbooks/compound-engineering/knowledge-compounding.json +63 -0
- package/playbooks/compound-engineering/learnings-research.json +54 -0
- package/playbooks/compound-engineering/maintainability-review.json +49 -0
- package/playbooks/compound-engineering/performance-review.json +54 -0
- package/playbooks/compound-engineering/plan-adversarial-review.json +56 -0
- package/playbooks/compound-engineering/plan-feasibility-review.json +56 -0
- package/playbooks/compound-engineering/project-standards-review.json +52 -0
- package/playbooks/compound-engineering/reliability-review.json +53 -0
- package/playbooks/compound-engineering/review-orchestration.json +64 -0
- package/playbooks/compound-engineering/security-review.json +54 -0
- package/playbooks/compound-engineering/systematic-execution.json +64 -0
- package/playbooks/compound-engineering/testing-review.json +50 -0
- package/src/atlas.ts +96 -0
- package/src/index.ts +27 -0
- package/src/learning/index.ts +1 -0
- package/src/learning/unified-pipeline.ts +271 -1
- package/src/memory/candidate-retrieval.ts +2 -1
- package/src/memory/curated-loader.ts +69 -16
- package/src/memory/index.ts +16 -0
- package/src/memory/playbook.ts +19 -0
- package/src/memory/source-resolver.ts +422 -0
- package/src/types/config.ts +46 -0
- package/src/types/index.ts +4 -0
- package/src/utils/error-classifier.ts +8 -8
- package/src/workspace/efficacy-toolkit.ts +496 -0
- package/src/workspace/index.ts +29 -0
- package/src/workspace/templates/index.ts +24 -0
- package/src/workspace/templates/playbook-decay-detection.ts +272 -0
- package/src/workspace/templates/playbook-efficacy-audit.ts +246 -0
- package/src/workspace/templates/playbook-lifecycle-review.ts +274 -0
- package/src/workspace/types.ts +22 -78
- package/tests/fixtures/behavioral-trajectories.ts +210 -0
- package/tests/integration/curated-sources-e2e.test.ts +502 -0
- package/tests/integration/pipeline-data-correctness.test.ts +794 -0
- package/tests/learning/meta-learner.test.ts +418 -0
- package/tests/learning/pipeline-memory-updates.test.ts +721 -0
- package/tests/learning/unified-pipeline-efficacy.test.ts +232 -0
- package/tests/memory/candidate-retrieval.test.ts +167 -0
- package/tests/memory/compound-engineering-seed.test.ts +338 -0
- package/tests/memory/curated-loader-extended.test.ts +225 -0
- package/tests/memory/meta.test.ts +399 -0
- package/tests/memory/playbook-quality-validation.test.ts +430 -0
- package/tests/memory/source-resolver.test.ts +700 -0
- package/tests/search/evaluator.test.ts +257 -0
- package/tests/search/verification-runner.test.ts +357 -0
- package/tests/utils/error-classifier.test.ts +149 -0
- package/tests/utils/trajectory-helpers.test.ts +163 -0
- package/tests/workspace/efficacy-toolkit.test.ts +404 -0
- package/tests/workspace/templates/playbook-efficacy.test.ts +377 -0
- package/.claude/settings.local.json +0 -11
- package/dist/learning/llm-extractor.d.ts +0 -88
- package/dist/learning/llm-extractor.d.ts.map +0 -1
- package/dist/learning/llm-extractor.js +0 -372
- package/dist/learning/llm-extractor.js.map +0 -1
- package/dist/learning/loop-coordinator.d.ts +0 -61
- package/dist/learning/loop-coordinator.d.ts.map +0 -1
- package/dist/learning/loop-coordinator.js +0 -96
- package/dist/learning/loop-coordinator.js.map +0 -1
- package/references/agent-workspace/CLAUDE.md +0 -74
- package/references/agent-workspace/README.md +0 -587
- package/references/agent-workspace/media/banner.png +0 -0
- package/references/agent-workspace/package-lock.json +0 -2061
- package/references/agent-workspace/package.json +0 -54
- package/references/agent-workspace/src/handle.ts +0 -122
- package/references/agent-workspace/src/index.ts +0 -32
- package/references/agent-workspace/src/manager.ts +0 -102
- package/references/agent-workspace/src/readers/json.ts +0 -71
- package/references/agent-workspace/src/readers/markdown.ts +0 -37
- package/references/agent-workspace/src/readers/raw.ts +0 -27
- package/references/agent-workspace/src/types.ts +0 -68
- package/references/agent-workspace/src/validation.ts +0 -93
- package/references/agent-workspace/src/writers/json.ts +0 -17
- package/references/agent-workspace/src/writers/markdown.ts +0 -27
- package/references/agent-workspace/src/writers/raw.ts +0 -22
- package/references/agent-workspace/tests/errors.test.ts +0 -652
- package/references/agent-workspace/tests/handle.test.ts +0 -144
- package/references/agent-workspace/tests/manager.test.ts +0 -124
- package/references/agent-workspace/tests/readers.test.ts +0 -205
- package/references/agent-workspace/tests/validation.test.ts +0 -196
- package/references/agent-workspace/tests/writers.test.ts +0 -108
- package/references/agent-workspace/tsconfig.json +0 -20
- package/references/agent-workspace/tsup.config.ts +0 -9
- package/references/minimem/.claude/settings.json +0 -7
- package/references/minimem/.sudocode/issues.jsonl +0 -18
- package/references/minimem/.sudocode/specs.jsonl +0 -1
- package/references/minimem/CLAUDE.md +0 -310
- package/references/minimem/README.md +0 -556
- package/references/minimem/claude-plugin/.claude-plugin/plugin.json +0 -10
- package/references/minimem/claude-plugin/.mcp.json +0 -7
- package/references/minimem/claude-plugin/README.md +0 -158
- package/references/minimem/claude-plugin/commands/recall.md +0 -47
- package/references/minimem/claude-plugin/commands/remember.md +0 -41
- package/references/minimem/claude-plugin/hooks/__tests__/hooks.test.ts +0 -272
- package/references/minimem/claude-plugin/hooks/hooks.json +0 -27
- package/references/minimem/claude-plugin/hooks/session-end.sh +0 -86
- package/references/minimem/claude-plugin/hooks/session-start.sh +0 -85
- package/references/minimem/claude-plugin/skills/memory/SKILL.md +0 -108
- package/references/minimem/package-lock.json +0 -5373
- package/references/minimem/package.json +0 -60
- package/references/minimem/scripts/postbuild.js +0 -35
- package/references/minimem/src/__tests__/edge-cases.test.ts +0 -371
- package/references/minimem/src/__tests__/errors.test.ts +0 -265
- package/references/minimem/src/__tests__/helpers.ts +0 -199
- package/references/minimem/src/__tests__/internal.test.ts +0 -407
- package/references/minimem/src/__tests__/knowledge.test.ts +0 -287
- package/references/minimem/src/__tests__/minimem.integration.test.ts +0 -1127
- package/references/minimem/src/__tests__/session.test.ts +0 -190
- package/references/minimem/src/cli/__tests__/commands.test.ts +0 -759
- package/references/minimem/src/cli/commands/__tests__/conflicts.test.ts +0 -141
- package/references/minimem/src/cli/commands/append.ts +0 -76
- package/references/minimem/src/cli/commands/config.ts +0 -262
- package/references/minimem/src/cli/commands/conflicts.ts +0 -413
- package/references/minimem/src/cli/commands/daemon.ts +0 -169
- package/references/minimem/src/cli/commands/index.ts +0 -12
- package/references/minimem/src/cli/commands/init.ts +0 -88
- package/references/minimem/src/cli/commands/mcp.ts +0 -177
- package/references/minimem/src/cli/commands/push-pull.ts +0 -213
- package/references/minimem/src/cli/commands/search.ts +0 -158
- package/references/minimem/src/cli/commands/status.ts +0 -84
- package/references/minimem/src/cli/commands/sync-init.ts +0 -290
- package/references/minimem/src/cli/commands/sync.ts +0 -70
- package/references/minimem/src/cli/commands/upsert.ts +0 -197
- package/references/minimem/src/cli/config.ts +0 -584
- package/references/minimem/src/cli/index.ts +0 -264
- package/references/minimem/src/cli/shared.ts +0 -161
- package/references/minimem/src/cli/sync/__tests__/central.test.ts +0 -152
- package/references/minimem/src/cli/sync/__tests__/conflicts.test.ts +0 -209
- package/references/minimem/src/cli/sync/__tests__/daemon.test.ts +0 -118
- package/references/minimem/src/cli/sync/__tests__/detection.test.ts +0 -207
- package/references/minimem/src/cli/sync/__tests__/integration.test.ts +0 -476
- package/references/minimem/src/cli/sync/__tests__/registry.test.ts +0 -363
- package/references/minimem/src/cli/sync/__tests__/state.test.ts +0 -255
- package/references/minimem/src/cli/sync/__tests__/validation.test.ts +0 -193
- package/references/minimem/src/cli/sync/__tests__/watcher.test.ts +0 -178
- package/references/minimem/src/cli/sync/central.ts +0 -292
- package/references/minimem/src/cli/sync/conflicts.ts +0 -204
- package/references/minimem/src/cli/sync/daemon.ts +0 -407
- package/references/minimem/src/cli/sync/detection.ts +0 -138
- package/references/minimem/src/cli/sync/index.ts +0 -107
- package/references/minimem/src/cli/sync/operations.ts +0 -373
- package/references/minimem/src/cli/sync/registry.ts +0 -279
- package/references/minimem/src/cli/sync/state.ts +0 -355
- package/references/minimem/src/cli/sync/validation.ts +0 -206
- package/references/minimem/src/cli/sync/watcher.ts +0 -234
- package/references/minimem/src/cli/version.ts +0 -34
- package/references/minimem/src/core/index.ts +0 -9
- package/references/minimem/src/core/indexer.ts +0 -628
- package/references/minimem/src/core/searcher.ts +0 -221
- package/references/minimem/src/db/schema.ts +0 -183
- package/references/minimem/src/db/sqlite-vec.ts +0 -24
- package/references/minimem/src/embeddings/__tests__/embeddings.test.ts +0 -431
- package/references/minimem/src/embeddings/batch-gemini.ts +0 -392
- package/references/minimem/src/embeddings/batch-openai.ts +0 -409
- package/references/minimem/src/embeddings/embeddings.ts +0 -434
- package/references/minimem/src/index.ts +0 -109
- package/references/minimem/src/internal.ts +0 -299
- package/references/minimem/src/minimem.ts +0 -1276
- package/references/minimem/src/search/__tests__/hybrid.test.ts +0 -247
- package/references/minimem/src/search/graph.ts +0 -234
- package/references/minimem/src/search/hybrid.ts +0 -151
- package/references/minimem/src/search/search.ts +0 -256
- package/references/minimem/src/server/__tests__/mcp.test.ts +0 -341
- package/references/minimem/src/server/__tests__/tools.test.ts +0 -364
- package/references/minimem/src/server/mcp.ts +0 -326
- package/references/minimem/src/server/tools.ts +0 -720
- package/references/minimem/src/session.ts +0 -460
- package/references/minimem/tsconfig.json +0 -19
- package/references/minimem/tsup.config.ts +0 -26
- package/references/minimem/vitest.config.ts +0 -24
- package/references/sessionlog/.husky/pre-commit +0 -1
- package/references/sessionlog/.lintstagedrc.json +0 -4
- package/references/sessionlog/.prettierignore +0 -4
- package/references/sessionlog/.prettierrc.json +0 -11
- package/references/sessionlog/LICENSE +0 -21
- package/references/sessionlog/README.md +0 -453
- package/references/sessionlog/eslint.config.js +0 -58
- package/references/sessionlog/package-lock.json +0 -3672
- package/references/sessionlog/package.json +0 -65
- package/references/sessionlog/src/__tests__/agent-hooks.test.ts +0 -570
- package/references/sessionlog/src/__tests__/agent-registry.test.ts +0 -127
- package/references/sessionlog/src/__tests__/claude-code-hooks.test.ts +0 -225
- package/references/sessionlog/src/__tests__/claude-generator.test.ts +0 -46
- package/references/sessionlog/src/__tests__/commit-msg.test.ts +0 -86
- package/references/sessionlog/src/__tests__/cursor-agent.test.ts +0 -224
- package/references/sessionlog/src/__tests__/e2e-live.test.ts +0 -890
- package/references/sessionlog/src/__tests__/event-log.test.ts +0 -183
- package/references/sessionlog/src/__tests__/flush-sentinel.test.ts +0 -105
- package/references/sessionlog/src/__tests__/gemini-agent.test.ts +0 -375
- package/references/sessionlog/src/__tests__/git-hooks.test.ts +0 -78
- package/references/sessionlog/src/__tests__/hook-managers.test.ts +0 -121
- package/references/sessionlog/src/__tests__/lifecycle-tasks.test.ts +0 -759
- package/references/sessionlog/src/__tests__/opencode-agent.test.ts +0 -338
- package/references/sessionlog/src/__tests__/redaction.test.ts +0 -136
- package/references/sessionlog/src/__tests__/session-repo.test.ts +0 -353
- package/references/sessionlog/src/__tests__/session-store.test.ts +0 -166
- package/references/sessionlog/src/__tests__/setup-ccweb.test.ts +0 -466
- package/references/sessionlog/src/__tests__/skill-live.test.ts +0 -461
- package/references/sessionlog/src/__tests__/summarize.test.ts +0 -348
- package/references/sessionlog/src/__tests__/task-plan-e2e.test.ts +0 -610
- package/references/sessionlog/src/__tests__/task-plan-live.test.ts +0 -632
- package/references/sessionlog/src/__tests__/transcript-timestamp.test.ts +0 -121
- package/references/sessionlog/src/__tests__/types.test.ts +0 -166
- package/references/sessionlog/src/__tests__/utils.test.ts +0 -333
- package/references/sessionlog/src/__tests__/validation.test.ts +0 -103
- package/references/sessionlog/src/__tests__/worktree.test.ts +0 -57
- package/references/sessionlog/src/agent/agents/claude-code.ts +0 -1089
- package/references/sessionlog/src/agent/agents/cursor.ts +0 -361
- package/references/sessionlog/src/agent/agents/gemini-cli.ts +0 -632
- package/references/sessionlog/src/agent/agents/opencode.ts +0 -540
- package/references/sessionlog/src/agent/registry.ts +0 -143
- package/references/sessionlog/src/agent/session-types.ts +0 -113
- package/references/sessionlog/src/agent/types.ts +0 -220
- package/references/sessionlog/src/cli.ts +0 -597
- package/references/sessionlog/src/commands/clean.ts +0 -133
- package/references/sessionlog/src/commands/disable.ts +0 -84
- package/references/sessionlog/src/commands/doctor.ts +0 -145
- package/references/sessionlog/src/commands/enable.ts +0 -202
- package/references/sessionlog/src/commands/explain.ts +0 -261
- package/references/sessionlog/src/commands/reset.ts +0 -105
- package/references/sessionlog/src/commands/resume.ts +0 -180
- package/references/sessionlog/src/commands/rewind.ts +0 -195
- package/references/sessionlog/src/commands/setup-ccweb.ts +0 -275
- package/references/sessionlog/src/commands/status.ts +0 -172
- package/references/sessionlog/src/config.ts +0 -165
- package/references/sessionlog/src/events/event-log.ts +0 -126
- package/references/sessionlog/src/git-operations.ts +0 -558
- package/references/sessionlog/src/hooks/git-hooks.ts +0 -165
- package/references/sessionlog/src/hooks/lifecycle.ts +0 -391
- package/references/sessionlog/src/index.ts +0 -650
- package/references/sessionlog/src/security/redaction.ts +0 -283
- package/references/sessionlog/src/session/state-machine.ts +0 -452
- package/references/sessionlog/src/store/checkpoint-store.ts +0 -509
- package/references/sessionlog/src/store/native-store.ts +0 -173
- package/references/sessionlog/src/store/provider-types.ts +0 -99
- package/references/sessionlog/src/store/session-store.ts +0 -266
- package/references/sessionlog/src/strategy/attribution.ts +0 -296
- package/references/sessionlog/src/strategy/common.ts +0 -207
- package/references/sessionlog/src/strategy/content-overlap.ts +0 -228
- package/references/sessionlog/src/strategy/manual-commit.ts +0 -988
- package/references/sessionlog/src/strategy/types.ts +0 -279
- package/references/sessionlog/src/summarize/claude-generator.ts +0 -115
- package/references/sessionlog/src/summarize/summarize.ts +0 -432
- package/references/sessionlog/src/types.ts +0 -508
- package/references/sessionlog/src/utils/chunk-files.ts +0 -49
- package/references/sessionlog/src/utils/commit-message.ts +0 -65
- package/references/sessionlog/src/utils/detect-agent.ts +0 -36
- package/references/sessionlog/src/utils/hook-managers.ts +0 -125
- package/references/sessionlog/src/utils/ide-tags.ts +0 -32
- package/references/sessionlog/src/utils/paths.ts +0 -79
- package/references/sessionlog/src/utils/preview-rewind.ts +0 -80
- package/references/sessionlog/src/utils/rewind-conflict.ts +0 -121
- package/references/sessionlog/src/utils/shadow-branch.ts +0 -109
- package/references/sessionlog/src/utils/string-utils.ts +0 -46
- package/references/sessionlog/src/utils/todo-extract.ts +0 -188
- package/references/sessionlog/src/utils/trailers.ts +0 -187
- package/references/sessionlog/src/utils/transcript-parse.ts +0 -177
- package/references/sessionlog/src/utils/transcript-timestamp.ts +0 -59
- package/references/sessionlog/src/utils/tree-ops.ts +0 -219
- package/references/sessionlog/src/utils/tty.ts +0 -72
- package/references/sessionlog/src/utils/validation.ts +0 -65
- package/references/sessionlog/src/utils/worktree.ts +0 -58
- package/references/sessionlog/src/wire-types.ts +0 -59
- package/references/sessionlog/templates/setup-env.sh +0 -153
- package/references/sessionlog/tsconfig.json +0 -18
- package/references/sessionlog/vitest.config.ts +0 -12
- package/references/skill-tree/.claude/settings.json +0 -6
- package/references/skill-tree/.sudocode/issues.jsonl +0 -19
- package/references/skill-tree/.sudocode/specs.jsonl +0 -3
- package/references/skill-tree/CLAUDE.md +0 -126
- package/references/skill-tree/README.md +0 -372
- package/references/skill-tree/docs/GAPS_v1.md +0 -221
- package/references/skill-tree/docs/INTEGRATION_PLAN.md +0 -467
- package/references/skill-tree/docs/TODOS.md +0 -91
- package/references/skill-tree/docs/anthropic_skill_guide.md +0 -1364
- package/references/skill-tree/docs/design/federated-skill-trees.md +0 -524
- package/references/skill-tree/docs/design/multi-agent-sync.md +0 -759
- package/references/skill-tree/docs/scraper/BRAINSTORM.md +0 -583
- package/references/skill-tree/docs/scraper/POC_PLAN.md +0 -420
- package/references/skill-tree/docs/scraper/README.md +0 -170
- package/references/skill-tree/examples/basic-usage.ts +0 -164
- package/references/skill-tree/package-lock.json +0 -1852
- package/references/skill-tree/package.json +0 -66
- package/references/skill-tree/scraper/README.md +0 -123
- package/references/skill-tree/scraper/docs/DESIGN.md +0 -683
- package/references/skill-tree/scraper/docs/PLAN.md +0 -336
- package/references/skill-tree/scraper/drizzle.config.ts +0 -10
- package/references/skill-tree/scraper/package-lock.json +0 -6329
- package/references/skill-tree/scraper/package.json +0 -68
- package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-description.md +0 -7
- package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-name.md +0 -7
- package/references/skill-tree/scraper/test/fixtures/minimal-skill/SKILL.md +0 -27
- package/references/skill-tree/scraper/test/fixtures/skill-json/SKILL.json +0 -21
- package/references/skill-tree/scraper/test/fixtures/skill-with-meta/SKILL.md +0 -54
- package/references/skill-tree/scraper/test/fixtures/skill-with-meta/_meta.json +0 -24
- package/references/skill-tree/scraper/test/fixtures/valid-skill/SKILL.md +0 -93
- package/references/skill-tree/scraper/test/fixtures/valid-skill/_meta.json +0 -22
- package/references/skill-tree/scraper/tsup.config.ts +0 -14
- package/references/skill-tree/scraper/vitest.config.ts +0 -17
- package/references/skill-tree/scripts/convert-to-vitest.ts +0 -166
- package/references/skill-tree/skills/skill-writer/SKILL.md +0 -339
- package/references/skill-tree/skills/skill-writer/references/examples.md +0 -326
- package/references/skill-tree/skills/skill-writer/references/patterns.md +0 -210
- package/references/skill-tree/skills/skill-writer/references/quality-checklist.md +0 -123
- package/references/skill-tree/test/run-all.ts +0 -106
- package/references/skill-tree/test/utils.ts +0 -128
- package/references/skill-tree/vitest.config.ts +0 -16
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { PlaybookLibrary, createPlaybookLibrary } from '../../src/memory/playbook.js';
|
|
3
|
+
import { loadCuratedPlaybooks, BUNDLED_SEED_PACK_DIR } from '../../src/memory/curated-loader.js';
|
|
4
|
+
import { createSqlitePersistence } from '../../src/persistence/index.js';
|
|
5
|
+
import { createAtlas } from '../../src/atlas.js';
|
|
6
|
+
import { mkdtemp, rm } from 'node:fs/promises';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { tmpdir } from 'node:os';
|
|
9
|
+
|
|
10
|
+
const SEED_DIR = join(__dirname, '../../playbooks/compound-engineering');
|
|
11
|
+
|
|
12
|
+
describe('Compound Engineering Seed Pack', () => {
|
|
13
|
+
let tempDir: string;
|
|
14
|
+
let library: PlaybookLibrary;
|
|
15
|
+
let persistence: ReturnType<typeof createSqlitePersistence>;
|
|
16
|
+
|
|
17
|
+
beforeEach(async () => {
|
|
18
|
+
tempDir = await mkdtemp(join(tmpdir(), 'atlas-ce-seed-'));
|
|
19
|
+
persistence = createSqlitePersistence({ baseDir: tempDir });
|
|
20
|
+
await persistence.init();
|
|
21
|
+
library = createPlaybookLibrary(persistence);
|
|
22
|
+
await library.init();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
afterEach(async () => {
|
|
26
|
+
await library.close();
|
|
27
|
+
persistence.close();
|
|
28
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should load all seed playbooks without errors', async () => {
|
|
32
|
+
const result = await loadCuratedPlaybooks(SEED_DIR, library);
|
|
33
|
+
|
|
34
|
+
expect(result.errors).toEqual([]);
|
|
35
|
+
expect(result.loaded).toBe(25);
|
|
36
|
+
expect(result.skipped).toBe(0);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should mark all playbooks as curated', async () => {
|
|
40
|
+
await loadCuratedPlaybooks(SEED_DIR, library);
|
|
41
|
+
|
|
42
|
+
const curated = await library.getByOrigin('curated');
|
|
43
|
+
expect(curated).toHaveLength(25);
|
|
44
|
+
for (const p of curated) {
|
|
45
|
+
expect(p.provenance.origin).toBe('curated');
|
|
46
|
+
expect(['compound-engineering', 'cognitive-core']).toContain(p.provenance.curatedBy);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should set higher confidence for curated playbooks (>= 0.7)', async () => {
|
|
51
|
+
await loadCuratedPlaybooks(SEED_DIR, library);
|
|
52
|
+
|
|
53
|
+
const all = await library.getAll();
|
|
54
|
+
for (const p of all) {
|
|
55
|
+
expect(p.confidence).toBeGreaterThanOrEqual(0.7);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should load expected playbook names', async () => {
|
|
60
|
+
await loadCuratedPlaybooks(SEED_DIR, library);
|
|
61
|
+
|
|
62
|
+
const expectedNames = [
|
|
63
|
+
// Original 11
|
|
64
|
+
'review-orchestration',
|
|
65
|
+
'correctness-review',
|
|
66
|
+
'testing-review',
|
|
67
|
+
'maintainability-review',
|
|
68
|
+
'agent-native-review',
|
|
69
|
+
'knowledge-compounding',
|
|
70
|
+
'brainstorm-requirements',
|
|
71
|
+
'implementation-planning',
|
|
72
|
+
'systematic-execution',
|
|
73
|
+
'learnings-research',
|
|
74
|
+
'confidence-calibration',
|
|
75
|
+
// Code review personas
|
|
76
|
+
'security-review',
|
|
77
|
+
'performance-review',
|
|
78
|
+
'reliability-review',
|
|
79
|
+
'adversarial-review',
|
|
80
|
+
'api-contract-review',
|
|
81
|
+
'data-migration-safety',
|
|
82
|
+
'project-standards-review',
|
|
83
|
+
// Plan review
|
|
84
|
+
'plan-adversarial-review',
|
|
85
|
+
'plan-feasibility-review',
|
|
86
|
+
// Workflows
|
|
87
|
+
'bug-reproduction',
|
|
88
|
+
'agent-native-architecture',
|
|
89
|
+
'issue-pattern-analysis',
|
|
90
|
+
'deployment-verification',
|
|
91
|
+
// Cognitive-core native
|
|
92
|
+
'error-recovery-patterns',
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
for (const name of expectedNames) {
|
|
96
|
+
const p = await library.getByName(name);
|
|
97
|
+
expect(p, `missing playbook: ${name}`).toBeDefined();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should cover expected domains', async () => {
|
|
102
|
+
await loadCuratedPlaybooks(SEED_DIR, library);
|
|
103
|
+
|
|
104
|
+
const domains = await library.getDomains();
|
|
105
|
+
expect(domains).toContain('code-review');
|
|
106
|
+
expect(domains).toContain('software-engineering');
|
|
107
|
+
expect(domains).toContain('quality-assurance');
|
|
108
|
+
expect(domains).toContain('planning');
|
|
109
|
+
expect(domains).toContain('knowledge-management');
|
|
110
|
+
expect(domains).toContain('security');
|
|
111
|
+
expect(domains).toContain('performance');
|
|
112
|
+
expect(domains).toContain('reliability');
|
|
113
|
+
expect(domains).toContain('debugging');
|
|
114
|
+
expect(domains).toContain('deployment');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should have non-empty guidance for all playbooks', async () => {
|
|
118
|
+
await loadCuratedPlaybooks(SEED_DIR, library);
|
|
119
|
+
|
|
120
|
+
const all = await library.getAll();
|
|
121
|
+
for (const p of all) {
|
|
122
|
+
expect(p.guidance.strategy.length, `${p.name} has empty strategy`).toBeGreaterThan(0);
|
|
123
|
+
expect(p.guidance.tactics.length, `${p.name} has no tactics`).toBeGreaterThan(0);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('should have verification criteria for all playbooks', async () => {
|
|
128
|
+
await loadCuratedPlaybooks(SEED_DIR, library);
|
|
129
|
+
|
|
130
|
+
const all = await library.getAll();
|
|
131
|
+
for (const p of all) {
|
|
132
|
+
expect(
|
|
133
|
+
p.verification.successIndicators.length,
|
|
134
|
+
`${p.name} has no success indicators`
|
|
135
|
+
).toBeGreaterThan(0);
|
|
136
|
+
expect(
|
|
137
|
+
p.verification.failureIndicators.length,
|
|
138
|
+
`${p.name} has no failure indicators`
|
|
139
|
+
).toBeGreaterThan(0);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('should support recreate workflow for seed updates', async () => {
|
|
144
|
+
// Load initial
|
|
145
|
+
await loadCuratedPlaybooks(SEED_DIR, library);
|
|
146
|
+
expect(await library.count()).toBe(25);
|
|
147
|
+
|
|
148
|
+
// Recreate — simulates updating the seed pack
|
|
149
|
+
const result = await loadCuratedPlaybooks(SEED_DIR, library, { recreate: true });
|
|
150
|
+
expect(result.recreated).toBe(true);
|
|
151
|
+
expect(result.loaded).toBe(25);
|
|
152
|
+
expect(await library.count()).toBe(25);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('should be findable by relevant search queries', async () => {
|
|
156
|
+
await loadCuratedPlaybooks(SEED_DIR, library);
|
|
157
|
+
|
|
158
|
+
const reviewMatches = await library.findMatching('code review before PR');
|
|
159
|
+
expect(reviewMatches.length).toBeGreaterThan(0);
|
|
160
|
+
const reviewNames = reviewMatches.map(m => m.playbook.name);
|
|
161
|
+
expect(reviewNames).toContain('review-orchestration');
|
|
162
|
+
|
|
163
|
+
const planMatches = await library.findMatching('create implementation plan for feature');
|
|
164
|
+
expect(planMatches.length).toBeGreaterThan(0);
|
|
165
|
+
|
|
166
|
+
const knowledgeMatches = await library.findMatching('document solved problem');
|
|
167
|
+
expect(knowledgeMatches.length).toBeGreaterThan(0);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
describe('BUNDLED_SEED_PACK_DIR', () => {
|
|
172
|
+
it('should resolve to a valid directory', () => {
|
|
173
|
+
const { existsSync } = require('node:fs');
|
|
174
|
+
expect(existsSync(BUNDLED_SEED_PACK_DIR)).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('should match the manual SEED_DIR path', () => {
|
|
178
|
+
// Both should point to the same playbooks directory
|
|
179
|
+
const { realpathSync } = require('node:fs');
|
|
180
|
+
expect(realpathSync(BUNDLED_SEED_PACK_DIR)).toBe(realpathSync(SEED_DIR));
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
describe('Atlas.init() with loadBundledSeedPack', () => {
|
|
185
|
+
let tempDir: string;
|
|
186
|
+
|
|
187
|
+
beforeEach(async () => {
|
|
188
|
+
tempDir = await mkdtemp(join(tmpdir(), 'atlas-init-seed-'));
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
afterEach(async () => {
|
|
192
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('should not load seed pack by default', async () => {
|
|
196
|
+
const atlas = createAtlas({ storage: { baseDir: tempDir } });
|
|
197
|
+
await atlas.init();
|
|
198
|
+
|
|
199
|
+
const memory = atlas.getMemory();
|
|
200
|
+
const count = await memory.playbooks.count();
|
|
201
|
+
expect(count).toBe(0);
|
|
202
|
+
|
|
203
|
+
await atlas.close();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('should load seed pack when loadBundledSeedPack is true', async () => {
|
|
207
|
+
const atlas = createAtlas({
|
|
208
|
+
storage: { baseDir: tempDir },
|
|
209
|
+
curatedPlaybooks: { loadBundledSeedPack: true },
|
|
210
|
+
});
|
|
211
|
+
await atlas.init();
|
|
212
|
+
|
|
213
|
+
const memory = atlas.getMemory();
|
|
214
|
+
const count = await memory.playbooks.count();
|
|
215
|
+
expect(count).toBe(25);
|
|
216
|
+
|
|
217
|
+
// Verify they're curated
|
|
218
|
+
const curated = await memory.playbooks.getByOrigin('curated');
|
|
219
|
+
expect(curated).toHaveLength(25);
|
|
220
|
+
|
|
221
|
+
await atlas.close();
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('should skip already-loaded seed pack on second init', async () => {
|
|
225
|
+
const config = {
|
|
226
|
+
storage: { baseDir: tempDir },
|
|
227
|
+
curatedPlaybooks: { loadBundledSeedPack: true },
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// First init
|
|
231
|
+
const atlas1 = createAtlas(config);
|
|
232
|
+
await atlas1.init();
|
|
233
|
+
expect(await atlas1.getMemory().playbooks.count()).toBe(25);
|
|
234
|
+
await atlas1.close();
|
|
235
|
+
|
|
236
|
+
// Second init — should skip (already loaded by name)
|
|
237
|
+
const atlas2 = createAtlas(config);
|
|
238
|
+
await atlas2.init();
|
|
239
|
+
expect(await atlas2.getMemory().playbooks.count()).toBe(25);
|
|
240
|
+
await atlas2.close();
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('should load from additional directories', async () => {
|
|
244
|
+
const customDir = join(tempDir, 'custom-playbooks');
|
|
245
|
+
const { mkdirSync, writeFileSync } = require('node:fs');
|
|
246
|
+
mkdirSync(customDir, { recursive: true });
|
|
247
|
+
writeFileSync(join(customDir, 'custom.json'), JSON.stringify({
|
|
248
|
+
name: 'custom-playbook',
|
|
249
|
+
applicability: { situations: ['Custom situation'], domains: ['custom'] },
|
|
250
|
+
guidance: { strategy: 'Custom strategy', tactics: ['Custom tactic'] },
|
|
251
|
+
}));
|
|
252
|
+
|
|
253
|
+
const atlas = createAtlas({
|
|
254
|
+
storage: { baseDir: tempDir },
|
|
255
|
+
curatedPlaybooks: {
|
|
256
|
+
loadBundledSeedPack: true,
|
|
257
|
+
additionalDirs: [customDir],
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
await atlas.init();
|
|
261
|
+
|
|
262
|
+
const count = await atlas.getMemory().playbooks.count();
|
|
263
|
+
expect(count).toBe(26); // 25 bundled + 1 custom
|
|
264
|
+
|
|
265
|
+
const custom = await atlas.getMemory().playbooks.getByName('custom-playbook');
|
|
266
|
+
expect(custom).toBeDefined();
|
|
267
|
+
|
|
268
|
+
await atlas.close();
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('should support recreateOnInit for seed updates', async () => {
|
|
272
|
+
const config = {
|
|
273
|
+
storage: { baseDir: tempDir },
|
|
274
|
+
curatedPlaybooks: { loadBundledSeedPack: true, recreateOnInit: true },
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// First init
|
|
278
|
+
const atlas1 = createAtlas(config);
|
|
279
|
+
await atlas1.init();
|
|
280
|
+
expect(await atlas1.getMemory().playbooks.count()).toBe(25);
|
|
281
|
+
await atlas1.close();
|
|
282
|
+
|
|
283
|
+
// Second init with recreate — should reload all
|
|
284
|
+
const atlas2 = createAtlas(config);
|
|
285
|
+
await atlas2.init();
|
|
286
|
+
expect(await atlas2.getMemory().playbooks.count()).toBe(25);
|
|
287
|
+
await atlas2.close();
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
it('should load from sources (local path)', async () => {
|
|
291
|
+
// Create a local source directory with playbooks
|
|
292
|
+
const sourceDir = join(tempDir, 'my-source', 'playbooks');
|
|
293
|
+
const { mkdirSync, writeFileSync } = require('node:fs');
|
|
294
|
+
mkdirSync(sourceDir, { recursive: true });
|
|
295
|
+
writeFileSync(join(sourceDir, 'src-pb.json'), JSON.stringify({
|
|
296
|
+
name: 'source-playbook',
|
|
297
|
+
applicability: { situations: ['Source test'], domains: ['testing'] },
|
|
298
|
+
guidance: { strategy: 'Source strategy', tactics: ['Source tactic'] },
|
|
299
|
+
confidence: 0.9,
|
|
300
|
+
}));
|
|
301
|
+
|
|
302
|
+
const atlas = createAtlas({
|
|
303
|
+
storage: { baseDir: tempDir },
|
|
304
|
+
curatedPlaybooks: {
|
|
305
|
+
// Use the parent dir as source — discoverPlaybookDir should find playbooks/
|
|
306
|
+
sources: [sourceDir],
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
await atlas.init();
|
|
310
|
+
|
|
311
|
+
// Local sources are loaded directly (not via git resolver)
|
|
312
|
+
// But the sources flow resolves them as local paths first.
|
|
313
|
+
// Since sourceDir exists and is local, it will be loaded.
|
|
314
|
+
const count = await atlas.getMemory().playbooks.count();
|
|
315
|
+
expect(count).toBe(1);
|
|
316
|
+
|
|
317
|
+
const pb = await atlas.getMemory().playbooks.getByName('source-playbook');
|
|
318
|
+
expect(pb).toBeDefined();
|
|
319
|
+
expect(pb!.provenance?.origin).toBe('curated');
|
|
320
|
+
|
|
321
|
+
await atlas.close();
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('should accept new config shape with cache settings', () => {
|
|
325
|
+
// Verify the config schema accepts the new fields without error
|
|
326
|
+
const atlas = createAtlas({
|
|
327
|
+
storage: { baseDir: tempDir },
|
|
328
|
+
curatedPlaybooks: {
|
|
329
|
+
loadBundledSeedPack: false,
|
|
330
|
+
sources: ['github:org/repo#v1.0.0', '/local/path'],
|
|
331
|
+
cache: { dir: 'my-cache', maxAgeMs: 3600_000 },
|
|
332
|
+
recreateOnInit: false,
|
|
333
|
+
},
|
|
334
|
+
});
|
|
335
|
+
// No init — just verify config was accepted
|
|
336
|
+
expect(atlas).toBeDefined();
|
|
337
|
+
});
|
|
338
|
+
});
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { PlaybookLibrary, createPlaybookLibrary } from '../../src/memory/playbook.js';
|
|
3
|
+
import { loadCuratedPlaybooks } from '../../src/memory/curated-loader.js';
|
|
4
|
+
import { createSqlitePersistence } from '../../src/persistence/index.js';
|
|
5
|
+
import { mkdtemp, rm, mkdir, writeFile } from 'node:fs/promises';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import { tmpdir } from 'node:os';
|
|
8
|
+
|
|
9
|
+
function makePlaybookJson(name: string, domain: string, curatedBy?: string) {
|
|
10
|
+
return JSON.stringify({
|
|
11
|
+
name,
|
|
12
|
+
applicability: {
|
|
13
|
+
situations: [`${name} situation`],
|
|
14
|
+
triggers: [`${name} trigger`],
|
|
15
|
+
domains: [domain],
|
|
16
|
+
},
|
|
17
|
+
guidance: {
|
|
18
|
+
strategy: `${name} strategy`,
|
|
19
|
+
tactics: [`${name} tactic 1`, `${name} tactic 2`],
|
|
20
|
+
},
|
|
21
|
+
verification: {
|
|
22
|
+
successIndicators: ['Indicator'],
|
|
23
|
+
failureIndicators: ['Bad indicator'],
|
|
24
|
+
},
|
|
25
|
+
confidence: 0.8,
|
|
26
|
+
curatedBy: curatedBy ?? 'test',
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
describe('Recursive curated loading', () => {
|
|
31
|
+
let tempDir: string;
|
|
32
|
+
let library: PlaybookLibrary;
|
|
33
|
+
let persistence: ReturnType<typeof createSqlitePersistence>;
|
|
34
|
+
|
|
35
|
+
beforeEach(async () => {
|
|
36
|
+
tempDir = await mkdtemp(join(tmpdir(), 'curated-recursive-'));
|
|
37
|
+
persistence = createSqlitePersistence({ baseDir: tempDir });
|
|
38
|
+
await persistence.init();
|
|
39
|
+
library = createPlaybookLibrary(persistence);
|
|
40
|
+
await library.init();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
afterEach(async () => {
|
|
44
|
+
await library.close();
|
|
45
|
+
persistence.close();
|
|
46
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should load playbooks from nested subdirectories', async () => {
|
|
50
|
+
const sourceDir = join(tempDir, 'playbooks');
|
|
51
|
+
const subDir = join(sourceDir, 'code-review');
|
|
52
|
+
const deepDir = join(sourceDir, 'planning', 'deep');
|
|
53
|
+
await mkdir(subDir, { recursive: true });
|
|
54
|
+
await mkdir(deepDir, { recursive: true });
|
|
55
|
+
|
|
56
|
+
await writeFile(join(sourceDir, 'root.json'), makePlaybookJson('root-pb', 'general'));
|
|
57
|
+
await writeFile(join(subDir, 'review.json'), makePlaybookJson('review-pb', 'code-review'));
|
|
58
|
+
await writeFile(join(deepDir, 'plan.json'), makePlaybookJson('plan-pb', 'planning'));
|
|
59
|
+
|
|
60
|
+
const result = await loadCuratedPlaybooks(sourceDir, library);
|
|
61
|
+
|
|
62
|
+
expect(result.loaded).toBe(3);
|
|
63
|
+
expect(result.errors).toEqual([]);
|
|
64
|
+
|
|
65
|
+
expect(await library.getByName('root-pb')).toBeDefined();
|
|
66
|
+
expect(await library.getByName('review-pb')).toBeDefined();
|
|
67
|
+
expect(await library.getByName('plan-pb')).toBeDefined();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should skip non-json files in subdirectories', async () => {
|
|
71
|
+
const sourceDir = join(tempDir, 'playbooks');
|
|
72
|
+
await mkdir(sourceDir);
|
|
73
|
+
|
|
74
|
+
await writeFile(join(sourceDir, 'valid.json'), makePlaybookJson('valid-pb', 'general'));
|
|
75
|
+
await writeFile(join(sourceDir, 'readme.md'), '# Not a playbook');
|
|
76
|
+
await writeFile(join(sourceDir, 'data.txt'), 'some text');
|
|
77
|
+
|
|
78
|
+
const result = await loadCuratedPlaybooks(sourceDir, library);
|
|
79
|
+
expect(result.loaded).toBe(1);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('Source-aware recreate (deleteByCuratedSource)', () => {
|
|
84
|
+
let tempDir: string;
|
|
85
|
+
let library: PlaybookLibrary;
|
|
86
|
+
let persistence: ReturnType<typeof createSqlitePersistence>;
|
|
87
|
+
|
|
88
|
+
beforeEach(async () => {
|
|
89
|
+
tempDir = await mkdtemp(join(tmpdir(), 'curated-source-'));
|
|
90
|
+
persistence = createSqlitePersistence({ baseDir: tempDir });
|
|
91
|
+
await persistence.init();
|
|
92
|
+
library = createPlaybookLibrary(persistence);
|
|
93
|
+
await library.init();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
afterEach(async () => {
|
|
97
|
+
await library.close();
|
|
98
|
+
persistence.close();
|
|
99
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should track source in provenance.sourceFile', async () => {
|
|
103
|
+
const sourceDir = join(tempDir, 'source-a');
|
|
104
|
+
await mkdir(sourceDir);
|
|
105
|
+
await writeFile(join(sourceDir, 'a.json'), makePlaybookJson('pb-a', 'general'));
|
|
106
|
+
|
|
107
|
+
await loadCuratedPlaybooks(sourceDir, library, {
|
|
108
|
+
sourceId: 'github:org/repo-a',
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const pb = await library.getByName('pb-a');
|
|
112
|
+
expect(pb).toBeDefined();
|
|
113
|
+
expect(pb!.provenance?.sourceFile).toMatch(/^github:org\/repo-a:/);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should delete only playbooks from a specific source on recreate', async () => {
|
|
117
|
+
const sourceA = join(tempDir, 'source-a');
|
|
118
|
+
const sourceB = join(tempDir, 'source-b');
|
|
119
|
+
await mkdir(sourceA);
|
|
120
|
+
await mkdir(sourceB);
|
|
121
|
+
|
|
122
|
+
await writeFile(join(sourceA, 'a.json'), makePlaybookJson('pb-a', 'general'));
|
|
123
|
+
await writeFile(join(sourceB, 'b.json'), makePlaybookJson('pb-b', 'general'));
|
|
124
|
+
|
|
125
|
+
// Load from both sources
|
|
126
|
+
await loadCuratedPlaybooks(sourceA, library, { sourceId: 'source-a' });
|
|
127
|
+
await loadCuratedPlaybooks(sourceB, library, { sourceId: 'source-b' });
|
|
128
|
+
expect(await library.count()).toBe(2);
|
|
129
|
+
|
|
130
|
+
// Recreate only source-a
|
|
131
|
+
await loadCuratedPlaybooks(sourceA, library, {
|
|
132
|
+
sourceId: 'source-a',
|
|
133
|
+
recreate: true,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// source-b's playbook should still exist
|
|
137
|
+
expect(await library.count()).toBe(2);
|
|
138
|
+
expect(await library.getByName('pb-a')).toBeDefined();
|
|
139
|
+
expect(await library.getByName('pb-b')).toBeDefined();
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('should delete all curated when no sourceId on recreate', async () => {
|
|
143
|
+
const sourceA = join(tempDir, 'source-a');
|
|
144
|
+
const sourceB = join(tempDir, 'source-b');
|
|
145
|
+
await mkdir(sourceA);
|
|
146
|
+
await mkdir(sourceB);
|
|
147
|
+
|
|
148
|
+
await writeFile(join(sourceA, 'a.json'), makePlaybookJson('pb-a', 'general'));
|
|
149
|
+
await writeFile(join(sourceB, 'b.json'), makePlaybookJson('pb-b', 'general'));
|
|
150
|
+
|
|
151
|
+
await loadCuratedPlaybooks(sourceA, library, { sourceId: 'source-a' });
|
|
152
|
+
await loadCuratedPlaybooks(sourceB, library, { sourceId: 'source-b' });
|
|
153
|
+
expect(await library.count()).toBe(2);
|
|
154
|
+
|
|
155
|
+
// Recreate without sourceId — deletes all curated, then reloads source-a
|
|
156
|
+
await loadCuratedPlaybooks(sourceA, library, { recreate: true });
|
|
157
|
+
|
|
158
|
+
// Only source-a playbooks remain
|
|
159
|
+
expect(await library.count()).toBe(1);
|
|
160
|
+
expect(await library.getByName('pb-a')).toBeDefined();
|
|
161
|
+
expect(await library.getByName('pb-b')).toBeUndefined();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should handle malformed JSON gracefully and continue loading others', async () => {
|
|
165
|
+
const sourceDir = join(tempDir, 'source-mixed');
|
|
166
|
+
await mkdir(sourceDir);
|
|
167
|
+
|
|
168
|
+
await writeFile(join(sourceDir, 'good.json'), makePlaybookJson('good-pb', 'general'));
|
|
169
|
+
await writeFile(join(sourceDir, 'bad.json'), '{ this is not valid json !!!');
|
|
170
|
+
await writeFile(join(sourceDir, 'also-good.json'), makePlaybookJson('also-good-pb', 'general'));
|
|
171
|
+
|
|
172
|
+
const result = await loadCuratedPlaybooks(sourceDir, library);
|
|
173
|
+
|
|
174
|
+
expect(result.loaded).toBe(2);
|
|
175
|
+
expect(result.errors.length).toBe(1);
|
|
176
|
+
expect(result.errors[0].file).toBe('bad.json');
|
|
177
|
+
expect(result.errors[0].error).toContain('JSON');
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should report error for JSON missing required fields', async () => {
|
|
181
|
+
const sourceDir = join(tempDir, 'source-invalid');
|
|
182
|
+
await mkdir(sourceDir);
|
|
183
|
+
|
|
184
|
+
// Valid JSON but missing required playbook fields
|
|
185
|
+
await writeFile(
|
|
186
|
+
join(sourceDir, 'incomplete.json'),
|
|
187
|
+
JSON.stringify({ name: 'only-name' }),
|
|
188
|
+
);
|
|
189
|
+
await writeFile(join(sourceDir, 'good.json'), makePlaybookJson('good-pb', 'general'));
|
|
190
|
+
|
|
191
|
+
const result = await loadCuratedPlaybooks(sourceDir, library);
|
|
192
|
+
|
|
193
|
+
expect(result.loaded).toBe(1);
|
|
194
|
+
expect(result.errors.length).toBe(1);
|
|
195
|
+
expect(result.errors[0].error).toContain('Missing required fields');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('should return empty result for non-existent directory', async () => {
|
|
199
|
+
const result = await loadCuratedPlaybooks('/nonexistent/dir', library);
|
|
200
|
+
expect(result.loaded).toBe(0);
|
|
201
|
+
expect(result.skipped).toBe(0);
|
|
202
|
+
expect(result.errors).toEqual([]);
|
|
203
|
+
expect(result.recreated).toBe(false);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('deleteByCuratedSource should only affect matching prefix', async () => {
|
|
207
|
+
const sourceDir = join(tempDir, 'source');
|
|
208
|
+
await mkdir(sourceDir);
|
|
209
|
+
await writeFile(join(sourceDir, 'x.json'), makePlaybookJson('pb-x', 'general'));
|
|
210
|
+
await writeFile(join(sourceDir, 'y.json'), makePlaybookJson('pb-y', 'general'));
|
|
211
|
+
|
|
212
|
+
await loadCuratedPlaybooks(sourceDir, library, { sourceId: 'github:org/repo' });
|
|
213
|
+
expect(await library.count()).toBe(2);
|
|
214
|
+
|
|
215
|
+
// Delete by a non-matching prefix
|
|
216
|
+
const deleted = await library.deleteByCuratedSource('github:other/repo');
|
|
217
|
+
expect(deleted).toBe(0);
|
|
218
|
+
expect(await library.count()).toBe(2);
|
|
219
|
+
|
|
220
|
+
// Delete by matching prefix
|
|
221
|
+
const deleted2 = await library.deleteByCuratedSource('github:org/repo');
|
|
222
|
+
expect(deleted2).toBe(2);
|
|
223
|
+
expect(await library.count()).toBe(0);
|
|
224
|
+
});
|
|
225
|
+
});
|