halfcycle 0.12.0-rc.6 → 0.12.0-rc.7

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.12.0-rc.6",
3
+ "version": "0.12.0-rc.7",
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
  {
@@ -17367,7 +17367,8 @@ var timeSummarySchema = external_exports.object({
17367
17367
  totals: timeTotalsSchema,
17368
17368
  usage: timeUsageTotalsSchema
17369
17369
  }).strict(),
17370
- share: timeSummaryShareSchema.optional()
17370
+ share: timeSummaryShareSchema.optional(),
17371
+ workMinutes: timeCountSchema.nullable().optional()
17371
17372
  }).strict().superRefine((v, ctx) => {
17372
17373
  if (v.closed !== (v.closedAt !== null)) {
17373
17374
  ctx.addIssue({ code: "custom", path: ["closedAt"], message: "must be set exactly when the phase is closed" });
@@ -17482,6 +17483,7 @@ var METHOD_FILE_PATTERNS = [
17482
17483
  "CLAUDE.md",
17483
17484
  "AGENTS.md",
17484
17485
  ".claude/context",
17486
+ "docs/context",
17485
17487
  ".claude/commands",
17486
17488
  ".claude/hooks",
17487
17489
  ".claude/settings.json",
@@ -17541,7 +17543,7 @@ var PROJECT_RECORD_PATTERNS = [
17541
17543
  { pattern: "docs/build-records/task-plan.json", name: () => "the build's plan (task-plan.json)", shrinkAsked: false },
17542
17544
  { pattern: "docs/build-records", name: (file2) => `a closed phase's Build Record (${file2})` },
17543
17545
  {
17544
- pattern: ".claude/context/tasks/*",
17546
+ pattern: "docs/context/tasks/*",
17545
17547
  name: (file2) => `a task's notes for this phase (${file2})`,
17546
17548
  shrinkAsked: false,
17547
17549
  deleteAsked: false
@@ -20780,6 +20782,7 @@ function pathsDifferingFromHead(repoRoot, timeoutMs = PROVE_GIT_TIMEOUT_MS) {
20780
20782
  return result;
20781
20783
  return parseStatusPathsZ(result.value);
20782
20784
  }
20785
+ var GENERATED_CACHE = /(^|\/)(__pycache__|\.pytest_cache|\.mypy_cache|\.ruff_cache|node_modules)\/|\.py[co]$/;
20783
20786
  function parseStatusPathsZ(output) {
20784
20787
  if (output === "")
20785
20788
  return { ok: true, value: [] };
@@ -20790,7 +20793,10 @@ function parseStatusPathsZ(output) {
20790
20793
  if (record2.length < 4 || record2.charAt(2) !== " " || /[RC]/.test(record2.slice(0, 2))) {
20791
20794
  return { ok: false, message: "git gave an unreadable list of changed files" };
20792
20795
  }
20793
- paths.add(record2.slice(3));
20796
+ const path = record2.slice(3);
20797
+ if (record2.startsWith("??") && GENERATED_CACHE.test(path))
20798
+ continue;
20799
+ paths.add(path);
20794
20800
  }
20795
20801
  return { ok: true, value: [...paths] };
20796
20802
  }
@@ -369,6 +369,7 @@ halfcycle_pt_records() {
369
369
  halfcycle_pt_holds 'build-tasks.json' $'b?(\x01)u?(\x01)i?(\x01)l?(\x01)d?(\x01)-?(\x01)t?(\x01)a?(\x01)s?(\x01)k?(\x01)s?(\x01).?(\x01)j?(\x01)s?(\x01)o?(\x01)n' && return 1
370
370
  halfcycle_pt_holds 'task-plan.json' $'t?(\x01)a?(\x01)s?(\x01)k?(\x01)-?(\x01)p?(\x01)l?(\x01)a?(\x01)n?(\x01).?(\x01)j?(\x01)s?(\x01)o?(\x01)n' && return 1
371
371
  halfcycle_pt_holds 'build-records' $'b?(\x01)u?(\x01)i?(\x01)l?(\x01)d?(\x01)-?(\x01)r?(\x01)e?(\x01)c?(\x01)o?(\x01)r?(\x01)d?(\x01)s' && return 1
372
+ halfcycle_pt_holds 'context' $'c?(\x01)o?(\x01)n?(\x01)t?(\x01)e?(\x01)x?(\x01)t' && return 1
372
373
  halfcycle_pt_holds '.claude' $'.?(\x01)c?(\x01)l?(\x01)a?(\x01)u?(\x01)d?(\x01)e' && return 1
373
374
  return 0
374
375
  }
@@ -1 +1 @@
1
- {"version":3,"file":"check-tasks.d.ts","sourceRoot":"","sources":["../src/check-tasks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"check-tasks.d.ts","sourceRoot":"","sources":["../src/check-tasks.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -4028,7 +4028,8 @@ var timeSummarySchema = z11.object({
4028
4028
  totals: timeTotalsSchema,
4029
4029
  usage: timeUsageTotalsSchema
4030
4030
  }).strict(),
4031
- share: timeSummaryShareSchema.optional()
4031
+ share: timeSummaryShareSchema.optional(),
4032
+ workMinutes: timeCountSchema.nullable().optional()
4032
4033
  }).strict().superRefine((v, ctx) => {
4033
4034
  if (v.closed !== (v.closedAt !== null)) {
4034
4035
  ctx.addIssue({ code: "custom", path: ["closedAt"], message: "must be set exactly when the phase is closed" });
@@ -6675,7 +6676,7 @@ function aboutShareOf(percent) {
6675
6676
  }
6676
6677
  var PLAN_USAGE_CAVEAT = "These figures are estimates. Many things affect usage, and some of them are outside Halfcycle's control.";
6677
6678
  var SMALL_PROJECT_WORK_START = "A small project like this is usually about ";
6678
- var SMALL_PROJECT_WORK_NOTE = "When your plan is written, this phase gets its own figure, counted from the time each task in it is given.";
6679
+ var SMALL_PROJECT_WORK_NOTE = "Once your build plan is written, its own figure replaces this one: the time it sets for each task, added up.";
6679
6680
  function sizeAnswerPrintedLinesOf(usage5) {
6680
6681
  const out = [];
6681
6682
  for (const line of usage5) {
@@ -7719,11 +7720,11 @@ function expectedActualLineOf(expected, actual) {
7719
7720
  const took = `The phase took ${timeDurationLabelOf(actual.seconds)} and ${tokenCountWordsOf(actual.tokens)} tokens.`;
7720
7721
  if (expected.minutes === null)
7721
7722
  return `Expected about ${tokenCountWordsOf(expected.tokens)} tokens. ${took}`;
7722
- return `Expected ${timeDurationLabelOf(expected.minutes * 60)} and about ${tokenCountWordsOf(expected.tokens)} tokens. ${took}`;
7723
+ return `The plan expected about ${timeDurationLabelOf(expected.minutes * 60)} of agent work and about ${tokenCountWordsOf(expected.tokens)} tokens. ${took}`;
7723
7724
  }
7724
7725
  function expectedActualTimeLineOf(expectedMinutes, elapsedSeconds) {
7725
7726
  const took = `The phase took ${timeDurationLabelOf(elapsedSeconds)}.`;
7726
- return expectedMinutes === null ? took : `Expected ${timeDurationLabelOf(expectedMinutes * 60)}. ${took}`;
7727
+ return expectedMinutes === null ? took : `The plan expected about ${timeDurationLabelOf(expectedMinutes * 60)} of agent work. ${took}`;
7727
7728
  }
7728
7729
  function joinedOf(names) {
7729
7730
  if (names.length <= 1)
@@ -13164,9 +13165,13 @@ function repositoryNameFromRemote(remote) {
13164
13165
  const name = segment.replace(/\.git$/i, "").trim();
13165
13166
  return name.length > 0 ? name : void 0;
13166
13167
  }
13168
+ function isLocalRemote(remote) {
13169
+ const r = remote.trim();
13170
+ return /^(\/|\.{1,2}[\\/]|~|file:|[A-Za-z]:[\\/]|\\\\)/.test(r);
13171
+ }
13167
13172
  function deriveProjectName(targetRepoRoot) {
13168
13173
  const remote = readRemote(targetRepoRoot);
13169
- const fromRemote = remote ? repositoryNameFromRemote(remote) : void 0;
13174
+ const fromRemote = remote && !isLocalRemote(remote) ? repositoryNameFromRemote(remote) : void 0;
13170
13175
  const candidate = fromRemote ?? basename(resolve2(targetRepoRoot));
13171
13176
  const name = candidate.trim();
13172
13177
  if (EMPTY_SEGMENTS.has(name))
@@ -17807,7 +17812,7 @@ function assertNever3(value) {
17807
17812
  throw new Error(`unexpected answer: ${JSON.stringify(value)}`);
17808
17813
  }
17809
17814
  function readTimeTotalsUrl(credential, phase) {
17810
- return `${credential.serviceUrl}/engagements/${encodeURIComponent(credential.engagementId)}/phases/${encodeURIComponent(phase)}/time?with=share`;
17815
+ return `${credential.serviceUrl}/engagements/${encodeURIComponent(credential.engagementId)}/phases/${encodeURIComponent(phase)}/time?with=share&work=true`;
17811
17816
  }
17812
17817
  async function readCloseTimeSummary(credential, phase) {
17813
17818
  let res;
@@ -18002,15 +18007,19 @@ function readPhaseModels(engagementId, phase, openedAt, home) {
18002
18007
  function usageTokensOf(usage5) {
18003
18008
  return usage5.inputTokens + usage5.outputTokens + usage5.cacheWriteTokens + usage5.cacheReadTokens;
18004
18009
  }
18010
+ function planWorkMinutesOf(summary) {
18011
+ return summary.workMinutes ?? null;
18012
+ }
18005
18013
  function tierFigureLines(work, expected, summary, models, details = false) {
18006
18014
  const lines = [];
18007
18015
  const figures = work === null ? null : tierFiguresOf(work);
18008
18016
  if (figures !== null)
18009
18017
  lines.push(tierCountsLineOf(figures));
18010
- if (expected === null)
18018
+ const planMinutes = summary === null ? null : planWorkMinutesOf(summary);
18019
+ if (expected === null && planMinutes === null)
18011
18020
  lines.push(NO_EXPECTED_LINE);
18012
18021
  else if (summary !== null) {
18013
- lines.push(details ? expectedActualLineOf(expected, { seconds: summary.elapsedSeconds, tokens: usageTokensOf(summary.usage) }) : expectedActualTimeLineOf(expected.minutes, summary.elapsedSeconds));
18022
+ lines.push(details && expected !== null ? expectedActualLineOf({ tokens: expected.tokens, minutes: planMinutes }, { seconds: summary.elapsedSeconds, tokens: usageTokensOf(summary.usage) }) : expectedActualTimeLineOf(planMinutes, summary.elapsedSeconds));
18014
18023
  }
18015
18024
  if (figures !== null && models !== null) {
18016
18025
  for (const task of figures.hadCheaperAttempt) {
@@ -18743,8 +18752,18 @@ function readPlanSpecFiles(repoRoot, plan) {
18743
18752
  return { kind: "ok", specFiles: { folder: SPEC_FOLDER, entries } };
18744
18753
  }
18745
18754
  function readCriteriaRecordFile(repoRoot, rel = CRITERIA_RECORD_FILE) {
18746
- return readJsonFile(repoRoot, rel, (raw) => workCriteriaRecordSchema.safeParse(raw));
18755
+ return readJsonFile(repoRoot, rel, (raw) => {
18756
+ const parsed = workCriteriaRecordSchema.safeParse(raw);
18757
+ if (parsed.success)
18758
+ return parsed;
18759
+ const first = parsed.error.issues[0];
18760
+ if (first !== void 0 && (first.path[0] === "record" || first.path[0] === "subject")) {
18761
+ return { success: false, error: { issues: [{ path: [], message: CRITERIA_RECORD_START }] } };
18762
+ }
18763
+ return parsed;
18764
+ });
18747
18765
  }
18766
+ var CRITERIA_RECORD_START = 'does not start the way a criteria record does. Begin it with "record": "criteria" and "subject": {"kind": "phase", "phase": "<the phase>"}, then "check" (the check task), "by" (who holds it) and "rows"';
18748
18767
  function readCriteriaRecord(repoRoot, plan) {
18749
18768
  const read = readCriteriaRecordFile(repoRoot);
18750
18769
  if (read.kind === "missing")
@@ -20292,7 +20311,7 @@ function openingBannerContent(projectDir, env = process.env, probes = REAL_PROBE
20292
20311
  facts,
20293
20312
  tag: TAGLINE,
20294
20313
  tagNarrow: TAGLINE_NARROW,
20295
- url: BRAND_URL,
20314
+ url: probes.websiteHost(env) ?? BRAND_URL,
20296
20315
  // `''` when even this package's own manifest could not be read. The one-line cut
20297
20316
  // drops the whole `vX.Y.Z` clause in that case rather than printing a bare `v`.
20298
20317
  version: version ?? ""