@skrr-ai/cli 0.1.63 → 0.1.64

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.
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ /** The buyer's installed copies, including stopped copies and their source releases. */
3
+ export default class StoreInstalls extends BaseCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,54 @@
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 format_1 = require("../../lib/format");
7
+ /** The buyer's installed copies, including stopped copies and their source releases. */
8
+ class StoreInstalls extends base_command_1.BaseCommand {
9
+ static description = 'List your Store installs and the releases they came from';
10
+ static examples = [
11
+ '<%= config.bin %> store installs',
12
+ '<%= config.bin %> store installs --json',
13
+ ];
14
+ static flags = {
15
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
16
+ };
17
+ async run() {
18
+ this.requireAuth();
19
+ const { flags } = await this.parse(StoreInstalls);
20
+ let response;
21
+ try {
22
+ response = await data_provider_1.dataService.getStoreInstalls();
23
+ }
24
+ catch (error) {
25
+ this.handleApiError(error);
26
+ return;
27
+ }
28
+ const installs = response?.installs ?? [];
29
+ if (flags.json) {
30
+ this.log(JSON.stringify({ object: 'list', data: installs }, null, 2));
31
+ return;
32
+ }
33
+ if (installs.length === 0) {
34
+ this.log('No Store installs found.');
35
+ return;
36
+ }
37
+ (0, format_1.renderTable)(installs.map((install) => ({
38
+ agent: install.agentId,
39
+ copy: install.installedAgentId ?? '-',
40
+ release: install.installedReleaseId ?? '-',
41
+ version: install.installedVersionLabel ?? '-',
42
+ state: install.copyMissing ? 'copy missing' : install.stopReason ? 'stopped' : 'installed',
43
+ reason: install.stopReason ?? '-',
44
+ })), [
45
+ { key: 'agent', header: 'LISTING' },
46
+ { key: 'copy', header: 'YOUR COPY' },
47
+ { key: 'release', header: 'RELEASE' },
48
+ { key: 'version', header: 'VERSION' },
49
+ { key: 'state', header: 'STATE' },
50
+ { key: 'reason', header: 'REASON', maxWidth: 40 },
51
+ ], (line) => this.log(line));
52
+ }
53
+ }
54
+ exports.default = StoreInstalls;
@@ -37,4 +37,10 @@ export declare function decideStatusBinary(pathBinary: string, profile: string,
37
37
  /** One stderr line naming the binary that rendered status, when it is not obvious. */
38
38
  export declare function describeStatusBinary(decision: StatusBinaryDecision): string | null;
39
39
  export declare function scriptFromArgs(exec: string, args: string): string | null;
40
+ /**
41
+ * The daemon keeps its singleton holder while auth is latched, but removes the
42
+ * broker bootstrap because it cannot serve hand-offs. Status and login still
43
+ * need to address that live process during recovery (OSK-12807).
44
+ */
45
+ export declare function livePidFromLockInfo(profile: string, homeDir?: string): number | null;
40
46
  export declare function defaultLiveRuntimeDeps(): LiveRuntimeDeps;
@@ -7,6 +7,7 @@ exports.profileFromArgs = profileFromArgs;
7
7
  exports.decideStatusBinary = decideStatusBinary;
8
8
  exports.describeStatusBinary = describeStatusBinary;
9
9
  exports.scriptFromArgs = scriptFromArgs;
10
+ exports.livePidFromLockInfo = livePidFromLockInfo;
10
11
  exports.defaultLiveRuntimeDeps = defaultLiveRuntimeDeps;
11
12
  /**
12
13
  * Which runtime binary is the LIVE daemon running, and is it the one
@@ -29,6 +30,7 @@ exports.defaultLiveRuntimeDeps = defaultLiveRuntimeDeps;
29
30
  */
30
31
  const node_child_process_1 = require("node:child_process");
31
32
  const node_fs_1 = require("node:fs");
33
+ const node_os_1 = __importDefault(require("node:os"));
32
34
  const node_path_1 = __importDefault(require("node:path"));
33
35
  const daemonBroker_1 = require("./daemonBroker");
34
36
  const exec_runtime_binary_1 = require("./exec-runtime-binary");
@@ -163,6 +165,35 @@ function scriptFromArgs(exec, args) {
163
165
  }
164
166
  return null;
165
167
  }
168
+ /**
169
+ * The daemon keeps its singleton holder while auth is latched, but removes the
170
+ * broker bootstrap because it cannot serve hand-offs. Status and login still
171
+ * need to address that live process during recovery (OSK-12807).
172
+ */
173
+ function livePidFromLockInfo(profile, homeDir = node_os_1.default.homedir()) {
174
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(profile) || profile === '..')
175
+ return null;
176
+ try {
177
+ const lockInfoPath = node_path_1.default.join(homeDir, '.skrr', 'profiles', profile, 'daemon.lock.info.json');
178
+ const parsed = JSON.parse((0, node_fs_1.readFileSync)(lockInfoPath, 'utf8'));
179
+ const pid = parsed?.pid;
180
+ if (typeof pid !== 'number' || !Number.isSafeInteger(pid) || pid <= 0)
181
+ return null;
182
+ try {
183
+ process.kill(pid, 0);
184
+ }
185
+ catch (error) {
186
+ // EPERM still means a process holds the PID; all other probe failures
187
+ // leave this untrusted, potentially stale sidecar out of the decision.
188
+ if (error.code !== 'EPERM')
189
+ return null;
190
+ }
191
+ return pid;
192
+ }
193
+ catch {
194
+ return null;
195
+ }
196
+ }
166
197
  function defaultLiveRuntimeDeps() {
167
198
  return {
168
199
  livePid(profile) {
@@ -171,7 +202,7 @@ function defaultLiveRuntimeDeps() {
171
202
  if (typeof bootstrap?.pid === 'number' && bootstrap.pid > 0)
172
203
  return bootstrap.pid;
173
204
  }
174
- return null;
205
+ return livePidFromLockInfo(profile);
175
206
  },
176
207
  programOf(pid) {
177
208
  if (process.platform === 'darwin')
@@ -239,11 +239,16 @@ function createNodeAdapter(opts = {}) {
239
239
  const cred = currentCredential();
240
240
  if (cred.kind === 'ci')
241
241
  return false;
242
- // Bare-mode signal is on the resolved credential when populated by
243
- // BaseCommand. We don't have direct access here; instead we look at
244
- // the override's source — `bareMode` produces tokens sourced from
245
- // `flag` or `env-token`, both of which we already filter above. The
246
- // remaining bareMode case (no token at all) wouldn't reach this
242
+ // An operator-supplied `--token` is that operator's explicit
243
+ // authority: when the server refuses it, the honest answer is the
244
+ // 401 — not a silent retry under the daemon's principal (OSK-12801).
245
+ // `isEnvAuthOverride` above covers OVERSKY_TOKEN; the flag slot was
246
+ // missed because `kind` stays 'standard' for arbitrary flag strings.
247
+ // Broker-minted overrides carry 'env-token' too but are the daemon's
248
+ // own principal — re-recovering them preserves today's renewal path.
249
+ if (_credOverride?.source === 'flag')
250
+ return false;
251
+ // The remaining bareMode case (no token at all) wouldn't reach this
247
252
  // function — the adapter only retries on 401, which presupposes a
248
253
  // request was made with SOME bearer.
249
254
  let outcome;