cognitive-core 0.2.1 → 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/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/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/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/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 +2 -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/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/workspace/types.ts +22 -78
- package/tests/integration/curated-sources-e2e.test.ts +502 -0
- package/tests/memory/compound-engineering-seed.test.ts +338 -0
- package/tests/memory/curated-loader-extended.test.ts +225 -0
- package/tests/memory/playbook-quality-validation.test.ts +430 -0
- package/tests/memory/source-resolver.test.ts +700 -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
package/src/types/index.ts
CHANGED
|
@@ -250,6 +250,8 @@ export {
|
|
|
250
250
|
type GraphConfigType,
|
|
251
251
|
type DefragConfig,
|
|
252
252
|
type SkillTreeConfig,
|
|
253
|
+
type CuratedCacheConfig,
|
|
254
|
+
type CuratedPlaybooksConfig,
|
|
253
255
|
type SessionBankConfig,
|
|
254
256
|
type FeaturesConfig,
|
|
255
257
|
type AtlasConfig,
|
|
@@ -282,6 +284,8 @@ export {
|
|
|
282
284
|
TeamLearningConfigSchema,
|
|
283
285
|
AgenticTaskRunnerConfigSchema,
|
|
284
286
|
SkillTreeConfigSchema,
|
|
287
|
+
CuratedCacheConfigSchema,
|
|
288
|
+
CuratedPlaybooksConfigSchema,
|
|
285
289
|
FeaturesConfigSchema,
|
|
286
290
|
AtlasConfigSchema,
|
|
287
291
|
createDefaultConfig,
|
package/src/workspace/types.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
TaskTemplate,
|
|
3
|
+
TaskComplexity,
|
|
4
|
+
SkillSpec,
|
|
5
|
+
ResourceSpec as BaseResourceSpec,
|
|
6
|
+
} from 'agent-workspace';
|
|
2
7
|
import type { MemorySystem, MemoryQueryResultV2 } from '../memory/system.js';
|
|
3
8
|
import type { Trajectory } from '../types/index.js';
|
|
4
9
|
import type { ComputeRequirements } from '../runtime/compute-provider.js';
|
|
5
10
|
|
|
6
11
|
// Re-export agent-workspace types used by consumers
|
|
7
12
|
export type { WorkspaceHandle, OutputSpec, OutputFileSpec, ValidationResult } from 'agent-workspace';
|
|
13
|
+
export type { TaskTemplate, TaskComplexity, SkillSpec, TaskRunner, TaskResult, AgentBackend, AgentSpawnConfig, AgentResult, TaskRunnerHooks, TaskRunnerConfig } from 'agent-workspace';
|
|
8
14
|
|
|
9
15
|
// ============================================================
|
|
10
16
|
// Agent Skills
|
|
@@ -12,13 +18,9 @@ export type { WorkspaceHandle, OutputSpec, OutputFileSpec, ValidationResult } fr
|
|
|
12
18
|
|
|
13
19
|
/**
|
|
14
20
|
* Skill to load into workspace skills/ directory.
|
|
15
|
-
*
|
|
21
|
+
* Extends agent-workspace's SkillSpec with source tracking.
|
|
16
22
|
*/
|
|
17
|
-
export interface AgentSkillSpec {
|
|
18
|
-
/** Skill directory name */
|
|
19
|
-
name: string;
|
|
20
|
-
/** SKILL.md content */
|
|
21
|
-
content: string;
|
|
23
|
+
export interface AgentSkillSpec extends SkillSpec {
|
|
22
24
|
/** Source of this skill */
|
|
23
25
|
source: 'playbook-conversion' | 'curated' | 'extracted';
|
|
24
26
|
}
|
|
@@ -29,14 +31,9 @@ export interface AgentSkillSpec {
|
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
33
|
* Supplementary resource to load into workspace resources/ directory.
|
|
34
|
+
* Extends agent-workspace's ResourceSpec with description.
|
|
32
35
|
*/
|
|
33
|
-
export interface ResourceSpec {
|
|
34
|
-
/** Path relative to resources/ directory */
|
|
35
|
-
path: string;
|
|
36
|
-
/** How to populate this resource */
|
|
37
|
-
type: 'directory' | 'file' | 'symlink';
|
|
38
|
-
/** Source path (for symlink/copy) or content (for file) */
|
|
39
|
-
source: string;
|
|
36
|
+
export interface ResourceSpec extends BaseResourceSpec {
|
|
40
37
|
/** Description for the agent */
|
|
41
38
|
description?: string;
|
|
42
39
|
}
|
|
@@ -46,13 +43,9 @@ export interface ResourceSpec {
|
|
|
46
43
|
// ============================================================
|
|
47
44
|
|
|
48
45
|
/**
|
|
49
|
-
*
|
|
46
|
+
* Backward-compatible alias for agent-workspace's TaskComplexity.
|
|
50
47
|
*/
|
|
51
|
-
export type AnalysisComplexity =
|
|
52
|
-
| 'heuristic' // Use heuristicFallback(), no agent needed
|
|
53
|
-
| 'lightweight' // Agent with small budget, simple workspace
|
|
54
|
-
| 'standard' // Agent with moderate budget, full workspace
|
|
55
|
-
| 'thorough'; // Agent with large budget, full workspace, more time
|
|
48
|
+
export type AnalysisComplexity = TaskComplexity;
|
|
56
49
|
|
|
57
50
|
// ============================================================
|
|
58
51
|
// Processing Context
|
|
@@ -81,34 +74,14 @@ export interface ProcessingContext {
|
|
|
81
74
|
/**
|
|
82
75
|
* Declarative recipe for an agentic analysis task.
|
|
83
76
|
*
|
|
77
|
+
* Extends agent-workspace's TaskTemplate with cognitive-core-specific hooks
|
|
78
|
+
* for memory injection, output processing, and compute requirements.
|
|
79
|
+
*
|
|
84
80
|
* TInput: the typed input data for this analysis
|
|
85
81
|
* TOutput: the typed output the agent produces
|
|
86
82
|
*/
|
|
87
|
-
export interface AgenticTaskTemplate<TInput, TOutput> {
|
|
88
|
-
|
|
89
|
-
taskType: string;
|
|
90
|
-
|
|
91
|
-
/** Domain for knowledge injection and meta-learning */
|
|
92
|
-
domain: string;
|
|
93
|
-
|
|
94
|
-
/** Human-readable description */
|
|
95
|
-
description: string;
|
|
96
|
-
|
|
97
|
-
// === WORKSPACE SETUP ===
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Prepare the workspace filesystem from typed input.
|
|
101
|
-
* Uses the WorkspaceHandle to write input files via typed I/O methods.
|
|
102
|
-
*/
|
|
103
|
-
prepareWorkspace(input: TInput, handle: WorkspaceHandle): Promise<void>;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Build the task description for the agent.
|
|
107
|
-
* Natural language prompt explaining what to do and what output to produce.
|
|
108
|
-
*/
|
|
109
|
-
buildTaskPrompt(input: TInput): string;
|
|
110
|
-
|
|
111
|
-
// === SKILLS ===
|
|
83
|
+
export interface AgenticTaskTemplate<TInput, TOutput> extends TaskTemplate<TInput, TOutput> {
|
|
84
|
+
// === SKILLS (override with source tracking) ===
|
|
112
85
|
|
|
113
86
|
/**
|
|
114
87
|
* Skills to load into the workspace skills/ directory.
|
|
@@ -116,14 +89,14 @@ export interface AgenticTaskTemplate<TInput, TOutput> {
|
|
|
116
89
|
*/
|
|
117
90
|
getSkills(input: TInput): AgentSkillSpec[];
|
|
118
91
|
|
|
119
|
-
// === RESOURCES ===
|
|
92
|
+
// === RESOURCES (override with description) ===
|
|
120
93
|
|
|
121
94
|
/**
|
|
122
95
|
* Supplementary resources for the workspace resources/ directory.
|
|
123
96
|
*/
|
|
124
97
|
getResources(input: TInput): ResourceSpec[];
|
|
125
98
|
|
|
126
|
-
// === KNOWLEDGE ===
|
|
99
|
+
// === KNOWLEDGE (cognitive-core extension) ===
|
|
127
100
|
|
|
128
101
|
/**
|
|
129
102
|
* Additional memory queries beyond the automatic domain-scoped query.
|
|
@@ -133,17 +106,7 @@ export interface AgenticTaskTemplate<TInput, TOutput> {
|
|
|
133
106
|
memory: MemorySystem
|
|
134
107
|
): Promise<MemoryQueryResultV2>;
|
|
135
108
|
|
|
136
|
-
// === OUTPUT ===
|
|
137
|
-
|
|
138
|
-
/** Configuration defining the expected output shape */
|
|
139
|
-
outputConfig: OutputSpec;
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Read and validate agent output from workspace.
|
|
143
|
-
* Uses the WorkspaceHandle to read output via typed I/O methods.
|
|
144
|
-
* Returns typed output or throws if validation fails.
|
|
145
|
-
*/
|
|
146
|
-
collectOutput(handle: WorkspaceHandle): Promise<TOutput>;
|
|
109
|
+
// === OUTPUT PROCESSING (cognitive-core extension) ===
|
|
147
110
|
|
|
148
111
|
/**
|
|
149
112
|
* Process the validated output — store results, accumulate for batch learning, etc.
|
|
@@ -154,31 +117,12 @@ export interface AgenticTaskTemplate<TInput, TOutput> {
|
|
|
154
117
|
context: ProcessingContext
|
|
155
118
|
): Promise<void>;
|
|
156
119
|
|
|
157
|
-
// === COMPLEXITY ASSESSMENT ===
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Assess whether this input needs agentic analysis or heuristic fallback.
|
|
161
|
-
*/
|
|
162
|
-
assessComplexity(input: TInput): AnalysisComplexity;
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Heuristic fallback for simple cases.
|
|
166
|
-
* Called when assessComplexity returns 'heuristic'.
|
|
167
|
-
*/
|
|
168
|
-
heuristicFallback?(input: TInput): Promise<TOutput>;
|
|
169
|
-
|
|
170
120
|
// === CONFIGURATION ===
|
|
171
121
|
|
|
172
|
-
/** Agent type to spawn (default: 'claude-code') */
|
|
173
|
-
agentType?: string;
|
|
174
|
-
|
|
175
|
-
/** Timeout for the analysis agent (default: 120_000ms) */
|
|
176
|
-
timeout?: number;
|
|
177
|
-
|
|
178
122
|
/** Whether to capture detailed tool calls (default: true) */
|
|
179
123
|
captureToolCalls?: boolean;
|
|
180
124
|
|
|
181
|
-
// === COMPUTE ===
|
|
125
|
+
// === COMPUTE (cognitive-core extension) ===
|
|
182
126
|
|
|
183
127
|
/**
|
|
184
128
|
* Static compute requirements for this template.
|
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration test: Curated playbook sources (local + git)
|
|
3
|
+
*
|
|
4
|
+
* Verifies the full flow from Atlas config → source resolution → playbook
|
|
5
|
+
* loading → search/retrieval. Uses real git repos, real SQLite, no mocks.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
9
|
+
import { Atlas, createAtlas } from '../../src/atlas.js';
|
|
10
|
+
import { mkdtemp, rm, mkdir, writeFile } from 'node:fs/promises';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
import { tmpdir } from 'node:os';
|
|
13
|
+
import { execFile as execFileCb } from 'node:child_process';
|
|
14
|
+
import { promisify } from 'node:util';
|
|
15
|
+
import { existsSync } from 'node:fs';
|
|
16
|
+
|
|
17
|
+
const execFile = promisify(execFileCb);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Helper: create a local bare git repo with playbook JSON files.
|
|
21
|
+
*/
|
|
22
|
+
async function createGitPlaybookRepo(
|
|
23
|
+
baseDir: string,
|
|
24
|
+
playbooks: Array<{
|
|
25
|
+
name: string;
|
|
26
|
+
domain: string;
|
|
27
|
+
situation: string;
|
|
28
|
+
confidence?: number;
|
|
29
|
+
}>,
|
|
30
|
+
opts?: { subdir?: string; manifest?: boolean; tag?: string },
|
|
31
|
+
): Promise<string> {
|
|
32
|
+
const repoDir = join(baseDir, `bare-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`);
|
|
33
|
+
await mkdir(repoDir);
|
|
34
|
+
await execFile('git', ['init', '--bare', repoDir]);
|
|
35
|
+
|
|
36
|
+
const workDir = join(baseDir, `work-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`);
|
|
37
|
+
await mkdir(workDir);
|
|
38
|
+
await execFile('git', ['clone', repoDir, workDir]);
|
|
39
|
+
await execFile('git', ['config', 'commit.gpgSign', 'false'], { cwd: workDir });
|
|
40
|
+
|
|
41
|
+
const subdir = opts?.subdir ?? 'playbooks';
|
|
42
|
+
const pbDir = join(workDir, subdir);
|
|
43
|
+
await mkdir(pbDir, { recursive: true });
|
|
44
|
+
|
|
45
|
+
for (const pb of playbooks) {
|
|
46
|
+
await writeFile(
|
|
47
|
+
join(pbDir, `${pb.name}.json`),
|
|
48
|
+
JSON.stringify({
|
|
49
|
+
name: pb.name,
|
|
50
|
+
applicability: {
|
|
51
|
+
situations: [pb.situation],
|
|
52
|
+
triggers: [`${pb.name} trigger`],
|
|
53
|
+
domains: [pb.domain],
|
|
54
|
+
},
|
|
55
|
+
guidance: {
|
|
56
|
+
strategy: `Strategy for ${pb.name}`,
|
|
57
|
+
tactics: [`Tactic 1 for ${pb.name}`, `Tactic 2 for ${pb.name}`],
|
|
58
|
+
},
|
|
59
|
+
verification: {
|
|
60
|
+
successIndicators: [`${pb.name} succeeds`],
|
|
61
|
+
failureIndicators: [`${pb.name} fails`],
|
|
62
|
+
},
|
|
63
|
+
confidence: pb.confidence ?? 0.8,
|
|
64
|
+
curatedBy: 'integration-test',
|
|
65
|
+
}),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (opts?.manifest) {
|
|
70
|
+
await writeFile(
|
|
71
|
+
join(workDir, 'cognitive-core.json'),
|
|
72
|
+
JSON.stringify({ playbooks: subdir, name: 'test-source' }),
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
await execFile('git', ['add', '.'], { cwd: workDir });
|
|
77
|
+
await execFile('git', ['commit', '-m', 'Add playbooks'], {
|
|
78
|
+
cwd: workDir,
|
|
79
|
+
env: {
|
|
80
|
+
...process.env,
|
|
81
|
+
GIT_AUTHOR_NAME: 'Test',
|
|
82
|
+
GIT_AUTHOR_EMAIL: 'test@test.com',
|
|
83
|
+
GIT_COMMITTER_NAME: 'Test',
|
|
84
|
+
GIT_COMMITTER_EMAIL: 'test@test.com',
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
await execFile('git', ['push', 'origin', 'HEAD'], { cwd: workDir });
|
|
88
|
+
|
|
89
|
+
if (opts?.tag) {
|
|
90
|
+
await execFile('git', ['tag', opts.tag], { cwd: workDir });
|
|
91
|
+
await execFile('git', ['push', 'origin', opts.tag], { cwd: workDir });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return repoDir;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
describe('Curated sources integration', () => {
|
|
98
|
+
let tempDir: string;
|
|
99
|
+
|
|
100
|
+
beforeEach(async () => {
|
|
101
|
+
tempDir = await mkdtemp(join(tmpdir(), 'curated-source-e2e-'));
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
afterEach(async () => {
|
|
105
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// ========================================================================
|
|
109
|
+
// Local path sources
|
|
110
|
+
// ========================================================================
|
|
111
|
+
|
|
112
|
+
it('should load playbooks from a local path via sources[]', async () => {
|
|
113
|
+
// Create local playbooks directory
|
|
114
|
+
const localDir = join(tempDir, 'local-playbooks');
|
|
115
|
+
await mkdir(localDir);
|
|
116
|
+
await writeFile(
|
|
117
|
+
join(localDir, 'local-review.json'),
|
|
118
|
+
JSON.stringify({
|
|
119
|
+
name: 'local-review',
|
|
120
|
+
applicability: {
|
|
121
|
+
situations: ['Code review for local project'],
|
|
122
|
+
triggers: ['review needed'],
|
|
123
|
+
domains: ['code-review'],
|
|
124
|
+
},
|
|
125
|
+
guidance: {
|
|
126
|
+
strategy: 'Review code thoroughly',
|
|
127
|
+
tactics: ['Check logic', 'Check tests'],
|
|
128
|
+
},
|
|
129
|
+
confidence: 0.85,
|
|
130
|
+
}),
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const atlas = createAtlas({
|
|
134
|
+
storage: { baseDir: join(tempDir, '.atlas') },
|
|
135
|
+
curatedPlaybooks: {
|
|
136
|
+
sources: [localDir],
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
await atlas.init();
|
|
140
|
+
|
|
141
|
+
const memory = atlas.getMemory();
|
|
142
|
+
expect(await memory.playbooks.count()).toBe(1);
|
|
143
|
+
|
|
144
|
+
const pb = await memory.playbooks.getByName('local-review');
|
|
145
|
+
expect(pb).toBeDefined();
|
|
146
|
+
expect(pb!.provenance?.origin).toBe('curated');
|
|
147
|
+
expect(pb!.confidence).toBe(0.85);
|
|
148
|
+
|
|
149
|
+
// Should be searchable
|
|
150
|
+
const matches = await memory.playbooks.findMatching('code review');
|
|
151
|
+
expect(matches.length).toBeGreaterThan(0);
|
|
152
|
+
expect(matches[0].playbook.name).toBe('local-review');
|
|
153
|
+
|
|
154
|
+
await atlas.close();
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('should load from local source with nested subdirectories', async () => {
|
|
158
|
+
const localDir = join(tempDir, 'nested-playbooks');
|
|
159
|
+
const subA = join(localDir, 'review');
|
|
160
|
+
const subB = join(localDir, 'planning', 'deep');
|
|
161
|
+
await mkdir(subA, { recursive: true });
|
|
162
|
+
await mkdir(subB, { recursive: true });
|
|
163
|
+
|
|
164
|
+
await writeFile(join(localDir, 'root.json'), JSON.stringify({
|
|
165
|
+
name: 'root-pb',
|
|
166
|
+
applicability: { situations: ['Root'], domains: ['general'] },
|
|
167
|
+
guidance: { strategy: 'Root', tactics: ['Root tactic'] },
|
|
168
|
+
}));
|
|
169
|
+
await writeFile(join(subA, 'review.json'), JSON.stringify({
|
|
170
|
+
name: 'nested-review',
|
|
171
|
+
applicability: { situations: ['Review'], domains: ['review'] },
|
|
172
|
+
guidance: { strategy: 'Review', tactics: ['Review tactic'] },
|
|
173
|
+
}));
|
|
174
|
+
await writeFile(join(subB, 'deep-plan.json'), JSON.stringify({
|
|
175
|
+
name: 'deep-plan',
|
|
176
|
+
applicability: { situations: ['Planning'], domains: ['planning'] },
|
|
177
|
+
guidance: { strategy: 'Plan', tactics: ['Plan tactic'] },
|
|
178
|
+
}));
|
|
179
|
+
|
|
180
|
+
const atlas = createAtlas({
|
|
181
|
+
storage: { baseDir: join(tempDir, '.atlas') },
|
|
182
|
+
curatedPlaybooks: { sources: [localDir] },
|
|
183
|
+
});
|
|
184
|
+
await atlas.init();
|
|
185
|
+
|
|
186
|
+
expect(await atlas.getMemory().playbooks.count()).toBe(3);
|
|
187
|
+
expect(await atlas.getMemory().playbooks.getByName('root-pb')).toBeDefined();
|
|
188
|
+
expect(await atlas.getMemory().playbooks.getByName('nested-review')).toBeDefined();
|
|
189
|
+
expect(await atlas.getMemory().playbooks.getByName('deep-plan')).toBeDefined();
|
|
190
|
+
|
|
191
|
+
await atlas.close();
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// ========================================================================
|
|
195
|
+
// Git sources
|
|
196
|
+
// ========================================================================
|
|
197
|
+
|
|
198
|
+
it('should clone a git repo source and load its playbooks', async () => {
|
|
199
|
+
const repoDir = await createGitPlaybookRepo(tempDir, [
|
|
200
|
+
{ name: 'git-review', domain: 'review', situation: 'Git-based code review' },
|
|
201
|
+
{ name: 'git-planning', domain: 'planning', situation: 'Git-based planning' },
|
|
202
|
+
]);
|
|
203
|
+
|
|
204
|
+
const atlas = createAtlas({
|
|
205
|
+
storage: { baseDir: join(tempDir, '.atlas') },
|
|
206
|
+
curatedPlaybooks: {
|
|
207
|
+
sources: [`git:${repoDir}`],
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
await atlas.init();
|
|
211
|
+
|
|
212
|
+
const memory = atlas.getMemory();
|
|
213
|
+
expect(await memory.playbooks.count()).toBe(2);
|
|
214
|
+
|
|
215
|
+
const review = await memory.playbooks.getByName('git-review');
|
|
216
|
+
expect(review).toBeDefined();
|
|
217
|
+
expect(review!.provenance?.origin).toBe('curated');
|
|
218
|
+
expect(review!.provenance?.sourceFile).toMatch(/^git:/);
|
|
219
|
+
expect(review!.provenance?.curatedBy).toBe('integration-test');
|
|
220
|
+
|
|
221
|
+
const planning = await memory.playbooks.getByName('git-planning');
|
|
222
|
+
expect(planning).toBeDefined();
|
|
223
|
+
|
|
224
|
+
// Verify searchable
|
|
225
|
+
const matches = await memory.playbooks.findMatching('code review');
|
|
226
|
+
expect(matches.some(m => m.playbook.name === 'git-review')).toBe(true);
|
|
227
|
+
|
|
228
|
+
await atlas.close();
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('should clone a git repo with tag ref', async () => {
|
|
232
|
+
const repoDir = await createGitPlaybookRepo(
|
|
233
|
+
tempDir,
|
|
234
|
+
[{ name: 'tagged-pb', domain: 'ops', situation: 'Tagged release' }],
|
|
235
|
+
{ tag: 'v1.0.0' },
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
const atlas = createAtlas({
|
|
239
|
+
storage: { baseDir: join(tempDir, '.atlas') },
|
|
240
|
+
curatedPlaybooks: {
|
|
241
|
+
sources: [`git:${repoDir}#v1.0.0`],
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
await atlas.init();
|
|
245
|
+
|
|
246
|
+
expect(await atlas.getMemory().playbooks.count()).toBe(1);
|
|
247
|
+
expect(await atlas.getMemory().playbooks.getByName('tagged-pb')).toBeDefined();
|
|
248
|
+
|
|
249
|
+
await atlas.close();
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it('should discover playbook dir via manifest', async () => {
|
|
253
|
+
const repoDir = await createGitPlaybookRepo(
|
|
254
|
+
tempDir,
|
|
255
|
+
[{ name: 'manifest-pb', domain: 'custom', situation: 'Custom dir via manifest' }],
|
|
256
|
+
{ subdir: 'my-custom-dir', manifest: true },
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
const atlas = createAtlas({
|
|
260
|
+
storage: { baseDir: join(tempDir, '.atlas') },
|
|
261
|
+
curatedPlaybooks: {
|
|
262
|
+
sources: [`git:${repoDir}`],
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
await atlas.init();
|
|
266
|
+
|
|
267
|
+
expect(await atlas.getMemory().playbooks.count()).toBe(1);
|
|
268
|
+
expect(await atlas.getMemory().playbooks.getByName('manifest-pb')).toBeDefined();
|
|
269
|
+
|
|
270
|
+
await atlas.close();
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// ========================================================================
|
|
274
|
+
// Mixed sources + bundled seed pack
|
|
275
|
+
// ========================================================================
|
|
276
|
+
|
|
277
|
+
it('should load from bundled + git + local sources simultaneously', async () => {
|
|
278
|
+
// Git source
|
|
279
|
+
const repoDir = await createGitPlaybookRepo(tempDir, [
|
|
280
|
+
{ name: 'git-pb', domain: 'git-domain', situation: 'From git' },
|
|
281
|
+
]);
|
|
282
|
+
|
|
283
|
+
// Local source
|
|
284
|
+
const localDir = join(tempDir, 'local-source');
|
|
285
|
+
await mkdir(localDir);
|
|
286
|
+
await writeFile(join(localDir, 'local.json'), JSON.stringify({
|
|
287
|
+
name: 'local-pb',
|
|
288
|
+
applicability: { situations: ['From local'], domains: ['local-domain'] },
|
|
289
|
+
guidance: { strategy: 'Local', tactics: ['Local tactic'] },
|
|
290
|
+
}));
|
|
291
|
+
|
|
292
|
+
const atlas = createAtlas({
|
|
293
|
+
storage: { baseDir: join(tempDir, '.atlas') },
|
|
294
|
+
curatedPlaybooks: {
|
|
295
|
+
loadBundledSeedPack: true,
|
|
296
|
+
sources: [`git:${repoDir}`, localDir],
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
await atlas.init();
|
|
300
|
+
|
|
301
|
+
const memory = atlas.getMemory();
|
|
302
|
+
const count = await memory.playbooks.count();
|
|
303
|
+
expect(count).toBe(27); // 25 bundled + 1 git + 1 local
|
|
304
|
+
|
|
305
|
+
expect(await memory.playbooks.getByName('git-pb')).toBeDefined();
|
|
306
|
+
expect(await memory.playbooks.getByName('local-pb')).toBeDefined();
|
|
307
|
+
expect(await memory.playbooks.getByName('review-orchestration')).toBeDefined(); // from bundled
|
|
308
|
+
|
|
309
|
+
await atlas.close();
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// ========================================================================
|
|
313
|
+
// Persistence across restarts
|
|
314
|
+
// ========================================================================
|
|
315
|
+
|
|
316
|
+
it('should skip re-cloning on second init when SHA unchanged', async () => {
|
|
317
|
+
const repoDir = await createGitPlaybookRepo(tempDir, [
|
|
318
|
+
{ name: 'persist-pb', domain: 'persist', situation: 'Persisted' },
|
|
319
|
+
]);
|
|
320
|
+
|
|
321
|
+
const atlasDir = join(tempDir, '.atlas');
|
|
322
|
+
const config = {
|
|
323
|
+
storage: { baseDir: atlasDir },
|
|
324
|
+
curatedPlaybooks: {
|
|
325
|
+
sources: [`git:${repoDir}`],
|
|
326
|
+
},
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
// First init — clones and loads
|
|
330
|
+
const atlas1 = createAtlas(config);
|
|
331
|
+
await atlas1.init();
|
|
332
|
+
expect(await atlas1.getMemory().playbooks.count()).toBe(1);
|
|
333
|
+
await atlas1.close();
|
|
334
|
+
|
|
335
|
+
// Second init — should use cached SHA, skip reload
|
|
336
|
+
// Playbooks are already in SQLite from first init
|
|
337
|
+
const atlas2 = createAtlas(config);
|
|
338
|
+
await atlas2.init();
|
|
339
|
+
expect(await atlas2.getMemory().playbooks.count()).toBe(1);
|
|
340
|
+
|
|
341
|
+
const pb = await atlas2.getMemory().playbooks.getByName('persist-pb');
|
|
342
|
+
expect(pb).toBeDefined();
|
|
343
|
+
|
|
344
|
+
await atlas2.close();
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it('should detect new commits and reload on next init', async () => {
|
|
348
|
+
const repoDir = await createGitPlaybookRepo(tempDir, [
|
|
349
|
+
{ name: 'original-pb', domain: 'evolve', situation: 'Original version' },
|
|
350
|
+
]);
|
|
351
|
+
|
|
352
|
+
const atlasDir = join(tempDir, '.atlas');
|
|
353
|
+
const config = {
|
|
354
|
+
storage: { baseDir: atlasDir },
|
|
355
|
+
curatedPlaybooks: {
|
|
356
|
+
sources: [`git:${repoDir}`],
|
|
357
|
+
cache: { maxAgeMs: 0 }, // always stale → always re-fetch
|
|
358
|
+
recreateOnInit: true, // reload when updated
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
// First init
|
|
363
|
+
const atlas1 = createAtlas(config);
|
|
364
|
+
await atlas1.init();
|
|
365
|
+
expect(await atlas1.getMemory().playbooks.count()).toBe(1);
|
|
366
|
+
await atlas1.close();
|
|
367
|
+
|
|
368
|
+
// Push a new playbook to the repo
|
|
369
|
+
const workDir = join(tempDir, 'update-work');
|
|
370
|
+
await mkdir(workDir);
|
|
371
|
+
await execFile('git', ['clone', repoDir, workDir]);
|
|
372
|
+
await execFile('git', ['config', 'commit.gpgSign', 'false'], { cwd: workDir });
|
|
373
|
+
await writeFile(
|
|
374
|
+
join(workDir, 'playbooks', 'new-pb.json'),
|
|
375
|
+
JSON.stringify({
|
|
376
|
+
name: 'new-pb',
|
|
377
|
+
applicability: { situations: ['Newly added'], domains: ['evolve'] },
|
|
378
|
+
guidance: { strategy: 'New', tactics: ['New tactic'] },
|
|
379
|
+
}),
|
|
380
|
+
);
|
|
381
|
+
await execFile('git', ['add', '.'], { cwd: workDir });
|
|
382
|
+
await execFile('git', ['commit', '-m', 'Add new playbook'], {
|
|
383
|
+
cwd: workDir,
|
|
384
|
+
env: {
|
|
385
|
+
...process.env,
|
|
386
|
+
GIT_AUTHOR_NAME: 'Test',
|
|
387
|
+
GIT_AUTHOR_EMAIL: 'test@test.com',
|
|
388
|
+
GIT_COMMITTER_NAME: 'Test',
|
|
389
|
+
GIT_COMMITTER_EMAIL: 'test@test.com',
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
await execFile('git', ['push', 'origin', 'HEAD'], { cwd: workDir });
|
|
393
|
+
|
|
394
|
+
// Second init — should detect new SHA and reload
|
|
395
|
+
const atlas2 = createAtlas(config);
|
|
396
|
+
await atlas2.init();
|
|
397
|
+
expect(await atlas2.getMemory().playbooks.count()).toBe(2);
|
|
398
|
+
expect(await atlas2.getMemory().playbooks.getByName('original-pb')).toBeDefined();
|
|
399
|
+
expect(await atlas2.getMemory().playbooks.getByName('new-pb')).toBeDefined();
|
|
400
|
+
await atlas2.close();
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
// ========================================================================
|
|
404
|
+
// Per-source recreate isolation
|
|
405
|
+
// ========================================================================
|
|
406
|
+
|
|
407
|
+
it('should recreate only the specified source without clobbering others', async () => {
|
|
408
|
+
const repoA = await createGitPlaybookRepo(tempDir, [
|
|
409
|
+
{ name: 'source-a-pb', domain: 'a', situation: 'From source A' },
|
|
410
|
+
]);
|
|
411
|
+
const repoB = await createGitPlaybookRepo(tempDir, [
|
|
412
|
+
{ name: 'source-b-pb', domain: 'b', situation: 'From source B' },
|
|
413
|
+
]);
|
|
414
|
+
|
|
415
|
+
const atlasDir = join(tempDir, '.atlas');
|
|
416
|
+
|
|
417
|
+
// First init with both sources
|
|
418
|
+
const atlas1 = createAtlas({
|
|
419
|
+
storage: { baseDir: atlasDir },
|
|
420
|
+
curatedPlaybooks: {
|
|
421
|
+
sources: [`git:${repoA}`, `git:${repoB}`],
|
|
422
|
+
cache: { maxAgeMs: 0 },
|
|
423
|
+
recreateOnInit: true,
|
|
424
|
+
},
|
|
425
|
+
});
|
|
426
|
+
await atlas1.init();
|
|
427
|
+
expect(await atlas1.getMemory().playbooks.count()).toBe(2);
|
|
428
|
+
await atlas1.close();
|
|
429
|
+
|
|
430
|
+
// Second init — recreate triggers per-source delete + reload
|
|
431
|
+
// Both sources should still have their playbooks
|
|
432
|
+
const atlas2 = createAtlas({
|
|
433
|
+
storage: { baseDir: atlasDir },
|
|
434
|
+
curatedPlaybooks: {
|
|
435
|
+
sources: [`git:${repoA}`, `git:${repoB}`],
|
|
436
|
+
cache: { maxAgeMs: 0 },
|
|
437
|
+
recreateOnInit: true,
|
|
438
|
+
},
|
|
439
|
+
});
|
|
440
|
+
await atlas2.init();
|
|
441
|
+
expect(await atlas2.getMemory().playbooks.count()).toBe(2);
|
|
442
|
+
expect(await atlas2.getMemory().playbooks.getByName('source-a-pb')).toBeDefined();
|
|
443
|
+
expect(await atlas2.getMemory().playbooks.getByName('source-b-pb')).toBeDefined();
|
|
444
|
+
await atlas2.close();
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
// ========================================================================
|
|
448
|
+
// Cache directory structure
|
|
449
|
+
// ========================================================================
|
|
450
|
+
|
|
451
|
+
it('should create cache directory under storage.baseDir', async () => {
|
|
452
|
+
const repoDir = await createGitPlaybookRepo(tempDir, [
|
|
453
|
+
{ name: 'cache-test-pb', domain: 'cache', situation: 'Cache test' },
|
|
454
|
+
]);
|
|
455
|
+
|
|
456
|
+
const atlasDir = join(tempDir, '.atlas');
|
|
457
|
+
const atlas = createAtlas({
|
|
458
|
+
storage: { baseDir: atlasDir },
|
|
459
|
+
curatedPlaybooks: {
|
|
460
|
+
sources: [`git:${repoDir}`],
|
|
461
|
+
cache: { dir: 'my-cache' },
|
|
462
|
+
},
|
|
463
|
+
});
|
|
464
|
+
await atlas.init();
|
|
465
|
+
|
|
466
|
+
// Verify cache dir was created
|
|
467
|
+
expect(existsSync(join(atlasDir, 'my-cache'))).toBe(true);
|
|
468
|
+
|
|
469
|
+
await atlas.close();
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// ========================================================================
|
|
473
|
+
// Error resilience
|
|
474
|
+
// ========================================================================
|
|
475
|
+
|
|
476
|
+
it('should skip invalid git source and continue with others', async () => {
|
|
477
|
+
const localDir = join(tempDir, 'fallback-local');
|
|
478
|
+
await mkdir(localDir);
|
|
479
|
+
await writeFile(join(localDir, 'ok.json'), JSON.stringify({
|
|
480
|
+
name: 'fallback-pb',
|
|
481
|
+
applicability: { situations: ['Fallback'], domains: ['test'] },
|
|
482
|
+
guidance: { strategy: 'Fallback', tactics: ['Fallback'] },
|
|
483
|
+
}));
|
|
484
|
+
|
|
485
|
+
const atlas = createAtlas({
|
|
486
|
+
storage: { baseDir: join(tempDir, '.atlas') },
|
|
487
|
+
curatedPlaybooks: {
|
|
488
|
+
sources: [
|
|
489
|
+
'git:/nonexistent/repo/that/does/not/exist',
|
|
490
|
+
localDir,
|
|
491
|
+
],
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
await atlas.init();
|
|
495
|
+
|
|
496
|
+
// Invalid git source should be skipped; local source should load
|
|
497
|
+
expect(await atlas.getMemory().playbooks.count()).toBe(1);
|
|
498
|
+
expect(await atlas.getMemory().playbooks.getByName('fallback-pb')).toBeDefined();
|
|
499
|
+
|
|
500
|
+
await atlas.close();
|
|
501
|
+
});
|
|
502
|
+
});
|