@atolis-hq/wake 0.1.9 → 0.1.11
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/dist/src/adapters/fake/fake-ticketing-system.js +9 -1
- package/dist/src/adapters/github/github-issues-work-source.js +11 -1
- package/dist/src/core/tick-runner.js +14 -3
- package/dist/src/domain/workflows.js +4 -0
- package/dist/src/main.js +13 -1
- package/dist/src/version.js +1 -1
- package/docker/entrypoint.sh +20 -5
- package/package.json +1 -1
|
@@ -91,14 +91,22 @@ export function createFakeTicketingSystem(options) {
|
|
|
91
91
|
const stageLabel = typeof input.event.payload.stageLabel === 'string'
|
|
92
92
|
? input.event.payload.stageLabel
|
|
93
93
|
: undefined;
|
|
94
|
+
const workflowLabel = typeof input.event.payload.workflowLabel === 'string'
|
|
95
|
+
? input.event.payload.workflowLabel
|
|
96
|
+
: undefined;
|
|
94
97
|
const labels = [
|
|
95
|
-
...currentLabels.filter((label) => !label.startsWith('wake:status.') &&
|
|
98
|
+
...currentLabels.filter((label) => !label.startsWith('wake:status.') &&
|
|
99
|
+
!label.startsWith('wake:stage.') &&
|
|
100
|
+
!label.startsWith('wake:workflow.')),
|
|
96
101
|
...(statusLabel === undefined
|
|
97
102
|
? currentLabels.filter((label) => label.startsWith('wake:status.'))
|
|
98
103
|
: [statusLabel]),
|
|
99
104
|
...(stageLabel === undefined
|
|
100
105
|
? currentLabels.filter((label) => label.startsWith('wake:stage.'))
|
|
101
106
|
: [stageLabel]),
|
|
107
|
+
...(workflowLabel === undefined
|
|
108
|
+
? currentLabels.filter((label) => label.startsWith('wake:workflow.'))
|
|
109
|
+
: [workflowLabel]),
|
|
102
110
|
];
|
|
103
111
|
return [
|
|
104
112
|
createEventEnvelope({
|
|
@@ -3,6 +3,7 @@ import { resolve } from 'node:path';
|
|
|
3
3
|
import { defaultAgentIdentity } from '../../domain/schema.js';
|
|
4
4
|
import { buildResourceUri } from '../../domain/resource-uri.js';
|
|
5
5
|
import { wakeStageLabelPrefix } from '../../domain/stages.js';
|
|
6
|
+
import { wakeWorkflowLabelPrefix } from '../../domain/workflows.js';
|
|
6
7
|
import { createEventEnvelope, createUnkeyedEventEnvelope } from '../../lib/event-log.js';
|
|
7
8
|
import { wakeVersion } from '../../version.js';
|
|
8
9
|
import { buildResumeCommandForCli } from '../runner/runner-cli-adapter.js';
|
|
@@ -340,14 +341,22 @@ export function createGitHubIssuesWorkSource(deps) {
|
|
|
340
341
|
const nextStageLabel = typeof input.event.payload.stageLabel === 'string'
|
|
341
342
|
? input.event.payload.stageLabel
|
|
342
343
|
: undefined;
|
|
344
|
+
const nextWorkflowLabel = typeof input.event.payload.workflowLabel === 'string'
|
|
345
|
+
? input.event.payload.workflowLabel
|
|
346
|
+
: undefined;
|
|
343
347
|
const nextLabels = [
|
|
344
|
-
...currentLabels.filter((label) => !label.startsWith(wakeStatusLabelPrefix) &&
|
|
348
|
+
...currentLabels.filter((label) => !label.startsWith(wakeStatusLabelPrefix) &&
|
|
349
|
+
!label.startsWith(wakeStageLabelPrefix) &&
|
|
350
|
+
!label.startsWith(wakeWorkflowLabelPrefix)),
|
|
345
351
|
...(nextStatusLabel !== undefined
|
|
346
352
|
? [nextStatusLabel]
|
|
347
353
|
: currentLabels.filter((label) => label.startsWith(wakeStatusLabelPrefix))),
|
|
348
354
|
...(nextStageLabel !== undefined
|
|
349
355
|
? [nextStageLabel]
|
|
350
356
|
: currentLabels.filter((label) => label.startsWith(wakeStageLabelPrefix))),
|
|
357
|
+
...(nextWorkflowLabel !== undefined
|
|
358
|
+
? [nextWorkflowLabel]
|
|
359
|
+
: currentLabels.filter((label) => label.startsWith(wakeWorkflowLabelPrefix))),
|
|
351
360
|
];
|
|
352
361
|
const labelsChanged = nextLabels.length !== currentLabels.length ||
|
|
353
362
|
!nextLabels.every((label, index) => label === currentLabels[index]);
|
|
@@ -372,6 +381,7 @@ export function createGitHubIssuesWorkSource(deps) {
|
|
|
372
381
|
intentEventId: input.event.eventId,
|
|
373
382
|
...(nextStatusLabel !== undefined ? { statusLabel: nextStatusLabel } : {}),
|
|
374
383
|
...(nextStageLabel !== undefined ? { stageLabel: nextStageLabel } : {}),
|
|
384
|
+
...(nextWorkflowLabel !== undefined ? { workflowLabel: nextWorkflowLabel } : {}),
|
|
375
385
|
labels: nextLabels,
|
|
376
386
|
providerEventType: 'github.issue.labels.updated',
|
|
377
387
|
},
|
|
@@ -9,7 +9,7 @@ import { createWorkId } from '../lib/work-id.js';
|
|
|
9
9
|
import { CORRELATION_REGISTERED_EVENT, UNRESOLVED_WORK_ITEM_KEY, WORK_ITEM_CREATED_EVENT, parseRunnerArtifacts, parseRunnerResult, } from '../domain/schema.js';
|
|
10
10
|
import { maxConfiguredRunnerTimeoutMs, resolveRunnerRouting } from '../domain/runner-routing.js';
|
|
11
11
|
import { awaitingApprovalRunnerSentinel, stageLabelForStage } from '../domain/stages.js';
|
|
12
|
-
import { chooseAction as chooseWorkflowAction, isKnownWorkflowStage, workflowChangedBlockReason, workflowForProjection, workflowNameForProjection, } from '../domain/workflows.js';
|
|
12
|
+
import { chooseAction as chooseWorkflowAction, isKnownWorkflowStage, workflowChangedBlockReason, workflowForProjection, workflowLabelForWorkflowName, workflowNameForProjection, } from '../domain/workflows.js';
|
|
13
13
|
import { createEventEnvelope } from '../lib/event-log.js';
|
|
14
14
|
import { branchNameForIssue } from '../domain/branch-naming.js';
|
|
15
15
|
import { customCommandWorkspace, isCustomCommandAction } from '../domain/custom-commands.js';
|
|
@@ -227,7 +227,7 @@ export function createTickRunner(deps) {
|
|
|
227
227
|
}
|
|
228
228
|
function createLabelsEvent(input) {
|
|
229
229
|
return createEventEnvelope({
|
|
230
|
-
eventId: `${input.runId}-labels-${input.statusLabel.replace(/[^a-z0-9]+/gi, '-')}-${input.stageLabel.replace(/[^a-z0-9]+/gi, '-')}`,
|
|
230
|
+
eventId: `${input.runId}-labels-${input.statusLabel.replace(/[^a-z0-9]+/gi, '-')}-${input.stageLabel.replace(/[^a-z0-9]+/gi, '-')}-${input.workflowLabel.replace(/[^a-z0-9]+/gi, '-')}`,
|
|
231
231
|
workItemKey: input.projection.workItemKey,
|
|
232
232
|
streamScope: 'work-item',
|
|
233
233
|
direction: 'outbound',
|
|
@@ -244,6 +244,7 @@ export function createTickRunner(deps) {
|
|
|
244
244
|
payload: {
|
|
245
245
|
statusLabel: input.statusLabel,
|
|
246
246
|
stageLabel: input.stageLabel,
|
|
247
|
+
workflowLabel: input.workflowLabel,
|
|
247
248
|
origin: input.projection.origin ?? 'github',
|
|
248
249
|
},
|
|
249
250
|
});
|
|
@@ -340,8 +341,11 @@ export function createTickRunner(deps) {
|
|
|
340
341
|
for (const projection of projections) {
|
|
341
342
|
const statusLabel = statusLabelForStage(projection.wake.stage);
|
|
342
343
|
const stageLabel = stageLabelForStage(projection.wake.stage);
|
|
344
|
+
const workflowLabel = workflowLabelForWorkflowName(workflowNameForProjection(projection, deps.config));
|
|
343
345
|
if (!shouldMarkPending(projection) ||
|
|
344
|
-
(hasLabel(projection, statusLabel) &&
|
|
346
|
+
(hasLabel(projection, statusLabel) &&
|
|
347
|
+
hasLabel(projection, stageLabel) &&
|
|
348
|
+
hasLabel(projection, workflowLabel))) {
|
|
345
349
|
continue;
|
|
346
350
|
}
|
|
347
351
|
await deliverOutboundEvent(createLabelsEvent({
|
|
@@ -349,6 +353,7 @@ export function createTickRunner(deps) {
|
|
|
349
353
|
runId: `pending-${projection.workItemKey}-${deps.clock.now().getTime()}`,
|
|
350
354
|
statusLabel,
|
|
351
355
|
stageLabel,
|
|
356
|
+
workflowLabel,
|
|
352
357
|
occurredAt: eventStampNow(),
|
|
353
358
|
}));
|
|
354
359
|
}
|
|
@@ -732,6 +737,7 @@ export function createTickRunner(deps) {
|
|
|
732
737
|
runId: record.runId,
|
|
733
738
|
statusLabel: 'wake:status.failed',
|
|
734
739
|
stageLabel: stageLabelForStage(updatedProjection.wake.stage),
|
|
740
|
+
workflowLabel: workflowLabelForWorkflowName(workflowNameForProjection(updatedProjection, deps.config)),
|
|
735
741
|
occurredAt: finishedAt,
|
|
736
742
|
}));
|
|
737
743
|
}
|
|
@@ -779,6 +785,7 @@ export function createTickRunner(deps) {
|
|
|
779
785
|
runId: eventId,
|
|
780
786
|
statusLabel: 'wake:status.blocked',
|
|
781
787
|
stageLabel: stageLabelForStage(projection.wake.stage),
|
|
788
|
+
workflowLabel: workflowLabelForWorkflowName(workflowNameForProjection(projection, deps.config)),
|
|
782
789
|
occurredAt,
|
|
783
790
|
}));
|
|
784
791
|
parked = true;
|
|
@@ -1031,6 +1038,7 @@ export function createTickRunner(deps) {
|
|
|
1031
1038
|
runId: approvalId,
|
|
1032
1039
|
statusLabel: statusLabelForStage(nextStage),
|
|
1033
1040
|
stageLabel: stageLabelForStage(nextStage),
|
|
1041
|
+
workflowLabel: workflowLabelForWorkflowName(workflowName),
|
|
1034
1042
|
occurredAt: approvedAt,
|
|
1035
1043
|
}));
|
|
1036
1044
|
return {
|
|
@@ -1130,6 +1138,7 @@ export function createTickRunner(deps) {
|
|
|
1130
1138
|
runId,
|
|
1131
1139
|
statusLabel: 'wake:status.working',
|
|
1132
1140
|
stageLabel: stageLabelForStage(claimedStage),
|
|
1141
|
+
workflowLabel: workflowLabelForWorkflowName(workflowName),
|
|
1133
1142
|
occurredAt: eventStampNow(),
|
|
1134
1143
|
}));
|
|
1135
1144
|
try {
|
|
@@ -1288,6 +1297,7 @@ export function createTickRunner(deps) {
|
|
|
1288
1297
|
stage: nextStage ?? claimedStage,
|
|
1289
1298
|
}),
|
|
1290
1299
|
stageLabel: stageLabelForStage(nextStage ?? claimedStage),
|
|
1300
|
+
workflowLabel: workflowLabelForWorkflowName(workflowName),
|
|
1291
1301
|
occurredAt: finishedAt,
|
|
1292
1302
|
}));
|
|
1293
1303
|
if (runnerResult.failureClass !== 'quota') {
|
|
@@ -1358,6 +1368,7 @@ export function createTickRunner(deps) {
|
|
|
1358
1368
|
runId,
|
|
1359
1369
|
statusLabel: 'wake:status.failed',
|
|
1360
1370
|
stageLabel: stageLabelForStage(claimedStage),
|
|
1371
|
+
workflowLabel: workflowLabelForWorkflowName(workflowName),
|
|
1361
1372
|
occurredAt: finishedAt,
|
|
1362
1373
|
}));
|
|
1363
1374
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
@@ -2,6 +2,7 @@ import { stageLabelForStage } from './stages.js';
|
|
|
2
2
|
export const universalQueueStage = 'queue';
|
|
3
3
|
export const universalDoneStage = 'done';
|
|
4
4
|
export const workflowChangedBlockReason = 'workflow-changed';
|
|
5
|
+
export const wakeWorkflowLabelPrefix = 'wake:workflow.';
|
|
5
6
|
export const builtInDefaultWorkflowDefinition = {
|
|
6
7
|
stages: {
|
|
7
8
|
refine: {
|
|
@@ -45,6 +46,9 @@ export function workflowStageVocabulary(workflow) {
|
|
|
45
46
|
export function stageLabelsForWorkflow(workflow) {
|
|
46
47
|
return workflowStageVocabulary(workflow).map((stage) => stageLabelForStage(stage));
|
|
47
48
|
}
|
|
49
|
+
export function workflowLabelForWorkflowName(workflowName) {
|
|
50
|
+
return `${wakeWorkflowLabelPrefix}${workflowName}`;
|
|
51
|
+
}
|
|
48
52
|
export function isKnownWorkflowStage(stage, workflow) {
|
|
49
53
|
return workflowStageVocabulary(workflow).includes(stage);
|
|
50
54
|
}
|
package/dist/src/main.js
CHANGED
|
@@ -52,6 +52,18 @@ function routesOnlyToFake(config) {
|
|
|
52
52
|
return first !== undefined && config.runners[first]?.kind === 'fake';
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
|
+
async function resolveSelfLogin(githubClient) {
|
|
56
|
+
if (githubClient === undefined) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
return await githubClient.getAuthenticatedLogin();
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error(`wake: failed to resolve authenticated GitHub login; continuing without self-login bot detection: ${String(error)}`);
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
55
67
|
export function formatTickFailureDetails(runRecord) {
|
|
56
68
|
if (runRecord === null) {
|
|
57
69
|
return null;
|
|
@@ -180,7 +192,7 @@ export async function buildRuntime(args) {
|
|
|
180
192
|
// by direct API/CLI call (not through formatWakeComment, so it never
|
|
181
193
|
// carries the wake:agent marker) as bot-authored instead of a fresh human
|
|
182
194
|
// reply that would re-trigger another run against itself.
|
|
183
|
-
const selfLogin =
|
|
195
|
+
const selfLogin = await resolveSelfLogin(githubClient);
|
|
184
196
|
const artifactVerifier = prTrackingEnabled && githubClient !== undefined
|
|
185
197
|
? createGitHubArtifactVerifier({ client: githubClient })
|
|
186
198
|
: undefined;
|
package/dist/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const wakeVersion = "0.1.
|
|
1
|
+
export const wakeVersion = "0.1.11+gbbbf616";
|
package/docker/entrypoint.sh
CHANGED
|
@@ -44,6 +44,25 @@ req.setTimeout(1000, () => req.destroy());
|
|
|
44
44
|
echo "wake ui: ngrok tunnel started but public URL was not discovered; see /wake/logs/ngrok.log"
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
supervise_wake_start() {
|
|
48
|
+
local restart_delay="${WAKE_START_RESTART_DELAY_SECONDS:-10}"
|
|
49
|
+
|
|
50
|
+
while true; do
|
|
51
|
+
echo "wake start: starting resident loop"
|
|
52
|
+
node /app/dist/src/main.js start \
|
|
53
|
+
--wake-root /wake \
|
|
54
|
+
>> /wake/logs/start.log 2>&1 &
|
|
55
|
+
|
|
56
|
+
local child_pid="$!"
|
|
57
|
+
echo "${child_pid}" > /wake/logs/start.pid
|
|
58
|
+
|
|
59
|
+
wait "${child_pid}"
|
|
60
|
+
local exit_code="$?"
|
|
61
|
+
echo "wake start: resident loop exited with status ${exit_code}; restarting in ${restart_delay}s"
|
|
62
|
+
sleep "${restart_delay}"
|
|
63
|
+
done
|
|
64
|
+
}
|
|
65
|
+
|
|
47
66
|
if [ "${WAKE_UI_ENABLED:-false}" = "true" ]; then
|
|
48
67
|
echo "wake ui: starting on 0.0.0.0:${WAKE_UI_PORT:-4317}"
|
|
49
68
|
node /app/dist/src/main.js ui \
|
|
@@ -65,11 +84,7 @@ if [ "${WAKE_UI_ENABLED:-false}" = "true" ]; then
|
|
|
65
84
|
fi
|
|
66
85
|
|
|
67
86
|
if [ "${WAKE_START_ENABLED:-false}" = "true" ]; then
|
|
68
|
-
|
|
69
|
-
node /app/dist/src/main.js start \
|
|
70
|
-
--wake-root /wake \
|
|
71
|
-
>> /wake/logs/start.log 2>&1 &
|
|
72
|
-
echo "$!" > /wake/logs/start.pid
|
|
87
|
+
supervise_wake_start &
|
|
73
88
|
fi
|
|
74
89
|
|
|
75
90
|
exec sleep infinity
|