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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "halfcycle",
3
- "version": "0.5.2",
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
  {
@@ -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 match2 = matchReviewPhraseShape(shape, readShownRecord(read2.config.guardEngagementId, opts.home).reviews);
31877
- if (match2.kind === "nothing")
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
- return checkAndSendReview(match2, read2.config.guardEngagementId, read2.config.guardServiceToken, env, opts);
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"}
@@ -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 at most three files on the person's own machine —
6
- * `docs/build-records/task-plan.json`, `docs/system.json` when it is there, and, with
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 path and check; no
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, and, with `withTaskList`,
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAkBH,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;AA8ED,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;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,aAAa,CAqCnG"}
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"}
@@ -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,6MAA8M,CAAC;AAErO,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;AAwID,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"}
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"}