spawnfile 0.1.1 → 0.1.3
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 +80 -396
- package/dist/cli/index.js +0 -0
- package/dist/cli/modelCommands.d.ts +3 -0
- package/dist/cli/modelCommands.js +68 -0
- package/dist/cli/runCli.d.ts +23 -2
- package/dist/cli/runCli.js +78 -122
- package/dist/cli/runtimeCommands.d.ts +3 -0
- package/dist/cli/runtimeCommands.js +20 -0
- package/dist/cli/surfaceCommands.d.ts +3 -0
- package/dist/cli/surfaceCommands.js +98 -0
- package/dist/cli/viewCommand.d.ts +3 -0
- package/dist/cli/viewCommand.js +87 -0
- package/dist/compiler/agentSurfaces.js +51 -5
- package/dist/compiler/buildCompilePlan.js +38 -40
- package/dist/compiler/buildCompilePlanRuntime.d.ts +14 -0
- package/dist/compiler/buildCompilePlanRuntime.js +39 -0
- package/dist/compiler/buildCompilePlanTeams.d.ts +5 -0
- package/dist/compiler/buildCompilePlanTeams.js +38 -0
- package/dist/compiler/compilePlanHelpers.js +4 -1
- package/dist/compiler/compileProject.js +62 -13
- package/dist/compiler/compileProjectSupport.d.ts +17 -0
- package/dist/compiler/compileProjectSupport.js +136 -0
- package/dist/compiler/containerArtifacts.d.ts +6 -1
- package/dist/compiler/containerArtifacts.js +26 -4
- package/dist/compiler/containerArtifactsPlans.js +16 -1
- package/dist/compiler/containerArtifactsRender.d.ts +4 -2
- package/dist/compiler/containerArtifactsRender.js +21 -126
- package/dist/compiler/containerArtifactsTypes.d.ts +7 -0
- package/dist/compiler/containerEntrypointRender.d.ts +12 -0
- package/dist/compiler/containerEntrypointRender.js +186 -0
- package/dist/compiler/index.d.ts +4 -0
- package/dist/compiler/index.js +4 -0
- package/dist/compiler/interactiveSurfaceScopes.d.ts +2 -0
- package/dist/compiler/interactiveSurfaceScopes.js +21 -0
- package/dist/compiler/moltnetArtifacts.d.ts +27 -0
- package/dist/compiler/moltnetArtifacts.js +208 -0
- package/dist/compiler/moltnetBinaries.d.ts +4 -0
- package/dist/compiler/moltnetBinaries.js +103 -0
- package/dist/compiler/moltnetClientConfig.d.ts +11 -0
- package/dist/compiler/moltnetClientConfig.js +89 -0
- package/dist/compiler/moltnetRepresentativeResolution.d.ts +16 -0
- package/dist/compiler/moltnetRepresentativeResolution.js +86 -0
- package/dist/compiler/moltnetResolution.d.ts +3 -0
- package/dist/compiler/moltnetResolution.js +182 -0
- package/dist/compiler/moltnetRoomMemberships.d.ts +3 -0
- package/dist/compiler/moltnetRoomMemberships.js +140 -0
- package/dist/compiler/runProject.js +1 -1
- package/dist/compiler/surfaceDefinitions.d.ts +55 -0
- package/dist/compiler/surfaceDefinitions.js +204 -0
- package/dist/compiler/teamContextHelpers.d.ts +18 -0
- package/dist/compiler/teamContextHelpers.js +112 -0
- package/dist/compiler/teamContextSupport.d.ts +4 -0
- package/dist/compiler/teamContextSupport.js +264 -0
- package/dist/compiler/teamContextSupport.testHelpers.d.ts +16 -0
- package/dist/compiler/teamContextSupport.testHelpers.js +68 -0
- package/dist/compiler/teamContextTypes.d.ts +28 -0
- package/dist/compiler/teamContextTypes.js +1 -0
- package/dist/compiler/teamRoster.d.ts +12 -0
- package/dist/compiler/teamRoster.js +48 -0
- package/dist/compiler/teamRosterEntries.d.ts +13 -0
- package/dist/compiler/teamRosterEntries.js +230 -0
- package/dist/compiler/teamRosterTypes.d.ts +45 -0
- package/dist/compiler/teamRosterTypes.js +1 -0
- package/dist/compiler/types.d.ts +90 -6
- package/dist/compiler/updateProjectRuntime.d.ts +9 -0
- package/dist/compiler/updateProjectRuntime.js +67 -0
- package/dist/compiler/updateProjectSurfaces.d.ts +8 -0
- package/dist/compiler/updateProjectSurfaces.js +106 -0
- package/dist/compiler/view/buildOrganizationView.d.ts +2 -0
- package/dist/compiler/view/buildOrganizationView.js +180 -0
- package/dist/compiler/view/index.d.ts +4 -0
- package/dist/compiler/view/index.js +4 -0
- package/dist/compiler/view/renderNetworks.d.ts +2 -0
- package/dist/compiler/view/renderNetworks.js +93 -0
- package/dist/compiler/view/renderTree.d.ts +2 -0
- package/dist/compiler/view/renderTree.js +59 -0
- package/dist/compiler/view/sourcePaths.d.ts +2 -0
- package/dist/compiler/view/sourcePaths.js +19 -0
- package/dist/compiler/view/types.d.ts +80 -0
- package/dist/compiler/view/types.js +1 -0
- package/dist/manifest/loadManifest.js +4 -4
- package/dist/manifest/renderSpawnfile.js +74 -8
- package/dist/manifest/scaffold.js +1 -3
- package/dist/manifest/schemas.d.ts +227 -17
- package/dist/manifest/schemas.js +62 -20
- package/dist/manifest/surfaceSchemas.d.ts +154 -0
- package/dist/manifest/surfaceSchemas.js +77 -5
- package/dist/runtime/common.js +3 -0
- package/dist/runtime/openclaw/adapter.js +38 -5
- package/dist/runtime/openclaw/moltnet.d.ts +12 -0
- package/dist/runtime/openclaw/moltnet.js +124 -0
- package/dist/runtime/openclaw/surfaces.js +3 -0
- package/dist/runtime/picoclaw/adapter.js +27 -8
- package/dist/runtime/picoclaw/pico.d.ts +2 -0
- package/dist/runtime/picoclaw/pico.js +2 -0
- package/dist/runtime/picoclaw/surfaces.js +11 -0
- package/dist/runtime/tinyclaw/adapter.js +22 -8
- package/dist/runtime/tinyclaw/runAuth.js +28 -1
- package/dist/runtime/tinyclaw/surfaces.js +8 -0
- package/dist/runtime/types.d.ts +11 -0
- package/package.json +5 -3
- package/runtimes.yaml +4 -4
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { getCanonicalManifestPath, getManifestPath, resolveProjectPath } from "../filesystem/index.js";
|
|
2
|
-
import { isAgentManifest, isTeamManifest, loadManifest, mergeExecution
|
|
3
|
-
import { assertRuntimeCanCompile } from "../runtime/index.js";
|
|
2
|
+
import { isAgentManifest, isTeamManifest, loadManifest, mergeExecution } from "../manifest/index.js";
|
|
4
3
|
import { SpawnfileError } from "../shared/index.js";
|
|
5
4
|
import { getAgentFingerprint, getMcpNames, getTeamFingerprint, validateEffectiveSkillRequirements } from "./compilePlanHelpers.js";
|
|
6
5
|
import { resolveAgentSurfaces } from "./agentSurfaces.js";
|
|
@@ -9,30 +8,17 @@ import { loadResolvedDocuments, mergeResolvedSkills, loadResolvedSkills, mergeSh
|
|
|
9
8
|
import { assertRuntimeSupportsExecutionModelAuth } from "./modelAuth.js";
|
|
10
9
|
import { assertRuntimeSupportsAgentSurfaces } from "./surfaceSupport.js";
|
|
11
10
|
import { applyExecutionDefaults } from "./executionDefaults.js";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
throw new SpawnfileError("runtime_error", `Subagent ${manifest.name} is missing inherited runtime context`);
|
|
17
|
-
}
|
|
18
|
-
if (localRuntime &&
|
|
19
|
-
localRuntime.name !== context.inheritedRuntime.name) {
|
|
20
|
-
throw new SpawnfileError("runtime_error", `Subagent ${manifest.name} must match parent runtime`);
|
|
21
|
-
}
|
|
22
|
-
return context.inheritedRuntime;
|
|
23
|
-
}
|
|
24
|
-
if (!localRuntime) {
|
|
25
|
-
throw new SpawnfileError("runtime_error", `Agent ${manifest.name} does not declare a runtime`);
|
|
26
|
-
}
|
|
27
|
-
await assertRuntimeCanCompile(localRuntime.name);
|
|
28
|
-
return localRuntime;
|
|
29
|
-
};
|
|
11
|
+
import { resolvePlanMoltnetAttachments } from "./moltnetResolution.js";
|
|
12
|
+
import { resolveMoltnetRoomMemberships } from "./moltnetRoomMemberships.js";
|
|
13
|
+
import { normalizeDescription, resolveDescription, resolveRuntime } from "./buildCompilePlanRuntime.js";
|
|
14
|
+
import { resolveTeamExternalIds, resolveTeamNetworks, validateTeamNetworkRooms } from "./buildCompilePlanTeams.js";
|
|
30
15
|
export const buildCompilePlan = async (inputPath) => {
|
|
31
16
|
const rootManifestPath = getCanonicalManifestPath(getManifestPath(inputPath));
|
|
32
17
|
const loadCache = new Map();
|
|
33
18
|
const nodeCache = new Map();
|
|
34
19
|
const fingerprintCache = new Map();
|
|
35
20
|
const edges = [];
|
|
21
|
+
const memberships = new Map();
|
|
36
22
|
const visitStack = [];
|
|
37
23
|
const getLoadedManifest = (manifestPath) => {
|
|
38
24
|
const canonicalPath = getCanonicalManifestPath(manifestPath);
|
|
@@ -70,10 +56,13 @@ export const buildCompilePlan = async (inputPath) => {
|
|
|
70
56
|
const localSkills = await loadResolvedSkills(canonicalPath, loadedManifest.manifest.skills);
|
|
71
57
|
const skills = mergeResolvedSkills(inheritedSkills, localSkills);
|
|
72
58
|
validateEffectiveSkillRequirements(loadedManifest.manifest.name, getMcpNames(sharedSurface.mcpServers), skills);
|
|
59
|
+
const docs = await loadResolvedDocuments(canonicalPath, loadedManifest.manifest.docs);
|
|
73
60
|
const candidate = {
|
|
74
|
-
|
|
61
|
+
description: resolveDescription(loadedManifest.manifest.description, docs),
|
|
62
|
+
docs,
|
|
75
63
|
env: sharedSurface.env,
|
|
76
64
|
execution,
|
|
65
|
+
expose: loadedManifest.manifest.expose ?? false,
|
|
77
66
|
kind: "agent",
|
|
78
67
|
mcpServers: sharedSurface.mcpServers,
|
|
79
68
|
name: loadedManifest.manifest.name,
|
|
@@ -135,31 +124,29 @@ export const buildCompilePlan = async (inputPath) => {
|
|
|
135
124
|
}
|
|
136
125
|
const sharedSkills = await loadResolvedSkills(canonicalPath, loadedManifest.manifest.shared?.skills);
|
|
137
126
|
validateEffectiveSkillRequirements(loadedManifest.manifest.name, getMcpNames(loadedManifest.manifest.shared?.mcp_servers ?? []), sharedSkills);
|
|
138
|
-
const
|
|
139
|
-
const
|
|
140
|
-
const
|
|
141
|
-
?? (structure.mode === "hierarchical" && structure.leader
|
|
142
|
-
? [structure.leader]
|
|
143
|
-
: memberIds);
|
|
127
|
+
const manifest = loadedManifest.manifest;
|
|
128
|
+
const resolvedExternal = resolveTeamExternalIds(manifest);
|
|
129
|
+
const docs = await loadResolvedDocuments(canonicalPath, manifest.docs);
|
|
144
130
|
const candidate = {
|
|
145
|
-
|
|
131
|
+
description: manifest.description ? normalizeDescription(manifest.description) : "",
|
|
132
|
+
docs,
|
|
133
|
+
external: resolvedExternal,
|
|
134
|
+
externalExplicit: manifest.external !== undefined,
|
|
146
135
|
kind: "team",
|
|
136
|
+
lead: manifest.lead ?? null,
|
|
147
137
|
members: [],
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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,
|
|
151
143
|
shared: {
|
|
152
|
-
env:
|
|
153
|
-
mcpServers:
|
|
154
|
-
secrets:
|
|
144
|
+
env: manifest.shared?.env ?? {},
|
|
145
|
+
mcpServers: manifest.shared?.mcp_servers ?? [],
|
|
146
|
+
secrets: manifest.shared?.secrets ?? [],
|
|
155
147
|
skills: sharedSkills
|
|
156
148
|
},
|
|
157
149
|
source: canonicalPath,
|
|
158
|
-
structure: {
|
|
159
|
-
external: resolvedExternal,
|
|
160
|
-
leader: structure.leader ?? null,
|
|
161
|
-
mode: structure.mode
|
|
162
|
-
}
|
|
163
150
|
};
|
|
164
151
|
const fingerprint = getTeamFingerprint(candidate);
|
|
165
152
|
const existingFingerprint = fingerprintCache.get(canonicalPath);
|
|
@@ -195,6 +182,12 @@ export const buildCompilePlan = async (inputPath) => {
|
|
|
195
182
|
nodeSource: resolvedAgent.source,
|
|
196
183
|
runtimeName: resolvedAgent.runtime.name
|
|
197
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
|
+
});
|
|
198
191
|
}
|
|
199
192
|
else {
|
|
200
193
|
const resolvedTeam = await visitTeam(childManifestPath);
|
|
@@ -213,6 +206,7 @@ export const buildCompilePlan = async (inputPath) => {
|
|
|
213
206
|
to: resolvedMember.nodeSource
|
|
214
207
|
});
|
|
215
208
|
}
|
|
209
|
+
validateTeamNetworkRooms(candidate);
|
|
216
210
|
visitStack.pop();
|
|
217
211
|
return candidate;
|
|
218
212
|
};
|
|
@@ -249,10 +243,14 @@ export const buildCompilePlan = async (inputPath) => {
|
|
|
249
243
|
groups[node.runtimeName] = group;
|
|
250
244
|
return groups;
|
|
251
245
|
}, {});
|
|
252
|
-
|
|
246
|
+
const compilePlan = {
|
|
253
247
|
edges: compilePlanEdges,
|
|
248
|
+
memberships: [...memberships.values()].sort((left, right) => `${left.agentSource}:${left.teamSource}:${left.memberId}`.localeCompare(`${right.agentSource}:${right.teamSource}:${right.memberId}`)),
|
|
254
249
|
nodes: compilePlanNodes,
|
|
255
250
|
root: rootManifestPath,
|
|
256
251
|
runtimes
|
|
257
252
|
};
|
|
253
|
+
compilePlan.moltnetRoomMemberships = resolveMoltnetRoomMemberships(compilePlan);
|
|
254
|
+
resolvePlanMoltnetAttachments(compilePlan);
|
|
255
|
+
return compilePlan;
|
|
258
256
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type AgentManifest, type ExecutionBlock, type SharedSurface } from "../manifest/index.js";
|
|
2
|
+
import type { ResolvedDocument, ResolvedRuntime } from "./types.js";
|
|
3
|
+
export interface AgentVisitContext {
|
|
4
|
+
inheritedExecution?: ExecutionBlock;
|
|
5
|
+
inheritedShared?: {
|
|
6
|
+
manifestPath: string;
|
|
7
|
+
surface: SharedSurface | undefined;
|
|
8
|
+
};
|
|
9
|
+
inheritedRuntime?: ResolvedRuntime;
|
|
10
|
+
isSubagent: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const resolveRuntime: (manifest: AgentManifest, context: AgentVisitContext) => Promise<ResolvedRuntime>;
|
|
13
|
+
export declare const normalizeDescription: (description: string) => string;
|
|
14
|
+
export declare const resolveDescription: (description: string | undefined, docs: ResolvedDocument[]) => string;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { normalizeRuntimeBinding } from "../manifest/index.js";
|
|
2
|
+
import { assertRuntimeCanCompile } from "../runtime/index.js";
|
|
3
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
4
|
+
export const resolveRuntime = async (manifest, context) => {
|
|
5
|
+
const localRuntime = normalizeRuntimeBinding(manifest.runtime);
|
|
6
|
+
if (context.isSubagent) {
|
|
7
|
+
if (!context.inheritedRuntime) {
|
|
8
|
+
throw new SpawnfileError("runtime_error", `Subagent ${manifest.name} is missing inherited runtime context`);
|
|
9
|
+
}
|
|
10
|
+
if (localRuntime &&
|
|
11
|
+
localRuntime.name !== context.inheritedRuntime.name) {
|
|
12
|
+
throw new SpawnfileError("runtime_error", `Subagent ${manifest.name} must match parent runtime`);
|
|
13
|
+
}
|
|
14
|
+
return context.inheritedRuntime;
|
|
15
|
+
}
|
|
16
|
+
if (!localRuntime) {
|
|
17
|
+
throw new SpawnfileError("runtime_error", `Agent ${manifest.name} does not declare a runtime`);
|
|
18
|
+
}
|
|
19
|
+
await assertRuntimeCanCompile(localRuntime.name);
|
|
20
|
+
return localRuntime;
|
|
21
|
+
};
|
|
22
|
+
export const normalizeDescription = (description) => description.replace(/\s+/g, " ").trim();
|
|
23
|
+
const deriveDescriptionFromDocs = (docs) => {
|
|
24
|
+
const identity = docs.find((doc) => doc.role === "identity")?.content;
|
|
25
|
+
if (!identity) {
|
|
26
|
+
return "";
|
|
27
|
+
}
|
|
28
|
+
const paragraph = identity
|
|
29
|
+
.split(/\n\s*\n/)
|
|
30
|
+
.map((block) => normalizeDescription(block))
|
|
31
|
+
.find((block) => block.length > 0 && !/^#{1,6}\s+/.test(block));
|
|
32
|
+
if (!paragraph) {
|
|
33
|
+
return "";
|
|
34
|
+
}
|
|
35
|
+
return paragraph.length > 200 ? paragraph.slice(0, 200).trimEnd() : paragraph;
|
|
36
|
+
};
|
|
37
|
+
export const resolveDescription = (description, docs) => description !== undefined
|
|
38
|
+
? normalizeDescription(description)
|
|
39
|
+
: deriveDescriptionFromDocs(docs);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TeamManifest } from "../manifest/index.js";
|
|
2
|
+
import type { ResolvedTeamNetwork, ResolvedTeamNode } from "./types.js";
|
|
3
|
+
export declare const resolveTeamExternalIds: (manifest: TeamManifest) => string[];
|
|
4
|
+
export declare const resolveTeamNetworks: (manifest: TeamManifest) => ResolvedTeamNetwork[];
|
|
5
|
+
export declare const validateTeamNetworkRooms: (teamNode: ResolvedTeamNode) => void;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
2
|
+
export const resolveTeamExternalIds = (manifest) => {
|
|
3
|
+
const memberIds = manifest.members.map((member) => member.id);
|
|
4
|
+
if (manifest.lead && !memberIds.includes(manifest.lead)) {
|
|
5
|
+
throw new SpawnfileError("validation_error", `Team ${manifest.name} lead references unknown member ${manifest.lead}`);
|
|
6
|
+
}
|
|
7
|
+
for (const externalMemberId of manifest.external ?? []) {
|
|
8
|
+
if (!memberIds.includes(externalMemberId)) {
|
|
9
|
+
throw new SpawnfileError("validation_error", `Team ${manifest.name} external representative references unknown member ${externalMemberId}`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return manifest.external
|
|
13
|
+
?? (manifest.mode === "hierarchical" && manifest.lead
|
|
14
|
+
? [manifest.lead]
|
|
15
|
+
: memberIds);
|
|
16
|
+
};
|
|
17
|
+
export const resolveTeamNetworks = (manifest) => (manifest.networks ?? []).map((network) => ({
|
|
18
|
+
expose: network.expose ?? false,
|
|
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
|
+
}))
|
|
26
|
+
}));
|
|
27
|
+
export const validateTeamNetworkRooms = (teamNode) => {
|
|
28
|
+
for (const network of teamNode.networks ?? []) {
|
|
29
|
+
for (const room of network.rooms) {
|
|
30
|
+
for (const roomMemberId of room.members) {
|
|
31
|
+
const resolvedMember = teamNode.members.find((member) => member.id === roomMemberId);
|
|
32
|
+
if (!resolvedMember) {
|
|
33
|
+
throw new SpawnfileError("validation_error", `Team ${teamNode.name} Moltnet room ${room.id} references unknown member ${roomMemberId}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
@@ -25,7 +25,10 @@ export const getAgentFingerprint = (node) => stableStringify({
|
|
|
25
25
|
});
|
|
26
26
|
export const getTeamFingerprint = (node) => stableStringify({
|
|
27
27
|
members: node.members,
|
|
28
|
-
|
|
28
|
+
mode: node.mode,
|
|
29
|
+
lead: node.lead,
|
|
30
|
+
external: node.external,
|
|
31
|
+
networks: node.networks ?? [],
|
|
29
32
|
shared: {
|
|
30
33
|
env: node.shared.env,
|
|
31
34
|
mcpServers: node.shared.mcpServers,
|
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { chmod } from "node:fs/promises";
|
|
3
|
-
import { ensureDirectory, removeDirectory
|
|
3
|
+
import { ensureDirectory, removeDirectory } from "../filesystem/index.js";
|
|
4
4
|
import { createCompileReport, createDiagnostic, writeCompileReport } from "../report/index.js";
|
|
5
5
|
import { DEFAULT_OUTPUT_DIRECTORY } from "../shared/index.js";
|
|
6
6
|
import { assertRuntimeCanCompile, createRuntimeLifecycleDiagnostics, getRuntimeAdapter } from "../runtime/index.js";
|
|
7
7
|
import { buildCompilePlan } from "./buildCompilePlan.js";
|
|
8
8
|
import { createContainerArtifacts } from "./containerArtifacts.js";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
await ensureDirectory(path.dirname(targetPath));
|
|
13
|
-
await writeUtf8File(targetPath, file.content);
|
|
14
|
-
}));
|
|
15
|
-
};
|
|
9
|
+
import { injectMoltnetWorkspaceFiles, injectTeamCompileSupportFiles, prepareTeamCompileSupport, writeEmittedFiles } from "./compileProjectSupport.js";
|
|
10
|
+
import { generateMoltnetArtifacts } from "./moltnetArtifacts.js";
|
|
11
|
+
import { stageMoltnetBinaries } from "./moltnetBinaries.js";
|
|
16
12
|
const createTeamCapabilities = (outcome, message) => [
|
|
17
13
|
{ key: "team.members", message, outcome },
|
|
18
|
-
{ key: "team.
|
|
19
|
-
{ key: "team.
|
|
20
|
-
{ key: "team.
|
|
14
|
+
{ key: "team.mode", message, outcome },
|
|
15
|
+
{ key: "team.lead", message, outcome },
|
|
16
|
+
{ key: "team.external", message, outcome },
|
|
21
17
|
{ key: "team.shared", message, outcome },
|
|
22
18
|
{ key: "team.nested", message, outcome }
|
|
23
19
|
];
|
|
@@ -148,6 +144,46 @@ const enforcePolicy = (nodeReport, policyMode, onDegrade) => {
|
|
|
148
144
|
}
|
|
149
145
|
}
|
|
150
146
|
};
|
|
147
|
+
const createIdentityCapabilities = (node) => [
|
|
148
|
+
...(node.surfaces?.slack?.identity
|
|
149
|
+
? [{
|
|
150
|
+
key: "surfaces.slack.identity",
|
|
151
|
+
message: "Declared Slack identity was preserved for roster output",
|
|
152
|
+
outcome: "supported"
|
|
153
|
+
}]
|
|
154
|
+
: []),
|
|
155
|
+
...(node.surfaces?.discord?.identity
|
|
156
|
+
? [{
|
|
157
|
+
key: "surfaces.discord.identity",
|
|
158
|
+
message: "Declared Discord identity was preserved for roster output",
|
|
159
|
+
outcome: "supported"
|
|
160
|
+
}]
|
|
161
|
+
: []),
|
|
162
|
+
...(node.surfaces?.telegram?.identity
|
|
163
|
+
? [{
|
|
164
|
+
key: "surfaces.telegram.identity",
|
|
165
|
+
message: "Declared Telegram identity was preserved for roster output",
|
|
166
|
+
outcome: "supported"
|
|
167
|
+
}]
|
|
168
|
+
: []),
|
|
169
|
+
...(node.surfaces?.whatsapp?.identity
|
|
170
|
+
? [{
|
|
171
|
+
key: "surfaces.whatsapp.identity",
|
|
172
|
+
message: "Declared WhatsApp identity was preserved for roster output",
|
|
173
|
+
outcome: "supported"
|
|
174
|
+
}]
|
|
175
|
+
: [])
|
|
176
|
+
];
|
|
177
|
+
const augmentNodeReports = (compiledNodes, support) => {
|
|
178
|
+
for (const compiled of compiledNodes) {
|
|
179
|
+
if (compiled.value.kind === "team") {
|
|
180
|
+
compiled.report.capabilities.push(...(support.capabilitiesByTeamSource.get(compiled.value.source) ?? []));
|
|
181
|
+
compiled.report.diagnostics.push(...(support.diagnosticsByTeamSource.get(compiled.value.source) ?? []));
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
compiled.report.capabilities.push(...createIdentityCapabilities(compiled.value));
|
|
185
|
+
}
|
|
186
|
+
};
|
|
151
187
|
export const compileProject = async (inputPath, options = {}) => {
|
|
152
188
|
const plan = await buildCompilePlan(inputPath);
|
|
153
189
|
const outputDirectory = path.resolve(options.outputDirectory ?? DEFAULT_OUTPUT_DIRECTORY);
|
|
@@ -155,21 +191,34 @@ export const compileProject = async (inputPath, options = {}) => {
|
|
|
155
191
|
await removeDirectory(outputDirectory);
|
|
156
192
|
}
|
|
157
193
|
await ensureDirectory(outputDirectory);
|
|
194
|
+
const teamCompileSupport = await prepareTeamCompileSupport(plan);
|
|
158
195
|
const nodeReports = [];
|
|
159
196
|
const compiledNodes = [];
|
|
160
197
|
for (const node of plan.nodes) {
|
|
161
198
|
let compiled;
|
|
162
199
|
if (node.kind === "agent") {
|
|
163
200
|
compiled = await compileAgentNode(outputDirectory, node);
|
|
201
|
+
await injectTeamCompileSupportFiles(outputDirectory, compiled, teamCompileSupport);
|
|
164
202
|
}
|
|
165
203
|
else {
|
|
166
204
|
compiled = await compileTeamNode(outputDirectory, node);
|
|
167
205
|
}
|
|
168
|
-
enforcePolicy(compiled.report, node.value.policyMode, node.value.policyOnDegrade);
|
|
169
206
|
nodeReports.push(compiled.report);
|
|
170
207
|
compiledNodes.push(compiled);
|
|
171
208
|
}
|
|
172
|
-
|
|
209
|
+
augmentNodeReports(compiledNodes, teamCompileSupport);
|
|
210
|
+
for (const compiled of compiledNodes) {
|
|
211
|
+
enforcePolicy(compiled.report, compiled.value.policyMode, compiled.value.policyOnDegrade);
|
|
212
|
+
}
|
|
213
|
+
const moltnetArtifacts = await generateMoltnetArtifacts(plan);
|
|
214
|
+
const hasStagedMoltnetBinaries = moltnetArtifacts
|
|
215
|
+
? await stageMoltnetBinaries(outputDirectory)
|
|
216
|
+
: false;
|
|
217
|
+
await injectMoltnetWorkspaceFiles(outputDirectory, compiledNodes, moltnetArtifacts);
|
|
218
|
+
const containerArtifacts = await createContainerArtifacts(plan, compiledNodes, {
|
|
219
|
+
hasStagedMoltnetBinaries,
|
|
220
|
+
moltnet: moltnetArtifacts
|
|
221
|
+
});
|
|
173
222
|
await writeEmittedFiles(outputDirectory, containerArtifacts.files);
|
|
174
223
|
await Promise.all(containerArtifacts.executablePaths.map((filePath) => chmod(path.join(outputDirectory, filePath), 0o755)));
|
|
175
224
|
const report = createCompileReport(plan.root, nodeReports, [], containerArtifacts.report);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type EmittedFile } from "../runtime/index.js";
|
|
2
|
+
import type { MoltnetArtifacts } from "./moltnetArtifacts.js";
|
|
3
|
+
import type { TeamCompileSupport } from "./teamContextSupport.js";
|
|
4
|
+
import type { ResolvedAgentNode, ResolvedTeamNode } from "./types.js";
|
|
5
|
+
export { prepareTeamCompileSupport } from "./teamContextSupport.js";
|
|
6
|
+
export type { TeamCompileSupport } from "./teamContextSupport.js";
|
|
7
|
+
export interface CompiledNodeOutput {
|
|
8
|
+
emittedFiles: EmittedFile[];
|
|
9
|
+
kind: "agent" | "team";
|
|
10
|
+
report: {
|
|
11
|
+
output_dir: string | null;
|
|
12
|
+
};
|
|
13
|
+
value: ResolvedAgentNode | ResolvedTeamNode;
|
|
14
|
+
}
|
|
15
|
+
export declare const writeEmittedFiles: (outputDirectory: string, files: EmittedFile[]) => Promise<void>;
|
|
16
|
+
export declare const injectTeamCompileSupportFiles: (outputDirectory: string, compiled: CompiledNodeOutput, support: TeamCompileSupport) => Promise<void>;
|
|
17
|
+
export declare const injectMoltnetWorkspaceFiles: (outputDirectory: string, compiledNodes: CompiledNodeOutput[], artifacts: MoltnetArtifacts | null) => Promise<void>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { execFile as execFileCallback } from "node:child_process";
|
|
2
|
+
import { chmod, readFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { ensureDirectory, writeUtf8File } from "../filesystem/index.js";
|
|
6
|
+
import { getRuntimeAdapter } from "../runtime/index.js";
|
|
7
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
8
|
+
import { resolveMoltnetCliCommand } from "./moltnetBinaries.js";
|
|
9
|
+
import { createMoltnetClientConfigFiles, resolveMoltnetWorkspaceLayout } from "./moltnetClientConfig.js";
|
|
10
|
+
export { prepareTeamCompileSupport } from "./teamContextSupport.js";
|
|
11
|
+
const execFile = promisify(execFileCallback);
|
|
12
|
+
const resolveAgentWorkspacePaths = (node) => {
|
|
13
|
+
const systemInstructionSurface = getRuntimeAdapter(node.runtime.name).systemInstructionSurface;
|
|
14
|
+
if (!systemInstructionSurface) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const systemInstructionPath = systemInstructionSurface.resolvePath({ node });
|
|
18
|
+
const systemInstructionDirectory = path.posix.dirname(systemInstructionPath);
|
|
19
|
+
return {
|
|
20
|
+
systemInstructionPath,
|
|
21
|
+
spawnfileDirectory: systemInstructionDirectory === "."
|
|
22
|
+
? ".spawnfile"
|
|
23
|
+
: `${systemInstructionDirectory}/.spawnfile`
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const upsertEmittedFile = (emittedFiles, nextFile) => {
|
|
27
|
+
const existing = emittedFiles.find((file) => file.path === nextFile.path);
|
|
28
|
+
if (existing) {
|
|
29
|
+
existing.content = nextFile.content;
|
|
30
|
+
return existing;
|
|
31
|
+
}
|
|
32
|
+
emittedFiles.push(nextFile);
|
|
33
|
+
return nextFile;
|
|
34
|
+
};
|
|
35
|
+
export const writeEmittedFiles = async (outputDirectory, files) => {
|
|
36
|
+
await Promise.all(files.map(async (file) => {
|
|
37
|
+
const targetPath = path.join(outputDirectory, file.path);
|
|
38
|
+
await ensureDirectory(path.dirname(targetPath));
|
|
39
|
+
await writeUtf8File(targetPath, file.content);
|
|
40
|
+
if (file.mode !== undefined) {
|
|
41
|
+
await chmod(targetPath, file.mode);
|
|
42
|
+
}
|
|
43
|
+
}));
|
|
44
|
+
};
|
|
45
|
+
export const injectTeamCompileSupportFiles = async (outputDirectory, compiled, support) => {
|
|
46
|
+
if (compiled.kind !== "agent" ||
|
|
47
|
+
compiled.value.kind !== "agent" ||
|
|
48
|
+
!compiled.report.output_dir) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const supportFiles = support.filesByAgentSource.get(compiled.value.source);
|
|
52
|
+
if (!supportFiles || supportFiles.length === 0) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const workspacePaths = resolveAgentWorkspacePaths(compiled.value);
|
|
56
|
+
if (!workspacePaths) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const filesToWrite = supportFiles.map((file) => upsertEmittedFile(compiled.emittedFiles, {
|
|
60
|
+
...file,
|
|
61
|
+
path: file.path.startsWith(".spawnfile/") || file.path === "TEAM.md"
|
|
62
|
+
? path.posix.join(path.posix.dirname(workspacePaths.spawnfileDirectory), file.path)
|
|
63
|
+
: file.path
|
|
64
|
+
}));
|
|
65
|
+
const rosterBlock = "\n\n<!-- spawnfile-team-context:start -->\n" +
|
|
66
|
+
"## Spawnfile Team Context\n\n" +
|
|
67
|
+
"Read `.spawnfile/team-contexts.md` and `.spawnfile/team-contexts.yaml` for generated team membership, representative context, and surface bindings.\n" +
|
|
68
|
+
"<!-- spawnfile-team-context:end -->\n";
|
|
69
|
+
const existingAgentsMd = compiled.emittedFiles.find((file) => file.path === workspacePaths.systemInstructionPath);
|
|
70
|
+
filesToWrite.push(existingAgentsMd
|
|
71
|
+
? (() => {
|
|
72
|
+
existingAgentsMd.content += rosterBlock;
|
|
73
|
+
return existingAgentsMd;
|
|
74
|
+
})()
|
|
75
|
+
: upsertEmittedFile(compiled.emittedFiles, {
|
|
76
|
+
content: rosterBlock.trimStart(),
|
|
77
|
+
path: workspacePaths.systemInstructionPath
|
|
78
|
+
}));
|
|
79
|
+
await writeEmittedFiles(path.join(outputDirectory, compiled.report.output_dir), filesToWrite);
|
|
80
|
+
};
|
|
81
|
+
export const injectMoltnetWorkspaceFiles = async (outputDirectory, compiledNodes, artifacts) => {
|
|
82
|
+
if (!artifacts) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
let moltnetCliCommand = null;
|
|
86
|
+
for (const compiled of compiledNodes) {
|
|
87
|
+
if (compiled.kind !== "agent" ||
|
|
88
|
+
compiled.value.kind !== "agent" ||
|
|
89
|
+
!compiled.report.output_dir) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const runtimeOutputDirectory = path.join(outputDirectory, compiled.report.output_dir);
|
|
93
|
+
const moltnetClientConfigFiles = createMoltnetClientConfigFiles(compiled.value, artifacts);
|
|
94
|
+
if (moltnetClientConfigFiles.length === 0) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const layout = resolveMoltnetWorkspaceLayout(compiled.value.runtime.name, compiled.value.name);
|
|
98
|
+
const workspacePath = path.join(runtimeOutputDirectory, layout.workspaceRootPath);
|
|
99
|
+
for (const file of moltnetClientConfigFiles) {
|
|
100
|
+
upsertEmittedFile(compiled.emittedFiles, file);
|
|
101
|
+
}
|
|
102
|
+
await writeEmittedFiles(runtimeOutputDirectory, moltnetClientConfigFiles);
|
|
103
|
+
if (!moltnetCliCommand) {
|
|
104
|
+
moltnetCliCommand = await resolveMoltnetCliCommand();
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
await execFile(moltnetCliCommand, [
|
|
108
|
+
"skill",
|
|
109
|
+
"install",
|
|
110
|
+
"--runtime",
|
|
111
|
+
layout.cliRuntime,
|
|
112
|
+
"--workspace",
|
|
113
|
+
workspacePath
|
|
114
|
+
]);
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
118
|
+
throw new SpawnfileError("compile_error", `Unable to install the Moltnet skill into ${compiled.value.name}: ${reason}`);
|
|
119
|
+
}
|
|
120
|
+
const moltnetSkillFiles = await Promise.all(layout.skillPaths.map(async (filePath) => {
|
|
121
|
+
try {
|
|
122
|
+
return {
|
|
123
|
+
content: await readFile(path.join(runtimeOutputDirectory, filePath), "utf8"),
|
|
124
|
+
path: filePath
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
129
|
+
throw new SpawnfileError("compile_error", `Moltnet skill install for ${compiled.value.name} did not produce ${filePath}: ${reason}`);
|
|
130
|
+
}
|
|
131
|
+
}));
|
|
132
|
+
for (const file of moltnetSkillFiles) {
|
|
133
|
+
upsertEmittedFile(compiled.emittedFiles, file);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
import type { MoltnetArtifacts } from "./moltnetArtifacts.js";
|
|
1
2
|
import type { CompiledNodeArtifact, GeneratedContainerArtifacts } from "./containerArtifactsTypes.js";
|
|
2
3
|
import type { CompilePlan } from "./types.js";
|
|
3
4
|
export type { CompiledNodeArtifact, GeneratedContainerArtifacts } from "./containerArtifactsTypes.js";
|
|
4
|
-
export
|
|
5
|
+
export interface ContainerArtifactOptions {
|
|
6
|
+
hasStagedMoltnetBinaries?: boolean;
|
|
7
|
+
moltnet?: MoltnetArtifacts | null;
|
|
8
|
+
}
|
|
9
|
+
export declare const createContainerArtifacts: (plan: CompilePlan, compiledNodes: CompiledNodeArtifact[], options?: ContainerArtifactOptions) => Promise<GeneratedContainerArtifacts>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createEnvVariableMap, createRuntimeTargetPlans } from "./containerArtifactsPlans.js";
|
|
2
2
|
import { createRootfsFiles, renderDockerfile, renderEntrypoint, renderEnvExample } from "./containerArtifactsRender.js";
|
|
3
|
-
export const createContainerArtifacts = async (plan, compiledNodes) => {
|
|
3
|
+
export const createContainerArtifacts = async (plan, compiledNodes, options = {}) => {
|
|
4
4
|
const runtimePlans = await createRuntimeTargetPlans(plan, compiledNodes);
|
|
5
5
|
const envVariables = [...createEnvVariableMap(compiledNodes, runtimePlans).values()].sort((left, right) => left.name.localeCompare(right.name));
|
|
6
6
|
const requiredSecrets = envVariables
|
|
@@ -17,12 +17,24 @@ export const createContainerArtifacts = async (plan, compiledNodes) => {
|
|
|
17
17
|
.sort();
|
|
18
18
|
const files = [
|
|
19
19
|
...createRootfsFiles(runtimePlans),
|
|
20
|
+
...(options.moltnet?.files ?? []),
|
|
20
21
|
{
|
|
21
|
-
content: await renderDockerfile(runtimePlans
|
|
22
|
+
content: await renderDockerfile(runtimePlans, {
|
|
23
|
+
hasMoltnet: Boolean(options.moltnet),
|
|
24
|
+
hasStagedMoltnetBinaries: options.hasStagedMoltnetBinaries,
|
|
25
|
+
moltnetPublishedPorts: options.moltnet?.publishedPorts ?? []
|
|
26
|
+
}),
|
|
22
27
|
path: "Dockerfile"
|
|
23
28
|
},
|
|
24
29
|
{
|
|
25
|
-
content: renderEntrypoint(runtimePlans, requiredSecrets.filter((secretName) => !modelSecretsRequired.includes(secretName))
|
|
30
|
+
content: renderEntrypoint(runtimePlans, requiredSecrets.filter((secretName) => !modelSecretsRequired.includes(secretName)), {
|
|
31
|
+
moltnet: options.moltnet
|
|
32
|
+
? {
|
|
33
|
+
bridgePlans: options.moltnet.bridgePlans,
|
|
34
|
+
serverPlans: options.moltnet.serverPlans
|
|
35
|
+
}
|
|
36
|
+
: undefined
|
|
37
|
+
}),
|
|
26
38
|
path: "entrypoint.sh"
|
|
27
39
|
},
|
|
28
40
|
{
|
|
@@ -30,7 +42,9 @@ export const createContainerArtifacts = async (plan, compiledNodes) => {
|
|
|
30
42
|
path: ".env.example"
|
|
31
43
|
}
|
|
32
44
|
];
|
|
33
|
-
const
|
|
45
|
+
const runtimePorts = runtimePlans.flatMap((plan) => plan.publishedPort ? [plan.publishedPort] : []);
|
|
46
|
+
const moltnetPorts = options.moltnet?.publishedPorts ?? [];
|
|
47
|
+
const ports = [...new Set([...runtimePorts, ...moltnetPorts])].sort((left, right) => left - right);
|
|
34
48
|
const runtimeHomes = [
|
|
35
49
|
...new Set(runtimePlans.flatMap((plan) => (plan.instancePaths.homePath ? [plan.instancePaths.homePath] : [])))
|
|
36
50
|
].sort();
|
|
@@ -48,6 +62,14 @@ export const createContainerArtifacts = async (plan, compiledNodes) => {
|
|
|
48
62
|
return {
|
|
49
63
|
executablePaths: ["entrypoint.sh"],
|
|
50
64
|
files,
|
|
65
|
+
...(options.moltnet
|
|
66
|
+
? {
|
|
67
|
+
moltnet: {
|
|
68
|
+
bridgePlans: options.moltnet.bridgePlans,
|
|
69
|
+
serverPlans: options.moltnet.serverPlans
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
: {}),
|
|
51
73
|
report: {
|
|
52
74
|
dockerfile: "Dockerfile",
|
|
53
75
|
entrypoint: "entrypoint.sh",
|
|
@@ -76,6 +76,9 @@ export const createEnvVariableMap = (compiledNodes, runtimePlans) => {
|
|
|
76
76
|
for (const variable of runtimePlan.meta.env ?? []) {
|
|
77
77
|
register(variable.name, variable.required, variable.description, "runtime");
|
|
78
78
|
}
|
|
79
|
+
for (const binding of runtimePlan.targetConfigEnvBindings ?? []) {
|
|
80
|
+
register(binding.envName, true, `Injected into ${runtimePlan.runtimeName} runtime config`, "runtime");
|
|
81
|
+
}
|
|
79
82
|
}
|
|
80
83
|
return variables;
|
|
81
84
|
};
|
|
@@ -115,6 +118,13 @@ const resolveTargetModelAuthMethods = (target, inputs) => {
|
|
|
115
118
|
}
|
|
116
119
|
return Object.fromEntries([...methods.entries()].sort(([left], [right]) => left.localeCompare(right)));
|
|
117
120
|
};
|
|
121
|
+
const resolveTargetExposure = (target, inputs) => {
|
|
122
|
+
const sourceIds = new Set(target.sourceIds ?? []);
|
|
123
|
+
if (sourceIds.size === 0) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
return inputs.some((input) => sourceIds.has(input.id) && input.value.kind === "agent" && input.value.expose === true);
|
|
127
|
+
};
|
|
118
128
|
export const createRuntimeTargetPlans = async (plan, compiledNodes) => {
|
|
119
129
|
const runtimeNames = Object.keys(plan.runtimes).sort();
|
|
120
130
|
const runtimePlans = [];
|
|
@@ -135,6 +145,7 @@ export const createRuntimeTargetPlans = async (plan, compiledNodes) => {
|
|
|
135
145
|
targets.forEach((target, index) => {
|
|
136
146
|
assertTargetHasConfig(runtimeName, target.id, adapter.container, target.files);
|
|
137
147
|
const instancePaths = resolveInstancePaths(runtimeName, target.id, adapter.container);
|
|
148
|
+
const portStride = adapter.container.portStride ?? 1;
|
|
138
149
|
runtimePlans.push({
|
|
139
150
|
configEnvBindings: resolveTargetConfigEnvBindings(adapter.container, target) ?? [],
|
|
140
151
|
envFiles: resolveTargetEnvFiles(instancePaths.configPath, target),
|
|
@@ -143,9 +154,13 @@ export const createRuntimeTargetPlans = async (plan, compiledNodes) => {
|
|
|
143
154
|
meta: adapter.container,
|
|
144
155
|
modelAuthMethods: resolveTargetModelAuthMethods(target, targetInputs),
|
|
145
156
|
modelSecretsRequired: resolveTargetModelSecrets(target, targetInputs),
|
|
146
|
-
port: adapter.container.port ? adapter.container.port + index : undefined,
|
|
157
|
+
port: adapter.container.port ? adapter.container.port + (index * portStride) : undefined,
|
|
158
|
+
publishedPort: resolveTargetExposure(target, targetInputs) && adapter.container.port
|
|
159
|
+
? adapter.container.port + (index * portStride)
|
|
160
|
+
: undefined,
|
|
147
161
|
runtimeName,
|
|
148
162
|
runtimeRoot: recipe.runtimeRoot,
|
|
163
|
+
targetConfigEnvBindings: target.configEnvBindings,
|
|
149
164
|
targetFiles: target.files
|
|
150
165
|
});
|
|
151
166
|
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { EmittedFile } from "../runtime/index.js";
|
|
2
2
|
import type { ContainerEnvVariable, RuntimeTargetPlan } from "./containerArtifactsTypes.js";
|
|
3
|
+
import type { EntrypointOptions } from "./containerEntrypointRender.js";
|
|
4
|
+
export { renderEntrypoint } from "./containerEntrypointRender.js";
|
|
5
|
+
export type { EntrypointOptions } from "./containerEntrypointRender.js";
|
|
3
6
|
export declare const renderEnvExample: (variables: ContainerEnvVariable[]) => string;
|
|
4
|
-
export declare const renderDockerfile: (runtimePlans: RuntimeTargetPlan[]) => Promise<string>;
|
|
7
|
+
export declare const renderDockerfile: (runtimePlans: RuntimeTargetPlan[], options?: EntrypointOptions) => Promise<string>;
|
|
5
8
|
export declare const createRootfsFiles: (runtimePlans: RuntimeTargetPlan[]) => EmittedFile[];
|
|
6
|
-
export declare const renderEntrypoint: (runtimePlans: RuntimeTargetPlan[], requiredSecrets: string[]) => string;
|