zk-agent-cli 1.0.0 → 1.0.1
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 +83 -12
- package/dist/index.js +916 -61
- package/package.json +9 -2
package/dist/index.js
CHANGED
|
@@ -8090,6 +8090,12 @@ function buildPaymentDashboardRecommendedCommand() {
|
|
|
8090
8090
|
function buildPaymentFeedRecommendedCommand() {
|
|
8091
8091
|
return "zk-agent payment feed";
|
|
8092
8092
|
}
|
|
8093
|
+
function buildPaymentPublishRecommendedCommand() {
|
|
8094
|
+
return "zk-agent payment publish";
|
|
8095
|
+
}
|
|
8096
|
+
function buildPaymentServeRecommendedCommand() {
|
|
8097
|
+
return "zk-agent payment serve";
|
|
8098
|
+
}
|
|
8093
8099
|
function buildPaymentApprovalRecommendedCommand(requestId) {
|
|
8094
8100
|
return `zk-agent payment approval --request-id ${requestId}`;
|
|
8095
8101
|
}
|
|
@@ -10393,7 +10399,7 @@ function buildSetupHelpText() {
|
|
|
10393
10399
|
" zk-agent next -> canonical live routing contract",
|
|
10394
10400
|
"",
|
|
10395
10401
|
"Then stay on the default local-first path:",
|
|
10396
|
-
" zk-agent
|
|
10402
|
+
" zk-agent start",
|
|
10397
10403
|
" zk-agent wallet create --await-local",
|
|
10398
10404
|
" zk-agent next",
|
|
10399
10405
|
` ${buildTopLevelPayRecommendedCommand("main")}`,
|
|
@@ -11384,7 +11390,7 @@ function buildNextHelpText() {
|
|
|
11384
11390
|
"",
|
|
11385
11391
|
"Default first-run path:",
|
|
11386
11392
|
" zk-agent setup",
|
|
11387
|
-
" zk-agent
|
|
11393
|
+
" zk-agent start",
|
|
11388
11394
|
" zk-agent wallet create --await-local",
|
|
11389
11395
|
" zk-agent next",
|
|
11390
11396
|
` ${buildTopLevelPayRecommendedCommand("main")}`,
|
|
@@ -11454,7 +11460,7 @@ function buildStartHelpText() {
|
|
|
11454
11460
|
"",
|
|
11455
11461
|
"Shortest first proof:",
|
|
11456
11462
|
" zk-agent setup",
|
|
11457
|
-
" zk-agent
|
|
11463
|
+
" zk-agent start",
|
|
11458
11464
|
" zk-agent wallet create --await-local",
|
|
11459
11465
|
" zk-agent next",
|
|
11460
11466
|
` ${buildTopLevelPayRecommendedCommand("main")}`,
|
|
@@ -13263,6 +13269,8 @@ function createDefaultsCommand() {
|
|
|
13263
13269
|
|
|
13264
13270
|
// src/commands/payment.ts
|
|
13265
13271
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
13272
|
+
import { mkdir as mkdir2, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
|
|
13273
|
+
import path7 from "node:path";
|
|
13266
13274
|
import { Command as Command7 } from "commander";
|
|
13267
13275
|
|
|
13268
13276
|
// ../agent-pay/src/lifecycle.ts
|
|
@@ -15180,6 +15188,117 @@ async function removeStoredPaymentRequest(requestId) {
|
|
|
15180
15188
|
return deletePaymentRequest(requestId);
|
|
15181
15189
|
}
|
|
15182
15190
|
|
|
15191
|
+
// src/lib/static-server.ts
|
|
15192
|
+
import { readFile as readFile2, stat } from "node:fs/promises";
|
|
15193
|
+
import { createServer } from "node:http";
|
|
15194
|
+
import path6 from "node:path";
|
|
15195
|
+
function writeBody(response, statusCode, contentType, value) {
|
|
15196
|
+
response.statusCode = statusCode;
|
|
15197
|
+
response.setHeader("Content-Type", contentType);
|
|
15198
|
+
response.end(value);
|
|
15199
|
+
}
|
|
15200
|
+
function writeJson2(response, statusCode, value) {
|
|
15201
|
+
writeBody(
|
|
15202
|
+
response,
|
|
15203
|
+
statusCode,
|
|
15204
|
+
"application/json; charset=utf-8",
|
|
15205
|
+
`${JSON.stringify(value, null, 2)}
|
|
15206
|
+
`
|
|
15207
|
+
);
|
|
15208
|
+
}
|
|
15209
|
+
function contentTypeFor(filePath) {
|
|
15210
|
+
switch (path6.extname(filePath).toLowerCase()) {
|
|
15211
|
+
case ".html":
|
|
15212
|
+
return "text/html; charset=utf-8";
|
|
15213
|
+
case ".json":
|
|
15214
|
+
return "application/json; charset=utf-8";
|
|
15215
|
+
case ".js":
|
|
15216
|
+
return "text/javascript; charset=utf-8";
|
|
15217
|
+
case ".css":
|
|
15218
|
+
return "text/css; charset=utf-8";
|
|
15219
|
+
case ".svg":
|
|
15220
|
+
return "image/svg+xml";
|
|
15221
|
+
case ".txt":
|
|
15222
|
+
return "text/plain; charset=utf-8";
|
|
15223
|
+
default:
|
|
15224
|
+
return "application/octet-stream";
|
|
15225
|
+
}
|
|
15226
|
+
}
|
|
15227
|
+
function isSafeResolvedPath(rootDir, filePath) {
|
|
15228
|
+
if (filePath === rootDir) return true;
|
|
15229
|
+
const rootWithSeparator = rootDir.endsWith(path6.sep) ? rootDir : `${rootDir}${path6.sep}`;
|
|
15230
|
+
return filePath.startsWith(rootWithSeparator);
|
|
15231
|
+
}
|
|
15232
|
+
async function startStaticServer(options) {
|
|
15233
|
+
const rootDir = path6.resolve(options.rootDir);
|
|
15234
|
+
const healthPath = options.healthPath?.trim() || "/health";
|
|
15235
|
+
const server = createServer(async (request, response) => {
|
|
15236
|
+
try {
|
|
15237
|
+
const requestUrl = new URL(request.url || "/", "http://localhost");
|
|
15238
|
+
const pathname = decodeURIComponent(requestUrl.pathname);
|
|
15239
|
+
const method = request.method || "GET";
|
|
15240
|
+
if (method === "OPTIONS") {
|
|
15241
|
+
writeJson2(response, 204, {});
|
|
15242
|
+
return;
|
|
15243
|
+
}
|
|
15244
|
+
if (method === "GET" && pathname === healthPath) {
|
|
15245
|
+
writeJson2(response, 200, options.healthPayload ? options.healthPayload() : { ok: true });
|
|
15246
|
+
return;
|
|
15247
|
+
}
|
|
15248
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
15249
|
+
writeJson2(response, 405, { error: `Unsupported static-server method: ${method}` });
|
|
15250
|
+
return;
|
|
15251
|
+
}
|
|
15252
|
+
const relativePath = pathname === "/" ? "/index.html" : pathname;
|
|
15253
|
+
const filePath = path6.resolve(rootDir, `.${relativePath}`);
|
|
15254
|
+
if (!isSafeResolvedPath(rootDir, filePath)) {
|
|
15255
|
+
writeJson2(response, 403, { error: "Forbidden path" });
|
|
15256
|
+
return;
|
|
15257
|
+
}
|
|
15258
|
+
const fileStats = await stat(filePath).catch(() => null);
|
|
15259
|
+
if (!fileStats?.isFile()) {
|
|
15260
|
+
writeJson2(response, 404, { error: `Static file not found: ${pathname}` });
|
|
15261
|
+
return;
|
|
15262
|
+
}
|
|
15263
|
+
const body = await readFile2(filePath);
|
|
15264
|
+
response.statusCode = 200;
|
|
15265
|
+
response.setHeader("Content-Type", contentTypeFor(filePath));
|
|
15266
|
+
response.end(method === "HEAD" ? void 0 : body);
|
|
15267
|
+
} catch (error) {
|
|
15268
|
+
writeJson2(response, 500, {
|
|
15269
|
+
error: error instanceof Error ? error.message : String(error)
|
|
15270
|
+
});
|
|
15271
|
+
}
|
|
15272
|
+
});
|
|
15273
|
+
const address = await new Promise((resolve, reject) => {
|
|
15274
|
+
server.once("error", reject);
|
|
15275
|
+
server.listen(options.port, options.host, () => {
|
|
15276
|
+
const bound = server.address();
|
|
15277
|
+
if (!bound || typeof bound === "string") {
|
|
15278
|
+
reject(new Error("Unable to resolve static server address."));
|
|
15279
|
+
return;
|
|
15280
|
+
}
|
|
15281
|
+
resolve({
|
|
15282
|
+
address: bound.address,
|
|
15283
|
+
port: bound.port
|
|
15284
|
+
});
|
|
15285
|
+
});
|
|
15286
|
+
});
|
|
15287
|
+
return {
|
|
15288
|
+
origin: `http://${address.address}:${address.port}`,
|
|
15289
|
+
port: address.port,
|
|
15290
|
+
close: async () => await new Promise((resolve, reject) => {
|
|
15291
|
+
server.close((error) => {
|
|
15292
|
+
if (error) {
|
|
15293
|
+
reject(error);
|
|
15294
|
+
return;
|
|
15295
|
+
}
|
|
15296
|
+
resolve();
|
|
15297
|
+
});
|
|
15298
|
+
})
|
|
15299
|
+
};
|
|
15300
|
+
}
|
|
15301
|
+
|
|
15183
15302
|
// src/commands/payment.ts
|
|
15184
15303
|
function parseMetadataEntries2(entries) {
|
|
15185
15304
|
const metadata = {};
|
|
@@ -15566,15 +15685,435 @@ function paymentIntentLines(intent, inspectCommand, handoffCommand, partiesComma
|
|
|
15566
15685
|
function buildAgentPayProductLayer(surface) {
|
|
15567
15686
|
return {
|
|
15568
15687
|
stage: "local-first-workbench",
|
|
15569
|
-
publicShell: "submit -> next -> approval -> workspace -> handoff -> feed",
|
|
15688
|
+
publicShell: "submit -> payment next -> approval -> workspace -> handoff -> feed",
|
|
15570
15689
|
productClaim: "compact ingress, wallet-aware follow-up, one cross-request workspace, and stable exports",
|
|
15571
15690
|
surfaceRole: surface === "workspace" ? "cross-request-workbench" : surface === "handoff" ? "single-request-export" : "cross-request-export",
|
|
15572
15691
|
platformDirection: "handoff and feed are already shaped for external dashboards, agents, or backend ingestion",
|
|
15573
15692
|
boundary: "local-first only today; not a hosted multi-tenant control plane"
|
|
15574
15693
|
};
|
|
15575
15694
|
}
|
|
15695
|
+
function buildAgentPayIntegrationLayer() {
|
|
15696
|
+
return {
|
|
15697
|
+
stage: "operator-controlled-export",
|
|
15698
|
+
currentMode: "same-runtime, static export, or operator-controlled hosted preview",
|
|
15699
|
+
currentProof: "stable workspace/feed/handoff JSON can already be published and served as a static bundle for external dashboards, agents, or backends from the same runtime or one operator-controlled host",
|
|
15700
|
+
workbenchSurface: buildWorkspaceRecommendedCommand(),
|
|
15701
|
+
singleRequestSurface: buildHandoffRecommendedCommand("<request-id>"),
|
|
15702
|
+
batchSurface: buildFeedRecommendedCommand(),
|
|
15703
|
+
publishSurface: buildPaymentPublishRecommendedCommand(),
|
|
15704
|
+
serveSurface: buildPaymentServeRecommendedCommand(),
|
|
15705
|
+
nextHostedStep: "prove the served static workspace/feed/handoff bundle behind one externally reachable operator URL before adding multi-tenant persistence",
|
|
15706
|
+
boundary: "not yet a hosted multi-tenant control plane"
|
|
15707
|
+
};
|
|
15708
|
+
}
|
|
15709
|
+
function sanitizePublishSegment(value) {
|
|
15710
|
+
const normalized = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
15711
|
+
return normalized || "all";
|
|
15712
|
+
}
|
|
15713
|
+
function defaultPaymentPublishDir(filters) {
|
|
15714
|
+
const generatedAt = (/* @__PURE__ */ new Date()).toISOString().replace(/[:]/g, "-");
|
|
15715
|
+
const walletSegment = sanitizePublishSegment(filters.walletName || "all-wallets");
|
|
15716
|
+
const statusSegment = sanitizePublishSegment(filters.status || "all-statuses");
|
|
15717
|
+
return path7.join(
|
|
15718
|
+
storageDir(),
|
|
15719
|
+
"exports",
|
|
15720
|
+
"agent-pay",
|
|
15721
|
+
`${generatedAt}-${walletSegment}-${statusSegment}`
|
|
15722
|
+
);
|
|
15723
|
+
}
|
|
15724
|
+
function resolvePaymentPublishDir(dir, filters) {
|
|
15725
|
+
const trimmed = dir?.trim();
|
|
15726
|
+
return trimmed ? path7.resolve(trimmed) : defaultPaymentPublishDir(filters);
|
|
15727
|
+
}
|
|
15728
|
+
function resolvePaymentPublishPublicBaseUrl(value) {
|
|
15729
|
+
return resolvePaymentAbsoluteHttpUrl(
|
|
15730
|
+
value,
|
|
15731
|
+
"--public-base-url",
|
|
15732
|
+
"PAYMENT_PUBLISH_PUBLIC_BASE_URL_INVALID"
|
|
15733
|
+
);
|
|
15734
|
+
}
|
|
15735
|
+
function resolvePaymentServePublicOrigin(value) {
|
|
15736
|
+
return resolvePaymentAbsoluteHttpUrl(
|
|
15737
|
+
value,
|
|
15738
|
+
"--public-origin",
|
|
15739
|
+
"PAYMENT_SERVE_PUBLIC_ORIGIN_INVALID"
|
|
15740
|
+
);
|
|
15741
|
+
}
|
|
15742
|
+
function resolvePaymentAbsoluteHttpUrl(value, optionLabel, errorCode) {
|
|
15743
|
+
const trimmed = value?.trim();
|
|
15744
|
+
if (!trimmed) return null;
|
|
15745
|
+
let parsed;
|
|
15746
|
+
try {
|
|
15747
|
+
parsed = new URL(trimmed);
|
|
15748
|
+
} catch {
|
|
15749
|
+
throw new AgentError(
|
|
15750
|
+
errorCode,
|
|
15751
|
+
`Invalid ${optionLabel} value: ${value}. Use an absolute http(s) URL.`
|
|
15752
|
+
);
|
|
15753
|
+
}
|
|
15754
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
15755
|
+
throw new AgentError(
|
|
15756
|
+
errorCode,
|
|
15757
|
+
`Invalid ${optionLabel} value: ${value}. Use an absolute http(s) URL.`
|
|
15758
|
+
);
|
|
15759
|
+
}
|
|
15760
|
+
return parsed.href.replace(/\/+$/, "");
|
|
15761
|
+
}
|
|
15762
|
+
function paymentPublicOriginLooksLocal(origin) {
|
|
15763
|
+
try {
|
|
15764
|
+
const { hostname } = new URL(origin);
|
|
15765
|
+
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "0.0.0.0" || hostname === "::1" || hostname === "[::1]";
|
|
15766
|
+
} catch {
|
|
15767
|
+
return false;
|
|
15768
|
+
}
|
|
15769
|
+
}
|
|
15770
|
+
function resolvePaymentServePort(value) {
|
|
15771
|
+
const parsed = Number.parseInt(value?.trim() || "4495", 10);
|
|
15772
|
+
if (!Number.isInteger(parsed) || parsed < 0 || parsed > 65535) {
|
|
15773
|
+
throw new AgentError(
|
|
15774
|
+
"PAYMENT_SERVE_PORT_INVALID",
|
|
15775
|
+
`Invalid payment serve port: ${value}. Use an integer between 0 and 65535.`
|
|
15776
|
+
);
|
|
15777
|
+
}
|
|
15778
|
+
return parsed;
|
|
15779
|
+
}
|
|
15780
|
+
function buildPaymentPublishArtifactLink(relativePath, publicBaseUrl) {
|
|
15781
|
+
const normalizedPath = relativePath.replace(/\\/g, "/");
|
|
15782
|
+
return {
|
|
15783
|
+
path: normalizedPath,
|
|
15784
|
+
publicUrl: publicBaseUrl ? `${publicBaseUrl}/${normalizedPath}` : null
|
|
15785
|
+
};
|
|
15786
|
+
}
|
|
15787
|
+
async function writePublishJsonFile(filePath, payload) {
|
|
15788
|
+
await mkdir2(path7.dirname(filePath), { recursive: true, mode: 448 });
|
|
15789
|
+
await writeFile2(filePath, `${JSON.stringify(payload, null, 2)}
|
|
15790
|
+
`, { mode: 384 });
|
|
15791
|
+
}
|
|
15792
|
+
async function writePublishTextFile(filePath, content) {
|
|
15793
|
+
await mkdir2(path7.dirname(filePath), { recursive: true, mode: 448 });
|
|
15794
|
+
await writeFile2(filePath, content, { mode: 384 });
|
|
15795
|
+
}
|
|
15796
|
+
function resolvePaymentPublishSelection(options) {
|
|
15797
|
+
return {
|
|
15798
|
+
walletName: options.wallet,
|
|
15799
|
+
status: options.status ? resolvePaymentStatus(options.status) : void 0,
|
|
15800
|
+
queueLimit: resolvePositiveInteger(options.queueLimit, "--queue-limit"),
|
|
15801
|
+
walletLimit: resolvePositiveInteger(options.walletLimit, "--wallet-limit"),
|
|
15802
|
+
recentActivityLimit: resolvePositiveInteger(options.activityLimit, "--activity-limit"),
|
|
15803
|
+
feedLimit: resolvePositiveInteger(options.feedLimit, "--feed-limit")
|
|
15804
|
+
};
|
|
15805
|
+
}
|
|
15806
|
+
async function loadPaymentPublishData(input) {
|
|
15807
|
+
const workspaceResult = await buildStoredPaymentRequestsWorkspace({
|
|
15808
|
+
walletName: input.walletName,
|
|
15809
|
+
status: input.status,
|
|
15810
|
+
queueLimit: input.queueLimit,
|
|
15811
|
+
walletLimit: input.walletLimit,
|
|
15812
|
+
recentActivityLimit: input.recentActivityLimit,
|
|
15813
|
+
feedLimit: input.feedLimit
|
|
15814
|
+
});
|
|
15815
|
+
const requests = await listStoredPaymentRequests({
|
|
15816
|
+
walletName: input.walletName,
|
|
15817
|
+
status: input.status
|
|
15818
|
+
});
|
|
15819
|
+
const handoffResults = await Promise.all(
|
|
15820
|
+
requests.map((record) => getStoredPaymentRequestHandoff(record.requestId))
|
|
15821
|
+
);
|
|
15822
|
+
return {
|
|
15823
|
+
outputDir: resolvePaymentPublishDir(input.dir, workspaceResult.workspace.filters),
|
|
15824
|
+
workspace: workspaceResult.workspace,
|
|
15825
|
+
requests,
|
|
15826
|
+
handoffResults
|
|
15827
|
+
};
|
|
15828
|
+
}
|
|
15829
|
+
function buildPaymentPublishBundle(input) {
|
|
15830
|
+
const workspaceRelativePath = "workspace.json";
|
|
15831
|
+
const feedRelativePath = "feed.json";
|
|
15832
|
+
const manifestRelativePath = "manifest.json";
|
|
15833
|
+
const indexRelativePath = "index.html";
|
|
15834
|
+
const handoffsRelativeDir = "handoffs";
|
|
15835
|
+
const workspacePayload = buildPublishedWorkspacePayload(input.data.workspace);
|
|
15836
|
+
const feedPayload = buildPublishedFeedPayload(input.data.workspace.feed);
|
|
15837
|
+
const handoffPayloads = input.data.handoffResults.map((result) => {
|
|
15838
|
+
const relativePath = `${handoffsRelativeDir}/${result.paymentRequest.requestId}.json`;
|
|
15839
|
+
return {
|
|
15840
|
+
requestId: result.paymentRequest.requestId,
|
|
15841
|
+
status: result.paymentRequest.settlement.status,
|
|
15842
|
+
relativePath,
|
|
15843
|
+
payload: buildPublishedHandoffPayload(result)
|
|
15844
|
+
};
|
|
15845
|
+
});
|
|
15846
|
+
const manifest = {
|
|
15847
|
+
format: "zk-agent-payment-publish-manifest",
|
|
15848
|
+
version: 1,
|
|
15849
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
15850
|
+
source: "local-first",
|
|
15851
|
+
mode: "operator-controlled-static-export",
|
|
15852
|
+
productLayer: buildAgentPayProductLayer("workspace"),
|
|
15853
|
+
integrationLayer: buildAgentPayIntegrationLayer(),
|
|
15854
|
+
filters: {
|
|
15855
|
+
walletName: input.data.workspace.filters.walletName,
|
|
15856
|
+
status: input.data.workspace.filters.status,
|
|
15857
|
+
recentActivityLimit: input.data.workspace.filters.recentActivityLimit,
|
|
15858
|
+
queueLimit: input.data.workspace.filters.queueLimit,
|
|
15859
|
+
walletLimit: input.data.workspace.filters.walletLimit,
|
|
15860
|
+
feedLimit: input.data.workspace.filters.feedLimit
|
|
15861
|
+
},
|
|
15862
|
+
summary: {
|
|
15863
|
+
totalRequests: input.data.requests.length,
|
|
15864
|
+
workspaceRequests: input.data.workspace.summary.totalRequests,
|
|
15865
|
+
feedItems: input.data.workspace.feed.items.length,
|
|
15866
|
+
queueItems: input.data.workspace.queue.items.length,
|
|
15867
|
+
recentActivityCount: input.data.workspace.summary.recentActivityCount,
|
|
15868
|
+
handoffCount: handoffPayloads.length
|
|
15869
|
+
},
|
|
15870
|
+
output: {
|
|
15871
|
+
directory: input.data.outputDir,
|
|
15872
|
+
publicBaseUrl: input.publicBaseUrl
|
|
15873
|
+
},
|
|
15874
|
+
entrypoints: {
|
|
15875
|
+
index: buildPaymentPublishArtifactLink(indexRelativePath, input.publicBaseUrl),
|
|
15876
|
+
manifest: buildPaymentPublishArtifactLink(manifestRelativePath, input.publicBaseUrl),
|
|
15877
|
+
workspace: buildPaymentPublishArtifactLink(workspaceRelativePath, input.publicBaseUrl),
|
|
15878
|
+
feed: buildPaymentPublishArtifactLink(feedRelativePath, input.publicBaseUrl),
|
|
15879
|
+
handoffs: buildPaymentPublishArtifactLink(`${handoffsRelativeDir}/`, input.publicBaseUrl)
|
|
15880
|
+
},
|
|
15881
|
+
handoffs: handoffPayloads.map((entry) => ({
|
|
15882
|
+
requestId: entry.requestId,
|
|
15883
|
+
status: entry.status,
|
|
15884
|
+
path: entry.relativePath,
|
|
15885
|
+
publicUrl: buildPaymentPublishArtifactLink(entry.relativePath, input.publicBaseUrl).publicUrl
|
|
15886
|
+
}))
|
|
15887
|
+
};
|
|
15888
|
+
return {
|
|
15889
|
+
outputDir: input.data.outputDir,
|
|
15890
|
+
publicBaseUrl: input.publicBaseUrl,
|
|
15891
|
+
workspacePayload,
|
|
15892
|
+
feedPayload,
|
|
15893
|
+
handoffPayloads,
|
|
15894
|
+
manifest
|
|
15895
|
+
};
|
|
15896
|
+
}
|
|
15897
|
+
async function writePaymentPublishBundle(bundle) {
|
|
15898
|
+
await mkdir2(bundle.outputDir, { recursive: true, mode: 448 });
|
|
15899
|
+
await rm2(path7.join(bundle.outputDir, "handoffs"), { recursive: true, force: true });
|
|
15900
|
+
await Promise.all([
|
|
15901
|
+
writePublishJsonFile(path7.join(bundle.outputDir, "workspace.json"), bundle.workspacePayload),
|
|
15902
|
+
writePublishJsonFile(path7.join(bundle.outputDir, "feed.json"), bundle.feedPayload),
|
|
15903
|
+
writePublishJsonFile(path7.join(bundle.outputDir, "manifest.json"), bundle.manifest),
|
|
15904
|
+
writePublishTextFile(
|
|
15905
|
+
path7.join(bundle.outputDir, "index.html"),
|
|
15906
|
+
buildPaymentPublishIndexHtml({
|
|
15907
|
+
manifest: bundle.manifest,
|
|
15908
|
+
workspaceLink: bundle.manifest.entrypoints.workspace,
|
|
15909
|
+
feedLink: bundle.manifest.entrypoints.feed
|
|
15910
|
+
})
|
|
15911
|
+
),
|
|
15912
|
+
...bundle.handoffPayloads.map(
|
|
15913
|
+
(entry) => writePublishJsonFile(path7.join(bundle.outputDir, entry.relativePath), entry.payload)
|
|
15914
|
+
)
|
|
15915
|
+
]);
|
|
15916
|
+
}
|
|
15917
|
+
function buildPaymentPublishPayload(bundle) {
|
|
15918
|
+
return {
|
|
15919
|
+
productLayer: bundle.manifest.productLayer,
|
|
15920
|
+
integrationLayer: bundle.manifest.integrationLayer,
|
|
15921
|
+
publish: {
|
|
15922
|
+
format: "zk-agent-payment-publish",
|
|
15923
|
+
version: 1,
|
|
15924
|
+
generatedAt: bundle.manifest.generatedAt,
|
|
15925
|
+
source: bundle.manifest.source,
|
|
15926
|
+
mode: bundle.manifest.mode,
|
|
15927
|
+
outputDir: bundle.outputDir,
|
|
15928
|
+
publicBaseUrl: bundle.publicBaseUrl,
|
|
15929
|
+
filters: bundle.manifest.filters,
|
|
15930
|
+
summary: bundle.manifest.summary,
|
|
15931
|
+
entrypoints: bundle.manifest.entrypoints
|
|
15932
|
+
},
|
|
15933
|
+
manifest: bundle.manifest
|
|
15934
|
+
};
|
|
15935
|
+
}
|
|
15936
|
+
function buildPaymentServeRecommendedCommands(options) {
|
|
15937
|
+
return {
|
|
15938
|
+
serve: buildPaymentServeRecommendedCommand(),
|
|
15939
|
+
publish: buildPaymentPublishRecommendedCommand(),
|
|
15940
|
+
workspace: buildPaymentWorkspaceRecommendedCommand(),
|
|
15941
|
+
handoff: buildPaymentHandoffRecommendedCommand("<request-id>"),
|
|
15942
|
+
feed: buildPaymentFeedRecommendedCommand(),
|
|
15943
|
+
...options.publicOriginLooksLocal ? {
|
|
15944
|
+
restartWithPublicOrigin: "zk-agent payment serve --public-origin https://pay.example.com"
|
|
15945
|
+
} : {}
|
|
15946
|
+
};
|
|
15947
|
+
}
|
|
15948
|
+
function buildPaymentServeNotes(options) {
|
|
15949
|
+
if (!options.publicOriginLooksLocal) {
|
|
15950
|
+
return [];
|
|
15951
|
+
}
|
|
15952
|
+
return [
|
|
15953
|
+
options.publicOrigin.startsWith("http://127.0.0.1") || options.publicOrigin.startsWith("http://localhost") ? "Static bundle is still advertising a local bind origin. Set --public-origin to the externally reachable URL before using this as an externally hosted Agent Pay preview." : "Static bundle is still advertising a local-only public origin. Set --public-origin to the externally reachable URL before using this as an externally hosted Agent Pay preview."
|
|
15954
|
+
];
|
|
15955
|
+
}
|
|
15956
|
+
function buildPaymentPublishIndexHtml(input) {
|
|
15957
|
+
const handoffItems = input.manifest.handoffs.length === 0 ? "<li>No handoff files were published for the current filter.</li>" : input.manifest.handoffs.slice(0, 20).map(
|
|
15958
|
+
(entry) => `<li><a href="./${entry.path}">${entry.requestId}</a> <span>${entry.status}</span></li>`
|
|
15959
|
+
).join("\n");
|
|
15960
|
+
const publicBaseUrl = input.manifest.output.publicBaseUrl ? `<p><strong>Public base URL:</strong> <code>${input.manifest.output.publicBaseUrl}</code></p>` : "";
|
|
15961
|
+
return `<!doctype html>
|
|
15962
|
+
<html lang="en">
|
|
15963
|
+
<head>
|
|
15964
|
+
<meta charset="utf-8" />
|
|
15965
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
15966
|
+
<title>zk-agent Agent Pay Publish Bundle</title>
|
|
15967
|
+
<style>
|
|
15968
|
+
:root {
|
|
15969
|
+
color-scheme: light;
|
|
15970
|
+
--bg: #f6f1e8;
|
|
15971
|
+
--panel: #fffaf2;
|
|
15972
|
+
--text: #1f2a22;
|
|
15973
|
+
--muted: #5e675f;
|
|
15974
|
+
--line: #d6c9b4;
|
|
15975
|
+
--accent: #0d7a52;
|
|
15976
|
+
}
|
|
15977
|
+
body {
|
|
15978
|
+
margin: 0;
|
|
15979
|
+
font-family: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", serif;
|
|
15980
|
+
background:
|
|
15981
|
+
radial-gradient(circle at top right, rgba(13, 122, 82, 0.08), transparent 28rem),
|
|
15982
|
+
linear-gradient(180deg, #fcf8f1 0%, var(--bg) 100%);
|
|
15983
|
+
color: var(--text);
|
|
15984
|
+
}
|
|
15985
|
+
main {
|
|
15986
|
+
max-width: 960px;
|
|
15987
|
+
margin: 0 auto;
|
|
15988
|
+
padding: 48px 20px 72px;
|
|
15989
|
+
}
|
|
15990
|
+
section {
|
|
15991
|
+
background: rgba(255, 250, 242, 0.92);
|
|
15992
|
+
border: 1px solid var(--line);
|
|
15993
|
+
border-radius: 20px;
|
|
15994
|
+
padding: 24px;
|
|
15995
|
+
margin-top: 20px;
|
|
15996
|
+
box-shadow: 0 18px 40px rgba(52, 45, 29, 0.08);
|
|
15997
|
+
}
|
|
15998
|
+
h1, h2 {
|
|
15999
|
+
margin: 0 0 12px;
|
|
16000
|
+
font-weight: 600;
|
|
16001
|
+
}
|
|
16002
|
+
p, li {
|
|
16003
|
+
line-height: 1.5;
|
|
16004
|
+
}
|
|
16005
|
+
ul {
|
|
16006
|
+
padding-left: 20px;
|
|
16007
|
+
}
|
|
16008
|
+
a {
|
|
16009
|
+
color: var(--accent);
|
|
16010
|
+
}
|
|
16011
|
+
code {
|
|
16012
|
+
background: rgba(31, 42, 34, 0.06);
|
|
16013
|
+
padding: 0.1rem 0.35rem;
|
|
16014
|
+
border-radius: 0.35rem;
|
|
16015
|
+
}
|
|
16016
|
+
.meta {
|
|
16017
|
+
color: var(--muted);
|
|
16018
|
+
}
|
|
16019
|
+
.grid {
|
|
16020
|
+
display: grid;
|
|
16021
|
+
gap: 12px;
|
|
16022
|
+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
16023
|
+
}
|
|
16024
|
+
.card {
|
|
16025
|
+
border: 1px solid var(--line);
|
|
16026
|
+
border-radius: 14px;
|
|
16027
|
+
padding: 14px 16px;
|
|
16028
|
+
background: rgba(255, 255, 255, 0.72);
|
|
16029
|
+
}
|
|
16030
|
+
</style>
|
|
16031
|
+
</head>
|
|
16032
|
+
<body>
|
|
16033
|
+
<main>
|
|
16034
|
+
<section>
|
|
16035
|
+
<p class="meta">zk-agent Agent Pay static export</p>
|
|
16036
|
+
<h1>Operator-controlled publish bundle</h1>
|
|
16037
|
+
<p>This directory is the current static export proof for Agent Pay. It snapshots the stable <code>workspace</code>, <code>feed</code>, and per-request <code>handoff</code> contracts without claiming a hosted multi-tenant control plane.</p>
|
|
16038
|
+
<p class="meta">Generated at ${input.manifest.generatedAt}</p>
|
|
16039
|
+
${publicBaseUrl}
|
|
16040
|
+
</section>
|
|
16041
|
+
<section>
|
|
16042
|
+
<h2>Bundle summary</h2>
|
|
16043
|
+
<div class="grid">
|
|
16044
|
+
<div class="card"><strong>${input.manifest.summary.totalRequests}</strong><br />requests</div>
|
|
16045
|
+
<div class="card"><strong>${input.manifest.summary.feedItems}</strong><br />feed items</div>
|
|
16046
|
+
<div class="card"><strong>${input.manifest.summary.queueItems}</strong><br />queue items</div>
|
|
16047
|
+
<div class="card"><strong>${input.manifest.summary.handoffCount}</strong><br />handoff files</div>
|
|
16048
|
+
</div>
|
|
16049
|
+
</section>
|
|
16050
|
+
<section>
|
|
16051
|
+
<h2>Entry points</h2>
|
|
16052
|
+
<ul>
|
|
16053
|
+
<li><a href="./manifest.json">manifest.json</a></li>
|
|
16054
|
+
<li><a href="./${input.workspaceLink.path}">${input.workspaceLink.path}</a></li>
|
|
16055
|
+
<li><a href="./${input.feedLink.path}">${input.feedLink.path}</a></li>
|
|
16056
|
+
</ul>
|
|
16057
|
+
</section>
|
|
16058
|
+
<section>
|
|
16059
|
+
<h2>Published handoffs</h2>
|
|
16060
|
+
<ul>
|
|
16061
|
+
${handoffItems}
|
|
16062
|
+
</ul>
|
|
16063
|
+
</section>
|
|
16064
|
+
</main>
|
|
16065
|
+
</body>
|
|
16066
|
+
</html>
|
|
16067
|
+
`;
|
|
16068
|
+
}
|
|
16069
|
+
function paymentPublishLines(input) {
|
|
16070
|
+
return [
|
|
16071
|
+
["mode", input.manifest.mode],
|
|
16072
|
+
["output dir", input.outputDir],
|
|
16073
|
+
["requests", String(input.manifest.summary.totalRequests)],
|
|
16074
|
+
["feed items", String(input.manifest.summary.feedItems)],
|
|
16075
|
+
["handoffs", String(input.manifest.summary.handoffCount)],
|
|
16076
|
+
["workspace", input.manifest.entrypoints.workspace.path],
|
|
16077
|
+
["feed", input.manifest.entrypoints.feed.path],
|
|
16078
|
+
["manifest", input.manifest.entrypoints.manifest.path],
|
|
16079
|
+
["index", input.manifest.entrypoints.index.path],
|
|
16080
|
+
["publish", buildPaymentPublishRecommendedCommand()],
|
|
16081
|
+
["serve", buildPaymentServeRecommendedCommand()],
|
|
16082
|
+
["workspace command", buildPaymentWorkspaceRecommendedCommand()],
|
|
16083
|
+
["feed command", buildPaymentFeedRecommendedCommand()]
|
|
16084
|
+
];
|
|
16085
|
+
}
|
|
16086
|
+
function paymentServeLines(input) {
|
|
16087
|
+
return [
|
|
16088
|
+
["status", "payment-serving"],
|
|
16089
|
+
["origin", input.origin],
|
|
16090
|
+
["public origin", input.publicOrigin],
|
|
16091
|
+
["public origin source", input.publicOriginSource],
|
|
16092
|
+
["output dir", input.bundle.outputDir],
|
|
16093
|
+
[
|
|
16094
|
+
"workspace",
|
|
16095
|
+
input.bundle.manifest.entrypoints.workspace.publicUrl || input.bundle.manifest.entrypoints.workspace.path
|
|
16096
|
+
],
|
|
16097
|
+
[
|
|
16098
|
+
"feed",
|
|
16099
|
+
input.bundle.manifest.entrypoints.feed.publicUrl || input.bundle.manifest.entrypoints.feed.path
|
|
16100
|
+
],
|
|
16101
|
+
[
|
|
16102
|
+
"manifest",
|
|
16103
|
+
input.bundle.manifest.entrypoints.manifest.publicUrl || input.bundle.manifest.entrypoints.manifest.path
|
|
16104
|
+
],
|
|
16105
|
+
[
|
|
16106
|
+
"index",
|
|
16107
|
+
input.bundle.manifest.entrypoints.index.publicUrl || input.bundle.manifest.entrypoints.index.path
|
|
16108
|
+
],
|
|
16109
|
+
["health", `${input.origin}/health`],
|
|
16110
|
+
["publish", buildPaymentPublishRecommendedCommand()],
|
|
16111
|
+
["serve", buildPaymentServeRecommendedCommand()]
|
|
16112
|
+
];
|
|
16113
|
+
}
|
|
15576
16114
|
function paymentHandoffLines(handoff, inspectCommand, partiesCommand, shareCommand, settlementCommand) {
|
|
15577
16115
|
const productLayer = buildAgentPayProductLayer("handoff");
|
|
16116
|
+
const integrationLayer = buildAgentPayIntegrationLayer();
|
|
15578
16117
|
const lines = [
|
|
15579
16118
|
["request", handoff.requestId],
|
|
15580
16119
|
["product stage", productLayer.stage],
|
|
@@ -15582,6 +16121,15 @@ function paymentHandoffLines(handoff, inspectCommand, partiesCommand, shareComma
|
|
|
15582
16121
|
["surface role", productLayer.surfaceRole],
|
|
15583
16122
|
["platform direction", productLayer.platformDirection],
|
|
15584
16123
|
["boundary", productLayer.boundary],
|
|
16124
|
+
["integration stage", integrationLayer.stage],
|
|
16125
|
+
["integration mode", integrationLayer.currentMode],
|
|
16126
|
+
["integration proof", integrationLayer.currentProof],
|
|
16127
|
+
[
|
|
16128
|
+
"integration surfaces",
|
|
16129
|
+
`${integrationLayer.workbenchSurface} -> ${integrationLayer.singleRequestSurface} -> ${integrationLayer.batchSurface}`
|
|
16130
|
+
],
|
|
16131
|
+
["hosted direction", integrationLayer.nextHostedStep],
|
|
16132
|
+
["integration boundary", integrationLayer.boundary],
|
|
15585
16133
|
["source", handoff.source],
|
|
15586
16134
|
["chain", `${handoff.chain} (${handoff.chainId})`],
|
|
15587
16135
|
["status", handoff.summary.settlementStatus],
|
|
@@ -15840,6 +16388,7 @@ function paymentIngressLines(input) {
|
|
|
15840
16388
|
function paymentWorkspaceLines(workspace, workspaceCommand = buildDefaultPaymentWorkspaceCommand(), submitCommand = buildDefaultPaymentSubmitCommand(), approvalCommand = buildPaymentApprovalRecommendedCommand("<request-id>"), handoffCommand = buildPaymentHandoffRecommendedCommand("<request-id>"), feedCommand = buildPaymentFeedRecommendedCommand()) {
|
|
15841
16389
|
const walletName = workspace.filters.walletName || "main";
|
|
15842
16390
|
const productLayer = buildAgentPayProductLayer("workspace");
|
|
16391
|
+
const integrationLayer = buildAgentPayIntegrationLayer();
|
|
15843
16392
|
const lines = [
|
|
15844
16393
|
["surface", "cross-request Agent Pay workspace"],
|
|
15845
16394
|
[
|
|
@@ -15852,6 +16401,15 @@ function paymentWorkspaceLines(workspace, workspaceCommand = buildDefaultPayment
|
|
|
15852
16401
|
["public shell", productLayer.publicShell],
|
|
15853
16402
|
["platform direction", productLayer.platformDirection],
|
|
15854
16403
|
["boundary", productLayer.boundary],
|
|
16404
|
+
["integration stage", integrationLayer.stage],
|
|
16405
|
+
["integration mode", integrationLayer.currentMode],
|
|
16406
|
+
["integration proof", integrationLayer.currentProof],
|
|
16407
|
+
[
|
|
16408
|
+
"integration surfaces",
|
|
16409
|
+
`${integrationLayer.workbenchSurface} -> ${integrationLayer.singleRequestSurface} -> ${integrationLayer.batchSurface}`
|
|
16410
|
+
],
|
|
16411
|
+
["hosted direction", integrationLayer.nextHostedStep],
|
|
16412
|
+
["integration boundary", integrationLayer.boundary],
|
|
15855
16413
|
["generated", workspace.generatedAt],
|
|
15856
16414
|
["source", workspace.source],
|
|
15857
16415
|
["submit", submitCommand || buildPaymentSubmitRecommendedCommand(walletName)],
|
|
@@ -15916,6 +16474,72 @@ function buildDefaultPaymentWorkspaceCommand() {
|
|
|
15916
16474
|
function buildDefaultPaymentSubmitCommand() {
|
|
15917
16475
|
return buildPaymentSubmitRecommendedCommand();
|
|
15918
16476
|
}
|
|
16477
|
+
function buildPublishedWorkspacePayload(workspace) {
|
|
16478
|
+
const walletName = workspace.filters.walletName || "main";
|
|
16479
|
+
return {
|
|
16480
|
+
ok: true,
|
|
16481
|
+
productLayer: buildAgentPayProductLayer("workspace"),
|
|
16482
|
+
integrationLayer: buildAgentPayIntegrationLayer(),
|
|
16483
|
+
workspace: {
|
|
16484
|
+
...workspace,
|
|
16485
|
+
queue: {
|
|
16486
|
+
...workspace.queue,
|
|
16487
|
+
items: workspace.queue.items.map((item) => ({
|
|
16488
|
+
descriptor: item.descriptor,
|
|
16489
|
+
executionPlan: buildPaymentExecutionPlanJson(item.executionPlan),
|
|
16490
|
+
next: item.next
|
|
16491
|
+
}))
|
|
16492
|
+
}
|
|
16493
|
+
},
|
|
16494
|
+
recommendedCommands: {
|
|
16495
|
+
workspace: buildPaymentWorkspaceRecommendedCommand(),
|
|
16496
|
+
approval: buildPaymentApprovalRecommendedCommand("<request-id>"),
|
|
16497
|
+
handoff: buildPaymentHandoffRecommendedCommand("<request-id>"),
|
|
16498
|
+
feed: buildPaymentFeedRecommendedCommand(),
|
|
16499
|
+
dashboard: buildPaymentDashboardRecommendedCommand(),
|
|
16500
|
+
queue: buildPaymentQueueRecommendedCommand(),
|
|
16501
|
+
report: buildPaymentReportRecommendedCommand(),
|
|
16502
|
+
submit: buildPaymentSubmitRecommendedCommand(walletName),
|
|
16503
|
+
next: buildPaymentNextRecommendedCommand("<request-id>"),
|
|
16504
|
+
publish: buildPaymentPublishRecommendedCommand(),
|
|
16505
|
+
serve: buildPaymentServeRecommendedCommand()
|
|
16506
|
+
}
|
|
16507
|
+
};
|
|
16508
|
+
}
|
|
16509
|
+
function buildPublishedFeedPayload(feed) {
|
|
16510
|
+
const walletName = feed.filters.walletName || "main";
|
|
16511
|
+
return {
|
|
16512
|
+
ok: true,
|
|
16513
|
+
productLayer: buildAgentPayProductLayer("feed"),
|
|
16514
|
+
integrationLayer: buildAgentPayIntegrationLayer(),
|
|
16515
|
+
feed,
|
|
16516
|
+
recommendedCommands: {
|
|
16517
|
+
workspace: buildPaymentWorkspaceRecommendedCommand(),
|
|
16518
|
+
handoff: buildPaymentHandoffRecommendedCommand("<request-id>"),
|
|
16519
|
+
feed: buildPaymentFeedRecommendedCommand(),
|
|
16520
|
+
dashboard: buildPaymentDashboardRecommendedCommand(),
|
|
16521
|
+
queue: buildPaymentQueueRecommendedCommand(),
|
|
16522
|
+
report: buildPaymentReportRecommendedCommand(),
|
|
16523
|
+
submit: buildPaymentSubmitRecommendedCommand(walletName),
|
|
16524
|
+
publish: buildPaymentPublishRecommendedCommand(),
|
|
16525
|
+
serve: buildPaymentServeRecommendedCommand()
|
|
16526
|
+
}
|
|
16527
|
+
};
|
|
16528
|
+
}
|
|
16529
|
+
function buildPublishedHandoffPayload(input) {
|
|
16530
|
+
return {
|
|
16531
|
+
ok: true,
|
|
16532
|
+
requestId: input.paymentRequest.requestId,
|
|
16533
|
+
productLayer: buildAgentPayProductLayer("handoff"),
|
|
16534
|
+
integrationLayer: buildAgentPayIntegrationLayer(),
|
|
16535
|
+
handoff: input.handoff,
|
|
16536
|
+
recommendedCommands: {
|
|
16537
|
+
...buildPaymentRecommendedCommands(input.paymentRequest, input.executionPlan),
|
|
16538
|
+
publish: buildPaymentPublishRecommendedCommand(),
|
|
16539
|
+
serve: buildPaymentServeRecommendedCommand()
|
|
16540
|
+
}
|
|
16541
|
+
};
|
|
16542
|
+
}
|
|
15919
16543
|
function buildWorkspaceSurfaceHelpText(options) {
|
|
15920
16544
|
if (options.topLevel) {
|
|
15921
16545
|
return [
|
|
@@ -15923,6 +16547,10 @@ function buildWorkspaceSurfaceHelpText(options) {
|
|
|
15923
16547
|
" Public workspace shortcut:",
|
|
15924
16548
|
" Use this when you already know the current question is the cross-request Agent Pay workbench.",
|
|
15925
16549
|
" This is the top-level shortcut for `zk-agent payment workspace`.",
|
|
16550
|
+
" Today this same workspace -> handoff -> feed chain already gives one operator-controlled external export path.",
|
|
16551
|
+
" `zk-agent payment publish` now materializes that same workspace/feed/handoff bundle as a hostable static export.",
|
|
16552
|
+
" `zk-agent payment serve` now turns that same bundle into the current operator-controlled hosted preview.",
|
|
16553
|
+
" The next hosted step is to keep that served bundle stable behind one externally reachable operator URL without claiming a multi-tenant control plane yet.",
|
|
15926
16554
|
" Stay on `suite` when the question is broader than the Agent Pay workbench.",
|
|
15927
16555
|
" Stay on `payment next`, `approval`, or `handoff` when the question is still one request lifecycle.",
|
|
15928
16556
|
"",
|
|
@@ -15940,7 +16568,11 @@ function buildWorkspaceSurfaceHelpText(options) {
|
|
|
15940
16568
|
" Product workspace surface:",
|
|
15941
16569
|
" Use this when you need one cross-request Agent Pay workspace instead of stitching dashboard, queue, report, and feed together manually.",
|
|
15942
16570
|
" Public shortcut: zk-agent workspace.",
|
|
15943
|
-
" Shortest route into workspace: submit -> next -> approval -> workspace.",
|
|
16571
|
+
" Shortest route into workspace: submit -> payment next -> approval -> workspace.",
|
|
16572
|
+
" Today this same workspace -> handoff -> feed chain already gives one operator-controlled external export path.",
|
|
16573
|
+
" `zk-agent payment publish` now materializes that same workspace/feed/handoff bundle as a hostable static export.",
|
|
16574
|
+
" `zk-agent payment serve` now turns that same bundle into the current operator-controlled hosted preview.",
|
|
16575
|
+
" The next hosted step is to keep that served bundle stable behind one externally reachable operator URL without claiming a multi-tenant control plane yet.",
|
|
15944
16576
|
" Stay on `dashboard`, `queue`, `report`, or `feed` only when the workspace question has already narrowed to one slice.",
|
|
15945
16577
|
" Stay on `payment next`, `payment approval`, or `payment handoff` when the question is still one request lifecycle.",
|
|
15946
16578
|
"",
|
|
@@ -15999,6 +16631,7 @@ function addWorkspaceSurfaceCommand(command, options) {
|
|
|
15999
16631
|
{
|
|
16000
16632
|
ok: true,
|
|
16001
16633
|
productLayer: buildAgentPayProductLayer("workspace"),
|
|
16634
|
+
integrationLayer: buildAgentPayIntegrationLayer(),
|
|
16002
16635
|
workspace: {
|
|
16003
16636
|
...result.workspace,
|
|
16004
16637
|
queue: {
|
|
@@ -16212,6 +16845,7 @@ function paymentDashboardLines(dashboard) {
|
|
|
16212
16845
|
}
|
|
16213
16846
|
function paymentFeedLines(feed, options = {}) {
|
|
16214
16847
|
const productLayer = buildAgentPayProductLayer("feed");
|
|
16848
|
+
const integrationLayer = buildAgentPayIntegrationLayer();
|
|
16215
16849
|
const workspaceCommand = options.workspaceCommand ?? buildPaymentWorkspaceRecommendedCommand();
|
|
16216
16850
|
const feedCommand = options.feedCommand ?? buildPaymentFeedRecommendedCommand();
|
|
16217
16851
|
const lines = [
|
|
@@ -16220,6 +16854,15 @@ function paymentFeedLines(feed, options = {}) {
|
|
|
16220
16854
|
["surface role", productLayer.surfaceRole],
|
|
16221
16855
|
["platform direction", productLayer.platformDirection],
|
|
16222
16856
|
["boundary", productLayer.boundary],
|
|
16857
|
+
["integration stage", integrationLayer.stage],
|
|
16858
|
+
["integration mode", integrationLayer.currentMode],
|
|
16859
|
+
["integration proof", integrationLayer.currentProof],
|
|
16860
|
+
[
|
|
16861
|
+
"integration surfaces",
|
|
16862
|
+
`${integrationLayer.workbenchSurface} -> ${integrationLayer.singleRequestSurface} -> ${integrationLayer.batchSurface}`
|
|
16863
|
+
],
|
|
16864
|
+
["hosted direction", integrationLayer.nextHostedStep],
|
|
16865
|
+
["integration boundary", integrationLayer.boundary],
|
|
16223
16866
|
["generated", feed.generatedAt],
|
|
16224
16867
|
["source", feed.source],
|
|
16225
16868
|
["requests", String(feed.summary.totalRequests)],
|
|
@@ -16263,6 +16906,10 @@ function buildFeedSurfaceHelpText(options) {
|
|
|
16263
16906
|
" Public feed shortcut:",
|
|
16264
16907
|
" Use this when the current question is already the integration-ready cross-request Agent Pay export.",
|
|
16265
16908
|
" This is the top-level shortcut for `zk-agent payment feed`.",
|
|
16909
|
+
" This already works as the current operator-controlled external export proof on the same runtime or host.",
|
|
16910
|
+
" `zk-agent payment publish` now snapshots the same feed/handoff bundle as a hostable static export.",
|
|
16911
|
+
" `zk-agent payment serve` now turns that same bundle into the current operator-controlled hosted preview.",
|
|
16912
|
+
" The next hosted step is to keep that served bundle stable behind one externally reachable operator URL before claiming a control plane.",
|
|
16266
16913
|
" Stay on `workspace` when you still need the broader cross-request Agent Pay workbench.",
|
|
16267
16914
|
" Stay on `handoff` when the current question is still one single-request export.",
|
|
16268
16915
|
"",
|
|
@@ -16281,6 +16928,10 @@ function buildFeedSurfaceHelpText(options) {
|
|
|
16281
16928
|
" Integration-ready feed surface:",
|
|
16282
16929
|
" Use this when you need the stable cross-request Agent Pay batch export for dashboards, agents, or backend ingestion.",
|
|
16283
16930
|
" Public shortcut: zk-agent feed.",
|
|
16931
|
+
" This already works as the current operator-controlled external export proof on the same runtime or host.",
|
|
16932
|
+
" `zk-agent payment publish` now snapshots the same feed/handoff bundle as a hostable static export.",
|
|
16933
|
+
" `zk-agent payment serve` now turns that same bundle into the current operator-controlled hosted preview.",
|
|
16934
|
+
" The next hosted step is to keep that served bundle stable behind one externally reachable operator URL before claiming a control plane.",
|
|
16284
16935
|
" Stay on `payment workspace` when you still need the broader cross-request workbench first.",
|
|
16285
16936
|
" Stay on `payment handoff` when the current question is still one single-request export.",
|
|
16286
16937
|
"",
|
|
@@ -16324,6 +16975,7 @@ function addFeedSurfaceCommand(command, options) {
|
|
|
16324
16975
|
{
|
|
16325
16976
|
ok: true,
|
|
16326
16977
|
productLayer: buildAgentPayProductLayer("feed"),
|
|
16978
|
+
integrationLayer: buildAgentPayIntegrationLayer(),
|
|
16327
16979
|
feed: result.feed,
|
|
16328
16980
|
recommendedCommands: {
|
|
16329
16981
|
workspace: workspaceCommand,
|
|
@@ -16367,6 +17019,10 @@ function buildHandoffSurfaceHelpText(options) {
|
|
|
16367
17019
|
" Public handoff shortcut:",
|
|
16368
17020
|
" Use this when the current question is already the stable single-request Agent Pay export.",
|
|
16369
17021
|
" This is the top-level shortcut for `zk-agent payment handoff`.",
|
|
17022
|
+
" This is already the single-request export proof for the current operator-controlled hosted direction.",
|
|
17023
|
+
" `zk-agent payment publish` now snapshots this handoff alongside workspace/feed as a hostable static export bundle.",
|
|
17024
|
+
" `zk-agent payment serve` now turns that same bundle into the current operator-controlled hosted preview.",
|
|
17025
|
+
" The next hosted step is to keep that served bundle stable behind one externally reachable operator URL before claiming a control plane.",
|
|
16370
17026
|
" Stay on `workspace` when you still need the broader cross-request Agent Pay workbench.",
|
|
16371
17027
|
" Stay on `feed` when the current question has already widened to the cross-request batch export.",
|
|
16372
17028
|
"",
|
|
@@ -16385,6 +17041,10 @@ function buildHandoffSurfaceHelpText(options) {
|
|
|
16385
17041
|
" Integration-ready handoff surface:",
|
|
16386
17042
|
" Use this when you need one stable local-first Agent Pay export bundle for an external dashboard, agent, or backend.",
|
|
16387
17043
|
" Public shortcut: zk-agent handoff.",
|
|
17044
|
+
" This is already the single-request export proof for the current operator-controlled hosted direction.",
|
|
17045
|
+
" `zk-agent payment publish` now snapshots this handoff alongside workspace/feed as a hostable static export bundle.",
|
|
17046
|
+
" `zk-agent payment serve` now turns that same bundle into the current operator-controlled hosted preview.",
|
|
17047
|
+
" The next hosted step is to keep that served bundle stable behind one externally reachable operator URL before claiming a control plane.",
|
|
16388
17048
|
" Stay on `payment inspect` when you still need the broader single-request aggregate view.",
|
|
16389
17049
|
" Stay on `payment share` or `payment parties` when the question has already narrowed to one projection.",
|
|
16390
17050
|
"",
|
|
@@ -16412,6 +17072,7 @@ async function executePaymentHandoffSurface(requestId, topLevel) {
|
|
|
16412
17072
|
ok: true,
|
|
16413
17073
|
requestId: result.paymentRequest.requestId,
|
|
16414
17074
|
productLayer: buildAgentPayProductLayer("handoff"),
|
|
17075
|
+
integrationLayer: buildAgentPayIntegrationLayer(),
|
|
16415
17076
|
handoff: result.handoff,
|
|
16416
17077
|
recommendedCommands: buildPaymentRecommendedCommands(
|
|
16417
17078
|
result.paymentRequest,
|
|
@@ -16720,7 +17381,10 @@ function createPaymentCommand() {
|
|
|
16720
17381
|
" `workspace`: review the cross-request operator view.",
|
|
16721
17382
|
" `handoff`: export one stable single-request integration bundle.",
|
|
16722
17383
|
" `feed`: export the stable cross-request batch view.",
|
|
16723
|
-
"
|
|
17384
|
+
" `publish`: materialize the same stable workspace/feed/handoff bundle as a hostable static export.",
|
|
17385
|
+
" `serve`: host that same bundle from one operator-controlled endpoint.",
|
|
17386
|
+
" If you only remember one route: submit -> payment next -> approval -> workspace -> handoff -> feed.",
|
|
17387
|
+
" Current public hosted proof: publish -> serve the same workspace/feed/handoff bundle behind one operator-controlled URL.",
|
|
16724
17388
|
"",
|
|
16725
17389
|
" Payment request surface:",
|
|
16726
17390
|
" Use this layer when execution is not the whole story and you need request capture, follow-up, sharing, reporting, or approval repair around the write path.",
|
|
@@ -16745,13 +17409,21 @@ function createPaymentCommand() {
|
|
|
16745
17409
|
" zk-agent workspace",
|
|
16746
17410
|
" zk-agent handoff --request-id <id>",
|
|
16747
17411
|
" zk-agent feed",
|
|
17412
|
+
" zk-agent payment publish --public-base-url <https-url>",
|
|
17413
|
+
" zk-agent payment serve --public-origin <https-url>",
|
|
16748
17414
|
" This proves compact ingress -> wallet-aware follow-up -> approval readiness -> cross-request workspace -> integration-ready export.",
|
|
17415
|
+
" `payment publish` turns those same exports into one static bundle that can be hosted by the operator.",
|
|
17416
|
+
" `payment serve` turns that same bundle into the current operator-controlled hosted preview.",
|
|
17417
|
+
" Together, publish -> serve is the current public Agent Pay proof on the hosted-preview boundary.",
|
|
17418
|
+
" The next hosted step is to keep that served bundle stable behind one externally reachable operator URL before claiming a multi-tenant control plane.",
|
|
16749
17419
|
"",
|
|
16750
17420
|
" Public start here:",
|
|
16751
17421
|
" zk-agent submit --wallet main --to <address> --amount <amount>",
|
|
16752
17422
|
" zk-agent workspace",
|
|
16753
17423
|
" zk-agent handoff --request-id <id>",
|
|
16754
17424
|
" zk-agent feed",
|
|
17425
|
+
" zk-agent payment publish --public-base-url <https-url>",
|
|
17426
|
+
" zk-agent payment serve --public-origin <https-url>",
|
|
16755
17427
|
" zk-agent approval --request-id <id>",
|
|
16756
17428
|
" zk-agent payment next --request-id <id>",
|
|
16757
17429
|
"",
|
|
@@ -16759,6 +17431,8 @@ function createPaymentCommand() {
|
|
|
16759
17431
|
" zk-agent payment dashboard",
|
|
16760
17432
|
" zk-agent payment queue",
|
|
16761
17433
|
" zk-agent payment report",
|
|
17434
|
+
" zk-agent payment publish",
|
|
17435
|
+
" zk-agent payment serve",
|
|
16762
17436
|
" zk-agent payment sync-approval --request-id <id>",
|
|
16763
17437
|
" zk-agent payment inspect --request-id <id>",
|
|
16764
17438
|
" zk-agent payment parties --request-id <id>",
|
|
@@ -16770,6 +17444,8 @@ function createPaymentCommand() {
|
|
|
16770
17444
|
" `dashboard`: what is the current dashboard summary across requests?",
|
|
16771
17445
|
" `handoff`: what is the stable single-request integration bundle?",
|
|
16772
17446
|
" `feed`: what is the stable cross-request integration feed?",
|
|
17447
|
+
" `publish`: what is the hostable static export bundle for the current Agent Pay surface?",
|
|
17448
|
+
" `serve`: what is the operator-controlled hosted preview for the current Agent Pay surface?",
|
|
16773
17449
|
" `suite`: I still need the packaged catalog across requests, discovery, funding, paymaster, and remote recovery.",
|
|
16774
17450
|
"",
|
|
16775
17451
|
" Deeper per-request reads and writes:",
|
|
@@ -16800,6 +17476,8 @@ function createPaymentCommand() {
|
|
|
16800
17476
|
" zk-agent feed",
|
|
16801
17477
|
" zk-agent payment queue",
|
|
16802
17478
|
" zk-agent payment report",
|
|
17479
|
+
" zk-agent payment publish",
|
|
17480
|
+
" zk-agent payment serve",
|
|
16803
17481
|
" zk-agent approval --request-id <id>",
|
|
16804
17482
|
" zk-agent payment sync-approval --request-id <id>",
|
|
16805
17483
|
" zk-agent payment list",
|
|
@@ -16939,6 +17617,157 @@ function createPaymentCommand() {
|
|
|
16939
17617
|
}
|
|
16940
17618
|
)
|
|
16941
17619
|
);
|
|
17620
|
+
payment.command("publish").description(
|
|
17621
|
+
"Materialize the current Agent Pay workspace/feed/handoff bundle as a hostable static export"
|
|
17622
|
+
).option("--wallet <name>", "Optional payer wallet filter").option(
|
|
17623
|
+
"--status <status>",
|
|
17624
|
+
"Optional status filter: draft, approval_pending, ready, paid, failed, expired, or cancelled"
|
|
17625
|
+
).option("--queue-limit <count>", "Optional maximum number of queue items to include in workspace.json").option("--wallet-limit <count>", "Optional maximum number of wallet summaries in workspace.json").option("--activity-limit <count>", "Optional recent-activity limit in workspace.json").option("--feed-limit <count>", "Optional maximum number of feed items in workspace.json and feed.json").option("--dir <path>", "Optional explicit output directory for the static export bundle").option(
|
|
17626
|
+
"--public-base-url <url>",
|
|
17627
|
+
"Optional absolute public base URL used to precompute public artifact URLs in the manifest"
|
|
17628
|
+
).addHelpText(
|
|
17629
|
+
"after",
|
|
17630
|
+
[
|
|
17631
|
+
"",
|
|
17632
|
+
" Hosted static export surface:",
|
|
17633
|
+
" Use this when the current Agent Pay question is no longer just local inspection and you need one hostable static bundle.",
|
|
17634
|
+
" This command writes `index.html`, `manifest.json`, `workspace.json`, `feed.json`, and one `handoffs/<request-id>.json` file per matching request.",
|
|
17635
|
+
" This is the static half of the current public Agent Pay proof.",
|
|
17636
|
+
" It does not start a service or claim a hosted multi-tenant control plane.",
|
|
17637
|
+
" Pass `--public-base-url` when you already know where the bundle will be hosted and you want absolute artifact URLs in the manifest.",
|
|
17638
|
+
"",
|
|
17639
|
+
" Common commands:",
|
|
17640
|
+
` ${buildPaymentPublishRecommendedCommand()}`,
|
|
17641
|
+
" zk-agent payment publish --wallet main --public-base-url <https-url>",
|
|
17642
|
+
" zk-agent payment workspace",
|
|
17643
|
+
" zk-agent payment handoff --request-id <id>",
|
|
17644
|
+
" zk-agent payment feed"
|
|
17645
|
+
].join("\n")
|
|
17646
|
+
).action(async (options) => {
|
|
17647
|
+
const selection = resolvePaymentPublishSelection(options);
|
|
17648
|
+
const publicBaseUrl = resolvePaymentPublishPublicBaseUrl(options.publicBaseUrl);
|
|
17649
|
+
const data = await loadPaymentPublishData({
|
|
17650
|
+
...selection,
|
|
17651
|
+
dir: options.dir
|
|
17652
|
+
});
|
|
17653
|
+
const bundle = buildPaymentPublishBundle({
|
|
17654
|
+
data,
|
|
17655
|
+
publicBaseUrl
|
|
17656
|
+
});
|
|
17657
|
+
await writePaymentPublishBundle(bundle);
|
|
17658
|
+
printResult(paymentPublishLines({ manifest: bundle.manifest, outputDir: bundle.outputDir }), {
|
|
17659
|
+
ok: true,
|
|
17660
|
+
...buildPaymentPublishPayload(bundle),
|
|
17661
|
+
recommendedCommands: {
|
|
17662
|
+
publish: buildPaymentPublishRecommendedCommand(),
|
|
17663
|
+
serve: buildPaymentServeRecommendedCommand(),
|
|
17664
|
+
workspace: buildPaymentWorkspaceRecommendedCommand(),
|
|
17665
|
+
handoff: buildPaymentHandoffRecommendedCommand("<request-id>"),
|
|
17666
|
+
feed: buildPaymentFeedRecommendedCommand()
|
|
17667
|
+
}
|
|
17668
|
+
});
|
|
17669
|
+
});
|
|
17670
|
+
payment.command("serve").description(
|
|
17671
|
+
"Serve the current Agent Pay workspace/feed/handoff bundle from one operator-controlled static endpoint"
|
|
17672
|
+
).option("--wallet <name>", "Optional payer wallet filter").option(
|
|
17673
|
+
"--status <status>",
|
|
17674
|
+
"Optional status filter: draft, approval_pending, ready, paid, failed, expired, or cancelled"
|
|
17675
|
+
).option("--queue-limit <count>", "Optional maximum number of queue items to include in workspace.json").option("--wallet-limit <count>", "Optional maximum number of wallet summaries in workspace.json").option("--activity-limit <count>", "Optional recent-activity limit in workspace.json").option("--feed-limit <count>", "Optional maximum number of feed items in workspace.json and feed.json").option("--dir <path>", "Optional explicit output directory for the static export bundle").option("--host <host>", "Host to bind", "127.0.0.1").option("--port <port>", "Port to bind (0 = choose a free port)", "4495").option(
|
|
17676
|
+
"--public-origin <url>",
|
|
17677
|
+
"Optional absolute public origin to advertise when this static bundle is behind a tunnel or reverse proxy"
|
|
17678
|
+
).addHelpText(
|
|
17679
|
+
"after",
|
|
17680
|
+
[
|
|
17681
|
+
"",
|
|
17682
|
+
" Hosted preview surface:",
|
|
17683
|
+
" Use this when the static Agent Pay bundle is no longer enough on disk and you need one operator-controlled hosted endpoint.",
|
|
17684
|
+
" This command regenerates the same `index.html`, `manifest.json`, `workspace.json`, `feed.json`, and `handoffs/<request-id>.json` bundle before serving it.",
|
|
17685
|
+
" This is the hosted half of the current public Agent Pay proof.",
|
|
17686
|
+
" Pass `--public-origin` when the bind origin is not the externally reachable URL.",
|
|
17687
|
+
"",
|
|
17688
|
+
" Common commands:",
|
|
17689
|
+
` ${buildPaymentServeRecommendedCommand()}`,
|
|
17690
|
+
" zk-agent payment serve --public-origin <https-url>",
|
|
17691
|
+
" zk-agent payment publish --public-base-url <https-url>",
|
|
17692
|
+
" zk-agent workspace",
|
|
17693
|
+
" zk-agent feed"
|
|
17694
|
+
].join("\n")
|
|
17695
|
+
).action(async (options) => {
|
|
17696
|
+
const selection = resolvePaymentPublishSelection(options);
|
|
17697
|
+
const host = options.host?.trim() || "127.0.0.1";
|
|
17698
|
+
const port = resolvePaymentServePort(options.port);
|
|
17699
|
+
const data = await loadPaymentPublishData({
|
|
17700
|
+
...selection,
|
|
17701
|
+
dir: options.dir
|
|
17702
|
+
});
|
|
17703
|
+
let origin = "";
|
|
17704
|
+
let publicOrigin = "";
|
|
17705
|
+
const server = await startStaticServer({
|
|
17706
|
+
rootDir: data.outputDir,
|
|
17707
|
+
host,
|
|
17708
|
+
port,
|
|
17709
|
+
healthPayload: () => ({
|
|
17710
|
+
ok: true,
|
|
17711
|
+
service: "zk-agent-payment-static",
|
|
17712
|
+
mode: "operator-controlled-static-export",
|
|
17713
|
+
origin,
|
|
17714
|
+
publicOrigin,
|
|
17715
|
+
outputDir: data.outputDir
|
|
17716
|
+
})
|
|
17717
|
+
});
|
|
17718
|
+
origin = server.origin;
|
|
17719
|
+
publicOrigin = resolvePaymentServePublicOrigin(options.publicOrigin) || server.origin;
|
|
17720
|
+
const publicOriginSource = options.publicOrigin?.trim() ? "configured" : "bind-origin-default";
|
|
17721
|
+
const publicOriginLooksLocal = paymentPublicOriginLooksLocal(publicOrigin);
|
|
17722
|
+
const bundle = buildPaymentPublishBundle({
|
|
17723
|
+
data,
|
|
17724
|
+
publicBaseUrl: publicOrigin
|
|
17725
|
+
});
|
|
17726
|
+
await writePaymentPublishBundle(bundle);
|
|
17727
|
+
const recommendedCommands = buildPaymentServeRecommendedCommands({
|
|
17728
|
+
publicOriginLooksLocal
|
|
17729
|
+
});
|
|
17730
|
+
const notes = buildPaymentServeNotes({
|
|
17731
|
+
publicOrigin,
|
|
17732
|
+
publicOriginLooksLocal
|
|
17733
|
+
});
|
|
17734
|
+
printResult(
|
|
17735
|
+
paymentServeLines({
|
|
17736
|
+
origin,
|
|
17737
|
+
publicOrigin,
|
|
17738
|
+
publicOriginSource,
|
|
17739
|
+
bundle
|
|
17740
|
+
}),
|
|
17741
|
+
{
|
|
17742
|
+
ok: true,
|
|
17743
|
+
status: "payment-serving",
|
|
17744
|
+
origin,
|
|
17745
|
+
publicOrigin,
|
|
17746
|
+
publicOriginSource,
|
|
17747
|
+
publicOriginLooksLocal,
|
|
17748
|
+
port: server.port,
|
|
17749
|
+
outputDir: bundle.outputDir,
|
|
17750
|
+
healthUrl: `${origin}/health`,
|
|
17751
|
+
publicHealthUrl: `${publicOrigin}/health`,
|
|
17752
|
+
...buildPaymentPublishPayload(bundle),
|
|
17753
|
+
recommendedCommands,
|
|
17754
|
+
notes
|
|
17755
|
+
}
|
|
17756
|
+
);
|
|
17757
|
+
const shutdown = async () => {
|
|
17758
|
+
process.off("SIGINT", handleSignal);
|
|
17759
|
+
process.off("SIGTERM", handleSignal);
|
|
17760
|
+
await server.close();
|
|
17761
|
+
process.exit(0);
|
|
17762
|
+
};
|
|
17763
|
+
const handleSignal = () => {
|
|
17764
|
+
void shutdown();
|
|
17765
|
+
};
|
|
17766
|
+
process.on("SIGINT", handleSignal);
|
|
17767
|
+
process.on("SIGTERM", handleSignal);
|
|
17768
|
+
await new Promise(() => {
|
|
17769
|
+
});
|
|
17770
|
+
});
|
|
16942
17771
|
payment.command("queue").description(
|
|
16943
17772
|
"Build the wallet-aware queue slice inside the cross-request Agent Pay workspace"
|
|
16944
17773
|
).option("--wallet <name>", "Optional payer wallet filter").option(
|
|
@@ -18092,9 +18921,11 @@ function buildOperatorSuitePayload(options = {}) {
|
|
|
18092
18921
|
productClaim: "flagship pay, Agent Pay request routing, and hosted approval recovery already read like one product shell",
|
|
18093
18922
|
flagshipSurface: publicFlagshipCommand,
|
|
18094
18923
|
agentPaySurface: `${publicPaymentCommand} -> ${buildApprovalRecommendedCommand("<request-id>")} -> ${publicWorkspaceCommand} -> ${publicHandoffCommand} -> ${publicFeedCommand}`,
|
|
18924
|
+
agentPayExportSurface: `${publicWorkspaceCommand} -> ${publicHandoffCommand} -> ${publicFeedCommand}`,
|
|
18095
18925
|
hostedRecoverySurface: hostedRelayBaselineCommand,
|
|
18096
18926
|
proofSurfaceIds: proofPaths.map((entry) => entry.id),
|
|
18097
|
-
|
|
18927
|
+
hostedDirection: "current public proof is to publish and serve the stable workspace/feed/handoff bundle behind one operator-controlled hosted endpoint instead of claiming a multi-tenant control plane",
|
|
18928
|
+
nextMaturityTarget: "prove the hosted Agent Pay bundle repeatedly behind one externally reachable operator URL",
|
|
18098
18929
|
boundary: "local-first by default today; Agent Pay is not yet a hosted multi-tenant control plane"
|
|
18099
18930
|
};
|
|
18100
18931
|
return {
|
|
@@ -18255,8 +19086,10 @@ function operatorSuiteLines(payload) {
|
|
|
18255
19086
|
["platform claim", payload.platformLayer.productClaim],
|
|
18256
19087
|
["platform flagship surface", payload.platformLayer.flagshipSurface],
|
|
18257
19088
|
["platform agent pay surface", payload.platformLayer.agentPaySurface],
|
|
19089
|
+
["platform agent pay export surface", payload.platformLayer.agentPayExportSurface],
|
|
18258
19090
|
["platform hosted recovery surface", payload.platformLayer.hostedRecoverySurface],
|
|
18259
19091
|
["platform proof surfaces", payload.platformLayer.proofSurfaceIds.join(" -> ")],
|
|
19092
|
+
["platform hosted direction", payload.platformLayer.hostedDirection],
|
|
18260
19093
|
["platform next maturity", payload.platformLayer.nextMaturityTarget],
|
|
18261
19094
|
["platform boundary", payload.platformLayer.boundary],
|
|
18262
19095
|
["entry modes", payload.summary.entryModes.join(" -> ")],
|
|
@@ -18328,7 +19161,7 @@ function createSuiteCommand() {
|
|
|
18328
19161
|
"",
|
|
18329
19162
|
" Most common product journeys:",
|
|
18330
19163
|
" send value now: go straight to the flagship pay path",
|
|
18331
|
-
" capture and track payments: follow submit -> next -> approval -> workspace -> handoff -> feed",
|
|
19164
|
+
" capture and track payments: follow submit -> payment next -> approval -> workspace -> handoff -> feed",
|
|
18332
19165
|
" inspect before acting: open assets/defaults/token inspection first",
|
|
18333
19166
|
" unstick a write: recover paymaster/funding readiness on the workflow path",
|
|
18334
19167
|
" recover remote approval: move approval to the hosted relay path",
|
|
@@ -18339,7 +19172,13 @@ function createSuiteCommand() {
|
|
|
18339
19172
|
" `workspace`: review the cross-request operator surface",
|
|
18340
19173
|
" `handoff`: export one stable single-request bundle",
|
|
18341
19174
|
" `feed`: export the stable cross-request batch view",
|
|
18342
|
-
" shortest tracked route: submit -> next -> approval -> workspace -> handoff -> feed",
|
|
19175
|
+
" shortest tracked route: submit -> payment next -> approval -> workspace -> handoff -> feed",
|
|
19176
|
+
"",
|
|
19177
|
+
" Hosted/platform direction inside suite:",
|
|
19178
|
+
" current export proof: zk-agent workspace -> zk-agent handoff --request-id <id> -> zk-agent feed",
|
|
19179
|
+
` hostable bundle: ${buildPaymentPublishRecommendedCommand()} --public-base-url <https-url>`,
|
|
19180
|
+
" current public hosted proof: zk-agent payment publish --public-base-url <https-url> -> zk-agent payment serve --public-origin <https-url>",
|
|
19181
|
+
" next hosted step: keep one served bundle stable behind one externally reachable operator URL before claiming a multi-tenant control plane",
|
|
18343
19182
|
"",
|
|
18344
19183
|
" If you only need one default starting point inside suite:",
|
|
18345
19184
|
" send value now",
|
|
@@ -18744,16 +19583,16 @@ function normalizeRole2(value) {
|
|
|
18744
19583
|
import { Command as Command11 } from "commander";
|
|
18745
19584
|
|
|
18746
19585
|
// src/lib/relay.ts
|
|
18747
|
-
import { createServer } from "node:http";
|
|
19586
|
+
import { createServer as createServer2 } from "node:http";
|
|
18748
19587
|
import fs7 from "node:fs";
|
|
18749
|
-
import
|
|
19588
|
+
import path9 from "node:path";
|
|
18750
19589
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
18751
19590
|
|
|
18752
19591
|
// src/lib/http.ts
|
|
18753
19592
|
import { spawn } from "node:child_process";
|
|
18754
|
-
import { mkdtemp, readFile as
|
|
19593
|
+
import { mkdtemp, readFile as readFile3, rm as rm3 } from "node:fs/promises";
|
|
18755
19594
|
import os2 from "node:os";
|
|
18756
|
-
import
|
|
19595
|
+
import path8 from "node:path";
|
|
18757
19596
|
function isDnsResolutionFailure(error) {
|
|
18758
19597
|
if (!error || typeof error !== "object") {
|
|
18759
19598
|
return false;
|
|
@@ -18792,9 +19631,9 @@ function parseCurlHeaders(rawHeaders) {
|
|
|
18792
19631
|
return { status, headers };
|
|
18793
19632
|
}
|
|
18794
19633
|
async function runCurlRequest(url, options) {
|
|
18795
|
-
const tempDir = await mkdtemp(
|
|
18796
|
-
const headersPath =
|
|
18797
|
-
const bodyPath =
|
|
19634
|
+
const tempDir = await mkdtemp(path8.join(os2.tmpdir(), "zk-agent-http-"));
|
|
19635
|
+
const headersPath = path8.join(tempDir, "headers.txt");
|
|
19636
|
+
const bodyPath = path8.join(tempDir, "body.txt");
|
|
18798
19637
|
try {
|
|
18799
19638
|
const args = [
|
|
18800
19639
|
"--silent",
|
|
@@ -18838,8 +19677,8 @@ async function runCurlRequest(url, options) {
|
|
|
18838
19677
|
throw new Error(stderr.trim() || stdout.trim() || `curl exited with code ${exitCode}`);
|
|
18839
19678
|
}
|
|
18840
19679
|
const [rawHeaders, body] = await Promise.all([
|
|
18841
|
-
|
|
18842
|
-
|
|
19680
|
+
readFile3(headersPath, "utf8"),
|
|
19681
|
+
readFile3(bodyPath, "utf8")
|
|
18843
19682
|
]);
|
|
18844
19683
|
const { status, headers } = parseCurlHeaders(rawHeaders);
|
|
18845
19684
|
return {
|
|
@@ -18849,7 +19688,7 @@ async function runCurlRequest(url, options) {
|
|
|
18849
19688
|
body
|
|
18850
19689
|
};
|
|
18851
19690
|
} finally {
|
|
18852
|
-
await
|
|
19691
|
+
await rm3(tempDir, { recursive: true, force: true });
|
|
18853
19692
|
}
|
|
18854
19693
|
}
|
|
18855
19694
|
async function fetchTextWithFallback(url, options = {}) {
|
|
@@ -18889,14 +19728,14 @@ var RELAY_SCHEMA_VERSION = 1;
|
|
|
18889
19728
|
var RELAY_STATE_BACKEND = "local-filesystem";
|
|
18890
19729
|
var RELAY_DEPLOYMENT_SCOPE = "single-host";
|
|
18891
19730
|
function relayDir() {
|
|
18892
|
-
const directory =
|
|
19731
|
+
const directory = path9.join(storageDir(), "relay");
|
|
18893
19732
|
if (!fs7.existsSync(directory)) {
|
|
18894
19733
|
fs7.mkdirSync(directory, { recursive: true, mode: 448 });
|
|
18895
19734
|
}
|
|
18896
19735
|
return directory;
|
|
18897
19736
|
}
|
|
18898
19737
|
function relayRecordPath(requestId) {
|
|
18899
|
-
return
|
|
19738
|
+
return path9.join(relayDir(), `${requestId}.json`);
|
|
18900
19739
|
}
|
|
18901
19740
|
function writeRelayRecord(record) {
|
|
18902
19741
|
fs7.writeFileSync(relayRecordPath(record.request_id), JSON.stringify(record, null, 2), {
|
|
@@ -18964,14 +19803,14 @@ function readRequestBody(request, limitBytes = RELAY_BODY_LIMIT_BYTES) {
|
|
|
18964
19803
|
request.once("error", reject);
|
|
18965
19804
|
});
|
|
18966
19805
|
}
|
|
18967
|
-
function
|
|
18968
|
-
|
|
19806
|
+
function writeJson3(response, statusCode, payload) {
|
|
19807
|
+
writeBody2(response, statusCode, "application/json; charset=utf-8", JSON.stringify(payload, null, 2), {
|
|
18969
19808
|
"Access-Control-Allow-Origin": "*",
|
|
18970
19809
|
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
|
|
18971
19810
|
"Access-Control-Allow-Headers": "Content-Type"
|
|
18972
19811
|
});
|
|
18973
19812
|
}
|
|
18974
|
-
function
|
|
19813
|
+
function writeBody2(response, statusCode, contentType, value, extraHeaders = {}) {
|
|
18975
19814
|
response.statusCode = statusCode;
|
|
18976
19815
|
response.setHeader("Content-Type", contentType);
|
|
18977
19816
|
response.setHeader("Content-Length", Buffer.isBuffer(value) ? String(value.byteLength) : String(Buffer.byteLength(value)));
|
|
@@ -18982,20 +19821,20 @@ function writeBody(response, statusCode, contentType, value, extraHeaders = {})
|
|
|
18982
19821
|
}
|
|
18983
19822
|
function resolveConnectorUiDistRoot() {
|
|
18984
19823
|
const currentFile = fileURLToPath3(import.meta.url);
|
|
18985
|
-
const currentDir2 =
|
|
19824
|
+
const currentDir2 = path9.dirname(currentFile);
|
|
18986
19825
|
const candidates = [
|
|
18987
|
-
|
|
18988
|
-
|
|
18989
|
-
|
|
19826
|
+
path9.resolve(currentDir2, "./connector-ui"),
|
|
19827
|
+
path9.resolve(currentDir2, "../../../zk-connector-ui/dist"),
|
|
19828
|
+
path9.resolve(currentDir2, "../../zk-connector-ui/dist")
|
|
18990
19829
|
];
|
|
18991
19830
|
for (const candidate of candidates) {
|
|
18992
|
-
if (fs7.existsSync(
|
|
19831
|
+
if (fs7.existsSync(path9.join(candidate, "index.html"))) {
|
|
18993
19832
|
return candidate;
|
|
18994
19833
|
}
|
|
18995
19834
|
}
|
|
18996
19835
|
return null;
|
|
18997
19836
|
}
|
|
18998
|
-
function
|
|
19837
|
+
function contentTypeFor2(filePath) {
|
|
18999
19838
|
if (filePath.endsWith(".html")) return "text/html; charset=utf-8";
|
|
19000
19839
|
if (filePath.endsWith(".js")) return "text/javascript; charset=utf-8";
|
|
19001
19840
|
if (filePath.endsWith(".css")) return "text/css; charset=utf-8";
|
|
@@ -19107,18 +19946,18 @@ async function startRelayServer(options) {
|
|
|
19107
19946
|
const uiDistRoot = resolveConnectorUiDistRoot();
|
|
19108
19947
|
let bindBaseUrl = "";
|
|
19109
19948
|
const publicOriginSource = options.publicOrigin?.trim() ? "configured" : "bind-origin-default";
|
|
19110
|
-
const server =
|
|
19949
|
+
const server = createServer2(async (request, response) => {
|
|
19111
19950
|
try {
|
|
19112
19951
|
const requestUrl = new URL(request.url || "/", "http://localhost");
|
|
19113
19952
|
const pathname = requestUrl.pathname;
|
|
19114
19953
|
const method = request.method || "GET";
|
|
19115
19954
|
const publicBaseUrl = resolveRelayPublicBaseUrl(bindBaseUrl, options.publicOrigin);
|
|
19116
19955
|
if (method === "OPTIONS") {
|
|
19117
|
-
|
|
19956
|
+
writeJson3(response, 204, {});
|
|
19118
19957
|
return;
|
|
19119
19958
|
}
|
|
19120
19959
|
if (method === "GET" && pathname === "/health") {
|
|
19121
|
-
|
|
19960
|
+
writeJson3(
|
|
19122
19961
|
response,
|
|
19123
19962
|
200,
|
|
19124
19963
|
relayHealthResponse(
|
|
@@ -19141,7 +19980,7 @@ async function startRelayServer(options) {
|
|
|
19141
19980
|
request: body.request
|
|
19142
19981
|
};
|
|
19143
19982
|
writeRelayRecord(record);
|
|
19144
|
-
|
|
19983
|
+
writeJson3(response, existing ? 200 : 201, {
|
|
19145
19984
|
request_id: record.request_id,
|
|
19146
19985
|
status: relayStatus(record),
|
|
19147
19986
|
share_url: relayShareUrl(publicBaseUrl, record.request_id),
|
|
@@ -19154,33 +19993,33 @@ async function startRelayServer(options) {
|
|
|
19154
19993
|
if (requestMatch && method === "GET") {
|
|
19155
19994
|
const record = loadRelayRecord(requestMatch[1]);
|
|
19156
19995
|
if (!record) {
|
|
19157
|
-
|
|
19996
|
+
writeJson3(response, 404, { error: `Relay request not found: ${requestMatch[1]}` });
|
|
19158
19997
|
return;
|
|
19159
19998
|
}
|
|
19160
|
-
|
|
19999
|
+
writeJson3(response, 200, relayStatusResponse(publicBaseUrl, record));
|
|
19161
20000
|
return;
|
|
19162
20001
|
}
|
|
19163
20002
|
const approvalMatch = pathname.match(/^\/api\/requests\/([^/]+)\/approval$/);
|
|
19164
20003
|
if (approvalMatch && method === "GET") {
|
|
19165
20004
|
const record = loadRelayRecord(approvalMatch[1]);
|
|
19166
20005
|
if (!record) {
|
|
19167
|
-
|
|
20006
|
+
writeJson3(response, 404, { error: `Relay request not found: ${approvalMatch[1]}` });
|
|
19168
20007
|
return;
|
|
19169
20008
|
}
|
|
19170
|
-
|
|
20009
|
+
writeJson3(response, 200, relayApprovalResponse(record));
|
|
19171
20010
|
return;
|
|
19172
20011
|
}
|
|
19173
20012
|
if (approvalMatch && method === "POST") {
|
|
19174
20013
|
const record = loadRelayRecord(approvalMatch[1]);
|
|
19175
20014
|
if (!record) {
|
|
19176
|
-
|
|
20015
|
+
writeJson3(response, 404, { error: `Relay request not found: ${approvalMatch[1]}` });
|
|
19177
20016
|
return;
|
|
19178
20017
|
}
|
|
19179
20018
|
const body = JSON.parse(await readRequestBody(request));
|
|
19180
20019
|
record.encrypted_payload = body.encrypted_payload;
|
|
19181
20020
|
record.approval_submitted_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
19182
20021
|
writeRelayRecord(record);
|
|
19183
|
-
|
|
20022
|
+
writeJson3(response, 200, relayApprovalResponse(record));
|
|
19184
20023
|
return;
|
|
19185
20024
|
}
|
|
19186
20025
|
const shareMatch = pathname.match(/^\/r\/([^/]+)$/);
|
|
@@ -19195,24 +20034,24 @@ async function startRelayServer(options) {
|
|
|
19195
20034
|
}
|
|
19196
20035
|
if (method === "GET" && uiDistRoot) {
|
|
19197
20036
|
const relativePath = pathname === "/" ? "/index.html" : pathname;
|
|
19198
|
-
const filePath =
|
|
20037
|
+
const filePath = path9.resolve(uiDistRoot, `.${relativePath}`);
|
|
19199
20038
|
if (!filePath.startsWith(uiDistRoot)) {
|
|
19200
|
-
|
|
20039
|
+
writeJson3(response, 403, { error: "Forbidden path" });
|
|
19201
20040
|
return;
|
|
19202
20041
|
}
|
|
19203
20042
|
if (fs7.existsSync(filePath) && fs7.statSync(filePath).isFile()) {
|
|
19204
|
-
|
|
20043
|
+
writeBody2(response, 200, contentTypeFor2(filePath), fs7.readFileSync(filePath));
|
|
19205
20044
|
return;
|
|
19206
20045
|
}
|
|
19207
|
-
const indexPath =
|
|
20046
|
+
const indexPath = path9.join(uiDistRoot, "index.html");
|
|
19208
20047
|
if (fs7.existsSync(indexPath)) {
|
|
19209
|
-
|
|
20048
|
+
writeBody2(response, 200, "text/html; charset=utf-8", fs7.readFileSync(indexPath));
|
|
19210
20049
|
return;
|
|
19211
20050
|
}
|
|
19212
20051
|
}
|
|
19213
|
-
|
|
20052
|
+
writeJson3(response, 404, { error: `Relay route not found: ${pathname}` });
|
|
19214
20053
|
} catch (error) {
|
|
19215
|
-
|
|
20054
|
+
writeJson3(response, 500, {
|
|
19216
20055
|
error: error instanceof Error ? error.message : String(error)
|
|
19217
20056
|
});
|
|
19218
20057
|
}
|
|
@@ -20044,18 +20883,18 @@ function createRelayCommand() {
|
|
|
20044
20883
|
}
|
|
20045
20884
|
|
|
20046
20885
|
// src/commands/wallet.ts
|
|
20047
|
-
import { createServer as
|
|
20886
|
+
import { createServer as createServer3 } from "node:http";
|
|
20048
20887
|
import { createInterface } from "node:readline/promises";
|
|
20049
20888
|
import { Command as Command12 } from "commander";
|
|
20050
20889
|
|
|
20051
20890
|
// ../account-profiles/src/profiles.ts
|
|
20052
20891
|
import fs8 from "node:fs";
|
|
20053
|
-
import
|
|
20892
|
+
import path10 from "node:path";
|
|
20054
20893
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
20055
20894
|
var PACKAGE_NAME = "@zk-agent/account-profiles";
|
|
20056
20895
|
var PACKAGE_ROOT_FALLBACK = `<${PACKAGE_NAME} package root unavailable>`;
|
|
20057
20896
|
function isExpectedPackageRoot(candidate) {
|
|
20058
|
-
const manifestPath =
|
|
20897
|
+
const manifestPath = path10.join(candidate, "package.json");
|
|
20059
20898
|
if (!fs8.existsSync(manifestPath)) return false;
|
|
20060
20899
|
try {
|
|
20061
20900
|
const manifest = JSON.parse(fs8.readFileSync(manifestPath, "utf8"));
|
|
@@ -20065,19 +20904,19 @@ function isExpectedPackageRoot(candidate) {
|
|
|
20065
20904
|
}
|
|
20066
20905
|
}
|
|
20067
20906
|
function resolvePackageRoot() {
|
|
20068
|
-
const moduleRoot =
|
|
20907
|
+
const moduleRoot = path10.resolve(path10.dirname(fileURLToPath4(import.meta.url)), "..");
|
|
20069
20908
|
const cwd = process.cwd();
|
|
20070
20909
|
const candidates = [
|
|
20071
20910
|
process.env.ZK_AGENT_ACCOUNT_PROFILES_ROOT,
|
|
20072
|
-
|
|
20911
|
+
path10.join(moduleRoot, "dist", "builtin-account-profiles"),
|
|
20073
20912
|
moduleRoot,
|
|
20074
|
-
|
|
20075
|
-
|
|
20913
|
+
path10.join(cwd, "packages", "account-profiles"),
|
|
20914
|
+
path10.join(cwd, "account-profiles"),
|
|
20076
20915
|
cwd
|
|
20077
20916
|
].filter((value) => typeof value === "string" && value.trim().length > 0);
|
|
20078
20917
|
const seen = /* @__PURE__ */ new Set();
|
|
20079
20918
|
for (const candidate of candidates) {
|
|
20080
|
-
const normalized =
|
|
20919
|
+
const normalized = path10.resolve(candidate);
|
|
20081
20920
|
if (seen.has(normalized)) continue;
|
|
20082
20921
|
seen.add(normalized);
|
|
20083
20922
|
if (isExpectedPackageRoot(normalized)) {
|
|
@@ -20149,11 +20988,11 @@ function missingArtifactError(profileId, artifactPath2) {
|
|
|
20149
20988
|
}
|
|
20150
20989
|
function contractPath(...segments) {
|
|
20151
20990
|
const packageRoot = tryResolvePackageRoot();
|
|
20152
|
-
return packageRoot ?
|
|
20991
|
+
return packageRoot ? path10.join(packageRoot, "contracts", ...segments) : path10.join(PACKAGE_ROOT_FALLBACK, "contracts", ...segments);
|
|
20153
20992
|
}
|
|
20154
20993
|
function artifactPath(...segments) {
|
|
20155
20994
|
const packageRoot = tryResolvePackageRoot();
|
|
20156
|
-
return packageRoot ?
|
|
20995
|
+
return packageRoot ? path10.join(packageRoot, "artifacts", ...segments) : path10.join(PACKAGE_ROOT_FALLBACK, "artifacts", ...segments);
|
|
20157
20996
|
}
|
|
20158
20997
|
function createDailySpendLimitProfile() {
|
|
20159
20998
|
const resolvedArtifactPath = artifactPath("daily-spend-limit", "Account.json");
|
|
@@ -22586,7 +23425,7 @@ function buildCallbackUrl(host, port) {
|
|
|
22586
23425
|
async function awaitLocalWalletApproval(options) {
|
|
22587
23426
|
const { walletRequest, walletName, host, requestedPort, timeoutSeconds } = options;
|
|
22588
23427
|
assertRequestActive(walletRequest.expiresAt);
|
|
22589
|
-
const server =
|
|
23428
|
+
const server = createServer3();
|
|
22590
23429
|
let settled = false;
|
|
22591
23430
|
const completion = new Promise((resolve, reject) => {
|
|
22592
23431
|
server.on("error", reject);
|
|
@@ -28031,14 +28870,30 @@ function buildDefaultOperatorPathHelpText() {
|
|
|
28031
28870
|
" One-shot CLI: npx zk-agent-cli --help",
|
|
28032
28871
|
" Global CLI: npm install -g zk-agent-cli",
|
|
28033
28872
|
"",
|
|
28873
|
+
"Install -> first proof -> broader follow-up:",
|
|
28874
|
+
" install once -> pick skills, npx, or npm -g",
|
|
28875
|
+
" prove once -> zk-agent setup -> zk-agent start -> zk-agent wallet create --await-local -> zk-agent next -> zk-agent pay --wallet main --to <address> --amount <amount>",
|
|
28876
|
+
" broaden only after that first success -> zk-agent suite",
|
|
28877
|
+
"",
|
|
28878
|
+
"Product shell in one line:",
|
|
28879
|
+
" prove one local-first zkSync-native pay path first",
|
|
28880
|
+
" grow into Agent Pay requests, workspace, handoff, and feed on the same wallet runtime",
|
|
28881
|
+
" open hosted relay approval only when the browser is remote",
|
|
28882
|
+
"",
|
|
28883
|
+
"Payment-first product story:",
|
|
28884
|
+
" first proof -> get one wallet ready and send value once",
|
|
28885
|
+
" first expansion -> keep the same wallet runtime and add Agent Pay follow-up, workspace, handoff, and feed",
|
|
28886
|
+
" hosted fallback -> move approval to relay only when the browser is remote",
|
|
28887
|
+
"",
|
|
28034
28888
|
"Why use it:",
|
|
28035
28889
|
" local-first wallet and session control",
|
|
28036
28890
|
" zkSync-native smart-account and paymaster path centered on sed-lite",
|
|
28037
|
-
"
|
|
28891
|
+
" payment-first public shell: prove pay first, then grow into Agent Pay on the same runtime",
|
|
28038
28892
|
"",
|
|
28039
28893
|
"Best fit:",
|
|
28040
28894
|
" you want wallet and session control to stay local instead of starting with a managed browser product",
|
|
28041
28895
|
" you want a zkSync-native pay and paymaster path instead of a generic multichain wrapper",
|
|
28896
|
+
" you want to prove one pay route before reading a broad command catalog",
|
|
28042
28897
|
" you want Agent Pay request capture and a workbench on the same wallet runtime",
|
|
28043
28898
|
"",
|
|
28044
28899
|
"What makes zk-agent-cli different:",
|
|
@@ -28067,7 +28922,7 @@ function buildDefaultOperatorPathHelpText() {
|
|
|
28067
28922
|
"",
|
|
28068
28923
|
"First proof from a clean machine:",
|
|
28069
28924
|
" zk-agent setup",
|
|
28070
|
-
" zk-agent
|
|
28925
|
+
" zk-agent start",
|
|
28071
28926
|
" zk-agent wallet create --await-local",
|
|
28072
28927
|
" zk-agent next",
|
|
28073
28928
|
` ${buildTopLevelPayRecommendedCommand("main")}`,
|
|
@@ -28181,7 +29036,7 @@ function applyRootHelpCommandOrder(program) {
|
|
|
28181
29036
|
}
|
|
28182
29037
|
function createProgram() {
|
|
28183
29038
|
const program = new Command14().name("zk-agent").description(
|
|
28184
|
-
"
|
|
29039
|
+
"Payment-first local-first zkSync-native CLI for flagship pay, Agent Pay follow-up, and hosted approval fallback"
|
|
28185
29040
|
).showHelpAfterError().option("--json", "Force JSON output for agent harnesses", false).hook("preAction", (thisCommand) => {
|
|
28186
29041
|
if (thisCommand.optsWithGlobals().json) process.env.ZK_AGENT_OUTPUT = "json";
|
|
28187
29042
|
});
|