@skrr-ai/cli 0.1.80 → 0.1.81

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 (80) hide show
  1. package/dist/base-command.d.ts +4 -0
  2. package/dist/base-command.js +31 -2
  3. package/dist/commands/agents/visibility.d.ts +14 -0
  4. package/dist/commands/agents/visibility.js +52 -0
  5. package/dist/commands/create-token.d.ts +0 -1
  6. package/dist/commands/create-token.js +3 -1
  7. package/dist/commands/list-tokens.d.ts +0 -1
  8. package/dist/commands/list-tokens.js +1 -1
  9. package/dist/commands/machines/dedicated/ssh-proxy.js +1 -0
  10. package/dist/commands/revoke-token.d.ts +0 -1
  11. package/dist/commands/revoke-token.js +1 -1
  12. package/dist/commands/store/follow.d.ts +1 -0
  13. package/dist/commands/store/follow.js +7 -1
  14. package/dist/commands/store/follows/list.d.ts +11 -0
  15. package/dist/commands/store/follows/list.js +29 -0
  16. package/dist/commands/store/follows/remove.d.ts +16 -0
  17. package/dist/commands/store/follows/remove.js +37 -0
  18. package/dist/commands/store/publishers/profile/draft.d.ts +17 -0
  19. package/dist/commands/store/publishers/profile/draft.js +54 -0
  20. package/dist/commands/store/publishers/profile/handle.d.ts +14 -0
  21. package/dist/commands/store/publishers/profile/handle.js +39 -0
  22. package/dist/commands/store/publishers/profile/hide.d.ts +12 -0
  23. package/dist/commands/store/publishers/profile/hide.js +39 -0
  24. package/dist/commands/store/publishers/profile/preview.d.ts +11 -0
  25. package/dist/commands/store/publishers/profile/preview.js +39 -0
  26. package/dist/commands/store/publishers/profile/publish.d.ts +12 -0
  27. package/dist/commands/store/publishers/profile/publish.js +41 -0
  28. package/dist/commands/store/publishers/profile/restore.d.ts +15 -0
  29. package/dist/commands/store/publishers/profile/restore.js +49 -0
  30. package/dist/commands/store/publishers/profile/revisions.d.ts +11 -0
  31. package/dist/commands/store/publishers/profile/revisions.js +30 -0
  32. package/dist/commands/store/publishers/profile/show.d.ts +11 -0
  33. package/dist/commands/store/publishers/profile/show.js +39 -0
  34. package/dist/commands/store/review.d.ts +26 -0
  35. package/dist/commands/store/review.js +93 -0
  36. package/dist/commands/store/reviews.d.ts +29 -0
  37. package/dist/commands/store/reviews.js +170 -0
  38. package/dist/commands/store/tip.d.ts +20 -0
  39. package/dist/commands/store/tip.js +57 -0
  40. package/dist/commands/tokens/create.d.ts +28 -0
  41. package/dist/commands/tokens/create.js +136 -0
  42. package/dist/commands/tokens/list.d.ts +11 -0
  43. package/dist/commands/tokens/list.js +53 -0
  44. package/dist/commands/tokens/revoke.d.ts +14 -0
  45. package/dist/commands/tokens/revoke.js +42 -0
  46. package/dist/lib/access-tokens.d.ts +59 -0
  47. package/dist/lib/access-tokens.js +50 -0
  48. package/dist/lib/auth-core-init.d.ts +6 -0
  49. package/dist/lib/auth-core-init.js +28 -6
  50. package/dist/lib/credential-resolver.d.ts +1 -1
  51. package/dist/lib/credential-resolver.js +8 -2
  52. package/dist/lib/daemonBroker.d.ts +13 -2
  53. package/dist/lib/daemonBroker.js +6 -4
  54. package/dist/lib/dedicated-ssh.d.ts +9 -0
  55. package/dist/lib/dedicated-ssh.js +232 -63
  56. package/dist/lib/node-adapter.js +2 -2
  57. package/dist/lib/publisher-profile-flags.d.ts +19 -0
  58. package/dist/lib/publisher-profile-flags.js +48 -0
  59. package/dist/lib/refresh.d.ts +1 -1
  60. package/dist/lib/refresh.js +6 -1
  61. package/dist/lib/ssh-ordered-bytes.d.ts +8 -0
  62. package/dist/lib/ssh-ordered-bytes.js +31 -0
  63. package/dist/lib/usd-micros.d.ts +9 -0
  64. package/dist/lib/usd-micros.js +21 -0
  65. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialResolver.d.ts +22 -3
  66. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialResolver.js +29 -5
  67. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.d.ts +7 -1
  68. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.js +7 -1
  69. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -1
  70. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +7 -5
  71. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialResolver.d.ts +22 -3
  72. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialResolver.js +27 -4
  73. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.d.ts +7 -1
  74. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.js +7 -1
  75. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -1
  76. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -1
  77. package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
  78. package/dist/node_modules/@skrr-ai/data-provider/index.js +3857 -3859
  79. package/oclif.manifest.json +38008 -36666
  80. package/package.json +28 -4
