@openwop/cli 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +57 -11
- package/dist/openwop.js +56 -11
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -578,7 +578,7 @@ function errText(err) {
|
|
|
578
578
|
// package.json
|
|
579
579
|
var package_default = {
|
|
580
580
|
name: "@openwop/cli",
|
|
581
|
-
version: "1.
|
|
581
|
+
version: "1.6.0",
|
|
582
582
|
description: "OpenWOP CLI for operating the workflow-engine demo app and OpenWOP-compatible hosts.",
|
|
583
583
|
license: "Apache-2.0",
|
|
584
584
|
type: "module",
|
|
@@ -1209,6 +1209,14 @@ function hostRootFor(path, roots) {
|
|
|
1209
1209
|
}
|
|
1210
1210
|
return best === null ? null : `${roots[best]}${path.slice(best.length)}`;
|
|
1211
1211
|
}
|
|
1212
|
+
function hostSurfaceAdvertised(discovery, v1Prefix) {
|
|
1213
|
+
if (!discovery || typeof discovery !== "object") return false;
|
|
1214
|
+
const { paths, extensions } = discovery;
|
|
1215
|
+
if (paths !== null && typeof paths === "object") {
|
|
1216
|
+
return Object.keys(paths).some((p) => p.startsWith(v1Prefix));
|
|
1217
|
+
}
|
|
1218
|
+
return hostRootFor(v1Prefix, hostRootsFrom(extensions)) !== null;
|
|
1219
|
+
}
|
|
1212
1220
|
async function negotiateMajor(ctx) {
|
|
1213
1221
|
if (ctx.protocolMajor !== void 0) return ctx.protocolMajor;
|
|
1214
1222
|
const pinned = ctx.env?.OPENWOP_PROTOCOL_MAJOR;
|
|
@@ -16898,8 +16906,8 @@ var APPROVALS_ROUTES = [
|
|
|
16898
16906
|
var APPROVALS_HELP = `Usage:
|
|
16899
16907
|
openwop approvals list [--status pending|approved|rejected] [--json]
|
|
16900
16908
|
openwop approvals get <approvalId> [--json]
|
|
16901
|
-
openwop approvals claim <approvalId> [--note <text>] [--acted-for <subject>] [--expected-hash <h>] [--json]
|
|
16902
|
-
openwop approvals reject <approvalId> [--note <text>] [--acted-for <subject>] [--expected-hash <h>] [--json]
|
|
16909
|
+
openwop approvals claim <approvalId> [--note <text>] [--acted-for <subject>] [--expected-hash <h>] [--content-hash <h>] [--json]
|
|
16910
|
+
openwop approvals reject <approvalId> [--note <text>] [--acted-for <subject>] [--expected-hash <h>] [--content-hash <h>] [--json]
|
|
16903
16911
|
openwop approvals sla-policy [--json]
|
|
16904
16912
|
openwop approvals sla-policy set (--enabled | --disabled) [--remind-after-ms n] [--escalate-after-ms n] [--expire-after-ms n] [--json]
|
|
16905
16913
|
openwop approvals email-pref [--json]
|
|
@@ -16937,6 +16945,11 @@ Endpoints:
|
|
|
16937
16945
|
--acted-for <s> (claim/reject) As a delegate covering several people, whose approval this is.
|
|
16938
16946
|
--expected-hash <h> (claim/reject) The definition hash you reviewed (composed-workflow proposals;
|
|
16939
16947
|
the host refuses the decision if the proposal changed since).
|
|
16948
|
+
--content-hash <h> (claim/reject) The contentHash of the assistant-action card you reviewed
|
|
16949
|
+
(\`approvals get\` prints it under the card). REQUIRED to claim an
|
|
16950
|
+
assistant action (ADR 0862): the host refuses a claim without it (exit 2),
|
|
16951
|
+
and refuses one whose action changed since you read it (exit 1; re-read
|
|
16952
|
+
it with \`approvals get\` and review the new card).
|
|
16940
16953
|
--status <s> (list) Filter the queue: pending | approved | rejected (default: all).
|
|
16941
16954
|
--note <text> (claim/reject) Optional human note recorded with the decision.
|
|
16942
16955
|
--json Print the raw host response instead of the rendered view.
|
|
@@ -16953,6 +16966,8 @@ Examples:
|
|
|
16953
16966
|
openwop approvals list --status pending
|
|
16954
16967
|
openwop approvals get appr_123 --json
|
|
16955
16968
|
openwop approvals claim appr_123 --note "LGTM, ship it"
|
|
16969
|
+
openwop approvals get appr_456 # an assistant action: read the card
|
|
16970
|
+
openwop approvals claim appr_456 --content-hash 9f2c\u2026 # \u2026then approve exactly what you read
|
|
16956
16971
|
openwop approvals reject appr_123 --note "out of policy"
|
|
16957
16972
|
|
|
16958
16973
|
Teams approval delivery:
|
|
@@ -16999,8 +17014,7 @@ function exitForStatus(status) {
|
|
|
16999
17014
|
async function ensureApprovalsAdvertised(ctx) {
|
|
17000
17015
|
const wk = await safeRequest(ctx, "/.well-known/openwop", { auth: false });
|
|
17001
17016
|
if (!wk.ok) return;
|
|
17002
|
-
const
|
|
17003
|
-
const advertised = paths !== null && typeof paths === "object" && Object.keys(paths).some((p) => p.startsWith("/v1/host/openwop-app/approvals"));
|
|
17017
|
+
const advertised = hostSurfaceAdvertised(wk.body, "/v1/host/openwop-app/approvals");
|
|
17004
17018
|
if (!advertised) {
|
|
17005
17019
|
throw new CliError(
|
|
17006
17020
|
"approvals: this host does not advertise the approval-inbox surface (/v1/host/openwop-app/approvals is absent from /.well-known/openwop). The host is the authority \u2014 refusing to guess.",
|
|
@@ -17085,12 +17099,31 @@ async function runApprovalsGet(ctx, argv) {
|
|
|
17085
17099
|
if (approval.resolvedAt) writeLine(ctx.io.stdout, `resolvedAt: ${approval.resolvedAt}`);
|
|
17086
17100
|
if (approval.runId) writeLine(ctx.io.stdout, `runId: ${approval.runId}`);
|
|
17087
17101
|
if (approval.note) writeLine(ctx.io.stdout, `note: ${approval.note}`);
|
|
17102
|
+
if (approval.action && typeof approval.action === "object") renderActionCard(ctx, approval.action);
|
|
17088
17103
|
return exitForStatus(approval.status);
|
|
17089
17104
|
}
|
|
17105
|
+
function renderActionCard(ctx, action) {
|
|
17106
|
+
writeLine(ctx.io.stdout, "action:");
|
|
17107
|
+
if (action.actionId) writeLine(ctx.io.stdout, ` actionId: ${action.actionId}`);
|
|
17108
|
+
if (action.kind) writeLine(ctx.io.stdout, ` kind: ${action.kind}`);
|
|
17109
|
+
if (action.riskLevel) writeLine(ctx.io.stdout, ` riskLevel: ${action.riskLevel}`);
|
|
17110
|
+
if (action.reason) writeLine(ctx.io.stdout, ` reason: ${action.reason}`);
|
|
17111
|
+
if (typeof action.draft === "string" && action.draft.length) writeLine(ctx.io.stdout, ` draft: ${action.draft}`);
|
|
17112
|
+
if (action.payload && typeof action.payload === "object") {
|
|
17113
|
+
for (const [k, v] of Object.entries(action.payload)) {
|
|
17114
|
+
writeLine(ctx.io.stdout, ` ${k}: ${typeof v === "string" ? v : JSON.stringify(v)}`);
|
|
17115
|
+
}
|
|
17116
|
+
}
|
|
17117
|
+
if (action.contentHash) writeLine(ctx.io.stdout, ` contentHash: ${action.contentHash} (claim with --content-hash ${action.contentHash})`);
|
|
17118
|
+
}
|
|
17119
|
+
function detailsOf(body) {
|
|
17120
|
+
const d = body && typeof body === "object" ? body.details : void 0;
|
|
17121
|
+
return d && typeof d === "object" ? d : {};
|
|
17122
|
+
}
|
|
17090
17123
|
async function runApprovalsResolve(ctx, argv, verb) {
|
|
17091
|
-
const { options, positionals } = parseOptions(argv, { bool: ["--help"], value: ["--note", "--acted-for", "--expected-hash"] });
|
|
17124
|
+
const { options, positionals } = parseOptions(argv, { bool: ["--help"], value: ["--note", "--acted-for", "--expected-hash", "--content-hash"] });
|
|
17092
17125
|
if (options.help || positionals.length !== 1) {
|
|
17093
|
-
write(ctx.io.stdout, `Usage: openwop approvals ${verb} <approvalId> [--note <text>] [--acted-for <subject>] [--expected-hash <h>] [--json]
|
|
17126
|
+
write(ctx.io.stdout, `Usage: openwop approvals ${verb} <approvalId> [--note <text>] [--acted-for <subject>] [--expected-hash <h>] [--content-hash <h>] [--json]
|
|
17094
17127
|
`);
|
|
17095
17128
|
return options.help ? 0 : 2;
|
|
17096
17129
|
}
|
|
@@ -17100,11 +17133,25 @@ async function runApprovalsResolve(ctx, argv, verb) {
|
|
|
17100
17133
|
if (options.note !== void 0) decision.note = options.note;
|
|
17101
17134
|
if (options.actedFor !== void 0) decision.actedFor = options.actedFor;
|
|
17102
17135
|
if (options.expectedHash !== void 0) decision.expectedDefinitionHash = options.expectedHash;
|
|
17136
|
+
if (options.contentHash !== void 0) decision.expectedContentHash = options.contentHash;
|
|
17103
17137
|
const body = Object.keys(decision).length ? decision : void 0;
|
|
17104
17138
|
let res;
|
|
17105
17139
|
try {
|
|
17106
17140
|
res = await requestJson(ctx, path, { method: "POST", ...body !== void 0 ? { body } : {} });
|
|
17107
17141
|
} catch (err) {
|
|
17142
|
+
if (err instanceof HttpError && err.status === 409 && detailsOf(err.body).reason === "action_changed") {
|
|
17143
|
+
const now = detailsOf(err.body).contentHash;
|
|
17144
|
+
throw new CliError(
|
|
17145
|
+
`approvals: the action behind ${positionals[0]} changed since you reviewed it \u2014 nothing was ${verb === "claim" ? "approved" : "rejected"}. Re-read it with \`openwop approvals get ${positionals[0]}\`${now ? ` (its card now hashes to ${now})` : ""} and decide on what it says now.`,
|
|
17146
|
+
1
|
|
17147
|
+
);
|
|
17148
|
+
}
|
|
17149
|
+
if (err instanceof HttpError && err.status === 400 && detailsOf(err.body).reason === "content_hash_required") {
|
|
17150
|
+
throw new CliError(
|
|
17151
|
+
`approvals: ${positionals[0]} is an assistant action \u2014 read its card with \`openwop approvals get ${positionals[0]}\`, then pass the contentHash it shows: --content-hash <hash>.`,
|
|
17152
|
+
2
|
|
17153
|
+
);
|
|
17154
|
+
}
|
|
17108
17155
|
if (err instanceof HttpError && err.status === 409) {
|
|
17109
17156
|
const status = err.body?.status;
|
|
17110
17157
|
throw new CliError(`approvals: ${positionals[0]} is already ${status ?? "resolved"} \u2014 the host rejected a second decision.`, 1);
|
|
@@ -17986,8 +18033,7 @@ Run \`openwop connections --help\` for usage.`);
|
|
|
17986
18033
|
async function ensureAdvertised(ctx) {
|
|
17987
18034
|
const wk = await safeRequest(ctx, "/.well-known/openwop", { auth: false });
|
|
17988
18035
|
if (!wk.ok) return;
|
|
17989
|
-
const
|
|
17990
|
-
const advertised = paths !== null && typeof paths === "object" && Object.keys(paths).some((p) => p.startsWith("/v1/host/openwop-app/connections"));
|
|
18036
|
+
const advertised = hostSurfaceAdvertised(wk.body, "/v1/host/openwop-app/connections");
|
|
17991
18037
|
if (!advertised) {
|
|
17992
18038
|
throw new CliError(
|
|
17993
18039
|
"connections: this host does not advertise the connections surface (/v1/host/openwop-app/connections is absent from /.well-known/openwop). The host is the authority \u2014 refusing to guess.",
|
|
@@ -19396,8 +19442,7 @@ Run \`openwop workforces --help\` for usage.`);
|
|
|
19396
19442
|
async function ensureAdvertised2(ctx) {
|
|
19397
19443
|
const wk = await safeRequest(ctx, "/.well-known/openwop", { auth: false });
|
|
19398
19444
|
if (!wk.ok) return;
|
|
19399
|
-
const
|
|
19400
|
-
const advertised = paths !== null && typeof paths === "object" && Object.keys(paths).some((p) => p.startsWith("/v1/host/openwop-app/workforces"));
|
|
19445
|
+
const advertised = hostSurfaceAdvertised(wk.body, "/v1/host/openwop-app/workforces");
|
|
19401
19446
|
if (!advertised) {
|
|
19402
19447
|
throw new CliError(
|
|
19403
19448
|
"workforces: this host does not advertise the workforces surface (/v1/host/openwop-app/workforces is absent from /.well-known/openwop). The host is the authority \u2014 refusing to guess.",
|
|
@@ -30944,6 +30989,7 @@ export {
|
|
|
30944
30989
|
getChannelPlugin,
|
|
30945
30990
|
hostRootFor,
|
|
30946
30991
|
hostRootsFrom,
|
|
30992
|
+
hostSurfaceAdvertised,
|
|
30947
30993
|
idempotencyHeaders,
|
|
30948
30994
|
isNoCredentialChallenge,
|
|
30949
30995
|
isTerminalRunEvent,
|
package/dist/openwop.js
CHANGED
|
@@ -579,7 +579,7 @@ function errText(err) {
|
|
|
579
579
|
// package.json
|
|
580
580
|
var package_default = {
|
|
581
581
|
name: "@openwop/cli",
|
|
582
|
-
version: "1.
|
|
582
|
+
version: "1.6.0",
|
|
583
583
|
description: "OpenWOP CLI for operating the workflow-engine demo app and OpenWOP-compatible hosts.",
|
|
584
584
|
license: "Apache-2.0",
|
|
585
585
|
type: "module",
|
|
@@ -1209,6 +1209,14 @@ function hostRootFor(path, roots) {
|
|
|
1209
1209
|
}
|
|
1210
1210
|
return best === null ? null : `${roots[best]}${path.slice(best.length)}`;
|
|
1211
1211
|
}
|
|
1212
|
+
function hostSurfaceAdvertised(discovery, v1Prefix) {
|
|
1213
|
+
if (!discovery || typeof discovery !== "object") return false;
|
|
1214
|
+
const { paths, extensions } = discovery;
|
|
1215
|
+
if (paths !== null && typeof paths === "object") {
|
|
1216
|
+
return Object.keys(paths).some((p) => p.startsWith(v1Prefix));
|
|
1217
|
+
}
|
|
1218
|
+
return hostRootFor(v1Prefix, hostRootsFrom(extensions)) !== null;
|
|
1219
|
+
}
|
|
1212
1220
|
async function negotiateMajor(ctx) {
|
|
1213
1221
|
if (ctx.protocolMajor !== void 0) return ctx.protocolMajor;
|
|
1214
1222
|
const pinned = ctx.env?.OPENWOP_PROTOCOL_MAJOR;
|
|
@@ -16898,8 +16906,8 @@ var APPROVALS_ROUTES = [
|
|
|
16898
16906
|
var APPROVALS_HELP = `Usage:
|
|
16899
16907
|
openwop approvals list [--status pending|approved|rejected] [--json]
|
|
16900
16908
|
openwop approvals get <approvalId> [--json]
|
|
16901
|
-
openwop approvals claim <approvalId> [--note <text>] [--acted-for <subject>] [--expected-hash <h>] [--json]
|
|
16902
|
-
openwop approvals reject <approvalId> [--note <text>] [--acted-for <subject>] [--expected-hash <h>] [--json]
|
|
16909
|
+
openwop approvals claim <approvalId> [--note <text>] [--acted-for <subject>] [--expected-hash <h>] [--content-hash <h>] [--json]
|
|
16910
|
+
openwop approvals reject <approvalId> [--note <text>] [--acted-for <subject>] [--expected-hash <h>] [--content-hash <h>] [--json]
|
|
16903
16911
|
openwop approvals sla-policy [--json]
|
|
16904
16912
|
openwop approvals sla-policy set (--enabled | --disabled) [--remind-after-ms n] [--escalate-after-ms n] [--expire-after-ms n] [--json]
|
|
16905
16913
|
openwop approvals email-pref [--json]
|
|
@@ -16937,6 +16945,11 @@ Endpoints:
|
|
|
16937
16945
|
--acted-for <s> (claim/reject) As a delegate covering several people, whose approval this is.
|
|
16938
16946
|
--expected-hash <h> (claim/reject) The definition hash you reviewed (composed-workflow proposals;
|
|
16939
16947
|
the host refuses the decision if the proposal changed since).
|
|
16948
|
+
--content-hash <h> (claim/reject) The contentHash of the assistant-action card you reviewed
|
|
16949
|
+
(\`approvals get\` prints it under the card). REQUIRED to claim an
|
|
16950
|
+
assistant action (ADR 0862): the host refuses a claim without it (exit 2),
|
|
16951
|
+
and refuses one whose action changed since you read it (exit 1; re-read
|
|
16952
|
+
it with \`approvals get\` and review the new card).
|
|
16940
16953
|
--status <s> (list) Filter the queue: pending | approved | rejected (default: all).
|
|
16941
16954
|
--note <text> (claim/reject) Optional human note recorded with the decision.
|
|
16942
16955
|
--json Print the raw host response instead of the rendered view.
|
|
@@ -16953,6 +16966,8 @@ Examples:
|
|
|
16953
16966
|
openwop approvals list --status pending
|
|
16954
16967
|
openwop approvals get appr_123 --json
|
|
16955
16968
|
openwop approvals claim appr_123 --note "LGTM, ship it"
|
|
16969
|
+
openwop approvals get appr_456 # an assistant action: read the card
|
|
16970
|
+
openwop approvals claim appr_456 --content-hash 9f2c\u2026 # \u2026then approve exactly what you read
|
|
16956
16971
|
openwop approvals reject appr_123 --note "out of policy"
|
|
16957
16972
|
|
|
16958
16973
|
Teams approval delivery:
|
|
@@ -16999,8 +17014,7 @@ function exitForStatus(status) {
|
|
|
16999
17014
|
async function ensureApprovalsAdvertised(ctx) {
|
|
17000
17015
|
const wk = await safeRequest(ctx, "/.well-known/openwop", { auth: false });
|
|
17001
17016
|
if (!wk.ok) return;
|
|
17002
|
-
const
|
|
17003
|
-
const advertised = paths !== null && typeof paths === "object" && Object.keys(paths).some((p) => p.startsWith("/v1/host/openwop-app/approvals"));
|
|
17017
|
+
const advertised = hostSurfaceAdvertised(wk.body, "/v1/host/openwop-app/approvals");
|
|
17004
17018
|
if (!advertised) {
|
|
17005
17019
|
throw new CliError(
|
|
17006
17020
|
"approvals: this host does not advertise the approval-inbox surface (/v1/host/openwop-app/approvals is absent from /.well-known/openwop). The host is the authority \u2014 refusing to guess.",
|
|
@@ -17085,12 +17099,31 @@ async function runApprovalsGet(ctx, argv) {
|
|
|
17085
17099
|
if (approval.resolvedAt) writeLine(ctx.io.stdout, `resolvedAt: ${approval.resolvedAt}`);
|
|
17086
17100
|
if (approval.runId) writeLine(ctx.io.stdout, `runId: ${approval.runId}`);
|
|
17087
17101
|
if (approval.note) writeLine(ctx.io.stdout, `note: ${approval.note}`);
|
|
17102
|
+
if (approval.action && typeof approval.action === "object") renderActionCard(ctx, approval.action);
|
|
17088
17103
|
return exitForStatus(approval.status);
|
|
17089
17104
|
}
|
|
17105
|
+
function renderActionCard(ctx, action) {
|
|
17106
|
+
writeLine(ctx.io.stdout, "action:");
|
|
17107
|
+
if (action.actionId) writeLine(ctx.io.stdout, ` actionId: ${action.actionId}`);
|
|
17108
|
+
if (action.kind) writeLine(ctx.io.stdout, ` kind: ${action.kind}`);
|
|
17109
|
+
if (action.riskLevel) writeLine(ctx.io.stdout, ` riskLevel: ${action.riskLevel}`);
|
|
17110
|
+
if (action.reason) writeLine(ctx.io.stdout, ` reason: ${action.reason}`);
|
|
17111
|
+
if (typeof action.draft === "string" && action.draft.length) writeLine(ctx.io.stdout, ` draft: ${action.draft}`);
|
|
17112
|
+
if (action.payload && typeof action.payload === "object") {
|
|
17113
|
+
for (const [k, v] of Object.entries(action.payload)) {
|
|
17114
|
+
writeLine(ctx.io.stdout, ` ${k}: ${typeof v === "string" ? v : JSON.stringify(v)}`);
|
|
17115
|
+
}
|
|
17116
|
+
}
|
|
17117
|
+
if (action.contentHash) writeLine(ctx.io.stdout, ` contentHash: ${action.contentHash} (claim with --content-hash ${action.contentHash})`);
|
|
17118
|
+
}
|
|
17119
|
+
function detailsOf(body) {
|
|
17120
|
+
const d = body && typeof body === "object" ? body.details : void 0;
|
|
17121
|
+
return d && typeof d === "object" ? d : {};
|
|
17122
|
+
}
|
|
17090
17123
|
async function runApprovalsResolve(ctx, argv, verb) {
|
|
17091
|
-
const { options, positionals } = parseOptions(argv, { bool: ["--help"], value: ["--note", "--acted-for", "--expected-hash"] });
|
|
17124
|
+
const { options, positionals } = parseOptions(argv, { bool: ["--help"], value: ["--note", "--acted-for", "--expected-hash", "--content-hash"] });
|
|
17092
17125
|
if (options.help || positionals.length !== 1) {
|
|
17093
|
-
write(ctx.io.stdout, `Usage: openwop approvals ${verb} <approvalId> [--note <text>] [--acted-for <subject>] [--expected-hash <h>] [--json]
|
|
17126
|
+
write(ctx.io.stdout, `Usage: openwop approvals ${verb} <approvalId> [--note <text>] [--acted-for <subject>] [--expected-hash <h>] [--content-hash <h>] [--json]
|
|
17094
17127
|
`);
|
|
17095
17128
|
return options.help ? 0 : 2;
|
|
17096
17129
|
}
|
|
@@ -17100,11 +17133,25 @@ async function runApprovalsResolve(ctx, argv, verb) {
|
|
|
17100
17133
|
if (options.note !== void 0) decision.note = options.note;
|
|
17101
17134
|
if (options.actedFor !== void 0) decision.actedFor = options.actedFor;
|
|
17102
17135
|
if (options.expectedHash !== void 0) decision.expectedDefinitionHash = options.expectedHash;
|
|
17136
|
+
if (options.contentHash !== void 0) decision.expectedContentHash = options.contentHash;
|
|
17103
17137
|
const body = Object.keys(decision).length ? decision : void 0;
|
|
17104
17138
|
let res;
|
|
17105
17139
|
try {
|
|
17106
17140
|
res = await requestJson(ctx, path, { method: "POST", ...body !== void 0 ? { body } : {} });
|
|
17107
17141
|
} catch (err) {
|
|
17142
|
+
if (err instanceof HttpError && err.status === 409 && detailsOf(err.body).reason === "action_changed") {
|
|
17143
|
+
const now = detailsOf(err.body).contentHash;
|
|
17144
|
+
throw new CliError(
|
|
17145
|
+
`approvals: the action behind ${positionals[0]} changed since you reviewed it \u2014 nothing was ${verb === "claim" ? "approved" : "rejected"}. Re-read it with \`openwop approvals get ${positionals[0]}\`${now ? ` (its card now hashes to ${now})` : ""} and decide on what it says now.`,
|
|
17146
|
+
1
|
|
17147
|
+
);
|
|
17148
|
+
}
|
|
17149
|
+
if (err instanceof HttpError && err.status === 400 && detailsOf(err.body).reason === "content_hash_required") {
|
|
17150
|
+
throw new CliError(
|
|
17151
|
+
`approvals: ${positionals[0]} is an assistant action \u2014 read its card with \`openwop approvals get ${positionals[0]}\`, then pass the contentHash it shows: --content-hash <hash>.`,
|
|
17152
|
+
2
|
|
17153
|
+
);
|
|
17154
|
+
}
|
|
17108
17155
|
if (err instanceof HttpError && err.status === 409) {
|
|
17109
17156
|
const status = err.body?.status;
|
|
17110
17157
|
throw new CliError(`approvals: ${positionals[0]} is already ${status ?? "resolved"} \u2014 the host rejected a second decision.`, 1);
|
|
@@ -17986,8 +18033,7 @@ Run \`openwop connections --help\` for usage.`);
|
|
|
17986
18033
|
async function ensureAdvertised(ctx) {
|
|
17987
18034
|
const wk = await safeRequest(ctx, "/.well-known/openwop", { auth: false });
|
|
17988
18035
|
if (!wk.ok) return;
|
|
17989
|
-
const
|
|
17990
|
-
const advertised = paths !== null && typeof paths === "object" && Object.keys(paths).some((p) => p.startsWith("/v1/host/openwop-app/connections"));
|
|
18036
|
+
const advertised = hostSurfaceAdvertised(wk.body, "/v1/host/openwop-app/connections");
|
|
17991
18037
|
if (!advertised) {
|
|
17992
18038
|
throw new CliError(
|
|
17993
18039
|
"connections: this host does not advertise the connections surface (/v1/host/openwop-app/connections is absent from /.well-known/openwop). The host is the authority \u2014 refusing to guess.",
|
|
@@ -19396,8 +19442,7 @@ Run \`openwop workforces --help\` for usage.`);
|
|
|
19396
19442
|
async function ensureAdvertised2(ctx) {
|
|
19397
19443
|
const wk = await safeRequest(ctx, "/.well-known/openwop", { auth: false });
|
|
19398
19444
|
if (!wk.ok) return;
|
|
19399
|
-
const
|
|
19400
|
-
const advertised = paths !== null && typeof paths === "object" && Object.keys(paths).some((p) => p.startsWith("/v1/host/openwop-app/workforces"));
|
|
19445
|
+
const advertised = hostSurfaceAdvertised(wk.body, "/v1/host/openwop-app/workforces");
|
|
19401
19446
|
if (!advertised) {
|
|
19402
19447
|
throw new CliError(
|
|
19403
19448
|
"workforces: this host does not advertise the workforces surface (/v1/host/openwop-app/workforces is absent from /.well-known/openwop). The host is the authority \u2014 refusing to guess.",
|