@fungi.computer/agar 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +766 -2
- package/dist/agent-message-meta.d.ts +74 -0
- package/dist/agent-message-meta.js +63 -0
- package/dist/agents.d.ts +170 -0
- package/dist/agents.js +218 -0
- package/dist/app-build-contract.d.ts +43 -0
- package/dist/app-build-contract.js +24 -0
- package/dist/apps.d.ts +66 -0
- package/dist/apps.js +47 -0
- package/dist/backend-declaration.d.ts +6 -0
- package/dist/backend-declaration.js +65 -0
- package/dist/backend-definition.d.ts +88 -0
- package/dist/backend-definition.js +158 -0
- package/dist/backend-refusal.d.ts +10 -0
- package/dist/backend-refusal.js +10 -0
- package/dist/backend.d.ts +30 -0
- package/dist/backend.js +28 -0
- package/dist/capabilities.d.ts +30 -0
- package/dist/capabilities.js +50 -0
- package/dist/channels.d.ts +142 -0
- package/dist/channels.js +97 -0
- package/dist/commands.d.ts +33 -0
- package/dist/commands.js +46 -0
- package/dist/computer-contracts.d.ts +73 -0
- package/dist/computer-contracts.js +57 -0
- package/dist/computer.d.ts +294 -0
- package/dist/computer.js +319 -0
- package/dist/connect.d.ts +11 -0
- package/dist/connect.js +211 -0
- package/dist/errors.d.ts +34 -0
- package/dist/errors.js +106 -0
- package/dist/failure.d.ts +2 -0
- package/dist/failure.js +9 -0
- package/dist/files.d.ts +25 -0
- package/dist/files.js +84 -0
- package/dist/game-servers.d.ts +530 -0
- package/dist/game-servers.js +244 -0
- package/dist/gills.d.ts +43 -0
- package/dist/gills.js +174 -0
- package/dist/git-commit.d.ts +143 -0
- package/dist/git-commit.js +251 -0
- package/dist/git-rpc.d.ts +310 -0
- package/dist/git-rpc.js +166 -0
- package/dist/git-steps.d.ts +579 -0
- package/dist/git-steps.js +804 -0
- package/dist/git-wire.d.ts +33 -0
- package/dist/git-wire.js +240 -0
- package/dist/git.d.ts +322 -0
- package/dist/git.js +98 -0
- package/dist/host.d.ts +97 -0
- package/dist/host.js +732 -0
- package/dist/inbox.d.ts +99 -0
- package/dist/inbox.js +184 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +15 -0
- package/dist/inference.d.ts +17 -0
- package/dist/inference.js +115 -0
- package/dist/internal/app-error.d.ts +8 -0
- package/dist/internal/app-error.js +36 -0
- package/dist/internal/app-session.d.ts +8 -0
- package/dist/internal/app-session.js +551 -0
- package/dist/internal/back-inputs.d.ts +22 -0
- package/dist/internal/back-inputs.js +93 -0
- package/dist/internal/browser-bridge.d.ts +30 -0
- package/dist/internal/browser-bridge.js +203 -0
- package/dist/internal/capabilities.d.ts +13 -0
- package/dist/internal/capabilities.js +138 -0
- package/dist/internal/commands.d.ts +9 -0
- package/dist/internal/commands.js +257 -0
- package/dist/internal/disconnect-host.d.ts +7 -0
- package/dist/internal/disconnect-host.js +19 -0
- package/dist/internal/git-edit-tree.d.ts +6 -0
- package/dist/internal/git-edit-tree.js +46 -0
- package/dist/internal/memory-fs.d.ts +39 -0
- package/dist/internal/memory-fs.js +154 -0
- package/dist/internal/protocol.d.ts +116 -0
- package/dist/internal/protocol.js +6 -0
- package/dist/internal/query-feed.d.ts +23 -0
- package/dist/internal/query-feed.js +111 -0
- package/dist/internal/result.d.ts +22 -0
- package/dist/internal/result.js +61 -0
- package/dist/internal/rpc-contract.d.ts +24 -0
- package/dist/internal/rpc-contract.js +78 -0
- package/dist/internal/schemas.d.ts +307 -0
- package/dist/internal/schemas.js +524 -0
- package/dist/internal/store.d.ts +8 -0
- package/dist/internal/store.js +30 -0
- package/dist/internal/terminal-gate.d.ts +17 -0
- package/dist/internal/terminal-gate.js +94 -0
- package/dist/lifecycle.d.ts +44 -0
- package/dist/lifecycle.js +1 -0
- package/dist/marketplace.d.ts +159 -0
- package/dist/marketplace.js +102 -0
- package/dist/media-json.d.ts +181 -0
- package/dist/media-json.js +204 -0
- package/dist/media-library.d.ts +11 -0
- package/dist/media-library.js +15 -0
- package/dist/media-request-id.d.ts +7 -0
- package/dist/media-request-id.js +16 -0
- package/dist/media.d.ts +354 -0
- package/dist/media.js +654 -0
- package/dist/method-refusal.d.ts +64 -0
- package/dist/method-refusal.js +48 -0
- package/dist/pending.d.ts +10 -0
- package/dist/pending.js +10 -0
- package/dist/query.d.ts +76 -0
- package/dist/query.js +195 -0
- package/dist/react-mount.d.ts +23 -0
- package/dist/react-mount.js +108 -0
- package/dist/react.d.ts +41 -0
- package/dist/react.js +111 -0
- package/dist/read-copy.d.ts +103 -0
- package/dist/read-copy.js +195 -0
- package/dist/roles/files.d.ts +295 -0
- package/dist/roles/files.js +184 -0
- package/dist/root.d.ts +21 -0
- package/dist/root.js +1 -0
- package/dist/rpc.d.ts +1 -0
- package/dist/rpc.js +1 -0
- package/dist/status.d.ts +17 -0
- package/dist/status.js +50 -0
- package/dist/storage-wire.d.ts +167 -0
- package/dist/storage-wire.js +115 -0
- package/dist/storage.d.ts +72 -0
- package/dist/storage.js +143 -0
- package/dist/store.d.ts +11 -0
- package/dist/store.js +1 -0
- package/dist/test-kit/git.d.ts +31 -0
- package/dist/test-kit/git.js +174 -0
- package/dist/ui.d.ts +169 -0
- package/dist/ui.js +10 -0
- package/dist/window.d.ts +41 -0
- package/dist/window.js +15 -0
- package/dist/world.d.ts +16 -0
- package/dist/world.js +17 -0
- package/docs/api/README.md +28 -0
- package/docs/api/app-build-contract.md +113 -0
- package/docs/api/backend-declaration.md +62 -0
- package/docs/api/backend-definition.md +215 -0
- package/docs/api/backend.md +269 -0
- package/docs/api/errors.md +169 -0
- package/docs/api/files.md +91 -0
- package/docs/api/gills.md +164 -0
- package/docs/api/git-commit.md +279 -0
- package/docs/api/git-rpc.md +243 -0
- package/docs/api/git-steps.md +1010 -0
- package/docs/api/git-wire.md +197 -0
- package/docs/api/git.md +579 -0
- package/docs/api/index.md +2880 -0
- package/docs/api/media-json.md +507 -0
- package/docs/api/media-request-id.md +32 -0
- package/docs/api/modules.md +32 -0
- package/docs/api/query.md +253 -0
- package/docs/api/react.md +216 -0
- package/docs/api/read-copy.md +204 -0
- package/docs/api/rpc.md +128 -0
- package/docs/api/storage.md +620 -0
- package/package.json +197 -3
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
/** The one versioned reply owner of a channel conversation. */
|
|
3
|
+
export declare const handoffSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
4
|
+
state: z.ZodLiteral<"agent">;
|
|
5
|
+
version: z.ZodNumber;
|
|
6
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
7
|
+
state: z.ZodLiteral<"requested">;
|
|
8
|
+
version: z.ZodNumber;
|
|
9
|
+
reason: z.ZodString;
|
|
10
|
+
at: z.ZodNumber;
|
|
11
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
12
|
+
state: z.ZodLiteral<"person">;
|
|
13
|
+
version: z.ZodNumber;
|
|
14
|
+
memberId: z.ZodString;
|
|
15
|
+
memberName: z.ZodString;
|
|
16
|
+
since: z.ZodNumber;
|
|
17
|
+
}, z.core.$strict>], "state">;
|
|
18
|
+
export type Handoff = z.output<typeof handoffSchema>;
|
|
19
|
+
/** An addressed website binding; no visitor credentials or site keys. */
|
|
20
|
+
export declare const appWebsiteSchema: z.ZodObject<{
|
|
21
|
+
bindingId: z.ZodString;
|
|
22
|
+
agentId: z.ZodString;
|
|
23
|
+
origins: z.ZodArray<z.ZodString>;
|
|
24
|
+
lifecycle: z.ZodEnum<{
|
|
25
|
+
suspended: "suspended";
|
|
26
|
+
active: "active";
|
|
27
|
+
}>;
|
|
28
|
+
}, z.core.$strict>;
|
|
29
|
+
/** Owner-projected takeover state for one website conversation. */
|
|
30
|
+
export declare const appWebsiteConversationSchema: z.ZodObject<{
|
|
31
|
+
sessionId: z.ZodString;
|
|
32
|
+
label: z.ZodString;
|
|
33
|
+
lastEventAt: z.ZodNumber;
|
|
34
|
+
needsYou: z.ZodNullable<z.ZodObject<{
|
|
35
|
+
at: z.ZodNumber;
|
|
36
|
+
reason: z.ZodString;
|
|
37
|
+
}, z.core.$strict>>;
|
|
38
|
+
held: z.ZodBoolean;
|
|
39
|
+
heldByYou: z.ZodBoolean;
|
|
40
|
+
heldByName: z.ZodNullable<z.ZodString>;
|
|
41
|
+
holdVersion: z.ZodNumber;
|
|
42
|
+
}, z.core.$strict>;
|
|
43
|
+
/** The binding is selected by its owner, never by an Agent identity. */
|
|
44
|
+
export declare const appWebsiteSelectionSchema: z.ZodObject<{
|
|
45
|
+
bindingId: z.ZodString;
|
|
46
|
+
}, z.core.$strict>;
|
|
47
|
+
/** An exact conversation under that binding. */
|
|
48
|
+
export declare const appWebsiteConversationSelectionSchema: z.ZodObject<{
|
|
49
|
+
bindingId: z.ZodString;
|
|
50
|
+
sessionId: z.ZodString;
|
|
51
|
+
}, z.core.$strict>;
|
|
52
|
+
/** An idempotent member reply through the takeover owner, not Session.prompt. */
|
|
53
|
+
export declare const appWebsiteReplySchema: z.ZodObject<{
|
|
54
|
+
bindingId: z.ZodString;
|
|
55
|
+
sessionId: z.ZodString;
|
|
56
|
+
requestId: z.ZodString;
|
|
57
|
+
text: z.ZodString;
|
|
58
|
+
}, z.core.$strict>;
|
|
59
|
+
/** Take over or hand back only the handoff version the member observed. */
|
|
60
|
+
export declare const handoffChangeSchema: z.ZodObject<{
|
|
61
|
+
expectedVersion: z.ZodNumber;
|
|
62
|
+
confirm: z.ZodBoolean;
|
|
63
|
+
}, z.core.$strict>;
|
|
64
|
+
export declare const appWebsiteHoldSchema: z.ZodObject<{
|
|
65
|
+
bindingId: z.ZodString;
|
|
66
|
+
sessionId: z.ZodString;
|
|
67
|
+
expectedVersion: z.ZodNumber;
|
|
68
|
+
confirm: z.ZodBoolean;
|
|
69
|
+
}, z.core.$strict>;
|
|
70
|
+
/** Dismiss only an Agent's unanswered request for a person. */
|
|
71
|
+
export declare const appWebsiteDismissSchema: z.ZodObject<{
|
|
72
|
+
bindingId: z.ZodString;
|
|
73
|
+
sessionId: z.ZodString;
|
|
74
|
+
expectedVersion: z.ZodNumber;
|
|
75
|
+
}, z.core.$strict>;
|
|
76
|
+
/** The bounded website directory returned by the channel owner. */
|
|
77
|
+
export declare const appWebsitePageSchema: z.ZodObject<{
|
|
78
|
+
websites: z.ZodArray<z.ZodObject<{
|
|
79
|
+
bindingId: z.ZodString;
|
|
80
|
+
agentId: z.ZodString;
|
|
81
|
+
origins: z.ZodArray<z.ZodString>;
|
|
82
|
+
lifecycle: z.ZodEnum<{
|
|
83
|
+
suspended: "suspended";
|
|
84
|
+
active: "active";
|
|
85
|
+
}>;
|
|
86
|
+
}, z.core.$strict>>;
|
|
87
|
+
}, z.core.$strict>;
|
|
88
|
+
/** At most 100 recent conversations projected by the App host. */
|
|
89
|
+
export declare const appWebsiteConversationPageSchema: z.ZodObject<{
|
|
90
|
+
conversations: z.ZodArray<z.ZodObject<{
|
|
91
|
+
sessionId: z.ZodString;
|
|
92
|
+
label: z.ZodString;
|
|
93
|
+
lastEventAt: z.ZodNumber;
|
|
94
|
+
needsYou: z.ZodNullable<z.ZodObject<{
|
|
95
|
+
at: z.ZodNumber;
|
|
96
|
+
reason: z.ZodString;
|
|
97
|
+
}, z.core.$strict>>;
|
|
98
|
+
held: z.ZodBoolean;
|
|
99
|
+
heldByYou: z.ZodBoolean;
|
|
100
|
+
heldByName: z.ZodNullable<z.ZodString>;
|
|
101
|
+
holdVersion: z.ZodNumber;
|
|
102
|
+
}, z.core.$strict>>;
|
|
103
|
+
}, z.core.$strict>;
|
|
104
|
+
export type AppWebsiteConversation = z.output<typeof appWebsiteConversationSchema>;
|
|
105
|
+
/** Read-only channel data admitted to a member's App installation. */
|
|
106
|
+
export type AppChannelsReadHandle = {
|
|
107
|
+
list(): Promise<z.output<typeof appWebsitePageSchema>>;
|
|
108
|
+
conversations(input: z.output<typeof appWebsiteSelectionSchema>): Promise<z.output<typeof appWebsiteConversationPageSchema>>;
|
|
109
|
+
};
|
|
110
|
+
/** Takeover actions keep the authenticated member and live grant on the host. */
|
|
111
|
+
export type AppChannelsManageHandle = {
|
|
112
|
+
hold(input: z.output<typeof appWebsiteHoldSchema>): Promise<AppWebsiteConversation>;
|
|
113
|
+
release(input: z.output<typeof appWebsiteHoldSchema>): Promise<AppWebsiteConversation>;
|
|
114
|
+
dismiss(input: z.output<typeof appWebsiteDismissSchema>): Promise<AppWebsiteConversation>;
|
|
115
|
+
reply(input: z.output<typeof appWebsiteReplySchema>): Promise<Readonly<{
|
|
116
|
+
status: "sent";
|
|
117
|
+
}>>;
|
|
118
|
+
};
|
|
119
|
+
/** Response to a successful member takeover action. */
|
|
120
|
+
export declare const appWebsiteActionResponseSchema: z.ZodObject<{
|
|
121
|
+
conversation: z.ZodObject<{
|
|
122
|
+
sessionId: z.ZodString;
|
|
123
|
+
label: z.ZodString;
|
|
124
|
+
lastEventAt: z.ZodNumber;
|
|
125
|
+
needsYou: z.ZodNullable<z.ZodObject<{
|
|
126
|
+
at: z.ZodNumber;
|
|
127
|
+
reason: z.ZodString;
|
|
128
|
+
}, z.core.$strict>>;
|
|
129
|
+
held: z.ZodBoolean;
|
|
130
|
+
heldByYou: z.ZodBoolean;
|
|
131
|
+
heldByName: z.ZodNullable<z.ZodString>;
|
|
132
|
+
holdVersion: z.ZodNumber;
|
|
133
|
+
}, z.core.$strict>;
|
|
134
|
+
}, z.core.$strict>;
|
|
135
|
+
/** A successful reply is recorded without starting an Agent turn. */
|
|
136
|
+
export declare const appWebsiteReplyResponseSchema: z.ZodObject<{
|
|
137
|
+
status: z.ZodLiteral<"sent">;
|
|
138
|
+
}, z.core.$strict>;
|
|
139
|
+
/** Reading website conversations is never an automatic default-App grant. */
|
|
140
|
+
export declare const channelsRead: import("./capabilities.js").CapabilityContract<AppChannelsReadHandle>;
|
|
141
|
+
/** Member-only takeover; separate consent from read-only channel access. */
|
|
142
|
+
export declare const channelsPersonalManage: import("./capabilities.js").CapabilityContract<AppChannelsManageHandle>;
|
package/dist/channels.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { defineCapability } from "./capabilities.js";
|
|
3
|
+
import { rpcDataSchema, rpcHandleSchema, rpcMethod, } from "./internal/rpc-contract.js";
|
|
4
|
+
const identity = z.string().min(1).max(256);
|
|
5
|
+
const handoffVersion = z.number().int().nonnegative();
|
|
6
|
+
/** The one versioned reply owner of a channel conversation. */
|
|
7
|
+
export const handoffSchema = z.discriminatedUnion("state", [
|
|
8
|
+
z.strictObject({ state: z.literal("agent"), version: handoffVersion }),
|
|
9
|
+
z.strictObject({
|
|
10
|
+
state: z.literal("requested"),
|
|
11
|
+
version: handoffVersion,
|
|
12
|
+
reason: z.string().max(4000),
|
|
13
|
+
at: z.number().int().nonnegative(),
|
|
14
|
+
}),
|
|
15
|
+
z.strictObject({
|
|
16
|
+
state: z.literal("person"),
|
|
17
|
+
version: handoffVersion,
|
|
18
|
+
memberId: identity,
|
|
19
|
+
memberName: z.string().min(1).max(128),
|
|
20
|
+
since: z.number().int().nonnegative(),
|
|
21
|
+
}),
|
|
22
|
+
]);
|
|
23
|
+
/** An addressed website binding; no visitor credentials or site keys. */
|
|
24
|
+
export const appWebsiteSchema = z.strictObject({
|
|
25
|
+
bindingId: identity,
|
|
26
|
+
agentId: identity,
|
|
27
|
+
origins: z.array(z.string().min(1).max(2048)).min(1).max(16),
|
|
28
|
+
lifecycle: z.enum(["active", "suspended"]),
|
|
29
|
+
});
|
|
30
|
+
/** Owner-projected takeover state for one website conversation. */
|
|
31
|
+
export const appWebsiteConversationSchema = z.strictObject({
|
|
32
|
+
sessionId: identity,
|
|
33
|
+
label: z.string().max(4096),
|
|
34
|
+
lastEventAt: z.number().int().nonnegative(),
|
|
35
|
+
needsYou: z
|
|
36
|
+
.strictObject({
|
|
37
|
+
at: z.number().int().nonnegative(),
|
|
38
|
+
reason: z.string().max(4000),
|
|
39
|
+
})
|
|
40
|
+
.nullable(),
|
|
41
|
+
held: z.boolean(),
|
|
42
|
+
heldByYou: z.boolean(),
|
|
43
|
+
heldByName: z.string().min(1).max(128).nullable(),
|
|
44
|
+
holdVersion: z.number().int().nonnegative(),
|
|
45
|
+
});
|
|
46
|
+
/** The binding is selected by its owner, never by an Agent identity. */
|
|
47
|
+
export const appWebsiteSelectionSchema = z.strictObject({
|
|
48
|
+
bindingId: identity,
|
|
49
|
+
});
|
|
50
|
+
/** An exact conversation under that binding. */
|
|
51
|
+
export const appWebsiteConversationSelectionSchema = appWebsiteSelectionSchema.extend({
|
|
52
|
+
sessionId: identity,
|
|
53
|
+
});
|
|
54
|
+
/** An idempotent member reply through the takeover owner, not Session.prompt. */
|
|
55
|
+
export const appWebsiteReplySchema = appWebsiteConversationSelectionSchema.extend({
|
|
56
|
+
requestId: z.string().min(1).max(128),
|
|
57
|
+
text: z.string().trim().min(1).max(4000),
|
|
58
|
+
});
|
|
59
|
+
/** Take over or hand back only the handoff version the member observed. */
|
|
60
|
+
export const handoffChangeSchema = z.strictObject({
|
|
61
|
+
expectedVersion: handoffVersion,
|
|
62
|
+
confirm: z.boolean(),
|
|
63
|
+
});
|
|
64
|
+
export const appWebsiteHoldSchema = appWebsiteConversationSelectionSchema.extend(handoffChangeSchema.shape);
|
|
65
|
+
/** Dismiss only an Agent's unanswered request for a person. */
|
|
66
|
+
export const appWebsiteDismissSchema = appWebsiteConversationSelectionSchema.extend({
|
|
67
|
+
expectedVersion: handoffVersion,
|
|
68
|
+
});
|
|
69
|
+
/** The bounded website directory returned by the channel owner. */
|
|
70
|
+
export const appWebsitePageSchema = z.strictObject({
|
|
71
|
+
websites: z.array(appWebsiteSchema).max(1000),
|
|
72
|
+
});
|
|
73
|
+
/** At most 100 recent conversations projected by the App host. */
|
|
74
|
+
export const appWebsiteConversationPageSchema = z.strictObject({
|
|
75
|
+
conversations: z.array(appWebsiteConversationSchema).max(100),
|
|
76
|
+
});
|
|
77
|
+
const conversationResult = z.strictObject({
|
|
78
|
+
conversation: appWebsiteConversationSchema,
|
|
79
|
+
});
|
|
80
|
+
/** Response to a successful member takeover action. */
|
|
81
|
+
export const appWebsiteActionResponseSchema = conversationResult;
|
|
82
|
+
/** A successful reply is recorded without starting an Agent turn. */
|
|
83
|
+
export const appWebsiteReplyResponseSchema = z.strictObject({
|
|
84
|
+
status: z.literal("sent"),
|
|
85
|
+
});
|
|
86
|
+
/** Reading website conversations is never an automatic default-App grant. */
|
|
87
|
+
export const channelsRead = defineCapability("channels.read", 1, rpcHandleSchema({
|
|
88
|
+
list: rpcMethod(rpcDataSchema(appWebsitePageSchema)),
|
|
89
|
+
conversations: rpcMethod(rpcDataSchema(appWebsiteConversationPageSchema)),
|
|
90
|
+
}));
|
|
91
|
+
/** Member-only takeover; separate consent from read-only channel access. */
|
|
92
|
+
export const channelsPersonalManage = defineCapability("channels.personal.manage", 1, rpcHandleSchema({
|
|
93
|
+
hold: rpcMethod(rpcDataSchema(appWebsiteConversationSchema)),
|
|
94
|
+
release: rpcMethod(rpcDataSchema(appWebsiteConversationSchema)),
|
|
95
|
+
dismiss: rpcMethod(rpcDataSchema(appWebsiteConversationSchema)),
|
|
96
|
+
reply: rpcMethod(rpcDataSchema(appWebsiteReplyResponseSchema)),
|
|
97
|
+
}));
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Disposer } from "./store.js";
|
|
2
|
+
import type { WhistleCommand, WhistleCommandDefinition, WhistleExecutionOrigin, WhistleJsonValue } from "@fungi.computer/whistle";
|
|
3
|
+
/** Semantic command metadata supplied by an App and owned by Whistle. */
|
|
4
|
+
export type AppCommand = WhistleCommandDefinition;
|
|
5
|
+
/** One invocation's semantic input; host correlation IDs are private. */
|
|
6
|
+
export type AppCommandHandler = (invocation: AppCommandInvocation) => Promise<WhistleJsonValue | undefined> | WhistleJsonValue | undefined;
|
|
7
|
+
/** One command invocation's semantic input, passed to its handler. */
|
|
8
|
+
export type AppCommandInvocation = {
|
|
9
|
+
readonly arguments?: WhistleJsonValue;
|
|
10
|
+
readonly origin: WhistleExecutionOrigin;
|
|
11
|
+
readonly signal: AbortSignal;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Registers a command with the authenticated host for this page session.
|
|
15
|
+
* The promise resolves only after the host accepts the registration.
|
|
16
|
+
*/
|
|
17
|
+
export type AppCommands = {
|
|
18
|
+
/** Register one command and its handler with the host; resolves once
|
|
19
|
+
* the host accepts it. Call the returned Disposer to unregister. */
|
|
20
|
+
register(command: AppCommand, handler: AppCommandHandler): Promise<Disposer>;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Register one App's Whistle catalog with its host. An App defines each
|
|
24
|
+
* command once, contributes the same catalog to its own composer runtime for
|
|
25
|
+
* slash commands, and registers it here so the shell projects it into the
|
|
26
|
+
* palette, menus, keys and the agent view. Availability is read once at
|
|
27
|
+
* registration; register again to publish a change.
|
|
28
|
+
*
|
|
29
|
+
* @param commands - The App's host command door, `app.commands`.
|
|
30
|
+
* @param catalog - The App's Whistle commands, handlers included.
|
|
31
|
+
* @returns Release every registration made by this call.
|
|
32
|
+
*/
|
|
33
|
+
export declare function registerCatalog(commands: AppCommands, catalog: readonly WhistleCommand<never>[]): Disposer;
|
package/dist/commands.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { parseJsonValue } from "@fungi.computer/whistle/wire";
|
|
2
|
+
/**
|
|
3
|
+
* Register one App's Whistle catalog with its host. An App defines each
|
|
4
|
+
* command once, contributes the same catalog to its own composer runtime for
|
|
5
|
+
* slash commands, and registers it here so the shell projects it into the
|
|
6
|
+
* palette, menus, keys and the agent view. Availability is read once at
|
|
7
|
+
* registration; register again to publish a change.
|
|
8
|
+
*
|
|
9
|
+
* @param commands - The App's host command door, `app.commands`.
|
|
10
|
+
* @param catalog - The App's Whistle commands, handlers included.
|
|
11
|
+
* @returns Release every registration made by this call.
|
|
12
|
+
*/
|
|
13
|
+
export function registerCatalog(commands, catalog) {
|
|
14
|
+
let released = false;
|
|
15
|
+
const releases = [];
|
|
16
|
+
for (const command of catalog) {
|
|
17
|
+
const { availability, handler, ...metadata } = command;
|
|
18
|
+
const run = handler;
|
|
19
|
+
const definition = availability === undefined
|
|
20
|
+
? metadata
|
|
21
|
+
: { ...metadata, availability: availability() };
|
|
22
|
+
void commands
|
|
23
|
+
.register(definition, async ({ arguments: args, origin, signal }) => {
|
|
24
|
+
const input = args === undefined
|
|
25
|
+
? { origin, signal }
|
|
26
|
+
: { arguments: args, origin, signal };
|
|
27
|
+
const result = await run(input);
|
|
28
|
+
return result === undefined ? undefined : parseJsonValue(result);
|
|
29
|
+
})
|
|
30
|
+
.then((release) => {
|
|
31
|
+
if (released)
|
|
32
|
+
release();
|
|
33
|
+
else
|
|
34
|
+
releases.push(release);
|
|
35
|
+
}, (cause) => {
|
|
36
|
+
console.warn(`App command ${command.id} was not registered`, cause);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return () => {
|
|
40
|
+
if (released)
|
|
41
|
+
return;
|
|
42
|
+
released = true;
|
|
43
|
+
for (const release of releases.splice(0))
|
|
44
|
+
release();
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
/** Public metadata for one host-admitted Workflow Git pass; parsing never grants authority. */
|
|
3
|
+
export declare const workflowGitPassResultSchema: z.ZodObject<{
|
|
4
|
+
passId: z.ZodString;
|
|
5
|
+
remote: z.ZodURL;
|
|
6
|
+
expiresAt: z.ZodNumber;
|
|
7
|
+
bearer: z.ZodExactOptional<z.ZodString>;
|
|
8
|
+
}, z.core.$strict>;
|
|
9
|
+
/** The complete remote stays opaque; the host owns admission, renewal and revocation. */
|
|
10
|
+
export type WorkflowGitPassResult = z.output<typeof workflowGitPassResultSchema>;
|
|
11
|
+
/** Existing attachment budget operation kinds shared by Computer and Media. */
|
|
12
|
+
export declare const connectorOperationBudgetKindSchema: z.ZodEnum<{
|
|
13
|
+
write: "write";
|
|
14
|
+
media: "media";
|
|
15
|
+
exec: "exec";
|
|
16
|
+
}>;
|
|
17
|
+
/** Existing owner budget refusal; it remains a domain result, not a wire envelope. */
|
|
18
|
+
export declare const connectorOperationBudgetRefusalSchema: z.ZodObject<{
|
|
19
|
+
error: z.ZodLiteral<"attachment_budget_exceeded">;
|
|
20
|
+
kind: z.ZodEnum<{
|
|
21
|
+
write: "write";
|
|
22
|
+
media: "media";
|
|
23
|
+
exec: "exec";
|
|
24
|
+
}>;
|
|
25
|
+
retryAfterMs: z.ZodNumber;
|
|
26
|
+
}, z.core.$strict>;
|
|
27
|
+
/** Computer admission refusals returned before native dispatch. */
|
|
28
|
+
export declare const appComputerAdmissionRefusalSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
29
|
+
error: z.ZodEnum<{
|
|
30
|
+
unavailable: "unavailable";
|
|
31
|
+
revoked: "revoked";
|
|
32
|
+
not_granted: "not_granted";
|
|
33
|
+
grantor_lost_authority: "grantor_lost_authority";
|
|
34
|
+
}>;
|
|
35
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
36
|
+
error: z.ZodLiteral<"attachment_budget_exceeded">;
|
|
37
|
+
kind: z.ZodEnum<{
|
|
38
|
+
write: "write";
|
|
39
|
+
media: "media";
|
|
40
|
+
exec: "exec";
|
|
41
|
+
}>;
|
|
42
|
+
retryAfterMs: z.ZodNumber;
|
|
43
|
+
}, z.core.$strict>]>;
|
|
44
|
+
/** Existing Computer broker argument refusals. */
|
|
45
|
+
export declare const appComputerInputRefusalSchema: z.ZodObject<{
|
|
46
|
+
error: z.ZodEnum<{
|
|
47
|
+
invalid: "invalid";
|
|
48
|
+
too_large: "too_large";
|
|
49
|
+
invalid_path: "invalid_path";
|
|
50
|
+
}>;
|
|
51
|
+
}, z.core.$strict>;
|
|
52
|
+
/** Existing Computer dispatch status/decoding refusals. */
|
|
53
|
+
export declare const appComputerDispatchRefusalSchema: z.ZodObject<{
|
|
54
|
+
error: z.ZodEnum<{
|
|
55
|
+
unavailable: "unavailable";
|
|
56
|
+
conflict: "conflict";
|
|
57
|
+
not_granted: "not_granted";
|
|
58
|
+
too_large: "too_large";
|
|
59
|
+
}>;
|
|
60
|
+
}, z.core.$strict>;
|
|
61
|
+
/** An execution wait can time out while its durable request remains identifiable. */
|
|
62
|
+
export declare const appComputerExecTimeoutSchema: z.ZodObject<{
|
|
63
|
+
error: z.ZodLiteral<"timeout">;
|
|
64
|
+
requestId: z.ZodString;
|
|
65
|
+
}, z.core.$strict>;
|
|
66
|
+
/** The Workflow Git-pass owner has exactly these existing domain refusals. */
|
|
67
|
+
export declare const workflowGitPassRefusalSchema: z.ZodObject<{
|
|
68
|
+
error: z.ZodEnum<{
|
|
69
|
+
unavailable: "unavailable";
|
|
70
|
+
revoked: "revoked";
|
|
71
|
+
not_granted: "not_granted";
|
|
72
|
+
}>;
|
|
73
|
+
}, z.core.$strict>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
/** Public metadata for one host-admitted Workflow Git pass; parsing never grants authority. */
|
|
3
|
+
export const workflowGitPassResultSchema = z.strictObject({
|
|
4
|
+
passId: z.string().min(1),
|
|
5
|
+
remote: z.url({ protocol: /^https$/, abort: true }).refine((value) => {
|
|
6
|
+
const remote = new URL(value);
|
|
7
|
+
return remote.username === "" && remote.password === "";
|
|
8
|
+
}, "Workflow Git remotes must not contain credentials"),
|
|
9
|
+
expiresAt: z.number().int().positive(),
|
|
10
|
+
/**
|
|
11
|
+
* Present when the host admits this pass by `Authorization: Bearer` on the
|
|
12
|
+
* remote. It is never part of the remote; a command receives it only as
|
|
13
|
+
* command-local Git config, never written to a repository config.
|
|
14
|
+
*/
|
|
15
|
+
bearer: z.string().min(1).exactOptional(),
|
|
16
|
+
});
|
|
17
|
+
/** Existing attachment budget operation kinds shared by Computer and Media. */
|
|
18
|
+
export const connectorOperationBudgetKindSchema = z.enum([
|
|
19
|
+
"exec",
|
|
20
|
+
"write",
|
|
21
|
+
"media",
|
|
22
|
+
]);
|
|
23
|
+
/** Existing owner budget refusal; it remains a domain result, not a wire envelope. */
|
|
24
|
+
export const connectorOperationBudgetRefusalSchema = z.strictObject({
|
|
25
|
+
error: z.literal("attachment_budget_exceeded"),
|
|
26
|
+
kind: connectorOperationBudgetKindSchema,
|
|
27
|
+
retryAfterMs: z.number(),
|
|
28
|
+
});
|
|
29
|
+
/** Computer admission refusals returned before native dispatch. */
|
|
30
|
+
export const appComputerAdmissionRefusalSchema = z.union([
|
|
31
|
+
z.strictObject({
|
|
32
|
+
error: z.enum([
|
|
33
|
+
"revoked",
|
|
34
|
+
"not_granted",
|
|
35
|
+
"grantor_lost_authority",
|
|
36
|
+
"unavailable",
|
|
37
|
+
]),
|
|
38
|
+
}),
|
|
39
|
+
connectorOperationBudgetRefusalSchema,
|
|
40
|
+
]);
|
|
41
|
+
/** Existing Computer broker argument refusals. */
|
|
42
|
+
export const appComputerInputRefusalSchema = z.strictObject({
|
|
43
|
+
error: z.enum(["too_large", "invalid_path", "invalid"]),
|
|
44
|
+
});
|
|
45
|
+
/** Existing Computer dispatch status/decoding refusals. */
|
|
46
|
+
export const appComputerDispatchRefusalSchema = z.strictObject({
|
|
47
|
+
error: z.enum(["not_granted", "too_large", "conflict", "unavailable"]),
|
|
48
|
+
});
|
|
49
|
+
/** An execution wait can time out while its durable request remains identifiable. */
|
|
50
|
+
export const appComputerExecTimeoutSchema = z.strictObject({
|
|
51
|
+
error: z.literal("timeout"),
|
|
52
|
+
requestId: z.string(),
|
|
53
|
+
});
|
|
54
|
+
/** The Workflow Git-pass owner has exactly these existing domain refusals. */
|
|
55
|
+
export const workflowGitPassRefusalSchema = z.strictObject({
|
|
56
|
+
error: z.enum(["revoked", "not_granted", "unavailable"]),
|
|
57
|
+
});
|