@@ -52,6 +52,10 @@ export declare abstract class BaseCommand extends Command {
52
52
  * from here.
53
53
  */
54
54
  protected resolvedCredential: ResolvedCredential;
55
+ /** Re-authorize a long-lived transport using this command's credential
56
+ * source. A daemon handoff is redeemed again; its refresh family is never
57
+ * borrowed or written into the CLI's own login. */
58
+ protected refreshTransportToken(): Promise<string>;
55
59
  /**
56
60
  * Where `resolvedCredential` really came from when its `source` slot cannot
57
61
  * say — an in-memory daemon hand-off or Agent session token is recorded as
@@ -155,6 +155,25 @@ class BaseCommand extends core_1.Command {
155
155
  * from here.
156
156
  */
157
157
  resolvedCredential;
158
+ /** Re-authorize a long-lived transport using this command's credential
159
+ * source. A daemon handoff is redeemed again; its refresh family is never
160
+ * borrowed or written into the CLI's own login. */
161
+ async refreshTransportToken() {
162
+ if (this.credentialProvenance?.kind === 'daemon-handoff') {
163
+ const result = await (0, daemonBroker_1.redeemBrokeredHandoffToken)(true);
164
+ if (!result?.accessToken)
165
+ throw new Error('The local daemon could not renew CLI authentication.');
166
+ this.resolvedCredential = { token: result.accessToken, source: 'env-token',
167
+ kind: (0, auth_core_1.classifyTokenKind)(result.accessToken) };
168
+ }
169
+ else {
170
+ this.resolvedCredential = (await (0, refresh_1.ensureFreshCliCredential)({ credential: this.resolvedCredential,
171
+ bareMode: this.bareMode })).credential;
172
+ }
173
+ if (!this.resolvedCredential.token)
174
+ throw new Error('CLI authentication is unavailable.');
175
+ return this.resolvedCredential.token;
176
+ }
158
177
  /**
159
178
  * Where `resolvedCredential` really came from when its `source` slot cannot
160
179
  * say — an in-memory daemon hand-off or Agent session token is recorded as
@@ -1176,11 +1195,15 @@ class BaseCommand extends core_1.Command {
1176
1195
  // `login` sends a CI job to do the one thing it cannot, and hides the
1177
1196
  // real mistake (dogfood OSK-4693). Name the credential instead.
1178
1197
  const presentedCiToken = Boolean(this.resolvedCredential?.token?.startsWith('osk_ci_'));
1198
+ // A personal access token (OSK-13208) has no session behind it to renew
1199
+ // and no daemon to ask: the server's own reason (expired, revoked) IS
1200
+ // the answer, and the repair is a new token, not `login`.
1201
+ const presentedPat = Boolean(this.resolvedCredential?.token?.startsWith('osk_pat_'));
1179
1202
  // OSK-12116 — the 401 is usually the SECOND failure: the token expired
1180
1203
  // (routine) and renewing it was refused (the fault). The server's code
1181
1204
  // for the retry is `TOKEN_EXPIRED`, which names the routine half; the
1182
1205
  // latched refresh refusal names the half the reader can act on.
1183
- const refreshRefusal = presentedCiToken
1206
+ const refreshRefusal = presentedCiToken || presentedPat
1184
1207
  ? null
1185
1208
  : (0, auth_failure_1.describeRefreshRefusal)(readRefreshRefusal(), {
1186
1209
  bin: this.config.bin,
@@ -1190,7 +1213,7 @@ class BaseCommand extends core_1.Command {
1190
1213
  // refused refresh, and the daemon refused too. Its reason decides the
1191
1214
  // repair (OSK-12149, OSK-12151), and on a Dedicated guest there is no
1192
1215
  // login to run, so its remedy replaces the generic "Run login".
1193
- const brokerRefusal = presentedCiToken || !e.brokerFailure
1216
+ const brokerRefusal = presentedCiToken || presentedPat || !e.brokerFailure
1194
1217
  ? null
1195
1218
  : (0, daemonBrokerRefusal_1.describeBrokerRefusal)(e.brokerFailure, this.config.bin);
1196
1219
  const renewal = refreshRefusal
@@ -1209,6 +1232,12 @@ class BaseCommand extends core_1.Command {
1209
1232
  `daemon (\`OVERSKY_TOKEN=<token> skrrd start\`). ${this.config.bin} commands do ` +
1210
1233
  `not accept it — sign in with \`${this.config.bin} login\` instead.`;
1211
1234
  }
1235
+ else if (presentedPat) {
1236
+ authMessage =
1237
+ `Authentication failed: ${bodyMessage || 'the personal access token was refused.'} ` +
1238
+ `Create a new token with \`${this.config.bin} tokens create\` from a signed-in terminal ` +
1239
+ `and update the secret that sets SKRR_TOKEN.`;
1240
+ }
1212
1241
  else if (brokerRefusal) {
1213
1242
  authMessage = `Authentication failed. ${renewal} ${brokerRefusal.headline}\n→ ${brokerRefusal.remedy}`;
1214
1243
  }
@@ -1,3 +1,4 @@
1
+ import type { StoreReleaseLicense } from '@skrr-ai/data-provider';
1
2
  import { BaseCommand } from '../../base-command';
2
3
  /**
3
4
  * `--capability-rationale <permission-key>=<note>` → the publisher notes a
@@ -18,6 +19,16 @@ export declare function parseReleaseDependencies(entries: readonly string[] | un
18
19
  }>;
19
20
  error?: string;
20
21
  };
22
+ /**
23
+ * `--license` / `--remix` → the `license` declaration a public release carries
24
+ * (SUP11). Values are already constrained by the flags' `options`; this only
25
+ * enforces the pairing the flags cannot express: a remix grant is part of a
26
+ * license declaration, so it is meaningless without one.
27
+ */
28
+ export declare function buildReleaseLicense(licenseId: string | undefined, remix: string | undefined): {
29
+ license?: StoreReleaseLicense;
30
+ error?: string;
31
+ };
21
32
  export default class AgentsVisibility extends BaseCommand {
22
33
  static description: string;
23
34
  static examples: string[];
@@ -36,6 +47,9 @@ export default class AgentsVisibility extends BaseCommand {
36
47
  'capability-rationale': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
37
48
  language: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
38
49
  dependency: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
50
+ license: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
51
+ remix: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
52
+ 'source-visibility': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
39
53
  };
40
54
  run(): Promise<void>;
41
55
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseCapabilityRationales = parseCapabilityRationales;
4
4
  exports.parseReleaseDependencies = parseReleaseDependencies;
5
+ exports.buildReleaseLicense = buildReleaseLicense;
5
6
  const core_1 = require("@oclif/core");
6
7
  const data_provider_1 = require("@skrr-ai/data-provider");
7
8
  const base_command_1 = require("../../base-command");
@@ -48,6 +49,25 @@ function parseReleaseDependencies(entries) {
48
49
  }
49
50
  return { dependencies };
50
51
  }
52
+ /**
53
+ * `--license` / `--remix` → the `license` declaration a public release carries
54
+ * (SUP11). Values are already constrained by the flags' `options`; this only
55
+ * enforces the pairing the flags cannot express: a remix grant is part of a
56
+ * license declaration, so it is meaningless without one.
57
+ */
58
+ function buildReleaseLicense(licenseId, remix) {
59
+ if (!licenseId) {
60
+ return remix
61
+ ? { error: '--remix is part of a license declaration; pass it with --license <id>.' }
62
+ : {};
63
+ }
64
+ return {
65
+ license: {
66
+ id: licenseId,
67
+ ...(remix ? { remix: remix } : {}),
68
+ },
69
+ };
70
+ }
51
71
  class AgentsVisibility extends base_command_1.BaseCommand {
52
72
  static description = 'Set the visibility of an agent';
53
73
  static examples = [
@@ -57,6 +77,8 @@ class AgentsVisibility extends base_command_1.BaseCommand {
57
77
  '<%= config.bin %> agents visibility <agent-id> --public --capability-rationale "network:*=Looks up flight prices on the web"',
58
78
  '<%= config.bin %> agents visibility <agent-id> --public --language en --language zh-Hans',
59
79
  '<%= config.bin %> agents visibility <agent-id> --public --dependency skill:<skill-id>@<store-release-id>',
80
+ '<%= config.bin %> agents visibility <agent-id> --public --license mit --remix attributed --source-visibility public',
81
+ '<%= config.bin %> agents visibility <agent-id> --public --license proprietary --source-visibility sealed',
60
82
  ];
61
83
  static args = {
62
84
  id: core_1.Args.string({ description: 'Agent ID', required: true, ignoreStdin: true }),
@@ -96,6 +118,18 @@ class AgentsVisibility extends base_command_1.BaseCommand {
96
118
  description: 'Pin an attached Skill or Action to its immutable Store release: skill:<id>@<store-release-id> (repeatable)',
97
119
  multiple: true,
98
120
  }),
121
+ license: core_1.Flags.string({
122
+ description: 'The license the public release is offered under. Recorded on the release and shown on the listing; proprietary grants no reuse',
123
+ options: [...data_provider_1.STORE_RELEASE_LICENSE_IDS],
124
+ }),
125
+ remix: core_1.Flags.string({
126
+ description: "Whether a buyer's installed copy may be published as a derived listing: attributed (the fork credits this release) or none. Needs --license; defaults to none",
127
+ options: [...data_provider_1.STORE_RELEASE_REMIX_GRANTS],
128
+ }),
129
+ 'source-visibility': core_1.Flags.string({
130
+ description: "Who may read the release's source, independent of price: licensed (license holders), public (anyone who sees the listing) or sealed (you only). Omit to keep the price-derived rule",
131
+ options: [...data_provider_1.STORE_RELEASE_SOURCE_VISIBILITIES],
132
+ }),
99
133
  };
100
134
  async run() {
101
135
  this.requireAuth();
@@ -128,6 +162,15 @@ class AgentsVisibility extends base_command_1.BaseCommand {
128
162
  exit: 1,
129
163
  });
130
164
  }
165
+ const { license, error: licenseError } = buildReleaseLicense(flags.license, flags.remix);
166
+ if (licenseError)
167
+ this.error(licenseError, { exit: 1 });
168
+ const sourceVisibility = flags['source-visibility'];
169
+ // The server refuses both declarations with isPublic: false — they are
170
+ // terms of a public release, and an unpublish creates none.
171
+ if ((license || sourceVisibility) && !isPublic) {
172
+ this.error('--license, --remix and --source-visibility are terms of a public release; pass them with --public.', { exit: 1 });
173
+ }
131
174
  let result;
132
175
  try {
133
176
  result = await data_provider_1.dataService.setAgentVisibility({
@@ -141,6 +184,8 @@ class AgentsVisibility extends base_command_1.BaseCommand {
141
184
  capabilityRationales,
142
185
  supportedLanguages: flags.language,
143
186
  dependencies,
187
+ license,
188
+ sourceVisibility,
144
189
  });
145
190
  }
146
191
  catch (err) {
@@ -152,6 +197,13 @@ class AgentsVisibility extends base_command_1.BaseCommand {
152
197
  }
153
198
  const label = isPublic ? 'public' : 'private';
154
199
  this.log(`Set agent ${args.id} visibility: ${label}`);
200
+ const recorded = result;
201
+ if (recorded?.license) {
202
+ this.log(`License: ${recorded.license.id} (remix: ${recorded.license.remix})`);
203
+ }
204
+ if (recorded?.sourceVisibility) {
205
+ this.log(`Source visibility: ${recorded.sourceVisibility}`);
206
+ }
155
207
  }
156
208
  }
157
209
  exports.default = AgentsVisibility;
@@ -43,7 +43,6 @@ import { BaseCommand } from '../base-command';
43
43
  */
44
44
  export default class CreateToken extends BaseCommand {
45
45
  static description: string;
46
- static aliases: string[];
47
46
  static examples: string[];
48
47
  static flags: {
49
48
  name: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
@@ -49,7 +49,9 @@ const api_fetch_1 = require("../lib/api-fetch");
49
49
  class CreateToken extends base_command_1.BaseCommand {
50
50
  static description = 'Create a long-lived token for bootstrapping a daemon on a CI/headless machine. ' +
51
51
  'Printed exactly once. Not accepted by `skrr` commands themselves.';
52
- static aliases = ['tokens:create'];
52
+ // `tokens:create` used to alias this command. It now names personal access
53
+ // tokens (OSK-13208), the credential `skrr` itself accepts; this one only
54
+ // bootstraps a daemon, and sharing the name is what sent CI here.
53
55
  static examples = [
54
56
  '<%= config.bin %> create-token --name "github-actions-prod" --ttl 1y',
55
57
  '<%= config.bin %> create-token --name "local-ci" --ttl 30d',
@@ -8,7 +8,6 @@ import { BaseCommand } from '../base-command';
8
8
  */
9
9
  export default class ListTokens extends BaseCommand {
10
10
  static description: string;
11
- static aliases: string[];
12
11
  static flags: {
13
12
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
14
13
  all: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
@@ -13,7 +13,7 @@ const api_fetch_1 = require("../lib/api-fetch");
13
13
  */
14
14
  class ListTokens extends base_command_1.BaseCommand {
15
15
  static description = 'List your long-lived CI tokens';
16
- static aliases = ['tokens:list'];
16
+ // No `tokens:list` alias: `skrr tokens` is personal access tokens (OSK-13208).
17
17
  static flags = {
18
18
  json: core_1.Flags.boolean({ description: 'Output as JSON' }),
19
19
  all: core_1.Flags.boolean({
@@ -44,6 +44,7 @@ class DedicatedMachinesSshProxy extends dedicated_lease_command_1.DedicatedLease
44
44
  code = await (0, dedicated_ssh_1.runSshProxy)({
45
45
  baseURL: this.cliConfig.baseURL,
46
46
  token: this.resolvedCredential.token,
47
+ getToken: () => this.refreshTransportToken(),
47
48
  leaseId: lease,
48
49
  input: process.stdin,
49
50
  output: process.stdout,
@@ -11,7 +11,6 @@ import { BaseCommand } from '../base-command';
11
11
  */
12
12
  export default class RevokeToken extends BaseCommand {
13
13
  static description: string;
14
- static aliases: string[];
15
14
  static args: {
16
15
  id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
17
16
  };
@@ -15,7 +15,7 @@ const api_fetch_1 = require("../lib/api-fetch");
15
15
  */
16
16
  class RevokeToken extends base_command_1.BaseCommand {
17
17
  static description = 'Revoke a long-lived CI token by ID or unique prefix';
18
- static aliases = ['tokens:revoke'];
18
+ // No `tokens:revoke` alias: `skrr tokens` is personal access tokens (OSK-13208).
19
19
  static args = {
20
20
  id: core_1.Args.string({
21
21
  name: 'id',
@@ -8,6 +8,7 @@ export default class StoreFollow extends BaseCommand {
8
8
  };
9
9
  static flags: {
10
10
  undo: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
+ status: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
12
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
13
  };
13
14
  run(): Promise<void>;
@@ -18,13 +18,19 @@ class StoreFollow extends base_command_1.BaseCommand {
18
18
  }),
19
19
  };
20
20
  static flags = {
21
- undo: core_1.Flags.boolean({ description: 'Unfollow the publisher' }),
21
+ undo: core_1.Flags.boolean({ description: 'Unfollow the publisher', exclusive: ['status'] }),
22
+ status: core_1.Flags.boolean({ description: 'Show whether you follow the publisher; change nothing' }),
22
23
  json: core_1.Flags.boolean({ description: 'Output as JSON' }),
23
24
  };
24
25
  async run() {
25
26
  this.requireAuth();
26
27
  const { args, flags } = await this.parse(StoreFollow);
27
28
  try {
29
+ if (flags.status) {
30
+ const overlay = await data_provider_1.dataService.getStorePublisherFollowOverlay(args.handle);
31
+ this.log(JSON.stringify(overlay, null, 2));
32
+ return;
33
+ }
28
34
  const result = flags.undo
29
35
  ? await data_provider_1.dataService.unfollowStorePublisherByHandle(args.handle)
30
36
  : await data_provider_1.dataService.followStorePublisherByHandle(args.handle);
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ /** The publishers you follow, newest first, one page at a time. */
3
+ export default class StoreFollowsList extends BaseCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ cursor: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,29 @@
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
+ /** The publishers you follow, newest first, one page at a time. */
7
+ class StoreFollowsList extends base_command_1.BaseCommand {
8
+ static description = 'List the store publishers you follow';
9
+ static examples = [
10
+ '<%= config.bin %> store follows list',
11
+ '<%= config.bin %> store follows list --cursor <next>',
12
+ ];
13
+ static flags = {
14
+ cursor: core_1.Flags.string({ description: 'Continue from a previous page' }),
15
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
16
+ };
17
+ async run() {
18
+ this.requireAuth();
19
+ const { flags } = await this.parse(StoreFollowsList);
20
+ try {
21
+ const result = await data_provider_1.dataService.getStorePublisherFollows(flags.cursor);
22
+ this.log(JSON.stringify(result, null, 2));
23
+ }
24
+ catch (err) {
25
+ this.handleApiError(err);
26
+ }
27
+ }
28
+ }
29
+ exports.default = StoreFollowsList;
@@ -0,0 +1,16 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ /**
3
+ * Remove a follow by its follow id — the one way to drop a follow whose
4
+ * publisher has since renamed, hidden or lost its handle.
5
+ */
6
+ export default class StoreFollowsRemove extends BaseCommand {
7
+ static description: string;
8
+ static examples: string[];
9
+ static args: {
10
+ followId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
11
+ };
12
+ static flags: {
13
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
14
+ };
15
+ run(): Promise<void>;
16
+ }
@@ -0,0 +1,37 @@
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
+ /**
7
+ * Remove a follow by its follow id — the one way to drop a follow whose
8
+ * publisher has since renamed, hidden or lost its handle.
9
+ */
10
+ class StoreFollowsRemove extends base_command_1.BaseCommand {
11
+ static description = 'Remove a follow by id (works even when the publisher no longer has a public handle)';
12
+ static examples = ['<%= config.bin %> store follows remove pf_abc123'];
13
+ static args = {
14
+ followId: core_1.Args.string({
15
+ description: 'Follow id (from `store follows list`)',
16
+ required: true,
17
+ ignoreStdin: true,
18
+ }),
19
+ };
20
+ static flags = { json: core_1.Flags.boolean({ description: 'Output as JSON' }) };
21
+ async run() {
22
+ this.requireAuth();
23
+ const { args, flags } = await this.parse(StoreFollowsRemove);
24
+ try {
25
+ const result = await data_provider_1.dataService.unfollowStorePublisherById(args.followId);
26
+ if (flags.json) {
27
+ this.log(JSON.stringify(result, null, 2));
28
+ return;
29
+ }
30
+ this.log(result.removed ? `Removed ${args.followId}.` : `${args.followId} was not followed.`);
31
+ }
32
+ catch (err) {
33
+ this.handleApiError(err);
34
+ }
35
+ }
36
+ }
37
+ exports.default = StoreFollowsRemove;
@@ -0,0 +1,17 @@
1
+ import { BaseCommand } from '../../../../base-command';
2
+ /**
3
+ * Replace the profile draft. `--revision` is required: a draft is a whole
4
+ * document, and writing one without naming the revision you edited would
5
+ * silently overwrite a change made meanwhile in the browser.
6
+ */
7
+ export default class StorePublishersProfileDraft extends BaseCommand {
8
+ static description: string;
9
+ static examples: string[];
10
+ static flags: {
11
+ 'publish-as': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
+ file: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
13
+ revision: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
14
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
15
+ };
16
+ run(): Promise<void>;
17
+ }
@@ -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 publisher_profile_flags_1 = require("../../../../lib/publisher-profile-flags");
7
+ /**
8
+ * Replace the profile draft. `--revision` is required: a draft is a whole
9
+ * document, and writing one without naming the revision you edited would
10
+ * silently overwrite a change made meanwhile in the browser.
11
+ */
12
+ class StorePublishersProfileDraft extends base_command_1.BaseCommand {
13
+ static description = 'Replace your publisher profile draft from a JSON file (compare-and-set on --revision)';
14
+ static examples = [
15
+ '<%= config.bin %> store publishers profile draft --file draft.json --revision 7',
16
+ ];
17
+ static flags = {
18
+ 'publish-as': publisher_profile_flags_1.publishAsFlag,
19
+ file: core_1.Flags.string({ description: 'JSON file holding the draft', required: true }),
20
+ revision: core_1.Flags.integer({
21
+ description: 'The revision you edited (from `profile show`); a stale one is refused',
22
+ required: true,
23
+ min: 0,
24
+ }),
25
+ json: publisher_profile_flags_1.jsonFlag,
26
+ };
27
+ async run() {
28
+ this.requireAuth();
29
+ const { flags } = await this.parse(StorePublishersProfileDraft);
30
+ let draft;
31
+ try {
32
+ draft = (0, publisher_profile_flags_1.readDraftFile)(flags.file);
33
+ }
34
+ catch (err) {
35
+ this.error(err.message);
36
+ }
37
+ try {
38
+ const result = await data_provider_1.dataService.replaceStorePublisherProfileDraft({
39
+ publishAs: flags['publish-as'],
40
+ expectedRevision: flags.revision,
41
+ draft,
42
+ });
43
+ if (flags.json) {
44
+ this.log(JSON.stringify(result, null, 2));
45
+ return;
46
+ }
47
+ this.log(`Draft saved at revision ${result.profile.revision}. Nothing is public until you publish.`);
48
+ }
49
+ catch (err) {
50
+ this.handleApiError(err);
51
+ }
52
+ }
53
+ }
54
+ exports.default = StorePublishersProfileDraft;
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../../../base-command';
2
+ /** Rename your public handle. The server refuses a lookalike of an existing one. */
3
+ export default class StorePublishersProfileHandle extends BaseCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static args: {
7
+ handle: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
8
+ };
9
+ static flags: {
10
+ 'publish-as': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
@@ -0,0 +1,39 @@
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 publisher_profile_flags_1 = require("../../../../lib/publisher-profile-flags");
7
+ /** Rename your public handle. The server refuses a lookalike of an existing one. */
8
+ class StorePublishersProfileHandle extends base_command_1.BaseCommand {
9
+ static description = 'Rename your public publisher handle (a lookalike handle is refused)';
10
+ static examples = ['<%= config.bin %> store publishers profile handle acme-labs'];
11
+ static args = {
12
+ handle: core_1.Args.string({
13
+ description: 'The new handle (with or without @)',
14
+ required: true,
15
+ ignoreStdin: true,
16
+ }),
17
+ };
18
+ static flags = { 'publish-as': publisher_profile_flags_1.publishAsFlag, json: publisher_profile_flags_1.jsonFlag };
19
+ async run() {
20
+ this.requireAuth();
21
+ const { args, flags } = await this.parse(StorePublishersProfileHandle);
22
+ const handle = args.handle.replace(/^@/, '');
23
+ try {
24
+ const result = await data_provider_1.dataService.renameStorePublisherProfileHandle({
25
+ publishAs: flags['publish-as'],
26
+ handle,
27
+ });
28
+ if (flags.json) {
29
+ this.log(JSON.stringify(result, null, 2));
30
+ return;
31
+ }
32
+ this.log(`Handle is now @${handle}.`);
33
+ }
34
+ catch (err) {
35
+ this.handleApiError(err);
36
+ }
37
+ }
38
+ }
39
+ exports.default = StorePublishersProfileHandle;
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from '../../../../base-command';
2
+ /** Take the public profile down; published revisions stay restorable. */
3
+ export default class StorePublishersProfileHide extends BaseCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ 'publish-as': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ revision: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
9
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,39 @@
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 publisher_profile_flags_1 = require("../../../../lib/publisher-profile-flags");
7
+ /** Take the public profile down; published revisions stay restorable. */
8
+ class StorePublishersProfileHide extends base_command_1.BaseCommand {
9
+ static description = 'Hide your public publisher profile (published revisions stay restorable)';
10
+ static examples = ['<%= config.bin %> store publishers profile hide'];
11
+ static flags = {
12
+ 'publish-as': publisher_profile_flags_1.publishAsFlag,
13
+ revision: core_1.Flags.integer({
14
+ description: 'Apply only if the profile is still at this revision (default: its current one)',
15
+ min: 0,
16
+ }),
17
+ json: publisher_profile_flags_1.jsonFlag,
18
+ };
19
+ async run() {
20
+ this.requireAuth();
21
+ const { flags } = await this.parse(StorePublishersProfileHide);
22
+ try {
23
+ const publishAs = flags['publish-as'];
24
+ const result = await data_provider_1.dataService.hideStorePublisherProfile({
25
+ publishAs,
26
+ expectedRevision: await (0, publisher_profile_flags_1.currentRevision)(publishAs, flags.revision),
27
+ });
28
+ if (flags.json) {
29
+ this.log(JSON.stringify(result, null, 2));
30
+ return;
31
+ }
32
+ this.log('Hidden. Restore a revision or publish again to make it public.');
33
+ }
34
+ catch (err) {
35
+ this.handleApiError(err);
36
+ }
37
+ }
38
+ }
39
+ exports.default = StorePublishersProfileHide;
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from '../../../../base-command';
2
+ /** Render a draft exactly as the public page would, without saving anything. */
3
+ export default class StorePublishersProfilePreview extends BaseCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ 'publish-as': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ file: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,39 @@
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 publisher_profile_flags_1 = require("../../../../lib/publisher-profile-flags");
7
+ /** Render a draft exactly as the public page would, without saving anything. */
8
+ class StorePublishersProfilePreview extends base_command_1.BaseCommand {
9
+ static description = 'Preview a publisher profile draft as the public page would render it (writes nothing)';
10
+ static examples = [
11
+ '<%= config.bin %> store publishers profile preview --file draft.json',
12
+ ];
13
+ static flags = {
14
+ 'publish-as': publisher_profile_flags_1.publishAsFlag,
15
+ file: core_1.Flags.string({ description: 'JSON file holding the draft', required: true }),
16
+ };
17
+ async run() {
18
+ this.requireAuth();
19
+ const { flags } = await this.parse(StorePublishersProfilePreview);
20
+ let draft;
21
+ try {
22
+ draft = (0, publisher_profile_flags_1.readDraftFile)(flags.file);
23
+ }
24
+ catch (err) {
25
+ this.error(err.message);
26
+ }
27
+ try {
28
+ const result = await data_provider_1.dataService.previewStorePublisherProfile({
29
+ publishAs: flags['publish-as'],
30
+ draft,
31
+ });
32
+ this.log(JSON.stringify(result, null, 2));
33
+ }
34
+ catch (err) {
35
+ this.handleApiError(err);
36
+ }
37
+ }
38
+ }
39
+ exports.default = StorePublishersProfilePreview;