terminalhire 0.41.2 → 0.42.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.
@@ -166,24 +166,8 @@ function nextPolledState(from, observed) {
166
166
  function nowISO() {
167
167
  return (/* @__PURE__ */ new Date()).toISOString();
168
168
  }
169
- function defangText(s) {
170
- return typeof s === "string" ? s.replace(CONTROL_CHARS, "") : s;
171
- }
172
- function finiteAmount(a) {
173
- if (typeof a === "number") return Number.isFinite(a) ? a : null;
174
- if (typeof a !== "string" || a.trim() === "") return null;
175
- const n = Number(a);
176
- return Number.isFinite(n) ? n : null;
177
- }
178
169
  function normalizeClaim(c) {
179
- return {
180
- ...c,
181
- kind: c.kind ?? "bounty",
182
- policy: c.policy ?? null,
183
- title: defangText(c.title),
184
- repoFullName: defangText(c.repoFullName),
185
- amountUSD: finiteAmount(c.amountUSD)
186
- };
170
+ return { ...c, kind: c.kind ?? "bounty", policy: c.policy ?? null };
187
171
  }
188
172
  function readClaims() {
189
173
  try {
@@ -305,7 +289,7 @@ function acceptedPRRate(claims = readClaims()) {
305
289
  const merged = claims.filter((c) => c.state === "merged").length;
306
290
  return { merged, total, rate: total === 0 ? 0 : merged / total };
307
291
  }
308
- var TERMINALHIRE_DIR3, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS, CONTROL_CHARS;
292
+ var TERMINALHIRE_DIR3, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
309
293
  var init_claims = __esm({
310
294
  "src/claims.ts"() {
311
295
  "use strict";
@@ -361,7 +345,6 @@ var init_claims = __esm({
361
345
  ]),
362
346
  submitted: /* @__PURE__ */ new Set(["claimed", "working", "in-review", "ready"])
363
347
  };
364
- CONTROL_CHARS = /[\x00-\x1f\x7f-\x9f]/g;
365
348
  }
366
349
  });
367
350
 
@@ -11338,24 +11338,8 @@ function nextPolledState(from, observed) {
11338
11338
  function nowISO2() {
11339
11339
  return (/* @__PURE__ */ new Date()).toISOString();
11340
11340
  }
11341
- function defangText(s) {
11342
- return typeof s === "string" ? s.replace(CONTROL_CHARS2, "") : s;
11343
- }
11344
- function finiteAmount(a) {
11345
- if (typeof a === "number") return Number.isFinite(a) ? a : null;
11346
- if (typeof a !== "string" || a.trim() === "") return null;
11347
- const n = Number(a);
11348
- return Number.isFinite(n) ? n : null;
11349
- }
11350
11341
  function normalizeClaim(c) {
11351
- return {
11352
- ...c,
11353
- kind: c.kind ?? "bounty",
11354
- policy: c.policy ?? null,
11355
- title: defangText(c.title),
11356
- repoFullName: defangText(c.repoFullName),
11357
- amountUSD: finiteAmount(c.amountUSD)
11358
- };
11342
+ return { ...c, kind: c.kind ?? "bounty", policy: c.policy ?? null };
11359
11343
  }
11360
11344
  function readClaims() {
11361
11345
  try {
@@ -11477,7 +11461,7 @@ function acceptedPRRate(claims = readClaims()) {
11477
11461
  const merged = claims.filter((c) => c.state === "merged").length;
11478
11462
  return { merged, total, rate: total === 0 ? 0 : merged / total };
11479
11463
  }
11480
- var TERMINALHIRE_DIR5, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS, CONTROL_CHARS2;
11464
+ var TERMINALHIRE_DIR5, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
11481
11465
  var init_claims = __esm({
11482
11466
  "src/claims.ts"() {
11483
11467
  "use strict";
@@ -11533,7 +11517,6 @@ var init_claims = __esm({
11533
11517
  ]),
11534
11518
  submitted: /* @__PURE__ */ new Set(["claimed", "working", "in-review", "ready"])
11535
11519
  };
11536
- CONTROL_CHARS2 = /[\x00-\x1f\x7f-\x9f]/g;
11537
11520
  }
11538
11521
  });
11539
11522
 
@@ -10638,24 +10638,8 @@ function nextPolledState(from, observed) {
10638
10638
  function nowISO() {
10639
10639
  return (/* @__PURE__ */ new Date()).toISOString();
10640
10640
  }
10641
- function defangText(s) {
10642
- return typeof s === "string" ? s.replace(CONTROL_CHARS2, "") : s;
10643
- }
10644
- function finiteAmount(a) {
10645
- if (typeof a === "number") return Number.isFinite(a) ? a : null;
10646
- if (typeof a !== "string" || a.trim() === "") return null;
10647
- const n = Number(a);
10648
- return Number.isFinite(n) ? n : null;
10649
- }
10650
10641
  function normalizeClaim(c) {
10651
- return {
10652
- ...c,
10653
- kind: c.kind ?? "bounty",
10654
- policy: c.policy ?? null,
10655
- title: defangText(c.title),
10656
- repoFullName: defangText(c.repoFullName),
10657
- amountUSD: finiteAmount(c.amountUSD)
10658
- };
10642
+ return { ...c, kind: c.kind ?? "bounty", policy: c.policy ?? null };
10659
10643
  }
10660
10644
  function readClaims() {
10661
10645
  try {
@@ -10777,7 +10761,7 @@ function acceptedPRRate(claims = readClaims()) {
10777
10761
  const merged = claims.filter((c) => c.state === "merged").length;
10778
10762
  return { merged, total, rate: total === 0 ? 0 : merged / total };
10779
10763
  }
10780
- var TERMINALHIRE_DIR2, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS, CONTROL_CHARS2;
10764
+ var TERMINALHIRE_DIR2, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
10781
10765
  var init_claims = __esm({
10782
10766
  "src/claims.ts"() {
10783
10767
  "use strict";
@@ -10833,7 +10817,6 @@ var init_claims = __esm({
10833
10817
  ]),
10834
10818
  submitted: /* @__PURE__ */ new Set(["claimed", "working", "in-review", "ready"])
10835
10819
  };
10836
- CONTROL_CHARS2 = /[\x00-\x1f\x7f-\x9f]/g;
10837
10820
  }
10838
10821
  });
10839
10822
 
@@ -11184,6 +11167,83 @@ var init_github_auth = __esm({
11184
11167
  }
11185
11168
  });
11186
11169
 
11170
+ // bin/founder-note-sync.js
11171
+ var founder_note_sync_exports = {};
11172
+ __export(founder_note_sync_exports, {
11173
+ acknowledgeFounderNotes: () => acknowledgeFounderNotes,
11174
+ computeFounderNotes: () => computeFounderNotes,
11175
+ fetchFounderNotes: () => fetchFounderNotes,
11176
+ formatNote: () => formatNote,
11177
+ noteKey: () => noteKey,
11178
+ syncFounderNotes: () => syncFounderNotes
11179
+ });
11180
+ async function fetchFounderNotes(pushToken, fetchImpl = fetch) {
11181
+ if (typeof pushToken !== "string" || pushToken.length === 0) return null;
11182
+ try {
11183
+ const res = await fetchImpl(`${CLAIM_SYNC_BASE2}/api/claim/notes`, {
11184
+ method: "POST",
11185
+ headers: { "Content-Type": "application/json" },
11186
+ body: JSON.stringify({ pushToken }),
11187
+ signal: AbortSignal.timeout(15e3)
11188
+ });
11189
+ if (!res?.ok) return null;
11190
+ const body = await res.json();
11191
+ if (!body || !Array.isArray(body.notes)) return null;
11192
+ const notes = body.notes.filter(
11193
+ (n) => n && typeof n.claimId === "string" && n.claimId !== "" && typeof n.note === "string" && n.note !== "" && typeof n.at === "string" && (n.kind === "founder_note" || n.kind === "feedback")
11194
+ );
11195
+ return { notes, latestAt: typeof body.latestAt === "string" ? body.latestAt : null };
11196
+ } catch {
11197
+ return null;
11198
+ }
11199
+ }
11200
+ function noteKey(note) {
11201
+ return `${note.claimId}@${note.at}`;
11202
+ }
11203
+ function computeFounderNotes(notes, previous) {
11204
+ const keys = Array.isArray(notes) ? notes.map(noteKey) : [];
11205
+ const prior = previous && Array.isArray(previous.seen) ? new Set(previous.seen) : /* @__PURE__ */ new Set();
11206
+ const seen = keys.filter((k) => prior.has(k));
11207
+ return { count: keys.length - seen.length, seen };
11208
+ }
11209
+ function acknowledgeFounderNotes(notes) {
11210
+ const keys = Array.isArray(notes) ? notes.map(noteKey) : [];
11211
+ return { count: 0, seen: keys };
11212
+ }
11213
+ async function syncFounderNotes({
11214
+ readAutoMarker: readAutoMarker2,
11215
+ readPushTokenEnc: readPushTokenEnc2,
11216
+ readPrevious,
11217
+ fetchImpl = fetch,
11218
+ timeoutMs = 15e3
11219
+ } = {}) {
11220
+ try {
11221
+ const marker = readAutoMarker2();
11222
+ const token = await readPushTokenEnc2();
11223
+ if (!marker || !token) return null;
11224
+ const answer = await fetchFounderNotes(
11225
+ token,
11226
+ (url, init) => fetchImpl(url, { ...init, signal: AbortSignal.timeout(timeoutMs) })
11227
+ );
11228
+ if (!answer) return null;
11229
+ return computeFounderNotes(answer.notes, readPrevious());
11230
+ } catch {
11231
+ return null;
11232
+ }
11233
+ }
11234
+ function formatNote(note) {
11235
+ const label = note.kind === "feedback" ? "changes requested" : "note";
11236
+ return ` ${note.at.slice(0, 16).replace("T", " ")} [${label}] ${note.claimId}
11237
+ ${note.note.split("\n").join("\n ")}`;
11238
+ }
11239
+ var CLAIM_SYNC_BASE2;
11240
+ var init_founder_note_sync = __esm({
11241
+ "bin/founder-note-sync.js"() {
11242
+ "use strict";
11243
+ CLAIM_SYNC_BASE2 = "https://terminalhire.com";
11244
+ }
11245
+ });
11246
+
11187
11247
  // ../../packages/core/src/policy-audit.ts
11188
11248
  function fence(nonce, body) {
11189
11249
  return `<<<UNTRUSTED-${nonce}
@@ -26339,6 +26399,7 @@ async function syncFounderVerdicts({
26339
26399
  }
26340
26400
 
26341
26401
  // bin/jpi-claim.js
26402
+ init_founder_note_sync();
26342
26403
  var TERMINALHIRE_DIR11 = process.env.TERMINALHIRE_DIR || join17(homedir11(), ".terminalhire");
26343
26404
  var INDEX_CACHE_FILE2 = join17(TERMINALHIRE_DIR11, "index-cache.json");
26344
26405
  var CLAIM_PUSH_MARKER = join17(TERMINALHIRE_DIR11, "claim-push.json");
@@ -26361,7 +26422,7 @@ function markClaimNudged(id) {
26361
26422
  }
26362
26423
  }
26363
26424
  var API_URL = process.env["TERMINALHIRE_API_URL"] ?? process.env["JPI_API_URL"] ?? "https://terminalhire.com";
26364
- var CLAIM_SYNC_BASE2 = "https://terminalhire.com";
26425
+ var CLAIM_SYNC_BASE3 = "https://terminalhire.com";
26365
26426
  var CLAIM_CONSENT_VERSION = 1;
26366
26427
  var CLAIM_POLL_INTERVAL_MS = 2e3;
26367
26428
  var CLAIM_POLL_TIMEOUT_MS = 10 * 60 * 1e3;
@@ -27003,10 +27064,7 @@ async function pollPR(prUrl) {
27003
27064
  }
27004
27065
  }
27005
27066
  function fmtAmount(a) {
27006
- if (a == null) return "$\u2014";
27007
- if (typeof a === "string" && a.trim() === "") return "$\u2014";
27008
- const n = typeof a === "number" ? a : Number(a);
27009
- return Number.isFinite(n) ? "$" + n.toLocaleString() : "$\u2014";
27067
+ return a != null ? "$" + a.toLocaleString() : "$\u2014";
27010
27068
  }
27011
27069
  function fmtClaimAmount(c) {
27012
27070
  return c.kind === "contribution" ? "contribution" : fmtAmount(c.amountUSD);
@@ -27199,7 +27257,7 @@ async function mintRegistrationProof() {
27199
27257
  console.log(" GitHub identity has to be verified once in the browser.");
27200
27258
  let begin;
27201
27259
  try {
27202
- const r = await fetch(`${CLAIM_SYNC_BASE2}/api/claim-sync/begin`, {
27260
+ const r = await fetch(`${CLAIM_SYNC_BASE3}/api/claim-sync/begin`, {
27203
27261
  method: "POST",
27204
27262
  headers: { "Content-Type": "application/json" },
27205
27263
  body: JSON.stringify({ hostname: osHostname() }),
@@ -27232,7 +27290,7 @@ async function mintRegistrationProof() {
27232
27290
  let statusRes;
27233
27291
  try {
27234
27292
  statusRes = await fetch(
27235
- `${CLAIM_SYNC_BASE2}/api/claim-sync/status?challenge=${encodeURIComponent(challenge)}`,
27293
+ `${CLAIM_SYNC_BASE3}/api/claim-sync/status?challenge=${encodeURIComponent(challenge)}`,
27236
27294
  { signal: AbortSignal.timeout(1e4) }
27237
27295
  );
27238
27296
  } catch {
@@ -27359,7 +27417,7 @@ terminalhire claim: refusing to record \u2014 ${reason}
27359
27417
  };
27360
27418
  if (!auth) await acquireProofAuth();
27361
27419
  console.log("\n Registering this claim with terminalhire (founder posting)...");
27362
- const sendRegistration = async (includeExpectation) => fetch(`${CLAIM_SYNC_BASE2}/api/claim/register`, {
27420
+ const sendRegistration = async (includeExpectation) => fetch(`${CLAIM_SYNC_BASE3}/api/claim/register`, {
27363
27421
  method: "POST",
27364
27422
  headers: { "Content-Type": "application/json" },
27365
27423
  body: JSON.stringify({
@@ -27939,7 +27997,7 @@ async function resolveIssueOutcome(c, res, claims) {
27939
27997
  async function fetchFounderApprovals(pushToken, fetchImpl = fetch) {
27940
27998
  if (typeof pushToken !== "string" || pushToken.length === 0) return null;
27941
27999
  try {
27942
- const res = await fetchImpl(`${CLAIM_SYNC_BASE2}/api/claim/approvals`, {
28000
+ const res = await fetchImpl(`${CLAIM_SYNC_BASE3}/api/claim/approvals`, {
27943
28001
  method: "POST",
27944
28002
  headers: { "Content-Type": "application/json" },
27945
28003
  body: JSON.stringify({ pushToken }),
@@ -28344,7 +28402,7 @@ function startableRow(c) {
28344
28402
  }
28345
28403
  async function pickStartableClaim(claims, { prompt = ask, isTTY = process.stdin.isTTY } = {}) {
28346
28404
  const active = claims.listClaims({ active: true });
28347
- const { approvalsChecked, approvalsUnavailable } = await syncFounderApprovals(claims, active);
28405
+ await syncFounderApprovals(claims, active);
28348
28406
  const startable = claims.listClaims({ active: true }).filter((c) => c.state === "claimed");
28349
28407
  if (startable.length === 0) {
28350
28408
  console.log("No claims ready to start. Claim one first: terminalhire claim <ref>");
@@ -28372,24 +28430,23 @@ Which one? (1-${startable.length}, or q to quit) `);
28372
28430
  Nothing started \u2014 '${answer}' is not one of 1-${startable.length}.`);
28373
28431
  return null;
28374
28432
  }
28375
- return { id: startable[n - 1].id, approvalsChecked, approvalsUnavailable };
28433
+ return startable[n - 1].id;
28376
28434
  }
28377
28435
  async function cmdStart(id, flags = {}) {
28378
28436
  const claims = await Promise.resolve().then(() => (init_claims(), claims_exports));
28379
- let approvalsChecked = false;
28380
- let approvalsUnavailable = false;
28381
28437
  if (!id) {
28382
28438
  const picked = await pickStartableClaim(claims);
28383
28439
  if (!picked) return;
28384
- ({ id, approvalsChecked, approvalsUnavailable } = picked);
28440
+ id = picked;
28385
28441
  }
28386
28442
  let claim = claims.findClaim(id);
28387
28443
  if (!claim) {
28388
28444
  console.error(`terminalhire claim: no claim with id '${id}'.`);
28389
28445
  process.exit(1);
28390
28446
  }
28391
- if (claim.approval?.state === "pending" && !approvalsChecked) {
28392
- ({ approvalsChecked, approvalsUnavailable } = await syncFounderApprovals(claims, [claim]));
28447
+ let approvalsChecked = false;
28448
+ if (claim.approval?.state === "pending") {
28449
+ ({ approvalsChecked } = await syncFounderApprovals(claims, [claim]));
28393
28450
  claim = claims.findClaim(id);
28394
28451
  }
28395
28452
  if (claim.worktreePath) {
@@ -28416,10 +28473,6 @@ ${sanitizeText(claim.title)}`);
28416
28473
  console.log(" same way.");
28417
28474
  if (shouldStatePending(claim, approvalsChecked)) {
28418
28475
  console.log("\n Access is pending \u2014 the founder has not approved your claim yet.");
28419
- } else if (approvalsUnavailable) {
28420
- console.log(
28421
- "\n Terminalhire could not check approvals right now; local state was preserved.\n The next step below still works \u2014 it asks the server directly."
28422
- );
28423
28476
  }
28424
28477
  printNextSteps([claim]);
28425
28478
  return;
@@ -28671,10 +28724,10 @@ var CLAIM_EVENT_LABEL = {
28671
28724
  rejected: "the founder rejected"
28672
28725
  };
28673
28726
  var LINE_BREAKS = /\r\n|[\r\n\v\f\u0085\u2028\u2029]/;
28674
- var CONTROL_CHARS3 = /[\u0000-\u001F\u007F-\u009F]/g;
28727
+ var CONTROL_CHARS2 = /[\u0000-\u001F\u007F-\u009F]/g;
28675
28728
  function terminalSafeLines(raw) {
28676
28729
  if (typeof raw !== "string" || raw === "") return [];
28677
- return raw.split(LINE_BREAKS).map((l) => l.replace(CONTROL_CHARS3, ""));
28730
+ return raw.split(LINE_BREAKS).map((l) => l.replace(CONTROL_CHARS2, ""));
28678
28731
  }
28679
28732
  function terminalSafeInline(raw) {
28680
28733
  return terminalSafeLines(raw).join(" ");
@@ -28798,7 +28851,7 @@ async function cmdSlice(id, flags = {}) {
28798
28851
  const pushToken = await requireReadPushToken("fetching your granted slice");
28799
28852
  let res;
28800
28853
  try {
28801
- res = await fetch(`${CLAIM_SYNC_BASE2}/api/claim/slice`, {
28854
+ res = await fetch(`${CLAIM_SYNC_BASE3}/api/claim/slice`, {
28802
28855
  method: "POST",
28803
28856
  headers: { "Content-Type": "application/json" },
28804
28857
  body: JSON.stringify({
@@ -28906,7 +28959,7 @@ async function cmdRuns(id, flags = {}) {
28906
28959
  const fetchOnce = async () => {
28907
28960
  let res;
28908
28961
  try {
28909
- res = await fetch(`${CLAIM_SYNC_BASE2}/api/patch/runs`, {
28962
+ res = await fetch(`${CLAIM_SYNC_BASE3}/api/patch/runs`, {
28910
28963
  method: "POST",
28911
28964
  headers: { "Content-Type": "application/json" },
28912
28965
  body: JSON.stringify({
@@ -29054,7 +29107,7 @@ async function submitFounderPatch({ claims, claim, id, wt, flags }) {
29054
29107
  console.log("\n Submitting the patch through terminalhire...");
29055
29108
  let res;
29056
29109
  try {
29057
- res = await fetch(`${CLAIM_SYNC_BASE2}/api/patch`, {
29110
+ res = await fetch(`${CLAIM_SYNC_BASE3}/api/patch`, {
29058
29111
  method: "POST",
29059
29112
  headers: { "Content-Type": "application/json" },
29060
29113
  body: JSON.stringify(submission),
@@ -29627,7 +29680,7 @@ async function cmdPush({ keepUpdated = false } = {}) {
29627
29680
  console.log("\n Starting browser verification...");
29628
29681
  let begin;
29629
29682
  try {
29630
- const r = await fetch(`${CLAIM_SYNC_BASE2}/api/claim-sync/begin`, {
29683
+ const r = await fetch(`${CLAIM_SYNC_BASE3}/api/claim-sync/begin`, {
29631
29684
  method: "POST",
29632
29685
  headers: { "Content-Type": "application/json" },
29633
29686
  body: JSON.stringify({ hostname: osHostname() }),
@@ -29670,7 +29723,7 @@ async function cmdPush({ keepUpdated = false } = {}) {
29670
29723
  let statusRes;
29671
29724
  try {
29672
29725
  statusRes = await fetch(
29673
- `${CLAIM_SYNC_BASE2}/api/claim-sync/status?challenge=${encodeURIComponent(challenge)}`,
29726
+ `${CLAIM_SYNC_BASE3}/api/claim-sync/status?challenge=${encodeURIComponent(challenge)}`,
29674
29727
  { signal: AbortSignal.timeout(1e4) }
29675
29728
  );
29676
29729
  } catch {
@@ -29701,7 +29754,7 @@ async function cmdPush({ keepUpdated = false } = {}) {
29701
29754
  console.log("\n Verified. Sharing your claims...");
29702
29755
  let res;
29703
29756
  try {
29704
- res = await fetch(`${CLAIM_SYNC_BASE2}/api/claim-sync`, {
29757
+ res = await fetch(`${CLAIM_SYNC_BASE3}/api/claim-sync`, {
29705
29758
  method: "POST",
29706
29759
  headers: { "Content-Type": "application/json" },
29707
29760
  // autoConsent is included ONLY when the dev opted into background updates —
@@ -29828,7 +29881,7 @@ async function cmdRevoke() {
29828
29881
  console.log("\n Requesting deletion...");
29829
29882
  let res;
29830
29883
  try {
29831
- res = await fetch(`${CLAIM_SYNC_BASE2}/api/claim-sync`, {
29884
+ res = await fetch(`${CLAIM_SYNC_BASE3}/api/claim-sync`, {
29832
29885
  method: "DELETE",
29833
29886
  headers: { "Content-Type": "application/json" },
29834
29887
  body: JSON.stringify({ login, deleteToken }),
@@ -30005,6 +30058,50 @@ async function cmdAudit(id, flags = {}) {
30005
30058
  }
30006
30059
  renderAudit(view);
30007
30060
  }
30061
+ async function cmdNotes(flags) {
30062
+ let pushToken = null;
30063
+ try {
30064
+ pushToken = await readPushTokenEnc();
30065
+ } catch {
30066
+ }
30067
+ if (!pushToken) {
30068
+ console.error("terminalhire claim notes: needs background push enrolment.");
30069
+ console.error(" Enrol once: terminalhire claim --push --keep-updated");
30070
+ process.exit(1);
30071
+ }
30072
+ const answer = await fetchFounderNotes(pushToken);
30073
+ if (answer === null) {
30074
+ console.error("terminalhire claim notes: could not reach terminalhire just now.");
30075
+ console.error(' This is NOT "no notes" \u2014 try again shortly.');
30076
+ process.exit(1);
30077
+ }
30078
+ if (flags.json) {
30079
+ console.log(JSON.stringify(answer, null, 2));
30080
+ await acknowledgeNotesQuietly(answer.notes);
30081
+ return;
30082
+ }
30083
+ if (answer.notes.length === 0) {
30084
+ console.log("\n No notes from founders on your claims.\n");
30085
+ await acknowledgeNotesQuietly(answer.notes);
30086
+ return;
30087
+ }
30088
+ console.log(
30089
+ `
30090
+ ${answer.notes.length} note${answer.notes.length === 1 ? "" : "s"} from founders:
30091
+ `
30092
+ );
30093
+ for (const note of answer.notes) console.log(formatNote(note));
30094
+ console.log("");
30095
+ await acknowledgeNotesQuietly(answer.notes);
30096
+ }
30097
+ async function acknowledgeNotesQuietly(notes) {
30098
+ try {
30099
+ const { acknowledgeFounderNotes: acknowledgeFounderNotes2 } = await Promise.resolve().then(() => (init_founder_note_sync(), founder_note_sync_exports));
30100
+ const { updateIndexCache: updateIndexCache2 } = await Promise.resolve().then(() => (init_cache_store(), cache_store_exports));
30101
+ updateIndexCache2({ founderNotes: acknowledgeFounderNotes2(notes) });
30102
+ } catch {
30103
+ }
30104
+ }
30008
30105
  async function run() {
30009
30106
  const verb = process.argv[2];
30010
30107
  const rawArgs = process.argv.slice(3).map((a) => a === "-y" ? "--yes" : a);
@@ -30067,9 +30164,12 @@ async function run() {
30067
30164
  case "audit":
30068
30165
  await cmdAudit(positional[0], flags);
30069
30166
  break;
30167
+ case "notes":
30168
+ await cmdNotes(flags);
30169
+ break;
30070
30170
  default:
30071
30171
  console.error(
30072
- `terminalhire claim: unknown verb '${verb ?? ""}'. Expected: preview | record | start | attach | slice | list | status | update | submit | runs | audit | release`
30172
+ `terminalhire claim: unknown verb '${verb ?? ""}'. Expected: preview | record | start | attach | slice | list | status | update | submit | runs | notes | audit | release`
30073
30173
  );
30074
30174
  process.exit(1);
30075
30175
  }
@@ -3617,24 +3617,8 @@ function nextPolledState(from, observed) {
3617
3617
  function nowISO2() {
3618
3618
  return (/* @__PURE__ */ new Date()).toISOString();
3619
3619
  }
3620
- function defangText(s) {
3621
- return typeof s === "string" ? s.replace(CONTROL_CHARS2, "") : s;
3622
- }
3623
- function finiteAmount(a) {
3624
- if (typeof a === "number") return Number.isFinite(a) ? a : null;
3625
- if (typeof a !== "string" || a.trim() === "") return null;
3626
- const n = Number(a);
3627
- return Number.isFinite(n) ? n : null;
3628
- }
3629
3620
  function normalizeClaim(c) {
3630
- return {
3631
- ...c,
3632
- kind: c.kind ?? "bounty",
3633
- policy: c.policy ?? null,
3634
- title: defangText(c.title),
3635
- repoFullName: defangText(c.repoFullName),
3636
- amountUSD: finiteAmount(c.amountUSD)
3637
- };
3621
+ return { ...c, kind: c.kind ?? "bounty", policy: c.policy ?? null };
3638
3622
  }
3639
3623
  function readClaims() {
3640
3624
  try {
@@ -3756,7 +3740,7 @@ function acceptedPRRate(claims = readClaims()) {
3756
3740
  const merged = claims.filter((c) => c.state === "merged").length;
3757
3741
  return { merged, total, rate: total === 0 ? 0 : merged / total };
3758
3742
  }
3759
- var TERMINALHIRE_DIR7, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS, CONTROL_CHARS2;
3743
+ var TERMINALHIRE_DIR7, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
3760
3744
  var init_claims = __esm({
3761
3745
  "src/claims.ts"() {
3762
3746
  "use strict";
@@ -3812,7 +3796,6 @@ var init_claims = __esm({
3812
3796
  ]),
3813
3797
  submitted: /* @__PURE__ */ new Set(["claimed", "working", "in-review", "ready"])
3814
3798
  };
3815
- CONTROL_CHARS2 = /[\x00-\x1f\x7f-\x9f]/g;
3816
3799
  }
3817
3800
  });
3818
3801