@skrr-ai/cli 0.1.39 → 0.1.41
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 +1 -1
- package/dist/base-command.d.ts +9 -0
- package/dist/base-command.js +26 -3
- package/dist/commands/agent-shares/list-for.js +4 -11
- package/dist/commands/agent-shares/received.js +4 -11
- package/dist/commands/agent-shares/sent.js +4 -11
- package/dist/commands/agent-shares/with.js +3 -10
- package/dist/commands/agents/activity.js +1 -1
- package/dist/commands/agents/api-actions/add.js +6 -0
- package/dist/commands/agents/chat.js +6 -1
- package/dist/commands/agents/create.d.ts +7 -0
- package/dist/commands/agents/create.js +19 -2
- package/dist/commands/agents/manager/ensure.d.ts +18 -0
- package/dist/commands/agents/manager/ensure.js +56 -0
- package/dist/commands/agents/show.js +4 -0
- package/dist/commands/agents/tools/auth.d.ts +6 -0
- package/dist/commands/agents/tools/auth.js +27 -1
- package/dist/commands/agents/tools/index.js +11 -1
- package/dist/commands/agents/triggers/policy.d.ts +1 -0
- package/dist/commands/agents/triggers/policy.js +32 -0
- package/dist/commands/agents/update.js +10 -4
- package/dist/commands/code/install.d.ts +4 -2
- package/dist/commands/code/install.js +12 -10
- package/dist/commands/convos/list.js +1 -3
- package/dist/commands/convos/show.js +4 -11
- package/dist/commands/daemon/index.js +3 -3
- package/dist/commands/daemon/install.js +4 -4
- package/dist/commands/daemon/login.js +1 -1
- package/dist/commands/daemon/logs.d.ts +3 -1
- package/dist/commands/daemon/logs.js +16 -1
- package/dist/commands/daemon/start.js +3 -3
- package/dist/commands/daemon/status.d.ts +9 -0
- package/dist/commands/daemon/status.js +22 -0
- package/dist/commands/dm/messages.js +1 -11
- package/dist/commands/followups/cancel.js +1 -1
- package/dist/commands/followups/observability.js +6 -2
- package/dist/commands/followups/remind.js +5 -2
- package/dist/commands/followups/reschedule.js +2 -1
- package/dist/commands/followups/resolve.js +1 -1
- package/dist/commands/followups/show.js +20 -0
- package/dist/commands/followups/watch.d.ts +1 -0
- package/dist/commands/followups/watch.js +9 -3
- package/dist/commands/harnesses/forget.js +20 -3
- package/dist/commands/harnesses/install.js +18 -6
- package/dist/commands/harnesses/installers.d.ts +1 -1
- package/dist/commands/harnesses/installers.js +36 -12
- package/dist/commands/harnesses/list.d.ts +74 -2
- package/dist/commands/harnesses/list.js +231 -15
- package/dist/commands/harnesses/ping.d.ts +2 -0
- package/dist/commands/harnesses/ping.js +21 -0
- package/dist/commands/harnesses/show.d.ts +22 -0
- package/dist/commands/harnesses/show.js +116 -17
- package/dist/commands/harnesses/update.d.ts +8 -0
- package/dist/commands/harnesses/update.js +25 -1
- package/dist/commands/harnesses/usage.d.ts +2 -0
- package/dist/commands/harnesses/usage.js +7 -2
- package/dist/commands/instructions/status.js +13 -0
- package/dist/commands/instructions/update-target.d.ts +1 -0
- package/dist/commands/instructions/update-target.js +11 -3
- package/dist/commands/login.js +5 -5
- package/dist/commands/machines/list.js +8 -9
- package/dist/commands/machines/show.js +46 -17
- package/dist/commands/messages/show.js +3 -10
- package/dist/commands/shares/get.js +2 -9
- package/dist/commands/shares/list.js +1 -9
- package/dist/commands/shortcuts/show.js +4 -11
- package/dist/commands/skills/local.js +6 -0
- package/dist/commands/spaces/actions/run.js +3 -4
- package/dist/commands/spaces/briefs/get.js +2 -9
- package/dist/commands/spaces/briefs/list.js +1 -9
- package/dist/commands/spaces/conversations.js +1 -9
- package/dist/commands/spaces/heartbeats/list.js +1 -9
- package/dist/commands/spaces/heartbeats/status.js +2 -9
- package/dist/commands/tasks/activity.js +1 -10
- package/dist/commands/tasks/approvals/list.js +1 -9
- package/dist/commands/tasks/attachments/list.js +1 -9
- package/dist/commands/tasks/comments/list.js +1 -9
- package/dist/commands/tasks/dri-status.js +2 -9
- package/dist/commands/tasks/events/append.js +9 -7
- package/dist/commands/tasks/execution-timeline.js +1 -9
- package/dist/commands/tasks/lifecycle/detach.js +26 -5
- package/dist/commands/tasks/monitor.js +1 -9
- package/dist/commands/tasks/result/submit.js +9 -0
- package/dist/commands/tasks/runs.js +1 -9
- package/dist/commands/tasks/show.js +5 -12
- package/dist/commands/token/list.d.ts +8 -0
- package/dist/commands/token/list.js +51 -6
- package/dist/help.js +8 -12
- package/dist/lib/agent-home-workspace.d.ts +19 -0
- package/dist/lib/agent-home-workspace.js +39 -0
- package/dist/lib/agent-resolver.js +2 -2
- package/dist/lib/agentic-stream.d.ts +22 -1
- package/dist/lib/agentic-stream.js +48 -7
- package/dist/lib/cli-installers.d.ts +84 -2
- package/dist/lib/cli-installers.js +146 -13
- package/dist/lib/command-miss.d.ts +22 -0
- package/dist/lib/command-miss.js +78 -0
- package/dist/lib/daemon-setup.js +2 -2
- package/dist/lib/daemon-target.d.ts +14 -0
- package/dist/lib/daemon-target.js +32 -0
- package/dist/lib/daemonBroker.js +1 -1
- package/dist/lib/daemonHandoff.js +1 -1
- package/dist/lib/dedicated-lease-command.js +4 -1
- package/dist/lib/dedicated-machines.d.ts +8 -1
- package/dist/lib/dedicated-machines.js +22 -6
- package/dist/lib/dedicated-wait.js +13 -0
- package/dist/lib/exec-runtime-binary.js +2 -2
- package/dist/lib/followups.d.ts +18 -0
- package/dist/lib/followups.js +14 -1
- package/dist/lib/format.d.ts +11 -0
- package/dist/lib/format.js +21 -0
- package/dist/lib/harness-labels.d.ts +39 -0
- package/dist/lib/harness-labels.js +60 -0
- package/dist/lib/harnesses.d.ts +6 -0
- package/dist/lib/instruction-input.d.ts +13 -0
- package/dist/lib/instruction-input.js +20 -1
- package/dist/lib/label-ref.d.ts +8 -1
- package/dist/lib/label-ref.js +12 -2
- package/dist/lib/local-skills.d.ts +17 -1
- package/dist/lib/local-skills.js +20 -2
- package/dist/lib/login.js +5 -5
- package/dist/lib/machines.d.ts +6 -0
- package/dist/lib/machines.js +68 -2
- package/dist/lib/option-hint.d.ts +15 -0
- package/dist/lib/option-hint.js +75 -0
- package/dist/lib/runtime-tool-support.d.ts +34 -0
- package/dist/lib/runtime-tool-support.js +77 -0
- package/dist/lib/share-rows.d.ts +17 -0
- package/dist/lib/share-rows.js +35 -0
- package/dist/lib/workspaces.d.ts +3 -0
- package/dist/lib/workspaces.js +38 -0
- package/dist/node_modules/@skrr-ai/data-provider/index.js +5029 -5007
- package/oclif.manifest.json +34255 -34142
- package/package.json +10 -5
|
@@ -4,6 +4,7 @@ const core_1 = require("@oclif/core");
|
|
|
4
4
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
5
|
const base_command_1 = require("../../../base-command");
|
|
6
6
|
const space_output_1 = require("../../../lib/space-output");
|
|
7
|
+
const format_1 = require("../../../lib/format");
|
|
7
8
|
class SpacesHeartbeatsStatus extends base_command_1.BaseCommand {
|
|
8
9
|
static description = 'Get the live status of a heartbeat for an agent in a space';
|
|
9
10
|
static examples = [
|
|
@@ -45,16 +46,8 @@ class SpacesHeartbeatsStatus extends base_command_1.BaseCommand {
|
|
|
45
46
|
// `running`/`nextRun`/`jobKey` which always rendered "no" / "-".
|
|
46
47
|
const s = result;
|
|
47
48
|
this.log(`Running: ${s.isRunning === true ? 'yes' : 'no'}`);
|
|
48
|
-
this.log(`Next Run: ${s.nextRunAt ?
|
|
49
|
+
this.log(`Next Run: ${s.nextRunAt ? (0, format_1.localTime)(s.nextRunAt) : '-'}`);
|
|
49
50
|
this.log(`BullMQ Job Key: ${s.bullmqJobKey ?? '-'}`);
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
exports.default = SpacesHeartbeatsStatus;
|
|
53
|
-
function formatTime(value) {
|
|
54
|
-
try {
|
|
55
|
-
return new Date(String(value)).toISOString().slice(0, 19).replace('T', ' ');
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
return String(value);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
@@ -19,7 +19,7 @@ function activityRow(entry) {
|
|
|
19
19
|
: `system:${actor.service}`
|
|
20
20
|
: (entry.userId ?? entry.actorId);
|
|
21
21
|
return {
|
|
22
|
-
time:
|
|
22
|
+
time: (0, format_1.localTime)(entry.occurredAt ?? entry.timestamp ?? entry.createdAt),
|
|
23
23
|
event: (0, format_1.formatCell)(entry.action ?? entry.event ?? entry.type),
|
|
24
24
|
actor: (0, format_1.formatCell)(actorText),
|
|
25
25
|
details: (0, format_1.formatCell)(entry.data ?? entry.details ?? entry.metadata),
|
|
@@ -71,15 +71,6 @@ function runFailuresFromActivity(entries) {
|
|
|
71
71
|
}
|
|
72
72
|
return out;
|
|
73
73
|
}
|
|
74
|
-
/** Same contract as `tasks monitor`'s timestamp column — never throws, never prints "undefined". */
|
|
75
|
-
function formatTime(value) {
|
|
76
|
-
if (!value)
|
|
77
|
-
return '-';
|
|
78
|
-
const date = new Date(String(value));
|
|
79
|
-
if (Number.isNaN(date.getTime()))
|
|
80
|
-
return String(value);
|
|
81
|
-
return date.toISOString().slice(0, 19).replace('T', ' ');
|
|
82
|
-
}
|
|
83
74
|
class TasksActivity extends base_command_1.BaseCommand {
|
|
84
75
|
static description = 'Show the immutable, multi-actor Activity ledger for a Task';
|
|
85
76
|
static examples = [
|
|
@@ -5,14 +5,6 @@ const core_1 = require("@oclif/core");
|
|
|
5
5
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
6
6
|
const base_command_1 = require("../../../base-command");
|
|
7
7
|
const format_1 = require("../../../lib/format");
|
|
8
|
-
function formatTime(value) {
|
|
9
|
-
try {
|
|
10
|
-
return new Date(String(value)).toISOString().slice(0, 19).replace('T', ' ');
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
return String(value);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
8
|
/**
|
|
17
9
|
* One approval document → one table row.
|
|
18
10
|
*
|
|
@@ -27,7 +19,7 @@ function approvalRow(a) {
|
|
|
27
19
|
type: (0, format_1.formatCell)(a.type),
|
|
28
20
|
status: (0, format_1.formatCell)(a.status),
|
|
29
21
|
approver: (0, format_1.formatCell)(a.approverAgentId ?? a.approverUserId ?? a.approver),
|
|
30
|
-
created: a.createdAt ?
|
|
22
|
+
created: a.createdAt ? (0, format_1.localTime)(a.createdAt) : '-',
|
|
31
23
|
};
|
|
32
24
|
}
|
|
33
25
|
class TasksApprovalsList extends base_command_1.BaseCommand {
|
|
@@ -5,14 +5,6 @@ const core_1 = require("@oclif/core");
|
|
|
5
5
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
6
6
|
const base_command_1 = require("../../../base-command");
|
|
7
7
|
const format_1 = require("../../../lib/format");
|
|
8
|
-
function formatTime(value) {
|
|
9
|
-
try {
|
|
10
|
-
return new Date(String(value)).toISOString().slice(0, 19).replace('T', ' ');
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
return String(value);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
8
|
function humanBytes(bytes) {
|
|
17
9
|
const n = Number(bytes);
|
|
18
10
|
if (!Number.isFinite(n))
|
|
@@ -41,7 +33,7 @@ function attachmentRow(a) {
|
|
|
41
33
|
filename: (0, format_1.formatCell)(a.originalName ?? a.filename ?? a.name),
|
|
42
34
|
size: humanBytes(a.size ?? a.fileSize),
|
|
43
35
|
mime: (0, format_1.formatCell)(a.mimeType ?? a.contentType),
|
|
44
|
-
uploaded: a.createdAt ?
|
|
36
|
+
uploaded: a.createdAt ? (0, format_1.localTime)(a.createdAt) : '-',
|
|
45
37
|
};
|
|
46
38
|
}
|
|
47
39
|
class TasksAttachmentsList extends base_command_1.BaseCommand {
|
|
@@ -5,14 +5,6 @@ const data_provider_1 = require("@skrr-ai/data-provider");
|
|
|
5
5
|
const base_command_1 = require("../../../base-command");
|
|
6
6
|
const format_1 = require("../../../lib/format");
|
|
7
7
|
const task_resolver_1 = require("../../../lib/task-resolver");
|
|
8
|
-
function formatTime(value) {
|
|
9
|
-
try {
|
|
10
|
-
return new Date(String(value)).toISOString().slice(0, 19).replace('T', ' ');
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
return String(value);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
8
|
class TasksCommentsList extends base_command_1.BaseCommand {
|
|
17
9
|
static description = 'List comments on a task';
|
|
18
10
|
static examples = [
|
|
@@ -76,7 +68,7 @@ class TasksCommentsList extends base_command_1.BaseCommand {
|
|
|
76
68
|
return;
|
|
77
69
|
}
|
|
78
70
|
const rows = items.map((c) => ({
|
|
79
|
-
time:
|
|
71
|
+
time: (0, format_1.localTime)(c.createdAt),
|
|
80
72
|
author: String(c.authorAgentId ?? c.authorUserId ?? c.author ?? '-'),
|
|
81
73
|
body: (0, format_1.truncate)(String(c.body ?? c.content ?? '-'), 60),
|
|
82
74
|
id: String(c.id ?? c._id ?? '-'),
|
|
@@ -3,14 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
4
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
5
|
const base_command_1 = require("../../base-command");
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
return new Date(String(value)).toISOString().slice(0, 19).replace('T', ' ');
|
|
9
|
-
}
|
|
10
|
-
catch {
|
|
11
|
-
return String(value);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
6
|
+
const format_1 = require("../../lib/format");
|
|
14
7
|
class TasksDriStatus extends base_command_1.BaseCommand {
|
|
15
8
|
static description = 'Show DRI agent status for a task';
|
|
16
9
|
static examples = [
|
|
@@ -40,7 +33,7 @@ class TasksDriStatus extends base_command_1.BaseCommand {
|
|
|
40
33
|
const s = result;
|
|
41
34
|
this.log(`Status: ${s.status ?? '-'}`);
|
|
42
35
|
this.log(`Mode: ${s.mode ?? '-'}`);
|
|
43
|
-
this.log(`Started At: ${s.startedAt ?
|
|
36
|
+
this.log(`Started At: ${s.startedAt ? (0, format_1.localTime)(s.startedAt) : '-'}`);
|
|
44
37
|
this.log(`Total: ${s.totalSubtasks ?? s.total ?? '-'}`);
|
|
45
38
|
this.log(`Done: ${s.doneCount ?? s.done ?? '-'}`);
|
|
46
39
|
this.log(`In Progress: ${s.inProgressCount ?? s.inProgress ?? '-'}`);
|
|
@@ -18,15 +18,17 @@ class TasksEventsAppend extends base_command_1.BaseCommand {
|
|
|
18
18
|
static summary = 'DEPRECATED compatibility spelling for `tasks updates add` — append a legacy task event';
|
|
19
19
|
// The FULL mapping, not a sample of it. The previous description named
|
|
20
20
|
// `handoff`/`checkpoint` and `started|lifecycle` and stopped — so a caller
|
|
21
|
-
// passing `--kind evidence` had no way to learn, before writing,
|
|
22
|
-
//
|
|
23
|
-
// says a flow was exercised, `verification` says a claim was
|
|
24
|
-
//
|
|
21
|
+
// passing `--kind evidence` had no way to learn, before writing, what it
|
|
22
|
+
// became. It used to become a `verification` with an invented `inconclusive`
|
|
23
|
+
// result; `evidence` says a flow was exercised, `verification` says a claim was
|
|
24
|
+
// CHECKED, so it now becomes `progress` and keeps the evidence as a reference
|
|
25
|
+
// (OSK-9312).
|
|
25
26
|
// Mirrors `LEGACY_KIND_TO_UPDATE_TYPE` in `api/server/services/TaskWorkEvent.js`.
|
|
26
27
|
static description = 'DEPRECATED compatibility adapter for the historical Event vocabulary. Every kind is ' +
|
|
27
28
|
'stored as a canonical Update of a DIFFERENT name, so read this before relying on one: ' +
|
|
28
|
-
'`
|
|
29
|
-
|
|
29
|
+
'`verification` becomes a passed `verification`; `evidence`, `checkpoint`, `changed`, ' +
|
|
30
|
+
"`completed` and `handoff` all become `progress` (evidence text is kept as the Update's reference, " +
|
|
31
|
+
'with no invented result); `input_requested` and `failed` become ' +
|
|
30
32
|
'`blocker`; `decision` stays `decision`. `--kind started|lifecycle` writes only to the ' +
|
|
31
33
|
'Activity ledger and will NOT appear in `tasks updates list`. Use `tasks updates add` ' +
|
|
32
34
|
'instead, which writes the type you name.';
|
|
@@ -129,7 +131,7 @@ class TasksEventsAppend extends base_command_1.BaseCommand {
|
|
|
129
131
|
* where it happens to be true. `finding` and `progress` exist only on the
|
|
130
132
|
* canonical command; `evidence`, `checkpoint` and the rest only here.
|
|
131
133
|
*/
|
|
132
|
-
this.log(`\`tasks events append --kind ${
|
|
134
|
+
this.log(`\`tasks events append --kind ${flags.kind}\` maps onto ` +
|
|
133
135
|
`\`${this.config.bin} tasks updates add --type ${written.canonicalType}\`, which is the ` +
|
|
134
136
|
'canonical command. Their vocabularies differ otherwise — `--type ' +
|
|
135
137
|
'progress|finding` exist only there — and `tasks updates list` reads them back.');
|
|
@@ -4,14 +4,6 @@ const core_1 = require("@oclif/core");
|
|
|
4
4
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
5
|
const base_command_1 = require("../../base-command");
|
|
6
6
|
const format_1 = require("../../lib/format");
|
|
7
|
-
function formatTime(value) {
|
|
8
|
-
try {
|
|
9
|
-
return new Date(String(value)).toISOString().slice(0, 19).replace('T', ' ');
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
return String(value);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
7
|
class TasksExecutionTimeline extends base_command_1.BaseCommand {
|
|
16
8
|
static description = 'Show execution timeline for a task';
|
|
17
9
|
static examples = [
|
|
@@ -49,7 +41,7 @@ class TasksExecutionTimeline extends base_command_1.BaseCommand {
|
|
|
49
41
|
return;
|
|
50
42
|
}
|
|
51
43
|
const rows = items.map((entry) => ({
|
|
52
|
-
timestamp:
|
|
44
|
+
timestamp: (0, format_1.localTime)(entry.timestamp ?? entry.createdAt),
|
|
53
45
|
event: String(entry.event ?? entry.type ?? '-'),
|
|
54
46
|
duration: entry.durationMs != null ? `${entry.durationMs}ms` : '-',
|
|
55
47
|
tokens: String(entry.tokens ?? entry.totalTokens ?? '-'),
|
|
@@ -43,11 +43,26 @@ class TasksLifecycleDetach extends base_command_1.BaseCommand {
|
|
|
43
43
|
return this.log('No lifecycle is attached to this Task — nothing to detach.');
|
|
44
44
|
this.log(`Would detach ${lifecycle.packId ? `pack ${lifecycle.packId}` : `definition ${lifecycle.definitionId}`}` +
|
|
45
45
|
` at generation ${lifecycle.generation}, stage ${lifecycle.currentStageKey ?? '—'}.`);
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
if (lifecycle.runId) {
|
|
47
|
+
this.log(' The run is cancelled and kept as history; nothing already recorded is removed.');
|
|
48
|
+
this.log(' The generation is bumped, so no in-flight writer from the old run can land.');
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
this.log(' It has not started, so there is no run to cancel.');
|
|
52
|
+
}
|
|
48
53
|
this.log(' Re-attaching afterwards starts a NEW generation — it does not resume this one.');
|
|
49
54
|
return;
|
|
50
55
|
}
|
|
56
|
+
// The server clears runId on detach, so whether there WAS a run to cancel
|
|
57
|
+
// is only knowable before the write. Best-effort: a failed read must not
|
|
58
|
+
// block the detach, it only costs the sentence its precision.
|
|
59
|
+
let hadRun;
|
|
60
|
+
try {
|
|
61
|
+
hadRun = Boolean((await data_provider_1.dataService.getTaskLifecycle(taskId)).lifecycle?.runId);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
hadRun = undefined;
|
|
65
|
+
}
|
|
51
66
|
let response;
|
|
52
67
|
try {
|
|
53
68
|
response = await data_provider_1.dataService.detachTaskLifecycle({
|
|
@@ -62,9 +77,15 @@ class TasksLifecycleDetach extends base_command_1.BaseCommand {
|
|
|
62
77
|
return this.log(JSON.stringify(response, null, 2));
|
|
63
78
|
const lifecycle = response.lifecycle;
|
|
64
79
|
// Name what changed. "Detached lifecycle from the Task." left the reader to
|
|
65
|
-
// diff the state afterwards to learn what had happened
|
|
66
|
-
|
|
67
|
-
|
|
80
|
+
// diff the state afterwards to learn what had happened — and saying a run
|
|
81
|
+
// was cancelled when none had started is the same problem the other way.
|
|
82
|
+
const runSentence = hadRun === false
|
|
83
|
+
? 'it had not started, so there was no run to cancel'
|
|
84
|
+
: hadRun
|
|
85
|
+
? 'the run is cancelled and kept as history'
|
|
86
|
+
: 'any run is cancelled and kept as history';
|
|
87
|
+
this.log(`Detached${lifecycle?.packId ? ` pack ${lifecycle.packId}` : ''} — ${runSentence},` +
|
|
88
|
+
` and the binding is now generation ${lifecycle?.generation ?? '?'}` +
|
|
68
89
|
` (${lifecycle?.status ?? 'detached'}).`);
|
|
69
90
|
this.log('Re-attach with: skrr tasks lifecycle attach <task-id> --pack <pack>');
|
|
70
91
|
}
|
|
@@ -205,7 +205,7 @@ async function fetchRecentEvents(tasks, limit) {
|
|
|
205
205
|
ref: String(task.identifier ?? task.taskNumber ?? '-'),
|
|
206
206
|
taskId: (0, tasks_1.taskId)(task),
|
|
207
207
|
event: String(record.event ?? record.type ?? '-'),
|
|
208
|
-
time:
|
|
208
|
+
time: (0, format_1.localTime)(record.timestamp ?? record.createdAt),
|
|
209
209
|
run: String(record.runId ?? '-'),
|
|
210
210
|
};
|
|
211
211
|
});
|
|
@@ -216,11 +216,3 @@ async function fetchRecentEvents(tasks, limit) {
|
|
|
216
216
|
}));
|
|
217
217
|
return responses.flat();
|
|
218
218
|
}
|
|
219
|
-
function formatTime(value) {
|
|
220
|
-
if (!value)
|
|
221
|
-
return '-';
|
|
222
|
-
const date = new Date(String(value));
|
|
223
|
-
if (Number.isNaN(date.getTime()))
|
|
224
|
-
return String(value);
|
|
225
|
-
return date.toISOString().slice(0, 19).replace('T', ' ');
|
|
226
|
-
}
|
|
@@ -122,6 +122,15 @@ class TasksResultSubmit extends base_command_1.BaseCommand {
|
|
|
122
122
|
: await data_provider_1.dataService.submitTaskResult({ taskId: task.id, data });
|
|
123
123
|
}
|
|
124
124
|
catch (error) {
|
|
125
|
+
// A closed Task refuses a Result. Name the two ways forward here, where
|
|
126
|
+
// the commands are known: the API's own message stays surface-neutral
|
|
127
|
+
// (OSK-10031).
|
|
128
|
+
const refusal = (0, base_command_1.apiRefusal)(error);
|
|
129
|
+
if (refusal.code === 'TASK_REOPEN_REQUIRED') {
|
|
130
|
+
this.error(`${refusal.message ?? 'This Task is closed.'}\n` +
|
|
131
|
+
`→ Reopen it and submit again: ${this.config.bin} tasks move ${task.id} --status in_progress\n` +
|
|
132
|
+
`→ Or record the Result and close it in one step: ${this.config.bin} tasks complete ${task.id} --summary "…"`, { exit: 1, code: 'TASK_REOPEN_REQUIRED' });
|
|
133
|
+
}
|
|
125
134
|
this.handleApiError(error);
|
|
126
135
|
}
|
|
127
136
|
const url = (0, web_url_1.taskUrlFrom)(this.cliConfig.baseURL, { id: task.id });
|
|
@@ -10,14 +10,6 @@ const data_provider_1 = require("@skrr-ai/data-provider");
|
|
|
10
10
|
const base_command_1 = require("../../base-command");
|
|
11
11
|
const format_1 = require("../../lib/format");
|
|
12
12
|
const activity_1 = require("./activity");
|
|
13
|
-
function formatTime(value) {
|
|
14
|
-
try {
|
|
15
|
-
return new Date(String(value)).toISOString().slice(0, 19).replace('T', ' ');
|
|
16
|
-
}
|
|
17
|
-
catch {
|
|
18
|
-
return String(value);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
13
|
/**
|
|
22
14
|
* OSK-4836 — say WHERE a run executed. A named daemon wins over the environment
|
|
23
15
|
* label; an environment with no daemon is the cloud worker (or a runtime whose
|
|
@@ -163,7 +155,7 @@ class TasksRuns extends base_command_1.BaseCommand {
|
|
|
163
155
|
runId: String(run.runId ?? run.id ?? run._id ?? '-'),
|
|
164
156
|
status: String(run.status ?? '-'),
|
|
165
157
|
executor: formatRunExecutor(run),
|
|
166
|
-
started: run.startedAt ?
|
|
158
|
+
started: run.startedAt ? (0, format_1.localTime)(run.startedAt) : '-',
|
|
167
159
|
duration: run.durationMs != null ? `${run.durationMs}ms` : '-',
|
|
168
160
|
tokens: String(run.totalTokens ?? run.tokens ?? '-'),
|
|
169
161
|
}));
|
|
@@ -11,6 +11,7 @@ const task_closure_1 = require("../../lib/task-closure");
|
|
|
11
11
|
const task_resolver_1 = require("../../lib/task-resolver");
|
|
12
12
|
const web_url_1 = require("../../lib/web-url");
|
|
13
13
|
const html_text_1 = require("../../lib/html-text");
|
|
14
|
+
const format_1 = require("../../lib/format");
|
|
14
15
|
/**
|
|
15
16
|
* Where to look next — as COMMANDS, not as facts about the task.
|
|
16
17
|
*
|
|
@@ -67,7 +68,7 @@ function taskPointerLines(t, ref, bin = 'skrr') {
|
|
|
67
68
|
*/
|
|
68
69
|
function taskFailureLines(t, bin = 'skrr') {
|
|
69
70
|
const error = typeof t.executionError === 'string' ? t.executionError.trim() : '';
|
|
70
|
-
const failedAt = t.lastFailedAt ?
|
|
71
|
+
const failedAt = t.lastFailedAt ? (0, format_1.localTime)(t.lastFailedAt) : null;
|
|
71
72
|
const isFailed = t.status === 'failed';
|
|
72
73
|
if (!error && !failedAt && !isFailed)
|
|
73
74
|
return [];
|
|
@@ -335,7 +336,7 @@ class TasksShow extends base_command_1.BaseCommand {
|
|
|
335
336
|
this.log(`Previews: ${delivery.previewLinks.length}`);
|
|
336
337
|
}
|
|
337
338
|
if (delivery.prStateUpdatedAt)
|
|
338
|
-
this.log(`PR updated: ${
|
|
339
|
+
this.log(`PR updated: ${(0, format_1.localTime)(delivery.prStateUpdatedAt)}`);
|
|
339
340
|
}
|
|
340
341
|
// Prefer server-enriched names; fall back to bare ids under --no-enrich.
|
|
341
342
|
const enrichedSkills = Array.isArray(t._pinnedSkills)
|
|
@@ -369,9 +370,9 @@ class TasksShow extends base_command_1.BaseCommand {
|
|
|
369
370
|
.join(', ')} (attached; injected on every run)`);
|
|
370
371
|
}
|
|
371
372
|
if (t.createdAt)
|
|
372
|
-
this.log(`Created: ${
|
|
373
|
+
this.log(`Created: ${(0, format_1.localTime)(t.createdAt)}`);
|
|
373
374
|
if (t.updatedAt)
|
|
374
|
-
this.log(`Updated: ${
|
|
375
|
+
this.log(`Updated: ${(0, format_1.localTime)(t.updatedAt)}`);
|
|
375
376
|
/**
|
|
376
377
|
* Say which Task model this row belongs to, on the one surface everybody
|
|
377
378
|
* reads first.
|
|
@@ -434,11 +435,3 @@ class TasksShow extends base_command_1.BaseCommand {
|
|
|
434
435
|
}
|
|
435
436
|
}
|
|
436
437
|
exports.default = TasksShow;
|
|
437
|
-
function formatTime(value) {
|
|
438
|
-
try {
|
|
439
|
-
return new Date(String(value)).toISOString().slice(0, 19).replace('T', ' ');
|
|
440
|
-
}
|
|
441
|
-
catch {
|
|
442
|
-
return String(value);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
@@ -11,11 +11,19 @@ import { BaseCommand } from '../../base-command';
|
|
|
11
11
|
*
|
|
12
12
|
* `GET /api/auth/sessions/refresh` has served exactly this list all along; it
|
|
13
13
|
* was simply not reachable from the CLI.
|
|
14
|
+
*
|
|
15
|
+
* The server returns at most `--limit` rows and says whether it left any out.
|
|
16
|
+
* It used to stop at 100 without saying so, and the session somebody went
|
|
17
|
+
* looking for — an old daemon's, still holding the login a purge refusal named
|
|
18
|
+
* — was exactly the one past the cut (OSK-9980). So a partial list says it is
|
|
19
|
+
* partial, and `--kind daemon` is the short way to the row that matters.
|
|
14
20
|
*/
|
|
15
21
|
export default class TokenList extends BaseCommand {
|
|
16
22
|
static description: string;
|
|
17
23
|
static examples: string[];
|
|
18
24
|
static flags: {
|
|
25
|
+
kind: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
26
|
+
limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
27
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
20
28
|
};
|
|
21
29
|
run(): Promise<void>;
|
|
@@ -4,6 +4,7 @@ const core_1 = require("@oclif/core");
|
|
|
4
4
|
const base_command_1 = require("../../base-command");
|
|
5
5
|
const api_fetch_1 = require("../../lib/api-fetch");
|
|
6
6
|
const format_1 = require("../../lib/format");
|
|
7
|
+
const SESSION_KINDS = ['web', 'daemon', 'cli', 'ci'];
|
|
7
8
|
/**
|
|
8
9
|
* `skrr token list`
|
|
9
10
|
*
|
|
@@ -16,20 +17,44 @@ const format_1 = require("../../lib/format");
|
|
|
16
17
|
*
|
|
17
18
|
* `GET /api/auth/sessions/refresh` has served exactly this list all along; it
|
|
18
19
|
* was simply not reachable from the CLI.
|
|
20
|
+
*
|
|
21
|
+
* The server returns at most `--limit` rows and says whether it left any out.
|
|
22
|
+
* It used to stop at 100 without saying so, and the session somebody went
|
|
23
|
+
* looking for — an old daemon's, still holding the login a purge refusal named
|
|
24
|
+
* — was exactly the one past the cut (OSK-9980). So a partial list says it is
|
|
25
|
+
* partial, and `--kind daemon` is the short way to the row that matters.
|
|
19
26
|
*/
|
|
20
27
|
class TokenList extends base_command_1.BaseCommand {
|
|
21
28
|
static description = 'List the active sessions a minted token belongs to — the other half of `token mint`';
|
|
22
29
|
static examples = [
|
|
23
30
|
'<%= config.bin %> token list',
|
|
24
|
-
'<%= config.bin %> token list --
|
|
31
|
+
'<%= config.bin %> token list --kind daemon',
|
|
32
|
+
'<%= config.bin %> token list --kind cli --limit 500 --json',
|
|
25
33
|
];
|
|
26
|
-
static flags = {
|
|
34
|
+
static flags = {
|
|
35
|
+
kind: core_1.Flags.string({
|
|
36
|
+
description: 'Only sessions of this kind',
|
|
37
|
+
options: [...SESSION_KINDS],
|
|
38
|
+
}),
|
|
39
|
+
limit: core_1.Flags.integer({
|
|
40
|
+
description: 'Most sessions to list (server maximum 500)',
|
|
41
|
+
min: 1,
|
|
42
|
+
max: 500,
|
|
43
|
+
}),
|
|
44
|
+
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
45
|
+
};
|
|
27
46
|
async run() {
|
|
28
47
|
this.requireAuth();
|
|
29
48
|
const { flags } = await this.parse(TokenList);
|
|
49
|
+
const query = new URLSearchParams();
|
|
50
|
+
if (flags.kind)
|
|
51
|
+
query.set('kind', flags.kind);
|
|
52
|
+
if (flags.limit)
|
|
53
|
+
query.set('limit', String(flags.limit));
|
|
54
|
+
const suffix = query.toString() ? `?${query.toString()}` : '';
|
|
30
55
|
let data = null;
|
|
31
56
|
try {
|
|
32
|
-
data = await (0, api_fetch_1.apiFetch)(
|
|
57
|
+
data = await (0, api_fetch_1.apiFetch)(`/api/auth/sessions/refresh${suffix}`, {
|
|
33
58
|
method: 'GET',
|
|
34
59
|
credential: this.resolvedCredential,
|
|
35
60
|
});
|
|
@@ -37,9 +62,17 @@ class TokenList extends base_command_1.BaseCommand {
|
|
|
37
62
|
catch (err) {
|
|
38
63
|
this.handleApiError(err);
|
|
39
64
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
65
|
+
// Filtered here as well: a server from before `kind` existed ignores the
|
|
66
|
+
// parameter and returns every kind, and `--kind daemon` must never list a
|
|
67
|
+
// web session as if it were one.
|
|
68
|
+
const sessions = (data?.sessions || []).filter((session) => !flags.kind || session.kind === flags.kind);
|
|
69
|
+
// A server from before `hasMore` stopped at 100 and said nothing about it,
|
|
70
|
+
// and ignores `--limit` too — so it gets its own, weaker statement.
|
|
71
|
+
const olderServer = data?.hasMore === undefined;
|
|
72
|
+
const hasMore = olderServer ? (data?.sessions?.length ?? 0) >= 100 : data?.hasMore === true;
|
|
73
|
+
if (flags.json) {
|
|
74
|
+
return this.log(JSON.stringify({ sessions, count: sessions.length, hasMore }, null, 2));
|
|
75
|
+
}
|
|
43
76
|
if (!sessions.length)
|
|
44
77
|
return this.log('No active sessions.');
|
|
45
78
|
(0, format_1.renderTable)(sessions.map((session) => ({
|
|
@@ -48,6 +81,8 @@ class TokenList extends base_command_1.BaseCommand {
|
|
|
48
81
|
// The operator's own name for the credential wins over a derived
|
|
49
82
|
// device string — it is what they would search by.
|
|
50
83
|
device: session.label || session.device || '-',
|
|
84
|
+
// What `instructions`, `machines` and a purge refusal call it.
|
|
85
|
+
daemon: session.daemonId || '-',
|
|
51
86
|
ip: session.ip || '-',
|
|
52
87
|
lastActive: session.lastActiveAt || session.createdAt || '-',
|
|
53
88
|
// The session you are typing in. Revoking it signs THIS machine out,
|
|
@@ -57,11 +92,21 @@ class TokenList extends base_command_1.BaseCommand {
|
|
|
57
92
|
{ key: 'id', header: 'ID' },
|
|
58
93
|
{ key: 'kind', header: 'KIND' },
|
|
59
94
|
{ key: 'device', header: 'DEVICE', maxWidth: 34 },
|
|
95
|
+
{ key: 'daemon', header: 'DAEMON', maxWidth: 40 },
|
|
60
96
|
{ key: 'ip', header: 'IP' },
|
|
61
97
|
{ key: 'lastActive', header: 'LAST ACTIVE' },
|
|
62
98
|
{ key: 'current', header: 'CURRENT' },
|
|
63
99
|
], (line) => this.log(line));
|
|
64
100
|
this.log('');
|
|
101
|
+
if (hasMore && olderServer) {
|
|
102
|
+
this.log('This server lists at most 100 sessions and does not say whether it left any out, so older ones may be missing.');
|
|
103
|
+
}
|
|
104
|
+
else if (hasMore) {
|
|
105
|
+
const remedy = flags.kind
|
|
106
|
+
? 'Raise --limit (up to 500) to see them.'
|
|
107
|
+
: 'Narrow the list with --kind, or raise --limit (up to 500).';
|
|
108
|
+
this.log(`Showing the ${sessions.length} most recently active sessions; older ones were left out. ${remedy}`);
|
|
109
|
+
}
|
|
65
110
|
this.log('Retire one with: skrr token revoke <id>');
|
|
66
111
|
}
|
|
67
112
|
}
|
package/dist/help.js
CHANGED
|
@@ -46,26 +46,22 @@ class SkrrHelp extends core_1.Help {
|
|
|
46
46
|
*/
|
|
47
47
|
async showRootHelp() {
|
|
48
48
|
this.log('GETTING STARTED');
|
|
49
|
-
this.log(' skrr login Sign in. Offers to
|
|
50
|
-
this.log(' skrr daemon install Install the
|
|
49
|
+
this.log(' skrr login Sign in. Offers to install the background service if this computer has none.');
|
|
50
|
+
this.log(' skrr daemon install Install the background service by hand (fetches the signed release).');
|
|
51
51
|
this.log('');
|
|
52
52
|
return super.showRootHelp();
|
|
53
53
|
}
|
|
54
54
|
async showHelp(argv) {
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
break;
|
|
61
|
-
tokens.push(token);
|
|
62
|
-
}
|
|
63
|
-
const id = tokens.join(':');
|
|
55
|
+
// Resolve the id exactly as running the same words would — a word after a
|
|
56
|
+
// command that takes arguments is an argument, not part of the name
|
|
57
|
+
// (OSK-10099: `harnesses install devin --help` was refused).
|
|
58
|
+
const lookup = (0, command_miss_1.lookupFromConfig)(this.config);
|
|
59
|
+
const id = (0, command_miss_1.helpSubjectId)(argv, lookup);
|
|
64
60
|
// A bare topic (`skrr daemon`) has no command but DOES have help to show,
|
|
65
61
|
// so it must fall through — only an id that is neither a command nor a
|
|
66
62
|
// topic is a miss.
|
|
67
63
|
if (id && !this.config.findCommand(id) && !this.config.findTopic(id)) {
|
|
68
|
-
throw new Error((0, command_miss_1.describeCommandMiss)(
|
|
64
|
+
throw new Error((0, command_miss_1.describeCommandMiss)(lookup, id));
|
|
69
65
|
}
|
|
70
66
|
return super.showHelp(argv);
|
|
71
67
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The workspace an `agents chat` turn runs in when the caller named none.
|
|
3
|
+
*
|
|
4
|
+
* A turn with no workspace context reaches the server without `X-Workspace-Id`.
|
|
5
|
+
* The server lets it through after checking membership in the agent's own
|
|
6
|
+
* workspace, but the agent runtime then has no workspace, so the shared
|
|
7
|
+
* workspace memory tier refuses with "no workspace context" (OSK-9937). By
|
|
8
|
+
* owner decision the CLI now uses the agent's home workspace in that case: the
|
|
9
|
+
* same thing the web app sends, and the only workspace the server would accept
|
|
10
|
+
* for that agent anyway.
|
|
11
|
+
*
|
|
12
|
+
* Never applied when anything already chose: `--workspace`, an exported
|
|
13
|
+
* `OVERSKY_WORKSPACE_ID`, or `skrr workspaces use` (all arrive as that env var),
|
|
14
|
+
* and never inside an autonomous Agent process, whose workspace belongs to its
|
|
15
|
+
* daemon session.
|
|
16
|
+
*/
|
|
17
|
+
export declare function applyAgentHomeWorkspaceDefault(agentId: string, lookup: (agentId: string) => Promise<{
|
|
18
|
+
workspaceId?: string | null;
|
|
19
|
+
} | null | undefined>, env?: NodeJS.ProcessEnv): Promise<string | null>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyAgentHomeWorkspaceDefault = applyAgentHomeWorkspaceDefault;
|
|
4
|
+
/**
|
|
5
|
+
* The workspace an `agents chat` turn runs in when the caller named none.
|
|
6
|
+
*
|
|
7
|
+
* A turn with no workspace context reaches the server without `X-Workspace-Id`.
|
|
8
|
+
* The server lets it through after checking membership in the agent's own
|
|
9
|
+
* workspace, but the agent runtime then has no workspace, so the shared
|
|
10
|
+
* workspace memory tier refuses with "no workspace context" (OSK-9937). By
|
|
11
|
+
* owner decision the CLI now uses the agent's home workspace in that case: the
|
|
12
|
+
* same thing the web app sends, and the only workspace the server would accept
|
|
13
|
+
* for that agent anyway.
|
|
14
|
+
*
|
|
15
|
+
* Never applied when anything already chose: `--workspace`, an exported
|
|
16
|
+
* `OVERSKY_WORKSPACE_ID`, or `skrr workspaces use` (all arrive as that env var),
|
|
17
|
+
* and never inside an autonomous Agent process, whose workspace belongs to its
|
|
18
|
+
* daemon session.
|
|
19
|
+
*/
|
|
20
|
+
async function applyAgentHomeWorkspaceDefault(agentId, lookup, env = process.env) {
|
|
21
|
+
if (env.OVERSKY_AUTONOMOUS_SESSION === '1')
|
|
22
|
+
return null;
|
|
23
|
+
if (env.OVERSKY_WORKSPACE_ID?.trim())
|
|
24
|
+
return null;
|
|
25
|
+
let agent;
|
|
26
|
+
try {
|
|
27
|
+
agent = await lookup(agentId);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Unreadable agent: keep the headerless request. The server still decides
|
|
31
|
+
// access, and the chat call itself reports a missing or forbidden agent.
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const workspaceId = typeof agent?.workspaceId === 'string' ? agent.workspaceId.trim() : '';
|
|
35
|
+
if (!workspaceId)
|
|
36
|
+
return null;
|
|
37
|
+
env.OVERSKY_WORKSPACE_ID = workspaceId;
|
|
38
|
+
return workspaceId;
|
|
39
|
+
}
|
|
@@ -38,7 +38,7 @@ async function resolveAgentIdentity(explicitAgentId) {
|
|
|
38
38
|
if (explicitAgentId && explicitAgentId !== runtime.agent.id) {
|
|
39
39
|
throw new AgentResolutionError({
|
|
40
40
|
code: 'AGENT_CONTEXT_CONFLICT',
|
|
41
|
-
message: 'This
|
|
41
|
+
message: 'This session is bound to the agent in OVERSKY_SESSION_AGENT_ID. Do not override it with another agent ID.',
|
|
42
42
|
suggestion: 'Use the bound session agent, or start a new daemon session for a different agent.',
|
|
43
43
|
details: {
|
|
44
44
|
explicitAgentId,
|
|
@@ -129,7 +129,7 @@ function resolveSessionAgentIdentity(explicitAgentId, env = process.env) {
|
|
|
129
129
|
if (explicitAgentId && explicitAgentId !== runtime.agent.id) {
|
|
130
130
|
throw new AgentResolutionError({
|
|
131
131
|
code: 'AGENT_CONTEXT_CONFLICT',
|
|
132
|
-
message: 'This
|
|
132
|
+
message: 'This session is bound to the agent in OVERSKY_SESSION_AGENT_ID. Do not override it with another agent ID.',
|
|
133
133
|
suggestion: 'Use the bound session agent, or start a new daemon session for a different agent.',
|
|
134
134
|
details: {
|
|
135
135
|
explicitAgentId,
|