@toon-protocol/rig 2.1.0 → 2.2.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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { G as GitObjectType, P as Publisher, F as FeeRates, a as PublishReceipt } from './publisher-Cdr1H1hg.js';
2
- export { C as COMMENT_KIND, b as GitObject, c as GitObjectUpload, M as MAX_OBJECT_SIZE, R as REPOSITORY_STATE_KIND, S as StatusKind, U as UnsignedEvent, d as UploadReceipt, e as buildComment, f as buildIssue, g as buildPatch, h as buildRepoAnnouncement, i as buildRepoRefs, j as buildStatus, k as createGitBlob, l as createGitCommit, m as createGitTag, n as createGitTree, o as hashGitObject } from './publisher-Cdr1H1hg.js';
1
+ import { c as GitObjectType, P as Publisher, F as FeeRates, b as PublishReceipt } from './publisher-CrwaNQrK.js';
2
+ export { C as COMMENT_KIND, d as GitObject, G as GitObjectUpload, M as MAX_OBJECT_SIZE, R as REPOSITORY_STATE_KIND, S as StatusKind, U as UnsignedEvent, a as UploadReceipt, e as buildComment, f as buildIssue, g as buildPatch, h as buildRepoAnnouncement, i as buildRepoRefs, j as buildStatus, k as createGitBlob, l as createGitCommit, m as createGitTag, n as createGitTree, o as hashGitObject } from './publisher-CrwaNQrK.js';
3
3
  import '@toon-protocol/core/nip34';
4
4
 
5
5
  /**
@@ -209,6 +209,18 @@ interface NostrEvent {
209
209
  content: string;
210
210
  sig: string;
211
211
  }
212
+ /** NIP-01 subscription filter (only the fields rig's readers send). */
213
+ interface NostrFilter {
214
+ ids?: string[];
215
+ kinds?: number[];
216
+ authors?: string[];
217
+ '#d'?: string[];
218
+ /** Repo address tag filter, e.g. `30617:<owner>:<repoId>` (#278 tracker). */
219
+ '#a'?: string[];
220
+ /** Event-reference tag filter (#278 tracker: statuses + comments). */
221
+ '#e'?: string[];
222
+ limit?: number;
223
+ }
212
224
  /**
213
225
  * Minimal structural WebSocket type — satisfied by the WHATWG WebSocket
214
226
  * global (Node >= 22 / undici, browsers) and by the `ws` package.
@@ -270,6 +282,12 @@ interface RemoteState {
270
282
  */
271
283
  resolveMissing(shas: string[]): Promise<Map<string, string>>;
272
284
  }
285
+ /**
286
+ * Query one relay: send a REQ, collect EVENTs until EOSE, then CLOSE.
287
+ * Mirrors rig's `queryRelay` (partial results on timeout / early close).
288
+ * Exported for reuse by the network-bootstrap discovery (kind:10032).
289
+ */
290
+ declare function queryRelay(relayUrl: string, filter: NostrFilter, timeoutMs: number, webSocketFactory: WebSocketFactory): Promise<NostrEvent[]>;
273
291
  /**
274
292
  * Fetch the remote repository state from the relay(s).
275
293
  *
@@ -283,6 +301,251 @@ interface RemoteState {
283
301
  */
284
302
  declare function fetchRemoteState(options: FetchRemoteStateOptions): Promise<RemoteState>;
285
303
 
