@topolo/cli 0.7.1 → 0.7.3
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/index.js +59 -4
- package/package.json +2 -2
- package/skills/topolo/SKILL.md +2 -2
package/dist/index.js
CHANGED
|
@@ -4644,6 +4644,18 @@ function emit(data, mode, pretty) {
|
|
|
4644
4644
|
process.stdout.write(pretty() + "\n");
|
|
4645
4645
|
}
|
|
4646
4646
|
}
|
|
4647
|
+
function handleOutputStreamError(err, exit = process.exit) {
|
|
4648
|
+
if (err?.code === "EPIPE") {
|
|
4649
|
+
exit(0);
|
|
4650
|
+
return;
|
|
4651
|
+
}
|
|
4652
|
+
throw err;
|
|
4653
|
+
}
|
|
4654
|
+
function installOutputErrorHandlers(stdout = process.stdout, stderr = process.stderr, exit = process.exit) {
|
|
4655
|
+
const handler = (err) => handleOutputStreamError(err, exit);
|
|
4656
|
+
stdout.on("error", handler);
|
|
4657
|
+
stderr.on("error", handler);
|
|
4658
|
+
}
|
|
4647
4659
|
function fail(err, mode) {
|
|
4648
4660
|
const payload = normalizeError(err);
|
|
4649
4661
|
if (mode === "json") {
|
|
@@ -5268,20 +5280,62 @@ function registerActionsCommand(program2) {
|
|
|
5268
5280
|
fail(err, mode);
|
|
5269
5281
|
}
|
|
5270
5282
|
});
|
|
5271
|
-
actions.command("capabilities").description("List every published action for one application (its capability contract)").option("-s, --service <service>", "App id, slug, or name").option("--detail", "Include full schemas and agent contracts").option("--json", "Output JSON").option("--no-json", "Output human-readable table").action(async (opts, command) => {
|
|
5283
|
+
actions.command("capabilities").description("List every published action for one application (its capability contract)").option("-s, --service <service>", "App id, slug, or name").option("--summary", "Return compact capability counts without action rows").option("--detail", "Include full schemas and agent contracts").option("--json", "Output JSON").option("--no-json", "Output human-readable table").action(async (opts, command) => {
|
|
5272
5284
|
const mode = resolveOutputMode(opts.json ?? command.parent?.opts().json);
|
|
5273
5285
|
try {
|
|
5274
5286
|
const topolo = await requiredClient();
|
|
5275
5287
|
const service = opts.service || command.parent?.opts().service;
|
|
5276
5288
|
if (!service?.trim()) throw new Error("--service is required for capability discovery");
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5289
|
+
if (opts.summary && detailRequested(opts.detail, command)) {
|
|
5290
|
+
throw new Error("--summary cannot be combined with --detail");
|
|
5291
|
+
}
|
|
5292
|
+
const resolvedService = service.trim();
|
|
5293
|
+
const discovered = [];
|
|
5294
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
5295
|
+
let cursor;
|
|
5296
|
+
for (; ; ) {
|
|
5297
|
+
const page = await topolo.client.searchActions({
|
|
5298
|
+
service: resolvedService,
|
|
5299
|
+
limit: 100,
|
|
5300
|
+
...cursor ? { cursor } : {}
|
|
5301
|
+
});
|
|
5302
|
+
discovered.push(...page.actions);
|
|
5303
|
+
if (!page.page.hasMore) break;
|
|
5304
|
+
const nextCursor = page.page.nextCursor?.trim();
|
|
5305
|
+
if (!nextCursor || seenCursors.has(nextCursor)) {
|
|
5306
|
+
throw new Error("Capability discovery returned an invalid continuation cursor.");
|
|
5307
|
+
}
|
|
5308
|
+
seenCursors.add(nextCursor);
|
|
5309
|
+
cursor = nextCursor;
|
|
5310
|
+
}
|
|
5311
|
+
const result = { actions: discovered, page: { nextCursor: null, hasMore: false } };
|
|
5312
|
+
const output2 = opts.summary ? summarizeActionCapabilities(resolvedService, discovered) : detailRequested(opts.detail, command) ? result : { actions: discovered.map(compactActionCatalogEntry), page: result.page };
|
|
5313
|
+
emit(output2, mode, () => opts.summary ? formatActionCapabilitySummary(summarizeActionCapabilities(resolvedService, discovered)) : formatActionRows(discovered));
|
|
5280
5314
|
} catch (err) {
|
|
5281
5315
|
fail(err, mode);
|
|
5282
5316
|
}
|
|
5283
5317
|
});
|
|
5284
5318
|
}
|
|
5319
|
+
function summarizeActionCapabilities(service, actions) {
|
|
5320
|
+
return {
|
|
5321
|
+
service,
|
|
5322
|
+
total: actions.length,
|
|
5323
|
+
readOnly: actions.filter((action) => action.readOnly).length,
|
|
5324
|
+
mutating: actions.filter((action) => !action.readOnly).length,
|
|
5325
|
+
destructive: actions.filter((action) => action.destructive).length,
|
|
5326
|
+
confirmationRequired: actions.filter((action) => action.requiresConfirmation).length,
|
|
5327
|
+
resourceTypes: [...new Set(actions.map((action) => action.agentContract?.resource?.kind).filter(Boolean))].sort()
|
|
5328
|
+
};
|
|
5329
|
+
}
|
|
5330
|
+
function formatActionCapabilitySummary(summary) {
|
|
5331
|
+
return [
|
|
5332
|
+
`Service: ${summary.service}`,
|
|
5333
|
+
`Actions: ${summary.total} (${summary.readOnly} read-only, ${summary.mutating} mutating)`,
|
|
5334
|
+
`Destructive: ${summary.destructive}`,
|
|
5335
|
+
`Confirmation required: ${summary.confirmationRequired}`,
|
|
5336
|
+
`Resource types: ${summary.resourceTypes.join(", ") || "-"}`
|
|
5337
|
+
].join("\n");
|
|
5338
|
+
}
|
|
5285
5339
|
function detailRequested(local, command) {
|
|
5286
5340
|
return local === true || command.parent?.opts().detail === true;
|
|
5287
5341
|
}
|
|
@@ -13697,6 +13751,7 @@ Workspace: ${workspace.name} (${workspace.id})${workspace.isDefault ? "\nDefault
|
|
|
13697
13751
|
}
|
|
13698
13752
|
|
|
13699
13753
|
// src/index.ts
|
|
13754
|
+
installOutputErrorHandlers();
|
|
13700
13755
|
var program = new Command();
|
|
13701
13756
|
var argv;
|
|
13702
13757
|
try {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topolo/cli",
|
|
3
|
-
"version": "0.7.
|
|
4
|
-
"topoloPublishedVersion": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
|
+
"topoloPublishedVersion": "0.7.3",
|
|
5
5
|
"description": "Command-line interface for Topolo developers, operators, and agents, with internal first-party scaffolding available under the topolo platform namespace.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
package/skills/topolo/SKILL.md
CHANGED
|
@@ -169,7 +169,7 @@ For large inputs, write one schema-valid JSON object to a file and pass it witho
|
|
|
169
169
|
|
|
170
170
|
```bash
|
|
171
171
|
topolo actions validate <action-id> --data @payload.json --json
|
|
172
|
-
topolo actions plan <action-id> --data @payload.json --json
|
|
172
|
+
topolo actions plan <action-id> --data @payload.json --confirm --json
|
|
173
173
|
topolo actions call <action-id> --data @payload.json --confirm --json
|
|
174
174
|
```
|
|
175
175
|
|
|
@@ -183,7 +183,7 @@ topolo actions plan <action-id> --data '<json>' --json
|
|
|
183
183
|
|
|
184
184
|
MCP: `topolo_plan_action`.
|
|
185
185
|
|
|
186
|
-
The plan must be valid and must expose the resolved request, confirmation requirement, verification steps, and rollback when one is published.
|
|
186
|
+
The plan must be valid and must expose the resolved request, confirmation requirement, verification steps, and rollback when one is published. For a mutation that the user has already authorized, include `--confirm` in the plan so `executable` reflects the exact confirmed call; planning never executes the action. Before approval, omit `--confirm`, present the plan, and treat `executable: false` with `confirmationRequired: true` and `confirmationProvided: false` as awaiting approval rather than an invalid contract. Once approval is obtained, call the unchanged request with `--confirm` without planning it a second time. Any other `executable: false` result blocks the call.
|
|
187
187
|
|
|
188
188
|
### 6. Confirm mutations
|
|
189
189
|
|