xytara 2.6.0 → 2.7.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/RELEASE_NOTES.md +11 -0
- package/lib/release_history.js +12 -0
- package/package.json +2 -1
- package/scripts/generate_treasury_destinations.js +195 -0
- package/scripts/registry_cli.js +275 -0
- package/scripts/verify_adapters.js +554 -0
- package/scripts/verify_all.js +4963 -0
- package/scripts/verify_examples.js +19 -0
- package/scripts/verify_integrations.js +620 -0
- package/scripts/verify_production_readiness.js +251 -0
- package/scripts/verify_release_candidate.js +54 -0
- package/scripts/verify_service.js +14810 -0
- package/scripts/verify_tooling.js +1404 -0
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
# xytara 2.7.0 Release Notes
|
|
2
|
+
|
|
3
|
+
`xytara` 2.7.0 is the expansion-closeout release line for package-hardening, clean-consumer release smoke testing, and disciplined adapter/product claim boundaries.
|
|
4
|
+
|
|
5
|
+
Highlights:
|
|
6
|
+
|
|
7
|
+
- ships `scripts/` in the npm artifact so packaged verification commands are available to consumers
|
|
8
|
+
- adds release-candidate guards that fail if required verifier scripts are missing from `npm pack`
|
|
9
|
+
- participates in the Naxytra release-smoke harness that installs packed tarballs into a clean consumer project before synchronized release
|
|
10
|
+
- keeps the 2.6.0 expansion capabilities and adapter surfaces intact while closing the packaging reliability gap
|
|
11
|
+
|
|
1
12
|
# xytara 2.6.0 Release Notes
|
|
2
13
|
|
|
3
14
|
`xytara` 2.6.0 is the expansion release line for first-run execution polish, provider-backed adapter depth, and framework reference adapters while preserving the existing machine-commerce, settlement, observability, and release surfaces.
|
package/lib/release_history.js
CHANGED
|
@@ -10,6 +10,18 @@ function buildReleaseHistory() {
|
|
|
10
10
|
current_version: packageJson.version,
|
|
11
11
|
release_track: "public_release",
|
|
12
12
|
history: [
|
|
13
|
+
{
|
|
14
|
+
version: "2.7.0",
|
|
15
|
+
channel: "public_release",
|
|
16
|
+
maturity_posture: "expansion_closeout",
|
|
17
|
+
headline: "expansion-closeout release with package-hardening, clean-consumer release smoke testing, and disciplined adapter claim boundaries",
|
|
18
|
+
milestone_refs: [
|
|
19
|
+
"npm_packaged_verification_scripts",
|
|
20
|
+
"release_candidate_packaging_guard",
|
|
21
|
+
"clean_consumer_release_smoke",
|
|
22
|
+
"expansion_closeout_claim_boundaries"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
13
25
|
{
|
|
14
26
|
version: "2.6.0",
|
|
15
27
|
channel: "public_release",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xytara",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "Agent-commerce runtime for quote, pay, execute, deliver, meter, and integrate.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"client.js",
|
|
36
36
|
"server.js",
|
|
37
37
|
"bin/",
|
|
38
|
+
"scripts/",
|
|
38
39
|
"fixtures/",
|
|
39
40
|
"integrations/",
|
|
40
41
|
"lib/",
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const readline = require("readline/promises");
|
|
6
|
+
const { stdin: input, stdout: output } = require("process");
|
|
7
|
+
|
|
8
|
+
const TEMPLATE_PATH = path.resolve(__dirname, "..", "TREASURY_DESTINATIONS.production.template.json");
|
|
9
|
+
const DEFAULT_OUTPUT_PATH = path.resolve(__dirname, "..", "TREASURY_DESTINATIONS.production.json");
|
|
10
|
+
|
|
11
|
+
const RAIL_ORDER = [
|
|
12
|
+
"bsv_teranode",
|
|
13
|
+
"evm",
|
|
14
|
+
"base",
|
|
15
|
+
"usdc",
|
|
16
|
+
"dai",
|
|
17
|
+
"solana_payment",
|
|
18
|
+
"xpr_payment",
|
|
19
|
+
"antelope_payment",
|
|
20
|
+
"monero"
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
const RAIL_HELP = {
|
|
24
|
+
bsv_teranode: "BSV treasury receive address or paymail.",
|
|
25
|
+
evm: "Ethereum mainnet treasury receive address.",
|
|
26
|
+
base: "Base treasury receive address.",
|
|
27
|
+
usdc: "USDC treasury receive address on the chain you actually use.",
|
|
28
|
+
dai: "DAI treasury receive address on the chain you actually use.",
|
|
29
|
+
solana_payment: "Solana treasury receive address.",
|
|
30
|
+
xpr_payment: "Proton/XPR treasury account or address.",
|
|
31
|
+
antelope_payment: "Antelope treasury account or address.",
|
|
32
|
+
monero: "Monero treasury receive address. Keep this internal-only unless truly needed."
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
function loadTemplate() {
|
|
36
|
+
return JSON.parse(fs.readFileSync(TEMPLATE_PATH, "utf8"));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function parseArgs(argv) {
|
|
40
|
+
const args = { outputPath: DEFAULT_OUTPUT_PATH };
|
|
41
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
42
|
+
const part = argv[i];
|
|
43
|
+
if (part === "--output" && argv[i + 1]) {
|
|
44
|
+
args.outputPath = path.resolve(process.cwd(), argv[i + 1]);
|
|
45
|
+
i += 1;
|
|
46
|
+
} else if (part === "--include-monero") {
|
|
47
|
+
args.includeMonero = true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return args;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function slugFromRail(rail) {
|
|
54
|
+
return String(rail || "").replace(/_payment$/, "").replace(/[^a-z0-9]+/gi, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function defaultRef(prefix, rail, suffix = "primary") {
|
|
58
|
+
return `${prefix}.${slugFromRail(rail)}.${suffix}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function defaultStorageClassForRail(rail) {
|
|
62
|
+
if (rail === "bsv_teranode") return "cold_primary";
|
|
63
|
+
if (rail === "monero") return "isolated_policy_gated";
|
|
64
|
+
return "warm_operational";
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function defaultProviderRefForRail(rail) {
|
|
68
|
+
if (rail === "bsv_teranode") return "";
|
|
69
|
+
if (rail === "usdc" || rail === "dai") return "";
|
|
70
|
+
return defaultRef("rpc", rail);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function defaultWalletRefForRail(rail) {
|
|
74
|
+
if (rail === "bsv_teranode") return "";
|
|
75
|
+
if (rail === "monero") return "";
|
|
76
|
+
return defaultRef("wallet", rail);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function defaultReportingRefForRail(rail) {
|
|
80
|
+
if (rail === "monero") return "ledger.monero.internal";
|
|
81
|
+
return defaultRef("ledger", rail);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function defaultCustodyRefForRail(rail) {
|
|
85
|
+
if (rail === "monero") return "vault.monero.policy_gated";
|
|
86
|
+
return defaultRef("vault", rail);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function validateLikelyAddress(rail, value) {
|
|
90
|
+
if (!value) return null;
|
|
91
|
+
if (rail === "evm" || rail === "base" || rail === "usdc" || rail === "dai") {
|
|
92
|
+
return /^0x[a-fA-F0-9]{40}$/.test(value) ? null : "Expected a 0x-prefixed 20-byte EVM address.";
|
|
93
|
+
}
|
|
94
|
+
if (rail === "solana_payment") {
|
|
95
|
+
return /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(value) ? null : "Expected a likely Solana base58 address.";
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function ask(rl, prompt, fallback = "") {
|
|
101
|
+
const suffix = fallback ? ` [${fallback}]` : "";
|
|
102
|
+
const answer = (await rl.question(`${prompt}${suffix}: `)).trim();
|
|
103
|
+
return answer || fallback;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function askYesNo(rl, prompt, fallback = true) {
|
|
107
|
+
const hint = fallback ? "Y/n" : "y/N";
|
|
108
|
+
const answer = (await rl.question(`${prompt} [${hint}]: `)).trim().toLowerCase();
|
|
109
|
+
if (!answer) return fallback;
|
|
110
|
+
return answer === "y" || answer === "yes";
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function pruneEmptyStrings(entry) {
|
|
114
|
+
return Object.fromEntries(
|
|
115
|
+
Object.entries(entry).filter(([, value]) => value !== "")
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function buildRailEntry(rl, rail, templateEntry, args) {
|
|
120
|
+
if (rail === "monero" && !args.includeMonero) {
|
|
121
|
+
const wantsMonero = await askYesNo(rl, "Include Monero in this treasury file?", false);
|
|
122
|
+
if (!wantsMonero) return templateEntry;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
output.write(`\n[${rail}] ${RAIL_HELP[rail] || ""}\n`);
|
|
126
|
+
const shouldConfigure = await askYesNo(rl, `Configure ${rail} now?`, rail !== "monero");
|
|
127
|
+
if (!shouldConfigure) return templateEntry;
|
|
128
|
+
|
|
129
|
+
const entry = { ...templateEntry };
|
|
130
|
+
const externalRef = await ask(rl, "external_ref", entry.external_ref || "");
|
|
131
|
+
const validationMessage = validateLikelyAddress(rail, externalRef);
|
|
132
|
+
if (validationMessage) {
|
|
133
|
+
output.write(` Warning: ${validationMessage}\n`);
|
|
134
|
+
}
|
|
135
|
+
entry.external_ref = externalRef;
|
|
136
|
+
|
|
137
|
+
if (entry.destination_id) {
|
|
138
|
+
entry.destination_id = await ask(rl, "destination_id", entry.destination_id);
|
|
139
|
+
}
|
|
140
|
+
if (entry.destination_kind) {
|
|
141
|
+
entry.destination_kind = await ask(rl, "destination_kind", entry.destination_kind);
|
|
142
|
+
}
|
|
143
|
+
if (Object.prototype.hasOwnProperty.call(entry, "network")) {
|
|
144
|
+
entry.network = await ask(rl, "network", entry.network || "mainnet");
|
|
145
|
+
}
|
|
146
|
+
if (Object.prototype.hasOwnProperty.call(entry, "chain_id")) {
|
|
147
|
+
entry.chain_id = await ask(rl, "chain_id", entry.chain_id || "");
|
|
148
|
+
}
|
|
149
|
+
if (Object.prototype.hasOwnProperty.call(entry, "asset_symbol")) {
|
|
150
|
+
entry.asset_symbol = await ask(rl, "asset_symbol", entry.asset_symbol || "");
|
|
151
|
+
}
|
|
152
|
+
if (Object.prototype.hasOwnProperty.call(entry, "policy_scope")) {
|
|
153
|
+
entry.policy_scope = await ask(rl, "policy_scope", entry.policy_scope || "internal_optional_privacy_reserve");
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
entry.custody_ref = await ask(rl, "custody_ref", defaultCustodyRefForRail(rail));
|
|
157
|
+
entry.reporting_ref = await ask(rl, "reporting_ref", defaultReportingRefForRail(rail));
|
|
158
|
+
|
|
159
|
+
if (Object.prototype.hasOwnProperty.call(entry, "wallet_ref")) {
|
|
160
|
+
entry.wallet_ref = await ask(rl, "wallet_ref", defaultWalletRefForRail(rail));
|
|
161
|
+
}
|
|
162
|
+
if (Object.prototype.hasOwnProperty.call(entry, "provider_ref")) {
|
|
163
|
+
entry.provider_ref = await ask(rl, "provider_ref", defaultProviderRefForRail(rail));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
entry.storage_class = await ask(rl, "storage_class", defaultStorageClassForRail(rail));
|
|
167
|
+
return pruneEmptyStrings(entry);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async function main() {
|
|
171
|
+
const args = parseArgs(process.argv.slice(2));
|
|
172
|
+
const template = loadTemplate();
|
|
173
|
+
const rl = readline.createInterface({ input, output });
|
|
174
|
+
|
|
175
|
+
output.write("xytara treasury destination generator\n");
|
|
176
|
+
output.write("This script does not create wallets or keys. It builds TREASURY_DESTINATIONS.production.json from the receive destinations you already control.\n");
|
|
177
|
+
output.write(`Template: ${TEMPLATE_PATH}\n`);
|
|
178
|
+
output.write(`Output: ${args.outputPath}\n`);
|
|
179
|
+
|
|
180
|
+
const result = {};
|
|
181
|
+
for (const rail of RAIL_ORDER) {
|
|
182
|
+
result[rail] = await buildRailEntry(rl, rail, template[rail], args);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
await rl.close();
|
|
186
|
+
|
|
187
|
+
fs.writeFileSync(args.outputPath, `${JSON.stringify(result, null, 2)}\n`, "utf8");
|
|
188
|
+
output.write(`\nWrote ${args.outputPath}\n`);
|
|
189
|
+
output.write("Upload this file to Render Secret Files, then set XYTARA_TREASURY_DESTINATIONS_PATH=./TREASURY_DESTINATIONS.production.json\n");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
main().catch((error) => {
|
|
193
|
+
console.error(error && error.stack ? error.stack : error);
|
|
194
|
+
process.exitCode = 1;
|
|
195
|
+
});
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const {
|
|
6
|
+
createIntegrationRegistrySnapshotFromBundles,
|
|
7
|
+
exportIntegrationSubmissionBundleSet,
|
|
8
|
+
importIntegrationSubmissionBundle,
|
|
9
|
+
summarizeIntegrationPromotionActionPreview,
|
|
10
|
+
summarizeIntegrationPromotionActionSet,
|
|
11
|
+
summarizeIntegrationPromotionActionSetList,
|
|
12
|
+
summarizeIntegrationPromotionReadiness,
|
|
13
|
+
summarizeIntegrationPromotionWorkflow,
|
|
14
|
+
summarizeIntegrationPromotionWorkflowList,
|
|
15
|
+
summarizeIntegrationRegistrySnapshotReview,
|
|
16
|
+
summarizeIntegrationSubmissionBundleReview,
|
|
17
|
+
summarizeIntegrationSubmissionBundleSetReview,
|
|
18
|
+
validateIntegrationSubmissionBundle
|
|
19
|
+
} = require("../integrations/registry");
|
|
20
|
+
|
|
21
|
+
function readJson(filePath) {
|
|
22
|
+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function writeJson(payload) {
|
|
26
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function resolveExampleBundle(name) {
|
|
30
|
+
const filename = name === "settlement"
|
|
31
|
+
? "example-third-party-settlement-registration.submission-bundle.json"
|
|
32
|
+
: name === "identity"
|
|
33
|
+
? "example-third-party-identity-registration.submission-bundle.json"
|
|
34
|
+
: "example-third-party-registration.submission-bundle.json";
|
|
35
|
+
return path.resolve(__dirname, "..", "adapters", "examples", filename);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function importExampleBundles() {
|
|
39
|
+
return [
|
|
40
|
+
importIntegrationSubmissionBundle(readJson(resolveExampleBundle("protocol")), {
|
|
41
|
+
source: "third_party_example",
|
|
42
|
+
protocols: ["mcp"],
|
|
43
|
+
execution_backends: ["mcp"],
|
|
44
|
+
adapter_lanes: ["mcp"],
|
|
45
|
+
task_refs: ["adapter.mcp.invoke"]
|
|
46
|
+
}),
|
|
47
|
+
importIntegrationSubmissionBundle(readJson(resolveExampleBundle("identity")), {
|
|
48
|
+
source: "third_party_example",
|
|
49
|
+
protocols: [],
|
|
50
|
+
execution_backends: ["http", "chain"],
|
|
51
|
+
adapter_lanes: ["http", "chain"],
|
|
52
|
+
task_refs: ["registry.register", "trust.handoff.emit", "trust.handoff.validate"]
|
|
53
|
+
}),
|
|
54
|
+
importIntegrationSubmissionBundle(readJson(resolveExampleBundle("settlement")), {
|
|
55
|
+
source: "third_party_example",
|
|
56
|
+
protocols: [],
|
|
57
|
+
execution_backends: ["chain"],
|
|
58
|
+
adapter_lanes: ["chain"],
|
|
59
|
+
task_refs: ["anchoring.submit"]
|
|
60
|
+
})
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function parseArgs(argv) {
|
|
65
|
+
const [command, ...rest] = argv;
|
|
66
|
+
const options = {};
|
|
67
|
+
for (let index = 0; index < rest.length; index += 1) {
|
|
68
|
+
const token = rest[index];
|
|
69
|
+
if (!token.startsWith("--")) continue;
|
|
70
|
+
const key = token.slice(2);
|
|
71
|
+
const next = rest[index + 1];
|
|
72
|
+
if (!next || next.startsWith("--")) {
|
|
73
|
+
options[key] = true;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
options[key] = next;
|
|
77
|
+
index += 1;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
command: command || "",
|
|
81
|
+
options
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function runValidateBundle(options) {
|
|
86
|
+
const filePath = options.file
|
|
87
|
+
? path.resolve(process.cwd(), options.file)
|
|
88
|
+
: resolveExampleBundle(options.example === "settlement" ? "settlement" : options.example === "identity" ? "identity" : "protocol");
|
|
89
|
+
const bundle = readJson(filePath);
|
|
90
|
+
const validation = validateIntegrationSubmissionBundle(bundle);
|
|
91
|
+
writeJson({
|
|
92
|
+
ok: validation.ok,
|
|
93
|
+
file: filePath,
|
|
94
|
+
errors: validation.errors
|
|
95
|
+
});
|
|
96
|
+
process.exitCode = validation.ok ? 0 : 1;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function runExportBundleSet(options) {
|
|
100
|
+
const payload = exportIntegrationSubmissionBundleSet({
|
|
101
|
+
source: "third_party_example",
|
|
102
|
+
bundled: "false"
|
|
103
|
+
}, options.notes || "generated by registry_cli");
|
|
104
|
+
writeJson(payload);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function runExportSnapshot(options) {
|
|
108
|
+
const snapshot = createIntegrationRegistrySnapshotFromBundles(
|
|
109
|
+
importExampleBundles(),
|
|
110
|
+
{ source: "third_party_example" },
|
|
111
|
+
{ source: "third_party_example" }
|
|
112
|
+
);
|
|
113
|
+
writeJson({
|
|
114
|
+
generated_by: "registry_cli",
|
|
115
|
+
mode: options.mode || "examples",
|
|
116
|
+
snapshot
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function runReviewBundle(options) {
|
|
121
|
+
const filePath = options.file
|
|
122
|
+
? path.resolve(process.cwd(), options.file)
|
|
123
|
+
: resolveExampleBundle(options.example === "settlement" ? "settlement" : options.example === "identity" ? "identity" : "protocol");
|
|
124
|
+
const bundle = readJson(filePath);
|
|
125
|
+
writeJson({
|
|
126
|
+
file: filePath,
|
|
127
|
+
review: summarizeIntegrationSubmissionBundleReview(bundle)
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function runReviewBundleSet(options) {
|
|
132
|
+
const payload = exportIntegrationSubmissionBundleSet({
|
|
133
|
+
source: "third_party_example",
|
|
134
|
+
bundled: "false"
|
|
135
|
+
}, options.notes || "generated by registry_cli");
|
|
136
|
+
writeJson({
|
|
137
|
+
review: summarizeIntegrationSubmissionBundleSetReview(payload)
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function runReviewSnapshot() {
|
|
142
|
+
const snapshot = createIntegrationRegistrySnapshotFromBundles(
|
|
143
|
+
importExampleBundles(),
|
|
144
|
+
{ source: "third_party_example" },
|
|
145
|
+
{ source: "third_party_example" }
|
|
146
|
+
);
|
|
147
|
+
writeJson({
|
|
148
|
+
review: summarizeIntegrationRegistrySnapshotReview(snapshot)
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function runPromotionReadiness(options) {
|
|
153
|
+
const integrationId = options.integration || "partner.protocol.acme_mcp";
|
|
154
|
+
writeJson({
|
|
155
|
+
integration_id: integrationId,
|
|
156
|
+
review: summarizeIntegrationPromotionReadiness(integrationId)
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function runPromotionWorkflow(options) {
|
|
161
|
+
const integrationId = options.integration || "partner.protocol.acme_mcp";
|
|
162
|
+
writeJson({
|
|
163
|
+
integration_id: integrationId,
|
|
164
|
+
review: summarizeIntegrationPromotionWorkflow(integrationId)
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function runPromotionWorkflowSummary(options) {
|
|
169
|
+
writeJson({
|
|
170
|
+
review: summarizeIntegrationPromotionWorkflowList({
|
|
171
|
+
source: options.source || "",
|
|
172
|
+
bundled: options.bundled || ""
|
|
173
|
+
})
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function runPromotionActionPreview(options) {
|
|
178
|
+
writeJson({
|
|
179
|
+
review: summarizeIntegrationPromotionActionPreview({
|
|
180
|
+
integration_id: options.integration || "partner.protocol.acme_mcp",
|
|
181
|
+
action: options.action || "complete_certification"
|
|
182
|
+
})
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function runPromotionActionSet(options) {
|
|
187
|
+
const integrationId = options.integration || "partner.protocol.acme_mcp";
|
|
188
|
+
writeJson({
|
|
189
|
+
integration_id: integrationId,
|
|
190
|
+
review: summarizeIntegrationPromotionActionSet(integrationId)
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function runPromotionActionSetSummary(options) {
|
|
195
|
+
writeJson({
|
|
196
|
+
review: summarizeIntegrationPromotionActionSetList({
|
|
197
|
+
source: options.source || "",
|
|
198
|
+
bundled: options.bundled || ""
|
|
199
|
+
})
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function main() {
|
|
204
|
+
const { command, options } = parseArgs(process.argv.slice(2));
|
|
205
|
+
if (command === "validate-bundle") {
|
|
206
|
+
runValidateBundle(options);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (command === "export-bundle-set") {
|
|
210
|
+
runExportBundleSet(options);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (command === "export-snapshot") {
|
|
214
|
+
runExportSnapshot(options);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (command === "review-bundle") {
|
|
218
|
+
runReviewBundle(options);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (command === "review-bundle-set") {
|
|
222
|
+
runReviewBundleSet(options);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (command === "review-snapshot") {
|
|
226
|
+
runReviewSnapshot();
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (command === "promotion-readiness") {
|
|
230
|
+
runPromotionReadiness(options);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (command === "promotion-workflow") {
|
|
234
|
+
runPromotionWorkflow(options);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (command === "promotion-workflow-summary") {
|
|
238
|
+
runPromotionWorkflowSummary(options);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (command === "promotion-action-preview") {
|
|
242
|
+
runPromotionActionPreview(options);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (command === "promotion-action-set") {
|
|
246
|
+
runPromotionActionSet(options);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
if (command === "promotion-action-set-summary") {
|
|
250
|
+
runPromotionActionSetSummary(options);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
writeJson({
|
|
255
|
+
ok: false,
|
|
256
|
+
usage: [
|
|
257
|
+
"node scripts/registry_cli.js validate-bundle [--file <path>] [--example protocol|settlement]",
|
|
258
|
+
"node scripts/registry_cli.js validate-bundle [--file <path>] [--example identity]",
|
|
259
|
+
"node scripts/registry_cli.js export-bundle-set [--notes <text>]",
|
|
260
|
+
"node scripts/registry_cli.js export-snapshot",
|
|
261
|
+
"node scripts/registry_cli.js review-bundle [--file <path>] [--example protocol|identity|settlement]",
|
|
262
|
+
"node scripts/registry_cli.js review-bundle-set [--notes <text>]",
|
|
263
|
+
"node scripts/registry_cli.js review-snapshot",
|
|
264
|
+
"node scripts/registry_cli.js promotion-readiness [--integration <integration_id>]",
|
|
265
|
+
"node scripts/registry_cli.js promotion-workflow [--integration <integration_id>]",
|
|
266
|
+
"node scripts/registry_cli.js promotion-workflow-summary [--source <source>] [--bundled true|false]",
|
|
267
|
+
"node scripts/registry_cli.js promotion-action-preview [--integration <integration_id>] [--action <action>]",
|
|
268
|
+
"node scripts/registry_cli.js promotion-action-set [--integration <integration_id>]",
|
|
269
|
+
"node scripts/registry_cli.js promotion-action-set-summary [--source <source>] [--bundled true|false]"
|
|
270
|
+
]
|
|
271
|
+
});
|
|
272
|
+
process.exitCode = 1;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
main();
|