@toon-protocol/rig 4.5.0 → 4.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/README.md +13 -5
- package/dist/{chunk-S2BMLXAD.js → chunk-DCGV6ALH.js} +429 -14
- package/dist/chunk-DCGV6ALH.js.map +1 -0
- package/dist/{chunk-HMED76GU.js → chunk-JBFBD7HV.js} +99 -55
- package/dist/chunk-JBFBD7HV.js.map +1 -0
- package/dist/{chunk-UZZ2JKEC.js → chunk-X232W4TG.js} +491 -185
- package/dist/chunk-X232W4TG.js.map +1 -0
- package/dist/{ci-serve-PYEHIBN7.js → ci-serve-AYFZOY4O.js} +8 -19
- package/dist/ci-serve-AYFZOY4O.js.map +1 -0
- package/dist/cli/rig.js +4 -3
- package/dist/cli/rig.js.map +1 -1
- package/dist/index.d.ts +362 -20
- package/dist/index.js +494 -3
- package/dist/index.js.map +1 -1
- package/dist/{publisher-Cf6tKnZ3.d.ts → publisher-DgbfziOm.d.ts} +152 -26
- package/dist/standalone/index.d.ts +1 -1
- package/dist/{standalone-mode-W3ZEKC6M.js → standalone-mode-UQSP4677.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-HMED76GU.js.map +0 -1
- package/dist/chunk-S2BMLXAD.js.map +0 -1
- package/dist/chunk-UZZ2JKEC.js.map +0 -1
- package/dist/ci-serve-PYEHIBN7.js.map +0 -1
- /package/dist/{standalone-mode-W3ZEKC6M.js.map → standalone-mode-UQSP4677.js.map} +0 -0
|
@@ -10,11 +10,15 @@ import {
|
|
|
10
10
|
UnconfiguredRepoAddressError,
|
|
11
11
|
UnknownRemoteError,
|
|
12
12
|
addGitRemote,
|
|
13
|
+
amendRepoAnnouncement,
|
|
13
14
|
buildCiManualTrigger,
|
|
14
15
|
buildCiSecretUpdate,
|
|
15
16
|
buildCiServiceRequest,
|
|
16
17
|
buildCiServiceStop,
|
|
17
18
|
collectRepoObjects,
|
|
19
|
+
conformanceEdits,
|
|
20
|
+
diffAnnouncementTags,
|
|
21
|
+
earliestUniqueCommit,
|
|
18
22
|
emitCliError,
|
|
19
23
|
encryptSecretUpdate,
|
|
20
24
|
executePush,
|
|
@@ -48,22 +52,24 @@ import {
|
|
|
48
52
|
updateRef,
|
|
49
53
|
writeGitObjects,
|
|
50
54
|
writeToonConfig
|
|
51
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-DCGV6ALH.js";
|
|
52
56
|
import {
|
|
53
57
|
ARWEAVE_GATEWAYS,
|
|
54
58
|
COMMENT_KIND,
|
|
55
59
|
DEFAULT_KEYSTORE_PASSWORD,
|
|
60
|
+
LEGACY_COMMENT_KIND,
|
|
56
61
|
MissingIdentityError,
|
|
57
62
|
authorizedStatusAuthors,
|
|
58
63
|
buildComment,
|
|
59
64
|
buildIssue,
|
|
60
65
|
buildPatch,
|
|
61
|
-
buildRepoAnnouncement,
|
|
62
66
|
buildStatus,
|
|
63
67
|
clientConfigPath,
|
|
64
68
|
clientKeystorePath,
|
|
69
|
+
commentBelongsToThread,
|
|
65
70
|
defaultWebSocketFactory,
|
|
66
71
|
fetchRemoteState,
|
|
72
|
+
firstTagValue,
|
|
67
73
|
isValidEvmPayoutAddress,
|
|
68
74
|
linkKeystoreInClientConfig,
|
|
69
75
|
parseMaintainers,
|
|
@@ -71,7 +77,7 @@ import {
|
|
|
71
77
|
readClientConfigFile,
|
|
72
78
|
resolveAccountIndex,
|
|
73
79
|
resolveIdentity
|
|
74
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-JBFBD7HV.js";
|
|
75
81
|
import {
|
|
76
82
|
ChannelMapStore,
|
|
77
83
|
channelStatus,
|
|
@@ -100,6 +106,12 @@ function mirrorGatewaysFor(primary) {
|
|
|
100
106
|
}
|
|
101
107
|
|
|
102
108
|
// src/cli/render.ts
|
|
109
|
+
function describeAnnouncementDiff(diff) {
|
|
110
|
+
return [
|
|
111
|
+
...diff.removed.map((tag) => ` - ${tag.join(" ")}`),
|
|
112
|
+
...diff.added.map((tag) => ` + ${tag.join(" ")}`)
|
|
113
|
+
];
|
|
114
|
+
}
|
|
103
115
|
function formatNumber(value) {
|
|
104
116
|
return String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
105
117
|
}
|
|
@@ -214,6 +226,14 @@ function repoHashRoute(options) {
|
|
|
214
226
|
function rigWebRoute(options) {
|
|
215
227
|
return `${options.rigWebUrl.replace(/\/+$/, "")}/${repoHashRoute(options)}`;
|
|
216
228
|
}
|
|
229
|
+
function repoWebUrl(options) {
|
|
230
|
+
return rigWebRoute({
|
|
231
|
+
rigWebUrl: options.env[RIG_WEB_URL_ENV] ?? DEFAULT_RIG_WEB_URL,
|
|
232
|
+
relay: options.relay,
|
|
233
|
+
ownerNpub: hexToNpub(options.ownerPubkey),
|
|
234
|
+
repoId: options.repoId
|
|
235
|
+
});
|
|
236
|
+
}
|
|
217
237
|
function escapeHtml(value) {
|
|
218
238
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
219
239
|
}
|
|
@@ -300,7 +320,7 @@ function loadPaidSession(deps, relayUrl) {
|
|
|
300
320
|
});
|
|
301
321
|
}
|
|
302
322
|
var defaultLoadStandalone = async (options) => {
|
|
303
|
-
const mod = await import("./standalone-mode-
|
|
323
|
+
const mod = await import("./standalone-mode-UQSP4677.js");
|
|
304
324
|
return mod.createStandaloneContext(options);
|
|
305
325
|
};
|
|
306
326
|
function identityReport(ctx) {
|
|
@@ -559,6 +579,14 @@ async function runPush(args, deps) {
|
|
|
559
579
|
`warning: git config toon.owner (${toonConfig.owner.slice(0, 8)}\u2026) differs from the active identity (${identity.pubkey.slice(0, 8)}\u2026) \u2014 this push publishes under the ACTIVE identity's repo namespace, not the configured owner's. Re-run \`rig init\` to adopt the active identity.`
|
|
560
580
|
);
|
|
561
581
|
}
|
|
582
|
+
const announcement = relaysUsed[0] === void 0 ? void 0 : {
|
|
583
|
+
web: repoWebUrl({
|
|
584
|
+
env: deps.env,
|
|
585
|
+
relay: relaysUsed[0],
|
|
586
|
+
ownerPubkey: identity.pubkey,
|
|
587
|
+
repoId
|
|
588
|
+
})
|
|
589
|
+
};
|
|
562
590
|
let plan;
|
|
563
591
|
let execute;
|
|
564
592
|
let pointerPlan;
|
|
@@ -577,7 +605,8 @@ async function runPush(args, deps) {
|
|
|
577
605
|
feeRates,
|
|
578
606
|
repoId,
|
|
579
607
|
refs: refspecs,
|
|
580
|
-
force: flags.force
|
|
608
|
+
force: flags.force,
|
|
609
|
+
...announcement ? { announcement } : {}
|
|
581
610
|
});
|
|
582
611
|
plan = serializePushPlan(pushPlan);
|
|
583
612
|
execute = async () => serializePushResult(
|
|
@@ -612,7 +641,8 @@ async function runPush(args, deps) {
|
|
|
612
641
|
repoId,
|
|
613
642
|
refspecs,
|
|
614
643
|
force: flags.force,
|
|
615
|
-
relayUrls: relaysUsed
|
|
644
|
+
relayUrls: relaysUsed,
|
|
645
|
+
...announcement ? { announcement } : {}
|
|
616
646
|
});
|
|
617
647
|
execute = () => client.gitPush({
|
|
618
648
|
repoPath: repoRoot,
|
|
@@ -620,7 +650,8 @@ async function runPush(args, deps) {
|
|
|
620
650
|
refspecs,
|
|
621
651
|
force: flags.force,
|
|
622
652
|
relayUrls: relaysUsed,
|
|
623
|
-
confirm: true
|
|
653
|
+
confirm: true,
|
|
654
|
+
...announcement ? { announcement } : {}
|
|
624
655
|
});
|
|
625
656
|
rigPageSkipDetail = "skipped on the daemon path (refreshes on the next standalone push)";
|
|
626
657
|
}
|
|
@@ -879,6 +910,82 @@ async function resolveRepoContext(flags, deps) {
|
|
|
879
910
|
...repoRoot !== void 0 ? { repoRoot } : {}
|
|
880
911
|
};
|
|
881
912
|
}
|
|
913
|
+
async function conformanceFactsFor(options) {
|
|
914
|
+
const { ctx, relayUrl, deps } = options;
|
|
915
|
+
const repoRoot = ctx.repoRoot;
|
|
916
|
+
const rootCommits = deps.rootCommits ?? (repoRoot === void 0 ? void 0 : (rev) => new GitRepoReader(repoRoot).rootCommits(rev));
|
|
917
|
+
let euc = null;
|
|
918
|
+
if (rootCommits !== void 0) {
|
|
919
|
+
try {
|
|
920
|
+
euc = await earliestUniqueCommit({ rootCommits });
|
|
921
|
+
} catch {
|
|
922
|
+
euc = null;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
let web = null;
|
|
926
|
+
try {
|
|
927
|
+
web = repoWebUrl({
|
|
928
|
+
env: deps.env,
|
|
929
|
+
relay: relayUrl,
|
|
930
|
+
ownerPubkey: ctx.owner,
|
|
931
|
+
repoId: ctx.repoId
|
|
932
|
+
});
|
|
933
|
+
} catch {
|
|
934
|
+
web = null;
|
|
935
|
+
}
|
|
936
|
+
return { relays: [relayUrl], web, earliestUniqueCommit: euc };
|
|
937
|
+
}
|
|
938
|
+
async function openAnnouncementRepublish(options) {
|
|
939
|
+
const { deps, flags, what, before } = options;
|
|
940
|
+
const { io } = deps;
|
|
941
|
+
const ctx = await resolveRepoContext(flags, deps);
|
|
942
|
+
if (ctx.relays.length > 1) {
|
|
943
|
+
io.err(singleRelayRefusal(ctx.resolved, "Nothing was published or paid."));
|
|
944
|
+
return { ok: false, exitCode: 1 };
|
|
945
|
+
}
|
|
946
|
+
const relayUrl = ctx.relays[0];
|
|
947
|
+
if (relayUrl === void 0 || !WS_URL_RE.test(relayUrl)) {
|
|
948
|
+
throw new InvalidRelayUrlError(
|
|
949
|
+
relayUrl ?? "",
|
|
950
|
+
"a paid publish needs a ws:// or wss:// relay"
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
const load = deps.loadStandalone ?? defaultLoadStandalone;
|
|
954
|
+
const standalone = await load({
|
|
955
|
+
env: deps.env,
|
|
956
|
+
cwd: deps.cwd,
|
|
957
|
+
warn: (line) => io.err(line),
|
|
958
|
+
relayUrl
|
|
959
|
+
});
|
|
960
|
+
const identity = identityReport(standalone);
|
|
961
|
+
if (identity.pubkey.toLowerCase() !== ctx.owner.toLowerCase()) {
|
|
962
|
+
io.err(
|
|
963
|
+
`rig: only the repo owner (${ctx.owner.slice(0, 8)}\u2026) can ${what} \u2014 the active identity is ${identity.pubkey.slice(0, 8)}\u2026. A non-owner republish would write your own (ignored) announcement. Nothing was published or paid.`
|
|
964
|
+
);
|
|
965
|
+
return { ok: false, exitCode: 1, standalone };
|
|
966
|
+
}
|
|
967
|
+
const remote = await fetchRemoteState({
|
|
968
|
+
relayUrls: [relayUrl],
|
|
969
|
+
ownerPubkey: ctx.owner,
|
|
970
|
+
repoId: ctx.repoId,
|
|
971
|
+
...deps.webSocketFactory ? { webSocketFactory: deps.webSocketFactory } : {}
|
|
972
|
+
});
|
|
973
|
+
if (!remote.announced) {
|
|
974
|
+
io.err(
|
|
975
|
+
`rig: 30617:${ctx.owner.slice(0, 8)}\u2026:${ctx.repoId} has no announcement yet \u2014 run \`rig push\` to publish the repo (with its real name/description) ${before}. Nothing was published or paid.`
|
|
976
|
+
);
|
|
977
|
+
return { ok: false, exitCode: 1, standalone };
|
|
978
|
+
}
|
|
979
|
+
return {
|
|
980
|
+
ok: true,
|
|
981
|
+
ctx,
|
|
982
|
+
relayUrl,
|
|
983
|
+
standalone,
|
|
984
|
+
identity,
|
|
985
|
+
remote,
|
|
986
|
+
facts: await conformanceFactsFor({ ctx, relayUrl, deps })
|
|
987
|
+
};
|
|
988
|
+
}
|
|
882
989
|
|
|
883
990
|
// src/cli/dispatch.ts
|
|
884
991
|
import { createRequire } from "module";
|
|
@@ -2378,7 +2485,7 @@ async function runCi(args, deps) {
|
|
|
2378
2485
|
case "status":
|
|
2379
2486
|
return runCiStatus(rest, deps);
|
|
2380
2487
|
case "serve":
|
|
2381
|
-
return (await import("./ci-serve-
|
|
2488
|
+
return (await import("./ci-serve-AYFZOY4O.js")).runCiServe(rest, deps);
|
|
2382
2489
|
case "--help":
|
|
2383
2490
|
case "-h":
|
|
2384
2491
|
case "help":
|
|
@@ -2640,7 +2747,6 @@ async function runClone(args, deps) {
|
|
|
2640
2747
|
import { readFile } from "fs/promises";
|
|
2641
2748
|
import { parseArgs as parseArgs8 } from "util";
|
|
2642
2749
|
import {
|
|
2643
|
-
REPOSITORY_ANNOUNCEMENT_KIND as REPOSITORY_ANNOUNCEMENT_KIND2,
|
|
2644
2750
|
STATUS_APPLIED_KIND as STATUS_APPLIED_KIND2,
|
|
2645
2751
|
STATUS_CLOSED_KIND as STATUS_CLOSED_KIND2,
|
|
2646
2752
|
STATUS_DRAFT_KIND as STATUS_DRAFT_KIND2,
|
|
@@ -2675,9 +2781,10 @@ Options:
|
|
|
2675
2781
|
${READ_COMMON_FLAGS}`;
|
|
2676
2782
|
var ISSUE_SHOW_USAGE = `Usage: rig issue show <event-id> [options]
|
|
2677
2783
|
|
|
2678
|
-
Show one issue (kind:1621): metadata, derived state, body, and its
|
|
2679
|
-
kind:1622
|
|
2680
|
-
|
|
2784
|
+
Show one issue (kind:1621): metadata, derived state, body, and its comments
|
|
2785
|
+
\u2014 NIP-22 kind:1111 merged with legacy kind:1622 in time order \u2014 FREE (relay
|
|
2786
|
+
reads only). <event-id> is the 64-char hex id \`rig issue create\` printed
|
|
2787
|
+
(also visible in \`rig issue list\`).
|
|
2681
2788
|
|
|
2682
2789
|
Options:
|
|
2683
2790
|
${READ_COMMON_FLAGS}`;
|
|
@@ -2694,7 +2801,8 @@ var PR_SHOW_USAGE = `Usage: rig pr show <event-id> [options]
|
|
|
2694
2801
|
|
|
2695
2802
|
Show one patch/PR (kind:1617): metadata, derived state, the FULL patch text
|
|
2696
2803
|
(real \`git format-patch\` output \u2014 pipe it to \`git am\` to apply), and its
|
|
2697
|
-
|
|
2804
|
+
comments \u2014 NIP-22 kind:1111 merged with legacy kind:1622 in time order \u2014
|
|
2805
|
+
FREE (relay reads only).
|
|
2698
2806
|
|
|
2699
2807
|
Options:
|
|
2700
2808
|
${READ_COMMON_FLAGS}`;
|
|
@@ -2710,9 +2818,7 @@ var STATUS_KINDS = [
|
|
|
2710
2818
|
STATUS_CLOSED_KIND,
|
|
2711
2819
|
STATUS_DRAFT_KIND
|
|
2712
2820
|
];
|
|
2713
|
-
|
|
2714
|
-
return tags.find((t) => t[0] === name)?.[1];
|
|
2715
|
-
}
|
|
2821
|
+
var tagValue = firstTagValue;
|
|
2716
2822
|
function tagValues(tags, name) {
|
|
2717
2823
|
return tags.filter((t) => t[0] === name && t[1]).map((t) => t[1]);
|
|
2718
2824
|
}
|
|
@@ -2729,6 +2835,9 @@ function deriveStatus(targetEventId, statusEvents, authorized) {
|
|
|
2729
2835
|
}
|
|
2730
2836
|
return winner === null ? "open" : STATUS_BY_KIND[winner.kind];
|
|
2731
2837
|
}
|
|
2838
|
+
function withTargetAuthor(authorized, targetAuthorPubkey) {
|
|
2839
|
+
return /* @__PURE__ */ new Set([...authorized, targetAuthorPubkey.toLowerCase()]);
|
|
2840
|
+
}
|
|
2732
2841
|
var RELAY_TIMEOUT_MS = 1e4;
|
|
2733
2842
|
var HEX64_RE2 = /^[0-9a-f]{64}$/;
|
|
2734
2843
|
var WS_URL_RE3 = /^wss?:\/\//i;
|
|
@@ -2872,7 +2981,7 @@ function parseTrackerItem(event, status) {
|
|
|
2872
2981
|
};
|
|
2873
2982
|
if (event.kind === PATCH_KIND) {
|
|
2874
2983
|
item.commitShas = tagValues(event.tags, "commit");
|
|
2875
|
-
const branch = tagValue(event.tags, "branch");
|
|
2984
|
+
const branch = tagValue(event.tags, "branch-name") ?? tagValue(event.tags, "branch");
|
|
2876
2985
|
if (branch !== void 0) item.branch = branch;
|
|
2877
2986
|
const description = tagValue(event.tags, "description");
|
|
2878
2987
|
if (description !== void 0) item.description = description;
|
|
@@ -2917,7 +3026,14 @@ async function fetchItems(ctx, kind) {
|
|
|
2917
3026
|
}
|
|
2918
3027
|
const authorized = await authorizedPromise;
|
|
2919
3028
|
return items.map(
|
|
2920
|
-
(event) => parseTrackerItem(
|
|
3029
|
+
(event) => parseTrackerItem(
|
|
3030
|
+
event,
|
|
3031
|
+
deriveStatus(
|
|
3032
|
+
event.id,
|
|
3033
|
+
statuses.values(),
|
|
3034
|
+
withTargetAuthor(authorized, event.pubkey)
|
|
3035
|
+
)
|
|
3036
|
+
)
|
|
2921
3037
|
).sort((a, b) => b.createdAt - a.createdAt);
|
|
2922
3038
|
}
|
|
2923
3039
|
async function fetchItem(ctx, eventId, expectedKind) {
|
|
@@ -2942,16 +3058,23 @@ async function fetchItem(ctx, eventId, expectedKind) {
|
|
|
2942
3058
|
[{ kinds: STATUS_KINDS, "#e": [eventId] }],
|
|
2943
3059
|
ctx.webSocketFactory
|
|
2944
3060
|
),
|
|
3061
|
+
// One thread, two wire shapes (#159): NIP-22 kind:1111 comments hang off
|
|
3062
|
+
// the root's UPPERCASE `E` tag (a nested reply's lowercase `e` names its
|
|
3063
|
+
// parent comment, so `#e` would miss it); legacy kind:1622 comments only
|
|
3064
|
+
// ever carry the lowercase `e`. Both are merged below by `created_at`.
|
|
2945
3065
|
queryAll(
|
|
2946
3066
|
ctx.relays,
|
|
2947
|
-
[
|
|
3067
|
+
[
|
|
3068
|
+
{ kinds: [COMMENT_KIND], "#E": [eventId] },
|
|
3069
|
+
{ kinds: [LEGACY_COMMENT_KIND], "#e": [eventId] }
|
|
3070
|
+
],
|
|
2948
3071
|
ctx.webSocketFactory
|
|
2949
3072
|
)
|
|
2950
3073
|
]);
|
|
2951
|
-
const comments = [...commentEvents.values()].filter(
|
|
2952
|
-
(e) => e.kind === COMMENT_KIND && e.tags.some((t) => t[0] === "e" && t[1] === eventId)
|
|
2953
|
-
).sort((a, b) => a.created_at - b.created_at).map((e) => ({
|
|
3074
|
+
const comments = [...commentEvents.values()].filter((e) => commentBelongsToThread(e, eventId)).sort((a, b) => a.created_at - b.created_at).map((e) => ({
|
|
2954
3075
|
eventId: e.id,
|
|
3076
|
+
kind: e.kind,
|
|
3077
|
+
replyToEventId: tagValue(e.tags, "e") ?? null,
|
|
2955
3078
|
authorPubkey: e.pubkey,
|
|
2956
3079
|
createdAt: e.created_at,
|
|
2957
3080
|
content: e.content
|
|
@@ -2962,7 +3085,11 @@ async function fetchItem(ctx, eventId, expectedKind) {
|
|
|
2962
3085
|
return {
|
|
2963
3086
|
item: parseTrackerItem(
|
|
2964
3087
|
event,
|
|
2965
|
-
deriveStatus(
|
|
3088
|
+
deriveStatus(
|
|
3089
|
+
eventId,
|
|
3090
|
+
statusEvents.values(),
|
|
3091
|
+
withTargetAuthor(authorized, event.pubkey)
|
|
3092
|
+
)
|
|
2966
3093
|
),
|
|
2967
3094
|
comments,
|
|
2968
3095
|
repoATag: repoATag2
|
|
@@ -3028,8 +3155,9 @@ async function runList(args, deps, spec) {
|
|
|
3028
3155
|
}
|
|
3029
3156
|
for (const item of items) {
|
|
3030
3157
|
const labels = item.labels.length > 0 ? ` [${item.labels.join(", ")}]` : "";
|
|
3158
|
+
const branch = item.branch !== void 0 ? ` \u2192 ${item.branch}` : "";
|
|
3031
3159
|
io.out(
|
|
3032
|
-
`${item.status.padEnd(7)} ${item.eventId.slice(0, 8)} ${item.title} (${item.authorPubkey.slice(0, 8)}, ${isoDate(item.createdAt)})${labels}`
|
|
3160
|
+
`${item.status.padEnd(7)} ${item.eventId.slice(0, 8)} ${item.title} (${item.authorPubkey.slice(0, 8)}, ${isoDate(item.createdAt)})${labels}${branch}`
|
|
3033
3161
|
);
|
|
3034
3162
|
}
|
|
3035
3163
|
io.out(
|
|
@@ -3105,8 +3233,9 @@ async function runShow(args, deps, spec) {
|
|
|
3105
3233
|
io.out("");
|
|
3106
3234
|
io.out(`Comments (${shown.comments.length}):`);
|
|
3107
3235
|
for (const comment of shown.comments) {
|
|
3236
|
+
const replyTo = comment.replyToEventId !== null && comment.replyToEventId !== item.eventId ? ` in reply to ${comment.replyToEventId.slice(0, 8)}` : "";
|
|
3108
3237
|
io.out(
|
|
3109
|
-
`--- ${comment.eventId.slice(0, 8)} by ${comment.authorPubkey.slice(0, 8)} on ${isoDate(comment.createdAt)}`
|
|
3238
|
+
`--- ${comment.eventId.slice(0, 8)} by ${comment.authorPubkey.slice(0, 8)} on ${isoDate(comment.createdAt)}${replyTo}`
|
|
3110
3239
|
);
|
|
3111
3240
|
for (const line of comment.content.split("\n")) io.out(line);
|
|
3112
3241
|
}
|
|
@@ -3194,18 +3323,27 @@ ${COMMON_FLAGS_USAGE2}
|
|
|
3194
3323
|
Related (FREE reads \u2014 no payment):
|
|
3195
3324
|
rig issue list [--state open|closed|all] list the repo's issues
|
|
3196
3325
|
rig issue show <event-id> one issue + its comments`;
|
|
3197
|
-
var COMMENT_USAGE = `Usage: rig comment <
|
|
3326
|
+
var COMMENT_USAGE = `Usage: rig comment <target-event-id> --body <text> [options]
|
|
3198
3327
|
|
|
3199
|
-
Comment (kind:
|
|
3200
|
-
permanent and non-refundable. <
|
|
3201
|
-
|
|
3328
|
+
Comment (NIP-22 kind:1111) on an issue or patch \u2014 a paid publish; writes are
|
|
3329
|
+
permanent and non-refundable. <target-event-id> is the 64-char hex id of
|
|
3330
|
+
either:
|
|
3331
|
+
|
|
3332
|
+
the kind:1621 issue / kind:1617 patch being commented on \u2192 a top-level
|
|
3333
|
+
comment, whose NIP-22 root scope (E/K/P) and parent (e/k/p) both name it;
|
|
3334
|
+
an existing kind:1111 comment \u2192 a REPLY: the comment becomes the lowercase
|
|
3335
|
+
parent (k=1111) while the uppercase root stays the issue/patch it hangs
|
|
3336
|
+
off.
|
|
3337
|
+
|
|
3338
|
+
The target is read from the resolved relay first (a FREE read) so the root's
|
|
3339
|
+
kind and author are taken from the wire rather than guessed. The repo
|
|
3340
|
+
coordinate rides along as an \`a\` tag for subscription filtering.
|
|
3341
|
+
|
|
3342
|
+
Older rig releases read only the legacy kind:1622 dialect and will NOT see
|
|
3343
|
+
comments published by this version.
|
|
3202
3344
|
|
|
3203
3345
|
Options:
|
|
3204
3346
|
--body <text> comment body (Markdown) [required]
|
|
3205
|
-
--parent-author <pubkey> pubkey of the TARGET event's author (p threading
|
|
3206
|
-
tag; default: the repo owner)
|
|
3207
|
-
--marker <root|reply> e-tag marker (default: root \u2014 commenting directly
|
|
3208
|
-
on the issue/patch)
|
|
3209
3347
|
${COMMON_FLAGS_USAGE2}`;
|
|
3210
3348
|
var PR_CREATE_USAGE = `Usage: rig pr create --title <title> (--range <range> | --patch-file <path>) [options]
|
|
3211
3349
|
|
|
@@ -3228,7 +3366,7 @@ Options:
|
|
|
3228
3366
|
--patch-file <path> literal patch text to publish
|
|
3229
3367
|
--body <text> PR description (Markdown; description tag)
|
|
3230
3368
|
--body-file <path> read the PR description from a file
|
|
3231
|
-
--branch <name> branch name (
|
|
3369
|
+
--branch <name> branch name (branch-name tag)
|
|
3232
3370
|
${COMMON_FLAGS_USAGE2}`;
|
|
3233
3371
|
var PR_STATUS_USAGE = `Usage: rig pr status <target-event-id> <open|applied|closed|draft> [options]
|
|
3234
3372
|
|
|
@@ -3333,7 +3471,7 @@ async function runEvent(opts) {
|
|
|
3333
3471
|
}
|
|
3334
3472
|
const owner = flags.owner ?? toonConfig.owner ?? identity.pubkey;
|
|
3335
3473
|
const addr = { ownerPubkey: owner, repoId };
|
|
3336
|
-
const event = await opts.buildEvent(addr);
|
|
3474
|
+
const event = await opts.buildEvent(addr, relaysUsed[0]);
|
|
3337
3475
|
const action = `kind:${event.kind} ${actionLabel}`;
|
|
3338
3476
|
if (opts.preConfirm) {
|
|
3339
3477
|
await opts.preConfirm({ identity, addr, relayUrl: relaysUsed[0] });
|
|
@@ -3506,19 +3644,64 @@ async function runIssue(args, deps) {
|
|
|
3506
3644
|
})
|
|
3507
3645
|
});
|
|
3508
3646
|
}
|
|
3647
|
+
var TARGET_LOOKUP_TIMEOUT_MS = 1e4;
|
|
3648
|
+
async function resolveCommentTarget(deps, targetEventId, relayUrl) {
|
|
3649
|
+
if (relayUrl === void 0) {
|
|
3650
|
+
throw new Error(
|
|
3651
|
+
"no relay resolved \u2014 a comment needs the target event to derive its NIP-22 root; pass --relay <url> or configure a remote"
|
|
3652
|
+
);
|
|
3653
|
+
}
|
|
3654
|
+
const found = await queryRelay(
|
|
3655
|
+
relayUrl,
|
|
3656
|
+
{ ids: [targetEventId] },
|
|
3657
|
+
TARGET_LOOKUP_TIMEOUT_MS,
|
|
3658
|
+
deps.webSocketFactory ?? defaultWebSocketFactory
|
|
3659
|
+
);
|
|
3660
|
+
const target = found.find((e) => e.id === targetEventId);
|
|
3661
|
+
if (!target) {
|
|
3662
|
+
throw new Error(
|
|
3663
|
+
`event ${targetEventId} not found on ${relayUrl} \u2014 nothing was published or paid`
|
|
3664
|
+
);
|
|
3665
|
+
}
|
|
3666
|
+
if (target.kind === LEGACY_COMMENT_KIND) {
|
|
3667
|
+
throw new Error(
|
|
3668
|
+
`event ${targetEventId} is a legacy kind:1622 comment \u2014 replies to it are not representable in NIP-22; comment on the issue or patch instead`
|
|
3669
|
+
);
|
|
3670
|
+
}
|
|
3671
|
+
if (target.kind === COMMENT_KIND) {
|
|
3672
|
+
const rootEventId = firstTagValue(target.tags, "E");
|
|
3673
|
+
const rootKind = Number(firstTagValue(target.tags, "K"));
|
|
3674
|
+
const rootAuthor = firstTagValue(target.tags, "P");
|
|
3675
|
+
if (rootEventId === void 0 || !HEX64_RE3.test(rootEventId) || !Number.isSafeInteger(rootKind) || rootAuthor === void 0 || !HEX64_RE3.test(rootAuthor)) {
|
|
3676
|
+
throw new Error(
|
|
3677
|
+
`kind:1111 comment ${targetEventId} carries no usable NIP-22 root scope (E/K/P tags) \u2014 cannot derive the thread root to reply into`
|
|
3678
|
+
);
|
|
3679
|
+
}
|
|
3680
|
+
return {
|
|
3681
|
+
root: { eventId: rootEventId, kind: rootKind, authorPubkey: rootAuthor },
|
|
3682
|
+
parent: { eventId: target.id, authorPubkey: target.pubkey }
|
|
3683
|
+
};
|
|
3684
|
+
}
|
|
3685
|
+
return {
|
|
3686
|
+
root: {
|
|
3687
|
+
eventId: target.id,
|
|
3688
|
+
kind: target.kind,
|
|
3689
|
+
authorPubkey: target.pubkey
|
|
3690
|
+
}
|
|
3691
|
+
};
|
|
3692
|
+
}
|
|
3509
3693
|
async function runComment(args, deps) {
|
|
3510
3694
|
const { io } = deps;
|
|
3511
3695
|
let flags;
|
|
3512
|
-
let
|
|
3696
|
+
let targetEventId;
|
|
3513
3697
|
let body;
|
|
3514
|
-
let parentAuthor;
|
|
3515
|
-
let marker;
|
|
3516
3698
|
try {
|
|
3517
3699
|
const { values, positionals } = parseArgs8({
|
|
3518
3700
|
args,
|
|
3519
3701
|
options: {
|
|
3520
3702
|
...COMMON_OPTIONS2,
|
|
3521
3703
|
body: { type: "string" },
|
|
3704
|
+
// Retired by #159 — parsed only to explain the migration.
|
|
3522
3705
|
"parent-author": { type: "string" },
|
|
3523
3706
|
marker: { type: "string" }
|
|
3524
3707
|
},
|
|
@@ -3529,49 +3712,59 @@ async function runComment(args, deps) {
|
|
|
3529
3712
|
io.out(COMMENT_USAGE);
|
|
3530
3713
|
return 0;
|
|
3531
3714
|
}
|
|
3715
|
+
if (values.marker !== void 0 || values["parent-author"] !== void 0) {
|
|
3716
|
+
throw new Error(
|
|
3717
|
+
"--marker and --parent-author were removed with the move to NIP-22 kind:1111 (#159): pass the comment you are replying to as <target-event-id> instead \u2014 its author and the thread root are read from the relay"
|
|
3718
|
+
);
|
|
3719
|
+
}
|
|
3532
3720
|
if (positionals.length !== 1) {
|
|
3533
3721
|
throw new Error(
|
|
3534
|
-
positionals.length === 0 ? "<
|
|
3722
|
+
positionals.length === 0 ? "<target-event-id> is required" : `expected exactly one <target-event-id>, got ${positionals.length} positionals`
|
|
3535
3723
|
);
|
|
3536
3724
|
}
|
|
3537
|
-
|
|
3538
|
-
assertHex64(
|
|
3725
|
+
targetEventId = positionals[0];
|
|
3726
|
+
assertHex64(targetEventId, "<target-event-id>");
|
|
3539
3727
|
if (values.body === void 0 || values.body === "") {
|
|
3540
3728
|
throw new Error("--body is required");
|
|
3541
3729
|
}
|
|
3542
3730
|
body = values.body;
|
|
3543
|
-
parentAuthor = values["parent-author"];
|
|
3544
|
-
if (parentAuthor !== void 0) assertHex64(parentAuthor, "--parent-author");
|
|
3545
|
-
const rawMarker = values.marker ?? "root";
|
|
3546
|
-
if (rawMarker !== "root" && rawMarker !== "reply") {
|
|
3547
|
-
throw new Error(`--marker must be root or reply (got ${JSON.stringify(rawMarker)})`);
|
|
3548
|
-
}
|
|
3549
|
-
marker = rawMarker;
|
|
3550
3731
|
} catch (err) {
|
|
3551
3732
|
io.err(err instanceof Error ? err.message : String(err));
|
|
3552
3733
|
io.err(COMMENT_USAGE);
|
|
3553
3734
|
return 2;
|
|
3554
3735
|
}
|
|
3736
|
+
let threading;
|
|
3555
3737
|
return runEvent({
|
|
3556
3738
|
command: "comment",
|
|
3557
3739
|
flags,
|
|
3558
3740
|
deps,
|
|
3559
|
-
actionLabel: `comment on ${
|
|
3560
|
-
buildEvent: async (addr) =>
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3741
|
+
actionLabel: `comment on ${targetEventId.slice(0, 8)}\u2026`,
|
|
3742
|
+
buildEvent: async (addr, relayUrl) => {
|
|
3743
|
+
threading = await resolveCommentTarget(deps, targetEventId, relayUrl);
|
|
3744
|
+
return buildComment(
|
|
3745
|
+
addr.ownerPubkey,
|
|
3746
|
+
addr.repoId,
|
|
3747
|
+
threading.root,
|
|
3748
|
+
body,
|
|
3749
|
+
threading.parent
|
|
3750
|
+
);
|
|
3751
|
+
},
|
|
3752
|
+
sendDaemon: (client, addr) => {
|
|
3753
|
+
if (threading === void 0) {
|
|
3754
|
+
throw new Error(
|
|
3755
|
+
"internal: the comment target was not resolved before the publish"
|
|
3756
|
+
);
|
|
3757
|
+
}
|
|
3758
|
+
const { root, parent } = threading;
|
|
3759
|
+
return client.gitComment({
|
|
3760
|
+
repoAddr: addr,
|
|
3761
|
+
body,
|
|
3762
|
+
rootEventId: root.eventId,
|
|
3763
|
+
rootKind: root.kind,
|
|
3764
|
+
rootAuthorPubkey: root.authorPubkey,
|
|
3765
|
+
...parent !== void 0 ? { parentComment: parent } : {}
|
|
3766
|
+
});
|
|
3767
|
+
}
|
|
3575
3768
|
});
|
|
3576
3769
|
}
|
|
3577
3770
|
var PATCH_FROM_RE = /^From ([0-9a-f]{40}) /gm;
|
|
@@ -3776,14 +3969,18 @@ async function runPrStatus(args, deps) {
|
|
|
3776
3969
|
flags,
|
|
3777
3970
|
deps,
|
|
3778
3971
|
actionLabel: `status ${status} on ${targetEventId.slice(0, 8)}\u2026`,
|
|
3779
|
-
buildEvent: async (addr) =>
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3972
|
+
buildEvent: async (addr) => (
|
|
3973
|
+
// buildStatus (rig#160) now emits the root-marked `e` tag and the repo
|
|
3974
|
+
// `a` tag itself, so readers can scope a status stream to the
|
|
3975
|
+
// repository without resolving the target first (mirrors the
|
|
3976
|
+
// daemon's gitStatus).
|
|
3977
|
+
buildStatus(
|
|
3978
|
+
addr.ownerPubkey,
|
|
3979
|
+
addr.repoId,
|
|
3980
|
+
targetEventId,
|
|
3981
|
+
STATUS_KIND_BY_VALUE[status]
|
|
3982
|
+
)
|
|
3983
|
+
),
|
|
3787
3984
|
// Authority warning (#287): a status event only moves an issue/PR's
|
|
3788
3985
|
// resolved state for repo-authority-honoring clients if its author is the
|
|
3789
3986
|
// owner or a declared maintainer. Warn clearly when the active identity is
|
|
@@ -3811,11 +4008,11 @@ async function warnIfNotMaintainer(deps, args) {
|
|
|
3811
4008
|
);
|
|
3812
4009
|
if (authorized.has(identity.pubkey.toLowerCase())) return;
|
|
3813
4010
|
io.err(
|
|
3814
|
-
`warning: you (${identity.pubkey.slice(0, 8)}\u2026) are not a maintainer of 30617:${addr.ownerPubkey.slice(0, 8)}\u2026:${addr.repoId} \u2014 clients honoring repo authority (rig, rig-web) will IGNORE this status when resolving the issue/PR's state. Publishing anyway (the relay is permissionless); ask the owner to \`rig maintainers add\` you if this should stick.`
|
|
4011
|
+
`warning: you (${identity.pubkey.slice(0, 8)}\u2026) are not a maintainer of 30617:${addr.ownerPubkey.slice(0, 8)}\u2026:${addr.repoId} \u2014 clients honoring repo authority (rig, rig-web) will IGNORE this status when resolving the issue/PR's state, UNLESS you are also the target event's own author (rig#160: an issue/PR author may move their own item\u2019s status even without maintainer standing \u2014 this check cannot tell from here, since it does not know the target's author without a second relay read). Publishing anyway (the relay is permissionless); ask the owner to \`rig maintainers add\` you if this should stick for OTHER items too.`
|
|
3815
4012
|
);
|
|
3816
4013
|
} catch {
|
|
3817
4014
|
io.err(
|
|
3818
|
-
"warning: could not read the repo announcement to verify your maintainer status \u2014 if you are not the owner
|
|
4015
|
+
"warning: could not read the repo announcement to verify your maintainer status \u2014 if you are not the owner, a declared maintainer, or the target event's own author, authority-honoring clients will ignore this status."
|
|
3819
4016
|
);
|
|
3820
4017
|
}
|
|
3821
4018
|
}
|
|
@@ -4178,12 +4375,7 @@ async function runFetch(args, deps) {
|
|
|
4178
4375
|
}
|
|
4179
4376
|
const reader = new GitRepoReader(repoRoot);
|
|
4180
4377
|
const tips = [...new Set(planned.map((p) => p.newSha))];
|
|
4181
|
-
const
|
|
4182
|
-
const { missing: absent } = await reader.statObjects(candidates);
|
|
4183
|
-
const absentSet = new Set(absent);
|
|
4184
|
-
const presentLocally = new Set(
|
|
4185
|
-
candidates.filter((sha) => !absentSet.has(sha))
|
|
4186
|
-
);
|
|
4378
|
+
const presentLocally = new Set(await reader.listAllObjectShas());
|
|
4187
4379
|
const collected = await collectRepoObjects({
|
|
4188
4380
|
tips,
|
|
4189
4381
|
shaToTxId: remoteState.shaToTxId,
|
|
@@ -5522,44 +5714,15 @@ async function runMutate(op, args, deps) {
|
|
|
5522
5714
|
}
|
|
5523
5715
|
let standaloneCtx;
|
|
5524
5716
|
try {
|
|
5525
|
-
const
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
const relayUrl = ctx.relays[0];
|
|
5531
|
-
if (relayUrl === void 0 || !WS_URL_RE.test(relayUrl)) {
|
|
5532
|
-
throw new InvalidRelayUrlError(
|
|
5533
|
-
relayUrl ?? "",
|
|
5534
|
-
"a paid publish needs a ws:// or wss:// relay"
|
|
5535
|
-
);
|
|
5536
|
-
}
|
|
5537
|
-
const load = deps.loadStandalone ?? defaultLoadStandalone;
|
|
5538
|
-
standaloneCtx = await load({
|
|
5539
|
-
env: deps.env,
|
|
5540
|
-
cwd: deps.cwd,
|
|
5541
|
-
warn: (line) => io.err(line),
|
|
5542
|
-
relayUrl
|
|
5543
|
-
});
|
|
5544
|
-
const identity = identityReport(standaloneCtx);
|
|
5545
|
-
if (identity.pubkey.toLowerCase() !== ctx.owner.toLowerCase()) {
|
|
5546
|
-
io.err(
|
|
5547
|
-
`rig: only the repo owner (${ctx.owner.slice(0, 8)}\u2026) can change the maintainer set \u2014 the active identity is ${identity.pubkey.slice(0, 8)}\u2026. A non-owner republish would write your own (ignored) announcement. Nothing was published or paid.`
|
|
5548
|
-
);
|
|
5549
|
-
return 1;
|
|
5550
|
-
}
|
|
5551
|
-
const remote = await fetchRemoteState({
|
|
5552
|
-
relayUrls: [relayUrl],
|
|
5553
|
-
ownerPubkey: ctx.owner,
|
|
5554
|
-
repoId: ctx.repoId,
|
|
5555
|
-
...deps.webSocketFactory ? { webSocketFactory: deps.webSocketFactory } : {}
|
|
5717
|
+
const opened = await openAnnouncementRepublish({
|
|
5718
|
+
deps,
|
|
5719
|
+
flags,
|
|
5720
|
+
what: "change the maintainer set",
|
|
5721
|
+
before: "before managing maintainers"
|
|
5556
5722
|
});
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
);
|
|
5561
|
-
return 1;
|
|
5562
|
-
}
|
|
5723
|
+
standaloneCtx = opened.standalone;
|
|
5724
|
+
if (!opened.ok) return opened.exitCode;
|
|
5725
|
+
const { ctx, relayUrl, identity, remote, facts } = opened;
|
|
5563
5726
|
const current = remote.announceEvent ? parseMaintainers(remote.announceEvent.tags) : [];
|
|
5564
5727
|
const currentSet = new Set(current);
|
|
5565
5728
|
if (op === "add" && currentSet.has(pubkey)) {
|
|
@@ -5575,21 +5738,23 @@ async function runMutate(op, args, deps) {
|
|
|
5575
5738
|
return 0;
|
|
5576
5739
|
}
|
|
5577
5740
|
const next = op === "add" ? [...current, pubkey] : current.filter((m) => m !== pubkey);
|
|
5578
|
-
const
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
);
|
|
5587
|
-
const fee = (await standaloneCtx.publisher.getFeeRates()).eventFee.toString();
|
|
5741
|
+
const event = amendRepoAnnouncement(remote.announceEvent, {
|
|
5742
|
+
repoId: ctx.repoId,
|
|
5743
|
+
maintainers: next,
|
|
5744
|
+
...conformanceEdits(remote.announceEvent, facts)
|
|
5745
|
+
});
|
|
5746
|
+
const diff = diffAnnouncementTags(remote.announceEvent, event);
|
|
5747
|
+
const changes = { added: diff.added, removed: diff.removed };
|
|
5748
|
+
const fee = (await opened.standalone.publisher.getFeeRates()).eventFee.toString();
|
|
5588
5749
|
const action = `kind:30617 maintainers ${op} ${pubkey.slice(0, 8)}\u2026`;
|
|
5589
5750
|
if (!flags.json) {
|
|
5590
5751
|
io.out(`Republish ${action}`);
|
|
5591
5752
|
io.out(`Repo: 30617:${ctx.owner}:${ctx.repoId}`);
|
|
5592
5753
|
io.out(`Maintainers after: ${next.length === 0 ? "(none)" : next.join(", ")}`);
|
|
5754
|
+
if (!diff.unchanged) {
|
|
5755
|
+
io.out("Tags changed:");
|
|
5756
|
+
for (const line of describeAnnouncementDiff(diff)) io.out(line);
|
|
5757
|
+
}
|
|
5593
5758
|
io.out(`Fee: ${feeLabel(fee)}. Writes are permanent and non-refundable.`);
|
|
5594
5759
|
}
|
|
5595
5760
|
if (!flags.yes) {
|
|
@@ -5601,6 +5766,7 @@ async function runMutate(op, args, deps) {
|
|
|
5601
5766
|
executed: false,
|
|
5602
5767
|
feeEstimate: fee,
|
|
5603
5768
|
maintainers: next,
|
|
5769
|
+
changes,
|
|
5604
5770
|
hint: "estimate only \u2014 re-run with --yes to publish (permanent, non-refundable)"
|
|
5605
5771
|
});
|
|
5606
5772
|
return 0;
|
|
@@ -5619,7 +5785,7 @@ async function runMutate(op, args, deps) {
|
|
|
5619
5785
|
return 1;
|
|
5620
5786
|
}
|
|
5621
5787
|
}
|
|
5622
|
-
const receipt = await
|
|
5788
|
+
const receipt = await opened.standalone.publisher.publishEvent(event, [
|
|
5623
5789
|
relayUrl
|
|
5624
5790
|
]);
|
|
5625
5791
|
const result = serializeEventReceipt(event.kind, receipt);
|
|
@@ -5631,6 +5797,7 @@ async function runMutate(op, args, deps) {
|
|
|
5631
5797
|
executed: true,
|
|
5632
5798
|
feeEstimate: fee,
|
|
5633
5799
|
maintainers: next,
|
|
5800
|
+
changes,
|
|
5634
5801
|
result
|
|
5635
5802
|
});
|
|
5636
5803
|
} else {
|
|
@@ -5651,9 +5818,167 @@ async function runMutate(op, args, deps) {
|
|
|
5651
5818
|
}
|
|
5652
5819
|
}
|
|
5653
5820
|
|
|
5821
|
+
// src/cli/refresh.ts
|
|
5822
|
+
import { parseArgs as parseArgs15 } from "util";
|
|
5823
|
+
var REFRESH_USAGE = `Usage: rig refresh [options]
|
|
5824
|
+
|
|
5825
|
+
Republish this repo's kind:30617 announcement with no field edit, refreshing
|
|
5826
|
+
its NIP-34 conformance tags (#158) so other clients can find and group it:
|
|
5827
|
+
|
|
5828
|
+
relays the relay this repo publishes to \u2014 where its issues,
|
|
5829
|
+
patches and state live. Added to the relays the
|
|
5830
|
+
announcement already lists; none are removed
|
|
5831
|
+
web the repo's rig-web viewer URL, added alongside any
|
|
5832
|
+
viewer URL another client already announced
|
|
5833
|
+
r <sha> euc the earliest unique commit: the repo's fork identity.
|
|
5834
|
+
Written only if the announcement has none \u2014 once declared it
|
|
5835
|
+
never changes, so forks stay grouped
|
|
5836
|
+
|
|
5837
|
+
Every other tag rides along verbatim, including tags written by other NIP-34
|
|
5838
|
+
clients. rig never writes a \`clone\` tag (it has no git-clonable URL) and never
|
|
5839
|
+
removes one.
|
|
5840
|
+
|
|
5841
|
+
PAID: republishing the kind:30617 costs one event fee (permanent,
|
|
5842
|
+
non-refundable). Nothing is published and nothing is paid when no tag would
|
|
5843
|
+
change. Must run under the repo OWNER's identity \u2014 only the owner's
|
|
5844
|
+
announcement is authoritative.
|
|
5845
|
+
|
|
5846
|
+
Options:
|
|
5847
|
+
--repo-id <id> repository id / NIP-34 d-tag (default: git config)
|
|
5848
|
+
--owner <pubkey> repository owner (npub or hex; default: git config)
|
|
5849
|
+
--remote <name> publish/read via this configured git remote (default: origin)
|
|
5850
|
+
--relay <url> ad-hoc relay override (exactly one)
|
|
5851
|
+
--yes skip the fee confirmation (required when not a TTY)
|
|
5852
|
+
--json machine-readable envelope
|
|
5853
|
+
-h, --help show this help`;
|
|
5854
|
+
async function runRefresh(args, deps) {
|
|
5855
|
+
const { io } = deps;
|
|
5856
|
+
let flags;
|
|
5857
|
+
try {
|
|
5858
|
+
const { values, positionals } = parseArgs15({
|
|
5859
|
+
args,
|
|
5860
|
+
options: REPO_COMMAND_OPTIONS,
|
|
5861
|
+
allowPositionals: true
|
|
5862
|
+
});
|
|
5863
|
+
flags = pickRepoCommandFlags(values);
|
|
5864
|
+
if (flags.help) {
|
|
5865
|
+
io.out(REFRESH_USAGE);
|
|
5866
|
+
return 0;
|
|
5867
|
+
}
|
|
5868
|
+
if (positionals.length > 0) {
|
|
5869
|
+
throw new Error("rig refresh takes no positional arguments");
|
|
5870
|
+
}
|
|
5871
|
+
} catch (err) {
|
|
5872
|
+
io.err(err instanceof Error ? err.message : String(err));
|
|
5873
|
+
io.err(REFRESH_USAGE);
|
|
5874
|
+
return 2;
|
|
5875
|
+
}
|
|
5876
|
+
let standaloneCtx;
|
|
5877
|
+
try {
|
|
5878
|
+
const opened = await openAnnouncementRepublish({
|
|
5879
|
+
deps,
|
|
5880
|
+
flags,
|
|
5881
|
+
what: "refresh the announcement",
|
|
5882
|
+
before: "before refreshing it"
|
|
5883
|
+
});
|
|
5884
|
+
standaloneCtx = opened.standalone;
|
|
5885
|
+
if (!opened.ok) return opened.exitCode;
|
|
5886
|
+
const { ctx, relayUrl, identity, remote, facts } = opened;
|
|
5887
|
+
const event = amendRepoAnnouncement(remote.announceEvent, {
|
|
5888
|
+
repoId: ctx.repoId,
|
|
5889
|
+
...conformanceEdits(remote.announceEvent, facts)
|
|
5890
|
+
});
|
|
5891
|
+
const diff = diffAnnouncementTags(remote.announceEvent, event);
|
|
5892
|
+
if (diff.unchanged) {
|
|
5893
|
+
const changes2 = { added: diff.added, removed: diff.removed };
|
|
5894
|
+
if (flags.json) {
|
|
5895
|
+
io.emitJson({
|
|
5896
|
+
command: "refresh",
|
|
5897
|
+
repoAddr: { ownerPubkey: ctx.owner, repoId: ctx.repoId },
|
|
5898
|
+
identity,
|
|
5899
|
+
executed: false,
|
|
5900
|
+
feeEstimate: null,
|
|
5901
|
+
changes: changes2,
|
|
5902
|
+
hint: "announcement is already up to date \u2014 nothing published, nothing paid"
|
|
5903
|
+
});
|
|
5904
|
+
return 0;
|
|
5905
|
+
}
|
|
5906
|
+
io.out(
|
|
5907
|
+
`Announcement 30617:${ctx.owner}:${ctx.repoId} is already up to date \u2014 nothing to do (not published, nothing paid).`
|
|
5908
|
+
);
|
|
5909
|
+
return 0;
|
|
5910
|
+
}
|
|
5911
|
+
const fee = (await opened.standalone.publisher.getFeeRates()).eventFee.toString();
|
|
5912
|
+
const changes = { added: diff.added, removed: diff.removed };
|
|
5913
|
+
if (!flags.json) {
|
|
5914
|
+
io.out("Republish kind:30617 announcement (refresh)");
|
|
5915
|
+
io.out(`Repo: 30617:${ctx.owner}:${ctx.repoId}`);
|
|
5916
|
+
io.out("Tags changed:");
|
|
5917
|
+
for (const line of describeAnnouncementDiff(diff)) io.out(line);
|
|
5918
|
+
io.out(`Fee: ${feeLabel(fee)}. Writes are permanent and non-refundable.`);
|
|
5919
|
+
}
|
|
5920
|
+
if (!flags.yes) {
|
|
5921
|
+
if (flags.json) {
|
|
5922
|
+
io.emitJson({
|
|
5923
|
+
command: "refresh",
|
|
5924
|
+
repoAddr: { ownerPubkey: ctx.owner, repoId: ctx.repoId },
|
|
5925
|
+
identity,
|
|
5926
|
+
executed: false,
|
|
5927
|
+
feeEstimate: fee,
|
|
5928
|
+
changes,
|
|
5929
|
+
hint: "estimate only \u2014 re-run with --yes to publish (permanent, non-refundable)"
|
|
5930
|
+
});
|
|
5931
|
+
return 0;
|
|
5932
|
+
}
|
|
5933
|
+
if (!io.isInteractive) {
|
|
5934
|
+
io.err(
|
|
5935
|
+
"refusing to spend channel funds without confirmation in a non-interactive session \u2014 re-run with --yes (or use --json for an estimate)"
|
|
5936
|
+
);
|
|
5937
|
+
return 1;
|
|
5938
|
+
}
|
|
5939
|
+
const proceed = await io.confirm(
|
|
5940
|
+
`Proceed with paid republish (${feeLabel(fee)})? [y/N] `
|
|
5941
|
+
);
|
|
5942
|
+
if (!proceed) {
|
|
5943
|
+
io.err("aborted \u2014 nothing was published.");
|
|
5944
|
+
return 1;
|
|
5945
|
+
}
|
|
5946
|
+
}
|
|
5947
|
+
const receipt = await opened.standalone.publisher.publishEvent(event, [
|
|
5948
|
+
relayUrl
|
|
5949
|
+
]);
|
|
5950
|
+
const result = serializeEventReceipt(event.kind, receipt);
|
|
5951
|
+
if (flags.json) {
|
|
5952
|
+
io.emitJson({
|
|
5953
|
+
command: "refresh",
|
|
5954
|
+
repoAddr: { ownerPubkey: ctx.owner, repoId: ctx.repoId },
|
|
5955
|
+
identity,
|
|
5956
|
+
executed: true,
|
|
5957
|
+
feeEstimate: fee,
|
|
5958
|
+
changes,
|
|
5959
|
+
result
|
|
5960
|
+
});
|
|
5961
|
+
} else {
|
|
5962
|
+
io.out(
|
|
5963
|
+
`Published kind:30617 refresh: ${result.eventId} paid ${result.feePaid} base units`
|
|
5964
|
+
);
|
|
5965
|
+
}
|
|
5966
|
+
return 0;
|
|
5967
|
+
} catch (err) {
|
|
5968
|
+
return emitCliError(io, flags.json, "refresh", err);
|
|
5969
|
+
} finally {
|
|
5970
|
+
if (standaloneCtx) {
|
|
5971
|
+
try {
|
|
5972
|
+
await standaloneCtx.stop();
|
|
5973
|
+
} catch {
|
|
5974
|
+
}
|
|
5975
|
+
}
|
|
5976
|
+
}
|
|
5977
|
+
}
|
|
5978
|
+
|
|
5654
5979
|
// src/cli/name.ts
|
|
5655
5980
|
import { randomUUID } from "crypto";
|
|
5656
|
-
import { parseArgs as
|
|
5981
|
+
import { parseArgs as parseArgs16 } from "util";
|
|
5657
5982
|
var ARIO_DECIMALS = 6;
|
|
5658
5983
|
function renderMario(mario) {
|
|
5659
5984
|
return `${mario.toString()} mARIO (~${formatUnits(mario.toString(), ARIO_DECIMALS)} ARIO)`;
|
|
@@ -6162,7 +6487,7 @@ async function resolveNameContext(deps, network, processId, mode) {
|
|
|
6162
6487
|
return { identity, solanaAddress, network, processId, sdk, nostrSecretKey };
|
|
6163
6488
|
}
|
|
6164
6489
|
function parseNameFlags(args, env) {
|
|
6165
|
-
const { values, positionals } =
|
|
6490
|
+
const { values, positionals } = parseArgs16({
|
|
6166
6491
|
args,
|
|
6167
6492
|
allowPositionals: true,
|
|
6168
6493
|
options: {
|
|
@@ -6721,7 +7046,7 @@ async function runName(args, deps) {
|
|
|
6721
7046
|
}
|
|
6722
7047
|
|
|
6723
7048
|
// src/cli/payout.ts
|
|
6724
|
-
import { parseArgs as
|
|
7049
|
+
import { parseArgs as parseArgs17 } from "util";
|
|
6725
7050
|
import { getAddress } from "viem";
|
|
6726
7051
|
var PAYOUT_USAGE = `Usage: rig payout <set|clear|show> [<address>] [options]
|
|
6727
7052
|
|
|
@@ -6777,7 +7102,7 @@ async function runShow2(args, deps) {
|
|
|
6777
7102
|
const { io } = deps;
|
|
6778
7103
|
let flags;
|
|
6779
7104
|
try {
|
|
6780
|
-
const { values, positionals } =
|
|
7105
|
+
const { values, positionals } = parseArgs17({
|
|
6781
7106
|
args,
|
|
6782
7107
|
options: REPO_COMMAND_OPTIONS,
|
|
6783
7108
|
allowPositionals: true
|
|
@@ -6839,7 +7164,7 @@ async function runMutate2(op, args, deps) {
|
|
|
6839
7164
|
let flags;
|
|
6840
7165
|
let nextPayout = null;
|
|
6841
7166
|
try {
|
|
6842
|
-
const { values, positionals } =
|
|
7167
|
+
const { values, positionals } = parseArgs17({
|
|
6843
7168
|
args,
|
|
6844
7169
|
options: REPO_COMMAND_OPTIONS,
|
|
6845
7170
|
allowPositionals: true
|
|
@@ -6870,44 +7195,15 @@ async function runMutate2(op, args, deps) {
|
|
|
6870
7195
|
}
|
|
6871
7196
|
let standaloneCtx;
|
|
6872
7197
|
try {
|
|
6873
|
-
const
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
const relayUrl = ctx.relays[0];
|
|
6879
|
-
if (relayUrl === void 0 || !WS_URL_RE.test(relayUrl)) {
|
|
6880
|
-
throw new InvalidRelayUrlError(
|
|
6881
|
-
relayUrl ?? "",
|
|
6882
|
-
"a paid publish needs a ws:// or wss:// relay"
|
|
6883
|
-
);
|
|
6884
|
-
}
|
|
6885
|
-
const load = deps.loadStandalone ?? defaultLoadStandalone;
|
|
6886
|
-
standaloneCtx = await load({
|
|
6887
|
-
env: deps.env,
|
|
6888
|
-
cwd: deps.cwd,
|
|
6889
|
-
warn: (line) => io.err(line),
|
|
6890
|
-
relayUrl
|
|
6891
|
-
});
|
|
6892
|
-
const identity = identityReport(standaloneCtx);
|
|
6893
|
-
if (identity.pubkey.toLowerCase() !== ctx.owner.toLowerCase()) {
|
|
6894
|
-
io.err(
|
|
6895
|
-
`rig: only the repo owner (${ctx.owner.slice(0, 8)}\u2026) can change the payout pointer \u2014 the active identity is ${identity.pubkey.slice(0, 8)}\u2026. A non-owner republish would write your own (ignored) announcement. Nothing was published or paid.`
|
|
6896
|
-
);
|
|
6897
|
-
return 1;
|
|
6898
|
-
}
|
|
6899
|
-
const remote = await fetchRemoteState({
|
|
6900
|
-
relayUrls: [relayUrl],
|
|
6901
|
-
ownerPubkey: ctx.owner,
|
|
6902
|
-
repoId: ctx.repoId,
|
|
6903
|
-
...deps.webSocketFactory ? { webSocketFactory: deps.webSocketFactory } : {}
|
|
7198
|
+
const opened = await openAnnouncementRepublish({
|
|
7199
|
+
deps,
|
|
7200
|
+
flags,
|
|
7201
|
+
what: "change the payout pointer",
|
|
7202
|
+
before: "before managing the payout pointer"
|
|
6904
7203
|
});
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
);
|
|
6909
|
-
return 1;
|
|
6910
|
-
}
|
|
7204
|
+
standaloneCtx = opened.standalone;
|
|
7205
|
+
if (!opened.ok) return opened.exitCode;
|
|
7206
|
+
const { ctx, relayUrl, identity, remote, facts } = opened;
|
|
6911
7207
|
const current = remote.payout;
|
|
6912
7208
|
if (nextPayout !== null && current !== null && current.chain === nextPayout.chain && current.address === nextPayout.address) {
|
|
6913
7209
|
io.err(
|
|
@@ -6919,16 +7215,14 @@ async function runMutate2(op, args, deps) {
|
|
|
6919
7215
|
io.err("rig: no payout pointer is set \u2014 nothing to do (not published).");
|
|
6920
7216
|
return 0;
|
|
6921
7217
|
}
|
|
6922
|
-
const
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
);
|
|
6931
|
-
const fee = (await standaloneCtx.publisher.getFeeRates()).eventFee.toString();
|
|
7218
|
+
const event = amendRepoAnnouncement(remote.announceEvent, {
|
|
7219
|
+
repoId: ctx.repoId,
|
|
7220
|
+
payout: nextPayout,
|
|
7221
|
+
...conformanceEdits(remote.announceEvent, facts)
|
|
7222
|
+
});
|
|
7223
|
+
const diff = diffAnnouncementTags(remote.announceEvent, event);
|
|
7224
|
+
const changes = { added: diff.added, removed: diff.removed };
|
|
7225
|
+
const fee = (await opened.standalone.publisher.getFeeRates()).eventFee.toString();
|
|
6932
7226
|
const action = nextPayout ? `kind:30617 payout set ${nextPayout.chain} ${nextPayout.address}` : "kind:30617 payout clear";
|
|
6933
7227
|
if (!flags.json) {
|
|
6934
7228
|
io.out(`Republish ${action}`);
|
|
@@ -6936,6 +7230,10 @@ async function runMutate2(op, args, deps) {
|
|
|
6936
7230
|
io.out(
|
|
6937
7231
|
`Payout after: ${nextPayout ? `${nextPayout.chain} ${nextPayout.address}` : "(none)"}`
|
|
6938
7232
|
);
|
|
7233
|
+
if (!diff.unchanged) {
|
|
7234
|
+
io.out("Tags changed:");
|
|
7235
|
+
for (const line of describeAnnouncementDiff(diff)) io.out(line);
|
|
7236
|
+
}
|
|
6939
7237
|
io.out(`Fee: ${feeLabel(fee)}. Writes are permanent and non-refundable.`);
|
|
6940
7238
|
}
|
|
6941
7239
|
if (!flags.yes) {
|
|
@@ -6947,6 +7245,7 @@ async function runMutate2(op, args, deps) {
|
|
|
6947
7245
|
executed: false,
|
|
6948
7246
|
feeEstimate: fee,
|
|
6949
7247
|
payout: nextPayout,
|
|
7248
|
+
changes,
|
|
6950
7249
|
hint: "estimate only \u2014 re-run with --yes to publish (permanent, non-refundable)"
|
|
6951
7250
|
});
|
|
6952
7251
|
return 0;
|
|
@@ -6965,7 +7264,7 @@ async function runMutate2(op, args, deps) {
|
|
|
6965
7264
|
return 1;
|
|
6966
7265
|
}
|
|
6967
7266
|
}
|
|
6968
|
-
const receipt = await
|
|
7267
|
+
const receipt = await opened.standalone.publisher.publishEvent(event, [
|
|
6969
7268
|
relayUrl
|
|
6970
7269
|
]);
|
|
6971
7270
|
const result = serializeEventReceipt(event.kind, receipt);
|
|
@@ -6977,6 +7276,7 @@ async function runMutate2(op, args, deps) {
|
|
|
6977
7276
|
executed: true,
|
|
6978
7277
|
feeEstimate: fee,
|
|
6979
7278
|
payout: nextPayout,
|
|
7279
|
+
changes,
|
|
6980
7280
|
result
|
|
6981
7281
|
});
|
|
6982
7282
|
} else {
|
|
@@ -6998,7 +7298,7 @@ async function runMutate2(op, args, deps) {
|
|
|
6998
7298
|
}
|
|
6999
7299
|
|
|
7000
7300
|
// src/cli/site.ts
|
|
7001
|
-
import { parseArgs as
|
|
7301
|
+
import { parseArgs as parseArgs18 } from "util";
|
|
7002
7302
|
|
|
7003
7303
|
// src/arweave-manifest.ts
|
|
7004
7304
|
var DEFAULT_INDEX = "index.html";
|
|
@@ -7089,7 +7389,7 @@ Options (publish):
|
|
|
7089
7389
|
estimate (nothing uploaded)
|
|
7090
7390
|
-h, --help show this help`;
|
|
7091
7391
|
function parseSiteArgs(args) {
|
|
7092
|
-
const { values, positionals } =
|
|
7392
|
+
const { values, positionals } = parseArgs18({
|
|
7093
7393
|
args,
|
|
7094
7394
|
options: {
|
|
7095
7395
|
index: { type: "string" },
|
|
@@ -7492,7 +7792,8 @@ Commands rig owns:
|
|
|
7492
7792
|
issue list | show <id> read the repo's issues + comments (free)
|
|
7493
7793
|
pr list | show <id> read the repo's patches; show prints the full
|
|
7494
7794
|
patch text (free)
|
|
7495
|
-
comment <
|
|
7795
|
+
comment <target-event-id> comment (NIP-22 kind:1111) on an issue or patch,
|
|
7796
|
+
or reply to an existing kind:1111 comment
|
|
7496
7797
|
pr create publish a patch (kind:1617) with real
|
|
7497
7798
|
\`git format-patch\` content
|
|
7498
7799
|
pr status <event-id> <state> set an issue/patch status (kind:1630-1633):
|
|
@@ -7501,6 +7802,9 @@ Commands rig owns:
|
|
|
7501
7802
|
maintainers add <pubkey> remove republish the kind:30617 to change who may
|
|
7502
7803
|
maintainers remove <pubkey> author authoritative issue/PR status (owner is
|
|
7503
7804
|
always an implicit maintainer)
|
|
7805
|
+
refresh republish the kind:30617 with no field edit to
|
|
7806
|
+
refresh its NIP-34 tags (relays, web, the euc fork
|
|
7807
|
+
identity) \u2014 PAID, and free when nothing changes
|
|
7504
7808
|
payout show show the repo's declared payout pointer (free);
|
|
7505
7809
|
payout set <address> set/clear republish the kind:30617 \u2014 no pointer
|
|
7506
7810
|
payout clear means the serving node keeps 100% of
|
|
@@ -7619,6 +7923,8 @@ async function dispatch(argv, deps) {
|
|
|
7619
7923
|
return runMaintainers(rest, deps);
|
|
7620
7924
|
case "payout":
|
|
7621
7925
|
return runPayout(rest, deps);
|
|
7926
|
+
case "refresh":
|
|
7927
|
+
return runRefresh(rest, deps);
|
|
7622
7928
|
case "channel":
|
|
7623
7929
|
return runChannel(rest, deps);
|
|
7624
7930
|
case "channels":
|
|
@@ -7670,4 +7976,4 @@ export {
|
|
|
7670
7976
|
rigVersion,
|
|
7671
7977
|
dispatch
|
|
7672
7978
|
};
|
|
7673
|
-
//# sourceMappingURL=chunk-
|
|
7979
|
+
//# sourceMappingURL=chunk-X232W4TG.js.map
|