304
+ /**
305
+ * The Git-from-TOON READ pipeline core (#278): download git object bodies
306
+ * from Arweave gateways, verify them against their SHA-1, and walk the
307
+ * object graph to prove a ref closure is complete.
308
+ *
309
+ * This is the CLI counterpart of rig-web's proven browser read path
310
+ * (`web/arweave-client.ts` + `web/git-objects.ts` + the commit walker) — the
311
+ * logic is mirrored, not imported, because the SPA package is not a library.
312
+ *
313
+ * Everything here is FREE (reads only: Arweave gateway GETs + the GraphQL
314
+ * Git-SHA resolver) and pure of git — materializing objects into a real
315
+ * repository lives in ./materialize.ts.
316
+ *
317
+ * INTEGRITY IS NON-NEGOTIABLE: an Arweave upload stores the object BODY
318
+ * (content after the envelope NUL). Re-wrapping the body as each of the four
319
+ * git object types and comparing the envelope SHA-1 against the expected SHA
320
+ * both AUTHENTICATES the bytes and DISCOVERS the object's type in one step —
321
+ * a body that matches under no type is rejected as corrupt/tampered, never
322
+ * written.
323
+ */
324
+
325
+ /** A downloaded git object: SHA-verified body + the type that verified it. */
326
+ interface FetchedObject {
327
+ /** Full 40-hex SHA-1 (verified against the body). */
328
+ sha: string;
329
+ type: GitObjectType;
330
+ /** Raw object body (content only, no envelope header). May be binary. */
331
+ body: Buffer;
332
+ }
333
+ /** WHATWG-fetch seam (injectable for tests). */
334
+ type FetchLike = (url: string, init?: {
335
+ signal?: AbortSignal;
336
+ }) => Promise<{
337
+ ok: boolean;
338
+ arrayBuffer(): Promise<ArrayBuffer>;
339
+ }>;
340
+ interface GatewayFetchOptions {
341
+ /** Ordered gateway base URLs (default: the shared preference list). */
342
+ gateways?: readonly string[];
343
+ /** fetch implementation (default: global fetch). */
344
+ fetchFn?: FetchLike;
345
+ /** Per-request timeout in milliseconds. */
346
+ timeoutMs?: number;
347
+ }
348
+ interface DownloadOptions extends GatewayFetchOptions {
349
+ /** Maximum concurrent gateway downloads (default {@link DEFAULT_CONCURRENCY}). */
350
+ concurrency?: number;
351
+ /** Progress callback, called once per finished object. */
352
+ onObject?: (done: number, total: number) => void;
353
+ }
354
+ /** Result of {@link downloadGitObjects}. */
355
+ interface DownloadResult {
356
+ /** SHA → verified object, for every SHA that could be downloaded. */
357
+ objects: Map<string, FetchedObject>;
358
+ /** SHAs whose txId 404'd/errored on EVERY gateway (propagation lag). */
359
+ unavailable: {
360
+ sha: string;
361
+ txId: string;
362
+ }[];
363
+ }
364
+ /** Default parallel-download cap. */
365
+ declare const DEFAULT_CONCURRENCY = 8;
366
+ /**
367
+ * A downloaded body did not hash to its expected SHA under ANY git object
368
+ * type — corrupt or tampered content. The clone/fetch pipelines treat this
369
+ * as a hard failure: nothing is written.
370
+ */
371
+ declare class ObjectIntegrityError extends Error {
372
+ /** The objects that failed verification. */
373
+ readonly objects: {
374
+ sha: string;
375
+ txId: string;
376
+ }[];
377
+ constructor(
378
+ /** The objects that failed verification. */
379
+ objects: {
380
+ sha: string;
381
+ txId: string;
382
+ }[]);
383
+ }
384
+ /**
385
+ * Verify a downloaded body against its expected SHA-1 by trying the four git
386
+ * envelope types. Returns the verified object, or null when no type matches
387
+ * (corrupt/tampered bytes).
388
+ */
389
+ declare function verifyObjectBody(expectedSha: string, bytes: Uint8Array): FetchedObject | null;
390
+ /**
391
+ * Fetch raw bytes for an Arweave tx id, trying each gateway in preference
392
+ * order. Returns null when every gateway fails (404 / error / timeout).
393
+ */
394
+ declare function fetchTxBytes(txId: string, options?: GatewayFetchOptions): Promise<Uint8Array | null>;
395
+ /**
396
+ * Download + verify a batch of git objects (sha → Arweave txId) with a
397
+ * concurrency cap and per-gateway fallback.
398
+ *
399
+ * Objects that 404 on every gateway are reported in `unavailable` (Arweave
400
+ * propagation lag — the caller decides whether that is fatal). Objects whose
401
+ * bytes fail SHA-1 verification throw {@link ObjectIntegrityError}: corrupt
402
+ * content is NEVER returned.
403
+ */
404
+ declare function downloadGitObjects(entries: Iterable<[sha: string, txId: string]>, options?: DownloadOptions): Promise<DownloadResult>;
405
+ /**
406
+ * SHAs an object references inside the SAME repository:
407
+ * - commit → its tree + parents
408
+ * - tree → entry SHAs, EXCEPT gitlinks (mode 160000: submodule commits
409
+ * live in another repository and are never present — git fsck
410
+ * skips them too)
411
+ * - tag → the tagged object
412
+ * - blob → nothing
413
+ */
414
+ declare function referencedShas(object: FetchedObject): string[];
415
+ /** Result of {@link walkClosure}. */
416
+ interface ClosureResult {
417
+ /** Every SHA reachable from the tips that lives in `objects`. */
418
+ reachable: Set<string>;
419
+ /** Reachable SHAs found NEITHER in `objects` nor in `presentLocally`. */
420
+ missing: string[];
421
+ }
422
+ /**
423
+ * Walk the object graph from the ref tips over the downloaded object set and
424
+ * report which reachable SHAs are missing. `presentLocally` marks SHAs that
425
+ * already exist in the destination repository — the walk does not descend
426
+ * into them (a consistent local repo carries its own closure; the same
427
+ * assumption `git fetch` makes).
428
+ */
429
+ declare function walkClosure(tips: Iterable<string>, objects: ReadonlyMap<string, FetchedObject>, presentLocally?: ReadonlySet<string>): ClosureResult;
430
+
431
+ /**
432
+ * The shared clone/fetch object-collection engine (#278).
433
+ *
434
+ * Given the remote's ref tips and its kind:30618 sha→Arweave-txId map, gather
435
+ * every object the refs need:
436
+ *
437
+ * 1. download the mapped objects the destination repo doesn't already have
438
+ * (parallel, gateway fallback chain, SHA-verified — ./object-fetch.ts);
439
+ * 2. walk the object graph from the tips (./object-fetch.ts walkClosure) —
440
+ * the local repository's objects count as present (git fetch's own
441
+ * assumption: a consistent repo carries its own closure);
442
+ * 3. SHAs the map doesn't cover are resolved through the Arweave GraphQL
443
+ * Git-SHA resolver (RemoteState.resolveMissing) and downloaded, looping
444
+ * until the closure is complete or no progress can be made.
445
+ *
446
+ * The result separates FATAL gaps (reachable objects that could not be
447
+ * obtained — usually Arweave gateway propagation lag, 10–20 min for fresh
448
+ * pushes) from harmless ones (mapped-but-unreachable objects, e.g. history
449
+ * that was force-pushed away). Corrupt objects throw ObjectIntegrityError
450
+ * from the download layer and never surface here.
451
+ */
452
+
453
+ /** A reachable object that could not be obtained. */
454
+ interface MissingObject {
455
+ sha: string;
456
+ /** The txId that failed on every gateway, or null when no txId resolved. */
457
+ txId: string | null;
458
+ }
459
+ interface CollectRepoObjectsOptions extends DownloadOptions {
460
+ /** Ref tip SHAs (commits or annotated tags) the closure must reach. */
461
+ tips: string[];
462
+ /** kind:30618 `arweave` tag map: git SHA → Arweave txId. */
463
+ shaToTxId: ReadonlyMap<string, string>;
464
+ /** GraphQL fallback for SHAs the map doesn't cover (RemoteState.resolveMissing). */
465
+ resolveMissing: (shas: string[]) => Promise<Map<string, string>>;
466
+ /** SHAs already present in the destination repository (fetch delta). */
467
+ presentLocally?: ReadonlySet<string>;
468
+ }
469
+ interface CollectRepoObjectsResult {
470
+ /** Verified objects to write, keyed by SHA. */
471
+ objects: Map<string, FetchedObject>;
472
+ /** Reachable SHAs that could not be obtained — FATAL for clone/fetch. */
473
+ missing: MissingObject[];
474
+ /** Mapped-but-unreachable SHAs that failed to download — warn only. */
475
+ skippedUnavailable: {
476
+ sha: string;
477
+ txId: string;
478
+ }[];
479
+ }
480
+ /** Collect (download + verify + close over) the objects the ref tips need. */
481
+ declare function collectRepoObjects(options: CollectRepoObjectsOptions): Promise<CollectRepoObjectsResult>;
482
+ /**
483
+ * The honest propagation-lag error text: which SHAs are unobtainable and why
484
+ * retrying later is the expected remedy.
485
+ */
486
+ declare function missingObjectsMessage(missing: MissingObject[], context: string): string;
487
+
488
+ /**
489
+ * Materialize downloaded git objects into a REAL repository (#278).
490
+ *
491
+ * Objects are written through git's own plumbing — `git hash-object -w
492
+ * --stdin -t <type>` with the raw body on stdin — so git computes, validates
493
+ * (syntax checks for trees/commits/tags), stores (loose object + zlib), and
494
+ * RETURNS the SHA. The returned SHA is compared against the expected one:
495
+ * a second, independent integrity gate after ./object-fetch.ts's envelope
496
+ * verification. Refs land via `git update-ref`, HEAD via `git symbolic-ref`.
497
+ *
498
+ * Same injection posture as GitRepoReader: child processes use
499
+ * `execFile`/`spawn` with argument ARRAYS (never a shell), and refnames are
500
+ * validated with `git check-ref-format` semantics before use.
501
+ */
502
+
503
+ /** A written object's SHA disagreed with what `git hash-object` computed. */
504
+ declare class ObjectWriteMismatchError extends Error {
505
+ readonly expectedSha: string;
506
+ readonly writtenSha: string;
507
+ constructor(expectedSha: string, writtenSha: string);
508
+ }
509
+ /**
510
+ * Conservative refname validation (superset-safe subset of
511
+ * `git check-ref-format`): must start `refs/`, no component may start with
512
+ * `-` or `.`, no `..`, no control/space/git-special characters, no trailing
513
+ * `/`, `.`, or `.lock`. Rejecting odd-but-legal names is fine — these
514
+ * refnames come from relay events, and a hostile relay must not be able to
515
+ * smuggle options or path traversal into git invocations.
516
+ */
517
+ declare function isSafeRefname(refname: string): boolean;
518
+ /**
519
+ * Write one object via `git hash-object -w --stdin -t <type>` (binary-safe
520
+ * stdin) and verify the SHA git computed matches the expected one.
521
+ */
522
+ declare function writeGitObject(repoPath: string, object: FetchedObject): Promise<void>;
523
+ /** Write a batch of verified objects into the repository (sequential). */
524
+ declare function writeGitObjects(repoPath: string, objects: Iterable<FetchedObject>): Promise<number>;
525
+ /** `git update-ref <refname> <sha>` with refname/SHA validation. */
526
+ declare function updateRef(repoPath: string, refname: string, sha: string): Promise<void>;
527
+ /** Point HEAD at a branch via `git symbolic-ref HEAD <refname>`. */
528
+ declare function setHeadSymref(repoPath: string, refname: string): Promise<void>;
529
+
530
+ /**
531
+ * Minimal bech32 npub encoding/decoding for Nostr pubkeys (BIP-173 / NIP-19),
532
+ * dependency-free. Mirrors rig-web's proven `web/npub.ts` — the CLI must not
533
+ * import from the SPA package, so the ~100 lines live here too (#278: `rig
534
+ * clone` accepts `<owner-npub-or-hex>/<repo-id>` addresses).
535
+ */
536
+ /** Encode a 64-char hex pubkey as an `npub1…` bech32 string. */
537
+ declare function hexToNpub(hexPubkey: string): string;
538
+ /**
539
+ * Decode an `npub1…` bech32 string back to a 64-char hex pubkey.
540
+ * Throws on malformed input (prefix, length, charset, checksum, padding).
541
+ */
542
+ declare function npubToHex(npub: string): string;
543
+ /**
544
+ * Normalize a repo-owner reference to a 64-char hex pubkey: accepts lowercase
545
+ * hex verbatim or an `npub1…` string. Throws a caller-facing error otherwise.
546
+ */
547
+ declare function ownerToHex(owner: string): string;
548
+
286
549
  /**
287
550
  * Push planner/executor — the core of `rig push` (epic #222, ticket #226).
288
551
  *
@@ -665,6 +928,11 @@ interface GitPatchRequest {
665
928
  repoAddr: GitRepoAddr;
666
929
  /** Patch/PR title (`subject` tag). */
