@atolis-hq/wake 0.1.7 → 0.1.8
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/core/policy-engine.js +3 -9
- package/dist/src/core/projection-updater.js +8 -4
- package/dist/src/core/tick-runner.js +21 -14
- package/dist/src/domain/custom-commands.js +58 -0
- package/dist/src/domain/runner-routing.js +28 -4
- package/dist/src/domain/schema.js +28 -0
- package/dist/src/version.js +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { awaitingApprovalRunnerSentinel, failedRunnerSentinel } from '../domain/stages.js';
|
|
2
|
+
import { resolveCustomCommand } from '../domain/custom-commands.js';
|
|
2
3
|
import { builtInDefaultWorkflowDefinition, chooseAction as chooseWorkflowAction, } from '../domain/workflows.js';
|
|
3
4
|
function isAwaitingApproval(issue) {
|
|
4
5
|
const context = issue.context;
|
|
@@ -10,12 +11,10 @@ function isAwaitingApproval(issue) {
|
|
|
10
11
|
const approvedCommandPattern = /^\/approved\b/i;
|
|
11
12
|
const changesCommandPattern = /^\/changes\b/i;
|
|
12
13
|
const questionCommandPattern = /^\/question\b/i;
|
|
13
|
-
const codeReviewCommandPattern = /^\/codereview\b/i;
|
|
14
14
|
// The action Wake runs when a correlated PR gets new reviewer feedback while
|
|
15
15
|
// the work item is awaiting approval. Not configurable per workflow: it's a
|
|
16
16
|
// lateral response to a PR surface, not a workflow stage.
|
|
17
17
|
const reviewFeedbackAction = 'revise';
|
|
18
|
-
const codeReviewAction = 'codereview';
|
|
19
18
|
function matchesCommand(body, pattern) {
|
|
20
19
|
return body.split(/\r?\n/).some((line) => pattern.test(line.trim()));
|
|
21
20
|
}
|
|
@@ -173,13 +172,8 @@ export function createPolicyEngine() {
|
|
|
173
172
|
}
|
|
174
173
|
return reviewFeedbackAction;
|
|
175
174
|
},
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (latestHumanComment === undefined ||
|
|
179
|
-
!matchesCommand(latestHumanComment.body, codeReviewCommandPattern)) {
|
|
180
|
-
return null;
|
|
181
|
-
}
|
|
182
|
-
return codeReviewAction;
|
|
175
|
+
resolveCustomCommandRequest(issue, config) {
|
|
176
|
+
return resolveCustomCommand(issue, config);
|
|
183
177
|
},
|
|
184
178
|
qualifiesForMint(unresolved, config) {
|
|
185
179
|
const resourceUri = unresolved.sourceRefs.resourceUri;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CORRELATION_PRIMARY_CONFLICT_EVENT, CORRELATION_REGISTERED_EVENT, CORRELATION_RETRACTED_EVENT, UNRESOLVED_WORK_ITEM_KEY, parseIssueStateRecord, } from '../domain/schema.js';
|
|
2
2
|
import { doneRunnerSentinel, stageFromLabels } from '../domain/stages.js';
|
|
3
3
|
import { builtInDefaultWorkflowDefinition, defaultWorkflowName, workflowStageVocabulary, } from '../domain/workflows.js';
|
|
4
|
+
import { isCustomCommandAction } from '../domain/custom-commands.js';
|
|
4
5
|
import { createEventEnvelope } from '../lib/event-log.js';
|
|
5
6
|
function stringArrayFromPayload(value) {
|
|
6
7
|
return Array.isArray(value)
|
|
@@ -150,7 +151,10 @@ async function applyEvent(current, event, ctx, config) {
|
|
|
150
151
|
const isForwardProgression = payload.nextStage !== undefined && payload.nextStage !== current.wake.stage;
|
|
151
152
|
const stageChanged = payload.nextStage !== undefined && payload.nextStage !== current.wake.stage;
|
|
152
153
|
const isFailed = payload.sentinel === 'FAILED';
|
|
153
|
-
const
|
|
154
|
+
const isCompletedCustomCommand = payload.action !== undefined &&
|
|
155
|
+
payload.sentinel === doneRunnerSentinel &&
|
|
156
|
+
config !== undefined &&
|
|
157
|
+
isCustomCommandAction(payload.action, config);
|
|
154
158
|
const shouldClearSession = isForwardProgression || isFailed;
|
|
155
159
|
return parseIssueStateRecord({
|
|
156
160
|
...current,
|
|
@@ -160,15 +164,15 @@ async function applyEvent(current, event, ctx, config) {
|
|
|
160
164
|
...(payload.handledCommentId === undefined
|
|
161
165
|
? {}
|
|
162
166
|
: { lastHandledCommentId: payload.handledCommentId }),
|
|
163
|
-
...(payload.sentinel === undefined ||
|
|
167
|
+
...(payload.sentinel === undefined || isCompletedCustomCommand
|
|
164
168
|
? {}
|
|
165
169
|
: { lastRunSentinel: payload.sentinel }),
|
|
166
|
-
...(payload.action === undefined ||
|
|
170
|
+
...(payload.action === undefined || isCompletedCustomCommand
|
|
167
171
|
? {}
|
|
168
172
|
: { lastRunAction: payload.action }),
|
|
169
173
|
...(payload.sentinel === doneRunnerSentinel &&
|
|
170
174
|
payload.action !== undefined &&
|
|
171
|
-
!
|
|
175
|
+
!isCompletedCustomCommand
|
|
172
176
|
? { lastCompletedAction: payload.action }
|
|
173
177
|
: {}),
|
|
174
178
|
// Remembered so the approval path knows which action to resume or
|
|
@@ -12,6 +12,7 @@ import { awaitingApprovalRunnerSentinel, stageLabelForStage } from '../domain/st
|
|
|
12
12
|
import { chooseAction as chooseWorkflowAction, isKnownWorkflowStage, workflowChangedBlockReason, workflowForProjection, workflowNameForProjection, } from '../domain/workflows.js';
|
|
13
13
|
import { createEventEnvelope } from '../lib/event-log.js';
|
|
14
14
|
import { branchNameForIssue } from '../domain/branch-naming.js';
|
|
15
|
+
import { customCommandWorkspace, isCustomCommandAction } from '../domain/custom-commands.js';
|
|
15
16
|
import { resolveQuotaPauseUntil } from './quota-backoff.js';
|
|
16
17
|
function latestHumanCommentId(candidate) {
|
|
17
18
|
const human = candidate.comments.filter((c) => !c.isBotAuthored);
|
|
@@ -36,8 +37,11 @@ function latestHumanCommentId(candidate) {
|
|
|
36
37
|
function isReviewThreadResourceUri(resourceUri) {
|
|
37
38
|
return resourceUri.split(':')[1] === 'pr-review-thread';
|
|
38
39
|
}
|
|
39
|
-
function isLateralReadOnlyAction(action) {
|
|
40
|
-
return action
|
|
40
|
+
function isLateralReadOnlyAction(action, config) {
|
|
41
|
+
return isCustomCommandAction(action, config);
|
|
42
|
+
}
|
|
43
|
+
function workspaceModeForCustomCommand(action, config) {
|
|
44
|
+
return customCommandWorkspace(action, config);
|
|
41
45
|
}
|
|
42
46
|
function isFreshTriggeringComment(candidate) {
|
|
43
47
|
const context = candidate.context;
|
|
@@ -212,11 +216,11 @@ export function createTickRunner(deps) {
|
|
|
212
216
|
return false;
|
|
213
217
|
}
|
|
214
218
|
if (isAwaitingApproval(projection)) {
|
|
215
|
-
return (policy.
|
|
219
|
+
return (policy.resolveCustomCommandRequest(projection, deps.config) !== null ||
|
|
216
220
|
policy.resolveApprovalTransition(projection) !== null ||
|
|
217
221
|
policy.resolvePendingReviewFeedback(projection) !== null);
|
|
218
222
|
}
|
|
219
|
-
const nextAction = policy.
|
|
223
|
+
const nextAction = policy.resolveCustomCommandRequest(projection, deps.config)?.action ??
|
|
220
224
|
policy.chooseAction(projection, workflow) ??
|
|
221
225
|
policy.chooseRetryActionAfterHumanReply(projection);
|
|
222
226
|
return nextAction !== null && policy.needsWakeAction(projection, workflow);
|
|
@@ -952,7 +956,7 @@ export function createTickRunner(deps) {
|
|
|
952
956
|
if (isAwaitingApproval(issue)) {
|
|
953
957
|
return policy.needsWakeAction(issue, workflow);
|
|
954
958
|
}
|
|
955
|
-
const nextAction = policy.
|
|
959
|
+
const nextAction = policy.resolveCustomCommandRequest(issue, deps.config)?.action ??
|
|
956
960
|
policy.chooseAction(issue, workflow) ??
|
|
957
961
|
policy.chooseRetryActionAfterHumanReply(issue);
|
|
958
962
|
return nextAction !== null && policy.needsWakeAction(issue, workflow);
|
|
@@ -966,14 +970,16 @@ export function createTickRunner(deps) {
|
|
|
966
970
|
}
|
|
967
971
|
const workflowName = workflowNameForProjection(candidate, deps.config);
|
|
968
972
|
let action;
|
|
973
|
+
let command;
|
|
969
974
|
let claimedStage = candidate.wake.stage;
|
|
970
975
|
let workspaceMode = 'none';
|
|
971
976
|
if (isAwaitingApproval(candidate)) {
|
|
972
|
-
const
|
|
973
|
-
if (
|
|
974
|
-
action =
|
|
977
|
+
const customCommandRequest = policy.resolveCustomCommandRequest(candidate, deps.config);
|
|
978
|
+
if (customCommandRequest !== null) {
|
|
979
|
+
action = customCommandRequest.action;
|
|
980
|
+
command = customCommandRequest.command;
|
|
975
981
|
claimedStage = candidate.wake.stage;
|
|
976
|
-
workspaceMode =
|
|
982
|
+
workspaceMode = customCommandRequest.workspace;
|
|
977
983
|
}
|
|
978
984
|
else {
|
|
979
985
|
const approvalResolution = policy.resolveApprovalTransition(candidate);
|
|
@@ -1054,7 +1060,7 @@ export function createTickRunner(deps) {
|
|
|
1054
1060
|
// scratch (#258 follow-up incident: a FAILED `revise` run fell
|
|
1055
1061
|
// back to a full fresh `implement` run and lost the PR-feedback
|
|
1056
1062
|
// context).
|
|
1057
|
-
const nextAction = policy.
|
|
1063
|
+
const nextAction = policy.resolveCustomCommandRequest(candidate, deps.config)?.action ??
|
|
1058
1064
|
policy.chooseRetryActionAfterHumanReply(candidate) ??
|
|
1059
1065
|
workflowAction?.action ??
|
|
1060
1066
|
null;
|
|
@@ -1062,10 +1068,10 @@ export function createTickRunner(deps) {
|
|
|
1062
1068
|
return { status: 'idle' };
|
|
1063
1069
|
}
|
|
1064
1070
|
action = nextAction;
|
|
1071
|
+
command = policy.resolveCustomCommandRequest(candidate, deps.config)?.command;
|
|
1065
1072
|
claimedStage = workflowAction?.stage ?? candidate.wake.stage;
|
|
1066
|
-
workspaceMode =
|
|
1067
|
-
|
|
1068
|
-
: (workflowAction?.workspace ?? 'none');
|
|
1073
|
+
workspaceMode =
|
|
1074
|
+
workspaceModeForCustomCommand(action, deps.config) ?? workflowAction?.workspace ?? 'none';
|
|
1069
1075
|
}
|
|
1070
1076
|
// Resolve routing (with sideways fallback across quota-paused runners,
|
|
1071
1077
|
// #67) before claiming a run, so a fully-paused tier costs nothing more
|
|
@@ -1076,6 +1082,7 @@ export function createTickRunner(deps) {
|
|
|
1076
1082
|
stage: claimedStage,
|
|
1077
1083
|
action,
|
|
1078
1084
|
workflowName,
|
|
1085
|
+
...(command === undefined ? {} : { command }),
|
|
1079
1086
|
now: tickStartedAt,
|
|
1080
1087
|
...(ledgerAtStart === null ? {} : { ledger: ledgerAtStart }),
|
|
1081
1088
|
});
|
|
@@ -1162,7 +1169,7 @@ export function createTickRunner(deps) {
|
|
|
1162
1169
|
// the protocol; treat it as AWAITING_APPROVAL so the gate is enforced.
|
|
1163
1170
|
const skipApproval = runnerResult.metadata?.skipApproval;
|
|
1164
1171
|
const sentinel = rawSentinel === 'DONE' && skipApproval === false ? 'AWAITING_APPROVAL' : rawSentinel;
|
|
1165
|
-
const nextStage = isLateralReadOnlyAction(action) && sentinel === 'DONE'
|
|
1172
|
+
const nextStage = isLateralReadOnlyAction(action, deps.config) && sentinel === 'DONE'
|
|
1166
1173
|
? null
|
|
1167
1174
|
: lifecycle.nextStageFromSentinel(claimedStage, sentinel, workflow);
|
|
1168
1175
|
const finishedAt = deps.clock.now().toISOString();
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const reservedCommandNames = ['approved', 'changes', 'question'];
|
|
2
|
+
function latestUnhandledHumanComment(issue) {
|
|
3
|
+
const context = issue.context;
|
|
4
|
+
const handledCommentId = typeof context.lastHandledCommentId === 'string' ? context.lastHandledCommentId : undefined;
|
|
5
|
+
const lastBotIndex = issue.comments.reduce((acc, c, i) => (c.isBotAuthored ? i : acc), -1);
|
|
6
|
+
const humanCommentsAfterBot = issue.comments
|
|
7
|
+
.slice(lastBotIndex + 1)
|
|
8
|
+
.filter((c) => !c.isBotAuthored);
|
|
9
|
+
const latestHumanComment = humanCommentsAfterBot.at(-1);
|
|
10
|
+
if (latestHumanComment === undefined || latestHumanComment.id === handledCommentId) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
return latestHumanComment;
|
|
14
|
+
}
|
|
15
|
+
function commandNameFromBody(body) {
|
|
16
|
+
for (const line of body.split(/\r?\n/)) {
|
|
17
|
+
const match = /^\/([A-Za-z0-9_.-]+)\b/.exec(line.trim());
|
|
18
|
+
if (match?.[1] !== undefined) {
|
|
19
|
+
return match[1].toLowerCase();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
export function customCommandAction(command, config) {
|
|
25
|
+
const entry = Object.entries(config.commands).find(([name]) => name.toLowerCase() === command.toLowerCase());
|
|
26
|
+
if (entry === undefined) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
const [name, definition] = entry;
|
|
30
|
+
return definition.action ?? name;
|
|
31
|
+
}
|
|
32
|
+
export function isCustomCommandAction(action, config) {
|
|
33
|
+
return Object.entries(config.commands).some(([name, definition]) => (definition.action ?? name) === action);
|
|
34
|
+
}
|
|
35
|
+
export function customCommandWorkspace(action, config) {
|
|
36
|
+
return Object.entries(config.commands).find(([name, definition]) => (definition.action ?? name) === action)?.[1].workspace;
|
|
37
|
+
}
|
|
38
|
+
export function resolveCustomCommand(issue, config) {
|
|
39
|
+
const latestHumanComment = latestUnhandledHumanComment(issue);
|
|
40
|
+
if (latestHumanComment === undefined) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const command = commandNameFromBody(latestHumanComment.body);
|
|
44
|
+
if (command === null) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const definitionEntry = Object.entries(config.commands).find(([name]) => name.toLowerCase() === command);
|
|
48
|
+
if (definitionEntry === undefined) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const [configuredName, definition] = definitionEntry;
|
|
52
|
+
return {
|
|
53
|
+
action: definition.action ?? configuredName,
|
|
54
|
+
command: configuredName,
|
|
55
|
+
comment: latestHumanComment,
|
|
56
|
+
workspace: definition.workspace,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -13,6 +13,11 @@ export function maxConfiguredRunnerTimeoutMs(config) {
|
|
|
13
13
|
activeRunnerNames.add(stageRoute.runner);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
+
for (const commandRoute of Object.values(config.commands)) {
|
|
17
|
+
if (commandRoute.runner !== undefined) {
|
|
18
|
+
activeRunnerNames.add(commandRoute.runner);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
16
21
|
const registryTimeouts = [...activeRunnerNames]
|
|
17
22
|
.map((name) => config.runners[name])
|
|
18
23
|
.map((entry) => (entry === undefined || entry.kind === 'fake' ? undefined : entry.timeoutMs))
|
|
@@ -57,6 +62,23 @@ export function resolveRunnerRouting(input) {
|
|
|
57
62
|
if (workflow === undefined) {
|
|
58
63
|
throw new Error(`Unknown workflow "${workflowName}".`);
|
|
59
64
|
}
|
|
65
|
+
const commandRouteEntry = input.command === undefined
|
|
66
|
+
? Object.entries(input.config.commands).find(([name, route]) => (route.action ?? name) === input.action)
|
|
67
|
+
: Object.entries(input.config.commands).find(([name]) => name.toLowerCase() === input.command?.toLowerCase());
|
|
68
|
+
const commandRoute = commandRouteEntry?.[1];
|
|
69
|
+
if (commandRoute?.runner !== undefined) {
|
|
70
|
+
const runnerName = commandRoute.runner;
|
|
71
|
+
const entry = input.config.runners[runnerName];
|
|
72
|
+
if (entry === undefined) {
|
|
73
|
+
throw new Error(`Command ${input.action} pins unknown runner "${runnerName}".`);
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
runnerName,
|
|
77
|
+
runnerKind: entry.kind,
|
|
78
|
+
...(commandRoute.tier === undefined ? {} : { tier: commandRoute.tier }),
|
|
79
|
+
reason: `command ${input.action} pins runner ${runnerName}`,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
60
82
|
const stageRoute = workflow.stages[input.stage];
|
|
61
83
|
if (stageRoute?.runner !== undefined) {
|
|
62
84
|
const entry = input.config.runners[stageRoute.runner];
|
|
@@ -70,7 +92,7 @@ export function resolveRunnerRouting(input) {
|
|
|
70
92
|
reason: `stage ${input.stage} pins runner ${stageRoute.runner}`,
|
|
71
93
|
};
|
|
72
94
|
}
|
|
73
|
-
const tier = stageRoute?.tier ?? input.config.defaultTier;
|
|
95
|
+
const tier = commandRoute?.tier ?? stageRoute?.tier ?? input.config.defaultTier;
|
|
74
96
|
const candidates = input.config.tiers[tier];
|
|
75
97
|
if (candidates === undefined || candidates.length === 0) {
|
|
76
98
|
throw new Error(`Stage ${input.stage} routes to unknown or empty tier "${tier}".`);
|
|
@@ -101,8 +123,10 @@ export function resolveRunnerRouting(input) {
|
|
|
101
123
|
? `tier ${tier} recovery probe on ${runnerName} (estimated pause not yet elapsed)`
|
|
102
124
|
: isFallback
|
|
103
125
|
? `tier ${tier} fell back to ${runnerName} (higher-priority candidates paused)`
|
|
104
|
-
:
|
|
105
|
-
? `
|
|
106
|
-
:
|
|
126
|
+
: commandRoute?.tier !== undefined
|
|
127
|
+
? `command ${input.action} tier ${tier} selected runner ${runnerName}`
|
|
128
|
+
: stageRoute?.tier === undefined
|
|
129
|
+
? `defaultTier ${tier} selected runner ${runnerName}`
|
|
130
|
+
: `stage ${input.stage} tier ${tier} selected runner ${runnerName}`,
|
|
107
131
|
};
|
|
108
132
|
}
|
|
@@ -2,6 +2,7 @@ import { existsSync } from 'node:fs';
|
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
+
import { reservedCommandNames } from './custom-commands.js';
|
|
5
6
|
import { runnerSentinelValues } from './stages.js';
|
|
6
7
|
import { correlationProvenanceSchema, correlationRelationSchema, correlationRoleSchema, resourceUriSchema, } from './resource-uri.js';
|
|
7
8
|
const isoTimestampSchema = z.string().datetime({ offset: true });
|
|
@@ -308,6 +309,9 @@ const workflowStageSchema = stageRouteSchema.extend({
|
|
|
308
309
|
workspace: workflowWorkspaceSchema,
|
|
309
310
|
onDone: identifierSchema,
|
|
310
311
|
});
|
|
312
|
+
const customCommandSchema = stageRouteSchema.extend({
|
|
313
|
+
workspace: workflowWorkspaceSchema.default('read-only'),
|
|
314
|
+
});
|
|
311
315
|
const workflowDefinitionSchema = z.object({
|
|
312
316
|
entryStage: identifierSchema.optional(),
|
|
313
317
|
stages: z.record(identifierSchema, workflowStageSchema),
|
|
@@ -511,6 +515,13 @@ export const wakeConfigSchema = z
|
|
|
511
515
|
},
|
|
512
516
|
},
|
|
513
517
|
}),
|
|
518
|
+
commands: z.record(identifierSchema, customCommandSchema).default({
|
|
519
|
+
codereview: {
|
|
520
|
+
action: 'codereview',
|
|
521
|
+
workspace: 'read-only',
|
|
522
|
+
tier: 'standard',
|
|
523
|
+
},
|
|
524
|
+
}),
|
|
514
525
|
stages: z.record(z.string(), stageRouteSchema).default({
|
|
515
526
|
queue: { action: 'refine', tier: 'light' },
|
|
516
527
|
implement: { action: 'implement', tier: 'standard' },
|
|
@@ -615,6 +626,7 @@ export const wakeConfigSchema = z
|
|
|
615
626
|
.superRefine((config, ctx) => {
|
|
616
627
|
const promptsRoot = config.paths.promptsRoot ?? defaultPromptsRoot();
|
|
617
628
|
const workflowEntries = Object.entries(config.workflows);
|
|
629
|
+
const commandEntries = Object.entries(config.commands);
|
|
618
630
|
if (workflowEntries.length === 0) {
|
|
619
631
|
ctx.addIssue({
|
|
620
632
|
code: z.ZodIssueCode.custom,
|
|
@@ -690,6 +702,22 @@ export const wakeConfigSchema = z
|
|
|
690
702
|
});
|
|
691
703
|
}
|
|
692
704
|
}
|
|
705
|
+
for (const [commandName, command] of commandEntries) {
|
|
706
|
+
if (reservedCommandNames.includes(commandName.toLowerCase())) {
|
|
707
|
+
ctx.addIssue({
|
|
708
|
+
code: z.ZodIssueCode.custom,
|
|
709
|
+
path: ['commands', commandName],
|
|
710
|
+
message: `Command "/${commandName}" is reserved for Wake approval control.`,
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
if (command.action === undefined && !promptExists(promptsRoot, commandName)) {
|
|
714
|
+
ctx.addIssue({
|
|
715
|
+
code: z.ZodIssueCode.custom,
|
|
716
|
+
path: ['commands', commandName, 'action'],
|
|
717
|
+
message: `Command "/${commandName}" omits action but no prompts/${commandName}.md template exists.`,
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
}
|
|
693
721
|
});
|
|
694
722
|
export const claudePrintResultSchema = z
|
|
695
723
|
.object({
|
package/dist/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const wakeVersion = "0.1.
|
|
1
|
+
export const wakeVersion = "0.1.8+g8f32cc9";
|