@skrr-ai/cli 0.1.94 → 0.1.96
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 +175 -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/agent/message/send.d.ts +2 -0
- package/dist/commands/agent/message/send.js +75 -5
- package/dist/commands/agents/chat.js +1 -1
- package/dist/commands/agents/create.d.ts +0 -3
- package/dist/commands/agents/create.js +0 -26
- package/dist/commands/agents/egress.d.ts +17 -0
- package/dist/commands/agents/egress.js +84 -0
- package/dist/commands/agents/mailbox/messages.d.ts +14 -0
- package/dist/commands/agents/mailbox/messages.js +52 -0
- package/dist/commands/agents/mailbox/show.d.ts +13 -0
- package/dist/commands/agents/mailbox/show.js +52 -0
- package/dist/commands/agents/operating-plan.js +8 -0
- package/dist/commands/agents/roles/capture.d.ts +16 -0
- package/dist/commands/agents/roles/capture.js +53 -0
- package/dist/commands/agents/roles/install.d.ts +1 -0
- package/dist/commands/agents/roles/install.js +8 -1
- package/dist/commands/agents/roles/preview.d.ts +2 -0
- package/dist/commands/agents/roles/preview.js +27 -3
- package/dist/commands/agents/update.d.ts +0 -3
- package/dist/commands/agents/update.js +1 -31
- package/dist/commands/agents/usage-cap.d.ts +4 -1
- package/dist/commands/agents/usage-cap.js +49 -10
- 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/jobs/show.js +12 -0
- 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/action-proposals/decide.d.ts +2 -0
- package/dist/commands/commitments/action-proposals/decide.js +12 -0
- package/dist/commands/commitments/action-proposals.js +7 -0
- package/dist/commands/commitments/create.d.ts +1 -0
- package/dist/commands/commitments/create.js +17 -1
- package/dist/commands/commitments/delivery.d.ts +1 -0
- package/dist/commands/commitments/delivery.js +11 -1
- package/dist/commands/commitments/doctor.js +4 -0
- package/dist/commands/commitments/effective-policy.js +26 -0
- package/dist/commands/commitments/endpoints/create.js +5 -2
- package/dist/commands/commitments/observations.d.ts +10 -0
- package/dist/commands/commitments/observations.js +88 -0
- package/dist/commands/commitments/pause.d.ts +1 -1
- package/dist/commands/commitments/pause.js +4 -3
- package/dist/commands/commitments/preflight.js +2 -1
- package/dist/commands/commitments/reports.d.ts +2 -0
- package/dist/commands/commitments/reports.js +22 -4
- package/dist/commands/commitments/update.d.ts +1 -0
- package/dist/commands/commitments/update.js +35 -5
- 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/grants/create.d.ts +1 -0
- package/dist/commands/grants/create.js +8 -0
- package/dist/commands/grants/rotate.d.ts +5 -0
- package/dist/commands/grants/rotate.js +13 -1
- package/dist/commands/grants/update.d.ts +12 -0
- package/dist/commands/grants/update.js +27 -0
- 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/machines/hosted/start.js +7 -1
- package/dist/commands/machines/list.js +4 -4
- package/dist/commands/measures/confirm.d.ts +1 -7
- package/dist/commands/measures/confirm.js +15 -14
- package/dist/commands/measures/list.d.ts +1 -7
- package/dist/commands/measures/list.js +1 -7
- package/dist/commands/measures/record.js +4 -4
- package/dist/commands/measures/show.d.ts +11 -0
- package/dist/commands/measures/show.js +26 -0
- package/dist/commands/northstars/governance/configure.d.ts +1 -0
- package/dist/commands/northstars/governance/configure.js +8 -1
- package/dist/commands/proposals/discard.d.ts +5 -0
- package/dist/commands/proposals/discard.js +8 -0
- package/dist/commands/proposals/keep.d.ts +5 -0
- package/dist/commands/proposals/keep.js +8 -0
- package/dist/commands/proposals/list.d.ts +15 -0
- package/dist/commands/proposals/list.js +74 -0
- package/dist/commands/proposals/show.d.ts +12 -0
- package/dist/commands/proposals/show.js +27 -0
- package/dist/commands/proposals/snooze.d.ts +5 -0
- package/dist/commands/proposals/snooze.js +8 -0
- package/dist/commands/security/overview.d.ts +11 -0
- package/dist/commands/security/overview.js +158 -0
- package/dist/commands/signals/monitors/create.d.ts +9 -0
- package/dist/commands/signals/monitors/create.js +29 -0
- package/dist/commands/signals/monitors/list.d.ts +8 -0
- package/dist/commands/signals/monitors/list.js +16 -0
- package/dist/commands/signals/monitors/pause.d.ts +11 -0
- package/dist/commands/signals/monitors/pause.js +17 -0
- package/dist/commands/signals/monitors/resume.d.ts +11 -0
- package/dist/commands/signals/monitors/resume.js +17 -0
- package/dist/commands/signals/monitors/revise.d.ts +12 -0
- package/dist/commands/signals/monitors/revise.js +25 -0
- package/dist/commands/signals/monitors/show.d.ts +11 -0
- package/dist/commands/signals/monitors/show.js +17 -0
- package/dist/commands/signals/monitors/test.d.ts +12 -0
- package/dist/commands/signals/monitors/test.js +25 -0
- package/dist/commands/signals/monitors/transitions.d.ts +11 -0
- package/dist/commands/signals/monitors/transitions.js +17 -0
- package/dist/commands/signals/monitors/validate.d.ts +9 -0
- package/dist/commands/signals/monitors/validate.js +24 -0
- package/dist/commands/signals/schemas/list.d.ts +8 -0
- package/dist/commands/signals/schemas/list.js +16 -0
- package/dist/commands/signals/schemas/show.d.ts +11 -0
- package/dist/commands/signals/schemas/show.js +17 -0
- package/dist/commands/signals/sources/list.d.ts +8 -0
- package/dist/commands/signals/sources/list.js +16 -0
- package/dist/commands/signals/sources/receipts.d.ts +11 -0
- package/dist/commands/signals/sources/receipts.js +17 -0
- package/dist/commands/signals/sources/show.d.ts +11 -0
- package/dist/commands/signals/sources/show.js +17 -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/spaces/usage.d.ts +12 -0
- package/dist/commands/spaces/usage.js +28 -0
- package/dist/commands/spaces/workflows/run.js +3 -0
- package/dist/commands/spaces/workflows/runs.js +2 -1
- package/dist/commands/spaces/workflows/update.d.ts +6 -1
- package/dist/commands/spaces/workflows/update.js +34 -2
- package/dist/commands/tasks/cancel-cascade.js +1 -1
- package/dist/commands/tasks/cascade-status.d.ts +2 -0
- package/dist/commands/tasks/cascade-status.js +27 -1
- package/dist/commands/tasks/create-tree.d.ts +5 -1
- package/dist/commands/tasks/create-tree.js +35 -7
- package/dist/commands/tasks/create.d.ts +4 -0
- package/dist/commands/tasks/create.js +16 -0
- package/dist/commands/tasks/deliverable/add.js +12 -3
- package/dist/commands/tasks/economics-compare.d.ts +15 -0
- package/dist/commands/tasks/economics-compare.js +60 -0
- package/dist/commands/tasks/expectations/evaluate.d.ts +13 -0
- package/dist/commands/tasks/expectations/evaluate.js +43 -0
- package/dist/commands/tasks/interrupt.js +2 -2
- package/dist/commands/tasks/list.d.ts +1 -0
- package/dist/commands/tasks/list.js +44 -1
- package/dist/commands/tasks/pause-schedule.js +1 -1
- package/dist/commands/tasks/show.d.ts +5 -0
- package/dist/commands/tasks/show.js +17 -0
- package/dist/commands/tasks/update.d.ts +4 -0
- package/dist/commands/tasks/update.js +9 -0
- package/dist/commands/tasks/workflow-findings.js +2 -2
- package/dist/commands/token/list.d.ts +3 -5
- package/dist/commands/token/list.js +99 -57
- package/dist/commands/triggers/create.d.ts +2 -0
- package/dist/commands/triggers/create.js +15 -0
- package/dist/commands/update.d.ts +14 -0
- package/dist/commands/update.js +61 -0
- package/dist/commands/workspaces/grants.d.ts +12 -0
- package/dist/commands/workspaces/grants.js +31 -0
- package/dist/commands/workspaces/stewardship.d.ts +13 -0
- package/dist/commands/workspaces/stewardship.js +34 -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/agent-config.d.ts +0 -12
- package/dist/lib/agent-config.js +1 -27
- package/dist/lib/agent-mailbox.d.ts +35 -0
- package/dist/lib/agent-mailbox.js +55 -0
- package/dist/lib/commitment-endpoints.d.ts +2 -1
- package/dist/lib/commitment-endpoints.js +2 -5
- package/dist/lib/commitment-product.d.ts +3 -1
- package/dist/lib/commitment-product.js +10 -0
- package/dist/lib/commitment-terms.js +1 -1
- package/dist/lib/commitments.d.ts +17 -15
- package/dist/lib/commitments.js +173 -137
- package/dist/lib/compasses.d.ts +14 -0
- package/dist/lib/compasses.js +25 -11
- 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/grants.d.ts +5 -1
- package/dist/lib/grants.js +9 -1
- package/dist/lib/hosted-machines.d.ts +7 -0
- package/dist/lib/mailbox-human-command.d.ts +11 -0
- package/dist/lib/mailbox-human-command.js +41 -0
- 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/measures.d.ts +28 -2
- package/dist/lib/measures.js +38 -14
- package/dist/lib/memory-sync.d.ts +1 -0
- package/dist/lib/memory-sync.js +279 -68
- package/dist/lib/message-intent.d.ts +6 -2
- package/dist/lib/message-intent.js +1 -0
- package/dist/lib/northstars.js +2 -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/proposal-decision-command.d.ts +19 -0
- package/dist/lib/proposal-decision-command.js +64 -0
- package/dist/lib/proposals.d.ts +8 -0
- package/dist/lib/proposals.js +22 -0
- package/dist/lib/roles.d.ts +141 -6
- package/dist/lib/roles.js +8 -2
- package/dist/lib/signals.d.ts +20 -0
- package/dist/lib/signals.js +24 -0
- package/dist/lib/space-usage.d.ts +3 -0
- package/dist/lib/space-usage.js +17 -0
- package/dist/lib/stewardship-output.d.ts +4 -0
- package/dist/lib/stewardship-output.js +82 -0
- package/dist/lib/task-asset-upload.d.ts +3 -1
- package/dist/lib/task-asset-upload.js +1 -0
- package/dist/lib/task-batch.d.ts +9 -0
- package/dist/lib/task-batch.js +94 -17
- package/dist/lib/task-economics.d.ts +16 -0
- package/dist/lib/task-economics.js +22 -0
- package/dist/lib/task-instruction-offer.d.ts +1 -4
- package/dist/lib/task-instruction-offer.js +3 -129
- package/dist/lib/triggers.d.ts +11 -3
- package/dist/lib/triggers.js +58 -1
- package/dist/lib/update-check.d.ts +61 -53
- package/dist/lib/update-check.js +453 -314
- package/dist/lib/usage-discovery.d.ts +10 -0
- package/dist/lib/usage-discovery.js +24 -3
- package/dist/lib/workflow-run-budget.d.ts +12 -0
- package/dist/lib/workflow-run-budget.js +37 -0
- package/dist/lib/workspaces.d.ts +48 -0
- package/dist/lib/workspaces.js +8 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/cliHandoffWire.d.ts +4 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/cliHandoffWire.js +14 -1
- 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/githubPushRefusal.d.ts +9 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/githubPushRefusal.js +49 -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/esm/cliHandoffWire.d.ts +4 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/cliHandoffWire.js +12 -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/githubPushRefusal.d.ts +9 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/githubPushRefusal.js +44 -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/package.json +41 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +8069 -7121
- 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 +49424 -46174
- package/package.json +34 -11
|
@@ -37,16 +37,16 @@ class MachinesList extends base_command_1.BaseCommand {
|
|
|
37
37
|
catch (err) {
|
|
38
38
|
this.handleApiError(err);
|
|
39
39
|
}
|
|
40
|
+
const all = machines ?? [];
|
|
41
|
+
const shown = flags.all ? all : all.filter((m) => (0, machines_1.isReachableMachine)(m));
|
|
40
42
|
if (flags.json) {
|
|
41
|
-
this.log(JSON.stringify(
|
|
43
|
+
this.log(JSON.stringify(shown, null, 2));
|
|
42
44
|
return;
|
|
43
45
|
}
|
|
44
|
-
if (
|
|
46
|
+
if (all.length === 0) {
|
|
45
47
|
this.log('No machines. Install a daemon with `skrr harnesses install-token`.');
|
|
46
48
|
return;
|
|
47
49
|
}
|
|
48
|
-
const all = machines;
|
|
49
|
-
const shown = flags.all ? all : all.filter((m) => (0, machines_1.isReachableMachine)(m));
|
|
50
50
|
if (shown.length === 0) {
|
|
51
51
|
this.log(`No machine is reachable right now (${(0, machines_1.hiddenMachinesSummary)(all)}) — see them with --all.`);
|
|
52
52
|
return;
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { BaseCommand } from '../../base-command';
|
|
2
|
-
/**
|
|
3
|
-
* `skrr measures confirm` — turn a claim into ground truth.
|
|
4
|
-
*
|
|
5
|
-
* This is the human-in-the-loop step whose `agentOutcome` equivalent shipped
|
|
6
|
-
* with zero callers, which left every value claim in the system permanently
|
|
7
|
-
* unverified.
|
|
8
|
-
*/
|
|
2
|
+
/** Confirm a reading and display the server-derived attribution. */
|
|
9
3
|
export default class MeasuresConfirm extends BaseCommand {
|
|
10
4
|
static description: string;
|
|
11
5
|
static examples: string[];
|
|
@@ -1,17 +1,12 @@
|
|
|
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 measures_1 = require("../../lib/measures");
|
|
6
|
-
/**
|
|
7
|
-
* `skrr measures confirm` — turn a claim into ground truth.
|
|
8
|
-
*
|
|
9
|
-
* This is the human-in-the-loop step whose `agentOutcome` equivalent shipped
|
|
10
|
-
* with zero callers, which left every value claim in the system permanently
|
|
11
|
-
* unverified.
|
|
12
|
-
*/
|
|
7
|
+
/** Confirm a reading and display the server-derived attribution. */
|
|
13
8
|
class MeasuresConfirm extends base_command_1.BaseCommand {
|
|
14
|
-
static description = 'Confirm an observation
|
|
9
|
+
static description = 'Confirm an observation with credential-derived evidence attribution';
|
|
15
10
|
static examples = [
|
|
16
11
|
'<%= config.bin %> measures confirm <measure-id> --at 2026-07-28T00:00:00Z',
|
|
17
12
|
'<%= config.bin %> measures confirm <measure-id> --latest',
|
|
@@ -22,7 +17,9 @@ class MeasuresConfirm extends base_command_1.BaseCommand {
|
|
|
22
17
|
static flags = {
|
|
23
18
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
24
19
|
at: core_1.Flags.string({ description: 'observedAt of the reading to confirm (ISO-8601)' }),
|
|
25
|
-
latest: core_1.Flags.boolean({
|
|
20
|
+
latest: core_1.Flags.boolean({
|
|
21
|
+
description: 'Confirm the most recent reading lacking person confirmation',
|
|
22
|
+
}),
|
|
26
23
|
};
|
|
27
24
|
async run() {
|
|
28
25
|
this.requireAuth();
|
|
@@ -33,19 +30,23 @@ class MeasuresConfirm extends base_command_1.BaseCommand {
|
|
|
33
30
|
this.error('Specify --at <iso-instant> or --latest.');
|
|
34
31
|
}
|
|
35
32
|
const measure = await measures_1.measureApi.get(args.measureId);
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
this.
|
|
33
|
+
const selection = (0, data_provider_1.latestConfirmableMeasureReading)(measure.observations);
|
|
34
|
+
if (selection.ambiguous) {
|
|
35
|
+
this.error('Multiple retained readings have the same timestamp; the existing confirmation endpoint cannot distinguish them. No confirmation was sent.');
|
|
36
|
+
}
|
|
37
|
+
const unconfirmed = selection.reading;
|
|
38
|
+
if (!unconfirmed) {
|
|
39
|
+
this.log('Nothing to confirm — no eligible reading lacking person confirmation is available.');
|
|
39
40
|
return;
|
|
40
41
|
}
|
|
41
|
-
observedAt = unconfirmed
|
|
42
|
+
observedAt = unconfirmed.observedAt;
|
|
42
43
|
}
|
|
43
44
|
const measure = await measures_1.measureApi.confirm(args.measureId, observedAt);
|
|
44
45
|
if (flags.json) {
|
|
45
46
|
this.log(JSON.stringify(measure, null, 2));
|
|
46
47
|
return;
|
|
47
48
|
}
|
|
48
|
-
this.log(
|
|
49
|
+
this.log((0, measures_1.recordConfirmationForObservation)(measure.observations.find((o) => Date.parse(o.observedAt) === Date.parse(observedAt))).message);
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
exports.default = MeasuresConfirm;
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { BaseCommand } from '../../base-command';
|
|
2
|
-
/**
|
|
3
|
-
* `skrr measures list` — what an agent is supposed to move.
|
|
4
|
-
*
|
|
5
|
-
* The CONFIRMED column is `confirmed/total`: an agent-reported reading is a
|
|
6
|
-
* claim until a human confirms it, and collapsing the two would reproduce the
|
|
7
|
-
* unverified-self-estimate problem with a unit attached.
|
|
8
|
-
*/
|
|
2
|
+
/** Read numeric movement alongside server-derived evidence counts. */
|
|
9
3
|
export default class MeasuresList extends BaseCommand {
|
|
10
4
|
static description: string;
|
|
11
5
|
static examples: string[];
|
|
@@ -4,13 +4,7 @@ const core_1 = require("@oclif/core");
|
|
|
4
4
|
const base_command_1 = require("../../base-command");
|
|
5
5
|
const measures_1 = require("../../lib/measures");
|
|
6
6
|
const triggers_1 = require("../../lib/triggers");
|
|
7
|
-
/**
|
|
8
|
-
* `skrr measures list` — what an agent is supposed to move.
|
|
9
|
-
*
|
|
10
|
-
* The CONFIRMED column is `confirmed/total`: an agent-reported reading is a
|
|
11
|
-
* claim until a human confirms it, and collapsing the two would reproduce the
|
|
12
|
-
* unverified-self-estimate problem with a unit attached.
|
|
13
|
-
*/
|
|
7
|
+
/** Read numeric movement alongside server-derived evidence counts. */
|
|
14
8
|
class MeasuresList extends base_command_1.BaseCommand {
|
|
15
9
|
static description = 'List measures (numeric outcomes with unit + baseline)';
|
|
16
10
|
static examples = [
|
|
@@ -23,8 +23,8 @@ class MeasuresRecord extends base_command_1.BaseCommand {
|
|
|
23
23
|
static flags = {
|
|
24
24
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
25
25
|
source: core_1.Flags.string({
|
|
26
|
-
description: '
|
|
27
|
-
options: [...measures_1.
|
|
26
|
+
description: 'Declared source; credential-derived evidence is reported by the server',
|
|
27
|
+
options: [...measures_1.MEASURE_WRITABLE_SOURCES],
|
|
28
28
|
default: 'manual',
|
|
29
29
|
}),
|
|
30
30
|
at: core_1.Flags.string({ description: 'Observation instant (ISO-8601); defaults to now' }),
|
|
@@ -44,13 +44,13 @@ class MeasuresRecord extends base_command_1.BaseCommand {
|
|
|
44
44
|
note: flags.note,
|
|
45
45
|
evidence: flags.evidence,
|
|
46
46
|
});
|
|
47
|
-
const confirmation = (0, measures_1.
|
|
47
|
+
const confirmation = (0, measures_1.recordConfirmationForObservation)(measure.observations.at(-1));
|
|
48
48
|
if (flags.json) {
|
|
49
49
|
this.log(JSON.stringify({ ...measure, record: { source: flags.source, confirmation } }, null, 2));
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
52
|
const r = measure.rollup;
|
|
53
|
-
this.log(`Recorded ${value} on ${measure.label}
|
|
53
|
+
this.log(`Recorded ${value} on ${measure.label}.`);
|
|
54
54
|
if (r.delta !== null) {
|
|
55
55
|
this.log(` ${r.baseline} → ${r.latest} (${r.delta > 0 ? '+' : ''}${r.delta}) — ${r.improved === null
|
|
56
56
|
? 'no direction'
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
export default class MeasuresShow extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
measureId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static flags: {
|
|
8
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
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 measures_1 = require("../../lib/measures");
|
|
7
|
+
class MeasuresShow extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Show measure readings, credential provenance and target revisions';
|
|
9
|
+
static args = { measureId: core_1.Args.string({ required: true, ignoreStdin: true }) };
|
|
10
|
+
static flags = { json: core_1.Flags.boolean({ description: 'Output as JSON' }) };
|
|
11
|
+
async run() {
|
|
12
|
+
this.requireAuth();
|
|
13
|
+
const { args, flags } = await this.parse(MeasuresShow);
|
|
14
|
+
const measure = await measures_1.measureApi.get(args.measureId);
|
|
15
|
+
if (flags.json) {
|
|
16
|
+
this.log(JSON.stringify(measure, null, 2));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
this.log(`${measure.label} (${measure.id})`);
|
|
20
|
+
for (const o of measure.observations)
|
|
21
|
+
this.log(`${o.observedAt} ${o.value}: ${o.provenance ? (0, data_provider_1.describeMeasureEvidence)(o.provenance.level, o.provenance.confirmedBy || o.provenance.recordedBy) : 'Before provenance tracking'}; declared ${o.source}; by ${o.provenance?.recordedBy?.kind || 'unattributed'} via ${o.provenance?.recordedBy?.via || 'unknown'}`);
|
|
22
|
+
for (const revision of measure.revisions || [])
|
|
23
|
+
this.log(`${revision.at} ${revision.by.kind} via ${revision.by.via}: ${revision.changes.map((c) => `${c.field} ${JSON.stringify(c.from)} → ${JSON.stringify(c.to)}`).join(', ')}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.default = MeasuresShow;
|
|
@@ -29,6 +29,7 @@ export default class NorthstarsGovernanceConfigure extends BaseCommand {
|
|
|
29
29
|
'min-interval-hours': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
30
30
|
'max-interval-hours': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
31
31
|
'max-relative-change': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
32
|
+
'max-observation-runs-per-day': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
32
33
|
'max-runs-per-day': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
33
34
|
'max-concurrent-runs': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
34
35
|
'critical-reserve': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
@@ -84,8 +84,13 @@ class NorthstarsGovernanceConfigure extends base_command_1.BaseCommand {
|
|
|
84
84
|
'max-relative-change': core_1.Flags.string({
|
|
85
85
|
description: 'Largest single-step relative change a bounded-auto adjustment may make (0..1)',
|
|
86
86
|
}),
|
|
87
|
+
'max-observation-runs-per-day': core_1.Flags.integer({
|
|
88
|
+
description: 'Opt-in portfolio observation runs per UTC day',
|
|
89
|
+
min: 0,
|
|
90
|
+
max: 10000,
|
|
91
|
+
}),
|
|
87
92
|
'max-runs-per-day': core_1.Flags.integer({
|
|
88
|
-
description: 'Portfolio-wide
|
|
93
|
+
description: 'Portfolio-wide action run budget (execution, NOT attention)',
|
|
89
94
|
min: 0,
|
|
90
95
|
max: 10000,
|
|
91
96
|
}),
|
|
@@ -145,6 +150,8 @@ class NorthstarsGovernanceConfigure extends base_command_1.BaseCommand {
|
|
|
145
150
|
if (Object.keys(cadencePolicy).length)
|
|
146
151
|
body.cadencePolicy = cadencePolicy;
|
|
147
152
|
const executionBudget = {};
|
|
153
|
+
if (flags['max-observation-runs-per-day'] !== undefined)
|
|
154
|
+
executionBudget.maxObservationRunsPerDay = flags['max-observation-runs-per-day'];
|
|
148
155
|
if (flags['max-runs-per-day'] !== undefined) {
|
|
149
156
|
executionBudget.maxRunsPerDay = flags['max-runs-per-day'];
|
|
150
157
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const proposal_decision_command_1 = require("../../lib/proposal-decision-command");
|
|
4
|
+
class ProposalsDiscard extends proposal_decision_command_1.ProposalDecisionCommand {
|
|
5
|
+
static description = 'Discard one displayed proposal through its domain authority';
|
|
6
|
+
static decision = 'discard';
|
|
7
|
+
}
|
|
8
|
+
exports.default = ProposalsDiscard;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const proposal_decision_command_1 = require("../../lib/proposal-decision-command");
|
|
4
|
+
class ProposalsKeep extends proposal_decision_command_1.ProposalDecisionCommand {
|
|
5
|
+
static description = 'Keep one displayed proposal through its domain authority';
|
|
6
|
+
static decision = 'keep';
|
|
7
|
+
}
|
|
8
|
+
exports.default = ProposalsKeep;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
export default class ProposalsList extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static flags: {
|
|
5
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
6
|
+
kind: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
disposition: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
'commitment-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
|
+
'agent-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
limit: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
cursor: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
sort: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
+
};
|
|
14
|
+
run(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
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 proposals_1 = require("../../lib/proposals");
|
|
7
|
+
const format_1 = require("../../lib/format");
|
|
8
|
+
/** A snoozed proposal reads `proposed` in its disposition; the wake time is what tells them apart. */
|
|
9
|
+
function noteFor(row) {
|
|
10
|
+
if (row.sourceStatus === 'snoozed' && row.snoozedUntil)
|
|
11
|
+
return `snoozed until ${row.snoozedUntil}`;
|
|
12
|
+
if (!row.canDecide && row.undecidableReason && row.undecidableReason !== 'settled')
|
|
13
|
+
return data_provider_1.PROPOSAL_UNDECIDABLE_TEXT[row.undecidableReason];
|
|
14
|
+
return '—';
|
|
15
|
+
}
|
|
16
|
+
class ProposalsList extends base_command_1.BaseCommand {
|
|
17
|
+
static description = 'List the bounded proposal inbox and source coverage';
|
|
18
|
+
static flags = {
|
|
19
|
+
json: core_1.Flags.boolean(),
|
|
20
|
+
kind: core_1.Flags.string({ options: [...data_provider_1.PROPOSAL_KINDS] }),
|
|
21
|
+
disposition: core_1.Flags.string({ options: [...data_provider_1.PROPOSAL_DISPOSITIONS] }),
|
|
22
|
+
'commitment-id': core_1.Flags.string(),
|
|
23
|
+
'agent-id': core_1.Flags.string(),
|
|
24
|
+
limit: core_1.Flags.integer({ min: 1, max: 100, default: 50 }),
|
|
25
|
+
cursor: core_1.Flags.string(),
|
|
26
|
+
sort: core_1.Flags.string({ options: ['recent', 'value'], default: 'recent' }),
|
|
27
|
+
};
|
|
28
|
+
async run() {
|
|
29
|
+
this.requireAuth();
|
|
30
|
+
const { flags } = await this.parse(ProposalsList);
|
|
31
|
+
let result;
|
|
32
|
+
try {
|
|
33
|
+
result = await proposals_1.proposalApi.list({
|
|
34
|
+
kind: flags.kind,
|
|
35
|
+
disposition: flags.disposition,
|
|
36
|
+
commitmentId: flags['commitment-id'],
|
|
37
|
+
agentId: flags['agent-id'],
|
|
38
|
+
limit: flags.limit,
|
|
39
|
+
cursor: flags.cursor,
|
|
40
|
+
sort: flags.sort,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
this.handleApiError(error);
|
|
45
|
+
}
|
|
46
|
+
if (flags.json) {
|
|
47
|
+
this.log(JSON.stringify(result, null, 2));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
(0, format_1.renderTable)(result.data.map((row) => ({
|
|
51
|
+
id: row.id,
|
|
52
|
+
title: row.title,
|
|
53
|
+
disposition: row.disposition,
|
|
54
|
+
basis: row.economics?.basis || 'unknown',
|
|
55
|
+
deadline: row.deadline || '—',
|
|
56
|
+
note: noteFor(row),
|
|
57
|
+
})), [
|
|
58
|
+
{ key: 'id', header: 'PROPOSAL', verbatim: true },
|
|
59
|
+
{ key: 'title', header: 'TITLE' },
|
|
60
|
+
{ key: 'disposition', header: 'DISPOSITION' },
|
|
61
|
+
{ key: 'basis', header: 'BASIS' },
|
|
62
|
+
{ key: 'deadline', header: 'DEADLINE' },
|
|
63
|
+
{ key: 'note', header: 'NOTE' },
|
|
64
|
+
], (line) => this.log(line));
|
|
65
|
+
if (!result.coverage.complete)
|
|
66
|
+
this.log(`Partial coverage: ${result.coverage.sources
|
|
67
|
+
.filter((source) => source.status !== 'available')
|
|
68
|
+
.map((source) => `${source.kind}:${source.status}`)
|
|
69
|
+
.join(', ')}`);
|
|
70
|
+
if (result.nextCursor)
|
|
71
|
+
this.log(`Next cursor: ${result.nextCursor}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.default = ProposalsList;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
export default class ProposalsShow extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
kind: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
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 proposals_1 = require("../../lib/proposals");
|
|
7
|
+
class ProposalsShow extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Show one viewer-scoped proposal and its frozen revision';
|
|
9
|
+
static args = {
|
|
10
|
+
kind: core_1.Args.string({ required: true, options: [...data_provider_1.PROPOSAL_KINDS], ignoreStdin: true }),
|
|
11
|
+
id: core_1.Args.string({ required: true, ignoreStdin: true }),
|
|
12
|
+
};
|
|
13
|
+
static flags = { json: core_1.Flags.boolean() };
|
|
14
|
+
async run() {
|
|
15
|
+
this.requireAuth();
|
|
16
|
+
const { args } = await this.parse(ProposalsShow);
|
|
17
|
+
let result;
|
|
18
|
+
try {
|
|
19
|
+
result = await proposals_1.proposalApi.show(args.kind, args.id);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
this.handleApiError(error);
|
|
23
|
+
}
|
|
24
|
+
this.log(JSON.stringify(result, null, 2));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = ProposalsShow;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const proposal_decision_command_1 = require("../../lib/proposal-decision-command");
|
|
4
|
+
class ProposalsSnooze extends proposal_decision_command_1.ProposalDecisionCommand {
|
|
5
|
+
static description = 'Snooze one displayed proposal through its domain authority';
|
|
6
|
+
static decision = 'snooze';
|
|
7
|
+
}
|
|
8
|
+
exports.default = ProposalsSnooze;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/** A single read of the three owner-only Security Center surfaces. */
|
|
3
|
+
export default class SecurityOverview extends BaseCommand {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
limit: import("@oclif/core/lib/interfaces").OptionFlag<number | 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,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../base-command");
|
|
5
|
+
const api_fetch_1 = require("../../lib/api-fetch");
|
|
6
|
+
function rows(value, name) {
|
|
7
|
+
if (!Array.isArray(value))
|
|
8
|
+
throw new Error(`Security overview: invalid ${name} response`);
|
|
9
|
+
if (value.some((row) => row === null || typeof row !== 'object' || Array.isArray(row))) {
|
|
10
|
+
throw new Error(`Security overview: invalid ${name} row`);
|
|
11
|
+
}
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
function hasMore(value, name) {
|
|
15
|
+
if (typeof value !== 'boolean') {
|
|
16
|
+
throw new Error(`Security overview: invalid ${name} pagination`);
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
function activeTokens(value) {
|
|
21
|
+
const tokens = rows(value, 'access tokens');
|
|
22
|
+
// A missing or unfamiliar state must not turn an active credential into a
|
|
23
|
+
// reassuring "None". Validate the whole list before filtering it.
|
|
24
|
+
if (tokens.some((row) => typeof row.state !== 'string' || !['active', 'expired', 'revoked'].includes(row.state))) {
|
|
25
|
+
throw new Error('Security overview: invalid access token state');
|
|
26
|
+
}
|
|
27
|
+
return tokens.filter((row) => row.state === 'active');
|
|
28
|
+
}
|
|
29
|
+
function string(value) {
|
|
30
|
+
return typeof value === 'string' ? value : null;
|
|
31
|
+
}
|
|
32
|
+
/** Explicit allow-lists: the sessions API also returns a full IP address. */
|
|
33
|
+
function safeSession(row) {
|
|
34
|
+
return {
|
|
35
|
+
id: string(row.id) ?? '',
|
|
36
|
+
kind: string(row.kind) ?? 'unknown',
|
|
37
|
+
device: string(row.device) ?? 'Unknown device',
|
|
38
|
+
label: string(row.label),
|
|
39
|
+
daemonId: string(row.daemonId),
|
|
40
|
+
network: string(row.network),
|
|
41
|
+
country: string(row.country),
|
|
42
|
+
createdAt: string(row.createdAt),
|
|
43
|
+
lastActiveAt: string(row.lastActiveAt),
|
|
44
|
+
current: row.current === true,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function safeActivity(row) {
|
|
48
|
+
const device = row.device && typeof row.device === 'object' && !Array.isArray(row.device)
|
|
49
|
+
? row.device
|
|
50
|
+
: {};
|
|
51
|
+
const session = row.session && typeof row.session === 'object' && !Array.isArray(row.session)
|
|
52
|
+
? row.session
|
|
53
|
+
: {};
|
|
54
|
+
return {
|
|
55
|
+
id: string(row.id) ?? '',
|
|
56
|
+
action: string(row.action) ?? 'unknown',
|
|
57
|
+
outcome: string(row.outcome) ?? 'unknown',
|
|
58
|
+
method: string(row.method),
|
|
59
|
+
device: string(device.label),
|
|
60
|
+
network: string(row.network),
|
|
61
|
+
country: string(row.country),
|
|
62
|
+
newDevice: row.newDevice === true,
|
|
63
|
+
reportedNotMe: row.reportedNotMe === true,
|
|
64
|
+
createdAt: string(row.createdAt) ?? '',
|
|
65
|
+
sessionId: string(session.id),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function safeToken(row) {
|
|
69
|
+
return {
|
|
70
|
+
id: string(row.id) ?? '',
|
|
71
|
+
name: string(row.name) ?? '',
|
|
72
|
+
lastFour: string(row.lastFour) ?? '',
|
|
73
|
+
scopes: Array.isArray(row.scopes)
|
|
74
|
+
? row.scopes.filter((v) => typeof v === 'string')
|
|
75
|
+
: [],
|
|
76
|
+
expiresAt: string(row.expiresAt),
|
|
77
|
+
lastUsedAt: string(row.lastUsedAt),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/** A single read of the three owner-only Security Center surfaces. */
|
|
81
|
+
class SecurityOverview extends base_command_1.BaseCommand {
|
|
82
|
+
static description = 'Review active sessions, recent security activity, and access tokens';
|
|
83
|
+
static examples = [
|
|
84
|
+
'<%= config.bin %> security overview',
|
|
85
|
+
'<%= config.bin %> security overview --limit 50 --json',
|
|
86
|
+
];
|
|
87
|
+
static flags = {
|
|
88
|
+
limit: core_1.Flags.integer({
|
|
89
|
+
description: 'Sessions and events to show (default 25, maximum 100)',
|
|
90
|
+
min: 1,
|
|
91
|
+
max: 100,
|
|
92
|
+
}),
|
|
93
|
+
json: core_1.Flags.boolean({ description: 'Output JSON' }),
|
|
94
|
+
};
|
|
95
|
+
async run() {
|
|
96
|
+
this.requireAuth();
|
|
97
|
+
const { flags } = await this.parse(SecurityOverview);
|
|
98
|
+
const limit = flags.limit ?? 25;
|
|
99
|
+
let sessionPage;
|
|
100
|
+
let activityPage;
|
|
101
|
+
let tokenPage;
|
|
102
|
+
try {
|
|
103
|
+
// All three reads must succeed. A partial response could claim an
|
|
104
|
+
// account has no sessions or tokens when a Security Center read failed.
|
|
105
|
+
[sessionPage, activityPage, tokenPage] = await Promise.all([
|
|
106
|
+
(0, api_fetch_1.apiFetch)(`/api/auth/sessions/refresh?limit=${limit}`, {
|
|
107
|
+
credential: this.resolvedCredential,
|
|
108
|
+
}),
|
|
109
|
+
(0, api_fetch_1.apiFetch)(`/api/user/security-activity?limit=${limit}`, {
|
|
110
|
+
credential: this.resolvedCredential,
|
|
111
|
+
}),
|
|
112
|
+
(0, api_fetch_1.apiFetch)('/api/user/access-tokens', {
|
|
113
|
+
credential: this.resolvedCredential,
|
|
114
|
+
}),
|
|
115
|
+
]);
|
|
116
|
+
const sessions = rows(sessionPage?.sessions, 'sessions').map(safeSession);
|
|
117
|
+
const activity = rows(activityPage?.events, 'activity').map(safeActivity);
|
|
118
|
+
const accessTokens = activeTokens(tokenPage?.accessTokens).map(safeToken);
|
|
119
|
+
const overview = {
|
|
120
|
+
sessions,
|
|
121
|
+
sessionsHaveMore: hasMore(sessionPage?.hasMore, 'sessions'),
|
|
122
|
+
activity,
|
|
123
|
+
activityHasMore: hasMore(activityPage?.hasMore, 'activity'),
|
|
124
|
+
accessTokens,
|
|
125
|
+
};
|
|
126
|
+
if (flags.json) {
|
|
127
|
+
this.log(JSON.stringify(overview, null, 2));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
this.log(`Active sessions (${sessions.length}${overview.sessionsHaveMore ? '+' : ''}):`);
|
|
131
|
+
for (const s of sessions) {
|
|
132
|
+
this.log(` ${s.id} ${s.current ? '[this session] ' : ''}${s.label || s.device} ${s.kind} ${s.country || s.network || 'unknown location'} last active ${s.lastActiveAt || 'unknown'}`);
|
|
133
|
+
}
|
|
134
|
+
if (!sessions.length)
|
|
135
|
+
this.log(' None.');
|
|
136
|
+
this.log(`Recent security activity (${activity.length}${overview.activityHasMore ? '+' : ''}):`);
|
|
137
|
+
for (const event of activity) {
|
|
138
|
+
this.log(` ${event.createdAt} ${event.action} (${event.outcome}) ${event.device || 'unknown device'} ${event.country || event.network || 'unknown location'}${event.newDevice ? ' NEW DEVICE' : ''}${event.reportedNotMe ? ' REPORTED' : ''} ${event.id}`);
|
|
139
|
+
}
|
|
140
|
+
if (!activity.length)
|
|
141
|
+
this.log(' None.');
|
|
142
|
+
this.log(`Active access tokens (${accessTokens.length}):`);
|
|
143
|
+
for (const token of accessTokens) {
|
|
144
|
+
this.log(` ${token.id} ${token.name} …${token.lastFour} expires ${token.expiresAt || 'unknown'}`);
|
|
145
|
+
}
|
|
146
|
+
if (!accessTokens.length)
|
|
147
|
+
this.log(' None.');
|
|
148
|
+
if (overview.sessionsHaveMore || overview.activityHasMore) {
|
|
149
|
+
this.log('More sessions or events are available in Account settings; increase --limit to see up to 100 here.');
|
|
150
|
+
}
|
|
151
|
+
this.log('To review an unfamiliar sign-in and secure your account, open Account settings > Security activity.');
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
this.handleApiError(err);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.default = SecurityOverview;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class MonitorsCreate extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static flags: {
|
|
5
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
6
|
+
'from-json': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../../base-command");
|
|
5
|
+
const signals_1 = require("../../../lib/signals");
|
|
6
|
+
const prompt_1 = require("../../../lib/prompt");
|
|
7
|
+
class MonitorsCreate extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Validate, then create, a Signal Monitor (a repeated monitorId answers 409: use revise)';
|
|
9
|
+
static flags = {
|
|
10
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
11
|
+
'from-json': core_1.Flags.string({
|
|
12
|
+
description: 'Monitor definition JSON file path, or - for stdin',
|
|
13
|
+
required: true,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
async run() {
|
|
17
|
+
this.requireAuth();
|
|
18
|
+
const { flags } = await this.parse(MonitorsCreate);
|
|
19
|
+
const body = await (0, prompt_1.readJsonBody)(flags['from-json']);
|
|
20
|
+
// Validation runs first so a refusal never reaches the writer, and the
|
|
21
|
+
// compiled summary is shown before anything is persisted.
|
|
22
|
+
const validation = await signals_1.signalsApi.validateMonitor(body);
|
|
23
|
+
if (!flags.json)
|
|
24
|
+
this.log(JSON.stringify(validation, null, 2));
|
|
25
|
+
const result = await signals_1.signalsApi.createMonitor(body);
|
|
26
|
+
this.log(JSON.stringify(flags.json ? { validation, ...result } : result, null, 2));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.default = MonitorsCreate;
|