spawnfile 0.1.11 → 0.1.13
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 +21 -3
- package/dist/auth/runtimeCredentials.js +18 -2
- package/dist/cli/devCommands.d.ts +3 -0
- package/dist/cli/devCommands.js +115 -0
- package/dist/cli/lifecycleCommands.js +103 -1
- package/dist/cli/modelCommands.js +3 -0
- package/dist/cli/resolveCommandInput.d.ts +19 -0
- package/dist/cli/resolveCommandInput.js +25 -0
- package/dist/cli/runCli.d.ts +10 -1
- package/dist/cli/runCli.js +41 -13
- package/dist/cli/runtimeCommands.js +1 -0
- package/dist/cli/statusCommand.d.ts +43 -0
- package/dist/cli/statusCommand.js +428 -0
- package/dist/cli/surfaceCommands.js +4 -0
- package/dist/compiler/agentSurfaces.js +2 -4
- package/dist/compiler/buildProject.d.ts +9 -1
- package/dist/compiler/buildProject.js +44 -5
- package/dist/compiler/compileProject.d.ts +2 -0
- package/dist/compiler/compileProject.js +22 -11
- package/dist/compiler/containerArtifacts.d.ts +1 -0
- package/dist/compiler/containerArtifacts.js +208 -32
- package/dist/compiler/containerArtifactsPlans.js +7 -4
- package/dist/compiler/containerArtifactsRender.d.ts +7 -1
- package/dist/compiler/containerArtifactsRender.js +31 -69
- package/dist/compiler/containerArtifactsTypes.d.ts +9 -0
- package/dist/compiler/containerEntrypointRender.js +22 -32
- package/dist/compiler/containerPackageRender.d.ts +15 -0
- package/dist/compiler/containerPackageRender.js +63 -0
- package/dist/compiler/containerTargetResources.js +3 -1
- package/dist/compiler/index.d.ts +1 -0
- package/dist/compiler/index.js +1 -0
- package/dist/compiler/moltnetArtifacts.js +21 -1
- package/dist/compiler/moltnetBinaries.d.ts +4 -1
- package/dist/compiler/moltnetBinaries.js +24 -3
- package/dist/compiler/moltnetClientConfig.d.ts +1 -1
- package/dist/compiler/moltnetClientConfig.js +14 -16
- package/dist/compiler/moltnetNodeConfig.js +2 -4
- package/dist/compiler/moltnetResolution.js +1 -1
- package/dist/compiler/moltnetRoomMemberships.js +1 -2
- package/dist/compiler/moltnetRuntimeConfig.d.ts +1 -1
- package/dist/compiler/moltnetRuntimeConfig.js +9 -10
- package/dist/compiler/networkBinding.d.ts +14 -0
- package/dist/compiler/networkBinding.js +34 -0
- package/dist/compiler/publishProject.d.ts +13 -0
- package/dist/compiler/publishProject.js +72 -0
- package/dist/compiler/runProject.d.ts +26 -12
- package/dist/compiler/runProject.js +109 -126
- package/dist/compiler/runProjectAuth.d.ts +5 -0
- package/dist/compiler/runProjectAuth.js +98 -0
- package/dist/compiler/runProjectDocker.d.ts +19 -0
- package/dist/compiler/runProjectDocker.js +202 -0
- package/dist/compiler/types.d.ts +1 -2
- package/dist/compiler/upProject.d.ts +6 -0
- package/dist/compiler/upProject.js +43 -8
- package/dist/compiler/view/buildOrganizationView.js +4 -1
- package/dist/compiler/view/declarations.d.ts +4 -0
- package/dist/compiler/view/declarations.js +104 -0
- package/dist/compiler/view/renderNetworks.js +1 -2
- package/dist/compiler/view/renderTree.js +6 -2
- package/dist/compiler/view/types.d.ts +64 -1
- package/dist/deployment/dockerInspect.d.ts +29 -0
- package/dist/deployment/dockerInspect.js +130 -0
- package/dist/deployment/dockerLabels.d.ts +16 -0
- package/dist/deployment/dockerLabels.js +32 -0
- package/dist/deployment/dockerLogs.d.ts +24 -0
- package/dist/deployment/dockerLogs.js +96 -0
- package/dist/deployment/dockerManager.d.ts +59 -0
- package/dist/deployment/dockerManager.js +76 -0
- package/dist/deployment/dockerProbeGateway.d.ts +16 -0
- package/dist/deployment/dockerProbeGateway.js +48 -0
- package/dist/deployment/dockerRecover.d.ts +17 -0
- package/dist/deployment/dockerRecover.js +129 -0
- package/dist/deployment/homeStore.d.ts +19 -0
- package/dist/deployment/homeStore.js +130 -0
- package/dist/deployment/index.d.ts +10 -0
- package/dist/deployment/index.js +10 -0
- package/dist/deployment/names.d.ts +3 -0
- package/dist/deployment/names.js +12 -0
- package/dist/deployment/record.d.ts +76 -0
- package/dist/deployment/record.js +174 -0
- package/dist/deployment/target.d.ts +35 -0
- package/dist/deployment/target.js +96 -0
- package/dist/dev/activity.d.ts +14 -0
- package/dist/dev/activity.js +48 -0
- package/dist/dev/docker.d.ts +16 -0
- package/dist/dev/docker.js +71 -0
- package/dist/dev/index.d.ts +2 -0
- package/dist/dev/index.js +2 -0
- package/dist/dev/project.d.ts +35 -0
- package/dist/dev/project.js +164 -0
- package/dist/distribution/buildDistributionReport.d.ts +22 -0
- package/dist/distribution/buildDistributionReport.js +51 -0
- package/dist/distribution/consumeImage.d.ts +29 -0
- package/dist/distribution/consumeImage.js +254 -0
- package/dist/distribution/consumeImageSupport.d.ts +18 -0
- package/dist/distribution/consumeImageSupport.js +63 -0
- package/dist/distribution/distributionReportSchema.d.ts +84 -0
- package/dist/distribution/distributionReportSchema.js +107 -0
- package/dist/distribution/dockerRunner.d.ts +5 -0
- package/dist/distribution/dockerRunner.js +21 -0
- package/dist/distribution/extractImage.d.ts +25 -0
- package/dist/distribution/extractImage.js +96 -0
- package/dist/distribution/fingerprint.d.ts +2 -0
- package/dist/distribution/fingerprint.js +14 -0
- package/dist/distribution/imageRef.d.ts +9 -0
- package/dist/distribution/imageRef.js +65 -0
- package/dist/distribution/imageRuntimeAuth.d.ts +19 -0
- package/dist/distribution/imageRuntimeAuth.js +71 -0
- package/dist/distribution/index.d.ts +24 -0
- package/dist/distribution/index.js +16 -0
- package/dist/distribution/preflight.d.ts +11 -0
- package/dist/distribution/preflight.js +65 -0
- package/dist/distribution/projectImageView.d.ts +8 -0
- package/dist/distribution/projectImageView.js +83 -0
- package/dist/distribution/projectName.d.ts +1 -0
- package/dist/distribution/projectName.js +12 -0
- package/dist/distribution/renderImageInterface.d.ts +30 -0
- package/dist/distribution/renderImageInterface.js +86 -0
- package/dist/distribution/tarReader.d.ts +10 -0
- package/dist/distribution/tarReader.js +69 -0
- package/dist/distribution/types.d.ts +80 -0
- package/dist/distribution/types.js +4 -0
- package/dist/distribution/verifyDistributionReport.d.ts +12 -0
- package/dist/distribution/verifyDistributionReport.js +29 -0
- package/dist/filesystem/paths.d.ts +6 -0
- package/dist/filesystem/paths.js +11 -0
- package/dist/manifest/loadManifest.js +22 -2
- package/dist/manifest/renderSpawnfile.js +2 -4
- package/dist/manifest/schemas.d.ts +17 -41
- package/dist/manifest/surfaceSchemas.d.ts +19 -47
- package/dist/manifest/surfaceSchemas.js +3 -6
- package/dist/report/createReport.d.ts +7 -1
- package/dist/report/createReport.js +28 -1
- package/dist/report/types.d.ts +43 -0
- package/dist/runtime/common.d.ts +2 -0
- package/dist/runtime/common.js +1 -1
- package/dist/runtime/container.d.ts +1 -0
- package/dist/runtime/container.js +82 -15
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/install.d.ts +1 -11
- package/dist/runtime/install.js +27 -30
- package/dist/runtime/openclaw/adapter.js +9 -1
- package/dist/runtime/openclaw/configAuth.d.ts +15 -0
- package/dist/runtime/openclaw/configAuth.js +46 -0
- package/dist/runtime/openclaw/runAuth.d.ts +6 -0
- package/dist/runtime/openclaw/runAuth.js +7 -55
- package/dist/runtime/openclaw/statusProbes.d.ts +2 -0
- package/dist/runtime/openclaw/statusProbes.js +31 -0
- package/dist/runtime/pi/adapter.d.ts +4 -0
- package/dist/runtime/pi/adapter.js +198 -0
- package/dist/runtime/pi/appActivitySource.d.ts +1 -0
- package/dist/runtime/pi/appActivitySource.js +87 -0
- package/dist/runtime/pi/appCoreSource.d.ts +1 -0
- package/dist/runtime/pi/appCoreSource.js +354 -0
- package/dist/runtime/pi/appPreludeSource.d.ts +1 -0
- package/dist/runtime/pi/appPreludeSource.js +103 -0
- package/dist/runtime/pi/appSource.d.ts +1 -0
- package/dist/runtime/pi/appSource.js +8 -0
- package/dist/runtime/pi/appTemplate.d.ts +28 -0
- package/dist/runtime/pi/appTemplate.js +144 -0
- package/dist/runtime/pi/runAuth.d.ts +2 -0
- package/dist/runtime/pi/runAuth.js +68 -0
- package/dist/runtime/picoclaw/adapter.js +10 -0
- package/dist/runtime/picoclaw/runAuth.d.ts +7 -0
- package/dist/runtime/picoclaw/runAuth.js +8 -68
- package/dist/runtime/picoclaw/statusProbes.d.ts +2 -0
- package/dist/runtime/picoclaw/statusProbes.js +100 -0
- package/dist/runtime/registry.d.ts +0 -5
- package/dist/runtime/registry.js +5 -12
- package/dist/runtime/statusProbes.d.ts +16 -0
- package/dist/runtime/statusProbes.js +41 -0
- package/dist/runtime/types.d.ts +53 -1
- package/dist/shared/errors.d.ts +6 -0
- package/dist/shared/errors.js +9 -0
- package/dist/status/buildStatus.d.ts +13 -0
- package/dist/status/buildStatus.js +266 -0
- package/dist/status/compileReport.d.ts +96 -0
- package/dist/status/compileReport.js +230 -0
- package/dist/status/compiledContainerObservations.d.ts +5 -0
- package/dist/status/compiledContainerObservations.js +63 -0
- package/dist/status/deploymentLogs.d.ts +12 -0
- package/dist/status/deploymentLogs.js +45 -0
- package/dist/status/deployments.d.ts +14 -0
- package/dist/status/deployments.js +121 -0
- package/dist/status/imageStatusReport.d.ts +10 -0
- package/dist/status/imageStatusReport.js +73 -0
- package/dist/status/index.d.ts +14 -0
- package/dist/status/index.js +14 -0
- package/dist/status/moltnetProbes.d.ts +21 -0
- package/dist/status/moltnetProbes.js +240 -0
- package/dist/status/registryDrift.d.ts +28 -0
- package/dist/status/registryDrift.js +119 -0
- package/dist/status/renderStatus.d.ts +2 -0
- package/dist/status/renderStatus.js +230 -0
- package/dist/status/runtimeProbes.d.ts +13 -0
- package/dist/status/runtimeProbes.js +111 -0
- package/dist/status/selectionSubjects.d.ts +8 -0
- package/dist/status/selectionSubjects.js +77 -0
- package/dist/status/selectors.d.ts +14 -0
- package/dist/status/selectors.js +90 -0
- package/dist/status/traversal.d.ts +6 -0
- package/dist/status/traversal.js +15 -0
- package/dist/status/types.d.ts +113 -0
- package/dist/status/types.js +1 -0
- package/package.json +9 -2
- package/runtimes.yaml +44 -21
- package/dist/runtime/tinyclaw/adapter.d.ts +0 -2
- package/dist/runtime/tinyclaw/adapter.js +0 -284
- package/dist/runtime/tinyclaw/runAuth.d.ts +0 -2
- package/dist/runtime/tinyclaw/runAuth.js +0 -49
- package/dist/runtime/tinyclaw/scaffold-assets/AGENTS.md +0 -160
- package/dist/runtime/tinyclaw/scaffold-assets/CLAUDE.md +0 -5
- package/dist/runtime/tinyclaw/scaffold-assets/SOUL.md +0 -177
- package/dist/runtime/tinyclaw/scaffold.d.ts +0 -2
- package/dist/runtime/tinyclaw/scaffold.js +0 -24
- package/dist/runtime/tinyclaw/schedules.d.ts +0 -9
- package/dist/runtime/tinyclaw/schedules.js +0 -62
- package/dist/runtime/tinyclaw/surfaces.d.ts +0 -8
- package/dist/runtime/tinyclaw/surfaces.js +0 -94
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { execFile as execFileCallback, spawn } from "node:child_process";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
5
|
+
const execFile = promisify(execFileCallback);
|
|
6
|
+
const parseDockerContextHost = (stdout) => {
|
|
7
|
+
const trimmed = stdout.trim();
|
|
8
|
+
if (!trimmed) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const parsed = JSON.parse(trimmed);
|
|
13
|
+
return typeof parsed === "string" ? parsed : null;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return trimmed;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const resolveSshDockerContext = async (invocation) => {
|
|
20
|
+
if (!invocation.dockerContext) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const { stdout } = await execFile(invocation.command, [
|
|
24
|
+
"context",
|
|
25
|
+
"inspect",
|
|
26
|
+
invocation.dockerContext,
|
|
27
|
+
"--format",
|
|
28
|
+
"{{json .Endpoints.docker.Host}}"
|
|
29
|
+
], { cwd: invocation.cwd, timeout: 10_000 });
|
|
30
|
+
const host = parseDockerContextHost(stdout);
|
|
31
|
+
if (!host?.startsWith("ssh://")) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const url = new URL(host);
|
|
35
|
+
const user = decodeURIComponent(url.username);
|
|
36
|
+
const targetHost = url.hostname;
|
|
37
|
+
return {
|
|
38
|
+
host,
|
|
39
|
+
...(url.port ? { port: url.port } : {}),
|
|
40
|
+
target: user ? `${user}@${targetHost}` : targetHost
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
const sshArgs = (context, command) => [
|
|
44
|
+
...(context.port ? ["-p", context.port] : []),
|
|
45
|
+
context.target,
|
|
46
|
+
command
|
|
47
|
+
];
|
|
48
|
+
const scpArgs = (context, source, target) => [
|
|
49
|
+
...(context.port ? ["-P", context.port] : []),
|
|
50
|
+
"-r",
|
|
51
|
+
source,
|
|
52
|
+
`${context.target}:${target}`
|
|
53
|
+
];
|
|
54
|
+
const shellQuote = (value) => `'${value.replace(/'/g, `'\"'\"'`)}'`;
|
|
55
|
+
const createRemoteDirectory = async (context) => {
|
|
56
|
+
const { stdout } = await execFile("ssh", sshArgs(context, "mktemp -d /tmp/spawnfile-run-XXXXXX"), {
|
|
57
|
+
timeout: 10_000
|
|
58
|
+
});
|
|
59
|
+
return stdout.trim();
|
|
60
|
+
};
|
|
61
|
+
const copyPathToRemote = async (context, sourcePath, remotePath) => {
|
|
62
|
+
await execFile("scp", scpArgs(context, sourcePath, remotePath), { timeout: 120_000 });
|
|
63
|
+
};
|
|
64
|
+
const removeRemoteDirectory = async (context, remoteDirectory) => {
|
|
65
|
+
await execFile("ssh", sshArgs(context, `rm -rf ${shellQuote(remoteDirectory)}`), {
|
|
66
|
+
timeout: 10_000
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
const splitVolumeSpec = (spec) => {
|
|
70
|
+
const delimiter = spec.indexOf(":");
|
|
71
|
+
if (delimiter <= 0) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
rest: spec.slice(delimiter),
|
|
76
|
+
source: spec.slice(0, delimiter)
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
const collectBindMountSources = (args) => {
|
|
80
|
+
const sources = new Set();
|
|
81
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
82
|
+
if (args[index] !== "-v" && args[index] !== "--volume") {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const volume = args[index + 1];
|
|
86
|
+
if (!volume) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const parsed = splitVolumeSpec(volume);
|
|
90
|
+
if (parsed && path.isAbsolute(parsed.source)) {
|
|
91
|
+
sources.add(parsed.source);
|
|
92
|
+
}
|
|
93
|
+
index += 1;
|
|
94
|
+
}
|
|
95
|
+
return [...sources].sort();
|
|
96
|
+
};
|
|
97
|
+
const rewriteBindMountSources = (args, replacements) => args.map((arg, index) => {
|
|
98
|
+
const previous = args[index - 1];
|
|
99
|
+
if (previous !== "-v" && previous !== "--volume") {
|
|
100
|
+
return arg;
|
|
101
|
+
}
|
|
102
|
+
const parsed = splitVolumeSpec(arg);
|
|
103
|
+
if (!parsed) {
|
|
104
|
+
return arg;
|
|
105
|
+
}
|
|
106
|
+
const replacement = replacements.get(parsed.source);
|
|
107
|
+
return replacement ? `${replacement}${parsed.rest}` : arg;
|
|
108
|
+
});
|
|
109
|
+
const prepareRemoteBindMounts = async (invocation) => {
|
|
110
|
+
const context = await resolveSshDockerContext(invocation);
|
|
111
|
+
if (!context) {
|
|
112
|
+
return { cleanup: async () => undefined, invocation };
|
|
113
|
+
}
|
|
114
|
+
const sources = collectBindMountSources(invocation.args);
|
|
115
|
+
if (sources.length === 0) {
|
|
116
|
+
return { cleanup: async () => undefined, invocation };
|
|
117
|
+
}
|
|
118
|
+
const remoteDirectory = await createRemoteDirectory(context);
|
|
119
|
+
const replacements = new Map();
|
|
120
|
+
for (const [index, source] of sources.entries()) {
|
|
121
|
+
const remotePath = `${remoteDirectory}/${index}-${path.basename(source) || "mount"}`;
|
|
122
|
+
await copyPathToRemote(context, source, remotePath);
|
|
123
|
+
replacements.set(source, remotePath);
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
cleanup: invocation.detach
|
|
127
|
+
? async () => undefined
|
|
128
|
+
: async () => removeRemoteDirectory(context, remoteDirectory),
|
|
129
|
+
invocation: {
|
|
130
|
+
...invocation,
|
|
131
|
+
args: rewriteBindMountSources(invocation.args, replacements)
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
const inspectImageArgs = (invocation, containerId) => {
|
|
136
|
+
const base = invocation.dockerContext
|
|
137
|
+
? ["--context", invocation.dockerContext, "inspect"]
|
|
138
|
+
: invocation.dockerHost
|
|
139
|
+
? ["--host", invocation.dockerHost, "inspect"]
|
|
140
|
+
: ["inspect"];
|
|
141
|
+
return [...base, "--format", "{{.Image}}", containerId];
|
|
142
|
+
};
|
|
143
|
+
const inspectDetachedImageId = async (invocation, containerId) => {
|
|
144
|
+
try {
|
|
145
|
+
const { stdout } = await execFile(invocation.command, inspectImageArgs(invocation, containerId), {
|
|
146
|
+
cwd: invocation.cwd,
|
|
147
|
+
timeout: 10_000
|
|
148
|
+
});
|
|
149
|
+
return stdout.trim() || undefined;
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
153
|
+
throw new SpawnfileError("runtime_error", `Unable to inspect detached container ${containerId} image id: ${message}`);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
const runPreparedDockerContainer = (prepared) => new Promise((resolve, reject) => {
|
|
157
|
+
let stdout = "";
|
|
158
|
+
const child = spawn(prepared.invocation.command, prepared.invocation.args, {
|
|
159
|
+
cwd: prepared.invocation.cwd,
|
|
160
|
+
stdio: prepared.invocation.detach ? ["ignore", "pipe", "inherit"] : "inherit"
|
|
161
|
+
});
|
|
162
|
+
const settle = (finish) => {
|
|
163
|
+
prepared.cleanup().then(finish, reject);
|
|
164
|
+
};
|
|
165
|
+
const rejectAfterCleanup = (error) => {
|
|
166
|
+
prepared.cleanup().then(() => reject(error), reject);
|
|
167
|
+
};
|
|
168
|
+
if (prepared.invocation.detach && child.stdout) {
|
|
169
|
+
child.stdout.setEncoding("utf8");
|
|
170
|
+
child.stdout.on("data", (chunk) => {
|
|
171
|
+
stdout += chunk;
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
child.once("error", (error) => {
|
|
175
|
+
rejectAfterCleanup(new SpawnfileError("runtime_error", `Unable to start docker run for ${prepared.invocation.imageTag}: ${error.message}`));
|
|
176
|
+
});
|
|
177
|
+
child.once("exit", (code, signal) => {
|
|
178
|
+
if (code === 0) {
|
|
179
|
+
const containerId = stdout.trim().split(/\s+/)[0];
|
|
180
|
+
if (!prepared.invocation.detach || !containerId) {
|
|
181
|
+
settle(() => resolve(undefined));
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
inspectDetachedImageId(prepared.invocation, containerId)
|
|
185
|
+
.then((imageId) => resolve({ containerId, ...(imageId ? { imageId } : {}) }))
|
|
186
|
+
.catch(reject);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
rejectAfterCleanup(new SpawnfileError("runtime_error", signal
|
|
190
|
+
? `Docker run for ${prepared.invocation.imageTag} exited from signal ${signal}`
|
|
191
|
+
: `Docker run for ${prepared.invocation.imageTag} failed with exit code ${code ?? "unknown"}`));
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
export const runDockerContainer = (invocation) => {
|
|
195
|
+
if (!invocation.dockerContext || collectBindMountSources(invocation.args).length === 0) {
|
|
196
|
+
return runPreparedDockerContainer({
|
|
197
|
+
cleanup: async () => undefined,
|
|
198
|
+
invocation
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return prepareRemoteBindMounts(invocation).then(runPreparedDockerContainer);
|
|
202
|
+
};
|
package/dist/compiler/types.d.ts
CHANGED
|
@@ -82,8 +82,7 @@ export interface ResolvedHttpSurface {
|
|
|
82
82
|
port?: number;
|
|
83
83
|
}
|
|
84
84
|
export interface ResolvedMoltnetRoomPolicy {
|
|
85
|
-
|
|
86
|
-
reply?: "auto" | "never";
|
|
85
|
+
wake?: "all" | "mentions" | "thread_only" | "never";
|
|
87
86
|
}
|
|
88
87
|
export interface ResolvedMoltnetDMConfig extends ResolvedMoltnetRoomPolicy {
|
|
89
88
|
enabled: boolean;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type DockerTargetExecFile } from "../deployment/index.js";
|
|
1
2
|
import { type BuildProjectResult, type DockerBuildRunner } from "./buildProject.js";
|
|
2
3
|
import { type DockerRunRunner } from "./runProject.js";
|
|
3
4
|
import { CompileProjectOptions } from "./compileProject.js";
|
|
@@ -6,14 +7,19 @@ export interface UpProjectOptions extends CompileProjectOptions {
|
|
|
6
7
|
buildRunner?: DockerBuildRunner;
|
|
7
8
|
containerName?: string;
|
|
8
9
|
detach?: boolean;
|
|
10
|
+
deploymentName?: string;
|
|
9
11
|
dockerCommand?: string;
|
|
12
|
+
dockerContext?: string;
|
|
13
|
+
dockerHost?: string;
|
|
10
14
|
envFilePath?: string;
|
|
11
15
|
imageTag?: string;
|
|
12
16
|
runRunner?: DockerRunRunner;
|
|
17
|
+
targetExecFile?: DockerTargetExecFile;
|
|
13
18
|
}
|
|
14
19
|
export interface UpProjectResult extends BuildProjectResult {
|
|
15
20
|
authProfileName: string | null;
|
|
16
21
|
containerName: string | null;
|
|
22
|
+
deploymentRecordPath?: string | null;
|
|
17
23
|
supportDirectory: string | null;
|
|
18
24
|
}
|
|
19
25
|
export declare const upProject: (inputPath: string, options?: UpProjectOptions) => Promise<UpProjectResult>;
|
|
@@ -1,37 +1,72 @@
|
|
|
1
|
+
import path from "node:path";
|
|
1
2
|
import { removeDirectory } from "../filesystem/index.js";
|
|
3
|
+
import { writeDockerDeploymentRecordForRun } from "../deployment/index.js";
|
|
2
4
|
import { buildProject } from "./buildProject.js";
|
|
3
|
-
import { createDockerRunInvocation, runDockerContainer } from "./runProject.js";
|
|
5
|
+
import { createDockerRunInvocation, resolveDetachedDeploymentOptions, runDockerContainer } from "./runProject.js";
|
|
4
6
|
import { requireAuthProfile } from "../auth/index.js";
|
|
7
|
+
import { DEFAULT_OUTPUT_DIRECTORY } from "../shared/index.js";
|
|
5
8
|
export const upProject = async (inputPath, options = {}) => {
|
|
9
|
+
const resolvedOptions = await resolveDetachedDeploymentOptions(path.resolve(options.outputDirectory ?? DEFAULT_OUTPUT_DIRECTORY), {
|
|
10
|
+
authProfile: options.authProfile,
|
|
11
|
+
containerName: options.containerName,
|
|
12
|
+
deploymentName: options.deploymentName,
|
|
13
|
+
detach: options.detach,
|
|
14
|
+
dockerCommand: options.dockerCommand,
|
|
15
|
+
dockerContext: options.dockerContext,
|
|
16
|
+
dockerHost: options.dockerHost,
|
|
17
|
+
envFilePath: options.envFilePath,
|
|
18
|
+
imageTag: options.imageTag,
|
|
19
|
+
targetExecFile: options.targetExecFile
|
|
20
|
+
});
|
|
6
21
|
const buildResult = await buildProject(inputPath, {
|
|
7
22
|
buildRunner: options.buildRunner,
|
|
8
23
|
clean: options.clean,
|
|
24
|
+
dockerContext: resolvedOptions.dockerContext,
|
|
9
25
|
dockerCommand: options.dockerCommand,
|
|
10
|
-
imageTag:
|
|
26
|
+
imageTag: resolvedOptions.imageTag,
|
|
11
27
|
outputDirectory: options.outputDirectory
|
|
12
28
|
});
|
|
13
|
-
const authProfile =
|
|
14
|
-
? await requireAuthProfile(
|
|
29
|
+
const authProfile = resolvedOptions.authProfile
|
|
30
|
+
? await requireAuthProfile(resolvedOptions.authProfile)
|
|
15
31
|
: null;
|
|
16
|
-
const
|
|
32
|
+
const imageTag = resolvedOptions.imageTag ?? buildResult.imageTag;
|
|
33
|
+
const invocation = await createDockerRunInvocation(buildResult, imageTag, {
|
|
17
34
|
authProfile,
|
|
18
|
-
containerName:
|
|
35
|
+
containerName: resolvedOptions.containerName,
|
|
19
36
|
detach: options.detach,
|
|
37
|
+
deploymentName: resolvedOptions.deploymentName,
|
|
20
38
|
dockerCommand: options.dockerCommand,
|
|
21
|
-
|
|
39
|
+
dockerContext: resolvedOptions.dockerContext,
|
|
40
|
+
dockerHost: resolvedOptions.dockerHost,
|
|
41
|
+
envFilePath: resolvedOptions.envFilePath
|
|
22
42
|
});
|
|
43
|
+
let runMetadata;
|
|
23
44
|
try {
|
|
24
|
-
await (options.runRunner ?? runDockerContainer)(invocation);
|
|
45
|
+
runMetadata = await (options.runRunner ?? runDockerContainer)(invocation);
|
|
25
46
|
}
|
|
26
47
|
finally {
|
|
27
48
|
if (!invocation.detach) {
|
|
28
49
|
await removeDirectory(invocation.supportDirectory);
|
|
29
50
|
}
|
|
30
51
|
}
|
|
52
|
+
const deploymentRecordPath = invocation.detach && invocation.deploymentName
|
|
53
|
+
? await writeDockerDeploymentRecordForRun({
|
|
54
|
+
authProfileName: authProfile?.name ?? null,
|
|
55
|
+
envFilePath: resolvedOptions.envFilePath,
|
|
56
|
+
imageTag,
|
|
57
|
+
invocation,
|
|
58
|
+
outputDirectory: buildResult.outputDirectory,
|
|
59
|
+
report: buildResult.report,
|
|
60
|
+
runMetadata: runMetadata ?? undefined,
|
|
61
|
+
targetExecFile: options.targetExecFile
|
|
62
|
+
})
|
|
63
|
+
: null;
|
|
31
64
|
return {
|
|
32
65
|
...buildResult,
|
|
33
66
|
authProfileName: authProfile?.name ?? null,
|
|
34
67
|
containerName: invocation.containerName,
|
|
68
|
+
deploymentRecordPath,
|
|
69
|
+
imageTag,
|
|
35
70
|
supportDirectory: invocation.supportDirectory
|
|
36
71
|
};
|
|
37
72
|
};
|
|
@@ -2,6 +2,7 @@ import path from "node:path";
|
|
|
2
2
|
import { SpawnfileError } from "../../shared/index.js";
|
|
3
3
|
import { buildCompilePlan } from "../buildCompilePlan.js";
|
|
4
4
|
import { resolveMoltnetRoomMemberships } from "../moltnetRoomMemberships.js";
|
|
5
|
+
import { buildDeclaredNodeView, buildRuntimeViews } from "./declarations.js";
|
|
5
6
|
const createNameCounts = (plan) => {
|
|
6
7
|
const counts = new Map();
|
|
7
8
|
for (const node of plan.nodes) {
|
|
@@ -82,7 +83,9 @@ const buildTreeNode = (node, nodeById, edgesBySource, nameCounts, ancestors = []
|
|
|
82
83
|
kind: node.kind,
|
|
83
84
|
name: node.value.name,
|
|
84
85
|
networks: buildTreeNetworkSummaries(node),
|
|
86
|
+
declared: buildDeclaredNodeView(node),
|
|
85
87
|
runtimeName: node.runtimeName,
|
|
88
|
+
slug: node.slug,
|
|
86
89
|
source: node.value.source
|
|
87
90
|
};
|
|
88
91
|
};
|
|
@@ -219,6 +222,6 @@ export const buildOrganizationView = async (inputPath) => {
|
|
|
219
222
|
networks: buildNetworks(plan),
|
|
220
223
|
projectRoot: path.dirname(plan.root),
|
|
221
224
|
root,
|
|
222
|
-
runtimes:
|
|
225
|
+
runtimes: buildRuntimeViews(plan)
|
|
223
226
|
};
|
|
224
227
|
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CompilePlan, CompilePlanNode } from "../types.js";
|
|
2
|
+
import type { OrganizationRuntimeView, OrganizationViewDeclaredSummary } from "./types.js";
|
|
3
|
+
export declare const buildDeclaredNodeView: (node: CompilePlanNode) => OrganizationViewDeclaredSummary;
|
|
4
|
+
export declare const buildRuntimeViews: (plan: CompilePlan) => OrganizationRuntimeView[];
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { resolveEffectiveModelTarget } from "../modelEnv.js";
|
|
2
|
+
import { listInteractiveSurfaceScopes } from "../interactiveSurfaceScopes.js";
|
|
3
|
+
const summarizeModel = (node) => {
|
|
4
|
+
if (node.value.kind !== "agent" || !node.value.execution?.model?.primary) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
const target = resolveEffectiveModelTarget(node.value.execution.model.primary, node.value.execution);
|
|
8
|
+
return {
|
|
9
|
+
authMethod: target.auth.method,
|
|
10
|
+
name: target.name,
|
|
11
|
+
provider: target.provider
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
const summarizeSchedule = (node) => {
|
|
15
|
+
if (node.value.kind !== "agent" || !node.value.schedule) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const schedule = node.value.schedule;
|
|
19
|
+
if (schedule.kind === "cron") {
|
|
20
|
+
return {
|
|
21
|
+
expression: schedule.cron,
|
|
22
|
+
kind: schedule.kind,
|
|
23
|
+
...(schedule.timezone ? { timezone: schedule.timezone } : {})
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (schedule.kind === "every") {
|
|
27
|
+
return {
|
|
28
|
+
expression: schedule.every,
|
|
29
|
+
kind: schedule.kind,
|
|
30
|
+
...(schedule.timezone ? { timezone: schedule.timezone } : {})
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return { kind: schedule.kind };
|
|
34
|
+
};
|
|
35
|
+
const surfaceSummaryFor = (name, surfaces) => {
|
|
36
|
+
if (!surfaces[name]) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const scopes = name === "moltnet"
|
|
40
|
+
? listInteractiveSurfaceScopes(surfaces).filter((scope) => scope.startsWith("moltnet:"))
|
|
41
|
+
: listInteractiveSurfaceScopes(surfaces).filter((scope) => scope === name);
|
|
42
|
+
return {
|
|
43
|
+
name,
|
|
44
|
+
scopes: scopes.length > 0 ? scopes : [name]
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
const summarizeSurfaces = (node) => {
|
|
48
|
+
const surfaces = node.value.kind === "agent" ? node.value.surfaces : undefined;
|
|
49
|
+
if (!surfaces) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
return ["discord", "http", "moltnet", "slack", "telegram", "webhook", "whatsapp"]
|
|
53
|
+
.map((name) => surfaceSummaryFor(name, surfaces))
|
|
54
|
+
.filter((surface) => surface !== null);
|
|
55
|
+
};
|
|
56
|
+
const summarizePackages = (node) => {
|
|
57
|
+
const packages = node.value.kind === "agent"
|
|
58
|
+
? node.value.packages ?? []
|
|
59
|
+
: node.value.shared.packages ?? [];
|
|
60
|
+
return packages.map((pkg) => ({
|
|
61
|
+
id: pkg.id,
|
|
62
|
+
manager: pkg.manager,
|
|
63
|
+
name: pkg.name,
|
|
64
|
+
...(pkg.scope ? { scope: pkg.scope } : {}),
|
|
65
|
+
...(pkg.version ? { version: pkg.version } : {})
|
|
66
|
+
}));
|
|
67
|
+
};
|
|
68
|
+
const summarizeResources = (node) => (node.value.workspaceResources ?? []).map((resource) => ({
|
|
69
|
+
id: resource.id,
|
|
70
|
+
kind: resource.kind,
|
|
71
|
+
mode: resource.mode,
|
|
72
|
+
mount: resource.mount,
|
|
73
|
+
sharing: resource.sharing
|
|
74
|
+
}));
|
|
75
|
+
export const buildDeclaredNodeView = (node) => {
|
|
76
|
+
const skills = node.value.kind === "agent" ? node.value.skills : node.value.shared.skills;
|
|
77
|
+
const mcpServers = node.value.kind === "agent"
|
|
78
|
+
? node.value.mcpServers
|
|
79
|
+
: node.value.shared.mcpServers;
|
|
80
|
+
return {
|
|
81
|
+
docs: node.value.docs.map((doc) => ({ role: doc.role, source: doc.sourcePath })),
|
|
82
|
+
mcpServers: mcpServers.map((server) => ({
|
|
83
|
+
name: server.name,
|
|
84
|
+
transport: server.transport
|
|
85
|
+
})),
|
|
86
|
+
model: summarizeModel(node),
|
|
87
|
+
packages: summarizePackages(node),
|
|
88
|
+
policy: {
|
|
89
|
+
mode: node.value.policyMode,
|
|
90
|
+
onDegrade: node.value.policyOnDegrade
|
|
91
|
+
},
|
|
92
|
+
resources: summarizeResources(node),
|
|
93
|
+
schedule: summarizeSchedule(node),
|
|
94
|
+
skills: skills.map((skill) => ({
|
|
95
|
+
name: skill.name,
|
|
96
|
+
ref: skill.ref,
|
|
97
|
+
requiresMcp: [...skill.requiresMcp]
|
|
98
|
+
})),
|
|
99
|
+
surfaces: summarizeSurfaces(node)
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
export const buildRuntimeViews = (plan) => Object.entries(plan.runtimes)
|
|
103
|
+
.map(([name, runtime]) => ({ name, nodeIds: [...runtime.nodeIds].sort() }))
|
|
104
|
+
.sort((left, right) => left.name.localeCompare(right.name));
|
|
@@ -8,8 +8,7 @@ const formatPolicy = (member) => {
|
|
|
8
8
|
return [];
|
|
9
9
|
}
|
|
10
10
|
return [
|
|
11
|
-
member.policy.
|
|
12
|
-
member.policy.reply ? `reply=${member.policy.reply}` : undefined
|
|
11
|
+
member.policy.wake ? `wake=${member.policy.wake}` : undefined
|
|
13
12
|
].filter((entry) => entry !== undefined);
|
|
14
13
|
};
|
|
15
14
|
const formatMember = (member, options, projectRoot) => {
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { formatSourceMeta } from "./sourcePaths.js";
|
|
2
2
|
const color = (value, code, options) => options.color ? `\u001b[${code}m${value}\u001b[0m` : value;
|
|
3
|
+
const formatAnnotations = (subjectKey, options) => {
|
|
4
|
+
const annotations = options.annotationFor?.(subjectKey) ?? [];
|
|
5
|
+
return annotations.length > 0 ? ` ${annotations.join(" ")}` : "";
|
|
6
|
+
};
|
|
3
7
|
const formatNode = (node, options, projectRoot) => {
|
|
4
8
|
const kind = color(node.kind, node.kind === "team" ? "36" : "32", options);
|
|
5
9
|
const metadata = node.kind === "team"
|
|
@@ -17,7 +21,7 @@ const formatNode = (node, options, projectRoot) => {
|
|
|
17
21
|
const details = metadata.filter((entry) => entry !== undefined);
|
|
18
22
|
const source = options.paths ? formatSourceMeta("source", node.source, projectRoot) : "";
|
|
19
23
|
const separator = details[0]?.startsWith("[") ? " " : " ";
|
|
20
|
-
return `${kind} ${node.displayName}${details.length > 0 ? `${separator}${details.join(" ")}` : ""}${source}`;
|
|
24
|
+
return `${kind} ${node.displayName}${details.length > 0 ? `${separator}${details.join(" ")}` : ""}${source}${formatAnnotations(node.id, options)}`;
|
|
21
25
|
};
|
|
22
26
|
const formatEdgeLabel = (edge) => edge.relation === "subagent"
|
|
23
27
|
? `subagent ${edge.label}`
|
|
@@ -44,7 +48,7 @@ const formatNetworkSummary = (network, options) => {
|
|
|
44
48
|
return `${room.id}${roomMetadata.length > 0 ? ` ${roomMetadata.join(" ")}` : ""} [${room.declaredMembers.join(", ")}]`;
|
|
45
49
|
})
|
|
46
50
|
.join("; ");
|
|
47
|
-
return `network ${id} "${network.name}"${metadata.length > 0 ? ` ${metadata.join(" ")}` : ""}: ${rooms}`;
|
|
51
|
+
return `network ${id} "${network.name}"${metadata.length > 0 ? ` ${metadata.join(" ")}` : ""}: ${rooms}${formatAnnotations(`network:${network.id}`, options)}`;
|
|
48
52
|
};
|
|
49
53
|
const renderChildren = (node, options, projectRoot, prefix = "") => {
|
|
50
54
|
const glyphs = options.ascii
|
|
@@ -1,6 +1,63 @@
|
|
|
1
1
|
import type { ResolvedMoltnetRoomPolicy } from "../types.js";
|
|
2
|
+
export interface OrganizationViewDocSummary {
|
|
3
|
+
role: string;
|
|
4
|
+
source: string;
|
|
5
|
+
}
|
|
6
|
+
export interface OrganizationViewSkillSummary {
|
|
7
|
+
name: string;
|
|
8
|
+
ref: string;
|
|
9
|
+
requiresMcp: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface OrganizationViewResourceSummary {
|
|
12
|
+
id: string;
|
|
13
|
+
kind: "git" | "volume";
|
|
14
|
+
mode: "mutable" | "readonly";
|
|
15
|
+
mount: string;
|
|
16
|
+
sharing: "per_agent" | "team";
|
|
17
|
+
}
|
|
18
|
+
export interface OrganizationViewPackageSummary {
|
|
19
|
+
id: string;
|
|
20
|
+
manager: string;
|
|
21
|
+
name: string;
|
|
22
|
+
scope?: string;
|
|
23
|
+
version?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface OrganizationViewMcpSummary {
|
|
26
|
+
name: string;
|
|
27
|
+
transport: "sse" | "stdio" | "streamable_http";
|
|
28
|
+
}
|
|
29
|
+
export interface OrganizationViewModelSummary {
|
|
30
|
+
authMethod: string;
|
|
31
|
+
name: string;
|
|
32
|
+
provider: string;
|
|
33
|
+
}
|
|
34
|
+
export interface OrganizationViewScheduleSummary {
|
|
35
|
+
expression?: string;
|
|
36
|
+
kind: "cron" | "disabled" | "every";
|
|
37
|
+
timezone?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface OrganizationViewSurfaceSummary {
|
|
40
|
+
name: string;
|
|
41
|
+
scopes: string[];
|
|
42
|
+
}
|
|
43
|
+
export interface OrganizationViewPolicySummary {
|
|
44
|
+
mode: string | null;
|
|
45
|
+
onDegrade: string | null;
|
|
46
|
+
}
|
|
47
|
+
export interface OrganizationViewDeclaredSummary {
|
|
48
|
+
docs: OrganizationViewDocSummary[];
|
|
49
|
+
mcpServers: OrganizationViewMcpSummary[];
|
|
50
|
+
model: OrganizationViewModelSummary | null;
|
|
51
|
+
packages: OrganizationViewPackageSummary[];
|
|
52
|
+
policy: OrganizationViewPolicySummary;
|
|
53
|
+
resources: OrganizationViewResourceSummary[];
|
|
54
|
+
schedule: OrganizationViewScheduleSummary | null;
|
|
55
|
+
skills: OrganizationViewSkillSummary[];
|
|
56
|
+
surfaces: OrganizationViewSurfaceSummary[];
|
|
57
|
+
}
|
|
2
58
|
export interface OrganizationViewTreeNode {
|
|
3
59
|
children: OrganizationViewTreeEdge[];
|
|
60
|
+
declared?: OrganizationViewDeclaredSummary;
|
|
4
61
|
displayName: string;
|
|
5
62
|
external?: string[];
|
|
6
63
|
id: string;
|
|
@@ -10,6 +67,7 @@ export interface OrganizationViewTreeNode {
|
|
|
10
67
|
name: string;
|
|
11
68
|
networks?: OrganizationTreeNetworkSummary[];
|
|
12
69
|
runtimeName: string | null;
|
|
70
|
+
slug?: string;
|
|
13
71
|
source: string;
|
|
14
72
|
}
|
|
15
73
|
export interface OrganizationTreeNetworkRoomSummary {
|
|
@@ -94,6 +152,10 @@ export interface OrganizationNetworkView {
|
|
|
94
152
|
url?: string;
|
|
95
153
|
declarations?: OrganizationNetworkDeclarationView[];
|
|
96
154
|
}
|
|
155
|
+
export interface OrganizationRuntimeView {
|
|
156
|
+
name: string;
|
|
157
|
+
nodeIds: string[];
|
|
158
|
+
}
|
|
97
159
|
export interface OrganizationView {
|
|
98
160
|
contexts: [];
|
|
99
161
|
diagnostics: [];
|
|
@@ -101,9 +163,10 @@ export interface OrganizationView {
|
|
|
101
163
|
networks: OrganizationNetworkView[];
|
|
102
164
|
projectRoot?: string;
|
|
103
165
|
root: OrganizationViewTreeNode;
|
|
104
|
-
runtimes: [];
|
|
166
|
+
runtimes: OrganizationRuntimeView[];
|
|
105
167
|
}
|
|
106
168
|
export interface RenderOrganizationViewOptions {
|
|
169
|
+
annotationFor?: (subjectKey: string) => string[];
|
|
107
170
|
ascii?: boolean;
|
|
108
171
|
color?: boolean;
|
|
109
172
|
declared?: boolean;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { DeploymentRecord } from "./record.js";
|
|
2
|
+
export type DockerInspectExecFile = (file: string, args: string[], options: {
|
|
3
|
+
timeout: number;
|
|
4
|
+
}) => Promise<{
|
|
5
|
+
stderr: string;
|
|
6
|
+
stdout: string;
|
|
7
|
+
}>;
|
|
8
|
+
export interface DockerUnitInspection {
|
|
9
|
+
containerId: string | null;
|
|
10
|
+
drift: string[];
|
|
11
|
+
exists: boolean | null;
|
|
12
|
+
exitCode: number | null;
|
|
13
|
+
finishedAt: string | null;
|
|
14
|
+
imageId: string | null;
|
|
15
|
+
message: string;
|
|
16
|
+
restartCount: number | null;
|
|
17
|
+
running: boolean | null;
|
|
18
|
+
severity: "error" | "ok" | "unknown" | "warn";
|
|
19
|
+
startedAt: string | null;
|
|
20
|
+
status: string | null;
|
|
21
|
+
unitId: string;
|
|
22
|
+
}
|
|
23
|
+
export type DockerInspectionResult = Map<string, DockerUnitInspection>;
|
|
24
|
+
export interface DockerInspectOptions {
|
|
25
|
+
dockerCommand?: string;
|
|
26
|
+
execFile?: DockerInspectExecFile;
|
|
27
|
+
timeoutMs?: number;
|
|
28
|
+
}
|
|
29
|
+
export declare const inspectDockerDeployment: (record: DeploymentRecord, options?: DockerInspectOptions) => Promise<DockerInspectionResult>;
|