spawnfile 0.1.10 → 0.1.12
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 +13 -2
- package/dist/cli/lifecycleCommands.js +101 -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 +4 -1
- package/dist/cli/runCli.js +37 -13
- package/dist/cli/runtimeCommands.js +1 -0
- package/dist/cli/statusCommand.d.ts +42 -0
- package/dist/cli/statusCommand.js +394 -0
- package/dist/cli/surfaceCommands.js +4 -0
- package/dist/compiler/agentSurfaces.js +2 -4
- package/dist/compiler/buildCompilePlanTeams.js +3 -1
- package/dist/compiler/compileProject.js +19 -10
- package/dist/compiler/compileProjectSupport.d.ts +1 -0
- package/dist/compiler/compileProjectSupport.js +1 -1
- 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 +6 -0
- package/dist/compiler/containerArtifactsTypes.d.ts +9 -0
- package/dist/compiler/containerEntrypointRender.js +18 -31
- package/dist/compiler/index.d.ts +1 -0
- package/dist/compiler/index.js +1 -0
- package/dist/compiler/moltnetArtifacts.d.ts +2 -0
- package/dist/compiler/moltnetArtifacts.js +58 -99
- package/dist/compiler/moltnetClientConfig.d.ts +2 -2
- package/dist/compiler/moltnetClientConfig.js +16 -23
- package/dist/compiler/moltnetConfigLowering.d.ts +3 -0
- package/dist/compiler/moltnetConfigLowering.js +13 -2
- package/dist/compiler/moltnetNodeConfig.d.ts +27 -0
- package/dist/compiler/moltnetNodeConfig.js +68 -0
- package/dist/compiler/moltnetResolution.js +1 -1
- package/dist/compiler/moltnetRoomMemberships.js +1 -2
- package/dist/compiler/moltnetRoomPolicyCompatibility.d.ts +4 -0
- package/dist/compiler/moltnetRoomPolicyCompatibility.js +28 -0
- package/dist/compiler/moltnetRuntimeConfig.d.ts +1 -1
- package/dist/compiler/moltnetRuntimeConfig.js +1 -13
- 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 +102 -125
- 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 +57 -0
- package/dist/compiler/types.d.ts +3 -2
- package/dist/compiler/upProject.d.ts +6 -0
- package/dist/compiler/upProject.js +42 -8
- package/dist/compiler/view/buildOrganizationView.js +27 -3
- package/dist/compiler/view/declarations.d.ts +4 -0
- package/dist/compiler/view/declarations.js +104 -0
- package/dist/compiler/view/renderNetworks.js +12 -3
- package/dist/compiler/view/renderTree.js +16 -3
- package/dist/compiler/view/types.d.ts +77 -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/homeStore.d.ts +19 -0
- package/dist/deployment/homeStore.js +130 -0
- package/dist/deployment/index.d.ts +9 -0
- package/dist/deployment/index.js +9 -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/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/renderSpawnfileNetworks.js +5 -0
- package/dist/manifest/schemas.d.ts +71 -41
- package/dist/manifest/surfaceSchemas.d.ts +19 -47
- package/dist/manifest/surfaceSchemas.js +3 -6
- package/dist/manifest/teamNetworkAccessSchemas.d.ts +15 -0
- package/dist/manifest/teamNetworkAccessSchemas.js +8 -0
- package/dist/manifest/teamNetworkConsoleSchemas.d.ts +7 -0
- package/dist/manifest/teamNetworkConsoleSchemas.js +19 -0
- package/dist/manifest/teamNetworkSchemas.d.ts +60 -0
- package/dist/manifest/teamNetworkSchemas.js +20 -7
- 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/container.js +0 -16
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/install.d.ts +0 -10
- package/dist/runtime/install.js +0 -45
- 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/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 +2 -12
- package/dist/runtime/statusProbes.d.ts +16 -0
- package/dist/runtime/statusProbes.js +41 -0
- package/dist/runtime/types.d.ts +52 -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 +128 -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 +4 -2
- package/runtimes.yaml +22 -15
- 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,41 @@
|
|
|
1
|
+
const observation = (key, severity, message) => ({ key, message, severity });
|
|
2
|
+
const errorMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
3
|
+
export const createRuntimePathProbe = (input) => ({
|
|
4
|
+
id: input.id,
|
|
5
|
+
label: input.label,
|
|
6
|
+
async run(context) {
|
|
7
|
+
const targetPath = input.pathFor(context.instance);
|
|
8
|
+
if (!targetPath) {
|
|
9
|
+
return [
|
|
10
|
+
observation(input.key, "unknown", `${input.label} path is not present in the compile report`)
|
|
11
|
+
];
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
await context.manager.exec(["test", input.testFlag, targetPath]);
|
|
15
|
+
return [observation(input.key, "ok", `${input.label} exists at ${targetPath}`)];
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
return [
|
|
19
|
+
observation(input.key, "error", `${input.label} missing at ${targetPath}: ${errorMessage(error)}`)
|
|
20
|
+
];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
export const createRuntimeHttpProbe = (input) => ({
|
|
25
|
+
id: input.id,
|
|
26
|
+
label: input.label,
|
|
27
|
+
async run(context) {
|
|
28
|
+
const port = input.portFor(context.instance);
|
|
29
|
+
if (!port) {
|
|
30
|
+
return [
|
|
31
|
+
observation(input.key, "unknown", `${input.label} port is not present in the compile report`)
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
const response = await context.manager.httpGet(port, input.path);
|
|
35
|
+
return [
|
|
36
|
+
response.ok
|
|
37
|
+
? observation(input.key, "ok", `${input.label} responded on ${input.path}`)
|
|
38
|
+
: observation(input.key, "error", `${input.label} failed on ${input.path}: ${response.error ?? "request failed"}`)
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
});
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ import type { ResolvedAuthProfile } from "../auth/index.js";
|
|
|
3
3
|
import type { AgentManifest } from "../manifest/index.js";
|
|
4
4
|
import type { CapabilityReport, DiagnosticReport } from "../report/index.js";
|
|
5
5
|
import type { ContainerRuntimeInstanceReport } from "../report/index.js";
|
|
6
|
+
import type { DeploymentRecord, DockerUnitInspection } from "../deployment/index.js";
|
|
7
|
+
import type { ModelAuthMethod } from "../shared/index.js";
|
|
6
8
|
export interface EmittedFile {
|
|
7
9
|
content: string;
|
|
8
10
|
mode?: number;
|
|
@@ -38,6 +40,7 @@ export interface RuntimeContainerInstancePaths {
|
|
|
38
40
|
}
|
|
39
41
|
export interface RuntimeContainerConfigEnvBinding {
|
|
40
42
|
envName: string;
|
|
43
|
+
generated?: boolean;
|
|
41
44
|
jsonPath: string;
|
|
42
45
|
}
|
|
43
46
|
export interface RuntimeContainerMeta {
|
|
@@ -46,6 +49,7 @@ export interface RuntimeContainerMeta {
|
|
|
46
49
|
configPathEnv?: string;
|
|
47
50
|
env?: Array<{
|
|
48
51
|
description: string;
|
|
52
|
+
generated?: boolean;
|
|
49
53
|
name: string;
|
|
50
54
|
required: boolean;
|
|
51
55
|
}>;
|
|
@@ -60,10 +64,24 @@ export interface RuntimeContainerMeta {
|
|
|
60
64
|
staticEnv?: Record<string, string>;
|
|
61
65
|
systemDeps: string[];
|
|
62
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* The minimal runtime-instance shape an auth preparer needs. Both the compile
|
|
69
|
+
* report's `ContainerRuntimeInstanceReport` and the distribution report's
|
|
70
|
+
* runtime instances structurally satisfy this, so sourceless image consumption
|
|
71
|
+
* can reuse the same preparers without casting through compiler-only types.
|
|
72
|
+
*/
|
|
73
|
+
export interface RuntimeAuthInstance {
|
|
74
|
+
config_path: string;
|
|
75
|
+
home_path: string | null;
|
|
76
|
+
id: string;
|
|
77
|
+
model_auth_methods: Record<string, ModelAuthMethod>;
|
|
78
|
+
model_secrets_required: string[];
|
|
79
|
+
runtime: string;
|
|
80
|
+
}
|
|
63
81
|
export interface RuntimeAuthPreparationInput {
|
|
64
82
|
authProfile: ResolvedAuthProfile;
|
|
65
83
|
env: Record<string, string>;
|
|
66
|
-
instance:
|
|
84
|
+
instance: RuntimeAuthInstance;
|
|
67
85
|
outputDirectory: string;
|
|
68
86
|
tempRoot: string;
|
|
69
87
|
}
|
|
@@ -71,6 +89,38 @@ export interface RuntimeAuthPreparationResult {
|
|
|
71
89
|
coveredModelSecrets: string[];
|
|
72
90
|
mountArgs: string[];
|
|
73
91
|
}
|
|
92
|
+
export interface RuntimeProbeExecResult {
|
|
93
|
+
stderr: string;
|
|
94
|
+
stdout: string;
|
|
95
|
+
}
|
|
96
|
+
export interface RuntimeProbeHttpResult {
|
|
97
|
+
body: string;
|
|
98
|
+
error?: string;
|
|
99
|
+
ok: boolean;
|
|
100
|
+
}
|
|
101
|
+
export interface RuntimeProbeGateway {
|
|
102
|
+
exec(command: string[]): Promise<RuntimeProbeExecResult>;
|
|
103
|
+
httpGet(port: number, requestPath: string, headers?: Record<string, string>): Promise<RuntimeProbeHttpResult>;
|
|
104
|
+
inspectUnit(): Promise<DockerUnitInspection>;
|
|
105
|
+
}
|
|
106
|
+
export interface RuntimeProbeObservation {
|
|
107
|
+
details?: Record<string, unknown>;
|
|
108
|
+
key: string;
|
|
109
|
+
message: string;
|
|
110
|
+
severity: "error" | "ok" | "unknown" | "warn";
|
|
111
|
+
}
|
|
112
|
+
export interface RuntimeStatusProbeContext {
|
|
113
|
+
deployment: DeploymentRecord;
|
|
114
|
+
instance: ContainerRuntimeInstanceReport;
|
|
115
|
+
manager: RuntimeProbeGateway;
|
|
116
|
+
timeoutMs: number;
|
|
117
|
+
unit: DeploymentRecord["units"][number];
|
|
118
|
+
}
|
|
119
|
+
export interface RuntimeStatusProbe {
|
|
120
|
+
id: string;
|
|
121
|
+
label: string;
|
|
122
|
+
run(context: RuntimeStatusProbeContext): Promise<RuntimeProbeObservation[]>;
|
|
123
|
+
}
|
|
74
124
|
export interface RuntimeSystemInstructionSurfaceInput {
|
|
75
125
|
node: ResolvedAgentNode;
|
|
76
126
|
}
|
|
@@ -94,6 +144,7 @@ export interface RuntimeAdapter {
|
|
|
94
144
|
name: string;
|
|
95
145
|
prepareRuntimeAuth?(input: RuntimeAuthPreparationInput): Promise<RuntimeAuthPreparationResult>;
|
|
96
146
|
scaffoldAgentProject?(): RuntimeAgentScaffold;
|
|
147
|
+
statusProbes?: RuntimeStatusProbe[];
|
|
97
148
|
systemInstructionSurface?: RuntimeSystemInstructionSurface;
|
|
98
149
|
validateRuntimeOptions?(options: Record<string, unknown>): DiagnosticReport[];
|
|
99
150
|
}
|
package/dist/shared/errors.d.ts
CHANGED
|
@@ -4,3 +4,9 @@ export declare class SpawnfileError extends Error {
|
|
|
4
4
|
constructor(code: SpawnfileErrorCode, message: string);
|
|
5
5
|
}
|
|
6
6
|
export declare const isSpawnfileError: (value: unknown) => value is SpawnfileError;
|
|
7
|
+
/**
|
|
8
|
+
* Maps an error to the shared CLI exit-code convention: 2 for usage/input
|
|
9
|
+
* errors, 1 for runtime failures. Used wherever the CLI turns a caught error
|
|
10
|
+
* into a process exit code, so every path agrees (see specs/SPEC.md §9.1).
|
|
11
|
+
*/
|
|
12
|
+
export declare const errorExitCode: (error: unknown) => 1 | 2;
|
package/dist/shared/errors.js
CHANGED
|
@@ -7,3 +7,12 @@ export class SpawnfileError extends Error {
|
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
export const isSpawnfileError = (value) => value instanceof SpawnfileError;
|
|
10
|
+
// Codes that mean the input itself was bad (usage/input errors → exit 2).
|
|
11
|
+
// Everything else is a runtime failure that surfaced after validation (→ exit 1).
|
|
12
|
+
const USAGE_ERROR_CODES = new Set(["validation_error", "invalid_manifest"]);
|
|
13
|
+
/**
|
|
14
|
+
* Maps an error to the shared CLI exit-code convention: 2 for usage/input
|
|
15
|
+
* errors, 1 for runtime failures. Used wherever the CLI turns a caught error
|
|
16
|
+
* into a process exit code, so every path agrees (see specs/SPEC.md §9.1).
|
|
17
|
+
*/
|
|
18
|
+
export const errorExitCode = (error) => isSpawnfileError(error) && USAGE_ERROR_CODES.has(error.code) ? 2 : 1;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type LoadedCompileReport } from "./compileReport.js";
|
|
2
|
+
import type { StaticStatus, StatusDeploymentSummary, StatusExitCode, StatusLiveRequest, StatusObservation, StatusObservationCounts, StatusSelection } from "./types.js";
|
|
3
|
+
export declare const countObservations: (observations: StatusObservation[]) => StatusObservationCounts;
|
|
4
|
+
export declare const getVisibleObservations: (status: StaticStatus) => StatusObservation[];
|
|
5
|
+
export declare const exitCodeForStatus: (status: StaticStatus) => StatusExitCode;
|
|
6
|
+
export declare const createStaticStatus: (view: StaticStatus["view"], loadedReport: LoadedCompileReport, input: {
|
|
7
|
+
deployments?: StatusDeploymentSummary[];
|
|
8
|
+
inputPath: string;
|
|
9
|
+
liveObservations?: StatusObservation[];
|
|
10
|
+
live?: StatusLiveRequest;
|
|
11
|
+
outputDirectory: string;
|
|
12
|
+
selection: StatusSelection | null;
|
|
13
|
+
}) => StaticStatus;
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { createCompiledContainerObservations } from "./compiledContainerObservations.js";
|
|
3
|
+
import { createDeploymentObservations } from "./deployments.js";
|
|
4
|
+
import { expandStatusSelectionSubjects } from "./selectionSubjects.js";
|
|
5
|
+
import { countNodesByKind, flattenOrganizationNodes } from "./traversal.js";
|
|
6
|
+
export const countObservations = (observations) => ({
|
|
7
|
+
error: observations.filter((observation) => observation.severity === "error").length,
|
|
8
|
+
ok: observations.filter((observation) => observation.severity === "ok").length,
|
|
9
|
+
unknown: observations.filter((observation) => observation.severity === "unknown").length,
|
|
10
|
+
warn: observations.filter((observation) => observation.severity === "warn").length
|
|
11
|
+
});
|
|
12
|
+
export const getVisibleObservations = (status) => {
|
|
13
|
+
if (!status.selection) {
|
|
14
|
+
return status.observations;
|
|
15
|
+
}
|
|
16
|
+
const subjects = new Set(["compile", "status", ...status.selection.subjectKeys]);
|
|
17
|
+
return status.observations.filter((observation) => subjects.has(observation.subject));
|
|
18
|
+
};
|
|
19
|
+
export const exitCodeForStatus = (status) => getVisibleObservations(status).some((observation) => observation.severity === "error")
|
|
20
|
+
? 1
|
|
21
|
+
: 0;
|
|
22
|
+
const severityForDiagnostic = (diagnostic) => diagnostic.level === "error" ? "error" : diagnostic.level === "warn" ? "warn" : "ok";
|
|
23
|
+
const severityForCapability = (capability) => capability.outcome === "unsupported"
|
|
24
|
+
? "error"
|
|
25
|
+
: capability.outcome === "degraded"
|
|
26
|
+
? "warn"
|
|
27
|
+
: "ok";
|
|
28
|
+
const createNodeReportObservations = (node) => {
|
|
29
|
+
const observations = [];
|
|
30
|
+
for (const diagnostic of node.diagnostics) {
|
|
31
|
+
observations.push({
|
|
32
|
+
key: `diagnostic.${diagnostic.level}`,
|
|
33
|
+
label: node.id,
|
|
34
|
+
message: diagnostic.message,
|
|
35
|
+
severity: severityForDiagnostic(diagnostic),
|
|
36
|
+
source: "compile_report",
|
|
37
|
+
subject: node.id
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
for (const capability of node.capabilities) {
|
|
41
|
+
const severity = severityForCapability(capability);
|
|
42
|
+
if (severity === "ok") {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
observations.push({
|
|
46
|
+
key: `capability.${capability.key}`,
|
|
47
|
+
label: node.id,
|
|
48
|
+
message: capability.message,
|
|
49
|
+
severity,
|
|
50
|
+
source: "compile_report",
|
|
51
|
+
subject: node.id
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return observations;
|
|
55
|
+
};
|
|
56
|
+
const createObservation = (input) => ({
|
|
57
|
+
...input,
|
|
58
|
+
label: `${input.severity.toUpperCase()} ${input.key}`
|
|
59
|
+
});
|
|
60
|
+
const compileInfoFor = (loaded) => {
|
|
61
|
+
if (loaded.kind !== "loaded") {
|
|
62
|
+
return {
|
|
63
|
+
compileFingerprint: null,
|
|
64
|
+
generatedAt: null,
|
|
65
|
+
outputDirectory: null,
|
|
66
|
+
path: loaded.reportPath,
|
|
67
|
+
present: false,
|
|
68
|
+
root: null
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
compileFingerprint: loaded.report.compileFingerprint,
|
|
73
|
+
generatedAt: loaded.report.generatedAt,
|
|
74
|
+
outputDirectory: loaded.report.outputDirectory,
|
|
75
|
+
path: loaded.reportPath,
|
|
76
|
+
present: true,
|
|
77
|
+
root: loaded.report.root
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
const addDeclaredObservations = (observations, view, nodes) => {
|
|
81
|
+
observations.push(createObservation({
|
|
82
|
+
key: "source.valid",
|
|
83
|
+
message: `Loaded organization graph from ${view.root.source}`,
|
|
84
|
+
severity: "ok",
|
|
85
|
+
source: "declared",
|
|
86
|
+
subject: "status"
|
|
87
|
+
}));
|
|
88
|
+
for (const node of nodes) {
|
|
89
|
+
observations.push(createObservation({
|
|
90
|
+
key: `${node.kind}.declared`,
|
|
91
|
+
message: `${node.displayName} is declared`,
|
|
92
|
+
severity: "ok",
|
|
93
|
+
source: "declared",
|
|
94
|
+
subject: node.id
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
for (const network of view.networks) {
|
|
98
|
+
observations.push(createObservation({
|
|
99
|
+
key: "network.declared",
|
|
100
|
+
message: `${network.id} declares ${network.rooms.length} room(s)`,
|
|
101
|
+
severity: "ok",
|
|
102
|
+
source: "declared",
|
|
103
|
+
subject: `network:${network.id}`
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
for (const runtime of view.runtimes) {
|
|
107
|
+
observations.push(createObservation({
|
|
108
|
+
key: "runtime.declared",
|
|
109
|
+
message: `${runtime.name} serves ${runtime.nodeIds.length} node(s)`,
|
|
110
|
+
severity: "ok",
|
|
111
|
+
source: "declared",
|
|
112
|
+
subject: `runtime:${runtime.name}`
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const addCompiledObservations = (observations, loaded, view, nodes) => {
|
|
117
|
+
if (loaded.kind === "missing") {
|
|
118
|
+
observations.push(createObservation({
|
|
119
|
+
key: "compile.report",
|
|
120
|
+
message: `Compile report not found at ${loaded.reportPath}`,
|
|
121
|
+
severity: "unknown",
|
|
122
|
+
source: "compile_report",
|
|
123
|
+
subject: "compile"
|
|
124
|
+
}));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (loaded.kind === "failure") {
|
|
128
|
+
observations.push(createObservation({
|
|
129
|
+
key: "compile.report",
|
|
130
|
+
message: loaded.failure.message,
|
|
131
|
+
severity: "error",
|
|
132
|
+
source: "input",
|
|
133
|
+
subject: "compile"
|
|
134
|
+
}));
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
observations.push(createObservation({
|
|
138
|
+
key: "compile.report",
|
|
139
|
+
message: `Loaded compile report ${loaded.report.reportPath}`,
|
|
140
|
+
severity: "ok",
|
|
141
|
+
source: "compile_report",
|
|
142
|
+
subject: "compile"
|
|
143
|
+
}));
|
|
144
|
+
observations.push(createObservation({
|
|
145
|
+
key: "compile.fingerprint",
|
|
146
|
+
message: loaded.report.compileFingerprint
|
|
147
|
+
? `Compile fingerprint ${loaded.report.compileFingerprint}`
|
|
148
|
+
: "Compile report has no compile_fingerprint yet",
|
|
149
|
+
severity: loaded.report.compileFingerprint ? "ok" : "unknown",
|
|
150
|
+
source: "compile_report",
|
|
151
|
+
subject: "compile"
|
|
152
|
+
}));
|
|
153
|
+
observations.push(...createCompiledContainerObservations(loaded));
|
|
154
|
+
if (loaded.report.root && path.resolve(loaded.report.root) !== path.resolve(view.root.source)) {
|
|
155
|
+
observations.push(createObservation({
|
|
156
|
+
key: "compile.root",
|
|
157
|
+
message: `Compile report root ${loaded.report.root} differs from source ${view.root.source}`,
|
|
158
|
+
severity: "warn",
|
|
159
|
+
source: "compile_report",
|
|
160
|
+
subject: "compile"
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
163
|
+
const reportNodes = new Map(loaded.report.nodes.map((node) => [node.id, node]));
|
|
164
|
+
const declaredIds = new Set(nodes.map((node) => node.id));
|
|
165
|
+
for (const node of nodes) {
|
|
166
|
+
const reportNode = reportNodes.get(node.id);
|
|
167
|
+
observations.push(createObservation({
|
|
168
|
+
key: `${node.kind}.compiled`,
|
|
169
|
+
message: reportNode
|
|
170
|
+
? `${node.displayName} is present in the compile report`
|
|
171
|
+
: `${node.displayName} is missing from the compile report`,
|
|
172
|
+
severity: reportNode ? "ok" : "warn",
|
|
173
|
+
source: "compile_report",
|
|
174
|
+
subject: node.id
|
|
175
|
+
}));
|
|
176
|
+
if (reportNode) {
|
|
177
|
+
observations.push(...createNodeReportObservations(reportNode));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
for (const reportNode of loaded.report.nodes) {
|
|
181
|
+
if (!declaredIds.has(reportNode.id)) {
|
|
182
|
+
observations.push(createObservation({
|
|
183
|
+
key: "compile.extra_node",
|
|
184
|
+
message: `${reportNode.id} appears in the compile report but not in source`,
|
|
185
|
+
severity: "warn",
|
|
186
|
+
source: "compile_report",
|
|
187
|
+
subject: reportNode.id
|
|
188
|
+
}));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
const defaultLiveRequest = () => ({
|
|
193
|
+
context: null,
|
|
194
|
+
deploymentName: null,
|
|
195
|
+
logs: false,
|
|
196
|
+
recover: false,
|
|
197
|
+
requested: false
|
|
198
|
+
});
|
|
199
|
+
const addLivePlaceholderObservations = (observations, view, live, providedLiveObservations) => {
|
|
200
|
+
if (!live.requested) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (!providedLiveObservations.some((observation) => observation.source === "runtime")) {
|
|
204
|
+
for (const runtime of view.runtimes) {
|
|
205
|
+
observations.push(createObservation({
|
|
206
|
+
key: "runtime.probe",
|
|
207
|
+
message: `${runtime.name} live runtime probe is not available for this status request`,
|
|
208
|
+
severity: "unknown",
|
|
209
|
+
source: "runtime",
|
|
210
|
+
subject: `runtime:${runtime.name}`
|
|
211
|
+
}));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (!providedLiveObservations.some((observation) => observation.source === "network")) {
|
|
215
|
+
for (const network of view.networks) {
|
|
216
|
+
observations.push(createObservation({
|
|
217
|
+
key: "network.probe",
|
|
218
|
+
message: `${network.id} live network probe is not available for this status request`,
|
|
219
|
+
severity: "unknown",
|
|
220
|
+
source: "network",
|
|
221
|
+
subject: `network:${network.id}`
|
|
222
|
+
}));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
export const createStaticStatus = (view, loadedReport, input) => {
|
|
227
|
+
const nodes = flattenOrganizationNodes(view);
|
|
228
|
+
const observations = [];
|
|
229
|
+
const nodeCounts = countNodesByKind(nodes);
|
|
230
|
+
const deployments = input.deployments ?? [];
|
|
231
|
+
const live = input.live ?? defaultLiveRequest();
|
|
232
|
+
const liveObservations = input.liveObservations ?? [];
|
|
233
|
+
const selection = expandStatusSelectionSubjects(input.selection, {
|
|
234
|
+
deployments,
|
|
235
|
+
loadedReport,
|
|
236
|
+
view
|
|
237
|
+
});
|
|
238
|
+
addDeclaredObservations(observations, view, nodes);
|
|
239
|
+
addCompiledObservations(observations, loadedReport, view, nodes);
|
|
240
|
+
observations.push(...createDeploymentObservations(deployments, {
|
|
241
|
+
compileFingerprint: compileInfoFor(loadedReport).compileFingerprint,
|
|
242
|
+
liveRequested: live.requested,
|
|
243
|
+
outputDirectory: input.outputDirectory,
|
|
244
|
+
recover: live.recover
|
|
245
|
+
}));
|
|
246
|
+
observations.push(...liveObservations);
|
|
247
|
+
addLivePlaceholderObservations(observations, view, live, liveObservations);
|
|
248
|
+
return {
|
|
249
|
+
compile: compileInfoFor(loadedReport),
|
|
250
|
+
deployments,
|
|
251
|
+
inputPath: input.inputPath,
|
|
252
|
+
live,
|
|
253
|
+
observations,
|
|
254
|
+
outputDirectory: input.outputDirectory,
|
|
255
|
+
projectRoot: view.projectRoot ?? null,
|
|
256
|
+
selection,
|
|
257
|
+
summary: {
|
|
258
|
+
...nodeCounts,
|
|
259
|
+
deployments: deployments.length,
|
|
260
|
+
networks: view.networks.length,
|
|
261
|
+
runtimes: view.runtimes.length
|
|
262
|
+
},
|
|
263
|
+
view,
|
|
264
|
+
version: "spawnfile.status.v1"
|
|
265
|
+
};
|
|
266
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { StatusInputFailure } from "./types.js";
|
|
2
|
+
export interface StatusReportCapability {
|
|
3
|
+
key: string;
|
|
4
|
+
message: string;
|
|
5
|
+
outcome: "degraded" | "supported" | "unsupported";
|
|
6
|
+
}
|
|
7
|
+
export interface StatusReportDiagnostic {
|
|
8
|
+
level: "error" | "info" | "warn";
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
export interface StatusReportNode {
|
|
12
|
+
capabilities: StatusReportCapability[];
|
|
13
|
+
diagnostics: StatusReportDiagnostic[];
|
|
14
|
+
id: string;
|
|
15
|
+
kind: "agent" | "team";
|
|
16
|
+
outputDir: string | null;
|
|
17
|
+
runtime: string | null;
|
|
18
|
+
}
|
|
19
|
+
export interface StatusReportRuntimeInstance {
|
|
20
|
+
configPath: string | null;
|
|
21
|
+
homePath: string | null;
|
|
22
|
+
id: string;
|
|
23
|
+
internalPort: number | null;
|
|
24
|
+
nodeIds: string[];
|
|
25
|
+
publishedPort: number | null;
|
|
26
|
+
runtime: string;
|
|
27
|
+
workspacePath: string | null;
|
|
28
|
+
}
|
|
29
|
+
export interface StatusReportMoltnetRoom {
|
|
30
|
+
id: string;
|
|
31
|
+
members: string[];
|
|
32
|
+
visibility: string | null;
|
|
33
|
+
writePolicy: string | null;
|
|
34
|
+
}
|
|
35
|
+
export interface StatusReportMoltnetServerPlan {
|
|
36
|
+
authMode: string | null;
|
|
37
|
+
baseUrl: string;
|
|
38
|
+
directMessages: boolean | null;
|
|
39
|
+
id: string;
|
|
40
|
+
mode: "external" | "managed";
|
|
41
|
+
networkId: string;
|
|
42
|
+
operatorTokenSecret: string | null;
|
|
43
|
+
port: number | null;
|
|
44
|
+
publicRead: boolean | null;
|
|
45
|
+
rooms: StatusReportMoltnetRoom[];
|
|
46
|
+
storeKind: string | null;
|
|
47
|
+
}
|
|
48
|
+
export interface StatusReportContainerPortMapping {
|
|
49
|
+
internalPort: number;
|
|
50
|
+
publishedPort: number;
|
|
51
|
+
}
|
|
52
|
+
export interface StatusReportPersistentMount {
|
|
53
|
+
id: string;
|
|
54
|
+
mountPath: string;
|
|
55
|
+
reason: string;
|
|
56
|
+
volumeName: string;
|
|
57
|
+
}
|
|
58
|
+
export interface StatusReportWorkspaceResource {
|
|
59
|
+
backingPath: string;
|
|
60
|
+
id: string;
|
|
61
|
+
kind: string;
|
|
62
|
+
linkPath: string;
|
|
63
|
+
mode: string;
|
|
64
|
+
mount: string;
|
|
65
|
+
sharing: string;
|
|
66
|
+
}
|
|
67
|
+
export interface StatusReport {
|
|
68
|
+
compileFingerprint: string | null;
|
|
69
|
+
generatedAt: string | null;
|
|
70
|
+
internalPorts?: number[];
|
|
71
|
+
moltnetServers?: StatusReportMoltnetServerPlan[];
|
|
72
|
+
nodes: StatusReportNode[];
|
|
73
|
+
outputDirectory: string | null;
|
|
74
|
+
persistentMounts?: StatusReportPersistentMount[];
|
|
75
|
+
portMappings?: StatusReportContainerPortMapping[];
|
|
76
|
+
publishedPorts?: number[];
|
|
77
|
+
reportPath: string;
|
|
78
|
+
root: string | null;
|
|
79
|
+
runtimeInstances: StatusReportRuntimeInstance[];
|
|
80
|
+
secretsRequired?: string[];
|
|
81
|
+
workspaceResources?: StatusReportWorkspaceResource[];
|
|
82
|
+
}
|
|
83
|
+
export type LoadedCompileReport = {
|
|
84
|
+
kind: "failure";
|
|
85
|
+
failure: StatusInputFailure;
|
|
86
|
+
reportPath: string;
|
|
87
|
+
} | {
|
|
88
|
+
kind: "loaded";
|
|
89
|
+
report: StatusReport;
|
|
90
|
+
reportPath: string;
|
|
91
|
+
} | {
|
|
92
|
+
kind: "missing";
|
|
93
|
+
reportPath: string;
|
|
94
|
+
};
|
|
95
|
+
export declare const resolveCompileReportPath: (outputDirectory: string) => string;
|
|
96
|
+
export declare const loadCompileReport: (outputDirectory: string) => Promise<LoadedCompileReport>;
|