@mikeargento/bitgraph-mcp 0.7.0 → 0.8.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 +2 -2
- package/dist/format.js +2 -2
- package/dist/format.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +8 -8
- package/dist/server.js.map +1 -1
- package/package.json +4 -4
- package/src/format.ts +2 -2
- package/src/server.ts +8 -8
- package/dist/__tests__/encoding.test.d.ts +0 -2
- package/dist/__tests__/encoding.test.d.ts.map +0 -1
- package/dist/__tests__/encoding.test.js +0 -51
- package/dist/__tests__/encoding.test.js.map +0 -1
- package/dist/__tests__/scan.test.d.ts +0 -2
- package/dist/__tests__/scan.test.d.ts.map +0 -1
- package/dist/__tests__/scan.test.js +0 -73
- package/dist/__tests__/scan.test.js.map +0 -1
- package/dist/api.d.ts +0 -42
- package/dist/api.d.ts.map +0 -1
- package/dist/api.js +0 -121
- package/dist/api.js.map +0 -1
- package/dist/carrier-io.d.ts +0 -52
- package/dist/carrier-io.d.ts.map +0 -1
- package/dist/carrier-io.js +0 -91
- package/dist/carrier-io.js.map +0 -1
- package/dist/encoding.d.ts +0 -19
- package/dist/encoding.d.ts.map +0 -1
- package/dist/encoding.js +0 -64
- package/dist/encoding.js.map +0 -1
- package/dist/scan.d.ts +0 -60
- package/dist/scan.d.ts.map +0 -1
- package/dist/scan.js +0 -201
- package/dist/scan.js.map +0 -1
- package/dist/task.d.ts +0 -55
- package/dist/task.d.ts.map +0 -1
- package/dist/task.js +0 -182
- package/dist/task.js.map +0 -1
- package/dist/types.d.ts +0 -108
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
package/dist/api.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import type { BatchCheckResponse, ProofDetailResponse, SearchResponse, SetIndexResponse } from "./types.js";
|
|
2
|
-
export interface ApiConfig {
|
|
3
|
-
baseUrl: string;
|
|
4
|
-
apiKey?: string;
|
|
5
|
-
}
|
|
6
|
-
/** Read configuration from the environment at call time (testable via env). */
|
|
7
|
-
export declare function configFromEnv(): ApiConfig;
|
|
8
|
-
/** Matches the batch endpoint's MAX_DIGESTS. */
|
|
9
|
-
export declare const BATCH_CHECK_LIMIT = 500;
|
|
10
|
-
export declare class ApiError extends Error {
|
|
11
|
-
readonly status: number;
|
|
12
|
-
readonly retryAfterSec: number | null;
|
|
13
|
-
constructor(status: number, message: string, retryAfterSec?: number | null);
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Look up which digests are on record. Input digests must be URL-safe base64;
|
|
17
|
-
* the response is keyed by the exact strings sent. Pages of up to 500, a few
|
|
18
|
-
* in flight at once.
|
|
19
|
-
*/
|
|
20
|
-
export declare function batchCheck(config: ApiConfig, urlSafeDigests: readonly string[]): Promise<BatchCheckResponse>;
|
|
21
|
-
/** One request's worth of a set/2's member evidence, for the site to index. */
|
|
22
|
-
export interface SetIndexRequest {
|
|
23
|
-
/** The set proof's artifact digest, URL-safe base64. */
|
|
24
|
-
setDigest: string;
|
|
25
|
-
/** The set proof's epoch id, URL-safe base64. */
|
|
26
|
-
epoch: string;
|
|
27
|
-
/** The set proof's commit counter. */
|
|
28
|
-
counter: string;
|
|
29
|
-
members: unknown[];
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Index members of a set/2 from their evidence. The site reads the set proof
|
|
33
|
-
* from its own position, binds the root document, and checks every member's
|
|
34
|
-
* path before writing a key; a row that does not bind is rejected, never
|
|
35
|
-
* written.
|
|
36
|
-
*/
|
|
37
|
-
export declare function indexSetMembers(config: ApiConfig, body: SetIndexRequest): Promise<SetIndexResponse>;
|
|
38
|
-
/** Full detail for one digest: proof, all causal positions, anchor window. */
|
|
39
|
-
export declare function getProofDetail(config: ApiConfig, urlSafeDigest: string, counter?: string, urlSafeEpoch?: string): Promise<ProofDetailResponse>;
|
|
40
|
-
/** Resolve a BitGraph number (or digest string) to a digest via /api/search. */
|
|
41
|
-
export declare function search(config: ApiConfig, q: string): Promise<SearchResponse>;
|
|
42
|
-
//# sourceMappingURL=api.d.ts.map
|
package/dist/api.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE5G,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,+EAA+E;AAC/E,wBAAgB,aAAa,IAAI,SAAS,CAIzC;AAED,gDAAgD;AAChD,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAOrC,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;gBAE1B,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,GAAE,MAAM,GAAG,IAAW;CAKjF;AA0DD;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,SAAS,EACjB,cAAc,EAAE,SAAS,MAAM,EAAE,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAW7B;AAED,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,EAAE,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAEzG;AAED,8EAA8E;AAC9E,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,mBAAmB,CAAC,CAU9B;AAED,gFAAgF;AAChF,wBAAsB,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAMlF"}
|
package/dist/api.js
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2024-2026 Argento Computing Inc. Licensed under the MIT License. See LICENSE.
|
|
2
|
-
/**
|
|
3
|
-
* @mikeargento/bitgraph-mcp: HTTP client for the hosted BitGraph API.
|
|
4
|
-
*
|
|
5
|
-
* The reads: the batch lookup, the proof detail, the number search. Making a
|
|
6
|
-
* BitGraph goes through the core package's own transport against the same
|
|
7
|
-
* site (its /api/fuse routes), which is what maintains the per-position
|
|
8
|
-
* by-digest index that makes every member of a set discoverable afterward;
|
|
9
|
-
* the one write here is a set/2's member evidence, indexed after the commit.
|
|
10
|
-
*/
|
|
11
|
-
import { mapConcurrent } from "./encoding.js";
|
|
12
|
-
/** Read configuration from the environment at call time (testable via env). */
|
|
13
|
-
export function configFromEnv() {
|
|
14
|
-
const baseUrl = (process.env["BITGRAPH_API_URL"] ?? "https://bitgraph.ing").replace(/\/+$/, "");
|
|
15
|
-
const apiKey = process.env["BITGRAPH_API_KEY"];
|
|
16
|
-
return apiKey ? { baseUrl, apiKey } : { baseUrl };
|
|
17
|
-
}
|
|
18
|
-
/** Matches the batch endpoint's MAX_DIGESTS. */
|
|
19
|
-
export const BATCH_CHECK_LIMIT = 500;
|
|
20
|
-
/** Batch lookups in flight at once: a large folder is many pages. */
|
|
21
|
-
const BATCH_CHECK_CONCURRENCY = 4;
|
|
22
|
-
const CHECK_TIMEOUT_MS = 30_000;
|
|
23
|
-
const SET_INDEX_TIMEOUT_MS = 60_000;
|
|
24
|
-
export class ApiError extends Error {
|
|
25
|
-
status;
|
|
26
|
-
retryAfterSec;
|
|
27
|
-
constructor(status, message, retryAfterSec = null) {
|
|
28
|
-
super(message);
|
|
29
|
-
this.status = status;
|
|
30
|
-
this.retryAfterSec = retryAfterSec;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
async function parseError(res) {
|
|
34
|
-
let message = res.statusText || `HTTP ${res.status}`;
|
|
35
|
-
try {
|
|
36
|
-
const body = (await res.json());
|
|
37
|
-
if (typeof body.error === "string" && body.error.length > 0)
|
|
38
|
-
message = body.error;
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
/* non-JSON error body */
|
|
42
|
-
}
|
|
43
|
-
const retryAfterRaw = res.headers.get("retry-after");
|
|
44
|
-
const retryAfterSec = retryAfterRaw !== null ? Number.parseInt(retryAfterRaw, 10) : null;
|
|
45
|
-
return new ApiError(res.status, message, Number.isFinite(retryAfterSec) ? retryAfterSec : null);
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Redirects are refused everywhere: an Authorization header must never follow
|
|
49
|
-
* one to a different host, and the canonical endpoint serves without them.
|
|
50
|
-
*/
|
|
51
|
-
function redirectHint(err) {
|
|
52
|
-
if (err instanceof TypeError && /redirect/i.test(err.message)) {
|
|
53
|
-
throw new Error("The BitGraph endpoint redirected. Set BITGRAPH_API_URL to the canonical https://bitgraph.ing (apex, no www).");
|
|
54
|
-
}
|
|
55
|
-
throw err;
|
|
56
|
-
}
|
|
57
|
-
async function getJson(config, path, timeoutMs) {
|
|
58
|
-
const res = await fetch(`${config.baseUrl}${path}`, {
|
|
59
|
-
method: "GET",
|
|
60
|
-
redirect: "error",
|
|
61
|
-
signal: AbortSignal.timeout(timeoutMs),
|
|
62
|
-
}).catch(redirectHint);
|
|
63
|
-
if (!res.ok)
|
|
64
|
-
throw await parseError(res);
|
|
65
|
-
return (await res.json());
|
|
66
|
-
}
|
|
67
|
-
async function postJson(config, path, body, timeoutMs, authenticated) {
|
|
68
|
-
const headers = { "Content-Type": "application/json" };
|
|
69
|
-
if (authenticated && config.apiKey)
|
|
70
|
-
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
71
|
-
const res = await fetch(`${config.baseUrl}${path}`, {
|
|
72
|
-
method: "POST",
|
|
73
|
-
headers,
|
|
74
|
-
body: JSON.stringify(body),
|
|
75
|
-
redirect: "error",
|
|
76
|
-
signal: AbortSignal.timeout(timeoutMs),
|
|
77
|
-
}).catch(redirectHint);
|
|
78
|
-
if (!res.ok)
|
|
79
|
-
throw await parseError(res);
|
|
80
|
-
return (await res.json());
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Look up which digests are on record. Input digests must be URL-safe base64;
|
|
84
|
-
* the response is keyed by the exact strings sent. Pages of up to 500, a few
|
|
85
|
-
* in flight at once.
|
|
86
|
-
*/
|
|
87
|
-
export async function batchCheck(config, urlSafeDigests) {
|
|
88
|
-
const chunks = [];
|
|
89
|
-
for (let offset = 0; offset < urlSafeDigests.length; offset += BATCH_CHECK_LIMIT) {
|
|
90
|
-
chunks.push(urlSafeDigests.slice(offset, offset + BATCH_CHECK_LIMIT));
|
|
91
|
-
}
|
|
92
|
-
const pages = await mapConcurrent(chunks, BATCH_CHECK_CONCURRENCY, (chunk) => postJson(config, "/api/proofs/batch", { digests: chunk }, CHECK_TIMEOUT_MS, false));
|
|
93
|
-
const merged = { results: {} };
|
|
94
|
-
for (const page of pages)
|
|
95
|
-
Object.assign(merged.results, page.results);
|
|
96
|
-
return merged;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Index members of a set/2 from their evidence. The site reads the set proof
|
|
100
|
-
* from its own position, binds the root document, and checks every member's
|
|
101
|
-
* path before writing a key; a row that does not bind is rejected, never
|
|
102
|
-
* written.
|
|
103
|
-
*/
|
|
104
|
-
export async function indexSetMembers(config, body) {
|
|
105
|
-
return postJson(config, "/api/fuse/set-index", body, SET_INDEX_TIMEOUT_MS, false);
|
|
106
|
-
}
|
|
107
|
-
/** Full detail for one digest: proof, all causal positions, anchor window. */
|
|
108
|
-
export async function getProofDetail(config, urlSafeDigest, counter, urlSafeEpoch) {
|
|
109
|
-
const params = new URLSearchParams();
|
|
110
|
-
if (counter !== undefined)
|
|
111
|
-
params.set("counter", counter);
|
|
112
|
-
if (urlSafeEpoch !== undefined)
|
|
113
|
-
params.set("epoch", urlSafeEpoch);
|
|
114
|
-
const query = params.size > 0 ? `?${params.toString()}` : "";
|
|
115
|
-
return getJson(config, `/api/proofs/digest/${encodeURIComponent(urlSafeDigest)}${query}`, CHECK_TIMEOUT_MS);
|
|
116
|
-
}
|
|
117
|
-
/** Resolve a BitGraph number (or digest string) to a digest via /api/search. */
|
|
118
|
-
export async function search(config, q) {
|
|
119
|
-
return getJson(config, `/api/search?q=${encodeURIComponent(q)}`, CHECK_TIMEOUT_MS);
|
|
120
|
-
}
|
|
121
|
-
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/carrier-io.d.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { type CarrierVerifyResult } from "@mikeargento/bitgraph-verify";
|
|
2
|
-
/** The window as the tools state it. not_after null = NOT FETCHED, in those words. */
|
|
3
|
-
export interface CarrierWindowView {
|
|
4
|
-
verdict: "TRUE" | "FALSE" | "UNDETERMINED";
|
|
5
|
-
not_before: {
|
|
6
|
-
block: number;
|
|
7
|
-
hash: string;
|
|
8
|
-
time: string | null;
|
|
9
|
-
} | null;
|
|
10
|
-
/** null when the ceiling has not been fetched into the file yet. */
|
|
11
|
-
not_after: {
|
|
12
|
-
block: number;
|
|
13
|
-
hash: string;
|
|
14
|
-
time: string | null;
|
|
15
|
-
} | null;
|
|
16
|
-
ceiling: "present" | "unfetched" | null;
|
|
17
|
-
reasons: string[];
|
|
18
|
-
}
|
|
19
|
-
export declare function carrierWindowView(r: CarrierVerifyResult): CarrierWindowView;
|
|
20
|
-
/**
|
|
21
|
-
* One line for a markdown row: the verdict and the window, in the stated
|
|
22
|
-
* words. The floor is temporal (after the block's own time, cryptographically);
|
|
23
|
-
* the ceiling is POSITIONAL: committed before the ANCHORING of the later
|
|
24
|
-
* block, never before that block's mine time, because an anchor is built
|
|
25
|
-
* after the block it carries. Canon §3.5/§3.6: floor in time, ceiling in
|
|
26
|
-
* position; converting the positional ceiling into a clock reading is the
|
|
27
|
-
* one error.
|
|
28
|
-
*/
|
|
29
|
-
export declare function carrierLine(view: CarrierWindowView): string;
|
|
30
|
-
/**
|
|
31
|
-
* True when the file's last 8 bytes are the carrier magic. One positioned
|
|
32
|
-
* read; no file that is not a carrier pays more than that.
|
|
33
|
-
*/
|
|
34
|
-
export declare function sniffCarrierTail(path: string, size: number): Promise<boolean>;
|
|
35
|
-
export interface CarrierFileResult {
|
|
36
|
-
/** "ok": readable block, judged. "corrupt": block found but unreadable. */
|
|
37
|
-
status: "ok" | "corrupt";
|
|
38
|
-
/** Standard base64 SHA-256 of the COMMITTED bytes inside; the digest every lookup uses. */
|
|
39
|
-
innerDigestB64: string | null;
|
|
40
|
-
/** The committed bytes, for callers that go on to sniff or serve them. */
|
|
41
|
-
inner: Uint8Array | null;
|
|
42
|
-
result: CarrierVerifyResult | null;
|
|
43
|
-
view: CarrierWindowView | null;
|
|
44
|
-
corruptReason: string | null;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Read a tail-confirmed carrier whole and judge it offline: the carried
|
|
48
|
-
* proof, the floor by identity, the witnesses, the ceiling when present.
|
|
49
|
-
* Proof-level judgment (attestation depth stays the audit CLI's job).
|
|
50
|
-
*/
|
|
51
|
-
export declare function readCarrierFile(path: string): Promise<CarrierFileResult>;
|
|
52
|
-
//# sourceMappingURL=carrier-io.d.ts.map
|
package/dist/carrier-io.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"carrier-io.d.ts","sourceRoot":"","sources":["../src/carrier-io.ts"],"names":[],"mappings":"AAkBA,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,8BAA8B,CAAC;AAKtC,sFAAsF;AACtF,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,cAAc,CAAC;IAC3C,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACxE,oEAAoE;IACpE,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACvE,OAAO,EAAE,SAAS,GAAG,WAAW,GAAG,IAAI,CAAC;IACxC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,mBAAmB,GAAG,iBAAiB,CAQ3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAS3D;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUnF;AAED,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,MAAM,EAAE,IAAI,GAAG,SAAS,CAAC;IACzB,2FAA2F;IAC3F,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,0EAA0E;IAC1E,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACnC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAoB9E"}
|
package/dist/carrier-io.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2024-2026 Argento Computing Inc. Licensed under the MIT License. See LICENSE.
|
|
2
|
-
/**
|
|
3
|
-
* @mikeargento/bitgraph-mcp: BitGraphed files (bitgraph-carrier/1).
|
|
4
|
-
*
|
|
5
|
-
* A BitGraphed file is committed bytes followed by one structural block that
|
|
6
|
-
* carries the proof and the anchor evidence. The block is found from the END
|
|
7
|
-
* of the file, by structure, never by scanning. Everything here is local:
|
|
8
|
-
* an 8-byte tail read decides whether a file is a carrier at all, and the
|
|
9
|
-
* full judgment runs offline through @mikeargento/bitgraph-verify.
|
|
10
|
-
*
|
|
11
|
-
* The one rule that cannot bend: the envelope is never the recorded thing,
|
|
12
|
-
* the bytes inside it are. So the tools look up the INNER digest, and
|
|
13
|
-
* bitgraph_record never mints carrier bytes, the same structural guarantee
|
|
14
|
-
* the site's drop box gives.
|
|
15
|
-
*/
|
|
16
|
-
import { open } from "node:fs/promises";
|
|
17
|
-
import { CARRIER_MAGIC, CARRIER_OVERHEAD, parseCarrier, verifyCarrier, } from "@mikeargento/bitgraph-verify";
|
|
18
|
-
/** ISO string for a witness timestamp (seconds), or null when the header was unreadable. */
|
|
19
|
-
const iso = (ts) => (ts === null ? null : new Date(ts * 1000).toISOString());
|
|
20
|
-
export function carrierWindowView(r) {
|
|
21
|
-
return {
|
|
22
|
-
verdict: r.verdict,
|
|
23
|
-
not_before: r.bounds ? { block: r.bounds.notBefore.blockNumber, hash: r.bounds.notBefore.blockHash, time: iso(r.bounds.notBefore.timestamp) } : null,
|
|
24
|
-
not_after: r.bounds?.notAfter ? { block: r.bounds.notAfter.blockNumber, hash: r.bounds.notAfter.blockHash, time: iso(r.bounds.notAfter.timestamp) } : null,
|
|
25
|
-
ceiling: r.ceiling,
|
|
26
|
-
reasons: r.reasons,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* One line for a markdown row: the verdict and the window, in the stated
|
|
31
|
-
* words. The floor is temporal (after the block's own time, cryptographically);
|
|
32
|
-
* the ceiling is POSITIONAL: committed before the ANCHORING of the later
|
|
33
|
-
* block, never before that block's mine time, because an anchor is built
|
|
34
|
-
* after the block it carries. Canon §3.5/§3.6: floor in time, ceiling in
|
|
35
|
-
* position; converting the positional ceiling into a clock reading is the
|
|
36
|
-
* one error.
|
|
37
|
-
*/
|
|
38
|
-
export function carrierLine(view) {
|
|
39
|
-
const parts = [`carried proof ${view.verdict}`];
|
|
40
|
-
if (view.not_before)
|
|
41
|
-
parts.push(`after block ${view.not_before.block}${view.not_before.time ? ` (mined ${view.not_before.time})` : ""}`);
|
|
42
|
-
parts.push(view.not_after
|
|
43
|
-
? `before the anchoring of block ${view.not_after.block}${view.not_after.time ? ` (block mined ${view.not_after.time})` : ""}`
|
|
44
|
-
: "closing anchor NOT FETCHED (drop the file on bitgraph.ing to complete it)");
|
|
45
|
-
return parts.join(" · ");
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* True when the file's last 8 bytes are the carrier magic. One positioned
|
|
49
|
-
* read; no file that is not a carrier pays more than that.
|
|
50
|
-
*/
|
|
51
|
-
export async function sniffCarrierTail(path, size) {
|
|
52
|
-
if (size < CARRIER_OVERHEAD)
|
|
53
|
-
return false;
|
|
54
|
-
const fd = await open(path, "r");
|
|
55
|
-
try {
|
|
56
|
-
const tail = Buffer.alloc(CARRIER_MAGIC.length);
|
|
57
|
-
await fd.read(tail, 0, tail.length, size - tail.length);
|
|
58
|
-
return tail.equals(Buffer.from(CARRIER_MAGIC));
|
|
59
|
-
}
|
|
60
|
-
finally {
|
|
61
|
-
await fd.close();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Read a tail-confirmed carrier whole and judge it offline: the carried
|
|
66
|
-
* proof, the floor by identity, the witnesses, the ceiling when present.
|
|
67
|
-
* Proof-level judgment (attestation depth stays the audit CLI's job).
|
|
68
|
-
*/
|
|
69
|
-
export async function readCarrierFile(path) {
|
|
70
|
-
const fd = await open(path, "r");
|
|
71
|
-
let bytes;
|
|
72
|
-
try {
|
|
73
|
-
const info = await fd.stat();
|
|
74
|
-
const buf = Buffer.alloc(info.size);
|
|
75
|
-
await fd.read(buf, 0, info.size, 0);
|
|
76
|
-
bytes = new Uint8Array(buf);
|
|
77
|
-
}
|
|
78
|
-
finally {
|
|
79
|
-
await fd.close();
|
|
80
|
-
}
|
|
81
|
-
const parsed = parseCarrier(bytes);
|
|
82
|
-
if (parsed.kind !== "carrier") {
|
|
83
|
-
const reason = parsed.kind === "corrupt" ? parsed.reason : "the tail magic matched but no block parsed";
|
|
84
|
-
return { status: "corrupt", innerDigestB64: null, inner: null, result: null, view: null, corruptReason: reason };
|
|
85
|
-
}
|
|
86
|
-
const result = await verifyCarrier(bytes);
|
|
87
|
-
const { createHash } = await import("node:crypto");
|
|
88
|
-
const innerDigestB64 = createHash("sha256").update(parsed.inner).digest("base64");
|
|
89
|
-
return { status: "ok", innerDigestB64, inner: parsed.inner, result, view: carrierWindowView(result), corruptReason: null };
|
|
90
|
-
}
|
|
91
|
-
//# sourceMappingURL=carrier-io.js.map
|
package/dist/carrier-io.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"carrier-io.js","sourceRoot":"","sources":["../src/carrier-io.ts"],"names":[],"mappings":"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"}
|
package/dist/encoding.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/** Standard base64 → URL-safe unpadded base64. */
|
|
2
|
-
export declare function toUrlSafeB64(b64: string): string;
|
|
3
|
-
/**
|
|
4
|
-
* URL-safe base64 → standard base64 with padding.
|
|
5
|
-
* A no-op (apart from re-padding) when the input is already standard base64,
|
|
6
|
-
* so it is safe to call on either form.
|
|
7
|
-
*/
|
|
8
|
-
export declare function fromUrlSafeB64(urlSafe: string): string;
|
|
9
|
-
/** True if the string plausibly encodes 32 bytes of SHA-256 in either base64 form. */
|
|
10
|
-
export declare function looksLikeDigest(s: string): boolean;
|
|
11
|
-
/**
|
|
12
|
-
* SHA-256 of a file's bytes as standard base64.
|
|
13
|
-
* Streams from disk, so file size is not a memory concern. Only this digest
|
|
14
|
-
* ever leaves the machine; file contents are never uploaded.
|
|
15
|
-
*/
|
|
16
|
-
export declare function sha256FileB64(path: string): Promise<string>;
|
|
17
|
-
/** Run an async mapper over items with bounded concurrency, preserving order. */
|
|
18
|
-
export declare function mapConcurrent<T, R>(items: readonly T[], concurrency: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]>;
|
|
19
|
-
//# sourceMappingURL=encoding.d.ts.map
|
package/dist/encoding.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../src/encoding.ts"],"names":[],"mappings":"AAcA,kDAAkD;AAClD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAIlD;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUjE;AAED,iFAAiF;AACjF,wBAAsB,aAAa,CAAC,CAAC,EAAE,CAAC,EACtC,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GACzC,OAAO,CAAC,CAAC,EAAE,CAAC,CAYd"}
|
package/dist/encoding.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2024-2026 Argento Computing Inc. Licensed under the MIT License. See LICENSE.
|
|
2
|
-
/**
|
|
3
|
-
* @mikeargento/bitgraph-mcp: digest encoding and file hashing.
|
|
4
|
-
*
|
|
5
|
-
* BitGraph uses two base64 forms for the same SHA-256 digest:
|
|
6
|
-
* standard base64 with padding inside proof objects and commit requests,
|
|
7
|
-
* URL-safe unpadded base64 in API lookups, S3 keys, and proof page URLs.
|
|
8
|
-
*/
|
|
9
|
-
import { createHash } from "node:crypto";
|
|
10
|
-
import { createReadStream } from "node:fs";
|
|
11
|
-
import { stat } from "node:fs/promises";
|
|
12
|
-
/** Standard base64 → URL-safe unpadded base64. */
|
|
13
|
-
export function toUrlSafeB64(b64) {
|
|
14
|
-
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* URL-safe base64 → standard base64 with padding.
|
|
18
|
-
* A no-op (apart from re-padding) when the input is already standard base64,
|
|
19
|
-
* so it is safe to call on either form.
|
|
20
|
-
*/
|
|
21
|
-
export function fromUrlSafeB64(urlSafe) {
|
|
22
|
-
let b64 = urlSafe.replace(/-/g, "+").replace(/_/g, "/");
|
|
23
|
-
while (b64.length % 4 !== 0)
|
|
24
|
-
b64 += "=";
|
|
25
|
-
return b64;
|
|
26
|
-
}
|
|
27
|
-
/** True if the string plausibly encodes 32 bytes of SHA-256 in either base64 form. */
|
|
28
|
-
export function looksLikeDigest(s) {
|
|
29
|
-
const normalized = fromUrlSafeB64(s.trim());
|
|
30
|
-
if (!/^[A-Za-z0-9+/]{43}=$/.test(normalized))
|
|
31
|
-
return false;
|
|
32
|
-
return Buffer.from(normalized, "base64").length === 32;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* SHA-256 of a file's bytes as standard base64.
|
|
36
|
-
* Streams from disk, so file size is not a memory concern. Only this digest
|
|
37
|
-
* ever leaves the machine; file contents are never uploaded.
|
|
38
|
-
*/
|
|
39
|
-
export async function sha256FileB64(path) {
|
|
40
|
-
const info = await stat(path);
|
|
41
|
-
if (!info.isFile()) {
|
|
42
|
-
throw new Error(`Not a regular file: ${path}`);
|
|
43
|
-
}
|
|
44
|
-
const hash = createHash("sha256");
|
|
45
|
-
for await (const chunk of createReadStream(path)) {
|
|
46
|
-
hash.update(chunk);
|
|
47
|
-
}
|
|
48
|
-
return hash.digest("base64");
|
|
49
|
-
}
|
|
50
|
-
/** Run an async mapper over items with bounded concurrency, preserving order. */
|
|
51
|
-
export async function mapConcurrent(items, concurrency, fn) {
|
|
52
|
-
const results = new Array(items.length);
|
|
53
|
-
let next = 0;
|
|
54
|
-
async function worker() {
|
|
55
|
-
while (next < items.length) {
|
|
56
|
-
const index = next++;
|
|
57
|
-
results[index] = await fn(items[index], index);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
const workers = Array.from({ length: Math.min(concurrency, items.length) }, () => worker());
|
|
61
|
-
await Promise.all(workers);
|
|
62
|
-
return results;
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=encoding.js.map
|
package/dist/encoding.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.js","sourceRoot":"","sources":["../src/encoding.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAE9F;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,kDAAkD;AAClD,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACxE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,IAAI,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACxD,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC;QAAE,GAAG,IAAI,GAAG,CAAC;IACxC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,eAAe,CAAC,CAAS;IACvC,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3D,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,KAAe,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAmB,EACnB,WAAmB,EACnB,EAA0C;IAE1C,MAAM,OAAO,GAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,UAAU,MAAM;QACnB,OAAO,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,IAAI,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,KAAK,CAAM,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5F,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/scan.d.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @mikeargento/bitgraph-mcp: the scan.
|
|
3
|
-
*
|
|
4
|
-
* One pass over each file yields its SHA-256 (the member's origin) and a
|
|
5
|
-
* hasher left open after the placement's prefix and the file's last byte, so
|
|
6
|
-
* the member's fused digest can be finished later, for whatever slot the set
|
|
7
|
-
* is made under, without reading the file again. A placement is prefix,
|
|
8
|
-
* original, suffix (its frame): trailer/1 has no prefix and container/2's is
|
|
9
|
-
* the original's tar header, which depends on the size alone; the suffix
|
|
10
|
-
* carries the commitment and is hashed at BitGraph time. Node's SHA-256 is
|
|
11
|
-
* the platform's own, and a Hash can be copied mid-stream, which is the whole
|
|
12
|
-
* trick: the copy takes the suffix, so no file is read twice or held in
|
|
13
|
-
* memory, and the original is never touched.
|
|
14
|
-
*/
|
|
15
|
-
import { type Hash } from "node:crypto";
|
|
16
|
-
/** The placements the scan makes: chosen from the bytes by the core, never from the name. */
|
|
17
|
-
export type ScanPlacement = "trailer/1" | "container/2";
|
|
18
|
-
export interface ScannedFile {
|
|
19
|
-
path: string;
|
|
20
|
-
name: string;
|
|
21
|
-
size: number;
|
|
22
|
-
/** SHA-256 of the file, standard base64: the member's origin. */
|
|
23
|
-
digestB64: string;
|
|
24
|
-
originDigest: Uint8Array;
|
|
25
|
-
placement: ScanPlacement;
|
|
26
|
-
/**
|
|
27
|
-
* The hasher after the placement's prefix and the file's bytes, still open.
|
|
28
|
-
* Null when the file's length changed while it was read: its fused digest
|
|
29
|
-
* then needs the bytes again.
|
|
30
|
-
*/
|
|
31
|
-
state: Hash | null;
|
|
32
|
-
/** True when the bytes carry what looks like a C2PA manifest (Content Credentials). */
|
|
33
|
-
c2pa: boolean;
|
|
34
|
-
}
|
|
35
|
-
/** One-shot form for bytes already in memory (a carrier's committed bytes). */
|
|
36
|
-
export declare function sniffC2paBytes(bytes: Uint8Array): boolean;
|
|
37
|
-
/** Hash one file in a single pass. Throws, before any network call, when the path is not a regular file. */
|
|
38
|
-
export declare function scanFile(path: string): Promise<ScannedFile>;
|
|
39
|
-
/**
|
|
40
|
-
* A member's fused digest for a slot: the open hasher, copied, finished with
|
|
41
|
-
* the placement's suffix for that slot's commitment. The hash of prefix,
|
|
42
|
-
* original, suffix is exactly the hash of the placement's own build, which
|
|
43
|
-
* a test pins.
|
|
44
|
-
*/
|
|
45
|
-
export declare function fusedDigestFor(file: ScannedFile, commitment: Uint8Array): Uint8Array;
|
|
46
|
-
export interface Expansion {
|
|
47
|
-
/** Regular files in the order given; a directory contributes its files sorted by name, depth first. */
|
|
48
|
-
files: string[];
|
|
49
|
-
/** How many of the inputs were directories. */
|
|
50
|
-
directories: number;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Paths to files: a regular file is itself; a directory is every regular
|
|
54
|
-
* file under it, recursively, with hidden entries (names starting with a
|
|
55
|
-
* dot) and symbolic links left out. The same file twice is one file. A path
|
|
56
|
-
* that is missing or neither kind, or more than `limit` files in all, throws
|
|
57
|
-
* before any network call; the message names every path that failed.
|
|
58
|
-
*/
|
|
59
|
-
export declare function expandPaths(paths: readonly string[], limit: number): Promise<Expansion>;
|
|
60
|
-
//# sourceMappingURL=scan.d.ts.map
|
package/dist/scan.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAOpD,6FAA6F;AAC7F,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,aAAa,CAAC;AAExD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,UAAU,CAAC;IACzB,SAAS,EAAE,aAAa,CAAC;IACzB;;;;OAIG;IACH,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,uFAAuF;IACvF,IAAI,EAAE,OAAO,CAAC;CACf;AAuCD,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAEzD;AAKD,4GAA4G;AAC5G,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAuDjE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU,CAMpF;AAED,MAAM,WAAW,SAAS;IACxB,uGAAuG;IACvG,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CA2C7F"}
|