History

wip docs

Rhys Sullivan committed 8 months ago

Commit 38327c01 parent 0c3e41515 files · +942 −6Browse files

Unified · Split

15 files
  1. bun.lock +6 −1
  2. docs/developer/adapters-and-formats.mdx +96 −0
  3. docs/developer/cli.mdx +59 −0
  4. docs/developer/codemode.mdx +69 −0
  5. docs/developer/core-model.mdx +130 −0
  6. docs/developer/credentials-and-auth.mdx +100 −0
  7. docs/developer/extending-executor.mdx +83 −0
  8. docs/developer/mcp.mdx +51 −0
  9. docs/developer/overview.mdx +108 −0
  10. docs/developer/persistence-and-migrations.mdx +86 −0
  11. docs/developer/tool-catalog-and-execution.mdx +81 −0
  12. docs/docs.json +45 −3
  13. docs/introduction.mdx +14 −0
  14. docs/package.json +10 −0
  15. package.json +4 −2
bun.lock+6−1
@@ -12,7 +12,7 @@ · 11 unmodified lines
12 },12 },
13 "apps/executor": {13 "apps/executor": {
14 "name": "executor",14 "name": "executor",
15 "version": "1.1.8",15 "version": "1.1.9",
16 "bin": {16 "bin": {
17 "executor": "bin/executor",17 "executor": "bin/executor",
18 },18 },
@@ -79,6 +79,9 @@ · 60 unmodified lines
79 "vite": "^7.3.1",79 "vite": "^7.3.1",
80 },80 },
81 },81 },
82 "docs": {
83 "name": "@executor/docs",
84 },
82 "packages/ai-sdk-adapter": {85 "packages/ai-sdk-adapter": {
83 "name": "@executor/ai-sdk-adapter",86 "name": "@executor/ai-sdk-adapter",
84 "dependencies": {87 "dependencies": {
@@ -475,6 +478,8 @@ · 390 unmodified lines
475 478
476 "@executor/control-plane": ["@executor/control-plane@workspace:packages/control-plane"],479 "@executor/control-plane": ["@executor/control-plane@workspace:packages/control-plane"],
477 480
481 "@executor/docs": ["@executor/docs@workspace:docs"],
482
478 "@executor/executor-mcp": ["@executor/executor-mcp@workspace:packages/executor-mcp"],483 "@executor/executor-mcp": ["@executor/executor-mcp@workspace:packages/executor-mcp"],
479 484
480 "@executor/kitchen-sink": ["@executor/kitchen-sink@workspace:packages/kitchen-sink"],485 "@executor/kitchen-sink": ["@executor/kitchen-sink@workspace:packages/kitchen-sink"],
docs/developer/adapters-and-formats.mdx+96−0
@@ -0,0 +1,96 @@
1---
2title: "Adapters And Formats"
3description: "How executor supports multiple integration types without hardwiring the core to one protocol."
4---
5
6Adapters are the main extensibility boundary in executor.
7
8They let executor support multiple integration styles without turning the control plane into a long chain of provider-specific branches.
9
10## What an adapter does
11
12An adapter owns the format-specific or protocol-specific behavior for a source.
13
14That includes:
15
16- connect payload shape
17- binding config serialization and decoding
18- source validation
19- source config extraction
20- materialization
21- manifest parsing
22- operation description
23- invocation
24
25The control plane owns the generic lifecycle around that.
26
27## Why adapters exist
28
29Executor needs to support integrations that do not all look the same at the source boundary:
30
31- OpenAPI specs
32- GraphQL APIs
33- MCP servers
34- future Google Discovery imports
35- future Postman collections
36- future snippet bundles
37
38If the core storage model were shaped around one of those directly, every new integration family would cause another redesign.
39
40Adapters prevent that.
41
42## Family vs format
43
44It is important not to confuse the integration family with the import format.
45
46Examples:
47
48- OpenAPI and GraphQL are both broadly `http_api`-style integrations in executor
49- MCP is still its own family because it has distinct session and discovery semantics
50
51This lets executor share broad runtime behavior where appropriate without pretending every source is identical.
52
53## What gets stored
54
55Adapters do **not** get to invent arbitrary top-level storage models.
56
57They compile into the same canonical layers:
58
59- recipe
60- revision
61- raw documents
62- schema bundles
63- operations
64
65That means the control plane can stay generic while adapters remain flexible.
66
67## Why binding config is adapter-owned
68
69Adapter-owned binding config is one of the most important anti-churn decisions in the codebase.
70
71Instead of adding more and more provider columns to the source model, the adapter carries its own binding payload and version.
72
73That makes it much cheaper to evolve formats without reopening the core schema for every field addition.
74
75## Why provider-specific detail still exists
76
77Executor does still store some provider-shaped detail in operation metadata and bundle/document kinds.
78
79That is intentional, but the direction is:
80
81- keep the generic IR thin
82- keep provider-specific detail in adapter code or typed provider metadata
83
84The goal is not to erase differences between formats. The goal is to stop those differences from dominating the core architecture.
85
86## What a good new adapter should do
87
88A good new adapter should:
89
90- compile into the canonical recipe/revision/operation model
91- use adapter-owned binding config
92- avoid requiring new generic tables or provider columns unless truly necessary
93- expose stable tool paths and search text
94- make auth needs explicit through the existing auth slot model
95
96If an integration needs a whole new top-level execution family, that is a sign it may not belong as just another `http_api` adapter.
docs/developer/cli.mdx+59−0
@@ -0,0 +1,59 @@
1---
2title: "CLI"
3description: "How the executor CLI fits into the system and why it stays thin."
4---
5
6The CLI lives in `apps/executor`.
7
8Its job is to be the installed user-facing shell around the local daemon, not the place where product logic is implemented.
9
10## Responsibilities
11
12The CLI is responsible for:
13
14- starting and stopping the local daemon
15- checking daemon health and installation state
16- submitting executions
17- resuming paused interactions
18- packaging and distribution concerns for the installed binary
19
20## What it should not own
21
22The CLI should not own:
23
24- source persistence rules
25- auth workflows
26- tool discovery
27- execution state machines
28- tool invocation behavior
29
30Those belong in the control plane.
31
32## Why this boundary matters
33
34This split is intentional.
35
36It means the browser UI, CLI, and local MCP entrypoint all talk to the same product core instead of each carrying their own business logic. That keeps behavior consistent across entrypoints and avoids reimplementing source, credential, and execution rules in multiple places.
37
38## How it talks to the rest of the system
39
40At a high level, the CLI:
41
421. ensures the local daemon is available
432. calls the local HTTP API exposed by `packages/server`
443. hands off real work to `packages/control-plane`
45
46That makes the CLI a stable shell over a shared local runtime rather than a second product core.
47
48## Why this is flexible
49
50Because the CLI is thin, new product capabilities usually do not require redesigning the CLI architecture.
51
52Most new work lands in:
53
54- control-plane runtime logic
55- source adapters
56- codemode packages
57- server/API surfaces
58
59The CLI mostly needs new commands or command wiring on top of those primitives.
docs/developer/codemode.mdx+69−0
@@ -0,0 +1,69 @@
1---
2title: "Code Mode"
3description: "The shared tool abstractions and adapter packages that connect sources to execution."
4---
5
6The codemode packages are the bridge between imported integrations and executable tools.
7
8They provide the shared tool abstractions that both the control plane and runtime can depend on.
9
10## Core role
11
12The codemode layer is where executor turns "some external thing" into a discoverable and invokable tool surface.
13
14That is why it exists as a separate layer instead of being buried directly inside each product surface.
15
16## Main packages
17
18### `packages/codemode-core`
19
20This package holds the common tool model:
21
22- tool definitions
23- tool catalogs
24- tool invokers
25- discovery helpers
26- schema-aware tool contracts
27- shared system-tool concepts
28
29This is the main abstraction boundary that other layers build on.
30
31### `packages/codemode-openapi`
32
33This package handles OpenAPI-specific extraction and tool generation.
34
35Its job is to understand OpenAPI and compile it into the shared codemode tool model, not to own workspace persistence or auth lifecycle.
36
37### `packages/codemode-mcp`
38
39This package handles MCP-specific tool discovery and invocation behavior and adapts remote MCP tools into the same shared tool model.
40
41## Why this layer exists
42
43Without the codemode layer, the control plane would have to understand every source format and execution detail directly.
44
45Instead, executor keeps the core model broad and pushes format-specific transformation logic into focused packages.
46
47That is what makes the system extensible:
48
49- new adapters can target the same internal tool model
50- the runtime can execute against one logical tool surface
51- the same abstractions can be reused outside the control plane, including SDK-style consumers
52
53## How it fits with the control plane
54
55The control plane owns:
56
57- bindings
58- credentials
59- revisions and materialization
60- tool indexing
61- policy and invocation lifecycle
62
63The codemode layer owns:
64
65- how external formats become tools
66- how those tools are described
67- how format-specific invocation helpers are implemented
68
69That boundary is what keeps the architecture adapter-based instead of turning the control plane into one large protocol-specific switch statement.
docs/developer/core-model.mdx+130−0
@@ -0,0 +1,130 @@
1---
2title: "Core Model"
3description: "The main data and runtime concepts in executor today."
4---
5
6The most important thing to understand about executor is that it does **not** model the system as one flat `source` row.
7
8The current model has a few separate concepts that each exist for a different reason.
9
10## The primary concepts
11
12### Source binding
13
14A source is the workspace-local installation record.
15
16It answers:
17
18- what is this integration called in this workspace?
19- is it enabled?
20- what namespace should its tools use?
21- what install-local config does it have?
22
23This is why a source carries local concerns like name, namespace, enabled state, binding config, and status.
24
25### Recipe
26
27A recipe is the shareable integration identity.
28
29It answers:
30
31- what integration definition is this?
32- what adapter produced it?
33- what family does it belong to?
34
35A recipe is meant to converge across workspaces when the underlying integration definition is the same.
36
37### Revision / materialization
38
39A recipe revision is the compiled result of an import.
40
41It answers:
42
43- what source config produced this compiled shape?
44- what manifest, documents, schema bundles, and operations belong to it?
45
46This is the durable execution artifact layer.
47
48### Operation IR
49
50Operations are the canonical callable tool index.
51
52They answer:
53
54- what tools exist?
55- how should they be searched and described?
56- how does invocation find the right persisted operation quickly?
57
58The operation layer exists because raw upstream documents are not a good direct query surface for search, policy, and invocation lookup.
59
60### Credential
61
62Credentials are private auth bindings.
63
64They answer:
65
66- who can authenticate for this binding?
67- for which slot?
68- using what auth kind and secret refs?
69
70Credentials are actor-scoped by default because two users in the same workspace may connect different identities to the same source.
71
72## Why the split matters
73
74This split fixes a few old problems:
75
76- shareable definition is no longer confused with workspace-local installation
77- auth is no longer implicitly one-token-per-source
78- materialized tool content is no longer stored directly under one workspace source
79- provider-specific import details do not need to become universal top-level columns
80
81## Binding config
82
83Source-specific connection config now lives in adapter-owned binding payloads:
84
85- `bindingVersion`
86- `binding`
87
88That means the core model does not need built-in fields forever for every provider-specific connection knob.
89
90Examples:
91
92- OpenAPI binding can carry `specUrl` and `defaultHeaders`
93- MCP binding can carry `transport`, `queryParams`, and `headers`
94- internal bindings can be empty
95
96The adapter owns serialization, decoding, defaults, and validation for that payload.
97
98## Families vs adapters
99
100Executor separates broad runtime families from adapter keys.
101
102Broad families:
103
104- `http_api`
105- `mcp`
106- `internal`
107
108Adapters are more specific:
109
110- `openapi`
111- `graphql`
112- `mcp`
113- future `google_discovery`
114- future `postman_collection`
115- future `snippet_bundle`
116
117This distinction keeps the runtime model broad and stable while still allowing importer-specific behavior.
118
119## Why this is the right shape
120
121The current model is designed so that new support usually means:
122
123- add or evolve an adapter
124- compile into the same recipe/revision/operation layers
125
126and not:
127
128- redesign how source persistence fundamentally works
129
130That is the main goal of the current architecture.
docs/developer/credentials-and-auth.mdx+100−0
@@ -0,0 +1,100 @@
1---
2title: "Credentials And Auth"
3description: "How executor models auth, interactive flows, and actor-scoped credential ownership."
4---
5
6Auth in executor is not treated as a side detail on the source row.
7
8It is modeled as its own layer because auth has different ownership and lifecycle semantics from source bindings and recipe materialization.
9
10## Auth ownership
11
12Credentials are scoped to:
13
14- workspace
15- source binding
16- actor
17- slot
18
19This is important because different users in the same workspace may connect different identities to the same source.
20
21## Auth slots
22
23Executor distinguishes where auth is used.
24
25Important current slots:
26
27- `runtime`
28- `import`
29
30Why this matters:
31
32- some integrations use the same auth for both
33- some need auth only to fetch or generate the materialization
34- some may eventually need setup/bootstrap-specific auth
35
36This is why source auth is more than a single token field.
37
38## Static credentials
39
40The common case today is still static auth backed by secret references.
41
42Examples:
43
44- bearer token
45- OAuth access token
46- OAuth refresh token
47
48The control plane stores secret refs, not raw secret values inline on the source or credential rows.
49
50## Interactive auth sessions
51
52Interactive auth, such as OAuth flows, is modeled separately from stored credentials.
53
54That separation exists because:
55
56- a pending auth flow has state and lifecycle of its own
57- it may be tied to an interaction or execution
58- it is not the same thing as a resolved credential
59
60This is why executor has auth sessions and credentials as separate concepts.
61
62## Why actor scope matters
63
64The old one-token-per-source assumption does not hold once:
65
66- multiple users share a workspace
67- each user connects their own Google account, GitHub account, or other external identity
68
69Actor-scoped ownership is the durable fix for that.
70
71## The next auth primitive
72
73One important extension area is dynamic credentials.
74
75Static secret refs are not always enough for integrations that:
76
77- derive short-lived auth by calling login or refresh endpoints
78- need app-specific runtime headers
79- require token renewal logic
80
81The likely next auth-layer primitive is an auth provider or auth material resolver:
82
83- configured with secret refs and stable inputs
84- produces runtime auth material on demand
85- caches it with expiry metadata
86
87That is broader than sources and should be reusable by future source adapters, tool providers, and code bundles.
88
89## Why auth is separated from recipes
90
91Recipes are shareable integration definitions.
92Credentials are private installation-specific state.
93
94That separation is important both for correctness and for shareability:
95
96- a recipe can be portable
97- a source binding can be local
98- credentials stay private
99
100This is the main reason auth is not modeled as part of the shareable recipe layer.
docs/developer/extending-executor.mdx+83−0
@@ -0,0 +1,83 @@
1---
2title: "Extending Executor"
3description: "How to add new source support without breaking the current architecture."
4---
5
6The best way to extend executor is to respect the current boundaries instead of stretching the core model.
7
8## First question: is it really a source?
9
10Not every new integration should be modeled as a source.
11
12Use the source model when the thing is:
13
14- a persistent external system
15- with install-local configuration
16- with auth state
17- that materializes into callable tools
18
19If the new thing is really:
20
21- a local tool library
22- a package bundle
23- a browser automation runtime
24
25then it may need a different top-level primitive instead of being shoved into the source model.
26
27## If it is a source, add an adapter
28
29The happy path for a new integration is:
30
311. define the adapter key and family
322. define the connect and binding config shape
333. materialize into documents, schema bundles, and operations
344. implement invocation
355. add tests against the canonical model
36
37The adapter should absorb provider-specific logic so the core does not have to.
38
39## What a new adapter should not do
40
41Avoid these patterns:
42
43- adding new provider-specific columns to generic tables because one adapter wants them
44- storing expanded presentation output as canonical truth
45- bypassing the operation layer and invoking directly from raw documents
46- treating auth as provider-specific ad hoc fields on the source row
47
48Those are the patterns that lead back to churn.
49
50## The standard for a good extension
51
52A good new adapter should make the core system feel boring.
53
54That means:
55
56- persistence still looks like recipe/revision/operations
57- auth still flows through the same credential/session primitives
58- discovery and inspection still work through the same catalog ideas
59- execution still delegates through the same tool and adapter boundaries
60
61If a new adapter needs deep new behavior in all of those places, that is usually a sign it may be a new primitive, not just a new adapter.
62
63## What feels like the next natural extensions
64
65The current architecture is well-suited to future additions like:
66
67- Google Discovery imports
68- Postman collection imports
69- snippet bundles
70- richer auth material providers
71
72Those should mostly be adapter and auth-layer work, not another persistence redesign.
73
74## Why this is the best setup
75
76The current setup is not trying to be abstract for its own sake.
77It is trying to keep the codebase in a state where:
78
79- core concepts stay stable
80- new support lands as extensions
81- source support does not require philosophy rewrites every few weeks
82
83That is the real reason the system is shaped around adapters, recipes, revisions, operations, and actor-scoped credentials.
docs/developer/mcp.mdx+51−0
@@ -0,0 +1,51 @@
1---
2title: "MCP"
3description: "How executor uses MCP both as a source family and as an external interface."
4---
5
6MCP shows up in executor in two different ways.
7
8## 1. Executor can connect to MCP servers
9
10This is the source side of MCP.
11
12When a user connects an MCP endpoint, executor treats it as a source family with MCP-specific connection, discovery, and invocation behavior. The control plane persists the binding and credential state, while MCP-specific execution behavior lives behind the adapter and codemode layers.
13
14This is why MCP is modeled as its own broad family instead of being treated like just another HTTP format.
15
16## 2. Executor can expose itself as an MCP server
17
18This is the outward-facing side of MCP.
19
20`packages/executor-mcp` and the `/mcp` route in `packages/server` let external MCP clients talk to the local executor runtime.
21
22That means external MCP hosts can:
23
24- discover executor tools
25- trigger executions
26- resume paused interactions
27- work against the same local workspace state as the CLI and browser UI
28
29## Why the distinction matters
30
31These two roles are related, but they are not the same thing:
32
33- inbound MCP means executor is acting as a client to a remote MCP server
34- outbound MCP means executor is acting as a server for external MCP clients
35
36Keeping that distinction clear avoids collapsing very different responsibilities into one vague "MCP integration" concept.
37
38## Where the logic lives
39
40Broadly:
41
42- control plane owns workspace state, bindings, credentials, and execution lifecycle
43- `packages/codemode-mcp` owns MCP tool loading and invocation helpers
44- `packages/executor-mcp` owns the local MCP server surface
45- `packages/server` mounts the `/mcp` handler
46
47## Why MCP stays flexible in this model
48
49Because MCP is handled as a family with its own adapter/runtime behavior, executor can support protocol-specific features such as sessions, elicitation, and resume without bending the generic `http_api` model to fit them.
50
51That is the main reason MCP is a first-class category in the architecture.
docs/developer/overview.mdx+108−0
@@ -0,0 +1,108 @@
1---
2title: "Control Plane Overview"
3description: "How the control plane is structured today and how the major pieces fit together."
4---
5
6Executor is built around one central idea:
7
8- turn connected systems into a durable, discoverable tool catalog
9- run TypeScript against that catalog inside a controlled runtime
10- keep connection state, auth, execution, and inspection in one local control plane
11
12## One-line architecture
13
14Executor is a local control plane that:
15
161. stores connected integrations as sources
172. materializes those sources into callable tools
183. exposes those tools to the runtime, the UI, and MCP clients
194. resolves auth and policy at invocation time
20
21## Major packages
22
23### `apps/executor`
24
25The CLI and daemon manager.
26
27Responsibilities:
28
29- start and stop the local daemon
30- submit executions
31- resume paused interactions
32- seed and inspect sources in development flows
33
34### `packages/server`
35
36The local server shell around the control plane.
37
38Responsibilities:
39
40- mount the HTTP API at `/v1`
41- mount the local MCP server at `/mcp`
42- serve the web UI
43
44### `packages/control-plane`
45
46The product core.
47
48Responsibilities:
49
50- source connection and lifecycle
51- auth and credential state
52- persistence
53- tool discovery and inspection
54- execution management
55- policy-aware invocation
56
57### Runtime and codemode packages
58
59These packages provide the execution and tool abstractions:
60
61- `packages/runtime-ses`
62- `packages/codemode-core`
63- `packages/codemode-openapi`
64- `packages/codemode-mcp`
65- `packages/react`
66
67## The mental model
68
69The current architecture is easiest to understand if you think of it as an adapter-based compiler pipeline:
70
71- adapters ingest external formats and protocols
72- the control plane stores a canonical internal representation
73- the runtime executes against that representation
74
75That is why executor has strong internal concepts like:
76
77- source bindings
78- recipes and revisions
79- materialized operations
80- schema bundles
81- actor-scoped credentials
82
83Those are not UI concepts. They are the durable internal model that lets executor support multiple integration styles without rewriting the core every time.
84
85## What is intentionally centralized
86
87Executor intentionally centralizes a few things that many products split across multiple services:
88
89- local identity and workspace bootstrap
90- source connection state
91- secret material references
92- tool inspection data
93- execution history
94- interaction/resume state
95
96This is why the UI, CLI, and local MCP entrypoint can all behave like one system instead of separate tools bolted together.
97
98## Why the architecture is shaped this way
99
100The current implementation optimizes for:
101
102- local-first operation
103- strong schema-aware tool usage
104- reusable connected integrations
105- minimal provider-specific logic in the control plane core
106- extensibility through adapters instead of one-off execution paths
107
108The rest of the developer docs explain how those goals show up in the current model.
docs/developer/persistence-and-migrations.mdx+86−0
@@ -0,0 +1,86 @@
1---
2title: "Persistence And Migrations"
3description: "How executor stores source state today and how migration logic is intended to work."
4---
5
6Executor persistence is designed around durable runtime state, not just CRUD storage.
7
8That means the database stores:
9
10- installation and workspace identity
11- source bindings
12- recipes and revisions
13- raw documents
14- schema bundles
15- operations
16- credentials and auth sessions
17- executions and interactions
18
19## Why the storage is layered
20
21The storage model is layered because these concerns have different reuse and ownership semantics.
22
23Examples:
24
25- raw documents are provenance
26- revisions are compiled materializations
27- operations are the hot-path query surface
28- source bindings are workspace-local
29- credentials are private and actor-scoped
30
31Trying to collapse those into one table or one document shape causes churn quickly.
32
33## What is normalized vs serialized
34
35Executor intentionally uses both relational columns and serialized JSON.
36
37Normalized:
38
39- ownership
40- ids and references
41- search and lookup fields
42- status and visibility
43- auth/session ownership
44
45Serialized:
46
47- adapter-owned binding config
48- source config blobs
49- provider metadata
50- some session payloads
51
52This is deliberate.
53The rule is to normalize what the core system queries and enforces, and serialize what belongs to adapter-specific contracts.
54
55## Migrations philosophy
56
57The intended migration model is:
58
59- SQL migrations move structural schema into the new shape
60- one-shot code migrations repair or rebuild data that SQL cannot derive sanely
61- steady-state runtime paths should not carry compatibility branches forever
62
63That last point matters.
64Compatibility logic belongs in upgrade code, not in normal reads and writes.
65
66## What is still acceptable in migration code
67
68One-shot rebuilds are still acceptable when:
69
70- the old data shape is structurally valid but not yet in the best compiled form
71- the rebuild can be derived from already-stored documents
72- the logic is ledgered and run once
73
74What is not acceptable:
75
76- provider-specific legacy fallbacks in steady-state runtime logic
77- carrying old columns indefinitely because one path still reads them
78
79## Why this supports extensibility
80
81This persistence shape is meant to let new integrations land in one of two ways:
82
83- add a new adapter that compiles into the same source model
84- add a genuinely new top-level primitive if the thing is not really a source
85
86That is how executor avoids turning every new integration into another schema redesign.
docs/developer/tool-catalog-and-execution.mdx+81−0
@@ -0,0 +1,81 @@
1---
2title: "Tool Catalog And Execution"
3description: "How source materialization becomes callable tools and how invocation works."
4---
5
6Executor turns connected integrations into a workspace tool catalog.
7
8That catalog is the thing the runtime actually executes against.
9
10## How tools are produced
11
12At a high level:
13
141. an adapter materializes a source
152. the materialization writes documents, schema bundles, and operations
163. the control plane loads those persisted operations into a workspace tool index
174. the runtime invokes one tool at a time through the control plane
18
19This means executor does not rebuild every integration from scratch on every execution.
20
21## Why operations exist as a separate layer
22
23The operation layer exists to support:
24
25- search
26- inspection
27- policy
28- fast tool lookup
29- tool description without loading huge raw documents every time
30
31Raw upstream documents are still kept, but they are not the best hot-path query surface.
32
33## Schema transport
34
35Executor uses compact operation-root schemas plus shared schema bundles.
36
37This is better than storing expanded per-tool schema blobs because it avoids:
38
39- massive duplicate schema payloads
40- slow formatting and rendering
41- treating presentation output as canonical storage
42
43The result is:
44
45- smaller payloads
46- more reusable schema graphs
47- cleaner tool detail responses
48
49## Tool catalog shape
50
51The tool catalog is built from:
52
53- persisted source tools
54- built-in executor tools
55
56That lets executor present one unified discovery and invocation surface even though the underlying tools come from different places.
57
58## Invocation flow
59
60At a high level, invocation works like this:
61
621. resolve the persisted operation by tool path
632. run policy and approval checks
643. resolve auth material for the correct slot
654. load the manifest and schema bundle needed for the call
665. delegate actual invocation to the adapter
67
68This is the key point:
69
70- the control plane orchestrates
71- the adapter performs the protocol-specific call
72
73## Why this is flexible
74
75This architecture is flexible because it keeps a stable middle:
76
77- the runtime only needs tools and invokers
78- the control plane only needs the canonical operation and auth model
79- adapters can vary widely at the source boundary without changing the runtime contract
80
81That is what makes it possible to add more source types without constantly rewriting execution logic.
docs/docs.json+45−3
@@ -9,10 +9,52 @@ · 8 unmodified lines
9 "dark": "#0D9373"9 "dark": "#0D9373"
10 },10 },
11 "navigation": {11 "navigation": {
12 "groups": [12 "tabs": [
13 {13 {
14 "group": "Getting Started",14 "tab": "Product",
15 "pages": ["introduction"]15 "groups": [
16 {
17 "group": "Introduction",
18 "pages": [
19 "introduction"
20 ]
21 }
22 ]
23 },
24 {
25 "tab": "Developer",
26 "groups": [
27 {
28 "group": "Control Plane",
29 "pages": [
30 "developer/overview",
31 "developer/core-model",
32 "developer/adapters-and-formats",
33 "developer/credentials-and-auth",
34 "developer/tool-catalog-and-execution",
35 "developer/persistence-and-migrations",
36 "developer/extending-executor"
37 ]
38 },
39 {
40 "group": "CLI",
41 "pages": [
42 "developer/cli"
43 ]
44 },
45 {
46 "group": "MCP",
47 "pages": [
48 "developer/mcp"
49 ]
50 },
51 {
52 "group": "Code Mode",
53 "pages": [
54 "developer/codemode"
55 ]
56 }
57 ]
16 }58 }
17 ]59 ]
18 },60 },
docs/introduction.mdx+14−0
@@ -4,3 +4,17 @@ description: "A local-first execution environment for AI agents." · 3 unmodified lines
4---4---
5 5
6`executor` is a local-first execution environment for AI agents. It gives an agent a TypeScript runtime, a discoverable tool catalog, and a single local place to connect external systems such as MCP servers, OpenAPI APIs, and GraphQL APIs.6`executor` is a local-first execution environment for AI agents. It gives an agent a TypeScript runtime, a discoverable tool catalog, and a single local place to connect external systems such as MCP servers, OpenAPI APIs, and GraphQL APIs.
7
8This docs site is split into two documentation surfaces:
9
10- product-facing docs for how to install and use executor
11- developer-facing docs for how executor is built and how to extend it
12
13The product-facing section will come later. The current docs start with the developer-facing architecture and implementation model.
14
15If you are trying to understand the current system shape, start with:
16
17- [Control Plane](/developer/overview)
18- [CLI](/developer/cli)
19- [MCP](/developer/mcp)
20- [Code Mode](/developer/codemode)
docs/package.json+10−0
@@ -0,0 +1,10 @@
1{
2 "name": "@executor/docs",
3 "private": true,
4 "type": "module",
5 "scripts": {
6 "dev": "bunx --bun mint dev --no-open --port 3337",
7 "typecheck": "echo 'No typecheck for @executor/docs'",
8 "validate": "bunx --bun mint validate"
9 }
10}
package.json+4−2
@@ -5,7 +5,8 @@ · 4 unmodified lines
5 "packageManager": "bun@1.2.22",5 "packageManager": "bun@1.2.22",
6 "workspaces": [6 "workspaces": [
7 "packages/*",7 "packages/*",
8 "apps/*"8 "apps/*",
9 "docs"
9 ],10 ],
10 "catalog": {11 "catalog": {
11 "@effect/cli": "^0.73.2",12 "@effect/cli": "^0.73.2",
@@ -19,7 +20,8 @@ · 7 unmodified lines
19 "zod": "^4.3.6"20 "zod": "^4.3.6"
20 },21 },
21 "scripts": {22 "scripts": {
22 "dev": "turbo run dev --filter=@executor/web",23 "dev": "turbo run dev",
24 "docs:dev": "turbo run dev --filter=@executor/docs",
23 "test": "turbo run test",25 "test": "turbo run test",
24 "executor": "./apps/executor/bin/executor",26 "executor": "./apps/executor/bin/executor",
25 "typecheck": "bun run --filter='*' typecheck",27 "typecheck": "bun run --filter='*' typecheck",

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t