halfcycle 0.5.3 → 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 +37 -1
- 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 +947 -61
- 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 +106 -9
- package/dist/index.js.map +3 -3
- package/dist/ready.d.ts +103 -0
- package/dist/ready.d.ts.map +1 -0
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -20,4 +20,5 @@ export { runBootstrapScan, scanLayers, mergeWithRecords, HALFCYCLE_STATE_FORMAT
|
|
|
20
20
|
export type { HalfcycleStateFile, ScannedLayerEntry, ScannedLayerValue } from './scan.js';
|
|
21
21
|
export * from './setup/index.js';
|
|
22
22
|
export * from './build-record/index.js';
|
|
23
|
+
export { readyRowsFromFiles } from './ready.js';
|
|
23
24
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACrG,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC/G,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC/E,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACnF,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAyBhE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnG,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAI1F,cAAc,kBAAkB,CAAC;AAKjC,cAAc,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACrG,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC/G,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC/E,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACnF,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAyBhE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnG,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAI1F,cAAc,kBAAkB,CAAC;AAKjC,cAAc,yBAAyB,CAAC;AAKxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -298,9 +298,13 @@ var HOOK_REMEDY = `Run ${SIGN_IN_COMMAND} in the project folder to sign in.`;
|
|
|
298
298
|
|
|
299
299
|
// ../core/dist/task-plan.js
|
|
300
300
|
import { z as z2 } from "zod";
|
|
301
|
+
var TASK_PLAN_FILE = "docs/build-records/task-plan.json";
|
|
302
|
+
var TASK_LIST_FILE = "docs/build-records/build-tasks.json";
|
|
301
303
|
var TASK_PLAN_TASKS_MAX = 500;
|
|
302
304
|
var TASK_PLAN_ID_MAX = 64;
|
|
303
305
|
var TASK_PLAN_BUILDS_NONE = "none";
|
|
306
|
+
var TASK_PLAN_CRITERIA_NONE = "none";
|
|
307
|
+
var TASK_PLAN_SPECS_NONE = "none";
|
|
304
308
|
var TASK_PLAN_KINDS = ["build", "review", "spec", "walk", "check"];
|
|
305
309
|
var CONTROL_CHARACTER = /[\u0000-\u001f\u007f-\u009f]/;
|
|
306
310
|
var planText = z2.string().refine((text) => !CONTROL_CHARACTER.test(text), { message: "holds a control character" });
|
|
@@ -317,7 +321,9 @@ var taskPlanTaskSchema = z2.object({
|
|
|
317
321
|
}).strict().optional(),
|
|
318
322
|
wholeProject: z2.literal(true).optional(),
|
|
319
323
|
ships: z2.enum(["deploy", "release"]).optional(),
|
|
320
|
-
builds: z2.union([z2.literal(TASK_PLAN_BUILDS_NONE), z2.array(planText)]).optional()
|
|
324
|
+
builds: z2.union([z2.literal(TASK_PLAN_BUILDS_NONE), z2.array(planText)]).optional(),
|
|
325
|
+
criteria: z2.union([z2.literal(TASK_PLAN_CRITERIA_NONE), z2.array(planText)]).optional(),
|
|
326
|
+
whyOutsidePlan: planText.optional()
|
|
321
327
|
}).strict().superRefine((task, ctx) => {
|
|
322
328
|
if (task.reviews !== void 0 && task.kind !== "review") {
|
|
323
329
|
ctx.addIssue({
|
|
@@ -343,6 +349,7 @@ var taskPlanTaskSchema = z2.object({
|
|
|
343
349
|
});
|
|
344
350
|
var taskPlanSchema = z2.object({
|
|
345
351
|
phase: z2.string().min(1).refine((text) => !CONTROL_CHARACTER.test(text), { message: "holds a control character" }),
|
|
352
|
+
specs: z2.union([z2.literal(TASK_PLAN_SPECS_NONE), z2.array(planText)]).optional(),
|
|
346
353
|
tasks: z2.array(taskPlanTaskSchema).max(TASK_PLAN_TASKS_MAX)
|
|
347
354
|
}).strict();
|
|
348
355
|
var taskListRowSchema = z2.object({
|
|
@@ -451,6 +458,37 @@ var AGENT_PROFILES = {
|
|
|
451
458
|
};
|
|
452
459
|
var ALL_HOOK_COMMANDS = new Set(AGENT_IDS.flatMap((id) => [...AGENT_PROFILES[id].commands]));
|
|
453
460
|
|
|
461
|
+
// ../core/dist/worker-report.js
|
|
462
|
+
var WORKER_REPORT_STATUSES = Object.freeze([
|
|
463
|
+
"done",
|
|
464
|
+
"needs-human-verification",
|
|
465
|
+
"blocked-on-human",
|
|
466
|
+
"failed"
|
|
467
|
+
]);
|
|
468
|
+
var WORKER_REPORT_RULE_FIELDS = Object.freeze({
|
|
469
|
+
W1: "Worker report",
|
|
470
|
+
W2: "Status",
|
|
471
|
+
W3: "Head",
|
|
472
|
+
W4: "Head",
|
|
473
|
+
W5: "Verification",
|
|
474
|
+
W6: "Verification",
|
|
475
|
+
W7: "Verification",
|
|
476
|
+
W8: "Unverified"
|
|
477
|
+
});
|
|
478
|
+
var WORKER_REPORT_LINES = Object.freeze({
|
|
479
|
+
noBlock: () => 'There is no "## Worker report" block in this report.',
|
|
480
|
+
statusMissing: (statuses) => `The report has no Status line. Use one of: ${statuses.join(", ")}.`,
|
|
481
|
+
statusUnknown: (found, statuses) => `The report's Status is "${found}". Use one of: ${statuses.join(", ")}.`,
|
|
482
|
+
headMissing: () => "The report has no Head line. Give the full commit id the report is about.",
|
|
483
|
+
headMalformed: (found) => `The report's Head is "${found}", which is not a full commit id.`,
|
|
484
|
+
headDiffers: (found, head) => `The report is about commit ${found}, but the work's head is ${head}. Ask for a report on the current head.`,
|
|
485
|
+
noVerification: () => "The report does not say what was run. List each check under Verification with its exit code.",
|
|
486
|
+
noExitCode: (entry) => `"${entry}" under Verification does not give an exit code.`,
|
|
487
|
+
nonZeroOnDone: (entry) => `"${entry}" exited with a code other than 0, so the work is not done.`,
|
|
488
|
+
noUnverified: () => 'The report has no Unverified line. Say what was not checked, or "nothing".',
|
|
489
|
+
clear: () => "The report is complete and names the commit it is about."
|
|
490
|
+
});
|
|
491
|
+
|
|
454
492
|
// ../events/dist/result.js
|
|
455
493
|
import { z as z3 } from "zod";
|
|
456
494
|
var firedGuardSchema = z3.object({
|
|
@@ -5350,12 +5388,12 @@ function findNotShared(targetRepo, manifest, collidedPaths) {
|
|
|
5350
5388
|
if (ignored === null)
|
|
5351
5389
|
return null;
|
|
5352
5390
|
const sorted = [...ignored].sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
5353
|
-
const
|
|
5391
|
+
const named2 = sorted.find((entry) => entry.path === SETTINGS_REL) ?? sorted[0];
|
|
5354
5392
|
return {
|
|
5355
|
-
path:
|
|
5356
|
-
pattern:
|
|
5357
|
-
source:
|
|
5358
|
-
line:
|
|
5393
|
+
path: named2.path,
|
|
5394
|
+
pattern: named2.pattern,
|
|
5395
|
+
source: named2.source,
|
|
5396
|
+
line: named2.line,
|
|
5359
5397
|
others: sorted.length - 1
|
|
5360
5398
|
};
|
|
5361
5399
|
}
|
|
@@ -8106,10 +8144,10 @@ function leftForYouLines(left, p) {
|
|
|
8106
8144
|
return lines;
|
|
8107
8145
|
}
|
|
8108
8146
|
function shownBy(steps) {
|
|
8109
|
-
const
|
|
8110
|
-
if (
|
|
8147
|
+
const named2 = steps.filter((s) => s.name !== void 0).length;
|
|
8148
|
+
if (named2 === 0)
|
|
8111
8149
|
return "Each is shown by the method's own label for it:";
|
|
8112
|
-
if (
|
|
8150
|
+
if (named2 === steps.length)
|
|
8113
8151
|
return "Each is shown by the method's own name for it:";
|
|
8114
8152
|
return "Each is shown by the method's own name for it, or by its label where the record holds no name:";
|
|
8115
8153
|
}
|
|
@@ -8652,6 +8690,64 @@ async function obtainBuildRecord(credential, repoRoot, phase, io = NODE_RECORD_P
|
|
|
8652
8690
|
function refetchCommand(phase) {
|
|
8653
8691
|
return `${HALFCYCLE_COMMAND} build-record ${quoteForShell(phase)}`;
|
|
8654
8692
|
}
|
|
8693
|
+
|
|
8694
|
+
// dist/check-tasks.js
|
|
8695
|
+
var CHECK_TASKS_USAGE = `${HALFCYCLE_COMMAND} check-tasks <phase> [--with-task-list] [--repo <root>]`;
|
|
8696
|
+
var MISSING_PLAN_LINE = `there is no ${TASK_PLAN_FILE} in this project yet. Run the task-graph step to write it, then run this again.`;
|
|
8697
|
+
var SPEC_FOLDER = LAYER_ARTEFACT_PATHS.l4[0];
|
|
8698
|
+
|
|
8699
|
+
// dist/ready.js
|
|
8700
|
+
var READY_USAGE = `${HALFCYCLE_COMMAND} ready <phase> [--cap <n>] [--repo <root>]`;
|
|
8701
|
+
var STATES_TEXT = buildTaskStateSchema.options.join(", ");
|
|
8702
|
+
var READY_LINES = {
|
|
8703
|
+
start: (id, title) => `Ready to start: ${named(id, title)}`,
|
|
8704
|
+
pastCap: (id, title) => `Ready, but past the number allowed now: ${named(id, title)}`,
|
|
8705
|
+
person: (id, title) => `Waiting on a person: ${named(id, title)}`,
|
|
8706
|
+
noCap: () => "No number was given, so every task that can start is listed.",
|
|
8707
|
+
nothing: () => "Nothing can start now.",
|
|
8708
|
+
noTaskList: () => `There is no task list at ${TASK_LIST_FILE}, so which tasks are done is not known. Write the task list for this phase, then run this again.`,
|
|
8709
|
+
otherPhase: (phase) => `The task list in ${TASK_LIST_FILE} is not for "${phase}", so which tasks are done is not known. Write the task list for this phase, then run this again.`,
|
|
8710
|
+
noState: (id) => `"${id}" in ${TASK_LIST_FILE} does not give its state as one of: ${STATES_TEXT}.`
|
|
8711
|
+
};
|
|
8712
|
+
function named(id, title) {
|
|
8713
|
+
return title === void 0 ? id : `${id}, ${title}`;
|
|
8714
|
+
}
|
|
8715
|
+
var PROGRESS = {
|
|
8716
|
+
pending: "pending",
|
|
8717
|
+
completed: "completed",
|
|
8718
|
+
"in-flight": "other",
|
|
8719
|
+
failed: "other",
|
|
8720
|
+
blocked: "other"
|
|
8721
|
+
};
|
|
8722
|
+
function readyRowsFromFiles(plan, taskList) {
|
|
8723
|
+
const listed = /* @__PURE__ */ new Map();
|
|
8724
|
+
for (const entry of taskList.tasks) {
|
|
8725
|
+
if (!listed.has(entry.id))
|
|
8726
|
+
listed.set(entry.id, entry);
|
|
8727
|
+
}
|
|
8728
|
+
const rows = [];
|
|
8729
|
+
const lines = [];
|
|
8730
|
+
plan.tasks.forEach((task, place) => {
|
|
8731
|
+
const entry = listed.get(task.id);
|
|
8732
|
+
const state = buildTaskStateSchema.safeParse(entry?.state);
|
|
8733
|
+
if (entry === void 0 || !state.success) {
|
|
8734
|
+
lines.push(READY_LINES.noState(task.id));
|
|
8735
|
+
return;
|
|
8736
|
+
}
|
|
8737
|
+
const title = typeof entry.title === "string" && entry.title !== "" ? entry.title : void 0;
|
|
8738
|
+
const minutes = typeof entry.budgetMinutes === "number" ? entry.budgetMinutes : void 0;
|
|
8739
|
+
rows.push({
|
|
8740
|
+
id: task.id,
|
|
8741
|
+
dependsOn: task.dependsOn,
|
|
8742
|
+
progress: PROGRESS[state.data],
|
|
8743
|
+
person: task.heldBy === "person" || entry.agent === HUMAN_AGENT,
|
|
8744
|
+
...minutes === void 0 ? {} : { minutes },
|
|
8745
|
+
tieRank: place,
|
|
8746
|
+
title
|
|
8747
|
+
});
|
|
8748
|
+
});
|
|
8749
|
+
return lines.length > 0 ? { ok: false, lines } : { ok: true, rows };
|
|
8750
|
+
}
|
|
8655
8751
|
export {
|
|
8656
8752
|
BUILD_RECORD_DIR,
|
|
8657
8753
|
CreateEngagementRefused,
|
|
@@ -8687,6 +8783,7 @@ export {
|
|
|
8687
8783
|
readBundlePin,
|
|
8688
8784
|
readRemote,
|
|
8689
8785
|
readRootCommit,
|
|
8786
|
+
readyRowsFromFiles,
|
|
8690
8787
|
refetchCommand,
|
|
8691
8788
|
renderAnchor,
|
|
8692
8789
|
renderBuildRecordV2Markdown,
|