@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.
Files changed (159) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +766 -2
  3. package/dist/agent-message-meta.d.ts +74 -0
  4. package/dist/agent-message-meta.js +63 -0
  5. package/dist/agents.d.ts +170 -0
  6. package/dist/agents.js +218 -0
  7. package/dist/app-build-contract.d.ts +43 -0
  8. package/dist/app-build-contract.js +24 -0
  9. package/dist/apps.d.ts +66 -0
  10. package/dist/apps.js +47 -0
  11. package/dist/backend-declaration.d.ts +6 -0
  12. package/dist/backend-declaration.js +65 -0
  13. package/dist/backend-definition.d.ts +88 -0
  14. package/dist/backend-definition.js +158 -0
  15. package/dist/backend-refusal.d.ts +10 -0
  16. package/dist/backend-refusal.js +10 -0
  17. package/dist/backend.d.ts +30 -0
  18. package/dist/backend.js +28 -0
  19. package/dist/capabilities.d.ts +30 -0
  20. package/dist/capabilities.js +50 -0
  21. package/dist/channels.d.ts +142 -0
  22. package/dist/channels.js +97 -0
  23. package/dist/commands.d.ts +33 -0
  24. package/dist/commands.js +46 -0
  25. package/dist/computer-contracts.d.ts +73 -0
  26. package/dist/computer-contracts.js +57 -0
  27. package/dist/computer.d.ts +294 -0
  28. package/dist/computer.js +319 -0
  29. package/dist/connect.d.ts +11 -0
  30. package/dist/connect.js +211 -0
  31. package/dist/errors.d.ts +34 -0
  32. package/dist/errors.js +106 -0
  33. package/dist/failure.d.ts +2 -0
  34. package/dist/failure.js +9 -0
  35. package/dist/files.d.ts +25 -0
  36. package/dist/files.js +84 -0
  37. package/dist/game-servers.d.ts +530 -0
  38. package/dist/game-servers.js +244 -0
  39. package/dist/gills.d.ts +43 -0
  40. package/dist/gills.js +174 -0
  41. package/dist/git-commit.d.ts +143 -0
  42. package/dist/git-commit.js +251 -0
  43. package/dist/git-rpc.d.ts +310 -0
  44. package/dist/git-rpc.js +166 -0
  45. package/dist/git-steps.d.ts +579 -0
  46. package/dist/git-steps.js +804 -0
  47. package/dist/git-wire.d.ts +33 -0
  48. package/dist/git-wire.js +240 -0
  49. package/dist/git.d.ts +322 -0
  50. package/dist/git.js +98 -0
  51. package/dist/host.d.ts +97 -0
  52. package/dist/host.js +732 -0
  53. package/dist/inbox.d.ts +99 -0
  54. package/dist/inbox.js +184 -0
  55. package/dist/index.d.ts +31 -0
  56. package/dist/index.js +15 -0
  57. package/dist/inference.d.ts +17 -0
  58. package/dist/inference.js +115 -0
  59. package/dist/internal/app-error.d.ts +8 -0
  60. package/dist/internal/app-error.js +36 -0
  61. package/dist/internal/app-session.d.ts +8 -0
  62. package/dist/internal/app-session.js +551 -0
  63. package/dist/internal/back-inputs.d.ts +22 -0
  64. package/dist/internal/back-inputs.js +93 -0
  65. package/dist/internal/browser-bridge.d.ts +30 -0
  66. package/dist/internal/browser-bridge.js +203 -0
  67. package/dist/internal/capabilities.d.ts +13 -0
  68. package/dist/internal/capabilities.js +138 -0
  69. package/dist/internal/commands.d.ts +9 -0
  70. package/dist/internal/commands.js +257 -0
  71. package/dist/internal/disconnect-host.d.ts +7 -0
  72. package/dist/internal/disconnect-host.js +19 -0
  73. package/dist/internal/git-edit-tree.d.ts +6 -0
  74. package/dist/internal/git-edit-tree.js +46 -0
  75. package/dist/internal/memory-fs.d.ts +39 -0
  76. package/dist/internal/memory-fs.js +154 -0
  77. package/dist/internal/protocol.d.ts +116 -0
  78. package/dist/internal/protocol.js +6 -0
  79. package/dist/internal/query-feed.d.ts +23 -0
  80. package/dist/internal/query-feed.js +111 -0
  81. package/dist/internal/result.d.ts +22 -0
  82. package/dist/internal/result.js +61 -0
  83. package/dist/internal/rpc-contract.d.ts +24 -0
  84. package/dist/internal/rpc-contract.js +78 -0
  85. package/dist/internal/schemas.d.ts +307 -0
  86. package/dist/internal/schemas.js +524 -0
  87. package/dist/internal/store.d.ts +8 -0
  88. package/dist/internal/store.js +30 -0
  89. package/dist/internal/terminal-gate.d.ts +17 -0
  90. package/dist/internal/terminal-gate.js +94 -0
  91. package/dist/lifecycle.d.ts +44 -0
  92. package/dist/lifecycle.js +1 -0
  93. package/dist/marketplace.d.ts +159 -0
  94. package/dist/marketplace.js +102 -0
  95. package/dist/media-json.d.ts +181 -0
  96. package/dist/media-json.js +204 -0
  97. package/dist/media-library.d.ts +11 -0
  98. package/dist/media-library.js +15 -0
  99. package/dist/media-request-id.d.ts +7 -0
  100. package/dist/media-request-id.js +16 -0
  101. package/dist/media.d.ts +354 -0
  102. package/dist/media.js +654 -0
  103. package/dist/method-refusal.d.ts +64 -0
  104. package/dist/method-refusal.js +48 -0
  105. package/dist/pending.d.ts +10 -0
  106. package/dist/pending.js +10 -0
  107. package/dist/query.d.ts +76 -0
  108. package/dist/query.js +195 -0
  109. package/dist/react-mount.d.ts +23 -0
  110. package/dist/react-mount.js +108 -0
  111. package/dist/react.d.ts +41 -0
  112. package/dist/react.js +111 -0
  113. package/dist/read-copy.d.ts +103 -0
  114. package/dist/read-copy.js +195 -0
  115. package/dist/roles/files.d.ts +295 -0
  116. package/dist/roles/files.js +184 -0
  117. package/dist/root.d.ts +21 -0
  118. package/dist/root.js +1 -0
  119. package/dist/rpc.d.ts +1 -0
  120. package/dist/rpc.js +1 -0
  121. package/dist/status.d.ts +17 -0
  122. package/dist/status.js +50 -0
  123. package/dist/storage-wire.d.ts +167 -0
  124. package/dist/storage-wire.js +115 -0
  125. package/dist/storage.d.ts +72 -0
  126. package/dist/storage.js +143 -0
  127. package/dist/store.d.ts +11 -0
  128. package/dist/store.js +1 -0
  129. package/dist/test-kit/git.d.ts +31 -0
  130. package/dist/test-kit/git.js +174 -0
  131. package/dist/ui.d.ts +169 -0
  132. package/dist/ui.js +10 -0
  133. package/dist/window.d.ts +41 -0
  134. package/dist/window.js +15 -0
  135. package/dist/world.d.ts +16 -0
  136. package/dist/world.js +17 -0
  137. package/docs/api/README.md +28 -0
  138. package/docs/api/app-build-contract.md +113 -0
  139. package/docs/api/backend-declaration.md +62 -0
  140. package/docs/api/backend-definition.md +215 -0
  141. package/docs/api/backend.md +269 -0
  142. package/docs/api/errors.md +169 -0
  143. package/docs/api/files.md +91 -0
  144. package/docs/api/gills.md +164 -0
  145. package/docs/api/git-commit.md +279 -0
  146. package/docs/api/git-rpc.md +243 -0
  147. package/docs/api/git-steps.md +1010 -0
  148. package/docs/api/git-wire.md +197 -0
  149. package/docs/api/git.md +579 -0
  150. package/docs/api/index.md +2880 -0
  151. package/docs/api/media-json.md +507 -0
  152. package/docs/api/media-request-id.md +32 -0
  153. package/docs/api/modules.md +32 -0
  154. package/docs/api/query.md +253 -0
  155. package/docs/api/react.md +216 -0
  156. package/docs/api/read-copy.md +204 -0
  157. package/docs/api/rpc.md +128 -0
  158. package/docs/api/storage.md +620 -0
  159. package/package.json +197 -3
