@skrr-ai/cli 0.1.50 → 0.1.52
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 +7 -0
- package/dist/base-command.js +95 -8
- package/dist/commands/agents/chat.d.ts +14 -0
- package/dist/commands/agents/chat.js +37 -1
- package/dist/commands/agents/create.js +8 -4
- package/dist/commands/agents/show.d.ts +9 -0
- package/dist/commands/agents/show.js +53 -0
- package/dist/commands/agents/update.d.ts +32 -0
- package/dist/commands/agents/update.js +81 -9
- package/dist/commands/balance/show.d.ts +34 -0
- package/dist/commands/balance/show.js +92 -2
- package/dist/commands/commitments/doctor.d.ts +1 -0
- package/dist/commands/commitments/doctor.js +19 -4
- package/dist/commands/commitments/effective-policy.js +15 -1
- package/dist/commands/commitments/next-tick.js +12 -2
- package/dist/commands/commitments/preflight.js +10 -0
- package/dist/commands/commitments/show.js +11 -1
- package/dist/commands/context.js +2 -1
- package/dist/commands/daemon/config.d.ts +15 -0
- package/dist/commands/daemon/config.js +53 -0
- package/dist/commands/daemon/index.js +1 -0
- package/dist/commands/daemon/status.js +15 -1
- package/dist/commands/doctor.js +8 -1
- package/dist/commands/harnesses/models.d.ts +54 -0
- package/dist/commands/harnesses/models.js +100 -7
- package/dist/commands/harnesses/show.d.ts +11 -0
- package/dist/commands/harnesses/show.js +35 -0
- package/dist/commands/harnesses/update.d.ts +28 -1
- package/dist/commands/harnesses/update.js +73 -10
- package/dist/commands/login.d.ts +2 -1
- package/dist/commands/login.js +26 -7
- package/dist/commands/logout.js +3 -0
- package/dist/commands/machines/dedicated/show.js +25 -2
- package/dist/commands/outbox/list.d.ts +12 -1
- package/dist/commands/outbox/list.js +31 -2
- package/dist/commands/revoke-daemon.js +9 -0
- package/dist/commands/spaces/create.d.ts +1 -0
- package/dist/commands/spaces/create.js +17 -0
- package/dist/commands/spaces/show.js +5 -0
- package/dist/commands/spaces/update.d.ts +1 -0
- package/dist/commands/spaces/update.js +16 -0
- package/dist/commands/tasks/create.d.ts +6 -0
- package/dist/commands/tasks/create.js +31 -6
- package/dist/commands/tasks/show.js +45 -0
- package/dist/commands/tasks/start.d.ts +14 -0
- package/dist/commands/tasks/start.js +31 -1
- package/dist/commands/tasks/update.d.ts +1 -0
- package/dist/commands/tasks/update.js +29 -1
- package/dist/commands/tasks/upsert.d.ts +1 -0
- package/dist/commands/tasks/upsert.js +16 -0
- package/dist/commands/whoami.js +5 -3
- package/dist/lib/agent-config.d.ts +2 -0
- package/dist/lib/agent-config.js +14 -10
- package/dist/lib/agentic-stream.d.ts +88 -1
- package/dist/lib/agentic-stream.js +330 -9
- package/dist/lib/auth-core-init.d.ts +2 -10
- package/dist/lib/auth-core-init.js +20 -67
- package/dist/lib/auth-failure.d.ts +33 -0
- package/dist/lib/auth-failure.js +68 -0
- package/dist/lib/auth-storage.d.ts +24 -0
- package/dist/lib/auth-storage.js +342 -11
- package/dist/lib/cli-id.d.ts +22 -0
- package/dist/lib/cli-id.js +56 -0
- package/dist/lib/cli-identity.d.ts +49 -0
- package/dist/lib/cli-identity.js +159 -0
- package/dist/lib/commitments.d.ts +25 -1
- package/dist/lib/commitments.js +46 -1
- package/dist/lib/config.d.ts +17 -0
- package/dist/lib/config.js +15 -3
- package/dist/lib/daemonBroker.d.ts +37 -1
- package/dist/lib/daemonBroker.js +146 -22
- package/dist/lib/daemonBrokerRefusal.d.ts +51 -0
- package/dist/lib/daemonBrokerRefusal.js +127 -0
- package/dist/lib/dedicated-machines.d.ts +33 -2
- package/dist/lib/dedicated-machines.js +50 -1
- package/dist/lib/delegated-cli.js +20 -1
- package/dist/lib/exec-runtime-binary.d.ts +3 -1
- package/dist/lib/exec-runtime-binary.js +4 -2
- package/dist/lib/first-party-harness-broker.js +10 -5
- package/dist/lib/harnesses.d.ts +10 -0
- package/dist/lib/keychain.d.ts +39 -0
- package/dist/lib/keychain.js +228 -39
- package/dist/lib/label-ref.d.ts +34 -0
- package/dist/lib/label-ref.js +68 -1
- package/dist/lib/live-runtime-binary.d.ts +40 -0
- package/dist/lib/live-runtime-binary.js +193 -0
- package/dist/lib/login.d.ts +23 -0
- package/dist/lib/login.js +67 -21
- package/dist/lib/message-intent.js +3 -1
- package/dist/lib/oauthLogin.js +2 -8
- package/dist/lib/refresh.js +6 -2
- package/dist/lib/tasks.d.ts +20 -0
- package/dist/lib/tasks.js +87 -8
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialEnvelopeBridge.d.ts +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialEnvelopeBridge.js +26 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.d.ts +28 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.js +23 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.js +41 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +25 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/loopbackHttp.d.ts +32 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/loopbackHttp.js +268 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineId.d.ts +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineId.js +11 -10
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineUuid.d.ts +36 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineUuid.js +156 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refresh.d.ts +8 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refresh.js +8 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +22 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +61 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialEnvelopeBridge.d.ts +2 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialEnvelopeBridge.js +25 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.d.ts +28 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.js +22 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.js +41 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +10 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/loopbackHttp.d.ts +32 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/loopbackHttp.js +257 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineId.d.ts +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineId.js +11 -10
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineUuid.d.ts +36 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineUuid.js +147 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refresh.d.ts +8 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refresh.js +8 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +22 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +58 -1
- package/dist/node_modules/@skrr-ai/auth-core/package.json +21 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +3139 -3097
- package/oclif.manifest.json +28591 -28438
- package/package.json +1 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.profileScopedCliId = profileScopedCliId;
|
|
40
|
+
exports.hasStoredCredential = hasStoredCredential;
|
|
41
|
+
exports.planLoginCliId = planLoginCliId;
|
|
42
|
+
exports.cliIdForLogin = cliIdForLogin;
|
|
43
|
+
exports.persistPresentedCliId = persistPresentedCliId;
|
|
44
|
+
/**
|
|
45
|
+
* cli-identity.ts — which cliId a LOGIN presents, and when a profile gets its own.
|
|
46
|
+
*
|
|
47
|
+
* Reading the identity is `resolveCliId()` in `config.ts` (it has to live there:
|
|
48
|
+
* `auth-storage.ts` judges credential ownership by it, and this module reads
|
|
49
|
+
* auth-storage). This module owns the one decision a read must never make —
|
|
50
|
+
* issuing an identity — and the one write that restores a backed-up pair.
|
|
51
|
+
*
|
|
52
|
+
* Why a profile needs its own (OSK-12156): the server's `cli-handoff/confirm`
|
|
53
|
+
* retires every OTHER live cli family of (user, cliId) once a hand-off lands.
|
|
54
|
+
* That is right for one config replacing its own previous session, and wrong
|
|
55
|
+
* when every profile on the machine presents the same machine-scoped `cliId`:
|
|
56
|
+
* profile B's daemon-brokered login then revoked profile A's session, silently.
|
|
57
|
+
* The server scoping is already per cliId, so the fix is the id, not the route.
|
|
58
|
+
*
|
|
59
|
+
* Why only a profile with NO stored credential: an existing session was minted
|
|
60
|
+
* under the machine id, and the refresh route refuses a rotation that presents
|
|
61
|
+
* another. Re-identifying such a profile would log it out on its next refresh —
|
|
62
|
+
* and a re-login under a new id would leave its old family live (the confirm
|
|
63
|
+
* only sweeps the id it was minted for) in a bucket the server evicts
|
|
64
|
+
* oldest-first. So a profile keeps presenting the id its credential is bound
|
|
65
|
+
* to, and only a profile starting from nothing is issued one. That is also why
|
|
66
|
+
* an upgrade forces no re-login: nothing that already works changes id.
|
|
67
|
+
*
|
|
68
|
+
* The default profile keeps the machine id. It IS the machine file, and it is
|
|
69
|
+
* the identity every pre-profile install already presents.
|
|
70
|
+
*/
|
|
71
|
+
const node_crypto_1 = require("node:crypto");
|
|
72
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
73
|
+
const path = __importStar(require("node:path"));
|
|
74
|
+
const auth_storage_1 = require("./auth-storage");
|
|
75
|
+
const config_1 = require("./config");
|
|
76
|
+
const cli_id_1 = require("./cli-id");
|
|
77
|
+
const device_id_1 = require("./device-id");
|
|
78
|
+
const keychain_1 = require("./keychain");
|
|
79
|
+
/**
|
|
80
|
+
* A named profile's own identity. Deterministic in (host, user, config root,
|
|
81
|
+
* profile), so a profile that loses its config file and signs in again is
|
|
82
|
+
* issued the same id rather than scattering families, and two profiles — or the
|
|
83
|
+
* same profile name under two config roots — never share one. Same `cli_<12hex>`
|
|
84
|
+
* shape as the machine id: the server requires the `cli_` namespace.
|
|
85
|
+
*/
|
|
86
|
+
function profileScopedCliId(profile = (0, keychain_1.getActiveProfile)(), root = (0, config_1.configRoot)()) {
|
|
87
|
+
const hostname = node_os_1.default.hostname();
|
|
88
|
+
const username = node_os_1.default.userInfo().username || 'unknown';
|
|
89
|
+
const digest = (0, node_crypto_1.createHash)('sha256')
|
|
90
|
+
.update(`${hostname}|${username}|cli|profile:${profile}|root:${path.resolve(root)}`)
|
|
91
|
+
.digest('hex');
|
|
92
|
+
return `cli_${digest.slice(0, 12)}`;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Does this profile hold a credential it would present? Its own backend slot
|
|
96
|
+
* (ownership-checked, any origin) or a pre-migration token still in the config.
|
|
97
|
+
*
|
|
98
|
+
* A read that FAILS answers true: "keep the id you already present" is the
|
|
99
|
+
* outcome that cannot log anyone out, so doubt falls on that side.
|
|
100
|
+
*/
|
|
101
|
+
function hasStoredCredential(cfg) {
|
|
102
|
+
if (cfg.token || cfg.refreshToken)
|
|
103
|
+
return true;
|
|
104
|
+
try {
|
|
105
|
+
const read = (0, auth_storage_1.readFromBackend)();
|
|
106
|
+
return Boolean(read.bundle?.token || read.bundle?.refreshToken);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Decide the id a login is about to present. Pure apart from the credential
|
|
114
|
+
* read; the caller persists `updatedConfig` (see `cliIdForLogin`).
|
|
115
|
+
*/
|
|
116
|
+
function planLoginCliId(cfg, deps = {}) {
|
|
117
|
+
const env = (0, cli_id_1.envCliIdOverride)();
|
|
118
|
+
if (env)
|
|
119
|
+
return { cliId: env, source: 'env' };
|
|
120
|
+
const issued = cfg.profileCliId?.trim();
|
|
121
|
+
if (issued)
|
|
122
|
+
return { cliId: issued, source: 'profile' };
|
|
123
|
+
if ((0, cli_id_1.isNamedProfile)() && !(deps.hasStoredCredential ?? hasStoredCredential)(cfg)) {
|
|
124
|
+
const cliId = profileScopedCliId();
|
|
125
|
+
return { cliId, source: 'issued', updatedConfig: { ...cfg, profileCliId: cliId } };
|
|
126
|
+
}
|
|
127
|
+
const machine = cfg.cliId?.trim();
|
|
128
|
+
if (machine)
|
|
129
|
+
return { cliId: machine, source: 'machine' };
|
|
130
|
+
const cliId = (0, device_id_1.generateCliId)();
|
|
131
|
+
return { cliId, source: 'machine', updatedConfig: { ...cfg, cliId } };
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The id an interactive login presents, persisted BEFORE the exchange so a
|
|
135
|
+
* retry — or a sibling process — presents the same one.
|
|
136
|
+
*/
|
|
137
|
+
function cliIdForLogin(cfg = (0, config_1.loadConfig)()) {
|
|
138
|
+
const plan = planLoginCliId(cfg);
|
|
139
|
+
if (plan.updatedConfig)
|
|
140
|
+
(0, config_1.saveConfig)(plan.updatedConfig);
|
|
141
|
+
return plan.cliId;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Record that this profile now presents `cliId` — a restored (refresh token,
|
|
145
|
+
* cliId) pair. A named profile records it as its own identity; writing the
|
|
146
|
+
* machine field from a named profile would re-identify the default profile and
|
|
147
|
+
* every profile still on the machine id, whose next refresh would be refused.
|
|
148
|
+
*/
|
|
149
|
+
function persistPresentedCliId(cfg, cliId) {
|
|
150
|
+
if ((0, cli_id_1.isNamedProfile)()) {
|
|
151
|
+
const current = cfg.profileCliId?.trim() || cfg.cliId?.trim();
|
|
152
|
+
if (current === cliId)
|
|
153
|
+
return;
|
|
154
|
+
(0, config_1.saveConfig)({ ...cfg, profileCliId: cliId });
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (cfg.cliId !== cliId)
|
|
158
|
+
(0, config_1.saveConfig)({ ...cfg, cliId });
|
|
159
|
+
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* "hold this state", derived from a Compass invariant — not authored here).
|
|
18
18
|
*/
|
|
19
19
|
import { COMMITMENT_WATCHED_SOURCES, COMMITMENT_TEMPLATE_IDS, COMMITMENT_CADENCE_MODES, COMMITMENT_CADENCE_TIME_PATTERN, COMMITMENT_CADENCE_MAX_TIMES, COMMITMENT_AUTONOMY_MODES, COMMITMENT_EXECUTION_ISOLATION_MODES, COMMITMENT_STATUSES, COMMITMENT_KIND_VALUES } from '@skrr-ai/data-provider';
|
|
20
|
-
import type { CommitmentCheck, CommitmentChecksResponse, Commitment, CommitmentActionProposal, CommitmentListResponse, CommitmentPlanResponse, CommitmentStatusResponse, CommitmentWorkLink, CommitmentExecutionReceiptListResponse, CommitmentExecutionReceiptQuarterlyMetricsResponse, CommitmentCapabilitySource, CommitmentDeliveryPatchResponse, CommitmentDeliveryBundleResponse, CommitmentCyclesResponse, CommitmentExplanationResponse } from '@skrr-ai/data-provider';
|
|
20
|
+
import type { CommitmentCheck, CommitmentChecksResponse, Commitment, CommitmentActionProposal, CommitmentListResponse, CommitmentPlanResponse, CommitmentStatusResponse, CommitmentWorkLink, CommitmentExecutionReceiptListResponse, CommitmentExecutionReceiptQuarterlyMetricsResponse, CommitmentCapabilitySource, CommitmentDeliveryPatchResponse, CommitmentDeliveryBundleResponse, CommitmentCyclesResponse, CommitmentExplanationResponse, CommitmentRunPermissions } from '@skrr-ai/data-provider';
|
|
21
21
|
import { withQuery } from './triggers';
|
|
22
22
|
export { COMMITMENT_WATCHED_SOURCES, COMMITMENT_TEMPLATE_IDS, COMMITMENT_CADENCE_MODES, COMMITMENT_CADENCE_TIME_PATTERN, COMMITMENT_CADENCE_MAX_TIMES, COMMITMENT_STATUSES, COMMITMENT_KIND_VALUES, };
|
|
23
23
|
export type { CommitmentCheck, CommitmentChecksResponse, Commitment, CommitmentActionProposal, CommitmentListResponse, CommitmentPlanResponse, CommitmentStatusResponse, CommitmentWorkLink, };
|
|
@@ -99,7 +99,27 @@ export type CommitmentPreflightReport = {
|
|
|
99
99
|
suppressedBy?: string | null;
|
|
100
100
|
[key: string]: unknown;
|
|
101
101
|
};
|
|
102
|
+
/** Whose permissions a run uses (OSK-11975). Absent from older servers. */
|
|
103
|
+
permissions?: CommitmentRunPermissions | null;
|
|
104
|
+
/** `retired` names the fence fields OSK-11975 made inert (OSK-12065). */
|
|
105
|
+
execution?: {
|
|
106
|
+
retired?: string[];
|
|
107
|
+
retiredReason?: string;
|
|
108
|
+
} & Record<string, unknown>;
|
|
102
109
|
};
|
|
110
|
+
/**
|
|
111
|
+
* The lines every Commitment read surface prints for "whose permissions does a
|
|
112
|
+
* run use?" — `show`, `effective-policy` and `preflight` share it so the three
|
|
113
|
+
* cannot phrase it three ways (OSK-12065). The sentence and the warnings are
|
|
114
|
+
* the server's; this only lays them out. `null` (an older server that does not
|
|
115
|
+
* report it) prints nothing rather than a guess.
|
|
116
|
+
*/
|
|
117
|
+
export declare function permissionLines(permissions: CommitmentRunPermissions | null | undefined): string[];
|
|
118
|
+
/**
|
|
119
|
+
* One line naming fields that are still in the JSON but decide nothing any
|
|
120
|
+
* more. Deprecation, not removal: `--json` keeps them for scripts.
|
|
121
|
+
*/
|
|
122
|
+
export declare function retiredFieldsLine(retired: string[] | undefined, reason: string | undefined): string | null;
|
|
103
123
|
/**
|
|
104
124
|
* A Commitment Pack's readiness receipt.
|
|
105
125
|
*
|
|
@@ -466,6 +486,10 @@ export interface CommitmentNextTickProjection {
|
|
|
466
486
|
diagnosisKind?: string;
|
|
467
487
|
terminalDispositionCensus?: {
|
|
468
488
|
workFailures?: number;
|
|
489
|
+
/** Failed runs the runtime never started (`classifyRunFailure` machine). */
|
|
490
|
+
machineFailures?: number;
|
|
491
|
+
/** Failed runs whose result was rejected (`classifyRunFailure` contract). */
|
|
492
|
+
contractFailures?: number;
|
|
469
493
|
budgetRefusals?: number;
|
|
470
494
|
terminal?: number;
|
|
471
495
|
};
|
package/dist/lib/commitments.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.COMMITMENT_CLI_EVALUATORS = exports.COMMITMENT_CREATE_KEYS = exports.COM
|
|
|
4
4
|
exports.storedAutonomyModeForAuthoring = storedAutonomyModeForAuthoring;
|
|
5
5
|
exports.authoringAutonomyModeForStored = authoringAutonomyModeForStored;
|
|
6
6
|
exports.commitmentAutonomyLabel = commitmentAutonomyLabel;
|
|
7
|
+
exports.permissionLines = permissionLines;
|
|
8
|
+
exports.retiredFieldsLine = retiredFieldsLine;
|
|
7
9
|
exports.readCommitmentAgentDirective = readCommitmentAgentDirective;
|
|
8
10
|
exports.normalizeCreateBody = normalizeCreateBody;
|
|
9
11
|
exports.parseCommitmentConcurrencyLimit = parseCommitmentConcurrencyLimit;
|
|
@@ -109,6 +111,33 @@ function commitmentAutonomyLabel(mode) {
|
|
|
109
111
|
*/
|
|
110
112
|
exports.MIN_COMMITMENT_INTERVAL_MS = 60_000;
|
|
111
113
|
exports.MAX_COMMITMENT_INTERVAL_MS = 365 * 24 * 60 * 60 * 1000;
|
|
114
|
+
/**
|
|
115
|
+
* The lines every Commitment read surface prints for "whose permissions does a
|
|
116
|
+
* run use?" — `show`, `effective-policy` and `preflight` share it so the three
|
|
117
|
+
* cannot phrase it three ways (OSK-12065). The sentence and the warnings are
|
|
118
|
+
* the server's; this only lays them out. `null` (an older server that does not
|
|
119
|
+
* report it) prints nothing rather than a guess.
|
|
120
|
+
*/
|
|
121
|
+
function permissionLines(permissions) {
|
|
122
|
+
if (!permissions?.summary)
|
|
123
|
+
return [];
|
|
124
|
+
const lines = [`Permissions: ${permissions.summary}`];
|
|
125
|
+
for (const warning of permissions.warnings || []) {
|
|
126
|
+
lines.push(`Warning: ${warning.message}`);
|
|
127
|
+
if (warning.fix)
|
|
128
|
+
lines.push(` Fix: ${warning.fix}`);
|
|
129
|
+
}
|
|
130
|
+
return lines;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* One line naming fields that are still in the JSON but decide nothing any
|
|
134
|
+
* more. Deprecation, not removal: `--json` keeps them for scripts.
|
|
135
|
+
*/
|
|
136
|
+
function retiredFieldsLine(retired, reason) {
|
|
137
|
+
if (!Array.isArray(retired) || !retired.length)
|
|
138
|
+
return null;
|
|
139
|
+
return `Retired fields (no effect): ${retired.join(', ')}${reason ? ` — ${reason}` : ''}`;
|
|
140
|
+
}
|
|
112
141
|
function base(id) {
|
|
113
142
|
return `/api/commitments/${encodeURIComponent(id)}`;
|
|
114
143
|
}
|
|
@@ -626,6 +655,8 @@ function describeEvidenceHealth(health, criteriaCount) {
|
|
|
626
655
|
const STALLED_DIAGNOSES = {
|
|
627
656
|
scheduler_stalled: 'its expected checks are no longer arriving',
|
|
628
657
|
work_failing: 'every recent run reached the agent and failed while doing the work',
|
|
658
|
+
runtime_failing: 'recent runs never started — the runtime refused them',
|
|
659
|
+
result_rejected: 'every recent run reached the agent, but its result was rejected',
|
|
629
660
|
observation_unreadable: 'the latest check could not read every configured source',
|
|
630
661
|
execution_budget_exhausted: 'recent planned work was skipped — the execution budget is exhausted',
|
|
631
662
|
no_advancement: 'no server-recorded advancement exists inside the declared window',
|
|
@@ -645,8 +676,17 @@ function describeStalledHealth(commitment) {
|
|
|
645
676
|
const kind = typeof liveness.diagnosisKind === 'string' ? liveness.diagnosisKind : undefined;
|
|
646
677
|
const clause = (kind && STALLED_DIAGNOSES[kind]) ||
|
|
647
678
|
'this loop has stopped producing; the reconciler did not record which check failed';
|
|
679
|
+
// What refused and what to change, when the reconciler recorded them
|
|
680
|
+
// (OSK-12137). A machine failure has a specific fix; printing only the
|
|
681
|
+
// verdict would send the owner to read run history for it.
|
|
682
|
+
const code = typeof liveness.diagnosisCode === 'string' && liveness.diagnosisCode
|
|
683
|
+
? ` (${liveness.diagnosisCode})`
|
|
684
|
+
: '';
|
|
648
685
|
const since = typeof liveness.unhealthySinceAt === 'string' ? ` (since ${liveness.unhealthySinceAt})` : '';
|
|
649
|
-
|
|
686
|
+
const fix = typeof liveness.diagnosisFix === 'string' && liveness.diagnosisFix
|
|
687
|
+
? ` — ${liveness.diagnosisFix}`
|
|
688
|
+
: '';
|
|
689
|
+
return `${clause}${code}${since}${fix}`;
|
|
650
690
|
}
|
|
651
691
|
/** Render an interval back as a compact human string. */
|
|
652
692
|
function describeIntervalMs(ms) {
|
|
@@ -1013,6 +1053,11 @@ function describeWakeDecision(check) {
|
|
|
1013
1053
|
if (verdict === 'skipped') {
|
|
1014
1054
|
const reason = typeof entry.reason === 'string' ? entry.reason : '';
|
|
1015
1055
|
if (reason === 'posture_does_not_admit_agent_run') {
|
|
1056
|
+
// The server names the commonest cause on the check's `stop`: nothing
|
|
1057
|
+
// was open to act on. "record_only" alone read as a setting to change
|
|
1058
|
+
// when the remedy was to give the Commitment some work (OSK-12090).
|
|
1059
|
+
if (check.stop?.reason === 'no_open_loop')
|
|
1060
|
+
return 'no — nothing open';
|
|
1016
1061
|
const posture = typeof entry.posture === 'string' ? entry.posture : '';
|
|
1017
1062
|
return posture ? `no — ${posture}` : 'no — posture';
|
|
1018
1063
|
}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -29,6 +29,23 @@ export interface CliConfig {
|
|
|
29
29
|
* different daemonId.
|
|
30
30
|
*/
|
|
31
31
|
cliId?: string;
|
|
32
|
+
/**
|
|
33
|
+
* The CLI identity of ONE named profile (OSK-12156), stored in that profile's
|
|
34
|
+
* own file and never in the machine file.
|
|
35
|
+
*
|
|
36
|
+
* `cliId` above is machine-scoped, so every profile used to present it — and
|
|
37
|
+
* the server's `cli-handoff/confirm` retires every OTHER live family of
|
|
38
|
+
* (user, cliId), so one profile's daemon-brokered login silently ended
|
|
39
|
+
* another's session. This is issued ONLY to a named profile that holds no
|
|
40
|
+
* stored credential at the moment it signs in (`cli-identity.ts`), because
|
|
41
|
+
* an existing session was minted under the machine id and a refresh that
|
|
42
|
+
* presents another is refused: a profile that already has a session keeps
|
|
43
|
+
* presenting the id it was minted under, so an upgrade forces no re-login.
|
|
44
|
+
*
|
|
45
|
+
* Never read this field, or `cliId`, to decide what to PRESENT — call
|
|
46
|
+
* `resolveCliId()` (`cli-id.ts`), the one resolver every caller goes through.
|
|
47
|
+
*/
|
|
48
|
+
profileCliId?: string;
|
|
32
49
|
/**
|
|
33
50
|
* OSK-3892 — the agent a locally-hosted `skrr code` session is attributed to.
|
|
34
51
|
*
|
package/dist/lib/config.js
CHANGED
|
@@ -53,6 +53,7 @@ const os = __importStar(require("node:os"));
|
|
|
53
53
|
const path = __importStar(require("node:path"));
|
|
54
54
|
const keychain_1 = require("./keychain");
|
|
55
55
|
const auth_core_1 = require("@skrr-ai/auth-core");
|
|
56
|
+
const cli_id_1 = require("./cli-id");
|
|
56
57
|
const publicEndpoints_generated_1 = require("./publicEndpoints.generated");
|
|
57
58
|
// Both from config/public-endpoints.json, the one domain contract, rather than a
|
|
58
59
|
// fourth hand-copied pair. The CLI previously knew only about dev — there was no
|
|
@@ -174,7 +175,8 @@ const ENV_VAR = {
|
|
|
174
175
|
serverUrl: 'OVERSKY_SERVER_URL',
|
|
175
176
|
token: 'OVERSKY_TOKEN',
|
|
176
177
|
refreshToken: 'OVERSKY_REFRESH_TOKEN',
|
|
177
|
-
|
|
178
|
+
// OVERSKY_CLI_ID / SKRR_CLI_ID: `envCliIdOverride` (cli-id.ts), which
|
|
179
|
+
// `resolveCliId` shares, so the overlay and the resolver cannot disagree.
|
|
178
180
|
};
|
|
179
181
|
/**
|
|
180
182
|
* Read one overlay variable under either prefix.
|
|
@@ -215,8 +217,8 @@ function overlayEnv(cfg) {
|
|
|
215
217
|
const rt = envOverlayValue('refreshToken');
|
|
216
218
|
if (rt && rt.length > 0)
|
|
217
219
|
out.refreshToken = rt;
|
|
218
|
-
const cid =
|
|
219
|
-
if (cid
|
|
220
|
+
const cid = (0, cli_id_1.envCliIdOverride)();
|
|
221
|
+
if (cid)
|
|
220
222
|
out.cliId = cid;
|
|
221
223
|
return out;
|
|
222
224
|
}
|
|
@@ -275,6 +277,16 @@ function newConfigDir() {
|
|
|
275
277
|
* and rejects a rotation against a different one. Split it per profile and a
|
|
276
278
|
* second profile does not degrade — it fails to stay logged in.
|
|
277
279
|
*
|
|
280
|
+
* So `cliId` stays here, and a profile's OWN identity is a different key,
|
|
281
|
+
* `profileCliId`, which is profile-scoped (OSK-12156). Sharing the machine id
|
|
282
|
+
* meant the server's cli-handoff confirm — which retires the other families of
|
|
283
|
+
* (user, cliId) — could not tell two profiles of one user apart, so one
|
|
284
|
+
* profile's daemon-brokered login ended another's session. A named profile that
|
|
285
|
+
* signs in holding no credential is now issued its own id; a profile that
|
|
286
|
+
* already has a session keeps the machine id it was minted under, because a
|
|
287
|
+
* refresh presenting another is refused. `resolveCliId()` (`cli-id.ts`) is the
|
|
288
|
+
* one reader.
|
|
289
|
+
*
|
|
278
290
|
* `credentials.store` is a machine posture (keychain / file / env-only), and
|
|
279
291
|
* `migrated` is a breadcrumb about this machine's DISK LAYOUT. Neither is a
|
|
280
292
|
* property of which deployment you are addressing.
|
|
@@ -122,7 +122,7 @@ export interface DaemonBrokeredOutcome {
|
|
|
122
122
|
* fall through to PKCE; `ci_token_refused` is the one we surface
|
|
123
123
|
* because re-driving it via PKCE would not change the outcome.
|
|
124
124
|
*/
|
|
125
|
-
export type DaemonBrokerErrorReason = 'no_bootstrap' | 'stale_bootstrap' | 'bootstrap_parse' | 'base_url_mismatch' | 'daemon_not_authed' | 'ci_token_refused' | 'handoff_broker_only' | 'rate_limited' | 'server_error' | 'network' | 'timeout' | 'unknown';
|
|
125
|
+
export type DaemonBrokerErrorReason = 'no_bootstrap' | 'stale_bootstrap' | 'bootstrap_parse' | 'base_url_mismatch' | 'daemon_not_authed' | 'ci_token_refused' | 'handoff_broker_only' | 'rate_limited' | 'upstream_refused' | 'server_error' | 'network' | 'timeout' | 'unknown';
|
|
126
126
|
export interface DaemonBrokerFailure {
|
|
127
127
|
ok: false;
|
|
128
128
|
reason: DaemonBrokerErrorReason;
|
|
@@ -132,12 +132,40 @@ export interface DaemonBrokerFailure {
|
|
|
132
132
|
status?: number;
|
|
133
133
|
/** Server-supplied error code when present (e.g. 'CI_TOKEN_REFUSED'). */
|
|
134
134
|
code?: string;
|
|
135
|
+
/**
|
|
136
|
+
* Who refused, when the daemon answered at all: `daemon` for a refusal the
|
|
137
|
+
* local service made itself (not signed in, broker-only, its own outage),
|
|
138
|
+
* `server` for the skrr server's refusal of the daemon's request, carried
|
|
139
|
+
* through the loopback route (`upstreamCode` on the token route, the
|
|
140
|
+
* verbatim body on the legacy one). The two have different repairs, and a
|
|
141
|
+
* caller that cannot tell them apart can only say "Not signed in"
|
|
142
|
+
* (OSK-12149).
|
|
143
|
+
*/
|
|
144
|
+
refusedBy?: 'daemon' | 'server';
|
|
135
145
|
/**
|
|
136
146
|
* For `base_url_mismatch`: the daemon's serverUrl, so the caller can
|
|
137
147
|
* surface a helpful hint like "run `skrr login --base-url <X>` to use
|
|
138
148
|
* the daemon".
|
|
139
149
|
*/
|
|
140
150
|
daemonServerUrl?: string;
|
|
151
|
+
/**
|
|
152
|
+
* The descriptor file the outcome came from. For `base_url_mismatch` found
|
|
153
|
+
* locally it is the file that named `daemonServerUrl`, so a message can say
|
|
154
|
+
* what was read rather than assert where "the" daemon is logged in
|
|
155
|
+
* (OSK-12117). For a refusal it is the descriptor whose daemon answered —
|
|
156
|
+
* which is how a caller knows the answer came from a Dedicated Runtime
|
|
157
|
+
* guest's daemon (`DEDICATED_RUNTIME_CLI_HANDOFF_DESCRIPTOR`), where nobody
|
|
158
|
+
* signs in and the repair is the machine, not a login.
|
|
159
|
+
*/
|
|
160
|
+
descriptorPath?: string;
|
|
161
|
+
/** The answering daemon's id, from its descriptor, when it published one. */
|
|
162
|
+
daemonId?: string;
|
|
163
|
+
/**
|
|
164
|
+
* True when the answering descriptor is a Dedicated Runtime guest's
|
|
165
|
+
* (`DEDICATED_RUNTIME_CLI_HANDOFF_DESCRIPTOR`): nobody signs in there, so
|
|
166
|
+
* the repair for a refusal is the machine, never a login.
|
|
167
|
+
*/
|
|
168
|
+
dedicatedGuest?: boolean;
|
|
141
169
|
}
|
|
142
170
|
export type DaemonBrokerOutcome = (DaemonBrokerResult & {
|
|
143
171
|
ok: true;
|
|
@@ -224,6 +252,14 @@ export declare function resolveBootstrapCandidatePaths(profile?: string): string
|
|
|
224
252
|
export declare const DEDICATED_RUNTIME_CLI_HANDOFF_DESCRIPTOR = "/run/skrr-dedicated-runtime/cli-handoff/descriptor.json";
|
|
225
253
|
/** Where the cli-handoff broker looks, in order. */
|
|
226
254
|
export declare function resolveCliHandoffCandidatePaths(profile?: string): string[];
|
|
255
|
+
/**
|
|
256
|
+
* The island files that belong to exactly `profile` — its canonical path and
|
|
257
|
+
* the pre-rename darwin location — and never another profile's. The broker's
|
|
258
|
+
* candidate list for `default` deliberately falls through to any running
|
|
259
|
+
* profile, which is right for borrowing a credential and wrong for naming
|
|
260
|
+
* which daemon a profile's status describes (OSK-12102).
|
|
261
|
+
*/
|
|
262
|
+
export declare function resolveExactProfileBootstrapPaths(profile?: string): string[];
|
|
227
263
|
/**
|
|
228
264
|
* Resolve the first live daemon bootstrap for a profile. Message-intent
|
|
229
265
|
* submission reuses the same authenticated loopback discovery as the login
|