@fungi.computer/truffle 0.4.0 → 0.5.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/dist/local-board-agents.d.ts +46 -0
- package/dist/local-board-agents.js +138 -0
- package/dist/local-board-shipping.d.ts +129 -0
- package/dist/local-board-shipping.js +325 -0
- package/dist/local-extensions.d.ts +2 -0
- package/dist/local-extensions.js +13 -3
- package/dist/local-login.js +33 -25
- package/dist/private-local-agent-control.d.ts +5 -1
- package/dist/private-local-agent-control.js +11 -1
- package/dist/private-local-auth-rpc.d.ts +5 -0
- package/dist/private-local-auth-rpc.js +46 -4
- package/dist/private-local-client-version.js +3 -1
- package/dist/private-local-delegation.d.ts +18 -0
- package/dist/private-local-delegation.js +70 -16
- package/dist/private-local-runtime-host.js +52 -25
- package/dist/private-local-service-contract.d.ts +1 -0
- package/dist/private-local-service-owner.js +61 -2
- package/dist/private-local-service.js +7 -1
- package/dist/private-local-session-discovery.d.ts +10 -4
- package/dist/private-local-session-discovery.js +37 -4
- package/dist/private-provider-rejection.d.ts +1 -1
- package/dist/private-provider-rejection.js +28 -8
- package/dist/private-sqlite-owner.d.ts +7 -1
- package/dist/private-sqlite-owner.js +14 -2
- package/package.json +22 -13
|
@@ -17,12 +17,13 @@ import { z } from "zod";
|
|
|
17
17
|
import * as Schema from "effect/Schema";
|
|
18
18
|
import { selectionSchema } from "./private-local-service-discovery.js";
|
|
19
19
|
import { createShiitakeHttpRoutes } from "@fungi.computer/shiitake/http";
|
|
20
|
+
import { questionContract } from "@fungi.computer/shiitake-extensions/question";
|
|
20
21
|
import { listPrivateLocalAgentStores, LocalStoreSchemaError, readPrivateLocalAgentProfile, readPrivateLocalSessionSummaries, isArchivedStore, unreadableStoreReason, } from "./private-local-session-discovery.js";
|
|
21
22
|
import { createPrivateLocalSessionRequestId, openPrivateLocalRuntimeHost, resolvePrivateLocalCreateStore, } from "./private-local-runtime-host.js";
|
|
22
23
|
import { parsePrivateLocalExecPath } from "./private-local-exec-path.js";
|
|
23
24
|
import { createLocalMeshLinks, localMeshLinkKey, } from "./private-local-mesh-links.js";
|
|
24
25
|
import { agentMailAddressSchema, machineAgentRequestSchema, machineDirectorySchema, } from "@fungi.computer/seam/machine-link-protocol";
|
|
25
|
-
import { commandSettlementSchema } from "@fungi.computer/shiitake/fleet";
|
|
26
|
+
import { commandSettlementSchema, settlementReadableBy, } from "@fungi.computer/shiitake/fleet";
|
|
26
27
|
import { BirdDogMailSchema } from "@fungi.computer/bird-dog/effect";
|
|
27
28
|
export class LocalSessionPathConflict extends Error {
|
|
28
29
|
name = "LocalSessionPathConflict";
|
|
@@ -163,7 +164,7 @@ serviceNative, onExecApprovalDecision = () => undefined) {
|
|
|
163
164
|
return { status: "accepted", receipt: { sessionId } };
|
|
164
165
|
}
|
|
165
166
|
const facts = await admitted(owner, () => owner.readSettlement(operation.sessionId, operation.commandId));
|
|
166
|
-
if (facts !== undefined && facts
|
|
167
|
+
if (facts !== undefined && !settlementReadableBy(facts, actorAgentId))
|
|
167
168
|
return "refused";
|
|
168
169
|
return {
|
|
169
170
|
status: "accepted",
|
|
@@ -902,6 +903,62 @@ serviceNative, onExecApprovalDecision = () => undefined) {
|
|
|
902
903
|
throw new AgentArchiveRefused("archived", `Agent ${agentId} is archived; unarchive it to work with it`);
|
|
903
904
|
throw new Error("Agent is outside this Local project");
|
|
904
905
|
}
|
|
906
|
+
/**
|
|
907
|
+
* Run one sender-authenticated command on a child's question owner. Which
|
|
908
|
+
* Agent the item waits on is decided by the child's own store; this door
|
|
909
|
+
* only states who is calling.
|
|
910
|
+
*/
|
|
911
|
+
async function callQuestionAsSender(target, senderAgentId, senderSessionId, command, commandInput, output, signal) {
|
|
912
|
+
ensureRunning();
|
|
913
|
+
signal.throwIfAborted();
|
|
914
|
+
const databasePath = (await targets(signal, "all")).get(target.agentId);
|
|
915
|
+
if (databasePath === undefined)
|
|
916
|
+
return outsideOrArchived(target.agentId, signal);
|
|
917
|
+
const { owner, release } = await admittedOwner(target.agentId, signal);
|
|
918
|
+
try {
|
|
919
|
+
return await admitted(owner, async () => Schema.decodeUnknownSync(output)(await owner
|
|
920
|
+
.getSession(target.sessionId)
|
|
921
|
+
.extension("botanical-session-question")
|
|
922
|
+
.call(command, commandInput, {
|
|
923
|
+
agentId: senderAgentId,
|
|
924
|
+
sessionId: senderSessionId,
|
|
925
|
+
})));
|
|
926
|
+
}
|
|
927
|
+
finally {
|
|
928
|
+
release();
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
async function answerAsSender(input, senderAgentId, senderSessionId, signal) {
|
|
932
|
+
const decoded = await callQuestionAsSender(input, senderAgentId, senderSessionId, "answerAgent", {
|
|
933
|
+
askId: input.askId,
|
|
934
|
+
requestId: input.requestId,
|
|
935
|
+
answers: input.answers,
|
|
936
|
+
}, questionContract.commands.answerAgent.output, signal);
|
|
937
|
+
const { result } = decoded;
|
|
938
|
+
if (result.result === "accepted")
|
|
939
|
+
return result.commandId === undefined
|
|
940
|
+
? { status: "answered", via: result.via }
|
|
941
|
+
: {
|
|
942
|
+
status: "answered",
|
|
943
|
+
via: result.via,
|
|
944
|
+
commandId: result.commandId,
|
|
945
|
+
};
|
|
946
|
+
if (result.result === "closed")
|
|
947
|
+
return { status: "closed", reason: result.status };
|
|
948
|
+
if (result.result === "refused")
|
|
949
|
+
return { status: "refused", reason: result.reason };
|
|
950
|
+
return { status: "not_found" };
|
|
951
|
+
}
|
|
952
|
+
async function escalateAsSender(input, senderAgentId, senderSessionId, signal) {
|
|
953
|
+
const decoded = await callQuestionAsSender(input, senderAgentId, senderSessionId, "escalateAgent", { askId: input.itemId }, questionContract.commands.escalateAgent.output, signal);
|
|
954
|
+
if (decoded.result === "escalated")
|
|
955
|
+
return { status: "escalated", to: decoded.to };
|
|
956
|
+
if (decoded.result === "closed")
|
|
957
|
+
return { status: "closed", reason: decoded.status };
|
|
958
|
+
if (decoded.result === "refused")
|
|
959
|
+
return { status: "refused", reason: decoded.reason };
|
|
960
|
+
return { status: "not_found" };
|
|
961
|
+
}
|
|
905
962
|
/**
|
|
906
963
|
* The first command still queued or running on any of an Agent's Sessions,
|
|
907
964
|
* so an archive can name it rather than cancel it.
|
|
@@ -978,6 +1035,8 @@ serviceNative, onExecApprovalDecision = () => undefined) {
|
|
|
978
1035
|
}
|
|
979
1036
|
return {
|
|
980
1037
|
owner: admittedOwner,
|
|
1038
|
+
answer: answerAsSender,
|
|
1039
|
+
escalate: escalateAsSender,
|
|
981
1040
|
archive: (request, signal) => setArchived(request, true, signal),
|
|
982
1041
|
unarchive: (request, signal) => setArchived(request, false, signal),
|
|
983
1042
|
list: async (signal, options) => {
|
|
@@ -466,7 +466,13 @@ export function createPrivateLocalServiceManager(options = {}) {
|
|
|
466
466
|
// stopped it decides when it returns.
|
|
467
467
|
const ready = await status();
|
|
468
468
|
if (ready === undefined)
|
|
469
|
-
return {
|
|
469
|
+
return {
|
|
470
|
+
kind: "unavailable",
|
|
471
|
+
// The discovery owner's process-lifetime lease distinguishes an
|
|
472
|
+
// overloaded listener from a stopped service without guessing
|
|
473
|
+
// from the failed HTTP probe or an error message.
|
|
474
|
+
alive: await serviceOwnerIsLive(selectedDirectory),
|
|
475
|
+
};
|
|
470
476
|
accept(ready);
|
|
471
477
|
const again = await postSelection("select", {
|
|
472
478
|
invocationRoot: input.invocationRoot,
|
|
@@ -29,24 +29,29 @@ export declare class LocalStoreSchemaError extends Error {
|
|
|
29
29
|
readonly name = "LocalStoreSchemaError";
|
|
30
30
|
constructor(databasePath: string, options?: ErrorOptions);
|
|
31
31
|
}
|
|
32
|
+
export type PrivateLocalAgentProfile = ReturnType<typeof openAgentProfile>;
|
|
32
33
|
/**
|
|
33
34
|
* One Agent store's chosen display name, default model, whether it is
|
|
34
35
|
* archived and the Agent that created it (absent when a human made it), read
|
|
35
|
-
* without opening a host.
|
|
36
|
+
* without opening a host. Directory listings and the sub-agents footer read
|
|
37
|
+
* every store's profile on each call; an unchanged store file answers from
|
|
38
|
+
* memory instead of reopening SQLite (each Bun open/close also leaks native
|
|
39
|
+
* memory).
|
|
36
40
|
*/
|
|
37
|
-
export declare function readPrivateLocalAgentProfile(path: string):
|
|
41
|
+
export declare function readPrivateLocalAgentProfile(path: string): PrivateLocalAgentProfile;
|
|
42
|
+
declare function openAgentProfile(path: string): Readonly<{
|
|
38
43
|
name: string | undefined;
|
|
39
44
|
createdBy: string | null;
|
|
40
45
|
archived: boolean;
|
|
41
46
|
mode: "read-only" | "workspace" | "full-access";
|
|
42
|
-
writableFolders: string[];
|
|
47
|
+
writableFolders: readonly string[];
|
|
43
48
|
folder: string;
|
|
44
49
|
model: {
|
|
45
50
|
readonly providerId: string;
|
|
46
51
|
readonly modelId: string;
|
|
47
52
|
readonly reasoning?: "high" | "low" | "max" | "medium" | "minimal" | "xhigh" | undefined;
|
|
48
53
|
} | null;
|
|
49
|
-
}
|
|
54
|
+
}>;
|
|
50
55
|
export declare function readPrivateLocalSessionSummaries(path: string): Promise<readonly LocalSummary[]>;
|
|
51
56
|
/**
|
|
52
57
|
* Discover existing folder sessions without opening or reconciling a host.
|
|
@@ -71,3 +76,4 @@ export declare function readPrivateLocalSessionDiscovery(invocationRoot: string,
|
|
|
71
76
|
}>;
|
|
72
77
|
/** Project the service-owned discovery into choices that resume through it. */
|
|
73
78
|
export declare function projectPrivateLocalSessionDiscovery(discovered: Awaited<ReturnType<typeof readPrivateLocalSessionDiscovery>>, connect: PrivateLocalServiceManager["connect"]): PrivateLocalSessionDiscovery;
|
|
79
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { statSync } from "node:fs";
|
|
1
2
|
import { readdir, realpath, stat } from "node:fs/promises";
|
|
2
3
|
import { basename, dirname, join, resolve } from "node:path";
|
|
3
4
|
import * as Effect from "effect/Effect";
|
|
@@ -151,12 +152,44 @@ export class LocalStoreSchemaError extends Error {
|
|
|
151
152
|
this.databasePath = databasePath;
|
|
152
153
|
}
|
|
153
154
|
}
|
|
155
|
+
/** Profiles held at once; directory listings touch every store each call. */
|
|
156
|
+
const cachedProfiles = 1_024;
|
|
157
|
+
const profiles = new Map();
|
|
158
|
+
/** Every committed write moves the store file (or its WAL); none rewrites it in place unseen. */
|
|
159
|
+
function storeVersion(path) {
|
|
160
|
+
const version = (file) => {
|
|
161
|
+
const metadata = statSync(file, { bigint: true, throwIfNoEntry: false });
|
|
162
|
+
return metadata === undefined
|
|
163
|
+
? "-"
|
|
164
|
+
: `${String(metadata.dev)}:${String(metadata.ino)}:${String(metadata.size)}:${String(metadata.mtimeNs)}:${String(metadata.ctimeNs)}`;
|
|
165
|
+
};
|
|
166
|
+
return `${version(path)}/${version(`${path}-wal`)}`;
|
|
167
|
+
}
|
|
154
168
|
/**
|
|
155
169
|
* One Agent store's chosen display name, default model, whether it is
|
|
156
170
|
* archived and the Agent that created it (absent when a human made it), read
|
|
157
|
-
* without opening a host.
|
|
171
|
+
* without opening a host. Directory listings and the sub-agents footer read
|
|
172
|
+
* every store's profile on each call; an unchanged store file answers from
|
|
173
|
+
* memory instead of reopening SQLite (each Bun open/close also leaks native
|
|
174
|
+
* memory).
|
|
158
175
|
*/
|
|
159
176
|
export function readPrivateLocalAgentProfile(path) {
|
|
177
|
+
const version = storeVersion(path);
|
|
178
|
+
const cached = profiles.get(path);
|
|
179
|
+
if (cached?.version === version)
|
|
180
|
+
return cached.profile;
|
|
181
|
+
const profile = openAgentProfile(path);
|
|
182
|
+
// The version is taken before the read, so a write racing it misses next time.
|
|
183
|
+
profiles.delete(path);
|
|
184
|
+
profiles.set(path, { version, profile });
|
|
185
|
+
if (profiles.size > cachedProfiles) {
|
|
186
|
+
const oldest = profiles.keys().next().value;
|
|
187
|
+
if (oldest !== undefined)
|
|
188
|
+
profiles.delete(oldest);
|
|
189
|
+
}
|
|
190
|
+
return profile;
|
|
191
|
+
}
|
|
192
|
+
function openAgentProfile(path) {
|
|
160
193
|
const database = openPrivateReadOnlySqliteDatabase(path);
|
|
161
194
|
try {
|
|
162
195
|
const columns = database
|
|
@@ -184,15 +217,15 @@ export function readPrivateLocalAgentProfile(path) {
|
|
|
184
217
|
folder: identity?.folder,
|
|
185
218
|
model: readAgentDefaultModelJson(database),
|
|
186
219
|
});
|
|
187
|
-
return {
|
|
220
|
+
return Object.freeze({
|
|
188
221
|
name: stored.name ?? undefined,
|
|
189
222
|
createdBy: stored.createdBy,
|
|
190
223
|
archived: stored.archived === 1,
|
|
191
224
|
mode: stored.mode,
|
|
192
|
-
writableFolders: stored.writableFolders,
|
|
225
|
+
writableFolders: Object.freeze(stored.writableFolders),
|
|
193
226
|
folder: stored.folder,
|
|
194
227
|
model: parseModelPreferenceJson(stored.model),
|
|
195
|
-
};
|
|
228
|
+
});
|
|
196
229
|
}
|
|
197
230
|
finally {
|
|
198
231
|
database.close();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
2
|
-
import type
|
|
2
|
+
import { type ProviderRejection } from "@fungi.computer/mule";
|
|
3
3
|
/** Evidence owned by one Local request, never inferred from assistant prose. */
|
|
4
4
|
export type ModelFailureInput = Readonly<{
|
|
5
5
|
refusal?: Readonly<{
|
|
@@ -1,24 +1,44 @@
|
|
|
1
1
|
import { isContextOverflow } from "@earendil-works/pi-ai/utils/overflow";
|
|
2
|
+
import { isRetryableProviderRejection, } from "@fungi.computer/mule";
|
|
2
3
|
/** Local retries only a typed transient, never cancellation or a turn refusal. */
|
|
3
4
|
export function modelFailureRetryable(failure) {
|
|
4
5
|
return (failure.refusal === undefined &&
|
|
5
6
|
failure.upstream?.stopReason !== "aborted" &&
|
|
6
|
-
failure.rejection
|
|
7
|
+
isRetryableProviderRejection(failure.rejection));
|
|
7
8
|
}
|
|
8
9
|
/** The one owned wording for a failed Local model request. */
|
|
9
10
|
export function modelFailureMessage(provider, failure) {
|
|
11
|
+
const name = provider === "anthropic"
|
|
12
|
+
? "Anthropic"
|
|
13
|
+
: provider === "openai"
|
|
14
|
+
? "OpenAI"
|
|
15
|
+
: provider;
|
|
10
16
|
if (failure.refusal !== undefined)
|
|
11
17
|
return `${failure.refusal.category}: ${failure.refusal.message}`;
|
|
12
18
|
// Typed subscription evidence wins over all SDK/provider wording.
|
|
13
|
-
if (failure.rejection?.code === "usage-limit-reached")
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
if (failure.rejection?.code === "usage-limit-reached") {
|
|
20
|
+
const subscription = provider === "anthropic"
|
|
21
|
+
? " on your Claude subscription"
|
|
22
|
+
: provider === "openai"
|
|
23
|
+
? " on your ChatGPT subscription"
|
|
24
|
+
: "";
|
|
25
|
+
const resetAt = failure.rejection.resetAt;
|
|
26
|
+
const reset = resetAt === undefined
|
|
27
|
+
? ""
|
|
28
|
+
: `; resets at ${new Intl.DateTimeFormat(undefined, { hour: "2-digit", minute: "2-digit", hourCycle: "h23" }).format(resetAt)}`;
|
|
29
|
+
return `${name} usage limit reached${subscription}${reset}.`;
|
|
30
|
+
}
|
|
31
|
+
if (failure.rejection?.code === "rate-limit")
|
|
32
|
+
return `${name} rate limit reached; try again shortly.`;
|
|
33
|
+
if (failure.rejection?.code === "overloaded")
|
|
34
|
+
return `${name} is overloaded; try again shortly.`;
|
|
35
|
+
if (failure.rejection?.code === "provider_unavailable")
|
|
36
|
+
return `${name} is unavailable; try again shortly.`;
|
|
17
37
|
if (failure.upstream !== undefined) {
|
|
18
38
|
if (isContextOverflow(failure.upstream))
|
|
19
|
-
return `${
|
|
39
|
+
return `${name} request exceeds the context window; compact the Session or choose another model.`;
|
|
20
40
|
}
|
|
21
41
|
if (failure.rejection?.code === "provider_rejected")
|
|
22
|
-
return `${
|
|
23
|
-
return `${
|
|
42
|
+
return `${name} rejected the request (HTTP ${String(failure.rejection.status)}); check your sign-in or choose another model.`;
|
|
43
|
+
return `${name} model request failed; try again.`;
|
|
24
44
|
}
|
|
@@ -18,13 +18,19 @@ export type PrivateBunSqliteDatabase = {
|
|
|
18
18
|
};
|
|
19
19
|
/** The actual Node connection or Local's explicit native Bun adapter. */
|
|
20
20
|
export type PrivateSqliteDatabase = DatabaseSync | PrivateBunSqliteDatabase;
|
|
21
|
+
/**
|
|
22
|
+
* How long a store's writer waits out a reader's shared lock before its
|
|
23
|
+
* commit fails. Status reads and the Board read a live store; a reader holds
|
|
24
|
+
* its lock for one statement, so this bounds a rare wait, never a hang.
|
|
25
|
+
*/
|
|
26
|
+
export declare const storeWriteBusyTimeoutMs = 2000;
|
|
21
27
|
/**
|
|
22
28
|
* A listing owns this database until its existing finally close. Bun's
|
|
23
29
|
* node:sqlite prepare/close leaves native statements alive until GC. Native
|
|
24
30
|
* close(true) on the native Bun driver explicitly finalizes every statement
|
|
25
31
|
* before releasing the connection, including when a read or decoding fails.
|
|
26
32
|
*/
|
|
27
|
-
export declare function openPrivateReadOnlySqliteDatabase(path: string): PrivateSqliteDatabase;
|
|
33
|
+
export declare function openPrivateReadOnlySqliteDatabase(path: string, timeout?: number): PrivateSqliteDatabase;
|
|
28
34
|
/** Writable connections own their statements through deterministic close. */
|
|
29
35
|
export declare function openPrivateWritableSqliteDatabase(path: string, timeout: number): PrivateSqliteDatabase;
|
|
30
36
|
export type PrivateSqliteFailureCode = "busy" | "locked" | "corrupt" | "not_a_database" | "other";
|
|
@@ -7,14 +7,26 @@ const decodeSqliteRow = Schema.decodeUnknownSync(sqliteRowSchema);
|
|
|
7
7
|
const bunSqlite = Object.hasOwn(process.versions, "bun")
|
|
8
8
|
? await import("bun:sqlite")
|
|
9
9
|
: undefined;
|
|
10
|
+
/**
|
|
11
|
+
* How long a reader waits out a live runtime's commit. Stores use a rollback
|
|
12
|
+
* journal, so a commit briefly locks readers out; a reader that gives up at
|
|
13
|
+
* once would read a busy store as an unreadable one.
|
|
14
|
+
*/
|
|
15
|
+
const readBusyTimeoutMs = 250;
|
|
16
|
+
/**
|
|
17
|
+
* How long a store's writer waits out a reader's shared lock before its
|
|
18
|
+
* commit fails. Status reads and the Board read a live store; a reader holds
|
|
19
|
+
* its lock for one statement, so this bounds a rare wait, never a hang.
|
|
20
|
+
*/
|
|
21
|
+
export const storeWriteBusyTimeoutMs = 2_000;
|
|
10
22
|
/**
|
|
11
23
|
* A listing owns this database until its existing finally close. Bun's
|
|
12
24
|
* node:sqlite prepare/close leaves native statements alive until GC. Native
|
|
13
25
|
* close(true) on the native Bun driver explicitly finalizes every statement
|
|
14
26
|
* before releasing the connection, including when a read or decoding fails.
|
|
15
27
|
*/
|
|
16
|
-
export function openPrivateReadOnlySqliteDatabase(path) {
|
|
17
|
-
return openPrivateSqliteDatabase(path, true,
|
|
28
|
+
export function openPrivateReadOnlySqliteDatabase(path, timeout = readBusyTimeoutMs) {
|
|
29
|
+
return openPrivateSqliteDatabase(path, true, timeout);
|
|
18
30
|
}
|
|
19
31
|
/** Writable connections own their statements through deterministic close. */
|
|
20
32
|
export function openPrivateWritableSqliteDatabase(path, timeout) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fungi.computer/truffle",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Truffle: Fungi's local Agent runtime, bundled into the fungi command",
|
|
6
6
|
"type": "module",
|
|
@@ -57,6 +57,14 @@
|
|
|
57
57
|
"./rules": {
|
|
58
58
|
"types": "./dist/private-local-exec-rules.d.ts",
|
|
59
59
|
"import": "./dist/private-local-exec-rules.js"
|
|
60
|
+
},
|
|
61
|
+
"./board-agents": {
|
|
62
|
+
"types": "./dist/local-board-agents.d.ts",
|
|
63
|
+
"import": "./dist/local-board-agents.js"
|
|
64
|
+
},
|
|
65
|
+
"./board-shipping": {
|
|
66
|
+
"types": "./dist/local-board-shipping.d.ts",
|
|
67
|
+
"import": "./dist/local-board-shipping.js"
|
|
60
68
|
}
|
|
61
69
|
},
|
|
62
70
|
"files": [
|
|
@@ -69,26 +77,26 @@
|
|
|
69
77
|
"@cf-wasm/photon": "0.4.0",
|
|
70
78
|
"@earendil-works/pi-ai": "1.3.0",
|
|
71
79
|
"@effect/platform-node": "4.0.2",
|
|
72
|
-
"@fungi.computer/agar": "0.
|
|
80
|
+
"@fungi.computer/agar": "0.5.0",
|
|
73
81
|
"@fungi.computer/approvals": "0.2.0",
|
|
74
|
-
"@fungi.computer/bird-dog": "0.
|
|
82
|
+
"@fungi.computer/bird-dog": "0.3.0",
|
|
75
83
|
"@fungi.computer/cairn": "0.1.0",
|
|
76
84
|
"@fungi.computer/capnweb": "0.12.0",
|
|
77
85
|
"@fungi.computer/carrier": "0.2.0",
|
|
78
86
|
"@fungi.computer/cordyceps": "0.4.0",
|
|
79
87
|
"@fungi.computer/gills": "0.2.0",
|
|
80
|
-
"@fungi.computer/graft": "0.1.
|
|
81
|
-
"@fungi.computer/knapsack": "0.
|
|
82
|
-
"@fungi.computer/lantern": "0.3.
|
|
83
|
-
"@fungi.computer/mycelium": "0.2.
|
|
84
|
-
"@fungi.computer/nacre": "0.0
|
|
88
|
+
"@fungi.computer/graft": "0.1.4",
|
|
89
|
+
"@fungi.computer/knapsack": "0.4.0",
|
|
90
|
+
"@fungi.computer/lantern": "0.3.1",
|
|
91
|
+
"@fungi.computer/mycelium": "0.2.3",
|
|
92
|
+
"@fungi.computer/nacre": "0.1.0",
|
|
85
93
|
"@fungi.computer/seam": "0.2.0",
|
|
86
|
-
"@fungi.computer/shiitake": "0.
|
|
87
|
-
"@fungi.computer/shiitake-extensions": "0.
|
|
94
|
+
"@fungi.computer/shiitake": "0.6.0",
|
|
95
|
+
"@fungi.computer/shiitake-extensions": "0.4.0",
|
|
88
96
|
"@fungi.computer/veil": "0.2.1",
|
|
89
97
|
"@fungi.computer/watchdog": "0.1.0",
|
|
90
|
-
"@fungi.computer/whistle": "0.
|
|
91
|
-
"@fungi.computer/zookeeper": "0.0.
|
|
98
|
+
"@fungi.computer/whistle": "0.3.0",
|
|
99
|
+
"@fungi.computer/zookeeper": "0.0.5",
|
|
92
100
|
"@jellybrick/dbus-next": "0.11.4",
|
|
93
101
|
"@modelcontextprotocol/client": "2.0.0",
|
|
94
102
|
"@napi-rs/keyring": "2.1.2",
|
|
@@ -109,7 +117,7 @@
|
|
|
109
117
|
},
|
|
110
118
|
"devDependencies": {
|
|
111
119
|
"@cloudflare/codemode": "0.5.1",
|
|
112
|
-
"@fungi.computer/mule": "0.2.
|
|
120
|
+
"@fungi.computer/mule": "0.2.1",
|
|
113
121
|
"@modelcontextprotocol/server": "2.0.0",
|
|
114
122
|
"@types/node": "24.13.3",
|
|
115
123
|
"@types/proper-lockfile": "4.1.4",
|
|
@@ -156,6 +164,7 @@
|
|
|
156
164
|
"build": "if [ ! -f src/private-local-native-digests.js ]; then pnpm run build:native; fi && node scripts/generate-native-digests.mjs --verify && pnpm run clean && tsc -p tsconfig.build.json && cp src/private-local-native-digests.js dist/private-local-native-digests.js && node scripts/copy-seatbelt.mjs && esbuild src/internal/private-workerd-sandbox-worker.mjs --outfile=dist/internal/private-workerd-sandbox-worker.mjs --bundle --format=esm --platform=neutral --conditions=workerd,browser --target=es2024 --external:cloudflare:workers --metafile=dist/internal/sandbox-metafile.json --log-level=warning && esbuild src/internal/local-image-fit-worker.mjs --outfile=dist/internal/local-image-fit-worker.mjs --bundle --format=esm --platform=node --target=es2024 --metafile=dist/internal/image-fit-metafile.json --log-level=warning",
|
|
157
165
|
"clean": "node --input-type=module --eval \"import { rm } from 'node:fs/promises'; await rm('dist', { recursive: true, force: true });\"",
|
|
158
166
|
"test": "pnpm run test:node && pnpm run test:merge && pnpm run test:stop-all",
|
|
167
|
+
"soak:memory": "bun scripts/service-memory-soak.mjs",
|
|
159
168
|
"test:stop-all": "bun test ./test/private-local-stop-all.bun.test.ts",
|
|
160
169
|
"test:full": "pnpm run test && pnpm run test:bun",
|
|
161
170
|
"test:node": "../../node_modules/.bin/vitest run",
|