@kbediako/codex-orchestrator 0.1.0
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/LICENSE +7 -0
- package/README.md +238 -0
- package/dist/bin/codex-orchestrator.js +507 -0
- package/dist/orchestrator/src/agents/builder.js +16 -0
- package/dist/orchestrator/src/agents/index.js +4 -0
- package/dist/orchestrator/src/agents/planner.js +17 -0
- package/dist/orchestrator/src/agents/reviewer.js +13 -0
- package/dist/orchestrator/src/agents/tester.js +13 -0
- package/dist/orchestrator/src/cli/adapters/CommandBuilder.js +20 -0
- package/dist/orchestrator/src/cli/adapters/CommandPlanner.js +164 -0
- package/dist/orchestrator/src/cli/adapters/CommandReviewer.js +32 -0
- package/dist/orchestrator/src/cli/adapters/CommandTester.js +33 -0
- package/dist/orchestrator/src/cli/adapters/index.js +4 -0
- package/dist/orchestrator/src/cli/config/userConfig.js +28 -0
- package/dist/orchestrator/src/cli/doctor.js +48 -0
- package/dist/orchestrator/src/cli/events/runEvents.js +84 -0
- package/dist/orchestrator/src/cli/exec/command.js +56 -0
- package/dist/orchestrator/src/cli/exec/context.js +108 -0
- package/dist/orchestrator/src/cli/exec/experience.js +77 -0
- package/dist/orchestrator/src/cli/exec/finalization.js +140 -0
- package/dist/orchestrator/src/cli/exec/learning.js +62 -0
- package/dist/orchestrator/src/cli/exec/stageRunner.js +71 -0
- package/dist/orchestrator/src/cli/exec/summary.js +109 -0
- package/dist/orchestrator/src/cli/exec/telemetry.js +18 -0
- package/dist/orchestrator/src/cli/exec/tfgrpo.js +200 -0
- package/dist/orchestrator/src/cli/exec/tfgrpoArtifacts.js +19 -0
- package/dist/orchestrator/src/cli/exec/types.js +1 -0
- package/dist/orchestrator/src/cli/init.js +64 -0
- package/dist/orchestrator/src/cli/mcp.js +124 -0
- package/dist/orchestrator/src/cli/metrics/metricsAggregator.js +404 -0
- package/dist/orchestrator/src/cli/metrics/metricsRecorder.js +138 -0
- package/dist/orchestrator/src/cli/orchestrator.js +554 -0
- package/dist/orchestrator/src/cli/pipelines/defaultDiagnostics.js +32 -0
- package/dist/orchestrator/src/cli/pipelines/designReference.js +72 -0
- package/dist/orchestrator/src/cli/pipelines/hiFiDesignToolkit.js +71 -0
- package/dist/orchestrator/src/cli/pipelines/index.js +34 -0
- package/dist/orchestrator/src/cli/run/environment.js +24 -0
- package/dist/orchestrator/src/cli/run/manifest.js +367 -0
- package/dist/orchestrator/src/cli/run/manifestPersister.js +88 -0
- package/dist/orchestrator/src/cli/run/runPaths.js +30 -0
- package/dist/orchestrator/src/cli/selfCheck.js +12 -0
- package/dist/orchestrator/src/cli/services/commandRunner.js +420 -0
- package/dist/orchestrator/src/cli/services/controlPlaneService.js +107 -0
- package/dist/orchestrator/src/cli/services/execRuntime.js +69 -0
- package/dist/orchestrator/src/cli/services/pipelineResolver.js +47 -0
- package/dist/orchestrator/src/cli/services/runPreparation.js +82 -0
- package/dist/orchestrator/src/cli/services/runSummaryWriter.js +35 -0
- package/dist/orchestrator/src/cli/services/schedulerService.js +42 -0
- package/dist/orchestrator/src/cli/tasks/taskMetadata.js +19 -0
- package/dist/orchestrator/src/cli/telemetry/schema.js +8 -0
- package/dist/orchestrator/src/cli/types.js +1 -0
- package/dist/orchestrator/src/cli/ui/HudApp.js +112 -0
- package/dist/orchestrator/src/cli/ui/controller.js +26 -0
- package/dist/orchestrator/src/cli/ui/store.js +240 -0
- package/dist/orchestrator/src/cli/utils/enforcementMode.js +12 -0
- package/dist/orchestrator/src/cli/utils/fs.js +8 -0
- package/dist/orchestrator/src/cli/utils/interactive.js +25 -0
- package/dist/orchestrator/src/cli/utils/jsonlWriter.js +10 -0
- package/dist/orchestrator/src/cli/utils/optionalDeps.js +30 -0
- package/dist/orchestrator/src/cli/utils/packageInfo.js +25 -0
- package/dist/orchestrator/src/cli/utils/planFormatter.js +49 -0
- package/dist/orchestrator/src/cli/utils/runId.js +7 -0
- package/dist/orchestrator/src/cli/utils/specGuardRunner.js +26 -0
- package/dist/orchestrator/src/cli/utils/strings.js +8 -0
- package/dist/orchestrator/src/cli/utils/time.js +6 -0
- package/dist/orchestrator/src/control-plane/drift-reporter.js +109 -0
- package/dist/orchestrator/src/control-plane/index.js +3 -0
- package/dist/orchestrator/src/control-plane/request-builder.js +217 -0
- package/dist/orchestrator/src/control-plane/types.js +1 -0
- package/dist/orchestrator/src/control-plane/validator.js +50 -0
- package/dist/orchestrator/src/credentials/CredentialBroker.js +1 -0
- package/dist/orchestrator/src/events/EventBus.js +25 -0
- package/dist/orchestrator/src/learning/crystalizer.js +108 -0
- package/dist/orchestrator/src/learning/harvester.js +146 -0
- package/dist/orchestrator/src/learning/manifest.js +56 -0
- package/dist/orchestrator/src/learning/runner.js +177 -0
- package/dist/orchestrator/src/learning/validator.js +164 -0
- package/dist/orchestrator/src/logger.js +20 -0
- package/dist/orchestrator/src/manager.js +388 -0
- package/dist/orchestrator/src/persistence/ArtifactStager.js +95 -0
- package/dist/orchestrator/src/persistence/ExperienceStore.js +210 -0
- package/dist/orchestrator/src/persistence/PersistenceCoordinator.js +65 -0
- package/dist/orchestrator/src/persistence/RunManifestWriter.js +23 -0
- package/dist/orchestrator/src/persistence/TaskStateStore.js +172 -0
- package/dist/orchestrator/src/persistence/identifierGuards.js +1 -0
- package/dist/orchestrator/src/persistence/lockFile.js +26 -0
- package/dist/orchestrator/src/persistence/sanitizeIdentifier.js +26 -0
- package/dist/orchestrator/src/persistence/sanitizeRunId.js +8 -0
- package/dist/orchestrator/src/persistence/sanitizeTaskId.js +8 -0
- package/dist/orchestrator/src/persistence/writeAtomicFile.js +4 -0
- package/dist/orchestrator/src/privacy/guard.js +111 -0
- package/dist/orchestrator/src/scheduler/index.js +1 -0
- package/dist/orchestrator/src/scheduler/plan.js +171 -0
- package/dist/orchestrator/src/scheduler/types.js +1 -0
- package/dist/orchestrator/src/sync/CloudRunsClient.js +1 -0
- package/dist/orchestrator/src/sync/CloudRunsHttpClient.js +82 -0
- package/dist/orchestrator/src/sync/CloudSyncWorker.js +206 -0
- package/dist/orchestrator/src/sync/createCloudSyncWorker.js +15 -0
- package/dist/orchestrator/src/types.js +1 -0
- package/dist/orchestrator/src/utils/atomicWrite.js +15 -0
- package/dist/orchestrator/src/utils/errorMessage.js +14 -0
- package/dist/orchestrator/src/utils/executionMode.js +69 -0
- package/dist/packages/control-plane-schemas/src/index.js +1 -0
- package/dist/packages/control-plane-schemas/src/run-request.js +548 -0
- package/dist/packages/orchestrator/src/exec/handle-service.js +203 -0
- package/dist/packages/orchestrator/src/exec/session-manager.js +147 -0
- package/dist/packages/orchestrator/src/exec/unified-exec.js +432 -0
- package/dist/packages/orchestrator/src/index.js +3 -0
- package/dist/packages/orchestrator/src/instructions/loader.js +101 -0
- package/dist/packages/orchestrator/src/instructions/promptPacks.js +151 -0
- package/dist/packages/orchestrator/src/notifications/index.js +74 -0
- package/dist/packages/orchestrator/src/telemetry/otel-exporter.js +142 -0
- package/dist/packages/orchestrator/src/tool-orchestrator.js +161 -0
- package/dist/packages/sdk-node/src/orchestrator.js +195 -0
- package/dist/packages/shared/config/designConfig.js +495 -0
- package/dist/packages/shared/config/env.js +37 -0
- package/dist/packages/shared/config/index.js +2 -0
- package/dist/packages/shared/design-artifacts/writer.js +221 -0
- package/dist/packages/shared/events/serializer.js +84 -0
- package/dist/packages/shared/events/types.js +1 -0
- package/dist/packages/shared/manifest/artifactUtils.js +36 -0
- package/dist/packages/shared/manifest/designArtifacts.js +665 -0
- package/dist/packages/shared/manifest/fileIO.js +29 -0
- package/dist/packages/shared/manifest/toolRuns.js +78 -0
- package/dist/packages/shared/manifest/toolkitArtifacts.js +223 -0
- package/dist/packages/shared/manifest/types.js +5 -0
- package/dist/packages/shared/manifest/validator.js +73 -0
- package/dist/packages/shared/manifest/writer.js +2 -0
- package/dist/packages/shared/streams/stdio.js +112 -0
- package/dist/scripts/design/pipeline/advanced-assets.js +466 -0
- package/dist/scripts/design/pipeline/componentize.js +74 -0
- package/dist/scripts/design/pipeline/context.js +34 -0
- package/dist/scripts/design/pipeline/extract.js +249 -0
- package/dist/scripts/design/pipeline/optionalDeps.js +107 -0
- package/dist/scripts/design/pipeline/prepare.js +46 -0
- package/dist/scripts/design/pipeline/reference.js +94 -0
- package/dist/scripts/design/pipeline/state.js +206 -0
- package/dist/scripts/design/pipeline/toolkit/common.js +94 -0
- package/dist/scripts/design/pipeline/toolkit/extract.js +258 -0
- package/dist/scripts/design/pipeline/toolkit/publish.js +202 -0
- package/dist/scripts/design/pipeline/toolkit/publishActions.js +12 -0
- package/dist/scripts/design/pipeline/toolkit/reference.js +846 -0
- package/dist/scripts/design/pipeline/toolkit/snapshot.js +882 -0
- package/dist/scripts/design/pipeline/toolkit/tokens.js +456 -0
- package/dist/scripts/design/pipeline/visual-regression.js +137 -0
- package/dist/scripts/design/pipeline/write-artifacts.js +61 -0
- package/package.json +97 -0
- package/schemas/manifest.json +1064 -0
- package/templates/README.md +12 -0
- package/templates/codex/mcp-client.json +8 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { mkdir, rename, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join, relative as relativePath } from 'node:path';
|
|
3
|
+
import { persistDesignManifest } from '../manifest/writer.js';
|
|
4
|
+
export async function writeDesignSummary(options) {
|
|
5
|
+
const now = options.now ?? new Date();
|
|
6
|
+
const context = options.context;
|
|
7
|
+
const artifacts = options.artifacts ?? [];
|
|
8
|
+
const summary = options.summary ?? deriveSummary(artifacts, now);
|
|
9
|
+
const toolkitArtifacts = options.toolkitArtifacts ?? [];
|
|
10
|
+
const approvals = options.approvals ?? [];
|
|
11
|
+
const toolkitSummary = options.toolkitSummary ?? (toolkitArtifacts.length > 0 ? deriveToolkitSummary(toolkitArtifacts, approvals, now) : undefined);
|
|
12
|
+
const manifestUpdate = {
|
|
13
|
+
artifacts,
|
|
14
|
+
summary,
|
|
15
|
+
configSnapshot: options.configSnapshot ?? null,
|
|
16
|
+
...(toolkitArtifacts.length > 0 ? { toolkitArtifacts } : {}),
|
|
17
|
+
...(toolkitSummary ? { toolkitSummary } : {}),
|
|
18
|
+
...(options.designPlan !== undefined ? { designPlan: options.designPlan } : {}),
|
|
19
|
+
...(options.designGuardrail !== undefined ? { designGuardrail: options.designGuardrail } : {}),
|
|
20
|
+
...(options.designHistory !== undefined ? { designHistory: options.designHistory } : {}),
|
|
21
|
+
...(options.designStyleProfile !== undefined ? { designStyleProfile: options.designStyleProfile } : {}),
|
|
22
|
+
...(options.designMetrics !== undefined ? { designMetrics: options.designMetrics } : {})
|
|
23
|
+
};
|
|
24
|
+
const manifestOptions = {
|
|
25
|
+
retentionDays: options.retention.days,
|
|
26
|
+
retentionPolicy: options.retention.policy,
|
|
27
|
+
now,
|
|
28
|
+
...options.manifestOptions
|
|
29
|
+
};
|
|
30
|
+
const manifest = await persistDesignManifest(context.manifestPath, manifestUpdate, manifestOptions);
|
|
31
|
+
const payload = buildSummaryPayload(options, summary, toolkitSummary, manifest, now);
|
|
32
|
+
const summaryPath = await writeSummaryFile(options, payload);
|
|
33
|
+
return {
|
|
34
|
+
manifest: context.manifestPath,
|
|
35
|
+
summaryPath,
|
|
36
|
+
summary: payload
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function buildSummaryPayload(options, summary, toolkitSummary, manifest, now) {
|
|
40
|
+
const context = options.context;
|
|
41
|
+
const repoRoot = options.context.repoRoot ?? process.cwd();
|
|
42
|
+
const manifestRelative = relativePath(repoRoot, context.manifestPath);
|
|
43
|
+
const approvals = (options.approvals ?? [])
|
|
44
|
+
.map((approval) => ({
|
|
45
|
+
id: approval.id,
|
|
46
|
+
actor: approval.actor,
|
|
47
|
+
reason: approval.reason,
|
|
48
|
+
timestamp: approval.timestamp
|
|
49
|
+
}))
|
|
50
|
+
.filter((approval) => approval.id && approval.actor && approval.timestamp);
|
|
51
|
+
const stages = options.stages.map((stage) => {
|
|
52
|
+
const artifacts = (stage.artifacts ?? []).map((artifact) => ({
|
|
53
|
+
relative_path: artifact.relative_path,
|
|
54
|
+
stage: artifact.stage ?? stage.id,
|
|
55
|
+
status: artifact.status ?? stage.status,
|
|
56
|
+
type: artifact.type,
|
|
57
|
+
description: artifact.description
|
|
58
|
+
}));
|
|
59
|
+
return {
|
|
60
|
+
id: stage.id,
|
|
61
|
+
title: stage.title ?? null,
|
|
62
|
+
status: stage.status,
|
|
63
|
+
notes: stage.notes ?? [],
|
|
64
|
+
metrics: stage.metrics ?? {},
|
|
65
|
+
artifacts
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
const summaryArtifacts = (options.artifacts ?? []).map((artifact) => ({
|
|
69
|
+
stage: artifact.stage,
|
|
70
|
+
status: artifact.status,
|
|
71
|
+
relative_path: artifact.relative_path,
|
|
72
|
+
type: artifact.type,
|
|
73
|
+
description: artifact.description
|
|
74
|
+
}));
|
|
75
|
+
const toolkitArtifacts = (options.toolkitArtifacts ?? []).map((artifact) => ({
|
|
76
|
+
id: artifact.id,
|
|
77
|
+
stage: artifact.stage,
|
|
78
|
+
status: artifact.status,
|
|
79
|
+
relative_path: artifact.relative_path,
|
|
80
|
+
description: artifact.description ?? null,
|
|
81
|
+
metrics: artifact.metrics ?? {},
|
|
82
|
+
retention: artifact.retention ?? null
|
|
83
|
+
}));
|
|
84
|
+
const designMetrics = manifest.design_metrics ?? options.designMetrics ?? null;
|
|
85
|
+
const combinedMetrics = {
|
|
86
|
+
...(options.metrics ?? {}),
|
|
87
|
+
...(designMetrics ?? {})
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
task_id: context.taskId,
|
|
91
|
+
run_id: context.runId,
|
|
92
|
+
manifest: manifestRelative,
|
|
93
|
+
generated_at: now.toISOString(),
|
|
94
|
+
retention: {
|
|
95
|
+
days: options.retention.days,
|
|
96
|
+
auto_purge: options.retention.autoPurge,
|
|
97
|
+
policy: options.retention.policy ?? 'design.config.retention'
|
|
98
|
+
},
|
|
99
|
+
privacy: {
|
|
100
|
+
allow_third_party: options.privacy.allowThirdParty,
|
|
101
|
+
require_approval: options.privacy.requireApproval,
|
|
102
|
+
mask_selectors: options.privacy.maskSelectors,
|
|
103
|
+
approver: options.privacy.approver ?? null
|
|
104
|
+
},
|
|
105
|
+
approvals,
|
|
106
|
+
stages,
|
|
107
|
+
artifacts: summaryArtifacts,
|
|
108
|
+
summary,
|
|
109
|
+
design_toolkit_artifacts: toolkitArtifacts,
|
|
110
|
+
design_toolkit_summary: toolkitSummary ?? null,
|
|
111
|
+
design_plan: manifest.design_plan ?? options.designPlan ?? null,
|
|
112
|
+
design_guardrail: manifest.design_guardrail ?? options.designGuardrail ?? null,
|
|
113
|
+
design_history: manifest.design_history ?? options.designHistory ?? null,
|
|
114
|
+
design_style_profile: manifest.design_style_profile ?? options.designStyleProfile ?? null,
|
|
115
|
+
design_metrics: designMetrics,
|
|
116
|
+
metrics: combinedMetrics,
|
|
117
|
+
config_snapshot: options.configSnapshot ?? null
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
async function writeSummaryFile(options, payload) {
|
|
121
|
+
const outRoot = options.outDir ?? join(process.cwd(), 'out');
|
|
122
|
+
const safeTaskId = sanitizeTaskId(options.context.taskId);
|
|
123
|
+
const safeRunId = sanitizeRunId(options.context.runId);
|
|
124
|
+
const summaryPath = join(outRoot, safeTaskId, 'design', 'runs', `${safeRunId}.json`);
|
|
125
|
+
await writeJsonAtomic(summaryPath, payload);
|
|
126
|
+
return summaryPath;
|
|
127
|
+
}
|
|
128
|
+
function deriveSummary(artifacts, now) {
|
|
129
|
+
const stageMap = new Map();
|
|
130
|
+
for (const artifact of artifacts) {
|
|
131
|
+
const entry = stageMap.get(artifact.stage) ?? {
|
|
132
|
+
succeeded: 0,
|
|
133
|
+
failed: 0,
|
|
134
|
+
skipped: 0,
|
|
135
|
+
artifacts: 0
|
|
136
|
+
};
|
|
137
|
+
entry.artifacts += 1;
|
|
138
|
+
if (artifact.status === 'succeeded') {
|
|
139
|
+
entry.succeeded += 1;
|
|
140
|
+
}
|
|
141
|
+
else if (artifact.status === 'failed') {
|
|
142
|
+
entry.failed += 1;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
entry.skipped += 1;
|
|
146
|
+
}
|
|
147
|
+
stageMap.set(artifact.stage, entry);
|
|
148
|
+
}
|
|
149
|
+
const stages = Array.from(stageMap.entries()).map(([stage, stats]) => ({
|
|
150
|
+
stage,
|
|
151
|
+
succeeded: stats.succeeded,
|
|
152
|
+
failed: stats.failed,
|
|
153
|
+
skipped: stats.skipped,
|
|
154
|
+
artifacts: stats.artifacts
|
|
155
|
+
}));
|
|
156
|
+
return {
|
|
157
|
+
total_artifacts: artifacts.length,
|
|
158
|
+
generated_at: now.toISOString(),
|
|
159
|
+
stages
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function deriveToolkitSummary(artifacts, approvals, now) {
|
|
163
|
+
const stageMap = new Map();
|
|
164
|
+
const totals = {};
|
|
165
|
+
for (const artifact of artifacts) {
|
|
166
|
+
const entry = stageMap.get(artifact.stage) ?? { count: 0, metrics: {} };
|
|
167
|
+
entry.count += 1;
|
|
168
|
+
if (artifact.metrics) {
|
|
169
|
+
accumulateToolkitMetrics(entry.metrics, artifact.metrics);
|
|
170
|
+
accumulateNumericTotals(totals, artifact.metrics);
|
|
171
|
+
}
|
|
172
|
+
stageMap.set(artifact.stage, entry);
|
|
173
|
+
}
|
|
174
|
+
const stages = Array.from(stageMap.entries()).map(([stage, data]) => ({
|
|
175
|
+
stage,
|
|
176
|
+
artifacts: data.count,
|
|
177
|
+
metrics: data.metrics
|
|
178
|
+
}));
|
|
179
|
+
const approvalIds = approvals.map((approval) => approval.id).filter(Boolean);
|
|
180
|
+
return {
|
|
181
|
+
generated_at: now.toISOString(),
|
|
182
|
+
stages,
|
|
183
|
+
totals: Object.keys(totals).length > 0 ? totals : undefined,
|
|
184
|
+
approvals: approvalIds.length > 0 ? approvalIds : undefined
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function accumulateToolkitMetrics(target, incoming) {
|
|
188
|
+
for (const [key, value] of Object.entries(incoming)) {
|
|
189
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
190
|
+
const current = target[key];
|
|
191
|
+
if (typeof current === 'number') {
|
|
192
|
+
target[key] = current + value;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
target[key] = value;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
else if (typeof value === 'string') {
|
|
199
|
+
target[key] = value;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function accumulateNumericTotals(target, incoming) {
|
|
204
|
+
for (const [key, value] of Object.entries(incoming)) {
|
|
205
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
206
|
+
target[key] = (target[key] ?? 0) + value;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function sanitizeTaskId(value) {
|
|
211
|
+
return value.replace(/[^a-zA-Z0-9_-]/g, '').toLowerCase();
|
|
212
|
+
}
|
|
213
|
+
function sanitizeRunId(value) {
|
|
214
|
+
return value.replace(/[:]/g, '-');
|
|
215
|
+
}
|
|
216
|
+
async function writeJsonAtomic(targetPath, payload) {
|
|
217
|
+
const tmpPath = `${targetPath}.tmp-${process.pid}-${Date.now()}`;
|
|
218
|
+
await mkdir(dirname(targetPath), { recursive: true });
|
|
219
|
+
await writeFile(tmpPath, `${JSON.stringify(payload, null, 2)}\n`, 'utf8');
|
|
220
|
+
await rename(tmpPath, targetPath);
|
|
221
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
function serializeBegin(event) {
|
|
2
|
+
return {
|
|
3
|
+
type: event.type,
|
|
4
|
+
timestamp: event.timestamp,
|
|
5
|
+
payload: {
|
|
6
|
+
attempt: event.attempt,
|
|
7
|
+
correlationId: event.correlationId,
|
|
8
|
+
command: event.payload.command,
|
|
9
|
+
args: event.payload.args,
|
|
10
|
+
cwd: event.payload.cwd ?? null,
|
|
11
|
+
sessionId: event.payload.sessionId,
|
|
12
|
+
sandboxState: event.payload.sandboxState,
|
|
13
|
+
persisted: event.payload.persisted
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function serializeChunk(event) {
|
|
18
|
+
return {
|
|
19
|
+
type: event.type,
|
|
20
|
+
timestamp: event.timestamp,
|
|
21
|
+
payload: {
|
|
22
|
+
attempt: event.attempt,
|
|
23
|
+
correlationId: event.correlationId,
|
|
24
|
+
stream: event.payload.stream,
|
|
25
|
+
sequence: event.payload.sequence,
|
|
26
|
+
bytes: event.payload.bytes,
|
|
27
|
+
data: event.payload.data
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function serializeEnd(event) {
|
|
32
|
+
return {
|
|
33
|
+
type: event.type,
|
|
34
|
+
timestamp: event.timestamp,
|
|
35
|
+
payload: {
|
|
36
|
+
attempt: event.attempt,
|
|
37
|
+
correlationId: event.correlationId,
|
|
38
|
+
exitCode: event.payload.exitCode,
|
|
39
|
+
signal: event.payload.signal,
|
|
40
|
+
durationMs: event.payload.durationMs,
|
|
41
|
+
stdout: event.payload.stdout,
|
|
42
|
+
stderr: event.payload.stderr,
|
|
43
|
+
sandboxState: event.payload.sandboxState,
|
|
44
|
+
sessionId: event.payload.sessionId,
|
|
45
|
+
status: event.payload.status
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function serializeRetry(event) {
|
|
50
|
+
return {
|
|
51
|
+
type: event.type,
|
|
52
|
+
timestamp: event.timestamp,
|
|
53
|
+
payload: {
|
|
54
|
+
attempt: event.attempt,
|
|
55
|
+
correlationId: event.correlationId,
|
|
56
|
+
delayMs: event.payload.delayMs,
|
|
57
|
+
sandboxState: event.payload.sandboxState,
|
|
58
|
+
errorMessage: event.payload.errorMessage
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export function serializeExecEvent(event) {
|
|
63
|
+
switch (event.type) {
|
|
64
|
+
case 'exec:begin':
|
|
65
|
+
return serializeBegin(event);
|
|
66
|
+
case 'exec:chunk':
|
|
67
|
+
return serializeChunk(event);
|
|
68
|
+
case 'exec:end':
|
|
69
|
+
return serializeEnd(event);
|
|
70
|
+
case 'exec:retry':
|
|
71
|
+
return serializeRetry(event);
|
|
72
|
+
default: {
|
|
73
|
+
const exhaustive = event;
|
|
74
|
+
return exhaustive;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export function serializeRunSummaryEvent(payload, timestamp = new Date().toISOString()) {
|
|
79
|
+
return {
|
|
80
|
+
type: 'run:summary',
|
|
81
|
+
timestamp,
|
|
82
|
+
payload
|
|
83
|
+
};
|
|
84
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function sanitizeRelativeArtifactPath(value) {
|
|
2
|
+
const normalized = value.replace(/\\+/g, '/').split('/');
|
|
3
|
+
const segments = [];
|
|
4
|
+
for (const segmentRaw of normalized) {
|
|
5
|
+
const segment = segmentRaw.trim();
|
|
6
|
+
if (!segment || segment === '.') {
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
if (segment === '..' || segment.includes('..')) {
|
|
10
|
+
throw new Error(`relative_path contains invalid segment '${segment}'`);
|
|
11
|
+
}
|
|
12
|
+
segments.push(segment);
|
|
13
|
+
}
|
|
14
|
+
if (segments.length === 0) {
|
|
15
|
+
throw new Error('relative_path must include at least one segment');
|
|
16
|
+
}
|
|
17
|
+
return segments.join('/');
|
|
18
|
+
}
|
|
19
|
+
export function isIsoDate(value) {
|
|
20
|
+
const trimmed = value.trim();
|
|
21
|
+
const isoPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
22
|
+
if (!isoPattern.test(trimmed)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const date = new Date(trimmed);
|
|
26
|
+
return !Number.isNaN(date.getTime());
|
|
27
|
+
}
|
|
28
|
+
export function coerceNonNegativeInteger(value) {
|
|
29
|
+
if (typeof value === 'number' || typeof value === 'string') {
|
|
30
|
+
const converted = typeof value === 'number' ? value : Number(value);
|
|
31
|
+
if (Number.isFinite(converted) && converted >= 0) {
|
|
32
|
+
return Math.floor(converted);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|