toolcraft 0.0.92 → 0.0.94
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/README.md +74 -4
- package/composition.json +1 -6
- package/dist/agent-defs.d.ts +1 -0
- package/dist/agent-defs.js +1 -0
- package/dist/agent-human-in-loop.d.ts +1 -0
- package/dist/agent-human-in-loop.js +1 -0
- package/dist/agent-mcp-config.d.ts +1 -0
- package/dist/agent-mcp-config.js +1 -0
- package/dist/auth-store.d.ts +1 -0
- package/dist/auth-store.js +1 -0
- package/dist/cli.d.ts +4 -1
- package/dist/cli.js +23 -64
- package/dist/composition.json +1 -6
- package/dist/config-mutations.d.ts +1 -0
- package/dist/config-mutations.js +1 -0
- package/dist/frontmatter.d.ts +1 -0
- package/dist/frontmatter.js +1 -0
- package/dist/human-in-loop/gate.d.ts +5 -1
- package/dist/human-in-loop/gate.js +10 -8
- package/dist/human-in-loop/runner.js +1 -28
- package/dist/mcp.d.ts +4 -1
- package/dist/mcp.js +8 -51
- package/dist/process-runner.d.ts +1 -0
- package/dist/process-runner.js +1 -0
- package/dist/runtime/io.d.ts +5 -0
- package/dist/runtime/io.js +50 -0
- package/dist/sdk.d.ts +12 -8
- package/dist/sdk.js +7 -52
- package/dist/task-list.d.ts +1 -0
- package/dist/task-list.js +1 -0
- package/dist/testing/fakes.d.ts +20 -0
- package/dist/testing/fakes.js +83 -0
- package/dist/testing/fixtures.d.ts +8 -0
- package/dist/testing/fixtures.js +248 -0
- package/dist/testing/harness.d.ts +76 -0
- package/dist/testing/harness.js +391 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +3 -0
- package/dist/testing/memory-fs.d.ts +11 -0
- package/dist/testing/memory-fs.js +61 -0
- package/dist/testing/parity.d.ts +25 -0
- package/dist/testing/parity.js +384 -0
- package/dist/testing/render-capture.d.ts +6 -0
- package/dist/testing/render-capture.js +54 -0
- package/dist/tiny-mcp-client.d.ts +1 -0
- package/dist/tiny-mcp-client.js +1 -0
- package/node_modules/@poe-code/agent-defs/package.json +9 -3
- package/node_modules/@poe-code/agent-human-in-loop/README.md +12 -2
- package/node_modules/@poe-code/agent-human-in-loop/package.json +8 -2
- package/node_modules/@poe-code/agent-mcp-config/README.md +7 -7
- package/node_modules/@poe-code/agent-mcp-config/package.json +8 -2
- package/node_modules/@poe-code/config-mutations/README.md +8 -8
- package/node_modules/@poe-code/config-mutations/package.json +8 -2
- package/node_modules/@poe-code/frontmatter/README.md +2 -2
- package/node_modules/@poe-code/frontmatter/package.json +8 -2
- package/node_modules/@poe-code/process-runner/README.md +1 -1
- package/node_modules/@poe-code/process-runner/package.json +8 -2
- package/node_modules/@poe-code/task-list/README.md +15 -3
- package/node_modules/@poe-code/task-list/package.json +8 -2
- package/node_modules/auth-store/README.md +15 -0
- package/node_modules/auth-store/package.json +3 -2
- package/node_modules/tiny-mcp-client/.turbo/turbo-build.log +1 -1
- package/node_modules/tiny-mcp-client/README.md +36 -36
- package/node_modules/tiny-mcp-client/dist/index.d.ts +660 -2
- package/node_modules/tiny-mcp-client/dist/index.js +3870 -1
- package/node_modules/tiny-mcp-client/package.json +8 -2
- package/node_modules/tiny-mcp-client/scripts/build.mjs +63 -0
- package/node_modules/toolcraft-design/README.md +8 -4
- package/node_modules/toolcraft-design/dist/dashboard/terminal.js +48 -6
- package/node_modules/toolcraft-design/dist/explorer/actions.d.ts +4 -0
- package/node_modules/toolcraft-design/dist/explorer/actions.js +1 -0
- package/node_modules/toolcraft-design/dist/explorer/events.d.ts +4 -0
- package/node_modules/toolcraft-design/dist/explorer/reducer.js +52 -4
- package/node_modules/toolcraft-design/dist/explorer/render/list.js +47 -20
- package/node_modules/toolcraft-design/dist/explorer/render/modal.js +13 -1
- package/node_modules/toolcraft-design/dist/explorer/render/test-fixtures.js +1 -1
- package/node_modules/toolcraft-design/dist/explorer/runtime.js +3 -0
- package/node_modules/toolcraft-design/dist/explorer/state.d.ts +9 -0
- package/node_modules/toolcraft-design/package.json +3 -2
- package/package.json +44 -6
- package/node_modules/mcp-oauth/LICENSE +0 -21
- package/node_modules/mcp-oauth/README.md +0 -31
- package/node_modules/mcp-oauth/dist/client/auth-store-session-store.d.ts +0 -14
- package/node_modules/mcp-oauth/dist/client/auth-store-session-store.js +0 -169
- package/node_modules/mcp-oauth/dist/client/authorization-state.d.ts +0 -8
- package/node_modules/mcp-oauth/dist/client/authorization-state.js +0 -47
- package/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.d.ts +0 -3
- package/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.js +0 -627
- package/node_modules/mcp-oauth/dist/client/loopback-authorization.d.ts +0 -20
- package/node_modules/mcp-oauth/dist/client/loopback-authorization.js +0 -207
- package/node_modules/mcp-oauth/dist/client/pkce.d.ts +0 -2
- package/node_modules/mcp-oauth/dist/client/pkce.js +0 -7
- package/node_modules/mcp-oauth/dist/client/token-endpoint.d.ts +0 -40
- package/node_modules/mcp-oauth/dist/client/token-endpoint.js +0 -164
- package/node_modules/mcp-oauth/dist/client/types.d.ts +0 -113
- package/node_modules/mcp-oauth/dist/client/types.js +0 -1
- package/node_modules/mcp-oauth/dist/index.d.ts +0 -10
- package/node_modules/mcp-oauth/dist/index.js +0 -7
- package/node_modules/mcp-oauth/dist/resource-indicator.d.ts +0 -1
- package/node_modules/mcp-oauth/dist/resource-indicator.js +0 -11
- package/node_modules/mcp-oauth/dist/server/jwks-token-verifier.d.ts +0 -28
- package/node_modules/mcp-oauth/dist/server/jwks-token-verifier.js +0 -304
- package/node_modules/mcp-oauth/dist/types.compile-check.d.ts +0 -1
- package/node_modules/mcp-oauth/dist/types.compile-check.js +0 -22
- package/node_modules/mcp-oauth/package.json +0 -32
- package/node_modules/tiny-mcp-client/dist/internal.d.ts +0 -556
- package/node_modules/tiny-mcp-client/dist/internal.js +0 -2688
- package/node_modules/tiny-mcp-client/dist/jsonrpc-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/jsonrpc-types.compile-check.js +0 -37
- package/node_modules/tiny-mcp-client/dist/mcp-lifecycle-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/mcp-lifecycle-types.compile-check.js +0 -50
- package/node_modules/tiny-mcp-client/dist/mcp-prompt-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/mcp-prompt-types.compile-check.js +0 -50
- package/node_modules/tiny-mcp-client/dist/mcp-resource-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/mcp-resource-types.compile-check.js +0 -51
- package/node_modules/tiny-mcp-client/dist/mcp-tool-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/mcp-tool-types.compile-check.js +0 -99
- package/node_modules/tiny-mcp-client/dist/mcp-transport-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/mcp-transport-types.compile-check.js +0 -56
- package/node_modules/tiny-mcp-client/dist/mcp-utility-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/mcp-utility-types.compile-check.js +0 -145
- package/node_modules/tiny-mcp-client/dist/oauth-discovery.d.ts +0 -24
- package/node_modules/tiny-mcp-client/dist/oauth-discovery.js +0 -382
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiny-mcp-client",
|
|
3
3
|
"version": "0.1.0",
|
|
4
|
-
"license": "MIT",
|
|
5
4
|
"private": true,
|
|
5
|
+
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"scripts": {
|
|
10
|
-
"build": "node
|
|
10
|
+
"build": "node scripts/build.mjs"
|
|
11
11
|
},
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
@@ -16,6 +16,12 @@
|
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
19
|
+
"mcp-oauth": "*",
|
|
19
20
|
"tiny-stdio-mcp-server": "*"
|
|
21
|
+
},
|
|
22
|
+
"poeCode": {
|
|
23
|
+
"inlinedDependencies": [
|
|
24
|
+
"mcp-oauth"
|
|
25
|
+
]
|
|
20
26
|
}
|
|
21
27
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { cp, mkdir, mkdtemp, rm } from "node:fs/promises";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { build } from "esbuild";
|
|
8
|
+
import { rollup } from "rollup";
|
|
9
|
+
import { dts } from "rollup-plugin-dts";
|
|
10
|
+
import { assertSafeOutputDirectory } from "../../../scripts/guard-package-dist.mjs";
|
|
11
|
+
|
|
12
|
+
const require = createRequire(import.meta.url);
|
|
13
|
+
const packageDir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
|
14
|
+
const packagesDir = path.dirname(packageDir);
|
|
15
|
+
const distDir = path.join(packageDir, "dist");
|
|
16
|
+
const temporaryDir = await mkdtemp(path.join(os.tmpdir(), "tiny-mcp-client-build-"));
|
|
17
|
+
|
|
18
|
+
const declarationAliases = new Map([
|
|
19
|
+
["mcp-oauth", path.join(packagesDir, "mcp-oauth", "dist", "index.d.ts")],
|
|
20
|
+
["auth-store", path.join(packagesDir, "auth-store", "dist", "index.d.ts")]
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
const inlineWorkspaceDeclarations = {
|
|
24
|
+
name: "inline-workspace-declarations",
|
|
25
|
+
resolveId(source) {
|
|
26
|
+
return declarationAliases.get(source) ?? null;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
await assertSafeOutputDirectory(packageDir, distDir);
|
|
32
|
+
await rm(distDir, { recursive: true, force: true });
|
|
33
|
+
execFileSync(
|
|
34
|
+
process.execPath,
|
|
35
|
+
[require.resolve("typescript/bin/tsc"), "--emitDeclarationOnly"],
|
|
36
|
+
{ cwd: packageDir, stdio: "inherit" }
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const declarationBundle = await rollup({
|
|
40
|
+
input: path.join(distDir, "index.d.ts"),
|
|
41
|
+
external: (source) => source.startsWith("node:"),
|
|
42
|
+
plugins: [inlineWorkspaceDeclarations, dts()]
|
|
43
|
+
});
|
|
44
|
+
await declarationBundle.write({
|
|
45
|
+
file: path.join(temporaryDir, "index.d.ts"),
|
|
46
|
+
format: "es"
|
|
47
|
+
});
|
|
48
|
+
await declarationBundle.close();
|
|
49
|
+
|
|
50
|
+
await rm(distDir, { recursive: true, force: true });
|
|
51
|
+
await mkdir(distDir, { recursive: true });
|
|
52
|
+
await build({
|
|
53
|
+
entryPoints: [path.join(packageDir, "src", "index.ts")],
|
|
54
|
+
outfile: path.join(distDir, "index.js"),
|
|
55
|
+
bundle: true,
|
|
56
|
+
format: "esm",
|
|
57
|
+
platform: "node",
|
|
58
|
+
target: "node18"
|
|
59
|
+
});
|
|
60
|
+
await cp(path.join(temporaryDir, "index.d.ts"), path.join(distDir, "index.d.ts"));
|
|
61
|
+
} finally {
|
|
62
|
+
await rm(temporaryDir, { recursive: true, force: true });
|
|
63
|
+
}
|
|
@@ -118,16 +118,16 @@ Raw HTML in Markdown is escaped by default. Pass `{ allowRawHtml: true }` only w
|
|
|
118
118
|
|
|
119
119
|
Fenced code block syntax highlighting is opt-in:
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
````ts
|
|
122
122
|
import { renderMarkdown, renderMarkdownHtml } from "toolcraft-design";
|
|
123
123
|
|
|
124
|
-
const html = renderMarkdownHtml(
|
|
124
|
+
const html = renderMarkdownHtml('```ts\nconst value = "hello";\n```', {
|
|
125
125
|
syntaxHighlight: true
|
|
126
126
|
});
|
|
127
|
-
const terminal = renderMarkdown(
|
|
127
|
+
const terminal = renderMarkdown('```ts\nconst value = "hello";\n```', {
|
|
128
128
|
syntaxHighlight: true
|
|
129
129
|
});
|
|
130
|
-
|
|
130
|
+
````
|
|
131
131
|
|
|
132
132
|
HTML highlighting emits escaped code text with neutral Toolcraft-owned `<span>` wrappers. The renderer does not ship or inject CSS, so consumers control the appearance:
|
|
133
133
|
|
|
@@ -340,3 +340,7 @@ nvm exec 18.18 node packages/toolcraft-design/scripts/check-node18.mjs
|
|
|
340
340
|
- `NO_COLOR`: disables color when `FORCE_COLOR` does not enable it.
|
|
341
341
|
- `TERM`: participates in color support detection; an unset or `dumb` terminal disables color unless forced.
|
|
342
342
|
- `POE_NO_SPINNER`: uses non-animated spinner behavior when set to `1`.
|
|
343
|
+
|
|
344
|
+
## Configuration Options
|
|
345
|
+
|
|
346
|
+
Use `configureTheme({ brand?, label? })` for process-local brand settings, `withOutputFormat(format, fn)` for scoped output-format overrides, and component-specific options such as `RenderTableOptions`, `RenderMarkdownOptions`, prompt options, dashboard options, and explorer config. Environment variables above are process defaults, not config files.
|
|
@@ -118,19 +118,18 @@ export function createTerminalDriver(opts) {
|
|
|
118
118
|
if (destroyed) {
|
|
119
119
|
return () => { };
|
|
120
120
|
}
|
|
121
|
-
const listener = (
|
|
122
|
-
const event
|
|
123
|
-
if (event !== undefined) {
|
|
121
|
+
const listener = (chunk) => {
|
|
122
|
+
for (const event of parseKeypressChunk(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))) {
|
|
124
123
|
handler(event);
|
|
125
124
|
}
|
|
126
125
|
};
|
|
127
126
|
keypressListeners.add(listener);
|
|
128
|
-
stdin.on("
|
|
127
|
+
stdin.on("data", listener);
|
|
129
128
|
return () => {
|
|
130
129
|
if (!keypressListeners.delete(listener)) {
|
|
131
130
|
return;
|
|
132
131
|
}
|
|
133
|
-
stdin.off("
|
|
132
|
+
stdin.off("data", listener);
|
|
134
133
|
};
|
|
135
134
|
}
|
|
136
135
|
function destroy() {
|
|
@@ -138,7 +137,7 @@ export function createTerminalDriver(opts) {
|
|
|
138
137
|
return;
|
|
139
138
|
}
|
|
140
139
|
for (const listener of keypressListeners) {
|
|
141
|
-
stdin.off("
|
|
140
|
+
stdin.off("data", listener);
|
|
142
141
|
}
|
|
143
142
|
keypressListeners.clear();
|
|
144
143
|
for (const listener of resizeListeners) {
|
|
@@ -173,6 +172,9 @@ export function parseKeypress(data) {
|
|
|
173
172
|
if (data.length === 0) {
|
|
174
173
|
return undefined;
|
|
175
174
|
}
|
|
175
|
+
if (data.length === 1 && data[0] === 0x1b) {
|
|
176
|
+
return { name: "escape", ctrl: false, meta: false, shift: false };
|
|
177
|
+
}
|
|
176
178
|
const stream = new PassThrough();
|
|
177
179
|
const stdin = stream;
|
|
178
180
|
let event;
|
|
@@ -184,6 +186,46 @@ export function parseKeypress(data) {
|
|
|
184
186
|
stream.destroy();
|
|
185
187
|
return event;
|
|
186
188
|
}
|
|
189
|
+
function parseKeypressChunk(data) {
|
|
190
|
+
const events = [];
|
|
191
|
+
const input = data.toString("utf8");
|
|
192
|
+
let index = 0;
|
|
193
|
+
while (index < input.length) {
|
|
194
|
+
const sequence = nextKeySequence(input, index);
|
|
195
|
+
if (sequence.length === 0) {
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
const event = parseKeypress(Buffer.from(sequence));
|
|
199
|
+
if (event !== undefined) {
|
|
200
|
+
events.push(event);
|
|
201
|
+
}
|
|
202
|
+
index += sequence.length;
|
|
203
|
+
}
|
|
204
|
+
return events;
|
|
205
|
+
}
|
|
206
|
+
function nextKeySequence(input, index) {
|
|
207
|
+
const character = input[index];
|
|
208
|
+
if (character === undefined) {
|
|
209
|
+
return "";
|
|
210
|
+
}
|
|
211
|
+
if (character !== "\u001b") {
|
|
212
|
+
return character;
|
|
213
|
+
}
|
|
214
|
+
const next = input[index + 1];
|
|
215
|
+
if (next === undefined) {
|
|
216
|
+
return character;
|
|
217
|
+
}
|
|
218
|
+
if (next !== "[") {
|
|
219
|
+
return input.slice(index, index + 2);
|
|
220
|
+
}
|
|
221
|
+
for (let cursor = index + 2; cursor < input.length; cursor += 1) {
|
|
222
|
+
const code = input.charCodeAt(cursor);
|
|
223
|
+
if ((code >= 0x40 && code <= 0x7e) || input[cursor] === "~") {
|
|
224
|
+
return input.slice(index, cursor + 1);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return input.slice(index);
|
|
228
|
+
}
|
|
187
229
|
function toKeypressEvent(str, key) {
|
|
188
230
|
const controlCharacter = controlCharacterToKeypress(key?.sequence);
|
|
189
231
|
if (controlCharacter !== undefined) {
|
|
@@ -7,6 +7,10 @@ type ExplorerKeypressEvent = Extract<ExplorerEvent, {
|
|
|
7
7
|
export type ActionRuntimeHandles = {
|
|
8
8
|
refresh: () => Promise<void>;
|
|
9
9
|
suspendAnd: <T>(fn: () => Promise<T>) => Promise<T>;
|
|
10
|
+
openModal: (content: {
|
|
11
|
+
title: string;
|
|
12
|
+
content: string;
|
|
13
|
+
}) => void;
|
|
10
14
|
toast: (msg: string, tone?: Tone) => void;
|
|
11
15
|
confirm: (prompt: string) => Promise<boolean>;
|
|
12
16
|
exit: (after?: () => void | Promise<void>) => void;
|
|
@@ -20,6 +20,7 @@ export function buildActionContext(state, _action, source, runtimeHandles, rowsO
|
|
|
20
20
|
filter: state.filter,
|
|
21
21
|
refresh: runtimeHandles.refresh,
|
|
22
22
|
suspendAnd: runtimeHandles.suspendAnd,
|
|
23
|
+
openModal: runtimeHandles.openModal,
|
|
23
24
|
toast: runtimeHandles.toast,
|
|
24
25
|
confirm: runtimeHandles.confirm,
|
|
25
26
|
exit: runtimeHandles.exit
|
|
@@ -5,6 +5,7 @@ const NO_EFFECTS = [];
|
|
|
5
5
|
const DEFAULT_ACTION_HANDLES = {
|
|
6
6
|
refresh: async () => undefined,
|
|
7
7
|
suspendAnd: async (fn) => fn(),
|
|
8
|
+
openModal: () => undefined,
|
|
8
9
|
toast: () => undefined,
|
|
9
10
|
confirm: async () => false,
|
|
10
11
|
exit: () => undefined
|
|
@@ -31,6 +32,13 @@ export function step(state, event, runtimeHandles = DEFAULT_ACTION_HANDLES) {
|
|
|
31
32
|
return expireToast(state);
|
|
32
33
|
case "suspendResumed":
|
|
33
34
|
return suspendResumed(state, event.emit, runtimeHandles);
|
|
35
|
+
case "modalOpened":
|
|
36
|
+
return setModal(state, {
|
|
37
|
+
kind: "content",
|
|
38
|
+
title: event.title,
|
|
39
|
+
content: event.content,
|
|
40
|
+
scroll: 0
|
|
41
|
+
});
|
|
34
42
|
case "modalDismissed":
|
|
35
43
|
return modalDismissed(state, event.result, runtimeHandles);
|
|
36
44
|
}
|
|
@@ -164,6 +172,26 @@ function stepModalKey(state, key, target, runtimeHandles) {
|
|
|
164
172
|
}
|
|
165
173
|
return paletteInput(state, key);
|
|
166
174
|
}
|
|
175
|
+
if (state.modal?.kind === "content") {
|
|
176
|
+
if (target?.type === "builtin") {
|
|
177
|
+
switch (target.id) {
|
|
178
|
+
case "escape":
|
|
179
|
+
case "confirm":
|
|
180
|
+
return modalDismissed(state, false, runtimeHandles);
|
|
181
|
+
case "cursorDown":
|
|
182
|
+
case "detailScrollDown":
|
|
183
|
+
return scrollContentModal(state, 1);
|
|
184
|
+
case "cursorUp":
|
|
185
|
+
case "detailScrollUp":
|
|
186
|
+
return scrollContentModal(state, -1);
|
|
187
|
+
case "pageDown":
|
|
188
|
+
return scrollContentModal(state, modalBodyHeight(state));
|
|
189
|
+
case "pageUp":
|
|
190
|
+
return scrollContentModal(state, -modalBodyHeight(state));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return mark(state, 0);
|
|
194
|
+
}
|
|
167
195
|
return mark(state, 0);
|
|
168
196
|
}
|
|
169
197
|
function resize(state, cols, rows) {
|
|
@@ -287,7 +315,7 @@ function suspendResumed(state, emit, runtimeHandles) {
|
|
|
287
315
|
}
|
|
288
316
|
function modalDismissed(state, result, runtimeHandles) {
|
|
289
317
|
const modal = state.modal;
|
|
290
|
-
const closed = { ...state, modal: null, dirty:
|
|
318
|
+
const closed = { ...state, modal: null, dirty: REGION_ALL };
|
|
291
319
|
if (modal?.kind === "confirm") {
|
|
292
320
|
modal.resolver(result === true);
|
|
293
321
|
}
|
|
@@ -466,9 +494,6 @@ function selectionChanged(state, selected) {
|
|
|
466
494
|
return { state: next, effects: NO_EFFECTS };
|
|
467
495
|
}
|
|
468
496
|
function detailScroll(state, delta) {
|
|
469
|
-
if (state.focused !== "detail") {
|
|
470
|
-
return mark(state, 0);
|
|
471
|
-
}
|
|
472
497
|
const scroll = clamp(state.detail.scroll + delta, 0, maxDetailScroll(state));
|
|
473
498
|
if (scroll === state.detail.scroll) {
|
|
474
499
|
return mark(state, 0);
|
|
@@ -478,6 +503,29 @@ function detailScroll(state, delta) {
|
|
|
478
503
|
effects: NO_EFFECTS
|
|
479
504
|
};
|
|
480
505
|
}
|
|
506
|
+
function scrollContentModal(state, delta) {
|
|
507
|
+
if (state.modal?.kind !== "content") {
|
|
508
|
+
return mark(state, 0);
|
|
509
|
+
}
|
|
510
|
+
const scroll = clamp(state.modal.scroll + delta, 0, maxContentModalScroll(state));
|
|
511
|
+
if (scroll === state.modal.scroll) {
|
|
512
|
+
return mark(state, 0);
|
|
513
|
+
}
|
|
514
|
+
return setModal(state, { ...state.modal, scroll });
|
|
515
|
+
}
|
|
516
|
+
function maxContentModalScroll(state) {
|
|
517
|
+
if (state.modal?.kind !== "content") {
|
|
518
|
+
return 0;
|
|
519
|
+
}
|
|
520
|
+
return Math.max(0, state.modal.content.split("\n").length - modalBodyHeight(state));
|
|
521
|
+
}
|
|
522
|
+
function modalBodyHeight(state) {
|
|
523
|
+
const screenHeight = normalizeSize(state.size.rows);
|
|
524
|
+
if (screenHeight <= 2) {
|
|
525
|
+
return 0;
|
|
526
|
+
}
|
|
527
|
+
return Math.max(0, screenHeight - 4);
|
|
528
|
+
}
|
|
481
529
|
function clampDetailScroll(state) {
|
|
482
530
|
const scroll = clamp(state.detail.scroll, 0, maxDetailScroll(state));
|
|
483
531
|
if (scroll === state.detail.scroll) {
|
|
@@ -28,28 +28,34 @@ export function renderList(state, screen, layout) {
|
|
|
28
28
|
cache.clear();
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
const lines = buildDisplayLines(state);
|
|
32
|
+
const start = visibleStart(lines, bodyRect.height);
|
|
32
33
|
let y = 0;
|
|
33
|
-
for (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const row = state.rows[rowIndex];
|
|
38
|
-
if (!row) {
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
if (row.group && row.group !== lastGroup && y < bodyRect.height) {
|
|
42
|
-
const hash = `group:${row.group}`;
|
|
34
|
+
for (let lineIndex = start; lineIndex < lines.length && y < bodyRect.height; lineIndex += 1) {
|
|
35
|
+
const line = lines[lineIndex];
|
|
36
|
+
if (line.kind === "group") {
|
|
37
|
+
const hash = `group:${line.label}`;
|
|
43
38
|
if (cache.get(y) !== hash) {
|
|
44
|
-
writeLine(screen, bodyRect, y, formatGroupHeader(
|
|
39
|
+
writeLine(screen, bodyRect, y, formatGroupHeader(line.label, bodyRect), styles.muted);
|
|
45
40
|
cache.set(y, hash);
|
|
46
41
|
}
|
|
47
42
|
y += 1;
|
|
48
|
-
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (line.kind === "subtitle") {
|
|
46
|
+
const subtitleHash = `subtitle:${line.row.id}:${line.text}`;
|
|
47
|
+
if (cache.get(y) !== subtitleHash) {
|
|
48
|
+
writeLine(screen, bodyRect, y, ` ${line.text}`, styles.muted);
|
|
49
|
+
cache.set(y, subtitleHash);
|
|
50
|
+
}
|
|
51
|
+
y += 1;
|
|
52
|
+
continue;
|
|
49
53
|
}
|
|
54
|
+
const rowIndex = line.rowIndex;
|
|
50
55
|
if (y >= bodyRect.height) {
|
|
51
56
|
break;
|
|
52
57
|
}
|
|
58
|
+
const row = line.row;
|
|
53
59
|
const selected = state.multiSelect && state.selected.has(row.id);
|
|
54
60
|
const cursor = rowIndex === state.filtered[state.cursor];
|
|
55
61
|
const positions = state.matchPositions.get(rowIndex) ?? [];
|
|
@@ -64,15 +70,36 @@ export function renderList(state, screen, layout) {
|
|
|
64
70
|
cache.set(y, hash);
|
|
65
71
|
}
|
|
66
72
|
y += 1;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function buildDisplayLines(state) {
|
|
76
|
+
const lines = [];
|
|
77
|
+
let lastGroup;
|
|
78
|
+
for (const rowIndex of state.filtered) {
|
|
79
|
+
const row = state.rows[rowIndex];
|
|
80
|
+
if (!row) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (row.group && row.group !== lastGroup) {
|
|
84
|
+
lines.push({ kind: "group", label: row.group });
|
|
85
|
+
lastGroup = row.group;
|
|
74
86
|
}
|
|
87
|
+
lines.push({ kind: "row", rowIndex, row, cursor: rowIndex === state.filtered[state.cursor] });
|
|
88
|
+
if (row.subtitle) {
|
|
89
|
+
lines.push({ kind: "subtitle", row, text: row.subtitle });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return lines;
|
|
93
|
+
}
|
|
94
|
+
function visibleStart(lines, height) {
|
|
95
|
+
if (height <= 0) {
|
|
96
|
+
return 0;
|
|
97
|
+
}
|
|
98
|
+
const cursorLine = lines.findIndex((line) => line.kind === "row" && line.cursor);
|
|
99
|
+
if (cursorLine < 0) {
|
|
100
|
+
return 0;
|
|
75
101
|
}
|
|
102
|
+
return Math.max(0, Math.min(cursorLine, cursorLine - height + 1));
|
|
76
103
|
}
|
|
77
104
|
function formatGroupHeader(label, rect) {
|
|
78
105
|
const text = ` ${label} `;
|
|
@@ -4,7 +4,7 @@ export function renderModal(state, screen) {
|
|
|
4
4
|
if (state.modal === null || screen.width <= 0 || screen.height <= 0) {
|
|
5
5
|
return;
|
|
6
6
|
}
|
|
7
|
-
const width = Math.min(screen.width - 2, Math.max(34, Math.floor(screen.width *
|
|
7
|
+
const width = Math.min(screen.width - 2, Math.max(34, Math.floor(screen.width * modalWidthRatio(state))));
|
|
8
8
|
const height = Math.min(screen.height - 2, modalHeight(state));
|
|
9
9
|
const x = Math.max(0, Math.floor((screen.width - width) / 2));
|
|
10
10
|
const y = Math.max(0, Math.floor((screen.height - height) / 2));
|
|
@@ -39,6 +39,9 @@ function modalLines(state) {
|
|
|
39
39
|
...paletteLines(state)
|
|
40
40
|
];
|
|
41
41
|
}
|
|
42
|
+
if (state.modal?.kind === "content") {
|
|
43
|
+
return state.modal.content.split("\n").slice(state.modal.scroll);
|
|
44
|
+
}
|
|
42
45
|
return [];
|
|
43
46
|
}
|
|
44
47
|
function title(state) {
|
|
@@ -48,11 +51,20 @@ function title(state) {
|
|
|
48
51
|
if (state.modal?.kind === "confirm") {
|
|
49
52
|
return "Confirm";
|
|
50
53
|
}
|
|
54
|
+
if (state.modal?.kind === "content") {
|
|
55
|
+
return state.modal.title;
|
|
56
|
+
}
|
|
51
57
|
return "Command Palette";
|
|
52
58
|
}
|
|
53
59
|
function modalHeight(state) {
|
|
60
|
+
if (state.modal?.kind === "content") {
|
|
61
|
+
return Math.max(5, state.modal.content.split("\n").length + 2);
|
|
62
|
+
}
|
|
54
63
|
return Math.max(5, modalLines(state).length + 2);
|
|
55
64
|
}
|
|
65
|
+
function modalWidthRatio(state) {
|
|
66
|
+
return state.modal?.kind === "content" ? 0.86 : 0.62;
|
|
67
|
+
}
|
|
56
68
|
function drawBox(screen, x, y, width, height, boxTitle, style) {
|
|
57
69
|
screen.clearRect({ x, y, width, height });
|
|
58
70
|
const innerWidth = Math.max(0, width - 2);
|
|
@@ -6,7 +6,7 @@ import { renderExplorer } from "./index.js";
|
|
|
6
6
|
export function renderStateSnapshot(state) {
|
|
7
7
|
const screen = new ScreenBuffer(state.size.cols, state.size.rows);
|
|
8
8
|
renderExplorer(state, screen);
|
|
9
|
-
return dumpScreen(screen);
|
|
9
|
+
return dumpScreen(screen).split("\n").map((line) => line.trimEnd()).join("\n");
|
|
10
10
|
}
|
|
11
11
|
export function dumpScreen(screen) {
|
|
12
12
|
const lines = [];
|
|
@@ -45,6 +45,9 @@ class ExplorerRuntime {
|
|
|
45
45
|
await this.refreshRowsFromSource();
|
|
46
46
|
},
|
|
47
47
|
suspendAnd: async (fn) => this.suspendAnd(fn),
|
|
48
|
+
openModal: (content) => {
|
|
49
|
+
this.dispatch({ type: "modalOpened", title: content.title, content: content.content });
|
|
50
|
+
},
|
|
48
51
|
toast: (msg, tone) => {
|
|
49
52
|
this.showToast(msg, tone);
|
|
50
53
|
},
|
|
@@ -48,6 +48,10 @@ export interface ActionContext<R> {
|
|
|
48
48
|
filter: string;
|
|
49
49
|
refresh: () => Promise<void>;
|
|
50
50
|
suspendAnd: <T>(fn: () => Promise<T>) => Promise<T>;
|
|
51
|
+
openModal: (content: {
|
|
52
|
+
title: string;
|
|
53
|
+
content: string;
|
|
54
|
+
}) => void;
|
|
51
55
|
toast: (msg: string, tone?: Tone) => void;
|
|
52
56
|
confirm: (prompt: string) => Promise<boolean>;
|
|
53
57
|
exit: (after?: () => void | Promise<void>) => void;
|
|
@@ -114,6 +118,11 @@ export interface ExplorerState {
|
|
|
114
118
|
kind: "palette";
|
|
115
119
|
query: string;
|
|
116
120
|
cursor: number;
|
|
121
|
+
} | {
|
|
122
|
+
kind: "content";
|
|
123
|
+
title: string;
|
|
124
|
+
content: string;
|
|
125
|
+
scroll: number;
|
|
117
126
|
};
|
|
118
127
|
toast: {
|
|
119
128
|
message: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft-design",
|
|
3
3
|
"version": "0.0.2",
|
|
4
|
-
"license": "MIT",
|
|
5
4
|
"private": true,
|
|
5
|
+
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"generate:design-docs:all": "tsx scripts/generate-docs.ts all"
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
|
-
"dist"
|
|
21
|
+
"dist",
|
|
22
|
+
"LICENSE"
|
|
22
23
|
],
|
|
23
24
|
"dependencies": {
|
|
24
25
|
"fast-string-width": "^3.0.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.94",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,6 +18,26 @@
|
|
|
18
18
|
"types": "./dist/composition.d.ts",
|
|
19
19
|
"import": "./dist/composition.js"
|
|
20
20
|
},
|
|
21
|
+
"./agent-defs": {
|
|
22
|
+
"types": "./dist/agent-defs.d.ts",
|
|
23
|
+
"import": "./dist/agent-defs.js"
|
|
24
|
+
},
|
|
25
|
+
"./agent-human-in-loop": {
|
|
26
|
+
"types": "./dist/agent-human-in-loop.d.ts",
|
|
27
|
+
"import": "./dist/agent-human-in-loop.js"
|
|
28
|
+
},
|
|
29
|
+
"./agent-mcp-config": {
|
|
30
|
+
"types": "./dist/agent-mcp-config.d.ts",
|
|
31
|
+
"import": "./dist/agent-mcp-config.js"
|
|
32
|
+
},
|
|
33
|
+
"./auth-store": {
|
|
34
|
+
"types": "./dist/auth-store.d.ts",
|
|
35
|
+
"import": "./dist/auth-store.js"
|
|
36
|
+
},
|
|
37
|
+
"./config-mutations": {
|
|
38
|
+
"types": "./dist/config-mutations.d.ts",
|
|
39
|
+
"import": "./dist/config-mutations.js"
|
|
40
|
+
},
|
|
21
41
|
"./design": {
|
|
22
42
|
"types": "./dist/design.d.ts",
|
|
23
43
|
"import": "./dist/design.js"
|
|
@@ -46,9 +66,29 @@
|
|
|
46
66
|
"types": "./dist/human-in-loop/index.d.ts",
|
|
47
67
|
"import": "./dist/human-in-loop/index.js"
|
|
48
68
|
},
|
|
69
|
+
"./frontmatter": {
|
|
70
|
+
"types": "./dist/frontmatter.d.ts",
|
|
71
|
+
"import": "./dist/frontmatter.js"
|
|
72
|
+
},
|
|
73
|
+
"./process-runner": {
|
|
74
|
+
"types": "./dist/process-runner.d.ts",
|
|
75
|
+
"import": "./dist/process-runner.js"
|
|
76
|
+
},
|
|
49
77
|
"./source-snippet": {
|
|
50
78
|
"types": "./dist/source-snippet.d.ts",
|
|
51
79
|
"import": "./dist/source-snippet.js"
|
|
80
|
+
},
|
|
81
|
+
"./testing": {
|
|
82
|
+
"types": "./dist/testing/index.d.ts",
|
|
83
|
+
"import": "./dist/testing/index.js"
|
|
84
|
+
},
|
|
85
|
+
"./task-list": {
|
|
86
|
+
"types": "./dist/task-list.d.ts",
|
|
87
|
+
"import": "./dist/task-list.js"
|
|
88
|
+
},
|
|
89
|
+
"./tiny-mcp-client": {
|
|
90
|
+
"types": "./dist/tiny-mcp-client.d.ts",
|
|
91
|
+
"import": "./dist/tiny-mcp-client.js"
|
|
52
92
|
}
|
|
53
93
|
},
|
|
54
94
|
"scripts": {
|
|
@@ -56,11 +96,11 @@
|
|
|
56
96
|
"test": "cd ../.. && vitest run packages/toolcraft/src",
|
|
57
97
|
"test:unit": "cd ../.. && vitest run packages/toolcraft/src",
|
|
58
98
|
"lint": "cd ../.. && eslint packages/toolcraft/src --ext ts && tsc -p packages/toolcraft/tsconfig.json --noEmit",
|
|
59
|
-
"prepack": "node ../../scripts/manage-bundled-workspace-deps.mjs prepare . toolcraft-design @poe-code/frontmatter @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/agent-defs @poe-code/config-mutations @poe-code/process-runner tiny-mcp-client
|
|
60
|
-
"postpack": "node ../../scripts/manage-bundled-workspace-deps.mjs cleanup . toolcraft-design @poe-code/frontmatter @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/agent-defs @poe-code/config-mutations @poe-code/process-runner tiny-mcp-client
|
|
99
|
+
"prepack": "node ../../scripts/manage-bundled-workspace-deps.mjs prepare . toolcraft-design @poe-code/frontmatter @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/agent-defs @poe-code/config-mutations @poe-code/process-runner tiny-mcp-client auth-store",
|
|
100
|
+
"postpack": "node ../../scripts/manage-bundled-workspace-deps.mjs cleanup . toolcraft-design @poe-code/frontmatter @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/agent-defs @poe-code/config-mutations @poe-code/process-runner tiny-mcp-client auth-store"
|
|
61
101
|
},
|
|
62
102
|
"dependencies": {
|
|
63
|
-
"toolcraft-schema": "0.0.
|
|
103
|
+
"toolcraft-schema": "0.0.94",
|
|
64
104
|
"commander": "^13.1.0",
|
|
65
105
|
"fast-string-width": "^3.0.2",
|
|
66
106
|
"fast-wrap-ansi": "^0.2.0",
|
|
@@ -96,7 +136,6 @@
|
|
|
96
136
|
"@poe-code/config-mutations",
|
|
97
137
|
"@poe-code/process-runner",
|
|
98
138
|
"tiny-mcp-client",
|
|
99
|
-
"mcp-oauth",
|
|
100
139
|
"auth-store"
|
|
101
140
|
],
|
|
102
141
|
"optionalDependencies": {
|
|
@@ -109,7 +148,6 @@
|
|
|
109
148
|
"@poe-code/config-mutations": "*",
|
|
110
149
|
"@poe-code/process-runner": "*",
|
|
111
150
|
"tiny-mcp-client": "*",
|
|
112
|
-
"mcp-oauth": "*",
|
|
113
151
|
"auth-store": "*"
|
|
114
152
|
}
|
|
115
153
|
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Poe Platform
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|