@@ -0,0 +1,74 @@
1
+ import * as z from "zod";
2
+ /** Who a Session line came from, as the admitting host authenticated them. */
3
+ export declare const FungiAuthorSchema: z.ZodObject<{
4
+ id: z.ZodString;
5
+ name: z.ZodString;
6
+ }, z.core.$strict>;
7
+ /** Who a Session line came from, as the admitting host authenticated them. */
8
+ export type FungiAuthor = z.infer<typeof FungiAuthorSchema>;
9
+ /**
10
+ * A delegated Agent's reply as the admitting host authenticated it against the
11
+ * mail it sent. `commandId` is the replying Session's accepted command, the
12
+ * same id as the sender's `agents.send` receipt.
13
+ */
14
+ export declare const FungiDelegationReplySchema: z.ZodObject<{
15
+ agentId: z.ZodString;
16
+ sessionId: z.ZodString;
17
+ commandId: z.ZodString;
18
+ outcome: z.ZodEnum<{
19
+ completed: "completed";
20
+ failed: "failed";
21
+ interrupted: "interrupted";
22
+ cancelled: "cancelled";
23
+ outcome_unknown: "outcome_unknown";
24
+ }>;
25
+ diagnostic: z.ZodOptional<z.ZodString>;
26
+ }, z.core.$strict>;
27
+ /** A delegated Agent's reply as the admitting host authenticated it. */
28
+ export type FungiDelegationReply = z.infer<typeof FungiDelegationReplySchema>;
29
+ /**
30
+ * The metadata the host attaches to every prompt and operator line it admits.
31
+ * Shiitake stores it opaquely; the host writes it and Apps read it.
32
+ */
33
+ export declare const FungiMessageMetaSchema: z.ZodObject<{
34
+ author: z.ZodOptional<z.ZodObject<{
35
+ id: z.ZodString;
36
+ name: z.ZodString;
37
+ }, z.core.$strict>>;
38
+ delegation: z.ZodOptional<z.ZodObject<{
39
+ ancestors: z.ZodArray<z.ZodString>;
40
+ maxDepth: z.ZodNumber;
41
+ reply: z.ZodOptional<z.ZodObject<{
42
+ agentId: z.ZodString;
43
+ sessionId: z.ZodString;
44
+ commandId: z.ZodString;
45
+ outcome: z.ZodEnum<{
46
+ completed: "completed";
47
+ failed: "failed";
48
+ interrupted: "interrupted";
49
+ cancelled: "cancelled";
50
+ outcome_unknown: "outcome_unknown";
51
+ }>;
52
+ diagnostic: z.ZodOptional<z.ZodString>;
53
+ }, z.core.$strict>>;
54
+ }, z.core.$strict>>;
55
+ }, z.core.$strict>;
56
+ /** The metadata the host attaches to every prompt and operator line it admits. */
57
+ export type FungiMessageMeta = z.infer<typeof FungiMessageMetaSchema>;
58
+ /** Any JSON value, as Shiitake returns a message's metadata. */
59
+ export type MessageMetaValue = string | number | boolean | null | readonly MessageMetaValue[] | Readonly<{
60
+ [key: string]: MessageMetaValue;
61
+ }>;
62
+ /** The author a message's metadata names; none for anything else. */
63
+ export declare function messageAuthor(meta: MessageMetaValue | undefined): FungiAuthor | undefined;
64
+ /**
65
+ * The authenticated delegation reply a message's metadata carries; none for
66
+ * any other line, including text that merely looks like a reply.
67
+ */
68
+ export declare function messageDelegationReply(meta: MessageMetaValue | undefined): FungiDelegationReply | undefined;
69
+ /** The metadata the host attaches for one authenticated author, as JSON. */
70
+ export type AuthorMeta = Readonly<{
71
+ author: Readonly<FungiAuthor>;
72
+ }>;
73
+ /** The metadata the host attaches for one authenticated author. */
74
+ export declare function authorMeta(author: FungiAuthor): AuthorMeta;
@@ -0,0 +1,63 @@
1
+ import * as z from "zod";
2
+ /** Who a Session line came from, as the admitting host authenticated them. */
3
+ export const FungiAuthorSchema = z.strictObject({
4
+ id: z.string().min(1).max(256),
5
+ name: z.string().min(1).max(128),
6
+ });
7
+ const identifier = z.string().min(1).max(256);
8
+ /**
9
+ * A delegated Agent's reply as the admitting host authenticated it against the
10
+ * mail it sent. `commandId` is the replying Session's accepted command, the
11
+ * same id as the sender's `agents.send` receipt.
12
+ */
13
+ export const FungiDelegationReplySchema = z.strictObject({
14
+ agentId: identifier,
15
+ sessionId: identifier,
16
+ commandId: identifier,
17
+ /** The exact settlement outcome; failures are never collapsed. */
18
+ outcome: z.enum([
19
+ "completed",
20
+ "failed",
21
+ "interrupted",
22
+ "cancelled",
23
+ "outcome_unknown",
24
+ ]),
25
+ /** Bounded, single-line terminal diagnostic for work that did not complete. */
26
+ diagnostic: z.string().min(1).max(200).optional(),
27
+ });
28
+ /**
29
+ * The metadata the host attaches to every prompt and operator line it admits.
30
+ * Shiitake stores it opaquely; the host writes it and Apps read it.
31
+ */
32
+ export const FungiMessageMetaSchema = z.strictObject({
33
+ author: FungiAuthorSchema.optional(),
34
+ /** Host-admitted delegation path and its inherited abuse bound. */
35
+ delegation: z
36
+ .strictObject({
37
+ ancestors: z.array(identifier).max(8),
38
+ maxDepth: z.number().int().min(1).max(8),
39
+ /**
40
+ * Present only on a line the host admitted as an authenticated reply;
41
+ * a line's text never sets it.
42
+ */
43
+ reply: FungiDelegationReplySchema.optional(),
44
+ })
45
+ .optional(),
46
+ });
47
+ /** The author a message's metadata names; none for anything else. */
48
+ export function messageAuthor(meta) {
49
+ const parsed = FungiMessageMetaSchema.safeParse(meta);
50
+ return parsed.success ? parsed.data.author : undefined;
51
+ }
52
+ /**
53
+ * The authenticated delegation reply a message's metadata carries; none for
54
+ * any other line, including text that merely looks like a reply.
55
+ */
56
+ export function messageDelegationReply(meta) {
57
+ const parsed = FungiMessageMetaSchema.safeParse(meta);
58
+ return parsed.success ? parsed.data.delegation?.reply : undefined;
59
+ }
60
+ /** The metadata the host attaches for one authenticated author. */
61
+ export function authorMeta(author) {
62
+ return { author: { id: author.id, name: author.name } };
63
+ }
@@ -0,0 +1,170 @@
1
+ export { FungiAuthorSchema, FungiDelegationReplySchema, FungiMessageMetaSchema, messageAuthor, messageDelegationReply, authorMeta, } from "./agent-message-meta.js";
2
+ export type { FungiAuthor, FungiDelegationReply, FungiMessageMeta, MessageMetaValue, AuthorMeta, } from "./agent-message-meta.js";
3
+ import * as z from "zod";
4
+ import * as Schema from "effect/Schema";
5
+ import type { CapabilityContract, CapabilityDirectory } from "./capabilities.js";
6
+ /**
7
+ * Validates the wire shape of an Agent record: its id, display name,
8
+ * and which session operations (read, send, manage) this App may
9
+ * perform on it.
10
+ */
11
+ export declare const appAgentSchema: Schema.Struct<{
12
+ readonly agentId: Schema.String;
13
+ readonly name: Schema.String;
14
+ readonly sessionOperations: Schema.$Array<Schema.Literals<readonly ["agent.read", "agent.send", "agent.manage"]>>;
15
+ }>;
16
+ /**
17
+ * An Agent record as decoded from the host: its id, display name, and
18
+ * which session operations this App is permitted to perform on it.
19
+ */
20
+ export type AppAgent = Schema.Schema.Type<typeof appAgentSchema>;
21
+ /** The admitted AGENTS.list projection, containing only ids and display names. */
22
+ export declare const appAgentListResultSchema: z.ZodObject<{
23
+ agents: z.ZodArray<z.ZodObject<{
24
+ agentId: z.ZodString;
25
+ name: z.ZodString;
26
+ }, z.core.$strict>>;
27
+ }, z.core.$strict>;
28
+ /** Computer provisioning is a Team creation choice, separate from Home policy. */
29
+ export declare const appAgentComputerSchema: Schema.Literals<readonly ["new", "none"]>;
30
+ /** Validates Agent creation input: a name, a caller-chosen request id and an
31
+ * optional Computer provisioning choice. */
32
+ export declare const appAgentCreateInputSchema: Schema.Struct<{
33
+ readonly name: Schema.String;
34
+ readonly requestId: Schema.String;
35
+ readonly computer: Schema.optionalKey<Schema.Literals<readonly ["new", "none"]>>;
36
+ }>;
37
+ /**
38
+ * Input for creating a new Agent: its name, a caller-chosen request id
39
+ * for idempotency, and whether to provision a new Computer for it.
40
+ */
41
+ export type AppAgentCreateInput = Readonly<Schema.Schema.Type<typeof appAgentCreateInputSchema>>;
42
+ /** Live object-capability shape received from Cap'n Web. */
43
+ export type AppAgentTransportHandle = {
44
+ /** Send one request to the Agent's session endpoint. */
45
+ fetch(request: Request): Promise<Response>;
46
+ /** Release the underlying object capability. */
47
+ close(): Promise<void>;
48
+ /** Synchronously release local resources, for `using` disposal. */
49
+ [Symbol.dispose](): void;
50
+ };
51
+ /** Capability handle for listing the Agents in a directory. */
52
+ export type AppAgentListHandle = {
53
+ /** List the Agents visible to this App in the directory. */
54
+ list(): Promise<readonly AppAgent[]>;
55
+ };
56
+ /** Capability handle for creating a new Agent in a directory. */
57
+ export type AppAgentCreateHandle = {
58
+ /** Create a new Agent with the given name and request id. */
59
+ create(input: AppAgentCreateInput): Promise<AppAgent>;
60
+ };
61
+ /**
62
+ * Live capability handle for listing and creating Agents in a Team or
63
+ * local-project directory, and opening transports to them.
64
+ */
65
+ export type AppAgentDirectoryHandle = AppAgentListHandle & AppAgentCreateHandle & {
66
+ /** Open a transport to the Agent identified by `agentId`. */
67
+ open(input: {
68
+ agentId: string;
69
+ }): Promise<AppAgentTransportHandle>;
70
+ /** The member's inbox feed, limited to Agents this App may read. */
71
+ openInbox(): Promise<AppAgentTransportHandle>;
72
+ };
73
+ /** Capability to list the Agents visible to this App in read-only form. */
74
+ export declare const agentList: CapabilityContract<AppAgentListHandle>;
75
+ /** Capability to create new Agents and open transports to them. */
76
+ export declare const agentManage: CapabilityContract<Pick<AppAgentDirectoryHandle, "create" | "open">>;
77
+ /** Validates Agent rename input: the target Agent and its new display name. */
78
+ export declare const appAgentRenameInputSchema: Schema.Struct<{
79
+ readonly agentId: Schema.String;
80
+ readonly name: Schema.String;
81
+ }>;
82
+ /**
83
+ * Input for renaming an existing Agent: its id and the owner's chosen
84
+ * replacement display name.
85
+ */
86
+ export type AppAgentRenameInput = Readonly<Schema.Schema.Type<typeof appAgentRenameInputSchema>>;
87
+ /** Capability handle for renaming an Agent the owner already created. */
88
+ export type AppAgentRenameHandle = {
89
+ /** Rename an existing Agent and return its updated record. */
90
+ rename(input: AppAgentRenameInput): Promise<AppAgent>;
91
+ };
92
+ /** Owner-only capability to rename an existing Agent; not every host grants it. */
93
+ export declare const agentRename: CapabilityContract<AppAgentRenameHandle>;
94
+ /** Rename an Agent through the host-granted owner-only capability. */
95
+ export declare function renameAppAgent(capabilities: CapabilityDirectory, input: AppAgentRenameInput): Promise<AppAgent>;
96
+ /** One Agent's App-tool policy, as the owner-only policy capability reports it. */
97
+ export declare const appAgentToolPolicyStatusSchema: z.ZodUnion<readonly [z.ZodObject<{
98
+ status: z.ZodLiteral<"pending">;
99
+ revision: z.ZodString;
100
+ }, z.core.$strip>, z.ZodObject<{
101
+ status: z.ZodLiteral<"approved">;
102
+ revision: z.ZodString;
103
+ }, z.core.$strip>]>;
104
+ /** Whether an Agent's App tools are still pending the owner's approval. */
105
+ export type AppAgentToolPolicyStatus = z.infer<typeof appAgentToolPolicyStatusSchema>;
106
+ /** The outcome of an owner's direct App-tool approval. */
107
+ export declare const appAgentToolPolicyResultSchema: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
108
+ status: z.ZodLiteral<"pending">;
109
+ revision: z.ZodString;
110
+ }, z.core.$strip>, z.ZodObject<{
111
+ status: z.ZodLiteral<"approved">;
112
+ revision: z.ZodString;
113
+ }, z.core.$strip>]>, z.ZodObject<{
114
+ error: z.ZodString;
115
+ }, z.core.$strip>]>;
116
+ /** The outcome of an owner's direct App-tool approval. */
117
+ export type AppAgentToolPolicyResult = z.infer<typeof appAgentToolPolicyResultSchema>;
118
+ /** Capability handle for reading and approving an Agent's App-tool policy. */
119
+ export type AppAgentToolPolicyHandle = {
120
+ /** This Agent's current policy status, or `null` for no such Agent. */
121
+ status(input: {
122
+ agentId: string;
123
+ }): Promise<AppAgentToolPolicyStatus | null>;
124
+ /** Approve (or re-request) this Agent's App tools under a CAS revision. */
125
+ approve(input: {
126
+ agentId: string;
127
+ level: "read" | "write";
128
+ expectedRevision: string | null;
129
+ }): Promise<AppAgentToolPolicyResult>;
130
+ };
131
+ /** Owner-only capability to read and approve an Agent's App-tool policy. */
132
+ export declare const agentToolPolicy: CapabilityContract<AppAgentToolPolicyHandle>;
133
+ /**
134
+ * Capability for read-only Agent sessions: open a transport to an
135
+ * existing Agent, or read the member's inbox feed.
136
+ */
137
+ export declare const agentSessionRead: CapabilityContract<Pick<AppAgentDirectoryHandle, "open" | "openInbox">>;
138
+ /**
139
+ * Capability for read-write Agent sessions: open a transport to an
140
+ * existing Agent and send to it, including the member's inbox feed.
141
+ */
142
+ export declare const agentSessionWrite: CapabilityContract<Pick<AppAgentDirectoryHandle, "open" | "openInbox">>;
143
+ /** List the Agents in the host-granted Team or local-project scope. */
144
+ export declare function listAppAgents(capabilities: CapabilityDirectory): Promise<readonly AppAgent[]>;
145
+ /** Create an Agent through the Team directory selected by the host. */
146
+ export declare function createAppAgent(capabilities: CapabilityDirectory, input: AppAgentCreateInput): Promise<AppAgent>;
147
+ /**
148
+ * A Fetch-based transport to one Agent's session endpoint, scoped to
149
+ * this App and safe to hand to an HTTP client adapter.
150
+ */
151
+ export type AppAgentTransport = Readonly<{
152
+ /** Private location used only by Shiitake's existing HTTP client adapter. */
153
+ baseUrl: string;
154
+ /** Send a request to the Agent's session endpoint. */
155
+ fetch: typeof globalThis.fetch;
156
+ /** Close the transport and release the underlying Agent connection. */
157
+ close: () => Promise<void>;
158
+ }>;
159
+ /**
160
+ * Adapt one live object capability to Fetch without exposing the parent's
161
+ * authenticated URL or credentials to the isolated App.
162
+ */
163
+ export declare function openAppAgent(capabilities: CapabilityDirectory, input: {
164
+ agentId: string;
165
+ }): Promise<AppAgentTransport>;
166
+ /**
167
+ * Open the member's inbox feed through the host. The Hub owns the feed and
168
+ * filters it to the Agents this App may read; the App never sees the URL.
169
+ */
170
+ export declare function openAppInbox(capabilities: CapabilityDirectory): Promise<AppAgentTransport>;
package/dist/agents.js ADDED
@@ -0,0 +1,218 @@
1
+ export { FungiAuthorSchema, FungiDelegationReplySchema, FungiMessageMetaSchema, messageAuthor, messageDelegationReply, authorMeta, } from "./agent-message-meta.js";
2
+ import * as z from "zod";
3
+ import { defineCapability } from "./capabilities.js";
4
+ import { rpcDataSchema, rpcHandleSchema, rpcMethod, rpcFetchHandleSchema, } from "./internal/rpc-contract.js";
5
+ import * as Schema from "effect/Schema";
6
+ import { AppError } from "./errors.js";
7
+ import { reportCatchFailure } from "./failure.js";
8
+ const boundedIdentity = Schema.String.pipe(Schema.check(Schema.isMinLength(1)), Schema.check(Schema.isMaxLength(256)));
9
+ /**
10
+ * Validates the wire shape of an Agent record: its id, display name,
11
+ * and which session operations (read, send, manage) this App may
12
+ * perform on it.
13
+ */
14
+ export const appAgentSchema = Schema.Struct({
15
+ agentId: boundedIdentity,
16
+ name: boundedIdentity,
17
+ sessionOperations: Schema.Array(Schema.Literals(["agent.read", "agent.send", "agent.manage"])),
18
+ });
19
+ /** The admitted AGENTS.list projection, containing only ids and display names. */
20
+ export const appAgentListResultSchema = z.strictObject({
21
+ agents: z.array(z.strictObject({ agentId: z.string(), name: z.string() })),
22
+ });
23
+ /** Computer provisioning is a Team creation choice, separate from Home policy. */
24
+ export const appAgentComputerSchema = Schema.Literals(["new", "none"]);
25
+ /** Validates Agent creation input: a name, a caller-chosen request id and an
26
+ * optional Computer provisioning choice. */
27
+ export const appAgentCreateInputSchema = Schema.Struct({
28
+ name: boundedIdentity,
29
+ requestId: boundedIdentity,
30
+ computer: Schema.optionalKey(appAgentComputerSchema),
31
+ });
32
+ const appAgentDirectorySchema = Schema.Array(appAgentSchema);
33
+ const decodeAgents = Schema.decodeUnknownSync(appAgentDirectorySchema, {
34
+ onExcessProperty: "error",
35
+ });
36
+ const decodeAgentId = Schema.decodeUnknownSync(boundedIdentity);
37
+ const decodeResponse = Schema.decodeUnknownSync(Schema.instanceOf(Response));
38
+ /** Capability to list the Agents visible to this App in read-only form. */
39
+ export const agentList = defineCapability("agent.list", 1, rpcHandleSchema({
40
+ list: rpcMethod(rpcDataSchema(z.unknown().transform((value) => decodeAgents(value)))),
41
+ }));
42
+ /** Capability to create new Agents and open transports to them. */
43
+ export const agentManage = defineCapability("agent.manage", 1, rpcHandleSchema({
44
+ open: rpcMethod(rpcFetchHandleSchema),
45
+ create: rpcMethod(rpcDataSchema(z
46
+ .unknown()
47
+ .transform((value) => Schema.decodeUnknownSync(appAgentSchema)(value)))),
48
+ }));
49
+ /** Validates Agent rename input: the target Agent and its new display name. */
50
+ export const appAgentRenameInputSchema = Schema.Struct({
51
+ agentId: boundedIdentity,
52
+ name: boundedIdentity,
53
+ });
54
+ /** Owner-only capability to rename an existing Agent; not every host grants it. */
55
+ export const agentRename = defineCapability("agent.rename", 1, rpcHandleSchema({
56
+ rename: rpcMethod(rpcDataSchema(z
57
+ .unknown()
58
+ .transform((value) => Schema.decodeUnknownSync(appAgentSchema)(value)))),
59
+ }));
60
+ /** Rename an Agent through the host-granted owner-only capability. */
61
+ export async function renameAppAgent(capabilities, input) {
62
+ const request = Schema.decodeUnknownSync(appAgentRenameInputSchema)(input);
63
+ const agent = await capabilities.require(agentRename).rename(request);
64
+ return Schema.decodeUnknownSync(appAgentSchema)(agent);
65
+ }
66
+ /** One Agent's App-tool policy, as the owner-only policy capability reports it. */
67
+ export const appAgentToolPolicyStatusSchema = z.union([
68
+ z.object({ status: z.literal("pending"), revision: z.string() }),
69
+ z.object({ status: z.literal("approved"), revision: z.string() }),
70
+ ]);
71
+ /** The outcome of an owner's direct App-tool approval. */
72
+ export const appAgentToolPolicyResultSchema = z.union([
73
+ appAgentToolPolicyStatusSchema,
74
+ z.object({ error: z.string() }),
75
+ ]);
76
+ /** Owner-only capability to read and approve an Agent's App-tool policy. */
77
+ export const agentToolPolicy = defineCapability("agent.toolPolicy", 1, rpcHandleSchema({
78
+ status: rpcMethod(rpcDataSchema(z.union([appAgentToolPolicyStatusSchema, z.null()]))),
79
+ approve: rpcMethod(rpcDataSchema(appAgentToolPolicyResultSchema)),
80
+ }));
81
+ /**
82
+ * Capability for read-only Agent sessions: open a transport to an
83
+ * existing Agent, or read the member's inbox feed.
84
+ */
85
+ export const agentSessionRead = defineCapability("agent.read", 1, rpcHandleSchema({
86
+ open: rpcMethod(rpcFetchHandleSchema),
87
+ openInbox: rpcMethod(rpcFetchHandleSchema),
88
+ }));
89
+ /**
90
+ * Capability for read-write Agent sessions: open a transport to an
91
+ * existing Agent and send to it, including the member's inbox feed.
92
+ */
93
+ export const agentSessionWrite = defineCapability("agent.send", 1, rpcHandleSchema({
94
+ open: rpcMethod(rpcFetchHandleSchema),
95
+ openInbox: rpcMethod(rpcFetchHandleSchema),
96
+ }));
97
+ /** List the Agents in the host-granted Team or local-project scope. */
98
+ export async function listAppAgents(capabilities) {
99
+ return decodeAgents(await capabilities.require(agentList).list());
100
+ }
101
+ /** Create an Agent through the Team directory selected by the host. */
102
+ export async function createAppAgent(capabilities, input) {
103
+ const request = Schema.decodeUnknownSync(appAgentCreateInputSchema)(input);
104
+ const agent = await capabilities.require(agentManage).create(request);
105
+ return Schema.decodeUnknownSync(appAgentSchema)(agent);
106
+ }
107
+ /** Keep read and write handles separate while owning their shared connection lifetime. */
108
+ async function openOperationHandles(openRead, openWrite) {
109
+ const read = await openRead();
110
+ let write;
111
+ let closing;
112
+ const ensureOpen = () => {
113
+ if (closing)
114
+ throw new AppError("The Agent connection is closed", {
115
+ code: "DISCONNECTED",
116
+ retryable: true,
117
+ });
118
+ };
119
+ const closeHandle = async (handle) => {
120
+ try {
121
+ await handle.close();
122
+ }
123
+ finally {
124
+ handle[Symbol.dispose]();
125
+ }
126
+ };
127
+ return {
128
+ fetch: async (request) => {
129
+ ensureOpen();
130
+ const handle = request.method === "GET" ||
131
+ request.method === "HEAD" ||
132
+ openRead === openWrite
133
+ ? read
134
+ : await (write ??= openWrite());
135
+ ensureOpen();
136
+ return decodeResponse(await handle.fetch(request));
137
+ },
138
+ close: () => {
139
+ if (!closing) {
140
+ closing = Promise.all([
141
+ closeHandle(read),
142
+ ...(write ? [write.then(closeHandle)] : []),
143
+ ]).then(() => undefined);
144
+ void closing.catch((cause) => {
145
+ reportCatchFailure("agents.close", cause);
146
+ });
147
+ }
148
+ return closing;
149
+ },
150
+ };
151
+ }
152
+ const transportBaseUrl = "https://agent-session.fungi.invalid";
153
+ /**
154
+ * Adapt one live object capability to Fetch without exposing the parent's
155
+ * authenticated URL or credentials to the isolated App.
156
+ */
157
+ export async function openAppAgent(capabilities, input) {
158
+ const agentId = decodeAgentId(input.agentId);
159
+ // Shiitake uses this address as Session identity; reopening the same Agent
160
+ // must share a key without aliasing another Agent's identically named Session.
161
+ const agentPath = `/agents/id-${encodeURIComponent(agentId)}`;
162
+ const baseUrl = `${transportBaseUrl}${agentPath}`;
163
+ const directory = capabilities.has(agentSessionRead)
164
+ ? capabilities.require(agentSessionRead)
165
+ : capabilities.has(agentSessionWrite)
166
+ ? capabilities.require(agentSessionWrite)
167
+ : capabilities.require(agentManage);
168
+ const openRead = () => directory.open({ agentId });
169
+ const openWrite = capabilities.has(agentSessionRead)
170
+ ? () => (capabilities.has(agentSessionWrite)
171
+ ? capabilities.require(agentSessionWrite)
172
+ : capabilities.require(agentManage)).open({ agentId })
173
+ : openRead;
174
+ const handles = await openOperationHandles(openRead, openWrite);
175
+ const fetch = async (requestInput, init) => {
176
+ const request = new Request(requestInput, init);
177
+ const target = new URL(request.url);
178
+ if (target.origin !== transportBaseUrl ||
179
+ !target.pathname.startsWith(`${agentPath}/`))
180
+ throw new AppError("The Agent request target is invalid", {
181
+ code: "INVALID_ARGUMENT",
182
+ retryable: false,
183
+ });
184
+ // The capability already owns Agent selection. Preserve its ordinary
185
+ // /sessions and /acp routes while removing the local identity prefix.
186
+ target.pathname = target.pathname.slice(agentPath.length);
187
+ return handles.fetch(new Request(target, request));
188
+ };
189
+ return Object.freeze({ baseUrl, fetch, close: handles.close });
190
+ }
191
+ const inboxBaseUrl = `${transportBaseUrl}/member`;
192
+ /**
193
+ * Open the member's inbox feed through the host. The Hub owns the feed and
194
+ * filters it to the Agents this App may read; the App never sees the URL.
195
+ */
196
+ export async function openAppInbox(capabilities) {
197
+ const contract = capabilities.has(agentSessionRead)
198
+ ? agentSessionRead
199
+ : agentSessionWrite;
200
+ const openRead = () => capabilities.require(contract).openInbox();
201
+ const openWrite = capabilities.has(agentSessionRead)
202
+ ? () => capabilities.require(agentSessionWrite).openInbox()
203
+ : openRead;
204
+ const handles = await openOperationHandles(openRead, openWrite);
205
+ const fetch = async (requestInput, init) => {
206
+ const request = new Request(requestInput, init);
207
+ const target = new URL(request.url);
208
+ if (target.origin !== transportBaseUrl ||
209
+ !target.pathname.startsWith("/member/inbox"))
210
+ throw new AppError("The inbox request target is invalid", {
211
+ code: "INVALID_ARGUMENT",
212
+ retryable: false,
213
+ });
214
+ target.pathname = target.pathname.slice("/member".length);
215
+ return handles.fetch(new Request(target, request));
216
+ };
217
+ return Object.freeze({ baseUrl: inboxBaseUrl, fetch, close: handles.close });
218
+ }
@@ -0,0 +1,43 @@
1
+ import * as z from "zod";
2
+ /** Refusals emitted by the Team App build owner. */
3
+ export declare const teamAppBuildFailureCodeSchema: z.ZodEnum<{
4
+ unavailable: "unavailable";
5
+ denied: "denied";
6
+ invalid: "invalid";
7
+ conflict: "conflict";
8
+ build_failed: "build_failed";
9
+ }>;
10
+ /** Pending, completed or failed reply from the App build owner. */
11
+ export declare const appBuildReplySchema: z.ZodUnion<readonly [z.ZodObject<{
12
+ kind: z.ZodLiteral<"pending">;
13
+ retryAfterMs: z.ZodNumber;
14
+ }, z.core.$strict>, z.ZodObject<{
15
+ releaseId: z.ZodString;
16
+ previewUrl: z.ZodURL;
17
+ }, z.core.$strict>, z.ZodObject<{
18
+ error: z.ZodEnum<{
19
+ unavailable: "unavailable";
20
+ denied: "denied";
21
+ invalid: "invalid";
22
+ conflict: "conflict";
23
+ build_failed: "build_failed";
24
+ }>;
25
+ }, z.core.$strict>]>;
26
+ /** Complete App build binding reply, including broker admission failures. */
27
+ export declare const appBuildBrokerResultSchema: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodObject<{
28
+ kind: z.ZodLiteral<"pending">;
29
+ retryAfterMs: z.ZodNumber;
30
+ }, z.core.$strict>, z.ZodObject<{
31
+ releaseId: z.ZodString;
32
+ previewUrl: z.ZodURL;
33
+ }, z.core.$strict>, z.ZodObject<{
34
+ error: z.ZodEnum<{
35
+ unavailable: "unavailable";
36
+ denied: "denied";
37
+ invalid: "invalid";
38
+ conflict: "conflict";
39
+ build_failed: "build_failed";
40
+ }>;
41
+ }, z.core.$strict>]>, z.ZodObject<{
42
+ error: z.ZodString;
43
+ }, z.core.$strict>]>;
@@ -0,0 +1,24 @@
1
+ import * as z from "zod";
2
+ import { pendingSchema } from "./pending.js";
3
+ /** Refusals emitted by the Team App build owner. */
4
+ export const teamAppBuildFailureCodeSchema = z.enum([
5
+ "invalid",
6
+ "denied",
7
+ "conflict",
8
+ "unavailable",
9
+ "build_failed",
10
+ ]);
11
+ /** Pending, completed or failed reply from the App build owner. */
12
+ export const appBuildReplySchema = z.union([
13
+ pendingSchema,
14
+ z.strictObject({
15
+ releaseId: z.string().min(1).max(256),
16
+ previewUrl: z.url(),
17
+ }),
18
+ z.strictObject({ error: teamAppBuildFailureCodeSchema }),
19
+ ]);
20
+ /** Complete App build binding reply, including broker admission failures. */
21
+ export const appBuildBrokerResultSchema = z.union([
22
+ appBuildReplySchema,
23
+ z.strictObject({ error: z.string() }),
24
+ ]);
package/dist/apps.d.ts ADDED
@@ -0,0 +1,66 @@
1
+ import * as z from "zod";
2
+ import type { WhistleJsonValue } from "@fungi.computer/whistle";
3
+ import * as Schema from "effect/Schema";
4
+ import type { CapabilityContract, CapabilityDirectory } from "./capabilities.js";
5
+ /** A recipient App decides how to present this request; opening never sends it. */
6
+ export declare const appIntentSchema: Schema.Union<readonly [Schema.Struct<{
7
+ readonly kind: Schema.Literal<"compose">;
8
+ readonly text: Schema.String;
9
+ }>, Schema.Struct<{
10
+ readonly kind: Schema.Literal<"navigate">;
11
+ readonly params: Schema.$Array<Schema.Struct<{
12
+ readonly key: Schema.String;
13
+ readonly value: Schema.String;
14
+ }>>;
15
+ }>]>;
16
+ export type AppIntent = Schema.Schema.Type<typeof appIntentSchema>;
17
+ /** The navigate form of an App intent, whose params a role contract defines. */
18
+ export type AppNavigateIntent = Extract<AppIntent, {
19
+ kind: "navigate";
20
+ }>;
21
+ export declare const appOpenInputSchema: Schema.Union<readonly [Schema.Struct<{
22
+ readonly role: Schema.String;
23
+ readonly intent: Schema.Union<readonly [Schema.Struct<{
24
+ readonly kind: Schema.Literal<"compose">;
25
+ readonly text: Schema.String;
26
+ }>, Schema.Struct<{
27
+ readonly kind: Schema.Literal<"navigate">;
28
+ readonly params: Schema.$Array<Schema.Struct<{
29
+ readonly key: Schema.String;
30
+ readonly value: Schema.String;
31
+ }>>;
32
+ }>]>;
33
+ }>, Schema.Struct<{
34
+ readonly appId: Schema.String;
35
+ readonly intent: Schema.Union<readonly [Schema.Struct<{
36
+ readonly kind: Schema.Literal<"compose">;
37
+ readonly text: Schema.String;
38
+ }>, Schema.Struct<{
39
+ readonly kind: Schema.Literal<"navigate">;
40
+ readonly params: Schema.$Array<Schema.Struct<{
41
+ readonly key: Schema.String;
42
+ readonly value: Schema.String;
43
+ }>>;
44
+ }>]>;
45
+ }>]>;
46
+ export type AppOpenInput = Schema.Schema.Type<typeof appOpenInputSchema>;
47
+ /** The App the Team chose for a role, as the host's role routing resolves it; a null name is an unnamed App. */
48
+ export declare const appRoleChoiceSchema: z.ZodNullable<z.ZodObject<{
49
+ displayName: z.ZodNullable<z.ZodString>;
50
+ }, z.core.$strict>>;
51
+ export type AppRoleChoice = z.output<typeof appRoleChoiceSchema>;
52
+ /**
53
+ * Open the Team's chosen App for a role with a bounded presentation intent.
54
+ * `role` answers which App that open would reach (null when none fills it),
55
+ * so a caller can name or hide its entry without hard-coding another App.
56
+ */
57
+ export declare const appsOpen: CapabilityContract<{
58
+ open(input: AppOpenInput): Promise<void>;
59
+ role(role: string): Promise<AppRoleChoice>;
60
+ }>;
61
+ export declare const openApp: (directory: CapabilityDirectory, input: AppOpenInput) => Promise<void>;
62
+ /** Call a declared method of another App as the signed-in member. Caller grants never travel. */
63
+ export declare const appsCall: CapabilityContract<{
64
+ /** The input is JSON text, as with app.methods; the result is decoded owned JSON. */
65
+ call(appId: string, method: string, input: string): Promise<WhistleJsonValue>;
66
+ }>;