agentopology 0.2.4 → 0.3.0

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.
Files changed (64) hide show
  1. package/README.md +92 -10
  2. package/dist/bindings/__tests__/bindings.test.js +2 -2
  3. package/dist/bindings/__tests__/claude-code-hybrid.test.d.ts +2 -0
  4. package/dist/bindings/__tests__/claude-code-hybrid.test.d.ts.map +1 -0
  5. package/dist/bindings/__tests__/claude-code-hybrid.test.js +152 -0
  6. package/dist/bindings/__tests__/claude-code-hybrid.test.js.map +1 -0
  7. package/dist/bindings/__tests__/claude-workflow.test.d.ts +2 -0
  8. package/dist/bindings/__tests__/claude-workflow.test.d.ts.map +1 -0
  9. package/dist/bindings/__tests__/claude-workflow.test.js +204 -0
  10. package/dist/bindings/__tests__/claude-workflow.test.js.map +1 -0
  11. package/dist/bindings/__tests__/hybrid-e2e.test.d.ts +15 -0
  12. package/dist/bindings/__tests__/hybrid-e2e.test.d.ts.map +1 -0
  13. package/dist/bindings/__tests__/hybrid-e2e.test.js +94 -0
  14. package/dist/bindings/__tests__/hybrid-e2e.test.js.map +1 -0
  15. package/dist/bindings/claude-code.d.ts.map +1 -1
  16. package/dist/bindings/claude-code.js +407 -3
  17. package/dist/bindings/claude-code.js.map +1 -1
  18. package/dist/bindings/claude-workflow.d.ts +28 -0
  19. package/dist/bindings/claude-workflow.d.ts.map +1 -0
  20. package/dist/bindings/claude-workflow.js +684 -0
  21. package/dist/bindings/claude-workflow.js.map +1 -0
  22. package/dist/bindings/index.d.ts +1 -0
  23. package/dist/bindings/index.d.ts.map +1 -1
  24. package/dist/bindings/index.js +3 -0
  25. package/dist/bindings/index.js.map +1 -1
  26. package/dist/bindings/lib/seam.d.ts +35 -0
  27. package/dist/bindings/lib/seam.d.ts.map +1 -0
  28. package/dist/bindings/lib/seam.js +42 -0
  29. package/dist/bindings/lib/seam.js.map +1 -0
  30. package/dist/cli/index.js +195 -2
  31. package/dist/cli/index.js.map +1 -1
  32. package/dist/parser/__tests__/parser.test.js +170 -0
  33. package/dist/parser/__tests__/parser.test.js.map +1 -1
  34. package/dist/parser/ast.d.ts +39 -0
  35. package/dist/parser/ast.d.ts.map +1 -1
  36. package/dist/parser/index.d.ts.map +1 -1
  37. package/dist/parser/index.js +58 -2
  38. package/dist/parser/index.js.map +1 -1
  39. package/dist/parser/validator.d.ts.map +1 -1
  40. package/dist/parser/validator.js +66 -3
  41. package/dist/parser/validator.js.map +1 -1
  42. package/dist/visualizer/__tests__/brain.test.d.ts +2 -0
  43. package/dist/visualizer/__tests__/brain.test.d.ts.map +1 -0
  44. package/dist/visualizer/__tests__/brain.test.js +138 -0
  45. package/dist/visualizer/__tests__/brain.test.js.map +1 -0
  46. package/dist/visualizer/__tests__/topology-brain-link.test.d.ts +2 -0
  47. package/dist/visualizer/__tests__/topology-brain-link.test.d.ts.map +1 -0
  48. package/dist/visualizer/__tests__/topology-brain-link.test.js +41 -0
  49. package/dist/visualizer/__tests__/topology-brain-link.test.js.map +1 -0
  50. package/dist/visualizer/brain.d.ts +97 -0
  51. package/dist/visualizer/brain.d.ts.map +1 -0
  52. package/dist/visualizer/brain.js +473 -0
  53. package/dist/visualizer/brain.js.map +1 -0
  54. package/dist/visualizer/index.d.ts +19 -1
  55. package/dist/visualizer/index.d.ts.map +1 -1
  56. package/dist/visualizer/index.js +26 -11
  57. package/dist/visualizer/index.js.map +1 -1
  58. package/examples/company-brain-team.at +241 -0
  59. package/examples/company-brain.at +104 -0
  60. package/examples/logos/gmail.svg +1 -0
  61. package/examples/logos/slack.svg +1 -0
  62. package/examples/matchmat-ship.at +249 -0
  63. package/package.json +1 -1
  64. package/spec/grammar.md +42 -3
package/spec/grammar.md CHANGED
@@ -207,6 +207,7 @@ perm-enum = perm-identifier
207
207
  | `fan-out` | Parallel slices |
208
208
  | `event-driven` | Pub-sub |
209
209
  | `human-gate` | Human approval points |
210
+ | `brain` | Agent-maintained, Obsidian-portable markdown knowledge graph |
210
211
 
211
212
  ---
212
213
 
