@amalgm/tools 0.1.4 → 0.1.6

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/PURPOSE.md CHANGED
@@ -2,19 +2,20 @@
2
2
 
3
3
  ## Purpose
4
4
 
5
- Amalgm Tools lets a user define, keep, select, and run agent capabilities
6
- without installing Amalgm Engine. It serves people building agents,
5
+ Amalgm Tools lets a user define, keep, select, and run agent capabilities as a
6
+ standalone product or inside Amalgm. It serves people building agents,
7
7
  automations, and applications that need one small local source of truth for
8
8
  CLI, HTTP API, and MCP tools. When the product is healthy, every callable
9
9
  action has one stable identity and one owning tool, a selected loadout exposes
10
10
  only its granted capabilities, and the SDK, CLI, and MCP surfaces all observe
11
11
  and execute the same catalog.
12
12
 
13
- Amalgm Engine is the composition root for the complete Amalgm runtime. This
14
- repository owns the Tools product and its Toolbox. Engine may provide
15
- first-party actions, credentials, agent loadouts, state events, and UI
16
- composition through public adapters, but it does not maintain a second tool
17
- registry or execution implementation.
13
+ Amalgm Shell is the active machine composition root. This repository owns the
14
+ Tools product and its Toolbox. Shell may provide first-party product
15
+ projections, credential resolution, agent loadouts, state events, and route
16
+ mounting through public adapters, but it does not maintain a second tool
17
+ registry or execution implementation. Amalgm Engine is deprecated historical
18
+ and parity evidence only.
18
19
 
19
20
  ## Primitives
20
21
 
@@ -33,11 +34,14 @@ registry or execution implementation.
33
34
  one or more tools; selecting a tool never changes that server's identity.
34
35
  - A **system tool** is an embedder-owned definition projected into the catalog;
35
36
  it is not user state.
36
- - A **notification** is one request to inform the current user; a channel
37
- adapter turns that intent into delivery.
37
+ - A **notification compatibility adapter** is the retained legacy projection
38
+ of `notifications.notify_user`; Channels owns current durable delivery.
38
39
 
39
40
  ## Axioms
40
41
 
42
+ Managed releases bind to one exact published Core version and build from the
43
+ locked dependency graph on the supported Node toolchain.
44
+
41
45
  1. Every action belongs to exactly one tool and has the canonical id
42
46
  `<tool-id>.<action-name>`.
43
47
  2. Tool ids are stable, globally unique within one Toolbox, and never change
@@ -74,19 +78,21 @@ registry or execution implementation.
74
78
  15. System tools are immutable projections supplied by the embedder. Removing
75
79
  an embedder projection removes it from the catalog without mutating user
76
80
  state.
77
- 16. The SDK owns behavior. CLI, MCP, HTTP, UI, and Engine integrations only
78
- adapt the public Toolbox service.
81
+ 16. The SDK owns behavior. CLI, MCP, HTTP, UI, Shell, and other host
82
+ integrations only adapt the public Toolbox service.
79
83
  17. TypeScript under `src/` is the product source of truth. JavaScript and
80
84
  declarations under `dist/` are generated together and are never edited by
81
85
  hand.
82
86
  18. Tools may store opaque references owned by another product, but neither
83
87
  Tools nor a Core adapter silently rewrites that product. A cross-product
84
88
  workflow has one explicit product owner.
85
- 19. `notifications.notify_user` addresses only the current user. Callers may
86
- supply content and severity, never a recipient or delivery credential.
87
- 20. Notification channels are host capabilities. Tools owns validation and
88
- result semantics; an injected channel adapter owns formatting, recipient
89
- lookup, credentials, and delivery.
89
+ 19. The retained `notifications.notify_user` compatibility adapter addresses
90
+ only the current user. Callers may supply content and severity, never a
91
+ recipient or delivery credential.
92
+ 20. Channels owns current notification validation, persistence, formatting,
93
+ recipient lookup, credentials, and delivery. Tools may project Channels'
94
+ official MCP descriptors or expose its explicitly legacy email adapter; it
95
+ never becomes a second durable delivery authority.
90
96
  21. Reopening a Toolbox preserves the temporal fields of every semantically
91
97
  unchanged system projection already present in its portable index; boot
92
98
  never rewrites tracked bytes merely to stamp the current machine's time.
@@ -119,5 +125,5 @@ grants all of its enabled actions; selecting one action grants only that
119
125
  action. Disabling or deleting a tool immediately removes all of its actions
120
126
  from list and call surfaces. CLI arguments are passed directly to a process,
