spawnfile 0.1.4 → 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/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/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,80 @@
|
|
|
1
|
+
export const registerLifecycleCommands = (program, handlers, streams) => {
|
|
2
|
+
program
|
|
3
|
+
.command("compile")
|
|
4
|
+
.argument("[path]", "Project directory or Spawnfile path", process.cwd())
|
|
5
|
+
.option("-o, --out <directory>", "Output directory")
|
|
6
|
+
.action(async (inputPath, options) => {
|
|
7
|
+
const result = await handlers.compileProject(inputPath, { outputDirectory: options.out });
|
|
8
|
+
streams.stdout(`compiled to ${result.outputDirectory}`);
|
|
9
|
+
streams.stdout(`report: ${result.reportPath}`);
|
|
10
|
+
});
|
|
11
|
+
program
|
|
12
|
+
.command("build")
|
|
13
|
+
.argument("[path]", "Project directory or Spawnfile path", process.cwd())
|
|
14
|
+
.option("--docker-command <command>", "Docker command")
|
|
15
|
+
.option("-o, --out <directory>", "Output directory")
|
|
16
|
+
.option("-t, --tag <image>", "Docker image tag")
|
|
17
|
+
.action(async (inputPath, options) => {
|
|
18
|
+
const result = await handlers.buildProject(inputPath, {
|
|
19
|
+
dockerCommand: options.dockerCommand,
|
|
20
|
+
imageTag: options.tag,
|
|
21
|
+
outputDirectory: options.out
|
|
22
|
+
});
|
|
23
|
+
streams.stdout(`built image ${result.imageTag}`);
|
|
24
|
+
streams.stdout(`compiled to ${result.outputDirectory}`);
|
|
25
|
+
streams.stdout(`report: ${result.reportPath}`);
|
|
26
|
+
});
|
|
27
|
+
program
|
|
28
|
+
.command("run")
|
|
29
|
+
.argument("[path]", "Project directory or Spawnfile path", process.cwd())
|
|
30
|
+
.option("-o, --out <directory>", "Output directory")
|
|
31
|
+
.option("-t, --tag <image>", "Docker image tag")
|
|
32
|
+
.option("--auth-profile <name>", "Local Spawnfile auth profile")
|
|
33
|
+
.option("--docker-command <command>", "Docker command")
|
|
34
|
+
.option("--name <container>", "Docker container name")
|
|
35
|
+
.option("--env-file <file>", "Path to an env file for runtime secrets")
|
|
36
|
+
.option("-d, --detach", "Run the container in detached mode")
|
|
37
|
+
.action(async (inputPath, options) => {
|
|
38
|
+
const result = await handlers.runProject(inputPath, {
|
|
39
|
+
authProfile: options.authProfile,
|
|
40
|
+
containerName: options.name,
|
|
41
|
+
detach: options.detach,
|
|
42
|
+
dockerCommand: options.dockerCommand,
|
|
43
|
+
envFilePath: options.envFile,
|
|
44
|
+
imageTag: options.tag,
|
|
45
|
+
outputDirectory: options.out
|
|
46
|
+
});
|
|
47
|
+
if (options.detach) {
|
|
48
|
+
streams.stdout(`running container ${result.containerName ?? "unknown"}`);
|
|
49
|
+
streams.stdout(`image: ${result.imageTag}`);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
program
|
|
53
|
+
.command("up")
|
|
54
|
+
.argument("[path]", "Project directory or Spawnfile path", process.cwd())
|
|
55
|
+
.option("-o, --out <directory>", "Output directory")
|
|
56
|
+
.option("-t, --tag <image>", "Docker image tag")
|
|
57
|
+
.option("--auth-profile <name>", "Local Spawnfile auth profile")
|
|
58
|
+
.option("--docker-command <command>", "Docker command")
|
|
59
|
+
.option("--name <container>", "Docker container name")
|
|
60
|
+
.option("--env-file <file>", "Path to an env file for runtime secrets")
|
|
61
|
+
.option("-d, --detach", "Run the container in detached mode")
|
|
62
|
+
.action(async (inputPath, options) => {
|
|
63
|
+
const result = await handlers.upProject(inputPath, {
|
|
64
|
+
authProfile: options.authProfile,
|
|
65
|
+
containerName: options.name,
|
|
66
|
+
detach: options.detach,
|
|
67
|
+
dockerCommand: options.dockerCommand,
|
|
68
|
+
envFilePath: options.envFile,
|
|
69
|
+
imageTag: options.tag,
|
|
70
|
+
outputDirectory: options.out
|
|
71
|
+
});
|
|
72
|
+
streams.stdout(`built image ${result.imageTag}`);
|
|
73
|
+
streams.stdout(`compiled to ${result.outputDirectory}`);
|
|
74
|
+
streams.stdout(`report: ${result.reportPath}`);
|
|
75
|
+
if (options.detach) {
|
|
76
|
+
streams.stdout(`running container ${result.containerName ?? "unknown"}`);
|
|
77
|
+
streams.stdout(`image: ${result.imageTag}`);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
};
|
package/dist/cli/runCli.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { importClaudeCodeAuth, importCodexAuth, importEnvFile, requireAuthProfile } from "../auth/index.js";
|
|
2
|
-
import { addAgentProject, addProjectSurface, addProjectModelFallback, addSubagentProject, addTeamProject, buildOrganizationView, buildCompilePlan, buildProject, clearProjectModelFallbacks, compileProject, initProject, removeProjectSurface, runProject, setProjectPrimaryModel, setProjectRuntime, setProjectSurfaceAccess, showProjectSurfaces, syncProjectAuth } from "../compiler/index.js";
|
|
2
|
+
import { addAgentProject, addProjectSurface, addProjectModelFallback, addSubagentProject, addTeamProject, buildOrganizationView, buildCompilePlan, buildProject, clearProjectModelFallbacks, compileProject, initProject, upProject, removeProjectSurface, runProject, setProjectPrimaryModel, setProjectRuntime, setProjectSurfaceAccess, showProjectSurfaces, syncProjectAuth } from "../compiler/index.js";
|
|
3
3
|
import { listRuntimeAdapters } from "../runtime/index.js";
|
|
4
4
|
export interface CliStreams {
|
|
5
5
|
stderr: (message: string) => void;
|
|
@@ -29,6 +29,7 @@ export interface CliHandlers {
|
|
|
29
29
|
removeProjectSurface: typeof removeProjectSurface;
|
|
30
30
|
requireAuthProfile: typeof requireAuthProfile;
|
|
31
31
|
runProject: typeof runProject;
|
|
32
|
+
upProject: typeof upProject;
|
|
32
33
|
setProjectPrimaryModel: typeof setProjectPrimaryModel;
|
|
33
34
|
setProjectRuntime: typeof setProjectRuntime;
|
|
34
35
|
setProjectSurfaceAccess: typeof setProjectSurfaceAccess;
|
package/dist/cli/runCli.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { importClaudeCodeAuth, importCodexAuth, importEnvFile, requireAuthProfile } from "../auth/index.js";
|
|
3
|
-
import { addAgentProject, addProjectSurface, addProjectModelFallback, addSubagentProject, addTeamProject, buildOrganizationView, buildCompilePlan, buildProject, clearProjectModelFallbacks, compileProject, initProject, removeProjectSurface, runProject, setProjectPrimaryModel, setProjectRuntime, setProjectSurfaceAccess, showProjectSurfaces, syncProjectAuth } from "../compiler/index.js";
|
|
3
|
+
import { addAgentProject, addProjectSurface, addProjectModelFallback, addSubagentProject, addTeamProject, buildOrganizationView, buildCompilePlan, buildProject, clearProjectModelFallbacks, compileProject, initProject, upProject, removeProjectSurface, runProject, setProjectPrimaryModel, setProjectRuntime, setProjectSurfaceAccess, showProjectSurfaces, syncProjectAuth } from "../compiler/index.js";
|
|
4
4
|
import { isSpawnfileError } from "../shared/index.js";
|
|
5
5
|
import { listRuntimeAdapters } from "../runtime/index.js";
|
|
6
|
+
import { registerLifecycleCommands } from "./lifecycleCommands.js";
|
|
6
7
|
import { registerModelCommands } from "./modelCommands.js";
|
|
7
8
|
import { registerRuntimeCommands } from "./runtimeCommands.js";
|
|
8
9
|
import { registerSurfaceCommands } from "./surfaceCommands.js";
|
|
@@ -22,7 +23,7 @@ const createDefaultHandlers = () => ({
|
|
|
22
23
|
addSubagentProject, addTeamProject, clearProjectModelFallbacks,
|
|
23
24
|
importClaudeCodeAuth, importCodexAuth, importEnvFile,
|
|
24
25
|
initProject, listRuntimeAdapters, removeProjectSurface, requireAuthProfile,
|
|
25
|
-
runProject, setProjectPrimaryModel, setProjectRuntime,
|
|
26
|
+
runProject, setProjectPrimaryModel, setProjectRuntime, upProject,
|
|
26
27
|
setProjectSurfaceAccess, showProjectSurfaces, syncProjectAuth
|
|
27
28
|
});
|
|
28
29
|
const isCliStreams = (value) => {
|
|
@@ -83,52 +84,7 @@ export const runCli = async (argv, optionsOrStreams, handlerOverrides = {}) => {
|
|
|
83
84
|
writeErr: (message) => writeCommanderOutput(streams.stderr, message),
|
|
84
85
|
writeOut: (message) => writeCommanderOutput(streams.stdout, message)
|
|
85
86
|
});
|
|
86
|
-
program
|
|
87
|
-
.command("compile")
|
|
88
|
-
.argument("[path]", "Project directory or Spawnfile path", process.cwd())
|
|
89
|
-
.option("-o, --out <directory>", "Output directory")
|
|
90
|
-
.action(async (inputPath, options) => {
|
|
91
|
-
const result = await handlers.compileProject(inputPath, { outputDirectory: options.out });
|
|
92
|
-
streams.stdout(`compiled to ${result.outputDirectory}`);
|
|
93
|
-
streams.stdout(`report: ${result.reportPath}`);
|
|
94
|
-
});
|
|
95
|
-
program
|
|
96
|
-
.command("build")
|
|
97
|
-
.argument("[path]", "Project directory or Spawnfile path", process.cwd())
|
|
98
|
-
.option("-o, --out <directory>", "Output directory")
|
|
99
|
-
.option("-t, --tag <image>", "Docker image tag")
|
|
100
|
-
.action(async (inputPath, options) => {
|
|
101
|
-
const result = await handlers.buildProject(inputPath, {
|
|
102
|
-
imageTag: options.tag,
|
|
103
|
-
outputDirectory: options.out
|
|
104
|
-
});
|
|
105
|
-
streams.stdout(`built image ${result.imageTag}`);
|
|
106
|
-
streams.stdout(`compiled to ${result.outputDirectory}`);
|
|
107
|
-
streams.stdout(`report: ${result.reportPath}`);
|
|
108
|
-
});
|
|
109
|
-
program
|
|
110
|
-
.command("run")
|
|
111
|
-
.argument("[path]", "Project directory or Spawnfile path", process.cwd())
|
|
112
|
-
.option("-o, --out <directory>", "Output directory")
|
|
113
|
-
.option("-t, --tag <image>", "Docker image tag")
|
|
114
|
-
.option("--auth-profile <name>", "Local Spawnfile auth profile")
|
|
115
|
-
.option("--name <container>", "Docker container name")
|
|
116
|
-
.option("--env-file <file>", "Path to an env file for runtime secrets")
|
|
117
|
-
.option("-d, --detach", "Run the container in detached mode")
|
|
118
|
-
.action(async (inputPath, options) => {
|
|
119
|
-
const result = await handlers.runProject(inputPath, {
|
|
120
|
-
authProfile: options.authProfile,
|
|
121
|
-
containerName: options.name,
|
|
122
|
-
detach: options.detach,
|
|
123
|
-
envFilePath: options.envFile,
|
|
124
|
-
imageTag: options.tag,
|
|
125
|
-
outputDirectory: options.out
|
|
126
|
-
});
|
|
127
|
-
if (options.detach) {
|
|
128
|
-
streams.stdout(`running container ${result.containerName ?? "unknown"}`);
|
|
129
|
-
streams.stdout(`image: ${result.imageTag}`);
|
|
130
|
-
}
|
|
131
|
-
});
|
|
87
|
+
registerLifecycleCommands(program, handlers, streams);
|
|
132
88
|
program
|
|
133
89
|
.command("init")
|
|
134
90
|
.argument("[path]", "Directory to initialize", process.cwd())
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import { getCanonicalManifestPath, getManifestPath
|
|
2
|
-
import {
|
|
3
|
-
import { SpawnfileError } from "../shared/index.js";
|
|
4
|
-
import { getAgentFingerprint, getMcpNames, getTeamFingerprint, validateEffectiveSkillRequirements } from "./compilePlanHelpers.js";
|
|
5
|
-
import { resolveAgentSurfaces } from "./agentSurfaces.js";
|
|
1
|
+
import { getCanonicalManifestPath, getManifestPath } from "../filesystem/index.js";
|
|
2
|
+
import { loadManifest, isAgentManifest } from "../manifest/index.js";
|
|
6
3
|
import { assignStableNodeIds } from "./helpers.js";
|
|
7
|
-
import { loadResolvedDocuments, mergeResolvedSkills, loadResolvedSkills, mergeSharedSurface } from "./surfaces.js";
|
|
8
|
-
import { assertRuntimeSupportsExecutionModelAuth } from "./modelAuth.js";
|
|
9
|
-
import { assertRuntimeSupportsAgentSurfaces } from "./surfaceSupport.js";
|
|
10
|
-
import { applyExecutionDefaults } from "./executionDefaults.js";
|
|
11
4
|
import { resolvePlanMoltnetAttachments } from "./moltnetResolution.js";
|
|
12
5
|
import { resolveMoltnetRoomMemberships } from "./moltnetRoomMemberships.js";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
6
|
+
import { createRuntimeGroups } from "./buildCompilePlanRuntime.js";
|
|
7
|
+
import { createCompilePlanTraversal } from "./buildCompilePlanTraversal.js";
|
|
15
8
|
export const buildCompilePlan = async (inputPath) => {
|
|
16
9
|
const rootManifestPath = getCanonicalManifestPath(getManifestPath(inputPath));
|
|
17
10
|
const loadCache = new Map();
|
|
@@ -19,7 +12,6 @@ export const buildCompilePlan = async (inputPath) => {
|
|
|
19
12
|
const fingerprintCache = new Map();
|
|
20
13
|
const edges = [];
|
|
21
14
|
const memberships = new Map();
|
|
22
|
-
const visitStack = [];
|
|
23
15
|
const getLoadedManifest = (manifestPath) => {
|
|
24
16
|
const canonicalPath = getCanonicalManifestPath(manifestPath);
|
|
25
17
|
const cached = loadCache.get(canonicalPath);
|
|
@@ -30,186 +22,13 @@ export const buildCompilePlan = async (inputPath) => {
|
|
|
30
22
|
loadCache.set(canonicalPath, promise);
|
|
31
23
|
return promise;
|
|
32
24
|
};
|
|
33
|
-
const visitAgent =
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
throw new SpawnfileError("compile_error", `Expected agent manifest, got ${loadedManifest.manifest.kind} at ${canonicalPath}`);
|
|
41
|
-
}
|
|
42
|
-
const runtime = await resolveRuntime(loadedManifest.manifest, context);
|
|
43
|
-
const execution = applyExecutionDefaults(context.isSubagent
|
|
44
|
-
? mergeExecution(context.inheritedExecution, loadedManifest.manifest.execution)
|
|
45
|
-
: loadedManifest.manifest.execution);
|
|
46
|
-
assertRuntimeSupportsExecutionModelAuth(runtime.name, execution, loadedManifest.manifest.name);
|
|
47
|
-
const sharedSurface = mergeSharedSurface(context.inheritedShared?.surface, {
|
|
48
|
-
env: loadedManifest.manifest.env,
|
|
49
|
-
mcpServers: loadedManifest.manifest.mcp_servers,
|
|
50
|
-
secrets: loadedManifest.manifest.secrets,
|
|
51
|
-
skills: loadedManifest.manifest.skills
|
|
52
|
-
});
|
|
53
|
-
const inheritedSkills = context.inheritedShared
|
|
54
|
-
? await loadResolvedSkills(context.inheritedShared.manifestPath, context.inheritedShared.surface?.skills)
|
|
55
|
-
: [];
|
|
56
|
-
const localSkills = await loadResolvedSkills(canonicalPath, loadedManifest.manifest.skills);
|
|
57
|
-
const skills = mergeResolvedSkills(inheritedSkills, localSkills);
|
|
58
|
-
validateEffectiveSkillRequirements(loadedManifest.manifest.name, getMcpNames(sharedSurface.mcpServers), skills);
|
|
59
|
-
const docs = await loadResolvedDocuments(canonicalPath, loadedManifest.manifest.docs);
|
|
60
|
-
const candidate = {
|
|
61
|
-
description: resolveDescription(loadedManifest.manifest.description, docs),
|
|
62
|
-
docs,
|
|
63
|
-
env: sharedSurface.env,
|
|
64
|
-
execution,
|
|
65
|
-
expose: loadedManifest.manifest.expose ?? false,
|
|
66
|
-
kind: "agent",
|
|
67
|
-
mcpServers: sharedSurface.mcpServers,
|
|
68
|
-
name: loadedManifest.manifest.name,
|
|
69
|
-
policyMode: loadedManifest.manifest.policy?.mode ?? null,
|
|
70
|
-
policyOnDegrade: loadedManifest.manifest.policy?.on_degrade ?? null,
|
|
71
|
-
runtime,
|
|
72
|
-
secrets: sharedSurface.secrets,
|
|
73
|
-
skills,
|
|
74
|
-
source: canonicalPath,
|
|
75
|
-
surfaces: resolveAgentSurfaces(loadedManifest.manifest.surfaces),
|
|
76
|
-
subagents: []
|
|
77
|
-
};
|
|
78
|
-
assertRuntimeSupportsAgentSurfaces(runtime.name, candidate.surfaces, loadedManifest.manifest.name);
|
|
79
|
-
const fingerprint = getAgentFingerprint(candidate);
|
|
80
|
-
const existingFingerprint = fingerprintCache.get(canonicalPath);
|
|
81
|
-
if (existingFingerprint && existingFingerprint !== fingerprint) {
|
|
82
|
-
throw new SpawnfileError("compile_error", `Manifest ${canonicalPath} resolves differently across compile contexts`);
|
|
83
|
-
}
|
|
84
|
-
const cachedNode = nodeCache.get(canonicalPath);
|
|
85
|
-
if (cachedNode) {
|
|
86
|
-
return cachedNode.value;
|
|
87
|
-
}
|
|
88
|
-
fingerprintCache.set(canonicalPath, fingerprint);
|
|
89
|
-
nodeCache.set(canonicalPath, {
|
|
90
|
-
runtimeName: runtime.name,
|
|
91
|
-
source: canonicalPath,
|
|
92
|
-
value: candidate
|
|
93
|
-
});
|
|
94
|
-
visitStack.push(canonicalPath);
|
|
95
|
-
for (const subagent of loadedManifest.manifest.subagents ?? []) {
|
|
96
|
-
const childManifestPath = getManifestPath(resolveProjectPath(canonicalPath, subagent.ref));
|
|
97
|
-
const resolvedSubagent = await visitAgent(childManifestPath, {
|
|
98
|
-
inheritedExecution: execution,
|
|
99
|
-
inheritedRuntime: runtime,
|
|
100
|
-
isSubagent: true
|
|
101
|
-
});
|
|
102
|
-
candidate.subagents.push({
|
|
103
|
-
id: subagent.id,
|
|
104
|
-
nodeSource: resolvedSubagent.source
|
|
105
|
-
});
|
|
106
|
-
edges.push({
|
|
107
|
-
from: canonicalPath,
|
|
108
|
-
kind: "subagent",
|
|
109
|
-
label: subagent.id,
|
|
110
|
-
to: resolvedSubagent.source
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
visitStack.pop();
|
|
114
|
-
return candidate;
|
|
115
|
-
};
|
|
116
|
-
const visitTeam = async (manifestPath) => {
|
|
117
|
-
const canonicalPath = getCanonicalManifestPath(manifestPath);
|
|
118
|
-
if (visitStack.includes(canonicalPath)) {
|
|
119
|
-
throw new SpawnfileError("compile_error", `Cycle detected while visiting ${canonicalPath}`);
|
|
120
|
-
}
|
|
121
|
-
const loadedManifest = await getLoadedManifest(canonicalPath);
|
|
122
|
-
if (!isTeamManifest(loadedManifest.manifest)) {
|
|
123
|
-
throw new SpawnfileError("compile_error", `Expected team manifest, got ${loadedManifest.manifest.kind} at ${canonicalPath}`);
|
|
124
|
-
}
|
|
125
|
-
const sharedSkills = await loadResolvedSkills(canonicalPath, loadedManifest.manifest.shared?.skills);
|
|
126
|
-
validateEffectiveSkillRequirements(loadedManifest.manifest.name, getMcpNames(loadedManifest.manifest.shared?.mcp_servers ?? []), sharedSkills);
|
|
127
|
-
const manifest = loadedManifest.manifest;
|
|
128
|
-
const resolvedExternal = resolveTeamExternalIds(manifest);
|
|
129
|
-
const docs = await loadResolvedDocuments(canonicalPath, manifest.docs);
|
|
130
|
-
const candidate = {
|
|
131
|
-
description: manifest.description ? normalizeDescription(manifest.description) : "",
|
|
132
|
-
docs,
|
|
133
|
-
external: resolvedExternal,
|
|
134
|
-
externalExplicit: manifest.external !== undefined,
|
|
135
|
-
kind: "team",
|
|
136
|
-
lead: manifest.lead ?? null,
|
|
137
|
-
members: [],
|
|
138
|
-
mode: manifest.mode,
|
|
139
|
-
name: manifest.name,
|
|
140
|
-
networks: resolveTeamNetworks(manifest),
|
|
141
|
-
policyMode: manifest.policy?.mode ?? null,
|
|
142
|
-
policyOnDegrade: manifest.policy?.on_degrade ?? null,
|
|
143
|
-
shared: {
|
|
144
|
-
env: manifest.shared?.env ?? {},
|
|
145
|
-
mcpServers: manifest.shared?.mcp_servers ?? [],
|
|
146
|
-
secrets: manifest.shared?.secrets ?? [],
|
|
147
|
-
skills: sharedSkills
|
|
148
|
-
},
|
|
149
|
-
source: canonicalPath,
|
|
150
|
-
};
|
|
151
|
-
const fingerprint = getTeamFingerprint(candidate);
|
|
152
|
-
const existingFingerprint = fingerprintCache.get(canonicalPath);
|
|
153
|
-
if (existingFingerprint && existingFingerprint !== fingerprint) {
|
|
154
|
-
throw new SpawnfileError("compile_error", `Team manifest ${canonicalPath} resolves differently across compile contexts`);
|
|
155
|
-
}
|
|
156
|
-
const cachedNode = nodeCache.get(canonicalPath);
|
|
157
|
-
if (cachedNode) {
|
|
158
|
-
return cachedNode.value;
|
|
159
|
-
}
|
|
160
|
-
fingerprintCache.set(canonicalPath, fingerprint);
|
|
161
|
-
nodeCache.set(canonicalPath, {
|
|
162
|
-
runtimeName: null,
|
|
163
|
-
source: canonicalPath,
|
|
164
|
-
value: candidate
|
|
165
|
-
});
|
|
166
|
-
visitStack.push(canonicalPath);
|
|
167
|
-
for (const member of loadedManifest.manifest.members) {
|
|
168
|
-
const childManifestPath = getManifestPath(resolveProjectPath(canonicalPath, member.ref));
|
|
169
|
-
const childManifest = await getLoadedManifest(childManifestPath);
|
|
170
|
-
let resolvedMember;
|
|
171
|
-
if (isAgentManifest(childManifest.manifest)) {
|
|
172
|
-
const resolvedAgent = await visitAgent(childManifestPath, {
|
|
173
|
-
inheritedShared: {
|
|
174
|
-
manifestPath: canonicalPath,
|
|
175
|
-
surface: loadedManifest.manifest.shared
|
|
176
|
-
},
|
|
177
|
-
isSubagent: false
|
|
178
|
-
});
|
|
179
|
-
resolvedMember = {
|
|
180
|
-
id: member.id,
|
|
181
|
-
kind: "agent",
|
|
182
|
-
nodeSource: resolvedAgent.source,
|
|
183
|
-
runtimeName: resolvedAgent.runtime.name
|
|
184
|
-
};
|
|
185
|
-
memberships.set(`${canonicalPath}::${member.id}::${resolvedAgent.source}`, {
|
|
186
|
-
agentSource: resolvedAgent.source,
|
|
187
|
-
memberId: member.id,
|
|
188
|
-
teamName: candidate.name,
|
|
189
|
-
teamSource: canonicalPath
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
const resolvedTeam = await visitTeam(childManifestPath);
|
|
194
|
-
resolvedMember = {
|
|
195
|
-
id: member.id,
|
|
196
|
-
kind: "team",
|
|
197
|
-
nodeSource: resolvedTeam.source,
|
|
198
|
-
runtimeName: null
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
candidate.members.push(resolvedMember);
|
|
202
|
-
edges.push({
|
|
203
|
-
from: canonicalPath,
|
|
204
|
-
kind: "team_member",
|
|
205
|
-
label: member.id,
|
|
206
|
-
to: resolvedMember.nodeSource
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
validateTeamNetworkRooms(candidate);
|
|
210
|
-
visitStack.pop();
|
|
211
|
-
return candidate;
|
|
212
|
-
};
|
|
25
|
+
const { visitAgent, visitTeam } = createCompilePlanTraversal({
|
|
26
|
+
getLoadedManifest,
|
|
27
|
+
nodeCache,
|
|
28
|
+
edges,
|
|
29
|
+
fingerprintCache,
|
|
30
|
+
memberships
|
|
31
|
+
});
|
|
213
32
|
const rootLoadedManifest = await getLoadedManifest(rootManifestPath);
|
|
214
33
|
if (isAgentManifest(rootLoadedManifest.manifest)) {
|
|
215
34
|
await visitAgent(rootManifestPath, { isSubagent: false });
|
|
@@ -234,21 +53,12 @@ export const buildCompilePlan = async (inputPath) => {
|
|
|
234
53
|
from: idBySource.get(edge.from) ?? edge.from,
|
|
235
54
|
to: idBySource.get(edge.to) ?? edge.to
|
|
236
55
|
}));
|
|
237
|
-
const runtimes = compilePlanNodes.reduce((groups, node) => {
|
|
238
|
-
if (!node.runtimeName) {
|
|
239
|
-
return groups;
|
|
240
|
-
}
|
|
241
|
-
const group = groups[node.runtimeName] ?? { nodeIds: [] };
|
|
242
|
-
group.nodeIds.push(node.id);
|
|
243
|
-
groups[node.runtimeName] = group;
|
|
244
|
-
return groups;
|
|
245
|
-
}, {});
|
|
246
56
|
const compilePlan = {
|
|
247
57
|
edges: compilePlanEdges,
|
|
248
58
|
memberships: [...memberships.values()].sort((left, right) => `${left.agentSource}:${left.teamSource}:${left.memberId}`.localeCompare(`${right.agentSource}:${right.teamSource}:${right.memberId}`)),
|
|
249
59
|
nodes: compilePlanNodes,
|
|
250
60
|
root: rootManifestPath,
|
|
251
|
-
runtimes
|
|
61
|
+
runtimes: createRuntimeGroups(compilePlanNodes)
|
|
252
62
|
};
|
|
253
63
|
compilePlan.moltnetRoomMemberships = resolveMoltnetRoomMemberships(compilePlan);
|
|
254
64
|
resolvePlanMoltnetAttachments(compilePlan);
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type AgentManifest, type ExecutionBlock, type SharedSurface } from "../manifest/index.js";
|
|
2
|
-
import type { ResolvedDocument, ResolvedRuntime } from "./types.js";
|
|
2
|
+
import type { CompilePlanNode, ResolvedDocument, ResolvedRuntime } from "./types.js";
|
|
3
|
+
import type { ResolvedWorkspaceResource } from "./workspaceResources.js";
|
|
3
4
|
export interface AgentVisitContext {
|
|
4
5
|
inheritedExecution?: ExecutionBlock;
|
|
6
|
+
inheritedResources?: ResolvedWorkspaceResource[];
|
|
5
7
|
inheritedShared?: {
|
|
6
8
|
manifestPath: string;
|
|
7
9
|
surface: SharedSurface | undefined;
|
|
@@ -12,3 +14,6 @@ export interface AgentVisitContext {
|
|
|
12
14
|
export declare const resolveRuntime: (manifest: AgentManifest, context: AgentVisitContext) => Promise<ResolvedRuntime>;
|
|
13
15
|
export declare const normalizeDescription: (description: string) => string;
|
|
14
16
|
export declare const resolveDescription: (description: string | undefined, docs: ResolvedDocument[]) => string;
|
|
17
|
+
export declare const createRuntimeGroups: (nodes: CompilePlanNode[]) => Record<string, {
|
|
18
|
+
nodeIds: string[];
|
|
19
|
+
}>;
|
|
@@ -37,3 +37,12 @@ const deriveDescriptionFromDocs = (docs) => {
|
|
|
37
37
|
export const resolveDescription = (description, docs) => description !== undefined
|
|
38
38
|
? normalizeDescription(description)
|
|
39
39
|
: deriveDescriptionFromDocs(docs);
|
|
40
|
+
export const createRuntimeGroups = (nodes) => nodes.reduce((groups, node) => {
|
|
41
|
+
if (!node.runtimeName) {
|
|
42
|
+
return groups;
|
|
43
|
+
}
|
|
44
|
+
const group = groups[node.runtimeName] ?? { nodeIds: [] };
|
|
45
|
+
group.nodeIds.push(node.id);
|
|
46
|
+
groups[node.runtimeName] = group;
|
|
47
|
+
return groups;
|
|
48
|
+
}, {});
|
|
@@ -14,16 +14,22 @@ export const resolveTeamExternalIds = (manifest) => {
|
|
|
14
14
|
? [manifest.lead]
|
|
15
15
|
: memberIds);
|
|
16
16
|
};
|
|
17
|
-
export const resolveTeamNetworks = (manifest) => (manifest.networks ?? []).map((network) =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}))
|
|
17
|
+
export const resolveTeamNetworks = (manifest) => (manifest.networks ?? []).map((network) => {
|
|
18
|
+
const resolved = {
|
|
19
|
+
id: network.id,
|
|
20
|
+
name: network.name ?? network.id,
|
|
21
|
+
provider: network.provider,
|
|
22
|
+
rooms: network.rooms.map((room) => ({
|
|
23
|
+
id: room.id,
|
|
24
|
+
members: [...room.members],
|
|
25
|
+
...(room.name ? { name: room.name } : {})
|
|
26
|
+
}))
|
|
27
|
+
};
|
|
28
|
+
if (network.server) {
|
|
29
|
+
resolved.server = network.server;
|
|
30
|
+
}
|
|
31
|
+
return resolved;
|
|
32
|
+
});
|
|
27
33
|
export const validateTeamNetworkRooms = (teamNode) => {
|
|
28
34
|
for (const network of teamNode.networks ?? []) {
|
|
29
35
|
for (const room of network.rooms) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { LoadedManifest } from "../manifest/index.js";
|
|
2
|
+
import { CompilePlanEdge, ResolvedAgentNode, ResolvedTeamMembershipContext, ResolvedTeamNode } from "./types.js";
|
|
3
|
+
import { type AgentVisitContext } from "./buildCompilePlanRuntime.js";
|
|
4
|
+
import { type InternalNode } from "./buildCompilePlanTraversalHelpers.js";
|
|
5
|
+
type BuildCompilePlanTraversalDeps = {
|
|
6
|
+
getLoadedManifest: (manifestPath: string) => Promise<LoadedManifest>;
|
|
7
|
+
nodeCache: Map<string, InternalNode>;
|
|
8
|
+
fingerprintCache: Map<string, string>;
|
|
9
|
+
edges: CompilePlanEdge[];
|
|
10
|
+
memberships: Map<string, ResolvedTeamMembershipContext>;
|
|
11
|
+
};
|
|
12
|
+
export declare const createCompilePlanTraversal: ({ getLoadedManifest, nodeCache, fingerprintCache, edges, memberships }: BuildCompilePlanTraversalDeps) => {
|
|
13
|
+
visitAgent: (manifestPath: string, context: AgentVisitContext) => Promise<ResolvedAgentNode>;
|
|
14
|
+
visitTeam: (manifestPath: string, inheritedResources?: ResolvedAgentNode["workspaceResources"]) => Promise<ResolvedTeamNode>;
|
|
15
|
+
};
|
|
16
|
+
export type { InternalNode };
|