@@ -360,6 +361,7 @@ scale-field = 'mode' ':' ('auto' | 'fixed' | 'config')
360
361
  | `behavior` | `advisory` / `blocking` | no | `blocking` | Advisory never blocks flow |
361
362
  | `memory` | name-list | no | `[]` | Store IDs this agent can access (V35) |
362
363
  | `retrieval` | identifier | no | -- | Retrieval strategy ID for memory queries (V35) |
364
+ | `custodian-of` | name-list `{ does: name-list }?` | no | -- | Store IDs this agent **maintains** (not just reads). The primitive behind the `brain` pattern. Optional `does:` declares maintenance verbs (e.g. `link, tag, index, dedupe`). Refs validated by V88. |
363
365
  | `skills` | name-list | no | `[]` | Skills to preload |
364
366
  | `mcp-servers` | name-list | no | `[]` | MCP servers available |
365
367
  | `background` | boolean | no | `false` | Run in background |
@@ -531,7 +533,7 @@ store-field = 'type' ':' store-type
531
533
  | lifecycle-block
532
534
  | backend-config-block
533
535
  store-type = 'semantic' | 'episodic' | 'procedural' | 'entity'
534
- | 'graph' | 'user' | 'session' | 'temporal'
536
+ | 'graph' | 'user' | 'session' | 'temporal' | 'brain'
535
537
  scope-enum = 'agent' | 'user' | 'session' | 'org' | 'global'
536
538
  isolation-enum = 'strict' | 'soft' | 'none'
537
539
  backend-enum = 'lancedb' | 'sqlite-vec' | 'chroma' | 'kuzu' | 'falkordb'