121
127
  API paths stay under their registered origin, and MCP calls cross only the
122
- driver boundary supplied by the composing host. Engine and standalone users
128
+ driver boundary supplied by the composing host. Shell and standalone users
123
129
  therefore get the same identities, validation, selection, and execution rules.
package/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # Amalgm Tools
2
2
 
3
- `@amalgm/tools` is the standalone Tools product from Amalgm Engine. It owns
4
- tool definitions, the local Toolbox catalog, loadout selection, execution,
5
- and MCP projection. It can be used without the rest of Amalgm.
3
+ `@amalgm/tools` is the standalone Tools product. It owns tool definitions, the
4
+ local Toolbox catalog, immutable deployments, loadout selection, execution,
5
+ and MCP projection. It can be used without the rest of Amalgm and is composed
6
+ into the machine product by `@amalgm/shell`.
6
7
 
7
8
  ```js
8
9
  import { defineTool, Toolbox } from '@amalgm/tools';
@@ -82,18 +83,20 @@ const server = createToolboxHttpServer({ toolbox });
82
83
  await server.listen(8083);
83
84
  ```
84
85
 
85
- The read adapter serves the Engine-compatible `GET /toolbox`,
86
+ The read adapter serves the legacy-compatible `GET /toolbox`,
86
87
  `GET /toolbox/tools?id=...`, and `GET /toolbox/actions?id=...` routes over
87
88
  the same live Toolbox used by CLI and MCP consumers. Mutation routes return
88
89
  405 until their legacy record fields can be represented without data loss.
89
90
 
90
91
  ## Notifications
91
92
 
92
- `Notifications` projects the first-party `notifications.notify_user` action
93
- into the Toolbox. The action validates one channel-neutral request and hands
94
- it to an injected email delivery adapter; recipient lookup and credentials
95
- never enter the tool record. `createNotificationsHttpServer` exposes
96
- `GET /email` as the channel capability document used by the shell.
93
+ Channels is the current owner of durable notification delivery. Shell projects
94
+ the official `@amalgm/channels` MCP descriptors into Toolbox as the
95
+ `channels` first-party tool. Tools still exports `Notifications`,
96
+ `notificationToolDefinition`, and `createNotificationsHttpServer` as a legacy
97
+ compatibility adapter for the retired `notifications.notify_user` and
98
+ `GET /email` shapes; that adapter is not the current platform delivery store
99
+ and must not be presented as a second Channels implementation.
97
100
 
98
101
  ## Tool types
99
102
 
@@ -105,4 +108,5 @@ never enter the tool record. `createNotificationsHttpServer` exposes
105
108
  Secret values are never part of definitions. `secretEnv` and `secretHeaders`
106
109
  contain opaque references resolved through `CallOptions.resolveSecret`.
107
110
  See [PURPOSE.md](./PURPOSE.md) for the complete contract and
108
- [ENGINE_INTEGRATION.md](./docs/ENGINE_INTEGRATION.md) for composition.
111
+ [SHELL_INTEGRATION.md](./docs/SHELL_INTEGRATION.md) for active composition.
112
+ The [Engine integration](./docs/ENGINE_INTEGRATION.md) page is historical only.
@@ -1,60 +1,13 @@
1
- # Engine integration
1
+ # Historical Engine integration
2
2
 
3
- `@amalgm/tools` is the canonical Tools and Toolbox product. Amalgm Engine is a
4
- composition root and must adapt this public service rather than maintain a
5
- second registry.
3
+ Amalgm Engine is deprecated. Its Toolbox tables, MCP-connection registry,
4
+ notification adapter, and copied product output are read-only migration and
5
+ parity evidence. They are not active persistence, a source-flow destination,
6
+ or a runtime fallback.
6
7
 
7
- ## Tools owns
8
+ The old workflow copied generated Tools output into Engine and imported legacy
9
+ records. Active composition now installs the published package in
10
+ `@amalgm/shell`, which supplies host effects and projects other products
11
+ through their official MCP descriptors.
8
12
 
