@skrr-ai/cli 0.1.21 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -73
- package/bin/dev-fallback.js +221 -0
- package/bin/run.js +43 -0
- package/dist/base-command.d.ts +15 -0
- package/dist/base-command.js +71 -10
- package/dist/commands/agents/attach-harness.d.ts +37 -0
- package/dist/commands/agents/attach-harness.js +102 -3
- package/dist/commands/agents/chat.d.ts +69 -1
- package/dist/commands/agents/chat.js +202 -22
- package/dist/commands/agents/create.d.ts +38 -0
- package/dist/commands/agents/create.js +95 -2
- package/dist/commands/agents/schedule-trace.js +11 -0
- package/dist/commands/agents/show.js +29 -1
- package/dist/commands/api-keys/create.d.ts +24 -0
- package/dist/commands/api-keys/create.js +80 -0
- package/dist/commands/api-keys/list.d.ts +11 -0
- package/dist/commands/api-keys/list.js +42 -0
- package/dist/commands/api-keys/revoke.d.ts +14 -0
- package/dist/commands/api-keys/revoke.js +33 -0
- package/dist/commands/api-keys/rotate.d.ts +19 -0
- package/dist/commands/api-keys/rotate.js +42 -0
- package/dist/commands/balance/index.d.ts +18 -0
- package/dist/commands/balance/index.js +29 -0
- package/dist/commands/balance/show.d.ts +25 -0
- package/dist/commands/balance/show.js +60 -0
- package/dist/commands/balance/statement.d.ts +19 -0
- package/dist/commands/balance/statement.js +52 -0
- package/dist/commands/browser/doctor.d.ts +11 -0
- package/dist/commands/browser/doctor.js +11 -0
- package/dist/commands/code/jobs/approve.d.ts +25 -0
- package/dist/commands/code/jobs/approve.js +52 -0
- package/dist/commands/code/jobs/cancel.d.ts +12 -0
- package/dist/commands/code/jobs/cancel.js +39 -0
- package/dist/commands/code/jobs/index.d.ts +19 -0
- package/dist/commands/code/jobs/index.js +38 -0
- package/dist/commands/code/jobs/list.d.ts +12 -0
- package/dist/commands/code/jobs/list.js +87 -0
- package/dist/commands/code/jobs/run.d.ts +32 -0
- package/dist/commands/code/jobs/run.js +151 -0
- package/dist/commands/code/jobs/show.d.ts +12 -0
- package/dist/commands/code/jobs/show.js +86 -0
- package/dist/commands/commitments/create.d.ts +1 -0
- package/dist/commands/commitments/create.js +19 -5
- package/dist/commands/commitments/preflight.js +18 -4
- package/dist/commands/commitments/receipt-metrics.d.ts +39 -0
- package/dist/commands/commitments/receipt-metrics.js +78 -0
- package/dist/commands/convos/search.js +5 -5
- package/dist/commands/harnesses/leases/list.d.ts +3 -0
- package/dist/commands/harnesses/leases/list.js +59 -12
- package/dist/commands/harnesses/leases/show.js +36 -0
- package/dist/commands/harnesses/list.d.ts +18 -0
- package/dist/commands/harnesses/list.js +30 -0
- package/dist/commands/harnesses/products.js +48 -3
- package/dist/commands/harnesses/quota.d.ts +16 -0
- package/dist/commands/harnesses/quota.js +26 -1
- package/dist/commands/harnesses/usage.js +17 -0
- package/dist/commands/inbox/index.d.ts +2 -1
- package/dist/commands/inbox/index.js +27 -4
- package/dist/commands/login.js +4 -1
- package/dist/commands/machines/list.d.ts +1 -0
- package/dist/commands/machines/list.js +33 -5
- package/dist/commands/memory/approvals/issue.d.ts +18 -0
- package/dist/commands/memory/approvals/issue.js +63 -0
- package/dist/commands/memory/commit.js +5 -2
- package/dist/commands/memory/context.d.ts +3 -2
- package/dist/commands/memory/context.js +9 -11
- package/dist/commands/memory/delete.d.ts +1 -1
- package/dist/commands/memory/list.d.ts +1 -1
- package/dist/commands/memory/list.js +1 -1
- package/dist/commands/memory/mounts/resolve.d.ts +10 -0
- package/dist/commands/memory/mounts/resolve.js +27 -0
- package/dist/commands/memory/proposals/commit.d.ts +18 -0
- package/dist/commands/memory/proposals/commit.js +32 -0
- package/dist/commands/memory/proposals/create.d.ts +18 -0
- package/dist/commands/memory/proposals/create.js +56 -0
- package/dist/commands/memory/proposals/list.d.ts +13 -0
- package/dist/commands/memory/proposals/list.js +31 -0
- package/dist/commands/memory/proposals/promote.d.ts +22 -0
- package/dist/commands/memory/proposals/promote.js +33 -0
- package/dist/commands/memory/proposals/reject.d.ts +16 -0
- package/dist/commands/memory/proposals/reject.js +28 -0
- package/dist/commands/memory/rebuild-index.d.ts +20 -0
- package/dist/commands/memory/rebuild-index.js +25 -0
- package/dist/commands/memory/save.d.ts +1 -1
- package/dist/commands/memory/save.js +1 -1
- package/dist/commands/memory/search.d.ts +6 -3
- package/dist/commands/memory/search.js +27 -3
- package/dist/commands/memory/show.d.ts +1 -1
- package/dist/commands/memory/stores/archive.d.ts +14 -0
- package/dist/commands/memory/stores/archive.js +31 -0
- package/dist/commands/memory/stores/create.d.ts +12 -0
- package/dist/commands/memory/stores/create.js +30 -0
- package/dist/commands/memory/stores/delete.d.ts +15 -0
- package/dist/commands/memory/stores/delete.js +38 -0
- package/dist/commands/memory/stores/list.d.ts +10 -0
- package/dist/commands/memory/stores/list.js +29 -0
- package/dist/commands/memory/stores/show.d.ts +12 -0
- package/dist/commands/memory/stores/show.js +14 -0
- package/dist/commands/memory/stores/update.d.ts +15 -0
- package/dist/commands/memory/stores/update.js +39 -0
- package/dist/commands/memory/sync/delete.d.ts +13 -0
- package/dist/commands/memory/sync/delete.js +35 -0
- package/dist/commands/memory/sync/pull.d.ts +19 -0
- package/dist/commands/memory/sync/pull.js +52 -0
- package/dist/commands/memory/sync/push.d.ts +18 -0
- package/dist/commands/memory/sync/push.js +115 -0
- package/dist/commands/memory/sync/resolve.d.ts +23 -0
- package/dist/commands/memory/sync/resolve.js +27 -0
- package/dist/commands/memory/sync/status.d.ts +9 -0
- package/dist/commands/memory/sync/status.js +22 -0
- package/dist/commands/memory/topics/archive.d.ts +20 -0
- package/dist/commands/memory/topics/archive.js +29 -0
- package/dist/commands/memory/topics/create.d.ts +23 -0
- package/dist/commands/memory/topics/create.js +46 -0
- package/dist/commands/memory/topics/delete.d.ts +22 -0
- package/dist/commands/memory/topics/delete.js +30 -0
- package/dist/commands/memory/topics/forget.d.ts +22 -0
- package/dist/commands/memory/topics/forget.js +29 -0
- package/dist/commands/memory/topics/list.d.ts +13 -0
- package/dist/commands/memory/topics/list.js +22 -0
- package/dist/commands/memory/topics/move.d.ts +22 -0
- package/dist/commands/memory/topics/move.js +26 -0
- package/dist/commands/memory/topics/show.d.ts +17 -0
- package/dist/commands/memory/topics/show.js +21 -0
- package/dist/commands/memory/topics/update.d.ts +23 -0
- package/dist/commands/memory/topics/update.js +27 -0
- package/dist/commands/memory/tree.d.ts +5 -2
- package/dist/commands/memory/tree.js +20 -2
- package/dist/commands/memory/update.d.ts +1 -1
- package/dist/commands/memory/versions/list.d.ts +16 -0
- package/dist/commands/memory/versions/list.js +22 -0
- package/dist/commands/memory/versions/redact.d.ts +21 -0
- package/dist/commands/memory/versions/redact.js +22 -0
- package/dist/commands/memory/versions/restore.d.ts +20 -0
- package/dist/commands/memory/versions/restore.js +16 -0
- package/dist/commands/memory/versions/show.d.ts +15 -0
- package/dist/commands/memory/versions/show.js +17 -0
- package/dist/commands/messages/list.js +25 -8
- package/dist/commands/messages/show.js +10 -0
- package/dist/commands/store/install.js +5 -1
- package/dist/commands/store/releases.js +1 -1
- package/dist/commands/store/update.js +5 -1
- package/dist/commands/subscriptions/cancel.js +5 -1
- package/dist/commands/subscriptions/health.js +5 -1
- package/dist/commands/subscriptions/status.js +5 -1
- package/dist/commands/subscriptions/subscribe.js +5 -1
- package/dist/commands/tasks/activity.d.ts +2 -3
- package/dist/commands/tasks/activity.js +15 -5
- package/dist/commands/tasks/complete.d.ts +18 -150
- package/dist/commands/tasks/complete.js +161 -600
- package/dist/commands/tasks/create.d.ts +5 -0
- package/dist/commands/tasks/create.js +107 -4
- package/dist/commands/tasks/deliverable/add.d.ts +8 -0
- package/dist/commands/tasks/deliverable/add.js +41 -8
- package/dist/commands/tasks/deliverable/confirm.d.ts +5 -5
- package/dist/commands/tasks/deliverable/confirm.js +9 -18
- package/dist/commands/tasks/deliverable/list.d.ts +12 -0
- package/dist/commands/tasks/deliverable/list.js +37 -0
- package/dist/commands/tasks/events/append.d.ts +2 -0
- package/dist/commands/tasks/events/append.js +11 -4
- package/dist/commands/tasks/events/list.d.ts +1 -0
- package/dist/commands/tasks/events/list.js +1 -0
- package/dist/commands/tasks/events/tail.d.ts +1 -0
- package/dist/commands/tasks/events/tail.js +1 -0
- package/dist/commands/tasks/expectations/assess.d.ts +21 -0
- package/dist/commands/tasks/expectations/assess.js +77 -0
- package/dist/commands/tasks/expectations.js +14 -18
- package/dist/commands/tasks/judge.d.ts +1 -0
- package/dist/commands/tasks/judge.js +2 -1
- package/dist/commands/tasks/output.d.ts +2 -11
- package/dist/commands/tasks/output.js +64 -145
- package/dist/commands/tasks/report.d.ts +3 -3
- package/dist/commands/tasks/report.js +64 -41
- package/dist/commands/tasks/resource/add.d.ts +23 -0
- package/dist/commands/tasks/resource/add.js +76 -0
- package/dist/commands/tasks/resource/list.d.ts +13 -0
- package/dist/commands/tasks/resource/list.js +41 -0
- package/dist/commands/tasks/result/show.d.ts +13 -0
- package/dist/commands/tasks/result/show.js +46 -0
- package/dist/commands/tasks/result/submit.d.ts +26 -0
- package/dist/commands/tasks/result/submit.js +134 -0
- package/dist/commands/tasks/resume/save.d.ts +16 -0
- package/dist/commands/tasks/resume/save.js +59 -0
- package/dist/commands/tasks/resume/show.d.ts +13 -0
- package/dist/commands/tasks/resume/show.js +35 -0
- package/dist/commands/tasks/review.d.ts +17 -0
- package/dist/commands/tasks/review.js +54 -0
- package/dist/commands/tasks/runs.js +5 -0
- package/dist/commands/tasks/timeline.d.ts +2 -2
- package/dist/commands/tasks/timeline.js +10 -23
- package/dist/commands/tasks/updates/add.d.ts +22 -0
- package/dist/commands/tasks/updates/add.js +101 -0
- package/dist/commands/tasks/updates/list.d.ts +15 -0
- package/dist/commands/tasks/updates/list.js +57 -0
- package/dist/commands/tasks/waive.d.ts +1 -0
- package/dist/commands/tasks/waive.js +2 -1
- package/dist/lib/agentic-stream.d.ts +257 -0
- package/dist/lib/agentic-stream.js +490 -33
- package/dist/lib/balance.d.ts +8 -0
- package/dist/lib/commitment-product.d.ts +10 -1
- package/dist/lib/commitment-product.js +66 -2
- package/dist/lib/commitments.d.ts +4 -1
- package/dist/lib/commitments.js +32 -1
- package/dist/lib/conversation-search.d.ts +3 -0
- package/dist/lib/conversation-search.js +75 -0
- package/dist/lib/execution-target.d.ts +21 -0
- package/dist/lib/execution-target.js +22 -6
- package/dist/lib/harnesses.d.ts +82 -6
- package/dist/lib/harnesses.js +30 -2
- package/dist/lib/hosted-machines.js +9 -0
- package/dist/lib/inbox.d.ts +2 -1
- package/dist/lib/machines.d.ts +17 -0
- package/dist/lib/machines.js +29 -0
- package/dist/lib/managed-agent-keys.d.ts +104 -0
- package/dist/lib/managed-agent-keys.js +50 -0
- package/dist/lib/memory-scope.d.ts +4 -3
- package/dist/lib/memory-scope.js +9 -9
- package/dist/lib/memory-sync.d.ts +114 -0
- package/dist/lib/memory-sync.js +730 -0
- package/dist/lib/message-provenance.d.ts +42 -0
- package/dist/lib/message-provenance.js +89 -0
- package/dist/lib/scoped-memory-command.d.ts +68 -0
- package/dist/lib/scoped-memory-command.js +183 -0
- package/dist/lib/session-task-endpoints.d.ts +1 -1
- package/dist/lib/session-task-endpoints.js +7 -0
- package/dist/lib/sky-code-broker.d.ts +47 -0
- package/dist/lib/sky-code-broker.js +50 -0
- package/dist/lib/sky-code-doctor.js +10 -1
- package/dist/lib/task-artifact-flags.d.ts +2 -0
- package/dist/lib/task-artifact-flags.js +7 -0
- package/dist/lib/task-execution.d.ts +4 -5
- package/dist/lib/task-execution.js +4 -5
- package/dist/lib/task-extras.d.ts +1 -5
- package/dist/lib/task-extras.js +1 -5
- package/dist/lib/task-transcript.d.ts +5 -7
- package/dist/lib/task-transcript.js +8 -16
- package/dist/lib/tasks.d.ts +7 -21
- package/dist/lib/tasks.js +17 -20
- package/dist/lib/triggers.d.ts +39 -1
- package/dist/lib/triggers.js +70 -2
- package/dist/lib/usage-discovery.d.ts +17 -1
- package/dist/lib/usage-discovery.js +17 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +3733 -3618
- package/oclif.manifest.json +25726 -19886
- package/package.json +26 -5
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../base-command");
|
|
5
|
+
const managed_agent_keys_1 = require("../../lib/managed-agent-keys");
|
|
6
|
+
/**
|
|
7
|
+
* Mint a Managed Agents API key for a Space.
|
|
8
|
+
*
|
|
9
|
+
* The secret is displayed EXACTLY ONCE. There is no endpoint that reveals it
|
|
10
|
+
* again, so this command says that where the value is printed rather than in a
|
|
11
|
+
* footnote — a caller that scrolls past it has to rotate.
|
|
12
|
+
*/
|
|
13
|
+
class ApiKeysCreate extends base_command_1.BaseCommand {
|
|
14
|
+
static description = 'Mint a Managed Agents API key (osk_*) for a Space. The secret is shown once and never again.';
|
|
15
|
+
static examples = [
|
|
16
|
+
'<%= config.bin %> api-keys create --space <space-id> --name "ci"',
|
|
17
|
+
'<%= config.bin %> api-keys create --space <space-id> --name "probe" --env test --scope environments:write',
|
|
18
|
+
];
|
|
19
|
+
static args = {
|
|
20
|
+
name: core_1.Args.string({
|
|
21
|
+
description: 'Human label for the key (also settable with --name)',
|
|
22
|
+
// A positional that reads stdin would swallow a piped secret or script.
|
|
23
|
+
ignoreStdin: true,
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
static flags = {
|
|
27
|
+
space: core_1.Flags.string({ description: 'Space that owns the key', required: true }),
|
|
28
|
+
name: core_1.Flags.string({ description: 'Human label for the key (≤200 chars)' }),
|
|
29
|
+
env: core_1.Flags.string({ description: 'Key environment', options: ['live', 'test'] }),
|
|
30
|
+
scope: core_1.Flags.string({
|
|
31
|
+
description: 'Scope to grant (repeatable, e.g. environments:write)',
|
|
32
|
+
multiple: true,
|
|
33
|
+
}),
|
|
34
|
+
'expires-at': core_1.Flags.string({ description: 'ISO 8601 expiry; must be in the future' }),
|
|
35
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
36
|
+
};
|
|
37
|
+
async run() {
|
|
38
|
+
this.requireAuth();
|
|
39
|
+
const { args, flags } = await this.parse(ApiKeysCreate);
|
|
40
|
+
const name = flags.name || args.name;
|
|
41
|
+
if (!name) {
|
|
42
|
+
this.error('A name is required — pass it positionally or with --name.', { exit: 1 });
|
|
43
|
+
}
|
|
44
|
+
let minted;
|
|
45
|
+
try {
|
|
46
|
+
minted = await (0, managed_agent_keys_1.createManagedAgentKey)({
|
|
47
|
+
spaceId: flags.space,
|
|
48
|
+
name,
|
|
49
|
+
env: flags.env,
|
|
50
|
+
scopes: flags.scope,
|
|
51
|
+
expiresAt: flags['expires-at'],
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
// Includes the deployment-configuration case: an unconfigured server
|
|
56
|
+
// answers 503 with a sentence naming MANAGED_AGENTS_KEY_PEPPER, which is
|
|
57
|
+
// addressed to an operator and is worth passing through verbatim rather
|
|
58
|
+
// than flattening into "could not create key".
|
|
59
|
+
this.handleApiError(err);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (flags.json) {
|
|
63
|
+
this.log(JSON.stringify(minted, null, 2));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
this.log('');
|
|
67
|
+
this.log(` ${minted.secret}`);
|
|
68
|
+
this.log('');
|
|
69
|
+
this.log(minted.secret_warning ||
|
|
70
|
+
'This is the only time the secret will be displayed. Store it securely.');
|
|
71
|
+
this.log('');
|
|
72
|
+
this.log(` id ${minted.id}`);
|
|
73
|
+
this.log(` name ${minted.name}`);
|
|
74
|
+
// No `env` field exists — the environment lives in the prefix, which is
|
|
75
|
+
// also the only part of a secret any later read will ever show.
|
|
76
|
+
this.log(` prefix ${minted.prefix ?? '(none)'}`);
|
|
77
|
+
this.log(` scopes ${minted.scopes?.length ? minted.scopes.join(', ') : '(none)'}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.default = ApiKeysCreate;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/** Every Managed Agents API key on a Space, including revoked ones. */
|
|
3
|
+
export default class ApiKeysList extends BaseCommand {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
space: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../base-command");
|
|
5
|
+
const managed_agent_keys_1 = require("../../lib/managed-agent-keys");
|
|
6
|
+
/** Every Managed Agents API key on a Space, including revoked ones. */
|
|
7
|
+
class ApiKeysList extends base_command_1.BaseCommand {
|
|
8
|
+
static description = "List a Space's Managed Agents API keys. Secrets are never shown — only prefixes.";
|
|
9
|
+
static examples = ['<%= config.bin %> api-keys list --space <space-id>'];
|
|
10
|
+
static flags = {
|
|
11
|
+
space: core_1.Flags.string({ description: 'Space that owns the keys', required: true }),
|
|
12
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
13
|
+
};
|
|
14
|
+
async run() {
|
|
15
|
+
this.requireAuth();
|
|
16
|
+
const { flags } = await this.parse(ApiKeysList);
|
|
17
|
+
let keys;
|
|
18
|
+
try {
|
|
19
|
+
keys = await (0, managed_agent_keys_1.listManagedAgentKeys)(flags.space);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
this.handleApiError(err);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (flags.json) {
|
|
26
|
+
this.log(JSON.stringify(keys, null, 2));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (keys.length === 0) {
|
|
30
|
+
this.log('No API keys on this space.');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
for (const k of keys) {
|
|
34
|
+
// A revoked key is listed rather than hidden: "this key was revoked" and
|
|
35
|
+
// "this key never existed" want different next actions.
|
|
36
|
+
const state = k.revoked_at ? 'revoked' : k.expires_at ? `expires ${k.expires_at}` : 'active';
|
|
37
|
+
// The prefix carries the environment; there is no separate field.
|
|
38
|
+
this.log(`${k.id} ${(k.prefix ?? '').padEnd(12)} ${state.padEnd(28)} ${k.name}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.default = ApiKeysList;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/** Revoke a key. Irreversible — a revoked key is replaced, never re-enabled. */
|
|
3
|
+
export default class ApiKeysRevoke extends BaseCommand {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static args: {
|
|
7
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
space: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../base-command");
|
|
5
|
+
const managed_agent_keys_1 = require("../../lib/managed-agent-keys");
|
|
6
|
+
/** Revoke a key. Irreversible — a revoked key is replaced, never re-enabled. */
|
|
7
|
+
class ApiKeysRevoke extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Revoke a Managed Agents API key. Irreversible — mint a replacement rather than expecting to undo this.';
|
|
9
|
+
static examples = ['<%= config.bin %> api-keys revoke <key-id> --space <space-id>'];
|
|
10
|
+
static args = {
|
|
11
|
+
id: core_1.Args.string({ description: 'Key id', required: true, ignoreStdin: true }),
|
|
12
|
+
};
|
|
13
|
+
static flags = {
|
|
14
|
+
space: core_1.Flags.string({ description: 'Space that owns the key', required: true }),
|
|
15
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
16
|
+
};
|
|
17
|
+
async run() {
|
|
18
|
+
this.requireAuth();
|
|
19
|
+
const { args, flags } = await this.parse(ApiKeysRevoke);
|
|
20
|
+
try {
|
|
21
|
+
const res = await (0, managed_agent_keys_1.revokeManagedAgentKey)(args.id, flags.space);
|
|
22
|
+
if (flags.json) {
|
|
23
|
+
this.log(JSON.stringify(res, null, 2));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
this.log(`Revoked ${args.id}. Anything still presenting it will now be refused.`);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
this.handleApiError(err);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.default = ApiKeysRevoke;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* Mint a replacement secret for an existing key row.
|
|
4
|
+
*
|
|
5
|
+
* Same once-only rule as `create`: the new secret is displayed here and nowhere
|
|
6
|
+
* else, and the previous one stops working.
|
|
7
|
+
*/
|
|
8
|
+
export default class ApiKeysRotate extends BaseCommand {
|
|
9
|
+
static description: string;
|
|
10
|
+
static examples: string[];
|
|
11
|
+
static args: {
|
|
12
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
13
|
+
};
|
|
14
|
+
static flags: {
|
|
15
|
+
space: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
16
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
17
|
+
};
|
|
18
|
+
run(): Promise<void>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../base-command");
|
|
5
|
+
const managed_agent_keys_1 = require("../../lib/managed-agent-keys");
|
|
6
|
+
/**
|
|
7
|
+
* Mint a replacement secret for an existing key row.
|
|
8
|
+
*
|
|
9
|
+
* Same once-only rule as `create`: the new secret is displayed here and nowhere
|
|
10
|
+
* else, and the previous one stops working.
|
|
11
|
+
*/
|
|
12
|
+
class ApiKeysRotate extends base_command_1.BaseCommand {
|
|
13
|
+
static description = 'Rotate a Managed Agents API key. The new secret is shown once; the old one stops working.';
|
|
14
|
+
static examples = ['<%= config.bin %> api-keys rotate <key-id> --space <space-id>'];
|
|
15
|
+
static args = {
|
|
16
|
+
id: core_1.Args.string({ description: 'Key id', required: true, ignoreStdin: true }),
|
|
17
|
+
};
|
|
18
|
+
static flags = {
|
|
19
|
+
space: core_1.Flags.string({ description: 'Space that owns the key', required: true }),
|
|
20
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
21
|
+
};
|
|
22
|
+
async run() {
|
|
23
|
+
this.requireAuth();
|
|
24
|
+
const { args, flags } = await this.parse(ApiKeysRotate);
|
|
25
|
+
try {
|
|
26
|
+
const minted = await (0, managed_agent_keys_1.rotateManagedAgentKey)(args.id, flags.space);
|
|
27
|
+
if (flags.json) {
|
|
28
|
+
this.log(JSON.stringify(minted, null, 2));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
this.log('');
|
|
32
|
+
this.log(` ${minted.secret}`);
|
|
33
|
+
this.log('');
|
|
34
|
+
this.log(minted.secret_warning ||
|
|
35
|
+
'This is the only time the secret will be displayed. The previous secret no longer works.');
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
this.handleApiError(err);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.default = ApiKeysRotate;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import BalanceShow from './show';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr balance` — the balance, not a table of contents.
|
|
4
|
+
*
|
|
5
|
+
* The bare topic printed its tagline ("Your hosted usage balance — the ceiling
|
|
6
|
+
* that refuses a turn") and then a list of four subcommands, with no number
|
|
7
|
+
* anywhere. The tagline names the value and then does not show it, and three of
|
|
8
|
+
* the four subcommands are plausible answers to "what is my balance"
|
|
9
|
+
* (`show`, `usage`, `statement`) — so the reader who typed the noun they wanted
|
|
10
|
+
* has to disambiguate a menu to get it (OSK-7637).
|
|
11
|
+
*
|
|
12
|
+
* Running `show` is what the command's own first line promises. `--help` still
|
|
13
|
+
* lists every subcommand, which is where a menu belongs.
|
|
14
|
+
*/
|
|
15
|
+
export default class Balance extends BalanceShow {
|
|
16
|
+
static description: string;
|
|
17
|
+
static examples: string[];
|
|
18
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const show_1 = __importDefault(require("./show"));
|
|
7
|
+
/**
|
|
8
|
+
* `skrr balance` — the balance, not a table of contents.
|
|
9
|
+
*
|
|
10
|
+
* The bare topic printed its tagline ("Your hosted usage balance — the ceiling
|
|
11
|
+
* that refuses a turn") and then a list of four subcommands, with no number
|
|
12
|
+
* anywhere. The tagline names the value and then does not show it, and three of
|
|
13
|
+
* the four subcommands are plausible answers to "what is my balance"
|
|
14
|
+
* (`show`, `usage`, `statement`) — so the reader who typed the noun they wanted
|
|
15
|
+
* has to disambiguate a menu to get it (OSK-7637).
|
|
16
|
+
*
|
|
17
|
+
* Running `show` is what the command's own first line promises. `--help` still
|
|
18
|
+
* lists every subcommand, which is where a menu belongs.
|
|
19
|
+
*/
|
|
20
|
+
class Balance extends show_1.default {
|
|
21
|
+
static description = 'Show your hosted usage balance — the ceiling that refuses a turn (not the x402 wallet). ' +
|
|
22
|
+
'See `balance usage`, `balance statement` and `balance history` for the detail behind it.';
|
|
23
|
+
static examples = [
|
|
24
|
+
'<%= config.bin %> balance',
|
|
25
|
+
'<%= config.bin %> balance --json',
|
|
26
|
+
'<%= config.bin %> balance statement --desc',
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
exports.default = Balance;
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { BaseCommand } from '../../base-command';
|
|
2
|
+
import { type RuntimeMonthlySpend } from '../../lib/harnesses';
|
|
3
|
+
/**
|
|
4
|
+
* The hosted-runtime monthly cap rows, as lines.
|
|
5
|
+
*
|
|
6
|
+
* Pure so it can be tested the way `renderUsageSummary` is: this screen's job
|
|
7
|
+
* is to stop a user reading headroom off the wrong cap, and the wording is the
|
|
8
|
+
* fix, so the wording is what gets pinned.
|
|
9
|
+
*/
|
|
10
|
+
export declare function renderRuntimeSpend(spend: RuntimeMonthlySpend[], log: (line: string) => void): void;
|
|
2
11
|
/**
|
|
3
12
|
* YOUR hosted usage balance — the personal account, and only that one.
|
|
4
13
|
*
|
|
@@ -33,6 +42,22 @@ export default class BalanceShow extends BaseCommand {
|
|
|
33
42
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
34
43
|
};
|
|
35
44
|
run(): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* The OTHER cap — the one that actually refuses a Hosted Machine.
|
|
47
|
+
*
|
|
48
|
+
* Everything above is the credits account and its per-period rate limit. A
|
|
49
|
+
* hosted runtime is additionally bounded by a MONTHLY spend cap that this
|
|
50
|
+
* screen never mentioned, so a user could read `Spend cap: $10.00 per day`
|
|
51
|
+
* and `Cap remaining: $10.00` — headroom on every visible number — while
|
|
52
|
+
* every agent turn on a Hosted Machine was being refused by a limit with no
|
|
53
|
+
* surface at all. They could only discover it by being turned away
|
|
54
|
+
* (OSK-7920, split out of OSK-7900 / OSK-7909).
|
|
55
|
+
*
|
|
56
|
+
* Best-effort by design. This is a second call on a screen whose primary
|
|
57
|
+
* answer is the balance, so a failure here prints a short line and leaves
|
|
58
|
+
* that answer intact rather than failing the command.
|
|
59
|
+
*/
|
|
60
|
+
private renderRuntimeSpend;
|
|
36
61
|
/**
|
|
37
62
|
* The workspace account, which is the one a workspace-carrying session is
|
|
38
63
|
* funded from. Rendered in the SAME credits-plus-dollars unit and row labels
|
|
@@ -1,9 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderRuntimeSpend = renderRuntimeSpend;
|
|
3
4
|
const core_1 = require("@oclif/core");
|
|
4
5
|
const base_command_1 = require("../../base-command");
|
|
5
6
|
const balance_1 = require("../../lib/balance");
|
|
6
7
|
const workspaces_1 = require("../../lib/workspaces");
|
|
8
|
+
const harnesses_1 = require("../../lib/harnesses");
|
|
9
|
+
const usd = (cents) => (typeof cents === 'number' ? `$${(cents / 100).toFixed(2)}` : '—');
|
|
10
|
+
/**
|
|
11
|
+
* The hosted-runtime monthly cap rows, as lines.
|
|
12
|
+
*
|
|
13
|
+
* Pure so it can be tested the way `renderUsageSummary` is: this screen's job
|
|
14
|
+
* is to stop a user reading headroom off the wrong cap, and the wording is the
|
|
15
|
+
* fix, so the wording is what gets pinned.
|
|
16
|
+
*/
|
|
17
|
+
function renderRuntimeSpend(spend, log) {
|
|
18
|
+
const capped = spend.filter((row) => row.hasLimit);
|
|
19
|
+
if (capped.length === 0) {
|
|
20
|
+
// A product with no cap prints nothing rather than a reassuring "no limit"
|
|
21
|
+
// line: this section exists to warn, and an absent cap is not news.
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
log('');
|
|
25
|
+
log('Hosted runtime — a SEPARATE monthly cap from the spend cap above:');
|
|
26
|
+
for (const row of capped) {
|
|
27
|
+
// `projected`, not `spent`: admission compares the cap against spend PLUS
|
|
28
|
+
// the estimated cost of everything still open. Showing only spend would
|
|
29
|
+
// read as headroom right up to the moment of refusal.
|
|
30
|
+
const flag = row.exceeded ? ' <- at the cap; turns are being refused' : '';
|
|
31
|
+
log(` ${row.machineProduct.padEnd(18)} ${usd(row.projectedCents)} of ` +
|
|
32
|
+
`${usd(row.limitCents)} projected${flag}`);
|
|
33
|
+
if (typeof row.openUsageEstimateCents === 'number' && row.openUsageEstimateCents > 0) {
|
|
34
|
+
log(` ${''.padEnd(18)} (${usd(row.currentSpendCents)} billed + ` +
|
|
35
|
+
`${usd(row.openUsageEstimateCents)} estimated for machines still open)`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
7
39
|
/**
|
|
8
40
|
* YOUR hosted usage balance — the personal account, and only that one.
|
|
9
41
|
*
|
|
@@ -140,6 +172,7 @@ class BalanceShow extends base_command_1.BaseCommand {
|
|
|
140
172
|
else {
|
|
141
173
|
this.log(' Auto-refill: off');
|
|
142
174
|
}
|
|
175
|
+
await this.renderRuntimeSpend();
|
|
143
176
|
this.log('');
|
|
144
177
|
this.log('A credit is a micro-dollar: 1,000,000 credits = $1.00. The spend cap');
|
|
145
178
|
this.log('is a per-period ceiling, not a second balance. `skrr balance statement`');
|
|
@@ -150,6 +183,33 @@ class BalanceShow extends base_command_1.BaseCommand {
|
|
|
150
183
|
this.log('see `skrr balance show --workspace <id>`. `skrr payments wallet` is the');
|
|
151
184
|
this.log('separate x402 crypto wallet, in USDC — not this balance.');
|
|
152
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* The OTHER cap — the one that actually refuses a Hosted Machine.
|
|
188
|
+
*
|
|
189
|
+
* Everything above is the credits account and its per-period rate limit. A
|
|
190
|
+
* hosted runtime is additionally bounded by a MONTHLY spend cap that this
|
|
191
|
+
* screen never mentioned, so a user could read `Spend cap: $10.00 per day`
|
|
192
|
+
* and `Cap remaining: $10.00` — headroom on every visible number — while
|
|
193
|
+
* every agent turn on a Hosted Machine was being refused by a limit with no
|
|
194
|
+
* surface at all. They could only discover it by being turned away
|
|
195
|
+
* (OSK-7920, split out of OSK-7900 / OSK-7909).
|
|
196
|
+
*
|
|
197
|
+
* Best-effort by design. This is a second call on a screen whose primary
|
|
198
|
+
* answer is the balance, so a failure here prints a short line and leaves
|
|
199
|
+
* that answer intact rather than failing the command.
|
|
200
|
+
*/
|
|
201
|
+
async renderRuntimeSpend() {
|
|
202
|
+
let spend;
|
|
203
|
+
try {
|
|
204
|
+
({ spend } = await (0, harnesses_1.getRuntimeMonthlySpend)());
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
this.log('');
|
|
208
|
+
this.log(' Hosted runtime: monthly cap unavailable (`skrr harnesses products` to retry)');
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
renderRuntimeSpend(spend, (line) => this.log(line));
|
|
212
|
+
}
|
|
153
213
|
/**
|
|
154
214
|
* The workspace account, which is the one a workspace-carrying session is
|
|
155
215
|
* funded from. Rendered in the SAME credits-plus-dollars unit and row labels
|
|
@@ -39,6 +39,25 @@ export default class BalanceStatement extends BaseCommand {
|
|
|
39
39
|
};
|
|
40
40
|
run(): Promise<void>;
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* OSK-7641 — the ledger's default page is the OLDEST one, and nothing said so.
|
|
44
|
+
*
|
|
45
|
+
* With no flags the command returned 50 entries spanning three and a half
|
|
46
|
+
* WEEKS before today, opening with the account's legacy-balance-opening credit.
|
|
47
|
+
* A reader filtering for "entries since 06:45" got zero and concluded nothing
|
|
48
|
+
* had been billed at all. That conclusion was wrong, and the output gave them
|
|
49
|
+
* no way to know it: no range, no order, no "page 1 of many".
|
|
50
|
+
*
|
|
51
|
+
* `--desc` already existed (OSK-4823/OSK-4907) and is the fix — but only for
|
|
52
|
+
* someone who already suspected the default was wrong. So the page states what
|
|
53
|
+
* it is. The order word comes first because it is what changes the reading.
|
|
54
|
+
*/
|
|
55
|
+
export declare function statementWindowLine(args: {
|
|
56
|
+
wantNewestFirst: boolean;
|
|
57
|
+
firstCreatedAt: string | null;
|
|
58
|
+
lastCreatedAt: string | null;
|
|
59
|
+
hasMore: boolean;
|
|
60
|
+
}): string;
|
|
42
61
|
/**
|
|
43
62
|
* The "More rows" footer, pointing at the cursor that matches the direction the
|
|
44
63
|
* reader asked for: `--before` continues a newest-first page back through older
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.statementWindowLine = statementWindowLine;
|
|
3
4
|
exports.statementMoreRowsHint = statementMoreRowsHint;
|
|
4
5
|
exports.statementAmount = statementAmount;
|
|
5
6
|
exports.statementAccountHeading = statementAccountHeading;
|
|
@@ -130,6 +131,15 @@ class BalanceStatement extends base_command_1.BaseCommand {
|
|
|
130
131
|
this.log('No ledger entries.');
|
|
131
132
|
return;
|
|
132
133
|
}
|
|
134
|
+
// WHICH rows these are, before the reader starts drawing conclusions from
|
|
135
|
+
// them (OSK-7641).
|
|
136
|
+
this.log(statementWindowLine({
|
|
137
|
+
wantNewestFirst,
|
|
138
|
+
firstCreatedAt: entries[0]?.createdAt ?? null,
|
|
139
|
+
lastCreatedAt: entries[entries.length - 1]?.createdAt ?? null,
|
|
140
|
+
hasMore: Boolean(wantNewestFirst ? statement.nextBeforeEntryId : statement.nextAfterEntryId),
|
|
141
|
+
}));
|
|
142
|
+
this.log('');
|
|
133
143
|
(0, format_1.renderTable)(entries.map((entry) => ({
|
|
134
144
|
when: entry.createdAt ? String(entry.createdAt).slice(0, 19).replace('T', ' ') : '-',
|
|
135
145
|
event: (0, format_1.formatCell)(entry.eventType),
|
|
@@ -139,6 +149,11 @@ class BalanceStatement extends base_command_1.BaseCommand {
|
|
|
139
149
|
// in --json but never printed, so a human could not tell a code session
|
|
140
150
|
// from a hosted run (OSK-4825).
|
|
141
151
|
provider: (0, format_1.formatCell)(entry.provider),
|
|
152
|
+
// OSK-7641 — the command promises "what incurred it", and a bare
|
|
153
|
+
// session UUID does not answer that for anyone running more than one
|
|
154
|
+
// agent. Blank rather than '-' when the producer did not record one, so
|
|
155
|
+
// an unattributed row does not look like an attributed one.
|
|
156
|
+
agent: entry.agentId ? String(entry.agentId) : '',
|
|
142
157
|
// The answer to "which session was this?" — the thing the legacy view
|
|
143
158
|
// could never name, and the reason that view read as unexplainable. The
|
|
144
159
|
// compound sourceId already encodes the source type in its first
|
|
@@ -152,9 +167,18 @@ class BalanceStatement extends base_command_1.BaseCommand {
|
|
|
152
167
|
{ key: 'service', header: 'SERVICE', maxWidth: 20 },
|
|
153
168
|
{ key: 'model', header: 'MODEL', maxWidth: 26 },
|
|
154
169
|
{ key: 'provider', header: 'PROVIDER', maxWidth: 16 },
|
|
170
|
+
{ key: 'agent', header: 'AGENT', maxWidth: 26 },
|
|
155
171
|
{ key: 'source', header: 'SOURCE' },
|
|
156
172
|
{ key: 'amount', header: 'AMOUNT' },
|
|
157
173
|
], (line) => this.log(line));
|
|
174
|
+
// The reader's actual question is "what did my last few turns cost", and on
|
|
175
|
+
// page 1 of an oldest-first ledger the honest answer is "these are not
|
|
176
|
+
// those rows". Said next to the cursor hint, where a reader who has just
|
|
177
|
+
// seen three-week-old dates is looking (OSK-7641).
|
|
178
|
+
if (!wantNewestFirst && statement.nextAfterEntryId) {
|
|
179
|
+
this.log('');
|
|
180
|
+
this.log(`Looking for your most recent charges? \`${this.config.bin} balance statement --desc\``);
|
|
181
|
+
}
|
|
158
182
|
const hint = statementMoreRowsHint({
|
|
159
183
|
bin: this.config.bin,
|
|
160
184
|
workspaceId,
|
|
@@ -169,6 +193,34 @@ class BalanceStatement extends base_command_1.BaseCommand {
|
|
|
169
193
|
}
|
|
170
194
|
}
|
|
171
195
|
exports.default = BalanceStatement;
|
|
196
|
+
/**
|
|
197
|
+
* OSK-7641 — the ledger's default page is the OLDEST one, and nothing said so.
|
|
198
|
+
*
|
|
199
|
+
* With no flags the command returned 50 entries spanning three and a half
|
|
200
|
+
* WEEKS before today, opening with the account's legacy-balance-opening credit.
|
|
201
|
+
* A reader filtering for "entries since 06:45" got zero and concluded nothing
|
|
202
|
+
* had been billed at all. That conclusion was wrong, and the output gave them
|
|
203
|
+
* no way to know it: no range, no order, no "page 1 of many".
|
|
204
|
+
*
|
|
205
|
+
* `--desc` already existed (OSK-4823/OSK-4907) and is the fix — but only for
|
|
206
|
+
* someone who already suspected the default was wrong. So the page states what
|
|
207
|
+
* it is. The order word comes first because it is what changes the reading.
|
|
208
|
+
*/
|
|
209
|
+
function statementWindowLine(args) {
|
|
210
|
+
const order = args.wantNewestFirst ? 'Newest first' : 'Oldest first';
|
|
211
|
+
const from = statementDay(args.firstCreatedAt);
|
|
212
|
+
const to = statementDay(args.lastCreatedAt);
|
|
213
|
+
const range = from && to ? (from === to ? from : `${from} → ${to}`) : 'no dated rows';
|
|
214
|
+
// "more" is the load-bearing half: a page that does not say it is one reads
|
|
215
|
+
// as the whole ledger.
|
|
216
|
+
return `${order} · ${range}${args.hasMore ? ' · more rows follow' : ' · complete'}`;
|
|
217
|
+
}
|
|
218
|
+
function statementDay(value) {
|
|
219
|
+
if (!value)
|
|
220
|
+
return null;
|
|
221
|
+
const text = String(value);
|
|
222
|
+
return text.length >= 10 ? text.slice(0, 10) : text;
|
|
223
|
+
}
|
|
172
224
|
/**
|
|
173
225
|
* The "More rows" footer, pointing at the cursor that matches the direction the
|
|
174
226
|
* reader asked for: `--before` continues a newest-first page back through older
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
export default class BrowserDoctor extends Command {
|
|
3
3
|
static description: string;
|
|
4
|
+
/**
|
|
5
|
+
* `browser diagnose` reaches the same command.
|
|
6
|
+
*
|
|
7
|
+
* The group's own first line is "Install, diagnose, and configure
|
|
8
|
+
* capability-scoped skrr Browser access" — so a reader types the verb the
|
|
9
|
+
* product used to describe itself and gets `error: unknown command
|
|
10
|
+
* 'diagnose'`, one line, suggesting nothing and not even pointing at
|
|
11
|
+
* `--help`, which is how every other error surface in this CLI ends
|
|
12
|
+
* (OSK-7644). Two names for one command is cheaper than the round trip.
|
|
13
|
+
*/
|
|
14
|
+
static aliases: string[];
|
|
4
15
|
static flags: {
|
|
5
16
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
6
17
|
};
|
|
@@ -4,6 +4,17 @@ const core_1 = require("@oclif/core");
|
|
|
4
4
|
const browser_1 = require("../browser");
|
|
5
5
|
class BrowserDoctor extends core_1.Command {
|
|
6
6
|
static description = 'Diagnose browser runtime selection, relay, image, and MCP bridge';
|
|
7
|
+
/**
|
|
8
|
+
* `browser diagnose` reaches the same command.
|
|
9
|
+
*
|
|
10
|
+
* The group's own first line is "Install, diagnose, and configure
|
|
11
|
+
* capability-scoped skrr Browser access" — so a reader types the verb the
|
|
12
|
+
* product used to describe itself and gets `error: unknown command
|
|
13
|
+
* 'diagnose'`, one line, suggesting nothing and not even pointing at
|
|
14
|
+
* `--help`, which is how every other error surface in this CLI ends
|
|
15
|
+
* (OSK-7644). Two names for one command is cheaper than the round trip.
|
|
16
|
+
*/
|
|
17
|
+
static aliases = ['browser:diagnose'];
|
|
7
18
|
static flags = {
|
|
8
19
|
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
9
20
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr code jobs approve` — land the pull request a job opened.
|
|
4
|
+
*
|
|
5
|
+
* OSK-7789 listed six verbs on `/api/cloud-coding` and one CLI binding. Four of
|
|
6
|
+
* the missing five are now bound; this is the last, and it is the one that
|
|
7
|
+
* FINISHES the work. Without it a headless operator could start a job, watch
|
|
8
|
+
* it, and stop it — and still had to open a browser to get the result merged,
|
|
9
|
+
* which is the same shape as the create-only path the finding was about.
|
|
10
|
+
*
|
|
11
|
+
* Only a repository-backed job has a pull request. `code jobs run` is bare
|
|
12
|
+
* compute with no repo, so there is nothing here to approve, and the refusal
|
|
13
|
+
* says which command produces one rather than reporting a bare 4xx.
|
|
14
|
+
*/
|
|
15
|
+
export default class CodeJobsApprove extends BaseCommand {
|
|
16
|
+
static description: string;
|
|
17
|
+
static examples: string[];
|
|
18
|
+
static args: {
|
|
19
|
+
job: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
20
|
+
};
|
|
21
|
+
static flags: {
|
|
22
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
23
|
+
};
|
|
24
|
+
run(): Promise<void>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
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
|
+
/**
|
|
7
|
+
* `skrr code jobs approve` — land the pull request a job opened.
|
|
8
|
+
*
|
|
9
|
+
* OSK-7789 listed six verbs on `/api/cloud-coding` and one CLI binding. Four of
|
|
10
|
+
* the missing five are now bound; this is the last, and it is the one that
|
|
11
|
+
* FINISHES the work. Without it a headless operator could start a job, watch
|
|
12
|
+
* it, and stop it — and still had to open a browser to get the result merged,
|
|
13
|
+
* which is the same shape as the create-only path the finding was about.
|
|
14
|
+
*
|
|
15
|
+
* Only a repository-backed job has a pull request. `code jobs run` is bare
|
|
16
|
+
* compute with no repo, so there is nothing here to approve, and the refusal
|
|
17
|
+
* says which command produces one rather than reporting a bare 4xx.
|
|
18
|
+
*/
|
|
19
|
+
class CodeJobsApprove extends base_command_1.BaseCommand {
|
|
20
|
+
static description = 'Approve and merge the pull request a Hosted Job Machine job opened';
|
|
21
|
+
static examples = [
|
|
22
|
+
'<%= config.bin %> code jobs approve <job-id>',
|
|
23
|
+
'<%= config.bin %> code jobs approve <job-id> --json',
|
|
24
|
+
];
|
|
25
|
+
static args = {
|
|
26
|
+
job: core_1.Args.string({ description: 'Job id', required: true, ignoreStdin: true }),
|
|
27
|
+
};
|
|
28
|
+
static flags = { json: core_1.Flags.boolean({ description: 'Output as JSON' }) };
|
|
29
|
+
async run() {
|
|
30
|
+
this.requireAuth();
|
|
31
|
+
const { args, flags } = await this.parse(CodeJobsApprove);
|
|
32
|
+
let task;
|
|
33
|
+
try {
|
|
34
|
+
const res = await data_provider_1.dataService.approveCloudCodingPullRequest(args.job);
|
|
35
|
+
task = res?.task;
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
this.handleApiError(err);
|
|
39
|
+
}
|
|
40
|
+
if (flags.json) {
|
|
41
|
+
this.log(JSON.stringify(task, null, 2));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// The SERVER's status, never the one we asked for — approving races a
|
|
45
|
+
// branch someone merged by hand, and printing an outcome we did not observe
|
|
46
|
+
// is how a CLI starts inventing them.
|
|
47
|
+
this.log(`Job ${task?.id ?? args.job} is now ${task?.status ?? 'unknown'}.`);
|
|
48
|
+
if (task?.prUrl)
|
|
49
|
+
this.log(` ${String(task.prUrl)}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.default = CodeJobsApprove;
|