@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
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.STREAM_LOST_EXIT_CODE = exports.DETACH_EXIT_CODE = void 0;
|
|
4
|
+
exports.interruptedDetachMessage = interruptedDetachMessage;
|
|
5
|
+
exports.reconcileTerminalFromMessages = reconcileTerminalFromMessages;
|
|
6
|
+
exports.inspectTurnCommand = inspectTurnCommand;
|
|
3
7
|
exports.noOutputFailureMessage = noOutputFailureMessage;
|
|
4
8
|
exports.noStreamJsonPayload = noStreamJsonPayload;
|
|
5
9
|
exports.chatStreamHeaderLines = chatStreamHeaderLines;
|
|
@@ -8,6 +12,104 @@ const data_provider_1 = require("@skrr-ai/data-provider");
|
|
|
8
12
|
const base_command_1 = require("../../base-command");
|
|
9
13
|
const agentic_stream_1 = require("../../lib/agentic-stream");
|
|
10
14
|
const web_url_1 = require("../../lib/web-url");
|
|
15
|
+
/**
|
|
16
|
+
* Exit code for a run the USER stopped watching, by pressing Ctrl-C.
|
|
17
|
+
*
|
|
18
|
+
* OSK-2944 established that exiting 1 on a lost stream made "the run failed"
|
|
19
|
+
* and "we lost the view of a live run" indistinguishable, and invited duplicate
|
|
20
|
+
* execution. So a detach gets its own non-zero code.
|
|
21
|
+
*
|
|
22
|
+
* It must be non-zero on EVERY output mode. The `--jsonl` branch used to
|
|
23
|
+
* `return` here, which leaves the exit code at 0, so a script driving the CLI
|
|
24
|
+
* read a detached — possibly already-failed — run as a success. That is the
|
|
25
|
+
* mode automation actually uses.
|
|
26
|
+
*/
|
|
27
|
+
exports.DETACH_EXIT_CODE = 130;
|
|
28
|
+
/**
|
|
29
|
+
* Exit code for a detach nobody asked for — the stream was lost, or could not
|
|
30
|
+
* be attached at all.
|
|
31
|
+
*
|
|
32
|
+
* 130 is the conventional "killed by SIGINT" code, and it was returned for a
|
|
33
|
+
* detach that no signal caused: a script reading it concludes the user pressed
|
|
34
|
+
* Ctrl-C, which is the opposite of what happened (OSK-7660). Reserving 130 for
|
|
35
|
+
* an actual interrupt and giving the unattended case its own code keeps both
|
|
36
|
+
* answers true.
|
|
37
|
+
*/
|
|
38
|
+
exports.STREAM_LOST_EXIT_CODE = 75;
|
|
39
|
+
/**
|
|
40
|
+
* What to say when the user pressed Ctrl-C and the run did not stop.
|
|
41
|
+
*
|
|
42
|
+
* A cancel is REQUESTED over the session; whether the harness honours it is not
|
|
43
|
+
* something this process can guarantee. Measured on a local harness, where the
|
|
44
|
+
* answer is checkable with `ps`: the CLI exited, and the shell and the `sleep
|
|
45
|
+
* 200` it had spawned were still alive at +10s, +26s and +53s — while the CLI
|
|
46
|
+
* said nothing about it at all (OSK-7733). Three things compound there: work
|
|
47
|
+
* the user asked to stop keeps consuming their machine and their vendor tokens;
|
|
48
|
+
* they are not told, so they will not go and kill it; and the record is left
|
|
49
|
+
* `unfinished: true` with no error, so the cancellation is invisible in history
|
|
50
|
+
* too.
|
|
51
|
+
*
|
|
52
|
+
* Silence is the one unacceptable option, because the user will believe they
|
|
53
|
+
* cancelled. This says what was asked, what is not guaranteed, and how to look.
|
|
54
|
+
*/
|
|
55
|
+
function interruptedDetachMessage(input) {
|
|
56
|
+
return (`Cancel requested for run ${input.sessionId}, but no terminal event arrived before the ` +
|
|
57
|
+
'grace period ended. The runtime MAY STILL BE EXECUTING — a tool call already running on ' +
|
|
58
|
+
'your machine is not guaranteed to stop. ' +
|
|
59
|
+
`Check what it did with: ${inspectTurnCommand(input.conversationId)}` +
|
|
60
|
+
(process.platform === 'win32'
|
|
61
|
+
? ''
|
|
62
|
+
: ', and look for a surviving process with `ps -ef | grep -i claude`'));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* What the durable record says about a turn, read from its messages.
|
|
66
|
+
*
|
|
67
|
+
* The stream is not the only witness and must not be the only one consulted: a
|
|
68
|
+
* run refused during admission writes `error: true` plus the reason on the
|
|
69
|
+
* response message and never closes the session stream, so a joined subscriber
|
|
70
|
+
* waits forever for an event that will not come (OSK-7624, OSK-7635, OSK-7720,
|
|
71
|
+
* OSK-7735). Exported as a pure function so the mapping from a message row to a
|
|
72
|
+
* terminal verdict is testable without a socket.
|
|
73
|
+
*
|
|
74
|
+
* Returns null while the row is still in flight — the caller keeps waiting,
|
|
75
|
+
* because a long tool call is silence, not a failure.
|
|
76
|
+
*/
|
|
77
|
+
function reconcileTerminalFromMessages(messages, responseMessageId) {
|
|
78
|
+
const row = (responseMessageId && messages.find((m) => m?.messageId === responseMessageId)) ||
|
|
79
|
+
[...messages].reverse().find((m) => m && m.isCreatedByUser === false);
|
|
80
|
+
if (!row)
|
|
81
|
+
return null;
|
|
82
|
+
const agentic = row.metadata?.agentic;
|
|
83
|
+
const recordedError = typeof agentic?.error === 'string' ? agentic.error : undefined;
|
|
84
|
+
const text = typeof row.text === 'string' ? row.text : '';
|
|
85
|
+
if (row.error === true) {
|
|
86
|
+
return {
|
|
87
|
+
status: 'failed',
|
|
88
|
+
...(text ? { text } : {}),
|
|
89
|
+
// The reason exists on the row; it simply never reached the surface. Say
|
|
90
|
+
// it, rather than the transport error that masked it (OSK-7595).
|
|
91
|
+
error: recordedError ?? 'The run failed. No reason was recorded on the message.',
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
// `unfinished: false` is the persister's terminal marker; an empty body with
|
|
95
|
+
// it set is a turn that ended having produced nothing, which is still
|
|
96
|
+
// terminal and still better reported than waited on.
|
|
97
|
+
if (row.unfinished === false)
|
|
98
|
+
return { status: 'completed', text };
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* How to look at a turn the CLI is no longer watching.
|
|
103
|
+
*
|
|
104
|
+
* NOT `skrr agents chat --conversation <id>`, which is what this used to print:
|
|
105
|
+
* that command requires the `agentId` argument and `--prompt`, so it exits with
|
|
106
|
+
* `Missing 1 required arg: agentId` and never reattaches. A recovery
|
|
107
|
+
* instruction that cannot be run is worse than none — it costs the reader a
|
|
108
|
+
* round trip to discover the product was wrong.
|
|
109
|
+
*/
|
|
110
|
+
function inspectTurnCommand(conversationId) {
|
|
111
|
+
return `skrr messages list ${conversationId ?? '<conversation-id>'}`;
|
|
112
|
+
}
|
|
11
113
|
/**
|
|
12
114
|
* A terminal run that produced no text is NOT a success to report silently.
|
|
13
115
|
*
|
|
@@ -23,8 +125,7 @@ function noOutputFailureMessage(input) {
|
|
|
23
125
|
if (input.text?.trim())
|
|
24
126
|
return null;
|
|
25
127
|
return (`The turn ended with no output (status: ${input.status}). ` +
|
|
26
|
-
|
|
27
|
-
`--conversation ${input.conversationId ?? '<conversation-id>'}`);
|
|
128
|
+
`It may have failed on the runtime. Inspect it with: ${inspectTurnCommand(input.conversationId)}`);
|
|
28
129
|
}
|
|
29
130
|
function noStreamJsonPayload(input) {
|
|
30
131
|
const { result, conversationId, agentId, baseURL, threadRootMessageId } = input;
|
|
@@ -97,7 +198,19 @@ class AgentsChat extends base_command_1.BaseCommand {
|
|
|
97
198
|
'agent’s runtime, tools, session, or working directory and cannot perform work — ' +
|
|
98
199
|
'it is for inline text assistance. Use --no-stream for a real turn.',
|
|
99
200
|
}),
|
|
100
|
-
jsonl: core_1.Flags.boolean({
|
|
201
|
+
jsonl: core_1.Flags.boolean({
|
|
202
|
+
description: 'Emit one JSON event per line while streaming. Every line is a complete JSON value. ' +
|
|
203
|
+
'Assistant text arrives as `text.delta` whose `text` is the CUMULATIVE answer so far, ' +
|
|
204
|
+
'not a delta — take the last one, or `run.result` at the end. The same text is ' +
|
|
205
|
+
'mirrored inside `session.output` envelopes for consumers that want the raw stream, ' +
|
|
206
|
+
'so folding both doubles the answer: pick ONE lane. Inside a `session.output`, ' +
|
|
207
|
+
'`envelopes[].__seq` is the dedupe key and the ordering key — the same envelope is ' +
|
|
208
|
+
'delivered by more than one room, and a re-delivery repeats its `__seq`. A ' +
|
|
209
|
+
'`stream.gap` event means envelopes in that seq range never arrived and the streamed ' +
|
|
210
|
+
'text is short; `run.result` and the persisted message remain authoritative. Tool ' +
|
|
211
|
+
'calls arrive as `tool.started` / `tool.completed`, once per `toolUseId`, on cloud ' +
|
|
212
|
+
'and local-harness runs alike.',
|
|
213
|
+
}),
|
|
101
214
|
json: core_1.Flags.boolean({
|
|
102
215
|
description: 'Emit the final one-shot response as JSON (use with --no-stream)',
|
|
103
216
|
}),
|
|
@@ -122,7 +235,7 @@ class AgentsChat extends base_command_1.BaseCommand {
|
|
|
122
235
|
* canonical scope at all. Naming that at launch is cheap; discovering it
|
|
123
236
|
* mid-run costs a session.
|
|
124
237
|
*/
|
|
125
|
-
static TASK_REF_IN_PROMPT = /\b(?:
|
|
238
|
+
static TASK_REF_IN_PROMPT = /\b(?:OSK-\d+|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\b/;
|
|
126
239
|
async run() {
|
|
127
240
|
this.requireAuth();
|
|
128
241
|
const { args, flags } = await this.parse(AgentsChat);
|
|
@@ -131,6 +244,15 @@ class AgentsChat extends base_command_1.BaseCommand {
|
|
|
131
244
|
exit: 2,
|
|
132
245
|
});
|
|
133
246
|
}
|
|
247
|
+
if (flags.quick && flags.jsonl) {
|
|
248
|
+
// Accepted-and-ignored is worse than rejected: the caller had a parser
|
|
249
|
+
// waiting, got prose, and read the `JSONDecodeError` as the quick path
|
|
250
|
+
// having failed — which it had not (OSK-7647). `--quick` is a single
|
|
251
|
+
// one-shot response, so there is no event stream for `--jsonl` to carry.
|
|
252
|
+
this.error('--jsonl has no meaning with --quick: the persona-only summarizer returns one ' +
|
|
253
|
+
'response and streams no events. Use --quick --json for a machine-readable ' +
|
|
254
|
+
'one-shot, or drop --quick for a real streamed turn.', { exit: 2 });
|
|
255
|
+
}
|
|
134
256
|
if (flags['approve-tools'] && !process.stdin.isTTY) {
|
|
135
257
|
this.error('--approve-tools requires an interactive terminal.', { exit: 2 });
|
|
136
258
|
}
|
|
@@ -171,7 +293,12 @@ class AgentsChat extends base_command_1.BaseCommand {
|
|
|
171
293
|
'Address every task operation with this id explicitly, e.g.',
|
|
172
294
|
` skrr tasks show ${taskId} --json`,
|
|
173
295
|
` skrr tasks comments add ${taskId} --body "<progress>"`,
|
|
174
|
-
|
|
296
|
+
// `--deliverables`, not `--artifacts`: the flag was renamed with the
|
|
297
|
+
// domain and this line was not, so an agent following it verbatim got
|
|
298
|
+
// `Nonexistent flag: --artifacts` and had to reason its way out —
|
|
299
|
+
// costing a tool call, a model turn, and a paragraph of apology in the
|
|
300
|
+
// user-visible task output (OSK-7683).
|
|
301
|
+
` skrr tasks complete ${taskId} --summary "<what you did>" --deliverables "<refs>"`,
|
|
175
302
|
'',
|
|
176
303
|
'This is a chat turn, not a managed task run: the task is NOT checked out and its ' +
|
|
177
304
|
'status is not managed for you. Do not go looking for an implicit task context — ' +
|
|
@@ -181,11 +308,22 @@ class AgentsChat extends base_command_1.BaseCommand {
|
|
|
181
308
|
this.log(`Bound to task ${task.identifier ?? taskId} (chat turn — task not checked out)`);
|
|
182
309
|
}
|
|
183
310
|
}
|
|
184
|
-
else
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
311
|
+
else {
|
|
312
|
+
// Quote what matched. The warning states as fact that a task reference is
|
|
313
|
+
// present, and the old pattern `[A-Z][A-Z0-9]*-\d+` matched any uppercase
|
|
314
|
+
// token followed by a hyphen and digits — `UTF-8`, `GPT-4`, `RFC-2119`,
|
|
315
|
+
// `ERROR-500`, and every marker string a probe used — so it fired on
|
|
316
|
+
// prompts naming no task and gave the reader nothing to check it against.
|
|
317
|
+
// A warning that cries wolf on ordinary text is a warning people stop
|
|
318
|
+
// reading, and this one guards a genuinely expensive mistake (OSK-7736).
|
|
319
|
+
const match = AgentsChat.TASK_REF_IN_PROMPT.exec(flags.prompt);
|
|
320
|
+
if (match) {
|
|
321
|
+
this.warn(`The prompt names what looks like a task reference ("${match[0]}"), but this turn is ` +
|
|
322
|
+
'NOT bound to a task: the session will report ' +
|
|
323
|
+
'OVERSKY_SESSION_TASK_CONTEXT=main_chat and `skrr tasks show` without an id will ' +
|
|
324
|
+
'fail with TASK_CONTEXT_MISSING. Pass --task <id> to inject the canonical scope, ' +
|
|
325
|
+
'or use `skrr tasks start` for a managed run.');
|
|
326
|
+
}
|
|
189
327
|
}
|
|
190
328
|
// OSK-2936 — `--quick` is the ONLY route to the non-executing summarizer,
|
|
191
329
|
// and it says so.
|
|
@@ -253,7 +391,10 @@ class AgentsChat extends base_command_1.BaseCommand {
|
|
|
253
391
|
// `--no-stream` runs the SAME turn; it only withholds the live output.
|
|
254
392
|
const quiet = !!flags['no-stream'];
|
|
255
393
|
if (flags.jsonl) {
|
|
256
|
-
this.log
|
|
394
|
+
// Written through the one JSONL helper, not `this.log`: oclif routes that
|
|
395
|
+
// through `util.format`, which rewrites `%s`-shaped sequences that appear
|
|
396
|
+
// in ordinary agent output (OSK-7629).
|
|
397
|
+
(0, agentic_stream_1.writeJsonLine)(process.stdout, {
|
|
257
398
|
type: 'run.accepted',
|
|
258
399
|
sessionId: started.sessionId,
|
|
259
400
|
conversationId: started.conversationId,
|
|
@@ -261,7 +402,7 @@ class AgentsChat extends base_command_1.BaseCommand {
|
|
|
261
402
|
responseMessageId: started.responseMessageId,
|
|
262
403
|
agentId: args.agentId,
|
|
263
404
|
url: (0, web_url_1.agentUrlFrom)(this.cliConfig.baseURL, { id: args.agentId }),
|
|
264
|
-
})
|
|
405
|
+
});
|
|
265
406
|
}
|
|
266
407
|
else if (!quiet) {
|
|
267
408
|
for (const line of chatStreamHeaderLines({
|
|
@@ -274,6 +415,20 @@ class AgentsChat extends base_command_1.BaseCommand {
|
|
|
274
415
|
this.log(line);
|
|
275
416
|
}
|
|
276
417
|
}
|
|
418
|
+
// The durable record, consulted when the stream goes quiet. Without this
|
|
419
|
+
// the CLI has no terminal condition for a run-level failure at all: the
|
|
420
|
+
// refusal is written to the message and the session stream is never closed,
|
|
421
|
+
// so an interactive user waits forever and a script that shells out to
|
|
422
|
+
// `agents chat` never returns (OSK-7735).
|
|
423
|
+
const conversationId = started.conversationId;
|
|
424
|
+
const reconcileTerminal = conversationId
|
|
425
|
+
? async () => {
|
|
426
|
+
const messages = (await data_provider_1.dataService.getMessagesByConvoId(conversationId));
|
|
427
|
+
if (!Array.isArray(messages))
|
|
428
|
+
return null;
|
|
429
|
+
return reconcileTerminalFromMessages(messages, started.responseMessageId);
|
|
430
|
+
}
|
|
431
|
+
: undefined;
|
|
277
432
|
const client = new agentic_stream_1.AgenticStreamClient({
|
|
278
433
|
baseURL: this.cliConfig.baseURL,
|
|
279
434
|
token: this.resolvedCredential.token,
|
|
@@ -282,6 +437,7 @@ class AgentsChat extends base_command_1.BaseCommand {
|
|
|
282
437
|
jsonl: flags.jsonl,
|
|
283
438
|
quiet,
|
|
284
439
|
approveTools: flags['approve-tools'],
|
|
440
|
+
reconcileTerminal,
|
|
285
441
|
});
|
|
286
442
|
// OSK-2938 — Ctrl-C must be bounded, visible, and honest about what it
|
|
287
443
|
// did NOT stop.
|
|
@@ -311,7 +467,8 @@ class AgentsChat extends base_command_1.BaseCommand {
|
|
|
311
467
|
client.cancel();
|
|
312
468
|
if (!flags.jsonl) {
|
|
313
469
|
this.log(`\nCancelling run ${started.sessionId}… (waiting up to ${CANCEL_GRACE_MS / 1000}s; ` +
|
|
314
|
-
'press Ctrl-C again to detach)'
|
|
470
|
+
'press Ctrl-C again to detach). A tool call already running on the runtime is ' +
|
|
471
|
+
'not guaranteed to stop.');
|
|
315
472
|
}
|
|
316
473
|
graceTimer = setTimeout(() => detach?.(), CANCEL_GRACE_MS);
|
|
317
474
|
graceTimer.unref?.();
|
|
@@ -333,28 +490,51 @@ class AgentsChat extends base_command_1.BaseCommand {
|
|
|
333
490
|
}),
|
|
334
491
|
detached,
|
|
335
492
|
]);
|
|
493
|
+
// Ask the record before saying the run may still be running. That was
|
|
494
|
+
// said of a turn which had completed thirteen seconds earlier, and of
|
|
495
|
+
// turns the server had already finalised as errors — "it may still be
|
|
496
|
+
// executing" is the most expensive thing to be wrong about here, because
|
|
497
|
+
// it is what stops a caller retrying or alerting (OSK-7595, OSK-7660).
|
|
498
|
+
let reconciled = null;
|
|
336
499
|
if (outcome === 'detached') {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
500
|
+
if (await client.probeTerminal('detach'))
|
|
501
|
+
reconciled = client.settledResult();
|
|
502
|
+
}
|
|
503
|
+
if (outcome === 'detached' && !reconciled) {
|
|
504
|
+
const message = interrupts > 0
|
|
505
|
+
? interruptedDetachMessage({
|
|
506
|
+
sessionId: started.sessionId,
|
|
507
|
+
conversationId: started.conversationId,
|
|
508
|
+
})
|
|
509
|
+
: `Detached from run ${started.sessionId} before it reached a terminal state. ` +
|
|
510
|
+
'It may still be executing on the runtime. ' +
|
|
511
|
+
`Check with: ${inspectTurnCommand(started.conversationId)}`;
|
|
512
|
+
// 130 only when a signal actually caused this; otherwise the stream was
|
|
513
|
+
// lost and claiming SIGINT lies to every script reading the code
|
|
514
|
+
// (OSK-7660).
|
|
515
|
+
const exit = interrupts > 0 ? exports.DETACH_EXIT_CODE : exports.STREAM_LOST_EXIT_CODE;
|
|
341
516
|
if (flags.jsonl) {
|
|
342
|
-
|
|
517
|
+
(0, agentic_stream_1.writeJsonLine)(process.stdout, {
|
|
343
518
|
type: 'run.detached',
|
|
344
519
|
sessionId: started.sessionId,
|
|
345
520
|
conversationId: started.conversationId,
|
|
521
|
+
interrupted: interrupts > 0,
|
|
346
522
|
message,
|
|
347
|
-
})
|
|
523
|
+
});
|
|
524
|
+
// A detach is not a success in any output mode. `--jsonl` is the mode
|
|
525
|
+
// automation drives, so leaving this at 0 is the one that actually
|
|
526
|
+
// costs someone a wrong decision.
|
|
527
|
+
process.exitCode = exit;
|
|
348
528
|
return;
|
|
349
529
|
}
|
|
350
|
-
this.error(message, { exit
|
|
530
|
+
this.error(message, { exit });
|
|
351
531
|
}
|
|
352
|
-
const result = outcome;
|
|
532
|
+
const result = reconciled ?? outcome;
|
|
353
533
|
if (flags.jsonl) {
|
|
354
534
|
// The event stream already contains the terminal event. This summary
|
|
355
535
|
// makes shell consumers able to find the final text without replaying
|
|
356
536
|
// the event reducer.
|
|
357
|
-
|
|
537
|
+
(0, agentic_stream_1.writeJsonLine)(process.stdout, { type: 'run.result', ...result });
|
|
358
538
|
}
|
|
359
539
|
else if (quiet && flags.json) {
|
|
360
540
|
// A real executed turn — the metadata says so, unlike `--quick`.
|
|
@@ -27,6 +27,44 @@ export declare function agentCreateMissingFieldsMessage(missing: string[]): stri
|
|
|
27
27
|
* be reported.
|
|
28
28
|
*/
|
|
29
29
|
export declare function agentCreateMissingFields(payload: Record<string, unknown>): string[];
|
|
30
|
+
/**
|
|
31
|
+
* OSK-7680 — what creating ONE agent also starts.
|
|
32
|
+
*
|
|
33
|
+
* Within ~10 seconds of `agents create`, the new agent owns five
|
|
34
|
+
* system-managed commitments, four of them already active, on 30m/1h/2h/12h/1d
|
|
35
|
+
* cadences, three of them in Execute mode. Nothing in the create output said
|
|
36
|
+
* so: it carried only `proactiveProvisioning: {status: 'pending'}`, which does
|
|
37
|
+
* not read as "I am about to enrol this agent in four recurring autonomous
|
|
38
|
+
* loops". The person who asked for one agent got a standing workload, and the
|
|
39
|
+
* default `commitments list --agent <id>` then answered "No commitments."
|
|
40
|
+
*
|
|
41
|
+
* Said at creation because that is the moment the decision is being made and
|
|
42
|
+
* the moment `--no-relationship-loops` is still available. The opt-out already
|
|
43
|
+
* existed; only the disclosure was missing, and an opt-out nobody is told about
|
|
44
|
+
* is not one.
|
|
45
|
+
*/
|
|
46
|
+
/**
|
|
47
|
+
* KEYS THE SERVER DID NOT KEEP.
|
|
48
|
+
*
|
|
49
|
+
* OSK-7704 — a `--from-json` body carrying
|
|
50
|
+
* `"machineRequirements": {"capabilities": ["daemonTools"]}` created the agent
|
|
51
|
+
* and dropped the field: no warning, no 400, and `agents show --json` has no
|
|
52
|
+
* such key. The escape hatch the help points at for anything the flags do not
|
|
53
|
+
* cover accepts arbitrary keys and silently discards the ones the server does
|
|
54
|
+
* not model, so a caller who declares a requirement believes they declared it.
|
|
55
|
+
*
|
|
56
|
+
* Compared against the CREATED AGENT rather than a hard-coded field list: the
|
|
57
|
+
* server owns which keys it models, that set changes, and a list here would
|
|
58
|
+
* drift into warning about fields that now work. A key that came back — under
|
|
59
|
+
* any value, including `null` where the server deliberately stores one — is
|
|
60
|
+
* kept; anything absent from the response was not.
|
|
61
|
+
*
|
|
62
|
+
* A warning, never a refusal. Some keys legitimately do not round-trip (a
|
|
63
|
+
* write-only secret, a field the read projection omits), and turning those into
|
|
64
|
+
* a failed create would be worse than the silence.
|
|
65
|
+
*/
|
|
66
|
+
export declare function unappliedPayloadKeys(sent: Record<string, unknown>, created: unknown, ignore?: readonly string[]): string[];
|
|
67
|
+
export declare function backgroundLoopLines(agentId: string, relationshipLoopsSkipped: boolean): string[];
|
|
30
68
|
export default class AgentsCreate extends BaseCommand {
|
|
31
69
|
static description: string;
|
|
32
70
|
static examples: string[];
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.agentCreateMissingFieldsMessage = agentCreateMissingFieldsMessage;
|
|
4
4
|
exports.agentCreateMissingFields = agentCreateMissingFields;
|
|
5
|
+
exports.unappliedPayloadKeys = unappliedPayloadKeys;
|
|
6
|
+
exports.backgroundLoopLines = backgroundLoopLines;
|
|
5
7
|
const core_1 = require("@oclif/core");
|
|
6
8
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
7
9
|
const base_command_1 = require("../../base-command");
|
|
@@ -55,6 +57,72 @@ function agentCreateMissingFields(payload) {
|
|
|
55
57
|
missing.push('--target');
|
|
56
58
|
return missing;
|
|
57
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* OSK-7680 — what creating ONE agent also starts.
|
|
62
|
+
*
|
|
63
|
+
* Within ~10 seconds of `agents create`, the new agent owns five
|
|
64
|
+
* system-managed commitments, four of them already active, on 30m/1h/2h/12h/1d
|
|
65
|
+
* cadences, three of them in Execute mode. Nothing in the create output said
|
|
66
|
+
* so: it carried only `proactiveProvisioning: {status: 'pending'}`, which does
|
|
67
|
+
* not read as "I am about to enrol this agent in four recurring autonomous
|
|
68
|
+
* loops". The person who asked for one agent got a standing workload, and the
|
|
69
|
+
* default `commitments list --agent <id>` then answered "No commitments."
|
|
70
|
+
*
|
|
71
|
+
* Said at creation because that is the moment the decision is being made and
|
|
72
|
+
* the moment `--no-relationship-loops` is still available. The opt-out already
|
|
73
|
+
* existed; only the disclosure was missing, and an opt-out nobody is told about
|
|
74
|
+
* is not one.
|
|
75
|
+
*/
|
|
76
|
+
/**
|
|
77
|
+
* KEYS THE SERVER DID NOT KEEP.
|
|
78
|
+
*
|
|
79
|
+
* OSK-7704 — a `--from-json` body carrying
|
|
80
|
+
* `"machineRequirements": {"capabilities": ["daemonTools"]}` created the agent
|
|
81
|
+
* and dropped the field: no warning, no 400, and `agents show --json` has no
|
|
82
|
+
* such key. The escape hatch the help points at for anything the flags do not
|
|
83
|
+
* cover accepts arbitrary keys and silently discards the ones the server does
|
|
84
|
+
* not model, so a caller who declares a requirement believes they declared it.
|
|
85
|
+
*
|
|
86
|
+
* Compared against the CREATED AGENT rather than a hard-coded field list: the
|
|
87
|
+
* server owns which keys it models, that set changes, and a list here would
|
|
88
|
+
* drift into warning about fields that now work. A key that came back — under
|
|
89
|
+
* any value, including `null` where the server deliberately stores one — is
|
|
90
|
+
* kept; anything absent from the response was not.
|
|
91
|
+
*
|
|
92
|
+
* A warning, never a refusal. Some keys legitimately do not round-trip (a
|
|
93
|
+
* write-only secret, a field the read projection omits), and turning those into
|
|
94
|
+
* a failed create would be worse than the silence.
|
|
95
|
+
*/
|
|
96
|
+
function unappliedPayloadKeys(sent, created, ignore = []) {
|
|
97
|
+
if (!created || typeof created !== 'object' || Array.isArray(created))
|
|
98
|
+
return [];
|
|
99
|
+
const back = created;
|
|
100
|
+
const skip = new Set(ignore);
|
|
101
|
+
return Object.keys(sent)
|
|
102
|
+
.filter((key) => !skip.has(key))
|
|
103
|
+
.filter((key) => sent[key] !== undefined)
|
|
104
|
+
.filter((key) => !Object.prototype.hasOwnProperty.call(back, key))
|
|
105
|
+
.sort();
|
|
106
|
+
}
|
|
107
|
+
function backgroundLoopLines(agentId, relationshipLoopsSkipped) {
|
|
108
|
+
if (relationshipLoopsSkipped) {
|
|
109
|
+
return [
|
|
110
|
+
'Background loops: relationship portfolio skipped (--no-relationship-loops). ' +
|
|
111
|
+
'Self-reflection is still seeded and runs on its own cadence.',
|
|
112
|
+
` skrr commitments list --agent ${agentId} --include-system # what it still runs`,
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
return [
|
|
116
|
+
'Background loops: this agent is being enrolled in system-managed commitments — ' +
|
|
117
|
+
'self-reflection, conversation continuity, relationship pulse, commitment incubator ' +
|
|
118
|
+
'and open-loop closer. They run on their own cadence, unprompted, and are hidden ' +
|
|
119
|
+
'from the default commitments list.',
|
|
120
|
+
` skrr commitments list --agent ${agentId} --include-system # see them`,
|
|
121
|
+
` skrr commitments operating-review ${agentId} # what they are doing`,
|
|
122
|
+
' skrr commitments pause <commitment-id> # stop one',
|
|
123
|
+
' skrr agents create --no-relationship-loops # a single-purpose agent next time',
|
|
124
|
+
];
|
|
125
|
+
}
|
|
58
126
|
class AgentsCreate extends base_command_1.BaseCommand {
|
|
59
127
|
static description = 'Create a new agent in the selected workspace, or in your default workspace when --workspace is omitted (`skrr workspaces list` names it)';
|
|
60
128
|
static examples = [
|
|
@@ -91,7 +159,17 @@ class AgentsCreate extends base_command_1.BaseCommand {
|
|
|
91
159
|
}),
|
|
92
160
|
category: core_1.Flags.string({ description: 'Agent category' }),
|
|
93
161
|
target: core_1.Flags.string({
|
|
94
|
-
description: 'Required execution target. Use a Harness id, Hosted Machine session, or Agent Worker.
|
|
162
|
+
description: 'Required execution target. Use a Harness id, Hosted Machine session, or Agent Worker. ' +
|
|
163
|
+
'Use hosted-machine, sbs_..., agent-worker, or a connected Harness id. ' +
|
|
164
|
+
// There is no "unplaced" agent to create: a body that reaches the API
|
|
165
|
+
// without one is given an explicit `agent-worker` target server-side,
|
|
166
|
+
// so an operator who expected an unset field gets a real, visible
|
|
167
|
+
// placement they did not choose (OSK-7654). This command refuses the
|
|
168
|
+
// omission rather than letting that happen silently — say so, so the
|
|
169
|
+
// refusal reads as a contract rather than a missing feature.
|
|
170
|
+
'There is no unplaced agent: a create that omits this is given an ' +
|
|
171
|
+
'`agent-worker` target by the server, so this command asks instead of ' +
|
|
172
|
+
'letting a placement be chosen for you.',
|
|
95
173
|
}),
|
|
96
174
|
'next-target': core_1.Flags.string({
|
|
97
175
|
description: 'Next execution target in exact execution order after --target. Repeat in the order it should be tried.',
|
|
@@ -229,17 +307,32 @@ class AgentsCreate extends base_command_1.BaseCommand {
|
|
|
229
307
|
catch (err) {
|
|
230
308
|
this.handleApiError(err);
|
|
231
309
|
}
|
|
310
|
+
// Said before anything else, and in both output modes: a caller who
|
|
311
|
+
// declared a requirement the server does not model has NOT declared it, and
|
|
312
|
+
// finding that out later — from a run that landed somewhere it should not
|
|
313
|
+
// have — is the expensive way (OSK-7704).
|
|
314
|
+
// relationshipLoops is an input-only provisioning control. The server
|
|
315
|
+
// applies it by deciding which system commitments to seed, so it is not an
|
|
316
|
+
// Agent document field and is intentionally absent from the response.
|
|
317
|
+
const unapplied = unappliedPayloadKeys(payload, created, ['relationshipLoops']);
|
|
318
|
+
if (unapplied.length > 0) {
|
|
319
|
+
this.warn(`The server did not keep ${unapplied.join(', ')} — ${unapplied.length === 1 ? 'that field is' : 'those fields are'} not part of the agent it created. Check \`skrr agents show <id> --json\`.`);
|
|
320
|
+
}
|
|
232
321
|
if (flags.json) {
|
|
233
322
|
this.log(JSON.stringify((0, web_url_1.withAgentUrl)(this.cliConfig.baseURL, created), null, 2));
|
|
234
323
|
return;
|
|
235
324
|
}
|
|
236
325
|
const a = created;
|
|
237
|
-
|
|
326
|
+
const agentId = String(a.id ?? a._id ?? '?');
|
|
327
|
+
this.log(`Created agent ${agentId} — ${a.name ?? '(no name)'}`);
|
|
238
328
|
// Chosen for the user, so say so: a silent default is the kind of thing
|
|
239
329
|
// people discover much later, when it matters.
|
|
240
330
|
if (appliedDefaults.length > 0) {
|
|
241
331
|
this.log(`Defaults applied: ${appliedDefaults.join(', ')}`);
|
|
242
332
|
}
|
|
333
|
+
for (const line of backgroundLoopLines(agentId, flags['no-relationship-loops'] === true)) {
|
|
334
|
+
this.log(line);
|
|
335
|
+
}
|
|
243
336
|
this.log(`URL: ${(0, web_url_1.withAgentUrl)(this.cliConfig.baseURL, a).url ?? '-'}`);
|
|
244
337
|
}
|
|
245
338
|
}
|
|
@@ -77,7 +77,18 @@ class AgentsScheduleTrace extends base_command_1.BaseCommand {
|
|
|
77
77
|
if (events.length === 0) {
|
|
78
78
|
// An empty trace is a real answer — nothing touched this day's schedule —
|
|
79
79
|
// and must not read as a failed lookup.
|
|
80
|
+
//
|
|
81
|
+
// It is also a CLAIM, and it was wrong once (OSK-7658): the trace saw only
|
|
82
|
+
// triggers the smart-schedule planner had minted, so a one-shot from
|
|
83
|
+
// `skrr agents schedule --at` that fired and replied rendered as "nothing
|
|
84
|
+
// happened". The server-side filter is fixed; the sentence now names the
|
|
85
|
+
// two surfaces that would disagree, because a reader who has just been
|
|
86
|
+
// told nothing happened on a day they watched something happen should not
|
|
87
|
+
// have to guess where to look next.
|
|
80
88
|
this.log('No schedule events for this day.');
|
|
89
|
+
this.log('');
|
|
90
|
+
this.log(` ${this.config.bin} agents schedule-overview ${args.agent} # what is armed, and recent fires`);
|
|
91
|
+
this.log(` ${this.config.bin} agents activity ${args.agent} # what the agent actually did`);
|
|
81
92
|
return;
|
|
82
93
|
}
|
|
83
94
|
(0, format_1.renderTable)(events.map((e) => ({
|
|
@@ -57,6 +57,10 @@ function agentExecutionOrderLines(agent) {
|
|
|
57
57
|
const entries = projected.length > 0 ? projected : fallback;
|
|
58
58
|
if (entries.length === 0)
|
|
59
59
|
return ['Execution order: automatic (no configured target)'];
|
|
60
|
+
// Only the SERVER's projection knows whether a selector resolves. The local
|
|
61
|
+
// fallback is built from the stored policy and has no resolution information
|
|
62
|
+
// at all, so it must not claim one either way.
|
|
63
|
+
const resolved = projected.length > 0;
|
|
60
64
|
return [
|
|
61
65
|
'Execution order:',
|
|
62
66
|
...entries.map((entry, index) => {
|
|
@@ -64,10 +68,34 @@ function agentExecutionOrderLines(agent) {
|
|
|
64
68
|
const target = typeof entry.name === 'string' && entry.name ? entry.name : entry.selector;
|
|
65
69
|
const label = typeof entry.label === 'string' && entry.label ? ` — ${entry.label}` : '';
|
|
66
70
|
const status = typeof entry.status === 'string' ? ` (${entry.status})` : '';
|
|
67
|
-
|
|
71
|
+
// An UNRESOLVABLE target used to render as an absence — no name, no
|
|
72
|
+
// `(online)`/`(offline)` marker — on a line that otherwise looks like a
|
|
73
|
+
// normal one. `attach-harness` accepts an id that resolves to nothing
|
|
74
|
+
// with `ok: true`, so the typo persists silently, and an operator
|
|
75
|
+
// reviewing someone else's config reads entry 2 as a harness whose
|
|
76
|
+
// status is momentarily unknown. Entry 2 in a chain is by definition the
|
|
77
|
+
// one you have not looked at recently. An unresolvable target is a
|
|
78
|
+
// strictly worse condition than an offline one, and offline is loud
|
|
79
|
+
// (OSK-7677). An absence becomes a statement.
|
|
80
|
+
const unresolvable = resolved &&
|
|
81
|
+
!status &&
|
|
82
|
+
!(typeof entry.name === 'string' && entry.name) &&
|
|
83
|
+
!isSynthetic(entry)
|
|
84
|
+
? ' [!] no such harness — nothing is registered under this id'
|
|
85
|
+
: '';
|
|
86
|
+
return ` ${position}. ${target || '(invalid target)'}${status}${label}${unresolvable}`;
|
|
68
87
|
}),
|
|
69
88
|
];
|
|
70
89
|
}
|
|
90
|
+
/** The platform's own products resolve by name, not by a harness lookup. */
|
|
91
|
+
function isSynthetic(entry) {
|
|
92
|
+
const kind = typeof entry.kind === 'string' ? entry.kind : '';
|
|
93
|
+
if (kind === 'agent-worker' || kind === 'hosted-machine' || kind === 'hosted-job-machine') {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
const selector = typeof entry.selector === 'string' ? entry.selector : '';
|
|
97
|
+
return selector.startsWith('__oversky_') || selector.startsWith('sbs_');
|
|
98
|
+
}
|
|
71
99
|
class AgentsShow extends base_command_1.BaseCommand {
|
|
72
100
|
static description = 'Show details for a single agent';
|
|
73
101
|
static examples = [
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* Mint a Managed Agents API key for a Space.
|
|
4
|
+
*
|
|
5
|
+
* The secret is displayed EXACTLY ONCE. There is no endpoint that reveals it
|
|
6
|
+
* again, so this command says that where the value is printed rather than in a
|
|
7
|
+
* footnote — a caller that scrolls past it has to rotate.
|
|
8
|
+
*/
|
|
9
|
+
export default class ApiKeysCreate extends BaseCommand {
|
|
10
|
+
static description: string;
|
|
11
|
+
static examples: string[];
|
|
12
|
+
static args: {
|
|
13
|
+
name: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
14
|
+
};
|
|
15
|
+
static flags: {
|
|
16
|
+
space: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
17
|
+
name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
18
|
+
env: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
|
+
scope: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
20
|
+
'expires-at': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
22
|
+
};
|
|
23
|
+
run(): Promise<void>;
|
|
24
|
+
}
|