@skrr-ai/cli 0.1.113 → 0.1.114

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.
@@ -3,9 +3,11 @@
3
3
  // Park before npm executes. The parent publishes this process group's durable
4
4
  // mutation ownership before authorizing execution, closing its crash window.
5
5
  const fs = require('node:fs');
6
+ const path = require('node:path');
6
7
  const { spawn } = require('node:child_process');
7
8
  const requestFile = process.argv[2];
8
9
  const request = JSON.parse(fs.readFileSync(requestFile, 'utf8'));
10
+ if (request.npmPrefix != null && !path.isAbsolute(request.npmPrefix)) throw new Error('Invalid npm prefix');
9
11
  const deadline = Date.now() + 30000;
10
12
  const timer = setInterval(() => {
11
13
  let authorization;
@@ -16,7 +18,8 @@ const timer = setInterval(() => {
16
18
  }
17
19
  if (authorization?.pid === process.pid && authorization?.token === request.token) {
18
20
  clearInterval(timer);
19
- const child = spawn(request.npmPath, ['install', '-g', `@skrr-ai/cli@${request.version}`], {
21
+ const prefixArgs = request.npmPrefix ? ['--prefix', request.npmPrefix] : [];
22
+ const child = spawn(request.npmPath, ['install', '-g', ...prefixArgs, `@skrr-ai/cli@${request.version}`], {
20
23
  stdio: 'inherit',
21
24
  shell: process.platform === 'win32',
22
25
  });
@@ -41,7 +41,8 @@ async function run(directory, options = {}) {
41
41
  if (
42
42
  !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(attempt.version) ||
43
43
  !path.isAbsolute(attempt.packageRoot) ||
44
- !path.isAbsolute(attempt.npmPath)
44
+ !path.isAbsolute(attempt.npmPath) ||
45
+ (attempt.npmPrefix != null && !path.isAbsolute(attempt.npmPrefix))
45
46
  ) {
46
47
  throw new Error('Invalid persisted CLI update request');
47
48
  }
@@ -86,7 +87,8 @@ async function run(directory, options = {}) {
86
87
  });
87
88
  return;
88
89
  }
89
- const rootResult = await execFileAsync(attempt.npmPath, ['root', '-g'], {
90
+ const prefixArgs = attempt.npmPrefix ? ['--prefix', attempt.npmPrefix] : [];
91
+ const rootResult = await execFileAsync(attempt.npmPath, ['root', '-g', ...prefixArgs], {
90
92
  timeout: 1500,
91
93
  maxBuffer: 64 * 1024,
92
94
  shell: process.platform === 'win32',
@@ -117,7 +119,8 @@ async function run(directory, options = {}) {
117
119
  await new Promise((resolve, reject) => {
118
120
  const requestFile = path.join(directory, `runner-${crypto.randomUUID()}.json`);
119
121
  const token = crypto.randomUUID();
120
- runtime.writeJson(requestFile, { token, npmPath: attempt.npmPath, version: attempt.version });
122
+ runtime.writeJson(requestFile, { token, npmPath: attempt.npmPath, version: attempt.version,
123
+ ...(attempt.npmPrefix ? { npmPrefix: attempt.npmPrefix } : {}) });
121
124
  const child = spawn(
122
125
  process.execPath,
123
126
  [path.join(__dirname, 'update-npm-runner.cjs'), requestFile],
@@ -12,7 +12,7 @@ const agent_resolver_1 = require("../../lib/agent-resolver");
12
12
  * needs an agent context the passive form does not.
13
13
  */
14
14
  class FollowupsRemind extends base_command_1.BaseCommand {
15
- static description = 'Remind the owner at a time — the reminder follow-up';
15
+ static description = 'Remind the owner at a time. By default, deliver the literal content through owner notifications without an agent turn. Use --active for agent-written delivery.';
16
16
  static examples = [
17
17
  '<%= config.bin %> followups remind --subject task:OSK-42 --content "pick the deploy up" --in 2h',
18
18
  '<%= config.bin %> followups remind --subject conversation:conv_9 --content "ask how the move went" --at 2026-09-20T09:00:00Z --active --agent agent_1',
@@ -34,15 +34,23 @@ class FollowupsRemind extends base_command_1.BaseCommand {
34
34
  description: 'Wake the agent to word the reminder (needs an agent context)',
35
35
  default: false,
36
36
  }),
37
- agent: core_1.Flags.string({ description: 'Agent ID (default: bound session agent)' }),
38
- endpoint: core_1.Flags.string({ description: 'Delivery endpoint id (EndpointRegistry)' }),
39
- 'endpoint-target': core_1.Flags.string({ description: 'Channel target for channel endpoints' }),
40
- pin: core_1.Flags.string({ description: 'Conversation id the reminder was authored in' }),
37
+ agent: core_1.Flags.string({ description: 'Agent ID (default: bound session agent). Attribution only unless --active is set' }),
38
+ endpoint: core_1.Flags.string({ description: 'Active only: delivery endpoint id; requires --active' }),
39
+ 'endpoint-target': core_1.Flags.string({ description: 'Active only: channel target for a channel endpoint; requires --active' }),
40
+ pin: core_1.Flags.string({ description: 'Active only: deliver into this conversation; requires --active. Do not combine with --endpoint other than pinned' }),
41
41
  json: core_1.Flags.boolean({ description: 'Output as JSON' }),
42
42
  };
43
43
  async run() {
44
44
  this.requireAuth();
45
45
  const { flags } = await this.parse(FollowupsRemind);
46
+ if (!flags.active && (flags.endpoint || flags['endpoint-target'] || flags.pin)) {
47
+ this.failWithCliError({
48
+ message: '--endpoint, --endpoint-target and --pin require --active. For a passive reminder, remove these flags; the literal content is delivered through owner notifications without an agent turn. --agent alone records attribution.',
49
+ code: 'FOLLOWUP_INVALID_ENDPOINT',
50
+ exit: 2,
51
+ retryable: false,
52
+ });
53
+ }
46
54
  const at = flags.at ?? flags.in;
47
55
  if (!at) {
48
56
  this.failWithCliError({
@@ -83,9 +83,9 @@ class FollowupsWatch extends base_command_1.BaseCommand {
83
83
  description: 'SLA backstop — required for --wait event (an event may never arrive), optional for poll_until',
84
84
  }),
85
85
  // delivery
86
- endpoint: core_1.Flags.string({ description: 'Delivery endpoint id (EndpointRegistry)' }),
86
+ endpoint: core_1.Flags.string({ description: 'Delivery endpoint id (defaults to main). Use --pin to deliver into a specific conversation' }),
87
87
  'endpoint-target': core_1.Flags.string({ description: 'Channel target for channel endpoints' }),
88
- pin: core_1.Flags.string({ description: 'Conversation id the watch was authored in' }),
88
+ pin: core_1.Flags.string({ description: 'Deliver into this conversation. Do not combine with --endpoint other than pinned' }),
89
89
  json: core_1.Flags.boolean({ description: 'Output as JSON' }),
90
90
  };
91
91
  async run() {
@@ -1,4 +1,9 @@
1
1
  export type CliInstallKind = 'npm-global' | 'npm-local' | 'dev' | 'bundled' | 'image' | 'homebrew' | 'other';
2
+ export interface CliInstallDescriptor {
3
+ kind: CliInstallKind;
4
+ writable?: boolean;
5
+ npmPrefix?: string;
6
+ }
2
7
  export interface CliUpdateAttempt {
3
8
  status: 'queued' | 'running' | 'succeeded' | 'failed';
4
9
  version: string;
@@ -10,6 +15,7 @@ export interface CliUpdateAttempt {
10
15
  message?: string;
11
16
  packageRoot?: string;
12
17
  npmPath?: string;
18
+ npmPrefix?: string;
13
19
  coordinationVersion?: number;
14
20
  workerPid?: number;
15
21
  interrupted?: boolean;
@@ -19,10 +25,7 @@ export interface CheckCache {
19
25
  latest: string | null;
20
26
  npmPackage: string | null;
21
27
  baseURL: string;
22
- install?: {
23
- kind: CliInstallKind;
24
- writable?: boolean;
25
- };
28
+ install?: CliInstallDescriptor;
26
29
  packageRoot?: string;
27
30
  npmGlobalRoot?: string | null;
28
31
  autoUpdate?: {
@@ -45,6 +48,7 @@ export interface CliUpdateStatus {
45
48
  installedVersion: string | null;
46
49
  offeredVersion: string | null;
47
50
  owner: CliInstallKind;
51
+ npmPrefix?: string;
48
52
  state: 'up-to-date' | 'update-available' | 'pending' | 'restart-pending' | 'failed' | 'managed' | 'unknown' | 'check-failed';
49
53
  autoUpdateAllowed: boolean;
50
54
  autoUpdateReason: string | null;
@@ -76,12 +80,9 @@ export declare function resolveCliPackageDir(argv?: readonly string[]): string |
76
80
  * dir beside `dist` exists only in a checkout — published packages ship
77
81
  * `dist` and no `src`.
78
82
  */
79
- export declare function classifyCliInstall(env: NodeJS.ProcessEnv, argv: readonly string[], npmGlobalRoot: string | null, probeWritable?: boolean): {
80
- kind: CliInstallKind;
81
- writable?: boolean;
82
- };
83
- export declare function cliUpdateCommand(owner: CliInstallKind): string;
84
- export declare function buildNudgeLine(currentVersion: string, latest: string | null, _npmPackage: string | null, installKind?: CliInstallKind): string | null;
83
+ export declare function classifyCliInstall(env: NodeJS.ProcessEnv, argv: readonly string[], npmGlobalRoot: string | null, probeWritable?: boolean): CliInstallDescriptor;
84
+ export declare function cliUpdateCommand(owner: CliInstallKind, npmPrefix?: string): string;
85
+ export declare function buildNudgeLine(currentVersion: string, latest: string | null, _npmPackage: string | null, installKind?: CliInstallKind, npmPrefix?: string): string | null;
85
86
  export type CliUpdateAction = {
86
87
  type: 'nudge';
87
88
  line: string;
@@ -207,6 +207,20 @@ function classifyCliInstall(env, argv, npmGlobalRoot, probeWritable = true) {
207
207
  return { kind: 'other' };
208
208
  }
209
209
  const nodeModulesDir = path.dirname(path.dirname(packageDir)); // …/node_modules
210
+ const npmPrefix = process.platform !== 'win32' && path.basename(path.dirname(nodeModulesDir)) === 'lib'
211
+ ? path.dirname(path.dirname(nodeModulesDir)) : undefined;
212
+ // npm's current default may differ from the prefix that installed this
213
+ // executable. A project directory named `lib` is insufficient evidence:
214
+ // the prefix's public bin must resolve to this exact installed entry.
215
+ let linkedGlobalPrefix = false;
216
+ if (npmPrefix) {
217
+ try {
218
+ linkedGlobalPrefix = !fs.existsSync(path.join(npmPrefix, 'package.json')) &&
219
+ fs.realpathSync(path.join(npmPrefix, 'bin', 'skrr')) ===
220
+ fs.realpathSync(path.join(packageDir, 'bin', 'run.js'));
221
+ }
222
+ catch { /* no executable ownership proof */ }
223
+ }
210
224
  if (npmGlobalRoot) {
211
225
  let resolvedGlobal = npmGlobalRoot;
212
226
  try {
@@ -222,15 +236,13 @@ function classifyCliInstall(env, argv, npmGlobalRoot, probeWritable = true) {
222
236
  catch {
223
237
  /* compare the raw form */
224
238
  }
225
- if (resolvedNodeModules !== resolvedGlobal)
239
+ if (resolvedNodeModules !== resolvedGlobal && !linkedGlobalPrefix)
226
240
  return { kind: 'npm-local' };
227
241
  }
228
- else if (!/[/\\](lib|npm)[/\\]node_modules$/.test(nodeModulesDir)) {
242
+ else if (!linkedGlobalPrefix) {
229
243
  // `npm root -g` gave no answer, so prove the global shape from the path
230
- // instead: npm's unix global root is always `<prefix>/lib/node_modules`
231
- // (incl. nvm/volta) and on Windows `%APPDATA%\npm\node_modules`. A
232
- // project-local `<project>/node_modules` never matches either — without
233
- // proof we must not treat it as ours to auto-update.
244
+ // and matching public executable instead. Without ownership proof we
245
+ // must not treat a project's dependency as ours to auto-update.
234
246
  return { kind: 'npm-local' };
235
247
  }
236
248
  let writable = false;
@@ -245,7 +257,7 @@ function classifyCliInstall(env, argv, npmGlobalRoot, probeWritable = true) {
245
257
  /* read-only */
246
258
  }
247
259
  }
248
- return { kind: 'npm-global', writable };
260
+ return { kind: 'npm-global', writable, ...(npmPrefix ? { npmPrefix } : {}) };
249
261
  }
250
262
  /**
251
263
  * Resolve `npm root -g` for install classification. Runs ONLY inside the
@@ -269,12 +281,14 @@ async function resolveNpmGlobalRoot(env = process.env) {
269
281
  return null;
270
282
  }
271
283
  }
272
- function cliUpdateCommand(owner) {
284
+ function cliUpdateCommand(owner, npmPrefix) {
273
285
  switch (owner) {
274
286
  case 'npm-global':
275
- return `npm install -g ${CLI_PACKAGE}@latest`;
287
+ return npmPrefix
288
+ ? `npm install --global --prefix '${npmPrefix.replace(/'/g, "'\\''")}' ${CLI_PACKAGE}@latest`
289
+ : `npm install -g ${CLI_PACKAGE}@latest`;
276
290
  case 'npm-local':
277
- return `npm update ${CLI_PACKAGE}`;
291
+ return `Use npm in the project that owns ${CLI_PACKAGE}`;
278
292
  case 'dev':
279
293
  return 'npm --prefix cli run build';
280
294
  case 'bundled':
@@ -287,16 +301,18 @@ function cliUpdateCommand(owner) {
287
301
  return 'Update via your install method — see https://skrr.ai';
288
302
  }
289
303
  }
290
- function buildNudgeLine(currentVersion, latest, _npmPackage, installKind = 'npm-global') {
304
+ function buildNudgeLine(currentVersion, latest, _npmPackage, installKind = 'npm-global', npmPrefix) {
291
305
  if (!latest || !isOlderVersion(currentVersion, latest))
292
306
  return null;
293
- const command = installKind === 'npm-global' ? `npm update -g ${CLI_PACKAGE}` : cliUpdateCommand(installKind);
294
- const context = installKind === 'npm-local'
295
- ? ' in the owning project'
296
- : installKind === 'dev'
297
- ? ' to rebuild your checkout'
298
- : '';
299
- return `[skrr] Update available: ${currentVersion} → ${latest}. Run \`${command}\`${context}. Silence with OVERSKY_NO_UPDATE_NUDGE=1.\n`;
307
+ const command = installKind === 'npm-global' && !npmPrefix
308
+ ? `npm update -g ${CLI_PACKAGE}` : cliUpdateCommand(installKind, npmPrefix);
309
+ const context = installKind === 'dev'
310
+ ? ' to rebuild your checkout'
311
+ : '';
312
+ const advice = installKind === 'npm-local'
313
+ ? `Update ${CLI_PACKAGE} using the project that owns ${CLI_PACKAGE}.`
314
+ : `Run \`${command}\`${context}.`;
315
+ return `[skrr] Update available: ${currentVersion} → ${latest}. ${advice} Silence with OVERSKY_NO_UPDATE_NUDGE=1.\n`;
300
316
  }
301
317
  function decideCliUpdateAction(args) {
302
318
  const { currentVersion, cache, env, isTTY } = args;
@@ -327,10 +343,10 @@ function decideCliUpdateAction(args) {
327
343
  if (attempt?.status === 'failed')
328
344
  return {
329
345
  type: 'nudge',
330
- line: `[skrr] CLI update to ${cache.latest} failed. Inspect \`skrr update --status\` or run \`${cliUpdateCommand(install.kind)}\`.\n`,
346
+ line: `[skrr] CLI update to ${cache.latest} failed. Inspect \`skrr update --status\` or run \`${cliUpdateCommand(install.kind, install.npmPrefix)}\`.\n`,
331
347
  };
332
348
  }
333
- const line = buildNudgeLine(currentVersion, cache.latest, CLI_PACKAGE, install.kind);
349
+ const line = buildNudgeLine(currentVersion, cache.latest, CLI_PACKAGE, install.kind, install.npmPrefix);
334
350
  return line ? { type: 'nudge', line } : null;
335
351
  }
336
352
  function readCache(env = process.env) {
@@ -462,10 +478,11 @@ function readCliUpdateStatus(opts) {
462
478
  installedVersion,
463
479
  offeredVersion,
464
480
  owner: install.kind,
481
+ ...(install.npmPrefix ? { npmPrefix: install.npmPrefix } : {}),
465
482
  state,
466
483
  autoUpdateAllowed: autoUpdateReason === null,
467
484
  autoUpdateReason,
468
- command: cliUpdateCommand(install.kind),
485
+ command: cliUpdateCommand(install.kind, install.npmPrefix),
469
486
  lastCheckAt: matchingCache?.lastCheckAt ?? null,
470
487
  lastAttempt,
471
488
  logPath: path.join(directory, 'update.log'),
@@ -591,7 +608,7 @@ async function performCliUpdate(opts) {
591
608
  env.SKRR_CLI_UPDATE_SESSION_UNAVAILABLE === '1') {
592
609
  return {
593
610
  ...status,
594
- message: `This CLI is owned by ${install.kind}${install.kind === 'npm-global' ? ' in a shared or external prefix' : ''}. ${cliUpdateCommand(install.kind)}.`,
611
+ message: `This CLI is owned by ${install.kind}${install.kind === 'npm-global' ? ' in a shared or external prefix' : ''}. ${cliUpdateCommand(install.kind, install.npmPrefix)}.`,
595
612
  };
596
613
  }
597
614
  const recoverableAttempt = status.lastAttempt && ['queued', 'running'].includes(status.lastAttempt.status);
@@ -620,6 +637,7 @@ async function performCliUpdate(opts) {
620
637
  attemptedAt: Date.now(),
621
638
  packageRoot: packageRoot(argv),
622
639
  npmPath,
640
+ ...(install.npmPrefix ? { npmPrefix: install.npmPrefix } : {}),
623
641
  coordinationVersion: api.COORDINATION_VERSION,
624
642
  message: 'Waiting for active CLI sessions to exit; the next invocation uses the new version.',
625
643
  });
@@ -649,7 +667,7 @@ async function maybeWarnOutdatedCli(opts) {
649
667
  currentVersion: opts.currentVersion,
650
668
  cache: {
651
669
  ...cache,
652
- install: { kind: status.owner, writable: status.autoUpdateAllowed },
670
+ install: { kind: status.owner, writable: status.autoUpdateAllowed, npmPrefix: status.npmPrefix },
653
671
  autoUpdate: status.lastAttempt
654
672
  ? {
655
673
  attemptedAt: status.lastAttempt.attemptedAt,
@@ -2,7 +2,7 @@
2
2
  * The first-party harness identity — the ONLY place its product name is written.
3
3
  *
4
4
  * "First-party harness" is the harness provider this platform builds, signs,
5
- * distributes and installs itself: today a fork of OpenCode sold as skrr Code.
5
+ * distributes and installs itself: today a fork of OpenCode sold as Skrr Code.
6
6
  * It is a different axis from trust Tier 1 in `harnessTrust.ts`, whose
7
7
  * "first-party" means an audited VENDOR harness such as Claude Code.
8
8
  *
@@ -68,7 +68,7 @@
68
68
  * both bundles at a distance.
69
69
  */
70
70
  export interface FirstPartyHarnessIdentity {
71
- /** What a person reads. Lowercase brand inside a compound (naming map §1). */
71
+ /** What a person reads, with the product's proper-name capitalization. */
72
72
  readonly displayName: string;
73
73
  /** The command a person types, as it appears in prose. */
74
74
  readonly command: string;
@@ -93,7 +93,7 @@ export interface FirstPartyHarnessIdentity {
93
93
  * release or a stored value written before the rename is looked for.
94
94
  */
95
95
  declare const IDENTITY: {
96
- readonly displayName: "skrr Code";
96
+ readonly displayName: "Skrr Code";
97
97
  readonly command: "skrr code";
98
98
  readonly provider: "skrr-code";
99
99
  readonly aliases: readonly [];
@@ -3,7 +3,7 @@
3
3
  * The first-party harness identity — the ONLY place its product name is written.
4
4
  *
5
5
  * "First-party harness" is the harness provider this platform builds, signs,
6
- * distributes and installs itself: today a fork of OpenCode sold as skrr Code.
6
+ * distributes and installs itself: today a fork of OpenCode sold as Skrr Code.
7
7
  * It is a different axis from trust Tier 1 in `harnessTrust.ts`, whose
8
8
  * "first-party" means an audited VENDOR harness such as Claude Code.
9
9
  *
@@ -138,7 +138,7 @@ const PROVIDER = 'skrr-code';
138
138
  * release or a stored value written before the rename is looked for.
139
139
  */
140
140
  const IDENTITY = {
141
- displayName: 'skrr Code',
141
+ displayName: 'Skrr Code',
142
142
  command: 'skrr code',
143
143
  provider: PROVIDER,
144
144
  aliases: [],
@@ -2,7 +2,7 @@
2
2
  * The first-party harness identity — the ONLY place its product name is written.
3
3
  *
4
4
  * "First-party harness" is the harness provider this platform builds, signs,
5
- * distributes and installs itself: today a fork of OpenCode sold as skrr Code.
5
+ * distributes and installs itself: today a fork of OpenCode sold as Skrr Code.
6
6
  * It is a different axis from trust Tier 1 in `harnessTrust.ts`, whose
7
7
  * "first-party" means an audited VENDOR harness such as Claude Code.
8
8
  *
@@ -68,7 +68,7 @@
68
68
  * both bundles at a distance.
69
69
  */
70
70
  export interface FirstPartyHarnessIdentity {
71
- /** What a person reads. Lowercase brand inside a compound (naming map §1). */
71
+ /** What a person reads, with the product's proper-name capitalization. */
72
72
  readonly displayName: string;
73
73
  /** The command a person types, as it appears in prose. */
74
74
  readonly command: string;
@@ -93,7 +93,7 @@ export interface FirstPartyHarnessIdentity {
93
93
  * release or a stored value written before the rename is looked for.
94
94
  */
95
95
  declare const IDENTITY: {
96
- readonly displayName: "skrr Code";
96
+ readonly displayName: "Skrr Code";
97
97
  readonly command: "skrr code";
98
98
  readonly provider: "skrr-code";
99
99
  readonly aliases: readonly [];
@@ -2,7 +2,7 @@
2
2
  * The first-party harness identity — the ONLY place its product name is written.
3
3
  *
4
4
  * "First-party harness" is the harness provider this platform builds, signs,
5
- * distributes and installs itself: today a fork of OpenCode sold as skrr Code.
5
+ * distributes and installs itself: today a fork of OpenCode sold as Skrr Code.
6
6
  * It is a different axis from trust Tier 1 in `harnessTrust.ts`, whose
7
7
  * "first-party" means an audited VENDOR harness such as Claude Code.
8
8
  *
@@ -103,7 +103,7 @@ const PROVIDER = 'skrr-code';
103
103
  * release or a stored value written before the rename is looked for.
104
104
  */
105
105
  const IDENTITY = {
106
- displayName: 'skrr Code',
106
+ displayName: 'Skrr Code',
107
107
  command: 'skrr code',
108
108
  provider: PROVIDER,
109
109
  aliases: [],
@@ -23343,7 +23343,7 @@
23343
23343
  "aliases": [],
23344
23344
  "args": {
23345
23345
  "state": {
23346
- "description": "Whether personal stored balance may pay for skrr Code overage",
23346
+ "description": "Whether personal stored balance may pay for Skrr Code overage",
23347
23347
  "name": "state",
23348
23348
  "options": [
23349
23349
  "enabled",
@@ -23352,7 +23352,7 @@
23352
23352
  "required": true
23353
23353
  }
23354
23354
  },
23355
- "description": "Enable or disable personal skrr Code overage after included allowance is exhausted",
23355
+ "description": "Enable or disable personal Skrr Code overage after included allowance is exhausted",
23356
23356
  "examples": [
23357
23357
  "<%= config.bin %> balance overage enabled",
23358
23358
  "<%= config.bin %> balance overage disabled",
@@ -23420,7 +23420,7 @@
23420
23420
  "balance:plan": {
23421
23421
  "aliases": [],
23422
23422
  "args": {},
23423
- "description": "Show your skrr Code plan, renewal state, available tiers, and the matching lifecycle page",
23423
+ "description": "Show your Skrr Code plan, renewal state, available tiers, and the matching lifecycle page",
23424
23424
  "examples": [
23425
23425
  "<%= config.bin %> balance plan",
23426
23426
  "<%= config.bin %> balance plan --json"
@@ -23720,7 +23720,7 @@
23720
23720
  "balance:usage:breakdown": {
23721
23721
  "aliases": [],
23722
23722
  "args": {},
23723
- "description": "Aggregate settled skrr Code usage by model, surface, agent and member",
23723
+ "description": "Aggregate settled Skrr Code usage by model, surface, agent and member",
23724
23724
  "examples": [
23725
23725
  "<%= config.bin %> balance usage breakdown",
23726
23726
  "<%= config.bin %> balance usage breakdown --json",
@@ -23812,7 +23812,7 @@
23812
23812
  "balance:usage:events": {
23813
23813
  "aliases": [],
23814
23814
  "args": {},
23815
- "description": "List the skrr Code charges and run/session attribution behind aggregate allowance usage",
23815
+ "description": "List the Skrr Code charges and run/session attribution behind aggregate allowance usage",
23816
23816
  "examples": [
23817
23817
  "<%= config.bin %> balance usage events",
23818
23818
  "<%= config.bin %> balance usage events --limit 20 --json",
@@ -26995,7 +26995,7 @@
26995
26995
  "pluginName": "@skrr-ai/cli",
26996
26996
  "pluginType": "core",
26997
26997
  "strict": false,
26998
- "summary": "Start the skrr Code interactive coding agent in this directory",
26998
+ "summary": "Start the Skrr Code interactive coding agent in this directory",
26999
26999
  "enableJsonFlag": false,
27000
27000
  "isESM": false,
27001
27001
  "relativePath": [
@@ -27008,7 +27008,7 @@
27008
27008
  "code:acp": {
27009
27009
  "aliases": [],
27010
27010
  "args": {},
27011
- "description": "Run the skrr Code ACP server over stdio (used by the skrr daemon)",
27011
+ "description": "Run the Skrr Code ACP server over stdio (used by the skrr daemon)",
27012
27012
  "examples": [
27013
27013
  "<%= config.bin %> code acp"
27014
27014
  ],
@@ -27032,7 +27032,7 @@
27032
27032
  "code:doctor": {
27033
27033
  "aliases": [],
27034
27034
  "args": {},
27035
- "description": "Diagnose the local skrr Code engine, config sources, and trust posture",
27035
+ "description": "Diagnose the local Skrr Code engine, config sources, and trust posture",
27036
27036
  "examples": [
27037
27037
  "<%= config.bin %> code doctor",
27038
27038
  "<%= config.bin %> code doctor --json"
@@ -27194,7 +27194,7 @@
27194
27194
  "code:install": {
27195
27195
  "aliases": [],
27196
27196
  "args": {},
27197
- "description": "Install the local skrr Code signed release; use --daemon to install on another machine",
27197
+ "description": "Install the local Skrr Code signed release; use --daemon to install on another machine",
27198
27198
  "examples": [
27199
27199
  "<%= config.bin %> code install",
27200
27200
  "<%= config.bin %> code install --daemon <daemon-id>",
@@ -27743,7 +27743,7 @@
27743
27743
  ]
27744
27744
  }
27745
27745
  },
27746
- "description": "Migrate an existing OpenCode configuration into skrr Code",
27746
+ "description": "Migrate an existing OpenCode configuration into Skrr Code",
27747
27747
  "examples": [
27748
27748
  "<%= config.bin %> code migrate opencode",
27749
27749
  "<%= config.bin %> code migrate opencode --apply",
@@ -27760,7 +27760,7 @@
27760
27760
  "dependsOn": [
27761
27761
  "apply"
27762
27762
  ],
27763
- "description": "Replace existing skrr Code files, moving each aside to a timestamped .bak first",
27763
+ "description": "Replace existing Skrr Code files, moving each aside to a timestamped .bak first",
27764
27764
  "name": "overwrite",
27765
27765
  "allowNo": false,
27766
27766
  "type": "boolean"
@@ -27798,7 +27798,7 @@
27798
27798
  "code:rollback": {
27799
27799
  "aliases": [],
27800
27800
  "args": {},
27801
- "description": "Restore the previous verified local skrr Code release",
27801
+ "description": "Restore the previous verified local Skrr Code release",
27802
27802
  "flags": {
27803
27803
  "json": {
27804
27804
  "description": "Emit the result as JSON",
@@ -27826,7 +27826,7 @@
27826
27826
  "code:run": {
27827
27827
  "aliases": [],
27828
27828
  "args": {},
27829
- "description": "Run skrr Code headlessly on a single prompt",
27829
+ "description": "Run Skrr Code headlessly on a single prompt",
27830
27830
  "examples": [
27831
27831
  "<%= config.bin %> code run \"add a regression test for the parser\"",
27832
27832
  "<%= config.bin %> code run --json \"summarize the diff\"",
@@ -27853,7 +27853,7 @@
27853
27853
  "code:skrr-agent": {
27854
27854
  "aliases": [],
27855
27855
  "args": {},
27856
- "description": "Show or set the skrr agent a managed skrr Code session is attributed to",
27856
+ "description": "Show or set the skrr agent a managed Skrr Code session is attributed to",
27857
27857
  "examples": [
27858
27858
  "<%= config.bin %> code skrr-agent",
27859
27859
  "<%= config.bin %> code skrr-agent --set Engineer",
@@ -27931,7 +27931,7 @@
27931
27931
  "code:update": {
27932
27932
  "aliases": [],
27933
27933
  "args": {},
27934
- "description": "Check or update the local skrr Code signed release; use --daemon to update another machine",
27934
+ "description": "Check or update the local Skrr Code signed release; use --daemon to update another machine",
27935
27935
  "examples": [
27936
27936
  "<%= config.bin %> code update",
27937
27937
  "<%= config.bin %> code update --check",
@@ -46066,7 +46066,7 @@
46066
46066
  "followups:remind": {
46067
46067
  "aliases": [],
46068
46068
  "args": {},
46069
- "description": "Remind the owner at a time — the reminder follow-up",
46069
+ "description": "Remind the owner at a time. By default, deliver the literal content through owner notifications without an agent turn. Use --active for agent-written delivery.",
46070
46070
  "examples": [
46071
46071
  "<%= config.bin %> followups remind --subject task:OSK-42 --content \"pick the deploy up\" --in 2h",
46072
46072
  "<%= config.bin %> followups remind --subject conversation:conv_9 --content \"ask how the move went\" --at 2026-09-20T09:00:00Z --active --agent agent_1",
@@ -46156,28 +46156,28 @@
46156
46156
  "type": "boolean"
46157
46157
  },
46158
46158
  "agent": {
46159
- "description": "Agent ID (default: bound session agent)",
46159
+ "description": "Agent ID (default: bound session agent). Attribution only unless --active is set",
46160
46160
  "name": "agent",
46161
46161
  "hasDynamicHelp": false,
46162
46162
  "multiple": false,
46163
46163
  "type": "option"
46164
46164
  },
46165
46165
  "endpoint": {
46166
- "description": "Delivery endpoint id (EndpointRegistry)",
46166
+ "description": "Active only: delivery endpoint id; requires --active",
46167
46167
  "name": "endpoint",
46168
46168
  "hasDynamicHelp": false,
46169
46169
  "multiple": false,
46170
46170
  "type": "option"
46171
46171
  },
46172
46172
  "endpoint-target": {
46173
- "description": "Channel target for channel endpoints",
46173
+ "description": "Active only: channel target for a channel endpoint; requires --active",
46174
46174
  "name": "endpoint-target",
46175
46175
  "hasDynamicHelp": false,
46176
46176
  "multiple": false,
46177
46177
  "type": "option"
46178
46178
  },
46179
46179
  "pin": {
46180
- "description": "Conversation id the reminder was authored in",
46180
+ "description": "Active only: deliver into this conversation; requires --active. Do not combine with --endpoint other than pinned",
46181
46181
  "name": "pin",
46182
46182
  "hasDynamicHelp": false,
46183
46183
  "multiple": false,
@@ -46687,7 +46687,7 @@
46687
46687
  "type": "option"
46688
46688
  },
46689
46689
  "endpoint": {
46690
- "description": "Delivery endpoint id (EndpointRegistry)",
46690
+ "description": "Delivery endpoint id (defaults to main). Use --pin to deliver into a specific conversation",
46691
46691
  "name": "endpoint",
46692
46692
  "hasDynamicHelp": false,
46693
46693
  "multiple": false,
@@ -46701,7 +46701,7 @@
46701
46701
  "type": "option"
46702
46702
  },
46703
46703
  "pin": {
46704
- "description": "Conversation id the watch was authored in",
46704
+ "description": "Deliver into this conversation. Do not combine with --endpoint other than pinned",
46705
46705
  "name": "pin",
46706
46706
  "hasDynamicHelp": false,
46707
46707
  "multiple": false,
@@ -137226,5 +137226,5 @@
137226
137226
  ]
137227
137227
  }
137228
137228
  },
137229
- "version": "0.1.113"
137229
+ "version": "0.1.114"
137230
137230
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skrr-ai/cli",
3
- "version": "0.1.113",
3
+ "version": "0.1.114",
4
4
  "description": "Command-line interface for skrr",
5
5
  "license": "ISC",
6
6
  "author": "skrr",