@skrr-ai/cli 0.1.31 → 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.
Files changed (112) hide show
  1. package/bin/run.js +2 -2
  2. package/dist/commands/agents/list.d.ts +2 -1
  3. package/dist/commands/agents/list.js +2 -1
  4. package/dist/commands/agents/show.js +2 -1
  5. package/dist/commands/balance/statement.js +8 -4
  6. package/dist/commands/browser/install.js +6 -2
  7. package/dist/commands/browser/uninstall.js +6 -2
  8. package/dist/commands/code/acp.js +2 -1
  9. package/dist/commands/code/doctor.d.ts +1 -1
  10. package/dist/commands/code/doctor.js +6 -5
  11. package/dist/commands/code/handover.d.ts +2 -2
  12. package/dist/commands/code/handover.js +2 -2
  13. package/dist/commands/code/index.d.ts +2 -2
  14. package/dist/commands/code/index.js +18 -17
  15. package/dist/commands/code/install.d.ts +3 -3
  16. package/dist/commands/code/install.js +18 -11
  17. package/dist/commands/code/migrate.js +3 -2
  18. package/dist/commands/code/oversky-agent.d.ts +5 -4
  19. package/dist/commands/code/oversky-agent.js +24 -22
  20. package/dist/commands/code/run.js +2 -1
  21. package/dist/commands/harnesses/list.d.ts +9 -1
  22. package/dist/commands/harnesses/list.js +28 -7
  23. package/dist/commands/harnesses/show.js +7 -2
  24. package/dist/commands/instructions/install.js +16 -6
  25. package/dist/commands/learning/delete.d.ts +9 -0
  26. package/dist/commands/learning/delete.js +39 -0
  27. package/dist/commands/learning/export.d.ts +5 -0
  28. package/dist/commands/learning/export.js +22 -0
  29. package/dist/commands/learning/reset.d.ts +9 -0
  30. package/dist/commands/learning/reset.js +34 -0
  31. package/dist/commands/learning/set.d.ts +10 -0
  32. package/dist/commands/learning/set.js +52 -0
  33. package/dist/commands/learning/status.d.ts +8 -0
  34. package/dist/commands/learning/status.js +35 -0
  35. package/dist/commands/logout.js +10 -5
  36. package/dist/commands/machines/dedicated/attach.js +2 -1
  37. package/dist/commands/tasks/runs.js +3 -1
  38. package/dist/commands/workspaces/use.js +2 -1
  39. package/dist/lib/adaptive-learning.d.ts +37 -0
  40. package/dist/lib/adaptive-learning.js +39 -0
  41. package/dist/lib/code-handover.d.ts +1 -1
  42. package/dist/lib/code-handover.js +3 -2
  43. package/dist/lib/config.d.ts +30 -4
  44. package/dist/lib/config.js +2 -1
  45. package/dist/lib/daemon-installer.d.ts +1 -1
  46. package/dist/lib/daemon-target.js +2 -2
  47. package/dist/lib/dedicated-lease-command.js +2 -1
  48. package/dist/lib/dedicated-machines.d.ts +2 -2
  49. package/dist/lib/dedicated-machines.js +6 -3
  50. package/dist/lib/exec-runtime-binary.d.ts +2 -2
  51. package/dist/lib/exec-runtime-binary.js +2 -2
  52. package/dist/lib/{sky-code-agent.d.ts → first-party-harness-agent.d.ts} +20 -19
  53. package/dist/lib/{sky-code-agent.js → first-party-harness-agent.js} +85 -47
  54. package/dist/lib/{sky-code-broker.d.ts → first-party-harness-broker.d.ts} +6 -6
  55. package/dist/lib/{sky-code-broker.js → first-party-harness-broker.js} +23 -23
  56. package/dist/lib/{sky-code-doctor.d.ts → first-party-harness-doctor.d.ts} +12 -2
  57. package/dist/lib/{sky-code-doctor.js → first-party-harness-doctor.js} +181 -94
  58. package/dist/lib/{sky-code-managed.d.ts → first-party-harness-managed.d.ts} +55 -30
  59. package/dist/lib/{sky-code-managed.js → first-party-harness-managed.js} +92 -35
  60. package/dist/lib/{sky-code.d.ts → first-party-harness.d.ts} +107 -36
  61. package/dist/lib/{sky-code.js → first-party-harness.js} +172 -73
  62. package/dist/lib/harness-provider-input.d.ts +35 -0
  63. package/dist/lib/harness-provider-input.js +57 -0
  64. package/dist/lib/harness-tiers.d.ts +8 -2
  65. package/dist/lib/harness-tiers.js +11 -6
  66. package/dist/lib/task-instruction-offer.js +10 -4
  67. package/dist/lib/worklogs.js +2 -2
  68. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/configRoot.d.ts +2 -2
  69. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/configRoot.js +2 -2
  70. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.d.ts +248 -0
  71. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.js +361 -0
  72. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.d.ts +147 -0
  73. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.js +180 -0
  74. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessHome.d.ts +111 -0
  75. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessHome.js +314 -0
  76. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.d.ts +11 -5
  77. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.js +14 -7
  78. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +3 -1
  79. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +51 -14
  80. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releaseManifest.js +1 -1
  81. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +4 -4
  82. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +4 -4
  83. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/configRoot.d.ts +2 -2
  84. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/configRoot.js +2 -2
  85. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.d.ts +248 -0
  86. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.js +332 -0
  87. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.d.ts +147 -0
  88. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.js +170 -0
  89. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessHome.d.ts +111 -0
  90. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessHome.js +303 -0
  91. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.d.ts +11 -5
  92. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.js +14 -7
  93. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +3 -1
  94. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +12 -2
  95. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releaseManifest.js +1 -1
  96. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +4 -4
  97. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +4 -4
  98. package/dist/node_modules/@skrr-ai/auth-core/package.json +11 -1
  99. package/dist/node_modules/@skrr-ai/data-provider/index.js +4816 -4782
  100. package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/index.d.ts +1 -1
  101. package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/index.js +1 -1
  102. package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/managed-inference-broker.js +1 -1
  103. package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/index.d.ts +1 -1
  104. package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/index.js +1 -1
  105. package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/managed-inference-broker.js +1 -1
  106. package/dist/node_modules/@skrr-ai/inference-broker/package.json +1 -1
  107. package/oclif.manifest.json +27119 -26808
  108. package/package.json +5 -2
  109. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/skyCodeChannels.d.ts +0 -96
  110. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/skyCodeChannels.js +0 -115
  111. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/skyCodeChannels.d.ts +0 -96
  112. 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 sky_code_agent_1 = require("../../lib/sky-code-agent");
