@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.
- package/dist/base-command.d.ts +4 -0
- package/dist/base-command.js +31 -2
- package/dist/commands/agents/visibility.d.ts +14 -0
- package/dist/commands/agents/visibility.js +52 -0
- package/dist/commands/create-token.d.ts +0 -1
- package/dist/commands/create-token.js +3 -1
- package/dist/commands/list-tokens.d.ts +0 -1
- package/dist/commands/list-tokens.js +1 -1
- package/dist/commands/machines/dedicated/ssh-proxy.js +1 -0
- package/dist/commands/revoke-token.d.ts +0 -1
- package/dist/commands/revoke-token.js +1 -1
- package/dist/commands/store/follow.d.ts +1 -0
- package/dist/commands/store/follow.js +7 -1
- package/dist/commands/store/follows/list.d.ts +11 -0
- package/dist/commands/store/follows/list.js +29 -0
- package/dist/commands/store/follows/remove.d.ts +16 -0
- package/dist/commands/store/follows/remove.js +37 -0
- package/dist/commands/store/publishers/profile/draft.d.ts +17 -0
- package/dist/commands/store/publishers/profile/draft.js +54 -0
- package/dist/commands/store/publishers/profile/handle.d.ts +14 -0
- package/dist/commands/store/publishers/profile/handle.js +39 -0
- package/dist/commands/store/publishers/profile/hide.d.ts +12 -0
- package/dist/commands/store/publishers/profile/hide.js +39 -0
- package/dist/commands/store/publishers/profile/preview.d.ts +11 -0
- package/dist/commands/store/publishers/profile/preview.js +39 -0
- package/dist/commands/store/publishers/profile/publish.d.ts +12 -0
- package/dist/commands/store/publishers/profile/publish.js +41 -0
- package/dist/commands/store/publishers/profile/restore.d.ts +15 -0
- package/dist/commands/store/publishers/profile/restore.js +49 -0
- package/dist/commands/store/publishers/profile/revisions.d.ts +11 -0
- package/dist/commands/store/publishers/profile/revisions.js +30 -0
- package/dist/commands/store/publishers/profile/show.d.ts +11 -0
- package/dist/commands/store/publishers/profile/show.js +39 -0
- package/dist/commands/store/review.d.ts +26 -0
- package/dist/commands/store/review.js +93 -0
- package/dist/commands/store/reviews.d.ts +29 -0
- package/dist/commands/store/reviews.js +170 -0
- package/dist/commands/store/tip.d.ts +20 -0
- package/dist/commands/store/tip.js +57 -0
- package/dist/commands/tokens/create.d.ts +28 -0
- package/dist/commands/tokens/create.js +136 -0
- package/dist/commands/tokens/list.d.ts +11 -0
- package/dist/commands/tokens/list.js +53 -0
- package/dist/commands/tokens/revoke.d.ts +14 -0
- package/dist/commands/tokens/revoke.js +42 -0
- package/dist/lib/access-tokens.d.ts +59 -0
- package/dist/lib/access-tokens.js +50 -0
- package/dist/lib/auth-core-init.d.ts +6 -0
- package/dist/lib/auth-core-init.js +28 -6
- package/dist/lib/credential-resolver.d.ts +1 -1
- package/dist/lib/credential-resolver.js +8 -2
- package/dist/lib/daemonBroker.d.ts +13 -2
- package/dist/lib/daemonBroker.js +6 -4
- package/dist/lib/dedicated-ssh.d.ts +9 -0
- package/dist/lib/dedicated-ssh.js +232 -63
- package/dist/lib/node-adapter.js +2 -2
- package/dist/lib/publisher-profile-flags.d.ts +19 -0
- package/dist/lib/publisher-profile-flags.js +48 -0
- package/dist/lib/refresh.d.ts +1 -1
- package/dist/lib/refresh.js +6 -1
- package/dist/lib/ssh-ordered-bytes.d.ts +8 -0
- package/dist/lib/ssh-ordered-bytes.js +31 -0
- package/dist/lib/usd-micros.d.ts +9 -0
- package/dist/lib/usd-micros.js +21 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialResolver.d.ts +22 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialResolver.js +29 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.d.ts +7 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.js +7 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +7 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialResolver.d.ts +22 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialResolver.js +27 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.d.ts +7 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.js +7 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +3857 -3859
- package/oclif.manifest.json +38008 -36666
- package/package.json +28 -4
package/dist/base-command.d.ts
CHANGED
|
@@ -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
|
package/dist/base-command.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|