@skrr-ai/cli 0.1.93 → 0.1.95
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/README.md +153 -165
- package/bin/run.js +32 -0
- package/bin/update-npm-runner.cjs +33 -0
- package/bin/update-session.cjs +194 -0
- package/bin/update-worker.cjs +208 -0
- package/dist/base-command.js +0 -15
- package/dist/commands/agents/operating-plan.d.ts +11 -0
- package/dist/commands/agents/operating-plan.js +54 -0
- package/dist/commands/agents/roles/example.d.ts +11 -0
- package/dist/commands/agents/roles/example.js +30 -0
- package/dist/commands/{commitments/mode.d.ts → agents/roles/export.d.ts} +5 -5
- package/dist/commands/agents/roles/export.js +81 -0
- package/dist/commands/agents/roles/install.d.ts +12 -0
- package/dist/commands/agents/roles/install.js +48 -0
- package/dist/commands/agents/roles/list.d.ts +11 -0
- package/dist/commands/agents/roles/list.js +36 -0
- package/dist/commands/agents/roles/preview.d.ts +14 -0
- package/dist/commands/agents/roles/preview.js +49 -0
- package/dist/commands/agents/roles/withdraw.d.ts +13 -0
- package/dist/commands/agents/roles/withdraw.js +43 -0
- package/dist/commands/code/doctor.d.ts +1 -0
- package/dist/commands/code/doctor.js +6 -0
- package/dist/commands/code/index.js +4 -0
- package/dist/commands/code/install.d.ts +5 -62
- package/dist/commands/code/install.js +86 -279
- package/dist/commands/code/rollback.d.ts +8 -0
- package/dist/commands/code/rollback.js +20 -0
- package/dist/commands/code/update.d.ts +8 -37
- package/dist/commands/code/update.js +134 -213
- package/dist/commands/commitments/{autonomy-requests → cadence-requests}/decide.d.ts +5 -7
- package/dist/commands/commitments/{autonomy-requests → cadence-requests}/decide.js +13 -15
- package/dist/commands/commitments/cost.d.ts +1 -1
- package/dist/commands/commitments/cost.js +1 -1
- package/dist/commands/commitments/create.d.ts +0 -7
- package/dist/commands/commitments/create.js +9 -98
- package/dist/commands/commitments/delivery.js +3 -21
- package/dist/commands/commitments/doctor.js +28 -27
- package/dist/commands/commitments/effective-policy.js +5 -36
- package/dist/commands/commitments/evaluations.d.ts +15 -0
- package/dist/commands/commitments/evaluations.js +54 -0
- package/dist/commands/commitments/pack/activate.d.ts +11 -0
- package/dist/commands/commitments/pack/activate.js +22 -0
- package/dist/commands/commitments/pack/bind.js +1 -1
- package/dist/commands/commitments/remediate.js +2 -5
- package/dist/commands/commitments/show.js +1 -1
- package/dist/commands/commitments/update.js +9 -9
- package/dist/commands/commitments/wake-capabilities.d.ts +1 -3
- package/dist/commands/commitments/wake-capabilities.js +5 -21
- package/dist/commands/daemon/install.js +4 -0
- package/dist/commands/generate-recovery-code.d.ts +13 -1
- package/dist/commands/generate-recovery-code.js +146 -13
- package/dist/commands/instructions/guide.d.ts +20 -0
- package/dist/commands/instructions/guide.js +84 -0
- package/dist/commands/instructions/install.js +57 -33
- package/dist/commands/instructions/setup.d.ts +14 -0
- package/dist/commands/instructions/setup.js +72 -0
- package/dist/commands/integrations/execute.js +1 -1
- package/dist/commands/login.d.ts +5 -6
- package/dist/commands/login.js +27 -11
- package/dist/commands/logout.js +7 -7
- package/dist/commands/security/overview.d.ts +11 -0
- package/dist/commands/security/overview.js +158 -0
- package/dist/commands/spaces/claim.d.ts +12 -0
- package/dist/commands/spaces/claim.js +42 -0
- package/dist/commands/spaces/ownership.d.ts +12 -0
- package/dist/commands/spaces/ownership.js +46 -0
- package/dist/commands/tasks/cancel-cascade.js +1 -1
- package/dist/commands/tasks/create-tree.d.ts +5 -1
- package/dist/commands/tasks/create-tree.js +35 -7
- package/dist/commands/tasks/interrupt.js +2 -2
- package/dist/commands/tasks/pause-schedule.js +1 -1
- package/dist/commands/token/list.d.ts +3 -5
- package/dist/commands/token/list.js +99 -57
- package/dist/commands/update.d.ts +14 -0
- package/dist/commands/update.js +61 -0
- package/dist/generated/managed-instruction-guides.json +9 -0
- package/dist/hooks/init.d.ts +5 -0
- package/dist/hooks/init.js +27 -0
- package/dist/lib/commitment-product.d.ts +0 -6
- package/dist/lib/commitment-product.js +1 -30
- package/dist/lib/commitments.d.ts +9 -53
- package/dist/lib/commitments.js +23 -146
- package/dist/lib/daemon-installer.d.ts +2 -0
- package/dist/lib/daemon-installer.js +100 -24
- package/dist/lib/first-party-harness-doctor.js +31 -1
- package/dist/lib/first-party-harness-remote-install.d.ts +71 -0
- package/dist/lib/first-party-harness-remote-install.js +310 -0
- package/dist/lib/first-party-harness-remote-update.d.ts +46 -0
- package/dist/lib/first-party-harness-remote-update.js +242 -0
- package/dist/lib/first-party-harness-startup-update.d.ts +26 -0
- package/dist/lib/first-party-harness-startup-update.js +166 -0
- package/dist/lib/first-party-harness-update.d.ts +46 -0
- package/dist/lib/first-party-harness-update.js +289 -0
- package/dist/lib/first-party-harness.js +7 -4
- package/dist/lib/managed-instruction-local.d.ts +12 -0
- package/dist/lib/managed-instruction-local.js +58 -0
- package/dist/lib/managed-instruction-setup.d.ts +35 -0
- package/dist/lib/managed-instruction-setup.js +306 -0
- package/dist/lib/memory-sync.d.ts +1 -0
- package/dist/lib/memory-sync.js +279 -68
- package/dist/lib/northstars.js +1 -1
- package/dist/lib/platform-update-local.d.ts +2 -0
- package/dist/lib/platform-update-local.js +113 -0
- package/dist/lib/platform-update.d.ts +39 -0
- package/dist/lib/platform-update.js +84 -0
- package/dist/lib/profile-machine-identity-guard.d.ts +2 -0
- package/dist/lib/profile-machine-identity-guard.js +13 -0
- package/dist/lib/prompt.d.ts +1 -0
- package/dist/lib/prompt.js +4 -3
- package/dist/lib/roles.d.ts +98 -0
- package/dist/lib/roles.js +45 -0
- package/dist/lib/task-batch.d.ts +9 -0
- package/dist/lib/task-batch.js +94 -17
- package/dist/lib/task-instruction-offer.d.ts +1 -4
- package/dist/lib/task-instruction-offer.js +3 -129
- package/dist/lib/update-check.d.ts +61 -53
- package/dist/lib/update-check.js +453 -314
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/commitmentExecutionContract.d.ts +45 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/commitmentExecutionContract.js +550 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.d.ts +3 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.js +3 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessReleaseKeys.d.ts +82 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessReleaseKeys.js +105 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessUpdater.d.ts +110 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessUpdater.js +945 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessPermissionControls.d.ts +32 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessPermissionControls.js +62 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +4 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineUuid.js +35 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releasePolicy.d.ts +63 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releasePolicy.js +169 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releaseVersions.d.ts +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releaseVersions.js +44 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/sessionPermissionAuthority.d.ts +7 -44
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/sessionPermissionAuthority.js +8 -47
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/commitmentExecutionContract.d.ts +45 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/commitmentExecutionContract.js +545 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.d.ts +3 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.js +3 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessReleaseKeys.d.ts +82 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessReleaseKeys.js +102 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessUpdater.d.ts +110 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessUpdater.js +923 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessPermissionControls.d.ts +32 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessPermissionControls.js +59 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineUuid.js +35 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releasePolicy.d.ts +63 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releasePolicy.js +163 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releaseVersions.d.ts +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releaseVersions.js +41 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/sessionPermissionAuthority.d.ts +7 -44
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/sessionPermissionAuthority.js +8 -47
- package/dist/node_modules/@skrr-ai/auth-core/package.json +41 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +7362 -7232
- package/dist/node_modules/@skrr-ai/data-provider/package.json +2 -2
- package/docs/v1/README.md +28 -0
- package/docs/v1/api.md +55 -0
- package/docs/v1/changelog.md +16 -0
- package/docs/v1/check-examples.mjs +178 -0
- package/docs/v1/examples/api-readonly.mjs +144 -0
- package/docs/v1/operations.md +87 -0
- package/docs/v1/quickstart.md +71 -0
- package/oclif.manifest.json +46381 -45478
- package/package.json +16 -11
- package/dist/commands/commitments/autonomy.d.ts +0 -30
- package/dist/commands/commitments/autonomy.js +0 -67
- package/dist/commands/commitments/mode.js +0 -58
- package/dist/commands/commitments/pack/promote.d.ts +0 -19
- package/dist/commands/commitments/pack/promote.js +0 -46
- package/dist/commands/commitments/pack/shadow.d.ts +0 -20
- package/dist/commands/commitments/pack/shadow.js +0 -42
|
@@ -84,6 +84,10 @@ class DaemonInstall extends core_1.Command {
|
|
|
84
84
|
// is how a CLI and its daemon end up on different deployments
|
|
85
85
|
// (OSK-279) without anyone doing anything wrong.
|
|
86
86
|
const code = await (0, exec_runtime_binary_1.execRuntimeBinary)(['install', ...(0, daemon_binding_1.bindToCliSession)(argv)]);
|
|
87
|
+
if (code === 0 &&
|
|
88
|
+
!argv.some((arg) => ['--json', '--help', '-h'].includes(arg))) {
|
|
89
|
+
this.log('Coding-agent instructions: sign in with `skrr login`, or review installation choices with `skrr instructions setup`.');
|
|
90
|
+
}
|
|
87
91
|
this.exit(code);
|
|
88
92
|
}
|
|
89
93
|
catch (err) {
|
|
@@ -6,7 +6,9 @@ import { BaseCommand } from '../base-command';
|
|
|
6
6
|
* POST /api/auth/recovery/generate. The formatted code is printed
|
|
7
7
|
* exactly once to STDOUT; a warning goes to STDERR.
|
|
8
8
|
*
|
|
9
|
-
* Requires
|
|
9
|
+
* Requires a user sign-in session (NOT a CI token or PAT). When the server
|
|
10
|
+
* requests a fresh proof, this command verifies it for recovery_code_generate
|
|
11
|
+
* on the same session before retrying the generation exactly once.
|
|
10
12
|
* On success: any previously-active recovery code is revoked server-side
|
|
11
13
|
* and the new one is returned.
|
|
12
14
|
*
|
|
@@ -19,6 +21,16 @@ export default class GenerateRecoveryCode extends BaseCommand {
|
|
|
19
21
|
static examples: string[];
|
|
20
22
|
static flags: {
|
|
21
23
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
|
+
otp: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
25
|
+
'backup-code': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
26
|
+
'email-code': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
27
|
};
|
|
23
28
|
run(): Promise<void>;
|
|
29
|
+
private generate;
|
|
30
|
+
private proofFor;
|
|
31
|
+
private nonemptyCode;
|
|
32
|
+
private refuseUnavailableMethod;
|
|
33
|
+
private refusePasskeyOnly;
|
|
34
|
+
private refuseStepUp;
|
|
35
|
+
private handleGenerationError;
|
|
24
36
|
}
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
4
5
|
const base_command_1 = require("../base-command");
|
|
5
6
|
const api_fetch_1 = require("../lib/api-fetch");
|
|
7
|
+
const prompt_1 = require("../lib/prompt");
|
|
8
|
+
// Include passkey even though this terminal cannot run a WebAuthn ceremony.
|
|
9
|
+
// The server uses this header when choosing the account's strongest proof:
|
|
10
|
+
// omitting passkey would make a passkey-only account fall back to email.
|
|
11
|
+
// A passkey-only challenge is refused below with a first-party web handoff.
|
|
12
|
+
const STEP_UP_HEADERS = { 'X-Step-Up-Methods': 'passkey,totp,backup_code,email_code' };
|
|
13
|
+
const PURPOSE = data_provider_1.RECOVERY_CODE_GENERATE_STEP_UP_PURPOSE;
|
|
6
14
|
/**
|
|
7
15
|
* `skrr generate-recovery-code`
|
|
8
16
|
*
|
|
@@ -10,7 +18,9 @@ const api_fetch_1 = require("../lib/api-fetch");
|
|
|
10
18
|
* POST /api/auth/recovery/generate. The formatted code is printed
|
|
11
19
|
* exactly once to STDOUT; a warning goes to STDERR.
|
|
12
20
|
*
|
|
13
|
-
* Requires
|
|
21
|
+
* Requires a user sign-in session (NOT a CI token or PAT). When the server
|
|
22
|
+
* requests a fresh proof, this command verifies it for recovery_code_generate
|
|
23
|
+
* on the same session before retrying the generation exactly once.
|
|
14
24
|
* On success: any previously-active recovery code is revoked server-side
|
|
15
25
|
* and the new one is returned.
|
|
16
26
|
*
|
|
@@ -22,6 +32,8 @@ class GenerateRecoveryCode extends base_command_1.BaseCommand {
|
|
|
22
32
|
static description = 'Generate a printable account-recovery code. Shown once — store it safely. Recovery codes use letters A-Z and digits 2-7.';
|
|
23
33
|
static examples = [
|
|
24
34
|
'<%= config.bin %> generate-recovery-code',
|
|
35
|
+
'<%= config.bin %> generate-recovery-code --otp 123456',
|
|
36
|
+
'<%= config.bin %> generate-recovery-code --backup-code <unused-code>',
|
|
25
37
|
'<%= config.bin %> generate-recovery-code --json',
|
|
26
38
|
];
|
|
27
39
|
static flags = {
|
|
@@ -29,28 +41,60 @@ class GenerateRecoveryCode extends base_command_1.BaseCommand {
|
|
|
29
41
|
description: 'Output as JSON (for scripting). Code still printed only once.',
|
|
30
42
|
default: false,
|
|
31
43
|
}),
|
|
44
|
+
otp: core_1.Flags.string({
|
|
45
|
+
description: 'Current code from your authenticator app when a fresh proof is required',
|
|
46
|
+
exclusive: ['backup-code', 'email-code'],
|
|
47
|
+
}),
|
|
48
|
+
'backup-code': core_1.Flags.string({
|
|
49
|
+
description: 'Unused two-factor backup code when a fresh proof is required (it is spent)',
|
|
50
|
+
exclusive: ['otp', 'email-code'],
|
|
51
|
+
}),
|
|
52
|
+
'email-code': core_1.Flags.string({
|
|
53
|
+
description: 'Previously requested one-time email code when a fresh proof is required',
|
|
54
|
+
exclusive: ['otp', 'backup-code'],
|
|
55
|
+
}),
|
|
32
56
|
};
|
|
33
57
|
async run() {
|
|
34
58
|
this.requireAuth();
|
|
35
59
|
const { flags } = await this.parse(GenerateRecoveryCode);
|
|
36
|
-
//
|
|
37
|
-
if (this.resolvedCredential.kind === 'ci') {
|
|
38
|
-
this.error('CI tokens cannot generate recovery codes.
|
|
60
|
+
// Static credentials cannot mint account recovery credentials.
|
|
61
|
+
if (this.resolvedCredential.kind === 'ci' || this.resolvedCredential.kind === 'pat') {
|
|
62
|
+
this.error('CI and personal access tokens cannot generate recovery codes. Sign in with `skrr login` first.', { exit: 2 });
|
|
39
63
|
}
|
|
40
64
|
let result;
|
|
41
65
|
try {
|
|
42
|
-
result = await (
|
|
43
|
-
method: 'POST',
|
|
44
|
-
credential: this.resolvedCredential,
|
|
45
|
-
});
|
|
66
|
+
result = await this.generate();
|
|
46
67
|
}
|
|
47
68
|
catch (err) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
69
|
+
const challenge = err instanceof api_fetch_1.ApiFetchError && err.status === 403 ? (0, data_provider_1.stepUpChallengeFromError)(err) : null;
|
|
70
|
+
if (!challenge)
|
|
71
|
+
this.handleGenerationError(err);
|
|
72
|
+
if (challenge.purpose !== PURPOSE) {
|
|
73
|
+
this.error('The server asked for verification of a different action. Nothing changed.', {
|
|
74
|
+
code: 'STEP_UP_PURPOSE_MISMATCH',
|
|
75
|
+
exit: 2,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
if (challenge.reason !== 'no_recent_step_up')
|
|
79
|
+
this.refuseStepUp(challenge);
|
|
80
|
+
const proof = await this.proofFor(challenge, flags);
|
|
81
|
+
try {
|
|
82
|
+
await (0, api_fetch_1.apiFetch)('/api/auth/step-up', {
|
|
83
|
+
method: 'POST',
|
|
84
|
+
credential: this.resolvedCredential,
|
|
85
|
+
headers: STEP_UP_HEADERS,
|
|
86
|
+
body: { purpose: PURPOSE, ...proof },
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch (verifyError) {
|
|
90
|
+
this.handleApiError(verifyError);
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
result = await this.generate();
|
|
94
|
+
}
|
|
95
|
+
catch (retryError) {
|
|
96
|
+
this.handleGenerationError(retryError);
|
|
52
97
|
}
|
|
53
|
-
this.handleApiError(err);
|
|
54
98
|
}
|
|
55
99
|
if (flags.json) {
|
|
56
100
|
// JSON mode: print structured output to stdout for scripting.
|
|
@@ -75,5 +119,94 @@ class GenerateRecoveryCode extends base_command_1.BaseCommand {
|
|
|
75
119
|
process.stderr.write(` Generated at: ${new Date(result.createdAt).toISOString()}\n`);
|
|
76
120
|
process.stderr.write('\n');
|
|
77
121
|
}
|
|
122
|
+
generate() {
|
|
123
|
+
return (0, api_fetch_1.apiFetch)('/api/auth/recovery/generate', {
|
|
124
|
+
method: 'POST',
|
|
125
|
+
credential: this.resolvedCredential,
|
|
126
|
+
headers: STEP_UP_HEADERS,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
async proofFor(challenge, flags) {
|
|
130
|
+
if (challenge.methods.includes('passkey') &&
|
|
131
|
+
!challenge.methods.includes('totp') &&
|
|
132
|
+
!challenge.methods.includes('backup_code')) {
|
|
133
|
+
this.refusePasskeyOnly();
|
|
134
|
+
}
|
|
135
|
+
if (flags.otp !== undefined) {
|
|
136
|
+
if (!challenge.methods.includes('totp'))
|
|
137
|
+
this.refuseUnavailableMethod();
|
|
138
|
+
return { token: this.nonemptyCode(flags.otp) };
|
|
139
|
+
}
|
|
140
|
+
if (flags['backup-code'] !== undefined) {
|
|
141
|
+
if (!challenge.methods.includes('backup_code'))
|
|
142
|
+
this.refuseUnavailableMethod();
|
|
143
|
+
return { backupCode: this.nonemptyCode(flags['backup-code']) };
|
|
144
|
+
}
|
|
145
|
+
if (flags['email-code'] !== undefined) {
|
|
146
|
+
if (!challenge.methods.includes('email_code'))
|
|
147
|
+
this.refuseUnavailableMethod();
|
|
148
|
+
return { emailCode: this.nonemptyCode(flags['email-code']) };
|
|
149
|
+
}
|
|
150
|
+
if (!process.stdin.isTTY) {
|
|
151
|
+
this.error('A fresh identity check is required. Run this command at a terminal, or pass --otp, --backup-code, or a previously requested --email-code. Nothing changed.', { code: 'STEP_UP_PROOF_REQUIRED', exit: 2 });
|
|
152
|
+
}
|
|
153
|
+
if (challenge.methods.includes('totp')) {
|
|
154
|
+
const entered = await (0, prompt_1.prompt)('Authenticator code: ', {
|
|
155
|
+
hidden: true,
|
|
156
|
+
output: process.stderr,
|
|
157
|
+
});
|
|
158
|
+
return { token: this.nonemptyCode(entered) };
|
|
159
|
+
}
|
|
160
|
+
if (challenge.methods.includes('backup_code')) {
|
|
161
|
+
const entered = await (0, prompt_1.prompt)('Unused two-factor backup code: ', {
|
|
162
|
+
hidden: true,
|
|
163
|
+
output: process.stderr,
|
|
164
|
+
});
|
|
165
|
+
return { backupCode: this.nonemptyCode(entered) };
|
|
166
|
+
}
|
|
167
|
+
if (challenge.methods.includes('email_code')) {
|
|
168
|
+
try {
|
|
169
|
+
await (0, api_fetch_1.apiFetch)('/api/auth/step-up/email-code', {
|
|
170
|
+
method: 'POST',
|
|
171
|
+
credential: this.resolvedCredential,
|
|
172
|
+
headers: STEP_UP_HEADERS,
|
|
173
|
+
body: { purpose: PURPOSE },
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
catch (requestError) {
|
|
177
|
+
this.handleApiError(requestError);
|
|
178
|
+
}
|
|
179
|
+
process.stderr.write('A one-time code was sent to your account email.\n');
|
|
180
|
+
const entered = await (0, prompt_1.prompt)('Email code: ', { hidden: true, output: process.stderr });
|
|
181
|
+
return { emailCode: this.nonemptyCode(entered) };
|
|
182
|
+
}
|
|
183
|
+
this.refuseUnavailableMethod();
|
|
184
|
+
}
|
|
185
|
+
nonemptyCode(value) {
|
|
186
|
+
const code = value.trim();
|
|
187
|
+
if (!code)
|
|
188
|
+
this.error('A verification code cannot be empty. Nothing changed.', { exit: 2 });
|
|
189
|
+
return code;
|
|
190
|
+
}
|
|
191
|
+
refuseUnavailableMethod() {
|
|
192
|
+
this.error('This login has no identity-check method the CLI can complete. Use Settings → Account in the web app, or enroll an authenticator and try again. Nothing changed.', { code: 'STEP_UP_METHOD_UNAVAILABLE', exit: 2 });
|
|
193
|
+
}
|
|
194
|
+
refusePasskeyOnly() {
|
|
195
|
+
this.error('This account requires a passkey for this identity check. Open Settings → Account in the web app to generate a recovery code. Nothing changed.', { code: 'STEP_UP_PASSKEY_REQUIRED', exit: 2 });
|
|
196
|
+
}
|
|
197
|
+
refuseStepUp(challenge) {
|
|
198
|
+
if (challenge.reason === 'credential_not_session_bound') {
|
|
199
|
+
this.error('This credential has no sign-in session for an identity check. Run `skrr login` and try again. Nothing changed.', { code: 'STEP_UP_SESSION_UNBOUND', exit: 2 });
|
|
200
|
+
}
|
|
201
|
+
this.refuseUnavailableMethod();
|
|
202
|
+
}
|
|
203
|
+
handleGenerationError(err) {
|
|
204
|
+
if (err instanceof api_fetch_1.ApiFetchError && (err.status === 401 || err.status === 403)) {
|
|
205
|
+
this.error('Not authorized to generate a recovery code. Sign in with a user-scope session.', {
|
|
206
|
+
exit: 1,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
this.handleApiError(err);
|
|
210
|
+
}
|
|
78
211
|
}
|
|
79
212
|
exports.default = GenerateRecoveryCode;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class InstructionsGuide extends Command {
|
|
3
|
+
static baseFlags: {
|
|
4
|
+
bare: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
5
|
+
token: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
6
|
+
workspace: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
profile: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
raw: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
static description: string;
|
|
11
|
+
static args: {
|
|
12
|
+
name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
13
|
+
};
|
|
14
|
+
static flags: {
|
|
15
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
offline: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
17
|
+
};
|
|
18
|
+
static examples: string[];
|
|
19
|
+
run(): Promise<void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const core_1 = require("@oclif/core");
|
|
7
|
+
const node_crypto_1 = require("node:crypto");
|
|
8
|
+
const base_command_1 = require("../../base-command");
|
|
9
|
+
const managed_instruction_guides_json_1 = __importDefault(require("../../generated/managed-instruction-guides.json"));
|
|
10
|
+
const api_fetch_1 = require("../../lib/api-fetch");
|
|
11
|
+
const auth_core_init_1 = require("../../lib/auth-core-init");
|
|
12
|
+
const credential_resolver_1 = require("../../lib/credential-resolver");
|
|
13
|
+
const harness_context_1 = require("../../lib/harness-context");
|
|
14
|
+
const keychain_1 = require("../../lib/keychain");
|
|
15
|
+
// Documentation stays available when a daemon-issued Agent credential is
|
|
16
|
+
// unavailable. Do not run BaseCommand's mandatory credential initialization.
|
|
17
|
+
class InstructionsGuide extends core_1.Command {
|
|
18
|
+
static baseFlags = base_command_1.BaseCommand.baseFlags;
|
|
19
|
+
static description = 'Read the detailed task-management guide on demand';
|
|
20
|
+
static args = {
|
|
21
|
+
name: core_1.Args.string({
|
|
22
|
+
description: 'Guide to read',
|
|
23
|
+
options: ['task-management'],
|
|
24
|
+
default: 'task-management',
|
|
25
|
+
ignoreStdin: true,
|
|
26
|
+
}),
|
|
27
|
+
};
|
|
28
|
+
static flags = {
|
|
29
|
+
json: core_1.Flags.boolean({ description: 'Output the guide and source provenance as JSON' }),
|
|
30
|
+
offline: core_1.Flags.boolean({
|
|
31
|
+
description: 'Read the bundled release guide without checking credentials or the server',
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
static examples = [
|
|
35
|
+
'<%= config.bin %> instructions guide task-management',
|
|
36
|
+
'<%= config.bin %> instructions guide --json',
|
|
37
|
+
];
|
|
38
|
+
async run() {
|
|
39
|
+
const { flags } = await this.parse(InstructionsGuide);
|
|
40
|
+
let guide = managed_instruction_guides_json_1.default['oversky-task-management'];
|
|
41
|
+
let source = 'bundled';
|
|
42
|
+
let reason = flags.offline ? 'offline-requested' : 'no-session';
|
|
43
|
+
if (!flags.offline) {
|
|
44
|
+
try {
|
|
45
|
+
(0, keychain_1.setActiveProfile)(flags.profile ?? process.env.OVERSKY_PROFILE ?? '');
|
|
46
|
+
const autonomous = (0, credential_resolver_1.resolveTrustedAutonomousCredential)();
|
|
47
|
+
if (!autonomous && !flags.bare && !(0, harness_context_1.isHarnessCliContext)())
|
|
48
|
+
await (0, auth_core_init_1.prefetchCliAuth)();
|
|
49
|
+
const credential = autonomous ??
|
|
50
|
+
(await (0, credential_resolver_1.resolveCredential)({
|
|
51
|
+
flagToken: flags.token,
|
|
52
|
+
bareMode: flags.bare,
|
|
53
|
+
allowUnreadableStoredCredential: true,
|
|
54
|
+
}));
|
|
55
|
+
if (credential.token) {
|
|
56
|
+
reason = 'server-unavailable';
|
|
57
|
+
const response = await (0, api_fetch_1.apiFetch)('/api/instructions/presets/oversky-task-management/guide', { credential, signal: AbortSignal.timeout(3_000) });
|
|
58
|
+
if ((0, node_crypto_1.createHash)('sha256').update(response.body).digest('hex') !== response.hash) {
|
|
59
|
+
throw new Error('The server guide hash does not match its body.');
|
|
60
|
+
}
|
|
61
|
+
guide = response;
|
|
62
|
+
source = 'server';
|
|
63
|
+
reason = undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// A missing/unreadable auth envelope or delegated daemon cannot make
|
|
68
|
+
// a read-only local guide unavailable, and must never emit auth JSON.
|
|
69
|
+
reason ??= 'server-unavailable';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (flags.json)
|
|
73
|
+
this.log(JSON.stringify({
|
|
74
|
+
...guide,
|
|
75
|
+
provenance: { source, fallback: source === 'bundled', ...(reason ? { reason } : {}) },
|
|
76
|
+
}, null, 2));
|
|
77
|
+
else {
|
|
78
|
+
if (source === 'bundled')
|
|
79
|
+
this.logToStderr(`Using the CLI’s bundled task-management guide (template v${guide.templateVersion}).`);
|
|
80
|
+
this.log(guide.body);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.default = InstructionsGuide;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.conflictingTargetOf = conflictingTargetOf;
|
|
4
4
|
exports.describeTargetConflict = describeTargetConflict;
|
|
5
5
|
const core_1 = require("@oclif/core");
|
|
6
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
7
|
const auth_core_1 = require("@skrr-ai/auth-core");
|
|
7
8
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
8
9
|
const base_command_1 = require("../../base-command");
|
|
@@ -107,41 +108,67 @@ class InstructionsInstall extends base_command_1.BaseCommand {
|
|
|
107
108
|
exit: 2,
|
|
108
109
|
});
|
|
109
110
|
}
|
|
110
|
-
|
|
111
|
+
const daemonId = await this.resolveDaemon(flags.daemon);
|
|
112
|
+
const inputs = providers.map((provider) => ({
|
|
113
|
+
daemonId,
|
|
114
|
+
bundleId: flags.bundle,
|
|
115
|
+
provider,
|
|
116
|
+
scope,
|
|
117
|
+
mode: flags.mode,
|
|
118
|
+
projectPath: flags.project,
|
|
119
|
+
trackingMode: flags.pin ? 'pinned' : 'latest',
|
|
120
|
+
pinnedVersionId: flags.pin,
|
|
121
|
+
label: flags.label,
|
|
122
|
+
}));
|
|
123
|
+
// Inspect the selected machine before any consent or target write. This is
|
|
124
|
+
// also required for --yes: unattended consent does not waive readability.
|
|
125
|
+
let preparedTargets;
|
|
111
126
|
try {
|
|
112
|
-
|
|
113
|
-
if (flags.pin) {
|
|
114
|
-
const versions = await data_provider_1.dataService.listManagedInstructionVersions(flags.bundle, true);
|
|
115
|
-
const pinned = versions.versions.find((version) => version.id === flags.pin);
|
|
116
|
-
if (!pinned || pinned.archivedAt) {
|
|
117
|
-
this.error('The requested pinned version is missing or archived', { exit: 2 });
|
|
118
|
-
}
|
|
119
|
-
previewBody = pinned.body;
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
if (!bundle.currentVersion)
|
|
123
|
-
this.error('The prompt has no current version', { exit: 2 });
|
|
124
|
-
previewBody = bundle.currentVersion.body;
|
|
125
|
-
}
|
|
127
|
+
preparedTargets = await Promise.all(inputs.map((input) => data_provider_1.dataService.prepareManagedInstructionTarget(input)));
|
|
126
128
|
}
|
|
127
129
|
catch (error) {
|
|
128
130
|
this.handleApiError(error);
|
|
129
131
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
+
for (let index = 0; index < preparedTargets.length; index += 1) {
|
|
133
|
+
const entry = preparedTargets[index];
|
|
134
|
+
const provider = providers[index];
|
|
135
|
+
const placement = entry.providers.find((candidate) => candidate.provider === provider);
|
|
136
|
+
const preview = entry.previews.find((candidate) => candidate.provider === provider);
|
|
137
|
+
if (entry.daemonId !== daemonId || entry.readiness !== 'ready') {
|
|
138
|
+
this.error(entry.message ||
|
|
139
|
+
'The selected daemon cannot inspect its instruction files. Update or reconnect it and retry; no targets were created.', { exit: 1 });
|
|
140
|
+
}
|
|
141
|
+
if (!placement?.canInstall ||
|
|
142
|
+
!placement.instructionPath ||
|
|
143
|
+
placement.loadingStatus === 'shadowed') {
|
|
144
|
+
this.error(`${(0, harness_provider_input_1.canonicalHarnessInput)(provider)} cannot use this placement: ${placement?.issues.map((issue) => issue.message).join(' ') || placement?.loadingStatus || 'preflight unavailable'}. No targets were created.`, { exit: 1 });
|
|
145
|
+
}
|
|
146
|
+
if (!preview || (0, node_crypto_1.createHash)('sha256').update(preview.body).digest('hex') !== preview.hash) {
|
|
147
|
+
this.error('The instruction preview could not be verified; no targets were created.', {
|
|
148
|
+
exit: 1,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (!flags.json) {
|
|
152
|
+
this.log(`${(0, harness_provider_input_1.canonicalHarnessInput)(provider)} on ${daemonId}: ${placement.instructionPath} (${placement.loadingStatus})`);
|
|
153
|
+
for (const issue of placement.issues)
|
|
154
|
+
this.log(` ${issue.severity}: ${issue.message}`);
|
|
155
|
+
}
|
|
132
156
|
}
|
|
133
157
|
// The body is shown so the confirmation below is informed. With `--yes`
|
|
134
158
|
// there is no confirmation to inform, and printing a ~9 KB body anyway put
|
|
135
159
|
// the command's actual outcome — often a refusal — a screen of scrollback
|
|
136
160
|
// away (OSK-4631). Say what was authorized, and where to read it.
|
|
137
161
|
if (!flags.json && !flags.yes) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
162
|
+
for (let index = 0; index < providers.length; index += 1) {
|
|
163
|
+
const preview = preparedTargets[index].previews.find((entry) => entry.provider === providers[index]);
|
|
164
|
+
this.log(`Exact ${(0, harness_provider_input_1.canonicalHarnessInput)(providers[index])} managed instruction body (SHA-256 ${preview.hash}):`);
|
|
165
|
+
this.log('---');
|
|
166
|
+
this.log(preview.body);
|
|
167
|
+
this.log('---');
|
|
168
|
+
}
|
|
142
169
|
}
|
|
143
170
|
else if (!flags.json) {
|
|
144
|
-
this.log(`Authorizing ${Buffer.byteLength(
|
|
171
|
+
this.log(`Authorizing ${Buffer.byteLength(preparedTargets[0].version.body, 'utf8').toLocaleString()} bytes of instruction ` +
|
|
145
172
|
`${flags.bundle}; \`${this.config.bin} instructions show ${flags.bundle}\` prints them.`);
|
|
146
173
|
}
|
|
147
174
|
const teamWarning = scope === 'project' && flags.mode === 'team'
|
|
@@ -150,20 +177,17 @@ class InstructionsInstall extends base_command_1.BaseCommand {
|
|
|
150
177
|
const confirmed = await (0, prompt_1.confirmDestructive)(`Authorize continuous ${providers.join(', ')} reconciliation on this target?${teamWarning}`, flags.yes);
|
|
151
178
|
if (!confirmed)
|
|
152
179
|
return this.log('Aborted.');
|
|
153
|
-
const daemonId = await this.resolveDaemon(flags.daemon);
|
|
154
180
|
const results = [];
|
|
155
|
-
for (
|
|
181
|
+
for (let index = 0; index < providers.length; index += 1) {
|
|
182
|
+
const provider = providers[index];
|
|
183
|
+
const entry = preparedTargets[index];
|
|
156
184
|
try {
|
|
157
185
|
results.push(await data_provider_1.dataService.createManagedInstructionTarget({
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
projectPath: flags.project,
|
|
164
|
-
trackingMode: flags.pin ? 'pinned' : 'latest',
|
|
165
|
-
pinnedVersionId: flags.pin,
|
|
166
|
-
label: flags.label,
|
|
186
|
+
...inputs[index],
|
|
187
|
+
expectedHash: entry.version.hash,
|
|
188
|
+
expectedVersionId: entry.version.id,
|
|
189
|
+
expectedRenderedHash: entry.previews.find((preview) => preview.provider === provider)
|
|
190
|
+
.hash,
|
|
167
191
|
}));
|
|
168
192
|
}
|
|
169
193
|
catch (error) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
export default class InstructionsSetup extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
daemon: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
provider: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
'update-policy': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
|
+
yes: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
review: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const auth_core_1 = require("@skrr-ai/auth-core");
|
|
5
|
+
const base_command_1 = require("../../base-command");
|
|
6
|
+
const harness_provider_input_1 = require("../../lib/harness-provider-input");
|
|
7
|
+
const managed_instruction_setup_1 = require("../../lib/managed-instruction-setup");
|
|
8
|
+
class InstructionsSetup extends base_command_1.BaseCommand {
|
|
9
|
+
static description = 'Review and install removable global instructions for coding agents on this machine.\n\n' +
|
|
10
|
+
'Verifies the local daemon’s account, server and profile, then asks that daemon to check ' +
|
|
11
|
+
'its real instruction files. Choose providers separately and choose automatic updates or ' +
|
|
12
|
+
'a fixed current version. Existing installation decisions are preserved. Pass --daemon ' +
|
|
13
|
+
'to explicitly choose another connected machine. No files are written by the CLI.';
|
|
14
|
+
static examples = [
|
|
15
|
+
'<%= config.bin %> instructions setup',
|
|
16
|
+
'<%= config.bin %> instructions setup --provider codex --review',
|
|
17
|
+
'<%= config.bin %> instructions setup --provider claude --update-policy pinned --yes --json',
|
|
18
|
+
'<%= config.bin %> instructions setup --daemon <id> --provider codex --update-policy latest --yes',
|
|
19
|
+
];
|
|
20
|
+
static flags = {
|
|
21
|
+
daemon: core_1.Flags.string({
|
|
22
|
+
description: 'Explicit connected daemon ID; defaults only to a verified daemon on this computer',
|
|
23
|
+
}),
|
|
24
|
+
provider: core_1.Flags.string({
|
|
25
|
+
description: 'Provider to set up or revisit (repeatable); otherwise offers newly detected providers',
|
|
26
|
+
options: (0, harness_provider_input_1.harnessFlagOptions)(['claude', 'codex', auth_core_1.FIRST_PARTY_HARNESS.provider]),
|
|
27
|
+
multiple: true,
|
|
28
|
+
}),
|
|
29
|
+
'update-policy': core_1.Flags.string({
|
|
30
|
+
description: 'Track automatic updates, or pin today’s reviewed version',
|
|
31
|
+
options: ['latest', 'pinned'],
|
|
32
|
+
}),
|
|
33
|
+
yes: core_1.Flags.boolean({
|
|
34
|
+
char: 'y',
|
|
35
|
+
description: 'Authorize selected providers and update policy without prompting; requires --provider and --update-policy',
|
|
36
|
+
}),
|
|
37
|
+
review: core_1.Flags.boolean({
|
|
38
|
+
description: 'Show exact previews and daemon preflight without installing or changing decisions',
|
|
39
|
+
}),
|
|
40
|
+
json: core_1.Flags.boolean({ description: 'Output one JSON result; requires --review or --yes' }),
|
|
41
|
+
};
|
|
42
|
+
async run() {
|
|
43
|
+
this.requireAuth();
|
|
44
|
+
const { flags } = await this.parse(InstructionsSetup);
|
|
45
|
+
if (flags.json && !flags.review && !flags.yes)
|
|
46
|
+
this.error('--json requires --review or --yes', { exit: 2 });
|
|
47
|
+
if (flags.review && flags.yes)
|
|
48
|
+
this.error('--review cannot be combined with --yes', { exit: 2 });
|
|
49
|
+
try {
|
|
50
|
+
const result = await (0, managed_instruction_setup_1.runManagedInstructionSetup)({
|
|
51
|
+
trigger: 'manual',
|
|
52
|
+
log: flags.json ? () => { } : (message) => this.log(message),
|
|
53
|
+
daemonId: flags.daemon,
|
|
54
|
+
providers: flags.provider
|
|
55
|
+
? (0, harness_provider_input_1.canonicalHarnessInputs)(flags.provider)
|
|
56
|
+
: undefined,
|
|
57
|
+
trackingMode: flags['update-policy'],
|
|
58
|
+
yes: flags.yes,
|
|
59
|
+
review: flags.review,
|
|
60
|
+
json: flags.json,
|
|
61
|
+
});
|
|
62
|
+
if (flags.json)
|
|
63
|
+
this.log(JSON.stringify(result, null, 2));
|
|
64
|
+
if (result.status === 'unavailable')
|
|
65
|
+
this.exit(1);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
this.handleApiError(error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.default = InstructionsSetup;
|
|
@@ -33,7 +33,7 @@ class IntegrationsExecute extends base_command_1.BaseCommand {
|
|
|
33
33
|
description: 'Agent ID (falls back to OVERSKY_AGENT_ID, then primary agent)',
|
|
34
34
|
}),
|
|
35
35
|
'request-id': core_1.Flags.string({
|
|
36
|
-
description: '
|
|
36
|
+
description: 'Reuse only for the same tool, arguments and connection. A pending or unknown outcome requires reconciliation before another write (auto-generated if omitted)',
|
|
37
37
|
}),
|
|
38
38
|
json: core_1.Flags.boolean({
|
|
39
39
|
description: 'Output full response as JSON (recommended for daemon use)',
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -12,14 +12,13 @@ import { BaseCommand } from '../base-command';
|
|
|
12
12
|
* Refresh, rotation, family revoke, and the cross-process auth.lock are
|
|
13
13
|
* all the same substrate the daemon uses (@skrr-ai/auth-core).
|
|
14
14
|
*
|
|
15
|
-
* CI.
|
|
16
|
-
* `
|
|
17
|
-
*
|
|
18
|
-
* command rejects it with 401 (see create-token.ts and base-command.ts). What
|
|
19
|
-
* works today is a session minted for the machine with
|
|
15
|
+
* CI. `skrr tokens create` mints an expiring, revocable personal access token
|
|
16
|
+
* (`osk_pat_*`) for SKRR_TOKEN. It does not rotate and is distinct from a
|
|
17
|
+
* per-machine SESSION minted with
|
|
20
18
|
* `skrr token mint --for <id>`, restored by the `OVERSKY_REFRESH_TOKEN` path
|
|
21
19
|
* below — whose refresh token rotates on use — or `OVERSKY_AUTH_HELPER`.
|
|
22
|
-
* docs/cli/SKRR_AUTH.md
|
|
20
|
+
* docs/cli/SKRR_AUTH.md states credential precedence and revocation scopes.
|
|
21
|
+
* Legacy `skrr create-token` credentials only bootstrap a daemon.
|
|
23
22
|
*
|
|
24
23
|
* L13 — non-interactive restore from a refresh token. When
|
|
25
24
|
* `OVERSKY_REFRESH_TOKEN` is set in the environment, the browser /
|