@skrr-ai/cli 0.1.91 → 0.1.93
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/base-command.d.ts +44 -0
- package/dist/base-command.js +96 -0
- package/dist/commands/agents/badge.d.ts +41 -0
- package/dist/commands/agents/badge.js +158 -0
- package/dist/commands/agents/create.d.ts +24 -0
- package/dist/commands/agents/create.js +212 -0
- package/dist/commands/agents/embed.d.ts +20 -0
- package/dist/commands/agents/embed.js +61 -0
- package/dist/commands/agents/share.d.ts +27 -0
- package/dist/commands/agents/share.js +100 -0
- package/dist/commands/agents/vanity.d.ts +21 -0
- package/dist/commands/agents/vanity.js +77 -0
- package/dist/commands/agents/visibility.d.ts +21 -1
- package/dist/commands/agents/visibility.js +112 -0
- package/dist/commands/commands.d.ts +1 -0
- package/dist/commands/commands.js +22 -9
- package/dist/commands/earnings/attributions.d.ts +17 -0
- package/dist/commands/earnings/attributions.js +82 -0
- package/dist/commands/earnings/index.js +2 -1
- package/dist/commands/generate-recovery-code.js +4 -3
- package/dist/commands/github/allow-tools.d.ts +1 -0
- package/dist/commands/github/app/install.d.ts +1 -0
- package/dist/commands/github/app/status.d.ts +1 -0
- package/dist/commands/github/connect.d.ts +1 -0
- package/dist/commands/github/connections.d.ts +1 -0
- package/dist/commands/github/disconnect.d.ts +1 -0
- package/dist/commands/github/finalize.d.ts +1 -0
- package/dist/commands/github/reconnect.d.ts +1 -0
- package/dist/commands/github/run.d.ts +1 -0
- package/dist/commands/github/tools.d.ts +1 -0
- package/dist/commands/integrations/connections/connect.d.ts +1 -0
- package/dist/commands/integrations/connections/disconnect.d.ts +1 -0
- package/dist/commands/integrations/connections/finalize.d.ts +1 -0
- package/dist/commands/integrations/connections/list.d.ts +1 -0
- package/dist/commands/integrations/connections/reconnect.d.ts +1 -0
- package/dist/commands/integrations/execute.d.ts +1 -0
- package/dist/commands/integrations/search.d.ts +1 -0
- package/dist/commands/integrations/toolkits.d.ts +1 -0
- package/dist/commands/integrations/tools/allow.d.ts +1 -0
- package/dist/commands/integrations/tools/list.d.ts +1 -0
- package/dist/commands/login.js +12 -0
- package/dist/commands/machines/dedicated/logs.d.ts +19 -0
- package/dist/commands/machines/dedicated/logs.js +103 -0
- package/dist/commands/machines/dedicated/power/index.js +3 -2
- package/dist/commands/machines/dedicated/power/set.js +1 -1
- package/dist/commands/machines/dedicated/power/waiting.d.ts +13 -0
- package/dist/commands/machines/dedicated/power/waiting.js +36 -0
- package/dist/commands/open.d.ts +24 -0
- package/dist/commands/open.js +74 -0
- package/dist/commands/projects/archive.d.ts +1 -0
- package/dist/commands/projects/archive.js +23 -0
- package/dist/commands/projects/delete.d.ts +1 -0
- package/dist/commands/projects/delete.js +23 -0
- package/dist/commands/projects/list.d.ts +3 -0
- package/dist/commands/projects/list.js +12 -2
- package/dist/commands/spaces/actions/add.js +4 -3
- package/dist/commands/spaces/actions/available.js +3 -2
- package/dist/commands/spaces/actions/list.js +5 -4
- package/dist/commands/spaces/actions/replace.js +6 -5
- package/dist/commands/spaces/archive.js +3 -2
- package/dist/commands/spaces/auto-executor/preview.js +4 -3
- package/dist/commands/spaces/auto-executor/run.js +4 -3
- package/dist/commands/spaces/auto-executor/runs.js +3 -2
- package/dist/commands/spaces/auto-executor/update.js +4 -3
- package/dist/commands/spaces/bootstrap.js +3 -2
- package/dist/commands/spaces/briefs/delete.js +3 -2
- package/dist/commands/spaces/briefs/get.js +3 -2
- package/dist/commands/spaces/briefs/list.js +3 -2
- package/dist/commands/spaces/briefs/set.js +5 -4
- package/dist/commands/spaces/capacity.js +5 -4
- package/dist/commands/spaces/conversations.js +3 -2
- package/dist/commands/spaces/cycles/create.js +3 -2
- package/dist/commands/spaces/cycles/graph.js +2 -1
- package/dist/commands/spaces/cycles/list.js +3 -2
- package/dist/commands/spaces/cycles/settings.js +4 -3
- package/dist/commands/spaces/cycles/show.js +3 -2
- package/dist/commands/spaces/cycles/update.js +3 -2
- package/dist/commands/spaces/delete.js +4 -3
- package/dist/commands/spaces/expertise-suggestions.js +4 -3
- package/dist/commands/spaces/files/delete.js +3 -2
- package/dist/commands/spaces/files/folders/create.js +3 -2
- package/dist/commands/spaces/files/folders/delete.js +3 -2
- package/dist/commands/spaces/files/folders/list.js +3 -2
- package/dist/commands/spaces/files/folders/update.js +3 -2
- package/dist/commands/spaces/files/list.js +3 -2
- package/dist/commands/spaces/files/move.js +3 -2
- package/dist/commands/spaces/files/rename.js +3 -2
- package/dist/commands/spaces/files/upload.js +6 -5
- package/dist/commands/spaces/github-automations/set.js +3 -2
- package/dist/commands/spaces/github-automations/show.js +3 -2
- package/dist/commands/spaces/goals.js +2 -1
- package/dist/commands/spaces/heartbeats/create.js +4 -3
- package/dist/commands/spaces/heartbeats/delete.js +4 -3
- package/dist/commands/spaces/heartbeats/list.js +4 -3
- package/dist/commands/spaces/heartbeats/status.js +3 -2
- package/dist/commands/spaces/heartbeats/update.js +4 -3
- package/dist/commands/spaces/insights.js +5 -4
- package/dist/commands/spaces/labels/add.js +4 -3
- package/dist/commands/spaces/labels/list.js +2 -1
- package/dist/commands/spaces/labels/remove.js +4 -3
- package/dist/commands/spaces/list.d.ts +3 -0
- package/dist/commands/spaces/list.js +11 -2
- package/dist/commands/spaces/live/cards/create.js +3 -2
- package/dist/commands/spaces/live/cards/list.js +3 -2
- package/dist/commands/spaces/live/cards/reorder.js +7 -2
- package/dist/commands/spaces/live/scene.js +4 -3
- package/dist/commands/spaces/members/add.js +7 -6
- package/dist/commands/spaces/members/list.js +4 -3
- package/dist/commands/spaces/members/remove.js +7 -6
- package/dist/commands/spaces/move.js +3 -2
- package/dist/commands/spaces/pin.js +5 -4
- package/dist/commands/spaces/preferences/show.js +4 -3
- package/dist/commands/spaces/preferences/tabs.js +4 -3
- package/dist/commands/spaces/revisions.js +3 -2
- package/dist/commands/spaces/room/ensure.js +5 -4
- package/dist/commands/spaces/room/messages.js +3 -2
- package/dist/commands/spaces/room/show.js +5 -4
- package/dist/commands/spaces/skills/add.js +4 -3
- package/dist/commands/spaces/skills/list.js +3 -2
- package/dist/commands/spaces/skills/pin.js +4 -3
- package/dist/commands/spaces/skills/remove.js +4 -3
- package/dist/commands/spaces/snapshot.js +3 -2
- package/dist/commands/spaces/states/archive.js +3 -2
- package/dist/commands/spaces/states/create.js +3 -2
- package/dist/commands/spaces/states/list.js +3 -2
- package/dist/commands/spaces/states/reorder.js +2 -1
- package/dist/commands/spaces/states/update.js +3 -2
- package/dist/commands/spaces/summary.js +4 -3
- package/dist/commands/spaces/tasks.d.ts +3 -0
- package/dist/commands/spaces/tasks.js +14 -3
- package/dist/commands/spaces/triggers/delete.js +5 -4
- package/dist/commands/spaces/triggers/set.js +4 -3
- package/dist/commands/spaces/triggers/show.js +4 -3
- package/dist/commands/spaces/unarchive.js +3 -2
- package/dist/commands/spaces/update.js +5 -4
- package/dist/commands/spaces/views/create.js +3 -2
- package/dist/commands/spaces/views/list.js +3 -2
- package/dist/commands/spaces/views/reorder.js +6 -3
- package/dist/commands/spaces/views/subscribe.js +2 -1
- package/dist/commands/spaces/views/subscriptions.js +1 -0
- package/dist/commands/spaces/views/unsubscribe.js +2 -1
- package/dist/commands/spaces/widgets/add.js +4 -3
- package/dist/commands/spaces/widgets/list.js +3 -2
- package/dist/commands/spaces/widgets/remove.js +5 -4
- package/dist/commands/spaces/work-graph.js +2 -1
- package/dist/commands/store/install.d.ts +1 -1
- package/dist/commands/store/install.js +24 -8
- package/dist/commands/store/show.d.ts +25 -0
- package/dist/commands/store/show.js +203 -0
- package/dist/commands/store/stats.d.ts +33 -0
- package/dist/commands/store/stats.js +258 -0
- package/dist/commands/tasks/actions/attach.js +1 -1
- package/dist/commands/tasks/actions/detach.js +4 -3
- package/dist/commands/tasks/activity.js +3 -2
- package/dist/commands/tasks/ancestors.js +2 -1
- package/dist/commands/tasks/approvals/create.js +2 -1
- package/dist/commands/tasks/approvals/delete.js +3 -2
- package/dist/commands/tasks/approvals/list.js +5 -4
- package/dist/commands/tasks/approvals/resolve.js +2 -1
- package/dist/commands/tasks/archive.js +3 -2
- package/dist/commands/tasks/assign.js +4 -3
- package/dist/commands/tasks/attachments/delete.js +3 -2
- package/dist/commands/tasks/attachments/download.d.ts +1 -0
- package/dist/commands/tasks/attachments/download.js +20 -1
- package/dist/commands/tasks/attachments/list.js +2 -1
- package/dist/commands/tasks/attachments/set-role.js +2 -1
- package/dist/commands/tasks/attachments/upload.js +2 -1
- package/dist/commands/tasks/bulk-update.d.ts +1 -0
- package/dist/commands/tasks/bulk-update.js +106 -15
- package/dist/commands/tasks/cancel-cascade.d.ts +1 -0
- package/dist/commands/tasks/cancel-cascade.js +13 -3
- package/dist/commands/tasks/cascade-status.js +2 -1
- package/dist/commands/tasks/chat/send.d.ts +44 -0
- package/dist/commands/tasks/chat/send.js +112 -0
- package/dist/commands/tasks/checkout.js +3 -2
- package/dist/commands/tasks/children.js +2 -1
- package/dist/commands/tasks/comments/add.js +7 -6
- package/dist/commands/tasks/comments/anchor.js +8 -7
- package/dist/commands/tasks/comments/delete.js +3 -2
- package/dist/commands/tasks/comments/list.js +2 -1
- package/dist/commands/tasks/comments/reopen.js +3 -2
- package/dist/commands/tasks/comments/resolve.js +3 -2
- package/dist/commands/tasks/create-tree.d.ts +63 -0
- package/dist/commands/tasks/create-tree.js +197 -4
- package/dist/commands/tasks/delete.js +5 -4
- package/dist/commands/tasks/descendants.js +2 -1
- package/dist/commands/tasks/dri-plan.js +3 -2
- package/dist/commands/tasks/dri-run.js +3 -2
- package/dist/commands/tasks/dri-status.js +2 -1
- package/dist/commands/tasks/duplicate-pipeline.js +2 -1
- package/dist/commands/tasks/execution-summary.js +2 -1
- package/dist/commands/tasks/execution-timeline.js +2 -1
- package/dist/commands/tasks/fork.js +1 -0
- package/dist/commands/tasks/forward.js +4 -3
- package/dist/commands/tasks/handover.js +1 -0
- package/dist/commands/tasks/interrupt.js +3 -2
- package/dist/commands/tasks/labels/attach.js +4 -3
- package/dist/commands/tasks/labels/detach.js +4 -3
- package/dist/commands/tasks/labels/suggest.js +5 -4
- package/dist/commands/tasks/list.d.ts +27 -1
- package/dist/commands/tasks/list.js +101 -3
- package/dist/commands/tasks/move.js +4 -3
- package/dist/commands/tasks/output.js +6 -5
- package/dist/commands/tasks/pause-schedule.js +3 -2
- package/dist/commands/tasks/promote.js +1 -0
- package/dist/commands/tasks/prompt-log.js +2 -1
- package/dist/commands/tasks/release.js +5 -4
- package/dist/commands/tasks/remind.js +2 -1
- package/dist/commands/tasks/replay.js +3 -2
- package/dist/commands/tasks/report.js +1 -0
- package/dist/commands/tasks/resume-schedule.js +3 -2
- package/dist/commands/tasks/retry-schedule.js +3 -2
- package/dist/commands/tasks/retry.js +10 -9
- package/dist/commands/tasks/revisions.js +2 -1
- package/dist/commands/tasks/runs.js +6 -5
- package/dist/commands/tasks/schedule.js +3 -2
- package/dist/commands/tasks/self-schedule.js +6 -5
- package/dist/commands/tasks/skills/pin.js +3 -2
- package/dist/commands/tasks/skills/unpin.js +3 -2
- package/dist/commands/tasks/snooze.js +6 -5
- package/dist/commands/tasks/start-all.js +5 -4
- package/dist/commands/tasks/subscribe.js +1 -0
- package/dist/commands/tasks/tags/add.js +4 -3
- package/dist/commands/tasks/tags/remove.js +4 -3
- package/dist/commands/tasks/timeline.js +3 -2
- package/dist/commands/tasks/today.d.ts +4 -1
- package/dist/commands/tasks/today.js +12 -2
- package/dist/commands/tasks/transcript.js +6 -5
- package/dist/commands/tasks/unschedule.js +3 -2
- package/dist/commands/tasks/unsnooze.js +3 -2
- package/dist/commands/tasks/unsubscribe.js +2 -1
- package/dist/commands/tasks/update.js +5 -4
- package/dist/commands/tasks/wait.js +5 -4
- package/dist/lib/agent-distribution.d.ts +37 -0
- package/dist/lib/agent-distribution.js +63 -0
- package/dist/lib/agent-ref.d.ts +69 -0
- package/dist/lib/agent-ref.js +168 -0
- package/dist/lib/api-fetch.d.ts +2 -0
- package/dist/lib/api-fetch.js +14 -3
- package/dist/lib/command-hygiene.d.ts +13 -0
- package/dist/lib/command-hygiene.js +62 -2
- package/dist/lib/dedicated-power.d.ts +16 -1
- package/dist/lib/dedicated-power.js +153 -2
- package/dist/lib/dry-run-plans.d.ts +50 -0
- package/dist/lib/dry-run-plans.js +85 -0
- package/dist/lib/json-output.d.ts +31 -0
- package/dist/lib/json-output.js +78 -0
- package/dist/lib/list-output.d.ts +75 -0
- package/dist/lib/list-output.js +266 -0
- package/dist/lib/machine-daemon-log.d.ts +36 -0
- package/dist/lib/machine-daemon-log.js +78 -0
- package/dist/lib/node-adapter.js +10 -1
- package/dist/lib/open-target.d.ts +12 -0
- package/dist/lib/open-target.js +108 -0
- package/dist/lib/rate-limit-retry.d.ts +45 -0
- package/dist/lib/rate-limit-retry.js +88 -0
- package/dist/lib/store-listing.d.ts +45 -0
- package/dist/lib/store-listing.js +186 -0
- package/dist/lib/task-batch.d.ts +67 -0
- package/dist/lib/task-batch.js +227 -0
- package/dist/lib/terminal-qr.d.ts +55 -0
- package/dist/lib/terminal-qr.js +119 -0
- package/dist/lib/web-url.d.ts +11 -0
- package/dist/lib/web-url.js +24 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +68 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +47 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +68 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +46 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +6615 -6112
- package/oclif.manifest.json +41499 -32585
- package/package.json +2 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FROM_SPEC_COMPATIBLE_FLAGS = void 0;
|
|
3
4
|
exports.agentCreateMissingFieldsMessage = agentCreateMissingFieldsMessage;
|
|
4
5
|
exports.agentCreateMissingFields = agentCreateMissingFields;
|
|
5
6
|
exports.unappliedPayloadKeys = unappliedPayloadKeys;
|
|
@@ -15,6 +16,7 @@ const execution_target_1 = require("../../lib/execution-target");
|
|
|
15
16
|
const prompt_1 = require("../../lib/prompt");
|
|
16
17
|
const agent_config_1 = require("../../lib/agent-config");
|
|
17
18
|
const web_url_1 = require("../../lib/web-url");
|
|
19
|
+
const agent_spec_1 = require("../../lib/agent-spec");
|
|
18
20
|
/**
|
|
19
21
|
* OSK-4831 — build the missing-fields sentence from the real missing set.
|
|
20
22
|
*
|
|
@@ -138,6 +140,23 @@ function backgroundLoopLines(agentId, relationshipLoopsSkipped) {
|
|
|
138
140
|
' skrr agents create --no-relationship-loops # a single-purpose agent next time',
|
|
139
141
|
];
|
|
140
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* The flags `--from-spec` may be combined with: placement and identity for the
|
|
145
|
+
* NEW row, which a spec document deliberately cannot carry (where an agent runs
|
|
146
|
+
* is not portable). Every configuration flag is refused alongside it, because
|
|
147
|
+
* the file is the source — a flag that quietly overrode a line of it would
|
|
148
|
+
* leave git and the agent disagreeing from the first push.
|
|
149
|
+
*/
|
|
150
|
+
exports.FROM_SPEC_COMPATIBLE_FLAGS = Object.freeze([
|
|
151
|
+
'from-spec',
|
|
152
|
+
'json',
|
|
153
|
+
'name',
|
|
154
|
+
'target',
|
|
155
|
+
'next-target',
|
|
156
|
+
'working-directory',
|
|
157
|
+
'default-permission-mode',
|
|
158
|
+
'no-relationship-loops',
|
|
159
|
+
]);
|
|
141
160
|
class AgentsCreate extends base_command_1.BaseCommand {
|
|
142
161
|
static description = 'Create a new agent in the selected workspace, or in your default workspace when --workspace is omitted (`skrr workspaces list` names it)';
|
|
143
162
|
static examples = [
|
|
@@ -147,11 +166,19 @@ class AgentsCreate extends base_command_1.BaseCommand {
|
|
|
147
166
|
'<%= config.bin %> agents create --from-json agent.json',
|
|
148
167
|
'cat agent.json | <%= config.bin %> agents create --from-json -',
|
|
149
168
|
'<%= config.bin %> agents create --from-json template.json --name "Override name"',
|
|
169
|
+
'<%= config.bin %> agents create --from-spec agents/reviewer.agent.json',
|
|
170
|
+
'<%= config.bin %> agents create --from-spec agents/reviewer.agent.json --name "Reviewer (staging)" --target hosted-machine',
|
|
150
171
|
];
|
|
151
172
|
static flags = {
|
|
152
173
|
json: core_1.Flags.boolean({ description: 'Output the created agent as JSON' }),
|
|
153
174
|
'from-json': core_1.Flags.string({
|
|
154
175
|
description: 'Path to a JSON file (or "-" for stdin) to use as the request body',
|
|
176
|
+
exclusive: ['from-spec'],
|
|
177
|
+
}),
|
|
178
|
+
'from-spec': core_1.Flags.string({
|
|
179
|
+
description: 'Create the agent from an agent-as-code spec document (`skrr agents pull` writes one; "-" for stdin). ' +
|
|
180
|
+
'Checked with the same rules as `agents push`; a refused document leaves no agent behind',
|
|
181
|
+
exclusive: ['from-json'],
|
|
155
182
|
}),
|
|
156
183
|
// `--title` is an alias, not a rename (OSK-4850). tasks, spaces, projects,
|
|
157
184
|
// goals and `chats create` all name the thing with `--title`, so muscle
|
|
@@ -295,6 +322,10 @@ class AgentsCreate extends base_command_1.BaseCommand {
|
|
|
295
322
|
async run() {
|
|
296
323
|
this.requireAuth();
|
|
297
324
|
const { flags } = await this.parse(AgentsCreate);
|
|
325
|
+
if (flags['from-spec']) {
|
|
326
|
+
await this.createFromSpec(flags);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
298
329
|
// Default to {} so TS flow-analysis is satisfied — the catch calls this.error(), which throws.
|
|
299
330
|
let body = {};
|
|
300
331
|
try {
|
|
@@ -447,5 +478,186 @@ class AgentsCreate extends base_command_1.BaseCommand {
|
|
|
447
478
|
}
|
|
448
479
|
this.log(`URL: ${(0, web_url_1.withAgentUrl)(this.cliConfig.baseURL, a).url ?? '-'}`);
|
|
449
480
|
}
|
|
481
|
+
/**
|
|
482
|
+
* `agents create --from-spec <file>`: bootstrap a NEW agent from an
|
|
483
|
+
* agent-as-code document, so a repository can hold an agent before one
|
|
484
|
+
* exists (`agents push` needs an existing id).
|
|
485
|
+
*
|
|
486
|
+
* Two writes, one writer per concern. The create carries only what makes a
|
|
487
|
+
* row — its name, provider, model and placement — and every other field
|
|
488
|
+
* reaches the agent through the push endpoint, so the document is held to
|
|
489
|
+
* exactly the rules `agents push` and `agents validate` apply (portable
|
|
490
|
+
* fields only, no credentials, no withheld references, nothing push may not
|
|
491
|
+
* set). Validation runs first with no network. If the server then refuses
|
|
492
|
+
* the document, the agent just created is deleted again: a refused spec must
|
|
493
|
+
* not leave behind a half-configured agent that looks like it worked.
|
|
494
|
+
*/
|
|
495
|
+
async createFromSpec(flags) {
|
|
496
|
+
const source = String(flags['from-spec']);
|
|
497
|
+
const incompatible = Object.keys(flags)
|
|
498
|
+
// This command's own flags only: the global ones (--profile, --workspace,
|
|
499
|
+
// --token, --bare) choose WHO creates, not what is created.
|
|
500
|
+
.filter((flag) => Object.prototype.hasOwnProperty.call(AgentsCreate.flags, flag))
|
|
501
|
+
.filter((flag) => flags[flag] !== undefined && flags[flag] !== false)
|
|
502
|
+
.filter((flag) => !exports.FROM_SPEC_COMPATIBLE_FLAGS.includes(flag));
|
|
503
|
+
if (incompatible.length > 0) {
|
|
504
|
+
this.failWithCliError({
|
|
505
|
+
message: `--from-spec takes the agent's configuration from ${source}; ` +
|
|
506
|
+
`${incompatible.map((flag) => `--${flag}`).join(', ')} cannot be combined with it. ` +
|
|
507
|
+
'Edit the file instead (placement flags --target, --next-target, --working-directory, ' +
|
|
508
|
+
'--default-permission-mode, and --name, are accepted).',
|
|
509
|
+
code: 'AGENT_SPEC_FLAG_CONFLICT',
|
|
510
|
+
exit: 1,
|
|
511
|
+
retryable: false,
|
|
512
|
+
details: { incompatible },
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
let raw;
|
|
516
|
+
try {
|
|
517
|
+
raw = await (0, agent_spec_1.readSpecSource)(source);
|
|
518
|
+
}
|
|
519
|
+
catch (err) {
|
|
520
|
+
this.failWithCliError({
|
|
521
|
+
message: `Could not read ${source}: ${err.message}`,
|
|
522
|
+
code: 'AGENT_SPEC_READ_FAILED',
|
|
523
|
+
exit: 1,
|
|
524
|
+
retryable: true,
|
|
525
|
+
details: { path: source },
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
const parsed = (0, agent_spec_1.parseAndValidateAgentSpec)(raw, source);
|
|
529
|
+
if (!parsed.ok) {
|
|
530
|
+
this.failWithCliError({
|
|
531
|
+
message: parsed.message,
|
|
532
|
+
code: 'AGENT_SPEC_NOT_JSON',
|
|
533
|
+
exit: 1,
|
|
534
|
+
retryable: false,
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
if (!parsed.validation.ok) {
|
|
538
|
+
this.failWithCliError({
|
|
539
|
+
message: (0, agent_spec_1.issueBlock)(`Refused before sending: ${source} carries fields that may not travel. No agent was created.`, parsed.validation.issues),
|
|
540
|
+
code: 'AGENT_SPEC_INVALID',
|
|
541
|
+
exit: 1,
|
|
542
|
+
retryable: false,
|
|
543
|
+
details: { issues: parsed.validation.issues },
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
const document = parsed.validation.document;
|
|
547
|
+
const spec = { ...document.spec };
|
|
548
|
+
// `--name` renames the copy (a staging twin of a committed agent). It is
|
|
549
|
+
// written into the document too, or the push would rename it straight back.
|
|
550
|
+
if (typeof flags.name === 'string' && flags.name.trim())
|
|
551
|
+
spec.name = flags.name.trim();
|
|
552
|
+
const name = typeof spec.name === 'string' ? spec.name.trim() : '';
|
|
553
|
+
if (!name) {
|
|
554
|
+
this.failWithCliError({
|
|
555
|
+
message: `${source} has no "name" under "spec". Add one, or pass --name.`,
|
|
556
|
+
code: 'AGENT_CREATE_MISSING_FIELDS',
|
|
557
|
+
exit: 1,
|
|
558
|
+
retryable: false,
|
|
559
|
+
details: { missing: ['--name'] },
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
// Placement is never in a spec (it is not portable), so it defaults here
|
|
563
|
+
// exactly as a named create does, and the defaults are said out loud.
|
|
564
|
+
const appliedDefaults = [];
|
|
565
|
+
const provider = typeof spec.provider === 'string' && spec.provider ? spec.provider : 'agentic';
|
|
566
|
+
if (provider !== spec.provider)
|
|
567
|
+
appliedDefaults.push('provider=agentic');
|
|
568
|
+
const model = typeof spec.model === 'string' && spec.model ? spec.model : 'default';
|
|
569
|
+
if (model !== spec.model)
|
|
570
|
+
appliedDefaults.push('model=default');
|
|
571
|
+
let target = typeof flags.target === 'string' ? flags.target : undefined;
|
|
572
|
+
const nextTargets = flags['next-target'] ?? [];
|
|
573
|
+
if (!target) {
|
|
574
|
+
if (nextTargets.length > 0) {
|
|
575
|
+
this.error('--next-target requires --target.', { exit: 1 });
|
|
576
|
+
}
|
|
577
|
+
target = 'agent-worker';
|
|
578
|
+
appliedDefaults.push('target=agent-worker');
|
|
579
|
+
}
|
|
580
|
+
let executionPolicy;
|
|
581
|
+
try {
|
|
582
|
+
executionPolicy = (0, execution_target_1.buildExecutionOrderPatch)({
|
|
583
|
+
selectors: [target, ...nextTargets],
|
|
584
|
+
}).executionPolicy;
|
|
585
|
+
}
|
|
586
|
+
catch (err) {
|
|
587
|
+
this.error(err.message, { exit: 1 });
|
|
588
|
+
}
|
|
589
|
+
const payload = (0, prompt_1.mergeDefined)({}, {
|
|
590
|
+
name,
|
|
591
|
+
provider,
|
|
592
|
+
model,
|
|
593
|
+
executionPolicy,
|
|
594
|
+
workingDirectory: flags['working-directory'],
|
|
595
|
+
defaultPermissionMode: flags['default-permission-mode'],
|
|
596
|
+
relationshipLoops: flags['no-relationship-loops'] ? false : undefined,
|
|
597
|
+
});
|
|
598
|
+
let created;
|
|
599
|
+
try {
|
|
600
|
+
created = (await data_provider_1.dataService.createAgent(payload));
|
|
601
|
+
}
|
|
602
|
+
catch (err) {
|
|
603
|
+
this.handleApiError(err);
|
|
604
|
+
}
|
|
605
|
+
const agentId = String(created.id ?? created._id ?? '');
|
|
606
|
+
let pushed;
|
|
607
|
+
try {
|
|
608
|
+
pushed = await data_provider_1.dataService.pushAgentSpec(agentId, { ...document, spec });
|
|
609
|
+
}
|
|
610
|
+
catch (err) {
|
|
611
|
+
// Undo the create first, then report — whichever way the undo went.
|
|
612
|
+
let rollback;
|
|
613
|
+
try {
|
|
614
|
+
await data_provider_1.dataService.deleteAgent({ agent_id: agentId });
|
|
615
|
+
rollback = `The agent created for it (${agentId}) was deleted again.`;
|
|
616
|
+
}
|
|
617
|
+
catch (deleteErr) {
|
|
618
|
+
rollback =
|
|
619
|
+
`The agent created for it (${agentId}) could NOT be deleted ` +
|
|
620
|
+
`(${deleteErr.message}); remove it with \`skrr agents delete ${agentId}\`.`;
|
|
621
|
+
}
|
|
622
|
+
const refusal = (0, agent_spec_1.refusalIssues)(err);
|
|
623
|
+
this.failWithCliError({
|
|
624
|
+
message: refusal
|
|
625
|
+
? (0, agent_spec_1.issueBlock)(`The server refused ${source}. ${rollback}`, refusal.issues)
|
|
626
|
+
: `Could not apply ${source} (${err.message}). ${rollback}`,
|
|
627
|
+
code: refusal?.code ?? 'AGENT_SPEC_REFUSED',
|
|
628
|
+
status: err.status,
|
|
629
|
+
exit: 1,
|
|
630
|
+
retryable: !refusal,
|
|
631
|
+
details: { agentId, rolledBack: !rollback.includes('NOT'), issues: refusal?.issues },
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
if (flags.json) {
|
|
635
|
+
this.log(JSON.stringify({
|
|
636
|
+
agent: (0, web_url_1.withAgentUrl)(this.cliConfig.baseURL, created),
|
|
637
|
+
spec: {
|
|
638
|
+
source,
|
|
639
|
+
applied: pushed.applied,
|
|
640
|
+
unchanged: pushed.unchanged,
|
|
641
|
+
derived: pushed.derived ?? [],
|
|
642
|
+
untouched: pushed.untouched,
|
|
643
|
+
},
|
|
644
|
+
defaultsApplied: appliedDefaults,
|
|
645
|
+
}, null, 2));
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
const fields = [...pushed.applied, ...pushed.unchanged];
|
|
649
|
+
this.log(`Created agent ${agentId} — ${name}, from ${source} (${fields.length} field(s)).`);
|
|
650
|
+
if (appliedDefaults.length > 0)
|
|
651
|
+
this.log(`Defaults applied: ${appliedDefaults.join(', ')}`);
|
|
652
|
+
const derived = pushed.derived ?? [];
|
|
653
|
+
if (derived.length > 0) {
|
|
654
|
+
this.log(`Not taken from the file, because the server derives it from other fields: ${derived.join(', ')}.`);
|
|
655
|
+
}
|
|
656
|
+
this.log(`Keep the file in step: \`skrr agents push ${agentId} --file ${source === '-' ? '<file>' : source}\`.`);
|
|
657
|
+
for (const line of backgroundLoopLines(agentId, flags['no-relationship-loops'] === true)) {
|
|
658
|
+
this.log(line);
|
|
659
|
+
}
|
|
660
|
+
this.log(`URL: ${(0, web_url_1.withAgentUrl)(this.cliConfig.baseURL, created).url ?? '-'}`);
|
|
661
|
+
}
|
|
450
662
|
}
|
|
451
663
|
exports.default = AgentsCreate;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr agents embed <agent>` — the snippet that puts a listing CARD for a
|
|
4
|
+
* public agent on another site (agent-distribution-2026-10-08.md, "Embed").
|
|
5
|
+
*
|
|
6
|
+
* Mints (idempotently) your share code on the `embed` channel, so installs
|
|
7
|
+
* that start from the card are attributed to you and show up under that
|
|
8
|
+
* channel in the listing's funnel. The card is a listing, not a chat.
|
|
9
|
+
*/
|
|
10
|
+
export default class AgentsEmbed extends BaseCommand {
|
|
11
|
+
static description: string;
|
|
12
|
+
static examples: string[];
|
|
13
|
+
static args: {
|
|
14
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
15
|
+
};
|
|
16
|
+
static flags: {
|
|
17
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
18
|
+
};
|
|
19
|
+
run(): Promise<void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
const base_command_1 = require("../../base-command");
|
|
6
|
+
const web_url_1 = require("../../lib/web-url");
|
|
7
|
+
/**
|
|
8
|
+
* `skrr agents embed <agent>` — the snippet that puts a listing CARD for a
|
|
9
|
+
* public agent on another site (agent-distribution-2026-10-08.md, "Embed").
|
|
10
|
+
*
|
|
11
|
+
* Mints (idempotently) your share code on the `embed` channel, so installs
|
|
12
|
+
* that start from the card are attributed to you and show up under that
|
|
13
|
+
* channel in the listing's funnel. The card is a listing, not a chat.
|
|
14
|
+
*/
|
|
15
|
+
class AgentsEmbed extends base_command_1.BaseCommand {
|
|
16
|
+
static description = "Print the HTML snippet that embeds a public agent's listing card on another site, with your embed share code";
|
|
17
|
+
static examples = [
|
|
18
|
+
'<%= config.bin %> agents embed <agent-id>',
|
|
19
|
+
'<%= config.bin %> agents embed <agent-id> --json',
|
|
20
|
+
];
|
|
21
|
+
static args = {
|
|
22
|
+
id: core_1.Args.string({
|
|
23
|
+
description: 'Agent ID of a public Store listing',
|
|
24
|
+
required: true,
|
|
25
|
+
ignoreStdin: true,
|
|
26
|
+
}),
|
|
27
|
+
};
|
|
28
|
+
static flags = {
|
|
29
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON ({ code, snippet, cardUrl })' }),
|
|
30
|
+
};
|
|
31
|
+
async run() {
|
|
32
|
+
this.requireAuth();
|
|
33
|
+
const { args, flags } = await this.parse(AgentsEmbed);
|
|
34
|
+
let code;
|
|
35
|
+
try {
|
|
36
|
+
({ code } = await data_provider_1.dataService.mintDistributionCode({
|
|
37
|
+
entity: { kind: 'agent', id: args.id },
|
|
38
|
+
channel: 'embed',
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
// A private or missing agent answers ENTITY_NOT_FOUND: only a public
|
|
43
|
+
// listing can be embedded.
|
|
44
|
+
this.handleApiError(error, { subject: 'public agent listing' });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const origin = (0, web_url_1.webOrigin)(this.cliConfig.baseURL);
|
|
48
|
+
const snippet = (0, data_provider_1.buildAgentEmbedSnippet)({ origin, agentId: args.id, code });
|
|
49
|
+
const cardUrl = `${origin}${(0, data_provider_1.embedListingPath)(args.id, { code })}`;
|
|
50
|
+
if (flags.json) {
|
|
51
|
+
this.log(JSON.stringify({ code, snippet, cardUrl }, null, 2));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this.log('Paste this where the card should appear:');
|
|
55
|
+
this.log('');
|
|
56
|
+
this.log(snippet);
|
|
57
|
+
this.log('');
|
|
58
|
+
this.log(`Preview: ${cardUrl}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.default = AgentsEmbed;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr agents share <agent>` — the public, attributed link to a Store agent.
|
|
4
|
+
*
|
|
5
|
+
* Not `agent-shares`: that grants a NAMED person access to a private agent. A
|
|
6
|
+
* link is an address, not a permission (agent-distribution-2026-10-08,
|
|
7
|
+
* principle 1), so this works only for an agent with a public listing, and
|
|
8
|
+
* says what to do instead for one without.
|
|
9
|
+
*
|
|
10
|
+
* The printed URL carries the sharer's opaque code (`?s=`) and the channel
|
|
11
|
+
* (`?ch=`), so the publisher's analytics can say "this link drove N installs"
|
|
12
|
+
* without the link ever naming the sharer. Minting is idempotent: sharing the
|
|
13
|
+
* same agent the same way twice prints the same link.
|
|
14
|
+
*/
|
|
15
|
+
export default class AgentsShare extends BaseCommand {
|
|
16
|
+
static description: string;
|
|
17
|
+
static examples: string[];
|
|
18
|
+
static args: {
|
|
19
|
+
agent: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
20
|
+
};
|
|
21
|
+
static flags: {
|
|
22
|
+
channel: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
|
+
qr: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
25
|
+
};
|
|
26
|
+
run(): Promise<void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
const base_command_1 = require("../../base-command");
|
|
6
|
+
const agent_ref_1 = require("../../lib/agent-ref");
|
|
7
|
+
const agent_distribution_1 = require("../../lib/agent-distribution");
|
|
8
|
+
const terminal_qr_1 = require("../../lib/terminal-qr");
|
|
9
|
+
/** The channels a person sharing from a terminal can mean. */
|
|
10
|
+
const SHARE_CHANNELS = ['link', 'qr', 'cli'];
|
|
11
|
+
/**
|
|
12
|
+
* `skrr agents share <agent>` — the public, attributed link to a Store agent.
|
|
13
|
+
*
|
|
14
|
+
* Not `agent-shares`: that grants a NAMED person access to a private agent. A
|
|
15
|
+
* link is an address, not a permission (agent-distribution-2026-10-08,
|
|
16
|
+
* principle 1), so this works only for an agent with a public listing, and
|
|
17
|
+
* says what to do instead for one without.
|
|
18
|
+
*
|
|
19
|
+
* The printed URL carries the sharer's opaque code (`?s=`) and the channel
|
|
20
|
+
* (`?ch=`), so the publisher's analytics can say "this link drove N installs"
|
|
21
|
+
* without the link ever naming the sharer. Minting is idempotent: sharing the
|
|
22
|
+
* same agent the same way twice prints the same link.
|
|
23
|
+
*/
|
|
24
|
+
class AgentsShare extends base_command_1.BaseCommand {
|
|
25
|
+
static description = `Print a public, attributed link to a published agent — and a QR code a phone can scan (--qr). ` +
|
|
26
|
+
`For a private agent, use \`agent-shares create\`.`;
|
|
27
|
+
static examples = [
|
|
28
|
+
'<%= config.bin %> agents share agent_abc123',
|
|
29
|
+
'<%= config.bin %> agents share agent_abc123 --qr',
|
|
30
|
+
'<%= config.bin %> agents share https://skrr.ai/a/agent_abc123 --channel link',
|
|
31
|
+
'<%= config.bin %> agents share agent_abc123 --json',
|
|
32
|
+
];
|
|
33
|
+
static args = {
|
|
34
|
+
agent: core_1.Args.string({
|
|
35
|
+
description: 'The published agent: its id or a link to it',
|
|
36
|
+
required: true,
|
|
37
|
+
ignoreStdin: true,
|
|
38
|
+
}),
|
|
39
|
+
};
|
|
40
|
+
static flags = {
|
|
41
|
+
channel: core_1.Flags.string({
|
|
42
|
+
description: 'How you are sharing it, recorded on the link for analytics. Defaults to cli, or qr with --qr',
|
|
43
|
+
options: [...SHARE_CHANNELS],
|
|
44
|
+
}),
|
|
45
|
+
qr: core_1.Flags.boolean({
|
|
46
|
+
description: 'Also draw a QR code (only in an interactive terminal without NO_COLOR; the URL is always printed)',
|
|
47
|
+
}),
|
|
48
|
+
json: core_1.Flags.boolean({ description: 'Print {agentId, channel, code, url} as JSON' }),
|
|
49
|
+
};
|
|
50
|
+
async run() {
|
|
51
|
+
this.requireAuth();
|
|
52
|
+
const { args, flags } = await this.parse(AgentsShare);
|
|
53
|
+
const baseURL = this.cliConfig.baseURL;
|
|
54
|
+
let agentId;
|
|
55
|
+
try {
|
|
56
|
+
({ agentId } = await (0, agent_ref_1.resolveAgentRef)(args.agent, { baseURL }));
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
if (err instanceof agent_ref_1.AgentRefError) {
|
|
60
|
+
this.failWithCliError({ message: err.message, code: err.code, exit: 1, retryable: false });
|
|
61
|
+
}
|
|
62
|
+
this.handleApiError(err);
|
|
63
|
+
}
|
|
64
|
+
// Attribution is the SHARER's channel — the one this share is made through,
|
|
65
|
+
// never the channel of a link that was passed in to name the agent.
|
|
66
|
+
const channel = (flags.channel ?? (flags.qr ? 'qr' : 'cli'));
|
|
67
|
+
let link;
|
|
68
|
+
try {
|
|
69
|
+
link = await (0, agent_distribution_1.mintAgentShareLink)({ baseURL, agentId, channel });
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
if (err instanceof agent_distribution_1.AgentNotShareableError) {
|
|
73
|
+
this.failWithCliError({ message: err.message, code: err.code, exit: 1, retryable: false });
|
|
74
|
+
}
|
|
75
|
+
this.handleApiError(err, { subject: `agent ${agentId}` });
|
|
76
|
+
}
|
|
77
|
+
if (flags.json) {
|
|
78
|
+
this.log(JSON.stringify(link, null, 2));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (flags.qr) {
|
|
82
|
+
const decision = (0, terminal_qr_1.qrRenderDecision)(link.url);
|
|
83
|
+
if (decision.render) {
|
|
84
|
+
for (const line of (0, terminal_qr_1.renderQr)(link.url))
|
|
85
|
+
this.log(line);
|
|
86
|
+
this.log('');
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// The URL below is the share either way; say why the code is missing
|
|
90
|
+
// on stderr so a pipe still receives exactly one line.
|
|
91
|
+
this.logToStderr(`No QR code: ${decision.reason}. Share the link instead.`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
this.log(link.url);
|
|
95
|
+
if (process.stdout.isTTY) {
|
|
96
|
+
this.logToStderr(`Anyone with this link can open the listing on ${data_provider_1.BRAND.displayName}; installs through it are attributed to it.`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.default = AgentsShare;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AgentVanityView } from '@skrr-ai/data-provider';
|
|
2
|
+
import { BaseCommand } from '../../base-command';
|
|
3
|
+
/** The human rendering of a vanity view; exported for the spec. */
|
|
4
|
+
export declare function renderAgentVanity(view: AgentVanityView, origin: string, log: (line: string) => void): void;
|
|
5
|
+
/**
|
|
6
|
+
* `skrr agents vanity <agent>` — the agent's alias in your publisher namespace,
|
|
7
|
+
* `/@<handle>/<slug>`, which 301s to its canonical `/a/<id>` listing
|
|
8
|
+
* (agent-distribution-2026-10-08.md, "Vanity URLs").
|
|
9
|
+
*/
|
|
10
|
+
export default class AgentsVanity extends BaseCommand {
|
|
11
|
+
static description: string;
|
|
12
|
+
static examples: string[];
|
|
13
|
+
static args: {
|
|
14
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
15
|
+
};
|
|
16
|
+
static flags: {
|
|
17
|
+
slug: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
18
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
};
|
|
20
|
+
run(): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderAgentVanity = renderAgentVanity;
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
6
|
+
const base_command_1 = require("../../base-command");
|
|
7
|
+
const web_url_1 = require("../../lib/web-url");
|
|
8
|
+
const visibility_1 = require("./visibility");
|
|
9
|
+
/** The human rendering of a vanity view; exported for the spec. */
|
|
10
|
+
function renderAgentVanity(view, origin, log) {
|
|
11
|
+
if (view.path) {
|
|
12
|
+
log(`Vanity address: ${origin}${view.path}`);
|
|
13
|
+
}
|
|
14
|
+
else if (view.slug) {
|
|
15
|
+
log(`Slug: ${view.slug}`);
|
|
16
|
+
log('It starts resolving at /@<handle>/' + view.slug + ' once you claim a publisher handle.');
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
log('No vanity address yet.');
|
|
20
|
+
if (view.suggestedSlug) {
|
|
21
|
+
log(`Publishing (or --slug) would claim: ${view.suggestedSlug}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (view.retiredSlugs.length > 0) {
|
|
25
|
+
log(`Retired slugs (still resolve to this agent): ${view.retiredSlugs.join(', ')}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* `skrr agents vanity <agent>` — the agent's alias in your publisher namespace,
|
|
30
|
+
* `/@<handle>/<slug>`, which 301s to its canonical `/a/<id>` listing
|
|
31
|
+
* (agent-distribution-2026-10-08.md, "Vanity URLs").
|
|
32
|
+
*/
|
|
33
|
+
class AgentsVanity extends base_command_1.BaseCommand {
|
|
34
|
+
static description = "Show or change an agent's vanity address (/@<handle>/<slug>). A replaced slug keeps resolving to the same agent.";
|
|
35
|
+
static examples = [
|
|
36
|
+
'<%= config.bin %> agents vanity <agent-id>',
|
|
37
|
+
'<%= config.bin %> agents vanity <agent-id> --slug trip-planner',
|
|
38
|
+
'<%= config.bin %> agents vanity <agent-id> --json',
|
|
39
|
+
];
|
|
40
|
+
static args = {
|
|
41
|
+
id: core_1.Args.string({ description: 'Agent ID', required: true, ignoreStdin: true }),
|
|
42
|
+
};
|
|
43
|
+
static flags = {
|
|
44
|
+
slug: core_1.Flags.string({
|
|
45
|
+
description: 'Change the slug of a listed agent. Typed text is canonicalised (My Agent → my-agent); the old slug is retired and keeps working.',
|
|
46
|
+
}),
|
|
47
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
48
|
+
};
|
|
49
|
+
async run() {
|
|
50
|
+
this.requireAuth();
|
|
51
|
+
const { args, flags } = await this.parse(AgentsVanity);
|
|
52
|
+
let slug;
|
|
53
|
+
if (flags.slug !== undefined) {
|
|
54
|
+
const check = (0, data_provider_1.checkAgentSlug)(flags.slug);
|
|
55
|
+
if (!check.ok)
|
|
56
|
+
this.error((0, visibility_1.describeSlugRefusal)(flags.slug, check), { exit: 1 });
|
|
57
|
+
slug = check.slug;
|
|
58
|
+
}
|
|
59
|
+
let view;
|
|
60
|
+
try {
|
|
61
|
+
view =
|
|
62
|
+
slug !== undefined
|
|
63
|
+
? await data_provider_1.dataService.updateAgentVanity(args.id, { slug })
|
|
64
|
+
: await data_provider_1.dataService.getAgentVanity(args.id);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
this.handleApiError(error, { subject: 'agent' });
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (flags.json) {
|
|
71
|
+
this.log(JSON.stringify(view, null, 2));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
renderAgentVanity(view, (0, web_url_1.webOrigin)(this.cliConfig.baseURL), (line) => this.log(line));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.default = AgentsVanity;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { StoreReleaseLicense } from '@skrr-ai/data-provider';
|
|
1
|
+
import type { AgentSlugCheck, StoreReleaseLicense } from '@skrr-ai/data-provider';
|
|
2
2
|
import { BaseCommand } from '../../base-command';
|
|
3
3
|
/**
|
|
4
4
|
* `--capability-rationale <permission-key>=<note>` → the publisher notes a
|
|
@@ -29,6 +29,24 @@ export declare function buildReleaseLicense(licenseId: string | undefined, remix
|
|
|
29
29
|
license?: StoreReleaseLicense;
|
|
30
30
|
error?: string;
|
|
31
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* `--trial-brief <text|@file>` → the brief the server records on the release
|
|
34
|
+
* (`agents/trialBrief.ts`). A value starting with `@` names a file to read;
|
|
35
|
+
* `@@…` is the escape for a brief that itself begins with `@`. Validated with
|
|
36
|
+
* the server's own normalizer so an over-long brief is refused here, before a
|
|
37
|
+
* request, with the same limit.
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveTrialBrief(value: string | undefined, readFile?: (path: string) => string): {
|
|
40
|
+
trialBrief?: string;
|
|
41
|
+
error?: string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Whether a release published with these terms keeps its instructions from
|
|
45
|
+
* the public — the case where, without a brief, its listing has no trial.
|
|
46
|
+
*/
|
|
47
|
+
export declare function releaseIsSealed(price: number | undefined, sourceVisibility?: string): boolean;
|
|
48
|
+
/** One sentence for a slug the shared check refused, naming the canonical form. */
|
|
49
|
+
export declare function describeSlugRefusal(input: string, check: AgentSlugCheck): string;
|
|
32
50
|
export default class AgentsVisibility extends BaseCommand {
|
|
33
51
|
static description: string;
|
|
34
52
|
static examples: string[];
|
|
@@ -49,6 +67,8 @@ export default class AgentsVisibility extends BaseCommand {
|
|
|
49
67
|
dependency: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
50
68
|
license: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
51
69
|
remix: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
70
|
+
slug: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
71
|
+
'trial-brief': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
52
72
|
'source-visibility': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
53
73
|
};
|
|
54
74
|
run(): Promise<void>;
|