@skrr-ai/cli 0.1.36 → 0.1.38
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 +17 -4
- package/bin/dev-fallback.js +167 -4
- package/dist/base-command.js +46 -2
- package/dist/commands/agents/actions/create.d.ts +5 -0
- package/dist/commands/agents/actions/create.js +42 -5
- package/dist/commands/agents/actions/delete.d.ts +1 -0
- package/dist/commands/agents/actions/delete.js +7 -0
- package/dist/commands/agents/actions/update.d.ts +5 -0
- package/dist/commands/agents/actions/update.js +27 -1
- package/dist/commands/agents/api-actions/add.d.ts +41 -0
- package/dist/commands/agents/api-actions/add.js +205 -0
- package/dist/commands/agents/api-actions/index.d.ts +39 -0
- package/dist/commands/agents/api-actions/index.js +103 -0
- package/dist/commands/agents/api-actions/remove.d.ts +14 -0
- package/dist/commands/agents/api-actions/remove.js +36 -0
- package/dist/commands/agents/avatar/default/apply.d.ts +25 -0
- package/dist/commands/agents/avatar/default/apply.js +56 -0
- package/dist/commands/agents/avatar/default/index.d.ts +29 -0
- package/dist/commands/agents/avatar/default/index.js +61 -0
- package/dist/commands/agents/avatar/default/set.d.ts +24 -0
- package/dist/commands/agents/avatar/default/set.js +120 -0
- package/dist/commands/agents/avatar/library/delete.d.ts +20 -0
- package/dist/commands/agents/avatar/library/delete.js +47 -0
- package/dist/commands/agents/avatar/library/index.d.ts +16 -0
- package/dist/commands/agents/avatar/library/index.js +56 -0
- package/dist/commands/agents/avatar/presets.d.ts +19 -0
- package/dist/commands/agents/avatar/presets.js +56 -0
- package/dist/commands/agents/avatar/upload.js +7 -1
- package/dist/commands/agents/categories/create.d.ts +14 -0
- package/dist/commands/agents/categories/create.js +46 -0
- package/dist/commands/agents/categories/delete.d.ts +13 -0
- package/dist/commands/agents/categories/delete.js +41 -0
- package/dist/commands/agents/categories/index.d.ts +36 -0
- package/dist/commands/agents/categories/index.js +135 -0
- package/dist/commands/agents/categories/update.d.ts +22 -0
- package/dist/commands/agents/categories/update.js +59 -0
- package/dist/commands/agents/chat.d.ts +21 -0
- package/dist/commands/agents/chat.js +94 -7
- package/dist/commands/agents/create.d.ts +10 -0
- package/dist/commands/agents/create.js +64 -3
- package/dist/commands/agents/ensure-default.d.ts +27 -0
- package/dist/commands/agents/ensure-default.js +65 -0
- package/dist/commands/agents/list.d.ts +15 -0
- package/dist/commands/agents/list.js +31 -1
- package/dist/commands/agents/mute.d.ts +16 -0
- package/dist/commands/agents/mute.js +38 -0
- package/dist/commands/agents/pin.d.ts +16 -0
- package/dist/commands/agents/pin.js +38 -0
- package/dist/commands/agents/scene-background/upload.d.ts +30 -0
- package/dist/commands/agents/scene-background/upload.js +97 -0
- package/dist/commands/agents/show.js +13 -0
- package/dist/commands/agents/tools/auth.d.ts +19 -0
- package/dist/commands/agents/tools/auth.js +41 -0
- package/dist/commands/agents/tools/calls.d.ts +36 -0
- package/dist/commands/agents/tools/calls.js +117 -0
- package/dist/commands/agents/tools/index.d.ts +20 -0
- package/dist/commands/agents/tools/index.js +77 -0
- package/dist/commands/agents/unmute.d.ts +16 -0
- package/dist/commands/agents/unmute.js +38 -0
- package/dist/commands/agents/unpin.d.ts +16 -0
- package/dist/commands/agents/unpin.js +38 -0
- package/dist/commands/agents/update.d.ts +12 -0
- package/dist/commands/agents/update.js +74 -3
- package/dist/commands/code/{oversky-agent.d.ts → skrr-agent.d.ts} +3 -3
- package/dist/commands/code/{oversky-agent.js → skrr-agent.js} +11 -8
- package/dist/commands/convos/messages.d.ts +13 -0
- package/dist/commands/convos/messages.js +40 -16
- package/dist/commands/daemon/index.js +8 -1
- package/dist/commands/daemon/logs.d.ts +26 -0
- package/dist/commands/daemon/logs.js +56 -0
- package/dist/commands/daemon/uninstall.js +1 -1
- package/dist/commands/followups/act.d.ts +22 -0
- package/dist/commands/followups/act.js +103 -0
- package/dist/commands/followups/cancel.d.ts +20 -0
- package/dist/commands/followups/cancel.js +50 -0
- package/dist/commands/followups/checkin.d.ts +27 -0
- package/dist/commands/followups/checkin.js +107 -0
- package/dist/commands/followups/list.d.ts +24 -0
- package/dist/commands/followups/list.js +90 -0
- package/dist/commands/followups/observability.d.ts +23 -0
- package/dist/commands/followups/observability.js +114 -0
- package/dist/commands/followups/remind.d.ts +26 -0
- package/dist/commands/followups/remind.js +106 -0
- package/dist/commands/followups/reschedule.d.ts +15 -0
- package/dist/commands/followups/reschedule.js +48 -0
- package/dist/commands/followups/resolve.d.ts +23 -0
- package/dist/commands/followups/resolve.js +54 -0
- package/dist/commands/followups/show.d.ts +12 -0
- package/dist/commands/followups/show.js +46 -0
- package/dist/commands/followups/watch.d.ts +51 -0
- package/dist/commands/followups/watch.js +211 -0
- package/dist/commands/goals/labels/add.js +19 -2
- package/dist/commands/goals/labels/remove.js +22 -2
- package/dist/commands/harnesses/forget.js +28 -0
- package/dist/commands/harnesses/install.d.ts +41 -0
- package/dist/commands/harnesses/install.js +165 -0
- package/dist/commands/harnesses/installers.d.ts +45 -0
- package/dist/commands/harnesses/installers.js +155 -0
- package/dist/commands/harnesses/list.d.ts +82 -1
- package/dist/commands/harnesses/list.js +104 -12
- package/dist/commands/harnesses/models.js +10 -1
- package/dist/commands/harnesses/show.d.ts +15 -0
- package/dist/commands/harnesses/show.js +44 -3
- package/dist/commands/harnesses/update.js +1 -1
- package/dist/commands/harnesses/usage.d.ts +25 -0
- package/dist/commands/harnesses/usage.js +24 -2
- package/dist/commands/instructions/status.js +13 -1
- package/dist/commands/labels/list.d.ts +24 -1
- package/dist/commands/labels/list.js +62 -19
- package/dist/commands/machines/dedicated/catalog.js +4 -15
- package/dist/commands/machines/dedicated/create.d.ts +8 -0
- package/dist/commands/machines/dedicated/create.js +58 -1
- package/dist/commands/machines/dedicated/destroy.js +18 -4
- package/dist/commands/machines/dedicated/list.js +9 -6
- package/dist/commands/machines/hosted/list.js +12 -0
- package/dist/commands/machines/list.js +11 -0
- package/dist/commands/machines/show.d.ts +1 -0
- package/dist/commands/machines/show.js +40 -11
- package/dist/commands/memory/governance/index.d.ts +21 -0
- package/dist/commands/memory/governance/index.js +64 -0
- package/dist/commands/memory/governance/set.d.ts +24 -0
- package/dist/commands/memory/governance/set.js +95 -0
- package/dist/commands/memory/provenance.d.ts +18 -0
- package/dist/commands/memory/provenance.js +66 -0
- package/dist/commands/profiles/list.d.ts +23 -0
- package/dist/commands/profiles/list.js +96 -0
- package/dist/commands/search/skills.d.ts +11 -1
- package/dist/commands/search/skills.js +26 -8
- package/dist/commands/skills/details.d.ts +2 -0
- package/dist/commands/skills/details.js +24 -1
- package/dist/commands/skills/import-as-actions.d.ts +32 -0
- package/dist/commands/skills/import-as-actions.js +175 -0
- package/dist/commands/skills/install.d.ts +2 -0
- package/dist/commands/skills/install.js +24 -1
- package/dist/commands/skills/invocable.js +6 -2
- package/dist/commands/skills/local.d.ts +40 -0
- package/dist/commands/skills/local.js +160 -0
- package/dist/commands/skills/search.d.ts +11 -1
- package/dist/commands/skills/search.js +29 -8
- package/dist/commands/spaces/actions/add.js +23 -5
- package/dist/commands/spaces/actions/available.js +3 -0
- package/dist/commands/spaces/actions/list.d.ts +5 -0
- package/dist/commands/spaces/actions/list.js +49 -3
- package/dist/commands/spaces/actions/run.d.ts +28 -0
- package/dist/commands/spaces/actions/run.js +146 -0
- package/dist/commands/spaces/actions/update.js +27 -5
- package/dist/commands/spaces/create.d.ts +3 -0
- package/dist/commands/spaces/create.js +32 -2
- package/dist/commands/spaces/label-summaries.d.ts +27 -0
- package/dist/commands/spaces/label-summaries.js +64 -0
- package/dist/commands/spaces/labels/add.js +19 -2
- package/dist/commands/spaces/labels/remove.js +22 -2
- package/dist/commands/spaces/show.js +2 -0
- package/dist/commands/spaces/task-rollups.d.ts +5 -0
- package/dist/commands/spaces/task-rollups.js +15 -4
- package/dist/commands/spaces/update.d.ts +5 -0
- package/dist/commands/spaces/update.js +41 -4
- package/dist/commands/spaces/workflows/lifecycle-diagnostics.d.ts +11 -0
- package/dist/commands/spaces/workflows/lifecycle-diagnostics.js +105 -0
- package/dist/commands/tasks/actions/attach.js +32 -7
- package/dist/commands/tasks/complete.d.ts +1 -0
- package/dist/commands/tasks/complete.js +21 -1
- package/dist/commands/tasks/create.d.ts +3 -0
- package/dist/commands/tasks/create.js +34 -2
- package/dist/commands/tasks/events/append.js +29 -6
- package/dist/commands/tasks/expectations/assess.d.ts +12 -0
- package/dist/commands/tasks/expectations/assess.js +123 -14
- package/dist/commands/tasks/expectations.js +95 -17
- package/dist/commands/tasks/follow-up.js +2 -2
- package/dist/commands/tasks/labels/attach.js +20 -3
- package/dist/commands/tasks/labels/detach.js +21 -3
- package/dist/commands/tasks/lifecycle/attach.d.ts +14 -0
- package/dist/commands/tasks/lifecycle/attach.js +47 -0
- package/dist/commands/tasks/lifecycle/definitions.d.ts +11 -0
- package/dist/commands/tasks/lifecycle/definitions.js +59 -0
- package/dist/commands/tasks/lifecycle/detach.d.ts +19 -0
- package/dist/commands/tasks/lifecycle/detach.js +72 -0
- package/dist/commands/tasks/lifecycle/history.d.ts +13 -0
- package/dist/commands/tasks/lifecycle/history.js +38 -0
- package/dist/commands/tasks/lifecycle/migrate.d.ts +14 -0
- package/dist/commands/tasks/lifecycle/migrate.js +68 -0
- package/dist/commands/tasks/lifecycle/reconcile.d.ts +11 -0
- package/dist/commands/tasks/lifecycle/reconcile.js +27 -0
- package/dist/commands/tasks/lifecycle/reopen.d.ts +15 -0
- package/dist/commands/tasks/lifecycle/reopen.js +71 -0
- package/dist/commands/tasks/lifecycle/show.d.ts +11 -0
- package/dist/commands/tasks/lifecycle/show.js +27 -0
- package/dist/commands/tasks/lifecycle/start.d.ts +12 -0
- package/dist/commands/tasks/lifecycle/start.js +30 -0
- package/dist/commands/tasks/lifecycle/transition.d.ts +15 -0
- package/dist/commands/tasks/lifecycle/transition.js +109 -0
- package/dist/commands/tasks/list.js +16 -9
- package/dist/commands/tasks/move.d.ts +1 -0
- package/dist/commands/tasks/move.js +29 -0
- package/dist/commands/tasks/result/submit.js +11 -1
- package/dist/commands/tasks/review-queue.d.ts +44 -0
- package/dist/commands/tasks/review-queue.js +314 -0
- package/dist/commands/tasks/show.d.ts +11 -0
- package/dist/commands/tasks/show.js +139 -4
- package/dist/commands/tasks/trust.js +7 -2
- package/dist/commands/tasks/update.d.ts +1 -0
- package/dist/commands/tasks/update.js +83 -0
- package/dist/commands/tasks/updates/add.js +1 -1
- package/dist/commands/token/list.d.ts +22 -0
- package/dist/commands/token/list.js +68 -0
- package/dist/commands/token/revoke.d.ts +23 -0
- package/dist/commands/token/revoke.js +53 -0
- package/dist/lib/agent-actions.d.ts +92 -11
- package/dist/lib/agent-actions.js +171 -25
- package/dist/lib/agent-config.d.ts +11 -0
- package/dist/lib/agent-config.js +85 -3
- package/dist/lib/agent-pin-mute.d.ts +29 -0
- package/dist/lib/agent-pin-mute.js +30 -0
- package/dist/lib/agent-visual-refs.d.ts +33 -0
- package/dist/lib/agent-visual-refs.js +267 -0
- package/dist/lib/agentic-stream.d.ts +6 -0
- package/dist/lib/agentic-stream.js +34 -3
- package/dist/lib/assignee-resolver.d.ts +1 -1
- package/dist/lib/assignee-resolver.js +8 -0
- package/dist/lib/bulk-task-targets.d.ts +12 -0
- package/dist/lib/bulk-task-targets.js +34 -1
- package/dist/lib/cli-installers.d.ts +130 -0
- package/dist/lib/cli-installers.js +145 -0
- package/dist/lib/command-miss.js +55 -7
- package/dist/lib/dedicated-lease-command.d.ts +13 -0
- package/dist/lib/dedicated-lease-command.js +22 -1
- package/dist/lib/dedicated-machines.d.ts +95 -1
- package/dist/lib/dedicated-machines.js +236 -2
- package/dist/lib/failed-lookup.d.ts +3 -0
- package/dist/lib/failed-lookup.js +40 -0
- package/dist/lib/first-party-harness-agent.js +16 -2
- package/dist/lib/first-party-harness-doctor.d.ts +15 -0
- package/dist/lib/first-party-harness-doctor.js +126 -27
- package/dist/lib/followups.d.ts +115 -0
- package/dist/lib/followups.js +127 -0
- package/dist/lib/harnesses.d.ts +8 -0
- package/dist/lib/instruction-input.d.ts +19 -1
- package/dist/lib/instruction-input.js +52 -1
- package/dist/lib/label-ref.d.ts +95 -0
- package/dist/lib/label-ref.js +163 -0
- package/dist/lib/label-scope.d.ts +17 -2
- package/dist/lib/label-scope.js +27 -7
- package/dist/lib/local-skills.d.ts +98 -0
- package/dist/lib/local-skills.js +195 -0
- package/dist/lib/machines.d.ts +10 -10
- package/dist/lib/machines.js +23 -1
- package/dist/lib/search-query.d.ts +19 -0
- package/dist/lib/search-query.js +35 -0
- package/dist/lib/space-custom-actions.d.ts +72 -0
- package/dist/lib/space-custom-actions.js +117 -0
- package/dist/lib/space-resolver.d.ts +1 -21
- package/dist/lib/space-resolver.js +19 -10
- package/dist/lib/task-closure.d.ts +33 -0
- package/dist/lib/task-closure.js +104 -0
- package/dist/lib/task-lifecycle-output.d.ts +14 -0
- package/dist/lib/task-lifecycle-output.js +209 -0
- package/dist/lib/task-ref-resolver.d.ts +1 -17
- package/dist/lib/task-ref-resolver.js +18 -8
- package/dist/lib/tasks.d.ts +3 -0
- package/dist/lib/tasks.js +40 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.js +4 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.js +4 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +5559 -4897
- package/oclif.manifest.json +33890 -28690
- package/package.json +24 -6
|
@@ -78,6 +78,17 @@ class MachinesList extends base_command_1.BaseCommand {
|
|
|
78
78
|
{ key: 'platform', header: 'PLATFORM' },
|
|
79
79
|
{ key: 'seen', header: 'LAST SEEN' },
|
|
80
80
|
], (line) => this.log(line));
|
|
81
|
+
// Why a machine is not `online`, under the table. `degraded` on its own is
|
|
82
|
+
// unactionable — the dogfood note on this output was "I still do not know
|
|
83
|
+
// whether something is wrong with my laptop" — and it is usually one named
|
|
84
|
+
// row, not the machine.
|
|
85
|
+
const explained = shown.filter((m) => m.status !== 'online' && m.statusReason);
|
|
86
|
+
if (explained.length > 0) {
|
|
87
|
+
this.log('');
|
|
88
|
+
for (const m of explained) {
|
|
89
|
+
this.log(` ${m.preferences?.name || m.name}: ${m.statusReason}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
81
92
|
const hidden = all.length - shown.length;
|
|
82
93
|
if (hidden > 0) {
|
|
83
94
|
this.log('');
|
|
@@ -9,6 +9,7 @@ class MachinesShow extends base_command_1.BaseCommand {
|
|
|
9
9
|
static description = 'Show one machine — its identity, harnesses, and available actions';
|
|
10
10
|
static examples = [
|
|
11
11
|
'<%= config.bin %> machines show 03548116',
|
|
12
|
+
'<%= config.bin %> machines show 03548116 --all',
|
|
12
13
|
'<%= config.bin %> machines show "frankdu@DS-3" --json',
|
|
13
14
|
];
|
|
14
15
|
static args = {
|
|
@@ -18,7 +19,13 @@ class MachinesShow extends base_command_1.BaseCommand {
|
|
|
18
19
|
required: true,
|
|
19
20
|
}),
|
|
20
21
|
};
|
|
21
|
-
static flags = {
|
|
22
|
+
static flags = {
|
|
23
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
24
|
+
all: core_1.Flags.boolean({
|
|
25
|
+
description: 'Include harness registrations superseded by newer ones',
|
|
26
|
+
default: false,
|
|
27
|
+
}),
|
|
28
|
+
};
|
|
22
29
|
async run() {
|
|
23
30
|
this.requireAuth();
|
|
24
31
|
const { args, flags } = await this.parse(MachinesShow);
|
|
@@ -43,6 +50,10 @@ class MachinesShow extends base_command_1.BaseCommand {
|
|
|
43
50
|
this.log(` id ${machine.id}`);
|
|
44
51
|
this.log(` identity ${machine.identityKind}`);
|
|
45
52
|
this.log(` status ${machine.status}`);
|
|
53
|
+
// The status alone does not say what to do. Naming the rows that decided it
|
|
54
|
+
// is the actionable half — bring that provider back, or forget the row.
|
|
55
|
+
if (machine.statusReason)
|
|
56
|
+
this.log(` why ${machine.statusReason}`);
|
|
46
57
|
if (machine.machineUuid)
|
|
47
58
|
this.log(` machineUuid ${machine.machineUuid}`);
|
|
48
59
|
if (machine.daemonId)
|
|
@@ -60,20 +71,34 @@ class MachinesShow extends base_command_1.BaseCommand {
|
|
|
60
71
|
const harnesses = machine.harnesses ?? [];
|
|
61
72
|
const live = (0, machines_1.liveHarnessCount)(machine);
|
|
62
73
|
const superseded = harnesses.length - live;
|
|
74
|
+
// Superseded registrations are history, not capabilities, and they are not
|
|
75
|
+
// counted as missing ones next to a status of `online`. They are hidden by
|
|
76
|
+
// default, the convention `machines list` already set for dead machines:
|
|
77
|
+
// printed, they were 35 of a machine's 42 rows, back two months, under a
|
|
78
|
+
// header whose count read like a summary of rows it then printed anyway
|
|
79
|
+
// (OSK-9389). `--all` shows them, and `--json` always carries every row.
|
|
80
|
+
const shown = flags.all ? harnesses : harnesses.filter((h) => !h.superseded);
|
|
63
81
|
this.log('');
|
|
64
|
-
// The superseded rows are still listed — labelled, not dropped, so they can
|
|
65
|
-
// be seen and reaped — but they are not missing capabilities and must not
|
|
66
|
-
// be counted as such next to a status of `online`.
|
|
67
82
|
this.log(`Harnesses (${machine.onlineHarnessCount}/${live} online` +
|
|
68
|
-
(superseded > 0 ? `, ${superseded} superseded by newer registrations` : '') +
|
|
83
|
+
(flags.all && superseded > 0 ? `, ${superseded} superseded by newer registrations` : '') +
|
|
69
84
|
')');
|
|
70
|
-
if (
|
|
71
|
-
(0, format_1.renderTable)(
|
|
85
|
+
if (shown.length > 0) {
|
|
86
|
+
(0, format_1.renderTable)(shown.map((h) => ({
|
|
72
87
|
id: (0, format_1.formatCell)(h.id),
|
|
73
88
|
provider: (0, format_1.formatCell)(h.provider),
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
|
|
89
|
+
// Liveness only. Whether a newer registration replaced the row is a
|
|
90
|
+
// different fact — a superseded row can have been online — so it
|
|
91
|
+
// gets its own column rather than overwriting this one.
|
|
92
|
+
status: (0, format_1.formatCell)(h.status),
|
|
93
|
+
registration: h.superseded ? 'superseded' : 'current',
|
|
94
|
+
// `authStatus` is the DAEMON's standing with skrr, not this
|
|
95
|
+
// provider's standing with its vendor. It is written across every row
|
|
96
|
+
// of a daemon at once (`HarnessService.markAuthOkAfterRegister` does
|
|
97
|
+
// one `updateMany({owner, daemonId})`), so it is structurally the
|
|
98
|
+
// same value for all of them and can never answer "is this harness
|
|
99
|
+
// signed in". Under a bare `AUTH` header it read as the second
|
|
100
|
+
// question and answered `ok` for a Devin whose own CLI said
|
|
101
|
+
// "Not logged in." The header now names what the value is.
|
|
77
102
|
auth: (0, format_1.formatCell)(h.authStatus),
|
|
78
103
|
seen: h.lastSeenAt
|
|
79
104
|
? new Date(h.lastSeenAt).toISOString().slice(0, 16).replace('T', ' ')
|
|
@@ -82,10 +107,14 @@ class MachinesShow extends base_command_1.BaseCommand {
|
|
|
82
107
|
{ key: 'id', header: 'HARNESS ID' },
|
|
83
108
|
{ key: 'provider', header: 'PROVIDER' },
|
|
84
109
|
{ key: 'status', header: 'STATUS' },
|
|
85
|
-
{ key: '
|
|
110
|
+
...(flags.all ? [{ key: 'registration', header: 'REGISTRATION' }] : []),
|
|
111
|
+
{ key: 'auth', header: 'DAEMON AUTH' },
|
|
86
112
|
{ key: 'seen', header: 'LAST SEEN' },
|
|
87
113
|
], (line) => this.log(` ${line}`));
|
|
88
114
|
}
|
|
115
|
+
if (!flags.all && superseded > 0) {
|
|
116
|
+
this.log(` ${superseded} superseded registration(s) hidden — pass --all to include them.`);
|
|
117
|
+
}
|
|
89
118
|
// Print what is PERMITTED, not the whole control map: a list of six
|
|
90
119
|
// booleans mostly reading false is noise, and the useful question is
|
|
91
120
|
// "what can I do to this machine right now".
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* An agent's memory POLICY: which pools its runtime may read and write, how long
|
|
4
|
+
* retained facts are governed, and what deletion means.
|
|
5
|
+
*
|
|
6
|
+
* Its own route rather than a corner of `PATCH /api/agents/:id`, and the CLI
|
|
7
|
+
* uses the same door the web does. The distinction the route draws — and this
|
|
8
|
+
* command surfaces — is between a policy an owner has DELIBERATELY saved and the
|
|
9
|
+
* defaults an unconfigured agent reads as. Mongoose materializes the leaf
|
|
10
|
+
* defaults on every new agent row, so "has a policy" cannot be answered by the
|
|
11
|
+
* field being present; only `updatedAt` says a human decided something.
|
|
12
|
+
*/
|
|
13
|
+
export default class MemoryGovernanceShow extends BaseCommand {
|
|
14
|
+
static description: string;
|
|
15
|
+
static examples: string[];
|
|
16
|
+
static flags: {
|
|
17
|
+
agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
18
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
};
|
|
20
|
+
run(): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
const base_command_1 = require("../../../base-command");
|
|
6
|
+
const agent_resolver_1 = require("../../../lib/agent-resolver");
|
|
7
|
+
/**
|
|
8
|
+
* An agent's memory POLICY: which pools its runtime may read and write, how long
|
|
9
|
+
* retained facts are governed, and what deletion means.
|
|
10
|
+
*
|
|
11
|
+
* Its own route rather than a corner of `PATCH /api/agents/:id`, and the CLI
|
|
12
|
+
* uses the same door the web does. The distinction the route draws — and this
|
|
13
|
+
* command surfaces — is between a policy an owner has DELIBERATELY saved and the
|
|
14
|
+
* defaults an unconfigured agent reads as. Mongoose materializes the leaf
|
|
15
|
+
* defaults on every new agent row, so "has a policy" cannot be answered by the
|
|
16
|
+
* field being present; only `updatedAt` says a human decided something.
|
|
17
|
+
*/
|
|
18
|
+
class MemoryGovernanceShow extends base_command_1.BaseCommand {
|
|
19
|
+
static description = "Show an agent's memory governance policy";
|
|
20
|
+
static examples = [
|
|
21
|
+
'<%= config.bin %> memory governance --agent <agent-id>',
|
|
22
|
+
'<%= config.bin %> memory governance --agent <agent-id> --json',
|
|
23
|
+
];
|
|
24
|
+
static flags = {
|
|
25
|
+
agent: core_1.Flags.string({
|
|
26
|
+
description: 'Agent ID (falls back to OVERSKY_AGENT_ID, then your primary agent)',
|
|
27
|
+
}),
|
|
28
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
29
|
+
};
|
|
30
|
+
async run() {
|
|
31
|
+
this.requireAuth();
|
|
32
|
+
const { flags } = await this.parse(MemoryGovernanceShow);
|
|
33
|
+
let agentId;
|
|
34
|
+
try {
|
|
35
|
+
agentId = await (0, agent_resolver_1.resolveAgentId)(flags.agent);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
this.error(err.message, { exit: 1 });
|
|
39
|
+
}
|
|
40
|
+
let policy;
|
|
41
|
+
try {
|
|
42
|
+
policy = await data_provider_1.dataService.getAgentMemoryGovernance(agentId);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
this.handleApiError(err);
|
|
46
|
+
}
|
|
47
|
+
if (flags.json) {
|
|
48
|
+
this.log(this.agentJson(agentId, policy));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const p = policy;
|
|
52
|
+
this.log(`Memory governance for agent ${agentId}`);
|
|
53
|
+
this.log(` Read scopes: ${(p.allowedReadScopes ?? []).join(', ') || '-'}`);
|
|
54
|
+
this.log(` Write scopes: ${(p.allowedWriteScopes ?? []).join(', ') || '-'}`);
|
|
55
|
+
this.log(` Retention: ${p.retentionDays ?? '-'} days`);
|
|
56
|
+
this.log(` On deletion: ${p.deletionMode ?? '-'}`);
|
|
57
|
+
this.log(` Shared memory: ${p.requireEvidenceForSharedMemory ? 'requires evidence' : 'no evidence required'}`);
|
|
58
|
+
this.log('');
|
|
59
|
+
this.log(p.updatedAt
|
|
60
|
+
? `Configured ${String(p.updatedAt).slice(0, 10)}.`
|
|
61
|
+
: 'Never configured — these are the defaults a run reads, not a saved policy.');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.default = MemoryGovernanceShow;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* Change an agent's memory policy. Requires EDIT on the agent.
|
|
4
|
+
*
|
|
5
|
+
* PARTIAL by design and worth being explicit about: the route merges over the
|
|
6
|
+
* leaves an owner has actually set, so omitting a flag leaves that leaf unset
|
|
7
|
+
* rather than freezing today's default into the row. That is why `--read-scope`
|
|
8
|
+
* REPLACES the list instead of adding to it — a list flag that appended would
|
|
9
|
+
* make "only agent memory" unreachable once anything wider had been granted.
|
|
10
|
+
*/
|
|
11
|
+
export default class MemoryGovernanceSet extends BaseCommand {
|
|
12
|
+
static description: string;
|
|
13
|
+
static examples: string[];
|
|
14
|
+
static flags: {
|
|
15
|
+
agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
16
|
+
'read-scope': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
17
|
+
'write-scope': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
18
|
+
'retention-days': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
|
+
'deletion-mode': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
20
|
+
'require-evidence': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
21
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
22
|
+
};
|
|
23
|
+
run(): Promise<void>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
const base_command_1 = require("../../../base-command");
|
|
6
|
+
const agent_resolver_1 = require("../../../lib/agent-resolver");
|
|
7
|
+
const MEMORY_SCOPES = ['agent', 'user', 'workspace'];
|
|
8
|
+
/**
|
|
9
|
+
* Change an agent's memory policy. Requires EDIT on the agent.
|
|
10
|
+
*
|
|
11
|
+
* PARTIAL by design and worth being explicit about: the route merges over the
|
|
12
|
+
* leaves an owner has actually set, so omitting a flag leaves that leaf unset
|
|
13
|
+
* rather than freezing today's default into the row. That is why `--read-scope`
|
|
14
|
+
* REPLACES the list instead of adding to it — a list flag that appended would
|
|
15
|
+
* make "only agent memory" unreachable once anything wider had been granted.
|
|
16
|
+
*/
|
|
17
|
+
class MemoryGovernanceSet extends base_command_1.BaseCommand {
|
|
18
|
+
static description = "Change an agent's memory governance policy (requires EDIT)";
|
|
19
|
+
static examples = [
|
|
20
|
+
'<%= config.bin %> memory governance set --agent <agent-id> --retention-days 90',
|
|
21
|
+
'<%= config.bin %> memory governance set --agent <agent-id> --read-scope agent --read-scope workspace',
|
|
22
|
+
'<%= config.bin %> memory governance set --agent <agent-id> --deletion-mode delete --no-require-evidence',
|
|
23
|
+
];
|
|
24
|
+
static flags = {
|
|
25
|
+
agent: core_1.Flags.string({ description: 'Agent ID' }),
|
|
26
|
+
'read-scope': core_1.Flags.string({
|
|
27
|
+
description: 'Memory pool the runtime may READ (repeatable; replaces the list)',
|
|
28
|
+
options: [...MEMORY_SCOPES],
|
|
29
|
+
multiple: true,
|
|
30
|
+
}),
|
|
31
|
+
'write-scope': core_1.Flags.string({
|
|
32
|
+
description: 'Memory pool the runtime may WRITE (repeatable; replaces the list)',
|
|
33
|
+
options: [...MEMORY_SCOPES],
|
|
34
|
+
multiple: true,
|
|
35
|
+
}),
|
|
36
|
+
'retention-days': core_1.Flags.integer({
|
|
37
|
+
description: 'How long retained facts are governed (1-3650)',
|
|
38
|
+
}),
|
|
39
|
+
'deletion-mode': core_1.Flags.string({
|
|
40
|
+
description: 'What deletion means for this agent',
|
|
41
|
+
options: ['archive', 'delete'],
|
|
42
|
+
}),
|
|
43
|
+
'require-evidence': core_1.Flags.boolean({
|
|
44
|
+
description: 'Require evidence before a fact enters shared memory',
|
|
45
|
+
allowNo: true,
|
|
46
|
+
}),
|
|
47
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
48
|
+
};
|
|
49
|
+
async run() {
|
|
50
|
+
this.requireAuth();
|
|
51
|
+
const { flags } = await this.parse(MemoryGovernanceSet);
|
|
52
|
+
const patch = {
|
|
53
|
+
...(flags['read-scope'] === undefined
|
|
54
|
+
? {}
|
|
55
|
+
: { allowedReadScopes: flags['read-scope'] }),
|
|
56
|
+
...(flags['write-scope'] === undefined
|
|
57
|
+
? {}
|
|
58
|
+
: { allowedWriteScopes: flags['write-scope'] }),
|
|
59
|
+
...(flags['retention-days'] === undefined ? {} : { retentionDays: flags['retention-days'] }),
|
|
60
|
+
...(flags['deletion-mode'] === undefined
|
|
61
|
+
? {}
|
|
62
|
+
: { deletionMode: flags['deletion-mode'] }),
|
|
63
|
+
...(flags['require-evidence'] === undefined
|
|
64
|
+
? {}
|
|
65
|
+
: { requireEvidenceForSharedMemory: flags['require-evidence'] }),
|
|
66
|
+
};
|
|
67
|
+
if (Object.keys(patch).length === 0) {
|
|
68
|
+
this.error('Nothing to change. Pass at least one of --read-scope, --write-scope, ' +
|
|
69
|
+
'--retention-days, --deletion-mode, --require-evidence.', { exit: 1 });
|
|
70
|
+
}
|
|
71
|
+
let agentId;
|
|
72
|
+
try {
|
|
73
|
+
agentId = await (0, agent_resolver_1.resolveAgentId)(flags.agent);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
this.error(err.message, { exit: 1 });
|
|
77
|
+
}
|
|
78
|
+
let policy;
|
|
79
|
+
try {
|
|
80
|
+
policy = await data_provider_1.dataService.updateAgentMemoryGovernance(agentId, patch);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
this.handleApiError(err);
|
|
84
|
+
}
|
|
85
|
+
if (flags.json) {
|
|
86
|
+
this.log(this.agentJson(agentId, policy));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
this.log(`Updated memory governance for agent ${agentId}.`);
|
|
90
|
+
this.log(` Read scopes: ${(policy.allowedReadScopes ?? []).join(', ') || '-'}`);
|
|
91
|
+
this.log(` Write scopes: ${(policy.allowedWriteScopes ?? []).join(', ') || '-'}`);
|
|
92
|
+
this.log(` Retention: ${policy.retentionDays ?? '-'} days`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.default = MemoryGovernanceSet;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* Where an agent's stored memories came from.
|
|
4
|
+
*
|
|
5
|
+
* The other half of governance: a policy says what a runtime MAY remember, and
|
|
6
|
+
* this says what it actually did and on whose evidence. Read-only, VIEW on the
|
|
7
|
+
* agent.
|
|
8
|
+
*/
|
|
9
|
+
export default class MemoryProvenance extends BaseCommand {
|
|
10
|
+
static description: string;
|
|
11
|
+
static examples: string[];
|
|
12
|
+
static flags: {
|
|
13
|
+
agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
|
+
limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
};
|
|
17
|
+
run(): Promise<void>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
const base_command_1 = require("../../base-command");
|
|
6
|
+
const agent_resolver_1 = require("../../lib/agent-resolver");
|
|
7
|
+
const format_1 = require("../../lib/format");
|
|
8
|
+
/**
|
|
9
|
+
* Where an agent's stored memories came from.
|
|
10
|
+
*
|
|
11
|
+
* The other half of governance: a policy says what a runtime MAY remember, and
|
|
12
|
+
* this says what it actually did and on whose evidence. Read-only, VIEW on the
|
|
13
|
+
* agent.
|
|
14
|
+
*/
|
|
15
|
+
class MemoryProvenance extends base_command_1.BaseCommand {
|
|
16
|
+
static description = "Show where an agent's stored memories came from";
|
|
17
|
+
static examples = [
|
|
18
|
+
'<%= config.bin %> memory provenance --agent <agent-id>',
|
|
19
|
+
'<%= config.bin %> memory provenance --agent <agent-id> --limit 50 --json',
|
|
20
|
+
];
|
|
21
|
+
static flags = {
|
|
22
|
+
agent: core_1.Flags.string({ description: 'Agent ID' }),
|
|
23
|
+
limit: core_1.Flags.integer({ description: 'How many entries to return' }),
|
|
24
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
25
|
+
};
|
|
26
|
+
async run() {
|
|
27
|
+
this.requireAuth();
|
|
28
|
+
const { flags } = await this.parse(MemoryProvenance);
|
|
29
|
+
let agentId;
|
|
30
|
+
try {
|
|
31
|
+
agentId = await (0, agent_resolver_1.resolveAgentId)(flags.agent);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
this.error(err.message, { exit: 1 });
|
|
35
|
+
}
|
|
36
|
+
let response;
|
|
37
|
+
try {
|
|
38
|
+
response = await data_provider_1.dataService.getAgentMemoryProvenance(agentId, flags.limit === undefined ? undefined : { limit: flags.limit });
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
this.handleApiError(err);
|
|
42
|
+
}
|
|
43
|
+
if (flags.json) {
|
|
44
|
+
this.log(this.agentJson(agentId, response));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const payload = response;
|
|
48
|
+
const entries = Array.isArray(response)
|
|
49
|
+
? response
|
|
50
|
+
: (payload?.entries ?? []);
|
|
51
|
+
if (entries.length === 0) {
|
|
52
|
+
this.log(`No memory provenance recorded for agent ${agentId}.`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
(0, format_1.renderTable)(entries.map((entry) => ({
|
|
56
|
+
key: String(entry.key ?? '-'),
|
|
57
|
+
source: String(entry.source ?? entry.origin ?? '-'),
|
|
58
|
+
at: entry.updated_at ? String(entry.updated_at).slice(0, 10) : '-',
|
|
59
|
+
})), [
|
|
60
|
+
{ key: 'key', header: 'KEY', verbatim: true },
|
|
61
|
+
{ key: 'source', header: 'SOURCE', maxWidth: 30 },
|
|
62
|
+
{ key: 'at', header: 'UPDATED' },
|
|
63
|
+
], (line) => this.log(line));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.default = MemoryProvenance;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* Which stored sessions exist on this machine.
|
|
4
|
+
*
|
|
5
|
+
* Every command advertises `--profile` and nothing could tell you what to pass
|
|
6
|
+
* it. Profiles are additive and stored on disk — the default at
|
|
7
|
+
* `<root>/cli-config.json`, named ones at `<root>/profiles/<name>/cli-config.json`
|
|
8
|
+
* — so the list was always knowable; there was simply no way to ask.
|
|
9
|
+
*
|
|
10
|
+
* That is not only a discoverability nit. A second profile is how one machine
|
|
11
|
+
* holds a second identity, which is what any test of a NON-OWNER path needs. A
|
|
12
|
+
* dogfood run of the `force`-past-a-required-Review flow stalled on exactly
|
|
13
|
+
* this: the flag was there, the second identity was reachable, and nothing named
|
|
14
|
+
* it.
|
|
15
|
+
*/
|
|
16
|
+
export default class ProfilesList extends BaseCommand {
|
|
17
|
+
static description: string;
|
|
18
|
+
static examples: string[];
|
|
19
|
+
static flags: {
|
|
20
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
21
|
+
};
|
|
22
|
+
run(): Promise<void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
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 node_fs_1 = __importDefault(require("node:fs"));
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const core_1 = require("@oclif/core");
|
|
9
|
+
const base_command_1 = require("../../base-command");
|
|
10
|
+
const config_1 = require("../../lib/config");
|
|
11
|
+
const keychain_1 = require("../../lib/keychain");
|
|
12
|
+
/**
|
|
13
|
+
* Which stored sessions exist on this machine.
|
|
14
|
+
*
|
|
15
|
+
* Every command advertises `--profile` and nothing could tell you what to pass
|
|
16
|
+
* it. Profiles are additive and stored on disk — the default at
|
|
17
|
+
* `<root>/cli-config.json`, named ones at `<root>/profiles/<name>/cli-config.json`
|
|
18
|
+
* — so the list was always knowable; there was simply no way to ask.
|
|
19
|
+
*
|
|
20
|
+
* That is not only a discoverability nit. A second profile is how one machine
|
|
21
|
+
* holds a second identity, which is what any test of a NON-OWNER path needs. A
|
|
22
|
+
* dogfood run of the `force`-past-a-required-Review flow stalled on exactly
|
|
23
|
+
* this: the flag was there, the second identity was reachable, and nothing named
|
|
24
|
+
* it.
|
|
25
|
+
*/
|
|
26
|
+
class ProfilesList extends base_command_1.BaseCommand {
|
|
27
|
+
static description = 'List the stored sessions (profiles) on this machine';
|
|
28
|
+
static examples = [
|
|
29
|
+
'<%= config.bin %> profiles list',
|
|
30
|
+
'<%= config.bin %> profiles list --json',
|
|
31
|
+
'<%= config.bin %> login --profile reviewer',
|
|
32
|
+
];
|
|
33
|
+
static flags = {
|
|
34
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
35
|
+
};
|
|
36
|
+
async run() {
|
|
37
|
+
const { flags } = await this.parse(ProfilesList);
|
|
38
|
+
const root = (0, config_1.configRoot)();
|
|
39
|
+
const active = (0, keychain_1.getActiveProfile)() || keychain_1.DEFAULT_PROFILE;
|
|
40
|
+
const rows = [];
|
|
41
|
+
const seen = new Set();
|
|
42
|
+
const describe = (name, configFile) => {
|
|
43
|
+
/*
|
|
44
|
+
* Deliberately NOT a "signed in" column.
|
|
45
|
+
*
|
|
46
|
+
* The credential does not live in `cli-config.json` — it is in the
|
|
47
|
+
* keychain — so this file can only report the deployment. A first draft
|
|
48
|
+
* inferred sign-in from a `token` key that is never there and printed
|
|
49
|
+
* `no` for the profile the caller was actively authenticated as: a
|
|
50
|
+
* confident wrong answer, which is worse than an absent one and exactly
|
|
51
|
+
* the failure this whole surface keeps making. Read the server, say the
|
|
52
|
+
* server.
|
|
53
|
+
*/
|
|
54
|
+
if (seen.has(name))
|
|
55
|
+
return;
|
|
56
|
+
seen.add(name);
|
|
57
|
+
let server;
|
|
58
|
+
try {
|
|
59
|
+
const raw = JSON.parse(node_fs_1.default.readFileSync(configFile, 'utf8'));
|
|
60
|
+
server = typeof raw.baseURL === 'string' ? raw.baseURL : undefined;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// A profile directory with no readable config is still a profile; say
|
|
64
|
+
// so rather than hiding it, because a half-written one is exactly what
|
|
65
|
+
// someone would be trying to diagnose.
|
|
66
|
+
}
|
|
67
|
+
rows.push({ name, active: name === active, server });
|
|
68
|
+
};
|
|
69
|
+
describe(keychain_1.DEFAULT_PROFILE, node_path_1.default.join(root, 'cli-config.json'));
|
|
70
|
+
try {
|
|
71
|
+
for (const entry of node_fs_1.default.readdirSync(node_path_1.default.join(root, 'profiles'), { withFileTypes: true })) {
|
|
72
|
+
if (!entry.isDirectory())
|
|
73
|
+
continue;
|
|
74
|
+
describe(entry.name, node_path_1.default.join(root, 'profiles', entry.name, 'cli-config.json'));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// No `profiles/` directory means no named profiles — not an error.
|
|
79
|
+
}
|
|
80
|
+
if (flags.json) {
|
|
81
|
+
this.log(JSON.stringify({ root, active, profiles: rows }, null, 2));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Width from the DATA, so a long profile name cannot run into the next
|
|
85
|
+
// column — `df-memory-verify-isolated` did exactly that at a fixed 24.
|
|
86
|
+
const width = Math.max(4, ...rows.map((row) => row.name.length)) + 2;
|
|
87
|
+
this.log('NAME'.padEnd(width) + 'ACTIVE'.padEnd(9) + 'SERVER');
|
|
88
|
+
for (const row of rows) {
|
|
89
|
+
this.log(row.name.padEnd(width) + (row.active ? 'yes' : '-').padEnd(9) + (row.server || '-'));
|
|
90
|
+
}
|
|
91
|
+
this.log('');
|
|
92
|
+
this.log(`Add one: ${this.config.bin} login --profile <name>`);
|
|
93
|
+
this.log(`Use one: ${this.config.bin} <command> --profile <name> (or OVERSKY_PROFILE)`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
exports.default = ProfilesList;
|
|
@@ -2,9 +2,19 @@ import { BaseCommand } from '../../base-command';
|
|
|
2
2
|
export default class SearchSkills extends BaseCommand {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
|
+
/**
|
|
6
|
+
* `skills search` and `search skills` are the SAME search, and both spellings
|
|
7
|
+
* stay. Neither said so, their one-liners differed, and only one carried short
|
|
8
|
+
* flags — so a reader picked one at random with no way to tell whether they had
|
|
9
|
+
* picked a deprecated spelling. Duplication that is deliberate should say so;
|
|
10
|
+
* duplication that is silent reads as a mistake either way.
|
|
11
|
+
*/
|
|
12
|
+
static args: {
|
|
13
|
+
query: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
14
|
+
};
|
|
5
15
|
static flags: {
|
|
6
16
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
7
|
-
query: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
17
|
+
query: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
18
|
category: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
19
|
limit: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
20
|
};
|
|
@@ -4,19 +4,36 @@ 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
|
+
const search_query_1 = require("../../lib/search-query");
|
|
7
8
|
class SearchSkills extends base_command_1.BaseCommand {
|
|
8
|
-
static description = 'Search skills in the skrr store';
|
|
9
|
+
static description = 'Search skills in the skrr store by keyword (same as `skills search`)';
|
|
9
10
|
static examples = [
|
|
10
|
-
'<%= config.bin %> search skills
|
|
11
|
-
'<%= config.bin %> search skills
|
|
12
|
-
'<%= config.bin %> search skills
|
|
11
|
+
'<%= config.bin %> search skills "web scraping"',
|
|
12
|
+
'<%= config.bin %> search skills summarize --category productivity',
|
|
13
|
+
'<%= config.bin %> search skills translate --limit 10 --json',
|
|
14
|
+
'<%= config.bin %> search skills -q translate',
|
|
13
15
|
];
|
|
16
|
+
/**
|
|
17
|
+
* `skills search` and `search skills` are the SAME search, and both spellings
|
|
18
|
+
* stay. Neither said so, their one-liners differed, and only one carried short
|
|
19
|
+
* flags — so a reader picked one at random with no way to tell whether they had
|
|
20
|
+
* picked a deprecated spelling. Duplication that is deliberate should say so;
|
|
21
|
+
* duplication that is silent reads as a mistake either way.
|
|
22
|
+
*/
|
|
23
|
+
static args = {
|
|
24
|
+
query: core_1.Args.string({
|
|
25
|
+
description: 'Search term (same value as --query; pass either, not both)',
|
|
26
|
+
required: false,
|
|
27
|
+
ignoreStdin: true,
|
|
28
|
+
}),
|
|
29
|
+
};
|
|
14
30
|
static flags = {
|
|
15
31
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
32
|
+
// See `skills search` — the positional satisfies it and the flag stays so
|
|
33
|
+
// existing scripts keep working.
|
|
16
34
|
query: core_1.Flags.string({
|
|
17
35
|
char: 'q',
|
|
18
36
|
description: 'Search query',
|
|
19
|
-
required: true,
|
|
20
37
|
}),
|
|
21
38
|
category: core_1.Flags.string({
|
|
22
39
|
char: 'c',
|
|
@@ -29,11 +46,12 @@ class SearchSkills extends base_command_1.BaseCommand {
|
|
|
29
46
|
};
|
|
30
47
|
async run() {
|
|
31
48
|
this.requireAuth();
|
|
32
|
-
const { flags } = await this.parse(SearchSkills);
|
|
49
|
+
const { args, flags } = await this.parse(SearchSkills);
|
|
50
|
+
const query = (0, search_query_1.resolveSearchQuery)(this, args.query, flags.query, 'search skills');
|
|
33
51
|
let response;
|
|
34
52
|
try {
|
|
35
53
|
response = await data_provider_1.dataService.getStoreSkills({
|
|
36
|
-
q:
|
|
54
|
+
q: query,
|
|
37
55
|
category: flags.category,
|
|
38
56
|
limit: flags.limit,
|
|
39
57
|
});
|
|
@@ -48,7 +66,7 @@ class SearchSkills extends base_command_1.BaseCommand {
|
|
|
48
66
|
const r = response;
|
|
49
67
|
const items = Array.isArray(r) ? r : (r?.data ?? []);
|
|
50
68
|
if (items.length === 0) {
|
|
51
|
-
this.log(
|
|
69
|
+
this.log(`No skills found matching '${query}'.`);
|
|
52
70
|
return;
|
|
53
71
|
}
|
|
54
72
|
const rows = items.map((s) => ({
|
|
@@ -8,5 +8,7 @@ export default class SkillsDetails extends BaseCommand {
|
|
|
8
8
|
static flags: {
|
|
9
9
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
10
|
};
|
|
11
|
+
/** A store 404 for a name that may be a skill on the caller's machine. */
|
|
12
|
+
private failOnStoreMiss;
|
|
11
13
|
run(): Promise<void>;
|
|
12
14
|
}
|