7
- const sky_code_managed_1 = require("../../lib/sky-code-managed");
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`: `sky-code agent` is its own agent-management command.
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
- * `skyCodeAgentId` predates this and had no way to be written: nothing in
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 = 'Show or set the skrr agent a managed skrr Code session is attributed to';
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 "${sky_code_managed_1.AGENT_CONFIG_KEY}" setting`,
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
- // `sky-code-broker.ts` does the same thing for the same reason before its
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, sky_code_agent_1.setConfiguredAgentId)(trimmed);
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(`skrr Code will run as ${describe(agent)}.`);
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, sky_code_agent_1.clearConfiguredAgentId)();
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 "${sky_code_managed_1.AGENT_CONFIG_KEY}" (was ${previous}).`
116
- : `No "${sky_code_managed_1.AGENT_CONFIG_KEY}" was set; nothing to clear.`);
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
- * oversky-agent` — the bare, most likely invocation, and the one a user runs to
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, sky_code_agent_1.readConfiguredAgentId)();
131
+ const stored = (0, first_party_harness_agent_1.readConfiguredAgentId)();
130
132
  let agent;
131
133
  try {
132
- agent = await (0, sky_code_agent_1.resolveSkyCodeAgent)(undefined, {}, { createDefault: allowCreate });
134
+ agent = await (0, first_party_harness_agent_1.resolveFirstPartyHarnessAgent)(undefined, {}, { createDefault: allowCreate });
133
135
  }
134
136
  catch (err) {
135
- if (json && err instanceof sky_code_agent_1.SkyCodeAgentError) {
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
- `skrr code skrr-agent --set ${agent.id}`);
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
- * `SkyCodeAgentError` messages are already written to be actionable — they name
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 sky_code_agent_1.SkyCodeAgentError) {
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 `${sky_code_managed_1.SKRR_AGENT_FLAG} on the command line`;
197
+ return `${first_party_harness_managed_1.SKRR_AGENT_FLAG} on the command line`;
196
198
  case 'config':
197
- return `"${sky_code_managed_1.AGENT_CONFIG_KEY}" in ${(0, config_1.getConfigPath)()}`;
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 'your skrr Code default, used automatically because nothing above was set';
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 = 'Run skrr Code headlessly on a single prompt';
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/sky-code) registered by
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/sky-code) registered by
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 = 'List your harnesses — your local Claude Code, Codex, skrr Code, one row per (machine, provider). The id here is what `agents attach-harness` pins. Online only unless --all.';
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: 'Filter by provider (e.g. claude, codex, opencode, openclaw).',
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 (flags.provider)
200
- params.set('provider', flags.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: flags.provider ?? null,
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 harness = response?.harness;
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
- // `sky-code` or `codex` row with how CLAUDE Code would run — a fact about a
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: ['claude', 'codex', 'sky-code'],
30
+ options: (0, harness_provider_input_1.harnessFlagOptions)(MANAGED_INSTRUCTION_PROVIDERS),
24
31
  multiple: true,
25
- default: ['claude', 'codex', 'sky-code'],
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 (flags.provider.includes('codex') && Buffer.byteLength(previewBody, 'utf8') > 30 * 1024) {
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 ${flags.provider.join(', ')} reconciliation on this target?${teamWarning}`, flags.yes);
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 flags.provider) {
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,5 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ export default class LearningExport extends BaseCommand {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
@@ -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,8 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ export default class LearningStatus extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
6
+ };
7
+ run(): Promise<void>;
8
+ }
@@ -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;