9
- - tool and action definition, validation, identity, and persistence;
10
- - atomic apply, enable, disable, and removal behavior;
11
- - immutable deployment history, current heads, and the Tools Live surface;
12
- - loadout selection semantics and deterministic MCP action names;
13
- - CLI and HTTP API execution drivers and output bounds;
14
- - SDK, CLI, Toolbox management MCP tools, and action MCP projection;
15
- - the connection projection consumed by an MCP session host.
16
-
17
- ## Engine owns
18
-
19
- - first-party action implementations supplied as `systemTools` and drivers;
20
- - authenticated capability context and the execution-time secret resolver;
21
- - the long-lived MCP connection/session host;
22
- - the machine-local SQLite path, portable deployment directory, Live binding,
23
- state-event projection, REST shape translation, UI composition, and one-time
24
- import from Engine's superseded Toolbox tables or JSON file.
25
-
26
- Agents owns agent records and their loadout ids. Tools treats those ids as
27
- input to product-owned selection. Neither product is allowed to rewrite the
28
- other through a Core adapter.
29
-
30
- Engine adapters call one `Toolbox` instance. They do not write its SQLite
31
- database, synchronize database pages, or independently normalize, select,
32
- name, deploy, or execute tool actions.
33
- An absent loadout must be passed as `undefined`; an explicitly empty loadout
34
- must be passed as `[]`.
35
-
36
- For external MCP tools, Engine supplies a `ToolDriver` with type `mcp`. That
37
- driver delegates to Engine's existing MCP session owner. The Toolbox exposes
38
- connection definitions through `connections(loadout)` but never starts a
39
- parallel client or owns the same remote session twice.
40
-
41
- System tools are injected at construction and remain outside user storage.
42
- Engine can therefore update its built-in catalog with its own release while
43
- all standalone Toolbox behavior remains canonical in this package.
44
-
45
- ## Source flow and completed cutover
46
-
47
- Engine now consumes Tools as follows:
48
-
49
- 1. Build this repository.
50
- 2. Copy generated `dist/`, `PURPOSE.md`, and package metadata into
51
- `runtime/products/tools/` with a deterministic source manifest.
52
- 3. Mount the package CLI and MCP definitions over Engine's single Toolbox
53
- service.
54
- 4. Import existing records once, preserving canonical ids and status.
55
- 5. Remove Engine's superseded Toolbox tables after successful import.
56
-
57
- Product changes begin here. Generated Engine copies are never edited by hand.
58
- Engine runtime readers and writers use only this product database. The importer
59
- is the only module allowed to understand the superseded storage shapes, and
60
- malformed source data blocks destructive cleanup.
13
+ See [SHELL_INTEGRATION.md](./SHELL_INTEGRATION.md) for the current boundary.
@@ -0,0 +1,44 @@
1
+ # Shell integration
2
+
3
+ `@amalgm/tools` is the canonical Toolbox product. `@amalgm/shell` constructs
4
+ one Toolbox for a machine user, supplies its machine-local SQLite path and
5
+ portable deployment directory, and mounts the product's public HTTP and MCP
6
+ adapters.
7
+
8
+ ## Tools owns
9
+
10
+ - stable tool and action identity;
11
+ - immutable deployment history and current deployment heads;
12
+ - loadout selection and deterministic MCP names;
13
+ - CLI and API drivers, validation, cancellation, and output bounds;
14
+ - the Toolbox management MCP surface; and
15
+ - the versioned `deployment.activate` Live surface.
16
+
17
+ ## Shell owns
18
+
19
+ - the exact `@amalgm/tools` package version in the Shell release;
20
+ - the one host MCP driver and authenticated loopback routes;
21
+ - machine-local SQLite placement and the portable deployment directory;
22
+ - execution-time credential resolution;
23
+ - projection of owning products' official MCP descriptors as immutable system
24
+ tools; and
25
+ - binding Tools' deployment surface to broader product state when enabled.
26
+
27
+ Agents stores loadout identifiers; Chat pins the exact Toolbox `revisionId`
28
+ during preparation. Neither product writes Tools persistence.
29
+
30
+ ## First-party products and Channels
31
+
32
+ Shell builds first-party records from the official MCP descriptors exported by
33
+ Agents, Apps, Automations, Browser, Channels, Chat, and Tools. Selecting a
34
+ record controls capability; it does not transfer ownership of the underlying
35
+ product to Tools.
36
+
37
+ Channels owns current notification validation and durable delivery. The
38
+ `Notifications` class still exported by Tools is a legacy compatibility
39
+ adapter and is not the path Shell uses for the Channels product.
40
+
41
+ ## Engine evidence
42
+
43
+ Engine may be read to compare legacy Toolbox, MCP-connection, `/email`, or
44
+ notification shapes. It is never composed or copied into the active runtime.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amalgm/tools",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Local-first tool definitions, Toolbox registry, and agent execution surfaces.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -36,20 +36,21 @@
36
36
  "docs",
37
37
  "dist",
38
38
  "PURPOSE.md",
