run402 4.24.0 → 4.25.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/cli.mjs +6 -6
- package/git-remote-run402.mjs +270 -0
- package/lib/command-manifest.mjs +11 -1
- package/lib/credentials.mjs +4 -0
- package/lib/domains.mjs +0 -14
- package/lib/gitvault.mjs +370 -0
- package/lib/init.mjs +143 -1
- package/lib/pay.test.mjs +0 -4
- package/package.json +8 -2
- package/sdk/dist/index.d.ts +20 -3
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/index.js +22 -3
- package/sdk/dist/index.js.map +1 -1
- package/sdk/dist/namespaces/admin.d.ts +0 -5
- package/sdk/dist/namespaces/admin.d.ts.map +1 -1
- package/sdk/dist/namespaces/admin.js +0 -9
- package/sdk/dist/namespaces/admin.js.map +1 -1
- package/sdk/dist/namespaces/assets.d.ts +1 -20
- package/sdk/dist/namespaces/assets.d.ts.map +1 -1
- package/sdk/dist/namespaces/assets.js +0 -27
- package/sdk/dist/namespaces/assets.js.map +1 -1
- package/sdk/dist/namespaces/auth.js +1 -1
- package/sdk/dist/namespaces/auth.js.map +1 -1
- package/sdk/dist/namespaces/domains.d.ts +0 -19
- package/sdk/dist/namespaces/domains.d.ts.map +1 -1
- package/sdk/dist/namespaces/domains.js +0 -19
- package/sdk/dist/namespaces/domains.js.map +1 -1
- package/sdk/dist/namespaces/gitvault.crypto.d.ts +319 -0
- package/sdk/dist/namespaces/gitvault.crypto.d.ts.map +1 -0
- package/sdk/dist/namespaces/gitvault.crypto.js +690 -0
- package/sdk/dist/namespaces/gitvault.crypto.js.map +1 -0
- package/sdk/dist/namespaces/gitvault.d.ts +473 -0
- package/sdk/dist/namespaces/gitvault.d.ts.map +1 -0
- package/sdk/dist/namespaces/gitvault.js +714 -0
- package/sdk/dist/namespaces/gitvault.js.map +1 -0
- package/sdk/dist/namespaces/gitvault.types.d.ts +481 -0
- package/sdk/dist/namespaces/gitvault.types.d.ts.map +1 -0
- package/sdk/dist/namespaces/gitvault.types.js +19 -0
- package/sdk/dist/namespaces/gitvault.types.js.map +1 -0
- package/sdk/dist/namespaces/org.d.ts +1 -3
- package/sdk/dist/namespaces/org.d.ts.map +1 -1
- package/sdk/dist/namespaces/org.js +6 -10
- package/sdk/dist/namespaces/org.js.map +1 -1
- package/sdk/dist/namespaces/pay.d.ts +0 -8
- package/sdk/dist/namespaces/pay.d.ts.map +1 -1
- package/sdk/dist/namespaces/pay.js.map +1 -1
- package/sdk/dist/namespaces/projects.d.ts +2 -2
- package/sdk/dist/namespaces/projects.d.ts.map +1 -1
- package/sdk/dist/namespaces/projects.js +4 -12
- package/sdk/dist/namespaces/projects.js.map +1 -1
- package/sdk/dist/namespaces/secrets.d.ts +0 -2
- package/sdk/dist/namespaces/secrets.d.ts.map +1 -1
- package/sdk/dist/namespaces/secrets.js +3 -10
- package/sdk/dist/namespaces/secrets.js.map +1 -1
- package/sdk/dist/namespaces/subdomains.d.ts +0 -2
- package/sdk/dist/namespaces/subdomains.d.ts.map +1 -1
- package/sdk/dist/namespaces/subdomains.js +5 -16
- package/sdk/dist/namespaces/subdomains.js.map +1 -1
- package/sdk/dist/namespaces/transfers.d.ts +0 -2
- package/sdk/dist/namespaces/transfers.d.ts.map +1 -1
- package/sdk/dist/namespaces/transfers.js +8 -10
- package/sdk/dist/namespaces/transfers.js.map +1 -1
- package/sdk/dist/namespaces/wallets.d.ts +0 -12
- package/sdk/dist/namespaces/wallets.d.ts.map +1 -1
- package/sdk/dist/namespaces/wallets.js +0 -14
- package/sdk/dist/namespaces/wallets.js.map +1 -1
- package/sdk/dist/node/gitvault-creation-journal.d.ts +222 -0
- package/sdk/dist/node/gitvault-creation-journal.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-creation-journal.js +365 -0
- package/sdk/dist/node/gitvault-creation-journal.js.map +1 -0
- package/sdk/dist/node/gitvault-deploy.d.ts +211 -0
- package/sdk/dist/node/gitvault-deploy.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-deploy.js +292 -0
- package/sdk/dist/node/gitvault-deploy.js.map +1 -0
- package/sdk/dist/node/gitvault-keystore.d.ts +207 -0
- package/sdk/dist/node/gitvault-keystore.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-keystore.js +529 -0
- package/sdk/dist/node/gitvault-keystore.js.map +1 -0
- package/sdk/dist/node/gitvault-prune.d.ts +341 -0
- package/sdk/dist/node/gitvault-prune.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-prune.js +410 -0
- package/sdk/dist/node/gitvault-prune.js.map +1 -0
- package/sdk/dist/node/gitvault-publication.d.ts +730 -0
- package/sdk/dist/node/gitvault-publication.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-publication.js +1475 -0
- package/sdk/dist/node/gitvault-publication.js.map +1 -0
- package/sdk/dist/node/gitvault-snapshot.d.ts +190 -0
- package/sdk/dist/node/gitvault-snapshot.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-snapshot.js +505 -0
- package/sdk/dist/node/gitvault-snapshot.js.map +1 -0
- package/sdk/dist/node/index.d.ts +11 -0
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js +9 -0
- package/sdk/dist/node/index.js.map +1 -1
- package/sdk/dist/node/paid-fetch.d.ts.map +1 -1
- package/sdk/dist/node/paid-fetch.js +0 -4
- package/sdk/dist/node/paid-fetch.js.map +1 -1
- package/sdk/dist/node/sites-node.d.ts +1 -8
- package/sdk/dist/node/sites-node.d.ts.map +1 -1
- package/sdk/dist/node/sites-node.js +1 -7
- package/sdk/dist/node/sites-node.js.map +1 -1
- package/sdk/dist/scoped.d.ts +4 -35
- package/sdk/dist/scoped.d.ts.map +1 -1
- package/sdk/dist/scoped.js +9 -74
- package/sdk/dist/scoped.js.map +1 -1
- package/lib/sender-domain.mjs +0 -36
- package/sdk/dist/deprecate.d.ts +0 -23
- package/sdk/dist/deprecate.d.ts.map +0 -1
- package/sdk/dist/deprecate.js +0 -42
- package/sdk/dist/deprecate.js.map +0 -1
- package/sdk/dist/namespaces/sender-domain.d.ts +0 -47
- package/sdk/dist/namespaces/sender-domain.d.ts.map +0 -1
- package/sdk/dist/namespaces/sender-domain.js +0 -45
- package/sdk/dist/namespaces/sender-domain.js.map +0 -1
package/lib/gitvault.mjs
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `run402 gitvault` — the host-blind encrypted Git remote (wire tag `r402s/v0`).
|
|
3
|
+
*
|
|
4
|
+
* ARCHITECTURAL LAW (gitvault-client-surface, "All protocol logic lives in the
|
|
5
|
+
* SDK"): every piece of vault protocol behaviour — crypto core, keystore,
|
|
6
|
+
* creation journal, snapshot + capture, publication state machines, ref
|
|
7
|
+
* transactions, verification budget, token exchange, repair — lives ONCE in
|
|
8
|
+
* `@run402/sdk` under `r.gitvault`. This module is a THIN ADAPTER: argument
|
|
9
|
+
* parsing, TTY output, exit codes, local file I/O. It adds zero protocol
|
|
10
|
+
* behaviour, and imports only the SDK (via `./sdk.mjs`) plus the CLI's own
|
|
11
|
+
* argument/error helpers — never a crypto, HTTP, or git library.
|
|
12
|
+
*
|
|
13
|
+
* Pipe contract (docs/style.md): the payload is JSON on stdout; every human
|
|
14
|
+
* line — progress, the terminal-loss statement, advisories — goes to stderr, so
|
|
15
|
+
* `run402 gitvault status | jq` stays clean.
|
|
16
|
+
*
|
|
17
|
+
* Run these from inside the git working tree: `repo_dir` is `process.cwd()`.
|
|
18
|
+
*/
|
|
19
|
+
import { readFileSync } from "node:fs";
|
|
20
|
+
import { resolveProjectId } from "./config.mjs";
|
|
21
|
+
import { getSdk } from "./sdk.mjs";
|
|
22
|
+
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
23
|
+
import {
|
|
24
|
+
normalizeArgv,
|
|
25
|
+
hasHelp,
|
|
26
|
+
assertKnownFlags,
|
|
27
|
+
parseIntegerFlag,
|
|
28
|
+
flagValue,
|
|
29
|
+
requirePositionalCount,
|
|
30
|
+
failUnknownSubcommand,
|
|
31
|
+
} from "./argparse.mjs";
|
|
32
|
+
|
|
33
|
+
/** Value-taking flags every gitvault subcommand accepts. */
|
|
34
|
+
const COMMON_VALUE_FLAGS = ["--project", "--repo"];
|
|
35
|
+
|
|
36
|
+
export const HELP = `run402 gitvault — your source, encrypted before it leaves the machine
|
|
37
|
+
|
|
38
|
+
Usage:
|
|
39
|
+
run402 gitvault status [--project <id>] [--repo <repo_id>]
|
|
40
|
+
run402 gitvault push [--project <id>] [--repo <repo_id>] [--message <text>] [--checkpoint]
|
|
41
|
+
run402 gitvault compact [--project <id>] [--repo <repo_id>]
|
|
42
|
+
run402 gitvault prune [--project <id>] [--repo <repo_id>]
|
|
43
|
+
[--submit --intent-core <path> --verifier-receipt <path> [--wait]]
|
|
44
|
+
run402 gitvault verify [--project <id>] [--repo <repo_id>] [--budget <n>]
|
|
45
|
+
|
|
46
|
+
Subcommands:
|
|
47
|
+
status What this machine and the control plane each believe about the
|
|
48
|
+
vault: allocation, policy, whether this keystore can sign, the
|
|
49
|
+
authenticated and materialized pins, and any pending
|
|
50
|
+
unvaulted-override journals. Never reports key material.
|
|
51
|
+
push Capture the working tree and publish it. This is NOT gated on a
|
|
52
|
+
deploy — a vault-only project pushes for months without one.
|
|
53
|
+
Before reporting a push as landed the SDK compares finalization
|
|
54
|
+
receipts against the expected manifest and reads the admitted head
|
|
55
|
+
back from storage; a 200 alone is never enough.
|
|
56
|
+
compact Publish a checkpoint covering the canonical refs, every root
|
|
57
|
+
unexpired at the cutoff, and the HEAD target, under a maintenance
|
|
58
|
+
lease so a concurrent cycle cannot race it.
|
|
59
|
+
prune Plan a prune, and — with both verifier receipts — submit it.
|
|
60
|
+
Two phases, because the protocol is two-phase; see below.
|
|
61
|
+
verify Verify the head chain from the authenticated pin up to the newest
|
|
62
|
+
listed generation. Fails closed on a regression, a gap, or a
|
|
63
|
+
transition descriptor this client cannot validate.
|
|
64
|
+
|
|
65
|
+
Options:
|
|
66
|
+
--project <id> Project whose vault to act on (defaults to the active project)
|
|
67
|
+
--repo <repo_id> Address the vault directly by id, skipping project lookup
|
|
68
|
+
--message <text> push: commit message for the synthetic commit a dirty tree
|
|
69
|
+
produces (a clean tree pushes HEAD itself, no message used)
|
|
70
|
+
--checkpoint push: force the checkpoint-bearing form regardless of delta size
|
|
71
|
+
--budget <n> verify: heads to verify in this call. The verified prefix is
|
|
72
|
+
persisted, so a budget-exceeded run resumes where it stopped
|
|
73
|
+
instead of restarting.
|
|
74
|
+
--submit prune: submit the planned intent. Requires --intent-core and
|
|
75
|
+
--verifier-receipt.
|
|
76
|
+
--intent-core <path>
|
|
77
|
+
prune: the plan's \`intent_core\`, saved verbatim from a prior
|
|
78
|
+
planning run. A rebuilt core carries a different nonce, so
|
|
79
|
+
the r402s-verify receipt would no longer bind to it.
|
|
80
|
+
--verifier-receipt <path>
|
|
81
|
+
prune: r402s-verify's \`verifier_receipt\` over that core.
|
|
82
|
+
--wait prune: poll the submitted intent until the control-plane-
|
|
83
|
+
signed completion appears, instead of returning immediately.
|
|
84
|
+
--json No-op: stdout is already JSON.
|
|
85
|
+
|
|
86
|
+
prune is TWO PHASES, because the protocol is:
|
|
87
|
+
1. \`run402 gitvault prune\` plans. It walks the verified chain, computes the GC
|
|
88
|
+
root set, subtracts it, and prints a SIGNED \`intent_core\` plus its
|
|
89
|
+
\`intent_core_sha256\`. Nothing is submitted and nothing is deleted.
|
|
90
|
+
2. Run \`r402s-verify\` against that core, then re-run with
|
|
91
|
+
\`--submit --intent-core <core.json> --verifier-receipt <receipt.json>\`.
|
|
92
|
+
The intent carries TWO receipts over the same core, one per implementation:
|
|
93
|
+
this CLI produces the \`run402-cli\` half by restoring the latest checkpoint
|
|
94
|
+
and recomputing its commitments, and \`r402s-verify\` produces the other.
|
|
95
|
+
A second receipt from this lineage would prove nothing, so it is never
|
|
96
|
+
synthesized here.
|
|
97
|
+
Only the control-plane-signed completion says what was deleted, and only its
|
|
98
|
+
\`deleted\` result means the bytes are gone — \`present_after_attempt\` is a
|
|
99
|
+
FAILED deletion, never counted as a success. There is deliberately no purge
|
|
100
|
+
verb in V0 at all. Retention is an operational promise of the platform, not a
|
|
101
|
+
cryptographic guarantee against it.
|
|
102
|
+
|
|
103
|
+
Expiry is permissive, by design:
|
|
104
|
+
A retention root whose \`effective_admitted_at\` this client cannot resolve is
|
|
105
|
+
RETAINED, and a compact that cannot obtain a retention-cutoff ticket keeps
|
|
106
|
+
every root. That costs storage, never history.
|
|
107
|
+
|
|
108
|
+
Terminal loss (protocol §0):
|
|
109
|
+
In V0-A, whole-machine or whole-keystore loss is terminal for vault history
|
|
110
|
+
until human envelopes ship. \`status\` prints the full statement verbatim on
|
|
111
|
+
stderr and carries it in its JSON — read it before you rely on this.
|
|
112
|
+
|
|
113
|
+
Examples:
|
|
114
|
+
run402 gitvault status
|
|
115
|
+
run402 gitvault push --message "wip: refactor the parser"
|
|
116
|
+
run402 gitvault verify --budget 500
|
|
117
|
+
run402 gitvault prune --project prj_1a2b3c
|
|
118
|
+
`;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Resolve which vault to act on, plus the local git tree.
|
|
122
|
+
*
|
|
123
|
+
* `--repo` addresses the vault directly (the cold-restart path: an agent that
|
|
124
|
+
* knows its repo_id needs no project lookup). Otherwise the project is
|
|
125
|
+
* resolved the CLI-wide way — `--project`, then RUN402_PROJECT_ID, then the
|
|
126
|
+
* active project — and the SDK resolves the vault from it.
|
|
127
|
+
*/
|
|
128
|
+
function vaultTarget(a) {
|
|
129
|
+
const repoId = flagValue(a, "--repo");
|
|
130
|
+
const project = flagValue(a, "--project");
|
|
131
|
+
const target = { repo_dir: process.cwd() };
|
|
132
|
+
if (repoId != null) target.repo_id = repoId;
|
|
133
|
+
// Only demand a project when one is actually needed: `--repo` alone is a
|
|
134
|
+
// complete address, and requiring an active project on top of it would make
|
|
135
|
+
// the cold-restart path fail for no reason.
|
|
136
|
+
if (repoId == null || project != null) target.project_id = resolveProjectId(project);
|
|
137
|
+
return target;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Print the protocol §0 terminal-loss statement.
|
|
142
|
+
*
|
|
143
|
+
* NORMATIVE COPY, printed verbatim straight from the SDK's own constants and
|
|
144
|
+
* never paraphrased, summarized, or reassembled here. Both lines also ride in
|
|
145
|
+
* the JSON payload on stdout.
|
|
146
|
+
*/
|
|
147
|
+
function printTerminalLoss(status) {
|
|
148
|
+
console.error("");
|
|
149
|
+
console.error(status.terminal_loss_statement);
|
|
150
|
+
console.error(status.terminal_loss_detail);
|
|
151
|
+
console.error("");
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function status(args) {
|
|
155
|
+
const a = normalizeArgv(args);
|
|
156
|
+
assertKnownFlags(a, [...COMMON_VALUE_FLAGS, "--help", "-h"], COMMON_VALUE_FLAGS);
|
|
157
|
+
requirePositionalCount(a, COMMON_VALUE_FLAGS, {
|
|
158
|
+
min: 0, max: 0, command: "run402 gitvault status", missing: "",
|
|
159
|
+
});
|
|
160
|
+
try {
|
|
161
|
+
const s = await getSdk().gitvault.status(vaultTarget(a));
|
|
162
|
+
console.log(JSON.stringify(s, null, 2));
|
|
163
|
+
printTerminalLoss(s);
|
|
164
|
+
// Advisories are echoed EXACTLY as the SDK reported them. Nothing is
|
|
165
|
+
// synthesized here — in particular a project that has never deployed gets
|
|
166
|
+
// no deploy-related warning, because a vault-only project is a first-class
|
|
167
|
+
// shape (protocol D183), not a half-configured deploy.
|
|
168
|
+
for (const w of s.warnings) console.error(`warning (${w.kind}): ${w.message}`);
|
|
169
|
+
for (const n of s.next_actions) console.error(`next: ${n.action}${n.command ? ` — ${n.command}` : ""}`);
|
|
170
|
+
} catch (err) {
|
|
171
|
+
reportSdkError(err);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async function push(args) {
|
|
176
|
+
const a = normalizeArgv(args);
|
|
177
|
+
const valueFlags = [...COMMON_VALUE_FLAGS, "--message"];
|
|
178
|
+
assertKnownFlags(a, [...valueFlags, "--checkpoint", "--help", "-h"], valueFlags);
|
|
179
|
+
requirePositionalCount(a, valueFlags, {
|
|
180
|
+
min: 0, max: 0, command: "run402 gitvault push", missing: "",
|
|
181
|
+
});
|
|
182
|
+
const message = flagValue(a, "--message");
|
|
183
|
+
const opts = {
|
|
184
|
+
...vaultTarget(a),
|
|
185
|
+
// The gitvault_commit line is progress, not payload: print it the moment
|
|
186
|
+
// the snapshot exists, well before the publication round-trips finish, so
|
|
187
|
+
// a human watching a slow push sees what is being pushed.
|
|
188
|
+
onCommitLine: (line) => console.error(line),
|
|
189
|
+
};
|
|
190
|
+
// The message rides on `snapshot`, which is what `captureSnapshot` reads —
|
|
191
|
+
// and, since 5.12b removed the dead top-level `push({ message })` field, is
|
|
192
|
+
// the ONE place it can ride.
|
|
193
|
+
if (message != null) opts.snapshot = { message };
|
|
194
|
+
if (a.includes("--checkpoint")) opts.checkpoint = true;
|
|
195
|
+
try {
|
|
196
|
+
const result = await getSdk().gitvault.push(opts);
|
|
197
|
+
console.log(JSON.stringify(result, null, 2));
|
|
198
|
+
console.error(`published generation ${result.generation} (${result.form})`);
|
|
199
|
+
} catch (err) {
|
|
200
|
+
reportSdkError(err);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async function compact(args) {
|
|
205
|
+
const a = normalizeArgv(args);
|
|
206
|
+
assertKnownFlags(a, [...COMMON_VALUE_FLAGS, "--help", "-h"], COMMON_VALUE_FLAGS);
|
|
207
|
+
requirePositionalCount(a, COMMON_VALUE_FLAGS, {
|
|
208
|
+
min: 0, max: 0, command: "run402 gitvault compact", missing: "",
|
|
209
|
+
});
|
|
210
|
+
try {
|
|
211
|
+
const result = await getSdk().gitvault.compact(vaultTarget(a));
|
|
212
|
+
console.log(JSON.stringify(result, null, 2));
|
|
213
|
+
console.error(
|
|
214
|
+
`checkpoint published at generation ${result.generation}: ` +
|
|
215
|
+
`${result.covered_refs} ref(s), ${result.covered_roots} retention root(s).`,
|
|
216
|
+
);
|
|
217
|
+
if (!result.cutoff_bound) {
|
|
218
|
+
// Say what actually happened rather than reporting a clean compaction:
|
|
219
|
+
// without a ticket no root can leave the map, so this run reclaimed
|
|
220
|
+
// nothing from expiry.
|
|
221
|
+
console.error(
|
|
222
|
+
"no retention-cutoff ticket was obtained, so roots were RETAINED — expiry is permissive. " +
|
|
223
|
+
"The checkpoint published, but no expired root left the map; re-run compact once the ticket route answers.",
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
} catch (err) {
|
|
227
|
+
reportSdkError(err);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** Read a protocol object a prior planning run (or r402s-verify) wrote to disk. */
|
|
232
|
+
function readJsonFile(flag, path) {
|
|
233
|
+
let text;
|
|
234
|
+
try {
|
|
235
|
+
text = readFileSync(path, "utf8");
|
|
236
|
+
} catch (err) {
|
|
237
|
+
fail({
|
|
238
|
+
code: "BAD_USAGE",
|
|
239
|
+
message: `${flag} ${path} could not be read: ${err?.message ?? String(err)}`,
|
|
240
|
+
hint: "Point it at the file a prior `run402 gitvault prune` (or r402s-verify) wrote.",
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
return JSON.parse(text);
|
|
245
|
+
} catch (err) {
|
|
246
|
+
fail({
|
|
247
|
+
code: "BAD_USAGE",
|
|
248
|
+
message: `${flag} ${path} is not valid JSON: ${err?.message ?? String(err)}`,
|
|
249
|
+
hint: "Pass the file verbatim; do not reformat or re-serialize it.",
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async function prune(args) {
|
|
255
|
+
const a = normalizeArgv(args);
|
|
256
|
+
const valueFlags = [...COMMON_VALUE_FLAGS, "--intent-core", "--verifier-receipt"];
|
|
257
|
+
assertKnownFlags(a, [...valueFlags, "--submit", "--wait", "--help", "-h"], valueFlags);
|
|
258
|
+
requirePositionalCount(a, valueFlags, {
|
|
259
|
+
min: 0, max: 0, command: "run402 gitvault prune", missing: "",
|
|
260
|
+
});
|
|
261
|
+
const submitting = a.includes("--submit");
|
|
262
|
+
const corePath = flagValue(a, "--intent-core");
|
|
263
|
+
const receiptPath = flagValue(a, "--verifier-receipt");
|
|
264
|
+
// Refuse the half-specified submit here rather than planning and silently
|
|
265
|
+
// discarding the flags — an agent that typed --submit meant to submit.
|
|
266
|
+
if (submitting && (corePath == null || receiptPath == null)) {
|
|
267
|
+
fail({
|
|
268
|
+
code: "BAD_USAGE",
|
|
269
|
+
message: "run402 gitvault prune --submit needs both --intent-core and --verifier-receipt.",
|
|
270
|
+
hint: "Plan first (`run402 gitvault prune`), save its `intent_core`, run r402s-verify against it, then submit both.",
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
if (!submitting && (corePath != null || receiptPath != null)) {
|
|
274
|
+
fail({
|
|
275
|
+
code: "BAD_USAGE",
|
|
276
|
+
message: "--intent-core / --verifier-receipt only apply with --submit.",
|
|
277
|
+
hint: "Add --submit, or drop the flags to plan.",
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
const opts = vaultTarget(a);
|
|
281
|
+
if (submitting) {
|
|
282
|
+
opts.submit = {
|
|
283
|
+
core: readJsonFile("--intent-core", corePath),
|
|
284
|
+
verifier_receipt: readJsonFile("--verifier-receipt", receiptPath),
|
|
285
|
+
};
|
|
286
|
+
if (a.includes("--wait")) opts.submit.wait = {};
|
|
287
|
+
}
|
|
288
|
+
try {
|
|
289
|
+
const result = await getSdk().gitvault.prune(opts);
|
|
290
|
+
console.log(JSON.stringify(result, null, 2));
|
|
291
|
+
// Never imply a deletion. State what actually happened, then reproduce the
|
|
292
|
+
// SDK's own note verbatim rather than summarizing it.
|
|
293
|
+
if (!result.submitted) {
|
|
294
|
+
console.error(
|
|
295
|
+
result.blocked_reason
|
|
296
|
+
? `planned — nothing to submit: ${result.blocked_reason}`
|
|
297
|
+
: `planned — nothing submitted. ${result.object_candidates.length} object(s) proposed for deletion` +
|
|
298
|
+
`${result.deferred_object_count > 0 ? ` (${result.deferred_object_count} more deferred to a later intent)` : ""}` +
|
|
299
|
+
`; ${result.eligible_count} retention root(s) past their window, ${result.retained_count} retained.`,
|
|
300
|
+
);
|
|
301
|
+
if (result.intent_core_sha256) {
|
|
302
|
+
console.error(`intent_core_sha256: ${result.intent_core_sha256} — run r402s-verify against this core, then re-run with --submit.`);
|
|
303
|
+
}
|
|
304
|
+
} else if (result.confirmation?.outcome) {
|
|
305
|
+
console.error(
|
|
306
|
+
`submitted — the signed completion reports ${result.confirmation.deleted.length} deleted, ` +
|
|
307
|
+
`${result.confirmation.present.length} still present` +
|
|
308
|
+
`${result.confirmation.unadjudicated.length > 0 ? `, ${result.confirmation.unadjudicated.length} unadjudicated` : ""}.`,
|
|
309
|
+
);
|
|
310
|
+
} else {
|
|
311
|
+
console.error("submitted — no completion yet. Nothing is deleted until the control-plane-signed completion says so; re-run with --wait or poll the intent.");
|
|
312
|
+
}
|
|
313
|
+
console.error(result.note);
|
|
314
|
+
} catch (err) {
|
|
315
|
+
reportSdkError(err);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
async function verify(args) {
|
|
320
|
+
const a = normalizeArgv(args);
|
|
321
|
+
const valueFlags = [...COMMON_VALUE_FLAGS, "--budget"];
|
|
322
|
+
assertKnownFlags(a, [...valueFlags, "--help", "-h"], valueFlags);
|
|
323
|
+
requirePositionalCount(a, valueFlags, {
|
|
324
|
+
min: 0, max: 0, command: "run402 gitvault verify", missing: "",
|
|
325
|
+
});
|
|
326
|
+
const target = vaultTarget(a);
|
|
327
|
+
const budget = flagValue(a, "--budget");
|
|
328
|
+
if (budget != null) target.verification_budget = parseIntegerFlag("--budget", budget, { min: 1 });
|
|
329
|
+
try {
|
|
330
|
+
const state = await getSdk().gitvault.verify(target);
|
|
331
|
+
console.log(JSON.stringify(state, null, 2));
|
|
332
|
+
console.error(`verified through generation ${state.generation}`);
|
|
333
|
+
} catch (err) {
|
|
334
|
+
reportSdkError(err);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
export async function run(sub, args) {
|
|
339
|
+
const argv = Array.isArray(args) ? args : [];
|
|
340
|
+
if (!sub || hasHelp([sub, ...argv])) {
|
|
341
|
+
console.log(HELP);
|
|
342
|
+
process.exit(0);
|
|
343
|
+
}
|
|
344
|
+
switch (sub) {
|
|
345
|
+
case "status": {
|
|
346
|
+
await status(argv);
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
case "push": {
|
|
350
|
+
await push(argv);
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
case "compact": {
|
|
354
|
+
await compact(argv);
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
case "prune": {
|
|
358
|
+
await prune(argv);
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
case "verify": {
|
|
362
|
+
await verify(argv);
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
default:
|
|
366
|
+
failUnknownSubcommand("gitvault", sub, {
|
|
367
|
+
hint: "Run `run402 gitvault --help` for usage.",
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
package/lib/init.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readAllowance, saveAllowance, loadKeyStore, configDir, configureApiBase } from "./config.mjs";
|
|
1
|
+
import { readAllowance, saveAllowance, loadKeyStore, configDir, configureApiBase, getActiveProjectId, getProject, updateProject } from "./config.mjs";
|
|
2
2
|
import { getSdk } from "./sdk.mjs";
|
|
3
3
|
import { fail } from "./sdk-errors.mjs";
|
|
4
4
|
import { setTierAction, deployAction } from "./next-actions.mjs";
|
|
@@ -37,12 +37,20 @@ Options:
|
|
|
37
37
|
--switch-rail Confirm switching the persisted payment rail. Re-running
|
|
38
38
|
init with the SAME rail as the existing allowance is always
|
|
39
39
|
idempotent and does not need this flag.
|
|
40
|
+
--git-remote Also 'git init' the current directory when it is not a
|
|
41
|
+
repository yet, so the gitvault remote can be added there.
|
|
42
|
+
Opt-in on purpose: init is often run outside a project
|
|
43
|
+
directory and must never create a repository somewhere you
|
|
44
|
+
did not ask it to. Inside an EXISTING repository the remote
|
|
45
|
+
is added without this flag (see below).
|
|
40
46
|
|
|
41
47
|
Output:
|
|
42
48
|
Stdout is a JSON summary { config_dir, wallet, rail, network, balances,
|
|
43
49
|
tier, projects_saved, next_step }. Progress lines (Config / Allowance /
|
|
44
50
|
Balance / Tier / Next) go to stderr so a human re-running interactively
|
|
45
51
|
sees what's happening while a script piping stdout to jq stays clean.
|
|
52
|
+
With --git-remote the summary also carries { gitvault } (the scaffolded
|
|
53
|
+
remote) or { gitvault: null, gitvault_error } when it could not be added.
|
|
46
54
|
|
|
47
55
|
Steps (idempotent when re-run with the same rail; pass --switch-rail to change rails):
|
|
48
56
|
1. Creates config directory (~/.config/run402)
|
|
@@ -123,6 +131,17 @@ function parseVoucherFlag(args) {
|
|
|
123
131
|
return { value: null, args };
|
|
124
132
|
}
|
|
125
133
|
|
|
134
|
+
/**
|
|
135
|
+
* Pull the boolean `--git-remote` out of argv before the rail/positional logic
|
|
136
|
+
* runs, so `run402 init --git-remote mpp` still selects the mpp rail (the same
|
|
137
|
+
* reason `--voucher` is stripped first).
|
|
138
|
+
*/
|
|
139
|
+
function parseGitRemoteFlag(args) {
|
|
140
|
+
const idx = args.indexOf("--git-remote");
|
|
141
|
+
if (idx === -1) return { value: false, args };
|
|
142
|
+
return { value: true, args: [...args.slice(0, idx), ...args.slice(idx + 1)] };
|
|
143
|
+
}
|
|
144
|
+
|
|
126
145
|
function sameOrigin(a, b) {
|
|
127
146
|
try {
|
|
128
147
|
return new URL(a).origin === new URL(b).origin;
|
|
@@ -154,6 +173,45 @@ function errorMessage(err) {
|
|
|
154
173
|
return err?.message || String(err);
|
|
155
174
|
}
|
|
156
175
|
|
|
176
|
+
/**
|
|
177
|
+
* The owning org of the locally-active project — from the KEYSTORE first, and
|
|
178
|
+
* only then from the named inventory.
|
|
179
|
+
*
|
|
180
|
+
* Why the cache exists (task 5.12c): the gitvault scaffold is the one part of
|
|
181
|
+
* `run402 init` the client-surface spec says adds no network dependency to the
|
|
182
|
+
* cold-start path, and resolving the org through `projects.list()` quietly made
|
|
183
|
+
* that untrue. `org_id` is a non-secret routing identifier the control plane
|
|
184
|
+
* already hands back with every listing, so the honest fix is to remember it:
|
|
185
|
+
* the FIRST init on a machine still asks, every RETURNING init reads it locally
|
|
186
|
+
* and the scaffold really is network-free.
|
|
187
|
+
*
|
|
188
|
+
* Best-effort by construction — the caller treats `null` as "do not scaffold" —
|
|
189
|
+
* and an EXACT id match is required: a near-miss must never make init add a
|
|
190
|
+
* remote pointing at somebody else's project. `updateProject` is a no-op for a
|
|
191
|
+
* project this machine holds no credentials for, so such a project asks again
|
|
192
|
+
* next time rather than being silently mis-cached.
|
|
193
|
+
*/
|
|
194
|
+
async function resolveOwningOrgId(projectId) {
|
|
195
|
+
const cached = getProject(projectId)?.org_id;
|
|
196
|
+
if (typeof cached === "string" && cached.length > 0) return cached;
|
|
197
|
+
try {
|
|
198
|
+
const listed = await getSdk().projects.list();
|
|
199
|
+
const rows = Array.isArray(listed?.projects) ? listed.projects : [];
|
|
200
|
+
const row = rows.find((p) => (p?.id ?? p?.project_id) === projectId);
|
|
201
|
+
const orgId = row?.org_id;
|
|
202
|
+
if (typeof orgId !== "string" || orgId.length === 0) return null;
|
|
203
|
+
try {
|
|
204
|
+
updateProject(projectId, { org_id: orgId });
|
|
205
|
+
} catch {
|
|
206
|
+
// Caching is an optimization; a read-only or contended keystore costs a
|
|
207
|
+
// round trip next time and must never fail the scaffold.
|
|
208
|
+
}
|
|
209
|
+
return orgId;
|
|
210
|
+
} catch {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
157
215
|
export async function run(args = []) {
|
|
158
216
|
// Capability `astro-ssr-runtime` (v1.52): scaffold an Astro project.
|
|
159
217
|
// Sub-routes when first positional is 'astro'. Handle BEFORE the
|
|
@@ -177,6 +235,10 @@ export async function run(args = []) {
|
|
|
177
235
|
args = parsedVoucher.args;
|
|
178
236
|
const voucherCode = parsedVoucher.value;
|
|
179
237
|
|
|
238
|
+
const parsedGitRemote = parseGitRemoteFlag(args);
|
|
239
|
+
args = parsedGitRemote.args;
|
|
240
|
+
const scaffoldGitRemote = parsedGitRemote.value;
|
|
241
|
+
|
|
180
242
|
const parsedApiBase = parseApiBaseFlag(args);
|
|
181
243
|
if (parsedApiBase.value) {
|
|
182
244
|
if (parsedApiBase.args.some((arg) => typeof arg === "string" && !arg.startsWith("--"))) {
|
|
@@ -197,6 +259,16 @@ export async function run(args = []) {
|
|
|
197
259
|
hint: "Configure the target first (`run402 init --api-base=…`), then redeem against Run402 Cloud with `run402 redeem <code>`.",
|
|
198
260
|
});
|
|
199
261
|
}
|
|
262
|
+
// Same reasoning as --voucher: this branch configures a target and returns
|
|
263
|
+
// without an active project, so a git scaffold has nothing to point at.
|
|
264
|
+
// Say so rather than accepting the flag and silently dropping it.
|
|
265
|
+
if (scaffoldGitRemote) {
|
|
266
|
+
fail({
|
|
267
|
+
code: "BAD_USAGE",
|
|
268
|
+
message: "run402 init --api-base cannot be combined with --git-remote.",
|
|
269
|
+
hint: "Configure the target first (`run402 init --api-base=…`), provision a project, then run `run402 init --git-remote` from the project directory.",
|
|
270
|
+
});
|
|
271
|
+
}
|
|
200
272
|
const CONFIG_DIR = configDir();
|
|
201
273
|
const detected = await detectTarget(parsedApiBase.value);
|
|
202
274
|
const config = configureApiBase(parsedApiBase.value, {
|
|
@@ -479,6 +551,76 @@ export async function run(args = []) {
|
|
|
479
551
|
summary.projects_saved = Object.keys(store.projects).length;
|
|
480
552
|
line("Projects", `${summary.projects_saved} saved`);
|
|
481
553
|
|
|
554
|
+
// 5b. gitvault git remote (gitvault-client-surface, task 5.7).
|
|
555
|
+
//
|
|
556
|
+
// Purely LOCAL git. No vault is allocated and no key material is written
|
|
557
|
+
// here — the spec is explicit that neither exists until first capture, so the
|
|
558
|
+
// cold-start path gains no prompt and no new failure mode. Allocation happens
|
|
559
|
+
// on the first `run402 gitvault push` (or deploy).
|
|
560
|
+
//
|
|
561
|
+
// Adding the remote is the DEFAULT inside a repository that already exists,
|
|
562
|
+
// because it is pure addition: `origin` is never modified or claimed, no file
|
|
563
|
+
// is created, nothing is rewritten. CREATING a repository is NOT the default
|
|
564
|
+
// — `run402 init` is routinely run outside a project directory, and
|
|
565
|
+
// `git init`-ing whatever directory the user happened to be in would be a
|
|
566
|
+
// genuinely bad surprise. `--git-remote` opts into that one step.
|
|
567
|
+
//
|
|
568
|
+
// NON-FATAL in every branch: a missing git, a directory that is not a
|
|
569
|
+
// repository, an unreachable gateway, or a `run402` remote already pointing
|
|
570
|
+
// somewhere else must warn and let setup finish.
|
|
571
|
+
const activeProjectId = getActiveProjectId();
|
|
572
|
+
if (activeProjectId) {
|
|
573
|
+
summary.gitvault = null;
|
|
574
|
+
try {
|
|
575
|
+
// Dynamic import: the scaffold is the only thing here that needs the
|
|
576
|
+
// Node SDK's hardened git runner, and a top-level import would drag it
|
|
577
|
+
// into every init invocation (and every test that mocks ./sdk.mjs).
|
|
578
|
+
const { hardenedGit } = await import("#sdk/node");
|
|
579
|
+
let insideRepo = true;
|
|
580
|
+
try {
|
|
581
|
+
await hardenedGit(process.cwd(), ["rev-parse", "--git-dir"]);
|
|
582
|
+
} catch {
|
|
583
|
+
insideRepo = false;
|
|
584
|
+
}
|
|
585
|
+
if (!insideRepo && !scaffoldGitRemote) {
|
|
586
|
+
summary.gitvault_skipped = "not a git repository — re-run with --git-remote to create one and add the remote";
|
|
587
|
+
line("Gitvault", "skipped — not a git repository (--git-remote creates one)");
|
|
588
|
+
} else {
|
|
589
|
+
const orgId = await resolveOwningOrgId(activeProjectId);
|
|
590
|
+
if (!orgId) {
|
|
591
|
+
summary.gitvault_skipped = `could not resolve the owning org for ${activeProjectId} — the run402 remote was not added`;
|
|
592
|
+
line("Gitvault", "skipped — owning org unresolved");
|
|
593
|
+
} else {
|
|
594
|
+
const remote = await getSdk().gitvault.scaffoldRemote({
|
|
595
|
+
repo_dir: process.cwd(),
|
|
596
|
+
org_id: orgId,
|
|
597
|
+
project_id: activeProjectId,
|
|
598
|
+
});
|
|
599
|
+
// `allocated: false` is stated, not left to be inferred: this was
|
|
600
|
+
// local git only, and no vault exists for the project yet.
|
|
601
|
+
summary.gitvault = { ...remote, allocated: false };
|
|
602
|
+
if (remote.already_present && remote.existing_url !== remote.url) {
|
|
603
|
+
// Left exactly as it was. Name the URL that is actually in place
|
|
604
|
+
// rather than implying the remote now points at this project.
|
|
605
|
+
line("Gitvault", `remote '${remote.name}' already points at ${remote.existing_url} — left unchanged`);
|
|
606
|
+
} else if (remote.already_present) {
|
|
607
|
+
line("Gitvault", `remote '${remote.name}' already set (${remote.url})`);
|
|
608
|
+
} else {
|
|
609
|
+
line("Gitvault", `${remote.created_repository ? "initialized a repository and added" : "added"} remote '${remote.name}' -> ${remote.url}`);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
} catch (err) {
|
|
614
|
+
const reason = errorMessage(err);
|
|
615
|
+
summary.gitvault = null;
|
|
616
|
+
summary.gitvault_error = {
|
|
617
|
+
code: err?.body?.code ?? err?.code ?? "GITVAULT_SCAFFOLD_FAILED",
|
|
618
|
+
message: reason,
|
|
619
|
+
};
|
|
620
|
+
line("Gitvault", `remote not added: ${reason}`);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
482
624
|
// 6. Next step — canonical typed action(s); `next_step` is the back-compat
|
|
483
625
|
// string mirror of the first action's command (one spelling, surface-wide).
|
|
484
626
|
write("");
|
package/lib/pay.test.mjs
CHANGED
|
@@ -53,11 +53,7 @@ describe("run402 pay", () => {
|
|
|
53
53
|
headers: { "content-type": "application/json" },
|
|
54
54
|
}),
|
|
55
55
|
payment: {
|
|
56
|
-
amount_usd_micros: 10_000,
|
|
57
|
-
pay_to: "0xseller",
|
|
58
56
|
network: "eip155:8453",
|
|
59
|
-
tx_ref: "0xtx",
|
|
60
|
-
url,
|
|
61
57
|
paymentId: "txp_cli_1",
|
|
62
58
|
amountUsdMicros: 10_000,
|
|
63
59
|
asset: "USDC",
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "run402",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.25.0",
|
|
4
4
|
"description": "CLI for Run402 — provision Postgres databases, deploy static sites, generate images, and manage wallets via x402 and MPP micropayments.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"run402": "cli.mjs"
|
|
7
|
+
"run402": "cli.mjs",
|
|
8
|
+
"git-remote-run402": "git-remote-run402.mjs"
|
|
8
9
|
},
|
|
9
10
|
"imports": {
|
|
11
|
+
"#sdk": "./sdk/dist/index.js",
|
|
10
12
|
"#sdk/node": "./sdk/dist/node/index.js"
|
|
11
13
|
},
|
|
12
14
|
"scripts": {
|
|
@@ -14,13 +16,17 @@
|
|
|
14
16
|
},
|
|
15
17
|
"files": [
|
|
16
18
|
"cli.mjs",
|
|
19
|
+
"git-remote-run402.mjs",
|
|
17
20
|
"lib/",
|
|
18
21
|
"fixtures/",
|
|
19
22
|
"core-dist/",
|
|
20
23
|
"sdk/"
|
|
21
24
|
],
|
|
22
25
|
"dependencies": {
|
|
26
|
+
"@hpke/chacha20poly1305": "^1.8.0",
|
|
27
|
+
"@hpke/core": "^1.9.0",
|
|
23
28
|
"@humanwhocodes/momoa": "3.3.10",
|
|
29
|
+
"@noble/ciphers": "^2.3.0",
|
|
24
30
|
"@noble/curves": "^2.0.1",
|
|
25
31
|
"@noble/hashes": "^2.0.1",
|
|
26
32
|
"@scure/base": "1.2.6",
|
package/sdk/dist/index.d.ts
CHANGED
|
@@ -20,7 +20,6 @@ import { Tier } from "./namespaces/tier.js";
|
|
|
20
20
|
import { Allowance } from "./namespaces/allowance.js";
|
|
21
21
|
import { Ai } from "./namespaces/ai.js";
|
|
22
22
|
import { Auth } from "./namespaces/auth.js";
|
|
23
|
-
import { SenderDomain } from "./namespaces/sender-domain.js";
|
|
24
23
|
import { Billing } from "./namespaces/billing.js";
|
|
25
24
|
import { Vouchers } from "./namespaces/vouchers.js";
|
|
26
25
|
import { Wallets, ScopedWallet } from "./namespaces/wallets.js";
|
|
@@ -46,6 +45,7 @@ import { Errors } from "./namespaces/errors.js";
|
|
|
46
45
|
import { Pay, type PayExecutor } from "./namespaces/pay.js";
|
|
47
46
|
import { IdentityLinks } from "./namespaces/identity-links.js";
|
|
48
47
|
import { Buzz } from "./namespaces/buzz.js";
|
|
48
|
+
import { Gitvault } from "./namespaces/gitvault.js";
|
|
49
49
|
import type { ContentSource, FileSet } from "./namespaces/deploy.types.js";
|
|
50
50
|
import { ScopedRun402 } from "./scoped.js";
|
|
51
51
|
export interface Run402Options {
|
|
@@ -86,7 +86,6 @@ export declare class Run402 {
|
|
|
86
86
|
readonly ai: Ai;
|
|
87
87
|
readonly image: Ai;
|
|
88
88
|
readonly auth: Auth;
|
|
89
|
-
readonly senderDomain: SenderDomain;
|
|
90
89
|
readonly billing: Billing;
|
|
91
90
|
readonly vouchers: Vouchers;
|
|
92
91
|
readonly wallets: Wallets;
|
|
@@ -164,6 +163,20 @@ export declare class Run402 {
|
|
|
164
163
|
readonly identityLinks: IdentityLinks;
|
|
165
164
|
/** Buzz human adoption, community installation, and bounded agent enrollment workflows. */
|
|
166
165
|
readonly buzz: Buzz;
|
|
166
|
+
/**
|
|
167
|
+
* gitvault — the host-blind encrypted Git remote (`r402s/v0`). Vault reads
|
|
168
|
+
* (record, heads listing, policy) run anywhere; the verbs that touch a git
|
|
169
|
+
* tree or the on-disk keystore (`init`, `push`, `compact`, `verify`,
|
|
170
|
+
* `deploy`, `restore`) are Node-only and load `@run402/sdk/node` lazily.
|
|
171
|
+
*
|
|
172
|
+
* This namespace is where ALL vault protocol logic lives: the CLI's
|
|
173
|
+
* `run402 gitvault …`, `git-remote-run402`, and the MCP tools are adapters
|
|
174
|
+
* over it and add no behaviour of their own.
|
|
175
|
+
*
|
|
176
|
+
* Durability is keystore-qualified: the vault protects source history from
|
|
177
|
+
* host-side loss while a principal keystore survives.
|
|
178
|
+
*/
|
|
179
|
+
readonly gitvault: Gitvault;
|
|
167
180
|
readonly idempotency: {
|
|
168
181
|
fromParts: typeof fromParts;
|
|
169
182
|
};
|
|
@@ -341,11 +354,15 @@ export { Buzz, BuzzHumanAdoptions, BuzzHumanAdoptionOffers, BuzzCommunityInstall
|
|
|
341
354
|
export type * from "./namespaces/buzz.types.js";
|
|
342
355
|
export type * from "./namespaces/buzz-notifications.types.js";
|
|
343
356
|
export type * from "./namespaces/secrets.js";
|
|
344
|
-
export type * from "./namespaces/sender-domain.js";
|
|
345
357
|
export type * from "./namespaces/service.js";
|
|
346
358
|
export type * from "./namespaces/sites.js";
|
|
347
359
|
export type * from "./namespaces/subdomains.js";
|
|
348
360
|
export type * from "./namespaces/tier.js";
|
|
349
361
|
export { ScopedWallet } from "./namespaces/wallets.js";
|
|
350
362
|
export type * from "./namespaces/wallets.js";
|
|
363
|
+
export * from "./namespaces/gitvault.crypto.js";
|
|
364
|
+
export type * from "./namespaces/gitvault.crypto.js";
|
|
365
|
+
export type * from "./namespaces/gitvault.types.js";
|
|
366
|
+
export { Gitvault, gitvaultRemoteUrl, parseGitvaultRemoteUrl } from "./namespaces/gitvault.js";
|
|
367
|
+
export type * from "./namespaces/gitvault.js";
|
|
351
368
|
//# sourceMappingURL=index.d.ts.map
|