halfcycle 0.5.2 → 0.6.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/.claude-plugin/plugin.json +1 -1
- package/bin/bin.bundle.mjs +299 -4
- package/dist/check-report.d.ts +57 -0
- package/dist/check-report.d.ts.map +1 -0
- package/dist/check-tasks.d.ts +94 -4
- package/dist/check-tasks.d.ts.map +1 -1
- package/dist/cli-contract.d.ts +1 -1
- package/dist/cli-contract.d.ts.map +1 -1
- package/dist/cli.js +1083 -161
- package/dist/cli.js.map +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +178 -49
- package/dist/index.js.map +3 -3
- package/dist/ready.d.ts +103 -0
- package/dist/ready.d.ts.map +1 -0
- package/dist/review.d.ts +3 -3
- package/dist/review.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "halfcycle",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Halfcycle Method bundle — resolution-stub slash commands, remote method-delivery registration, and governance-hook wiring for a Halfcycle engagement repo. It ships NO worker role files: a project's roles are authored from that project's own recorded decisions at orchestration kickoff (FX-2, W3-F-27).",
|
|
5
5
|
"commands": [
|
|
6
6
|
{
|
package/bin/bin.bundle.mjs
CHANGED
|
@@ -15053,6 +15053,8 @@ var HOOK_REMEDY = `Run ${SIGN_IN_COMMAND} in the project folder to sign in.`;
|
|
|
15053
15053
|
var TASK_PLAN_TASKS_MAX = 500;
|
|
15054
15054
|
var TASK_PLAN_ID_MAX = 64;
|
|
15055
15055
|
var TASK_PLAN_BUILDS_NONE = "none";
|
|
15056
|
+
var TASK_PLAN_CRITERIA_NONE = "none";
|
|
15057
|
+
var TASK_PLAN_SPECS_NONE = "none";
|
|
15056
15058
|
var TASK_PLAN_KINDS = ["build", "review", "spec", "walk", "check"];
|
|
15057
15059
|
var CONTROL_CHARACTER = /[\u0000-\u001f\u007f-\u009f]/;
|
|
15058
15060
|
var planText = external_exports.string().refine((text) => !CONTROL_CHARACTER.test(text), { message: "holds a control character" });
|
|
@@ -15069,7 +15071,9 @@ var taskPlanTaskSchema = external_exports.object({
|
|
|
15069
15071
|
}).strict().optional(),
|
|
15070
15072
|
wholeProject: external_exports.literal(true).optional(),
|
|
15071
15073
|
ships: external_exports.enum(["deploy", "release"]).optional(),
|
|
15072
|
-
builds: external_exports.union([external_exports.literal(TASK_PLAN_BUILDS_NONE), external_exports.array(planText)]).optional()
|
|
15074
|
+
builds: external_exports.union([external_exports.literal(TASK_PLAN_BUILDS_NONE), external_exports.array(planText)]).optional(),
|
|
15075
|
+
criteria: external_exports.union([external_exports.literal(TASK_PLAN_CRITERIA_NONE), external_exports.array(planText)]).optional(),
|
|
15076
|
+
whyOutsidePlan: planText.optional()
|
|
15073
15077
|
}).strict().superRefine((task, ctx) => {
|
|
15074
15078
|
if (task.reviews !== void 0 && task.kind !== "review") {
|
|
15075
15079
|
ctx.addIssue({
|
|
@@ -15095,6 +15099,7 @@ var taskPlanTaskSchema = external_exports.object({
|
|
|
15095
15099
|
});
|
|
15096
15100
|
var taskPlanSchema = external_exports.object({
|
|
15097
15101
|
phase: external_exports.string().min(1).refine((text) => !CONTROL_CHARACTER.test(text), { message: "holds a control character" }),
|
|
15102
|
+
specs: external_exports.union([external_exports.literal(TASK_PLAN_SPECS_NONE), external_exports.array(planText)]).optional(),
|
|
15098
15103
|
tasks: external_exports.array(taskPlanTaskSchema).max(TASK_PLAN_TASKS_MAX)
|
|
15099
15104
|
}).strict();
|
|
15100
15105
|
var taskListRowSchema = external_exports.object({
|
|
@@ -15203,6 +15208,37 @@ var AGENT_PROFILES = {
|
|
|
15203
15208
|
};
|
|
15204
15209
|
var ALL_HOOK_COMMANDS = new Set(AGENT_IDS.flatMap((id) => [...AGENT_PROFILES[id].commands]));
|
|
15205
15210
|
|
|
15211
|
+
// ../core/dist/worker-report.js
|
|
15212
|
+
var WORKER_REPORT_STATUSES = Object.freeze([
|
|
15213
|
+
"done",
|
|
15214
|
+
"needs-human-verification",
|
|
15215
|
+
"blocked-on-human",
|
|
15216
|
+
"failed"
|
|
15217
|
+
]);
|
|
15218
|
+
var WORKER_REPORT_RULE_FIELDS = Object.freeze({
|
|
15219
|
+
W1: "Worker report",
|
|
15220
|
+
W2: "Status",
|
|
15221
|
+
W3: "Head",
|
|
15222
|
+
W4: "Head",
|
|
15223
|
+
W5: "Verification",
|
|
15224
|
+
W6: "Verification",
|
|
15225
|
+
W7: "Verification",
|
|
15226
|
+
W8: "Unverified"
|
|
15227
|
+
});
|
|
15228
|
+
var WORKER_REPORT_LINES = Object.freeze({
|
|
15229
|
+
noBlock: () => 'There is no "## Worker report" block in this report.',
|
|
15230
|
+
statusMissing: (statuses) => `The report has no Status line. Use one of: ${statuses.join(", ")}.`,
|
|
15231
|
+
statusUnknown: (found2, statuses) => `The report's Status is "${found2}". Use one of: ${statuses.join(", ")}.`,
|
|
15232
|
+
headMissing: () => "The report has no Head line. Give the full commit id the report is about.",
|
|
15233
|
+
headMalformed: (found2) => `The report's Head is "${found2}", which is not a full commit id.`,
|
|
15234
|
+
headDiffers: (found2, head) => `The report is about commit ${found2}, but the work's head is ${head}. Ask for a report on the current head.`,
|
|
15235
|
+
noVerification: () => "The report does not say what was run. List each check under Verification with its exit code.",
|
|
15236
|
+
noExitCode: (entry) => `"${entry}" under Verification does not give an exit code.`,
|
|
15237
|
+
nonZeroOnDone: (entry) => `"${entry}" exited with a code other than 0, so the work is not done.`,
|
|
15238
|
+
noUnverified: () => 'The report has no Unverified line. Say what was not checked, or "nothing".',
|
|
15239
|
+
clear: () => "The report is complete and names the commit it is about."
|
|
15240
|
+
});
|
|
15241
|
+
|
|
15206
15242
|
// dist/control-origin.js
|
|
15207
15243
|
var DEFAULT_CONTROL_ORIGIN = "https://control.halfcycle.ai";
|
|
15208
15244
|
function resolveControlOrigin(env) {
|
|
@@ -18103,6 +18139,30 @@ var phaseReviewViewSchema = external_exports.discriminatedUnion("state", [
|
|
|
18103
18139
|
phaseReviewOpenSchema,
|
|
18104
18140
|
phaseReviewClosedSchema
|
|
18105
18141
|
]);
|
|
18142
|
+
function reviewPartAwaitingAnswer(part) {
|
|
18143
|
+
return part.questions.some((q) => q.agentAnswer === void 0);
|
|
18144
|
+
}
|
|
18145
|
+
function reviewPartSentBackIn(part, round) {
|
|
18146
|
+
return part.sentBack.some((s) => s.round === round);
|
|
18147
|
+
}
|
|
18148
|
+
function shownReviewEntryOf(view, shownAt) {
|
|
18149
|
+
const parts = view.parts.map((p) => ({
|
|
18150
|
+
part: p.part,
|
|
18151
|
+
name: p.name,
|
|
18152
|
+
built: p.built,
|
|
18153
|
+
decidable: p.decidable,
|
|
18154
|
+
awaitingAnswer: reviewPartAwaitingAnswer(p),
|
|
18155
|
+
sentBack: reviewPartSentBackIn(p, view.round)
|
|
18156
|
+
}));
|
|
18157
|
+
return {
|
|
18158
|
+
phase: view.phase,
|
|
18159
|
+
number: view.number,
|
|
18160
|
+
round: view.round,
|
|
18161
|
+
reviewVersion: view.reviewVersion,
|
|
18162
|
+
shownAt,
|
|
18163
|
+
parts
|
|
18164
|
+
};
|
|
18165
|
+
}
|
|
18106
18166
|
|
|
18107
18167
|
// ../events/dist/client-version.js
|
|
18108
18168
|
var CLIENT_VERSION_HEADER = "x-halfcycle-client";
|
|
@@ -18563,6 +18623,42 @@ var ownerWaitDeclarationSchema = external_exports.object({
|
|
|
18563
18623
|
var ownerWaitDeclarationsSchema = external_exports.object({ declarations: external_exports.array(ownerWaitDeclarationSchema) }).strict();
|
|
18564
18624
|
var OWNER_WAIT_TOO_MANY = `This project already has ${String(OWNER_WAIT_ADDITIONS_MAX)} things added to what waits for the owner. Ask the owner to take one off on their settings page in the console first; it cannot be done by typing in chat.`;
|
|
18565
18625
|
|
|
18626
|
+
// ../events/dist/owner-wait-answer.js
|
|
18627
|
+
var OWNER_WAIT_SHORT_ID_LENGTH = 8;
|
|
18628
|
+
var ownerWaitShortIdSchema = external_exports.string().regex(/^[0-9a-f]{8}$/);
|
|
18629
|
+
function ownerWaitShortIdOf(declarationId) {
|
|
18630
|
+
return declarationId.slice(0, OWNER_WAIT_SHORT_ID_LENGTH).toLowerCase();
|
|
18631
|
+
}
|
|
18632
|
+
var OWNER_WAIT_ANSWER_ACTS = ["approve", "decline"];
|
|
18633
|
+
var ownerWaitAnswerActSchema = external_exports.enum(OWNER_WAIT_ANSWER_ACTS);
|
|
18634
|
+
function ownerWaitApproveLineOf(declarationId) {
|
|
18635
|
+
return `approve wait ${ownerWaitShortIdOf(declarationId)}`;
|
|
18636
|
+
}
|
|
18637
|
+
function ownerWaitDeclineLineOf(declarationId) {
|
|
18638
|
+
return `decline wait ${ownerWaitShortIdOf(declarationId)}: <why>`;
|
|
18639
|
+
}
|
|
18640
|
+
var ownerWaitChatRequestSchema = external_exports.discriminatedUnion("act", [
|
|
18641
|
+
external_exports.object({ act: external_exports.literal("approve"), wait: ownerWaitShortIdSchema }).strict(),
|
|
18642
|
+
external_exports.object({ act: external_exports.literal("decline"), wait: ownerWaitShortIdSchema, note: scopeNoteWireSchema }).strict()
|
|
18643
|
+
]);
|
|
18644
|
+
function bareOutcome3(outcome) {
|
|
18645
|
+
return external_exports.object({ outcome: external_exports.literal(outcome) }).strict();
|
|
18646
|
+
}
|
|
18647
|
+
var ownerWaitChatResultSchema = external_exports.discriminatedUnion("outcome", [
|
|
18648
|
+
external_exports.object({
|
|
18649
|
+
outcome: external_exports.literal("recorded"),
|
|
18650
|
+
act: ownerWaitAnswerActSchema,
|
|
18651
|
+
question: external_exports.string().min(1)
|
|
18652
|
+
}).strict(),
|
|
18653
|
+
external_exports.object({ outcome: external_exports.literal("refused"), problems: external_exports.array(systemDescriptionProblemSchema).min(1) }).strict(),
|
|
18654
|
+
bareOutcome3("not-owner"),
|
|
18655
|
+
bareOutcome3("no-owner"),
|
|
18656
|
+
bareOutcome3("not-found"),
|
|
18657
|
+
bareOutcome3("ambiguous"),
|
|
18658
|
+
bareOutcome3("not-offered"),
|
|
18659
|
+
bareOutcome3("unavailable")
|
|
18660
|
+
]);
|
|
18661
|
+
|
|
18566
18662
|
// ../events/dist/pacing.js
|
|
18567
18663
|
var CLAUDE_PLANS = Object.freeze([
|
|
18568
18664
|
Object.freeze({ id: "pro", words: "Pro", startingAgents: 2 }),
|
|
@@ -18765,6 +18861,8 @@ var autonomyActivityRowSchema = external_exports.object({
|
|
|
18765
18861
|
// whether the agent says it can be undone
|
|
18766
18862
|
how: statementText(STATEMENT_MAX).optional(),
|
|
18767
18863
|
// how to undo it, when it can be
|
|
18864
|
+
wait: ownerWaitShortIdSchema.optional(),
|
|
18865
|
+
// the short id the owner types to answer a waiting decision
|
|
18768
18866
|
at: utcIso8601
|
|
18769
18867
|
// when it happened
|
|
18770
18868
|
}).strict().superRefine((row, ctx) => {
|
|
@@ -18791,6 +18889,9 @@ var autonomyActivityRowSchema = external_exports.object({
|
|
|
18791
18889
|
});
|
|
18792
18890
|
}
|
|
18793
18891
|
}
|
|
18892
|
+
if (row.kind !== "waiting" && row.wait !== void 0) {
|
|
18893
|
+
ctx.addIssue({ code: "custom", message: "only a waiting decision is answered by typing", path: ["wait"] });
|
|
18894
|
+
}
|
|
18794
18895
|
if (row.kind === "waiting" && (row.undoable !== void 0 || row.how !== void 0)) {
|
|
18795
18896
|
ctx.addIssue({ code: "custom", message: "a waiting decision has not been made yet", path: ["undoable"] });
|
|
18796
18897
|
}
|
|
@@ -31287,6 +31388,14 @@ function partShape(act, head, words) {
|
|
|
31287
31388
|
return null;
|
|
31288
31389
|
return { kind: "part", act, reference, part, words };
|
|
31289
31390
|
}
|
|
31391
|
+
function bulkAcceptTargetOf(reference, record2) {
|
|
31392
|
+
const phases = /* @__PURE__ */ new Map();
|
|
31393
|
+
for (const shown2 of [...record2.reviews, ...record2.entries]) {
|
|
31394
|
+
if (!phases.has(shown2.phase))
|
|
31395
|
+
phases.set(shown2.phase, { phase: shown2.phase, number: shown2.number });
|
|
31396
|
+
}
|
|
31397
|
+
return resolvePhaseReference(reference, [...phases.values()]);
|
|
31398
|
+
}
|
|
31290
31399
|
function matchReviewPhraseShape(shape, reviews) {
|
|
31291
31400
|
const resolved = resolvePhaseReference(shape.reference, reviews);
|
|
31292
31401
|
const act = shape.kind === "phase" ? "accept" : shape.kind === "reject" ? "reject" : shape.act;
|
|
@@ -31377,6 +31486,28 @@ function moveListedReviewForward(engagementId, home, listed, reviewVersion, deci
|
|
|
31377
31486
|
}
|
|
31378
31487
|
}
|
|
31379
31488
|
|
|
31489
|
+
// dist/hooks/wait-phrase.js
|
|
31490
|
+
var APPROVE = /^approve wait ([0-9a-f]{8})$/i;
|
|
31491
|
+
var DECLINE = /^decline wait ([0-9a-f]{8})(?:\s*:(.*))?$/is;
|
|
31492
|
+
function waitPhraseShape(prompt) {
|
|
31493
|
+
if (typeof prompt !== "string")
|
|
31494
|
+
return null;
|
|
31495
|
+
const line2 = prompt.trim();
|
|
31496
|
+
if (LINE_BREAK.test(line2))
|
|
31497
|
+
return null;
|
|
31498
|
+
const approve = APPROVE.exec(line2);
|
|
31499
|
+
if (approve !== null)
|
|
31500
|
+
return shapeOf("approve", approve[1], null);
|
|
31501
|
+
const decline = DECLINE.exec(line2);
|
|
31502
|
+
if (decline !== null)
|
|
31503
|
+
return shapeOf("decline", decline[1], decline[2] === void 0 ? null : decline[2].trim());
|
|
31504
|
+
return null;
|
|
31505
|
+
}
|
|
31506
|
+
function shapeOf(act, typed, words) {
|
|
31507
|
+
const wait = typed.toLowerCase();
|
|
31508
|
+
return ownerWaitShortIdSchema.safeParse(wait).success ? { act, wait, words } : null;
|
|
31509
|
+
}
|
|
31510
|
+
|
|
31380
31511
|
// dist/hooks/user-prompt-submit-lines.js
|
|
31381
31512
|
var TELL_THE_PERSON = "Tell the person.";
|
|
31382
31513
|
function line(text) {
|
|
@@ -31744,6 +31875,69 @@ function codexReviewLine(act) {
|
|
|
31744
31875
|
function codexAutonomyLine() {
|
|
31745
31876
|
return codexLine(`${AUTONOMY_NOTHING_CHANGED}: ${CODEX_TYPING_NEVER_COUNTS}. Turn it on or off with "${AUTONOMY_A1_TITLE}" in the console's settings.`);
|
|
31746
31877
|
}
|
|
31878
|
+
function waitTypedLine(context) {
|
|
31879
|
+
return context.act === "approve" ? ownerWaitApproveLineOf(context.wait) : ownerWaitDeclineLineOf(context.wait);
|
|
31880
|
+
}
|
|
31881
|
+
function waitRecordedLine(act, question) {
|
|
31882
|
+
return act === "approve" ? line(`Recorded in your session: you approved "${question}". The agent can go ahead with it.`) : line(`Recorded in your session: you declined "${question}", with your words. The agent must not go ahead with it.`);
|
|
31883
|
+
}
|
|
31884
|
+
function waitNotAttendedLine() {
|
|
31885
|
+
return line(`${NOTHING_RECORDED}: an answer counts only when a person types it into an open session.`);
|
|
31886
|
+
}
|
|
31887
|
+
function waitNotSignedInLine() {
|
|
31888
|
+
return line(`${NOTHING_RECORDED}: this project is not signed in on this computer. ${HOOK_REMEDY}`);
|
|
31889
|
+
}
|
|
31890
|
+
function waitNotOwnerLine() {
|
|
31891
|
+
return line(`${NOTHING_RECORDED}: only the project's owner can answer a decision that waits for them.`);
|
|
31892
|
+
}
|
|
31893
|
+
function waitNoOwnerLine() {
|
|
31894
|
+
return line(`${NOTHING_RECORDED}: this project has no owner, so nobody can answer its decisions.`);
|
|
31895
|
+
}
|
|
31896
|
+
function waitNotFoundLine(context) {
|
|
31897
|
+
return line(`${NOTHING_RECORDED}: no decision waiting for you has the id ${context.wait}. Type the line the agent gave you with its question, such as ${waitTypedLine(context)}.`);
|
|
31898
|
+
}
|
|
31899
|
+
function waitAmbiguousLine(context) {
|
|
31900
|
+
return line(`${NOTHING_RECORDED}: more than one decision waiting for you starts with ${context.wait}. Ask the agent to put the question to you again.`);
|
|
31901
|
+
}
|
|
31902
|
+
function waitNoWordsLine(context) {
|
|
31903
|
+
return line(`${NOTHING_RECORDED}: a decline needs your reason after the colon, as in ${ownerWaitDeclineLineOf(context.wait)}.`);
|
|
31904
|
+
}
|
|
31905
|
+
function waitRefusedLine() {
|
|
31906
|
+
return line(`${NOTHING_RECORDED}: Halfcycle did not accept the words. Reword them in plain words and type the line again.`);
|
|
31907
|
+
}
|
|
31908
|
+
function waitSwitchedOffLine() {
|
|
31909
|
+
return line(`${NOTHING_RECORDED}. ${TYPED_APPROVAL_OFF_SENTENCE}`);
|
|
31910
|
+
}
|
|
31911
|
+
function waitCannotReachLine() {
|
|
31912
|
+
return line(`${NOTHING_RECORDED}: Halfcycle could not be reached just now. Type the line again in a minute.`);
|
|
31913
|
+
}
|
|
31914
|
+
function codexWaitLine(context) {
|
|
31915
|
+
return codexLine(`${NOTHING_RECORDED}: ${CODEX_TYPING_NEVER_COUNTS}. To answer, type ${waitTypedLine(context)} in a Claude Code session on this project.`);
|
|
31916
|
+
}
|
|
31917
|
+
function waitLineForAnswer(context, answer) {
|
|
31918
|
+
switch (answer.outcome) {
|
|
31919
|
+
case "recorded":
|
|
31920
|
+
return waitRecordedLine(answer.act, answer.question);
|
|
31921
|
+
case "refused":
|
|
31922
|
+
return waitRefusedLine();
|
|
31923
|
+
case "not-owner":
|
|
31924
|
+
return waitNotOwnerLine();
|
|
31925
|
+
case "no-owner":
|
|
31926
|
+
return waitNoOwnerLine();
|
|
31927
|
+
case "not-found":
|
|
31928
|
+
return waitNotFoundLine(context);
|
|
31929
|
+
case "ambiguous":
|
|
31930
|
+
return waitAmbiguousLine(context);
|
|
31931
|
+
case "not-offered":
|
|
31932
|
+
return waitSwitchedOffLine();
|
|
31933
|
+
case "unavailable":
|
|
31934
|
+
return waitCannotReachLine();
|
|
31935
|
+
default: {
|
|
31936
|
+
const unreachable = answer;
|
|
31937
|
+
return unreachable;
|
|
31938
|
+
}
|
|
31939
|
+
}
|
|
31940
|
+
}
|
|
31747
31941
|
|
|
31748
31942
|
// dist/hooks/user-prompt-submit.js
|
|
31749
31943
|
var CHAT_REQUEST_TIMEOUT_MS = 6e3;
|
|
@@ -31768,6 +31962,7 @@ function agentOf(opts) {
|
|
|
31768
31962
|
async function decideLine(opts) {
|
|
31769
31963
|
let act = null;
|
|
31770
31964
|
let autonomyAct = null;
|
|
31965
|
+
let waitRecognised = false;
|
|
31771
31966
|
const review = { recognised: false };
|
|
31772
31967
|
try {
|
|
31773
31968
|
const prompt = promptOf(opts.input);
|
|
@@ -31778,6 +31973,12 @@ async function decideLine(opts) {
|
|
|
31778
31973
|
if (autonomyShape !== null) {
|
|
31779
31974
|
autonomyAct = autonomyShape;
|
|
31780
31975
|
return `${await decideAutonomy(autonomyShape, opts)}
|
|
31976
|
+
`;
|
|
31977
|
+
}
|
|
31978
|
+
const waitShape = waitPhraseShape(prompt);
|
|
31979
|
+
if (waitShape !== null) {
|
|
31980
|
+
waitRecognised = true;
|
|
31981
|
+
return `${await decideWait(waitShape, opts)}
|
|
31781
31982
|
`;
|
|
31782
31983
|
}
|
|
31783
31984
|
const reviewShape = reviewPhraseShape(prompt);
|
|
@@ -31795,6 +31996,9 @@ async function decideLine(opts) {
|
|
|
31795
31996
|
} catch {
|
|
31796
31997
|
if (autonomyAct !== null)
|
|
31797
31998
|
return `${autonomyCannotReachLine()}
|
|
31999
|
+
`;
|
|
32000
|
+
if (waitRecognised)
|
|
32001
|
+
return `${waitCannotReachLine()}
|
|
31798
32002
|
`;
|
|
31799
32003
|
if (review.recognised)
|
|
31800
32004
|
return `${reviewCannotReachLine()}
|
|
@@ -31840,6 +32044,57 @@ async function decideAutonomy(act, opts) {
|
|
|
31840
32044
|
const { guardServiceToken, guardEngagementId } = read.config;
|
|
31841
32045
|
return postAutonomy(act, guardEngagementId, guardServiceToken, env, opts.fetchFn);
|
|
31842
32046
|
}
|
|
32047
|
+
async function decideWait(shape, opts) {
|
|
32048
|
+
const env = opts.env ?? process.env;
|
|
32049
|
+
const context = { act: shape.act, wait: shape.wait };
|
|
32050
|
+
const typed = whoTyped(opts);
|
|
32051
|
+
if (typed === "cannot-tell")
|
|
32052
|
+
return codexWaitLine(context);
|
|
32053
|
+
if (typed === "not-attended")
|
|
32054
|
+
return waitNotAttendedLine();
|
|
32055
|
+
const read = readConfig(env);
|
|
32056
|
+
if (read.config === null) {
|
|
32057
|
+
return readNeverConfiguredReason(env) === "not-this-account" ? waitNotOwnerLine() : waitNotSignedInLine();
|
|
32058
|
+
}
|
|
32059
|
+
let candidate = { act: "approve", wait: shape.wait };
|
|
32060
|
+
if (shape.act === "decline") {
|
|
32061
|
+
const words = shape.words ?? "";
|
|
32062
|
+
if (words === "")
|
|
32063
|
+
return waitNoWordsLine(context);
|
|
32064
|
+
if (!scopeNoteWireSchema.safeParse(words).success)
|
|
32065
|
+
return reviewWordsTooLongLine();
|
|
32066
|
+
if (looksLikeSecret(words))
|
|
32067
|
+
return reviewWordsLookSecretLine();
|
|
32068
|
+
candidate = { act: "decline", wait: shape.wait, note: words };
|
|
32069
|
+
}
|
|
32070
|
+
const request = ownerWaitChatRequestSchema.parse(candidate);
|
|
32071
|
+
const { guardServiceToken, guardEngagementId } = read.config;
|
|
32072
|
+
const url2 = `${readControlOrigin(env).origin}/engagements/${encodeURIComponent(guardEngagementId)}/owner-waits/chat`;
|
|
32073
|
+
const controller = new AbortController();
|
|
32074
|
+
const timer = setTimeout(() => controller.abort(), CHAT_REQUEST_TIMEOUT_MS);
|
|
32075
|
+
try {
|
|
32076
|
+
const response = await (opts.fetchFn ?? globalThis.fetch)(url2, {
|
|
32077
|
+
method: "POST",
|
|
32078
|
+
headers: { Authorization: `Bearer ${guardServiceToken}`, "Content-Type": "application/json" },
|
|
32079
|
+
body: JSON.stringify(request),
|
|
32080
|
+
signal: controller.signal
|
|
32081
|
+
});
|
|
32082
|
+
if (response.status === 401)
|
|
32083
|
+
return waitNotSignedInLine();
|
|
32084
|
+
if (response.status === 429 || response.status >= 500)
|
|
32085
|
+
return waitCannotReachLine();
|
|
32086
|
+
const parsed = ownerWaitChatResultSchema.safeParse(await response.json());
|
|
32087
|
+
if (!parsed.success)
|
|
32088
|
+
return waitCannotReachLine();
|
|
32089
|
+
if (parsed.data.outcome === "recorded" && response.status !== 200)
|
|
32090
|
+
return waitCannotReachLine();
|
|
32091
|
+
return waitLineForAnswer(context, parsed.data);
|
|
32092
|
+
} catch {
|
|
32093
|
+
return waitCannotReachLine();
|
|
32094
|
+
} finally {
|
|
32095
|
+
clearTimeout(timer);
|
|
32096
|
+
}
|
|
32097
|
+
}
|
|
31843
32098
|
async function postAutonomy(act, engagementId, credential, env, fetchFn = globalThis.fetch) {
|
|
31844
32099
|
const url2 = `${readControlOrigin(env).origin}/engagements/${encodeURIComponent(engagementId)}/autonomy/chat`;
|
|
31845
32100
|
const controller = new AbortController();
|
|
@@ -31873,8 +32128,12 @@ async function decideReview(shape, opts, progress) {
|
|
|
31873
32128
|
const read2 = readConfig(env);
|
|
31874
32129
|
if (read2.config === null)
|
|
31875
32130
|
return "";
|
|
31876
|
-
const
|
|
31877
|
-
|
|
32131
|
+
const { guardEngagementId: engagementId, guardServiceToken: credential } = read2.config;
|
|
32132
|
+
const record2 = readShownRecord(engagementId, opts.home);
|
|
32133
|
+
const listed = matchReviewPhraseShape(shape, record2.reviews);
|
|
32134
|
+
const fresh = listed.kind === "accept" && listedRecently(listed.entry.shownAt, (opts.now ?? Date.now)());
|
|
32135
|
+
const target = listed.kind === "ambiguous" || fresh ? null : bulkAcceptTargetOf(shape.reference, record2);
|
|
32136
|
+
if (target?.kind === "none")
|
|
31878
32137
|
return "";
|
|
31879
32138
|
progress.recognised = true;
|
|
31880
32139
|
const typed2 = whoTyped(opts);
|
|
@@ -31882,7 +32141,11 @@ async function decideReview(shape, opts, progress) {
|
|
|
31882
32141
|
return codexReviewLine("accept");
|
|
31883
32142
|
if (typed2 === "not-attended")
|
|
31884
32143
|
return reviewNotAttendedLine();
|
|
31885
|
-
|
|
32144
|
+
if (target === null)
|
|
32145
|
+
return checkAndSendReview(listed, engagementId, credential, env, opts);
|
|
32146
|
+
if (target.kind === "ambiguous")
|
|
32147
|
+
return reviewAmbiguousLine(target.entries.map((e) => e.phase));
|
|
32148
|
+
return readThenAccept(shape, target.entry.phase, engagementId, credential, env, opts);
|
|
31886
32149
|
}
|
|
31887
32150
|
progress.recognised = true;
|
|
31888
32151
|
const typed = whoTyped(opts);
|
|
@@ -31897,6 +32160,38 @@ async function decideReview(shape, opts, progress) {
|
|
|
31897
32160
|
const match = matchReviewPhraseShape(shape, readShownRecord(read.config.guardEngagementId, opts.home).reviews);
|
|
31898
32161
|
return checkAndSendReview(match, read.config.guardEngagementId, read.config.guardServiceToken, env, opts);
|
|
31899
32162
|
}
|
|
32163
|
+
var REVIEW_READ_TIMEOUT_MS = 3e3;
|
|
32164
|
+
async function readThenAccept(shape, phase, engagementId, credential, env, opts) {
|
|
32165
|
+
const fetchFn = opts.fetchFn ?? globalThis.fetch;
|
|
32166
|
+
const url2 = `${readControlOrigin(env).origin}/engagements/${encodeURIComponent(engagementId)}/phases/${encodeURIComponent(phase)}/review`;
|
|
32167
|
+
const controller = new AbortController();
|
|
32168
|
+
const timer = setTimeout(() => controller.abort(), REVIEW_READ_TIMEOUT_MS);
|
|
32169
|
+
let raw;
|
|
32170
|
+
try {
|
|
32171
|
+
const response = await fetchFn(url2, {
|
|
32172
|
+
method: "GET",
|
|
32173
|
+
headers: { Authorization: `Bearer ${credential}` },
|
|
32174
|
+
signal: controller.signal
|
|
32175
|
+
});
|
|
32176
|
+
if (response.status === 401)
|
|
32177
|
+
return reviewNotSignedInLine();
|
|
32178
|
+
if (response.status !== 200)
|
|
32179
|
+
return reviewCannotReachLine();
|
|
32180
|
+
raw = await response.json();
|
|
32181
|
+
} catch {
|
|
32182
|
+
return reviewCannotReachLine();
|
|
32183
|
+
} finally {
|
|
32184
|
+
clearTimeout(timer);
|
|
32185
|
+
}
|
|
32186
|
+
const parsed = phaseReviewViewSchema.safeParse(raw);
|
|
32187
|
+
if (!parsed.success)
|
|
32188
|
+
return reviewCannotReachLine();
|
|
32189
|
+
const view = parsed.data;
|
|
32190
|
+
if (view.state !== "open")
|
|
32191
|
+
return reviewNoReviewLine(phase);
|
|
32192
|
+
const entry = shownReviewEntryOf(view, new Date((opts.now ?? Date.now)()).toISOString());
|
|
32193
|
+
return checkAndSendReview(matchReviewPhraseShape(shape, [entry]), engagementId, credential, env, opts);
|
|
32194
|
+
}
|
|
31900
32195
|
async function checkAndSendReview(match, engagementId, credential, env, opts) {
|
|
31901
32196
|
if (match.kind === "nothing" || match.kind === "show-first")
|
|
31902
32197
|
return reviewShowFirstLine();
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `npx halfcycle@latest check-report <file | -> --head <sha>` (`checked-worker-reports`
|
|
3
|
+
* AC2).
|
|
4
|
+
*
|
|
5
|
+
* A coordinator saves a pull request's body to a file (or pipes it in as `-`) and
|
|
6
|
+
* runs this before it writes any task's state from the worker's report. It prints
|
|
7
|
+
* one plain line per problem, or one clear line, and exits 0 when the report
|
|
8
|
+
* passes, 1 when it is refused, 2 on a usage error or a file it cannot read.
|
|
9
|
+
*
|
|
10
|
+
* OFFLINE, ALWAYS. This verb reads the one file it is given, or standard input,
|
|
11
|
+
* and nothing else. It opens no credential file, makes no network call and needs
|
|
12
|
+
* no sign-in: the commit to compare with is handed to it as `--head`, so it never
|
|
13
|
+
* asks git or GitHub which commit that is.
|
|
14
|
+
*
|
|
15
|
+
* ONE HOME FOR THE RULES. `checkWorkerReport` (`@halfcycle/core`) holds the
|
|
16
|
+
* block reader, the rules and every line they print; this module only reads the
|
|
17
|
+
* text, passes it the four statuses of the served report block and the head, and
|
|
18
|
+
* turns what it returns into lines and an exit code.
|
|
19
|
+
*
|
|
20
|
+
* SHIPS TO CLIENT DISK inside the CLI: Node builtins and `@halfcycle/core` only.
|
|
21
|
+
* Every string here is a sentence a person reads in their own terminal, so none
|
|
22
|
+
* names an internal register, a route or this project's own tooling; no comment
|
|
23
|
+
* sits beside an object member.
|
|
24
|
+
*/
|
|
25
|
+
/** The usage line, printed for a missing report, an extra argument or an unknown flag. */
|
|
26
|
+
export declare const CHECK_REPORT_USAGE = "npx halfcycle@latest check-report <file | -> --head <sha>";
|
|
27
|
+
/** What the arguments after `check-report` came to: one report source and one head, or usage. */
|
|
28
|
+
export type CheckReportArgs = {
|
|
29
|
+
ok: true;
|
|
30
|
+
source: string;
|
|
31
|
+
head: string;
|
|
32
|
+
} | {
|
|
33
|
+
ok: false;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Exactly one positional (a file, or `-` for standard input) and exactly one
|
|
37
|
+
* `--head <sha>`; anything else is usage. A missing `--head` is refused before
|
|
38
|
+
* this is called, from the CLI's table of required flags.
|
|
39
|
+
*/
|
|
40
|
+
export declare function parseCheckReportArgs(argv: readonly string[]): CheckReportArgs;
|
|
41
|
+
/** What a run of the verb came to. */
|
|
42
|
+
export interface CheckReportRun {
|
|
43
|
+
readonly stdout: string;
|
|
44
|
+
readonly stderr: string;
|
|
45
|
+
readonly exitCode: number;
|
|
46
|
+
}
|
|
47
|
+
/** Where the report's text comes from; standard input is read only for `-`. */
|
|
48
|
+
export interface CheckReportDeps {
|
|
49
|
+
readonly readStdin?: () => string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The whole verb. Reads the report from `source` (standard input for `-`),
|
|
53
|
+
* checks it against `head` with the four statuses of the served block, and
|
|
54
|
+
* prints each problem's line, or the clear line. Never throws.
|
|
55
|
+
*/
|
|
56
|
+
export declare function runCheckReport(source: string, head: string, deps?: CheckReportDeps): CheckReportRun;
|
|
57
|
+
//# sourceMappingURL=check-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-report.d.ts","sourceRoot":"","sources":["../src/check-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAUH,0FAA0F;AAC1F,eAAO,MAAM,kBAAkB,8DAA8D,CAAC;AAE9F,iGAAiG;AACjG,MAAM,MAAM,eAAe,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;AAEzF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,eAAe,CAiB7E;AAED,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,MAAM,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB,GAAG,cAAc,CAoBvG"}
|
package/dist/check-tasks.d.ts
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
* `npx halfcycle@latest check-tasks <phase> [--with-task-list] [--repo <root>]`
|
|
3
3
|
* (`collision-free-parallel-work` AC3; `checks-as-work-lands` AC3, AC6).
|
|
4
4
|
*
|
|
5
|
-
* OFFLINE, ALWAYS. This verb reads
|
|
6
|
-
* `docs/build-records/task-plan.json`, `docs/system.json` when it is there,
|
|
5
|
+
* OFFLINE, ALWAYS. This verb reads only files on the person's own machine —
|
|
6
|
+
* `docs/build-records/task-plan.json`, `docs/system.json` when it is there, the
|
|
7
|
+
* phase's plan file in `docs/phases/` when it is there, each
|
|
8
|
+
* spec file the plan lists in `specs` (`docs/features/<name>.md`, once per name), and, with
|
|
7
9
|
* `--with-task-list`, `docs/build-records/build-tasks.json` — and nothing else. It opens no credential
|
|
8
10
|
* file, makes no network call, and needs no sign-in. Everything it prints comes from
|
|
9
11
|
* `checkTaskPlan` (`@halfcycle/core`), which is pure: this module's whole job is
|
|
@@ -38,13 +40,34 @@
|
|
|
38
40
|
* description that is broken, and passing it silently would let through the very
|
|
39
41
|
* plan this rule exists to catch.
|
|
40
42
|
*
|
|
43
|
+
* THE PHASE'S OWN PLAN NAMES THE PARTS IT CHANGES (O8, issue #2339). When the
|
|
44
|
+
* description passed its check and the phase's plan file (`planFileRel`, the plan
|
|
45
|
+
* verb's one home of that name) is there, reads as JSON, is for this phase and passes
|
|
46
|
+
* the plan verb's own check against that description (`checkPhasePlan`), its parts go
|
|
47
|
+
* to `checkTaskPlan`, which refuses a task building a part outside them with no
|
|
48
|
+
* reason. Anything short of that says nothing, never a stop: this verb runs while the
|
|
49
|
+
* plan may not be written yet, the plan verb is where a broken plan is named, and the
|
|
50
|
+
* method kit's validator is silent on the same cases.
|
|
51
|
+
*
|
|
52
|
+
* THE LISTED SPECS NAME THE CRITERIA (C1–C6, `criteria-coverage`). `readPlanSpecFiles`
|
|
53
|
+
* is the one place spec files are opened: for each name `planSpecNamesToRead` gives
|
|
54
|
+
* (a name that passed the spec-name rule, each once, in the plan's order) it reads
|
|
55
|
+
* `<spec folder>/<name>.md` and hands the criteria `readSpecCriteria` finds, and the
|
|
56
|
+
* Boundary section `readSpecBoundary` reads (B1, B2, N2, N3, `spec-boundaries`), to
|
|
57
|
+
* `checkTaskPlan`. The spec folder is the one the scan already knows for feature
|
|
58
|
+
* designs (`LAYER_ARTEFACT_PATHS`), not a second copy. A missing file is not an
|
|
59
|
+
* error here: the check names it (C6). A file that is there and cannot be read
|
|
60
|
+
* stops the run with exit 2, naming it, as an unreadable plan does.
|
|
61
|
+
*
|
|
41
62
|
* SHIPS TO CLIENT DISK inside the CLI (INV-001: Node builtins, `@halfcycle/core` and
|
|
42
|
-
* `@halfcycle/events` only, the latter for the description's
|
|
63
|
+
* `@halfcycle/events` only, the latter for the description's and the phase plan's checks; no
|
|
43
64
|
* network and no `fetch`). Every string here is
|
|
44
65
|
* a sentence a person reads in their own terminal, so none names an internal
|
|
45
66
|
* register, a route, or this project's own tooling; no comment sits beside an
|
|
46
67
|
* object member.
|
|
47
68
|
*/
|
|
69
|
+
import { type SystemDescription } from '@halfcycle/events';
|
|
70
|
+
import { type PlanSpecFiles, type TaskPlan } from '@halfcycle/core';
|
|
48
71
|
/** The usage line, printed for no phase, an extra argument or an unknown flag. */
|
|
49
72
|
export declare const CHECK_TASKS_USAGE = "npx halfcycle@latest check-tasks <phase> [--with-task-list] [--repo <root>]";
|
|
50
73
|
/**
|
|
@@ -61,6 +84,70 @@ export type CheckTasksArgs = {
|
|
|
61
84
|
ok: false;
|
|
62
85
|
};
|
|
63
86
|
export declare function parseCheckTasksArgs(argv: readonly string[]): CheckTasksArgs;
|
|
87
|
+
/**
|
|
88
|
+
* The sentence for a project with no plan file, without any verb's prefix: this verb
|
|
89
|
+
* and `ready` (`ready.ts`) each print it after their own.
|
|
90
|
+
*/
|
|
91
|
+
export declare const MISSING_PLAN_LINE = "there is no docs/build-records/task-plan.json in this project yet. Run the task-graph step to write it, then run this again.";
|
|
92
|
+
/** One JSON file, read and parsed: present and valid, missing, or unreadable/unparsable (with the line to print). */
|
|
93
|
+
type FileRead<T> = {
|
|
94
|
+
kind: 'ok';
|
|
95
|
+
value: T;
|
|
96
|
+
} | {
|
|
97
|
+
kind: 'missing';
|
|
98
|
+
} | {
|
|
99
|
+
kind: 'bad';
|
|
100
|
+
line: string;
|
|
101
|
+
};
|
|
102
|
+
/** A zod `safeParse` result, read structurally so this file never imports `zod` itself (INV-001). */
|
|
103
|
+
type SafeParse<T> = {
|
|
104
|
+
success: true;
|
|
105
|
+
data: T;
|
|
106
|
+
} | {
|
|
107
|
+
success: false;
|
|
108
|
+
error: {
|
|
109
|
+
issues: readonly {
|
|
110
|
+
path: readonly PropertyKey[];
|
|
111
|
+
message: string;
|
|
112
|
+
}[];
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Read and parse one JSON file under `repoRoot`. The line in a `bad` answer carries
|
|
117
|
+
* no verb's prefix; this verb and `ready` (`ready.ts`) each add their own. Never throws.
|
|
118
|
+
*/
|
|
119
|
+
export declare function readJsonFile<T>(repoRoot: string, rel: string, parse: (raw: unknown) => SafeParse<T>): FileRead<T>;
|
|
120
|
+
/**
|
|
121
|
+
* The parts the phase's own plan changes, with where that plan lives, or `undefined`
|
|
122
|
+
* when there is no plan to compare with: the phase is not a phase name, the file is
|
|
123
|
+
* missing, unreadable or not JSON, it is the plan for another phase, or it fails the
|
|
124
|
+
* plan verb's check against `description`. Never throws, never stops the run (see the
|
|
125
|
+
* module header).
|
|
126
|
+
*/
|
|
127
|
+
export declare function readPhasePlanParts(repoRoot: string, phase: string, description: SystemDescription): {
|
|
128
|
+
file: string;
|
|
129
|
+
partIds: string[];
|
|
130
|
+
} | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* The plan's listed specs, read: `ok` with the request's `specFiles`, or `bad` with
|
|
133
|
+
* the line naming a spec file that is there and could not be read, without any
|
|
134
|
+
* verb's prefix (each caller adds its own, as with `readJsonFile`'s line). A listed
|
|
135
|
+
* name with no file is an entry with no criteria, which the check names.
|
|
136
|
+
*/
|
|
137
|
+
export type PlanSpecFilesRead = {
|
|
138
|
+
kind: 'ok';
|
|
139
|
+
specFiles: PlanSpecFiles;
|
|
140
|
+
} | {
|
|
141
|
+
kind: 'bad';
|
|
142
|
+
line: string;
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* The one place spec files are opened. Reads `<spec folder>/<name>.md` under
|
|
146
|
+
* `repoRoot` once for each name `planSpecNamesToRead` gives for `plan`, in that
|
|
147
|
+
* order, and returns each one's criteria as `readSpecCriteria` finds them and its
|
|
148
|
+
* Boundary section as `readSpecBoundary` reads it. Never throws.
|
|
149
|
+
*/
|
|
150
|
+
export declare function readPlanSpecFiles(repoRoot: string, plan: TaskPlan): PlanSpecFilesRead;
|
|
64
151
|
/** What a run of the verb came to. */
|
|
65
152
|
export interface CheckTasksRun {
|
|
66
153
|
readonly stdout: string;
|
|
@@ -69,7 +156,9 @@ export interface CheckTasksRun {
|
|
|
69
156
|
}
|
|
70
157
|
/**
|
|
71
158
|
* The whole verb. Reads `docs/build-records/task-plan.json` under `repoRoot`,
|
|
72
|
-
* `docs/system.json` when it is there,
|
|
159
|
+
* `docs/system.json` when it is there, the phase's plan file when that is there too
|
|
160
|
+
* (`readPhasePlanParts`), each spec file the plan lists in `specs`
|
|
161
|
+
* (`docs/features/<name>.md`, through `readPlanSpecFiles`), and, with `withTaskList`,
|
|
73
162
|
* `docs/build-records/build-tasks.json`; hands them to
|
|
74
163
|
* `checkTaskPlan` and prints its lines, one per line, in the order it returns them,
|
|
75
164
|
* or `checkTaskPlan`'s own clear line when there is nothing to report. Never throws.
|
|
@@ -80,4 +169,5 @@ export interface CheckTasksRun {
|
|
|
80
169
|
* an error (see the module header) and never changes the exit code on its own.
|
|
81
170
|
*/
|
|
82
171
|
export declare function runCheckTasks(repoRoot: string, phase: string, withTaskList: boolean): CheckTasksRun;
|
|
172
|
+
export {};
|
|
83
173
|
//# sourceMappingURL=check-tasks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-tasks.d.ts","sourceRoot":"","sources":["../src/check-tasks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"check-tasks.d.ts","sourceRoot":"","sources":["../src/check-tasks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAIH,OAAO,EAML,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAWL,KAAK,aAAa,EAElB,KAAK,QAAQ,EAEd,MAAM,iBAAiB,CAAC;AAKzB,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,gFAAgF,CAAC;AAE/G;;;;GAIG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAChF;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;AAElB,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,cAAc,CAuB3E;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,iIAAiH,CAAC;AAEhJ,qHAAqH;AACrH,KAAK,QAAQ,CAAC,CAAC,IAAI;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAOlG,qGAAqG;AACrG,KAAK,SAAS,CAAC,CAAC,IACZ;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAC1B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE;QAAE,MAAM,EAAE,SAAS;YAAE,IAAI,EAAE,SAAS,WAAW,EAAE,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAAE,CAAA;CAAE,CAAC;AAExG;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CA0BjH;AAwCD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,iBAAiB,GAC7B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,CAYjD;AAQD;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzG;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,iBAAiB,CAkBrF;AAED,sCAAsC;AACtC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,aAAa,CA8CnG"}
|
package/dist/cli-contract.d.ts
CHANGED
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
* home is the failure mode it exists to prevent.
|
|
63
63
|
*/
|
|
64
64
|
/** The verbs the CLI dispatches. Anything else after `halfcycle ` is unknown. */
|
|
65
|
-
export declare const CLI_VERBS: readonly ["install", "check-drift", "build-record", "open-phase", "close-phase", "system", "draw", "plan", "review", "check-tasks", "uninstall", "change", "pace", "prove", "preview", "doctor", "restore"];
|
|
65
|
+
export declare const CLI_VERBS: readonly ["install", "check-drift", "build-record", "open-phase", "close-phase", "system", "draw", "plan", "review", "check-tasks", "check-report", "ready", "uninstall", "change", "pace", "prove", "preview", "doctor", "restore"];
|
|
66
66
|
export type CliVerb = (typeof CLI_VERBS)[number];
|
|
67
67
|
/** A flag every invocation of the verb must carry. */
|
|
68
68
|
export interface RequiredFlag {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-contract.d.ts","sourceRoot":"","sources":["../src/cli-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAIH,iFAAiF;AACjF,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"cli-contract.d.ts","sourceRoot":"","sources":["../src/cli-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAIH,iFAAiF;AACjF,eAAO,MAAM,SAAS,sOAAuO,CAAC;AAE9P,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,2DAA2D;IAC3D,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,+EAA+E;IAC/E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,CAAC;CAClD;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,CAAC;IACjD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAC1C;AA4JD,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAElE;AAED,iDAAiD;AACjD,MAAM,WAAW,SAAS;IACxB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAmBD;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAAE,CAyBxF;AAuBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAMvE;AASD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;CAErB,CAAC;AA0BX;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAa1F"}
|