@ccdd/default-tools 2.0.1

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 ADDED
@@ -0,0 +1,78 @@
1
+ # CCDD default tools
2
+
3
+ Published versions can be installed with `npm install --ignore-scripts @ccdd/core @ccdd/default-tools` on Node.js 24 or later. Install `@ccdd/project` as well to use the project CLI.
4
+
5
+ Optional tool implementations for `@ccdd/core`. This library does not register tools automatically. Import a factory and explicitly put its returned definition in your repository's `ccdd.config.ts`:
6
+
7
+ ```ts
8
+ import { defineConfig } from '@ccdd/core';
9
+ import { agent, human } from '@ccdd/default-tools';
10
+
11
+ export default defineConfig(() => ({
12
+ artifactTypes: {
13
+ markdown: {
14
+ agentTools: { read: agent.text.read() },
15
+ humanTools: { open: human.desktop.open() },
16
+ },
17
+ code: {
18
+ agentTools: { list: agent.files.list(), read: agent.files.read() },
19
+ humanTools: { open: human.desktop.open() },
20
+ },
21
+ },
22
+ artifacts: {
23
+ why: { type: 'markdown', path: 'why.md', basis: true },
24
+ spec: { type: 'markdown', path: 'spec.md' },
25
+ },
26
+ critics: [{
27
+ id: 'spec-matches-why', title: 'Spec matches Why', target: 'spec', deps: ['why'],
28
+ profile: { kind: 'agent', provider: 'openai-codex', model: 'gpt-6-astra', reasoning: 'medium' },
29
+ payload: { instruction: 'Read both Artifacts and evaluate whether Spec satisfies Why.' },
30
+ }],
31
+ }));
32
+ ```
33
+
34
+ Factories perform no I/O. Each returns `{ metadata, execute, preflight }`; CCDD connects its Artifact and validates call arguments before execution. Descriptions may contain `{artifactName}`. `description` and `timeoutMs` can be supplied to every factory.
35
+
36
+ - `agent.text.read()` reads a file Artifact. Arguments: optional `startLine` (default 1), `lineCount` (default 80, maximum 500).
37
+ - `agent.files.read()` reads a file inside a directory Artifact; additionally requires an internal `path`.
38
+ - `agent.files.list()` lists a directory Artifact or internal `path`; optional `offset` and `limit` (maximum 200).
39
+ - `agent.image.view()` returns an actual image block from a file Artifact (`{}`) or an internal file in a directory Artifact (`{path: 'frames/preview.png'}`). Register it with the key `view_image`.
40
+ - `human.desktop.open()` opens a file or folder with macOS's default application. A directory Artifact accepts an optional internal `path`. Other platforms require an explicit `command`.
41
+
42
+ Agent tools invoke a packaged Node CLI directly, without a shell or a global executable installation. Reads preserve UTF-8 and LF/CRLF, return complete lines, and bound returned text to 64 KiB. Results contain paging information. Invalid UTF-8, binary content, oversized individual lines, symlinks and paths outside the Artifact fail explicitly. Only returned text or a truly empty file counts as content observation; listing and reading beyond EOF do not.
43
+
44
+ ## Images
45
+
46
+ `agent.image.view()` is included in v1.1.0. The [image and group example](../../examples/artifact-groups/README.md) includes GitHub Release installation and tool verification instructions.
47
+
48
+ ```ts
49
+ // Register this type in ccdd.config.ts.
50
+ image: {
51
+ agentTools: { view_image: agent.image.view() },
52
+ humanTools: { open: human.desktop.open() },
53
+ }
54
+ ```
55
+
56
+ A `preview` Artifact of this type exposes `view_image_preview` to Agents and `open_preview` to Humans. The image CLI reuses Pi Agent Core 0.85.1's `createReadTool()` with a filesystem adapter exposing only the bound file. It makes no LLM call, starts no Agent session and provides no general filesystem or shell access. The package pins this Pi dependency directly; Pi types are not exposed through the public CCDD tool definition.
57
+
58
+ Image contents, rather than filename extensions, determine support. A successful result requires a PNG/JPEG/WebP image block of at most 4MiB and produces a content observation for that leaf. Text-only results, GIF, BMP and animated PNG are rejected. No image processor is installed: the tool does not resize or convert unsupported input. Preflight checks availability and shape without rendering; use `--execute` to verify the actual image result. Agent reviews need a model supporting image input.
59
+
60
+ ```sh
61
+ ccdd tools check --artifact preview --for agent --tool view_image --execute
62
+ ccdd tools check --artifact frames --for agent --tool view_image --execute --args '{"path":"preview.png"}'
63
+ ```
64
+
65
+ Artifact groups are configured in the core as `{kind:'group',members:[ID,...]}`. Tools stay registered on individual Artifact types, and shared leaf members receive one tool binding per operation. `tools check --artifact GROUP` preflights the member tools; execution explicitly selects a leaf.
66
+
67
+ ## Desktop opening
68
+
69
+ Human tools launch a desktop program and return a launch receipt, never decoded file contents. A successful launcher exit does not prove the person read the file and does not complete a review. Input snapshots are managed and retained by CCDD. Launchers should return after opening the application; avoid a wait-for-editor-exit flag. Preparation checks executable availability without launching the application.
70
+
71
+ ```ts
72
+ human.desktop.open({ app: 'TextEdit' }); // macOS
73
+ human.desktop.open({ command: '/path/to/viewer', args: ['--read-only', '{artifactPath}'] });
74
+ ```
75
+
76
+ `args` are fixed repository configuration and require a standalone `{artifactPath}` token; without `args`, an explicit command receives the Artifact path as its only argument. Reviewers cannot supply a command, argv or environment. The process receives only a small desktop environment allowlist, excluding Provider secrets and `NODE_OPTIONS`. CCDD configuration and custom executables are trusted repository code, not an OS sandbox.
77
+
78
+ The package contains no runtime import from CCDD and owns no Broker state. Its peer dependency supplies only the shared public tool contract; custom tools may implement that same contract without installing this library.
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,21 @@
1
+ import { readerRequest } from './reader.js';
2
+ try {
3
+ const chunks = [];
4
+ let bytes = 0;
5
+ for await (const chunk of process.stdin) {
6
+ const data = Buffer.from(chunk);
7
+ bytes += data.length;
8
+ if (bytes > 64 * 1024)
9
+ throw new Error('Reader request exceeded its limit');
10
+ chunks.push(data);
11
+ }
12
+ const input = JSON.parse(Buffer.concat(chunks).toString('utf8'));
13
+ const image = input && typeof input === 'object' && 'operation' in input && input.operation === 'view_image';
14
+ const data = image ? await (await import('./image.js')).imageRequest(input) : await readerRequest(input);
15
+ process.stdout.write(`${JSON.stringify({ ok: true, data })}\n`);
16
+ }
17
+ catch (error) {
18
+ // A single structured response distinguishes invalid input from process failures.
19
+ process.stdout.write(`${JSON.stringify({ ok: false, message: error instanceof Error ? error.message : 'Reader execution failed' })}\n`);
20
+ }
21
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,IAAI,CAAC;IACH,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC;QACrB,IAAI,KAAK,GAAG,EAAE,GAAG,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC5E,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,MAAM,KAAK,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1E,MAAM,KAAK,GAAG,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,WAAW,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,YAAY,CAAC;IAC7G,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC;IACzG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;AAClE,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,kFAAkF;IAClF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,EAAE,CAAC,IAAI,CAAC,CAAC;AAC1I,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { ToolContent } from '@ccdd/core';
2
+ export declare const MAX_IMAGE_BYTES: number;
3
+ export declare const MAX_IMAGE_OUTPUT_BYTES: number;
4
+ type ImageContent = Extract<ToolContent, {
5
+ type: 'image';
6
+ data: string;
7
+ }>;
8
+ /** Check the CLI/Pi boundary before assigning a content observation. The Runner checks again. */
9
+ export declare function imageContent(value: unknown): ImageContent;
10
+ export {};
@@ -0,0 +1,23 @@
1
+ export const MAX_IMAGE_BYTES = 4 * 1024 * 1024;
2
+ export const MAX_IMAGE_OUTPUT_BYTES = Math.ceil(MAX_IMAGE_BYTES / 3) * 4 + 4096;
3
+ /** Check the CLI/Pi boundary before assigning a content observation. The Runner checks again. */
4
+ export function imageContent(value) {
5
+ if (!value || typeof value !== 'object')
6
+ throw new Error('Pi read did not return a supported image');
7
+ const image = value;
8
+ if (image.type !== 'image' || !['image/png', 'image/jpeg', 'image/webp'].includes(image.mimeType)) {
9
+ throw new Error('view_image requires a PNG, JPEG or WebP image; text, GIF, BMP and animated PNG are not supported');
10
+ }
11
+ if (typeof image.data !== 'string' || !image.data.length || image.data.length > Math.ceil(MAX_IMAGE_BYTES / 3) * 4)
12
+ throw new Error('Image exceeds the 4 MiB limit or contains no data');
13
+ const bytes = Buffer.from(image.data, 'base64');
14
+ if (!bytes.length || bytes.length > MAX_IMAGE_BYTES || bytes.toString('base64') !== image.data)
15
+ throw new Error('Invalid image data or image exceeds the 4 MiB limit');
16
+ const valid = image.mimeType === 'image/png' ? bytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))
17
+ : image.mimeType === 'image/jpeg' ? bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255
18
+ : bytes.toString('ascii', 0, 4) === 'RIFF' && bytes.toString('ascii', 8, 12) === 'WEBP';
19
+ if (!valid)
20
+ throw new Error('Image bytes do not match the declared MIME type');
21
+ return { type: 'image', data: image.data, mimeType: image.mimeType };
22
+ }
23
+ //# sourceMappingURL=image-result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-result.js","sourceRoot":"","sources":["../src/image-result.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAC/C,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;AAGhF,iGAAiG;AACjG,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IACrG,MAAM,KAAK,GAAG,KAAgC,CAAC;IAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAkB,CAAC,EAAE,CAAC;QAC5G,MAAM,IAAI,KAAK,CAAC,kGAAkG,CAAC,CAAC;IACtH,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACzL,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAChD,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,GAAG,eAAe,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACvK,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACxH,CAAC,CAAC,KAAK,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;YAC1F,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC;IAC5F,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC/E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAoC,EAAE,CAAC;AACnG,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { imageContent } from './image-result.js';
2
+ /** Internal CLI adapter. The public tool remains a CCDD definition and creates no Agent or Provider session. */
3
+ export declare function imageRequest(input: unknown): Promise<ReturnType<typeof imageContent>>;
package/dist/image.js ADDED
@@ -0,0 +1,88 @@
1
+ import { constants } from 'node:fs';
2
+ import { open } from 'node:fs/promises';
3
+ import { BACKGROUND_CONTEXT, createReadTool, err, ExecutionError, FileError, ok, } from '@earendil-works/pi-agent-core';
4
+ import { imageContent, MAX_IMAGE_BYTES } from './image-result.js';
5
+ import { internalPath, objectArguments, scopedTarget } from './reader.js';
6
+ /** Pi receives one virtual file, never a workspace path or an unrestricted Node execution environment. */
7
+ function imageEnvironment(root, directory, path) {
8
+ const virtualPath = '/ccdd-image';
9
+ const checkPath = (candidate) => {
10
+ if (candidate !== virtualPath)
11
+ throw new Error('Pi image read is outside the bound Artifact');
12
+ };
13
+ const attempt = async (context, operation) => {
14
+ try {
15
+ context.abortSignal?.throwIfAborted();
16
+ const result = await operation();
17
+ context.abortSignal?.throwIfAborted();
18
+ return ok(result);
19
+ }
20
+ catch (error) {
21
+ return err(new FileError(context.abortSignal?.aborted ? 'aborted' : 'invalid', error instanceof Error ? error.message : 'Image read failed'));
22
+ }
23
+ };
24
+ const disabled = async () => err(new FileError('not_supported', 'Only the bound image read is available'));
25
+ return {
26
+ cwd: '/',
27
+ absolutePath: (candidate, context) => attempt(context, async () => { checkPath(candidate); return virtualPath; }),
28
+ exists: (candidate, context) => attempt(context, async () => { checkPath(candidate); await scopedTarget(root, directory, path); return true; }),
29
+ readBinaryFile: (candidate, context) => attempt(context, async () => {
30
+ checkPath(candidate);
31
+ const target = await scopedTarget(root, directory, path);
32
+ const file = await open(target, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
33
+ try {
34
+ const info = await file.stat();
35
+ if (!info.isFile())
36
+ throw new Error('Viewing an image requires a regular file');
37
+ if (!info.size || info.size > MAX_IMAGE_BYTES)
38
+ throw new Error('Image exceeds the 4 MiB limit or contains no data');
39
+ // A fixed upper bound also catches a file growing after stat without an unbounded readFile allocation.
40
+ const bytes = Buffer.alloc(MAX_IMAGE_BYTES + 1);
41
+ let length = 0;
42
+ while (length < bytes.length) {
43
+ context.abortSignal?.throwIfAborted();
44
+ const { bytesRead } = await file.read(bytes, length, bytes.length - length, length);
45
+ if (!bytesRead)
46
+ break;
47
+ length += bytesRead;
48
+ }
49
+ if (!length || length > MAX_IMAGE_BYTES)
50
+ throw new Error('Image exceeds the 4 MiB limit or contains no data');
51
+ return bytes.subarray(0, length);
52
+ }
53
+ finally {
54
+ await file.close();
55
+ }
56
+ }),
57
+ joinPath: disabled, readTextFile: disabled, readTextLines: disabled,
58
+ writeFile: disabled, appendFile: disabled, renameFile: disabled, fileInfo: disabled,
59
+ listDir: disabled, canonicalPath: disabled, createDir: disabled, remove: disabled,
60
+ createTempDir: disabled, createTempFile: disabled,
61
+ exec: async () => err(new ExecutionError('shell_unavailable', 'Image reads cannot execute shell commands')),
62
+ cleanup: async () => { },
63
+ };
64
+ }
65
+ /** Internal CLI adapter. The public tool remains a CCDD definition and creates no Agent or Provider session. */
66
+ export async function imageRequest(input) {
67
+ const request = objectArguments(input, ['operation', 'root', 'directory', 'args']);
68
+ if (request.operation !== 'view_image' || typeof request.root !== 'string' || typeof request.directory !== 'boolean')
69
+ throw new Error('Invalid image request');
70
+ const args = objectArguments(request.args, ['path']);
71
+ const path = internalPath(args.path);
72
+ if (request.directory && !path)
73
+ throw new Error('Viewing an image in a directory Artifact requires an internal file path');
74
+ if (!request.directory && Object.hasOwn(args, 'path'))
75
+ throw new Error('A file Artifact image view does not accept path');
76
+ const env = imageEnvironment(request.root, request.directory, path);
77
+ const invocation = {
78
+ invocationId: 'ccdd-image', operationId: 'view_image', turnId: 'ccdd-image',
79
+ async getMemo() { return undefined; },
80
+ async setMemo() { throw new Error('Image reads do not use session state'); },
81
+ };
82
+ const result = await createReadTool({ autoResizeImages: false }).execute('ccdd-image', { path: '/ccdd-image' }, () => { }, { env }, invocation, BACKGROUND_CONTEXT);
83
+ const images = result.content.filter(block => block.type === 'image');
84
+ if (images.length !== 1)
85
+ throw new Error('Pi read did not return a supported image. view_image requires PNG, JPEG or WebP; text, GIF, BMP and animated PNG are not supported');
86
+ return imageContent(images[0]);
87
+ }
88
+ //# sourceMappingURL=image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.js","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import type { ToolContext, ToolDefinition, ToolResult } from '@ccdd/core';
2
+ export interface ReaderOptions {
3
+ description?: string;
4
+ timeoutMs?: number;
5
+ }
6
+ export interface ReadArguments {
7
+ startLine?: number;
8
+ lineCount?: number;
9
+ }
10
+ export interface FileReadArguments extends ReadArguments {
11
+ path: string;
12
+ }
13
+ export interface ListArguments {
14
+ path?: string;
15
+ offset?: number;
16
+ limit?: number;
17
+ }
18
+ export interface ImageViewArguments {
19
+ path?: string;
20
+ }
21
+ export interface DesktopOpenArguments {
22
+ path?: string;
23
+ }
24
+ export interface DesktopOpenOptions {
25
+ /** Registered executable, never supplied by a reviewer. Defaults to macOS /usr/bin/open. */
26
+ command?: string;
27
+ /** Fixed argv containing a standalone {artifactPath}. Omit to append the Artifact path. */
28
+ args?: string[];
29
+ /** macOS application name or bundle path, passed to /usr/bin/open -a. */
30
+ app?: string;
31
+ description?: string;
32
+ timeoutMs?: number;
33
+ }
34
+ export interface DefaultToolDefinition<Args> extends ToolDefinition<Args> {
35
+ execute(context: ToolContext, args: Args): Promise<ToolResult>;
36
+ preflight(context: ToolContext): Promise<{
37
+ ok: boolean;
38
+ message: string;
39
+ }>;
40
+ }
41
+ declare function desktopOpen(options?: DesktopOpenOptions): DefaultToolDefinition<DesktopOpenArguments>;
42
+ declare function imageView(options?: ReaderOptions): DefaultToolDefinition<ImageViewArguments>;
43
+ /** Pure factories: importing this library or constructing tools performs no registration, I/O or process execution. */
44
+ export declare const agent: {
45
+ text: {
46
+ read: (options?: ReaderOptions) => DefaultToolDefinition<ReadArguments>;
47
+ };
48
+ files: {
49
+ read: (options?: ReaderOptions) => DefaultToolDefinition<FileReadArguments>;
50
+ list: (options?: ReaderOptions) => DefaultToolDefinition<ListArguments>;
51
+ };
52
+ image: {
53
+ view: typeof imageView;
54
+ };
55
+ };
56
+ export declare const human: {
57
+ desktop: {
58
+ open: typeof desktopOpen;
59
+ };
60
+ };
61
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,214 @@
1
+ import { constants } from 'node:fs';
2
+ import { access, stat } from 'node:fs/promises';
3
+ import { delimiter, isAbsolute, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { internalPath, objectArguments } from './reader.js';
6
+ import { runToolProcess, toolEnvironment } from './process.js';
7
+ import { imageContent, MAX_IMAGE_OUTPUT_BYTES } from './image-result.js';
8
+ function timeout(value, fallback) {
9
+ if (value === undefined)
10
+ return fallback;
11
+ if (!Number.isSafeInteger(value) || value < 1 || value > 120_000)
12
+ throw new Error('timeoutMs must be an integer from 1 to 120000');
13
+ return value;
14
+ }
15
+ async function availableExecutable(command, signal) {
16
+ signal.throwIfAborted();
17
+ if (!command || command.includes('\0') || (!isAbsolute(command) && /[/\\]/.test(command)))
18
+ throw new Error('Tool executable must be an absolute path or a PATH command name');
19
+ const candidates = isAbsolute(command) ? [command] : (process.env.PATH ?? '').split(delimiter).filter(isAbsolute).map(path => join(path, command));
20
+ for (const candidate of candidates) {
21
+ signal.throwIfAborted();
22
+ try {
23
+ if (!(await stat(candidate)).isFile())
24
+ continue;
25
+ await access(candidate, constants.X_OK);
26
+ signal.throwIfAborted();
27
+ return candidate;
28
+ }
29
+ catch {
30
+ signal.throwIfAborted();
31
+ }
32
+ }
33
+ throw new Error('The registered tool executable is unavailable');
34
+ }
35
+ const cliPath = fileURLToPath(new URL('./cli.js', import.meta.url));
36
+ async function prepareReader(context, directory) {
37
+ context.signal.throwIfAborted();
38
+ if (context.artifactDirectory !== directory)
39
+ throw new Error(directory ? 'This tool requires a directory Artifact' : 'This tool requires a file Artifact');
40
+ const root = await context.resolvePath();
41
+ const info = await stat(root);
42
+ if (directory ? !info.isDirectory() : !info.isFile())
43
+ throw new Error('Artifact shape changed');
44
+ await access(cliPath, constants.R_OK);
45
+ await access(process.execPath, constants.X_OK);
46
+ context.signal.throwIfAborted();
47
+ return root;
48
+ }
49
+ function readSchema(directory) {
50
+ return {
51
+ type: 'object',
52
+ properties: {
53
+ ...(directory ? { path: { type: 'string', minLength: 1, description: 'A file path relative to this Artifact directory.' } } : {}),
54
+ startLine: { type: 'integer', minimum: 1, maximum: Number.MAX_SAFE_INTEGER, default: 1, description: 'First line to read, starting at 1.' },
55
+ lineCount: { type: 'integer', minimum: 1, maximum: 500, default: 80, description: 'Maximum number of complete lines to return.' },
56
+ },
57
+ ...(directory ? { required: ['path'] } : {}), additionalProperties: false,
58
+ };
59
+ }
60
+ function readerTool(operation, directory, options) {
61
+ const timeoutMs = timeout(options.timeoutMs, 30_000);
62
+ return {
63
+ metadata: {
64
+ description: options.description ?? (operation === 'list' ? 'List files and directories inside {artifactName}.' : 'Read complete UTF-8 text lines from {artifactName}.'),
65
+ inputSchema: operation === 'read' ? readSchema(directory) : {
66
+ type: 'object', properties: {
67
+ path: { type: 'string', description: 'Optional directory path relative to this Artifact.' },
68
+ offset: { type: 'integer', minimum: 0, maximum: Number.MAX_SAFE_INTEGER, default: 0 },
69
+ limit: { type: 'integer', minimum: 1, maximum: 200, default: 200 },
70
+ }, additionalProperties: false,
71
+ },
72
+ resultKinds: ['json'], observation: operation === 'read' ? 'content' : 'none', artifactKind: directory ? 'directory' : 'file', timeoutMs,
73
+ },
74
+ async execute(context, args) {
75
+ const root = await prepareReader(context, directory);
76
+ const actualArgs = objectArguments(args, operation === 'read' ? (directory ? ['path', 'startLine', 'lineCount'] : ['startLine', 'lineCount']) : ['path', 'offset', 'limit']);
77
+ const path = internalPath(actualArgs.path);
78
+ if (operation === 'read' && directory && !path)
79
+ throw new Error('Reading a directory artifact requires an internal file path');
80
+ // Resolve with the Runner before sending data to the independent CLI path checks.
81
+ await context.resolvePath(path || undefined);
82
+ const raw = await runToolProcess(process.execPath, [cliPath], {
83
+ cwd: context.outputDir, env: toolEnvironment(context.tmpDir), signal: context.signal, timeoutMs,
84
+ input: JSON.stringify({ operation, root, directory, args: actualArgs }),
85
+ });
86
+ context.signal.throwIfAborted();
87
+ const response = JSON.parse(raw);
88
+ if (!response.ok || !response.data)
89
+ throw new Error(response.message ?? 'Invalid reader CLI response');
90
+ const data = { artifactId: context.artifactId, ...response.data };
91
+ const observed = operation === 'read' && typeof data.lineCount === 'number' && data.lineCount > 0;
92
+ const empty = operation === 'read' && data.lineCount === 0 && data.totalLines === 0;
93
+ return {
94
+ content: [{ type: 'json', data }],
95
+ ...(observed ? { observation: { kind: 'content' } } : empty ? { observation: { kind: 'empty' } } : {}),
96
+ };
97
+ },
98
+ async preflight(context) {
99
+ try {
100
+ await prepareReader(context, directory);
101
+ return { ok: true, message: 'Artifact and package-local Node CLI are available. No content was read.' };
102
+ }
103
+ catch (error) {
104
+ context.signal.throwIfAborted();
105
+ return { ok: false, message: error instanceof Error ? error.message : 'Reader preparation failed' };
106
+ }
107
+ },
108
+ };
109
+ }
110
+ function desktopOpen(options = {}) {
111
+ if (options.app !== undefined && (typeof options.app !== 'string' || !options.app || options.app.includes('\0')))
112
+ throw new Error('app must be a nonempty application name or path');
113
+ if (options.app !== undefined && (options.command !== undefined || options.args !== undefined))
114
+ throw new Error('app cannot be combined with command or args');
115
+ if (options.command !== undefined && (typeof options.command !== 'string' || !options.command || options.command.includes('\0')))
116
+ throw new Error('command must be a nonempty executable name or path');
117
+ if (options.args !== undefined && (!Array.isArray(options.args) || !options.args.includes('{artifactPath}') || options.args.some(arg => typeof arg !== 'string' || arg.includes('\0') || (arg.includes('{artifactPath}') && arg !== '{artifactPath}'))))
118
+ throw new Error('args must include a standalone {artifactPath} token');
119
+ if (options.args !== undefined && options.command === undefined)
120
+ throw new Error('args requires an explicit command');
121
+ const configured = { ...options, ...(options.args ? { args: [...options.args] } : {}) };
122
+ const timeoutMs = timeout(options.timeoutMs, 10_000);
123
+ const command = () => {
124
+ if (configured.command)
125
+ return configured.command;
126
+ if (process.platform !== 'darwin')
127
+ throw new Error('The default desktop opener is supported on macOS. Register an explicit command on this platform.');
128
+ return '/usr/bin/open';
129
+ };
130
+ return {
131
+ metadata: {
132
+ description: options.description ?? 'Open {artifactName} in a desktop application. Opening does not submit a verdict.',
133
+ inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Optional internal path for a directory Artifact. Omit for the Artifact itself.' } }, additionalProperties: false },
134
+ resultKinds: ['launch'], observation: 'none', artifactKind: 'any', timeoutMs,
135
+ },
136
+ async execute(context, args) {
137
+ const actualArgs = objectArguments(args, ['path']);
138
+ if (!context.artifactDirectory && Object.hasOwn(actualArgs, 'path'))
139
+ throw new Error('A file Artifact open does not accept path');
140
+ const target = await context.resolvePath(internalPath(actualArgs.path) || undefined);
141
+ const executable = await availableExecutable(command(), context.signal);
142
+ const argv = configured.args ? configured.args.map(arg => arg === '{artifactPath}' ? target : arg)
143
+ : configured.command ? [target] : [...(configured.app ? ['-a', configured.app] : []), '--', target];
144
+ await runToolProcess(executable, argv, { cwd: context.outputDir, env: toolEnvironment(context.tmpDir, true), signal: context.signal, timeoutMs, capture: false });
145
+ context.signal.throwIfAborted();
146
+ return { content: [{ type: 'launch', launched: true }] };
147
+ },
148
+ async preflight(context) {
149
+ try {
150
+ await context.resolvePath();
151
+ await availableExecutable(command(), context.signal);
152
+ return { ok: true, message: 'Artifact and registered desktop opener are available. No application was launched.' };
153
+ }
154
+ catch (error) {
155
+ context.signal.throwIfAborted();
156
+ return { ok: false, message: error instanceof Error ? error.message : 'Desktop opener preparation failed' };
157
+ }
158
+ },
159
+ };
160
+ }
161
+ function imageView(options = {}) {
162
+ const timeoutMs = timeout(options.timeoutMs, 30_000);
163
+ return {
164
+ metadata: {
165
+ description: options.description ?? 'View a PNG, JPEG or WebP image from {artifactName}. Omit path for a file Artifact; a directory Artifact requires an internal file path. Images must be at most 4 MiB.',
166
+ inputSchema: { type: 'object', properties: { path: { type: 'string', minLength: 1, description: 'Required internal image path for a directory Artifact. Omit for a file Artifact.' } }, additionalProperties: false },
167
+ resultKinds: ['image'], observation: 'content', artifactKind: 'any', timeoutMs,
168
+ },
169
+ async execute(context, args) {
170
+ const root = await prepareReader(context, context.artifactDirectory);
171
+ const actualArgs = objectArguments(args, ['path']);
172
+ const path = internalPath(actualArgs.path);
173
+ if (context.artifactDirectory && !path)
174
+ throw new Error('Viewing an image in a directory Artifact requires an internal file path');
175
+ if (!context.artifactDirectory && Object.hasOwn(actualArgs, 'path'))
176
+ throw new Error('A file Artifact image view does not accept path');
177
+ await context.resolvePath(path || undefined);
178
+ const raw = await runToolProcess(process.execPath, [cliPath], {
179
+ cwd: context.outputDir, env: toolEnvironment(context.tmpDir), signal: context.signal, timeoutMs,
180
+ input: JSON.stringify({ operation: 'view_image', root, directory: context.artifactDirectory, args: actualArgs }),
181
+ maxOutputBytes: MAX_IMAGE_OUTPUT_BYTES,
182
+ });
183
+ context.signal.throwIfAborted();
184
+ const response = JSON.parse(raw);
185
+ if (!response.ok)
186
+ throw new Error(response.message ?? 'Invalid image CLI response');
187
+ const content = imageContent(response.data);
188
+ return { content: [content], observation: { kind: 'content' } };
189
+ },
190
+ async preflight(context) {
191
+ try {
192
+ await prepareReader(context, context.artifactDirectory);
193
+ await access(fileURLToPath(import.meta.resolve('@earendil-works/pi-agent-core')), constants.R_OK);
194
+ context.signal.throwIfAborted();
195
+ return { ok: true, message: 'Artifact and package-local image CLI are available. No image was read.' };
196
+ }
197
+ catch (error) {
198
+ context.signal.throwIfAborted();
199
+ return { ok: false, message: error instanceof Error ? error.message : 'Image preparation failed' };
200
+ }
201
+ },
202
+ };
203
+ }
204
+ /** Pure factories: importing this library or constructing tools performs no registration, I/O or process execution. */
205
+ export const agent = {
206
+ text: { read: (options = {}) => readerTool('read', false, options) },
207
+ files: {
208
+ read: (options = {}) => readerTool('read', true, options),
209
+ list: (options = {}) => readerTool('list', true, options),
210
+ },
211
+ image: { view: imageView },
212
+ };
213
+ export const human = { desktop: { open: desktopOpen } };
214
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ interface ProcessOptions {
2
+ cwd: string;
3
+ env: NodeJS.ProcessEnv;
4
+ signal: AbortSignal;
5
+ timeoutMs: number;
6
+ input?: string;
7
+ capture?: boolean;
8
+ maxOutputBytes?: number;
9
+ }
10
+ /** Never forward arbitrary environment variables, including Provider credentials or NODE_OPTIONS. */
11
+ export declare function toolEnvironment(tmpDir: string, desktop?: boolean): NodeJS.ProcessEnv;
12
+ /** Kill the complete launcher group on cancellation, including children surviving their parent. */
13
+ export declare function runToolProcess(command: string, args: string[], options: ProcessOptions): Promise<string>;
14
+ export {};
@@ -0,0 +1,75 @@
1
+ import { spawn } from 'node:child_process';
2
+ /** Never forward arbitrary environment variables, including Provider credentials or NODE_OPTIONS. */
3
+ export function toolEnvironment(tmpDir, desktop = false) {
4
+ const names = desktop
5
+ ? ['PATH', 'HOME', 'USER', 'LOGNAME', 'DISPLAY', 'WAYLAND_DISPLAY', 'XDG_RUNTIME_DIR', 'DBUS_SESSION_BUS_ADDRESS', 'LANG', 'LC_ALL', 'SYSTEMROOT', 'WINDIR']
6
+ : ['LANG', 'LC_ALL', 'SYSTEMROOT', 'WINDIR'];
7
+ return { ...Object.fromEntries(names.flatMap(name => process.env[name] === undefined ? [] : [[name, process.env[name]]])), TMPDIR: tmpDir, TMP: tmpDir, TEMP: tmpDir };
8
+ }
9
+ /** Kill the complete launcher group on cancellation, including children surviving their parent. */
10
+ export function runToolProcess(command, args, options) {
11
+ options.signal.throwIfAborted();
12
+ return new Promise((resolve, reject) => {
13
+ const child = spawn(command, args, {
14
+ cwd: options.cwd, env: options.env, shell: false, detached: process.platform !== 'win32',
15
+ stdio: options.capture === false ? ['pipe', 'ignore', 'ignore'] : ['pipe', 'pipe', 'pipe'], windowsHide: true,
16
+ });
17
+ const chunks = [];
18
+ let bytes = 0, settled = false, failure, killTimer;
19
+ const kill = (signal) => {
20
+ try {
21
+ if (process.platform !== 'win32' && child.pid)
22
+ process.kill(-child.pid, signal);
23
+ else
24
+ child.kill(signal);
25
+ }
26
+ catch { /* Already exited. */ }
27
+ };
28
+ const finish = (error) => {
29
+ if (settled)
30
+ return;
31
+ settled = true;
32
+ clearTimeout(timer);
33
+ clearTimeout(killTimer);
34
+ options.signal.removeEventListener('abort', abort);
35
+ if (error)
36
+ reject(error);
37
+ else
38
+ resolve(Buffer.concat(chunks).toString('utf8'));
39
+ };
40
+ const stop = (error) => {
41
+ if (settled || failure)
42
+ return;
43
+ failure = error;
44
+ kill('SIGTERM');
45
+ killTimer = setTimeout(() => { kill('SIGKILL'); finish(error); }, 500);
46
+ killTimer.unref();
47
+ };
48
+ const abort = () => stop(new Error('Artifact tool execution aborted'));
49
+ const timer = setTimeout(() => stop(new Error(`Artifact tool execution timed out after ${options.timeoutMs} ms`)), options.timeoutMs);
50
+ timer.unref();
51
+ options.signal.addEventListener('abort', abort, { once: true });
52
+ child.stdout?.on('data', (chunk) => {
53
+ bytes += chunk.length;
54
+ if (bytes > (options.maxOutputBytes ?? 1024 * 1024)) {
55
+ stop(new Error('Artifact tool output exceeded its limit'));
56
+ return;
57
+ }
58
+ chunks.push(chunk);
59
+ });
60
+ // CLI errors use the bounded JSON protocol. Never return raw launcher stderr to reviewers.
61
+ child.stderr?.resume();
62
+ child.stdin?.on('error', () => { });
63
+ child.on('error', () => { if (failure)
64
+ kill('SIGKILL'); finish(failure ?? new Error('The registered tool executable could not be started')); });
65
+ child.on('close', code => {
66
+ if (failure)
67
+ kill('SIGKILL');
68
+ finish(failure ?? (code === 0 ? undefined : new Error('The registered tool executable did not finish successfully')));
69
+ });
70
+ child.stdin?.end(options.input ?? '');
71
+ if (options.signal.aborted)
72
+ abort();
73
+ });
74
+ }
75
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../src/process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface LineReadResult {
2
+ content: string;
3
+ startLine: number;
4
+ endLine: number | null;
5
+ lineCount: number;
6
+ totalLines?: number;
7
+ truncated: boolean;
8
+ nextStartLine: number | null;
9
+ }
10
+ export declare function objectArguments(args: unknown, allowed: readonly string[]): Record<string, unknown>;
11
+ export declare function internalPath(value?: unknown): string;
12
+ export declare function scopedTarget(root: string, directory: boolean, path: string): Promise<string>;
13
+ /** Package-local CLI entry logic; the public tool always invokes this in a child process. */
14
+ export declare function readerRequest(input: unknown): Promise<Record<string, unknown>>;
package/dist/reader.js ADDED
@@ -0,0 +1,143 @@
1
+ import { constants } from 'node:fs';
2
+ import { lstat, open, readdir, realpath, stat } from 'node:fs/promises';
3
+ import { isAbsolute, relative, resolve, sep } from 'node:path';
4
+ const MAX_READ_BYTES = 64 * 1024;
5
+ export function objectArguments(args, allowed) {
6
+ if (!args || typeof args !== 'object' || Array.isArray(args) || Object.keys(args).some(key => !allowed.includes(key)))
7
+ throw new Error('Invalid artifact tool arguments');
8
+ return args;
9
+ }
10
+ function integer(value, fallback, min, max, name) {
11
+ if (value === undefined)
12
+ return fallback;
13
+ if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < min || value > max)
14
+ throw new Error(`Invalid ${name}`);
15
+ return value;
16
+ }
17
+ export function internalPath(value = '') {
18
+ if (typeof value !== 'string' || value.includes('\0') || value.includes('\\') || isAbsolute(value) || value.split('/').some(part => part === '.' || part === '..'))
19
+ throw new Error('Artifact path must be a safe internal relative path');
20
+ return value;
21
+ }
22
+ export async function scopedTarget(root, directory, path) {
23
+ if (!isAbsolute(root) || (await lstat(root)).isSymbolicLink())
24
+ throw new Error('Artifact root must be an absolute non-symlink path');
25
+ const base = await realpath(root);
26
+ const info = await stat(base);
27
+ if (directory ? !info.isDirectory() : !info.isFile())
28
+ throw new Error('Artifact shape changed');
29
+ if (!directory && path)
30
+ throw new Error('A file artifact has no child paths');
31
+ let candidate = base;
32
+ for (const part of path.split('/').filter(Boolean)) {
33
+ candidate = resolve(candidate, part);
34
+ if ((await lstat(candidate)).isSymbolicLink())
35
+ throw new Error('Artifact paths must not contain symlinks');
36
+ }
37
+ candidate = await realpath(candidate);
38
+ const sub = relative(base, candidate);
39
+ if (sub === '..' || sub.startsWith(`..${sep}`) || isAbsolute(sub))
40
+ throw new Error('Requested path escapes the artifact');
41
+ return candidate;
42
+ }
43
+ /** Stream original LF/CRLF bytes. Skip preceding lines without retaining them or decoding unrelated content. */
44
+ async function readLines(file, size, startLine, requestedCount) {
45
+ const output = [];
46
+ let position = 0, currentLine = 1, currentBytes = 0, returnedBytes = 0, returnedLines = 0;
47
+ let fragments = [];
48
+ const result = (nextStartLine, totalLines) => {
49
+ let content;
50
+ try {
51
+ content = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(Buffer.concat(output, returnedBytes));
52
+ }
53
+ catch {
54
+ throw new Error(`Artifact contains invalid UTF-8 text in the requested lines starting at ${startLine}`);
55
+ }
56
+ return { content, startLine, endLine: returnedLines ? startLine + returnedLines - 1 : null, lineCount: returnedLines,
57
+ ...(totalLines === undefined ? {} : { totalLines }), truncated: nextStartLine !== null, nextStartLine };
58
+ };
59
+ for (;;) {
60
+ const bytes = Buffer.alloc(MAX_READ_BYTES);
61
+ const { bytesRead } = await file.read(bytes, 0, bytes.length, position);
62
+ if (!bytesRead)
63
+ break;
64
+ let cursor = 0;
65
+ while (cursor < bytesRead) {
66
+ const newline = bytes.subarray(0, bytesRead).indexOf(10, cursor);
67
+ const end = newline === -1 ? bytesRead : newline + 1;
68
+ const fragment = bytes.subarray(cursor, end);
69
+ if (currentLine >= startLine) {
70
+ if (currentBytes + fragment.length > MAX_READ_BYTES - returnedBytes) {
71
+ if (returnedLines)
72
+ return result(currentLine);
73
+ throw new Error(`Artifact line ${currentLine} exceeds the ${MAX_READ_BYTES}-byte read limit; use a tool that supports oversized lines`);
74
+ }
75
+ if (fragment.includes(0))
76
+ throw new Error('Binary artifacts require a different tool');
77
+ fragments.push(fragment);
78
+ }
79
+ currentBytes += fragment.length;
80
+ if (newline !== -1) {
81
+ if (currentLine >= startLine) {
82
+ output.push(...fragments);
83
+ returnedBytes += currentBytes;
84
+ returnedLines++;
85
+ fragments = [];
86
+ if (returnedLines === requestedCount || returnedBytes === MAX_READ_BYTES) {
87
+ const more = position + end < size;
88
+ return result(more ? currentLine + 1 : null, more ? undefined : currentLine);
89
+ }
90
+ }
91
+ currentLine++;
92
+ currentBytes = 0;
93
+ }
94
+ cursor = end;
95
+ }
96
+ position += bytesRead;
97
+ }
98
+ if (currentBytes && currentLine >= startLine) {
99
+ output.push(...fragments);
100
+ returnedBytes += currentBytes;
101
+ returnedLines++;
102
+ }
103
+ return result(null, currentLine - 1 + (currentBytes ? 1 : 0));
104
+ }
105
+ /** Package-local CLI entry logic; the public tool always invokes this in a child process. */
106
+ export async function readerRequest(input) {
107
+ const request = objectArguments(input, ['operation', 'root', 'directory', 'args']);
108
+ if (typeof request.root !== 'string' || typeof request.directory !== 'boolean' || !['read', 'list'].includes(request.operation))
109
+ throw new Error('Invalid reader request');
110
+ const operation = request.operation;
111
+ const args = objectArguments(request.args, operation === 'read' ? ['path', 'startLine', 'lineCount'] : ['path', 'offset', 'limit']);
112
+ const path = internalPath(args.path);
113
+ if (operation === 'read') {
114
+ if (request.directory && !path)
115
+ throw new Error('Reading a directory artifact requires an internal file path');
116
+ if (!request.directory && Object.hasOwn(args, 'path'))
117
+ throw new Error('A file artifact read does not accept path');
118
+ const startLine = integer(args.startLine, 1, 1, Number.MAX_SAFE_INTEGER, 'startLine');
119
+ const lineCount = integer(args.lineCount, 80, 1, 500, 'lineCount');
120
+ const candidate = await scopedTarget(request.root, request.directory, path);
121
+ const file = await open(candidate, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
122
+ try {
123
+ const info = await file.stat();
124
+ if (!info.isFile())
125
+ throw new Error('Reading requires a regular file; list the directory first');
126
+ return { path, ...await readLines(file, info.size, startLine, lineCount) };
127
+ }
128
+ finally {
129
+ await file.close();
130
+ }
131
+ }
132
+ if (!request.directory)
133
+ throw new Error('Listing requires a directory artifact');
134
+ const offset = integer(args.offset, 0, 0, Number.MAX_SAFE_INTEGER, 'offset');
135
+ const limit = integer(args.limit, 200, 1, 200, 'limit');
136
+ const candidate = await scopedTarget(request.root, true, path);
137
+ const all = await readdir(candidate, { withFileTypes: true });
138
+ all.sort((a, b) => a.name.localeCompare(b.name));
139
+ const entries = all.slice(offset, offset + limit).map(entry => ({ name: entry.name, path: path ? `${path}/${entry.name}` : entry.name,
140
+ kind: entry.isDirectory() ? 'directory' : entry.isFile() ? 'file' : entry.isSymbolicLink() ? 'symlink' : 'other' }));
141
+ return { path, entries, totalEntries: all.length, nextOffset: offset + entries.length < all.length ? offset + entries.length : null };
142
+ }
143
+ //# sourceMappingURL=reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../src/reader.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@ccdd/default-tools",
3
+ "version": "2.0.1",
4
+ "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" },
5
+ "repository": { "type": "git", "url": "git+https://github.com/lhj6102/ccdd.git", "directory": "packages/default-tools" },
6
+ "description": "Explicitly registered Agent CLI and Human desktop Artifact tools for CCDD",
7
+ "type": "module",
8
+ "engines": { "node": ">=24" },
9
+ "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } },
10
+ "types": "./dist/index.d.ts",
11
+ "files": ["dist/", "README.md"],
12
+ "scripts": {
13
+ "build": "node ../../node_modules/typescript/bin/tsc -p tsconfig.json",
14
+ "prepack": "npm run build"
15
+ },
16
+ "peerDependencies": { "@ccdd/core": ">=2.0.0 <3" },
17
+ "dependencies": { "@earendil-works/pi-agent-core": "0.85.1" },
18
+ "devDependencies": { "@ccdd/core": "file:../.." }
19
+ }