@@ -639,10 +641,12 @@ memory {
639
641
  | `description` | string | no | -- | Human-readable purpose |
640
642
  | `scope` | scope-enum | no | -- | Access scope (V32 warning if omitted) |
641
643
  | `isolation` | isolation-enum | no | -- | Isolation level between scopes |
642
- | `backend` | backend-enum | yes | -- | Storage backend (V30 enum check) |
644
+ | `backend` | backend-enum | yes | -- | Storage backend (V30 enum check). For `type: brain`, defaults to `files` and is exempt from the enum check (V81). |
643
645
  | `path` | string | no | -- | File system path for local backends |
644
646
  | `connection` | secret-string | no | -- | Connection URI for remote backends (V34) |
645
647
  | `extraction` | extraction-enum | no | -- | Entity/fact extraction method |
648
+ | `format` | string | no | -- | File format/convention for file-native stores. For `brain`, typically `obsidian` ([[wikilinks]], #tags, YAML frontmatter) — a promise the store round-trips as a real Obsidian vault. |
649
+ | `sources` | sources-block | no | -- | **Presentation only** — provenance styling for the brain graph view. Maps a note's `source:` frontmatter to a color/icon. Visualizer-only; bindings ignore it. See below. |
646
650
  | `embedding` | embedding-block | no | -- | Embedding configuration (V31 warning if omitted for semantic/episodic/procedural) |
647
651
  | `index` | index-block | no | -- | Index/collection configuration |
648
652
  | `ingestion` | ingestion-block | no | -- | Data ingestion configuration |
@@ -654,6 +658,30 @@ memory {
654
658
 
655
659
  **`backend-config`:** A passthrough block for backend-specific key-value pairs not covered by the standard fields. Stored as `Record<string, unknown>` on the AST. Same pattern as `ProviderDef.extra`.
656
660
 
661
+ **The `brain` store type (file-native).** A `brain` store is the file-native memory primitive behind the `brain` pattern: a folder of Obsidian-format markdown where the graph is a *projection* of the files, not a separate database. It is deliberately backend-less — its `backend` defaults to `files` and is exempt from the backend-enum check (V81), it needs no embedding (V82), and it compiles to direct file access (no MCP server). Edges come from inline `[[wikilinks]]` and `#tags`; backlinks are computed. Because the format is Obsidian, a `brain` store round-trips as a real Obsidian vault — agents build it, a human opens it in Obsidian for the graph view, and an existing vault becomes an agent-readable brain with zero migration. Heavyweight stores (`semantic`, `graph`, `entity`) remain available as an opt-in power-up alongside a brain. See `docs/company-brain-design.md`.
662
+
663
+ **Custody (`custodian-of`).** Custody is the one new primitive the brain pattern needs. `memory:` grants an agent *read* access to a store; `custodian-of:` makes the agent *responsible for the store's upkeep* — wiring dropped files into the graph (resolving mentions into `[[wikilinks]]`, assigning `#tags`, updating index/hub notes, flagging ghost nodes and duplicates). The optional `does:` sub-list declares the maintenance verbs as visible architecture (like an optional type annotation); omitting it lets the agent infer its duties from its prompt. The verb *names* are language vocabulary; *how* each verb is performed well is an implementation/skill concern, not part of the spec. V88 validates that every `custodian-of` reference resolves to a declared store and warns when custody targets a non-brain store.
664
+
665
+ **Provenance styling (`sources`).** A presentation-only sub-block on a brain store that colors the graph view by where each note came from. Each named entry maps a source key (matching a note's `source:` frontmatter, stamped by its ingester) to a `color` (hex) and/or `icon` (a file path):
666
+
667
+ ```
668
+ store brain {
669
+ type: brain
670
+ path: "brain/"
671
+ sources {
672
+ gmail {
673
+ color: "#EA4335"
674
+ icon: "./logos/gmail.svg"
675
+ }
676
+ slack {
677
+ color: "#4A154B"
678
+ }
679
+ }
680
+ }
681
+ ```
682
+
683
+ This is **strictly cosmetic and affects only the `visualize-brain` rendering** — it never touches ingestion, agents, files, or binding output. Bindings emit nothing for it; delete it and the brain behaves identically (the graph just falls back to category coloring). The language stores **no image bytes** — only the path string; the visualizer reads the icon file at generate-time and inlines it as a `data:` URI, keeping the output a single self-contained HTML file. When a node's `source` matches a `sources` key, it is colored/iconed accordingly; otherwise it falls back to category-based coloring (person/org/topic inferred from tag namespaces).
684
+
657
685
  **Local vs remote backends:** Backends `lancedb`, `sqlite-vec`, `sqlite`, `kuzu`, and `chroma` are local-first (use `path`). Backends `pinecone`, `qdrant`, `pgvector`, `neo4j`, `mongodb`, and `falkordb` are remote (require `connection`, V34).
658
686
 
659
687
  ##### `embedding` sub-block
@@ -1482,6 +1510,8 @@ agent explorer {
1482
1510
 
1483
1511
  **Why extensions:** The core `.at` language defines universal constructs that work across all platforms. Extensions allow bindings to expose platform-specific features (e.g., Claude Code's `memory: project`, Codex's `sandbox: true`) without adding fields to the core spec that only one platform uses. This keeps the language clean while remaining fully extensible.
1484
1512
 
1513
+ **Seam marker for the hybrid:** `extensions { claude-workflow { execution: workflow } }` on an agent marks its phase for the embedded-workflow rung — the deterministic fan-out compiled by the `claude-workflow` binding while the rest of the topology compiles to the `claude-code` host. Unmarked topologies compile to pure `claude-code`, unchanged (the hybrid is opt-in). See `docs/AT_VS_WORKFLOW_STRATEGY.md`.
1514
+
1485
1515
  **LL(2) note:** `extensions` is a block keyword. The parser sees `extensions` `{` and enters the extensions production. Inside, each `<identifier>` `{` starts a binding namespace block. No ambiguity -- `extensions` only appears inside other blocks, never at the top level.
1486
1516
 
1487
1517
  ---
@@ -1790,11 +1820,20 @@ Bindings map universal permissions to platform-specific modes:
1790
1820
 
1791
1821
  | Binding | Status | Target |
1792
1822
  |---------|--------|--------|
1793
- | `claude-code` | Stable | Claude Code agent files, settings, MCP config |
1823
+ | `claude-code` | Stable | Claude Code agent files, settings, MCP config (the event-driven HOST layer) |
1824
+ | `claude-workflow` | Stable | Claude Workflow tool script (`<topology>.workflow.js`) for the deterministic fan-out rung, plus SEAM/README/LOSSY-REPORT companion files |
1825
+ | `codex` | Stable | Codex agent definitions and config |
1826
+ | `gemini-cli` | Stable | Gemini CLI agent definitions and config |
1827
+ | `copilot-cli` | Stable | GitHub Copilot CLI agent definitions and config |
1828
+ | `openclaw` | Stable | OpenClaw soul.md, skill files, channel/gateway/workspace config |
1829
+ | `kiro` | Stable | Kiro agent definitions and config |
1830
+ | `cursor` | Stable | Cursor rules and agent config |
1794
1831
  | `agent-sdk` | Planned | Anthropic Agent SDK tool definitions |
1795
1832
  | `e2b` | Planned | E2B sandbox configuration |
1796
1833
  | `openai-swarm` | Planned | OpenAI Swarm agent definitions |
1797
1834
 
1835
+ **The `claude-code` + `claude-workflow` hybrid.** A single `.at` topology can compile to BOTH targets. `claude-code` is the HOST — the event-driven layer that owns agents, hooks, the Blackboard, concurrent observability, and the human/gate/branching nodes. `claude-workflow` is the embedded DETERMINISTIC rung — the parallel fan-out phases. They couple through the Blackboard files (`memory.workspace`): the host launches the rung and observes its Blackboard writes via a `PostToolUse` hook, giving concurrent observability the Workflow runtime can't do internally. The seam is opt-in: a phase joins the rung only when its agents carry `extensions { claude-workflow { execution: workflow } }`. Topologies with no such marker compile to pure `claude-code` exactly as before (backward compatible). See `docs/AT_VS_WORKFLOW_STRATEGY.md` for the rationale and `docs/bindings/claude-workflow-mapping.md` for the full primitive mapping.
1836
+
1798
1837
  See `docs/bindings.md` for details on creating new bindings.
1799
1838
 
1800
1839
  ---