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
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
## Project overview
|
|
4
|
-
|
|
5
|
-
`agent-workspace` is a TypeScript library for managing filesystem workspaces used by AI agents. It provides structured directory layouts, typed readers/writers (JSON, JSONL, Markdown with YAML frontmatter, raw text), and output validation with structured error collection.
|
|
6
|
-
|
|
7
|
-
## Commands
|
|
8
|
-
|
|
9
|
-
- `npm test` — run all tests (vitest)
|
|
10
|
-
- `npm run test:watch` — run tests in watch mode
|
|
11
|
-
- `npm run build` — build with tsup (outputs to `dist/`)
|
|
12
|
-
- `npm run typecheck` — type-check without emitting
|
|
13
|
-
|
|
14
|
-
## Architecture
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
src/
|
|
18
|
-
index.ts ← public API, re-exports everything
|
|
19
|
-
types.ts ← all shared types (Schema, OutputSpec, ValidationResult, etc.)
|
|
20
|
-
manager.ts ← WorkspaceManager: create, list, cleanup, pruneStale
|
|
21
|
-
handle.ts ← WorkspaceHandle: section-scoped I/O facade over readers/writers
|
|
22
|
-
validation.ts ← validateOutput: non-throwing batch output checker
|
|
23
|
-
readers/
|
|
24
|
-
json.ts ← readJson, readJsonl, readJsonDir
|
|
25
|
-
markdown.ts ← readMarkdown (with YAML frontmatter parsing via `yaml` package)
|
|
26
|
-
raw.ts ← readRaw, listFiles
|
|
27
|
-
writers/
|
|
28
|
-
json.ts ← writeJson, writeJsonl
|
|
29
|
-
markdown.ts ← writeMarkdown (with YAML frontmatter serialization)
|
|
30
|
-
raw.ts ← writeRaw, copyDir, symlink
|
|
31
|
-
|
|
32
|
-
tests/
|
|
33
|
-
readers.test.ts ← standalone reader function tests
|
|
34
|
-
writers.test.ts ← standalone writer function tests
|
|
35
|
-
handle.test.ts ← WorkspaceHandle round-trip and section tests
|
|
36
|
-
manager.test.ts ← WorkspaceManager lifecycle tests
|
|
37
|
-
validation.test.ts ← validateOutput tests
|
|
38
|
-
errors.test.ts ← comprehensive parse/validation error behavior tests
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Key design decisions
|
|
42
|
-
|
|
43
|
-
- **Two error strategies**: Reader functions **throw** on errors (for try/catch recovery). `validateOutput` **collects** errors into `{ valid, errors }` (for batch checking). Never mix these — readers always throw, validation never throws.
|
|
44
|
-
- **Schema interface**: `{ parse(data: unknown): T }` — deliberately minimal so it works with Zod, Joi, or any custom implementation. `parse` must throw on invalid data.
|
|
45
|
-
- **Section-scoped I/O**: `WorkspaceHandle` methods take a section name (`'input'`, `'output'`, `'resources'`, `'scratch'`, or custom) as the first argument. `handle.dir(section)` throws synchronously if the section is unknown.
|
|
46
|
-
- **Default dirs**: `input`, `output`, `resources`, `scratch` are always created. Additional dirs are specified at `manager.create()` time.
|
|
47
|
-
- **Workspace metadata**: Each workspace writes `.workspace.json` with `{ id, taskType, createdAt, dirs }`. The manager uses this to reconstruct handles when listing.
|
|
48
|
-
|
|
49
|
-
## Conventions
|
|
50
|
-
|
|
51
|
-
- ESM-first (`"type": "module"` in package.json), dual CJS/ESM output via tsup.
|
|
52
|
-
- All file path parameters in readers/writers are relative to the `dir` argument. Writers auto-create parent directories via `fs.mkdir({ recursive: true })`.
|
|
53
|
-
- Tests use temp directories (`os.tmpdir()` + `fs.mkdtemp`) and clean up in `afterEach`.
|
|
54
|
-
- No external dependencies except `yaml` for YAML parsing/serialization.
|
|
55
|
-
- TypeScript strict mode. Target ES2022.
|
|
56
|
-
|
|
57
|
-
## Error message contracts
|
|
58
|
-
|
|
59
|
-
Error messages are intentionally detailed to support agent re-prompting:
|
|
60
|
-
|
|
61
|
-
- `readJson` on bad JSON: native `JSON.parse` SyntaxError
|
|
62
|
-
- `readJson` schema failure: the schema's own error message (e.g., Zod's)
|
|
63
|
-
- `readJsonl` schema failure: `"JSONL validation failed at line N: <schema error>"`
|
|
64
|
-
- `handle.dir()` unknown section: `'Unknown section "X". Available: input, output, ...'`
|
|
65
|
-
- `validateOutput` errors: `{ path: string, message: string }` — path identifies the file, message describes the issue
|
|
66
|
-
|
|
67
|
-
## Testing
|
|
68
|
-
|
|
69
|
-
The test suite has 101 tests across 6 files. When adding new functionality:
|
|
70
|
-
|
|
71
|
-
- Add happy-path tests to the relevant existing test file (`readers.test.ts`, `handle.test.ts`, etc.)
|
|
72
|
-
- Add error/throw behavior tests to `errors.test.ts`
|
|
73
|
-
- All reader error paths must be tested: missing file, malformed content, schema rejection
|
|
74
|
-
- Validation tests must verify that errors are **collected** (not thrown) and include both `path` and `message`
|
|
@@ -1,587 +0,0 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
<picture>
|
|
3
|
-
<img alt="agent-workspace banner" src="https://raw.githubusercontent.com/alexngai/agent-workspace/main/media/banner.png">
|
|
4
|
-
</picture>
|
|
5
|
-
</div>
|
|
6
|
-
|
|
7
|
-
# agent-workspace
|
|
8
|
-
|
|
9
|
-
[](https://www.npmjs.com/package/agent-workspace)
|
|
10
|
-
[](https://github.com/alexngai/agent-workspace/blob/main/LICENSE)
|
|
11
|
-
[](https://nodejs.org)
|
|
12
|
-
|
|
13
|
-
TypeScript library for managing filesystem workspaces used by AI agents. Provides structured directory layouts, typed readers and writers for JSON, JSONL, Markdown with YAML frontmatter, and raw text, plus output validation that collects all errors instead of throwing on the first failure.
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## The problem
|
|
18
|
-
|
|
19
|
-
AI agents write intermediate results, final outputs, and scratch data to disk. Without structure, this becomes ad hoc file paths scattered across functions, inconsistent error handling across formats, and no reliable way to check what an agent actually produced before the calling code reads it.
|
|
20
|
-
|
|
21
|
-
`agent-workspace` gives each agent run a dedicated directory with a predictable layout, typed I/O, and a validation pass that reports all output problems at once. Error messages are written for agent re-prompting: each error identifies the file and describes the issue in plain terms.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Table of contents
|
|
26
|
-
|
|
27
|
-
- [Prerequisites](#prerequisites)
|
|
28
|
-
- [Installation](#installation)
|
|
29
|
-
- [Quick start](#quick-start)
|
|
30
|
-
- [Workspace layout](#workspace-layout)
|
|
31
|
-
- [WorkspaceManager](#workspacemanager)
|
|
32
|
-
- [WorkspaceHandle](#workspacehandle)
|
|
33
|
-
- [Formats](#formats)
|
|
34
|
-
- [Output validation](#output-validation)
|
|
35
|
-
- [Error handling](#error-handling)
|
|
36
|
-
- [Standalone functions](#standalone-functions)
|
|
37
|
-
- [Schema interface](#schema-interface)
|
|
38
|
-
- [TypeScript support](#typescript-support)
|
|
39
|
-
- [Limitations](#limitations)
|
|
40
|
-
- [Troubleshooting](#troubleshooting)
|
|
41
|
-
- [Contributing](#contributing)
|
|
42
|
-
- [License](#license)
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## Prerequisites
|
|
47
|
-
|
|
48
|
-
- Node.js >= 18
|
|
49
|
-
- npm, yarn, or pnpm
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## Installation
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
npm install agent-workspace
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
The only runtime dependency is `yaml`, used for YAML frontmatter in Markdown files. All other functionality relies on Node.js built-ins.
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
## Quick start
|
|
64
|
-
|
|
65
|
-
```typescript
|
|
66
|
-
import { WorkspaceManager } from 'agent-workspace';
|
|
67
|
-
|
|
68
|
-
const manager = new WorkspaceManager();
|
|
69
|
-
|
|
70
|
-
// Create a workspace for a summarization run
|
|
71
|
-
const ws = await manager.create('summarize-docs');
|
|
72
|
-
|
|
73
|
-
// Write inputs for the agent
|
|
74
|
-
await ws.writeJson('input', 'config.json', {
|
|
75
|
-
model: 'claude-sonnet',
|
|
76
|
-
maxSteps: 10,
|
|
77
|
-
sources: ['q1-report.pdf', 'q2-report.pdf'],
|
|
78
|
-
});
|
|
79
|
-
await ws.writeRaw('resources', 'system-prompt.txt', 'You are a research assistant...');
|
|
80
|
-
|
|
81
|
-
// Agent writes outputs
|
|
82
|
-
await ws.writeJson('output', 'result.json', { summary: '...', confidence: 0.92 });
|
|
83
|
-
await ws.writeMarkdown('output', 'report.md', {
|
|
84
|
-
frontmatter: { title: 'Q1-Q2 Summary', date: '2025-01-15' },
|
|
85
|
-
body: '# Findings\n\nRevenue grew 18% YoY...',
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// Validate what the agent produced before reading
|
|
89
|
-
const validation = await ws.validateOutput({
|
|
90
|
-
files: [
|
|
91
|
-
{ path: 'result.json', format: 'json', required: true, description: 'Structured result' },
|
|
92
|
-
{ path: 'report.md', format: 'markdown', required: true, description: 'Human-readable report' },
|
|
93
|
-
],
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
if (!validation.valid) {
|
|
97
|
-
// Each error has { path, message } — enough to re-prompt the agent
|
|
98
|
-
for (const err of validation.errors) {
|
|
99
|
-
console.error(`${err.path}: ${err.message}`);
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
console.log('Output valid. Workspace:', ws.id);
|
|
103
|
-
// => Output valid. Workspace: summarize-docs-1718300000000-a3f2b1c4
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Clean up when done
|
|
107
|
-
await manager.cleanup(ws);
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
To verify it worked: `validation.valid` is `true` and no errors are logged.
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Workspace layout
|
|
115
|
-
|
|
116
|
-
Every workspace gets four directories by default:
|
|
117
|
-
|
|
118
|
-
```
|
|
119
|
-
<baseDir>/agent-workspaces/<taskType>-<timestamp>-<uuid>/
|
|
120
|
-
input/ # configuration, prompts, data the agent reads
|
|
121
|
-
output/ # results the agent produces
|
|
122
|
-
resources/ # reference material, shared assets
|
|
123
|
-
scratch/ # intermediate work, logs, debug output
|
|
124
|
-
.workspace.json # metadata: { id, taskType, createdAt, dirs }
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
You can add custom directories at creation time:
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
const ws = await manager.create('pipeline', {
|
|
131
|
-
additionalDirs: ['logs', 'cache'],
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
ws.dir('logs'); // => /tmp/agent-workspaces/pipeline-.../logs
|
|
135
|
-
ws.dir('cache'); // => /tmp/agent-workspaces/pipeline-.../cache
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
The `.workspace.json` file lets the manager reconstruct handles when you call `list()`.
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
## WorkspaceManager
|
|
143
|
-
|
|
144
|
-
`WorkspaceManager` controls the lifecycle of workspaces on disk.
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
import { WorkspaceManager } from 'agent-workspace';
|
|
148
|
-
|
|
149
|
-
const manager = new WorkspaceManager({
|
|
150
|
-
baseDir: '/var/agent-runs', // default: os.tmpdir()
|
|
151
|
-
prefix: 'my-agent', // default: 'agent-workspaces'
|
|
152
|
-
});
|
|
153
|
-
// workspaces created under: /var/agent-runs/my-agent/<id>
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### `create(taskType, options?)`
|
|
157
|
-
|
|
158
|
-
Creates a new workspace and returns a `WorkspaceHandle`.
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
const ws = await manager.create('extract-entities', {
|
|
162
|
-
additionalDirs: ['entities'],
|
|
163
|
-
});
|
|
164
|
-
// ws.id => 'extract-entities-1718300000000-a3f2b1c4'
|
|
165
|
-
// ws.path => '/var/agent-runs/my-agent/extract-entities-1718300000000-a3f2b1c4'
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### `list()`
|
|
169
|
-
|
|
170
|
-
Returns handles for all workspaces under the managed root. Directories without valid `.workspace.json` files are silently skipped.
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
const all = await manager.list();
|
|
174
|
-
console.log(all.map(w => w.id));
|
|
175
|
-
// => ['summarize-docs-1718200000000-...', 'extract-entities-1718300000000-...']
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### `cleanup(handle)`
|
|
179
|
-
|
|
180
|
-
Removes a workspace directory from disk.
|
|
181
|
-
|
|
182
|
-
```typescript
|
|
183
|
-
await manager.cleanup(ws);
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### `pruneStale(maxAgeMs)`
|
|
187
|
-
|
|
188
|
-
Removes all workspaces older than `maxAgeMs` milliseconds. Returns the number of workspaces deleted.
|
|
189
|
-
|
|
190
|
-
```typescript
|
|
191
|
-
// Remove workspaces older than 24 hours
|
|
192
|
-
const pruned = await manager.pruneStale(24 * 60 * 60 * 1000);
|
|
193
|
-
console.log(`Pruned ${pruned} stale workspaces`);
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
## WorkspaceHandle
|
|
199
|
-
|
|
200
|
-
`WorkspaceHandle` is the I/O facade for a single workspace. Every read and write method takes a section name as its first argument.
|
|
201
|
-
|
|
202
|
-
### Properties
|
|
203
|
-
|
|
204
|
-
| Property | Type | Description |
|
|
205
|
-
|---|---|---|
|
|
206
|
-
| `id` | `string` | Unique workspace ID (`taskType-timestamp-uuid`) |
|
|
207
|
-
| `path` | `string` | Absolute path to the workspace root |
|
|
208
|
-
| `createdAt` | `Date` | When the workspace was created |
|
|
209
|
-
| `inputDir` | `string` | Absolute path to `input/` |
|
|
210
|
-
| `outputDir` | `string` | Absolute path to `output/` |
|
|
211
|
-
| `resourcesDir` | `string` | Absolute path to `resources/` |
|
|
212
|
-
| `scratchDir` | `string` | Absolute path to `scratch/` |
|
|
213
|
-
|
|
214
|
-
### `dir(section)`
|
|
215
|
-
|
|
216
|
-
Returns the absolute path to a section directory. Throws synchronously if the section does not exist in the workspace.
|
|
217
|
-
|
|
218
|
-
```typescript
|
|
219
|
-
ws.dir('output'); // => '/var/agent-runs/.../output'
|
|
220
|
-
ws.dir('nonexistent'); // throws: 'Unknown section "nonexistent". Available: input, output, ...'
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
---
|
|
224
|
-
|
|
225
|
-
## Formats
|
|
226
|
-
|
|
227
|
-
### JSON
|
|
228
|
-
|
|
229
|
-
```typescript
|
|
230
|
-
// Write (pretty-printed, trailing newline)
|
|
231
|
-
await ws.writeJson('output', 'result.json', {
|
|
232
|
-
entities: [{ name: 'Acme Corp', type: 'ORG' }],
|
|
233
|
-
extractedAt: new Date().toISOString(),
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
// Read without schema — returns unknown
|
|
237
|
-
const raw = await ws.readJson('output', 'result.json');
|
|
238
|
-
|
|
239
|
-
// Read with schema validation (Zod)
|
|
240
|
-
import { z } from 'zod';
|
|
241
|
-
|
|
242
|
-
const ResultSchema = z.object({
|
|
243
|
-
entities: z.array(z.object({ name: z.string(), type: z.string() })),
|
|
244
|
-
extractedAt: z.string(),
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
const result = await ws.readJson('output', 'result.json', { schema: ResultSchema });
|
|
248
|
-
// result.entities[0].name => 'Acme Corp'
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
### JSONL
|
|
252
|
-
|
|
253
|
-
Each line is a separate JSON object. Useful for streaming records or step logs.
|
|
254
|
-
|
|
255
|
-
```typescript
|
|
256
|
-
await ws.writeJsonl('scratch', 'steps.jsonl', [
|
|
257
|
-
{ step: 1, action: 'search', query: 'quantum computing fundamentals' },
|
|
258
|
-
{ step: 2, action: 'summarize', source: 'arxiv:2401.1234', tokens: 1842 },
|
|
259
|
-
{ step: 3, action: 'cite', count: 3 },
|
|
260
|
-
]);
|
|
261
|
-
|
|
262
|
-
const steps = await ws.readJsonl('scratch', 'steps.jsonl');
|
|
263
|
-
// => [{ step: 1, ... }, { step: 2, ... }, { step: 3, ... }]
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
Schema validation on JSONL applies per line. Errors include the line number:
|
|
267
|
-
|
|
268
|
-
```
|
|
269
|
-
JSONL validation failed at line 2: Expected number, received string at "step"
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### Markdown with YAML frontmatter
|
|
273
|
-
|
|
274
|
-
```typescript
|
|
275
|
-
// Write
|
|
276
|
-
await ws.writeMarkdown('output', 'report.md', {
|
|
277
|
-
frontmatter: {
|
|
278
|
-
title: 'Competitive Analysis',
|
|
279
|
-
status: 'draft',
|
|
280
|
-
confidence: 0.87,
|
|
281
|
-
},
|
|
282
|
-
body: '## Summary\n\nThree competitors identified in the APAC region.',
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
// Read — frontmatter typed as Record<string, unknown> by default
|
|
286
|
-
const doc = await ws.readMarkdown('output', 'report.md');
|
|
287
|
-
doc.frontmatter.title; // => 'Competitive Analysis'
|
|
288
|
-
doc.body; // => '## Summary\n\nThree competitors...'
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
Files without a `---` frontmatter block return `frontmatter: {}` and the full content as `body`.
|
|
292
|
-
|
|
293
|
-
You can validate frontmatter with a schema:
|
|
294
|
-
|
|
295
|
-
```typescript
|
|
296
|
-
const FrontmatterSchema = z.object({
|
|
297
|
-
title: z.string(),
|
|
298
|
-
confidence: z.number(),
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
const doc = await ws.readMarkdown('output', 'report.md', {
|
|
302
|
-
frontmatterSchema: FrontmatterSchema,
|
|
303
|
-
});
|
|
304
|
-
// doc.frontmatter is typed as { title: string; confidence: number }
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### Raw text
|
|
308
|
-
|
|
309
|
-
```typescript
|
|
310
|
-
await ws.writeRaw('scratch', 'debug.log', 'Token count: 4096\nLatency: 1.2s\n');
|
|
311
|
-
const log = await ws.readRaw('scratch', 'debug.log');
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
### Directory operations
|
|
315
|
-
|
|
316
|
-
```typescript
|
|
317
|
-
// List all files in a section (recursive, returns relative paths)
|
|
318
|
-
const files = await ws.listFiles('output');
|
|
319
|
-
// => ['report.md', 'result.json', 'charts/bar.svg']
|
|
320
|
-
|
|
321
|
-
// List files within a subdirectory
|
|
322
|
-
const charts = await ws.listFiles('output', 'charts');
|
|
323
|
-
// => ['bar.svg']
|
|
324
|
-
|
|
325
|
-
// Read all .json files in a subdirectory into a Map<filename, parsed>
|
|
326
|
-
const byDoc = await ws.readJsonDir('output', 'per-doc');
|
|
327
|
-
byDoc.get('doc1.json'); // => { ... }
|
|
328
|
-
|
|
329
|
-
// Copy an external directory into a section
|
|
330
|
-
await ws.copyDir('resources', 'reference-data', '/data/industry-codes');
|
|
331
|
-
|
|
332
|
-
// Create a symlink inside a section pointing to an external path
|
|
333
|
-
await ws.symlink('resources', 'model-weights', '/opt/ml/models/v3');
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
---
|
|
337
|
-
|
|
338
|
-
## Output validation
|
|
339
|
-
|
|
340
|
-
`validateOutput` checks a workspace's output directory against a specification. It never throws. All errors are collected and returned in `{ valid, errors }`.
|
|
341
|
-
|
|
342
|
-
```typescript
|
|
343
|
-
import { z } from 'zod';
|
|
344
|
-
|
|
345
|
-
const SummarySchema = z.object({
|
|
346
|
-
title: z.string(),
|
|
347
|
-
confidence: z.number().min(0).max(1),
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
const result = await ws.validateOutput({
|
|
351
|
-
files: [
|
|
352
|
-
{
|
|
353
|
-
path: 'result.json',
|
|
354
|
-
format: 'json',
|
|
355
|
-
required: true,
|
|
356
|
-
description: 'Structured result with confidence score',
|
|
357
|
-
schema: SummarySchema,
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
path: 'report.md',
|
|
361
|
-
format: 'markdown',
|
|
362
|
-
required: true,
|
|
363
|
-
description: 'Human-readable report',
|
|
364
|
-
},
|
|
365
|
-
{
|
|
366
|
-
path: 'steps.jsonl',
|
|
367
|
-
format: 'jsonl',
|
|
368
|
-
required: false,
|
|
369
|
-
validate: (items) => {
|
|
370
|
-
// Custom check: at least one step recorded
|
|
371
|
-
return (items as unknown[]).length > 0;
|
|
372
|
-
},
|
|
373
|
-
},
|
|
374
|
-
],
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
if (!result.valid) {
|
|
378
|
-
for (const err of result.errors) {
|
|
379
|
-
console.log(`${err.path}: ${err.message}`);
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
Example error messages:
|
|
385
|
-
|
|
386
|
-
```
|
|
387
|
-
result.json: Required file missing (Structured result with confidence score)
|
|
388
|
-
report.md: Schema validation failed: Expected string, received number at 'title'
|
|
389
|
-
steps.jsonl: Custom validation returned false
|
|
390
|
-
steps.jsonl: Custom validation threw: length must be greater than 0
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
**Collection rules:**
|
|
394
|
-
|
|
395
|
-
- Missing required files add an error and skip further checks for that file.
|
|
396
|
-
- Missing optional files are silently skipped.
|
|
397
|
-
- Schema and custom `validate` run independently; both can report errors for the same file.
|
|
398
|
-
- `validate` can return `false` or throw; both produce an error entry.
|
|
399
|
-
- `validateOutput` never throws under any circumstances.
|
|
400
|
-
|
|
401
|
-
---
|
|
402
|
-
|
|
403
|
-
## Error handling
|
|
404
|
-
|
|
405
|
-
Readers and `validateOutput` use two distinct error strategies.
|
|
406
|
-
|
|
407
|
-
**Readers throw** on any error: missing file, malformed content, schema failure. Use try/catch for recovery or retry logic.
|
|
408
|
-
|
|
409
|
-
```typescript
|
|
410
|
-
try {
|
|
411
|
-
const data = await ws.readJson('output', 'result.json', { schema: ResultSchema });
|
|
412
|
-
} catch (err) {
|
|
413
|
-
// err.message has enough detail to diagnose the problem
|
|
414
|
-
// ENOENT errors include the file path
|
|
415
|
-
// Schema errors include the schema library's message
|
|
416
|
-
}
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
**`validateOutput` collects** errors without throwing. Use it to check all output files before reading any of them.
|
|
420
|
-
|
|
421
|
-
```typescript
|
|
422
|
-
const { valid, errors } = await ws.validateOutput(spec);
|
|
423
|
-
if (!valid) {
|
|
424
|
-
const feedback = errors.map(e => `- ${e.path}: ${e.message}`).join('\n');
|
|
425
|
-
// Pass feedback to the agent for re-prompting
|
|
426
|
-
}
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
---
|
|
430
|
-
|
|
431
|
-
## Standalone functions
|
|
432
|
-
|
|
433
|
-
All readers and writers are exported as standalone functions. They take an absolute directory path as their first argument instead of a section name.
|
|
434
|
-
|
|
435
|
-
```typescript
|
|
436
|
-
import {
|
|
437
|
-
readJson, readJsonl, readJsonDir,
|
|
438
|
-
readMarkdown, readRaw, listFiles,
|
|
439
|
-
writeJson, writeJsonl,
|
|
440
|
-
writeMarkdown,
|
|
441
|
-
writeRaw, copyDir, symlink,
|
|
442
|
-
validateOutput,
|
|
443
|
-
} from 'agent-workspace';
|
|
444
|
-
|
|
445
|
-
const config = await readJson('/data/runs/run-42/input', 'config.json');
|
|
446
|
-
await writeJsonl('/data/runs/run-42/output', 'records.jsonl', records);
|
|
447
|
-
|
|
448
|
-
const result = await validateOutput('/data/runs/run-42/output', { files: [...] });
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
Writers automatically create parent directories. You do not need to `mkdir` first.
|
|
452
|
-
|
|
453
|
-
---
|
|
454
|
-
|
|
455
|
-
## Schema interface
|
|
456
|
-
|
|
457
|
-
The library uses a minimal interface so it works with any validation library:
|
|
458
|
-
|
|
459
|
-
```typescript
|
|
460
|
-
interface Schema<T> {
|
|
461
|
-
parse(data: unknown): T; // must throw on invalid data
|
|
462
|
-
}
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
**Zod** satisfies this interface directly:
|
|
466
|
-
|
|
467
|
-
```typescript
|
|
468
|
-
import { z } from 'zod';
|
|
469
|
-
|
|
470
|
-
const schema = z.object({ confidence: z.number().min(0).max(1) });
|
|
471
|
-
const data = await ws.readJson('output', 'result.json', { schema });
|
|
472
|
-
// data is typed as { confidence: number }
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
**Joi** returns a result object instead of throwing by default. Wrap it:
|
|
476
|
-
|
|
477
|
-
```typescript
|
|
478
|
-
import Joi from 'joi';
|
|
479
|
-
|
|
480
|
-
const joiSchema = Joi.object({ confidence: Joi.number().required() });
|
|
481
|
-
|
|
482
|
-
const schema = {
|
|
483
|
-
parse(data: unknown) {
|
|
484
|
-
const { error, value } = joiSchema.validate(data);
|
|
485
|
-
if (error) throw error;
|
|
486
|
-
return value;
|
|
487
|
-
},
|
|
488
|
-
};
|
|
489
|
-
```
|
|
490
|
-
|
|
491
|
-
Any object with a `parse` method that throws on failure works the same way.
|
|
492
|
-
|
|
493
|
-
---
|
|
494
|
-
|
|
495
|
-
## TypeScript support
|
|
496
|
-
|
|
497
|
-
The package ships TypeScript declarations for all exports. Both ESM and CJS builds are included via `exports` conditions.
|
|
498
|
-
|
|
499
|
-
```typescript
|
|
500
|
-
import type {
|
|
501
|
-
Schema,
|
|
502
|
-
WorkspaceMeta,
|
|
503
|
-
WorkspaceManagerConfig,
|
|
504
|
-
CreateWorkspaceOptions,
|
|
505
|
-
MarkdownDocument,
|
|
506
|
-
OutputSpec,
|
|
507
|
-
OutputFileSpec,
|
|
508
|
-
ValidationResult,
|
|
509
|
-
ValidationError,
|
|
510
|
-
ReadJsonOptions,
|
|
511
|
-
ReadMarkdownOptions,
|
|
512
|
-
} from 'agent-workspace';
|
|
513
|
-
```
|
|
514
|
-
|
|
515
|
-
The library targets ES2022, uses TypeScript strict mode, and ships `"type": "module"` with dual CJS/ESM output via `tsup`. It works in ESM and CommonJS projects without configuration changes.
|
|
516
|
-
|
|
517
|
-
---
|
|
518
|
-
|
|
519
|
-
## Limitations
|
|
520
|
-
|
|
521
|
-
**Node.js only.** The library uses `fs`, `path`, `os`, and `crypto` from Node.js. It does not run in browsers, Deno, Bun, or edge runtimes.
|
|
522
|
-
|
|
523
|
-
**Local filesystem only.** Workspaces live on disk. There is no S3, GCS, or remote storage backend.
|
|
524
|
-
|
|
525
|
-
**No concurrency control.** Two processes writing to the same workspace section simultaneously will produce undefined results. Coordinate parallel writes at the application level.
|
|
526
|
-
|
|
527
|
-
**No file watching.** The library does not emit events when files change. Poll `list()` or `listFiles()` to detect changes.
|
|
528
|
-
|
|
529
|
-
**Schema libraries that return result objects need a wrapper.** The `parse` method must throw on invalid data. Libraries like Joi require a thin wrapper (see [Schema interface](#schema-interface)).
|
|
530
|
-
|
|
531
|
-
**Pruning is time-based only.** `pruneStale` compares `createdAt` from `.workspace.json` against a maximum age. There is no size-based or access-based pruning.
|
|
532
|
-
|
|
533
|
-
---
|
|
534
|
-
|
|
535
|
-
## Troubleshooting
|
|
536
|
-
|
|
537
|
-
**`Unknown section "X". Available: input, output, ...`**
|
|
538
|
-
|
|
539
|
-
You passed a section name that was not created with the workspace. Either use one of the four default sections (`input`, `output`, `resources`, `scratch`) or declare the section at creation time:
|
|
540
|
-
|
|
541
|
-
```typescript
|
|
542
|
-
const ws = await manager.create('my-task', {
|
|
543
|
-
additionalDirs: ['X'],
|
|
544
|
-
});
|
|
545
|
-
```
|
|
546
|
-
|
|
547
|
-
**`JSONL validation failed at line N: ...`**
|
|
548
|
-
|
|
549
|
-
One line in the JSONL file failed schema validation. The error includes the 1-based line number. Open the file and check line N for malformed or unexpected data.
|
|
550
|
-
|
|
551
|
-
**`validateOutput` reports `Required file missing` but the file exists**
|
|
552
|
-
|
|
553
|
-
The `path` in `OutputFileSpec` is relative to the output directory, not the workspace root. Use `result.json`, not `output/result.json`.
|
|
554
|
-
|
|
555
|
-
**Writers silently overwrite existing files**
|
|
556
|
-
|
|
557
|
-
`writeJson`, `writeJsonl`, `writeMarkdown`, and `writeRaw` do not check for existing content before writing. Call `listFiles()` first if you need to guard against overwrites.
|
|
558
|
-
|
|
559
|
-
**`pruneStale` removes nothing even though workspaces are old**
|
|
560
|
-
|
|
561
|
-
`pruneStale` reads `createdAt` from each workspace's `.workspace.json`. If that file is missing or corrupt, `list()` skips the directory entirely and `pruneStale` never considers it. Remove such directories manually.
|
|
562
|
-
|
|
563
|
-
---
|
|
564
|
-
|
|
565
|
-
## Contributing
|
|
566
|
-
|
|
567
|
-
```bash
|
|
568
|
-
git clone https://github.com/alexngai/agent-workspace.git
|
|
569
|
-
cd agent-workspace
|
|
570
|
-
npm install
|
|
571
|
-
npm test # 101 tests across 6 files
|
|
572
|
-
npm test -- readers.test.ts # run a single test file
|
|
573
|
-
npm run typecheck # type-check without emitting
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
Tests use temporary directories under `os.tmpdir()` and clean up in `afterEach`. When adding functionality:
|
|
577
|
-
|
|
578
|
-
- Add happy-path tests to the relevant existing file (`readers.test.ts`, `writers.test.ts`, `handle.test.ts`, `manager.test.ts`, or `validation.test.ts`).
|
|
579
|
-
- Add error and throw behavior tests to `errors.test.ts`.
|
|
580
|
-
- All reader error paths require tests: missing file, malformed content, schema rejection.
|
|
581
|
-
- Validation tests must verify that errors are collected, not thrown, and that each error includes both `path` and `message`.
|
|
582
|
-
|
|
583
|
-
---
|
|
584
|
-
|
|
585
|
-
## License
|
|
586
|
-
|
|
587
|
-
MIT
|
|
Binary file
|