@amalgm/tools 0.1.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.
- package/PURPOSE.md +87 -0
- package/README.md +62 -0
- package/dist/api-driver.d.ts +3 -0
- package/dist/api-driver.js +92 -0
- package/dist/artifact-files.d.ts +28 -0
- package/dist/artifact-files.js +115 -0
- package/dist/artifacts.d.ts +66 -0
- package/dist/artifacts.js +112 -0
- package/dist/bin/mcp.d.ts +2 -0
- package/dist/bin/mcp.js +13 -0
- package/dist/bin/tools.d.ts +2 -0
- package/dist/bin/tools.js +3 -0
- package/dist/cli-driver.d.ts +3 -0
- package/dist/cli-driver.js +52 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.js +123 -0
- package/dist/definition.d.ts +7 -0
- package/dist/definition.js +170 -0
- package/dist/ids.d.ts +7 -0
- package/dist/ids.js +38 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +7 -0
- package/dist/input.d.ts +4 -0
- package/dist/input.js +43 -0
- package/dist/mcp-server.d.ts +18 -0
- package/dist/mcp-server.js +61 -0
- package/dist/mcp.d.ts +9 -0
- package/dist/mcp.js +95 -0
- package/dist/module.d.ts +3 -0
- package/dist/module.js +22 -0
- package/dist/process.d.ts +22 -0
- package/dist/process.js +46 -0
- package/dist/query.d.ts +23 -0
- package/dist/query.js +36 -0
- package/dist/results.d.ts +6 -0
- package/dist/results.js +27 -0
- package/dist/schema.d.ts +3 -0
- package/dist/schema.js +26 -0
- package/dist/secrets.d.ts +3 -0
- package/dist/secrets.js +13 -0
- package/dist/selection.d.ts +10 -0
- package/dist/selection.js +18 -0
- package/dist/store.d.ts +17 -0
- package/dist/store.js +96 -0
- package/dist/toolbox.d.ts +46 -0
- package/dist/toolbox.js +204 -0
- package/dist/types.d.ts +172 -0
- package/dist/types.js +1 -0
- package/dist/updates.d.ts +7 -0
- package/dist/updates.js +57 -0
- package/docs/ENGINE_INTEGRATION.md +57 -0
- package/package.json +57 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import type { Writable } from 'node:stream';
|
|
2
|
+
type JsonSchema = {
|
|
3
|
+
type: 'object';
|
|
4
|
+
properties?: Record<string, {
|
|
5
|
+
type?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
}>;
|
|
9
|
+
required?: string[];
|
|
10
|
+
additionalProperties?: boolean;
|
|
11
|
+
description?: string;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
};
|
|
14
|
+
type ToolType = 'cli' | 'api' | 'mcp';
|
|
15
|
+
type Origin = 'user' | 'catalog' | 'system';
|
|
16
|
+
type Status = 'enabled' | 'disabled';
|
|
17
|
+
type SecretReferences = Record<string, string>;
|
|
18
|
+
interface BaseSource {
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
maxOutputBytes?: number;
|
|
21
|
+
}
|
|
22
|
+
interface CliSource extends BaseSource {
|
|
23
|
+
type: 'cli';
|
|
24
|
+
command: string;
|
|
25
|
+
args?: string[];
|
|
26
|
+
cwd?: string;
|
|
27
|
+
inputMode?: 'json-stdin' | 'argv' | 'none';
|
|
28
|
+
outputMode?: 'json' | 'text';
|
|
29
|
+
secretEnv?: SecretReferences;
|
|
30
|
+
}
|
|
31
|
+
interface ApiSource extends BaseSource {
|
|
32
|
+
type: 'api';
|
|
33
|
+
baseUrl: string;
|
|
34
|
+
secretHeaders?: SecretReferences;
|
|
35
|
+
}
|
|
36
|
+
interface McpSource extends BaseSource {
|
|
37
|
+
type: 'mcp';
|
|
38
|
+
transport: 'http' | 'sse' | 'stdio' | 'host';
|
|
39
|
+
url?: string;
|
|
40
|
+
command?: string;
|
|
41
|
+
args?: string[];
|
|
42
|
+
cwd?: string;
|
|
43
|
+
serverName?: string;
|
|
44
|
+
secretHeaders?: SecretReferences;
|
|
45
|
+
secretEnv?: SecretReferences;
|
|
46
|
+
}
|
|
47
|
+
type ToolSource = CliSource | ApiSource | McpSource;
|
|
48
|
+
interface CliTarget {
|
|
49
|
+
args?: string[];
|
|
50
|
+
}
|
|
51
|
+
interface ApiTarget {
|
|
52
|
+
method: string;
|
|
53
|
+
path: string;
|
|
54
|
+
}
|
|
55
|
+
interface McpTarget {
|
|
56
|
+
name: string;
|
|
57
|
+
}
|
|
58
|
+
type ActionTarget = CliTarget | ApiTarget | McpTarget;
|
|
59
|
+
interface ActionDefinition {
|
|
60
|
+
name: string;
|
|
61
|
+
id?: string;
|
|
62
|
+
displayName?: string;
|
|
63
|
+
description?: string;
|
|
64
|
+
inputSchema?: JsonSchema;
|
|
65
|
+
outputSchema?: Record<string, unknown>;
|
|
66
|
+
status?: Status;
|
|
67
|
+
target?: ActionTarget;
|
|
68
|
+
policy?: Record<string, unknown>;
|
|
69
|
+
metadata?: Record<string, unknown>;
|
|
70
|
+
}
|
|
71
|
+
interface ToolDefinition {
|
|
72
|
+
id: string;
|
|
73
|
+
name: string;
|
|
74
|
+
description?: string;
|
|
75
|
+
owner?: string;
|
|
76
|
+
origin?: Origin;
|
|
77
|
+
status?: Status;
|
|
78
|
+
source: ToolSource;
|
|
79
|
+
actions?: ActionDefinition[];
|
|
80
|
+
display?: Record<string, unknown>;
|
|
81
|
+
policy?: Record<string, unknown>;
|
|
82
|
+
metadata?: Record<string, unknown>;
|
|
83
|
+
}
|
|
84
|
+
interface ToolQuery {
|
|
85
|
+
type?: ToolType;
|
|
86
|
+
owner?: string;
|
|
87
|
+
origin?: Origin;
|
|
88
|
+
origins?: Origin[];
|
|
89
|
+
status?: Status;
|
|
90
|
+
}
|
|
91
|
+
type ToolPatch = Omit<Partial<ToolDefinition>, 'id' | 'source'> & {
|
|
92
|
+
source?: Partial<CliSource> | Partial<ApiSource> | Partial<McpSource>;
|
|
93
|
+
};
|
|
94
|
+
type ActionPatch = Omit<Partial<ActionDefinition>, 'id'>;
|
|
95
|
+
interface ToolRecord extends Omit<ToolDefinition, 'actions'> {
|
|
96
|
+
origin: Origin;
|
|
97
|
+
status: Status;
|
|
98
|
+
owner: string;
|
|
99
|
+
createdAt: string;
|
|
100
|
+
updatedAt: string;
|
|
101
|
+
}
|
|
102
|
+
interface ActionRecord extends Omit<ActionDefinition, 'id' | 'status' | 'inputSchema'> {
|
|
103
|
+
id: string;
|
|
104
|
+
toolId: string;
|
|
105
|
+
status: Status;
|
|
106
|
+
inputSchema: JsonSchema;
|
|
107
|
+
createdAt: string;
|
|
108
|
+
updatedAt: string;
|
|
109
|
+
}
|
|
110
|
+
interface Catalog {
|
|
111
|
+
version: 1;
|
|
112
|
+
revision: number;
|
|
113
|
+
tools: ToolRecord[];
|
|
114
|
+
actions: ActionRecord[];
|
|
115
|
+
}
|
|
116
|
+
interface ApplyResult {
|
|
117
|
+
tool: ToolRecord;
|
|
118
|
+
actions: ActionRecord[];
|
|
119
|
+
}
|
|
120
|
+
interface Loadout {
|
|
121
|
+
toolIds: string[];
|
|
122
|
+
}
|
|
123
|
+
type LoadoutInput = Loadout | string[];
|
|
124
|
+
interface ToolResult {
|
|
125
|
+
content: Array<{
|
|
126
|
+
type: 'text';
|
|
127
|
+
text: string;
|
|
128
|
+
}>;
|
|
129
|
+
structuredContent?: unknown;
|
|
130
|
+
isError?: boolean;
|
|
131
|
+
truncated?: boolean;
|
|
132
|
+
}
|
|
133
|
+
type SecretResolver = (reference: string) => string | undefined | Promise<string | undefined>;
|
|
134
|
+
interface CallOptions {
|
|
135
|
+
loadout?: LoadoutInput;
|
|
136
|
+
signal?: AbortSignal;
|
|
137
|
+
resolveSecret?: SecretResolver;
|
|
138
|
+
context?: unknown;
|
|
139
|
+
}
|
|
140
|
+
interface DriverCall {
|
|
141
|
+
tool: ToolRecord;
|
|
142
|
+
action: ActionRecord;
|
|
143
|
+
input: Record<string, unknown>;
|
|
144
|
+
options: CallOptions;
|
|
145
|
+
}
|
|
146
|
+
interface ToolDriver {
|
|
147
|
+
type: ToolType;
|
|
148
|
+
supports?(tool: ToolRecord): boolean;
|
|
149
|
+
call(request: DriverCall): Promise<ToolResult>;
|
|
150
|
+
}
|
|
151
|
+
interface ToolboxOptions {
|
|
152
|
+
stateDir?: string;
|
|
153
|
+
databaseFile?: string;
|
|
154
|
+
systemTools?: ToolDefinition[];
|
|
155
|
+
drivers?: ToolDriver[];
|
|
156
|
+
onChange?: (catalog: Catalog) => void | Promise<void>;
|
|
157
|
+
}
|
|
158
|
+
interface McpTool {
|
|
159
|
+
name: string;
|
|
160
|
+
description: string;
|
|
161
|
+
inputSchema: JsonSchema;
|
|
162
|
+
handler(input?: Record<string, unknown>): Promise<ToolResult>;
|
|
163
|
+
}
|
|
164
|
+
interface McpOptions extends CallOptions {
|
|
165
|
+
includeManagement?: boolean;
|
|
166
|
+
}
|
|
167
|
+
interface CliIo {
|
|
168
|
+
stdout?: Writable;
|
|
169
|
+
stderr?: Writable;
|
|
170
|
+
toolbox?: import('./toolbox.js').Toolbox;
|
|
171
|
+
}
|
|
172
|
+
export type { ActionDefinition, ActionRecord, ActionTarget, ApiSource, ApiTarget, ApplyResult, CallOptions, Catalog, CliIo, CliSource, CliTarget, DriverCall, JsonSchema, Loadout, LoadoutInput, McpOptions, McpSource, McpTarget, McpTool, Origin, SecretResolver, Status, ToolDefinition, ToolDriver, ToolboxOptions, ToolRecord, ToolResult, ToolPatch, ActionPatch, ToolQuery, ToolSource, ToolType, };
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Toolbox } from './toolbox.js';
|
|
2
|
+
import type { ActionDefinition, ActionPatch, ActionRecord, ApplyResult, ToolPatch } from './types.js';
|
|
3
|
+
type UpdatePort = Pick<Toolbox, 'action' | 'apply' | 'get'>;
|
|
4
|
+
declare function updateTool(toolbox: UpdatePort, toolId: string, patch: ToolPatch): Promise<ApplyResult>;
|
|
5
|
+
declare function upsertAction(toolbox: UpdatePort, toolId: string, definition: ActionDefinition): Promise<ActionRecord>;
|
|
6
|
+
declare function updateAction(toolbox: UpdatePort, actionId: string, patch: ActionPatch): Promise<ActionRecord>;
|
|
7
|
+
export { updateAction, updateTool, upsertAction };
|
package/dist/updates.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
function actionDefinition(action) {
|
|
2
|
+
const { id, toolId: _toolId, createdAt: _createdAt, updatedAt: _updatedAt, ...definition } = action;
|
|
3
|
+
return { ...structuredClone(definition), id };
|
|
4
|
+
}
|
|
5
|
+
function toolDefinition(result) {
|
|
6
|
+
const { createdAt: _createdAt, updatedAt: _updatedAt, ...tool } = result.tool;
|
|
7
|
+
return { ...structuredClone(tool), actions: result.actions.map(actionDefinition) };
|
|
8
|
+
}
|
|
9
|
+
function mergedObject(current, patch) {
|
|
10
|
+
return patch === undefined ? current : { ...(current || {}), ...patch };
|
|
11
|
+
}
|
|
12
|
+
async function updateTool(toolbox, toolId, patch) {
|
|
13
|
+
const current = toolbox.get(toolId);
|
|
14
|
+
if (!current)
|
|
15
|
+
throw new Error(`Unknown tool: ${toolId}`);
|
|
16
|
+
const definition = toolDefinition(current);
|
|
17
|
+
return toolbox.apply({
|
|
18
|
+
...definition,
|
|
19
|
+
...patch,
|
|
20
|
+
id: definition.id,
|
|
21
|
+
source: mergedObject(definition.source, patch.source),
|
|
22
|
+
display: mergedObject(definition.display, patch.display),
|
|
23
|
+
policy: mergedObject(definition.policy, patch.policy),
|
|
24
|
+
metadata: mergedObject(definition.metadata, patch.metadata),
|
|
25
|
+
actions: patch.actions === undefined ? definition.actions : patch.actions,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
async function upsertAction(toolbox, toolId, definition) {
|
|
29
|
+
const current = toolbox.get(toolId);
|
|
30
|
+
if (!current)
|
|
31
|
+
throw new Error(`Unknown tool: ${toolId}`);
|
|
32
|
+
const actions = current.actions.map(actionDefinition);
|
|
33
|
+
const canonicalId = `${current.tool.id}.${definition.name}`;
|
|
34
|
+
const index = actions.findIndex((action) => action.id === canonicalId);
|
|
35
|
+
if (index === -1)
|
|
36
|
+
actions.push(definition);
|
|
37
|
+
else
|
|
38
|
+
actions[index] = definition;
|
|
39
|
+
const result = await toolbox.apply({ ...toolDefinition(current), actions });
|
|
40
|
+
return result.actions.find((action) => action.id === canonicalId);
|
|
41
|
+
}
|
|
42
|
+
async function updateAction(toolbox, actionId, patch) {
|
|
43
|
+
const current = toolbox.action(actionId);
|
|
44
|
+
if (!current)
|
|
45
|
+
throw new Error(`Unknown action: ${actionId}`);
|
|
46
|
+
const definition = actionDefinition(current);
|
|
47
|
+
return upsertAction(toolbox, current.toolId, {
|
|
48
|
+
...definition,
|
|
49
|
+
...patch,
|
|
50
|
+
id: definition.id,
|
|
51
|
+
name: definition.name,
|
|
52
|
+
target: mergedObject(definition.target, patch.target),
|
|
53
|
+
policy: mergedObject(definition.policy, patch.policy),
|
|
54
|
+
metadata: mergedObject(definition.metadata, patch.metadata),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
export { updateAction, updateTool, upsertAction };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Engine integration
|
|
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.
|
|
6
|
+
|
|
7
|
+
## Tools owns
|
|
8
|
+
|
|
9
|
+
- tool and action definition, validation, identity, and persistence;
|
|
10
|
+
- atomic apply, enable, disable, and removal behavior;
|
|
11
|
+
- loadout selection semantics and deterministic MCP action names;
|
|
12
|
+
- CLI and HTTP API execution drivers and output bounds;
|
|
13
|
+
- SDK, CLI, Toolbox management MCP tools, and action MCP projection;
|
|
14
|
+
- the connection projection consumed by an MCP session host.
|
|
15
|
+
|
|
16
|
+
## Engine owns
|
|
17
|
+
|
|
18
|
+
- first-party action implementations supplied as `systemTools` and drivers;
|
|
19
|
+
- authenticated capability context and the execution-time secret resolver;
|
|
20
|
+
- the long-lived MCP connection/session host;
|
|
21
|
+
- state-event projection, REST shape translation, UI composition, and one-time
|
|
22
|
+
import from Engine's superseded Toolbox tables or JSON file.
|
|
23
|
+
|
|
24
|
+
Agents owns agent records and their loadout ids. Tools treats those ids as
|
|
25
|
+
input to product-owned selection. Neither product is allowed to rewrite the
|
|
26
|
+
other through a Core adapter.
|
|
27
|
+
|
|
28
|
+
Engine adapters call one `Toolbox` instance. They do not write its SQLite
|
|
29
|
+
database or independently normalize, select, name, or execute tool actions.
|
|
30
|
+
An absent loadout must be passed as `undefined`; an explicitly empty loadout
|
|
31
|
+
must be passed as `[]`.
|
|
32
|
+
|
|
33
|
+
For external MCP tools, Engine supplies a `ToolDriver` with type `mcp`. That
|
|
34
|
+
driver delegates to Engine's existing MCP session owner. The Toolbox exposes
|
|
35
|
+
connection definitions through `connections(loadout)` but never starts a
|
|
36
|
+
parallel client or owns the same remote session twice.
|
|
37
|
+
|
|
38
|
+
System tools are injected at construction and remain outside user storage.
|
|
39
|
+
Engine can therefore update its built-in catalog with its own release while
|
|
40
|
+
all standalone Toolbox behavior remains canonical in this package.
|
|
41
|
+
|
|
42
|
+
## Source flow and completed cutover
|
|
43
|
+
|
|
44
|
+
Engine now consumes Tools as follows:
|
|
45
|
+
|
|
46
|
+
1. Build this repository.
|
|
47
|
+
2. Copy generated `dist/`, `PURPOSE.md`, and package metadata into
|
|
48
|
+
`runtime/products/tools/` with a deterministic source manifest.
|
|
49
|
+
3. Mount the package CLI and MCP definitions over Engine's single Toolbox
|
|
50
|
+
service.
|
|
51
|
+
4. Import existing records once, preserving canonical ids and status.
|
|
52
|
+
5. Remove Engine's superseded Toolbox tables after successful import.
|
|
53
|
+
|
|
54
|
+
Product changes begin here. Generated Engine copies are never edited by hand.
|
|
55
|
+
Engine runtime readers and writers use only this product database. The importer
|
|
56
|
+
is the only module allowed to understand the superseded storage shapes, and
|
|
57
|
+
malformed source data blocks destructive cleanup.
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@amalgm/tools",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Local-first tool definitions, Toolbox registry, and agent execution surfaces.",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"private": false,
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/amalgm-inc/amalgm-tools.git"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "dist/index.js",
|
|
16
|
+
"types": "dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./mcp": {
|
|
23
|
+
"types": "./dist/mcp.d.ts",
|
|
24
|
+
"default": "./dist/mcp.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"bin": {
|
|
28
|
+
"amalgm-tools": "./dist/bin/tools.js",
|
|
29
|
+
"amalgm-tools-mcp": "./dist/bin/mcp.js"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"docs",
|
|
33
|
+
"dist",
|
|
34
|
+
"PURPOSE.md",
|
|
35
|
+
"README.md"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && tsx scripts/mark-executables.ts",
|
|
39
|
+
"check": "tsx scripts/check-tree.ts && tsc -p tsconfig.json && tsc -p tsconfig.test.json",
|
|
40
|
+
"test": "tsx --test --test-concurrency=1 --test-timeout=30000 test/*.test.ts",
|
|
41
|
+
"verify": "npm run check && npm run build && npm test",
|
|
42
|
+
"prepack": "npm run build"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=20"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@amalgm/core": "^0.1.0",
|
|
49
|
+
"better-sqlite3": "^12.6.2"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
53
|
+
"@types/node": "^20.19.43",
|
|
54
|
+
"tsx": "^4.23.1",
|
|
55
|
+
"typescript": "^5.9.3"
|
|
56
|
+
}
|
|
57
|
+
}
|