spawnfile 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 +4 -48
- 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 +34 -24
- 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/surfaces.d.ts +3 -13
- package/dist/compiler/surfaces.js +1 -6
- package/dist/compiler/syncProjectAuth.js +14 -0
- 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/filesystem/paths.js +1 -10
- 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/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,140 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const modelAuthMethodSchema = z.enum(["api_key", "claude-code", "codex", "none"]);
|
|
3
|
+
const modelEndpointCompatibilitySchema = z.enum(["anthropic", "openai"]);
|
|
4
|
+
const modelAuthSchema = z
|
|
5
|
+
.object({
|
|
6
|
+
method: modelAuthMethodSchema.optional(),
|
|
7
|
+
methods: z.record(z.string(), modelAuthMethodSchema).optional()
|
|
8
|
+
})
|
|
9
|
+
.strict()
|
|
10
|
+
.superRefine((value, context) => {
|
|
11
|
+
if (!value.method && !value.methods) {
|
|
12
|
+
context.addIssue({
|
|
13
|
+
code: z.ZodIssueCode.custom,
|
|
14
|
+
message: "model auth must declare method or methods"
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
if (value.method && value.methods) {
|
|
18
|
+
context.addIssue({
|
|
19
|
+
code: z.ZodIssueCode.custom,
|
|
20
|
+
message: "model auth must not declare both method and methods"
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
if (value.methods && Object.keys(value.methods).length === 0) {
|
|
24
|
+
context.addIssue({
|
|
25
|
+
code: z.ZodIssueCode.custom,
|
|
26
|
+
message: "model auth methods must not be empty"
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
export const modelEntryAuthSchema = z
|
|
31
|
+
.object({
|
|
32
|
+
key: z.string().optional(),
|
|
33
|
+
method: modelAuthMethodSchema.optional()
|
|
34
|
+
})
|
|
35
|
+
.strict()
|
|
36
|
+
.superRefine((value, context) => {
|
|
37
|
+
if (!value.method) {
|
|
38
|
+
context.addIssue({
|
|
39
|
+
code: z.ZodIssueCode.custom,
|
|
40
|
+
message: "model auth must declare method"
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (value.key && value.method !== "api_key") {
|
|
44
|
+
context.addIssue({
|
|
45
|
+
code: z.ZodIssueCode.custom,
|
|
46
|
+
message: "model auth key is only valid for api_key auth"
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
export const modelEndpointSchema = z
|
|
51
|
+
.object({
|
|
52
|
+
base_url: z.string().min(1),
|
|
53
|
+
compatibility: modelEndpointCompatibilitySchema
|
|
54
|
+
})
|
|
55
|
+
.strict();
|
|
56
|
+
export const modelTargetSchema = z
|
|
57
|
+
.object({
|
|
58
|
+
auth: modelEntryAuthSchema.optional(),
|
|
59
|
+
endpoint: modelEndpointSchema.optional(),
|
|
60
|
+
name: z.string(),
|
|
61
|
+
provider: z.string()
|
|
62
|
+
})
|
|
63
|
+
.strict()
|
|
64
|
+
.superRefine((value, context) => {
|
|
65
|
+
const usesCustomEndpoint = value.provider === "custom" || value.provider === "local";
|
|
66
|
+
if (usesCustomEndpoint && !value.endpoint) {
|
|
67
|
+
context.addIssue({
|
|
68
|
+
code: z.ZodIssueCode.custom,
|
|
69
|
+
message: `${value.provider} models must declare endpoint`
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (!usesCustomEndpoint && value.endpoint) {
|
|
73
|
+
context.addIssue({
|
|
74
|
+
code: z.ZodIssueCode.custom,
|
|
75
|
+
message: "endpoint is only valid for custom or local models"
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
export const executionSchema = z
|
|
80
|
+
.object({
|
|
81
|
+
model: z
|
|
82
|
+
.object({
|
|
83
|
+
auth: modelAuthSchema.optional(),
|
|
84
|
+
fallback: z.array(modelTargetSchema).optional(),
|
|
85
|
+
primary: modelTargetSchema
|
|
86
|
+
})
|
|
87
|
+
.superRefine((value, context) => {
|
|
88
|
+
const declaredProviders = new Set([
|
|
89
|
+
value.primary.provider,
|
|
90
|
+
...(value.fallback ?? []).map((model) => model.provider)
|
|
91
|
+
]);
|
|
92
|
+
if (value.auth?.methods) {
|
|
93
|
+
for (const provider of declaredProviders) {
|
|
94
|
+
if (!(provider in value.auth.methods)) {
|
|
95
|
+
context.addIssue({
|
|
96
|
+
code: z.ZodIssueCode.custom,
|
|
97
|
+
message: `model auth methods must declare provider ${provider}`
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
for (const provider of Object.keys(value.auth.methods)) {
|
|
102
|
+
if (!declaredProviders.has(provider)) {
|
|
103
|
+
context.addIssue({
|
|
104
|
+
code: z.ZodIssueCode.custom,
|
|
105
|
+
message: `model auth methods declared unknown provider ${provider}`
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
for (const target of [value.primary, ...(value.fallback ?? [])]) {
|
|
111
|
+
const method = target.auth?.method ??
|
|
112
|
+
value.auth?.methods?.[target.provider] ??
|
|
113
|
+
value.auth?.method ??
|
|
114
|
+
(target.provider === "local" ? "none" : undefined);
|
|
115
|
+
if (target.provider === "custom" && !method) {
|
|
116
|
+
context.addIssue({
|
|
117
|
+
code: z.ZodIssueCode.custom,
|
|
118
|
+
message: "custom models must declare auth.method or inherit legacy model auth"
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if ((target.provider === "custom" || target.provider === "local") &&
|
|
122
|
+
method === "api_key" &&
|
|
123
|
+
!target.auth?.key) {
|
|
124
|
+
context.addIssue({
|
|
125
|
+
code: z.ZodIssueCode.custom,
|
|
126
|
+
message: `${target.provider} api_key auth must declare auth.key`
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
.strict()
|
|
132
|
+
.optional(),
|
|
133
|
+
sandbox: z
|
|
134
|
+
.object({
|
|
135
|
+
mode: z.enum(["sandboxed", "unrestricted", "workspace"])
|
|
136
|
+
})
|
|
137
|
+
.strict()
|
|
138
|
+
.optional()
|
|
139
|
+
})
|
|
140
|
+
.strict();
|
|
@@ -30,8 +30,7 @@ const assertMarkdownDocumentPath = (documentPath) => {
|
|
|
30
30
|
throw new SpawnfileError("validation_error", `Document paths must point to Markdown files: ${documentPath}`);
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
|
-
const validateDocFiles = async (manifestPath,
|
|
34
|
-
const docs = manifest.docs;
|
|
33
|
+
const validateDocFiles = async (manifestPath, docs) => {
|
|
35
34
|
if (!docs) {
|
|
36
35
|
return;
|
|
37
36
|
}
|
|
@@ -86,21 +85,25 @@ const validateSkills = async (manifestPath, skills) => {
|
|
|
86
85
|
}));
|
|
87
86
|
};
|
|
88
87
|
const validateLocalAgentManifest = async (manifestPath, manifest) => {
|
|
89
|
-
|
|
88
|
+
const agentWorkspaceSkills = manifest.workspace?.skills;
|
|
89
|
+
const agentEnvironment = manifest.environment;
|
|
90
|
+
ensureUniqueNames((agentEnvironment?.mcp_servers ?? []).map((server) => server.name), "MCP server");
|
|
90
91
|
ensureUniqueNames((manifest.subagents ?? []).map((subagent) => subagent.id), "subagent id");
|
|
91
|
-
await validateDocFiles(manifestPath, manifest);
|
|
92
|
-
await validateSkills(manifestPath,
|
|
92
|
+
await validateDocFiles(manifestPath, manifest.workspace?.docs);
|
|
93
|
+
await validateSkills(manifestPath, agentWorkspaceSkills);
|
|
93
94
|
await validateManifestRefs(manifestPath, manifest.subagents?.map((subagent) => subagent.ref), "Subagent");
|
|
94
|
-
validateSkillRequirements(
|
|
95
|
+
validateSkillRequirements(agentWorkspaceSkills, getMcpNames(agentEnvironment?.mcp_servers));
|
|
95
96
|
};
|
|
96
|
-
const getSharedMcpNames = (shared) => getMcpNames(shared?.mcp_servers);
|
|
97
|
+
const getSharedMcpNames = (shared) => getMcpNames(shared?.environment?.mcp_servers);
|
|
97
98
|
const validateLocalTeamManifest = async (manifestPath, manifest) => {
|
|
98
|
-
|
|
99
|
+
const sharedWorkspace = manifest.shared?.workspace;
|
|
100
|
+
const sharedEnvironment = manifest.shared?.environment;
|
|
101
|
+
ensureUniqueNames((sharedEnvironment?.mcp_servers ?? []).map((server) => server.name), "MCP server");
|
|
99
102
|
ensureUniqueNames(manifest.members.map((member) => member.id), "member id");
|
|
100
|
-
await validateDocFiles(manifestPath,
|
|
101
|
-
await validateSkills(manifestPath,
|
|
103
|
+
await validateDocFiles(manifestPath, sharedWorkspace?.docs);
|
|
104
|
+
await validateSkills(manifestPath, sharedWorkspace?.skills);
|
|
102
105
|
await validateManifestRefs(manifestPath, manifest.members.map((member) => member.ref), "Member");
|
|
103
|
-
validateSkillRequirements(
|
|
106
|
+
validateSkillRequirements(sharedWorkspace?.skills, getSharedMcpNames(manifest.shared));
|
|
104
107
|
const memberIds = new Set(manifest.members.map((member) => member.id));
|
|
105
108
|
if (manifest.lead && !memberIds.has(manifest.lead)) {
|
|
106
109
|
throw new SpawnfileError("validation_error", `Lead is not a declared team member: ${manifest.lead}`);
|
|
@@ -172,15 +175,6 @@ export const mergeExecution = (parentExecution, childExecution) => {
|
|
|
172
175
|
if (sandbox && !sandbox.mode) {
|
|
173
176
|
throw new SpawnfileError("validation_error", "Merged execution sandbox is missing mode");
|
|
174
177
|
}
|
|
175
|
-
const workspace = parentExecution.workspace || childExecution.workspace
|
|
176
|
-
? {
|
|
177
|
-
...parentExecution.workspace,
|
|
178
|
-
...childExecution.workspace
|
|
179
|
-
}
|
|
180
|
-
: undefined;
|
|
181
|
-
if (workspace && !workspace.isolation) {
|
|
182
|
-
throw new SpawnfileError("validation_error", "Merged execution workspace is missing isolation");
|
|
183
|
-
}
|
|
184
178
|
const resolvedModel = model
|
|
185
179
|
? {
|
|
186
180
|
auth: model.auth,
|
|
@@ -193,16 +187,10 @@ export const mergeExecution = (parentExecution, childExecution) => {
|
|
|
193
187
|
mode: sandbox.mode
|
|
194
188
|
}
|
|
195
189
|
: undefined;
|
|
196
|
-
const resolvedWorkspace = workspace
|
|
197
|
-
? {
|
|
198
|
-
isolation: workspace.isolation
|
|
199
|
-
}
|
|
200
|
-
: undefined;
|
|
201
190
|
return {
|
|
202
191
|
...parentExecution,
|
|
203
192
|
...childExecution,
|
|
204
193
|
model: resolvedModel,
|
|
205
|
-
sandbox: resolvedSandbox
|
|
206
|
-
workspace: resolvedWorkspace
|
|
194
|
+
sandbox: resolvedSandbox
|
|
207
195
|
};
|
|
208
196
|
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import YAML from "yaml";
|
|
2
|
+
import { orderTeamNetworks } from "./renderSpawnfileNetworks.js";
|
|
3
|
+
import { orderWorkspace } from "./renderSpawnfileWorkspace.js";
|
|
2
4
|
const withDefinedEntries = (entries) => Object.fromEntries(entries.filter((entry) => entry[1] !== undefined));
|
|
3
5
|
const hasEntries = (value) => Object.keys(value).length > 0;
|
|
4
6
|
const orderRuntimeBinding = (runtime) => {
|
|
@@ -10,19 +12,6 @@ const orderRuntimeBinding = (runtime) => {
|
|
|
10
12
|
["options", runtime.options]
|
|
11
13
|
]);
|
|
12
14
|
};
|
|
13
|
-
const orderDocs = (docs) => {
|
|
14
|
-
if (!docs) {
|
|
15
|
-
return undefined;
|
|
16
|
-
}
|
|
17
|
-
return withDefinedEntries([
|
|
18
|
-
["identity", docs.identity],
|
|
19
|
-
["soul", docs.soul],
|
|
20
|
-
["system", docs.system],
|
|
21
|
-
["memory", docs.memory],
|
|
22
|
-
["heartbeat", docs.heartbeat],
|
|
23
|
-
["extras", docs.extras]
|
|
24
|
-
]);
|
|
25
|
-
};
|
|
26
15
|
const orderDiscordSurface = (surface) => {
|
|
27
16
|
if (!surface) {
|
|
28
17
|
return undefined;
|
|
@@ -180,19 +169,49 @@ const orderExecution = (execution) => {
|
|
|
180
169
|
])
|
|
181
170
|
: undefined
|
|
182
171
|
],
|
|
183
|
-
["workspace", execution.workspace],
|
|
184
172
|
["sandbox", execution.sandbox]
|
|
185
173
|
]);
|
|
186
174
|
};
|
|
175
|
+
const orderAgentSchedule = (schedule) => {
|
|
176
|
+
if (!schedule) {
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
if (schedule.kind === "cron") {
|
|
180
|
+
return withDefinedEntries([
|
|
181
|
+
["kind", schedule.kind],
|
|
182
|
+
["cron", schedule.cron],
|
|
183
|
+
["timezone", schedule.timezone],
|
|
184
|
+
["prompt", schedule.prompt]
|
|
185
|
+
]);
|
|
186
|
+
}
|
|
187
|
+
if (schedule.kind === "every") {
|
|
188
|
+
return withDefinedEntries([
|
|
189
|
+
["kind", schedule.kind],
|
|
190
|
+
["every", schedule.every],
|
|
191
|
+
["timezone", schedule.timezone],
|
|
192
|
+
["prompt", schedule.prompt]
|
|
193
|
+
]);
|
|
194
|
+
}
|
|
195
|
+
return { kind: schedule.kind };
|
|
196
|
+
};
|
|
197
|
+
const orderEnvironment = (environment) => {
|
|
198
|
+
if (!environment) {
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
return withDefinedEntries([
|
|
202
|
+
["env", environment.env],
|
|
203
|
+
["secrets", environment.secrets],
|
|
204
|
+
["packages", environment.packages],
|
|
205
|
+
["mcp_servers", environment.mcp_servers]
|
|
206
|
+
]);
|
|
207
|
+
};
|
|
187
208
|
const orderSharedSurface = (shared) => {
|
|
188
209
|
if (!shared) {
|
|
189
210
|
return undefined;
|
|
190
211
|
}
|
|
191
212
|
return withDefinedEntries([
|
|
192
|
-
["
|
|
193
|
-
["
|
|
194
|
-
["secrets", shared.secrets],
|
|
195
|
-
["skills", shared.skills]
|
|
213
|
+
["workspace", orderWorkspace(shared.workspace)],
|
|
214
|
+
["environment", orderEnvironment(shared.environment)]
|
|
196
215
|
]);
|
|
197
216
|
};
|
|
198
217
|
const orderSurfaces = (surfaces) => {
|
|
@@ -208,19 +227,6 @@ const orderSurfaces = (surfaces) => {
|
|
|
208
227
|
["moltnet", orderMoltnetSurface(surfaces.moltnet)]
|
|
209
228
|
]);
|
|
210
229
|
};
|
|
211
|
-
const orderTeamNetworks = (networks) => networks?.map((network) => withDefinedEntries([
|
|
212
|
-
["id", network.id],
|
|
213
|
-
["provider", network.provider],
|
|
214
|
-
["name", network.name],
|
|
215
|
-
["expose", network.expose],
|
|
216
|
-
[
|
|
217
|
-
"rooms",
|
|
218
|
-
network.rooms.map((room) => withDefinedEntries([
|
|
219
|
-
["id", room.id],
|
|
220
|
-
["members", room.members]
|
|
221
|
-
]))
|
|
222
|
-
]
|
|
223
|
-
]));
|
|
224
230
|
const renderSections = (sections) => sections
|
|
225
231
|
.filter(hasEntries)
|
|
226
232
|
.map((section) => YAML.stringify(section))
|
|
@@ -234,15 +240,11 @@ const orderAgentManifestSections = (manifest) => [
|
|
|
234
240
|
]),
|
|
235
241
|
withDefinedEntries([["runtime", orderRuntimeBinding(manifest.runtime)]]),
|
|
236
242
|
withDefinedEntries([["execution", orderExecution(manifest.execution)]]),
|
|
237
|
-
withDefinedEntries([["
|
|
243
|
+
withDefinedEntries([["schedule", orderAgentSchedule(manifest.schedule)]]),
|
|
244
|
+
withDefinedEntries([["workspace", orderWorkspace(manifest.workspace)]]),
|
|
245
|
+
withDefinedEntries([["environment", orderEnvironment(manifest.environment)]]),
|
|
238
246
|
withDefinedEntries([["surfaces", orderSurfaces(manifest.surfaces)]]),
|
|
239
|
-
withDefinedEntries([
|
|
240
|
-
["skills", manifest.skills],
|
|
241
|
-
["mcp_servers", manifest.mcp_servers],
|
|
242
|
-
["secrets", manifest.secrets],
|
|
243
|
-
["env", manifest.env],
|
|
244
|
-
["policy", manifest.policy]
|
|
245
|
-
]),
|
|
247
|
+
withDefinedEntries([["policy", manifest.policy]]),
|
|
246
248
|
withDefinedEntries([["subagents", manifest.subagents]])
|
|
247
249
|
];
|
|
248
250
|
const orderTeamManifestSections = (manifest) => [
|
|
@@ -251,20 +253,10 @@ const orderTeamManifestSections = (manifest) => [
|
|
|
251
253
|
["kind", manifest.kind],
|
|
252
254
|
["name", manifest.name]
|
|
253
255
|
]),
|
|
254
|
-
withDefinedEntries([["runtime", orderRuntimeBinding(manifest.runtime)]]),
|
|
255
256
|
withDefinedEntries([["execution", orderExecution(manifest.execution)]]),
|
|
256
|
-
withDefinedEntries([
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
["networks", orderTeamNetworks(manifest.networks)]
|
|
260
|
-
]),
|
|
261
|
-
withDefinedEntries([
|
|
262
|
-
["skills", manifest.skills],
|
|
263
|
-
["mcp_servers", manifest.mcp_servers],
|
|
264
|
-
["secrets", manifest.secrets],
|
|
265
|
-
["env", manifest.env],
|
|
266
|
-
["policy", manifest.policy]
|
|
267
|
-
]),
|
|
257
|
+
withDefinedEntries([["shared", orderSharedSurface(manifest.shared)]]),
|
|
258
|
+
withDefinedEntries([["networks", orderTeamNetworks(manifest.networks)]]),
|
|
259
|
+
withDefinedEntries([["policy", manifest.policy]]),
|
|
268
260
|
withDefinedEntries([
|
|
269
261
|
["members", manifest.members],
|
|
270
262
|
["mode", manifest.mode],
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const withDefinedEntries = (entries) => Object.fromEntries(entries.filter((entry) => entry[1] !== undefined));
|
|
2
|
+
const orderTeamAuthToken = (token) => withDefinedEntries([
|
|
3
|
+
["id", token.id],
|
|
4
|
+
["agents", token.agents],
|
|
5
|
+
["scopes", token.scopes]
|
|
6
|
+
]);
|
|
7
|
+
const orderTeamAuthPairing = (pairing) => withDefinedEntries([
|
|
8
|
+
["id", pairing.id],
|
|
9
|
+
["remote_base_url", pairing.remote_base_url],
|
|
10
|
+
["remote_network_id", pairing.remote_network_id],
|
|
11
|
+
["remote_network_name", pairing.remote_network_name]
|
|
12
|
+
]);
|
|
13
|
+
const orderTeamAuth = (server) => withDefinedEntries([
|
|
14
|
+
["mode", server.mode],
|
|
15
|
+
["url", server.url],
|
|
16
|
+
["listen", server.mode === "managed" ? server.listen : undefined],
|
|
17
|
+
[
|
|
18
|
+
"auth",
|
|
19
|
+
withDefinedEntries([
|
|
20
|
+
["mode", server.auth.mode],
|
|
21
|
+
["tokens", server.auth.tokens?.map(orderTeamAuthToken)],
|
|
22
|
+
[
|
|
23
|
+
"client",
|
|
24
|
+
server.auth.client
|
|
25
|
+
? withDefinedEntries([
|
|
26
|
+
["static_token", server.auth.client.static_token],
|
|
27
|
+
["token_id", server.auth.client.token_id],
|
|
28
|
+
["token_env", server.auth.client.token_env],
|
|
29
|
+
["token_path", server.auth.client.token_path]
|
|
30
|
+
])
|
|
31
|
+
: undefined
|
|
32
|
+
]
|
|
33
|
+
])
|
|
34
|
+
],
|
|
35
|
+
["store", server.mode === "managed" ? server.store : undefined],
|
|
36
|
+
[
|
|
37
|
+
"pairings",
|
|
38
|
+
server.mode === "managed" && server.pairings
|
|
39
|
+
? server.pairings.map(orderTeamAuthPairing)
|
|
40
|
+
: undefined
|
|
41
|
+
],
|
|
42
|
+
["human_ingress", server.mode === "managed" ? server.human_ingress : undefined],
|
|
43
|
+
["direct_messages", server.mode === "managed" ? server.direct_messages : undefined],
|
|
44
|
+
[
|
|
45
|
+
"trust_forwarded_proto",
|
|
46
|
+
server.mode === "managed" ? server.trust_forwarded_proto : undefined
|
|
47
|
+
],
|
|
48
|
+
["allowed_origins", server.mode === "managed" ? server.allowed_origins : undefined]
|
|
49
|
+
]);
|
|
50
|
+
export const orderTeamNetworks = (networks) => networks?.map((network) => withDefinedEntries([
|
|
51
|
+
["id", network.id],
|
|
52
|
+
["provider", network.provider],
|
|
53
|
+
["name", network.name],
|
|
54
|
+
["server", orderTeamAuth(network.server)],
|
|
55
|
+
[
|
|
56
|
+
"rooms",
|
|
57
|
+
network.rooms.map((room) => withDefinedEntries([
|
|
58
|
+
["id", room.id],
|
|
59
|
+
["name", room.name],
|
|
60
|
+
["members", room.members]
|
|
61
|
+
]))
|
|
62
|
+
]
|
|
63
|
+
]));
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const withDefinedEntries = (entries) => Object.fromEntries(entries.filter((entry) => entry[1] !== undefined));
|
|
2
|
+
const orderDocs = (docs) => {
|
|
3
|
+
if (!docs) {
|
|
4
|
+
return undefined;
|
|
5
|
+
}
|
|
6
|
+
return withDefinedEntries([
|
|
7
|
+
["identity", docs.identity],
|
|
8
|
+
["soul", docs.soul],
|
|
9
|
+
["system", docs.system],
|
|
10
|
+
["memory", docs.memory],
|
|
11
|
+
["heartbeat", docs.heartbeat],
|
|
12
|
+
["extras", docs.extras]
|
|
13
|
+
]);
|
|
14
|
+
};
|
|
15
|
+
const orderWorkspaceResource = (resource) => {
|
|
16
|
+
if (resource.kind === "git") {
|
|
17
|
+
return withDefinedEntries([
|
|
18
|
+
["id", resource.id],
|
|
19
|
+
["kind", resource.kind],
|
|
20
|
+
["url", resource.url],
|
|
21
|
+
["branch", resource.branch],
|
|
22
|
+
["ref", resource.ref],
|
|
23
|
+
["tag", resource.tag],
|
|
24
|
+
["mount", resource.mount],
|
|
25
|
+
["mode", resource.mode],
|
|
26
|
+
["sharing", resource.sharing]
|
|
27
|
+
]);
|
|
28
|
+
}
|
|
29
|
+
return withDefinedEntries([
|
|
30
|
+
["id", resource.id],
|
|
31
|
+
["kind", resource.kind],
|
|
32
|
+
["mount", resource.mount],
|
|
33
|
+
["mode", resource.mode],
|
|
34
|
+
["name", resource.name],
|
|
35
|
+
["sharing", resource.sharing]
|
|
36
|
+
]);
|
|
37
|
+
};
|
|
38
|
+
export const orderWorkspace = (workspace) => {
|
|
39
|
+
if (!workspace) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
return withDefinedEntries([
|
|
43
|
+
["docs", orderDocs(workspace.docs)],
|
|
44
|
+
["resources", workspace.resources?.map(orderWorkspaceResource)],
|
|
45
|
+
["skills", workspace.skills]
|
|
46
|
+
]);
|
|
47
|
+
};
|
|
@@ -20,10 +20,12 @@ export const createAgentScaffoldManifest = (options) => {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
workspace: {
|
|
24
|
+
docs: {
|
|
25
|
+
...(options.docs.identity ? { identity: options.docs.identity } : {}),
|
|
26
|
+
...(options.docs.soul ? { soul: options.docs.soul } : {}),
|
|
27
|
+
system: options.docs.system
|
|
28
|
+
}
|
|
27
29
|
}
|
|
28
30
|
};
|
|
29
31
|
};
|
|
@@ -31,8 +33,12 @@ export const createTeamScaffoldManifest = () => ({
|
|
|
31
33
|
spawnfile_version: "0.1",
|
|
32
34
|
kind: "team",
|
|
33
35
|
name: "my-team",
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
shared: {
|
|
37
|
+
workspace: {
|
|
38
|
+
docs: {
|
|
39
|
+
system: "TEAM.md"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
36
42
|
},
|
|
37
43
|
members: [],
|
|
38
44
|
mode: "swarm"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const agentScheduleSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
3
|
+
cron: z.ZodString;
|
|
4
|
+
kind: z.ZodLiteral<"cron">;
|
|
5
|
+
prompt: z.ZodOptional<z.ZodString>;
|
|
6
|
+
timezone: z.ZodOptional<z.ZodString>;
|
|
7
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
8
|
+
every: z.ZodString;
|
|
9
|
+
kind: z.ZodLiteral<"every">;
|
|
10
|
+
prompt: z.ZodOptional<z.ZodString>;
|
|
11
|
+
timezone: z.ZodOptional<z.ZodString>;
|
|
12
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
13
|
+
kind: z.ZodLiteral<"disabled">;
|
|
14
|
+
}, z.core.$strict>], "kind">;
|
|
15
|
+
export type AgentSchedule = z.infer<typeof agentScheduleSchema>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const schedulePromptSchema = z.string().min(1);
|
|
3
|
+
const scheduleTimezoneSchema = z.string().min(1);
|
|
4
|
+
export const agentScheduleSchema = z.discriminatedUnion("kind", [
|
|
5
|
+
z
|
|
6
|
+
.object({
|
|
7
|
+
cron: z.string().min(1),
|
|
8
|
+
kind: z.literal("cron"),
|
|
9
|
+
prompt: schedulePromptSchema.optional(),
|
|
10
|
+
timezone: scheduleTimezoneSchema.optional()
|
|
11
|
+
})
|
|
12
|
+
.strict(),
|
|
13
|
+
z
|
|
14
|
+
.object({
|
|
15
|
+
every: z.string().min(1),
|
|
16
|
+
kind: z.literal("every"),
|
|
17
|
+
prompt: schedulePromptSchema.optional(),
|
|
18
|
+
timezone: scheduleTimezoneSchema.optional()
|
|
19
|
+
})
|
|
20
|
+
.strict(),
|
|
21
|
+
z
|
|
22
|
+
.object({
|
|
23
|
+
kind: z.literal("disabled")
|
|
24
|
+
})
|
|
25
|
+
.strict()
|
|
26
|
+
]);
|