halfcycle 0.4.10 → 0.4.12

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.4.10",
3
+ "version": "0.4.12",
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
  {
@@ -17024,7 +17024,7 @@ function approvalSentence(phase, offerTyping) {
17024
17024
  return TYPED_APPROVAL_OFF_SENTENCE;
17025
17025
  if (offerTyping === "update")
17026
17026
  return CLIENT_UPDATE_SENTENCE;
17027
- return `In their own Claude Code session, they ask to see the plan, check each part, and then type: approve ${phase}`;
17027
+ return `In their own Claude Code session, they ask to see the plan, check each part, and then type: approve ${phase}.`;
17028
17028
  }
17029
17029
  function phaseWords(phase) {
17030
17030
  return `phase "${phase}"`;
@@ -20814,6 +20814,9 @@ function reviewAlreadyDecidedLine(name) {
20814
20814
  function reviewAwaitingAnswerLine(name) {
20815
20815
  return line(`${NOTHING_RECORDED}: "${name}" is waiting for the agent's answer to your question. Once it is in, say "review what was built" to list it again and decide the part.`);
20816
20816
  }
20817
+ function reviewAnswerNotListedLine(name) {
20818
+ return line(`${NOTHING_RECORDED}: the review listed here does not show the agent's answer to your question on "${name}". Say "review what was built" to list it again: the answer shows there once it is in, and then you can decide the part.`);
20819
+ }
20817
20820
  function reviewSentBackLine(name) {
20818
20821
  return line(`${NOTHING_RECORDED}: "${name}" was sent back to building in this round, so it waits for the next round.`);
20819
20822
  }
@@ -21022,7 +21025,7 @@ async function checkAndSendReview(match, engagementId, credential, env, opts) {
21022
21025
  return reviewWordsLookSecretLine();
21023
21026
  }
21024
21027
  if (part.awaitingAnswer)
21025
- return reviewAwaitingAnswerLine(part.name);
21028
+ return reviewAnswerNotListedLine(part.name);
21026
21029
  if (part.sentBack)
21027
21030
  return reviewSentBackLine(part.name);
21028
21031
  if (!part.decidable)
@@ -71,6 +71,11 @@ export declare function printItemStartText(text: string): string;
71
71
  */
72
72
  export declare function latestCloseHeadline(record: BuildRecord): string;
73
73
  /**
74
+ * A v3 record whose review ran more than one round says so in its opening line and
75
+ * points down to "Earlier rounds of the review", and the close's walk line names the
76
+ * round that closed the phase (review R-FW10: a reader who stopped at the opening never
77
+ * learned an earlier round said something else).
78
+ *
74
79
  * Render a parsed Build Record as markdown: v2's observed and attested halves, which
75
80
  * a v3 record carries unchanged, and for a v3 record the owner's review after the
76
81
  * latest close (RM1–RM3, feature `close-review-and-carry-drop`).
@@ -1 +1 @@
1
- {"version":3,"file":"render-v2.d.ts","sourceRoot":"","sources":["../../src/build-record/render-v2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAA4B,KAAK,WAAW,EAA0C,MAAM,mBAAmB,CAAC;AA8JvH;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAepD;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASpD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOvD;AAgMD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAO/D;AAmOD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CA4DvE"}
1
+ {"version":3,"file":"render-v2.d.ts","sourceRoot":"","sources":["../../src/build-record/render-v2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAGL,KAAK,WAAW,EAKjB,MAAM,mBAAmB,CAAC;AA8J3B;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAepD;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASpD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOvD;AAgMD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAO/D;AAmRD;;;;;;;;;;;;GAYG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAyEvE"}
@@ -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,mIAAoI,CAAC;AAE3J,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,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;CAClD;AAiFD,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;AAED;;;;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;AAmBX;;;;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,mIAAoI,CAAC;AAE3J,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,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;CAClD;AAiFD,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;AAED;;;;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;AAyBX;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAa1F"}
package/dist/cli.js CHANGED
@@ -2867,11 +2867,16 @@ var phaseReviewViewSchema = z14.discriminatedUnion("state", [
2867
2867
 
2868
2868
  // ../events/dist/build-record-v3.js
2869
2869
  var BUILD_RECORD_V3_FORMAT = "halfcycle-build-record/v3";
2870
+ var recordRoundStatedSchema = z15.object({
2871
+ actor: attestedCloseSchema.shape.actor,
2872
+ statements: attestedStatementsSchema
2873
+ }).strict();
2870
2874
  var recordReviewRoundSchema = z15.object({
2871
2875
  round: z15.number().int().min(1),
2872
2876
  openedAt: utcIso8601,
2873
2877
  verdict: walkVerdictSchema,
2874
- findings: z15.number().int().min(0)
2878
+ findings: z15.number().int().min(0),
2879
+ stated: recordRoundStatedSchema.optional()
2875
2880
  }).strict();
2876
2881
  var recordReviewApprovalSchema = z15.discriminatedUnion("kind", [
2877
2882
  z15.object({
@@ -2933,6 +2938,9 @@ var recordReviewSchema = z15.object({
2933
2938
  if (r.round !== i + 1) {
2934
2939
  ctx.addIssue({ code: "custom", path: ["rounds", i, "round"], message: "rounds must be numbered 1, 2, 3 \u2026 in order with no gap" });
2935
2940
  }
2941
+ if (i === v.rounds.length - 1 && r.stated !== void 0) {
2942
+ ctx.addIssue({ code: "custom", path: ["rounds", i, "stated"], message: "the last round's words are the close's own, so the round does not repeat them" });
2943
+ }
2936
2944
  });
2937
2945
  const seen = /* @__PURE__ */ new Set();
2938
2946
  v.parts.forEach((p, i) => {
@@ -7138,12 +7146,13 @@ function machines(coverage, checks) {
7138
7146
  const line = `${label}${String(coverage.enrolled)}. Of these, ${String(coverage.conformant)} had reported Halfcycle's checks as fully set up.`;
7139
7147
  return checks === "not-observed" && coverage.conformant > 0 ? `${line} Set up is not the same as running: Halfcycle has no record of any check running during this phase.` : line;
7140
7148
  }
7141
- function walkLines(walk, p) {
7149
+ function walkLines(walk, p, closingRound = false) {
7142
7150
  const label = "> - Acceptance walk (the finished work tried as a user would, by someone other than its builder): ";
7143
7151
  if (walk === null)
7144
7152
  return [`${label}the person closing the phase reported none.`];
7153
+ const it = closingRound ? "the round that closed the phase" : "it";
7145
7154
  const lines = [
7146
- `${label}${walk.verdict === "clean" ? "the person closing the phase said it found no problems." : "the person closing the phase said it found problems."}`
7155
+ `${label}${walk.verdict === "clean" ? `the person closing the phase said ${it} found no problems.` : `the person closing the phase said ${it} found problems.`}`
7147
7156
  ];
7148
7157
  walk.findings.forEach((finding, i) => {
7149
7158
  lines.push(`> - Finding ${String(i + 1)}: ${p.text(finding)}`);
@@ -7162,12 +7171,12 @@ function decisionLine(attested) {
7162
7171
  }
7163
7172
  return attested.walk !== null && attested.walk.verdict === "defects" ? "> - Decision: close the phase as it stood, with the problems its acceptance walk found." : "> - Decision: the phase's agreed finish conditions were met.";
7164
7173
  }
7165
- function renderStated(attested, p) {
7174
+ function renderStated(attested, p, closingRound = false) {
7166
7175
  const lines = [
7167
7176
  decisionLine(attested),
7168
7177
  `> - Name given: ${attested.actor === null ? "removed with the account that made this close" : p.text(attested.actor)}`,
7169
7178
  `> - Reason given: ${attested.reason === null ? "none." : p.text(attested.reason)}`,
7170
- ...walkLines(attested.walk, p),
7179
+ ...walkLines(attested.walk, p, closingRound),
7171
7180
  `> - Code closed at (commit): ${statedOrNot(attested.closeCommit, p)}`,
7172
7181
  `> - What the phase set out to prove: ${statedOrNot(attested.statements.thesis, p)}`,
7173
7182
  `> - What came out of it: ${statedOrNot(attested.statements.outcome, p)}`
@@ -7183,7 +7192,7 @@ function renderStated(attested, p) {
7183
7192
  }
7184
7193
  return lines.join("\n");
7185
7194
  }
7186
- function renderClose(heading, observed, attested, checks, p) {
7195
+ function renderClose(heading, observed, attested, checks, p, closingRound = false) {
7187
7196
  return [
7188
7197
  heading,
7189
7198
  headline(observed, attested, checks),
@@ -7195,7 +7204,7 @@ function renderClose(heading, observed, attested, checks, p) {
7195
7204
  machines(observed.seatCoverage, checks)
7196
7205
  ].join("\n"),
7197
7206
  STATED_LABEL,
7198
- renderStated(attested, p)
7207
+ renderStated(attested, p, closingRound)
7199
7208
  ];
7200
7209
  }
7201
7210
  var REVIEW_LABEL = "**Recorded by Halfcycle from the owner's review.** Each part the review held, and how the project's owner decided it. A line marked as the agent's is the agent's own answer, not Halfcycle's.";
@@ -7244,6 +7253,37 @@ function renderReview(record2, p) {
7244
7253
  blocks.push(removals);
7245
7254
  return blocks;
7246
7255
  }
7256
+ var EARLIER_ROUNDS_LABEL = `${STATED_LABEL} What was said each time the owner's review was asked for, before the round that closed the phase. What was said for that last round is under the close above. If the account that asked for a round is later deleted, the name given for that round is removed.`;
7257
+ function renderRoundStated(round, stated, p) {
7258
+ const label = "> - Acceptance walk (the finished work tried as a user would, by someone other than its builder): ";
7259
+ const walk = round.verdict === "clean" ? "the person asking for this round said it found no problems." : round.findings === 0 ? "the person asking for this round said it found problems." : `the person asking for this round said it found ${counted(round.findings, "problem", "problems")}.`;
7260
+ const lines = [
7261
+ `> - Name given: ${stated.actor === null ? "removed with the account that asked for this round" : p.text(stated.actor)}`,
7262
+ `${label}${walk}`,
7263
+ `> - What the phase set out to prove: ${statedOrNot(stated.statements.thesis, p)}`,
7264
+ `> - What came out of it: ${statedOrNot(stated.statements.outcome, p)}`
7265
+ ];
7266
+ const deviations = stated.statements.deviations;
7267
+ if (deviations.length === 0) {
7268
+ lines.push("> - Changes from the plan: None stated by the client.");
7269
+ } else {
7270
+ lines.push("> - Changes from the plan:");
7271
+ deviations.forEach((deviation, i) => {
7272
+ lines.push(`> - Change ${String(i + 1)}: ${p.text(deviation)}`);
7273
+ });
7274
+ }
7275
+ return lines.join("\n");
7276
+ }
7277
+ function renderEarlierRounds(record2, p) {
7278
+ const rounds = record2.review.rounds;
7279
+ const blocks = [];
7280
+ for (const round of rounds) {
7281
+ if (round.stated === void 0)
7282
+ continue;
7283
+ blocks.push(`### Round ${String(round.round)} of ${String(rounds.length)}`, renderRoundStated(round, round.stated, p));
7284
+ }
7285
+ return blocks.length === 0 ? [] : ["## Earlier rounds of the review", EARLIER_ROUNDS_LABEL, ...blocks];
7286
+ }
7247
7287
  function renderBuildRecordV2Markdown(record2) {
7248
7288
  const p = makePrinter();
7249
7289
  const attestedBySequence = /* @__PURE__ */ new Map();
@@ -7257,6 +7297,8 @@ function renderBuildRecordV2Markdown(record2) {
7257
7297
  const closes = [...record2.observed.closes].sort((a, b) => a.sequence - b.sequence);
7258
7298
  const total = closes.length;
7259
7299
  const latest = closes[total - 1];
7300
+ const rounds = record2.format === "halfcycle-build-record/v3" ? record2.review.rounds : [];
7301
+ const roundsAfter = rounds.length <= 1 ? null : `after ${String(rounds.length)} rounds of the owner's review.${rounds.some((r) => r.stated !== void 0) ? ' What was said for each earlier round is under "Earlier rounds of the review".' : ""}`;
7260
7302
  const body = [
7261
7303
  `Phase: ${phase} (the name the client gave it)`,
7262
7304
  OBSERVED_LABEL,
@@ -7265,12 +7307,12 @@ function renderBuildRecordV2Markdown(record2) {
7265
7307
  `- Project identifier: ${p.text(record2.observed.engagementId)}. Halfcycle keeps this project's records under this identifier.`,
7266
7308
  `- Record format: ${p.text(record2.format)}. This names the layout this file and the .json file beside it follow, for software that reads them.`
7267
7309
  ].join("\n"),
7268
- total === 1 ? "This phase was closed once." : `This phase was closed ${String(total)} times. The latest close is described first; each earlier close follows, as it was recorded when it was made.`,
7310
+ total === 1 ? roundsAfter === null ? "This phase was closed once." : `This phase was closed once, ${roundsAfter}` : `This phase was closed ${String(total)} times. The latest close is described first; each earlier close follows, as it was recorded when it was made.${roundsAfter === null ? "" : ` The latest close came ${roundsAfter}`}`,
7269
7311
  ...renderChecks(record2.observed.checks, p),
7270
- ...renderClose(total === 1 ? "## The close" : `## The latest close (close ${String(latest.sequence)} of ${String(total)})`, latest, attestedBySequence.get(latest.sequence), record2.observed.checks.state, p)
7312
+ ...renderClose(total === 1 ? "## The close" : `## The latest close (close ${String(latest.sequence)} of ${String(total)})`, latest, attestedBySequence.get(latest.sequence), record2.observed.checks.state, p, rounds.length > 1)
7271
7313
  ];
7272
7314
  if (record2.format === "halfcycle-build-record/v3")
7273
- body.push(...renderReview(record2, p));
7315
+ body.push(...renderReview(record2, p), ...renderEarlierRounds(record2, p));
7274
7316
  if (total > 1) {
7275
7317
  body.push("## Earlier closes");
7276
7318
  for (const close of closes.slice(0, -1)) {
@@ -8891,7 +8933,7 @@ ${redraw}`;
8891
8933
  exitCode: 1
8892
8934
  };
8893
8935
  }
8894
- const stdout = listed + `${approvalLine2(shownPhase, outcome.phaseNumber, outcome.typedApprovalOffered, deps.pinnedClientVersion(repoRoot), written.entries, stage.credential.engagementId)}
8936
+ const stdout = outcome.state === "approved" ? listed : listed + `${approvalLine2(shownPhase, outcome.phaseNumber, outcome.typedApprovalOffered, deps.pinnedClientVersion(repoRoot), written.entries, stage.credential.engagementId)}
8895
8937
  `;
8896
8938
  return { stdout, stderr: warnings, exitCode: 0 };
8897
8939
  }
@@ -9636,6 +9678,7 @@ var REASON_PLACEHOLDER = {
9636
9678
  "open-phase": "<why you are opening it anyway>"
9637
9679
  };
9638
9680
  var OWN_WORDS = {
9681
+ "--actor": "name, the one you go by as the agent",
9639
9682
  "--reason": "reason",
9640
9683
  "--evidence": "evidence",
9641
9684
  "--finding": "finding"
@@ -10834,7 +10877,7 @@ ${PROJECT_RESET_LINE}
10834
10877
  }
10835
10878
  process.stdout.write(`[halfcycle] Found: ${foundLine}
10836
10879
  `);
10837
- process.stdout.write(`[halfcycle] Set up: ${written} file${written === 1 ? "" : "s"} written${merged > 0 ? ` (${merged} merged)` : ""}, ${credential ? "guards armed on every edit" : "not checked \u2014 this copy is not this account\u2019s project"}
10880
+ process.stdout.write(`[halfcycle] Set up: ${written} file${written === 1 ? "" : "s"} written${merged > 0 ? ` (${merged} merged)` : ""}, ${credential ? "checked on every edit" : "not checked \u2014 this copy is not this account\u2019s project"}
10838
10881
  `);
10839
10882
  if (result.notShared)
10840
10883
  process.stdout.write(`${renderNotShared(result.notShared)}