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
package/dist/runtime/install.js
CHANGED
|
@@ -9,6 +9,27 @@ const convertRemoteToHttps = (remote) => {
|
|
|
9
9
|
return remote.replace(/^git\+/, "");
|
|
10
10
|
};
|
|
11
11
|
const installHints = new Map([
|
|
12
|
+
[
|
|
13
|
+
"daimon",
|
|
14
|
+
{
|
|
15
|
+
container_image: {
|
|
16
|
+
ecosystem: "node",
|
|
17
|
+
installHint: "Copy a pinned Daimon runtime image."
|
|
18
|
+
},
|
|
19
|
+
github_release_archive: {
|
|
20
|
+
ecosystem: "node",
|
|
21
|
+
installHint: "Download a pinned Daimon runtime release archive."
|
|
22
|
+
},
|
|
23
|
+
npm: {
|
|
24
|
+
ecosystem: "node",
|
|
25
|
+
installHint: "Install the pinned Daimon package and Pi SDK dependencies inside the generated runtime app."
|
|
26
|
+
},
|
|
27
|
+
source_repo: {
|
|
28
|
+
ecosystem: "node",
|
|
29
|
+
installHint: "Checkout the pinned Daimon repo ref and install from the repository root."
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
],
|
|
12
33
|
[
|
|
13
34
|
"openclaw",
|
|
14
35
|
{
|
|
@@ -20,10 +41,6 @@ const installHints = new Map([
|
|
|
20
41
|
ecosystem: "node",
|
|
21
42
|
installHint: "Download the pinned OpenClaw artifact archive from the release."
|
|
22
43
|
},
|
|
23
|
-
github_release_bundle: {
|
|
24
|
-
ecosystem: "node",
|
|
25
|
-
installHint: "Download the pinned OpenClaw bundle artifact from the release."
|
|
26
|
-
},
|
|
27
44
|
npm: {
|
|
28
45
|
ecosystem: "node",
|
|
29
46
|
installHint: "Install the pinned OpenClaw package version from npm."
|
|
@@ -45,10 +62,6 @@ const installHints = new Map([
|
|
|
45
62
|
ecosystem: "go",
|
|
46
63
|
installHint: "Download the pinned PicoClaw release archive for the target platform."
|
|
47
64
|
},
|
|
48
|
-
github_release_bundle: {
|
|
49
|
-
ecosystem: "node",
|
|
50
|
-
installHint: "Download the pinned PicoClaw bundle artifact from the release."
|
|
51
|
-
},
|
|
52
65
|
npm: {
|
|
53
66
|
ecosystem: "node",
|
|
54
67
|
installHint: "Install the pinned PicoClaw package version from npm."
|
|
@@ -60,27 +73,23 @@ const installHints = new Map([
|
|
|
60
73
|
}
|
|
61
74
|
],
|
|
62
75
|
[
|
|
63
|
-
"
|
|
76
|
+
"pi",
|
|
64
77
|
{
|
|
65
78
|
container_image: {
|
|
66
79
|
ecosystem: "node",
|
|
67
|
-
installHint: "Copy
|
|
80
|
+
installHint: "Copy a pinned Pi harness runtime image."
|
|
68
81
|
},
|
|
69
82
|
github_release_archive: {
|
|
70
|
-
ecosystem: "go",
|
|
71
|
-
installHint: "Download the pinned TinyClaw release archive for the target platform."
|
|
72
|
-
},
|
|
73
|
-
github_release_bundle: {
|
|
74
83
|
ecosystem: "node",
|
|
75
|
-
installHint: "Download
|
|
84
|
+
installHint: "Download a pinned Pi harness release archive."
|
|
76
85
|
},
|
|
77
86
|
npm: {
|
|
78
87
|
ecosystem: "node",
|
|
79
|
-
installHint: "Install
|
|
88
|
+
installHint: "Install pinned Pi SDK dependencies inside the generated runtime app."
|
|
80
89
|
},
|
|
81
90
|
source_repo: {
|
|
82
91
|
ecosystem: "node",
|
|
83
|
-
installHint: "Checkout the pinned repo ref and
|
|
92
|
+
installHint: "Checkout the pinned Pi repo ref and install from the repository root."
|
|
84
93
|
}
|
|
85
94
|
}
|
|
86
95
|
]
|
|
@@ -94,7 +103,7 @@ export const resolveRuntimeInstallSelection = async (runtimeName) => {
|
|
|
94
103
|
switch (runtime.install?.kind) {
|
|
95
104
|
case "container_image":
|
|
96
105
|
return {
|
|
97
|
-
ecosystem:
|
|
106
|
+
ecosystem: installProfile.container_image.ecosystem,
|
|
98
107
|
image: runtime.install.image,
|
|
99
108
|
installHint: installProfile.container_image.installHint,
|
|
100
109
|
kind: "container_image",
|
|
@@ -127,18 +136,6 @@ export const resolveRuntimeInstallSelection = async (runtimeName) => {
|
|
|
127
136
|
tag: runtime.install.tag,
|
|
128
137
|
versionedAssets: runtime.install.assets
|
|
129
138
|
};
|
|
130
|
-
case "github_release_bundle":
|
|
131
|
-
return {
|
|
132
|
-
ecosystem: "node",
|
|
133
|
-
installHint: installProfile.github_release_bundle.installHint,
|
|
134
|
-
asset: runtime.install.asset,
|
|
135
|
-
kind: "github_release_bundle",
|
|
136
|
-
repository: runtime.install.repository,
|
|
137
|
-
runtimeName: runtime.name,
|
|
138
|
-
runtimeRef: runtime.ref,
|
|
139
|
-
selectionSource: "runtime_registry_install",
|
|
140
|
-
tag: runtime.install.tag
|
|
141
|
-
};
|
|
142
139
|
case "source_repo":
|
|
143
140
|
case undefined:
|
|
144
141
|
return {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { listEffectiveExecutionModelTargets } from "../../compiler/modelEnv.js";
|
|
2
2
|
import { createAgentCapabilities, createDiagnostic, createDocumentFiles, createSkillFiles } from "../common.js";
|
|
3
3
|
import { SpawnfileError } from "../../shared/index.js";
|
|
4
|
+
import { applyOpenClawImportAuthConfig, resolveOpenClawImportAuthModes } from "./configAuth.js";
|
|
4
5
|
import { prepareOpenClawRuntimeAuth } from "./runAuth.js";
|
|
5
6
|
import { createOpenClawAgentScaffold } from "./scaffold.js";
|
|
6
7
|
import { assertSupportedOpenClawSurfaces, buildOpenClawChannelConfig, buildOpenClawSurfaceEnvBindings } from "./surfaces.js";
|
|
7
8
|
import { buildOpenClawMoltnetConfig, buildOpenClawMoltnetEnvBindings, validateOpenClawMoltnetRuntimeOptions } from "./moltnet.js";
|
|
9
|
+
import { openClawStatusProbes } from "./statusProbes.js";
|
|
8
10
|
const buildEnvSecretRef = (envName) => ({
|
|
9
11
|
id: envName,
|
|
10
12
|
provider: "default",
|
|
@@ -86,7 +88,10 @@ const buildOpenClawConfig = (node) => {
|
|
|
86
88
|
if (moltnet) {
|
|
87
89
|
config.moltnet = moltnet;
|
|
88
90
|
}
|
|
89
|
-
|
|
91
|
+
// Bake the import-auth (claude-code/codex) OAuth structure at compile time so
|
|
92
|
+
// the image is self-sufficient; only the credential tokens are injected later.
|
|
93
|
+
const authBaked = applyOpenClawImportAuthConfig(config, resolveOpenClawImportAuthModes(node));
|
|
94
|
+
return `${JSON.stringify(authBaked, null, 2)}\n`;
|
|
90
95
|
};
|
|
91
96
|
const createOpenClawStateFiles = () => [
|
|
92
97
|
{
|
|
@@ -107,6 +112,7 @@ const createContainerTargets = async (inputs) => inputs.map((input) => {
|
|
|
107
112
|
? [
|
|
108
113
|
{
|
|
109
114
|
envName: "OPENCLAW_HOOKS_TOKEN",
|
|
115
|
+
generated: true,
|
|
110
116
|
jsonPath: "hooks.token"
|
|
111
117
|
}
|
|
112
118
|
]
|
|
@@ -153,6 +159,7 @@ export const openClawAdapter = {
|
|
|
153
159
|
env: [
|
|
154
160
|
{
|
|
155
161
|
description: "Gateway auth token required for non-loopback OpenClaw access",
|
|
162
|
+
generated: true,
|
|
156
163
|
name: "OPENCLAW_GATEWAY_TOKEN",
|
|
157
164
|
required: true
|
|
158
165
|
}
|
|
@@ -217,6 +224,7 @@ export const openClawAdapter = {
|
|
|
217
224
|
name: "openclaw",
|
|
218
225
|
prepareRuntimeAuth: prepareOpenClawRuntimeAuth,
|
|
219
226
|
scaffoldAgentProject: createOpenClawAgentScaffold,
|
|
227
|
+
statusProbes: openClawStatusProbes,
|
|
220
228
|
validateRuntimeOptions(options) {
|
|
221
229
|
const diagnostics = validateOpenClawMoltnetRuntimeOptions(options).map((message) => createDiagnostic("error", message));
|
|
222
230
|
if ("profile" in options && typeof options.profile !== "string") {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ResolvedAgentNode } from "../../compiler/types.js";
|
|
2
|
+
export interface OpenClawImportAuthModes {
|
|
3
|
+
useClaudeCode: boolean;
|
|
4
|
+
useCodex: boolean;
|
|
5
|
+
}
|
|
6
|
+
/** Determines which import-based auth modes an agent's models declare. */
|
|
7
|
+
export declare const resolveOpenClawImportAuthModes: (node: ResolvedAgentNode) => OpenClawImportAuthModes;
|
|
8
|
+
export declare const normalizeOpenClawCodexModel: (model: string) => string;
|
|
9
|
+
/**
|
|
10
|
+
* Applies the import-auth structure (OAuth profiles, provider order, and the
|
|
11
|
+
* Codex model rename) to an OpenClaw config. This is deterministic from the
|
|
12
|
+
* declared auth methods, so it is baked into the image at compile time. Only
|
|
13
|
+
* the OAuth credential tokens are injected at run time.
|
|
14
|
+
*/
|
|
15
|
+
export declare const applyOpenClawImportAuthConfig: (config: Record<string, unknown>, modes: OpenClawImportAuthModes) => Record<string, unknown>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { listEffectiveExecutionModelTargets } from "../../compiler/modelEnv.js";
|
|
2
|
+
/** Determines which import-based auth modes an agent's models declare. */
|
|
3
|
+
export const resolveOpenClawImportAuthModes = (node) => {
|
|
4
|
+
const targets = listEffectiveExecutionModelTargets(node.execution);
|
|
5
|
+
return {
|
|
6
|
+
useClaudeCode: targets.some((target) => target.provider === "anthropic" && target.auth.method === "claude-code"),
|
|
7
|
+
useCodex: targets.some((target) => target.provider === "openai" && target.auth.method === "codex")
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export const normalizeOpenClawCodexModel = (model) => {
|
|
11
|
+
const modelName = model.slice("openai/".length);
|
|
12
|
+
return modelName === "gpt-5" ? "gpt-5.4" : modelName;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Applies the import-auth structure (OAuth profiles, provider order, and the
|
|
16
|
+
* Codex model rename) to an OpenClaw config. This is deterministic from the
|
|
17
|
+
* declared auth methods, so it is baked into the image at compile time. Only
|
|
18
|
+
* the OAuth credential tokens are injected at run time.
|
|
19
|
+
*/
|
|
20
|
+
export const applyOpenClawImportAuthConfig = (config, modes) => {
|
|
21
|
+
if (!modes.useClaudeCode && !modes.useCodex) {
|
|
22
|
+
return config;
|
|
23
|
+
}
|
|
24
|
+
const agents = config.agents ?? {};
|
|
25
|
+
const defaults = agents.defaults ?? {};
|
|
26
|
+
const model = defaults.model;
|
|
27
|
+
const auth = config.auth ?? {};
|
|
28
|
+
const profiles = auth.profiles ?? {};
|
|
29
|
+
const order = auth.order ?? {};
|
|
30
|
+
if (modes.useCodex && typeof model === "string" && model.startsWith("openai/")) {
|
|
31
|
+
defaults.model = `openai-codex/${normalizeOpenClawCodexModel(model)}`;
|
|
32
|
+
}
|
|
33
|
+
if (modes.useClaudeCode) {
|
|
34
|
+
profiles["anthropic:default"] = { mode: "oauth", provider: "anthropic" };
|
|
35
|
+
order.anthropic = ["anthropic:default"];
|
|
36
|
+
}
|
|
37
|
+
if (modes.useCodex) {
|
|
38
|
+
profiles["openai-codex:default"] = { mode: "oauth", provider: "openai-codex" };
|
|
39
|
+
order["openai-codex"] = ["openai-codex:default"];
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
...config,
|
|
43
|
+
agents: { ...agents, defaults },
|
|
44
|
+
auth: { ...auth, order, profiles }
|
|
45
|
+
};
|
|
46
|
+
};
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import type { RuntimeAuthPreparationInput, RuntimeAuthPreparationResult } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Injects the consumer's imported OAuth credentials for an OpenClaw instance.
|
|
4
|
+
* The OAuth-mode config is already baked into the image at compile time, so this
|
|
5
|
+
* only materializes and mounts the credential tokens — no source rootfs needed,
|
|
6
|
+
* which is what lets it run for both project deployments and sourceless images.
|
|
7
|
+
*/
|
|
2
8
|
export declare const prepareOpenClawRuntimeAuth: (input: RuntimeAuthPreparationInput) => Promise<RuntimeAuthPreparationResult>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { loadImportedClaudeCodeCredential, loadImportedCodexCredential } from "../../auth/index.js";
|
|
3
|
-
import { ensureDirectory,
|
|
4
|
-
const resolveRootfsSourcePath = (outputDirectory, containerPath) => path.join(outputDirectory, "container", "rootfs", ...path.posix.relative("/", containerPath).split("/"));
|
|
3
|
+
import { ensureDirectory, writeUtf8File } from "../../filesystem/index.js";
|
|
5
4
|
const writeJsonFile = async (tempRoot, relativePath, value) => {
|
|
6
5
|
const hostPath = path.join(tempRoot, relativePath);
|
|
7
6
|
await ensureDirectory(path.dirname(hostPath));
|
|
@@ -35,47 +34,12 @@ const createOpenClawCredential = (provider, credential) => credential && "type"
|
|
|
35
34
|
refresh: credential.refresh,
|
|
36
35
|
type: "oauth"
|
|
37
36
|
};
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const defaults = agents.defaults ?? {};
|
|
45
|
-
const model = defaults.model;
|
|
46
|
-
const auth = config.auth ?? {};
|
|
47
|
-
const profiles = auth.profiles ?? {};
|
|
48
|
-
const order = auth.order ?? {};
|
|
49
|
-
if (options.useCodex && typeof model === "string" && model.startsWith("openai/")) {
|
|
50
|
-
defaults.model = `openai-codex/${normalizeOpenClawCodexModel(model)}`;
|
|
51
|
-
}
|
|
52
|
-
if (options.useClaudeCode) {
|
|
53
|
-
profiles["anthropic:default"] = {
|
|
54
|
-
mode: "oauth",
|
|
55
|
-
provider: "anthropic"
|
|
56
|
-
};
|
|
57
|
-
order.anthropic = ["anthropic:default"];
|
|
58
|
-
}
|
|
59
|
-
if (options.useCodex) {
|
|
60
|
-
profiles["openai-codex:default"] = {
|
|
61
|
-
mode: "oauth",
|
|
62
|
-
provider: "openai-codex"
|
|
63
|
-
};
|
|
64
|
-
order["openai-codex"] = ["openai-codex:default"];
|
|
65
|
-
}
|
|
66
|
-
return {
|
|
67
|
-
...config,
|
|
68
|
-
agents: {
|
|
69
|
-
...agents,
|
|
70
|
-
defaults
|
|
71
|
-
},
|
|
72
|
-
auth: {
|
|
73
|
-
...auth,
|
|
74
|
-
order,
|
|
75
|
-
profiles
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
};
|
|
37
|
+
/**
|
|
38
|
+
* Injects the consumer's imported OAuth credentials for an OpenClaw instance.
|
|
39
|
+
* The OAuth-mode config is already baked into the image at compile time, so this
|
|
40
|
+
* only materializes and mounts the credential tokens — no source rootfs needed,
|
|
41
|
+
* which is what lets it run for both project deployments and sourceless images.
|
|
42
|
+
*/
|
|
79
43
|
export const prepareOpenClawRuntimeAuth = async (input) => {
|
|
80
44
|
if (!input.instance.home_path) {
|
|
81
45
|
return { coveredModelSecrets: [], mountArgs: [] };
|
|
@@ -88,7 +52,6 @@ export const prepareOpenClawRuntimeAuth = async (input) => {
|
|
|
88
52
|
: null;
|
|
89
53
|
const coveredModelSecrets = [];
|
|
90
54
|
const authProfiles = {};
|
|
91
|
-
let patchedConfig = null;
|
|
92
55
|
const useClaudeCode = input.instance.model_auth_methods.anthropic === "claude-code" && claudeCode;
|
|
93
56
|
const useCodex = input.instance.model_auth_methods.openai === "codex" && codex;
|
|
94
57
|
if (useClaudeCode) {
|
|
@@ -99,13 +62,6 @@ export const prepareOpenClawRuntimeAuth = async (input) => {
|
|
|
99
62
|
authProfiles["openai-codex:default"] = createOpenClawCredential("openai-codex", codex);
|
|
100
63
|
coveredModelSecrets.push("OPENAI_API_KEY");
|
|
101
64
|
}
|
|
102
|
-
if (useClaudeCode || useCodex) {
|
|
103
|
-
const sourceConfig = JSON.parse(await readUtf8File(resolveRootfsSourcePath(input.outputDirectory, input.instance.config_path)));
|
|
104
|
-
patchedConfig = patchOpenClawConfig(sourceConfig, {
|
|
105
|
-
useClaudeCode: Boolean(useClaudeCode),
|
|
106
|
-
useCodex: Boolean(useCodex)
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
65
|
const mountArgs = [];
|
|
110
66
|
if (Object.keys(authProfiles).length > 0) {
|
|
111
67
|
const authStorePath = await writeJsonFile(input.tempRoot, path.join("runtime-auth", "openclaw", input.instance.id, "auth-profiles.json"), {
|
|
@@ -114,10 +70,6 @@ export const prepareOpenClawRuntimeAuth = async (input) => {
|
|
|
114
70
|
});
|
|
115
71
|
mountArgs.push(...createMountArgs(authStorePath, path.posix.join(input.instance.home_path, ".openclaw", "agents", "main", "agent", "auth-profiles.json")));
|
|
116
72
|
}
|
|
117
|
-
if (patchedConfig) {
|
|
118
|
-
const patchedConfigPath = await writeJsonFile(input.tempRoot, path.join("runtime-auth", "openclaw", input.instance.id, "openclaw.json"), patchedConfig);
|
|
119
|
-
mountArgs.push(...createMountArgs(patchedConfigPath, input.instance.config_path));
|
|
120
|
-
}
|
|
121
73
|
return {
|
|
122
74
|
coveredModelSecrets,
|
|
123
75
|
mountArgs
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createRuntimeHttpProbe, createRuntimePathProbe } from "../statusProbes.js";
|
|
2
|
+
export const openClawStatusProbes = [
|
|
3
|
+
createRuntimePathProbe({
|
|
4
|
+
id: "home",
|
|
5
|
+
key: "runtime.home",
|
|
6
|
+
label: "OpenClaw home",
|
|
7
|
+
pathFor: (instance) => instance.home_path,
|
|
8
|
+
testFlag: "-d"
|
|
9
|
+
}),
|
|
10
|
+
createRuntimePathProbe({
|
|
11
|
+
id: "workspace",
|
|
12
|
+
key: "runtime.workspace",
|
|
13
|
+
label: "OpenClaw workspace",
|
|
14
|
+
pathFor: (instance) => instance.workspace_path,
|
|
15
|
+
testFlag: "-d"
|
|
16
|
+
}),
|
|
17
|
+
createRuntimePathProbe({
|
|
18
|
+
id: "config",
|
|
19
|
+
key: "runtime.config",
|
|
20
|
+
label: "OpenClaw config",
|
|
21
|
+
pathFor: (instance) => instance.config_path,
|
|
22
|
+
testFlag: "-f"
|
|
23
|
+
}),
|
|
24
|
+
createRuntimeHttpProbe({
|
|
25
|
+
id: "healthz",
|
|
26
|
+
key: "runtime.health",
|
|
27
|
+
label: "OpenClaw gateway",
|
|
28
|
+
path: "/healthz",
|
|
29
|
+
portFor: (instance) => instance.internal_port
|
|
30
|
+
})
|
|
31
|
+
];
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { listExecutionModelSecretNames } from "../../compiler/modelEnv.js";
|
|
3
|
+
import { SpawnfileError } from "../../shared/index.js";
|
|
4
|
+
import { createAgentCapabilities, createDiagnostic, createDocumentFiles, createSkillFiles } from "../common.js";
|
|
5
|
+
import { createPiAgentConfig, PI_PACKAGE_NAME, PI_PACKAGE_VERSION, renderPiApp, renderPiAppConfig, renderPiModelsConfig, renderPiPackageJson } from "./appTemplate.js";
|
|
6
|
+
import { preparePiRuntimeAuth } from "./runAuth.js";
|
|
7
|
+
const PI_CONFIG_FILE = "pi-app.json";
|
|
8
|
+
const PI_CONTROL_PORT = 19690;
|
|
9
|
+
const PI_MODELS_FILE = "home/.pi/agent/models.json";
|
|
10
|
+
const moveWorkspaceFileToAgentWorkspace = (file, agentSlug) => {
|
|
11
|
+
if (!file.path.startsWith("workspace/")) {
|
|
12
|
+
return file;
|
|
13
|
+
}
|
|
14
|
+
const relativePath = file.path.slice("workspace/".length);
|
|
15
|
+
return {
|
|
16
|
+
...file,
|
|
17
|
+
path: path.posix.join("workspace", "agents", agentSlug, relativePath)
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const createContainerTargets = async (inputs) => {
|
|
21
|
+
const agentInputs = inputs.filter((input) => input.kind === "agent" && input.value.kind === "agent");
|
|
22
|
+
if (agentInputs.length === 0) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
const agents = agentInputs.map((input) => createPiAgentConfig(input.value, input.slug, input.id));
|
|
26
|
+
const envFiles = [
|
|
27
|
+
...new Set(agentInputs.flatMap((input) => listExecutionModelSecretNames(input.value.execution)))
|
|
28
|
+
].map((secretName) => ({
|
|
29
|
+
envName: secretName,
|
|
30
|
+
relativePath: `secrets/${secretName}`
|
|
31
|
+
}));
|
|
32
|
+
return [
|
|
33
|
+
{
|
|
34
|
+
envFiles,
|
|
35
|
+
files: [
|
|
36
|
+
...agentInputs.flatMap((input) => input.emittedFiles.map((file) => moveWorkspaceFileToAgentWorkspace(file, input.slug))),
|
|
37
|
+
{
|
|
38
|
+
content: renderPiAppConfig(agents),
|
|
39
|
+
path: PI_CONFIG_FILE
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
content: renderPiModelsConfig(agentInputs.map((input) => input.value)),
|
|
43
|
+
path: PI_MODELS_FILE
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
content: renderPiPackageJson(),
|
|
47
|
+
path: "runtime/package.json"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
content: renderPiApp(),
|
|
51
|
+
mode: 0o755,
|
|
52
|
+
path: "runtime/app.mjs"
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
id: "pi-app",
|
|
56
|
+
sourceIds: agentInputs.map((input) => input.id).sort()
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
};
|
|
60
|
+
const scheduleOutcomeFor = (node) => {
|
|
61
|
+
if (!node.schedule) {
|
|
62
|
+
return {};
|
|
63
|
+
}
|
|
64
|
+
if (node.schedule.kind === "every" || node.schedule.kind === "disabled") {
|
|
65
|
+
return {
|
|
66
|
+
message: "Pi generated runtime app owns this schedule",
|
|
67
|
+
outcome: "supported"
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
message: "Pi generated runtime app supports every schedules in Spawnfile v0.1",
|
|
72
|
+
outcome: "degraded"
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
const createScheduleDiagnostics = (node) => node.schedule?.kind === "cron"
|
|
76
|
+
? [
|
|
77
|
+
createDiagnostic("warn", "Pi generated runtime app supports every schedules in Spawnfile v0.1; cron schedules are degraded")
|
|
78
|
+
]
|
|
79
|
+
: [];
|
|
80
|
+
const moltnetCapabilityOptions = (node) => node.surfaces?.moltnet
|
|
81
|
+
? {
|
|
82
|
+
moltnetMessage: "Pi generated runtime app exposes a control endpoint for Moltnet bridge wake delivery",
|
|
83
|
+
moltnetOutcome: "supported"
|
|
84
|
+
}
|
|
85
|
+
: {};
|
|
86
|
+
const assertSupportedPiSurfaces = (surfaces) => {
|
|
87
|
+
if (!surfaces) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const unsupported = [
|
|
91
|
+
surfaces.discord ? "discord" : null,
|
|
92
|
+
surfaces.http ? "http" : null,
|
|
93
|
+
surfaces.slack ? "slack" : null,
|
|
94
|
+
surfaces.telegram ? "telegram" : null,
|
|
95
|
+
surfaces.webhook ? "webhook" : null,
|
|
96
|
+
surfaces.whatsapp ? "whatsapp" : null
|
|
97
|
+
].filter((surface) => surface !== null);
|
|
98
|
+
if (unsupported.length > 0) {
|
|
99
|
+
throw new SpawnfileError("validation_error", `Pi runtime only supports Moltnet surfaces in Spawnfile v0.1; unsupported surfaces: ${unsupported.join(", ")}`);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
export const piAdapter = {
|
|
103
|
+
assertSupportedModelTarget(target) {
|
|
104
|
+
if (target.endpoint) {
|
|
105
|
+
if (target.provider !== "custom" && target.provider !== "local") {
|
|
106
|
+
throw new SpawnfileError("validation_error", "Pi runtime only supports endpoints on custom or local model providers");
|
|
107
|
+
}
|
|
108
|
+
if (target.auth.method === "none" || target.auth.method === "api_key") {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
throw new SpawnfileError("validation_error", `Pi runtime endpoint models only support none or api_key auth, got ${target.auth.method}`);
|
|
112
|
+
}
|
|
113
|
+
if (target.provider === "openai") {
|
|
114
|
+
if (target.auth.method === "api_key" || target.auth.method === "codex") {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (target.provider === "anthropic" && target.auth.method === "api_key") {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (target.provider === "anthropic" && target.auth.method === "claude-code") {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
throw new SpawnfileError("validation_error", `Pi runtime does not support model auth method ${target.auth.method} for provider ${target.provider}`);
|
|
125
|
+
},
|
|
126
|
+
assertSupportedSurfaces(surfaces) {
|
|
127
|
+
assertSupportedPiSurfaces(surfaces);
|
|
128
|
+
},
|
|
129
|
+
container: {
|
|
130
|
+
configFileName: PI_CONFIG_FILE,
|
|
131
|
+
configPathEnv: "SPAWNFILE_PI_CONFIG",
|
|
132
|
+
homeEnv: "SPAWNFILE_PI_HOME",
|
|
133
|
+
instancePaths: {
|
|
134
|
+
configPathTemplate: "<instance-root>/pi/<config-file>",
|
|
135
|
+
homePathTemplate: "<instance-root>/home",
|
|
136
|
+
sourceWorkspacePathTemplate: "<instance-root>/workspace/agents/<source-slug>",
|
|
137
|
+
workspacePathTemplate: "<instance-root>/workspace"
|
|
138
|
+
},
|
|
139
|
+
port: PI_CONTROL_PORT,
|
|
140
|
+
portEnv: "SPAWNFILE_PI_CONTROL_PORT",
|
|
141
|
+
standaloneBaseImage: "node:24-bookworm-slim",
|
|
142
|
+
startCommand: ["node", "<runtime-root>/app.mjs", "<config-path>"],
|
|
143
|
+
systemDeps: ["bash", "ca-certificates", "curl", "git", "procps"]
|
|
144
|
+
},
|
|
145
|
+
systemInstructionSurface: {
|
|
146
|
+
placement: "append_pointer",
|
|
147
|
+
resolvePath() {
|
|
148
|
+
return "workspace/AGENTS.md";
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
async compileAgent(node) {
|
|
152
|
+
const scheduleOutcome = scheduleOutcomeFor(node);
|
|
153
|
+
return {
|
|
154
|
+
capabilities: createAgentCapabilities(node, {
|
|
155
|
+
...moltnetCapabilityOptions(node),
|
|
156
|
+
mcpOutcome: node.mcpServers.length > 0 ? "degraded" : "supported",
|
|
157
|
+
sandboxOutcome: node.execution?.sandbox ? "degraded" : "supported",
|
|
158
|
+
scheduleMessage: scheduleOutcome.message,
|
|
159
|
+
scheduleOutcome: scheduleOutcome.outcome,
|
|
160
|
+
subagentOutcome: node.subagents.length > 0 ? "degraded" : "supported"
|
|
161
|
+
}),
|
|
162
|
+
diagnostics: [
|
|
163
|
+
...createScheduleDiagnostics(node),
|
|
164
|
+
...(node.execution?.sandbox
|
|
165
|
+
? [createDiagnostic("warn", "Pi runtime relies on container and workspace isolation; Pi itself is not a sandbox engine")]
|
|
166
|
+
: []),
|
|
167
|
+
...(node.mcpServers.length > 0
|
|
168
|
+
? [createDiagnostic("warn", "Pi runtime does not lower MCP server declarations in Spawnfile v0.1")]
|
|
169
|
+
: []),
|
|
170
|
+
...(node.subagents.length > 0
|
|
171
|
+
? [createDiagnostic("warn", "Pi runtime groups compiled agents but does not preserve native parent-owned subagent semantics in v0.1")]
|
|
172
|
+
: [])
|
|
173
|
+
],
|
|
174
|
+
files: [
|
|
175
|
+
...createDocumentFiles("workspace", node.docs),
|
|
176
|
+
...createSkillFiles("workspace/skills", node.skills)
|
|
177
|
+
]
|
|
178
|
+
};
|
|
179
|
+
},
|
|
180
|
+
async createContainerTargets(inputs) {
|
|
181
|
+
return createContainerTargets(inputs);
|
|
182
|
+
},
|
|
183
|
+
name: "pi",
|
|
184
|
+
prepareRuntimeAuth: preparePiRuntimeAuth,
|
|
185
|
+
validateRuntimeOptions(options) {
|
|
186
|
+
const diagnostics = [];
|
|
187
|
+
const unsupported = Object.keys(options).filter((key) => key !== "restrict_to_workspace");
|
|
188
|
+
for (const key of unsupported) {
|
|
189
|
+
diagnostics.push(createDiagnostic("warn", `Pi runtime option ${key} is not used yet`));
|
|
190
|
+
}
|
|
191
|
+
return diagnostics;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
export const daimonAdapter = {
|
|
195
|
+
...piAdapter,
|
|
196
|
+
name: "daimon"
|
|
197
|
+
};
|
|
198
|
+
export const PI_RUNTIME_PACKAGE = `${PI_PACKAGE_NAME}@${PI_PACKAGE_VERSION}`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const renderPiActivitySource: () => string;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export const renderPiActivitySource = () => String.raw `
|
|
2
|
+
const maxActivityEvents = 500;
|
|
3
|
+
|
|
4
|
+
const createActivityBroker = () => {
|
|
5
|
+
let sequence = 0;
|
|
6
|
+
const events = [];
|
|
7
|
+
const clients = new Set();
|
|
8
|
+
|
|
9
|
+
const normalizeFilter = (value) => typeof value === "string" && value.trim().length > 0
|
|
10
|
+
? value.trim()
|
|
11
|
+
: "";
|
|
12
|
+
const matchesFilter = (event, filter) => {
|
|
13
|
+
const normalized = normalizeFilter(filter);
|
|
14
|
+
return normalized === "" ||
|
|
15
|
+
event.agent_id === normalized ||
|
|
16
|
+
event.agent_slug === normalized ||
|
|
17
|
+
event.agent_name === normalized ||
|
|
18
|
+
event.agent_id === "agent:" + normalized;
|
|
19
|
+
};
|
|
20
|
+
const parseTail = (value) => {
|
|
21
|
+
const parsed = Number(value);
|
|
22
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : maxActivityEvents;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const publish = (event) => {
|
|
26
|
+
const full = {
|
|
27
|
+
version: "spawnfile.activity.v1",
|
|
28
|
+
sequence: ++sequence,
|
|
29
|
+
created_at: new Date().toISOString(),
|
|
30
|
+
...event
|
|
31
|
+
};
|
|
32
|
+
events.push(full);
|
|
33
|
+
if (events.length > maxActivityEvents) {
|
|
34
|
+
events.splice(0, events.length - maxActivityEvents);
|
|
35
|
+
}
|
|
36
|
+
const frame = "data: " + JSON.stringify(full) + "\n\n";
|
|
37
|
+
for (const client of [...clients]) {
|
|
38
|
+
if (!matchesFilter(full, client.filter)) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
client.response.write(frame);
|
|
43
|
+
} catch {
|
|
44
|
+
clients.delete(client);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return full;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const list = (filter, tail) => {
|
|
51
|
+
const selected = events.filter((event) => matchesFilter(event, filter));
|
|
52
|
+
return selected.slice(Math.max(0, selected.length - parseTail(tail)));
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const stream = (request, response, filter, tail) => {
|
|
56
|
+
response.writeHead(200, {
|
|
57
|
+
"cache-control": "no-cache",
|
|
58
|
+
"connection": "keep-alive",
|
|
59
|
+
"content-type": "text/event-stream"
|
|
60
|
+
});
|
|
61
|
+
response.write("event: ready\ndata: {\"status\":\"ok\"}\n\n");
|
|
62
|
+
for (const event of list(filter, tail)) {
|
|
63
|
+
response.write("data: " + JSON.stringify(event) + "\n\n");
|
|
64
|
+
}
|
|
65
|
+
const client = { filter: normalizeFilter(filter), response };
|
|
66
|
+
clients.add(client);
|
|
67
|
+
request.on("close", () => clients.delete(client));
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return { list, publish, stream };
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const redactActivityText = (value) => {
|
|
74
|
+
let redacted = String(value);
|
|
75
|
+
redacted = redacted.replace(/\bBearer\s+[A-Za-z0-9._~+/=-]{12,}/gi, "Bearer [REDACTED]");
|
|
76
|
+
redacted = redacted.replace(/\bmagt_v1_[A-Za-z0-9_-]{16,}\b/g, "[REDACTED]");
|
|
77
|
+
redacted = redacted.replace(/\b(?:sk|sk-proj)-[A-Za-z0-9_-]{20,}\b/g, "[REDACTED]");
|
|
78
|
+
redacted = redacted.replace(
|
|
79
|
+
/("([^"]*(?:api[_-]?key|token|secret|password)[^"]*)"\s*:\s*")([^"]+)(")/gi,
|
|
80
|
+
"$1[REDACTED]$4"
|
|
81
|
+
);
|
|
82
|
+
redacted = redacted.replace(/\/(?:Users|home|private|tmp|var|opt|run)\/[^\s"']+/g, "[path]");
|
|
83
|
+
return redacted.length > 1000 ? redacted.slice(0, 1000) + "..." : redacted;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const formatActivityError = (error) => redactActivityText(error instanceof Error ? error.message : String(error));
|
|
87
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const renderPiCoreSource: () => string;
|