@skrr-ai/cli 0.1.32 → 0.1.33
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/bin/run.js +2 -2
- package/dist/commands/agents/list.d.ts +2 -1
- package/dist/commands/agents/list.js +2 -1
- package/dist/commands/agents/show.js +2 -1
- package/dist/commands/balance/statement.js +8 -4
- package/dist/commands/browser/install.js +6 -2
- package/dist/commands/browser/uninstall.js +6 -2
- package/dist/commands/code/acp.js +2 -1
- package/dist/commands/code/doctor.d.ts +1 -1
- package/dist/commands/code/doctor.js +6 -5
- package/dist/commands/code/handover.d.ts +2 -2
- package/dist/commands/code/handover.js +2 -2
- package/dist/commands/code/index.d.ts +2 -2
- package/dist/commands/code/index.js +18 -17
- package/dist/commands/code/install.d.ts +3 -3
- package/dist/commands/code/install.js +18 -11
- package/dist/commands/code/migrate.js +3 -2
- package/dist/commands/code/oversky-agent.d.ts +5 -4
- package/dist/commands/code/oversky-agent.js +24 -22
- package/dist/commands/code/run.js +2 -1
- package/dist/commands/harnesses/list.d.ts +9 -1
- package/dist/commands/harnesses/list.js +28 -7
- package/dist/commands/harnesses/show.js +7 -2
- package/dist/commands/instructions/install.js +16 -6
- package/dist/commands/learning/delete.d.ts +9 -0
- package/dist/commands/learning/delete.js +39 -0
- package/dist/commands/learning/export.d.ts +5 -0
- package/dist/commands/learning/export.js +22 -0
- package/dist/commands/learning/reset.d.ts +9 -0
- package/dist/commands/learning/reset.js +34 -0
- package/dist/commands/learning/set.d.ts +10 -0
- package/dist/commands/learning/set.js +52 -0
- package/dist/commands/learning/status.d.ts +8 -0
- package/dist/commands/learning/status.js +35 -0
- package/dist/commands/logout.js +10 -5
- package/dist/commands/machines/dedicated/attach.js +2 -1
- package/dist/commands/tasks/runs.js +3 -1
- package/dist/commands/workspaces/use.js +2 -1
- package/dist/lib/adaptive-learning.d.ts +37 -0
- package/dist/lib/adaptive-learning.js +39 -0
- package/dist/lib/code-handover.d.ts +1 -1
- package/dist/lib/code-handover.js +3 -2
- package/dist/lib/config.d.ts +30 -4
- package/dist/lib/config.js +2 -1
- package/dist/lib/daemon-installer.d.ts +1 -1
- package/dist/lib/daemon-target.js +2 -2
- package/dist/lib/dedicated-machines.d.ts +2 -2
- package/dist/lib/dedicated-machines.js +6 -3
- package/dist/lib/exec-runtime-binary.d.ts +2 -2
- package/dist/lib/exec-runtime-binary.js +2 -2
- package/dist/lib/{sky-code-agent.d.ts → first-party-harness-agent.d.ts} +20 -19
- package/dist/lib/{sky-code-agent.js → first-party-harness-agent.js} +85 -47
- package/dist/lib/{sky-code-broker.d.ts → first-party-harness-broker.d.ts} +6 -6
- package/dist/lib/{sky-code-broker.js → first-party-harness-broker.js} +23 -23
- package/dist/lib/{sky-code-doctor.d.ts → first-party-harness-doctor.d.ts} +12 -2
- package/dist/lib/{sky-code-doctor.js → first-party-harness-doctor.js} +181 -94
- package/dist/lib/{sky-code-managed.d.ts → first-party-harness-managed.d.ts} +55 -30
- package/dist/lib/{sky-code-managed.js → first-party-harness-managed.js} +92 -35
- package/dist/lib/{sky-code.d.ts → first-party-harness.d.ts} +107 -36
- package/dist/lib/{sky-code.js → first-party-harness.js} +172 -73
- package/dist/lib/harness-provider-input.d.ts +35 -0
- package/dist/lib/harness-provider-input.js +57 -0
- package/dist/lib/harness-tiers.d.ts +8 -2
- package/dist/lib/harness-tiers.js +11 -6
- package/dist/lib/task-instruction-offer.js +10 -4
- package/dist/lib/worklogs.js +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/configRoot.d.ts +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/configRoot.js +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.d.ts +248 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.js +361 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.d.ts +147 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.js +180 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessHome.d.ts +111 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessHome.js +314 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.d.ts +11 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.js +14 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +51 -14
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releaseManifest.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +4 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +4 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/configRoot.d.ts +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/configRoot.js +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.d.ts +248 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.js +332 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.d.ts +147 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.js +170 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessHome.d.ts +111 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessHome.js +303 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.d.ts +11 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.js +14 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +12 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releaseManifest.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +4 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +4 -4
- package/dist/node_modules/@skrr-ai/auth-core/package.json +11 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +4816 -4782
- package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/index.js +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/managed-inference-broker.js +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/index.js +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/managed-inference-broker.js +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/package.json +1 -1
- package/oclif.manifest.json +34682 -34371
- package/package.json +5 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/skyCodeChannels.d.ts +0 -96
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/skyCodeChannels.js +0 -115
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/skyCodeChannels.d.ts +0 -96
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/skyCodeChannels.js +0 -107
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
+
const auth_core_1 = require("@skrr-ai/auth-core");
|
|
4
5
|
const auth_core_init_1 = require("../../lib/auth-core-init");
|
|
5
6
|
const config_1 = require("../../lib/config");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
7
|
+
const first_party_harness_agent_1 = require("../../lib/first-party-harness-agent");
|
|
8
|
+
const first_party_harness_managed_1 = require("../../lib/first-party-harness-managed");
|
|
8
9
|
/**
|
|
9
10
|
* `skrr code skrr-agent` — read and write the agent a managed session runs as.
|
|
10
11
|
*
|
|
11
12
|
* ── Why the name carries the `oversky-` prefix ─────────────────────────────
|
|
12
13
|
*
|
|
13
|
-
* The engine owns `agent`: `
|
|
14
|
+
* The engine owns `agent`: the engine binary's `agent` is its own agent-management command.
|
|
14
15
|
* `skrr code` forwards argv VERBATIM, and oclif's spaced-topic dispatch collates
|
|
15
16
|
* `code agent …` into a command id BEFORE the forwarding command ever runs — so
|
|
16
17
|
* naming this `code:agent` would have silently taken that name away from the
|
|
@@ -23,7 +24,8 @@ const sky_code_managed_1 = require("../../lib/sky-code-managed");
|
|
|
23
24
|
*
|
|
24
25
|
* ── Why the setting needed a command at all ────────────────────────────────
|
|
25
26
|
*
|
|
26
|
-
*
|
|
27
|
+
* The setting (`AGENT_CONFIG_KEY`, then under an older product-named key)
|
|
28
|
+
* predates this and had no way to be written: nothing in
|
|
27
29
|
* `cli/src` called `saveConfig` with it, so the refusal that told users to set it
|
|
28
30
|
* was pointing at a file it expected them to hand-edit — and `skrr logout` then
|
|
29
31
|
* rebuilt the config without the key and dropped it silently.
|
|
@@ -38,7 +40,7 @@ class CodeOverskyAgent extends core_1.Command {
|
|
|
38
40
|
// path this file has and stays reachable, because it is in scripts and in
|
|
39
41
|
// muscle memory.
|
|
40
42
|
static aliases = ['code:skrr-agent'];
|
|
41
|
-
static description =
|
|
43
|
+
static description = `Show or set the skrr agent a managed ${auth_core_1.FIRST_PARTY_HARNESS.displayName} session is attributed to`;
|
|
42
44
|
static examples = [
|
|
43
45
|
'<%= config.bin %> code skrr-agent',
|
|
44
46
|
'<%= config.bin %> code skrr-agent --set Engineer',
|
|
@@ -56,7 +58,7 @@ class CodeOverskyAgent extends core_1.Command {
|
|
|
56
58
|
exclusive: ['clear', 'show'],
|
|
57
59
|
}),
|
|
58
60
|
clear: core_1.Flags.boolean({
|
|
59
|
-
description: `Remove the stored "${
|
|
61
|
+
description: `Remove the stored "${first_party_harness_managed_1.AGENT_CONFIG_KEY}" setting`,
|
|
60
62
|
exclusive: ['set', 'show'],
|
|
61
63
|
}),
|
|
62
64
|
create: core_1.Flags.boolean({
|
|
@@ -73,7 +75,7 @@ class CodeOverskyAgent extends core_1.Command {
|
|
|
73
75
|
// 401 reported as `agent-lookup-failed`, which reads like a server problem
|
|
74
76
|
// and sends them to re-login when they are already logged in.
|
|
75
77
|
//
|
|
76
|
-
// `
|
|
78
|
+
// `first-party-harness-broker.ts` does the same thing for the same reason before its
|
|
77
79
|
// own first API call; this command is simply the second caller on that path.
|
|
78
80
|
if (!flags.clear) {
|
|
79
81
|
await (0, auth_core_init_1.prefetchCliAuth)();
|
|
@@ -93,7 +95,7 @@ class CodeOverskyAgent extends core_1.Command {
|
|
|
93
95
|
}
|
|
94
96
|
let agent;
|
|
95
97
|
try {
|
|
96
|
-
agent = await (0,
|
|
98
|
+
agent = await (0, first_party_harness_agent_1.setConfiguredAgentId)(trimmed);
|
|
97
99
|
}
|
|
98
100
|
catch (err) {
|
|
99
101
|
this.fail(err);
|
|
@@ -102,18 +104,18 @@ class CodeOverskyAgent extends core_1.Command {
|
|
|
102
104
|
this.logJson({ action: 'set', agent: summarize(agent), configPath: (0, config_1.getConfigPath)() });
|
|
103
105
|
return;
|
|
104
106
|
}
|
|
105
|
-
this.log(
|
|
107
|
+
this.log(`${auth_core_1.FIRST_PARTY_HARNESS.displayName} will run as ${describe(agent)}.`);
|
|
106
108
|
this.log(`Saved to ${(0, config_1.getConfigPath)()}.`);
|
|
107
109
|
}
|
|
108
110
|
runClear(json) {
|
|
109
|
-
const previous = (0,
|
|
111
|
+
const previous = (0, first_party_harness_agent_1.clearConfiguredAgentId)();
|
|
110
112
|
if (json) {
|
|
111
113
|
this.logJson({ action: 'clear', cleared: previous ?? null, configPath: (0, config_1.getConfigPath)() });
|
|
112
114
|
return;
|
|
113
115
|
}
|
|
114
116
|
this.log(previous
|
|
115
|
-
? `Cleared "${
|
|
116
|
-
: `No "${
|
|
117
|
+
? `Cleared "${first_party_harness_managed_1.AGENT_CONFIG_KEY}" (was ${previous}).`
|
|
118
|
+
: `No "${first_party_harness_managed_1.AGENT_CONFIG_KEY}" was set; nothing to clear.`);
|
|
117
119
|
}
|
|
118
120
|
/**
|
|
119
121
|
* Report what a session WOULD resolve to.
|
|
@@ -121,18 +123,18 @@ class CodeOverskyAgent extends core_1.Command {
|
|
|
121
123
|
* `allowCreate` is off by default, and that is the whole design of this branch:
|
|
122
124
|
* a command whose job is to answer a question must not create a server-side
|
|
123
125
|
* agent as a side effect of being asked. Without the guard, `skrr code
|
|
124
|
-
*
|
|
126
|
+
* skrr-agent` — the bare, most likely invocation, and the one a user runs to
|
|
125
127
|
* find out what is going on — would mint the default agent it then reported,
|
|
126
128
|
* making the answer true only because the question was asked.
|
|
127
129
|
*/
|
|
128
130
|
async runShow(json, allowCreate) {
|
|
129
|
-
const stored = (0,
|
|
131
|
+
const stored = (0, first_party_harness_agent_1.readConfiguredAgentId)();
|
|
130
132
|
let agent;
|
|
131
133
|
try {
|
|
132
|
-
agent = await (0,
|
|
134
|
+
agent = await (0, first_party_harness_agent_1.resolveFirstPartyHarnessAgent)(undefined, {}, { createDefault: allowCreate });
|
|
133
135
|
}
|
|
134
136
|
catch (err) {
|
|
135
|
-
if (json && err instanceof
|
|
137
|
+
if (json && err instanceof first_party_harness_agent_1.FirstPartyHarnessAgentError) {
|
|
136
138
|
this.logJson({
|
|
137
139
|
action: 'show',
|
|
138
140
|
agent: null,
|
|
@@ -164,19 +166,19 @@ class CodeOverskyAgent extends core_1.Command {
|
|
|
164
166
|
// people to pin it would be noise on every run.
|
|
165
167
|
if (agent.source === 'sole-agent' && !stored) {
|
|
166
168
|
this.log(`\nThis changes if you create another agent. To pin it: ` +
|
|
167
|
-
|
|
169
|
+
`${auth_core_1.FIRST_PARTY_HARNESS.command} skrr-agent --set ${agent.id}`);
|
|
168
170
|
}
|
|
169
171
|
}
|
|
170
172
|
/**
|
|
171
173
|
* Report a resolution failure as the refusal it is.
|
|
172
174
|
*
|
|
173
|
-
* `
|
|
175
|
+
* `FirstPartyHarnessAgentError` messages are already written to be actionable — they name
|
|
174
176
|
* the flag, the config key, and the candidates — so this prints the message
|
|
175
177
|
* rather than wrapping it in a second sentence that would push the useful part
|
|
176
178
|
* off the first line.
|
|
177
179
|
*/
|
|
178
180
|
fail(err) {
|
|
179
|
-
if (err instanceof
|
|
181
|
+
if (err instanceof first_party_harness_agent_1.FirstPartyHarnessAgentError) {
|
|
180
182
|
this.error(err.message, { exit: 1, code: err.code });
|
|
181
183
|
}
|
|
182
184
|
throw err;
|
|
@@ -192,13 +194,13 @@ function describe(agent) {
|
|
|
192
194
|
function explainSource(agent) {
|
|
193
195
|
switch (agent.source) {
|
|
194
196
|
case 'flag':
|
|
195
|
-
return `${
|
|
197
|
+
return `${first_party_harness_managed_1.SKRR_AGENT_FLAG} on the command line`;
|
|
196
198
|
case 'config':
|
|
197
|
-
return `"${
|
|
199
|
+
return `"${first_party_harness_managed_1.AGENT_CONFIG_KEY}" in ${(0, config_1.getConfigPath)()}`;
|
|
198
200
|
case 'sole-agent':
|
|
199
201
|
return 'the only agent you own — not pinned, so this changes if you create another';
|
|
200
202
|
case 'default-agent':
|
|
201
|
-
return
|
|
203
|
+
return `your ${auth_core_1.FIRST_PARTY_HARNESS.displayName} default, used automatically because nothing above was set`;
|
|
202
204
|
default:
|
|
203
205
|
return agent.source;
|
|
204
206
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
+
const auth_core_1 = require("@skrr-ai/auth-core");
|
|
4
5
|
const index_1 = require("./index");
|
|
5
6
|
/**
|
|
6
7
|
* `skrr code run` — headless execution.
|
|
@@ -9,7 +10,7 @@ const index_1 = require("./index");
|
|
|
9
10
|
* engine's own code so CI can branch on it.
|
|
10
11
|
*/
|
|
11
12
|
class CodeRun extends core_1.Command {
|
|
12
|
-
static description =
|
|
13
|
+
static description = `Run ${auth_core_1.FIRST_PARTY_HARNESS.displayName} headlessly on a single prompt`;
|
|
13
14
|
static strict = false;
|
|
14
15
|
static examples = [
|
|
15
16
|
'<%= config.bin %> code run "add a regression test for the parser"',
|
|
@@ -133,11 +133,19 @@ export type HarnessesJson = {
|
|
|
133
133
|
* it is deliberate, so `.harnesses[0]` is the row you almost always want.
|
|
134
134
|
*/
|
|
135
135
|
export declare function buildHarnessesJson(selection: HarnessSelection, filters: HarnessesFilters): HarnessesJson;
|
|
136
|
+
/**
|
|
137
|
+
* Rows with the provider in its CANONICAL spelling.
|
|
138
|
+
*
|
|
139
|
+
* A row registered by a daemon on either side of a rename may carry either
|
|
140
|
+
* spelling of the first-party harness, and output — the table and `--json` alike —
|
|
141
|
+
* prints one, so a script grouping by provider never sees one harness as two.
|
|
142
|
+
*/
|
|
143
|
+
export declare function canonicalHarnessRows(rows: readonly HarnessRow[]): HarnessRow[];
|
|
136
144
|
/** `YYYY-MM-DD HH:MM` — the staleness of an offline row is the whole reason to show it. */
|
|
137
145
|
/**
|
|
138
146
|
* `skrr harnesses list`
|
|
139
147
|
*
|
|
140
|
-
* List the harnesses (claude/codex/opencode/openclaw/
|
|
148
|
+
* List the harnesses (claude/codex/opencode/openclaw/the first-party harness) registered by
|
|
141
149
|
* the caller's connected daemon(s) — one row per (daemon, provider) — and
|
|
142
150
|
* surface the `_id` that `agents attach-harness` pins.
|
|
143
151
|
*
|
|
@@ -3,10 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.isLocalHarnessRow = isLocalHarnessRow;
|
|
4
4
|
exports.selectHarnessRows = selectHarnessRows;
|
|
5
5
|
exports.buildHarnessesJson = buildHarnessesJson;
|
|
6
|
+
exports.canonicalHarnessRows = canonicalHarnessRows;
|
|
6
7
|
const core_1 = require("@oclif/core");
|
|
8
|
+
const auth_core_1 = require("@skrr-ai/auth-core");
|
|
7
9
|
const base_command_1 = require("../../base-command");
|
|
8
10
|
const api_fetch_1 = require("../../lib/api-fetch");
|
|
9
11
|
const format_1 = require("../../lib/format");
|
|
12
|
+
const harness_provider_input_1 = require("../../lib/harness-provider-input");
|
|
10
13
|
/**
|
|
11
14
|
* Products skrr provisions and owns. A row that says it is one of these is
|
|
12
15
|
* cloud, whatever `harnessLocation` reads.
|
|
@@ -124,6 +127,21 @@ function buildHarnessesJson(selection, filters) {
|
|
|
124
127
|
},
|
|
125
128
|
};
|
|
126
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Rows with the provider in its CANONICAL spelling.
|
|
132
|
+
*
|
|
133
|
+
* A row registered by a daemon on either side of a rename may carry either
|
|
134
|
+
* spelling of the first-party harness, and output — the table and `--json` alike —
|
|
135
|
+
* prints one, so a script grouping by provider never sees one harness as two.
|
|
136
|
+
*/
|
|
137
|
+
function canonicalHarnessRows(rows) {
|
|
138
|
+
return rows.map((row) => {
|
|
139
|
+
if (typeof row.provider !== 'string')
|
|
140
|
+
return row;
|
|
141
|
+
const provider = (0, harness_provider_input_1.canonicalHarnessInput)(row.provider);
|
|
142
|
+
return provider === row.provider ? row : { ...row, provider };
|
|
143
|
+
});
|
|
144
|
+
}
|
|
127
145
|
/** Online first, then most-recently-seen first — the row you want is row 1. */
|
|
128
146
|
function compareHarnessRows(a, b) {
|
|
129
147
|
const aOffline = a.status === 'online' ? 0 : 1;
|
|
@@ -140,7 +158,7 @@ function lastSeenMs(row) {
|
|
|
140
158
|
/**
|
|
141
159
|
* `skrr harnesses list`
|
|
142
160
|
*
|
|
143
|
-
* List the harnesses (claude/codex/opencode/openclaw/
|
|
161
|
+
* List the harnesses (claude/codex/opencode/openclaw/the first-party harness) registered by
|
|
144
162
|
* the caller's connected daemon(s) — one row per (daemon, provider) — and
|
|
145
163
|
* surface the `_id` that `agents attach-harness` pins.
|
|
146
164
|
*
|
|
@@ -149,7 +167,7 @@ function lastSeenMs(row) {
|
|
|
149
167
|
* previously undiscoverable.
|
|
150
168
|
*/
|
|
151
169
|
class HarnessesList extends base_command_1.BaseCommand {
|
|
152
|
-
static description =
|
|
170
|
+
static description = `List your harnesses — your local Claude Code, Codex, ${auth_core_1.FIRST_PARTY_HARNESS.displayName}, one row per (machine, provider). The id here is what \`agents attach-harness\` pins. Online only unless --all.`;
|
|
153
171
|
static examples = [
|
|
154
172
|
'<%= config.bin %> harnesses list',
|
|
155
173
|
'<%= config.bin %> harnesses list --provider claude',
|
|
@@ -172,7 +190,7 @@ class HarnessesList extends base_command_1.BaseCommand {
|
|
|
172
190
|
exclusive: ['status', 'online'],
|
|
173
191
|
}),
|
|
174
192
|
provider: core_1.Flags.string({
|
|
175
|
-
description:
|
|
193
|
+
description: `Filter by provider (e.g. claude, codex, opencode, openclaw, ${auth_core_1.FIRST_PARTY_HARNESS.provider}).`,
|
|
176
194
|
}),
|
|
177
195
|
daemon: core_1.Flags.string({
|
|
178
196
|
description: 'Filter by daemon id, matching any substring — e.g. the machine hash in daemon_<hash>_<source>_<profile>.',
|
|
@@ -193,11 +211,14 @@ class HarnessesList extends base_command_1.BaseCommand {
|
|
|
193
211
|
// mode. Materialize that default before the request so JSON cannot quietly
|
|
194
212
|
// return every historical offline row while the table shows seven live ones.
|
|
195
213
|
const status = flags.online ? 'online' : (flags.status ?? (flags.all ? undefined : 'online'));
|
|
214
|
+
// Any spelling of the first-party harness filters the same rows; the server is
|
|
215
|
+
// asked for the canonical one, which it matches against every stored spelling.
|
|
216
|
+
const provider = flags.provider ? (0, harness_provider_input_1.canonicalHarnessInput)(flags.provider) : undefined;
|
|
196
217
|
const params = new URLSearchParams();
|
|
197
218
|
if (status)
|
|
198
219
|
params.set('status', status);
|
|
199
|
-
if (
|
|
200
|
-
params.set('provider',
|
|
220
|
+
if (provider)
|
|
221
|
+
params.set('provider', provider);
|
|
201
222
|
const query = params.toString() ? `?${params.toString()}` : '';
|
|
202
223
|
let res;
|
|
203
224
|
try {
|
|
@@ -208,7 +229,7 @@ class HarnessesList extends base_command_1.BaseCommand {
|
|
|
208
229
|
catch (err) {
|
|
209
230
|
this.handleApiError(err);
|
|
210
231
|
}
|
|
211
|
-
const selection = selectHarnessRows(res.harnesses ?? [], {
|
|
232
|
+
const selection = selectHarnessRows(canonicalHarnessRows(res.harnesses ?? []), {
|
|
212
233
|
local: flags.local,
|
|
213
234
|
daemon: flags.daemon,
|
|
214
235
|
limit: flags.limit,
|
|
@@ -218,7 +239,7 @@ class HarnessesList extends base_command_1.BaseCommand {
|
|
|
218
239
|
const payload = buildHarnessesJson(selection, {
|
|
219
240
|
local: flags.local,
|
|
220
241
|
status: status ?? null,
|
|
221
|
-
provider:
|
|
242
|
+
provider: provider ?? null,
|
|
222
243
|
daemon: flags.daemon ?? null,
|
|
223
244
|
limit: flags.limit ?? null,
|
|
224
245
|
});
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
4
|
const base_command_1 = require("../../base-command");
|
|
5
|
+
const harness_provider_input_1 = require("../../lib/harness-provider-input");
|
|
5
6
|
const harnesses_1 = require("../../lib/harnesses");
|
|
6
7
|
const api_fetch_1 = require("../../lib/api-fetch");
|
|
7
8
|
class HarnessesShow extends base_command_1.BaseCommand {
|
|
@@ -42,7 +43,11 @@ class HarnessesShow extends base_command_1.BaseCommand {
|
|
|
42
43
|
this.handleApiError(err);
|
|
43
44
|
return;
|
|
44
45
|
}
|
|
45
|
-
const
|
|
46
|
+
const stored = response?.harness;
|
|
47
|
+
// Canonical spelling in every output, whichever spelling the row was stored under.
|
|
48
|
+
const harness = stored && typeof stored.provider === 'string'
|
|
49
|
+
? { ...stored, provider: (0, harness_provider_input_1.canonicalHarnessInput)(stored.provider) }
|
|
50
|
+
: stored;
|
|
46
51
|
if (!harness) {
|
|
47
52
|
this.error(`No harness ${args.harness}.`, { exit: 1 });
|
|
48
53
|
return;
|
|
@@ -60,7 +65,7 @@ class HarnessesShow extends base_command_1.BaseCommand {
|
|
|
60
65
|
this.log(` status ${harness.status ?? 'unknown'}`);
|
|
61
66
|
// Only for the claude provider. The daemon stamps `claudeEngine` on every
|
|
62
67
|
// harness it registers, so printing it whenever it is set labels a
|
|
63
|
-
//
|
|
68
|
+
// first-party harness or `codex` row with how CLAUDE Code would run — a fact about a
|
|
64
69
|
// different harness on the same machine.
|
|
65
70
|
if (harness.provider === 'claude' && harness.claudeEngine) {
|
|
66
71
|
this.log(` driven as ${harness.claudeEngine} (how Claude Code runs here)`);
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
+
const auth_core_1 = require("@skrr-ai/auth-core");
|
|
4
5
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
6
|
const base_command_1 = require("../../base-command");
|
|
6
7
|
const daemon_target_1 = require("../../lib/daemon-target");
|
|
8
|
+
const harness_provider_input_1 = require("../../lib/harness-provider-input");
|
|
7
9
|
const prompt_1 = require("../../lib/prompt");
|
|
10
|
+
/** The providers a managed instruction can target, canonical spellings. */
|
|
11
|
+
const MANAGED_INSTRUCTION_PROVIDERS = ['claude', 'codex', auth_core_1.FIRST_PARTY_HARNESS.provider];
|
|
8
12
|
class InstructionsInstall extends base_command_1.BaseCommand {
|
|
9
13
|
static description = 'Opt in a daemon target to ongoing managed instruction reconciliation';
|
|
10
14
|
static flags = {
|
|
@@ -19,10 +23,13 @@ class InstructionsInstall extends base_command_1.BaseCommand {
|
|
|
19
23
|
description: 'Daemon ID; defaults to this machine on a Dedicated Runtime, otherwise inferred when exactly one daemon is online',
|
|
20
24
|
}),
|
|
21
25
|
provider: core_1.Flags.string({
|
|
26
|
+
// Every accepted spelling of the first-party harness is a valid option, so a
|
|
27
|
+
// script written against either spelling still parses; the command
|
|
28
|
+
// normalises to canonical before anything leaves the CLI.
|
|
22
29
|
description: 'Provider to manage (repeatable)',
|
|
23
|
-
options:
|
|
30
|
+
options: (0, harness_provider_input_1.harnessFlagOptions)(MANAGED_INSTRUCTION_PROVIDERS),
|
|
24
31
|
multiple: true,
|
|
25
|
-
default:
|
|
32
|
+
default: MANAGED_INSTRUCTION_PROVIDERS,
|
|
26
33
|
}),
|
|
27
34
|
scope: core_1.Flags.string({ description: 'global or project', options: ['global', 'project'] }),
|
|
28
35
|
project: core_1.Flags.string({ description: 'Absolute project path on the daemon machine' }),
|
|
@@ -42,6 +49,9 @@ class InstructionsInstall extends base_command_1.BaseCommand {
|
|
|
42
49
|
async run() {
|
|
43
50
|
this.requireAuth();
|
|
44
51
|
const { flags } = await this.parse(InstructionsInstall);
|
|
52
|
+
// Canonical, deduplicated: `--provider <alias> --provider <canonical>` is one
|
|
53
|
+
// target, not two, and the server stores the canonical spelling.
|
|
54
|
+
const providers = (0, harness_provider_input_1.canonicalHarnessInputs)(flags.provider);
|
|
45
55
|
const scope = (flags.scope || (flags.project ? 'project' : 'global'));
|
|
46
56
|
if (scope === 'project' && !flags.project) {
|
|
47
57
|
this.error('--project is required for project scope', { exit: 2 });
|
|
@@ -74,7 +84,7 @@ class InstructionsInstall extends base_command_1.BaseCommand {
|
|
|
74
84
|
catch (error) {
|
|
75
85
|
this.handleApiError(error);
|
|
76
86
|
}
|
|
77
|
-
if (
|
|
87
|
+
if (providers.includes('codex') && Buffer.byteLength(previewBody, 'utf8') > 30 * 1024) {
|
|
78
88
|
this.error('Codex managed instruction bodies are limited to 30 KiB; no targets were created', { exit: 2 });
|
|
79
89
|
}
|
|
80
90
|
if (!flags.json) {
|
|
@@ -86,13 +96,13 @@ class InstructionsInstall extends base_command_1.BaseCommand {
|
|
|
86
96
|
const teamWarning = scope === 'project' && flags.mode === 'team'
|
|
87
97
|
? ' Team mode writes to repository files and may affect every contributor.'
|
|
88
98
|
: '';
|
|
89
|
-
const confirmed = await (0, prompt_1.confirmDestructive)(`Authorize continuous ${
|
|
99
|
+
const confirmed = await (0, prompt_1.confirmDestructive)(`Authorize continuous ${providers.join(', ')} reconciliation on this target?${teamWarning}`, flags.yes);
|
|
90
100
|
if (!confirmed)
|
|
91
101
|
return this.log('Aborted.');
|
|
92
102
|
const daemonId = await this.resolveDaemon(flags.daemon);
|
|
93
103
|
const results = [];
|
|
94
104
|
try {
|
|
95
|
-
for (const provider of
|
|
105
|
+
for (const provider of providers) {
|
|
96
106
|
results.push(await data_provider_1.dataService.createManagedInstructionTarget({
|
|
97
107
|
daemonId,
|
|
98
108
|
bundleId: flags.bundle,
|
|
@@ -112,7 +122,7 @@ class InstructionsInstall extends base_command_1.BaseCommand {
|
|
|
112
122
|
if (flags.json)
|
|
113
123
|
return this.log(JSON.stringify(results, null, 2));
|
|
114
124
|
for (const result of results) {
|
|
115
|
-
this.log(`Install queued: ${result.target.provider} ${result.target.scope}${result.target.projectPath ? ` ${result.target.projectPath}` : ''} (${result.target.id})`);
|
|
125
|
+
this.log(`Install queued: ${(0, harness_provider_input_1.canonicalHarnessInput)(result.target.provider)} ${result.target.scope}${result.target.projectPath ? ` ${result.target.projectPath}` : ''} (${result.target.id})`);
|
|
116
126
|
}
|
|
117
127
|
}
|
|
118
128
|
/**
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
export default class LearningDelete extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static flags: {
|
|
5
|
+
yes: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
6
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../base-command");
|
|
5
|
+
const api_fetch_1 = require("../../lib/api-fetch");
|
|
6
|
+
class LearningDelete extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Delete your governed adaptive-learning data and disable both consents';
|
|
8
|
+
static flags = {
|
|
9
|
+
yes: core_1.Flags.boolean({ char: 'y', description: 'Confirm deletion without prompting' }),
|
|
10
|
+
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
11
|
+
};
|
|
12
|
+
async run() {
|
|
13
|
+
this.requireAuth();
|
|
14
|
+
const { flags } = await this.parse(LearningDelete);
|
|
15
|
+
if (!flags.yes &&
|
|
16
|
+
!(await this.confirm('Delete all adaptive-learning state, episodes, and outcomes? [y/N] '))) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
let result;
|
|
20
|
+
try {
|
|
21
|
+
result = await (0, api_fetch_1.apiFetch)('/api/user/adaptive-learning/data', {
|
|
22
|
+
method: 'DELETE',
|
|
23
|
+
body: { confirm: 'DELETE' },
|
|
24
|
+
credential: this.resolvedCredential,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
this.handleApiError(err);
|
|
29
|
+
}
|
|
30
|
+
if (flags.json)
|
|
31
|
+
this.log(JSON.stringify(result, null, 2));
|
|
32
|
+
else {
|
|
33
|
+
this.log(`Deletion complete (${result.receiptId}): states=${result.removedStates}, ` +
|
|
34
|
+
`episodes=${result.removedEpisodes}, observations=${result.removedObservations}, ` +
|
|
35
|
+
`legacy mirrors=${result.removedLegacyMirrors}.`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.default = LearningDelete;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const base_command_1 = require("../../base-command");
|
|
4
|
+
const api_fetch_1 = require("../../lib/api-fetch");
|
|
5
|
+
class LearningExport extends base_command_1.BaseCommand {
|
|
6
|
+
static description = 'Export your adaptive-learning consent, state, episodes, and outcomes as JSON';
|
|
7
|
+
async run() {
|
|
8
|
+
this.requireAuth();
|
|
9
|
+
await this.parse(LearningExport);
|
|
10
|
+
let result;
|
|
11
|
+
try {
|
|
12
|
+
result = await (0, api_fetch_1.apiFetch)('/api/user/adaptive-learning/export', {
|
|
13
|
+
credential: this.resolvedCredential,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
this.handleApiError(err);
|
|
18
|
+
}
|
|
19
|
+
this.log(JSON.stringify(result, null, 2));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.default = LearningExport;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
export default class LearningReset extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static flags: {
|
|
5
|
+
yes: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
6
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../base-command");
|
|
5
|
+
const api_fetch_1 = require("../../lib/api-fetch");
|
|
6
|
+
class LearningReset extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Reset learned serving state while retaining governed evidence';
|
|
8
|
+
static flags = {
|
|
9
|
+
yes: core_1.Flags.boolean({ char: 'y', description: 'Confirm reset without prompting' }),
|
|
10
|
+
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
11
|
+
};
|
|
12
|
+
async run() {
|
|
13
|
+
this.requireAuth();
|
|
14
|
+
const { flags } = await this.parse(LearningReset);
|
|
15
|
+
if (!flags.yes && !(await this.confirm('Reset all learned serving state? [y/N] ')))
|
|
16
|
+
return;
|
|
17
|
+
let result;
|
|
18
|
+
try {
|
|
19
|
+
result = await (0, api_fetch_1.apiFetch)('/api/user/adaptive-learning/reset', {
|
|
20
|
+
method: 'POST',
|
|
21
|
+
credential: this.resolvedCredential,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
this.handleApiError(err);
|
|
26
|
+
}
|
|
27
|
+
if (flags.json)
|
|
28
|
+
this.log(JSON.stringify(result, null, 2));
|
|
29
|
+
else {
|
|
30
|
+
this.log(`Reset complete: removed ${result.removedStates} state(s); generation ${result.stateGeneration}.`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.default = LearningReset;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
export default class LearningSet extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static flags: {
|
|
5
|
+
personalization: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
6
|
+
'shared-training': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../base-command");
|
|
5
|
+
const api_fetch_1 = require("../../lib/api-fetch");
|
|
6
|
+
const adaptive_learning_1 = require("../../lib/adaptive-learning");
|
|
7
|
+
class LearningSet extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Change personal and shared adaptive-learning consent independently';
|
|
9
|
+
static flags = {
|
|
10
|
+
personalization: core_1.Flags.string({
|
|
11
|
+
description: 'Allow learned preferences for your own agents',
|
|
12
|
+
options: ['on', 'off'],
|
|
13
|
+
}),
|
|
14
|
+
'shared-training': core_1.Flags.string({
|
|
15
|
+
description: 'Allow permitted content-free evidence to improve shared models',
|
|
16
|
+
options: ['on', 'off'],
|
|
17
|
+
}),
|
|
18
|
+
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
19
|
+
};
|
|
20
|
+
async run() {
|
|
21
|
+
this.requireAuth();
|
|
22
|
+
const { flags } = await this.parse(LearningSet);
|
|
23
|
+
const patch = (0, adaptive_learning_1.consentPatch)({
|
|
24
|
+
personalization: flags.personalization,
|
|
25
|
+
sharedTraining: flags['shared-training'],
|
|
26
|
+
});
|
|
27
|
+
if (!Object.keys(patch).length) {
|
|
28
|
+
this.error('Set --personalization, --shared-training, or both.', { exit: 2 });
|
|
29
|
+
}
|
|
30
|
+
let result;
|
|
31
|
+
try {
|
|
32
|
+
result = await (0, api_fetch_1.apiFetch)('/api/user/adaptive-learning/preferences', {
|
|
33
|
+
method: 'PUT',
|
|
34
|
+
body: patch,
|
|
35
|
+
credential: this.resolvedCredential,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
this.handleApiError(err);
|
|
40
|
+
}
|
|
41
|
+
if (flags.json) {
|
|
42
|
+
this.log(JSON.stringify(result, null, 2));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.log(`Personalization ${result.consent.personalizationAllowed ? 'on' : 'off'}; ` +
|
|
46
|
+
`shared model training ${result.consent.sharedTrainingAllowed ? 'on' : 'off'}; ` +
|
|
47
|
+
`generation ${result.consent.stateGeneration}.`);
|
|
48
|
+
if (result.removedStates > 0)
|
|
49
|
+
this.log(`Removed ${result.removedStates} stale learned state(s).`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.default = LearningSet;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../base-command");
|
|
5
|
+
const api_fetch_1 = require("../../lib/api-fetch");
|
|
6
|
+
const adaptive_learning_1 = require("../../lib/adaptive-learning");
|
|
7
|
+
class LearningStatus extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Show adaptive-learning consent, state, and serving fallback';
|
|
9
|
+
static flags = { json: core_1.Flags.boolean({ description: 'Output JSON' }) };
|
|
10
|
+
async run() {
|
|
11
|
+
this.requireAuth();
|
|
12
|
+
const { flags } = await this.parse(LearningStatus);
|
|
13
|
+
let consent;
|
|
14
|
+
let state;
|
|
15
|
+
try {
|
|
16
|
+
[consent, state] = await Promise.all([
|
|
17
|
+
(0, api_fetch_1.apiFetch)('/api/user/adaptive-learning/preferences', {
|
|
18
|
+
credential: this.resolvedCredential,
|
|
19
|
+
}),
|
|
20
|
+
(0, api_fetch_1.apiFetch)('/api/user/adaptive-learning/state', {
|
|
21
|
+
credential: this.resolvedCredential,
|
|
22
|
+
}),
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
this.handleApiError(err);
|
|
27
|
+
}
|
|
28
|
+
if (flags.json) {
|
|
29
|
+
this.log(JSON.stringify({ consent, state }, null, 2));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
this.log((0, adaptive_learning_1.formatLearningStatus)(consent, state));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.default = LearningStatus;
|