spawnfile 0.1.3 → 0.1.5
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 +2 -0
- package/dist/cli/lifecycleCommands.d.ts +3 -0
- package/dist/cli/lifecycleCommands.js +80 -0
- package/dist/cli/runCli.d.ts +2 -1
- package/dist/cli/runCli.js +5 -47
- package/dist/compiler/buildCompilePlan.js +12 -202
- package/dist/compiler/buildCompilePlanRuntime.d.ts +6 -1
- package/dist/compiler/buildCompilePlanRuntime.js +9 -0
- package/dist/compiler/buildCompilePlanTeams.js +16 -10
- package/dist/compiler/buildCompilePlanTraversal.d.ts +16 -0
- package/dist/compiler/buildCompilePlanTraversal.js +214 -0
- package/dist/compiler/buildCompilePlanTraversalHelpers.d.ts +18 -0
- package/dist/compiler/buildCompilePlanTraversalHelpers.js +22 -0
- package/dist/compiler/compilePlanHelpers.d.ts +3 -1
- package/dist/compiler/compilePlanHelpers.js +37 -1
- package/dist/compiler/compileProject.js +14 -0
- package/dist/compiler/containerArtifacts.js +18 -3
- package/dist/compiler/containerArtifactsPlans.js +32 -0
- package/dist/compiler/containerArtifactsRender.js +86 -3
- package/dist/compiler/containerArtifactsTypes.d.ts +7 -3
- package/dist/compiler/containerEntrypointRender.d.ts +1 -1
- package/dist/compiler/containerEntrypointRender.js +37 -27
- package/dist/compiler/containerTargetResources.d.ts +4 -0
- package/dist/compiler/containerTargetResources.js +54 -0
- package/dist/compiler/containerWorkspaceResourceRender.d.ts +3 -0
- package/dist/compiler/containerWorkspaceResourceRender.js +128 -0
- package/dist/compiler/executionDefaults.js +0 -3
- package/dist/compiler/helpers.d.ts +1 -1
- package/dist/compiler/index.d.ts +1 -0
- package/dist/compiler/index.js +1 -0
- package/dist/compiler/moltnetArtifacts.d.ts +11 -5
- package/dist/compiler/moltnetArtifacts.js +133 -117
- package/dist/compiler/moltnetClientConfig.js +8 -2
- package/dist/compiler/moltnetConfigLowering.d.ts +36 -0
- package/dist/compiler/moltnetConfigLowering.js +125 -0
- package/dist/compiler/moltnetRuntimeConfig.d.ts +2 -0
- package/dist/compiler/moltnetRuntimeConfig.js +69 -0
- package/dist/compiler/runProject.d.ts +2 -0
- package/dist/compiler/runProject.js +20 -6
- package/dist/compiler/surfaces.d.ts +3 -13
- package/dist/compiler/surfaces.js +1 -6
- package/dist/compiler/syncProjectAuth.js +67 -19
- package/dist/compiler/types.d.ts +16 -1
- package/dist/compiler/upProject.d.ts +19 -0
- package/dist/compiler/upProject.js +37 -0
- package/dist/compiler/view/buildOrganizationView.js +22 -2
- package/dist/compiler/view/renderNetworks.js +14 -3
- package/dist/compiler/view/renderTree.js +8 -2
- package/dist/compiler/view/types.d.ts +18 -3
- package/dist/compiler/workspaceResources.d.ts +34 -0
- package/dist/compiler/workspaceResources.js +120 -0
- package/dist/manifest/executionSchemas.d.ts +106 -0
- package/dist/manifest/executionSchemas.js +140 -0
- package/dist/manifest/loadManifest.js +15 -27
- package/dist/manifest/renderSpawnfile.js +44 -52
- package/dist/manifest/renderSpawnfileNetworks.d.ts +2 -0
- package/dist/manifest/renderSpawnfileNetworks.js +63 -0
- package/dist/manifest/renderSpawnfileWorkspace.d.ts +2 -0
- package/dist/manifest/renderSpawnfileWorkspace.js +47 -0
- package/dist/manifest/scaffold.js +12 -6
- package/dist/manifest/scheduleSchemas.d.ts +15 -0
- package/dist/manifest/scheduleSchemas.js +26 -0
- package/dist/manifest/schemas.d.ts +626 -368
- package/dist/manifest/schemas.js +51 -191
- package/dist/manifest/teamNetworkSchemas.d.ts +228 -0
- package/dist/manifest/teamNetworkSchemas.js +295 -0
- package/dist/manifest/workspaceSchemas.d.ts +96 -0
- package/dist/manifest/workspaceSchemas.js +166 -0
- package/dist/report/types.d.ts +10 -0
- package/dist/runtime/common.d.ts +2 -1
- package/dist/runtime/common.js +3 -3
- package/dist/runtime/picoclaw/adapter.js +7 -0
- package/dist/runtime/picoclaw/runAuth.js +5 -41
- package/dist/runtime/tinyclaw/adapter.js +9 -2
- package/dist/runtime/tinyclaw/schedules.d.ts +9 -0
- package/dist/runtime/tinyclaw/schedules.js +62 -0
- package/dist/runtime/types.d.ts +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export { teamWorkspaceDocsSchema, teamWorkspaceSchema } from "./workspaceSchemas.js";
|
|
3
|
+
const moltnetScopeSchema = z.enum(["observe", "write", "admin", "attach", "pair"]);
|
|
4
|
+
const countTruthy = (value) => value.filter((entry) => Boolean(entry)).length;
|
|
5
|
+
const teamNetworkAuthTokenSchema = z
|
|
6
|
+
.object({
|
|
7
|
+
agents: z.array(z.string().trim().min(1)).optional(),
|
|
8
|
+
id: z.string().trim().min(1),
|
|
9
|
+
secret: z.string().trim().min(1),
|
|
10
|
+
scopes: z.array(moltnetScopeSchema).min(1)
|
|
11
|
+
})
|
|
12
|
+
.strict();
|
|
13
|
+
const teamNetworkAuthClientSchema = z
|
|
14
|
+
.object({
|
|
15
|
+
static_token: z.boolean().optional(),
|
|
16
|
+
token_env: z.string().trim().min(1).optional(),
|
|
17
|
+
token_id: z.string().trim().min(1).optional(),
|
|
18
|
+
token_path: z.string().trim().min(1).optional()
|
|
19
|
+
})
|
|
20
|
+
.strict()
|
|
21
|
+
.superRefine((value, context) => {
|
|
22
|
+
const tokenSourceCount = countTruthy([value.token_id, value.token_env, value.token_path]);
|
|
23
|
+
if (tokenSourceCount > 1) {
|
|
24
|
+
context.addIssue({
|
|
25
|
+
code: z.ZodIssueCode.custom,
|
|
26
|
+
message: "auth.client must declare exactly one of token_id, token_env, or token_path"
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (value.static_token === true && tokenSourceCount === 0) {
|
|
30
|
+
context.addIssue({
|
|
31
|
+
code: z.ZodIssueCode.custom,
|
|
32
|
+
message: "auth.client.static_token requires exactly one token source"
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
const teamNetworkAuthSchema = z
|
|
37
|
+
.object({
|
|
38
|
+
client: teamNetworkAuthClientSchema.optional(),
|
|
39
|
+
mode: z.enum(["none", "bearer", "open"]),
|
|
40
|
+
tokens: z.array(teamNetworkAuthTokenSchema).optional()
|
|
41
|
+
})
|
|
42
|
+
.strict()
|
|
43
|
+
.superRefine((value, context) => {
|
|
44
|
+
if (value.mode === "none") {
|
|
45
|
+
if (value.tokens && value.tokens.length > 0) {
|
|
46
|
+
context.addIssue({
|
|
47
|
+
code: z.ZodIssueCode.custom,
|
|
48
|
+
message: "auth.mode none must not declare tokens"
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (value.client) {
|
|
52
|
+
context.addIssue({
|
|
53
|
+
code: z.ZodIssueCode.custom,
|
|
54
|
+
message: "auth.mode none must not declare client"
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (value.mode === "bearer" && !value.client) {
|
|
60
|
+
context.addIssue({
|
|
61
|
+
code: z.ZodIssueCode.custom,
|
|
62
|
+
message: "auth.mode bearer requires auth.client"
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (value.mode === "open" && value.client) {
|
|
66
|
+
const tokenSourceCount = countTruthy([
|
|
67
|
+
value.client.token_id,
|
|
68
|
+
value.client.token_env,
|
|
69
|
+
value.client.token_path
|
|
70
|
+
]);
|
|
71
|
+
if (value.client.static_token !== true) {
|
|
72
|
+
context.addIssue({
|
|
73
|
+
code: z.ZodIssueCode.custom,
|
|
74
|
+
message: "open auth with auth.client requires static_token: true"
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
if (tokenSourceCount === 0) {
|
|
78
|
+
context.addIssue({
|
|
79
|
+
code: z.ZodIssueCode.custom,
|
|
80
|
+
message: "open auth with auth.client requires exactly one token source"
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (value.tokens) {
|
|
85
|
+
const tokenIds = value.tokens.map((token) => token.id);
|
|
86
|
+
if (new Set(tokenIds).size !== tokenIds.length) {
|
|
87
|
+
context.addIssue({
|
|
88
|
+
code: z.ZodIssueCode.custom,
|
|
89
|
+
message: "auth.tokens ids must be unique"
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
const teamNetworkStoreSqliteSchema = z
|
|
95
|
+
.object({
|
|
96
|
+
kind: z.literal("sqlite"),
|
|
97
|
+
path: z.string().trim().min(1)
|
|
98
|
+
})
|
|
99
|
+
.strict();
|
|
100
|
+
const teamNetworkStoreJsonSchema = z
|
|
101
|
+
.object({
|
|
102
|
+
kind: z.literal("json"),
|
|
103
|
+
path: z.string().trim().min(1)
|
|
104
|
+
})
|
|
105
|
+
.strict();
|
|
106
|
+
const teamNetworkStorePostgresSchema = z
|
|
107
|
+
.object({
|
|
108
|
+
kind: z.literal("postgres"),
|
|
109
|
+
dsn_secret: z.string().trim().min(1)
|
|
110
|
+
})
|
|
111
|
+
.strict();
|
|
112
|
+
const teamNetworkStoreMemorySchema = z.object({ kind: z.literal("memory") }).strict();
|
|
113
|
+
const teamNetworkStoreSchema = z.discriminatedUnion("kind", [
|
|
114
|
+
teamNetworkStoreSqliteSchema,
|
|
115
|
+
teamNetworkStoreJsonSchema,
|
|
116
|
+
teamNetworkStorePostgresSchema,
|
|
117
|
+
teamNetworkStoreMemorySchema
|
|
118
|
+
]);
|
|
119
|
+
const teamNetworkListenSchema = z
|
|
120
|
+
.object({
|
|
121
|
+
bind: z
|
|
122
|
+
.string()
|
|
123
|
+
.trim()
|
|
124
|
+
.min(1)
|
|
125
|
+
.superRefine((value, context) => {
|
|
126
|
+
if (value.startsWith("[") || value.endsWith("]") || /\[.*\]/.test(value)) {
|
|
127
|
+
context.addIssue({
|
|
128
|
+
code: z.ZodIssueCode.custom,
|
|
129
|
+
message: "listen.bind must be unbracketed"
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}),
|
|
133
|
+
port: z.number().int().min(1).max(65535)
|
|
134
|
+
})
|
|
135
|
+
.strict();
|
|
136
|
+
const teamNetworkPairingSchema = z
|
|
137
|
+
.object({
|
|
138
|
+
id: z.string().trim().min(1),
|
|
139
|
+
remote_base_url: z.string().trim().min(1),
|
|
140
|
+
remote_network_id: z.string().trim().min(1),
|
|
141
|
+
remote_network_name: z.string().trim().min(1),
|
|
142
|
+
token_secret: z.string().trim().min(1)
|
|
143
|
+
})
|
|
144
|
+
.strict();
|
|
145
|
+
const teamNetworkManagedServerSchema = z
|
|
146
|
+
.object({
|
|
147
|
+
allowed_origins: z.array(z.string().trim().min(1)).optional(),
|
|
148
|
+
auth: teamNetworkAuthSchema,
|
|
149
|
+
direct_messages: z.boolean().optional(),
|
|
150
|
+
human_ingress: z.boolean().optional(),
|
|
151
|
+
listen: teamNetworkListenSchema,
|
|
152
|
+
mode: z.literal("managed"),
|
|
153
|
+
pairings: z.array(teamNetworkPairingSchema).optional(),
|
|
154
|
+
store: teamNetworkStoreSchema,
|
|
155
|
+
trust_forwarded_proto: z.boolean().optional(),
|
|
156
|
+
url: z.string().trim().optional()
|
|
157
|
+
})
|
|
158
|
+
.strict()
|
|
159
|
+
.superRefine((value, context) => {
|
|
160
|
+
if (value.auth.mode === "bearer") {
|
|
161
|
+
if (!value.auth.tokens || value.auth.tokens.length === 0) {
|
|
162
|
+
context.addIssue({
|
|
163
|
+
code: z.ZodIssueCode.custom,
|
|
164
|
+
message: "managed server with auth.mode bearer requires at least one auth token"
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
if (!value.auth.client?.token_id) {
|
|
168
|
+
context.addIssue({
|
|
169
|
+
code: z.ZodIssueCode.custom,
|
|
170
|
+
message: "managed bearer auth requires auth.client.token_id"
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
if (value.auth.client?.token_env || value.auth.client?.token_path) {
|
|
174
|
+
context.addIssue({
|
|
175
|
+
code: z.ZodIssueCode.custom,
|
|
176
|
+
message: "managed bearer auth requires auth.client.token_id"
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
if (value.auth.client?.token_id && value.auth.tokens) {
|
|
180
|
+
const tokenById = new Map(value.auth.tokens.map((token) => [token.id, token]));
|
|
181
|
+
const selected = tokenById.get(value.auth.client.token_id);
|
|
182
|
+
if (!selected) {
|
|
183
|
+
context.addIssue({
|
|
184
|
+
code: z.ZodIssueCode.custom,
|
|
185
|
+
message: `managed bearer auth references unknown token: ${value.auth.client.token_id}`
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
else if (!(selected.scopes.includes("attach") && selected.scopes.includes("write"))) {
|
|
189
|
+
context.addIssue({
|
|
190
|
+
code: z.ZodIssueCode.custom,
|
|
191
|
+
message: "managed bearer auth.client.token_id must reference a token with attach and write scopes"
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (value.auth.mode === "open" && value.auth.client) {
|
|
197
|
+
if (!value.auth.client.token_id) {
|
|
198
|
+
context.addIssue({
|
|
199
|
+
code: z.ZodIssueCode.custom,
|
|
200
|
+
message: "managed open auth requires auth.client.token_id"
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
if (value.auth.client.token_env || value.auth.client.token_path) {
|
|
204
|
+
context.addIssue({
|
|
205
|
+
code: z.ZodIssueCode.custom,
|
|
206
|
+
message: "managed open auth client token source must be token_id"
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
const teamNetworkExternalServerSchema = z
|
|
212
|
+
.object({
|
|
213
|
+
auth: teamNetworkAuthSchema,
|
|
214
|
+
mode: z.literal("external"),
|
|
215
|
+
url: z.string().trim().min(1)
|
|
216
|
+
})
|
|
217
|
+
.strict()
|
|
218
|
+
.superRefine((value, context) => {
|
|
219
|
+
if (value.auth.tokens && value.auth.tokens.length > 0) {
|
|
220
|
+
context.addIssue({
|
|
221
|
+
code: z.ZodIssueCode.custom,
|
|
222
|
+
message: "external server does not accept auth.tokens"
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
if (value.auth.mode === "none" && value.auth.client) {
|
|
226
|
+
context.addIssue({
|
|
227
|
+
code: z.ZodIssueCode.custom,
|
|
228
|
+
message: "auth.mode none must not declare client"
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
if (!value.auth.client) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
if (value.auth.client.token_id) {
|
|
235
|
+
context.addIssue({
|
|
236
|
+
code: z.ZodIssueCode.custom,
|
|
237
|
+
message: "auth.client.token_id is only valid for managed servers"
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
if (value.auth.mode === "open" && value.auth.client.static_token !== true) {
|
|
241
|
+
context.addIssue({
|
|
242
|
+
code: z.ZodIssueCode.custom,
|
|
243
|
+
message: "open auth with auth.client requires static_token: true"
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
if (value.auth.mode === "open" &&
|
|
247
|
+
countTruthy([value.auth.client.token_env, value.auth.client.token_path]) !== 1) {
|
|
248
|
+
context.addIssue({
|
|
249
|
+
code: z.ZodIssueCode.custom,
|
|
250
|
+
message: "external open auth requires token_env or token_path"
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
if (value.auth.mode === "bearer") {
|
|
254
|
+
const sourceCount = countTruthy([
|
|
255
|
+
value.auth.client.token_id,
|
|
256
|
+
value.auth.client.token_env,
|
|
257
|
+
value.auth.client.token_path
|
|
258
|
+
]);
|
|
259
|
+
if (sourceCount !== 1 || !value.auth.client.token_env && !value.auth.client.token_path) {
|
|
260
|
+
context.addIssue({
|
|
261
|
+
code: z.ZodIssueCode.custom,
|
|
262
|
+
message: "external bearer auth requires exactly one external token source"
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
const teamNetworkServerSchema = z.discriminatedUnion("mode", [
|
|
268
|
+
teamNetworkManagedServerSchema,
|
|
269
|
+
teamNetworkExternalServerSchema
|
|
270
|
+
]);
|
|
271
|
+
const teamNetworkRoomSchema = z
|
|
272
|
+
.object({
|
|
273
|
+
id: z.string().trim().min(1),
|
|
274
|
+
members: z.array(z.string().trim().min(1)).min(1),
|
|
275
|
+
name: z.string().trim().min(1).optional()
|
|
276
|
+
})
|
|
277
|
+
.strict();
|
|
278
|
+
export const teamNetworkSchema = z
|
|
279
|
+
.object({
|
|
280
|
+
id: z.string().trim().min(1),
|
|
281
|
+
name: z.string().trim().min(1).optional(),
|
|
282
|
+
provider: z.literal("moltnet"),
|
|
283
|
+
rooms: z.array(teamNetworkRoomSchema).min(1),
|
|
284
|
+
server: teamNetworkServerSchema
|
|
285
|
+
})
|
|
286
|
+
.strict()
|
|
287
|
+
.superRefine((value, context) => {
|
|
288
|
+
const roomIds = value.rooms.map((room) => room.id);
|
|
289
|
+
if (new Set(roomIds).size !== roomIds.length) {
|
|
290
|
+
context.addIssue({
|
|
291
|
+
code: z.ZodIssueCode.custom,
|
|
292
|
+
message: `network ${value.id} declares duplicate room ids`
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const teamWorkspaceDocsSchema: z.ZodObject<{
|
|
3
|
+
extras: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
4
|
+
heartbeat: z.ZodOptional<z.ZodString>;
|
|
5
|
+
identity: z.ZodOptional<z.ZodString>;
|
|
6
|
+
memory: z.ZodOptional<z.ZodString>;
|
|
7
|
+
soul: z.ZodOptional<z.ZodString>;
|
|
8
|
+
system: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, z.core.$strict>;
|
|
10
|
+
declare const teamWorkspaceResourceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
11
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
12
|
+
id: z.ZodString;
|
|
13
|
+
kind: z.ZodLiteral<"git">;
|
|
14
|
+
mount: z.ZodString;
|
|
15
|
+
mode: z.ZodEnum<{
|
|
16
|
+
readonly: "readonly";
|
|
17
|
+
mutable: "mutable";
|
|
18
|
+
}>;
|
|
19
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
20
|
+
sharing: z.ZodOptional<z.ZodEnum<{
|
|
21
|
+
per_agent: "per_agent";
|
|
22
|
+
team: "team";
|
|
23
|
+
}>>;
|
|
24
|
+
tag: z.ZodOptional<z.ZodString>;
|
|
25
|
+
url: z.ZodString;
|
|
26
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
27
|
+
id: z.ZodString;
|
|
28
|
+
kind: z.ZodLiteral<"volume">;
|
|
29
|
+
mount: z.ZodString;
|
|
30
|
+
mode: z.ZodEnum<{
|
|
31
|
+
readonly: "readonly";
|
|
32
|
+
mutable: "mutable";
|
|
33
|
+
}>;
|
|
34
|
+
name: z.ZodOptional<z.ZodString>;
|
|
35
|
+
sharing: z.ZodOptional<z.ZodEnum<{
|
|
36
|
+
per_agent: "per_agent";
|
|
37
|
+
team: "team";
|
|
38
|
+
}>>;
|
|
39
|
+
}, z.core.$strict>], "kind">;
|
|
40
|
+
declare const workspaceSkillReferenceSchema: z.ZodObject<{
|
|
41
|
+
ref: z.ZodString;
|
|
42
|
+
requires: z.ZodOptional<z.ZodObject<{
|
|
43
|
+
mcp: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
44
|
+
}, z.core.$strict>>;
|
|
45
|
+
}, z.core.$strict>;
|
|
46
|
+
export declare const teamWorkspaceSchema: z.ZodObject<{
|
|
47
|
+
docs: z.ZodOptional<z.ZodObject<{
|
|
48
|
+
extras: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
49
|
+
heartbeat: z.ZodOptional<z.ZodString>;
|
|
50
|
+
identity: z.ZodOptional<z.ZodString>;
|
|
51
|
+
memory: z.ZodOptional<z.ZodString>;
|
|
52
|
+
soul: z.ZodOptional<z.ZodString>;
|
|
53
|
+
system: z.ZodOptional<z.ZodString>;
|
|
54
|
+
}, z.core.$strict>>;
|
|
55
|
+
resources: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
56
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
57
|
+
id: z.ZodString;
|
|
58
|
+
kind: z.ZodLiteral<"git">;
|
|
59
|
+
mount: z.ZodString;
|
|
60
|
+
mode: z.ZodEnum<{
|
|
61
|
+
readonly: "readonly";
|
|
62
|
+
mutable: "mutable";
|
|
63
|
+
}>;
|
|
64
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
65
|
+
sharing: z.ZodOptional<z.ZodEnum<{
|
|
66
|
+
per_agent: "per_agent";
|
|
67
|
+
team: "team";
|
|
68
|
+
}>>;
|
|
69
|
+
tag: z.ZodOptional<z.ZodString>;
|
|
70
|
+
url: z.ZodString;
|
|
71
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
72
|
+
id: z.ZodString;
|
|
73
|
+
kind: z.ZodLiteral<"volume">;
|
|
74
|
+
mount: z.ZodString;
|
|
75
|
+
mode: z.ZodEnum<{
|
|
76
|
+
readonly: "readonly";
|
|
77
|
+
mutable: "mutable";
|
|
78
|
+
}>;
|
|
79
|
+
name: z.ZodOptional<z.ZodString>;
|
|
80
|
+
sharing: z.ZodOptional<z.ZodEnum<{
|
|
81
|
+
per_agent: "per_agent";
|
|
82
|
+
team: "team";
|
|
83
|
+
}>>;
|
|
84
|
+
}, z.core.$strict>], "kind">>>;
|
|
85
|
+
skills: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
86
|
+
ref: z.ZodString;
|
|
87
|
+
requires: z.ZodOptional<z.ZodObject<{
|
|
88
|
+
mcp: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
89
|
+
}, z.core.$strict>>;
|
|
90
|
+
}, z.core.$strict>>>;
|
|
91
|
+
}, z.core.$strict>;
|
|
92
|
+
export type TeamWorkspace = z.infer<typeof teamWorkspaceSchema>;
|
|
93
|
+
export type TeamWorkspaceDocs = z.infer<typeof teamWorkspaceDocsSchema>;
|
|
94
|
+
export type TeamWorkspaceResource = z.infer<typeof teamWorkspaceResourceSchema>;
|
|
95
|
+
export type TeamWorkspaceSkill = z.infer<typeof workspaceSkillReferenceSchema>;
|
|
96
|
+
export {};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const workspaceResourceModeSchema = z.enum(["mutable", "readonly"]);
|
|
3
|
+
const workspaceResourceSharingSchema = z.enum(["per_agent", "team"]);
|
|
4
|
+
export const teamWorkspaceDocsSchema = z
|
|
5
|
+
.object({
|
|
6
|
+
extras: z.record(z.string(), z.string()).optional(),
|
|
7
|
+
heartbeat: z.string().min(1).optional(),
|
|
8
|
+
identity: z.string().min(1).optional(),
|
|
9
|
+
memory: z.string().min(1).optional(),
|
|
10
|
+
soul: z.string().min(1).optional(),
|
|
11
|
+
system: z.string().min(1).optional()
|
|
12
|
+
})
|
|
13
|
+
.strict();
|
|
14
|
+
const normalizeMount = (value) => {
|
|
15
|
+
const trimmed = value.trim();
|
|
16
|
+
const workspaceRelative = trimmed.startsWith("${workspace}/")
|
|
17
|
+
? `./${trimmed.slice("${workspace}/".length)}`
|
|
18
|
+
: trimmed;
|
|
19
|
+
const collapsed = workspaceRelative.replace(/\/+/g, "/");
|
|
20
|
+
if (collapsed.startsWith("./")) {
|
|
21
|
+
const relativePath = collapsed.slice(2).replace(/\/+$/u, "");
|
|
22
|
+
return `./${relativePath}`;
|
|
23
|
+
}
|
|
24
|
+
return collapsed.length > 1 ? collapsed.replace(/\/+$/u, "") : "/";
|
|
25
|
+
};
|
|
26
|
+
const mountHasParentSegment = (value) => value.split("/").some((segment) => segment === "..");
|
|
27
|
+
const resourceMountSchema = z
|
|
28
|
+
.string()
|
|
29
|
+
.trim()
|
|
30
|
+
.min(1)
|
|
31
|
+
.superRefine((value, context) => {
|
|
32
|
+
const normalized = normalizeMount(value);
|
|
33
|
+
if (mountHasParentSegment(normalized)) {
|
|
34
|
+
context.addIssue({
|
|
35
|
+
code: z.ZodIssueCode.custom,
|
|
36
|
+
message: "mount must not contain parent path segments"
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (normalized === "." || normalized === "./" || normalized === "${workspace}") {
|
|
40
|
+
context.addIssue({
|
|
41
|
+
code: z.ZodIssueCode.custom,
|
|
42
|
+
message: "mount must point inside the workspace, not at the workspace root"
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
if (!normalized.startsWith("/") &&
|
|
46
|
+
!normalized.startsWith("./") &&
|
|
47
|
+
!normalized.startsWith("${workspace}/")) {
|
|
48
|
+
context.addIssue({
|
|
49
|
+
code: z.ZodIssueCode.custom,
|
|
50
|
+
message: "mount must be an absolute POSIX path, ./ workspace path, or ${workspace}/ path"
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
const teamWorkspaceResourceGitSchema = z
|
|
55
|
+
.object({
|
|
56
|
+
branch: z.string().trim().optional(),
|
|
57
|
+
id: z.string().trim().min(1),
|
|
58
|
+
kind: z.literal("git"),
|
|
59
|
+
mount: resourceMountSchema,
|
|
60
|
+
mode: workspaceResourceModeSchema,
|
|
61
|
+
ref: z.string().trim().optional(),
|
|
62
|
+
sharing: workspaceResourceSharingSchema.optional(),
|
|
63
|
+
tag: z.string().trim().optional(),
|
|
64
|
+
url: z.string().trim().min(1)
|
|
65
|
+
})
|
|
66
|
+
.strict()
|
|
67
|
+
.superRefine((value, context) => {
|
|
68
|
+
const selectors = [value.branch, value.tag, value.ref].filter(Boolean).length;
|
|
69
|
+
if (selectors > 1) {
|
|
70
|
+
context.addIssue({
|
|
71
|
+
code: z.ZodIssueCode.custom,
|
|
72
|
+
message: "git resources may declare at most one of branch, tag, or ref"
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (value.sharing === "team") {
|
|
76
|
+
context.addIssue({
|
|
77
|
+
code: z.ZodIssueCode.custom,
|
|
78
|
+
message: "git resources do not support team sharing"
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
const teamWorkspaceResourceVolumeSchema = z
|
|
83
|
+
.object({
|
|
84
|
+
id: z.string().trim().min(1),
|
|
85
|
+
kind: z.literal("volume"),
|
|
86
|
+
mount: resourceMountSchema,
|
|
87
|
+
mode: workspaceResourceModeSchema,
|
|
88
|
+
name: z.string().trim().optional(),
|
|
89
|
+
sharing: workspaceResourceSharingSchema.optional()
|
|
90
|
+
})
|
|
91
|
+
.strict();
|
|
92
|
+
const teamWorkspaceResourceSchema = z.discriminatedUnion("kind", [
|
|
93
|
+
teamWorkspaceResourceGitSchema,
|
|
94
|
+
teamWorkspaceResourceVolumeSchema
|
|
95
|
+
]);
|
|
96
|
+
const workspaceSkillRequirementSchema = z
|
|
97
|
+
.object({
|
|
98
|
+
mcp: z.array(z.string()).optional()
|
|
99
|
+
})
|
|
100
|
+
.strict();
|
|
101
|
+
const workspaceSkillReferenceSchema = z
|
|
102
|
+
.object({
|
|
103
|
+
ref: z.string(),
|
|
104
|
+
requires: workspaceSkillRequirementSchema.optional()
|
|
105
|
+
})
|
|
106
|
+
.strict();
|
|
107
|
+
export const teamWorkspaceSchema = z
|
|
108
|
+
.object({
|
|
109
|
+
docs: teamWorkspaceDocsSchema.optional(),
|
|
110
|
+
resources: z.array(teamWorkspaceResourceSchema).optional(),
|
|
111
|
+
skills: z.array(workspaceSkillReferenceSchema).optional()
|
|
112
|
+
})
|
|
113
|
+
.strict()
|
|
114
|
+
.superRefine((value, context) => {
|
|
115
|
+
const resources = value.resources;
|
|
116
|
+
if (!resources || resources.length === 0) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const normalizeResourceIdentity = (resource) => {
|
|
120
|
+
if (resource.kind === "git") {
|
|
121
|
+
return JSON.stringify({
|
|
122
|
+
branch: resource.branch?.trim() ?? "",
|
|
123
|
+
kind: "git",
|
|
124
|
+
mode: resource.mode,
|
|
125
|
+
mount: normalizeMount(resource.mount),
|
|
126
|
+
ref: resource.ref?.trim() ?? "",
|
|
127
|
+
sharing: resource.sharing ?? "per_agent",
|
|
128
|
+
tag: resource.tag?.trim() ?? "",
|
|
129
|
+
url: resource.url
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return JSON.stringify({
|
|
133
|
+
kind: "volume",
|
|
134
|
+
mode: resource.mode,
|
|
135
|
+
mount: normalizeMount(resource.mount),
|
|
136
|
+
name: resource.name?.trim() ?? "",
|
|
137
|
+
sharing: resource.sharing ?? "per_agent"
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
for (let leftIndex = 0; leftIndex < resources.length; leftIndex += 1) {
|
|
141
|
+
const leftResource = resources[leftIndex];
|
|
142
|
+
const leftNormalizedIdentity = normalizeResourceIdentity(leftResource);
|
|
143
|
+
const leftMount = normalizeMount(leftResource.mount);
|
|
144
|
+
for (let rightIndex = leftIndex + 1; rightIndex < resources.length; rightIndex += 1) {
|
|
145
|
+
const rightResource = resources[rightIndex];
|
|
146
|
+
const rightNormalizedIdentity = normalizeResourceIdentity(rightResource);
|
|
147
|
+
const rightMount = normalizeMount(rightResource.mount);
|
|
148
|
+
if (leftResource.id === rightResource.id && leftNormalizedIdentity !== rightNormalizedIdentity) {
|
|
149
|
+
context.addIssue({
|
|
150
|
+
code: z.ZodIssueCode.custom,
|
|
151
|
+
message: `resource id ${leftResource.id} must use identical resource declarations`
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
if (leftMount === rightMount ||
|
|
155
|
+
leftMount.startsWith(`${rightMount}/`) ||
|
|
156
|
+
rightMount.startsWith(`${leftMount}/`)) {
|
|
157
|
+
if (leftResource.id !== rightResource.id) {
|
|
158
|
+
context.addIssue({
|
|
159
|
+
code: z.ZodIssueCode.custom,
|
|
160
|
+
message: `resources ${leftResource.id} and ${rightResource.id} use overlapping mounts`
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
});
|
package/dist/report/types.d.ts
CHANGED
|
@@ -18,6 +18,15 @@ export interface ContainerRuntimeInstanceReport {
|
|
|
18
18
|
model_secrets_required: string[];
|
|
19
19
|
runtime: string;
|
|
20
20
|
}
|
|
21
|
+
export interface ContainerWorkspaceResourceReport {
|
|
22
|
+
backing_path: string;
|
|
23
|
+
id: string;
|
|
24
|
+
kind: "git" | "volume";
|
|
25
|
+
link_path: string;
|
|
26
|
+
mode: "mutable" | "readonly";
|
|
27
|
+
mount: string;
|
|
28
|
+
sharing: "per_agent" | "team";
|
|
29
|
+
}
|
|
21
30
|
export interface NodeReport {
|
|
22
31
|
capabilities: CapabilityReport[];
|
|
23
32
|
diagnostics: DiagnosticReport[];
|
|
@@ -40,6 +49,7 @@ export interface ContainerReport {
|
|
|
40
49
|
runtime_secrets_required: string[];
|
|
41
50
|
runtimes_installed: string[];
|
|
42
51
|
secrets_required: string[];
|
|
52
|
+
workspace_resources?: ContainerWorkspaceResourceReport[];
|
|
43
53
|
}
|
|
44
54
|
export interface CompileReport {
|
|
45
55
|
container?: ContainerReport;
|
package/dist/runtime/common.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare const createSkillFiles: (baseDirectory: string, skills: ResolvedS
|
|
|
8
8
|
export declare const createAgentCapabilities: (node: ResolvedAgentNode, options?: {
|
|
9
9
|
mcpOutcome?: CapabilityReport["outcome"];
|
|
10
10
|
sandboxOutcome?: CapabilityReport["outcome"];
|
|
11
|
+
scheduleMessage?: string;
|
|
12
|
+
scheduleOutcome?: CapabilityReport["outcome"];
|
|
11
13
|
subagentOutcome?: CapabilityReport["outcome"];
|
|
12
|
-
workspaceOutcome?: CapabilityReport["outcome"];
|
|
13
14
|
}) => CapabilityReport[];
|
package/dist/runtime/common.js
CHANGED
|
@@ -38,12 +38,12 @@ export const createAgentCapabilities = (node, options = {}) => {
|
|
|
38
38
|
if (node.execution?.model) {
|
|
39
39
|
capabilities.push(createCapability("execution.model", "supported"));
|
|
40
40
|
}
|
|
41
|
-
if (node.execution?.workspace) {
|
|
42
|
-
capabilities.push(createCapability("execution.workspace", options.workspaceOutcome ?? "supported"));
|
|
43
|
-
}
|
|
44
41
|
if (node.execution?.sandbox) {
|
|
45
42
|
capabilities.push(createCapability("execution.sandbox", options.sandboxOutcome ?? "supported"));
|
|
46
43
|
}
|
|
44
|
+
if (node.schedule) {
|
|
45
|
+
capabilities.push(createCapability("agent.schedule", options.scheduleOutcome ?? "degraded", options.scheduleMessage ?? "Schedule intent is validated but no runtime scheduler is emitted yet"));
|
|
46
|
+
}
|
|
47
47
|
if (node.surfaces?.discord) {
|
|
48
48
|
capabilities.push(createCapability("surfaces.discord", "supported"));
|
|
49
49
|
}
|
|
@@ -47,6 +47,13 @@ const buildModelList = (node) => {
|
|
|
47
47
|
model_name: target.name
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
+
if (target.provider === "openai" && target.auth.method === "codex") {
|
|
51
|
+
return {
|
|
52
|
+
model: `codex-cli/${target.name}`,
|
|
53
|
+
model_name: target.name,
|
|
54
|
+
workspace: "<workspace-path>"
|
|
55
|
+
};
|
|
56
|
+
}
|
|
50
57
|
return {
|
|
51
58
|
...(target.auth.method === "api_key"
|
|
52
59
|
? {
|