@agent-api/sdk 1.1.5 → 1.2.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/CHANGELOG.md +7 -6
- package/README.md +15 -15
- package/dist/local/context.d.ts +4 -4
- package/dist/local/context.js +10 -10
- package/dist/local/core.d.ts +30 -30
- package/dist/local/core.js +12 -12
- package/dist/local/tools.d.ts +17 -17
- package/dist/local/tools.js +46 -46
- package/dist/node.d.ts +2 -2
- package/dist/node.js +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/dist-cjs/local/context.js +10 -10
- package/dist-cjs/local/core.js +15 -15
- package/dist-cjs/local/tools.js +51 -51
- package/dist-cjs/node.js +5 -5
- package/dist-cjs/version.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog — @agent-api/sdk
|
|
2
2
|
|
|
3
|
-
## 1.
|
|
3
|
+
## 1.2.0
|
|
4
4
|
|
|
5
5
|
### Added
|
|
6
6
|
|
|
@@ -9,18 +9,19 @@
|
|
|
9
9
|
|
|
10
10
|
### Changed
|
|
11
11
|
|
|
12
|
+
- Renamed local SDK concepts from workspace to workdir to avoid confusion with platform identity workspaces.
|
|
12
13
|
- Extended response input types so tool-call continuations can carry function-call metadata consistently.
|
|
13
14
|
|
|
14
15
|
## 1.1.2
|
|
15
16
|
|
|
16
17
|
### Added
|
|
17
18
|
|
|
18
|
-
- Added a model-facing `
|
|
19
|
-
- Added approval-aware dispatch for mutating local
|
|
19
|
+
- Added a model-facing `local_workdir` driver/tool primitive for local workdir operations.
|
|
20
|
+
- Added approval-aware dispatch for mutating local workdir actions.
|
|
20
21
|
|
|
21
22
|
### Changed
|
|
22
23
|
|
|
23
|
-
- Replaced fragmented local
|
|
24
|
+
- Replaced fragmented local workdir tool presentation with an action-based adapter over the low-level local APIs.
|
|
24
25
|
|
|
25
26
|
## 1.1.1
|
|
26
27
|
|
|
@@ -38,9 +39,9 @@
|
|
|
38
39
|
- Cross-platform app directory resolution for data, config, cache, logs, and temp files.
|
|
39
40
|
- Root-scoped local file stores with path traversal protection, atomic writes, JSON helpers, recursive listing, and local skill discovery.
|
|
40
41
|
- Local workdir operations for entry search, file delivery, line-range reads and edits, literal grep, and directory summaries.
|
|
41
|
-
- `
|
|
42
|
+
- `LocalWorkdir` and `LocalWorkdirManager` for project roots, default ignore rules, patch previews, snapshots, diffs, and file-watch handles.
|
|
42
43
|
- Typed local errors, `.gitignore` loading, sensitivity classification for likely secret paths, and multi-file line-edit plans with conflict detection and rollback.
|
|
43
|
-
- `createLocalContextPackage()` for bounded, secret-aware local
|
|
44
|
+
- `createLocalContextPackage()` for bounded, secret-aware local workdir manifests that app integrations can hand to agent workflows.
|
|
44
45
|
|
|
45
46
|
### Changed
|
|
46
47
|
|
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ Public package entrypoints:
|
|
|
44
44
|
|
|
45
45
|
- `@agent-api/sdk`: browser-safe REST client, public types, auth, responses, models, presets, tools, volumes, and skills HTTP APIs.
|
|
46
46
|
- `@agent-api/sdk/browser`: explicit alias of the browser-safe REST client entry.
|
|
47
|
-
- `@agent-api/sdk/local`: Node-only local runtime,
|
|
47
|
+
- `@agent-api/sdk/local`: Node-only local runtime, workdir, context, and local workdir tool support.
|
|
48
48
|
- `@agent-api/sdk/node`: Node aggregate entry for local helpers such as `localSkillFromDirectory()` plus `NodeAgentAPI`.
|
|
49
49
|
|
|
50
50
|
```
|
|
@@ -114,7 +114,7 @@ const binary = await client.volumes.readFile(volume.volume_id, "assets/logo.png"
|
|
|
114
114
|
|
|
115
115
|
const response = await client.agent.create({
|
|
116
116
|
preset: "pro-search",
|
|
117
|
-
input: "Use the attached
|
|
117
|
+
input: "Use the attached agent volume.",
|
|
118
118
|
volume_id: volume.volume_id,
|
|
119
119
|
});
|
|
120
120
|
```
|
|
@@ -125,10 +125,10 @@ const response = await client.agent.create({
|
|
|
125
125
|
|
|
126
126
|
```typescript
|
|
127
127
|
import { resolvePresetTools } from "@agent-api/sdk";
|
|
128
|
-
import {
|
|
128
|
+
import { createLocalWorkdirToolRegistry, LocalWorkdir } from "@agent-api/sdk/local";
|
|
129
129
|
|
|
130
|
-
const
|
|
131
|
-
const registry =
|
|
130
|
+
const workdir = new LocalWorkdir("/path/to/project", { trusted: true });
|
|
131
|
+
const registry = createLocalWorkdirToolRegistry(workdir);
|
|
132
132
|
|
|
133
133
|
const { tools } = await resolvePresetTools(client, {
|
|
134
134
|
preset: "pro-search",
|
|
@@ -188,7 +188,7 @@ The runtime provides:
|
|
|
188
188
|
- Root-scoped file stores with path traversal protection.
|
|
189
189
|
- Atomic text/JSON writes, byte reads/writes, recursive listing, copy, remove, and stat helpers.
|
|
190
190
|
- Local workdir operations inspired by platform volumes: `listEntries`, `searchEntries`, `readFile`, `writeFile`, `deletePath`, `createDirectory`, `readLines`, `patchLines`, `grep`, and `summarize`.
|
|
191
|
-
- First-class local
|
|
191
|
+
- First-class local workdirs with default ignore rules, scoped workbench operations, patch previews, snapshots, diffs, file-watch handles, and budgeted context packaging.
|
|
192
192
|
- Typed local errors, `.gitignore` loading, sensitivity classification, and multi-file edit plans with rollback on failure.
|
|
193
193
|
- JSON config helpers for typed app settings.
|
|
194
194
|
- Local skill discovery built on `localSkillFromDirectory()`.
|
|
@@ -196,24 +196,24 @@ The runtime provides:
|
|
|
196
196
|
Keep UI and OS interaction policy in your host framework. Electron, Tauri, Qt, or native apps should call this layer from their trusted local process and expose only the capabilities their UI needs.
|
|
197
197
|
|
|
198
198
|
```typescript
|
|
199
|
-
const
|
|
199
|
+
const workdir = local.data.child("workdirs/demo");
|
|
200
200
|
|
|
201
|
-
await
|
|
201
|
+
await workdir.writeText("src/index.ts", "console.log('hello');\n");
|
|
202
202
|
|
|
203
|
-
const matches = await
|
|
204
|
-
const lines = await
|
|
205
|
-
await
|
|
203
|
+
const matches = await workdir.grep({ pattern: "hello", path: "src" });
|
|
204
|
+
const lines = await workdir.readLines("src/index.ts", { startLine: 1, endLine: 20 });
|
|
205
|
+
await workdir.patchLines("src/index.ts", {
|
|
206
206
|
startLine: 1,
|
|
207
207
|
replacement: "console.log('patched');",
|
|
208
208
|
});
|
|
209
209
|
|
|
210
|
-
const summary = await
|
|
210
|
+
const summary = await workdir.summarize();
|
|
211
211
|
```
|
|
212
212
|
|
|
213
|
-
For project/
|
|
213
|
+
For project/workdir roots, prefer `local.workdir()` so SDK defaults protect common generated directories such as `.git`, `node_modules`, `dist`, and build caches.
|
|
214
214
|
|
|
215
215
|
```typescript
|
|
216
|
-
const project = local.
|
|
216
|
+
const project = local.workdir("/path/to/project", {
|
|
217
217
|
name: "my-project",
|
|
218
218
|
trusted: true,
|
|
219
219
|
ignore: ["vendor", /^tmp\//],
|
|
@@ -236,7 +236,7 @@ const diff = project.diff(before, after);
|
|
|
236
236
|
const sensitivity = project.classifyPath(".env");
|
|
237
237
|
```
|
|
238
238
|
|
|
239
|
-
Use `createLocalContextPackage()` when a local app needs to prepare bounded
|
|
239
|
+
Use `createLocalContextPackage()` when a local app needs to prepare bounded workdir context for an agent request. The package includes a manifest, selected file previews, optional search matches, hashes, sensitivity labels, and secret-aware omission by default.
|
|
240
240
|
|
|
241
241
|
```typescript
|
|
242
242
|
import { createLocalContextPackage } from "@agent-api/sdk/local";
|
package/dist/local/context.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type LocalFileDeliver, type LocalGrepResponse, type LocalPathSensitivity, type LocalPathSensitivityInfo, type LocalSummary, type
|
|
1
|
+
import { type LocalFileDeliver, type LocalGrepResponse, type LocalPathSensitivity, type LocalPathSensitivityInfo, type LocalSummary, type LocalWorkdir, type LocalWorkdirSnapshotFile } from "./core.js";
|
|
2
2
|
export interface LocalContextPackageParams {
|
|
3
3
|
path?: string;
|
|
4
4
|
include?: string[];
|
|
@@ -30,7 +30,7 @@ export interface LocalContextFile {
|
|
|
30
30
|
export interface LocalContextManifest {
|
|
31
31
|
object: "local_context_manifest";
|
|
32
32
|
root: string;
|
|
33
|
-
|
|
33
|
+
workdir_name: string;
|
|
34
34
|
generated_at_unix: number;
|
|
35
35
|
base_path: string;
|
|
36
36
|
file_count: number;
|
|
@@ -41,9 +41,9 @@ export interface LocalContextManifest {
|
|
|
41
41
|
summary?: LocalSummary;
|
|
42
42
|
search?: LocalGrepResponse;
|
|
43
43
|
}
|
|
44
|
-
export declare function createLocalContextPackage(
|
|
44
|
+
export declare function createLocalContextPackage(workdir: LocalWorkdir, params?: LocalContextPackageParams): Promise<LocalContextManifest>;
|
|
45
45
|
export declare function summarizeLocalContextSensitivity(files: Array<Pick<LocalContextFile, "path" | "sensitivity" | "sensitivity_reason">>): {
|
|
46
46
|
highest: LocalPathSensitivity;
|
|
47
47
|
files: LocalPathSensitivityInfo[];
|
|
48
48
|
};
|
|
49
|
-
export type LocalContextSnapshotFile =
|
|
49
|
+
export type LocalContextSnapshotFile = LocalWorkdirSnapshotFile;
|
package/dist/local/context.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import { classifyLocalPathSensitivity, } from "./core.js";
|
|
4
|
-
export async function createLocalContextPackage(
|
|
4
|
+
export async function createLocalContextPackage(workdir, params = {}) {
|
|
5
5
|
const basePath = params.path ?? ".";
|
|
6
6
|
const maxFiles = positiveInt(params.maxFiles, 80);
|
|
7
7
|
const maxBytes = positiveInt(params.maxBytes, 256 * 1024);
|
|
@@ -12,7 +12,7 @@ export async function createLocalContextPackage(workspace, params = {}) {
|
|
|
12
12
|
const includeSummary = params.includeSummary ?? true;
|
|
13
13
|
const includeSearch = Boolean(params.includeSearch && params.query?.trim());
|
|
14
14
|
const includeSecrets = params.includeSecrets ?? false;
|
|
15
|
-
const stats = await
|
|
15
|
+
const stats = await workdir.list(basePath, { recursive: true });
|
|
16
16
|
const fileStats = stats
|
|
17
17
|
.filter((item) => item.type === "file")
|
|
18
18
|
.filter((item) => matchesPathFilters(item.path, params.include, params.exclude))
|
|
@@ -49,7 +49,7 @@ export async function createLocalContextPackage(workspace, params = {}) {
|
|
|
49
49
|
truncated = true;
|
|
50
50
|
continue;
|
|
51
51
|
}
|
|
52
|
-
const delivered = await
|
|
52
|
+
const delivered = await workdir.readFile(item.path, { maxBytes: readBudget });
|
|
53
53
|
includedBytes += delivered.encoding === "text"
|
|
54
54
|
? Buffer.byteLength(delivered.content ?? "", "utf8")
|
|
55
55
|
: Buffer.byteLength(delivered.content_base64 ?? "", "base64");
|
|
@@ -64,7 +64,7 @@ export async function createLocalContextPackage(workspace, params = {}) {
|
|
|
64
64
|
packaged.content_base64 = delivered.content_base64;
|
|
65
65
|
}
|
|
66
66
|
if (includeHashes) {
|
|
67
|
-
packaged.sha256 = await sha256File(
|
|
67
|
+
packaged.sha256 = await sha256File(workdir, item.path);
|
|
68
68
|
}
|
|
69
69
|
if (delivered.truncated) {
|
|
70
70
|
truncated = true;
|
|
@@ -72,7 +72,7 @@ export async function createLocalContextPackage(workspace, params = {}) {
|
|
|
72
72
|
files.push(packaged);
|
|
73
73
|
}
|
|
74
74
|
const summary = includeSummary
|
|
75
|
-
? await
|
|
75
|
+
? await workdir.summarize({
|
|
76
76
|
path: basePath,
|
|
77
77
|
maxFiles,
|
|
78
78
|
previewBytes,
|
|
@@ -80,7 +80,7 @@ export async function createLocalContextPackage(workspace, params = {}) {
|
|
|
80
80
|
})
|
|
81
81
|
: undefined;
|
|
82
82
|
const search = includeSearch
|
|
83
|
-
? await
|
|
83
|
+
? await workdir.grep({
|
|
84
84
|
pattern: params.query,
|
|
85
85
|
path: basePath,
|
|
86
86
|
limit: maxFiles,
|
|
@@ -90,8 +90,8 @@ export async function createLocalContextPackage(workspace, params = {}) {
|
|
|
90
90
|
: undefined;
|
|
91
91
|
return {
|
|
92
92
|
object: "local_context_manifest",
|
|
93
|
-
root:
|
|
94
|
-
|
|
93
|
+
root: workdir.root,
|
|
94
|
+
workdir_name: workdir.name,
|
|
95
95
|
generated_at_unix: Math.floor(Date.now() / 1000),
|
|
96
96
|
base_path: basePath,
|
|
97
97
|
file_count: fileStats.length,
|
|
@@ -148,7 +148,7 @@ function positiveInt(value, fallback) {
|
|
|
148
148
|
const parsed = Number(value);
|
|
149
149
|
return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : fallback;
|
|
150
150
|
}
|
|
151
|
-
async function sha256File(
|
|
152
|
-
const fullPath =
|
|
151
|
+
async function sha256File(workdir, relativePath) {
|
|
152
|
+
const fullPath = workdir.files.resolvePath(relativePath);
|
|
153
153
|
return createHash("sha256").update(await readFile(fullPath)).digest("hex");
|
|
154
154
|
}
|
package/dist/local/core.d.ts
CHANGED
|
@@ -174,7 +174,7 @@ export interface LocalSummary {
|
|
|
174
174
|
generated_at_unix: number;
|
|
175
175
|
scan_truncated: boolean;
|
|
176
176
|
}
|
|
177
|
-
export interface
|
|
177
|
+
export interface LocalWorkdirOptions {
|
|
178
178
|
name?: string;
|
|
179
179
|
metadata?: Record<string, unknown>;
|
|
180
180
|
trusted?: boolean;
|
|
@@ -182,31 +182,31 @@ export interface LocalWorkspaceOptions {
|
|
|
182
182
|
gitignore?: boolean;
|
|
183
183
|
maxFileBytes?: number;
|
|
184
184
|
}
|
|
185
|
-
export interface
|
|
185
|
+
export interface LocalWorkdirSnapshotParams {
|
|
186
186
|
path?: string;
|
|
187
187
|
hash?: boolean;
|
|
188
188
|
maxBytesPerFile?: number;
|
|
189
189
|
}
|
|
190
|
-
export interface
|
|
190
|
+
export interface LocalWorkdirSnapshotFile {
|
|
191
191
|
path: string;
|
|
192
192
|
size: number;
|
|
193
193
|
modified_at_unix?: number;
|
|
194
194
|
sha256?: string;
|
|
195
195
|
}
|
|
196
|
-
export interface
|
|
196
|
+
export interface LocalWorkdirSnapshot {
|
|
197
197
|
root: string;
|
|
198
198
|
name: string;
|
|
199
199
|
generated_at_unix: number;
|
|
200
|
-
files:
|
|
200
|
+
files: LocalWorkdirSnapshotFile[];
|
|
201
201
|
}
|
|
202
|
-
export interface
|
|
203
|
-
added:
|
|
202
|
+
export interface LocalWorkdirDiff {
|
|
203
|
+
added: LocalWorkdirSnapshotFile[];
|
|
204
204
|
modified: Array<{
|
|
205
|
-
before:
|
|
206
|
-
after:
|
|
205
|
+
before: LocalWorkdirSnapshotFile;
|
|
206
|
+
after: LocalWorkdirSnapshotFile;
|
|
207
207
|
}>;
|
|
208
|
-
deleted:
|
|
209
|
-
unchanged:
|
|
208
|
+
deleted: LocalWorkdirSnapshotFile[];
|
|
209
|
+
unchanged: LocalWorkdirSnapshotFile[];
|
|
210
210
|
}
|
|
211
211
|
export interface LocalLinePatchPreview {
|
|
212
212
|
path: string;
|
|
@@ -216,18 +216,18 @@ export interface LocalLinePatchPreview {
|
|
|
216
216
|
before: string[];
|
|
217
217
|
after: string[];
|
|
218
218
|
}
|
|
219
|
-
export interface
|
|
219
|
+
export interface LocalWorkdirLineEdit {
|
|
220
220
|
path: string;
|
|
221
221
|
startLine: number;
|
|
222
222
|
endLine?: number;
|
|
223
223
|
replacement?: string;
|
|
224
224
|
expectedSha256?: string;
|
|
225
225
|
}
|
|
226
|
-
export interface
|
|
227
|
-
edits:
|
|
226
|
+
export interface LocalWorkdirEditPlan {
|
|
227
|
+
edits: LocalWorkdirLineEdit[];
|
|
228
228
|
previews: LocalLinePatchPreview[];
|
|
229
229
|
}
|
|
230
|
-
export interface
|
|
230
|
+
export interface LocalWorkdirEditResult {
|
|
231
231
|
applied: LocalFileLinesPatch[];
|
|
232
232
|
backups: Array<{
|
|
233
233
|
path: string;
|
|
@@ -240,11 +240,11 @@ export interface LocalPathSensitivityInfo {
|
|
|
240
240
|
sensitivity: LocalPathSensitivity;
|
|
241
241
|
reason?: string;
|
|
242
242
|
}
|
|
243
|
-
export interface
|
|
243
|
+
export interface LocalWorkdirWatchEvent {
|
|
244
244
|
type: "change" | "rename";
|
|
245
245
|
path: string;
|
|
246
246
|
}
|
|
247
|
-
export interface
|
|
247
|
+
export interface LocalWorkdirWatcher {
|
|
248
248
|
close(): void;
|
|
249
249
|
}
|
|
250
250
|
export interface LocalSkillDiscoveryOptions extends LocalSkillDirectoryOptions {
|
|
@@ -262,8 +262,8 @@ export interface LocalRuntime {
|
|
|
262
262
|
temp: LocalFileStore;
|
|
263
263
|
config: LocalConfigStore;
|
|
264
264
|
skills: LocalSkillStore;
|
|
265
|
-
|
|
266
|
-
|
|
265
|
+
workdirs: LocalWorkdirManager;
|
|
266
|
+
workdir(root: string, options?: LocalWorkdirOptions): LocalWorkdir;
|
|
267
267
|
ensure(): Promise<void>;
|
|
268
268
|
}
|
|
269
269
|
export declare function createLocalRuntime(options: LocalRuntimeOptions): LocalRuntime;
|
|
@@ -322,10 +322,10 @@ export declare class LocalConfigStore {
|
|
|
322
322
|
delete(name: string, key: string): Promise<string>;
|
|
323
323
|
private readRecord;
|
|
324
324
|
}
|
|
325
|
-
export declare class
|
|
326
|
-
open(root: string, options?:
|
|
325
|
+
export declare class LocalWorkdirManager {
|
|
326
|
+
open(root: string, options?: LocalWorkdirOptions): LocalWorkdir;
|
|
327
327
|
}
|
|
328
|
-
export declare class
|
|
328
|
+
export declare class LocalWorkdir {
|
|
329
329
|
readonly root: string;
|
|
330
330
|
readonly name: string;
|
|
331
331
|
readonly metadata: Record<string, unknown>;
|
|
@@ -334,10 +334,10 @@ export declare class LocalWorkspace {
|
|
|
334
334
|
readonly ignore: LocalIgnoreRule[];
|
|
335
335
|
readonly gitignore: boolean;
|
|
336
336
|
readonly maxFileBytes: number;
|
|
337
|
-
constructor(root: string, options?:
|
|
337
|
+
constructor(root: string, options?: LocalWorkdirOptions);
|
|
338
338
|
ensure(): Promise<void>;
|
|
339
339
|
loadIgnoreFiles(files?: string[]): Promise<LocalIgnoreRule[]>;
|
|
340
|
-
child(relativePath: string, options?:
|
|
340
|
+
child(relativePath: string, options?: LocalWorkdirOptions): LocalWorkdir;
|
|
341
341
|
resolvePath(relativePath?: string): string;
|
|
342
342
|
list(relativePath?: string, options?: LocalListOptions): Promise<LocalFileStat[]>;
|
|
343
343
|
listEntries(relativePath?: string, options?: LocalListOptions): Promise<LocalEntryList>;
|
|
@@ -358,16 +358,16 @@ export declare class LocalWorkspace {
|
|
|
358
358
|
readLines(relativePath: string, params: LocalReadLinesParams): Promise<LocalFileLines>;
|
|
359
359
|
previewPatchLines(relativePath: string, params: LocalPatchLinesParams): Promise<LocalLinePatchPreview>;
|
|
360
360
|
patchLines(relativePath: string, params: LocalPatchLinesParams): Promise<LocalFileLinesPatch>;
|
|
361
|
-
previewEdits(edits:
|
|
362
|
-
applyEdits(edits:
|
|
361
|
+
previewEdits(edits: LocalWorkdirLineEdit[]): Promise<LocalWorkdirEditPlan>;
|
|
362
|
+
applyEdits(edits: LocalWorkdirLineEdit[]): Promise<LocalWorkdirEditResult>;
|
|
363
363
|
classifyPath(relativePath: string): LocalPathSensitivityInfo;
|
|
364
364
|
grep(params: LocalGrepParams): Promise<LocalGrepResponse>;
|
|
365
365
|
summarize(params?: LocalSummarizeParams): Promise<LocalSummary>;
|
|
366
|
-
snapshot(params?:
|
|
367
|
-
diff(before:
|
|
368
|
-
watch(onEvent: (event:
|
|
366
|
+
snapshot(params?: LocalWorkdirSnapshotParams): Promise<LocalWorkdirSnapshot>;
|
|
367
|
+
diff(before: LocalWorkdirSnapshot, after: LocalWorkdirSnapshot): LocalWorkdirDiff;
|
|
368
|
+
watch(onEvent: (event: LocalWorkdirWatchEvent) => void, options?: {
|
|
369
369
|
recursive?: boolean;
|
|
370
|
-
}):
|
|
370
|
+
}): LocalWorkdirWatcher;
|
|
371
371
|
private scopedListOptions;
|
|
372
372
|
private mergeIgnore;
|
|
373
373
|
private assertAllowed;
|
package/dist/local/core.js
CHANGED
|
@@ -22,7 +22,7 @@ export class LocalPathError extends LocalError {
|
|
|
22
22
|
}
|
|
23
23
|
export class LocalIgnoredPathError extends LocalError {
|
|
24
24
|
constructor(path) {
|
|
25
|
-
super("local_ignored_path", `local
|
|
25
|
+
super("local_ignored_path", `local workdir path is ignored: ${path}`, { path });
|
|
26
26
|
this.name = "LocalIgnoredPathError";
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -62,9 +62,9 @@ export function createLocalRuntime(options) {
|
|
|
62
62
|
temp,
|
|
63
63
|
config: new LocalConfigStore(configFiles),
|
|
64
64
|
skills: new LocalSkillStore(data.child("skills")),
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return new
|
|
65
|
+
workdirs: new LocalWorkdirManager(),
|
|
66
|
+
workdir(root, workdirOptions = {}) {
|
|
67
|
+
return new LocalWorkdir(root, workdirOptions);
|
|
68
68
|
},
|
|
69
69
|
async ensure() {
|
|
70
70
|
await Promise.all([data.ensure(), cache.ensure(), logs.ensure(), temp.ensure(), configFiles.ensure()]);
|
|
@@ -456,12 +456,12 @@ export class LocalConfigStore {
|
|
|
456
456
|
return value;
|
|
457
457
|
}
|
|
458
458
|
}
|
|
459
|
-
export class
|
|
459
|
+
export class LocalWorkdirManager {
|
|
460
460
|
open(root, options = {}) {
|
|
461
|
-
return new
|
|
461
|
+
return new LocalWorkdir(root, options);
|
|
462
462
|
}
|
|
463
463
|
}
|
|
464
|
-
export class
|
|
464
|
+
export class LocalWorkdir {
|
|
465
465
|
root;
|
|
466
466
|
name;
|
|
467
467
|
metadata;
|
|
@@ -472,11 +472,11 @@ export class LocalWorkspace {
|
|
|
472
472
|
maxFileBytes;
|
|
473
473
|
constructor(root, options = {}) {
|
|
474
474
|
this.root = path.resolve(root);
|
|
475
|
-
this.name = options.name?.trim() || path.basename(this.root) || "
|
|
475
|
+
this.name = options.name?.trim() || path.basename(this.root) || "workdir";
|
|
476
476
|
this.metadata = { ...(options.metadata ?? {}) };
|
|
477
477
|
this.trusted = options.trusted ?? false;
|
|
478
|
-
this.files = new LocalFileStore(this.root, { label: "
|
|
479
|
-
this.ignore = [...
|
|
478
|
+
this.files = new LocalFileStore(this.root, { label: "workdir" });
|
|
479
|
+
this.ignore = [...defaultWorkdirIgnoreRules(), ...(options.ignore ?? [])];
|
|
480
480
|
this.gitignore = options.gitignore ?? true;
|
|
481
481
|
this.maxFileBytes = positiveInt(options.maxFileBytes, 10 * 1024 * 1024);
|
|
482
482
|
}
|
|
@@ -503,7 +503,7 @@ export class LocalWorkspace {
|
|
|
503
503
|
return loaded;
|
|
504
504
|
}
|
|
505
505
|
child(relativePath, options = {}) {
|
|
506
|
-
return new
|
|
506
|
+
return new LocalWorkdir(this.files.resolvePath(relativePath), {
|
|
507
507
|
name: options.name,
|
|
508
508
|
metadata: options.metadata ?? this.metadata,
|
|
509
509
|
trusted: options.trusted ?? this.trusted,
|
|
@@ -884,7 +884,7 @@ function ignored(relativePath, ignore) {
|
|
|
884
884
|
function ignoredDirectoryName(name) {
|
|
885
885
|
return name === ".git" || name === "node_modules" || name === "__pycache__";
|
|
886
886
|
}
|
|
887
|
-
function
|
|
887
|
+
function defaultWorkdirIgnoreRules() {
|
|
888
888
|
return [
|
|
889
889
|
".git",
|
|
890
890
|
"node_modules",
|
package/dist/local/tools.d.ts
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import type { FunctionTool } from "../types/tools.js";
|
|
2
|
-
import type {
|
|
3
|
-
export type
|
|
4
|
-
export type
|
|
5
|
-
export interface
|
|
6
|
-
accessMode?:
|
|
2
|
+
import type { LocalWorkdir } from "./core.js";
|
|
3
|
+
export type LocalWorkdirAccessMode = "approval" | "full";
|
|
4
|
+
export type LocalWorkdirAction = "summarize" | "list" | "search" | "grep" | "read" | "read_lines" | "context" | "snapshot" | "classify_path" | "preview_edits" | "apply_edits" | "write" | "mkdir" | "delete";
|
|
5
|
+
export interface LocalWorkdirToolRegistryOptions {
|
|
6
|
+
accessMode?: LocalWorkdirAccessMode;
|
|
7
7
|
toolName?: string;
|
|
8
8
|
}
|
|
9
|
-
export interface
|
|
10
|
-
readonly
|
|
11
|
-
readonly accessMode:
|
|
9
|
+
export interface LocalWorkdirToolRegistry {
|
|
10
|
+
readonly workdir: LocalWorkdir;
|
|
11
|
+
readonly accessMode: LocalWorkdirAccessMode;
|
|
12
12
|
readonly toolName: string;
|
|
13
13
|
definitions(): FunctionTool[];
|
|
14
14
|
handlers(): Record<string, (args: Record<string, unknown>) => Promise<Record<string, unknown>>>;
|
|
15
15
|
execute(name: string, args: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
16
16
|
requiresApproval(name: string, args?: Record<string, unknown>): boolean;
|
|
17
17
|
}
|
|
18
|
-
export interface
|
|
19
|
-
accessMode?:
|
|
18
|
+
export interface LocalWorkdirDriverOptions {
|
|
19
|
+
accessMode?: LocalWorkdirAccessMode;
|
|
20
20
|
}
|
|
21
|
-
export declare class
|
|
22
|
-
readonly
|
|
23
|
-
readonly accessMode:
|
|
24
|
-
constructor(
|
|
21
|
+
export declare class LocalWorkdirDriver {
|
|
22
|
+
readonly workdir: LocalWorkdir;
|
|
23
|
+
readonly accessMode: LocalWorkdirAccessMode;
|
|
24
|
+
constructor(workdir: LocalWorkdir, options?: LocalWorkdirDriverOptions);
|
|
25
25
|
dispatch(args: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
26
26
|
requiresApproval(args: Record<string, unknown>): boolean;
|
|
27
27
|
private dispatchApplyEdits;
|
|
@@ -29,6 +29,6 @@ export declare class LocalWorkspaceDriver {
|
|
|
29
29
|
private dispatchMkdir;
|
|
30
30
|
private dispatchDelete;
|
|
31
31
|
}
|
|
32
|
-
export declare function
|
|
33
|
-
export declare function
|
|
34
|
-
export declare function
|
|
32
|
+
export declare function createLocalWorkdirToolRegistry(workdir: LocalWorkdir, options?: LocalWorkdirToolRegistryOptions): LocalWorkdirToolRegistry;
|
|
33
|
+
export declare function localWorkdirToolDefinition(name?: string): FunctionTool;
|
|
34
|
+
export declare function localWorkdirToolInstructions(): string;
|
package/dist/local/tools.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
import { createLocalContextPackage } from "./context.js";
|
|
2
|
-
export class
|
|
3
|
-
|
|
2
|
+
export class LocalWorkdirDriver {
|
|
3
|
+
workdir;
|
|
4
4
|
accessMode;
|
|
5
|
-
constructor(
|
|
6
|
-
this.
|
|
5
|
+
constructor(workdir, options = {}) {
|
|
6
|
+
this.workdir = workdir;
|
|
7
7
|
this.accessMode = options.accessMode ?? "approval";
|
|
8
8
|
}
|
|
9
9
|
async dispatch(args) {
|
|
10
|
-
const action =
|
|
10
|
+
const action = workdirAction(args);
|
|
11
11
|
switch (action) {
|
|
12
12
|
case "summarize":
|
|
13
|
-
return localToolResult(action, localSummaryResult(await this.
|
|
13
|
+
return localToolResult(action, localSummaryResult(await this.workdir.summarize(summaryArgs(args))));
|
|
14
14
|
case "list":
|
|
15
|
-
return localToolResult(action, await this.
|
|
15
|
+
return localToolResult(action, await this.workdir.listEntries(optionalStringArg(args, "path") ?? ".", listArgs(args)));
|
|
16
16
|
case "search":
|
|
17
|
-
return localToolResult(action, await this.
|
|
17
|
+
return localToolResult(action, await this.workdir.searchEntries(searchEntriesArgs(args)));
|
|
18
18
|
case "grep":
|
|
19
|
-
return localToolResult(action, await this.
|
|
19
|
+
return localToolResult(action, await this.workdir.grep(grepArgs(args)));
|
|
20
20
|
case "read":
|
|
21
|
-
return localToolResult(action, await this.
|
|
21
|
+
return localToolResult(action, await this.workdir.readFile(stringArg(args, "path"), readFileArgs(args)));
|
|
22
22
|
case "read_lines":
|
|
23
|
-
return localToolResult(action, await this.
|
|
23
|
+
return localToolResult(action, await this.workdir.readLines(stringArg(args, "path"), readLinesArgs(args)));
|
|
24
24
|
case "context":
|
|
25
|
-
return localToolResult(action, await createLocalContextPackage(this.
|
|
25
|
+
return localToolResult(action, await createLocalContextPackage(this.workdir, contextPackageArgs(args)));
|
|
26
26
|
case "snapshot":
|
|
27
|
-
return localToolResult(action, await this.
|
|
27
|
+
return localToolResult(action, await this.workdir.snapshot(snapshotArgs(args)));
|
|
28
28
|
case "classify_path":
|
|
29
|
-
return localToolResult(action, this.
|
|
29
|
+
return localToolResult(action, this.workdir.classifyPath(stringArg(args, "path")));
|
|
30
30
|
case "preview_edits":
|
|
31
|
-
return localToolResult(action, await this.
|
|
31
|
+
return localToolResult(action, await this.workdir.previewEdits(editsArg(args)));
|
|
32
32
|
case "apply_edits":
|
|
33
33
|
return await this.dispatchApplyEdits(args);
|
|
34
34
|
case "write":
|
|
@@ -38,73 +38,73 @@ export class LocalWorkspaceDriver {
|
|
|
38
38
|
case "delete":
|
|
39
39
|
return await this.dispatchDelete(args);
|
|
40
40
|
default:
|
|
41
|
-
throw new Error(`unsupported
|
|
41
|
+
throw new Error(`unsupported local_workdir action: ${action}`);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
requiresApproval(args) {
|
|
45
45
|
if (this.accessMode === "full") {
|
|
46
46
|
return false;
|
|
47
47
|
}
|
|
48
|
-
return
|
|
48
|
+
return mutatingLocalWorkdirActions.has(workdirAction(args));
|
|
49
49
|
}
|
|
50
50
|
async dispatchApplyEdits(args) {
|
|
51
51
|
const edits = editsArg(args);
|
|
52
52
|
if (this.accessMode !== "full") {
|
|
53
|
-
return approvalRequired("apply_edits", args, await this.
|
|
53
|
+
return approvalRequired("apply_edits", args, await this.workdir.previewEdits(edits));
|
|
54
54
|
}
|
|
55
|
-
return localToolResult("apply_edits", await this.
|
|
55
|
+
return localToolResult("apply_edits", await this.workdir.applyEdits(edits));
|
|
56
56
|
}
|
|
57
57
|
async dispatchWrite(args) {
|
|
58
58
|
if (this.accessMode !== "full") {
|
|
59
59
|
return approvalRequired("write", args);
|
|
60
60
|
}
|
|
61
|
-
return localToolResult("write", await this.
|
|
61
|
+
return localToolResult("write", await this.workdir.writeText(stringArg(args, "path"), stringArg(args, "content")));
|
|
62
62
|
}
|
|
63
63
|
async dispatchMkdir(args) {
|
|
64
64
|
if (this.accessMode !== "full") {
|
|
65
65
|
return approvalRequired("mkdir", args);
|
|
66
66
|
}
|
|
67
|
-
return localToolResult("mkdir", await this.
|
|
67
|
+
return localToolResult("mkdir", await this.workdir.createDirectory(stringArg(args, "path")));
|
|
68
68
|
}
|
|
69
69
|
async dispatchDelete(args) {
|
|
70
70
|
if (this.accessMode !== "full") {
|
|
71
71
|
return approvalRequired("delete", args);
|
|
72
72
|
}
|
|
73
|
-
return localToolResult("delete", await this.
|
|
73
|
+
return localToolResult("delete", await this.workdir.deletePath(stringArg(args, "path")));
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
export function
|
|
77
|
-
const toolName = options.toolName ?? "
|
|
78
|
-
const driver = new
|
|
79
|
-
const definition =
|
|
76
|
+
export function createLocalWorkdirToolRegistry(workdir, options = {}) {
|
|
77
|
+
const toolName = options.toolName ?? "local_workdir";
|
|
78
|
+
const driver = new LocalWorkdirDriver(workdir, { accessMode: options.accessMode });
|
|
79
|
+
const definition = localWorkdirToolDefinition(toolName);
|
|
80
80
|
return {
|
|
81
|
-
|
|
81
|
+
workdir,
|
|
82
82
|
accessMode: driver.accessMode,
|
|
83
83
|
toolName,
|
|
84
84
|
definitions: () => [{ ...definition }],
|
|
85
85
|
handlers: () => ({ [toolName]: (args) => driver.dispatch(args) }),
|
|
86
86
|
execute: async (name, args) => {
|
|
87
87
|
if (name !== toolName) {
|
|
88
|
-
throw new Error(`unknown local
|
|
88
|
+
throw new Error(`unknown local workdir tool: ${name}`);
|
|
89
89
|
}
|
|
90
90
|
return await driver.dispatch(args);
|
|
91
91
|
},
|
|
92
92
|
requiresApproval: (name, args = {}) => name === toolName && driver.requiresApproval(args),
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
|
-
export function
|
|
95
|
+
export function localWorkdirToolDefinition(name = "local_workdir") {
|
|
96
96
|
return {
|
|
97
97
|
type: "function",
|
|
98
98
|
name,
|
|
99
|
-
description:
|
|
100
|
-
parameters:
|
|
99
|
+
description: localWorkdirToolDescription,
|
|
100
|
+
parameters: localWorkdirToolParameters(),
|
|
101
101
|
strict: false,
|
|
102
102
|
};
|
|
103
103
|
}
|
|
104
|
-
export function
|
|
105
|
-
return
|
|
104
|
+
export function localWorkdirToolInstructions() {
|
|
105
|
+
return localWorkdirToolDescription;
|
|
106
106
|
}
|
|
107
|
-
const
|
|
107
|
+
const localWorkdirActions = [
|
|
108
108
|
"summarize",
|
|
109
109
|
"list",
|
|
110
110
|
"search",
|
|
@@ -120,24 +120,24 @@ const localWorkspaceActions = [
|
|
|
120
120
|
"mkdir",
|
|
121
121
|
"delete",
|
|
122
122
|
];
|
|
123
|
-
const
|
|
123
|
+
const mutatingLocalWorkdirActions = new Set([
|
|
124
124
|
"apply_edits",
|
|
125
125
|
"write",
|
|
126
126
|
"mkdir",
|
|
127
127
|
"delete",
|
|
128
128
|
]);
|
|
129
|
-
const
|
|
130
|
-
"Inspect and modify the selected local
|
|
129
|
+
const localWorkdirToolDescription = [
|
|
130
|
+
"Inspect and modify the selected local workdir through one model-facing primitive.",
|
|
131
131
|
"Use action=list/search/grep/summarize/context to discover files, read/read_lines for file content, preview_edits before edits, and apply_edits/write/mkdir/delete only when mutation is intended.",
|
|
132
132
|
"In approval mode, mutating actions return requires_approval with a safe preview instead of changing files. In full mode, mutating actions execute immediately.",
|
|
133
|
-
"Paths are relative to the selected local
|
|
133
|
+
"Paths are relative to the selected local workdir; never use absolute paths.",
|
|
134
134
|
].join(" ");
|
|
135
|
-
function
|
|
135
|
+
function localWorkdirToolParameters() {
|
|
136
136
|
return objectSchema({
|
|
137
137
|
action: {
|
|
138
138
|
type: "string",
|
|
139
|
-
enum:
|
|
140
|
-
description: "
|
|
139
|
+
enum: localWorkdirActions,
|
|
140
|
+
description: "Workdir operation. Prefer summarize/list/search/grep before reading or editing. Prefer read_lines and apply_edits for source changes.",
|
|
141
141
|
},
|
|
142
142
|
path: stringSchema("Relative path. File path for read/write/delete/edit actions; directory base for list/search/grep/summarize/context/snapshot."),
|
|
143
143
|
query: stringSchema("Path/name query for search, or optional context query."),
|
|
@@ -168,17 +168,17 @@ function localWorkspaceToolParameters() {
|
|
|
168
168
|
max_bytes_per_file: integerSchema("Maximum bytes per file."),
|
|
169
169
|
max_previews: integerSchema("Maximum summary previews."),
|
|
170
170
|
include_content: booleanSchema("Include file contents in context packages."),
|
|
171
|
-
include_summary: booleanSchema("Include
|
|
171
|
+
include_summary: booleanSchema("Include workdir summary in context packages."),
|
|
172
172
|
include_search: booleanSchema("Include grep results in context packages when query is set."),
|
|
173
173
|
include_secrets: booleanSchema("Include likely secret file contents in context packages."),
|
|
174
174
|
hash: booleanSchema("Include SHA-256 hashes in snapshots."),
|
|
175
175
|
}),
|
|
176
176
|
}, ["action"]);
|
|
177
177
|
}
|
|
178
|
-
function
|
|
178
|
+
function workdirAction(args) {
|
|
179
179
|
const value = stringArg(args, "action").trim().toLowerCase();
|
|
180
|
-
if (!
|
|
181
|
-
throw new Error(`unsupported
|
|
180
|
+
if (!localWorkdirActions.includes(value)) {
|
|
181
|
+
throw new Error(`unsupported local_workdir action: ${value}`);
|
|
182
182
|
}
|
|
183
183
|
return value;
|
|
184
184
|
}
|
|
@@ -345,7 +345,7 @@ function approvalRequired(action, args, preview) {
|
|
|
345
345
|
requires_approval: true,
|
|
346
346
|
arguments: args,
|
|
347
347
|
preview,
|
|
348
|
-
message: `
|
|
348
|
+
message: `local_workdir action ${action} requires approval`,
|
|
349
349
|
};
|
|
350
350
|
}
|
|
351
351
|
function objectSchema(properties, required = []) {
|
package/dist/node.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export * from "./index.js";
|
|
2
2
|
export { NodeAgentAPI } from "./node-client.js";
|
|
3
3
|
export { NodeSkillsResource } from "./resources/skills-node.js";
|
|
4
|
-
export {
|
|
5
|
-
export type {
|
|
4
|
+
export { LocalWorkdirDriver, createLocalWorkdirToolRegistry, localWorkdirToolDefinition, localWorkdirToolInstructions, } from "./local/tools.js";
|
|
5
|
+
export type { LocalWorkdirAction, LocalWorkdirAccessMode, LocalWorkdirToolRegistry, LocalWorkdirToolRegistryOptions, } from "./local/tools.js";
|
|
6
6
|
export { localSkillFromDirectory, pendingLocalSkillCalls, runLocalSkillHandlers } from "./local-skills.js";
|
|
7
7
|
export type { LocalSkillDirectoryOptions } from "./local-skills.js";
|
|
8
8
|
export * from "./local/index.js";
|
package/dist/node.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./index.js";
|
|
2
2
|
export { NodeAgentAPI } from "./node-client.js";
|
|
3
3
|
export { NodeSkillsResource } from "./resources/skills-node.js";
|
|
4
|
-
export {
|
|
4
|
+
export { LocalWorkdirDriver, createLocalWorkdirToolRegistry, localWorkdirToolDefinition, localWorkdirToolInstructions, } from "./local/tools.js";
|
|
5
5
|
export { localSkillFromDirectory, pendingLocalSkillCalls, runLocalSkillHandlers } from "./local-skills.js";
|
|
6
6
|
export * from "./local/index.js";
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "1.
|
|
2
|
-
export declare const USER_AGENT = "@agent-api/sdk/1.
|
|
1
|
+
export declare const VERSION = "1.2.0";
|
|
2
|
+
export declare const USER_AGENT = "@agent-api/sdk/1.2.0";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = "1.
|
|
1
|
+
export const VERSION = "1.2.0";
|
|
2
2
|
export const USER_AGENT = `@agent-api/sdk/${VERSION}`;
|
|
@@ -5,7 +5,7 @@ exports.summarizeLocalContextSensitivity = summarizeLocalContextSensitivity;
|
|
|
5
5
|
const node_crypto_1 = require("node:crypto");
|
|
6
6
|
const promises_1 = require("node:fs/promises");
|
|
7
7
|
const core_js_1 = require("./core.js");
|
|
8
|
-
async function createLocalContextPackage(
|
|
8
|
+
async function createLocalContextPackage(workdir, params = {}) {
|
|
9
9
|
const basePath = params.path ?? ".";
|
|
10
10
|
const maxFiles = positiveInt(params.maxFiles, 80);
|
|
11
11
|
const maxBytes = positiveInt(params.maxBytes, 256 * 1024);
|
|
@@ -16,7 +16,7 @@ async function createLocalContextPackage(workspace, params = {}) {
|
|
|
16
16
|
const includeSummary = params.includeSummary ?? true;
|
|
17
17
|
const includeSearch = Boolean(params.includeSearch && params.query?.trim());
|
|
18
18
|
const includeSecrets = params.includeSecrets ?? false;
|
|
19
|
-
const stats = await
|
|
19
|
+
const stats = await workdir.list(basePath, { recursive: true });
|
|
20
20
|
const fileStats = stats
|
|
21
21
|
.filter((item) => item.type === "file")
|
|
22
22
|
.filter((item) => matchesPathFilters(item.path, params.include, params.exclude))
|
|
@@ -53,7 +53,7 @@ async function createLocalContextPackage(workspace, params = {}) {
|
|
|
53
53
|
truncated = true;
|
|
54
54
|
continue;
|
|
55
55
|
}
|
|
56
|
-
const delivered = await
|
|
56
|
+
const delivered = await workdir.readFile(item.path, { maxBytes: readBudget });
|
|
57
57
|
includedBytes += delivered.encoding === "text"
|
|
58
58
|
? Buffer.byteLength(delivered.content ?? "", "utf8")
|
|
59
59
|
: Buffer.byteLength(delivered.content_base64 ?? "", "base64");
|
|
@@ -68,7 +68,7 @@ async function createLocalContextPackage(workspace, params = {}) {
|
|
|
68
68
|
packaged.content_base64 = delivered.content_base64;
|
|
69
69
|
}
|
|
70
70
|
if (includeHashes) {
|
|
71
|
-
packaged.sha256 = await sha256File(
|
|
71
|
+
packaged.sha256 = await sha256File(workdir, item.path);
|
|
72
72
|
}
|
|
73
73
|
if (delivered.truncated) {
|
|
74
74
|
truncated = true;
|
|
@@ -76,7 +76,7 @@ async function createLocalContextPackage(workspace, params = {}) {
|
|
|
76
76
|
files.push(packaged);
|
|
77
77
|
}
|
|
78
78
|
const summary = includeSummary
|
|
79
|
-
? await
|
|
79
|
+
? await workdir.summarize({
|
|
80
80
|
path: basePath,
|
|
81
81
|
maxFiles,
|
|
82
82
|
previewBytes,
|
|
@@ -84,7 +84,7 @@ async function createLocalContextPackage(workspace, params = {}) {
|
|
|
84
84
|
})
|
|
85
85
|
: undefined;
|
|
86
86
|
const search = includeSearch
|
|
87
|
-
? await
|
|
87
|
+
? await workdir.grep({
|
|
88
88
|
pattern: params.query,
|
|
89
89
|
path: basePath,
|
|
90
90
|
limit: maxFiles,
|
|
@@ -94,8 +94,8 @@ async function createLocalContextPackage(workspace, params = {}) {
|
|
|
94
94
|
: undefined;
|
|
95
95
|
return {
|
|
96
96
|
object: "local_context_manifest",
|
|
97
|
-
root:
|
|
98
|
-
|
|
97
|
+
root: workdir.root,
|
|
98
|
+
workdir_name: workdir.name,
|
|
99
99
|
generated_at_unix: Math.floor(Date.now() / 1000),
|
|
100
100
|
base_path: basePath,
|
|
101
101
|
file_count: fileStats.length,
|
|
@@ -152,7 +152,7 @@ function positiveInt(value, fallback) {
|
|
|
152
152
|
const parsed = Number(value);
|
|
153
153
|
return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : fallback;
|
|
154
154
|
}
|
|
155
|
-
async function sha256File(
|
|
156
|
-
const fullPath =
|
|
155
|
+
async function sha256File(workdir, relativePath) {
|
|
156
|
+
const fullPath = workdir.files.resolvePath(relativePath);
|
|
157
157
|
return (0, node_crypto_1.createHash)("sha256").update(await (0, promises_1.readFile)(fullPath)).digest("hex");
|
|
158
158
|
}
|
package/dist-cjs/local/core.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.LocalSkillStore = exports.
|
|
6
|
+
exports.LocalSkillStore = exports.LocalWorkdir = exports.LocalWorkdirManager = exports.LocalConfigStore = exports.LocalFileStore = exports.LocalConfigError = exports.LocalNotTextFileError = exports.LocalFileTooLargeError = exports.LocalIgnoredPathError = exports.LocalPathError = exports.LocalError = void 0;
|
|
7
7
|
exports.createLocalRuntime = createLocalRuntime;
|
|
8
8
|
exports.localAppDirs = localAppDirs;
|
|
9
9
|
exports.classifyLocalPathSensitivity = classifyLocalPathSensitivity;
|
|
@@ -33,7 +33,7 @@ class LocalPathError extends LocalError {
|
|
|
33
33
|
exports.LocalPathError = LocalPathError;
|
|
34
34
|
class LocalIgnoredPathError extends LocalError {
|
|
35
35
|
constructor(path) {
|
|
36
|
-
super("local_ignored_path", `local
|
|
36
|
+
super("local_ignored_path", `local workdir path is ignored: ${path}`, { path });
|
|
37
37
|
this.name = "LocalIgnoredPathError";
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -77,9 +77,9 @@ function createLocalRuntime(options) {
|
|
|
77
77
|
temp,
|
|
78
78
|
config: new LocalConfigStore(configFiles),
|
|
79
79
|
skills: new LocalSkillStore(data.child("skills")),
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return new
|
|
80
|
+
workdirs: new LocalWorkdirManager(),
|
|
81
|
+
workdir(root, workdirOptions = {}) {
|
|
82
|
+
return new LocalWorkdir(root, workdirOptions);
|
|
83
83
|
},
|
|
84
84
|
async ensure() {
|
|
85
85
|
await Promise.all([data.ensure(), cache.ensure(), logs.ensure(), temp.ensure(), configFiles.ensure()]);
|
|
@@ -473,13 +473,13 @@ class LocalConfigStore {
|
|
|
473
473
|
}
|
|
474
474
|
}
|
|
475
475
|
exports.LocalConfigStore = LocalConfigStore;
|
|
476
|
-
class
|
|
476
|
+
class LocalWorkdirManager {
|
|
477
477
|
open(root, options = {}) {
|
|
478
|
-
return new
|
|
478
|
+
return new LocalWorkdir(root, options);
|
|
479
479
|
}
|
|
480
480
|
}
|
|
481
|
-
exports.
|
|
482
|
-
class
|
|
481
|
+
exports.LocalWorkdirManager = LocalWorkdirManager;
|
|
482
|
+
class LocalWorkdir {
|
|
483
483
|
root;
|
|
484
484
|
name;
|
|
485
485
|
metadata;
|
|
@@ -490,11 +490,11 @@ class LocalWorkspace {
|
|
|
490
490
|
maxFileBytes;
|
|
491
491
|
constructor(root, options = {}) {
|
|
492
492
|
this.root = node_path_1.default.resolve(root);
|
|
493
|
-
this.name = options.name?.trim() || node_path_1.default.basename(this.root) || "
|
|
493
|
+
this.name = options.name?.trim() || node_path_1.default.basename(this.root) || "workdir";
|
|
494
494
|
this.metadata = { ...(options.metadata ?? {}) };
|
|
495
495
|
this.trusted = options.trusted ?? false;
|
|
496
|
-
this.files = new LocalFileStore(this.root, { label: "
|
|
497
|
-
this.ignore = [...
|
|
496
|
+
this.files = new LocalFileStore(this.root, { label: "workdir" });
|
|
497
|
+
this.ignore = [...defaultWorkdirIgnoreRules(), ...(options.ignore ?? [])];
|
|
498
498
|
this.gitignore = options.gitignore ?? true;
|
|
499
499
|
this.maxFileBytes = positiveInt(options.maxFileBytes, 10 * 1024 * 1024);
|
|
500
500
|
}
|
|
@@ -521,7 +521,7 @@ class LocalWorkspace {
|
|
|
521
521
|
return loaded;
|
|
522
522
|
}
|
|
523
523
|
child(relativePath, options = {}) {
|
|
524
|
-
return new
|
|
524
|
+
return new LocalWorkdir(this.files.resolvePath(relativePath), {
|
|
525
525
|
name: options.name,
|
|
526
526
|
metadata: options.metadata ?? this.metadata,
|
|
527
527
|
trusted: options.trusted ?? this.trusted,
|
|
@@ -731,7 +731,7 @@ class LocalWorkspace {
|
|
|
731
731
|
}
|
|
732
732
|
}
|
|
733
733
|
}
|
|
734
|
-
exports.
|
|
734
|
+
exports.LocalWorkdir = LocalWorkdir;
|
|
735
735
|
class LocalSkillStore {
|
|
736
736
|
files;
|
|
737
737
|
constructor(files) {
|
|
@@ -904,7 +904,7 @@ function ignored(relativePath, ignore) {
|
|
|
904
904
|
function ignoredDirectoryName(name) {
|
|
905
905
|
return name === ".git" || name === "node_modules" || name === "__pycache__";
|
|
906
906
|
}
|
|
907
|
-
function
|
|
907
|
+
function defaultWorkdirIgnoreRules() {
|
|
908
908
|
return [
|
|
909
909
|
".git",
|
|
910
910
|
"node_modules",
|
package/dist-cjs/local/tools.js
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
5
|
-
exports.
|
|
6
|
-
exports.
|
|
3
|
+
exports.LocalWorkdirDriver = void 0;
|
|
4
|
+
exports.createLocalWorkdirToolRegistry = createLocalWorkdirToolRegistry;
|
|
5
|
+
exports.localWorkdirToolDefinition = localWorkdirToolDefinition;
|
|
6
|
+
exports.localWorkdirToolInstructions = localWorkdirToolInstructions;
|
|
7
7
|
const context_js_1 = require("./context.js");
|
|
8
|
-
class
|
|
9
|
-
|
|
8
|
+
class LocalWorkdirDriver {
|
|
9
|
+
workdir;
|
|
10
10
|
accessMode;
|
|
11
|
-
constructor(
|
|
12
|
-
this.
|
|
11
|
+
constructor(workdir, options = {}) {
|
|
12
|
+
this.workdir = workdir;
|
|
13
13
|
this.accessMode = options.accessMode ?? "approval";
|
|
14
14
|
}
|
|
15
15
|
async dispatch(args) {
|
|
16
|
-
const action =
|
|
16
|
+
const action = workdirAction(args);
|
|
17
17
|
switch (action) {
|
|
18
18
|
case "summarize":
|
|
19
|
-
return localToolResult(action, localSummaryResult(await this.
|
|
19
|
+
return localToolResult(action, localSummaryResult(await this.workdir.summarize(summaryArgs(args))));
|
|
20
20
|
case "list":
|
|
21
|
-
return localToolResult(action, await this.
|
|
21
|
+
return localToolResult(action, await this.workdir.listEntries(optionalStringArg(args, "path") ?? ".", listArgs(args)));
|
|
22
22
|
case "search":
|
|
23
|
-
return localToolResult(action, await this.
|
|
23
|
+
return localToolResult(action, await this.workdir.searchEntries(searchEntriesArgs(args)));
|
|
24
24
|
case "grep":
|
|
25
|
-
return localToolResult(action, await this.
|
|
25
|
+
return localToolResult(action, await this.workdir.grep(grepArgs(args)));
|
|
26
26
|
case "read":
|
|
27
|
-
return localToolResult(action, await this.
|
|
27
|
+
return localToolResult(action, await this.workdir.readFile(stringArg(args, "path"), readFileArgs(args)));
|
|
28
28
|
case "read_lines":
|
|
29
|
-
return localToolResult(action, await this.
|
|
29
|
+
return localToolResult(action, await this.workdir.readLines(stringArg(args, "path"), readLinesArgs(args)));
|
|
30
30
|
case "context":
|
|
31
|
-
return localToolResult(action, await (0, context_js_1.createLocalContextPackage)(this.
|
|
31
|
+
return localToolResult(action, await (0, context_js_1.createLocalContextPackage)(this.workdir, contextPackageArgs(args)));
|
|
32
32
|
case "snapshot":
|
|
33
|
-
return localToolResult(action, await this.
|
|
33
|
+
return localToolResult(action, await this.workdir.snapshot(snapshotArgs(args)));
|
|
34
34
|
case "classify_path":
|
|
35
|
-
return localToolResult(action, this.
|
|
35
|
+
return localToolResult(action, this.workdir.classifyPath(stringArg(args, "path")));
|
|
36
36
|
case "preview_edits":
|
|
37
|
-
return localToolResult(action, await this.
|
|
37
|
+
return localToolResult(action, await this.workdir.previewEdits(editsArg(args)));
|
|
38
38
|
case "apply_edits":
|
|
39
39
|
return await this.dispatchApplyEdits(args);
|
|
40
40
|
case "write":
|
|
@@ -44,74 +44,74 @@ class LocalWorkspaceDriver {
|
|
|
44
44
|
case "delete":
|
|
45
45
|
return await this.dispatchDelete(args);
|
|
46
46
|
default:
|
|
47
|
-
throw new Error(`unsupported
|
|
47
|
+
throw new Error(`unsupported local_workdir action: ${action}`);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
requiresApproval(args) {
|
|
51
51
|
if (this.accessMode === "full") {
|
|
52
52
|
return false;
|
|
53
53
|
}
|
|
54
|
-
return
|
|
54
|
+
return mutatingLocalWorkdirActions.has(workdirAction(args));
|
|
55
55
|
}
|
|
56
56
|
async dispatchApplyEdits(args) {
|
|
57
57
|
const edits = editsArg(args);
|
|
58
58
|
if (this.accessMode !== "full") {
|
|
59
|
-
return approvalRequired("apply_edits", args, await this.
|
|
59
|
+
return approvalRequired("apply_edits", args, await this.workdir.previewEdits(edits));
|
|
60
60
|
}
|
|
61
|
-
return localToolResult("apply_edits", await this.
|
|
61
|
+
return localToolResult("apply_edits", await this.workdir.applyEdits(edits));
|
|
62
62
|
}
|
|
63
63
|
async dispatchWrite(args) {
|
|
64
64
|
if (this.accessMode !== "full") {
|
|
65
65
|
return approvalRequired("write", args);
|
|
66
66
|
}
|
|
67
|
-
return localToolResult("write", await this.
|
|
67
|
+
return localToolResult("write", await this.workdir.writeText(stringArg(args, "path"), stringArg(args, "content")));
|
|
68
68
|
}
|
|
69
69
|
async dispatchMkdir(args) {
|
|
70
70
|
if (this.accessMode !== "full") {
|
|
71
71
|
return approvalRequired("mkdir", args);
|
|
72
72
|
}
|
|
73
|
-
return localToolResult("mkdir", await this.
|
|
73
|
+
return localToolResult("mkdir", await this.workdir.createDirectory(stringArg(args, "path")));
|
|
74
74
|
}
|
|
75
75
|
async dispatchDelete(args) {
|
|
76
76
|
if (this.accessMode !== "full") {
|
|
77
77
|
return approvalRequired("delete", args);
|
|
78
78
|
}
|
|
79
|
-
return localToolResult("delete", await this.
|
|
79
|
+
return localToolResult("delete", await this.workdir.deletePath(stringArg(args, "path")));
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
exports.
|
|
83
|
-
function
|
|
84
|
-
const toolName = options.toolName ?? "
|
|
85
|
-
const driver = new
|
|
86
|
-
const definition =
|
|
82
|
+
exports.LocalWorkdirDriver = LocalWorkdirDriver;
|
|
83
|
+
function createLocalWorkdirToolRegistry(workdir, options = {}) {
|
|
84
|
+
const toolName = options.toolName ?? "local_workdir";
|
|
85
|
+
const driver = new LocalWorkdirDriver(workdir, { accessMode: options.accessMode });
|
|
86
|
+
const definition = localWorkdirToolDefinition(toolName);
|
|
87
87
|
return {
|
|
88
|
-
|
|
88
|
+
workdir,
|
|
89
89
|
accessMode: driver.accessMode,
|
|
90
90
|
toolName,
|
|
91
91
|
definitions: () => [{ ...definition }],
|
|
92
92
|
handlers: () => ({ [toolName]: (args) => driver.dispatch(args) }),
|
|
93
93
|
execute: async (name, args) => {
|
|
94
94
|
if (name !== toolName) {
|
|
95
|
-
throw new Error(`unknown local
|
|
95
|
+
throw new Error(`unknown local workdir tool: ${name}`);
|
|
96
96
|
}
|
|
97
97
|
return await driver.dispatch(args);
|
|
98
98
|
},
|
|
99
99
|
requiresApproval: (name, args = {}) => name === toolName && driver.requiresApproval(args),
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
|
-
function
|
|
102
|
+
function localWorkdirToolDefinition(name = "local_workdir") {
|
|
103
103
|
return {
|
|
104
104
|
type: "function",
|
|
105
105
|
name,
|
|
106
|
-
description:
|
|
107
|
-
parameters:
|
|
106
|
+
description: localWorkdirToolDescription,
|
|
107
|
+
parameters: localWorkdirToolParameters(),
|
|
108
108
|
strict: false,
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
|
-
function
|
|
112
|
-
return
|
|
111
|
+
function localWorkdirToolInstructions() {
|
|
112
|
+
return localWorkdirToolDescription;
|
|
113
113
|
}
|
|
114
|
-
const
|
|
114
|
+
const localWorkdirActions = [
|
|
115
115
|
"summarize",
|
|
116
116
|
"list",
|
|
117
117
|
"search",
|
|
@@ -127,24 +127,24 @@ const localWorkspaceActions = [
|
|
|
127
127
|
"mkdir",
|
|
128
128
|
"delete",
|
|
129
129
|
];
|
|
130
|
-
const
|
|
130
|
+
const mutatingLocalWorkdirActions = new Set([
|
|
131
131
|
"apply_edits",
|
|
132
132
|
"write",
|
|
133
133
|
"mkdir",
|
|
134
134
|
"delete",
|
|
135
135
|
]);
|
|
136
|
-
const
|
|
137
|
-
"Inspect and modify the selected local
|
|
136
|
+
const localWorkdirToolDescription = [
|
|
137
|
+
"Inspect and modify the selected local workdir through one model-facing primitive.",
|
|
138
138
|
"Use action=list/search/grep/summarize/context to discover files, read/read_lines for file content, preview_edits before edits, and apply_edits/write/mkdir/delete only when mutation is intended.",
|
|
139
139
|
"In approval mode, mutating actions return requires_approval with a safe preview instead of changing files. In full mode, mutating actions execute immediately.",
|
|
140
|
-
"Paths are relative to the selected local
|
|
140
|
+
"Paths are relative to the selected local workdir; never use absolute paths.",
|
|
141
141
|
].join(" ");
|
|
142
|
-
function
|
|
142
|
+
function localWorkdirToolParameters() {
|
|
143
143
|
return objectSchema({
|
|
144
144
|
action: {
|
|
145
145
|
type: "string",
|
|
146
|
-
enum:
|
|
147
|
-
description: "
|
|
146
|
+
enum: localWorkdirActions,
|
|
147
|
+
description: "Workdir operation. Prefer summarize/list/search/grep before reading or editing. Prefer read_lines and apply_edits for source changes.",
|
|
148
148
|
},
|
|
149
149
|
path: stringSchema("Relative path. File path for read/write/delete/edit actions; directory base for list/search/grep/summarize/context/snapshot."),
|
|
150
150
|
query: stringSchema("Path/name query for search, or optional context query."),
|
|
@@ -175,17 +175,17 @@ function localWorkspaceToolParameters() {
|
|
|
175
175
|
max_bytes_per_file: integerSchema("Maximum bytes per file."),
|
|
176
176
|
max_previews: integerSchema("Maximum summary previews."),
|
|
177
177
|
include_content: booleanSchema("Include file contents in context packages."),
|
|
178
|
-
include_summary: booleanSchema("Include
|
|
178
|
+
include_summary: booleanSchema("Include workdir summary in context packages."),
|
|
179
179
|
include_search: booleanSchema("Include grep results in context packages when query is set."),
|
|
180
180
|
include_secrets: booleanSchema("Include likely secret file contents in context packages."),
|
|
181
181
|
hash: booleanSchema("Include SHA-256 hashes in snapshots."),
|
|
182
182
|
}),
|
|
183
183
|
}, ["action"]);
|
|
184
184
|
}
|
|
185
|
-
function
|
|
185
|
+
function workdirAction(args) {
|
|
186
186
|
const value = stringArg(args, "action").trim().toLowerCase();
|
|
187
|
-
if (!
|
|
188
|
-
throw new Error(`unsupported
|
|
187
|
+
if (!localWorkdirActions.includes(value)) {
|
|
188
|
+
throw new Error(`unsupported local_workdir action: ${value}`);
|
|
189
189
|
}
|
|
190
190
|
return value;
|
|
191
191
|
}
|
|
@@ -352,7 +352,7 @@ function approvalRequired(action, args, preview) {
|
|
|
352
352
|
requires_approval: true,
|
|
353
353
|
arguments: args,
|
|
354
354
|
preview,
|
|
355
|
-
message: `
|
|
355
|
+
message: `local_workdir action ${action} requires approval`,
|
|
356
356
|
};
|
|
357
357
|
}
|
|
358
358
|
function objectSchema(properties, required = []) {
|
package/dist-cjs/node.js
CHANGED
|
@@ -14,17 +14,17 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.runLocalSkillHandlers = exports.pendingLocalSkillCalls = exports.localSkillFromDirectory = exports.
|
|
17
|
+
exports.runLocalSkillHandlers = exports.pendingLocalSkillCalls = exports.localSkillFromDirectory = exports.localWorkdirToolInstructions = exports.localWorkdirToolDefinition = exports.createLocalWorkdirToolRegistry = exports.LocalWorkdirDriver = exports.NodeSkillsResource = exports.NodeAgentAPI = void 0;
|
|
18
18
|
__exportStar(require("./index.js"), exports);
|
|
19
19
|
var node_client_js_1 = require("./node-client.js");
|
|
20
20
|
Object.defineProperty(exports, "NodeAgentAPI", { enumerable: true, get: function () { return node_client_js_1.NodeAgentAPI; } });
|
|
21
21
|
var skills_node_js_1 = require("./resources/skills-node.js");
|
|
22
22
|
Object.defineProperty(exports, "NodeSkillsResource", { enumerable: true, get: function () { return skills_node_js_1.NodeSkillsResource; } });
|
|
23
23
|
var tools_js_1 = require("./local/tools.js");
|
|
24
|
-
Object.defineProperty(exports, "
|
|
25
|
-
Object.defineProperty(exports, "
|
|
26
|
-
Object.defineProperty(exports, "
|
|
27
|
-
Object.defineProperty(exports, "
|
|
24
|
+
Object.defineProperty(exports, "LocalWorkdirDriver", { enumerable: true, get: function () { return tools_js_1.LocalWorkdirDriver; } });
|
|
25
|
+
Object.defineProperty(exports, "createLocalWorkdirToolRegistry", { enumerable: true, get: function () { return tools_js_1.createLocalWorkdirToolRegistry; } });
|
|
26
|
+
Object.defineProperty(exports, "localWorkdirToolDefinition", { enumerable: true, get: function () { return tools_js_1.localWorkdirToolDefinition; } });
|
|
27
|
+
Object.defineProperty(exports, "localWorkdirToolInstructions", { enumerable: true, get: function () { return tools_js_1.localWorkdirToolInstructions; } });
|
|
28
28
|
var local_skills_js_1 = require("./local-skills.js");
|
|
29
29
|
Object.defineProperty(exports, "localSkillFromDirectory", { enumerable: true, get: function () { return local_skills_js_1.localSkillFromDirectory; } });
|
|
30
30
|
Object.defineProperty(exports, "pendingLocalSkillCalls", { enumerable: true, get: function () { return local_skills_js_1.pendingLocalSkillCalls; } });
|
package/dist-cjs/version.js
CHANGED