@fungi.computer/truffle 0.5.0 → 0.7.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/README.md +27 -4
- package/dist/internal/private-workerd-sandbox-worker.mjs +243 -273
- package/dist/internal/sandbox-metafile.json +35 -30
- package/dist/local-extensions.d.ts +2 -2
- package/dist/local-extensions.js +43 -19
- package/dist/log-event.d.ts +3 -0
- package/dist/log-event.js +19 -1
- package/dist/private-fungi-mcp-connection.js +6 -1
- package/dist/private-invocation-computer.d.ts +6 -2
- package/dist/private-invocation-computer.js +20 -13
- package/dist/private-local-auth-rpc.d.ts +1 -1
- package/dist/private-local-computer-processes.d.ts +7 -2
- package/dist/private-local-computer-processes.js +47 -23
- package/dist/private-local-delegation.js +15 -11
- package/dist/private-local-exec-environment.d.ts +5 -2
- package/dist/private-local-exec-environment.js +35 -1
- package/dist/private-local-exec-review.js +14 -7
- package/dist/private-local-exec-rules.d.ts +7 -0
- package/dist/private-local-exec-rules.js +23 -6
- package/dist/private-local-extension-records.d.ts +1 -1
- package/dist/private-local-runtime-host.js +2 -2
- package/dist/private-local-sandbox-policy.js +4 -0
- package/dist/private-local-sandbox.d.ts +3 -1
- package/dist/private-local-sandbox.js +2 -2
- package/dist/private-local-schedule-client.d.ts +12 -0
- package/dist/private-local-schedule-client.js +41 -0
- package/dist/private-local-schedules.d.ts +84 -0
- package/dist/private-local-schedules.js +66 -0
- package/dist/private-local-service-contract.d.ts +3 -0
- package/dist/private-local-service-discovery.d.ts +4 -4
- package/dist/private-local-service-discovery.js +1 -1
- package/dist/private-local-service-listener.js +9 -0
- package/dist/private-local-service-owner.d.ts +130 -0
- package/dist/private-local-service-owner.js +29 -0
- package/dist/private-local-service.d.ts +3 -0
- package/dist/private-local-service.js +2 -0
- package/dist/private-mcp-form-session.d.ts +2 -2
- package/dist/private-openai-claims.d.ts +1 -1
- package/package.json +18 -14
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { agentScheduleListInputSchema, agentSchedulePageSchema, agentScheduleTargetSchema, } from "@fungi.computer/shiitake-extensions/schedules";
|
|
4
|
+
import { readAgentSchedulePage } from "@fungi.computer/shiitake-extensions/schedules/client";
|
|
5
|
+
import { logEvent } from "./log-event.js";
|
|
6
|
+
/** Private service ingress, never a Team/member or machine-link request. */
|
|
7
|
+
export const localScheduleListInputSchema = z.strictObject({
|
|
8
|
+
invocationRoot: z.string().min(1),
|
|
9
|
+
...agentScheduleListInputSchema.shape,
|
|
10
|
+
});
|
|
11
|
+
/** Private person-only mutation, distinct from the finite list request. */
|
|
12
|
+
export const localScheduleControlInputSchema = z.strictObject({
|
|
13
|
+
invocationRoot: z.string().min(1),
|
|
14
|
+
target: agentScheduleTargetSchema,
|
|
15
|
+
});
|
|
16
|
+
/** Local directory pages reuse the schedule owner's decoder and retained state. */
|
|
17
|
+
export const localSchedulePageSchema = Schema.Struct({
|
|
18
|
+
items: agentSchedulePageSchema.fields.items,
|
|
19
|
+
unavailable: Schema.Array(Schema.Struct({
|
|
20
|
+
agentId: Schema.String,
|
|
21
|
+
reason: Schema.Literal("owner_unavailable"),
|
|
22
|
+
})).check(Schema.isMaxLength(8)),
|
|
23
|
+
next: agentSchedulePageSchema.fields.next,
|
|
24
|
+
});
|
|
25
|
+
/** One bounded read, borrowing existing admitted Agent owners one at a time. */
|
|
26
|
+
export async function readLocalSchedulePage(agentIds, open, input, signal) {
|
|
27
|
+
signal.throwIfAborted();
|
|
28
|
+
const candidates = agentIds
|
|
29
|
+
.filter((agentId) => input.after === undefined ? true : agentId >= input.after.agentId)
|
|
30
|
+
.sort();
|
|
31
|
+
const items = [];
|
|
32
|
+
const unavailable = [];
|
|
33
|
+
// Bound runtime fan-out even when many retained Agents have no schedules.
|
|
34
|
+
const owners = candidates.slice(0, 8);
|
|
35
|
+
for (const agentId of owners) {
|
|
36
|
+
signal.throwIfAborted();
|
|
37
|
+
try {
|
|
38
|
+
const { owner, release } = await open(agentId, signal);
|
|
39
|
+
try {
|
|
40
|
+
const limit = input.limit - items.length;
|
|
41
|
+
const pageInput = input.after?.agentId === agentId
|
|
42
|
+
? { limit, after: input.after }
|
|
43
|
+
: { limit };
|
|
44
|
+
const page = await readAgentSchedulePage(agentId, owner, pageInput);
|
|
45
|
+
signal.throwIfAborted();
|
|
46
|
+
items.push(...page.items);
|
|
47
|
+
if (page.next !== null)
|
|
48
|
+
return { items, unavailable, next: page.next };
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
release();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (cause) {
|
|
55
|
+
signal.throwIfAborted();
|
|
56
|
+
logEvent("schedule-directory.owner-unavailable", cause);
|
|
57
|
+
unavailable.push({ agentId, reason: "owner_unavailable" });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const unread = candidates.at(owners.length);
|
|
61
|
+
return {
|
|
62
|
+
items,
|
|
63
|
+
unavailable,
|
|
64
|
+
next: unread === undefined ? null : { agentId: unread, kind: "almanac" },
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -10,6 +10,7 @@ import type { ServiceDiagnosticsStatus } from "./private-local-service-log.js";
|
|
|
10
10
|
import type { LocalSandboxStatus } from "./private-local-sandbox.js";
|
|
11
11
|
import type { LocalPermissionMode } from "./private-local-permission-mode.js";
|
|
12
12
|
import type { LocalUiAttachmentLifetime } from "./private-local-ui-attachment.js";
|
|
13
|
+
import type { PrivateLocalScheduleCapability } from "./private-local-schedule-client.js";
|
|
13
14
|
/** Live health, not the on-disk identity record or a cached connection snapshot. */
|
|
14
15
|
export type PrivateLocalServiceStatus = Readonly<{
|
|
15
16
|
/** The client-service wire contract this service speaks. */
|
|
@@ -140,6 +141,8 @@ export type PrivateLocalSessionDiscovery = Readonly<{
|
|
|
140
141
|
}>;
|
|
141
142
|
/** Local process management stays outside the shared Session HTTP contract. */
|
|
142
143
|
export type PrivateLocalServiceManager = Readonly<{
|
|
144
|
+
/** Explicit private person-only capability; never provided by a mesh/App grant. */
|
|
145
|
+
schedules: (invocationRoot: string) => PrivateLocalScheduleCapability;
|
|
143
146
|
reload: (invocationRoot: string) => Promise<string>;
|
|
144
147
|
/** Throws `LocalServiceUpdated` when a live service speaks another protocol. */
|
|
145
148
|
status: () => Promise<PrivateLocalServiceStatus | undefined>;
|
|
@@ -4,7 +4,7 @@ export { sandboxStatusSchema } from "./private-local-sandbox.js";
|
|
|
4
4
|
* The client-service wire contract. Bump it with any change an older client
|
|
5
5
|
* cannot read; a running client then asks its window to restart.
|
|
6
6
|
*/
|
|
7
|
-
export declare const privateLocalServiceProtocol =
|
|
7
|
+
export declare const privateLocalServiceProtocol = 5;
|
|
8
8
|
/** This build's identity: the packed CLI's content hash, or `source` for a source run. */
|
|
9
9
|
export declare function privateLocalServiceVersion(): string;
|
|
10
10
|
/**
|
|
@@ -19,7 +19,7 @@ declare const serviceLifecycleSchema: z.ZodObject<{
|
|
|
19
19
|
startedAt: z.ZodString;
|
|
20
20
|
}, z.core.$loose>;
|
|
21
21
|
declare const serviceRecordSchema: z.ZodObject<{
|
|
22
|
-
protocol: z.ZodLiteral<
|
|
22
|
+
protocol: z.ZodLiteral<5>;
|
|
23
23
|
baseUrl: z.ZodURL;
|
|
24
24
|
version: z.ZodString;
|
|
25
25
|
serviceId: z.ZodString & z.ZodType<import("@fungi.computer/cairn").CairnId<"local-service", "service", 1>, string, z.core.$ZodTypeInternals<import("@fungi.computer/cairn").CairnId<"local-service", "service", 1>, string>>;
|
|
@@ -29,7 +29,7 @@ declare const serviceRecordSchema: z.ZodObject<{
|
|
|
29
29
|
export type ServiceRecord = z.infer<typeof serviceRecordSchema>;
|
|
30
30
|
/** Mandatory live diagnostics; never written into the registration pointer. */
|
|
31
31
|
export declare const liveServiceStatusSchema: z.ZodObject<{
|
|
32
|
-
protocol: z.ZodLiteral<
|
|
32
|
+
protocol: z.ZodLiteral<5>;
|
|
33
33
|
baseUrl: z.ZodURL;
|
|
34
34
|
version: z.ZodString;
|
|
35
35
|
serviceId: z.ZodString & z.ZodType<import("@fungi.computer/cairn").CairnId<"local-service", "service", 1>, string, z.core.$ZodTypeInternals<import("@fungi.computer/cairn").CairnId<"local-service", "service", 1>, string>>;
|
|
@@ -141,9 +141,9 @@ export declare const archiveRequestSchema: z.ZodObject<{
|
|
|
141
141
|
export declare const archiveRefusalSchema: z.ZodObject<{
|
|
142
142
|
code: z.ZodLiteral<"agent_archive_refused">;
|
|
143
143
|
reason: z.ZodEnum<{
|
|
144
|
+
archived: "archived";
|
|
144
145
|
pending: "pending";
|
|
145
146
|
running: "running";
|
|
146
|
-
archived: "archived";
|
|
147
147
|
not_creator: "not_creator";
|
|
148
148
|
self: "self";
|
|
149
149
|
unreadable: "unreadable";
|
|
@@ -17,7 +17,7 @@ export { sandboxStatusSchema } from "./private-local-sandbox.js";
|
|
|
17
17
|
* The client-service wire contract. Bump it with any change an older client
|
|
18
18
|
* cannot read; a running client then asks its window to restart.
|
|
19
19
|
*/
|
|
20
|
-
export const privateLocalServiceProtocol =
|
|
20
|
+
export const privateLocalServiceProtocol = 5;
|
|
21
21
|
/** This build's identity: the packed CLI's content hash, or `source` for a source run. */
|
|
22
22
|
export function privateLocalServiceVersion() {
|
|
23
23
|
return (z
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { localFailureMetadata, logEvent } from "./log-event.js";
|
|
2
2
|
import { bodyLimit } from "hono/body-limit";
|
|
3
|
+
import { ShiitakeError } from "@fungi.computer/shiitake";
|
|
4
|
+
import { toShiitakeErrorWire } from "@fungi.computer/shiitake/http";
|
|
5
|
+
import { localScheduleControlInputSchema, localScheduleListInputSchema, } from "./private-local-schedules.js";
|
|
3
6
|
import { enrollPrivateLocalMesh, localMeshJoinSchema, } from "./private-local-mesh-enrollment.js";
|
|
4
7
|
import { createLocalMachineEnrollmentAccount, registerFungiAccountOwner, signOutOwnedFungiAccount, } from "./private-fungi-account.js";
|
|
5
8
|
import { createServiceLogLifecycle, } from "./private-local-service-log.js";
|
|
@@ -103,6 +106,9 @@ readRecoveryManifest, root = capturePrivateLocalConfigRoot()) {
|
|
|
103
106
|
const app = new Hono();
|
|
104
107
|
app.onError((error, context) => {
|
|
105
108
|
diagnostics.failure(localFailureMetadata("service.request", error));
|
|
109
|
+
if (error instanceof ShiitakeError &&
|
|
110
|
+
context.req.path.startsWith(`${prefix}/schedules/`))
|
|
111
|
+
return context.json(toShiitakeErrorWire(error), error.cause === "conflict" ? 409 : 400);
|
|
106
112
|
if (error instanceof LocalStoreSchemaError)
|
|
107
113
|
return context.json({
|
|
108
114
|
code: "store_schema_incompatible",
|
|
@@ -308,6 +314,9 @@ readRecoveryManifest, root = capturePrivateLocalConfigRoot()) {
|
|
|
308
314
|
archived: input.archived,
|
|
309
315
|
}));
|
|
310
316
|
});
|
|
317
|
+
app.post(`${prefix}/schedules/list`, bodyLimit({ maxSize: 32 * 1024 }), async (context) => context.json(await owners.schedules(localScheduleListInputSchema.parse(await context.req.json()), context.req.raw.signal)));
|
|
318
|
+
app.post(`${prefix}/schedules/pause`, bodyLimit({ maxSize: 32 * 1024 }), async (context) => context.json(await owners.pauseSchedule(localScheduleControlInputSchema.parse(await context.req.json()), context.req.raw.signal)));
|
|
319
|
+
app.post(`${prefix}/schedules/delete`, bodyLimit({ maxSize: 32 * 1024 }), async (context) => context.json(await owners.deleteSchedule(localScheduleControlInputSchema.parse(await context.req.json()), context.req.raw.signal)));
|
|
311
320
|
app.post(`${prefix}/reload`, async (context) => {
|
|
312
321
|
try {
|
|
313
322
|
const input = z
|
|
@@ -3,10 +3,12 @@ import { type PrivateLocalConfigRoot } from "./private-local-config-root.js";
|
|
|
3
3
|
import type { ServiceLogLifecycle } from "./private-local-service-log.js";
|
|
4
4
|
import type { StopAllResult } from "./private-local-stop-all.js";
|
|
5
5
|
import { type LocalExtensions } from "./local-extensions.js";
|
|
6
|
+
import { z } from "zod";
|
|
6
7
|
import type { PrivateLocalServiceSelection, PrivateLocalSessionCreation } from "./private-local-service-contract.js";
|
|
7
8
|
import { openPrivateLocalRuntimeHost, type PrivateLocalRuntimeHost } from "./private-local-runtime-host.js";
|
|
8
9
|
import type { LocalUiAttachment } from "./private-local-ui-attachment.js";
|
|
9
10
|
import { createLocalMeshLinks } from "./private-local-mesh-links.js";
|
|
11
|
+
import { localScheduleControlInputSchema, localScheduleListInputSchema } from "./private-local-schedules.js";
|
|
10
12
|
export type LocalServiceRuntime = Pick<PrivateLocalRuntimeHost, "databasePath" | "agentId" | "name" | "getSession" | "effectiveModel" | "setModel" | "setArchived" | "setMode" | "sandboxStatus" | "pendingDelegation" | "assertModelReady" | "listSessions" | "createSession" | "deleteSession" | "extensions" | "prepareReload" | "bindSessionPath" | "acceptMail" | "readSettlement" | "idle" | "close">;
|
|
11
13
|
export declare class LocalSessionPathConflict extends Error {
|
|
12
14
|
readonly name = "LocalSessionPathConflict";
|
|
@@ -127,6 +129,134 @@ serviceNative?: () => NonNullable<Parameters<typeof openPrivateLocalRuntimeHost>
|
|
|
127
129
|
} | undefined;
|
|
128
130
|
}>;
|
|
129
131
|
sweepIdle: () => Promise<void>;
|
|
132
|
+
schedules: (request: z.input<typeof localScheduleListInputSchema>, signal: AbortSignal) => Promise<{
|
|
133
|
+
readonly items: readonly ({
|
|
134
|
+
readonly agentId: string;
|
|
135
|
+
readonly kind: "almanac";
|
|
136
|
+
readonly schedule: {
|
|
137
|
+
readonly id: string;
|
|
138
|
+
readonly sessionId: string;
|
|
139
|
+
readonly prompt: string;
|
|
140
|
+
readonly cron: {
|
|
141
|
+
readonly expression: string;
|
|
142
|
+
readonly timeZone: string;
|
|
143
|
+
} | null;
|
|
144
|
+
readonly nextDueAt: number;
|
|
145
|
+
readonly state: "cancelled" | "active" | "paused" | "finished";
|
|
146
|
+
readonly lastCommandId: string | null;
|
|
147
|
+
readonly lastError: string | null;
|
|
148
|
+
readonly attempt: number;
|
|
149
|
+
};
|
|
150
|
+
} | {
|
|
151
|
+
readonly agentId: string;
|
|
152
|
+
readonly kind: "loop";
|
|
153
|
+
readonly schedule: {
|
|
154
|
+
readonly sessionId: string;
|
|
155
|
+
readonly loopId: string;
|
|
156
|
+
readonly origin: "model" | "human";
|
|
157
|
+
readonly expiresAt: number | null;
|
|
158
|
+
readonly prompt: string;
|
|
159
|
+
readonly mode: "self_paced" | "fixed_interval";
|
|
160
|
+
readonly cron: {
|
|
161
|
+
readonly expression: string;
|
|
162
|
+
readonly timeZone: string;
|
|
163
|
+
} | null;
|
|
164
|
+
readonly state: "cancelled" | "active" | "failed" | "paused" | "finished";
|
|
165
|
+
readonly commandId: string;
|
|
166
|
+
readonly reason: string | null;
|
|
167
|
+
readonly nextDueAt: number | null;
|
|
168
|
+
readonly lastError: string | null;
|
|
169
|
+
readonly consecutiveFailures: number;
|
|
170
|
+
};
|
|
171
|
+
})[];
|
|
172
|
+
readonly unavailable: readonly {
|
|
173
|
+
readonly agentId: string;
|
|
174
|
+
readonly reason: "owner_unavailable";
|
|
175
|
+
}[];
|
|
176
|
+
readonly next: {
|
|
177
|
+
readonly agentId: string;
|
|
178
|
+
readonly kind: "almanac" | "loop";
|
|
179
|
+
readonly after?: string;
|
|
180
|
+
} | null;
|
|
181
|
+
}>;
|
|
182
|
+
pauseSchedule: (request: z.input<typeof localScheduleControlInputSchema>, signal: AbortSignal) => Promise<{
|
|
183
|
+
readonly agentId: string;
|
|
184
|
+
readonly kind: "almanac";
|
|
185
|
+
readonly schedule: {
|
|
186
|
+
readonly id: string;
|
|
187
|
+
readonly sessionId: string;
|
|
188
|
+
readonly prompt: string;
|
|
189
|
+
readonly cron: {
|
|
190
|
+
readonly expression: string;
|
|
191
|
+
readonly timeZone: string;
|
|
192
|
+
} | null;
|
|
193
|
+
readonly nextDueAt: number;
|
|
194
|
+
readonly state: "cancelled" | "active" | "paused" | "finished";
|
|
195
|
+
readonly lastCommandId: string | null;
|
|
196
|
+
readonly lastError: string | null;
|
|
197
|
+
readonly attempt: number;
|
|
198
|
+
};
|
|
199
|
+
} | {
|
|
200
|
+
readonly agentId: string;
|
|
201
|
+
readonly kind: "loop";
|
|
202
|
+
readonly schedule: {
|
|
203
|
+
readonly sessionId: string;
|
|
204
|
+
readonly loopId: string;
|
|
205
|
+
readonly origin: "model" | "human";
|
|
206
|
+
readonly expiresAt: number | null;
|
|
207
|
+
readonly prompt: string;
|
|
208
|
+
readonly mode: "self_paced" | "fixed_interval";
|
|
209
|
+
readonly cron: {
|
|
210
|
+
readonly expression: string;
|
|
211
|
+
readonly timeZone: string;
|
|
212
|
+
} | null;
|
|
213
|
+
readonly state: "cancelled" | "active" | "failed" | "paused" | "finished";
|
|
214
|
+
readonly commandId: string;
|
|
215
|
+
readonly reason: string | null;
|
|
216
|
+
readonly nextDueAt: number | null;
|
|
217
|
+
readonly lastError: string | null;
|
|
218
|
+
readonly consecutiveFailures: number;
|
|
219
|
+
};
|
|
220
|
+
}>;
|
|
221
|
+
deleteSchedule: (request: z.input<typeof localScheduleControlInputSchema>, signal: AbortSignal) => Promise<{
|
|
222
|
+
readonly agentId: string;
|
|
223
|
+
readonly kind: "almanac";
|
|
224
|
+
readonly schedule: {
|
|
225
|
+
readonly id: string;
|
|
226
|
+
readonly sessionId: string;
|
|
227
|
+
readonly prompt: string;
|
|
228
|
+
readonly cron: {
|
|
229
|
+
readonly expression: string;
|
|
230
|
+
readonly timeZone: string;
|
|
231
|
+
} | null;
|
|
232
|
+
readonly nextDueAt: number;
|
|
233
|
+
readonly state: "cancelled" | "active" | "paused" | "finished";
|
|
234
|
+
readonly lastCommandId: string | null;
|
|
235
|
+
readonly lastError: string | null;
|
|
236
|
+
readonly attempt: number;
|
|
237
|
+
};
|
|
238
|
+
} | {
|
|
239
|
+
readonly agentId: string;
|
|
240
|
+
readonly kind: "loop";
|
|
241
|
+
readonly schedule: {
|
|
242
|
+
readonly sessionId: string;
|
|
243
|
+
readonly loopId: string;
|
|
244
|
+
readonly origin: "model" | "human";
|
|
245
|
+
readonly expiresAt: number | null;
|
|
246
|
+
readonly prompt: string;
|
|
247
|
+
readonly mode: "self_paced" | "fixed_interval";
|
|
248
|
+
readonly cron: {
|
|
249
|
+
readonly expression: string;
|
|
250
|
+
readonly timeZone: string;
|
|
251
|
+
} | null;
|
|
252
|
+
readonly state: "cancelled" | "active" | "failed" | "paused" | "finished";
|
|
253
|
+
readonly commandId: string;
|
|
254
|
+
readonly reason: string | null;
|
|
255
|
+
readonly nextDueAt: number | null;
|
|
256
|
+
readonly lastError: string | null;
|
|
257
|
+
readonly consecutiveFailures: number;
|
|
258
|
+
};
|
|
259
|
+
}>;
|
|
130
260
|
archive: (request: Readonly<{
|
|
131
261
|
invocationRoot: string;
|
|
132
262
|
agentId: string;
|
|
@@ -25,6 +25,8 @@ import { createLocalMeshLinks, localMeshLinkKey, } from "./private-local-mesh-li
|
|
|
25
25
|
import { agentMailAddressSchema, machineAgentRequestSchema, machineDirectorySchema, } from "@fungi.computer/seam/machine-link-protocol";
|
|
26
26
|
import { commandSettlementSchema, settlementReadableBy, } from "@fungi.computer/shiitake/fleet";
|
|
27
27
|
import { BirdDogMailSchema } from "@fungi.computer/bird-dog/effect";
|
|
28
|
+
import { controlAgentScheduleWithContent } from "@fungi.computer/shiitake-extensions/schedules/client";
|
|
29
|
+
import { localScheduleControlInputSchema, localScheduleListInputSchema, readLocalSchedulePage, } from "./private-local-schedules.js";
|
|
28
30
|
export class LocalSessionPathConflict extends Error {
|
|
29
31
|
name = "LocalSessionPathConflict";
|
|
30
32
|
constructor() {
|
|
@@ -1034,6 +1036,7 @@ serviceNative, onExecApprovalDecision = () => undefined) {
|
|
|
1034
1036
|
}
|
|
1035
1037
|
}
|
|
1036
1038
|
return {
|
|
1039
|
+
targets,
|
|
1037
1040
|
owner: admittedOwner,
|
|
1038
1041
|
answer: answerAsSender,
|
|
1039
1042
|
escalate: escalateAsSender,
|
|
@@ -1366,6 +1369,29 @@ serviceNative, onExecApprovalDecision = () => undefined) {
|
|
|
1366
1369
|
scheduleWakes();
|
|
1367
1370
|
await saveRecovery();
|
|
1368
1371
|
}
|
|
1372
|
+
/** Private person-only schedule discovery, never the Agent or mesh directory. */
|
|
1373
|
+
async function schedules(request, signal) {
|
|
1374
|
+
ensureRunning();
|
|
1375
|
+
signal.throwIfAborted();
|
|
1376
|
+
const input = localScheduleListInputSchema.parse(request);
|
|
1377
|
+
const root = await realpath(input.invocationRoot);
|
|
1378
|
+
const control = directory(root);
|
|
1379
|
+
const agents = [...(await control.targets(signal, "all")).keys()];
|
|
1380
|
+
return readLocalSchedulePage(agents, (agentId, requestSignal) => control.owner(agentId, requestSignal, true), input, signal);
|
|
1381
|
+
}
|
|
1382
|
+
async function controlSchedule(request, action, signal) {
|
|
1383
|
+
ensureRunning();
|
|
1384
|
+
signal.throwIfAborted();
|
|
1385
|
+
const input = localScheduleControlInputSchema.parse(request);
|
|
1386
|
+
const root = await realpath(input.invocationRoot);
|
|
1387
|
+
const { owner, release } = await directory(root).owner(input.target.agentId, signal, true);
|
|
1388
|
+
try {
|
|
1389
|
+
return await controlAgentScheduleWithContent(owner, input.target, action);
|
|
1390
|
+
}
|
|
1391
|
+
finally {
|
|
1392
|
+
release();
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1369
1395
|
/** A person archives or restores any Agent of one project folder. */
|
|
1370
1396
|
async function archive(request, signal) {
|
|
1371
1397
|
const control = directory(await realpath(request.invocationRoot));
|
|
@@ -1521,6 +1547,9 @@ serviceNative, onExecApprovalDecision = () => undefined) {
|
|
|
1521
1547
|
effectiveModel,
|
|
1522
1548
|
sandboxStatus,
|
|
1523
1549
|
sweepIdle,
|
|
1550
|
+
schedules,
|
|
1551
|
+
pauseSchedule: (request, signal) => controlSchedule(request, "pause", signal),
|
|
1552
|
+
deleteSchedule: (request, signal) => controlSchedule(request, "delete", signal),
|
|
1524
1553
|
archive,
|
|
1525
1554
|
stopAll,
|
|
1526
1555
|
restore,
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export type { PrivateLocalScheduleCapability } from "./private-local-schedule-client.js";
|
|
2
|
+
export type { AgentScheduleRow, AgentScheduleTarget, } from "@fungi.computer/shiitake-extensions/schedules";
|
|
3
|
+
export type { LocalSchedulePage } from "./private-local-schedules.js";
|
|
1
4
|
export { LocalSandboxUnavailable } from "./private-local-containment.js";
|
|
2
5
|
export type { StopAllResult } from "./private-local-stop-all.js";
|
|
3
6
|
export { LocalAgentSelectionAmbiguous, LocalSessionPathConflict, } from "./private-local-service-owner.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FungiMcpSelectionConflict } from "./private-fungi-mcp-selection.js";
|
|
2
2
|
import { logEvent } from "./log-event.js";
|
|
3
|
+
import { createPrivateLocalScheduleCapability } from "./private-local-schedule-client.js";
|
|
3
4
|
import { readBoundedResponse } from "./private-bounded-response.js";
|
|
4
5
|
import { LocalSandboxUnavailable, sandboxUnavailableReasonSchema, } from "./private-local-containment.js";
|
|
5
6
|
export { LocalSandboxUnavailable } from "./private-local-containment.js";
|
|
@@ -513,6 +514,7 @@ export function createPrivateLocalServiceManager(options = {}) {
|
|
|
513
514
|
snapshot: z.unknown(),
|
|
514
515
|
});
|
|
515
516
|
return {
|
|
517
|
+
schedules: (invocationRoot) => createPrivateLocalScheduleCapability(invocationRoot, start),
|
|
516
518
|
status,
|
|
517
519
|
start,
|
|
518
520
|
createSession: (creation, request) => openConnection("sessions", creation, request),
|
|
@@ -142,8 +142,8 @@ export declare function createMcpFormSession(): {
|
|
|
142
142
|
readonly command: string;
|
|
143
143
|
readonly cwd: string;
|
|
144
144
|
readonly justification: string;
|
|
145
|
-
readonly argv?: readonly string[];
|
|
146
145
|
readonly prefix?: readonly string[];
|
|
146
|
+
readonly argv?: readonly string[];
|
|
147
147
|
readonly warning?: string;
|
|
148
148
|
readonly alwaysAllowCoverage?: string;
|
|
149
149
|
readonly alwaysAllowUnavailableReason?: string;
|
|
@@ -204,8 +204,8 @@ export declare function createMcpFormSession(): {
|
|
|
204
204
|
readonly command: string;
|
|
205
205
|
readonly cwd: string;
|
|
206
206
|
readonly justification: string;
|
|
207
|
-
readonly argv?: readonly string[];
|
|
208
207
|
readonly prefix?: readonly string[];
|
|
208
|
+
readonly argv?: readonly string[];
|
|
209
209
|
readonly warning?: string;
|
|
210
210
|
readonly alwaysAllowCoverage?: string;
|
|
211
211
|
readonly alwaysAllowUnavailableReason?: string;
|
|
@@ -11,9 +11,9 @@ export declare const openAIIdentityDetailSchema: z.ZodObject<{
|
|
|
11
11
|
"access_token.sub": "access_token.sub";
|
|
12
12
|
}>;
|
|
13
13
|
problem: z.ZodEnum<{
|
|
14
|
+
invalid: "invalid";
|
|
14
15
|
absent: "absent";
|
|
15
16
|
malformed: "malformed";
|
|
16
|
-
invalid: "invalid";
|
|
17
17
|
}>;
|
|
18
18
|
claimNames: z.ZodArray<z.ZodString>;
|
|
19
19
|
authClaimNames: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fungi.computer/truffle",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Truffle: Fungi's local Agent runtime, bundled into the fungi command",
|
|
6
6
|
"type": "module",
|
|
@@ -77,26 +77,26 @@
|
|
|
77
77
|
"@cf-wasm/photon": "0.4.0",
|
|
78
78
|
"@earendil-works/pi-ai": "1.3.0",
|
|
79
79
|
"@effect/platform-node": "4.0.2",
|
|
80
|
-
"@fungi.computer/agar": "0.
|
|
80
|
+
"@fungi.computer/agar": "0.6.1",
|
|
81
81
|
"@fungi.computer/approvals": "0.2.0",
|
|
82
|
-
"@fungi.computer/bird-dog": "0.3.
|
|
82
|
+
"@fungi.computer/bird-dog": "0.3.1",
|
|
83
83
|
"@fungi.computer/cairn": "0.1.0",
|
|
84
84
|
"@fungi.computer/capnweb": "0.12.0",
|
|
85
85
|
"@fungi.computer/carrier": "0.2.0",
|
|
86
86
|
"@fungi.computer/cordyceps": "0.4.0",
|
|
87
87
|
"@fungi.computer/gills": "0.2.0",
|
|
88
|
-
"@fungi.computer/graft": "0.1.
|
|
89
|
-
"@fungi.computer/knapsack": "0.4.
|
|
88
|
+
"@fungi.computer/graft": "0.1.6",
|
|
89
|
+
"@fungi.computer/knapsack": "0.4.2",
|
|
90
90
|
"@fungi.computer/lantern": "0.3.1",
|
|
91
|
-
"@fungi.computer/mycelium": "0.
|
|
92
|
-
"@fungi.computer/nacre": "0.1.
|
|
91
|
+
"@fungi.computer/mycelium": "0.3.1",
|
|
92
|
+
"@fungi.computer/nacre": "0.1.2",
|
|
93
93
|
"@fungi.computer/seam": "0.2.0",
|
|
94
|
-
"@fungi.computer/shiitake": "0.
|
|
95
|
-
"@fungi.computer/shiitake-extensions": "0.
|
|
96
|
-
"@fungi.computer/veil": "0.
|
|
94
|
+
"@fungi.computer/shiitake": "0.8.0",
|
|
95
|
+
"@fungi.computer/shiitake-extensions": "0.6.0",
|
|
96
|
+
"@fungi.computer/veil": "0.3.0",
|
|
97
97
|
"@fungi.computer/watchdog": "0.1.0",
|
|
98
98
|
"@fungi.computer/whistle": "0.3.0",
|
|
99
|
-
"@fungi.computer/zookeeper": "0.0.
|
|
99
|
+
"@fungi.computer/zookeeper": "0.0.7",
|
|
100
100
|
"@jellybrick/dbus-next": "0.11.4",
|
|
101
101
|
"@modelcontextprotocol/client": "2.0.0",
|
|
102
102
|
"@napi-rs/keyring": "2.1.2",
|
|
@@ -107,6 +107,7 @@
|
|
|
107
107
|
"image-size": "2.0.4",
|
|
108
108
|
"jose": "6.2.11",
|
|
109
109
|
"miniflare": "5.20260828.0-alpha",
|
|
110
|
+
"npm-package-arg": "14.0.0",
|
|
110
111
|
"proper-lockfile": "4.1.2",
|
|
111
112
|
"re2js": "1.3.3",
|
|
112
113
|
"semver": "7.8.5",
|
|
@@ -120,10 +121,11 @@
|
|
|
120
121
|
"@fungi.computer/mule": "0.2.1",
|
|
121
122
|
"@modelcontextprotocol/server": "2.0.0",
|
|
122
123
|
"@types/node": "24.13.3",
|
|
124
|
+
"@types/npm-package-arg": "6.1.4",
|
|
123
125
|
"@types/proper-lockfile": "4.1.4",
|
|
124
126
|
"@types/semver": "7.8.0",
|
|
125
127
|
"@types/write-file-atomic": "4.0.3",
|
|
126
|
-
"bun": "1.4.
|
|
128
|
+
"bun": "1.4.4",
|
|
127
129
|
"bun-types": "1.4.1",
|
|
128
130
|
"esbuild": "0.28.2",
|
|
129
131
|
"typescript": "5.9.3",
|
|
@@ -165,12 +167,14 @@
|
|
|
165
167
|
"clean": "node --input-type=module --eval \"import { rm } from 'node:fs/promises'; await rm('dist', { recursive: true, force: true });\"",
|
|
166
168
|
"test": "pnpm run test:node && pnpm run test:merge && pnpm run test:stop-all",
|
|
167
169
|
"soak:memory": "bun scripts/service-memory-soak.mjs",
|
|
170
|
+
"soak:sqlite-open-close": "bun scripts/sqlite-open-close-repro.mjs",
|
|
168
171
|
"test:stop-all": "bun test ./test/private-local-stop-all.bun.test.ts",
|
|
169
172
|
"test:full": "pnpm run test && pnpm run test:bun",
|
|
170
173
|
"test:node": "../../node_modules/.bin/vitest run",
|
|
174
|
+
"test:sandbox:native": "../../node_modules/.bin/vitest run --config vitest.native.config.ts",
|
|
171
175
|
"test:bun": "pnpm run test:mesh-link && pnpm run test:bun:batch && bun test ./test/private-workerd-deadline.bun.test.ts",
|
|
172
176
|
"test:mesh-link": "bun test ./test/private-local-mesh-links.bun.test.ts",
|
|
173
|
-
"test:bun:batch": "bun test ./test/private-sqlite-approval-driver.bun.test.ts ./test/mcp-form-service.bun.test.ts ./test/private-local-service-discovery.bun.test.ts ./test/private-local-service-listener.bun.test.ts ./test/private-local-service-manager.bun.test.ts ./test/private-local-service-rebind.bun.test.ts ./test/private-local-service-stop.bun.test.ts ./test/private-local-service-ensure.bun.test.ts ./test/private-local-service-identity.bun.test.ts ./test/private-local-service-kill-resume.bun.test.ts ./test/private-local-service-idle-owners.bun.test.ts ./test/private-local-service-idle-delegation.bun.test.ts ./test/private-local-mail-retry.bun.test.ts ./test/private-local-service-log-native.bun.test.ts ./test/private-local-service-log.bun.test.ts ./test/private-local-sqlite-lifetime.bun.test.ts ./test/private-sqlite-driver.bun.test.ts ./test/private-local-reload.bun.test.ts ./test/private-local-auth-rpc.bun.test.ts ./test/private-workerd-forage.bun.test.ts ./test/local-extensions.bun.test.ts ./test/local-extension-archive.bun.test.ts ./test/local-zookeeper-slot.bun.test.ts ./test/local-extension-skills.bun.test.ts ./test/private-local-sandbox-service.bun.test.ts ./test/private-local-native-service.bun.test.ts",
|
|
177
|
+
"test:bun:batch": "bun test ./test/private-sqlite-approval-driver.bun.test.ts ./test/mcp-form-service.bun.test.ts ./test/private-local-service-discovery.bun.test.ts ./test/private-local-service-listener.bun.test.ts ./test/private-local-schedules.bun.test.ts ./test/private-local-service-manager.bun.test.ts ./test/private-local-service-rebind.bun.test.ts ./test/private-local-service-stop.bun.test.ts ./test/private-local-service-ensure.bun.test.ts ./test/private-local-service-identity.bun.test.ts ./test/private-local-service-kill-resume.bun.test.ts ./test/private-local-service-idle-owners.bun.test.ts ./test/private-local-service-idle-delegation.bun.test.ts ./test/private-local-mail-retry.bun.test.ts ./test/private-local-service-log-native.bun.test.ts ./test/private-local-service-log.bun.test.ts ./test/private-local-sqlite-lifetime.bun.test.ts ./test/private-sqlite-driver.bun.test.ts ./test/private-local-reload.bun.test.ts ./test/private-local-auth-rpc.bun.test.ts ./test/private-workerd-forage.bun.test.ts ./test/local-extensions.bun.test.ts ./test/local-extension-archive.bun.test.ts ./test/local-zookeeper-slot.bun.test.ts ./test/local-extension-skills.bun.test.ts ./test/private-local-sandbox-service.bun.test.ts ./test/private-local-native-service.bun.test.ts",
|
|
174
178
|
"build:native": "fungi-apply-patch-build --out native/bin && node scripts/build-bwrap.mjs --out native/bin && node scripts/generate-native-digests.mjs",
|
|
175
179
|
"test:patch": "node --test --test-timeout=30000 test/apply-patch.native.mjs",
|
|
176
180
|
"test:sandbox:linux": "node --import tsx test/fixtures/local-sandbox-proof.mts",
|
|
@@ -178,7 +182,7 @@
|
|
|
178
182
|
"format:check": "node ../../tooling/repository/scripts/format-package-check.mjs",
|
|
179
183
|
"lint:anti-slop": "node ../../tooling/repository/scripts/lint-package-anti-slop.mjs",
|
|
180
184
|
"test:unit": "node ../../tooling/repository/scripts/test-file-pool.mjs pnpm run test:node && pnpm run test:mesh-link && pnpm run test:bun:batch && pnpm run test:stop-all",
|
|
181
|
-
"test:merge": "pnpm run test:patch && case \"$(uname -s)\" in Darwin) pnpm run test:sandbox:macos ;; *) pnpm run test:sandbox:linux ;; esac",
|
|
185
|
+
"test:merge": "pnpm run test:sandbox:native && pnpm run test:patch && case \"$(uname -s)\" in Darwin) pnpm run test:sandbox:macos ;; *) pnpm run test:sandbox:linux ;; esac",
|
|
182
186
|
"proof:goal-loop-sol": "bun scripts/goal-loop-model-proof.mjs",
|
|
183
187
|
"proof:unpatched-login": "node scripts/prove-unpatched-login.mjs",
|
|
184
188
|
"proof:sqlite-close": "bun test ./test/private-local-sqlite-close.bun.test.ts"
|