39
- "README.md"
39
+ "README.md",
40
+ "skills"
40
41
  ],
41
42
  "scripts": {
42
- "build": "rm -rf dist && tsc -p tsconfig.build.json && tsx scripts/mark-executables.ts",
43
+ "build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && tsx scripts/mark-executables.ts",
43
44
  "check": "tsx scripts/check-tree.ts && tsc -p tsconfig.json && tsc -p tsconfig.test.json",
44
45
  "test": "tsx --test --test-concurrency=1 --test-timeout=30000 test/*.test.ts",
45
46
  "verify": "npm run check && npm run build && npm test",
46
47
  "prepack": "npm run build"
47
48
  },
48
49
  "engines": {
49
- "node": ">=20"
50
+ "node": ">=24"
50
51
  },
51
52
  "dependencies": {
52
- "@amalgm/core": "0.2.0",
53
+ "@amalgm/core": "0.4.7",
53
54
  "better-sqlite3": "^12.6.2"
54
55
  },
55
56
  "devDependencies": {
@@ -0,0 +1,185 @@
1
+ ---
2
+ name: tools
3
+ description: Define, deploy, select, and execute stable Amalgm tools through @amalgm/tools. Use when creating CLI, API, or MCP tool definitions; managing immutable tool deployments and loadouts; projecting tools into MCP; resolving secrets at call time; or inspecting the local Toolbox catalog.
4
+ ---
5
+
6
+ # Amalgm Tools
7
+
8
+ Tools is the capability layer between an agent and the things it can do. It
9
+ gives every tool and action a stable identity, stores user-authored tools as
10
+ immutable deployments, selects bounded loadouts for a run, and executes CLI,
11
+ HTTP API, or MCP actions through one result contract. It works as a standalone
12
+ ESM package and is also composed into the Amalgm machine runtime.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @amalgm/tools
18
+ ```
19
+
20
+ Node.js 20 or newer is required. The package exposes:
21
+
22
+ - `@amalgm/tools` for definitions, the `Toolbox`, deployments, MCP projection,
23
+ ids, and driver contracts.
24
+ - `@amalgm/tools/mcp` for MCP helpers.
25
+ - `@amalgm/tools/http` for the read-only Toolbox HTTP adapter.
26
+ - `amalgm-tools` for local catalog management and execution.
27
+ - `amalgm-tools-mcp` for a newline-delimited stdio MCP server.
28
+
29
+ ## Define and run a tool
30
+
31
+ ```js
32
+ import { defineTool, Toolbox } from '@amalgm/tools';
33
+
34
+ const toolbox = new Toolbox({ stateDir: './.tools' });
35
+
36
+ await toolbox.apply(defineTool({
37
+ id: 'hello',
38
+ name: 'Hello',
39
+ source: {
40
+ type: 'cli',
41
+ command: 'node',
42
+ inputMode: 'json-stdin',
43
+ outputMode: 'json',
44
+ },
45
+ actions: [{
46
+ name: 'say',
47
+ target: { args: ['./hello.mjs'] },
48
+ inputSchema: {
49
+ type: 'object',
50
+ required: ['name'],
51
+ properties: { name: { type: 'string' } },
52
+ additionalProperties: false,
53
+ },
54
+ }],
55
+ }));
56
+
57
+ const result = await toolbox.call('hello.say', { name: 'Ada' });
58
+ toolbox.close();
59
+ ```
60
+
61
+ The tool id is `hello`; the derived action id is `hello.say`. Those ids are the
62
+ references agents, loadouts, and callers keep. Display names and implementations
63
+ can evolve without changing identity.
64
+
65
+ ## Tool sources
66
+
67
+ Every definition has exactly one source type:
68
+
69
+ - `cli` executes a command directly with `spawn`; no shell is inserted. Choose
70
+ JSON stdin, argv, or no input, and JSON or text output.
71
+ - `api` calls a path beneath one declared same-origin `baseUrl`; redirects are
72
+ refused.
73
+ - `mcp` projects actions from an HTTP, SSE, stdio, or host-mounted MCP server.
74
+ A composing host supplies the MCP driver that owns discovery, sessions, and
75
+ calls.
76
+
77
+ Sources may set `timeoutMs` and `maxOutputBytes`. These bounds travel with the
78
+ definition, so execution policy is visible before the call begins.
79
+
80
+ ## Immutable deployments and state
81
+
82
+ Applying an intentional semantic change creates an immutable deployment
83
+ document and advances the tool's local head atomically. Reapplying equivalent
84
+ bytes resolves to the same content identity. `catalog()` exposes both:
85
+
86
+ - `revision`, a local numeric freshness counter for presentation.
87
+ - `revisionId`, the digest of the exact current user deployments and system
88
+ projections. Use this immutable id when preparing an agent run.
89
+
90
+ By default state resolves through the shared Amalgm state-dir law:
91
+ `AMALGM_TOOLS_DIR`, then `AMALGM_DIR/toolbox`, then the current user's scoped
92
+ Toolbox directory. Pass `stateDir` for a self-contained Toolbox, or separate
93
+ portable deployments from machine-local coordination state:
94
+
95
+ ```js
96
+ const toolbox = new Toolbox({
97
+ deploymentDir: '/amalgm/users/person@example.com/toolbox',
98
+ databaseFile: '/machine-state/services/tools/tools.db',
99
+ });
100
+ ```
101
+
102
+ Deployment documents are portable. The SQLite database, WAL, local index, and
103
+ legacy flat artifacts are projections and should not be synchronized.
104
+
105
+ ## Loadouts
106
+
107
+ A loadout is a list of tool ids that bounds which enabled actions are visible
108
+ and callable for one context:
109
+
110
+ ```js
111
+ const loadout = { toolIds: ['hello', 'browser'] };
112
+ const visible = toolbox.list(loadout);
113
+ const result = await toolbox.call('hello.say', { name: 'Ada' }, { loadout });
114
+ ```
115
+
116
+ Passing no loadout uses the enabled catalog. Passing a loadout makes exclusion
117
+ explicit: an action outside it cannot be reached merely because it exists in
118
+ the Toolbox.
119
+
120
+ ## Secrets
121
+
122
+ Definitions never contain secret values. `secretEnv` and `secretHeaders` hold
123
+ opaque references, and the caller resolves them only for the duration of an
124
+ execution:
125
+
126
+ ```js
127
+ await toolbox.call('billing.lookup', { customerId: 'cus_123' }, {
128
+ resolveSecret: async (reference) => secretStore.get(reference),
129
+ });
130
+ ```
131
+
132
+ This keeps portable definitions and deployment documents safe to inspect and
133
+ synchronize.
134
+
135
+ ## CLI
136
+
137
+ The CLI prints JSON and exits non-zero on failure:
138
+
139
+ ```bash
140
+ amalgm-tools apply ./tool.mjs
141
+ amalgm-tools list
142
+ amalgm-tools catalog
143
+ amalgm-tools show hello.say
144
+ amalgm-tools enable hello.say
145
+ amalgm-tools disable hello.say
146
+ amalgm-tools remove hello
147
+ amalgm-tools run hello.say --input '{"name":"Ada"}'
148
+ amalgm-tools connections
149
+ ```
150
+
151
+ Use `--state-dir DIR` to select a Toolbox and `--loadout one,two` to bound
152
+ `list`, `run`, or connection projection.
153
+
154
+ ## MCP and HTTP surfaces
155
+
156
+ `createMcpTools(toolbox)` projects management operations and enabled actions,
157
+ while `createMcpServer()` creates a complete stdio server. A machine host can
158
+ also use `defineHostMcpTool` to represent another product's official MCP
159
+ descriptors as one system-owned Toolbox record.
160
+
161
+ For read-only dashboards, mount the HTTP adapter:
162
+
163
+ ```js
164
+ import { Toolbox } from '@amalgm/tools';
165
+ import { createToolboxHttpServer } from '@amalgm/tools/http';
166
+
167
+ const toolbox = new Toolbox({ stateDir: './.tools' });
168
+ const server = createToolboxHttpServer({ toolbox });
169
+ await server.listen(8083);
170
+ ```
171
+
172
+ It serves the legacy-compatible `GET /toolbox`, `GET /toolbox/tools?id=...`,
173
+ and `GET /toolbox/actions?id=...` catalog routes. Mutations belong through the
174
+ SDK, CLI, or MCP surface.
175
+
176
+ ## How Tools fits into Amalgam
177
+
178
+ The machine runtime projects the official capabilities from Agents, Apps,
179
+ Automations, Browser, Channels, Chat, and Tools into one Toolbox without moving
180
+ their ownership into Tools. Tools owns identity, deployment, selection, and
181
+ execution; each product continues to own its own behavior and state.
182
+
183
+ Channels is the current owner of durable notifications. The notification
184
+ exports retained by `@amalgm/tools` are compatibility adapters for retired
185
+ notification shapes, not a second delivery system.