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
|
@@ -1,890 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Comprehensive E2E Live Tests for Sessionlog
|
|
3
|
-
*
|
|
4
|
-
* Tests the full sessionlog lifecycle with real Claude Code sessions:
|
|
5
|
-
* session creation, file tracking, commit handling, status reporting,
|
|
6
|
-
* doctor/clean, token usage, and checkpoint verification via CLI binary.
|
|
7
|
-
*
|
|
8
|
-
* Note on checkpoints: In single-turn `-p` mode, Claude creates files and
|
|
9
|
-
* commits within one turn. The checkpoint trailer requires a shadow branch
|
|
10
|
-
* (created during saveStep/TurnEnd), which doesn't exist yet when
|
|
11
|
-
* prepare-commit-msg fires within the same turn. Checkpoint verification
|
|
12
|
-
* is therefore tested deterministically via CLI binary piping (Suite 7).
|
|
13
|
-
*
|
|
14
|
-
* Gated behind LIVE_AGENT=1 environment variable:
|
|
15
|
-
* LIVE_AGENT=1 npx vitest run src/__tests__/e2e-live.test.ts
|
|
16
|
-
*
|
|
17
|
-
* Prerequisites:
|
|
18
|
-
* - `claude` CLI installed and authenticated (Claude Max or API key)
|
|
19
|
-
* - `npm run build` has been run (dist/ exists)
|
|
20
|
-
* - `npm link` has been run (sessionlog available in PATH)
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
import { describe, it, expect, beforeAll, beforeEach, afterEach } from 'vitest';
|
|
24
|
-
import * as fs from 'node:fs';
|
|
25
|
-
import * as path from 'node:path';
|
|
26
|
-
import * as os from 'node:os';
|
|
27
|
-
import { execFileSync, execSync } from 'node:child_process';
|
|
28
|
-
|
|
29
|
-
const LIVE = process.env.LIVE_AGENT === '1';
|
|
30
|
-
const HOOK_WAIT_MS = 2000;
|
|
31
|
-
|
|
32
|
-
// ============================================================================
|
|
33
|
-
// Helpers
|
|
34
|
-
// ============================================================================
|
|
35
|
-
|
|
36
|
-
function initRepo(dir: string): void {
|
|
37
|
-
execFileSync('git', ['init'], { cwd: dir, stdio: 'pipe' });
|
|
38
|
-
execFileSync('git', ['config', 'user.email', 'test@test.com'], { cwd: dir, stdio: 'pipe' });
|
|
39
|
-
execFileSync('git', ['config', 'user.name', 'Test'], { cwd: dir, stdio: 'pipe' });
|
|
40
|
-
fs.writeFileSync(path.join(dir, 'README.md'), '# Test Project\n\nA simple test project.');
|
|
41
|
-
execFileSync('git', ['add', '.'], { cwd: dir, stdio: 'pipe' });
|
|
42
|
-
execFileSync('git', ['commit', '-m', 'initial commit'], { cwd: dir, stdio: 'pipe' });
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function enableSessionlog(dir: string): void {
|
|
46
|
-
execFileSync('sessionlog', ['enable', '--force', '--agent', 'claude-code'], {
|
|
47
|
-
cwd: dir,
|
|
48
|
-
stdio: 'pipe',
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Read all session state files from .git/sessionlog-sessions/.
|
|
54
|
-
*/
|
|
55
|
-
function readSessionStates(dir: string): Record<string, unknown>[] {
|
|
56
|
-
const sessionsDir = path.join(dir, '.git', 'sessionlog-sessions');
|
|
57
|
-
if (!fs.existsSync(sessionsDir)) return [];
|
|
58
|
-
|
|
59
|
-
return fs
|
|
60
|
-
.readdirSync(sessionsDir)
|
|
61
|
-
.filter((f) => f.endsWith('.json'))
|
|
62
|
-
.map((f) => {
|
|
63
|
-
try {
|
|
64
|
-
return JSON.parse(fs.readFileSync(path.join(sessionsDir, f), 'utf-8'));
|
|
65
|
-
} catch {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
})
|
|
69
|
-
.filter(Boolean) as Record<string, unknown>[];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Run claude in print mode with the given prompt.
|
|
74
|
-
*/
|
|
75
|
-
function runClaude(
|
|
76
|
-
dir: string,
|
|
77
|
-
prompt: string,
|
|
78
|
-
opts?: {
|
|
79
|
-
allowedTools?: string[];
|
|
80
|
-
systemPrompt?: string;
|
|
81
|
-
timeoutMs?: number;
|
|
82
|
-
model?: string;
|
|
83
|
-
},
|
|
84
|
-
): string {
|
|
85
|
-
const args = ['-p', '--dangerously-skip-permissions'];
|
|
86
|
-
|
|
87
|
-
if (opts?.model) {
|
|
88
|
-
args.push('--model', opts.model);
|
|
89
|
-
} else {
|
|
90
|
-
args.push('--model', 'sonnet');
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (opts?.allowedTools?.length) {
|
|
94
|
-
args.push('--allowedTools', opts.allowedTools.join(','));
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (opts?.systemPrompt) {
|
|
98
|
-
args.push('--system-prompt', opts.systemPrompt);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
args.push('--', prompt);
|
|
102
|
-
|
|
103
|
-
const cmd = ['claude', ...args].map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(' ');
|
|
104
|
-
|
|
105
|
-
const result = execSync(cmd, {
|
|
106
|
-
cwd: dir,
|
|
107
|
-
timeout: opts?.timeoutMs ?? 120_000,
|
|
108
|
-
encoding: 'utf-8',
|
|
109
|
-
env: {
|
|
110
|
-
...process.env,
|
|
111
|
-
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
return result;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Run a sessionlog CLI command and return stdout.
|
|
120
|
-
*/
|
|
121
|
-
function runSessionlog(dir: string, args: string[], timeoutMs = 30_000): string {
|
|
122
|
-
return execSync(`sessionlog ${args.join(' ')}`, {
|
|
123
|
-
cwd: dir,
|
|
124
|
-
timeout: timeoutMs,
|
|
125
|
-
encoding: 'utf-8',
|
|
126
|
-
env: { ...process.env },
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Parse sessionlog status --json output.
|
|
132
|
-
*/
|
|
133
|
-
function getStatus(dir: string): Record<string, unknown> {
|
|
134
|
-
const output = runSessionlog(dir, ['status', '--json']);
|
|
135
|
-
return JSON.parse(output);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Get the last commit message (full body with trailers).
|
|
140
|
-
*/
|
|
141
|
-
function getLastCommitMessage(dir: string): string {
|
|
142
|
-
return execFileSync('git', ['log', '-1', '--format=%B'], {
|
|
143
|
-
cwd: dir,
|
|
144
|
-
encoding: 'utf-8',
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Count commits on current branch.
|
|
150
|
-
*/
|
|
151
|
-
function getCommitCount(dir: string): number {
|
|
152
|
-
const output = execFileSync('git', ['rev-list', '--count', 'HEAD'], {
|
|
153
|
-
cwd: dir,
|
|
154
|
-
encoding: 'utf-8',
|
|
155
|
-
});
|
|
156
|
-
return parseInt(output.trim(), 10);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* List git branches matching a pattern.
|
|
161
|
-
*/
|
|
162
|
-
function listGitBranches(dir: string, pattern?: string): string[] {
|
|
163
|
-
const args = ['branch', '--list'];
|
|
164
|
-
if (pattern) args.push(pattern);
|
|
165
|
-
const output = execFileSync('git', args, { cwd: dir, encoding: 'utf-8' });
|
|
166
|
-
return output
|
|
167
|
-
.trim()
|
|
168
|
-
.split('\n')
|
|
169
|
-
.map((b) => b.replace('* ', '').trim())
|
|
170
|
-
.filter(Boolean);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Get HEAD commit SHA.
|
|
175
|
-
*/
|
|
176
|
-
function getHead(dir: string): string {
|
|
177
|
-
return execFileSync('git', ['rev-parse', 'HEAD'], {
|
|
178
|
-
cwd: dir,
|
|
179
|
-
encoding: 'utf-8',
|
|
180
|
-
}).trim();
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// ============================================================================
|
|
184
|
-
// Tests
|
|
185
|
-
// ============================================================================
|
|
186
|
-
|
|
187
|
-
describe.skipIf(!LIVE)('Live E2E — Core Sessionlog', () => {
|
|
188
|
-
let tmpDir: string;
|
|
189
|
-
|
|
190
|
-
beforeAll(() => {
|
|
191
|
-
// Verify prerequisites
|
|
192
|
-
try {
|
|
193
|
-
execFileSync('which', ['sessionlog'], { stdio: 'pipe' });
|
|
194
|
-
} catch {
|
|
195
|
-
throw new Error('sessionlog not found in PATH. Run: npm run build && npm link');
|
|
196
|
-
}
|
|
197
|
-
try {
|
|
198
|
-
execFileSync('which', ['claude'], { stdio: 'pipe' });
|
|
199
|
-
} catch {
|
|
200
|
-
throw new Error('claude CLI not found in PATH');
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
beforeEach(() => {
|
|
205
|
-
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'sessionlog-live-e2e-'));
|
|
206
|
-
initRepo(tmpDir);
|
|
207
|
-
enableSessionlog(tmpDir);
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
afterEach(() => {
|
|
211
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
// ==========================================================================
|
|
215
|
-
// Suite 1: Session Lifecycle
|
|
216
|
-
// ==========================================================================
|
|
217
|
-
|
|
218
|
-
describe('Session Lifecycle', () => {
|
|
219
|
-
it('should create session state when Claude edits a file', async () => {
|
|
220
|
-
const output = runClaude(
|
|
221
|
-
tmpDir,
|
|
222
|
-
'Create a file called src/hello.ts with this exact content: export function hello() { return "Hello"; }',
|
|
223
|
-
{
|
|
224
|
-
allowedTools: ['Write'],
|
|
225
|
-
systemPrompt: 'Create only the requested file. Do not run any other commands.',
|
|
226
|
-
timeoutMs: 120_000,
|
|
227
|
-
},
|
|
228
|
-
);
|
|
229
|
-
|
|
230
|
-
console.log('Claude output:', output.slice(0, 500));
|
|
231
|
-
|
|
232
|
-
await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
|
|
233
|
-
|
|
234
|
-
// Verify file was created
|
|
235
|
-
const srcDir = path.join(tmpDir, 'src');
|
|
236
|
-
const fileCreated =
|
|
237
|
-
fs.existsSync(path.join(srcDir, 'hello.ts')) ||
|
|
238
|
-
fs.existsSync(path.join(tmpDir, 'hello.ts'));
|
|
239
|
-
console.log('File created:', fileCreated);
|
|
240
|
-
|
|
241
|
-
// Verify session state
|
|
242
|
-
const sessions = readSessionStates(tmpDir);
|
|
243
|
-
console.log('Sessions found:', sessions.length);
|
|
244
|
-
|
|
245
|
-
expect(sessions.length).toBeGreaterThan(0);
|
|
246
|
-
|
|
247
|
-
const session = sessions[0];
|
|
248
|
-
expect(session.agentType).toBe('Claude Code');
|
|
249
|
-
expect(session.startedAt).toBeDefined();
|
|
250
|
-
expect(typeof session.startedAt).toBe('string');
|
|
251
|
-
expect(session.baseCommit).toBeDefined();
|
|
252
|
-
expect(typeof session.baseCommit).toBe('string');
|
|
253
|
-
expect((session.baseCommit as string).length).toBe(40);
|
|
254
|
-
}, 180_000);
|
|
255
|
-
|
|
256
|
-
it('should track files and commit when Claude creates and commits', async () => {
|
|
257
|
-
const initialHead = getHead(tmpDir);
|
|
258
|
-
|
|
259
|
-
const output = runClaude(
|
|
260
|
-
tmpDir,
|
|
261
|
-
[
|
|
262
|
-
'Do these two steps exactly:',
|
|
263
|
-
'1. Create a file at src/greet.ts with content: export const greet = (n: string) => "Hi " + n;',
|
|
264
|
-
'2. Then run these exact shell commands: git add src/greet.ts && git commit -m "feat: add greet function"',
|
|
265
|
-
].join('\n'),
|
|
266
|
-
{
|
|
267
|
-
allowedTools: ['Write', 'Bash'],
|
|
268
|
-
systemPrompt:
|
|
269
|
-
'Create the file and commit it using the exact commands specified. Do not do anything else.',
|
|
270
|
-
timeoutMs: 120_000,
|
|
271
|
-
},
|
|
272
|
-
);
|
|
273
|
-
|
|
274
|
-
console.log('Claude output:', output.slice(0, 500));
|
|
275
|
-
|
|
276
|
-
await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
|
|
277
|
-
|
|
278
|
-
// Verify file exists
|
|
279
|
-
const fileExists = fs.existsSync(path.join(tmpDir, 'src', 'greet.ts'));
|
|
280
|
-
console.log('File exists:', fileExists);
|
|
281
|
-
expect(fileExists).toBe(true);
|
|
282
|
-
|
|
283
|
-
// Verify a new commit was made
|
|
284
|
-
const commitCount = getCommitCount(tmpDir);
|
|
285
|
-
console.log('Commit count:', commitCount);
|
|
286
|
-
expect(commitCount).toBeGreaterThan(1);
|
|
287
|
-
|
|
288
|
-
// Verify HEAD changed
|
|
289
|
-
const newHead = getHead(tmpDir);
|
|
290
|
-
console.log('HEAD changed:', initialHead !== newHead);
|
|
291
|
-
expect(newHead).not.toBe(initialHead);
|
|
292
|
-
|
|
293
|
-
// Check commit message for checkpoint trailer (informational only).
|
|
294
|
-
// In single-turn -p mode, the shadow branch doesn't exist yet when
|
|
295
|
-
// prepare-commit-msg fires, so the trailer won't be injected.
|
|
296
|
-
// Checkpoint creation is tested deterministically in Suite 7 via CLI piping.
|
|
297
|
-
const commitMsg = getLastCommitMessage(tmpDir);
|
|
298
|
-
console.log('Commit message:', commitMsg.trim());
|
|
299
|
-
const hasCheckpointTrailer = /Sessionlog-Checkpoint:\s*[0-9a-f]{12}/.test(commitMsg);
|
|
300
|
-
console.log('Has checkpoint trailer:', hasCheckpointTrailer);
|
|
301
|
-
|
|
302
|
-
// Check for sessionlog branches (informational)
|
|
303
|
-
const checkpointBranches = listGitBranches(tmpDir, 'sessionlog/*');
|
|
304
|
-
console.log('Sessionlog branches:', checkpointBranches);
|
|
305
|
-
|
|
306
|
-
// Session state should exist with tracked files
|
|
307
|
-
const sessions = readSessionStates(tmpDir);
|
|
308
|
-
expect(sessions.length).toBeGreaterThan(0);
|
|
309
|
-
|
|
310
|
-
const session = sessions[0];
|
|
311
|
-
console.log(
|
|
312
|
-
'Session state:',
|
|
313
|
-
JSON.stringify(
|
|
314
|
-
{
|
|
315
|
-
phase: session.phase,
|
|
316
|
-
baseCommit: (session.baseCommit as string)?.slice(0, 8),
|
|
317
|
-
stepCount: session.stepCount,
|
|
318
|
-
filesTouched: session.filesTouched,
|
|
319
|
-
},
|
|
320
|
-
null,
|
|
321
|
-
2,
|
|
322
|
-
),
|
|
323
|
-
);
|
|
324
|
-
|
|
325
|
-
// Session should track the file Claude touched
|
|
326
|
-
const filesTouched = session.filesTouched as string[];
|
|
327
|
-
expect(filesTouched.length).toBeGreaterThan(0);
|
|
328
|
-
}, 180_000);
|
|
329
|
-
|
|
330
|
-
it('should mark session as ended after -p mode completes', async () => {
|
|
331
|
-
runClaude(tmpDir, 'Create a file called END_TEST.md with content: # End Test', {
|
|
332
|
-
allowedTools: ['Write'],
|
|
333
|
-
timeoutMs: 120_000,
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
|
|
337
|
-
|
|
338
|
-
const sessions = readSessionStates(tmpDir);
|
|
339
|
-
expect(sessions.length).toBeGreaterThan(0);
|
|
340
|
-
|
|
341
|
-
const session = sessions[0];
|
|
342
|
-
console.log('Session phase:', session.phase, 'endedAt:', session.endedAt);
|
|
343
|
-
|
|
344
|
-
// In -p mode, session_end hook fires, so phase should be 'ended'
|
|
345
|
-
// or at minimum endedAt should be set
|
|
346
|
-
const isEnded = session.phase === 'ended' || session.endedAt !== undefined;
|
|
347
|
-
expect(isEnded).toBe(true);
|
|
348
|
-
}, 180_000);
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
// ==========================================================================
|
|
352
|
-
// Suite 2: Commit & Explain
|
|
353
|
-
// ==========================================================================
|
|
354
|
-
|
|
355
|
-
describe('Commit & Explain', () => {
|
|
356
|
-
it('should show commit info via explain command after Claude commits', async () => {
|
|
357
|
-
runClaude(
|
|
358
|
-
tmpDir,
|
|
359
|
-
[
|
|
360
|
-
'Do these two steps exactly:',
|
|
361
|
-
'1. Create a file at lib/utils.ts with content: export const noop = () => {};',
|
|
362
|
-
'2. Then run: git add lib/utils.ts && git commit -m "feat: add noop utility"',
|
|
363
|
-
].join('\n'),
|
|
364
|
-
{
|
|
365
|
-
allowedTools: ['Write', 'Bash'],
|
|
366
|
-
systemPrompt: 'Create the file and commit it. Do exactly as instructed.',
|
|
367
|
-
timeoutMs: 120_000,
|
|
368
|
-
},
|
|
369
|
-
);
|
|
370
|
-
|
|
371
|
-
await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
|
|
372
|
-
|
|
373
|
-
const commitCount = getCommitCount(tmpDir);
|
|
374
|
-
console.log('Commit count:', commitCount);
|
|
375
|
-
|
|
376
|
-
if (commitCount <= 1) {
|
|
377
|
-
console.warn('Claude did not commit — skipping explain test');
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
// Run explain command — should always show commit info
|
|
382
|
-
const output = runSessionlog(tmpDir, ['explain', 'HEAD']);
|
|
383
|
-
console.log('Explain output:', output);
|
|
384
|
-
|
|
385
|
-
expect(output).toContain('Commit:');
|
|
386
|
-
expect(output).toContain('Message:');
|
|
387
|
-
|
|
388
|
-
// Checkpoint details are only present if shadow branch existed during commit.
|
|
389
|
-
// In single-turn -p mode this won't happen. Tested deterministically in Suite 7.
|
|
390
|
-
const hasCheckpoint = output.includes('Checkpoint:');
|
|
391
|
-
console.log('Has checkpoint in explain (expected false in single-turn):', hasCheckpoint);
|
|
392
|
-
}, 180_000);
|
|
393
|
-
|
|
394
|
-
it('should run rewind --list without errors after a session', async () => {
|
|
395
|
-
runClaude(tmpDir, 'Create a file called REWIND_TEST.md with content: # Rewind Test', {
|
|
396
|
-
allowedTools: ['Write'],
|
|
397
|
-
timeoutMs: 120_000,
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
|
|
401
|
-
|
|
402
|
-
// rewind --list should return valid JSON even with no checkpoints
|
|
403
|
-
const output = runSessionlog(tmpDir, ['rewind', '--list']);
|
|
404
|
-
console.log('Rewind list output:', output.slice(0, 300));
|
|
405
|
-
|
|
406
|
-
const points = JSON.parse(output);
|
|
407
|
-
expect(Array.isArray(points)).toBe(true);
|
|
408
|
-
console.log('Rewind points:', points.length);
|
|
409
|
-
}, 180_000);
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
// ==========================================================================
|
|
413
|
-
// Suite 3: Status Command
|
|
414
|
-
// ==========================================================================
|
|
415
|
-
|
|
416
|
-
describe('Status Command', () => {
|
|
417
|
-
it('should report enabled state and sessions after Claude session', async () => {
|
|
418
|
-
runClaude(tmpDir, 'Create a file called HELLO.md with content: # Hello', {
|
|
419
|
-
allowedTools: ['Write'],
|
|
420
|
-
systemPrompt: 'Only create the file.',
|
|
421
|
-
timeoutMs: 120_000,
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
|
|
425
|
-
|
|
426
|
-
const status = getStatus(tmpDir);
|
|
427
|
-
console.log('Status:', JSON.stringify(status, null, 2));
|
|
428
|
-
|
|
429
|
-
expect(status.enabled).toBe(true);
|
|
430
|
-
expect(status.strategy).toBe('manual-commit');
|
|
431
|
-
expect(status.gitHooksInstalled).toBe(true);
|
|
432
|
-
expect(status.agents).toBeDefined();
|
|
433
|
-
expect(status.agents as string[]).toContain('claude-code');
|
|
434
|
-
|
|
435
|
-
const sessions = status.sessions as Record<string, unknown>[];
|
|
436
|
-
expect(sessions.length).toBeGreaterThan(0);
|
|
437
|
-
|
|
438
|
-
const session = sessions[0];
|
|
439
|
-
expect(session.agentType).toBe('Claude Code');
|
|
440
|
-
expect(session.startedAt).toBeDefined();
|
|
441
|
-
expect(['idle', 'active', 'ended']).toContain(session.phase);
|
|
442
|
-
}, 180_000);
|
|
443
|
-
|
|
444
|
-
it('should report zero sessions before any Claude invocation', () => {
|
|
445
|
-
const status = getStatus(tmpDir);
|
|
446
|
-
console.log('Status (no sessions):', JSON.stringify(status, null, 2));
|
|
447
|
-
|
|
448
|
-
expect(status.enabled).toBe(true);
|
|
449
|
-
expect(status.strategy).toBe('manual-commit');
|
|
450
|
-
expect(status.gitHooksInstalled).toBe(true);
|
|
451
|
-
|
|
452
|
-
const sessions = status.sessions as Record<string, unknown>[];
|
|
453
|
-
expect(sessions).toHaveLength(0);
|
|
454
|
-
});
|
|
455
|
-
});
|
|
456
|
-
|
|
457
|
-
// ==========================================================================
|
|
458
|
-
// Suite 4: Doctor & Clean (no live Claude needed)
|
|
459
|
-
// ==========================================================================
|
|
460
|
-
|
|
461
|
-
describe('Doctor & Clean', () => {
|
|
462
|
-
it('should diagnose stuck sessions', () => {
|
|
463
|
-
// Create a synthetic stuck session
|
|
464
|
-
const sessionsDir = path.join(tmpDir, '.git', 'sessionlog-sessions');
|
|
465
|
-
fs.mkdirSync(sessionsDir, { recursive: true });
|
|
466
|
-
|
|
467
|
-
const head = getHead(tmpDir);
|
|
468
|
-
const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString();
|
|
469
|
-
|
|
470
|
-
const stuckState = {
|
|
471
|
-
sessionID: 'stuck-session-001',
|
|
472
|
-
baseCommit: head,
|
|
473
|
-
startedAt: twoHoursAgo,
|
|
474
|
-
lastInteractionTime: twoHoursAgo,
|
|
475
|
-
phase: 'active',
|
|
476
|
-
turnCheckpointIDs: [],
|
|
477
|
-
stepCount: 0,
|
|
478
|
-
checkpointTranscriptStart: 0,
|
|
479
|
-
untrackedFilesAtStart: [],
|
|
480
|
-
filesTouched: [],
|
|
481
|
-
agentType: 'Claude Code',
|
|
482
|
-
};
|
|
483
|
-
|
|
484
|
-
fs.writeFileSync(
|
|
485
|
-
path.join(sessionsDir, 'stuck-session-001.json'),
|
|
486
|
-
JSON.stringify(stuckState, null, 2),
|
|
487
|
-
);
|
|
488
|
-
|
|
489
|
-
const output = runSessionlog(tmpDir, ['doctor']);
|
|
490
|
-
console.log('Doctor output:', output);
|
|
491
|
-
|
|
492
|
-
expect(output).toContain('stuck');
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
it('should fix stuck sessions with --force', () => {
|
|
496
|
-
const sessionsDir = path.join(tmpDir, '.git', 'sessionlog-sessions');
|
|
497
|
-
fs.mkdirSync(sessionsDir, { recursive: true });
|
|
498
|
-
|
|
499
|
-
const head = getHead(tmpDir);
|
|
500
|
-
const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString();
|
|
501
|
-
|
|
502
|
-
const stuckState = {
|
|
503
|
-
sessionID: 'stuck-session-fix',
|
|
504
|
-
baseCommit: head,
|
|
505
|
-
startedAt: twoHoursAgo,
|
|
506
|
-
lastInteractionTime: twoHoursAgo,
|
|
507
|
-
phase: 'active',
|
|
508
|
-
turnCheckpointIDs: [],
|
|
509
|
-
stepCount: 0,
|
|
510
|
-
checkpointTranscriptStart: 0,
|
|
511
|
-
untrackedFilesAtStart: [],
|
|
512
|
-
filesTouched: [],
|
|
513
|
-
agentType: 'Claude Code',
|
|
514
|
-
};
|
|
515
|
-
|
|
516
|
-
fs.writeFileSync(
|
|
517
|
-
path.join(sessionsDir, 'stuck-session-fix.json'),
|
|
518
|
-
JSON.stringify(stuckState, null, 2),
|
|
519
|
-
);
|
|
520
|
-
|
|
521
|
-
const output = runSessionlog(tmpDir, ['doctor', '--force']);
|
|
522
|
-
console.log('Doctor --force output:', output);
|
|
523
|
-
|
|
524
|
-
expect(output).toContain('Discarded:');
|
|
525
|
-
|
|
526
|
-
// Session file should be deleted
|
|
527
|
-
const sessionFile = path.join(sessionsDir, 'stuck-session-fix.json');
|
|
528
|
-
expect(fs.existsSync(sessionFile)).toBe(false);
|
|
529
|
-
});
|
|
530
|
-
|
|
531
|
-
it('should report nothing to clean in a healthy repo', () => {
|
|
532
|
-
const output = runSessionlog(tmpDir, ['clean']);
|
|
533
|
-
console.log('Clean output:', output);
|
|
534
|
-
|
|
535
|
-
expect(output).toContain('Nothing to clean');
|
|
536
|
-
});
|
|
537
|
-
|
|
538
|
-
it('should detect orphaned shadow branches', () => {
|
|
539
|
-
// Create an orphaned shadow branch
|
|
540
|
-
execFileSync('git', ['branch', 'sessionlog/0000000'], { cwd: tmpDir, stdio: 'pipe' });
|
|
541
|
-
|
|
542
|
-
const branches = listGitBranches(tmpDir, 'sessionlog/*');
|
|
543
|
-
console.log('Branches before clean:', branches);
|
|
544
|
-
expect(branches).toContain('sessionlog/0000000');
|
|
545
|
-
|
|
546
|
-
const output = runSessionlog(tmpDir, ['clean']);
|
|
547
|
-
console.log('Clean output:', output);
|
|
548
|
-
|
|
549
|
-
// Should detect the orphaned branch
|
|
550
|
-
expect(output).toContain('sessionlog/0000000');
|
|
551
|
-
});
|
|
552
|
-
});
|
|
553
|
-
|
|
554
|
-
// ==========================================================================
|
|
555
|
-
// Suite 5: Token Usage
|
|
556
|
-
// ==========================================================================
|
|
557
|
-
|
|
558
|
-
describe('Token Usage', () => {
|
|
559
|
-
it('should populate token usage after a Claude session', async () => {
|
|
560
|
-
runClaude(tmpDir, 'What is 2 plus 2? Answer with just the number.', {
|
|
561
|
-
timeoutMs: 60_000,
|
|
562
|
-
});
|
|
563
|
-
|
|
564
|
-
await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
|
|
565
|
-
|
|
566
|
-
const sessions = readSessionStates(tmpDir);
|
|
567
|
-
console.log('Sessions found:', sessions.length);
|
|
568
|
-
expect(sessions.length).toBeGreaterThan(0);
|
|
569
|
-
|
|
570
|
-
const session = sessions[0];
|
|
571
|
-
console.log('Token usage:', JSON.stringify(session.tokenUsage, null, 2));
|
|
572
|
-
|
|
573
|
-
// Token usage depends on transcript parsing which may not fire in -p mode.
|
|
574
|
-
// Use soft assertions.
|
|
575
|
-
if (session.tokenUsage) {
|
|
576
|
-
const usage = session.tokenUsage as Record<string, number>;
|
|
577
|
-
expect.soft(usage.inputTokens, 'Expected inputTokens > 0').toBeGreaterThan(0);
|
|
578
|
-
expect.soft(usage.outputTokens, 'Expected outputTokens > 0').toBeGreaterThan(0);
|
|
579
|
-
} else {
|
|
580
|
-
console.warn('tokenUsage not populated — this is timing-dependent and may be expected');
|
|
581
|
-
}
|
|
582
|
-
}, 180_000);
|
|
583
|
-
});
|
|
584
|
-
|
|
585
|
-
// ==========================================================================
|
|
586
|
-
// Suite 6: Multiple Sessions
|
|
587
|
-
// ==========================================================================
|
|
588
|
-
|
|
589
|
-
describe('Multiple Sessions', () => {
|
|
590
|
-
it('should create separate session states for sequential invocations', async () => {
|
|
591
|
-
// First invocation: create a file
|
|
592
|
-
runClaude(tmpDir, 'Create a file called app/main.ts with content: console.log("hello");', {
|
|
593
|
-
allowedTools: ['Write'],
|
|
594
|
-
timeoutMs: 120_000,
|
|
595
|
-
});
|
|
596
|
-
|
|
597
|
-
await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
|
|
598
|
-
|
|
599
|
-
const sessionsAfterFirst = readSessionStates(tmpDir);
|
|
600
|
-
console.log('Sessions after first invocation:', sessionsAfterFirst.length);
|
|
601
|
-
|
|
602
|
-
// Second invocation: modify the file
|
|
603
|
-
runClaude(tmpDir, 'Read the file app/main.ts and add a second line: console.log("world");', {
|
|
604
|
-
allowedTools: ['Edit', 'Read', 'Write'],
|
|
605
|
-
timeoutMs: 120_000,
|
|
606
|
-
});
|
|
607
|
-
|
|
608
|
-
await new Promise((r) => setTimeout(r, HOOK_WAIT_MS));
|
|
609
|
-
|
|
610
|
-
const sessionsAfterSecond = readSessionStates(tmpDir);
|
|
611
|
-
console.log('Sessions after second invocation:', sessionsAfterSecond.length);
|
|
612
|
-
|
|
613
|
-
// Each -p invocation creates a new session, so we should have >= 2
|
|
614
|
-
expect(sessionsAfterSecond.length).toBeGreaterThanOrEqual(2);
|
|
615
|
-
|
|
616
|
-
// Verify sessions have different IDs
|
|
617
|
-
const sessionIDs = sessionsAfterSecond.map((s) => s.sessionID);
|
|
618
|
-
const uniqueIDs = new Set(sessionIDs);
|
|
619
|
-
expect(uniqueIDs.size).toBeGreaterThanOrEqual(2);
|
|
620
|
-
|
|
621
|
-
// Status should list all sessions
|
|
622
|
-
const status = getStatus(tmpDir);
|
|
623
|
-
const statusSessions = status.sessions as Record<string, unknown>[];
|
|
624
|
-
console.log('Status sessions count:', statusSessions.length);
|
|
625
|
-
expect(statusSessions.length).toBeGreaterThanOrEqual(2);
|
|
626
|
-
}, 300_000);
|
|
627
|
-
});
|
|
628
|
-
|
|
629
|
-
// ==========================================================================
|
|
630
|
-
// Suite 7: Checkpoint Lifecycle via CLI Binary (deterministic, no timing issues)
|
|
631
|
-
// ==========================================================================
|
|
632
|
-
|
|
633
|
-
describe('Checkpoint Lifecycle — CLI Binary', () => {
|
|
634
|
-
/**
|
|
635
|
-
* These tests pipe hook events directly to the sessionlog CLI binary,
|
|
636
|
-
* bypassing the need for a real Claude session. This allows deterministic
|
|
637
|
-
* testing of the checkpoint creation, rewind, and explain flows.
|
|
638
|
-
*/
|
|
639
|
-
|
|
640
|
-
let sessionsDir: string;
|
|
641
|
-
|
|
642
|
-
beforeEach(() => {
|
|
643
|
-
sessionsDir = path.join(tmpDir, '.git', 'sessionlog-sessions');
|
|
644
|
-
fs.mkdirSync(sessionsDir, { recursive: true });
|
|
645
|
-
|
|
646
|
-
// Pre-create an active session state
|
|
647
|
-
const head = getHead(tmpDir);
|
|
648
|
-
const sessionState = {
|
|
649
|
-
sessionID: 'cli-e2e-session',
|
|
650
|
-
baseCommit: head,
|
|
651
|
-
startedAt: new Date().toISOString(),
|
|
652
|
-
phase: 'active',
|
|
653
|
-
turnCheckpointIDs: [],
|
|
654
|
-
stepCount: 0,
|
|
655
|
-
checkpointTranscriptStart: 0,
|
|
656
|
-
untrackedFilesAtStart: [],
|
|
657
|
-
filesTouched: [],
|
|
658
|
-
agentType: 'Claude Code',
|
|
659
|
-
};
|
|
660
|
-
fs.writeFileSync(
|
|
661
|
-
path.join(sessionsDir, 'cli-e2e-session.json'),
|
|
662
|
-
JSON.stringify(sessionState, null, 2),
|
|
663
|
-
);
|
|
664
|
-
});
|
|
665
|
-
|
|
666
|
-
it('should dispatch session_start through the CLI and create session state', () => {
|
|
667
|
-
const payload = JSON.stringify({
|
|
668
|
-
session_id: 'cli-e2e-session',
|
|
669
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
670
|
-
});
|
|
671
|
-
|
|
672
|
-
execSync(`echo ${JSON.stringify(payload)} | sessionlog hooks claude-code session-start`, {
|
|
673
|
-
cwd: tmpDir,
|
|
674
|
-
timeout: 10_000,
|
|
675
|
-
stdio: 'pipe',
|
|
676
|
-
});
|
|
677
|
-
|
|
678
|
-
const sessionFile = path.join(sessionsDir, 'cli-e2e-session.json');
|
|
679
|
-
const state = JSON.parse(fs.readFileSync(sessionFile, 'utf-8'));
|
|
680
|
-
expect(state.sessionID).toBe('cli-e2e-session');
|
|
681
|
-
expect(state.agentType).toBe('Claude Code');
|
|
682
|
-
});
|
|
683
|
-
|
|
684
|
-
it('should dispatch session_end and mark session as ended', () => {
|
|
685
|
-
const payload = JSON.stringify({
|
|
686
|
-
session_id: 'cli-e2e-session',
|
|
687
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
688
|
-
});
|
|
689
|
-
|
|
690
|
-
execSync(`echo ${JSON.stringify(payload)} | sessionlog hooks claude-code session-end`, {
|
|
691
|
-
cwd: tmpDir,
|
|
692
|
-
timeout: 10_000,
|
|
693
|
-
stdio: 'pipe',
|
|
694
|
-
});
|
|
695
|
-
|
|
696
|
-
const sessionFile = path.join(sessionsDir, 'cli-e2e-session.json');
|
|
697
|
-
const state = JSON.parse(fs.readFileSync(sessionFile, 'utf-8'));
|
|
698
|
-
expect(state.phase).toBe('ended');
|
|
699
|
-
expect(state.endedAt).toBeDefined();
|
|
700
|
-
});
|
|
701
|
-
|
|
702
|
-
it('should handle full hook lifecycle: start → prompt → tool use → stop → end', () => {
|
|
703
|
-
// 1. Session start
|
|
704
|
-
execSync(
|
|
705
|
-
`echo ${JSON.stringify(
|
|
706
|
-
JSON.stringify({
|
|
707
|
-
session_id: 'cli-e2e-session',
|
|
708
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
709
|
-
}),
|
|
710
|
-
)} | sessionlog hooks claude-code session-start`,
|
|
711
|
-
{ cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
|
|
712
|
-
);
|
|
713
|
-
|
|
714
|
-
// 2. User prompt submit (turn start)
|
|
715
|
-
execSync(
|
|
716
|
-
`echo ${JSON.stringify(
|
|
717
|
-
JSON.stringify({
|
|
718
|
-
session_id: 'cli-e2e-session',
|
|
719
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
720
|
-
}),
|
|
721
|
-
)} | sessionlog hooks claude-code user-prompt-submit`,
|
|
722
|
-
{ cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
|
|
723
|
-
);
|
|
724
|
-
|
|
725
|
-
// 3. Post tool use (Write tool)
|
|
726
|
-
execSync(
|
|
727
|
-
`echo ${JSON.stringify(
|
|
728
|
-
JSON.stringify({
|
|
729
|
-
session_id: 'cli-e2e-session',
|
|
730
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
731
|
-
tool_use_id: 'toolu_01',
|
|
732
|
-
tool_name: 'Write',
|
|
733
|
-
tool_input: { file_path: '/tmp/test/src/app.ts', content: 'console.log("hi")' },
|
|
734
|
-
}),
|
|
735
|
-
)} | sessionlog hooks claude-code post-tool-Write`,
|
|
736
|
-
{ cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
|
|
737
|
-
);
|
|
738
|
-
|
|
739
|
-
// 4. Stop
|
|
740
|
-
execSync(
|
|
741
|
-
`echo ${JSON.stringify(
|
|
742
|
-
JSON.stringify({
|
|
743
|
-
session_id: 'cli-e2e-session',
|
|
744
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
745
|
-
}),
|
|
746
|
-
)} | sessionlog hooks claude-code stop`,
|
|
747
|
-
{ cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
|
|
748
|
-
);
|
|
749
|
-
|
|
750
|
-
// 5. Session end
|
|
751
|
-
execSync(
|
|
752
|
-
`echo ${JSON.stringify(
|
|
753
|
-
JSON.stringify({
|
|
754
|
-
session_id: 'cli-e2e-session',
|
|
755
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
756
|
-
}),
|
|
757
|
-
)} | sessionlog hooks claude-code session-end`,
|
|
758
|
-
{ cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
|
|
759
|
-
);
|
|
760
|
-
|
|
761
|
-
// Verify final state
|
|
762
|
-
const sessionFile = path.join(sessionsDir, 'cli-e2e-session.json');
|
|
763
|
-
const state = JSON.parse(fs.readFileSync(sessionFile, 'utf-8'));
|
|
764
|
-
|
|
765
|
-
expect(state.phase).toBe('ended');
|
|
766
|
-
expect(state.endedAt).toBeDefined();
|
|
767
|
-
});
|
|
768
|
-
|
|
769
|
-
it('should track tasks and plan mode through full CLI lifecycle', () => {
|
|
770
|
-
// 1. Enter plan mode
|
|
771
|
-
execSync(
|
|
772
|
-
`echo ${JSON.stringify(
|
|
773
|
-
JSON.stringify({
|
|
774
|
-
session_id: 'cli-e2e-session',
|
|
775
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
776
|
-
}),
|
|
777
|
-
)} | sessionlog hooks claude-code post-plan-enter`,
|
|
778
|
-
{ cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
|
|
779
|
-
);
|
|
780
|
-
|
|
781
|
-
// 2. Exit plan mode with plan file
|
|
782
|
-
const planDir = path.join(tmpDir, '.claude', 'plans');
|
|
783
|
-
fs.mkdirSync(planDir, { recursive: true });
|
|
784
|
-
const planPath = path.join(planDir, 'e2e-plan.md');
|
|
785
|
-
fs.writeFileSync(planPath, '# E2E Plan\n\n1. Create files\n2. Run tests');
|
|
786
|
-
|
|
787
|
-
execSync(
|
|
788
|
-
`echo ${JSON.stringify(
|
|
789
|
-
JSON.stringify({
|
|
790
|
-
session_id: 'cli-e2e-session',
|
|
791
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
792
|
-
tool_input: {},
|
|
793
|
-
tool_response: { planFilePath: planPath },
|
|
794
|
-
}),
|
|
795
|
-
)} | sessionlog hooks claude-code post-plan-exit`,
|
|
796
|
-
{ cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
|
|
797
|
-
);
|
|
798
|
-
|
|
799
|
-
// 3. Create task
|
|
800
|
-
execSync(
|
|
801
|
-
`echo ${JSON.stringify(
|
|
802
|
-
JSON.stringify({
|
|
803
|
-
session_id: 'cli-e2e-session',
|
|
804
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
805
|
-
tool_use_id: 'toolu_01',
|
|
806
|
-
tool_input: {
|
|
807
|
-
subject: 'Set up project',
|
|
808
|
-
description: 'Initialize project structure and dependencies',
|
|
809
|
-
},
|
|
810
|
-
tool_response: { taskId: '1' },
|
|
811
|
-
}),
|
|
812
|
-
)} | sessionlog hooks claude-code post-task-create`,
|
|
813
|
-
{ cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
|
|
814
|
-
);
|
|
815
|
-
|
|
816
|
-
// 4. Create second task
|
|
817
|
-
execSync(
|
|
818
|
-
`echo ${JSON.stringify(
|
|
819
|
-
JSON.stringify({
|
|
820
|
-
session_id: 'cli-e2e-session',
|
|
821
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
822
|
-
tool_use_id: 'toolu_02',
|
|
823
|
-
tool_input: {
|
|
824
|
-
subject: 'Write tests',
|
|
825
|
-
description: 'Add unit and integration tests',
|
|
826
|
-
},
|
|
827
|
-
tool_response: { taskId: '2' },
|
|
828
|
-
}),
|
|
829
|
-
)} | sessionlog hooks claude-code post-task-create`,
|
|
830
|
-
{ cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
|
|
831
|
-
);
|
|
832
|
-
|
|
833
|
-
// 5. Update first task to completed
|
|
834
|
-
execSync(
|
|
835
|
-
`echo ${JSON.stringify(
|
|
836
|
-
JSON.stringify({
|
|
837
|
-
session_id: 'cli-e2e-session',
|
|
838
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
839
|
-
tool_use_id: 'toolu_03',
|
|
840
|
-
tool_input: { taskId: '1', status: 'completed' },
|
|
841
|
-
}),
|
|
842
|
-
)} | sessionlog hooks claude-code post-task-update`,
|
|
843
|
-
{ cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
|
|
844
|
-
);
|
|
845
|
-
|
|
846
|
-
// Verify final state
|
|
847
|
-
const sessionFile = path.join(sessionsDir, 'cli-e2e-session.json');
|
|
848
|
-
const state = JSON.parse(fs.readFileSync(sessionFile, 'utf-8'));
|
|
849
|
-
|
|
850
|
-
// Plan mode tracking
|
|
851
|
-
expect(state.inPlanMode).toBe(false);
|
|
852
|
-
expect(state.planModeEntries).toBe(1);
|
|
853
|
-
expect(state.planEntries).toHaveLength(1);
|
|
854
|
-
expect(state.planEntries[0].content).toBe('# E2E Plan\n\n1. Create files\n2. Run tests');
|
|
855
|
-
expect(state.planEntries[0].exitedAt).toBeDefined();
|
|
856
|
-
|
|
857
|
-
// Task tracking
|
|
858
|
-
expect(Object.keys(state.tasks)).toHaveLength(2);
|
|
859
|
-
expect(state.tasks['1'].subject).toBe('Set up project');
|
|
860
|
-
expect(state.tasks['1'].description).toBe('Initialize project structure and dependencies');
|
|
861
|
-
expect(state.tasks['1'].status).toBe('completed');
|
|
862
|
-
expect(state.tasks['2'].subject).toBe('Write tests');
|
|
863
|
-
expect(state.tasks['2'].description).toBe('Add unit and integration tests');
|
|
864
|
-
expect(state.tasks['2'].status).toBe('pending');
|
|
865
|
-
});
|
|
866
|
-
|
|
867
|
-
it('should verify status command reflects CLI-dispatched session state', () => {
|
|
868
|
-
// Dispatch some events
|
|
869
|
-
execSync(
|
|
870
|
-
`echo ${JSON.stringify(
|
|
871
|
-
JSON.stringify({
|
|
872
|
-
session_id: 'cli-e2e-session',
|
|
873
|
-
transcript_path: '/path/to/transcript.jsonl',
|
|
874
|
-
}),
|
|
875
|
-
)} | sessionlog hooks claude-code session-start`,
|
|
876
|
-
{ cwd: tmpDir, timeout: 10_000, stdio: 'pipe' },
|
|
877
|
-
);
|
|
878
|
-
|
|
879
|
-
// Check status reflects the session
|
|
880
|
-
const status = getStatus(tmpDir);
|
|
881
|
-
const sessions = status.sessions as Record<string, unknown>[];
|
|
882
|
-
|
|
883
|
-
expect(sessions.length).toBeGreaterThanOrEqual(1);
|
|
884
|
-
|
|
885
|
-
const session = sessions.find((s) => s.sessionID === 'cli-e2e-session');
|
|
886
|
-
expect(session).toBeDefined();
|
|
887
|
-
expect(session!.agentType).toBe('Claude Code');
|
|
888
|
-
});
|
|
889
|
-
});
|
|
890
|
-
});
|