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
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { loadImportedClaudeCodeCredential
|
|
2
|
+
import { loadImportedClaudeCodeCredential } from "../../auth/index.js";
|
|
3
3
|
import { copyDirectory, ensureDirectory, readUtf8File, writeUtf8File } from "../../filesystem/index.js";
|
|
4
4
|
const resolveRootfsSourcePath = (outputDirectory, containerPath) => path.join(outputDirectory, "container", "rootfs", ...path.posix.relative("/", containerPath).split("/"));
|
|
5
5
|
const createMountArgs = (hostPath, containerPath) => [
|
|
6
6
|
"-v",
|
|
7
7
|
`${hostPath}:${containerPath}`
|
|
8
8
|
];
|
|
9
|
-
const createMountedHomeDirectory = async (input, patchedConfig
|
|
9
|
+
const createMountedHomeDirectory = async (input, patchedConfig) => {
|
|
10
10
|
const sourceHomePath = resolveRootfsSourcePath(input.outputDirectory, input.instance.home_path);
|
|
11
11
|
const mountedHomePath = path.join("runtime-auth", "picoclaw", input.instance.id, "home");
|
|
12
12
|
const hostHomePath = path.join(input.tempRoot, mountedHomePath);
|
|
@@ -14,26 +14,10 @@ const createMountedHomeDirectory = async (input, patchedConfig, authStore) => {
|
|
|
14
14
|
await copyDirectory(sourceHomePath, hostHomePath);
|
|
15
15
|
const relativeConfigPath = path.posix.relative(input.instance.home_path, input.instance.config_path);
|
|
16
16
|
const hostConfigPath = path.join(hostHomePath, ...relativeConfigPath.split("/"));
|
|
17
|
-
const hostAuthPath = path.join(hostHomePath, "auth.json");
|
|
18
17
|
await ensureDirectory(path.dirname(hostConfigPath));
|
|
19
18
|
await writeUtf8File(hostConfigPath, `${JSON.stringify(patchedConfig, null, 2)}\n`);
|
|
20
|
-
if (authStore) {
|
|
21
|
-
await writeUtf8File(hostAuthPath, `${JSON.stringify(authStore, null, 2)}\n`);
|
|
22
|
-
}
|
|
23
19
|
return hostHomePath;
|
|
24
20
|
};
|
|
25
|
-
const createPicoClawCredential = (provider, credential) => ({
|
|
26
|
-
access_token: credential.access,
|
|
27
|
-
...("type" in credential && credential.type === "oauth" && credential.refresh
|
|
28
|
-
? { refresh_token: credential.refresh }
|
|
29
|
-
: !("type" in credential)
|
|
30
|
-
? { refresh_token: credential.refresh }
|
|
31
|
-
: {}),
|
|
32
|
-
...("accountId" in credential && credential.accountId ? { account_id: credential.accountId } : {}),
|
|
33
|
-
auth_method: "oauth",
|
|
34
|
-
expires_at: new Date(credential.expires).toISOString(),
|
|
35
|
-
provider
|
|
36
|
-
});
|
|
37
21
|
const normalizeClaudeCliModelName = (modelName) => modelName.replaceAll(".", "-");
|
|
38
22
|
const patchPicoClawConfig = (config, options) => {
|
|
39
23
|
const agents = config.agents ?? {};
|
|
@@ -55,21 +39,11 @@ const patchPicoClawConfig = (config, options) => {
|
|
|
55
39
|
record.model = `claude-cli/${normalizeClaudeCliModelName(modelName)}`;
|
|
56
40
|
}
|
|
57
41
|
}
|
|
58
|
-
if (options.useCodex && typeof model === "string" && model.startsWith("openai/")) {
|
|
59
|
-
delete record.api_key;
|
|
60
|
-
record.auth_method = "oauth";
|
|
61
|
-
}
|
|
62
42
|
return record;
|
|
63
43
|
});
|
|
64
44
|
if (options.useClaudeCode) {
|
|
65
45
|
delete nextProviders.anthropic;
|
|
66
46
|
}
|
|
67
|
-
if (options.useCodex) {
|
|
68
|
-
nextProviders.openai = {
|
|
69
|
-
...(nextProviders.openai ?? {}),
|
|
70
|
-
auth_method: "oauth"
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
47
|
return {
|
|
74
48
|
...config,
|
|
75
49
|
agents: {
|
|
@@ -87,29 +61,19 @@ export const preparePicoClawRuntimeAuth = async (input) => {
|
|
|
87
61
|
const claudeCode = input.authProfile.imports["claude-code"]
|
|
88
62
|
? await loadImportedClaudeCodeCredential(input.authProfile.imports["claude-code"].path)
|
|
89
63
|
: null;
|
|
90
|
-
const codex = input.authProfile.imports.codex
|
|
91
|
-
? await loadImportedCodexCredential(input.authProfile.imports.codex.path)
|
|
92
|
-
: null;
|
|
93
64
|
const useClaudeCode = input.instance.model_auth_methods.anthropic === "claude-code" && claudeCode;
|
|
94
|
-
|
|
95
|
-
if (!useClaudeCode && !useCodex) {
|
|
65
|
+
if (!useClaudeCode) {
|
|
96
66
|
return { coveredModelSecrets: [], mountArgs: [] };
|
|
97
67
|
}
|
|
98
|
-
const credentials = {};
|
|
99
68
|
const coveredModelSecrets = [];
|
|
100
|
-
if (useCodex) {
|
|
101
|
-
credentials.openai = createPicoClawCredential("openai", codex);
|
|
102
|
-
coveredModelSecrets.push("OPENAI_API_KEY");
|
|
103
|
-
}
|
|
104
69
|
if (useClaudeCode) {
|
|
105
70
|
coveredModelSecrets.push("ANTHROPIC_API_KEY");
|
|
106
71
|
}
|
|
107
72
|
const sourceConfig = JSON.parse(await readUtf8File(resolveRootfsSourcePath(input.outputDirectory, input.instance.config_path)));
|
|
108
73
|
const patchedConfig = patchPicoClawConfig(sourceConfig, {
|
|
109
|
-
useClaudeCode: Boolean(useClaudeCode)
|
|
110
|
-
useCodex: Boolean(useCodex)
|
|
74
|
+
useClaudeCode: Boolean(useClaudeCode)
|
|
111
75
|
});
|
|
112
|
-
const mountedHomePath = await createMountedHomeDirectory(input, patchedConfig
|
|
76
|
+
const mountedHomePath = await createMountedHomeDirectory(input, patchedConfig);
|
|
113
77
|
return {
|
|
114
78
|
coveredModelSecrets,
|
|
115
79
|
mountArgs: createMountArgs(mountedHomePath, input.instance.home_path)
|
|
@@ -4,6 +4,7 @@ import { createCapability, createAgentCapabilities, createDocumentFiles, createS
|
|
|
4
4
|
import { prepareTinyClawRuntimeAuth } from "./runAuth.js";
|
|
5
5
|
import { createTinyClawAgentScaffold } from "./scaffold.js";
|
|
6
6
|
import { assertSupportedTinyClawSurfaces, buildTinyClawChannels, resolveTinyClawSurfaceTokenBindings } from "./surfaces.js";
|
|
7
|
+
import { createScheduleDiagnostics, createTinyClawSchedulesFile, scheduleOutcomeFor } from "./schedules.js";
|
|
7
8
|
const WORKSPACE_PLACEHOLDER = "<workspace-path>";
|
|
8
9
|
const SUPPORTED_TINYCLAW_OPENAI_MODEL_PREFIXES = ["gpt-5"];
|
|
9
10
|
const TINYCLAW_START_SCRIPT = `
|
|
@@ -106,6 +107,7 @@ const mergeTinyClawTargets = async (inputs) => {
|
|
|
106
107
|
let hasWhatsappChannel = false;
|
|
107
108
|
let hasTelegramChannel = false;
|
|
108
109
|
const workspaceFiles = agentInputs.flatMap((input) => input.emittedFiles.filter((file) => file.path !== "settings.json"));
|
|
110
|
+
const schedulesFile = createTinyClawSchedulesFile(agentInputs);
|
|
109
111
|
let mergedBase = null;
|
|
110
112
|
for (const input of agentInputs) {
|
|
111
113
|
const settings = parseJsonFile(input, "settings.json");
|
|
@@ -153,6 +155,7 @@ const mergeTinyClawTargets = async (inputs) => {
|
|
|
153
155
|
{
|
|
154
156
|
files: [
|
|
155
157
|
...workspaceFiles,
|
|
158
|
+
...(schedulesFile ? [schedulesFile] : []),
|
|
156
159
|
{
|
|
157
160
|
content: `${JSON.stringify(mergedSettings, null, 2)}\n`,
|
|
158
161
|
path: "settings.json"
|
|
@@ -207,6 +210,7 @@ export const tinyClawAdapter = {
|
|
|
207
210
|
instancePaths: {
|
|
208
211
|
configPathTemplate: "<instance-root>/tinyagi/<config-file>",
|
|
209
212
|
homePathTemplate: "<instance-root>/tinyagi",
|
|
213
|
+
sourceWorkspacePathTemplate: "<instance-root>/workspace/<agent-name>",
|
|
210
214
|
workspacePathTemplate: "<instance-root>/workspace"
|
|
211
215
|
},
|
|
212
216
|
port: 3777,
|
|
@@ -222,11 +226,14 @@ export const tinyClawAdapter = {
|
|
|
222
226
|
}
|
|
223
227
|
},
|
|
224
228
|
async compileAgent(node) {
|
|
229
|
+
const scheduleOutcome = scheduleOutcomeFor(node);
|
|
225
230
|
return {
|
|
226
231
|
capabilities: createAgentCapabilities(node, {
|
|
227
|
-
mcpOutcome: node.mcpServers.length > 0 ? "degraded" : "supported"
|
|
232
|
+
mcpOutcome: node.mcpServers.length > 0 ? "degraded" : "supported",
|
|
233
|
+
scheduleMessage: scheduleOutcome.message,
|
|
234
|
+
scheduleOutcome: scheduleOutcome.outcome
|
|
228
235
|
}),
|
|
229
|
-
diagnostics:
|
|
236
|
+
diagnostics: createScheduleDiagnostics(node),
|
|
230
237
|
files: [
|
|
231
238
|
...createDocumentFiles(`workspace/${node.name}`, node.docs),
|
|
232
239
|
...createSkillFiles(`workspace/${node.name}/.agents/skills`, node.skills),
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ResolvedAgentNode } from "../../compiler/types.js";
|
|
2
|
+
import type { CapabilityReport } from "../../report/index.js";
|
|
3
|
+
import type { ContainerTargetInput, EmittedFile } from "../types.js";
|
|
4
|
+
export declare const createTinyClawSchedulesFile: (inputs: ContainerTargetInput[]) => EmittedFile | null;
|
|
5
|
+
export declare const scheduleOutcomeFor: (node: ResolvedAgentNode) => {
|
|
6
|
+
message?: string;
|
|
7
|
+
outcome?: CapabilityReport["outcome"];
|
|
8
|
+
};
|
|
9
|
+
export declare const createScheduleDiagnostics: (node: ResolvedAgentNode) => import("../../report/types.js").DiagnosticReport[];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createDiagnostic } from "../common.js";
|
|
2
|
+
const TINYCLAW_SCHEDULE_CHANNEL = "schedule";
|
|
3
|
+
const TINYCLAW_SCHEDULE_SENDER = "Spawnfile Scheduler";
|
|
4
|
+
const createTinyClawSchedule = (node) => {
|
|
5
|
+
if (!node.schedule || node.schedule.kind !== "cron") {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
return {
|
|
9
|
+
agentId: node.name,
|
|
10
|
+
channel: TINYCLAW_SCHEDULE_CHANNEL,
|
|
11
|
+
createdAt: 0,
|
|
12
|
+
cron: node.schedule.cron,
|
|
13
|
+
enabled: true,
|
|
14
|
+
id: `spawnfile-${node.name}`,
|
|
15
|
+
label: `Spawnfile schedule for ${node.name}`,
|
|
16
|
+
message: node.schedule.prompt ?? "Run the scheduled Spawnfile task.",
|
|
17
|
+
sender: TINYCLAW_SCHEDULE_SENDER
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export const createTinyClawSchedulesFile = (inputs) => {
|
|
21
|
+
const schedules = inputs
|
|
22
|
+
.flatMap((input) => {
|
|
23
|
+
if (input.kind !== "agent" || input.value.kind !== "agent") {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
return [createTinyClawSchedule(input.value)];
|
|
27
|
+
})
|
|
28
|
+
.filter((schedule) => Boolean(schedule))
|
|
29
|
+
.sort((left, right) => left.id.localeCompare(right.id));
|
|
30
|
+
return schedules.length > 0
|
|
31
|
+
? {
|
|
32
|
+
content: `${JSON.stringify(schedules, null, 2)}\n`,
|
|
33
|
+
path: "home/schedules.json"
|
|
34
|
+
}
|
|
35
|
+
: null;
|
|
36
|
+
};
|
|
37
|
+
export const scheduleOutcomeFor = (node) => {
|
|
38
|
+
if (!node.schedule) {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
if (node.schedule.kind === "cron") {
|
|
42
|
+
return {
|
|
43
|
+
message: "TinyClaw native cron scheduler is emitted as schedules.json",
|
|
44
|
+
outcome: "supported"
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (node.schedule.kind === "disabled") {
|
|
48
|
+
return {
|
|
49
|
+
message: "Disabled schedule emits no wake registration",
|
|
50
|
+
outcome: "supported"
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
message: "TinyClaw native schedule lowering supports cron schedules in Spawnfile v0.1",
|
|
55
|
+
outcome: "degraded"
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
export const createScheduleDiagnostics = (node) => node.schedule?.kind === "every"
|
|
59
|
+
? [
|
|
60
|
+
createDiagnostic("warn", "TinyClaw native schedule lowering supports cron schedules in Spawnfile v0.1; every schedules are degraded")
|
|
61
|
+
]
|
|
62
|
+
: [];
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export interface ContainerTarget {
|
|
|
33
33
|
export interface RuntimeContainerInstancePaths {
|
|
34
34
|
configPathTemplate: string;
|
|
35
35
|
homePathTemplate?: string;
|
|
36
|
+
sourceWorkspacePathTemplate?: string;
|
|
36
37
|
workspacePathTemplate: string;
|
|
37
38
|
}
|
|
38
39
|
export interface RuntimeContainerConfigEnvBinding {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spawnfile",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Canonical source compiler for autonomous agents and teams.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"runtimes:sync": "./scripts/runtimes.sh && ./scripts/blueprints.sh",
|
|
30
30
|
"test:e2e:docker-auth": "tsx src/e2e/cli.ts",
|
|
31
31
|
"test:e2e:moltnet-team-chat": "tsx src/e2e/cli.ts moltnet-team-chat",
|
|
32
|
+
"test:e2e:operational-smoke": "tsx src/e2e/cli.ts operational-smoke",
|
|
32
33
|
"test": "vitest run",
|
|
33
34
|
"typecheck": "tsc --project tsconfig.json --noEmit"
|
|
34
35
|
},
|