appduct 0.11.0 → 0.11.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 +1 -1
- package/dist/cli/result-types.d.ts +5 -4
- package/dist/cli/routes/daemon/start.js +12 -3
- package/dist/cli/routes/daemon/status.js +12 -3
- package/dist/cli/routes/daemon/stop.js +12 -3
- package/dist/cli/routes/events.js +12 -3
- package/dist/cli/routes/invoke.js +12 -3
- package/dist/cli/routes/link.js +12 -3
- package/dist/cli/routes/ls.js +12 -3
- package/dist/cli/routes/mcp.js +16 -4
- package/dist/cli/routes/revoke.js +12 -3
- package/dist/cli/routes/tools.js +12 -3
- package/dist/client/app-client.d.ts +4 -3
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +14 -4
- package/dist/mcp/app-tools.d.ts +7 -7
- package/dist/rpc/client.d.ts +3 -2
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -232,7 +232,7 @@ import { connect } from "appduct/client";
|
|
|
232
232
|
// auto-spawns the daemon and picks the single session, or pass { selector: "pixel-8" } to target one explicitly
|
|
233
233
|
const app = await connect();
|
|
234
234
|
|
|
235
|
-
await app.tools(); //
|
|
235
|
+
await app.tools(); // ListedToolDescriptor[]; an ungrouped tool's group is null
|
|
236
236
|
const { total } = await app.call("sum", { a: 2, b: 3 });
|
|
237
237
|
const { payload } = await app.waitForEvent("checkout_done", { timeoutMs: 5_000 });
|
|
238
238
|
app.close();
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* the thin-client shapes for the v2 command table.
|
|
5
5
|
*/
|
|
6
6
|
import type { OpenTarget } from "./open-target.js";
|
|
7
|
-
import type { AgentEndpoint, EffectivePolicyDecision, EventNotification, SessionSummary,
|
|
7
|
+
import type { AgentEndpoint, EffectivePolicyDecision, EventNotification, SessionSummary, ToolGroupSummary, ToolsListEntry, ToolsListResult } from "@appduct/shared";
|
|
8
8
|
/**
|
|
9
9
|
* CLI-domain error classes, used only to pick a sysexits-style exit code (see `errors.ts`).
|
|
10
10
|
* `CliError.type` itself is *not* restricted to this union: RPC/app-originated failures preserve
|
|
@@ -129,9 +129,10 @@ export type ToolGroupsListing = {
|
|
|
129
129
|
/** Every tool in the session, grouped or not. */
|
|
130
130
|
total: number;
|
|
131
131
|
};
|
|
132
|
-
/** `appduct tools`: a listing, a groups summary (`--groups`), or a single
|
|
133
|
-
*
|
|
134
|
-
|
|
132
|
+
/** `appduct tools`: a listing, a groups summary (`--groups`), or a single entry when a tool name
|
|
133
|
+
* resolved to a detail lookup. The detail form is the daemon's own listing entry, picked out of
|
|
134
|
+
* `tools.list` — not a registration, so its `group` is `null` for an ungrouped tool. */
|
|
135
|
+
export type ToolsCommandData = ToolsListing | ToolGroupsListing | ToolsListEntry;
|
|
135
136
|
/** `appduct invoke`: the tool's raw result payload, printed as-is. */
|
|
136
137
|
export type InvokeCommandData = unknown;
|
|
137
138
|
export type RevokeCommandData = {
|
|
@@ -9,7 +9,7 @@ import { join as join3 } from "node:path";
|
|
|
9
9
|
import { RPC_METHODS } from "@appduct/shared";
|
|
10
10
|
|
|
11
11
|
// src/daemon/log-rotation.ts
|
|
12
|
-
import { chmod, rename, stat } from "node:fs/promises";
|
|
12
|
+
import { chmod as chmod2, rename, stat } from "node:fs/promises";
|
|
13
13
|
|
|
14
14
|
// src/daemon/config.ts
|
|
15
15
|
import { readFile } from "node:fs/promises";
|
|
@@ -236,6 +236,7 @@ var isSocketConnectable = (socketPath) => {
|
|
|
236
236
|
|
|
237
237
|
// src/daemon/state-dir.ts
|
|
238
238
|
import { join } from "node:path";
|
|
239
|
+
import { mkdir, chmod } from "node:fs/promises";
|
|
239
240
|
var getStateDirPaths = (stateDir) => {
|
|
240
241
|
return {
|
|
241
242
|
root: stateDir,
|
|
@@ -248,6 +249,13 @@ var getStateDirPaths = (stateDir) => {
|
|
|
248
249
|
spawnLockPath: join(stateDir, "daemon.spawn.lock")
|
|
249
250
|
};
|
|
250
251
|
};
|
|
252
|
+
var ensureStateDir = async (stateDir) => {
|
|
253
|
+
const paths = getStateDirPaths(stateDir);
|
|
254
|
+
await mkdir(paths.auditDir, { recursive: true });
|
|
255
|
+
await chmod(paths.root, 448);
|
|
256
|
+
await chmod(paths.auditDir, 448);
|
|
257
|
+
return paths;
|
|
258
|
+
};
|
|
251
259
|
|
|
252
260
|
// src/daemon/log-rotation.ts
|
|
253
261
|
var STATE_FILE_MODE = 384;
|
|
@@ -280,7 +288,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
280
288
|
const backupPath = daemonLogBackupPath(options.logFilePath);
|
|
281
289
|
await rename(options.logFilePath, backupPath);
|
|
282
290
|
try {
|
|
283
|
-
await
|
|
291
|
+
await chmod2(backupPath, STATE_FILE_MODE);
|
|
284
292
|
} catch (error) {
|
|
285
293
|
warn(`appduct: rotated "${options.logFilePath}" but could not set 0600 on "${backupPath}": ${error.message}`);
|
|
286
294
|
}
|
|
@@ -296,7 +304,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
296
304
|
var ensureDaemonLogMode = async (logFilePath, warn = (message) => process.stderr.write(`${message}
|
|
297
305
|
`)) => {
|
|
298
306
|
try {
|
|
299
|
-
await
|
|
307
|
+
await chmod2(logFilePath, STATE_FILE_MODE);
|
|
300
308
|
return true;
|
|
301
309
|
} catch (error) {
|
|
302
310
|
warn(`appduct: could not set 0600 on "${logFilePath}": ${error.message}`);
|
|
@@ -637,6 +645,7 @@ var acquireSpawnLock = async (lockPath) => {
|
|
|
637
645
|
return false;
|
|
638
646
|
};
|
|
639
647
|
var spawnDaemonAndWait = async (paths, spawn, waitTimeoutMs, pollIntervalMs, options = {}) => {
|
|
648
|
+
await ensureStateDir(paths.root);
|
|
640
649
|
const acquiredLock = await acquireSpawnLock(paths.spawnLockPath);
|
|
641
650
|
let lockWaitTimedOut = false;
|
|
642
651
|
if (acquiredLock) {
|
|
@@ -53,7 +53,7 @@ import { join as join4 } from "node:path";
|
|
|
53
53
|
import { RPC_METHODS } from "@appduct/shared";
|
|
54
54
|
|
|
55
55
|
// src/daemon/log-rotation.ts
|
|
56
|
-
import { chmod, rename, stat } from "node:fs/promises";
|
|
56
|
+
import { chmod as chmod2, rename, stat } from "node:fs/promises";
|
|
57
57
|
|
|
58
58
|
// src/daemon/config.ts
|
|
59
59
|
import { readFile } from "node:fs/promises";
|
|
@@ -280,6 +280,7 @@ var isSocketConnectable = (socketPath) => {
|
|
|
280
280
|
|
|
281
281
|
// src/daemon/state-dir.ts
|
|
282
282
|
import { join as join3 } from "node:path";
|
|
283
|
+
import { mkdir, chmod } from "node:fs/promises";
|
|
283
284
|
var getStateDirPaths = (stateDir) => {
|
|
284
285
|
return {
|
|
285
286
|
root: stateDir,
|
|
@@ -292,6 +293,13 @@ var getStateDirPaths = (stateDir) => {
|
|
|
292
293
|
spawnLockPath: join3(stateDir, "daemon.spawn.lock")
|
|
293
294
|
};
|
|
294
295
|
};
|
|
296
|
+
var ensureStateDir = async (stateDir) => {
|
|
297
|
+
const paths = getStateDirPaths(stateDir);
|
|
298
|
+
await mkdir(paths.auditDir, { recursive: true });
|
|
299
|
+
await chmod(paths.root, 448);
|
|
300
|
+
await chmod(paths.auditDir, 448);
|
|
301
|
+
return paths;
|
|
302
|
+
};
|
|
295
303
|
|
|
296
304
|
// src/daemon/log-rotation.ts
|
|
297
305
|
var STATE_FILE_MODE = 384;
|
|
@@ -324,7 +332,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
324
332
|
const backupPath = daemonLogBackupPath(options.logFilePath);
|
|
325
333
|
await rename(options.logFilePath, backupPath);
|
|
326
334
|
try {
|
|
327
|
-
await
|
|
335
|
+
await chmod2(backupPath, STATE_FILE_MODE);
|
|
328
336
|
} catch (error) {
|
|
329
337
|
warn(`appduct: rotated "${options.logFilePath}" but could not set 0600 on "${backupPath}": ${error.message}`);
|
|
330
338
|
}
|
|
@@ -340,7 +348,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
340
348
|
var ensureDaemonLogMode = async (logFilePath, warn = (message) => process.stderr.write(`${message}
|
|
341
349
|
`)) => {
|
|
342
350
|
try {
|
|
343
|
-
await
|
|
351
|
+
await chmod2(logFilePath, STATE_FILE_MODE);
|
|
344
352
|
return true;
|
|
345
353
|
} catch (error) {
|
|
346
354
|
warn(`appduct: could not set 0600 on "${logFilePath}": ${error.message}`);
|
|
@@ -646,6 +654,7 @@ var acquireSpawnLock = async (lockPath) => {
|
|
|
646
654
|
return false;
|
|
647
655
|
};
|
|
648
656
|
var spawnDaemonAndWait = async (paths, spawn, waitTimeoutMs, pollIntervalMs, options = {}) => {
|
|
657
|
+
await ensureStateDir(paths.root);
|
|
649
658
|
const acquiredLock = await acquireSpawnLock(paths.spawnLockPath);
|
|
650
659
|
let lockWaitTimedOut = false;
|
|
651
660
|
if (acquiredLock) {
|
|
@@ -42,6 +42,7 @@ var readPidFromFile = async (pidFilePath) => {
|
|
|
42
42
|
|
|
43
43
|
// src/daemon/state-dir.ts
|
|
44
44
|
import { join } from "node:path";
|
|
45
|
+
import { mkdir, chmod } from "node:fs/promises";
|
|
45
46
|
var getStateDirPaths = (stateDir) => {
|
|
46
47
|
return {
|
|
47
48
|
root: stateDir,
|
|
@@ -54,6 +55,13 @@ var getStateDirPaths = (stateDir) => {
|
|
|
54
55
|
spawnLockPath: join(stateDir, "daemon.spawn.lock")
|
|
55
56
|
};
|
|
56
57
|
};
|
|
58
|
+
var ensureStateDir = async (stateDir) => {
|
|
59
|
+
const paths = getStateDirPaths(stateDir);
|
|
60
|
+
await mkdir(paths.auditDir, { recursive: true });
|
|
61
|
+
await chmod(paths.root, 448);
|
|
62
|
+
await chmod(paths.auditDir, 448);
|
|
63
|
+
return paths;
|
|
64
|
+
};
|
|
57
65
|
|
|
58
66
|
// src/rpc/client.ts
|
|
59
67
|
import { connect as connect2 } from "node:net";
|
|
@@ -63,7 +71,7 @@ import { join as join3 } from "node:path";
|
|
|
63
71
|
import { RPC_METHODS } from "@appduct/shared";
|
|
64
72
|
|
|
65
73
|
// src/daemon/log-rotation.ts
|
|
66
|
-
import { chmod, rename, stat } from "node:fs/promises";
|
|
74
|
+
import { chmod as chmod2, rename, stat } from "node:fs/promises";
|
|
67
75
|
|
|
68
76
|
// src/daemon/config.ts
|
|
69
77
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
@@ -280,7 +288,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
280
288
|
const backupPath = daemonLogBackupPath(options.logFilePath);
|
|
281
289
|
await rename(options.logFilePath, backupPath);
|
|
282
290
|
try {
|
|
283
|
-
await
|
|
291
|
+
await chmod2(backupPath, STATE_FILE_MODE);
|
|
284
292
|
} catch (error) {
|
|
285
293
|
warn(`appduct: rotated "${options.logFilePath}" but could not set 0600 on "${backupPath}": ${error.message}`);
|
|
286
294
|
}
|
|
@@ -296,7 +304,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
296
304
|
var ensureDaemonLogMode = async (logFilePath, warn = (message) => process.stderr.write(`${message}
|
|
297
305
|
`)) => {
|
|
298
306
|
try {
|
|
299
|
-
await
|
|
307
|
+
await chmod2(logFilePath, STATE_FILE_MODE);
|
|
300
308
|
return true;
|
|
301
309
|
} catch (error) {
|
|
302
310
|
warn(`appduct: could not set 0600 on "${logFilePath}": ${error.message}`);
|
|
@@ -637,6 +645,7 @@ var acquireSpawnLock = async (lockPath) => {
|
|
|
637
645
|
return false;
|
|
638
646
|
};
|
|
639
647
|
var spawnDaemonAndWait = async (paths, spawn, waitTimeoutMs, pollIntervalMs, options = {}) => {
|
|
648
|
+
await ensureStateDir(paths.root);
|
|
640
649
|
const acquiredLock = await acquireSpawnLock(paths.spawnLockPath);
|
|
641
650
|
let lockWaitTimedOut = false;
|
|
642
651
|
if (acquiredLock) {
|
|
@@ -9,7 +9,7 @@ import { join as join3 } from "node:path";
|
|
|
9
9
|
import { RPC_METHODS } from "@appduct/shared";
|
|
10
10
|
|
|
11
11
|
// src/daemon/log-rotation.ts
|
|
12
|
-
import { chmod, rename, stat } from "node:fs/promises";
|
|
12
|
+
import { chmod as chmod2, rename, stat } from "node:fs/promises";
|
|
13
13
|
|
|
14
14
|
// src/daemon/config.ts
|
|
15
15
|
import { readFile } from "node:fs/promises";
|
|
@@ -236,6 +236,7 @@ var isSocketConnectable = (socketPath) => {
|
|
|
236
236
|
|
|
237
237
|
// src/daemon/state-dir.ts
|
|
238
238
|
import { join } from "node:path";
|
|
239
|
+
import { mkdir, chmod } from "node:fs/promises";
|
|
239
240
|
var getStateDirPaths = (stateDir) => {
|
|
240
241
|
return {
|
|
241
242
|
root: stateDir,
|
|
@@ -248,6 +249,13 @@ var getStateDirPaths = (stateDir) => {
|
|
|
248
249
|
spawnLockPath: join(stateDir, "daemon.spawn.lock")
|
|
249
250
|
};
|
|
250
251
|
};
|
|
252
|
+
var ensureStateDir = async (stateDir) => {
|
|
253
|
+
const paths = getStateDirPaths(stateDir);
|
|
254
|
+
await mkdir(paths.auditDir, { recursive: true });
|
|
255
|
+
await chmod(paths.root, 448);
|
|
256
|
+
await chmod(paths.auditDir, 448);
|
|
257
|
+
return paths;
|
|
258
|
+
};
|
|
251
259
|
|
|
252
260
|
// src/daemon/log-rotation.ts
|
|
253
261
|
var STATE_FILE_MODE = 384;
|
|
@@ -280,7 +288,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
280
288
|
const backupPath = daemonLogBackupPath(options.logFilePath);
|
|
281
289
|
await rename(options.logFilePath, backupPath);
|
|
282
290
|
try {
|
|
283
|
-
await
|
|
291
|
+
await chmod2(backupPath, STATE_FILE_MODE);
|
|
284
292
|
} catch (error) {
|
|
285
293
|
warn(`appduct: rotated "${options.logFilePath}" but could not set 0600 on "${backupPath}": ${error.message}`);
|
|
286
294
|
}
|
|
@@ -296,7 +304,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
296
304
|
var ensureDaemonLogMode = async (logFilePath, warn = (message) => process.stderr.write(`${message}
|
|
297
305
|
`)) => {
|
|
298
306
|
try {
|
|
299
|
-
await
|
|
307
|
+
await chmod2(logFilePath, STATE_FILE_MODE);
|
|
300
308
|
return true;
|
|
301
309
|
} catch (error) {
|
|
302
310
|
warn(`appduct: could not set 0600 on "${logFilePath}": ${error.message}`);
|
|
@@ -637,6 +645,7 @@ var acquireSpawnLock = async (lockPath) => {
|
|
|
637
645
|
return false;
|
|
638
646
|
};
|
|
639
647
|
var spawnDaemonAndWait = async (paths, spawn, waitTimeoutMs, pollIntervalMs, options = {}) => {
|
|
648
|
+
await ensureStateDir(paths.root);
|
|
640
649
|
const acquiredLock = await acquireSpawnLock(paths.spawnLockPath);
|
|
641
650
|
let lockWaitTimedOut = false;
|
|
642
651
|
if (acquiredLock) {
|
|
@@ -29,7 +29,7 @@ import { join as join3 } from "node:path";
|
|
|
29
29
|
import { RPC_METHODS } from "@appduct/shared";
|
|
30
30
|
|
|
31
31
|
// src/daemon/log-rotation.ts
|
|
32
|
-
import { chmod, rename, stat } from "node:fs/promises";
|
|
32
|
+
import { chmod as chmod2, rename, stat } from "node:fs/promises";
|
|
33
33
|
|
|
34
34
|
// src/daemon/config.ts
|
|
35
35
|
import { readFile } from "node:fs/promises";
|
|
@@ -256,6 +256,7 @@ var isSocketConnectable = (socketPath) => {
|
|
|
256
256
|
|
|
257
257
|
// src/daemon/state-dir.ts
|
|
258
258
|
import { join } from "node:path";
|
|
259
|
+
import { mkdir, chmod } from "node:fs/promises";
|
|
259
260
|
var getStateDirPaths = (stateDir) => {
|
|
260
261
|
return {
|
|
261
262
|
root: stateDir,
|
|
@@ -268,6 +269,13 @@ var getStateDirPaths = (stateDir) => {
|
|
|
268
269
|
spawnLockPath: join(stateDir, "daemon.spawn.lock")
|
|
269
270
|
};
|
|
270
271
|
};
|
|
272
|
+
var ensureStateDir = async (stateDir) => {
|
|
273
|
+
const paths = getStateDirPaths(stateDir);
|
|
274
|
+
await mkdir(paths.auditDir, { recursive: true });
|
|
275
|
+
await chmod(paths.root, 448);
|
|
276
|
+
await chmod(paths.auditDir, 448);
|
|
277
|
+
return paths;
|
|
278
|
+
};
|
|
271
279
|
|
|
272
280
|
// src/daemon/log-rotation.ts
|
|
273
281
|
var STATE_FILE_MODE = 384;
|
|
@@ -300,7 +308,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
300
308
|
const backupPath = daemonLogBackupPath(options.logFilePath);
|
|
301
309
|
await rename(options.logFilePath, backupPath);
|
|
302
310
|
try {
|
|
303
|
-
await
|
|
311
|
+
await chmod2(backupPath, STATE_FILE_MODE);
|
|
304
312
|
} catch (error) {
|
|
305
313
|
warn(`appduct: rotated "${options.logFilePath}" but could not set 0600 on "${backupPath}": ${error.message}`);
|
|
306
314
|
}
|
|
@@ -316,7 +324,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
316
324
|
var ensureDaemonLogMode = async (logFilePath, warn = (message) => process.stderr.write(`${message}
|
|
317
325
|
`)) => {
|
|
318
326
|
try {
|
|
319
|
-
await
|
|
327
|
+
await chmod2(logFilePath, STATE_FILE_MODE);
|
|
320
328
|
return true;
|
|
321
329
|
} catch (error) {
|
|
322
330
|
warn(`appduct: could not set 0600 on "${logFilePath}": ${error.message}`);
|
|
@@ -657,6 +665,7 @@ var acquireSpawnLock = async (lockPath) => {
|
|
|
657
665
|
return false;
|
|
658
666
|
};
|
|
659
667
|
var spawnDaemonAndWait = async (paths, spawn, waitTimeoutMs, pollIntervalMs, options = {}) => {
|
|
668
|
+
await ensureStateDir(paths.root);
|
|
660
669
|
const acquiredLock = await acquireSpawnLock(paths.spawnLockPath);
|
|
661
670
|
let lockWaitTimedOut = false;
|
|
662
671
|
if (acquiredLock) {
|
package/dist/cli/routes/link.js
CHANGED
|
@@ -12,7 +12,7 @@ import { join as join3 } from "node:path";
|
|
|
12
12
|
import { RPC_METHODS } from "@appduct/shared";
|
|
13
13
|
|
|
14
14
|
// src/daemon/log-rotation.ts
|
|
15
|
-
import { chmod, rename, stat } from "node:fs/promises";
|
|
15
|
+
import { chmod as chmod2, rename, stat } from "node:fs/promises";
|
|
16
16
|
|
|
17
17
|
// src/daemon/config.ts
|
|
18
18
|
import { readFile } from "node:fs/promises";
|
|
@@ -239,6 +239,7 @@ var isSocketConnectable = (socketPath) => {
|
|
|
239
239
|
|
|
240
240
|
// src/daemon/state-dir.ts
|
|
241
241
|
import { join } from "node:path";
|
|
242
|
+
import { mkdir, chmod } from "node:fs/promises";
|
|
242
243
|
var getStateDirPaths = (stateDir) => {
|
|
243
244
|
return {
|
|
244
245
|
root: stateDir,
|
|
@@ -251,6 +252,13 @@ var getStateDirPaths = (stateDir) => {
|
|
|
251
252
|
spawnLockPath: join(stateDir, "daemon.spawn.lock")
|
|
252
253
|
};
|
|
253
254
|
};
|
|
255
|
+
var ensureStateDir = async (stateDir) => {
|
|
256
|
+
const paths = getStateDirPaths(stateDir);
|
|
257
|
+
await mkdir(paths.auditDir, { recursive: true });
|
|
258
|
+
await chmod(paths.root, 448);
|
|
259
|
+
await chmod(paths.auditDir, 448);
|
|
260
|
+
return paths;
|
|
261
|
+
};
|
|
254
262
|
|
|
255
263
|
// src/daemon/log-rotation.ts
|
|
256
264
|
var STATE_FILE_MODE = 384;
|
|
@@ -283,7 +291,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
283
291
|
const backupPath = daemonLogBackupPath(options.logFilePath);
|
|
284
292
|
await rename(options.logFilePath, backupPath);
|
|
285
293
|
try {
|
|
286
|
-
await
|
|
294
|
+
await chmod2(backupPath, STATE_FILE_MODE);
|
|
287
295
|
} catch (error) {
|
|
288
296
|
warn(`appduct: rotated "${options.logFilePath}" but could not set 0600 on "${backupPath}": ${error.message}`);
|
|
289
297
|
}
|
|
@@ -299,7 +307,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
299
307
|
var ensureDaemonLogMode = async (logFilePath, warn = (message) => process.stderr.write(`${message}
|
|
300
308
|
`)) => {
|
|
301
309
|
try {
|
|
302
|
-
await
|
|
310
|
+
await chmod2(logFilePath, STATE_FILE_MODE);
|
|
303
311
|
return true;
|
|
304
312
|
} catch (error) {
|
|
305
313
|
warn(`appduct: could not set 0600 on "${logFilePath}": ${error.message}`);
|
|
@@ -640,6 +648,7 @@ var acquireSpawnLock = async (lockPath) => {
|
|
|
640
648
|
return false;
|
|
641
649
|
};
|
|
642
650
|
var spawnDaemonAndWait = async (paths, spawn, waitTimeoutMs, pollIntervalMs, options = {}) => {
|
|
651
|
+
await ensureStateDir(paths.root);
|
|
643
652
|
const acquiredLock = await acquireSpawnLock(paths.spawnLockPath);
|
|
644
653
|
let lockWaitTimedOut = false;
|
|
645
654
|
if (acquiredLock) {
|
package/dist/cli/routes/ls.js
CHANGED
|
@@ -9,7 +9,7 @@ import { join as join3 } from "node:path";
|
|
|
9
9
|
import { RPC_METHODS } from "@appduct/shared";
|
|
10
10
|
|
|
11
11
|
// src/daemon/log-rotation.ts
|
|
12
|
-
import { chmod, rename, stat } from "node:fs/promises";
|
|
12
|
+
import { chmod as chmod2, rename, stat } from "node:fs/promises";
|
|
13
13
|
|
|
14
14
|
// src/daemon/config.ts
|
|
15
15
|
import { readFile } from "node:fs/promises";
|
|
@@ -236,6 +236,7 @@ var isSocketConnectable = (socketPath) => {
|
|
|
236
236
|
|
|
237
237
|
// src/daemon/state-dir.ts
|
|
238
238
|
import { join } from "node:path";
|
|
239
|
+
import { mkdir, chmod } from "node:fs/promises";
|
|
239
240
|
var getStateDirPaths = (stateDir) => {
|
|
240
241
|
return {
|
|
241
242
|
root: stateDir,
|
|
@@ -248,6 +249,13 @@ var getStateDirPaths = (stateDir) => {
|
|
|
248
249
|
spawnLockPath: join(stateDir, "daemon.spawn.lock")
|
|
249
250
|
};
|
|
250
251
|
};
|
|
252
|
+
var ensureStateDir = async (stateDir) => {
|
|
253
|
+
const paths = getStateDirPaths(stateDir);
|
|
254
|
+
await mkdir(paths.auditDir, { recursive: true });
|
|
255
|
+
await chmod(paths.root, 448);
|
|
256
|
+
await chmod(paths.auditDir, 448);
|
|
257
|
+
return paths;
|
|
258
|
+
};
|
|
251
259
|
|
|
252
260
|
// src/daemon/log-rotation.ts
|
|
253
261
|
var STATE_FILE_MODE = 384;
|
|
@@ -280,7 +288,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
280
288
|
const backupPath = daemonLogBackupPath(options.logFilePath);
|
|
281
289
|
await rename(options.logFilePath, backupPath);
|
|
282
290
|
try {
|
|
283
|
-
await
|
|
291
|
+
await chmod2(backupPath, STATE_FILE_MODE);
|
|
284
292
|
} catch (error) {
|
|
285
293
|
warn(`appduct: rotated "${options.logFilePath}" but could not set 0600 on "${backupPath}": ${error.message}`);
|
|
286
294
|
}
|
|
@@ -296,7 +304,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
296
304
|
var ensureDaemonLogMode = async (logFilePath, warn = (message) => process.stderr.write(`${message}
|
|
297
305
|
`)) => {
|
|
298
306
|
try {
|
|
299
|
-
await
|
|
307
|
+
await chmod2(logFilePath, STATE_FILE_MODE);
|
|
300
308
|
return true;
|
|
301
309
|
} catch (error) {
|
|
302
310
|
warn(`appduct: could not set 0600 on "${logFilePath}": ${error.message}`);
|
|
@@ -637,6 +645,7 @@ var acquireSpawnLock = async (lockPath) => {
|
|
|
637
645
|
return false;
|
|
638
646
|
};
|
|
639
647
|
var spawnDaemonAndWait = async (paths, spawn, waitTimeoutMs, pollIntervalMs, options = {}) => {
|
|
648
|
+
await ensureStateDir(paths.root);
|
|
640
649
|
const acquiredLock = await acquireSpawnLock(paths.spawnLockPath);
|
|
641
650
|
let lockWaitTimedOut = false;
|
|
642
651
|
if (acquiredLock) {
|
package/dist/cli/routes/mcp.js
CHANGED
|
@@ -171,6 +171,7 @@ var loadConfig = async (paths, options = {}) => {
|
|
|
171
171
|
|
|
172
172
|
// src/daemon/state-dir.ts
|
|
173
173
|
import { join } from "node:path";
|
|
174
|
+
import { mkdir, chmod } from "node:fs/promises";
|
|
174
175
|
var getStateDirPaths = (stateDir) => {
|
|
175
176
|
return {
|
|
176
177
|
root: stateDir,
|
|
@@ -183,6 +184,13 @@ var getStateDirPaths = (stateDir) => {
|
|
|
183
184
|
spawnLockPath: join(stateDir, "daemon.spawn.lock")
|
|
184
185
|
};
|
|
185
186
|
};
|
|
187
|
+
var ensureStateDir = async (stateDir) => {
|
|
188
|
+
const paths = getStateDirPaths(stateDir);
|
|
189
|
+
await mkdir(paths.auditDir, { recursive: true });
|
|
190
|
+
await chmod(paths.root, 448);
|
|
191
|
+
await chmod(paths.auditDir, 448);
|
|
192
|
+
return paths;
|
|
193
|
+
};
|
|
186
194
|
|
|
187
195
|
// src/mcp/server.ts
|
|
188
196
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -267,7 +275,7 @@ import { join as join4 } from "node:path";
|
|
|
267
275
|
import { RPC_METHODS } from "@appduct/shared";
|
|
268
276
|
|
|
269
277
|
// src/daemon/log-rotation.ts
|
|
270
|
-
import { chmod, rename, stat } from "node:fs/promises";
|
|
278
|
+
import { chmod as chmod2, rename, stat } from "node:fs/promises";
|
|
271
279
|
|
|
272
280
|
// src/daemon/pidfile.ts
|
|
273
281
|
import { readFileSync as readFileSync3 } from "node:fs";
|
|
@@ -355,7 +363,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
355
363
|
const backupPath = daemonLogBackupPath(options.logFilePath);
|
|
356
364
|
await rename(options.logFilePath, backupPath);
|
|
357
365
|
try {
|
|
358
|
-
await
|
|
366
|
+
await chmod2(backupPath, STATE_FILE_MODE);
|
|
359
367
|
} catch (error) {
|
|
360
368
|
warn(`appduct: rotated "${options.logFilePath}" but could not set 0600 on "${backupPath}": ${error.message}`);
|
|
361
369
|
}
|
|
@@ -371,7 +379,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
371
379
|
var ensureDaemonLogMode = async (logFilePath, warn = (message) => process.stderr.write(`${message}
|
|
372
380
|
`)) => {
|
|
373
381
|
try {
|
|
374
|
-
await
|
|
382
|
+
await chmod2(logFilePath, STATE_FILE_MODE);
|
|
375
383
|
return true;
|
|
376
384
|
} catch (error) {
|
|
377
385
|
warn(`appduct: could not set 0600 on "${logFilePath}": ${error.message}`);
|
|
@@ -677,6 +685,7 @@ var acquireSpawnLock = async (lockPath) => {
|
|
|
677
685
|
return false;
|
|
678
686
|
};
|
|
679
687
|
var spawnDaemonAndWait = async (paths, spawn, waitTimeoutMs, pollIntervalMs, options = {}) => {
|
|
688
|
+
await ensureStateDir(paths.root);
|
|
680
689
|
const acquiredLock = await acquireSpawnLock(paths.spawnLockPath);
|
|
681
690
|
let lockWaitTimedOut = false;
|
|
682
691
|
if (acquiredLock) {
|
|
@@ -2531,7 +2540,10 @@ var toDescriptor = (entry) => {
|
|
|
2531
2540
|
output_schema: entry.output_schema,
|
|
2532
2541
|
annotations: entry.annotations,
|
|
2533
2542
|
timeout_ms: entry.timeout_ms,
|
|
2534
|
-
|
|
2543
|
+
// Normalised the same way the listing normalises it, so `appduct_describe_tool` never
|
|
2544
|
+
// disagrees with `appduct_list_tools` about whether a tool has a group. The `?? null` also
|
|
2545
|
+
// covers a daemon that predates groups and omits the key entirely.
|
|
2546
|
+
group: entry.group ?? null
|
|
2535
2547
|
};
|
|
2536
2548
|
};
|
|
2537
2549
|
var resolveSession = async (call, selector) => {
|
|
@@ -9,7 +9,7 @@ import { join as join3 } from "node:path";
|
|
|
9
9
|
import { RPC_METHODS } from "@appduct/shared";
|
|
10
10
|
|
|
11
11
|
// src/daemon/log-rotation.ts
|
|
12
|
-
import { chmod, rename, stat } from "node:fs/promises";
|
|
12
|
+
import { chmod as chmod2, rename, stat } from "node:fs/promises";
|
|
13
13
|
|
|
14
14
|
// src/daemon/config.ts
|
|
15
15
|
import { readFile } from "node:fs/promises";
|
|
@@ -236,6 +236,7 @@ var isSocketConnectable = (socketPath) => {
|
|
|
236
236
|
|
|
237
237
|
// src/daemon/state-dir.ts
|
|
238
238
|
import { join } from "node:path";
|
|
239
|
+
import { mkdir, chmod } from "node:fs/promises";
|
|
239
240
|
var getStateDirPaths = (stateDir) => {
|
|
240
241
|
return {
|
|
241
242
|
root: stateDir,
|
|
@@ -248,6 +249,13 @@ var getStateDirPaths = (stateDir) => {
|
|
|
248
249
|
spawnLockPath: join(stateDir, "daemon.spawn.lock")
|
|
249
250
|
};
|
|
250
251
|
};
|
|
252
|
+
var ensureStateDir = async (stateDir) => {
|
|
253
|
+
const paths = getStateDirPaths(stateDir);
|
|
254
|
+
await mkdir(paths.auditDir, { recursive: true });
|
|
255
|
+
await chmod(paths.root, 448);
|
|
256
|
+
await chmod(paths.auditDir, 448);
|
|
257
|
+
return paths;
|
|
258
|
+
};
|
|
251
259
|
|
|
252
260
|
// src/daemon/log-rotation.ts
|
|
253
261
|
var STATE_FILE_MODE = 384;
|
|
@@ -280,7 +288,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
280
288
|
const backupPath = daemonLogBackupPath(options.logFilePath);
|
|
281
289
|
await rename(options.logFilePath, backupPath);
|
|
282
290
|
try {
|
|
283
|
-
await
|
|
291
|
+
await chmod2(backupPath, STATE_FILE_MODE);
|
|
284
292
|
} catch (error) {
|
|
285
293
|
warn(`appduct: rotated "${options.logFilePath}" but could not set 0600 on "${backupPath}": ${error.message}`);
|
|
286
294
|
}
|
|
@@ -296,7 +304,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
296
304
|
var ensureDaemonLogMode = async (logFilePath, warn = (message) => process.stderr.write(`${message}
|
|
297
305
|
`)) => {
|
|
298
306
|
try {
|
|
299
|
-
await
|
|
307
|
+
await chmod2(logFilePath, STATE_FILE_MODE);
|
|
300
308
|
return true;
|
|
301
309
|
} catch (error) {
|
|
302
310
|
warn(`appduct: could not set 0600 on "${logFilePath}": ${error.message}`);
|
|
@@ -637,6 +645,7 @@ var acquireSpawnLock = async (lockPath) => {
|
|
|
637
645
|
return false;
|
|
638
646
|
};
|
|
639
647
|
var spawnDaemonAndWait = async (paths, spawn, waitTimeoutMs, pollIntervalMs, options = {}) => {
|
|
648
|
+
await ensureStateDir(paths.root);
|
|
640
649
|
const acquiredLock = await acquireSpawnLock(paths.spawnLockPath);
|
|
641
650
|
let lockWaitTimedOut = false;
|
|
642
651
|
if (acquiredLock) {
|
package/dist/cli/routes/tools.js
CHANGED
|
@@ -12,7 +12,7 @@ import { join as join3 } from "node:path";
|
|
|
12
12
|
import { RPC_METHODS } from "@appduct/shared";
|
|
13
13
|
|
|
14
14
|
// src/daemon/log-rotation.ts
|
|
15
|
-
import { chmod, rename, stat } from "node:fs/promises";
|
|
15
|
+
import { chmod as chmod2, rename, stat } from "node:fs/promises";
|
|
16
16
|
|
|
17
17
|
// src/daemon/config.ts
|
|
18
18
|
import { readFile } from "node:fs/promises";
|
|
@@ -239,6 +239,7 @@ var isSocketConnectable = (socketPath) => {
|
|
|
239
239
|
|
|
240
240
|
// src/daemon/state-dir.ts
|
|
241
241
|
import { join } from "node:path";
|
|
242
|
+
import { mkdir, chmod } from "node:fs/promises";
|
|
242
243
|
var getStateDirPaths = (stateDir) => {
|
|
243
244
|
return {
|
|
244
245
|
root: stateDir,
|
|
@@ -251,6 +252,13 @@ var getStateDirPaths = (stateDir) => {
|
|
|
251
252
|
spawnLockPath: join(stateDir, "daemon.spawn.lock")
|
|
252
253
|
};
|
|
253
254
|
};
|
|
255
|
+
var ensureStateDir = async (stateDir) => {
|
|
256
|
+
const paths = getStateDirPaths(stateDir);
|
|
257
|
+
await mkdir(paths.auditDir, { recursive: true });
|
|
258
|
+
await chmod(paths.root, 448);
|
|
259
|
+
await chmod(paths.auditDir, 448);
|
|
260
|
+
return paths;
|
|
261
|
+
};
|
|
254
262
|
|
|
255
263
|
// src/daemon/log-rotation.ts
|
|
256
264
|
var STATE_FILE_MODE = 384;
|
|
@@ -283,7 +291,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
283
291
|
const backupPath = daemonLogBackupPath(options.logFilePath);
|
|
284
292
|
await rename(options.logFilePath, backupPath);
|
|
285
293
|
try {
|
|
286
|
-
await
|
|
294
|
+
await chmod2(backupPath, STATE_FILE_MODE);
|
|
287
295
|
} catch (error) {
|
|
288
296
|
warn(`appduct: rotated "${options.logFilePath}" but could not set 0600 on "${backupPath}": ${error.message}`);
|
|
289
297
|
}
|
|
@@ -299,7 +307,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
299
307
|
var ensureDaemonLogMode = async (logFilePath, warn = (message) => process.stderr.write(`${message}
|
|
300
308
|
`)) => {
|
|
301
309
|
try {
|
|
302
|
-
await
|
|
310
|
+
await chmod2(logFilePath, STATE_FILE_MODE);
|
|
303
311
|
return true;
|
|
304
312
|
} catch (error) {
|
|
305
313
|
warn(`appduct: could not set 0600 on "${logFilePath}": ${error.message}`);
|
|
@@ -640,6 +648,7 @@ var acquireSpawnLock = async (lockPath) => {
|
|
|
640
648
|
return false;
|
|
641
649
|
};
|
|
642
650
|
var spawnDaemonAndWait = async (paths, spawn, waitTimeoutMs, pollIntervalMs, options = {}) => {
|
|
651
|
+
await ensureStateDir(paths.root);
|
|
643
652
|
const acquiredLock = await acquireSpawnLock(paths.spawnLockPath);
|
|
644
653
|
let lockWaitTimedOut = false;
|
|
645
654
|
if (acquiredLock) {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* `appduct_wait_for_event` MCP tool (`mcp/events-tool.ts`) — see that module's doc comment for
|
|
8
8
|
* why the notification listener has to be registered before the `events.since` drain call is sent.
|
|
9
9
|
*/
|
|
10
|
-
import { type
|
|
10
|
+
import { type ListedToolDescriptor } from "@appduct/shared";
|
|
11
11
|
import type { DaemonStream } from "../rpc/client.js";
|
|
12
12
|
/** A project's own tool map — declared once, e.g. `type Tools = { sum: { args: { a: number; b:
|
|
13
13
|
* number }; result: { total: number } } }` — to get typed {@link AppClient.call} throughout a test
|
|
@@ -80,8 +80,9 @@ export type AppEvent<TPayload = unknown> = {
|
|
|
80
80
|
};
|
|
81
81
|
export type AppClient<TTools = ToolMap> = {
|
|
82
82
|
readonly sessionId: string;
|
|
83
|
-
/** `tools.list` for this session.
|
|
84
|
-
|
|
83
|
+
/** `tools.list` for this session. An entry spells an ungrouped tool's `group` as `null`,
|
|
84
|
+
* where a registration omits it. */
|
|
85
|
+
tools(): Promise<ListedToolDescriptor[]>;
|
|
85
86
|
/** `tools.call`; rejects with a {@link AppductError} whose `type` preserves the wire error
|
|
86
87
|
* type verbatim (e.g. `"tool_timeout"`, `"policy_denied"`, `"session_suspended"`). */
|
|
87
88
|
call<K extends keyof TTools & string>(name: K, args: ToolArgs<TTools, K>, options?: CallOptions): Promise<ToolResult<TTools, K>>;
|
package/dist/client/index.d.ts
CHANGED
|
@@ -15,4 +15,4 @@ export { connect, type ConnectOptions } from "./connect.js";
|
|
|
15
15
|
export { link, waitForSession, type LinkOptions, type LinkResult, type WaitForSessionOptions } from "./bootstrap.js";
|
|
16
16
|
export { AppductError, type AppductErrorType } from "./errors.js";
|
|
17
17
|
export type { AppClient, AppEvent, CallOptions, EventsOptions, EventsResult, ToolMap, WaitForEventOptions, } from "./app-client.js";
|
|
18
|
-
export type { AgentEndpoint, ErrorType, ToolDescriptor } from "@appduct/shared";
|
|
18
|
+
export type { AgentEndpoint, ErrorType, ListedToolDescriptor, ToolDescriptor } from "@appduct/shared";
|
package/dist/client/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { RPC_METHODS as RPC_METHODS3 } from "@appduct/shared";
|
|
|
4
4
|
// src/daemon/state-dir.ts
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
import { join } from "node:path";
|
|
7
|
+
import { mkdir, chmod } from "node:fs/promises";
|
|
7
8
|
var resolveStateDir = (override) => {
|
|
8
9
|
return override ?? process.env.APPDUCT_STATE_DIR ?? join(homedir(), ".appduct");
|
|
9
10
|
};
|
|
@@ -19,6 +20,13 @@ var getStateDirPaths = (stateDir) => {
|
|
|
19
20
|
spawnLockPath: join(stateDir, "daemon.spawn.lock")
|
|
20
21
|
};
|
|
21
22
|
};
|
|
23
|
+
var ensureStateDir = async (stateDir) => {
|
|
24
|
+
const paths = getStateDirPaths(stateDir);
|
|
25
|
+
await mkdir(paths.auditDir, { recursive: true });
|
|
26
|
+
await chmod(paths.root, 448);
|
|
27
|
+
await chmod(paths.auditDir, 448);
|
|
28
|
+
return paths;
|
|
29
|
+
};
|
|
22
30
|
|
|
23
31
|
// src/rpc/client.ts
|
|
24
32
|
import { connect as connect2 } from "node:net";
|
|
@@ -28,7 +36,7 @@ import { join as join3 } from "node:path";
|
|
|
28
36
|
import { RPC_METHODS } from "@appduct/shared";
|
|
29
37
|
|
|
30
38
|
// src/daemon/log-rotation.ts
|
|
31
|
-
import { chmod, rename, stat } from "node:fs/promises";
|
|
39
|
+
import { chmod as chmod2, rename, stat } from "node:fs/promises";
|
|
32
40
|
|
|
33
41
|
// src/daemon/config.ts
|
|
34
42
|
import { readFile } from "node:fs/promises";
|
|
@@ -284,7 +292,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
284
292
|
const backupPath = daemonLogBackupPath(options.logFilePath);
|
|
285
293
|
await rename(options.logFilePath, backupPath);
|
|
286
294
|
try {
|
|
287
|
-
await
|
|
295
|
+
await chmod2(backupPath, STATE_FILE_MODE);
|
|
288
296
|
} catch (error) {
|
|
289
297
|
warn(`appduct: rotated "${options.logFilePath}" but could not set 0600 on "${backupPath}": ${error.message}`);
|
|
290
298
|
}
|
|
@@ -300,7 +308,7 @@ var rotateDaemonLogIfNeeded = async (options) => {
|
|
|
300
308
|
var ensureDaemonLogMode = async (logFilePath, warn = (message) => process.stderr.write(`${message}
|
|
301
309
|
`)) => {
|
|
302
310
|
try {
|
|
303
|
-
await
|
|
311
|
+
await chmod2(logFilePath, STATE_FILE_MODE);
|
|
304
312
|
return true;
|
|
305
313
|
} catch (error) {
|
|
306
314
|
warn(`appduct: could not set 0600 on "${logFilePath}": ${error.message}`);
|
|
@@ -641,6 +649,7 @@ var acquireSpawnLock = async (lockPath) => {
|
|
|
641
649
|
return false;
|
|
642
650
|
};
|
|
643
651
|
var spawnDaemonAndWait = async (paths, spawn, waitTimeoutMs, pollIntervalMs, options = {}) => {
|
|
652
|
+
await ensureStateDir(paths.root);
|
|
644
653
|
const acquiredLock = await acquireSpawnLock(paths.spawnLockPath);
|
|
645
654
|
let lockWaitTimedOut = false;
|
|
646
655
|
if (acquiredLock) {
|
|
@@ -1096,7 +1105,8 @@ var makeAppClient = (stream, sessionId) => {
|
|
|
1096
1105
|
const result = await stream.call(RPC_METHODS2.toolsList, {
|
|
1097
1106
|
selector: sessionId
|
|
1098
1107
|
});
|
|
1099
|
-
|
|
1108
|
+
const entries = Array.isArray(result) ? result : result.tools;
|
|
1109
|
+
return entries.map((entry) => ({ ...entry, group: entry.group ?? null }));
|
|
1100
1110
|
} catch (error) {
|
|
1101
1111
|
throw toAppductError(error);
|
|
1102
1112
|
}
|
package/dist/mcp/app-tools.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Every lookup goes to the daemon live, with no caching: the session and its registry can change
|
|
10
10
|
* between any two calls, and the daemon is the single source of truth for both.
|
|
11
11
|
*/
|
|
12
|
-
import { type EffectivePolicyDecision, type
|
|
12
|
+
import { type EffectivePolicyDecision, type ListedToolDescriptor } from "@appduct/shared";
|
|
13
13
|
import type { DaemonCall } from "./daemon-tools.js";
|
|
14
14
|
export declare const LIST_TOOLS_TOOL_NAME = "appduct_list_tools";
|
|
15
15
|
export declare const DESCRIBE_TOOL_TOOL_NAME = "appduct_describe_tool";
|
|
@@ -103,7 +103,7 @@ export declare const CALL_TOOL_TOOL_DESCRIPTOR: {
|
|
|
103
103
|
export type ResolvedAppTool = {
|
|
104
104
|
sessionId: string;
|
|
105
105
|
alias: string;
|
|
106
|
-
descriptor:
|
|
106
|
+
descriptor: ListedToolDescriptor;
|
|
107
107
|
policy: EffectivePolicyDecision;
|
|
108
108
|
};
|
|
109
109
|
export type CallToolArgs = {
|
|
@@ -132,11 +132,11 @@ export declare const handleListToolsTool: (rawArgs: unknown, call: DaemonCall) =
|
|
|
132
132
|
export declare const handleDescribeToolTool: (rawArgs: unknown, call: DaemonCall) => Promise<{
|
|
133
133
|
name: string;
|
|
134
134
|
description: string;
|
|
135
|
-
input_schema?: import("@appduct/shared").ToolSchemaDescriptor;
|
|
136
|
-
output_schema?: import("@appduct/shared").ToolSchemaDescriptor;
|
|
137
|
-
annotations?: import("@appduct/shared").ToolAnnotations;
|
|
138
|
-
timeout_ms?: number;
|
|
139
|
-
group
|
|
135
|
+
input_schema?: import("@appduct/shared").ToolSchemaDescriptor | undefined;
|
|
136
|
+
output_schema?: import("@appduct/shared").ToolSchemaDescriptor | undefined;
|
|
137
|
+
annotations?: import("@appduct/shared").ToolAnnotations | undefined;
|
|
138
|
+
timeout_ms?: number | undefined;
|
|
139
|
+
group: string | null;
|
|
140
140
|
session: string;
|
|
141
141
|
signature: string;
|
|
142
142
|
policy: EffectivePolicyDecision;
|
package/dist/rpc/client.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The auto-spawning RPC client library (ARCHITECTURE.md §4, §5) used by the CLI, MCP server, and
|
|
3
|
-
* tests to talk to `daemon.sock`. On `ENOENT`/`ECONNREFUSED` it
|
|
4
|
-
* spawns `daemon run` detached, polls the socket until
|
|
3
|
+
* tests to talk to `daemon.sock`. On `ENOENT`/`ECONNREFUSED` it creates the state dir if it is
|
|
4
|
+
* missing, takes an exclusive spawn-lock, spawns `daemon run` detached, polls the socket until
|
|
5
|
+
* ready, then retries the request once.
|
|
5
6
|
*/
|
|
6
7
|
import { type RpcErrorData } from "@appduct/shared";
|
|
7
8
|
export type SpawnContext = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appduct",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Driving React Native tools without in-app debug UI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -45,12 +45,13 @@
|
|
|
45
45
|
"reflect-metadata": "^0.2.2",
|
|
46
46
|
"toqr": "^0.1.1",
|
|
47
47
|
"ws": "^8.18.3",
|
|
48
|
-
"@appduct/shared": "0.11.
|
|
48
|
+
"@appduct/shared": "0.11.1"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/node": "^22.10.0",
|
|
52
52
|
"@types/ws": "^8.18.1",
|
|
53
53
|
"esbuild": "^0.25.12",
|
|
54
|
+
"eslint": "^10",
|
|
54
55
|
"typescript": "~5.9.2"
|
|
55
56
|
},
|
|
56
57
|
"files": [
|
|
@@ -60,6 +61,7 @@
|
|
|
60
61
|
"scripts": {
|
|
61
62
|
"build": "tsc -p tsconfig.build.json && node scripts/bundle.mjs",
|
|
62
63
|
"clean": "rm -rf dist",
|
|
64
|
+
"lint": "eslint src",
|
|
63
65
|
"test": "vitest run --config ../../vitest.config.ts src/__tests__",
|
|
64
66
|
"typecheck": "tsc -p tsconfig.json"
|
|
65
67
|
}
|