@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
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from '../../../../base-command';
2
+ /** Publish the current draft as a new public revision. */
3
+ export default class StorePublishersProfilePublish 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,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_crypto_1 = require("node:crypto");
4
+ const core_1 = require("@oclif/core");
5
+ const data_provider_1 = require("@skrr-ai/data-provider");
6
+ const base_command_1 = require("../../../../base-command");
7
+ const publisher_profile_flags_1 = require("../../../../lib/publisher-profile-flags");
8
+ /** Publish the current draft as a new public revision. */
9
+ class StorePublishersProfilePublish extends base_command_1.BaseCommand {
10
+ static description = 'Publish your current publisher profile draft as a new public revision';
11
+ static examples = ['<%= config.bin %> store publishers profile publish'];
12
+ static flags = {
13
+ 'publish-as': publisher_profile_flags_1.publishAsFlag,
14
+ revision: core_1.Flags.integer({
15
+ description: 'Apply only if the profile is still at this revision (default: its current one)',
16
+ min: 0,
17
+ }),
18
+ json: publisher_profile_flags_1.jsonFlag,
19
+ };
20
+ async run() {
21
+ this.requireAuth();
22
+ const { flags } = await this.parse(StorePublishersProfilePublish);
23
+ try {
24
+ const publishAs = flags['publish-as'];
25
+ const result = await data_provider_1.dataService.publishStorePublisherProfile({
26
+ publishAs,
27
+ expectedRevision: await (0, publisher_profile_flags_1.currentRevision)(publishAs, flags.revision),
28
+ idempotencyKey: (0, node_crypto_1.randomUUID)(),
29
+ });
30
+ if (flags.json) {
31
+ this.log(JSON.stringify(result, null, 2));
32
+ return;
33
+ }
34
+ this.log('Published.');
35
+ }
36
+ catch (err) {
37
+ this.handleApiError(err);
38
+ }
39
+ }
40
+ }
41
+ exports.default = StorePublishersProfilePublish;
@@ -0,0 +1,15 @@
1
+ import { BaseCommand } from '../../../../base-command';
2
+ /** Re-publish an earlier revision. Hidden revisions are not restore candidates. */
3
+ export default class StorePublishersProfileRestore extends BaseCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static args: {
7
+ revisionId: 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
+ revision: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_crypto_1 = require("node:crypto");
4
+ const core_1 = require("@oclif/core");
5
+ const data_provider_1 = require("@skrr-ai/data-provider");
6
+ const base_command_1 = require("../../../../base-command");
7
+ const publisher_profile_flags_1 = require("../../../../lib/publisher-profile-flags");
8
+ /** Re-publish an earlier revision. Hidden revisions are not restore candidates. */
9
+ class StorePublishersProfileRestore extends base_command_1.BaseCommand {
10
+ static description = 'Restore an earlier published revision of your publisher profile';
11
+ static examples = ['<%= config.bin %> store publishers profile restore ppr_abc123'];
12
+ static args = {
13
+ revisionId: core_1.Args.string({
14
+ description: 'Revision id (from `profile revisions`)',
15
+ required: true,
16
+ ignoreStdin: true,
17
+ }),
18
+ };
19
+ static flags = {
20
+ 'publish-as': publisher_profile_flags_1.publishAsFlag,
21
+ revision: core_1.Flags.integer({
22
+ description: 'Apply only if the profile is still at this revision (default: its current one)',
23
+ min: 0,
24
+ }),
25
+ json: publisher_profile_flags_1.jsonFlag,
26
+ };
27
+ async run() {
28
+ this.requireAuth();
29
+ const { args, flags } = await this.parse(StorePublishersProfileRestore);
30
+ try {
31
+ const publishAs = flags['publish-as'];
32
+ const result = await data_provider_1.dataService.restoreStorePublisherProfileRevision({
33
+ publishAs,
34
+ revisionId: args.revisionId,
35
+ expectedRevision: await (0, publisher_profile_flags_1.currentRevision)(publishAs, flags.revision),
36
+ idempotencyKey: (0, node_crypto_1.randomUUID)(),
37
+ });
38
+ if (flags.json) {
39
+ this.log(JSON.stringify(result, null, 2));
40
+ return;
41
+ }
42
+ this.log(`Restored ${args.revisionId}.`);
43
+ }
44
+ catch (err) {
45
+ this.handleApiError(err);
46
+ }
47
+ }
48
+ }
49
+ exports.default = StorePublishersProfileRestore;
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from '../../../../base-command';
2
+ /** Published revisions of your publisher profile — the restore candidates. */
3
+ export default class StorePublishersProfileRevisions 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
+ limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,30 @@
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
+ /** Published revisions of your publisher profile — the restore candidates. */
8
+ class StorePublishersProfileRevisions extends base_command_1.BaseCommand {
9
+ static description = 'List published revisions of your publisher profile (the restore candidates)';
10
+ static examples = ['<%= config.bin %> store publishers profile revisions --limit 10'];
11
+ static flags = {
12
+ 'publish-as': publisher_profile_flags_1.publishAsFlag,
13
+ limit: core_1.Flags.integer({ description: 'How many revisions to return', min: 1 }),
14
+ };
15
+ async run() {
16
+ this.requireAuth();
17
+ const { flags } = await this.parse(StorePublishersProfileRevisions);
18
+ try {
19
+ const result = await data_provider_1.dataService.getStorePublisherProfileRevisions({
20
+ publishAs: flags['publish-as'],
21
+ limit: flags.limit,
22
+ });
23
+ this.log(JSON.stringify(result, null, 2));
24
+ }
25
+ catch (err) {
26
+ this.handleApiError(err);
27
+ }
28
+ }
29
+ }
30
+ exports.default = StorePublishersProfileRevisions;
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from '../../../../base-command';
2
+ /** The private publisher-profile console: draft, visibility and CAS revision. */
3
+ export default class StorePublishersProfileShow 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
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const data_provider_1 = require("@skrr-ai/data-provider");
4
+ const base_command_1 = require("../../../../base-command");
5
+ const publisher_profile_flags_1 = require("../../../../lib/publisher-profile-flags");
6
+ /** The private publisher-profile console: draft, visibility and CAS revision. */
7
+ class StorePublishersProfileShow extends base_command_1.BaseCommand {
8
+ static description = 'Show your publisher profile console — draft, visibility and the revision a write must name';
9
+ static examples = [
10
+ '<%= config.bin %> store publishers profile show',
11
+ '<%= config.bin %> store publishers profile show --publish-as ws_123 --json > draft.json',
12
+ ];
13
+ static flags = { 'publish-as': publisher_profile_flags_1.publishAsFlag, json: publisher_profile_flags_1.jsonFlag };
14
+ async run() {
15
+ this.requireAuth();
16
+ const { flags } = await this.parse(StorePublishersProfileShow);
17
+ try {
18
+ const result = await data_provider_1.dataService.getStorePublisherProfileEditor(flags['publish-as']);
19
+ if (flags.json) {
20
+ this.log(JSON.stringify(result, null, 2));
21
+ return;
22
+ }
23
+ const { profile } = result;
24
+ this.log(`Profile: ${profile.profileId} (${profile.publisher.type} ${profile.publisher.id})`);
25
+ this.log(`Visibility: ${profile.visibility}`);
26
+ this.log(`Revision: ${profile.revision}`);
27
+ this.log(`Published: ${profile.publishedRevision
28
+ ? `#${profile.publishedRevision.number} at ${profile.publishedRevision.publishedAt}`
29
+ : 'never'}`);
30
+ this.log(`Name: ${profile.draft.displayName ?? '(unset)'}`);
31
+ if (profile.draft.headline)
32
+ this.log(`Headline: ${profile.draft.headline}`);
33
+ }
34
+ catch (err) {
35
+ this.handleApiError(err);
36
+ }
37
+ }
38
+ }
39
+ exports.default = StorePublishersProfileShow;
@@ -0,0 +1,26 @@
1
+ import type { StoreAgentRatedRelease } from '@skrr-ai/data-provider';
2
+ import { BaseCommand } from '../../base-command';
3
+ /** `1.2 (release 3)`, or the honest "unknown release" for a pre-release install. */
4
+ export declare function describeRatedRelease(release: StoreAgentRatedRelease | null | undefined): string;
5
+ /**
6
+ * Rate a Store agent you installed, optionally with a written review.
7
+ *
8
+ * The release the rating is recorded against is NOT a flag: the server stamps
9
+ * it from your own install, so a review cannot claim a version its author
10
+ * never ran. Rating again replaces your earlier rating; omitting --text keeps
11
+ * the review text you already wrote, and --clear-text removes it.
12
+ */
13
+ export default class StoreReview extends BaseCommand {
14
+ static description: string;
15
+ static examples: string[];
16
+ static args: {
17
+ agentId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
18
+ };
19
+ static flags: {
20
+ rating: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
21
+ text: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
22
+ 'clear-text': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
23
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
24
+ };
25
+ run(): Promise<void>;
26
+ }
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.describeRatedRelease = describeRatedRelease;
4
+ const core_1 = require("@oclif/core");
5
+ const data_provider_1 = require("@skrr-ai/data-provider");
6
+ const base_command_1 = require("../../base-command");
7
+ /** `1.2 (release 3)`, or the honest "unknown release" for a pre-release install. */
8
+ function describeRatedRelease(release) {
9
+ if (!release)
10
+ return 'an unknown release';
11
+ const label = release.versionLabel ? `v${release.versionLabel}` : release.id;
12
+ return release.releaseNumber != null ? `${label} (release ${release.releaseNumber})` : label;
13
+ }
14
+ /**
15
+ * Rate a Store agent you installed, optionally with a written review.
16
+ *
17
+ * The release the rating is recorded against is NOT a flag: the server stamps
18
+ * it from your own install, so a review cannot claim a version its author
19
+ * never ran. Rating again replaces your earlier rating; omitting --text keeps
20
+ * the review text you already wrote, and --clear-text removes it.
21
+ */
22
+ class StoreReview extends base_command_1.BaseCommand {
23
+ static description = 'Rate a Store agent you installed (1-5 stars), optionally with a written review';
24
+ static examples = [
25
+ '<%= config.bin %> store review agent_abc --rating 5',
26
+ '<%= config.bin %> store review agent_abc --rating 4 --text "Great at triage, slow on long threads"',
27
+ '<%= config.bin %> store review agent_abc --rating 4 --clear-text',
28
+ '<%= config.bin %> store reviews agent_abc --mine',
29
+ ];
30
+ static args = {
31
+ agentId: core_1.Args.string({
32
+ description: 'The Store agent to rate',
33
+ required: true,
34
+ ignoreStdin: true,
35
+ }),
36
+ };
37
+ static flags = {
38
+ rating: core_1.Flags.integer({
39
+ description: `Star rating, ${data_provider_1.STORE_AGENT_RATING_MIN}-${data_provider_1.STORE_AGENT_RATING_MAX}`,
40
+ required: true,
41
+ min: data_provider_1.STORE_AGENT_RATING_MIN,
42
+ max: data_provider_1.STORE_AGENT_RATING_MAX,
43
+ }),
44
+ text: core_1.Flags.string({
45
+ description: `Written review (at most ${data_provider_1.STORE_AGENT_REVIEW_MAX_LENGTH} characters). Omit to keep your existing review text`,
46
+ exclusive: ['clear-text'],
47
+ }),
48
+ 'clear-text': core_1.Flags.boolean({
49
+ description: 'Remove your written review and keep only the star rating',
50
+ exclusive: ['text'],
51
+ }),
52
+ json: core_1.Flags.boolean({ description: 'Output JSON' }),
53
+ };
54
+ async run() {
55
+ this.requireAuth();
56
+ const { args, flags } = await this.parse(StoreReview);
57
+ let review;
58
+ if (flags['clear-text']) {
59
+ review = '';
60
+ }
61
+ else if (flags.text !== undefined) {
62
+ review = flags.text.trim();
63
+ if (!review) {
64
+ this.error('--text is empty. Pass review text, or --clear-text to remove your review.', {
65
+ exit: 2,
66
+ });
67
+ }
68
+ if (review.length > data_provider_1.STORE_AGENT_REVIEW_MAX_LENGTH) {
69
+ this.error(`--text is ${review.length} characters; a review holds at most ${data_provider_1.STORE_AGENT_REVIEW_MAX_LENGTH}.`, { exit: 2 });
70
+ }
71
+ }
72
+ try {
73
+ const result = await data_provider_1.dataService.rateAgent({
74
+ agentId: args.agentId,
75
+ rating: flags.rating,
76
+ ...(review !== undefined ? { review } : {}),
77
+ });
78
+ if (flags.json) {
79
+ this.log(JSON.stringify(result, null, 2));
80
+ return;
81
+ }
82
+ this.log(`Rated ${args.agentId} ${result.userRating}/${data_provider_1.STORE_AGENT_RATING_MAX} on ${describeRatedRelease(result.ratedRelease)}.`);
83
+ this.log(result.userReview
84
+ ? `Review: ${result.userReview}`
85
+ : 'No written review (star rating only).');
86
+ this.log(`Listing now averages ${Number(result.rating).toFixed(1)} from ${result.ratingCount} rating(s).`);
87
+ }
88
+ catch (err) {
89
+ this.handleApiError(err, { subject: `Rating ${args.agentId}` });
90
+ }
91
+ }
92
+ }
93
+ exports.default = StoreReview;
@@ -0,0 +1,29 @@
1
+ import type { StoreAgentReview } from '@skrr-ai/data-provider';
2
+ import { BaseCommand } from '../../base-command';
3
+ /** Plain-text lines for one written review and the publisher's reply to it. */
4
+ export declare function describeReview(review: StoreAgentReview): string[];
5
+ /**
6
+ * Read a Store agent's written reviews, or your own rating of it, and — as the
7
+ * agent's publisher — answer a review publicly.
8
+ *
9
+ * Star-only ratings are not listed; they are anonymous contributions to the
10
+ * average. Only the agent's author may reply, and the server decides that
11
+ * (`viewerIsPublisher`), not this command.
12
+ */
13
+ export default class StoreReviews extends BaseCommand {
14
+ static description: string;
15
+ static examples: string[];
16
+ static args: {
17
+ agentId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
18
+ };
19
+ static flags: {
20
+ limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
21
+ cursor: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
22
+ mine: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
23
+ reply: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
24
+ body: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
25
+ 'remove-reply': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
26
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
27
+ };
28
+ run(): Promise<void>;
29
+ }
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.describeReview = describeReview;
4
+ const core_1 = require("@oclif/core");
5
+ const data_provider_1 = require("@skrr-ai/data-provider");
6
+ const base_command_1 = require("../../base-command");
7
+ const review_1 = require("./review");
8
+ const REVIEW_LIST_MAX = 50;
9
+ function reviewerName(review) {
10
+ return review.reviewer?.displayName || review.reviewer?.username || 'a former user';
11
+ }
12
+ /** Plain-text lines for one written review and the publisher's reply to it. */
13
+ function describeReview(review) {
14
+ const when = (review.reviewedAt || review.updatedAt || review.createdAt || '').slice(0, 10);
15
+ const lines = [
16
+ `${review.id} ${review.rating}/${data_provider_1.STORE_AGENT_RATING_MAX} ${(0, review_1.describeRatedRelease)(review.ratedRelease)} by ${reviewerName(review)}${when ? ` ${when}` : ''}`,
17
+ ];
18
+ if (review.review)
19
+ lines.push(` ${review.review}`);
20
+ const reply = review.publisherReply;
21
+ if (reply) {
22
+ lines.push(` Publisher reply${reply.predatesReviewEdit ? ' (written before the review was last edited)' : ''}: ${reply.body}`);
23
+ }
24
+ return lines;
25
+ }
26
+ /**
27
+ * Read a Store agent's written reviews, or your own rating of it, and — as the
28
+ * agent's publisher — answer a review publicly.
29
+ *
30
+ * Star-only ratings are not listed; they are anonymous contributions to the
31
+ * average. Only the agent's author may reply, and the server decides that
32
+ * (`viewerIsPublisher`), not this command.
33
+ */
34
+ class StoreReviews extends base_command_1.BaseCommand {
35
+ static description = "List a Store agent's written reviews, show your own rating, or reply to a review as its publisher";
36
+ static examples = [
37
+ '<%= config.bin %> store reviews agent_abc',
38
+ '<%= config.bin %> store reviews agent_abc --limit 20 --cursor <next-cursor>',
39
+ '<%= config.bin %> store reviews agent_abc --mine',
40
+ '<%= config.bin %> store reviews agent_abc --reply <review-id> --body "Fixed in 1.4.1, thanks"',
41
+ '<%= config.bin %> store reviews agent_abc --remove-reply <review-id>',
42
+ ];
43
+ static args = {
44
+ agentId: core_1.Args.string({
45
+ description: 'The Store agent (or, to reply, your own published agent)',
46
+ required: true,
47
+ ignoreStdin: true,
48
+ }),
49
+ };
50
+ static flags = {
51
+ limit: core_1.Flags.integer({
52
+ description: `Reviews per page (max ${REVIEW_LIST_MAX})`,
53
+ min: 1,
54
+ max: REVIEW_LIST_MAX,
55
+ }),
56
+ cursor: core_1.Flags.string({ description: 'Continue from the cursor a previous page printed' }),
57
+ mine: core_1.Flags.boolean({
58
+ description: 'Show only your own rating and review of this agent',
59
+ exclusive: ['reply', 'remove-reply', 'limit', 'cursor'],
60
+ }),
61
+ reply: core_1.Flags.string({
62
+ description: 'Review id to answer publicly (the agent publisher only); needs --body',
63
+ exclusive: ['remove-reply', 'mine', 'limit', 'cursor'],
64
+ dependsOn: ['body'],
65
+ }),
66
+ body: core_1.Flags.string({
67
+ description: `Reply text (at most ${data_provider_1.STORE_AGENT_REVIEW_MAX_LENGTH} characters). Replaces any earlier reply`,
68
+ dependsOn: ['reply'],
69
+ }),
70
+ 'remove-reply': core_1.Flags.string({
71
+ description: 'Review id whose publisher reply to withdraw (the agent publisher only)',
72
+ exclusive: ['reply', 'mine', 'limit', 'cursor'],
73
+ }),
74
+ json: core_1.Flags.boolean({ description: 'Output JSON' }),
75
+ };
76
+ async run() {
77
+ this.requireAuth();
78
+ const { args, flags } = await this.parse(StoreReviews);
79
+ const agentId = args.agentId;
80
+ if (flags.reply !== undefined) {
81
+ const body = (flags.body ?? '').trim();
82
+ if (!body)
83
+ this.error('--body is empty; a reply needs text.', { exit: 2 });
84
+ if (body.length > data_provider_1.STORE_AGENT_REVIEW_MAX_LENGTH) {
85
+ this.error(`--body is ${body.length} characters; a reply holds at most ${data_provider_1.STORE_AGENT_REVIEW_MAX_LENGTH}.`, { exit: 2 });
86
+ }
87
+ try {
88
+ const res = await data_provider_1.dataService.replyToAgentReview({
89
+ agentId,
90
+ reviewId: flags.reply,
91
+ body,
92
+ });
93
+ if (flags.json) {
94
+ this.log(JSON.stringify(res, null, 2));
95
+ return;
96
+ }
97
+ this.log(`Replied to review ${res.review.id}.`);
98
+ describeReview(res.review).forEach((line) => this.log(line));
99
+ }
100
+ catch (err) {
101
+ this.handleApiError(err, { subject: `Replying to review ${flags.reply}` });
102
+ }
103
+ return;
104
+ }
105
+ if (flags['remove-reply'] !== undefined) {
106
+ try {
107
+ const res = await data_provider_1.dataService.deleteAgentReviewReply({
108
+ agentId,
109
+ reviewId: flags['remove-reply'],
110
+ });
111
+ this.log(flags.json
112
+ ? JSON.stringify(res, null, 2)
113
+ : `Withdrew your reply to review ${res.review.id}.`);
114
+ }
115
+ catch (err) {
116
+ this.handleApiError(err, { subject: `Withdrawing the reply to ${flags['remove-reply']}` });
117
+ }
118
+ return;
119
+ }
120
+ if (flags.mine) {
121
+ try {
122
+ const res = await data_provider_1.dataService.getAgentUserRating(agentId);
123
+ if (flags.json) {
124
+ this.log(JSON.stringify(res, null, 2));
125
+ return;
126
+ }
127
+ if (res.userRating == null) {
128
+ this.log(`You have not rated ${agentId}. Rate it with: skrr store review ${agentId} --rating <1-5>`);
129
+ return;
130
+ }
131
+ this.log(`You rated ${agentId} ${res.userRating}/${data_provider_1.STORE_AGENT_RATING_MAX} on ${(0, review_1.describeRatedRelease)(res.ratedRelease)}.`);
132
+ this.log(res.userReview ? `Review: ${res.userReview}` : 'No written review.');
133
+ }
134
+ catch (err) {
135
+ this.handleApiError(err, { subject: `Reading your rating of ${agentId}` });
136
+ }
137
+ return;
138
+ }
139
+ try {
140
+ const res = await data_provider_1.dataService.getStoreAgentReviews(agentId, {
141
+ ...(flags.limit !== undefined ? { limit: flags.limit } : {}),
142
+ ...(flags.cursor ? { cursor: flags.cursor } : {}),
143
+ });
144
+ if (flags.json) {
145
+ this.log(JSON.stringify(res, null, 2));
146
+ return;
147
+ }
148
+ if (res.data.length === 0) {
149
+ this.log(`No written reviews of ${agentId}${flags.cursor ? ' on this page' : ''}.`);
150
+ }
151
+ res.data.forEach((review, index) => {
152
+ if (index > 0)
153
+ this.log('');
154
+ describeReview(review).forEach((line) => this.log(line));
155
+ });
156
+ if (res.has_more && res.next_cursor) {
157
+ this.log('');
158
+ this.log(`More: skrr store reviews ${agentId} --cursor ${res.next_cursor}`);
159
+ }
160
+ if (res.viewerIsPublisher && res.data.length > 0) {
161
+ this.log('');
162
+ this.log(`You publish this agent. Answer a review with: skrr store reviews ${agentId} --reply <review-id> --body "..."`);
163
+ }
164
+ }
165
+ catch (err) {
166
+ this.handleApiError(err, { subject: `Listing reviews of ${agentId}` });
167
+ }
168
+ }
169
+ }
170
+ exports.default = StoreReviews;
@@ -0,0 +1,20 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ /**
3
+ * Tip a public listing (SVC10). A tip is charged once from your balance under
4
+ * the fee schedule's tipping rate and grants nothing. `--tip-id` is the
5
+ * idempotency identity: repeat it to retry the SAME tip safely; omit it and
6
+ * every invocation is a new charge.
7
+ */
8
+ export default class StoreTip extends BaseCommand {
9
+ static description: string;
10
+ static examples: string[];
11
+ static args: {
12
+ agentId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
13
+ };
14
+ static flags: {
15
+ amount: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
16
+ 'tip-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
17
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
18
+ };
19
+ run(): Promise<void>;
20
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_crypto_1 = require("node:crypto");
4
+ const core_1 = require("@oclif/core");
5
+ const data_provider_1 = require("@skrr-ai/data-provider");
6
+ const base_command_1 = require("../../base-command");
7
+ const usd_micros_1 = require("../../lib/usd-micros");
8
+ /**
9
+ * Tip a public listing (SVC10). A tip is charged once from your balance under
10
+ * the fee schedule's tipping rate and grants nothing. `--tip-id` is the
11
+ * idempotency identity: repeat it to retry the SAME tip safely; omit it and
12
+ * every invocation is a new charge.
13
+ */
14
+ class StoreTip extends base_command_1.BaseCommand {
15
+ static description = 'Tip the publisher of a public store listing — charged once, grants no entitlement';
16
+ static examples = [
17
+ '<%= config.bin %> store tip agent_abc123 --amount 5',
18
+ '<%= config.bin %> store tip agent_abc123 --amount 2.50 --tip-id my-retry-key',
19
+ ];
20
+ static args = {
21
+ agentId: core_1.Args.string({
22
+ description: 'Store listing (agent) id',
23
+ required: true,
24
+ ignoreStdin: true,
25
+ }),
26
+ };
27
+ static flags = {
28
+ amount: core_1.Flags.string({ description: 'Amount in USD, e.g. 5 or 2.50', required: true }),
29
+ 'tip-id': core_1.Flags.string({
30
+ description: 'Idempotency key — reuse it to retry the same tip without charging twice',
31
+ }),
32
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
33
+ };
34
+ async run() {
35
+ this.requireAuth();
36
+ const { args, flags } = await this.parse(StoreTip);
37
+ const amountMicros = (0, usd_micros_1.usdToMicros)(flags.amount);
38
+ if (amountMicros === null) {
39
+ this.error(`--amount must be a positive USD amount with at most 2 decimals (got "${flags.amount}")`);
40
+ }
41
+ const tipId = flags['tip-id'] ?? (0, node_crypto_1.randomUUID)();
42
+ try {
43
+ const result = await data_provider_1.dataService.tipStoreAgent(args.agentId, { amountMicros, tipId });
44
+ if (flags.json) {
45
+ this.log(JSON.stringify(result, null, 2));
46
+ return;
47
+ }
48
+ this.log(result.replayed
49
+ ? `Already tipped under ${tipId}; nothing new was charged.`
50
+ : `Tipped $${(result.amountMicros / 1_000_000).toFixed(2)} (tip ${tipId}).`);
51
+ }
52
+ catch (err) {
53
+ this.handleApiError(err);
54
+ }
55
+ }
56
+ }
57
+ exports.default = StoreTip;
@@ -0,0 +1,28 @@
1
+ import { BaseCommand } from '../../base-command';
2
+ /**
3
+ * `skrr tokens create` — mint a personal access token (`osk_pat_*`, OSK-13208)
4
+ * for CI. The secret is printed EXACTLY ONCE.
5
+ *
6
+ * Creating one needs a sign-in session (a token cannot mint a token) and, for
7
+ * an account with two-factor authentication, a fresh authenticator code from
8
+ * that session. `--otp` / `--backup-code` supply it up front; at a terminal the
9
+ * command asks for it when the server does.
10
+ */
11
+ export default class TokensCreate extends BaseCommand {
12
+ static description: string;
13
+ static examples: string[];
14
+ static args: {
15
+ name: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
16
+ };
17
+ static flags: {
18
+ name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
19
+ scope: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
20
+ 'expires-in-days': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
21
+ otp: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
22
+ 'backup-code': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
23
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
24
+ };
25
+ run(): Promise<void>;
26
+ private verify;
27
+ private refuseStepUp;
28
+ }