667
930
  title: string;
931
+ /**
932
+ * PR body/cover text (`description` tag). Kept OUT of the event content so
933
+ * `git am` still consumes the patch text verbatim (#280).
934
+ */
935
+ description?: string;
668
936
  /** Literal patch text. Mutually exclusive with `repoPath`+`range`. */
669
937
  patchText?: string;
670
938
  /** Local repository to run format-patch in. Requires `range`. */
@@ -739,4 +1007,4 @@ declare function serializeEventReceipt(kind: number, receipt: PublishReceipt): G
739
1007
  /** Serialize a PushResult onto the wire (bigints → strings, Maps → records). */
740
1008
  declare function serializePushResult(plan: PushPlan, result: PushResult): GitPushResponse;
741
1009
 
742
- export { type ExecutePushOptions, FeeRates, type FetchRemoteStateOptions, type GitCommentRequest, GitError, type GitErrorEnvelope, type GitEstimateRequest, type GitEstimateResponse, type GitEventResponse, type GitFeeEstimate, type GitIssueRequest, GitObjectType, type GitPatchRequest, type GitPlannedObject, type GitPublishReceipt, type GitPushRequest, type GitPushResponse, type GitRef, type GitRefUpdate, type GitRepoAddr, GitRepoReader, type GitStatusRequest, type GitStatusValue, type GitUploadStep, NonFastForwardError, type NostrEvent, type ObjectStat, type ObjectWithPath, type OversizeObject, OversizeObjectsError, type PlanPushOptions, type PlannedObject, PublishReceipt, Publisher, type PushFeeEstimate, type PushPlan, type PushResult, type ReadGitObject, type ReadObjectsResult, type RefUpdate, type RefUpdateKind, type RejectedRefUpdate, type RemoteState, type RepoRefs, type StatObjectsResult, type UploadStepResult, type WebSocketFactory, type WebSocketLike, executePush, fetchRemoteState, planPush, serializeEventReceipt, serializeFeeEstimate, serializePushPlan, serializePushResult };
1010
+ export { type ClosureResult, type CollectRepoObjectsOptions, type CollectRepoObjectsResult, DEFAULT_CONCURRENCY, type DownloadOptions, type DownloadResult, type ExecutePushOptions, FeeRates, type FetchLike, type FetchRemoteStateOptions, type FetchedObject, type GatewayFetchOptions, type GitCommentRequest, GitError, type GitErrorEnvelope, type GitEstimateRequest, type GitEstimateResponse, type GitEventResponse, type GitFeeEstimate, type GitIssueRequest, GitObjectType, type GitPatchRequest, type GitPlannedObject, type GitPublishReceipt, type GitPushRequest, type GitPushResponse, type GitRef, type GitRefUpdate, type GitRepoAddr, GitRepoReader, type GitStatusRequest, type GitStatusValue, type GitUploadStep, type MissingObject, NonFastForwardError, type NostrEvent, type NostrFilter, ObjectIntegrityError, type ObjectStat, type ObjectWithPath, ObjectWriteMismatchError, type OversizeObject, OversizeObjectsError, type PlanPushOptions, type PlannedObject, PublishReceipt, Publisher, type PushFeeEstimate, type PushPlan, type PushResult, type ReadGitObject, type ReadObjectsResult, type RefUpdate, type RefUpdateKind, type RejectedRefUpdate, type RemoteState, type RepoRefs, type StatObjectsResult, type UploadStepResult, type WebSocketFactory, type WebSocketLike, collectRepoObjects, downloadGitObjects, executePush, fetchRemoteState, fetchTxBytes, hexToNpub, isSafeRefname, missingObjectsMessage, npubToHex, ownerToHex, planPush, queryRelay, referencedShas, serializeEventReceipt, serializeFeeEstimate, serializePushPlan, serializePushResult, setHeadSymref, updateRef, verifyObjectBody, walkClosure, writeGitObject, writeGitObjects };
package/dist/index.js CHANGED
@@ -1,18 +1,33 @@
1
1
  import {
2
+ DEFAULT_CONCURRENCY,
2
3
  GitError,
3
4
  GitRepoReader,
4
5
  NonFastForwardError,
6
+ ObjectIntegrityError,
7
+ ObjectWriteMismatchError,
5
8
  OversizeObjectsError,
9
+ collectRepoObjects,
10
+ downloadGitObjects,
6
11
  executePush,
12
+ fetchTxBytes,
13
+ hexToNpub,
14
+ isSafeRefname,
15
+ missingObjectsMessage,
16
+ npubToHex,
17
+ ownerToHex,
7
18
  planPush,
19
+ referencedShas,
8
20
  serializeEventReceipt,
9
21
  serializeFeeEstimate,
10
22
  serializePushPlan,
11
- serializePushResult
12
- } from "./chunk-LFGDLD6J.js";
13
- import {
14
- fetchRemoteState
15
- } from "./chunk-PLKZAUTG.js";
23
+ serializePushResult,
24
+ setHeadSymref,
25
+ updateRef,
26
+ verifyObjectBody,
27
+ walkClosure,
28
+ writeGitObject,
29
+ writeGitObjects
30
+ } from "./chunk-PS5QOT62.js";
16
31
  import {
17
32
  COMMENT_KIND,
18
33
  REPOSITORY_STATE_KIND,
@@ -21,8 +36,10 @@ import {
21
36
  buildPatch,
22
37
  buildRepoAnnouncement,
23
38
  buildRepoRefs,
24
- buildStatus
25
- } from "./chunk-HPSOQP7Q.js";
39
+ buildStatus,
40
+ fetchRemoteState,
41
+ queryRelay
42
+ } from "./chunk-JBB7HBQC.js";
26
43
  import {
27
44
  MAX_OBJECT_SIZE,
28
45
  createGitBlob,
@@ -33,10 +50,13 @@ import {
33
50
  } from "./chunk-X2CZPPDM.js";
34
51
  export {
35
52
  COMMENT_KIND,
53
+ DEFAULT_CONCURRENCY,
36
54
  GitError,
37
55
  GitRepoReader,
38
56
  MAX_OBJECT_SIZE,
39
57
  NonFastForwardError,
58
+ ObjectIntegrityError,
59
+ ObjectWriteMismatchError,
40
60
  OversizeObjectsError,
41
61
  REPOSITORY_STATE_KIND,
42
62
  buildComment,
@@ -45,17 +65,33 @@ export {
45
65
  buildRepoAnnouncement,
46
66
  buildRepoRefs,
47
67
  buildStatus,
68
+ collectRepoObjects,
48
69
  createGitBlob,
49
70
  createGitCommit,
50
71
  createGitTag,
51
72
  createGitTree,
73
+ downloadGitObjects,
52
74
  executePush,
53
75
  fetchRemoteState,
76
+ fetchTxBytes,
54
77
  hashGitObject,
78
+ hexToNpub,
79
+ isSafeRefname,
80
+ missingObjectsMessage,
81
+ npubToHex,
82
+ ownerToHex,
55
83
  planPush,
84
+ queryRelay,
85
+ referencedShas,
56
86
  serializeEventReceipt,
57
87
  serializeFeeEstimate,
58
88
  serializePushPlan,
59
- serializePushResult
89
+ serializePushResult,
90
+ setHeadSymref,
91
+ updateRef,
92
+ verifyObjectBody,
93
+ walkClosure,
94
+ writeGitObject,
95
+ writeGitObjects
60
96
  };
61
97
  //# sourceMappingURL=index.js.map
@@ -144,6 +144,13 @@ declare function buildComment(repoOwnerPubkey: string, repoId: string, issueOrPr
144
144
  /**
145
145
  * Build a kind:1617 patch event.
146
146
  *
147
+ * The PR body/description travels in a dedicated `description` tag, NEVER in
148
+ * `content` (#280): `content` is real `git format-patch` output that readers
149
+ * pipe straight into `git am`, and git's patch-format detection hard-fails on
150
+ * any leading prose (verified: "Patch format detection failed."). The tag
151
+ * route keeps `git am` consumption intact while `rig pr show` and the
152
+ * rig-web/views `parsePR` renderers surface the description.
153
+ *
147
154
  * @param repoOwnerPubkey - Pubkey of the repository owner
148
155
  * @param repoId - Repository identifier
149
156
  * @param title - Patch/PR title (subject tag)
@@ -151,11 +158,13 @@ declare function buildComment(repoOwnerPubkey: string, repoId: string, issueOrPr
151
158
  * @param branchTag - Branch name for the t tag
152
159
  * @param content - Real `git format-patch` text (NIP-34 patch body); defaults
153
160
  * to '' for callers that only reference commits by tag
161
+ * @param description - PR body/cover text (`description` tag) — kept out of
162
+ * `content` so `git am` still applies it
154
163
  */
155
164
  declare function buildPatch(repoOwnerPubkey: string, repoId: string, title: string, commits: {
156
165
  sha: string;
157
166
  parentSha: string;
158
- }[], branchTag?: string, content?: string): UnsignedEvent;
167
+ }[], branchTag?: string, content?: string, description?: string): UnsignedEvent;
159
168
  /** Status kinds: 1630 open, 1631 applied/merged, 1632 closed, 1633 draft. */
160
169
  type StatusKind = typeof STATUS_OPEN_KIND | typeof STATUS_APPLIED_KIND | typeof STATUS_CLOSED_KIND | typeof STATUS_DRAFT_KIND;
161
170
  /**
@@ -251,4 +260,4 @@ interface Publisher {
251
260
  publishEvent(event: UnsignedEvent, relayUrls: string[]): Promise<PublishReceipt>;
252
261
  }
253
262
 
254
- export { COMMENT_KIND as C, type FeeRates as F, type GitObjectType as G, MAX_OBJECT_SIZE as M, type Publisher as P, REPOSITORY_STATE_KIND as R, type StatusKind as S, type UnsignedEvent as U, type PublishReceipt as a, type GitObject as b, type GitObjectUpload as c, type UploadReceipt as d, buildComment as e, buildIssue as f, buildPatch as g, buildRepoAnnouncement as h, buildRepoRefs as i, buildStatus as j, createGitBlob as k, createGitCommit as l, createGitTag as m, createGitTree as n, hashGitObject as o };
263
+ export { COMMENT_KIND as C, type FeeRates as F, type GitObjectUpload as G, MAX_OBJECT_SIZE as M, type Publisher as P, REPOSITORY_STATE_KIND as R, type StatusKind as S, type UnsignedEvent as U, type UploadReceipt as a, type PublishReceipt as b, type GitObjectType as c, type GitObject as d, buildComment as e, buildIssue as f, buildPatch as g, buildRepoAnnouncement as h, buildRepoRefs as i, buildStatus as j, createGitBlob as k, createGitCommit as l, createGitTag as m, createGitTree as n, hashGitObject as o };
@@ -1,5 +1,5 @@
1
1
  import { ToonClientConfig, SignedBalanceProof, PublishEventResult } from '@toon-protocol/client';
2
- import { U as UnsignedEvent, P as Publisher, F as FeeRates, c as GitObjectUpload, d as UploadReceipt, a as PublishReceipt } from '../publisher-Cdr1H1hg.js';
2
+ import { U as UnsignedEvent, P as Publisher, F as FeeRates, G as GitObjectUpload, a as UploadReceipt, b as PublishReceipt } from '../publisher-CrwaNQrK.js';
3
3
  import '@toon-protocol/core/nip34';
4
4
 
5
5
  /**
@@ -583,6 +583,12 @@ declare class StandalonePublisher implements Publisher {
583
583
  * 1. Daemon detection — probe the toon-clientd loopback control API
584
584
  * (`GET /status`) and REFUSE when it reports the SAME identity. A daemon
585
585
  * on a different identity holds different channels and is harmless.
586
+ * Since #279 the CLI's paid WRITE commands never get here with a
587
+ * same-identity daemon up — they delegate to its `/git/*` routes first
588
+ * (`cli/daemon-session.ts`), which achieves the same one-writer goal by
589
+ * handing the watermark to the daemon. This guard remains the backstop
590
+ * for the probe→publish race window and for operations with no daemon
591
+ * route (channel close/settle, explicit open).
586
592
  * 2. Advisory lockfile — an exclusive per-pubkey lockfile under the shared
587
593
  * `~/.toon-client` state dir so two STANDALONE processes can't race each
588
594
  * other (the daemon check only covers the daemon). Stale locks (dead pid)
@@ -1,24 +1,24 @@
1
1
  import {
2
- DEFAULT_DAEMON_PORT,
3
- DaemonIdentityConflictError,
4
- NonceLock,
5
- StandaloneLockError,
6
2
  StandalonePublishError,
7
3
  StandalonePublisher,
8
- checkDaemonIdentity,
9
- defaultDaemonPort,
10
- defaultLockDir,
11
4
  deriveRouteDestinations,
12
5
  extractArweaveTxId
13
- } from "../chunk-3EKP7PMM.js";
6
+ } from "../chunk-OIJNRACA.js";
14
7
  import {
15
8
  ChannelMapCorruptError,
16
9
  ChannelMapStore,
10
+ DEFAULT_DAEMON_PORT,
11
+ DaemonIdentityConflictError,
12
+ NonceLock,
17
13
  RIG_CHANNEL_MAP_FILENAME,
14
+ StandaloneLockError,
18
15
  channelStatus,
16
+ checkDaemonIdentity,
17
+ defaultDaemonPort,
18
+ defaultLockDir,
19
19
  recordKey,
20
20
  resolveChannelPaths
21
- } from "../chunk-O6TXHKWG.js";
21
+ } from "../chunk-SW7ZHMGS.js";
22
22
  import "../chunk-X2CZPPDM.js";
23
23
  export {
24
24
  ChannelMapCorruptError,