@skrr-ai/cli 0.1.95 → 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 +22 -0
- 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/jobs/show.js +12 -0
- 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/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/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/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/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/cascade-status.d.ts +2 -0
- package/dist/commands/tasks/cascade-status.js +27 -1
- 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/list.d.ts +1 -0
- package/dist/commands/tasks/list.js +44 -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/triggers/create.d.ts +2 -0
- package/dist/commands/triggers/create.js +15 -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/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 -7
- package/dist/lib/commitments.js +173 -85
- package/dist/lib/compasses.d.ts +14 -0
- package/dist/lib/compasses.js +25 -11
- 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/measures.d.ts +28 -2
- package/dist/lib/measures.js +38 -14
- 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/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-economics.d.ts +16 -0
- package/dist/lib/task-economics.js +22 -0
- package/dist/lib/triggers.d.ts +11 -3
- package/dist/lib/triggers.js +58 -1
- 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/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/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/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/package.json +10 -0
- package/dist/node_modules/@skrr-ai/data-provider/index.js +8017 -7086
- package/oclif.manifest.json +3872 -1167
- package/package.json +22 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSpaceUsage = void 0;
|
|
4
|
+
exports.formatSpaceSpend = formatSpaceSpend;
|
|
5
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
6
|
+
const getSpaceUsage = (spaceId, window = '30d') => data_provider_1.dataService.getSpaceUsage(spaceId, window);
|
|
7
|
+
exports.getSpaceUsage = getSpaceUsage;
|
|
8
|
+
/** A positive amount under one cent must not print as $0.00; a measured zero stays $0.00. */
|
|
9
|
+
const usd = (amount) => amount > 0 && amount < 0.01 ? '<$0.01' : `$${amount.toFixed(2)}`;
|
|
10
|
+
function formatSpaceSpend(summary) {
|
|
11
|
+
const attribution = `Attribution since: ${summary.coverage.attributionSince || 'not certified'}; not attributed: ${summary.coverage.notAttributed.join(', ')}`;
|
|
12
|
+
if (summary.runCount === 0)
|
|
13
|
+
return `No runs in window\n${attribution}`;
|
|
14
|
+
const cost = summary.costUsd === null ? 'Not fully attributed' : usd(summary.costUsd);
|
|
15
|
+
const known = summary.knownCostUsd === null ? 'unavailable' : usd(summary.knownCostUsd);
|
|
16
|
+
return `${cost}; known subtotal ${known}; ${summary.runCount} cost records; ${summary.byCostStatus.unavailable} unavailable, ${summary.byCostStatus.partial} partial\n${attribution}`;
|
|
17
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WorkspaceGrantReport, WorkspaceStewardshipReport } from './workspaces';
|
|
2
|
+
export declare function printStewardshipCoverage(report: WorkspaceGrantReport, log: (line: string) => void): void;
|
|
3
|
+
export declare function printWorkspaceGrants(report: WorkspaceGrantReport, log: (line: string) => void): void;
|
|
4
|
+
export declare function printWorkspaceStewardship(report: WorkspaceStewardshipReport, log: (line: string) => void): void;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.printStewardshipCoverage = printStewardshipCoverage;
|
|
4
|
+
exports.printWorkspaceGrants = printWorkspaceGrants;
|
|
5
|
+
exports.printWorkspaceStewardship = printWorkspaceStewardship;
|
|
6
|
+
const format_1 = require("./format");
|
|
7
|
+
function printStewardshipCoverage(report, log) {
|
|
8
|
+
if (report.coverage.complete) {
|
|
9
|
+
log('Coverage: complete within the bounded sources.');
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
log('Coverage: incomplete. Unreadable sources do not confirm absence.');
|
|
13
|
+
for (const source of report.coverage.sources) {
|
|
14
|
+
if (source.status === 'unavailable')
|
|
15
|
+
log(`${source.name}: unavailable`);
|
|
16
|
+
else if (source.truncated)
|
|
17
|
+
log(`${source.name}: truncated at 200 rows`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function printWorkspaceGrants(report, log) {
|
|
21
|
+
printStewardshipCoverage(report, log);
|
|
22
|
+
printGrantRows(report, log);
|
|
23
|
+
}
|
|
24
|
+
function printGrantRows(report, log) {
|
|
25
|
+
if (report.grants === null) {
|
|
26
|
+
log('Grants: unavailable.');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (!report.grants.length) {
|
|
30
|
+
log('No workspace Grants observed.');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
(0, format_1.renderTable)(report.grants.map((row) => ({
|
|
34
|
+
id: row.id,
|
|
35
|
+
label: row.label,
|
|
36
|
+
owner: row.ownerUserId,
|
|
37
|
+
active: row.active ? 'yes' : 'no',
|
|
38
|
+
expires: row.expiresAt ?? '',
|
|
39
|
+
envKeys: row.credential?.envKeys.join(', ') ?? '',
|
|
40
|
+
referencedBy: row.referencedBy === null
|
|
41
|
+
? 'unavailable'
|
|
42
|
+
: `${row.referencedBy.join(', ')}${row.referencesTruncated ? ' (truncated)' : ''}`,
|
|
43
|
+
})), [
|
|
44
|
+
{ key: 'id', header: 'ID' },
|
|
45
|
+
{ key: 'label', header: 'LABEL' },
|
|
46
|
+
{ key: 'owner', header: 'OWNER' },
|
|
47
|
+
{ key: 'active', header: 'ACTIVE' },
|
|
48
|
+
{ key: 'expires', header: 'EXPIRES' },
|
|
49
|
+
{ key: 'envKeys', header: 'ENV NAMES' },
|
|
50
|
+
{ key: 'referencedBy', header: 'REFERENCED BY' },
|
|
51
|
+
], log);
|
|
52
|
+
}
|
|
53
|
+
function printWorkspaceStewardship(report, log) {
|
|
54
|
+
printStewardshipCoverage(report, log);
|
|
55
|
+
log(`Membership: ${report.membership.status}${report.membership.role ? ` (${report.membership.role})` : ''}`);
|
|
56
|
+
for (const [name, rows] of [
|
|
57
|
+
['Commitments', report.commitments],
|
|
58
|
+
['Approver seats', report.approverSeats],
|
|
59
|
+
]) {
|
|
60
|
+
log(`${name}: ${rows === null ? 'unavailable' : rows.length}`);
|
|
61
|
+
if (rows?.length)
|
|
62
|
+
(0, format_1.renderTable)(rows.map((row) => ({
|
|
63
|
+
id: row.id,
|
|
64
|
+
title: row.title ?? '',
|
|
65
|
+
status: row.status ?? '',
|
|
66
|
+
agentId: row.agentId ?? '',
|
|
67
|
+
})), [
|
|
68
|
+
{ key: 'id', header: 'ID' },
|
|
69
|
+
{ key: 'title', header: 'TITLE' },
|
|
70
|
+
{ key: 'status', header: 'STATUS' },
|
|
71
|
+
{ key: 'agentId', header: 'EXECUTOR' },
|
|
72
|
+
], log);
|
|
73
|
+
}
|
|
74
|
+
log(`Authored Agents: ${report.agents === null ? 'unavailable' : report.agents.length}`);
|
|
75
|
+
if (report.agents?.length)
|
|
76
|
+
(0, format_1.renderTable)(report.agents.map((row) => ({ id: row.id, name: row.name ?? '' })), [
|
|
77
|
+
{ key: 'id', header: 'ID' },
|
|
78
|
+
{ key: 'name', header: 'NAME' },
|
|
79
|
+
], log);
|
|
80
|
+
log('Grants:');
|
|
81
|
+
printGrantRows(report, log);
|
|
82
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { WorkResourceKind } from '@skrr-ai/data-provider';
|
|
1
|
+
import type { WorkResourceKind, TaskResourceWriteReceipt } from '@skrr-ai/data-provider';
|
|
2
2
|
export type TaskAssetRole = 'input' | 'evidence' | 'deliverable';
|
|
3
3
|
/**
|
|
4
4
|
* What the bytes ARE in the work ledger, for an upload that is the archived
|
|
@@ -24,6 +24,8 @@ export interface TaskAssetLedgerResource {
|
|
|
24
24
|
expectationIds?: string[];
|
|
25
25
|
}
|
|
26
26
|
export interface UploadedTaskAsset {
|
|
27
|
+
/** The canonical Task relationship and exact Resource version recorded by this upload. */
|
|
28
|
+
resourceReceipt?: TaskResourceWriteReceipt;
|
|
27
29
|
id: string;
|
|
28
30
|
/**
|
|
29
31
|
* sha256 (hex) of the bytes the server STORED, as the server recorded them.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare function economicsFromFlags(flags: {
|
|
2
|
+
savings?: string;
|
|
3
|
+
per?: string;
|
|
4
|
+
effort?: string;
|
|
5
|
+
risk?: string;
|
|
6
|
+
}, existing?: unknown): {
|
|
7
|
+
savings?: {
|
|
8
|
+
amount: number;
|
|
9
|
+
currency: "USD";
|
|
10
|
+
per: "month" | "year" | "once";
|
|
11
|
+
} | undefined;
|
|
12
|
+
effortHours?: number | undefined;
|
|
13
|
+
risk?: "low" | "medium" | "high" | undefined;
|
|
14
|
+
confidence?: "low" | "medium" | "high" | undefined;
|
|
15
|
+
rationale?: string | undefined;
|
|
16
|
+
} | undefined;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.economicsFromFlags = economicsFromFlags;
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
function economicsFromFlags(flags, existing) {
|
|
6
|
+
if ([flags.savings, flags.per, flags.effort, flags.risk].every((value) => value === undefined))
|
|
7
|
+
return undefined;
|
|
8
|
+
if ((flags.savings === undefined) !== (flags.per === undefined))
|
|
9
|
+
throw new Error('--savings and --per must be supplied together (USD/month, year or once).');
|
|
10
|
+
for (const value of [flags.savings, flags.effort])
|
|
11
|
+
if (value !== undefined && value.trim() === '')
|
|
12
|
+
throw new Error('Economic amounts must be explicit nonnegative numbers.');
|
|
13
|
+
const content = existing && typeof existing === 'object' ? existing : {};
|
|
14
|
+
return data_provider_1.ProposalEconomicsInputSchema.parse({
|
|
15
|
+
...content,
|
|
16
|
+
...(flags.savings !== undefined
|
|
17
|
+
? { savings: { amount: Number(flags.savings), currency: 'USD', per: flags.per } }
|
|
18
|
+
: {}),
|
|
19
|
+
...(flags.effort !== undefined ? { effortHours: Number(flags.effort) } : {}),
|
|
20
|
+
...(flags.risk !== undefined ? { risk: flags.risk } : {}),
|
|
21
|
+
});
|
|
22
|
+
}
|
package/dist/lib/triggers.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type EmbeddedActionRef, type TriggerPreflightReport } from '@skrr-ai/data-provider';
|
|
1
|
+
import { type EmbeddedActionRef, type TriggerPreflightReport, type TriggerSensorConfig } from '@skrr-ai/data-provider';
|
|
2
2
|
export declare const TRIGGER_KINDS: readonly ["schedule", "once", "event", "stochastic", "self_scheduled", "on_demand", "form", "chat_message"];
|
|
3
3
|
export declare const TRIGGER_SCOPE_KINDS: readonly ["agent", "group_chat_subscriber", "space_oracle", "space_subscriber", "key_result_watcher", "task_watcher", "goal_watcher", "entity_reminder"];
|
|
4
4
|
/**
|
|
@@ -18,7 +18,7 @@ export declare const TRIGGER_SCOPE_KINDS: readonly ["agent", "group_chat_subscri
|
|
|
18
18
|
* capability was live and unreachable. `watch_until` and `sensor_poll` had been
|
|
19
19
|
* in that state for longer.
|
|
20
20
|
*/
|
|
21
|
-
export declare const TRIGGER_EXECUTOR_MODES: readonly ["send_message", "run_only", "enqueue_group_chat_agent_turn", "enqueue_assistant_turn", "enqueue_space_assistant_turn", "proactive_orchestrator_check", "auto_dream_orchestrator", "task_schedule_fire", "goal_planner_tick", "morning_briefing", "builtin_action", "task_execute", "watch_until", "sensor_poll", "external_work_task", "notify_user", "space_cycle_rollover"];
|
|
21
|
+
export declare const TRIGGER_EXECUTOR_MODES: readonly ["send_message", "run_only", "enqueue_group_chat_agent_turn", "enqueue_assistant_turn", "enqueue_space_assistant_turn", "proactive_orchestrator_check", "auto_dream_orchestrator", "task_schedule_fire", "goal_planner_tick", "morning_briefing", "builtin_action", "task_execute", "watch_until", "sensor_poll", "external_work_task", "notify_user", "space_cycle_rollover", "workflow_signal"];
|
|
22
22
|
export declare const TRIGGER_EVENT_FILTER_MODES: readonly ["equals", "contains", "in_set"];
|
|
23
23
|
export declare const TRIGGER_CONCURRENCY_POLICIES: readonly ["coalesce_if_active", "allow_parallel"];
|
|
24
24
|
export declare const TRIGGER_FORM_RESPONSE_MODES: readonly ["thank_you_page", "redirect_url", "run_complete"];
|
|
@@ -85,7 +85,9 @@ export interface TriggerDefinition {
|
|
|
85
85
|
kind?: string;
|
|
86
86
|
refs?: Record<string, unknown>;
|
|
87
87
|
};
|
|
88
|
-
execution?: Record<string, unknown
|
|
88
|
+
execution?: Record<string, unknown> & {
|
|
89
|
+
sensor?: TriggerSensorConfig;
|
|
90
|
+
};
|
|
89
91
|
schedule?: Record<string, unknown>;
|
|
90
92
|
once?: Record<string, unknown>;
|
|
91
93
|
event?: Record<string, unknown>;
|
|
@@ -341,6 +343,12 @@ export declare function nextRunLabel(trigger: TriggerDefinition): string;
|
|
|
341
343
|
* (OSK-7711).
|
|
342
344
|
*/
|
|
343
345
|
export declare function armedLabel(trigger: TriggerDefinition): string;
|
|
346
|
+
/**
|
|
347
|
+
* A keyed sensor that is still ENABLED but degraded (an item has failed for
|
|
348
|
+
* dozens of polls) reads `yes` in ARMED, which is true and not the whole story.
|
|
349
|
+
* Marked here so the list says it, not only `triggers show`.
|
|
350
|
+
*/
|
|
351
|
+
export declare function degradedMarker(trigger: TriggerDefinition): string;
|
|
344
352
|
export declare function renderTriggerList(triggers: TriggerDefinition[], log: (line: string) => void): void;
|
|
345
353
|
/**
|
|
346
354
|
* The `duplicate_subscription` warning a create response may carry, as the
|
package/dist/lib/triggers.js
CHANGED
|
@@ -29,6 +29,7 @@ exports.fetchAgentScopedTrigger = fetchAgentScopedTrigger;
|
|
|
29
29
|
exports.scopeLabel = scopeLabel;
|
|
30
30
|
exports.nextRunLabel = nextRunLabel;
|
|
31
31
|
exports.armedLabel = armedLabel;
|
|
32
|
+
exports.degradedMarker = degradedMarker;
|
|
32
33
|
exports.renderTriggerList = renderTriggerList;
|
|
33
34
|
exports.formatDuplicateSubscriptionWarning = formatDuplicateSubscriptionWarning;
|
|
34
35
|
exports.armedStateLabel = armedStateLabel;
|
|
@@ -99,6 +100,9 @@ exports.TRIGGER_EXECUTOR_MODES = [
|
|
|
99
100
|
'external_work_task',
|
|
100
101
|
'notify_user',
|
|
101
102
|
'space_cycle_rollover',
|
|
103
|
+
// Resolve a workflow step an agent parked with `workflow_await`, when this
|
|
104
|
+
// trigger's event arrives. Needs `--workflow-event-key`.
|
|
105
|
+
'workflow_signal',
|
|
102
106
|
];
|
|
103
107
|
exports.TRIGGER_EVENT_FILTER_MODES = ['equals', 'contains', 'in_set'];
|
|
104
108
|
exports.TRIGGER_CONCURRENCY_POLICIES = ['coalesce_if_active', 'allow_parallel'];
|
|
@@ -748,6 +752,15 @@ function armedLabel(trigger) {
|
|
|
748
752
|
}
|
|
749
753
|
return 'yes';
|
|
750
754
|
}
|
|
755
|
+
/**
|
|
756
|
+
* A keyed sensor that is still ENABLED but degraded (an item has failed for
|
|
757
|
+
* dozens of polls) reads `yes` in ARMED, which is true and not the whole story.
|
|
758
|
+
* Marked here so the list says it, not only `triggers show`.
|
|
759
|
+
*/
|
|
760
|
+
function degradedMarker(trigger) {
|
|
761
|
+
const reason = trigger.execution?.sensor?.state?.degradedReason;
|
|
762
|
+
return reason ? ' (degraded)' : '';
|
|
763
|
+
}
|
|
751
764
|
function renderTriggerList(triggers, log) {
|
|
752
765
|
if (triggers.length === 0) {
|
|
753
766
|
log('No triggers.');
|
|
@@ -756,7 +769,7 @@ function renderTriggerList(triggers, log) {
|
|
|
756
769
|
(0, format_1.renderTable)(triggers.map((trigger) => ({
|
|
757
770
|
id: trigger.id ?? '-',
|
|
758
771
|
kind: trigger.kind ?? '-',
|
|
759
|
-
enabled: armedLabel(trigger)
|
|
772
|
+
enabled: `${armedLabel(trigger)}${degradedMarker(trigger)}`,
|
|
760
773
|
scope: scopeLabel(trigger),
|
|
761
774
|
next: nextRunLabel(trigger),
|
|
762
775
|
label: trigger.label ?? '',
|
|
@@ -768,6 +781,12 @@ function renderTriggerList(triggers, log) {
|
|
|
768
781
|
{ key: 'next', header: 'NEXT/LAST', maxWidth: 24 },
|
|
769
782
|
{ key: 'label', header: 'LABEL', maxWidth: 32 },
|
|
770
783
|
], log);
|
|
784
|
+
const degraded = triggers.filter((t) => degradedMarker(t));
|
|
785
|
+
if (degraded.length > 0) {
|
|
786
|
+
log('');
|
|
787
|
+
log(`${degraded.length} trigger(s) are enabled but degraded — ` +
|
|
788
|
+
'see `Degraded:` in `triggers show <id>`.');
|
|
789
|
+
}
|
|
771
790
|
const unsynced = triggers.filter((t) => armedLabel(t).startsWith('!'));
|
|
772
791
|
if (unsynced.length > 0) {
|
|
773
792
|
log('');
|
|
@@ -872,6 +891,44 @@ function renderTriggerSummary(trigger, log, options = {}) {
|
|
|
872
891
|
log(`Label: ${trigger.label}`);
|
|
873
892
|
if (trigger.execution?.mode)
|
|
874
893
|
log(`Mode: ${String(trigger.execution.mode)}`);
|
|
894
|
+
const sensor = trigger.execution?.mode === 'sensor_poll' ? trigger.execution.sensor : undefined;
|
|
895
|
+
if (sensor?.measureSink) {
|
|
896
|
+
log(`Measure: ${sensor.measureSink.measureId} — platform fetched, unconfirmed`);
|
|
897
|
+
if (sensor.state?.lastSinkError)
|
|
898
|
+
log(`Sink: ${sensor.state.lastSinkError}`);
|
|
899
|
+
else if (sensor.state?.lastSinkAt)
|
|
900
|
+
log(`Sink: last reading ${sensor.state.lastSinkValue ?? '-'} at ${sensor.state.lastSinkAt}`);
|
|
901
|
+
else
|
|
902
|
+
log('Sink: awaiting a numeric reading');
|
|
903
|
+
}
|
|
904
|
+
// A keyed sensor can be quietly blind (items held back, unreadable, failing).
|
|
905
|
+
// Each count is printed, and zero is printed too: "0" and "absent" must read
|
|
906
|
+
// differently from a sensor that has never been counted.
|
|
907
|
+
if (sensor?.cursor?.mode === 'keyed' && sensor.state) {
|
|
908
|
+
const st = sensor.state;
|
|
909
|
+
const n = (v) => v ?? 0;
|
|
910
|
+
log(`Keyed: deferred ${n(st.deferredCount)}, unreadable ${n(st.unreadableCount)}, failed ${n(st.failedItemCount)}, quarantined ${n(st.quarantinedCount)}, duplicates ${n(st.duplicateCount)}, unsubjected ${n(st.unsubjectedCount)} (cumulative)`);
|
|
911
|
+
}
|
|
912
|
+
if (sensor?.cursor?.mode === 'keyed' && sensor.state) {
|
|
913
|
+
const st = sensor.state;
|
|
914
|
+
// A reseed publishes nothing by design, so it is the one change nothing
|
|
915
|
+
// else records: say when it happened, why, and how often.
|
|
916
|
+
if (st.reseededAt) {
|
|
917
|
+
const why = st.reseededReason
|
|
918
|
+
? (data_provider_1.KEYED_RESEED_COPY[st.reseededReason] ?? st.reseededReason)
|
|
919
|
+
: 'reason not recorded';
|
|
920
|
+
log(`Reseeded: ${st.reseededAt} (${st.reseededReason ?? 'unknown'}: ${why}); ${st.reseedCount ?? 1} time(s); nothing was published for it`);
|
|
921
|
+
}
|
|
922
|
+
if (st.itemFailurePolls)
|
|
923
|
+
log(`Items: failing for ${st.itemFailurePolls} poll(s) in a row`);
|
|
924
|
+
}
|
|
925
|
+
// The sensor is degraded, not just carrying a line of text: say it first.
|
|
926
|
+
if (sensor?.state?.degradedReason)
|
|
927
|
+
log(`Degraded: ${sensor.state.degradedReason}`);
|
|
928
|
+
if (sensor?.state?.consecutiveErrors)
|
|
929
|
+
log(`Errors: ${sensor.state.consecutiveErrors} feed failure(s) in a row (the sensor disables itself if the feed keeps failing)`);
|
|
930
|
+
if (sensor?.state?.lastError)
|
|
931
|
+
log(`Problem: ${sensor.state.lastError}`);
|
|
875
932
|
// An `external_work_task` writes into someone else's system, and which
|
|
876
933
|
// contract governs that write — and whether it posts by itself — was readable
|
|
877
934
|
// only by pulling `execution.effectPolicy` out of raw JSON. A trigger that can
|
|
@@ -23,6 +23,14 @@ import type { CommandManifest } from './command-manifest';
|
|
|
23
23
|
* only then whether the bound is still the right size.
|
|
24
24
|
*/
|
|
25
25
|
export declare const USAGE_OVERVIEW_TOKEN_BUDGET = 240;
|
|
26
|
+
/**
|
|
27
|
+
* Topics listed under another domain instead of as their own overview line.
|
|
28
|
+
* Every command keeps its own id (`skrr proposals list`); only the discovery
|
|
29
|
+
* grouping changes, and `skrr usage <folded>` resolves to the host page, which
|
|
30
|
+
* names the folded topic in an `Includes:` line so it stays reachable.
|
|
31
|
+
* `proposals` is the unified proposal inbox, so it reads as part of `inbox`.
|
|
32
|
+
*/
|
|
33
|
+
export declare const USAGE_DOMAIN_FOLDS: Readonly<Record<string, string>>;
|
|
26
34
|
export declare const USAGE_DOMAIN_TOKEN_BUDGET = 500;
|
|
27
35
|
export type UsageCommand = {
|
|
28
36
|
command: string;
|
|
@@ -46,6 +54,8 @@ export type UsageReference = {
|
|
|
46
54
|
object: 'sky_usage_reference';
|
|
47
55
|
generatedFrom: 'oclif.manifest.json';
|
|
48
56
|
domain: string;
|
|
57
|
+
/** Topics folded into this domain (see `USAGE_DOMAIN_FOLDS`). */
|
|
58
|
+
includes?: string[];
|
|
49
59
|
tokenBudget: number;
|
|
50
60
|
estimatedTokens: number;
|
|
51
61
|
page: number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.USAGE_DOMAIN_TOKEN_BUDGET = exports.USAGE_OVERVIEW_TOKEN_BUDGET = void 0;
|
|
3
|
+
exports.USAGE_DOMAIN_TOKEN_BUDGET = exports.USAGE_DOMAIN_FOLDS = exports.USAGE_OVERVIEW_TOKEN_BUDGET = void 0;
|
|
4
4
|
exports.estimateUsageTokens = estimateUsageTokens;
|
|
5
5
|
exports.usageDomains = usageDomains;
|
|
6
6
|
exports.buildUsageOverview = buildUsageOverview;
|
|
@@ -34,6 +34,14 @@ const command_manifest_1 = require("./command-manifest");
|
|
|
34
34
|
* only then whether the bound is still the right size.
|
|
35
35
|
*/
|
|
36
36
|
exports.USAGE_OVERVIEW_TOKEN_BUDGET = 240;
|
|
37
|
+
/**
|
|
38
|
+
* Topics listed under another domain instead of as their own overview line.
|
|
39
|
+
* Every command keeps its own id (`skrr proposals list`); only the discovery
|
|
40
|
+
* grouping changes, and `skrr usage <folded>` resolves to the host page, which
|
|
41
|
+
* names the folded topic in an `Includes:` line so it stays reachable.
|
|
42
|
+
* `proposals` is the unified proposal inbox, so it reads as part of `inbox`.
|
|
43
|
+
*/
|
|
44
|
+
exports.USAGE_DOMAIN_FOLDS = { proposals: 'inbox' };
|
|
37
45
|
exports.USAGE_DOMAIN_TOKEN_BUDGET = 500;
|
|
38
46
|
const GENERIC_FLAGS = new Set(['bare', 'help', 'json', 'token', 'workspace']);
|
|
39
47
|
/**
|
|
@@ -74,7 +82,8 @@ function buildUsageOverview(manifest, bin = 'skrr') {
|
|
|
74
82
|
}
|
|
75
83
|
/** Return case-insensitive manifest domain names without inventing aliases. */
|
|
76
84
|
function resolveUsageDomain(manifest, value) {
|
|
77
|
-
const
|
|
85
|
+
const trimmed = value.trim().toLowerCase();
|
|
86
|
+
const needle = exports.USAGE_DOMAIN_FOLDS[trimmed] ?? trimmed;
|
|
78
87
|
return usageDomains(manifest).find(({ domain }) => domain.toLowerCase() === needle)?.domain;
|
|
79
88
|
}
|
|
80
89
|
/**
|
|
@@ -95,10 +104,12 @@ function buildUsageReference(manifest, domainInput, options = {}) {
|
|
|
95
104
|
if (!Number.isInteger(requested) || index < 0 || index >= pages.length)
|
|
96
105
|
return undefined;
|
|
97
106
|
const data = pages[index];
|
|
107
|
+
const includes = foldedTopics(manifest, domain);
|
|
98
108
|
const draft = {
|
|
99
109
|
object: 'sky_usage_reference',
|
|
100
110
|
generatedFrom: 'oclif.manifest.json',
|
|
101
111
|
domain,
|
|
112
|
+
...(includes.length > 0 ? { includes } : {}),
|
|
102
113
|
tokenBudget: exports.USAGE_DOMAIN_TOKEN_BUDGET,
|
|
103
114
|
estimatedTokens: 0,
|
|
104
115
|
page: requested,
|
|
@@ -122,6 +133,8 @@ function renderUsageReference(reference, bin = 'skrr') {
|
|
|
122
133
|
`${reference.domain} commands — page ${reference.page}/${reference.pages} ` +
|
|
123
134
|
`(${reference.commandCount} total; manifest-derived).`,
|
|
124
135
|
];
|
|
136
|
+
if (reference.includes?.length)
|
|
137
|
+
lines.push(`Includes: ${reference.includes.join(', ')}.`);
|
|
125
138
|
for (const command of reference.data) {
|
|
126
139
|
const flags = command.keyFlags.length > 0 ? ` Flags: ${command.keyFlags.join(', ')}.` : '';
|
|
127
140
|
lines.push(`${bin} ${command.command} — ${command.description}.${flags} Example: ${command.example}`);
|
|
@@ -167,13 +180,21 @@ function auditUsageBudgets(manifest, bin = 'skrr') {
|
|
|
167
180
|
function groupEntries(manifest) {
|
|
168
181
|
const grouped = new Map();
|
|
169
182
|
for (const entry of (0, command_manifest_1.visibleCommandEntries)(manifest)) {
|
|
170
|
-
const
|
|
183
|
+
const topic = entry.id.split(':')[0];
|
|
184
|
+
const domain = exports.USAGE_DOMAIN_FOLDS[topic] ?? topic;
|
|
171
185
|
const existing = grouped.get(domain) ?? [];
|
|
172
186
|
existing.push(entry);
|
|
173
187
|
grouped.set(domain, existing);
|
|
174
188
|
}
|
|
175
189
|
return grouped;
|
|
176
190
|
}
|
|
191
|
+
function foldedTopics(manifest, domain) {
|
|
192
|
+
const present = new Set((0, command_manifest_1.visibleCommandEntries)(manifest).map((entry) => entry.id.split(':')[0]));
|
|
193
|
+
return Object.entries(exports.USAGE_DOMAIN_FOLDS)
|
|
194
|
+
.filter(([topic, host]) => host === domain && present.has(topic))
|
|
195
|
+
.map(([topic]) => topic)
|
|
196
|
+
.sort();
|
|
197
|
+
}
|
|
177
198
|
function usageCommand(entry, bin) {
|
|
178
199
|
const flags = Object.entries(entry.flags)
|
|
179
200
|
.filter(([, value]) => !value.hidden)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type RunLike = Record<string, unknown>;
|
|
2
|
+
/**
|
|
3
|
+
* Human lines for a run's duration budget and for a run the budget stopped.
|
|
4
|
+
*
|
|
5
|
+
* The server derives `budget` per read and stamps `error.code =
|
|
6
|
+
* WORKFLOW_RUN_DEADLINE` on a run it cancelled; this only words them. A run with
|
|
7
|
+
* neither prints nothing: no budget is not "0 minutes left".
|
|
8
|
+
*/
|
|
9
|
+
export declare function describeRunBudget(run: RunLike): string[];
|
|
10
|
+
/** The status cell, naming a time-limit stop where the plain status would hide it. */
|
|
11
|
+
export declare function runStatusLabel(run: RunLike): string;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.describeRunBudget = describeRunBudget;
|
|
4
|
+
exports.runStatusLabel = runStatusLabel;
|
|
5
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
6
|
+
/**
|
|
7
|
+
* Human lines for a run's duration budget and for a run the budget stopped.
|
|
8
|
+
*
|
|
9
|
+
* The server derives `budget` per read and stamps `error.code =
|
|
10
|
+
* WORKFLOW_RUN_DEADLINE` on a run it cancelled; this only words them. A run with
|
|
11
|
+
* neither prints nothing: no budget is not "0 minutes left".
|
|
12
|
+
*/
|
|
13
|
+
function describeRunBudget(run) {
|
|
14
|
+
const lines = [];
|
|
15
|
+
const error = run.error;
|
|
16
|
+
if (error?.code === data_provider_1.WORKFLOW_RUN_DEADLINE) {
|
|
17
|
+
lines.push(`Stopped: ${error.code}${error.message ? ` - ${error.message}` : ''}`);
|
|
18
|
+
}
|
|
19
|
+
const budget = run.budget;
|
|
20
|
+
if (budget && Number.isFinite(budget.maxDurationMs)) {
|
|
21
|
+
const limit = (0, data_provider_1.describeWorkflowDuration)(budget.maxDurationMs);
|
|
22
|
+
if (budget.exceeded)
|
|
23
|
+
lines.push(`Time limit: ${limit}, exceeded (deadline ${budget.deadlineAt})`);
|
|
24
|
+
else if (budget.remainingMs > 0)
|
|
25
|
+
lines.push(`Time limit: ${limit}, ${(0, data_provider_1.describeWorkflowDuration)(budget.remainingMs)} left (deadline ${budget.deadlineAt})`);
|
|
26
|
+
else
|
|
27
|
+
lines.push(`Time limit: ${limit} (deadline ${budget.deadlineAt})`);
|
|
28
|
+
}
|
|
29
|
+
return lines;
|
|
30
|
+
}
|
|
31
|
+
/** The status cell, naming a time-limit stop where the plain status would hide it. */
|
|
32
|
+
function runStatusLabel(run) {
|
|
33
|
+
const status = String(run.status ?? '-');
|
|
34
|
+
return run.error?.code === data_provider_1.WORKFLOW_RUN_DEADLINE
|
|
35
|
+
? `${status} (time limit)`
|
|
36
|
+
: status;
|
|
37
|
+
}
|
package/dist/lib/workspaces.d.ts
CHANGED
|
@@ -1,3 +1,51 @@
|
|
|
1
|
+
import type { GrantPublic } from '@skrr-ai/data-schemas';
|
|
2
|
+
export interface StewardshipSource {
|
|
3
|
+
name: string;
|
|
4
|
+
status: 'available' | 'unavailable';
|
|
5
|
+
truncated: boolean;
|
|
6
|
+
code?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface StewardshipCoverage {
|
|
9
|
+
complete: boolean;
|
|
10
|
+
truncated: boolean;
|
|
11
|
+
sources: StewardshipSource[];
|
|
12
|
+
}
|
|
13
|
+
export type WorkspaceGrantMetadata = Omit<GrantPublic, 'credential' | 'createdAt' | 'updatedAt'> & {
|
|
14
|
+
ownerUserId: string;
|
|
15
|
+
credential: (NonNullable<GrantPublic['credential']> & {
|
|
16
|
+
fingerprint?: string;
|
|
17
|
+
}) | null;
|
|
18
|
+
createdAt?: string;
|
|
19
|
+
updatedAt?: string;
|
|
20
|
+
referencedBy: string[] | null;
|
|
21
|
+
referencesTruncated: boolean;
|
|
22
|
+
};
|
|
23
|
+
export interface WorkspaceGrantReport {
|
|
24
|
+
workspaceId: string;
|
|
25
|
+
grants: WorkspaceGrantMetadata[] | null;
|
|
26
|
+
coverage: StewardshipCoverage;
|
|
27
|
+
}
|
|
28
|
+
export interface StewardshipCommitmentMetadata {
|
|
29
|
+
id: string;
|
|
30
|
+
title?: string;
|
|
31
|
+
status?: string;
|
|
32
|
+
agentId?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface WorkspaceStewardshipReport extends WorkspaceGrantReport {
|
|
35
|
+
memberUserId: string;
|
|
36
|
+
membership: {
|
|
37
|
+
status: 'active' | 'absent' | 'unavailable';
|
|
38
|
+
role?: string;
|
|
39
|
+
};
|
|
40
|
+
commitments: StewardshipCommitmentMetadata[] | null;
|
|
41
|
+
approverSeats: StewardshipCommitmentMetadata[] | null;
|
|
42
|
+
agents: Array<{
|
|
43
|
+
id: string;
|
|
44
|
+
name?: string;
|
|
45
|
+
}> | null;
|
|
46
|
+
}
|
|
47
|
+
export declare function getWorkspaceStewardship(workspaceId: string, memberUserId: string): Promise<WorkspaceStewardshipReport>;
|
|
48
|
+
export declare function listWorkspaceGrants(workspaceId: string): Promise<WorkspaceGrantReport>;
|
|
1
49
|
/**
|
|
2
50
|
* The workspaces this account belongs to.
|
|
3
51
|
*
|
package/dist/lib/workspaces.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getWorkspaceStewardship = getWorkspaceStewardship;
|
|
4
|
+
exports.listWorkspaceGrants = listWorkspaceGrants;
|
|
3
5
|
exports.describeUnselectedWorkspace = describeUnselectedWorkspace;
|
|
4
6
|
exports.listWorkspaces = listWorkspaces;
|
|
5
7
|
exports.ambientWorkspaceId = ambientWorkspaceId;
|
|
@@ -10,6 +12,12 @@ exports.getWorkspace = getWorkspace;
|
|
|
10
12
|
exports.matchWorkspace = matchWorkspace;
|
|
11
13
|
const api_fetch_1 = require("./api-fetch");
|
|
12
14
|
const triggers_1 = require("./triggers");
|
|
15
|
+
async function getWorkspaceStewardship(workspaceId, memberUserId) {
|
|
16
|
+
return (0, api_fetch_1.apiFetch)(`/api/workspaces/${encodeURIComponent(workspaceId)}/stewardship/members/${encodeURIComponent(memberUserId)}`);
|
|
17
|
+
}
|
|
18
|
+
async function listWorkspaceGrants(workspaceId) {
|
|
19
|
+
return (0, api_fetch_1.apiFetch)(`/api/workspaces/${encodeURIComponent(workspaceId)}/stewardship/grants`);
|
|
20
|
+
}
|
|
13
21
|
/**
|
|
14
22
|
* The server's workspace document can include presentation metadata such as an
|
|
15
23
|
* avatar source. This CLI surface is a selector, not a workspace export: keep
|
|
@@ -129,3 +129,7 @@ export interface CliHandoffDpopProofResponse {
|
|
|
129
129
|
proof: string;
|
|
130
130
|
}
|
|
131
131
|
export declare function parseCliHandoffDpopProofResponse(value: unknown): CliHandoffDpopProofResponse | null;
|
|
132
|
+
/** Persisted credential families; deployed values must not change. */
|
|
133
|
+
export declare const DELEGATED_AGENT_CLI_ID_PREFIX = "oversky-daemon-agent-cli-";
|
|
134
|
+
export declare const WORKLOAD_CLI_ID_PREFIX = "oversky-daemon-workload-cli-";
|
|
135
|
+
export declare function classifyCliFamilyId(id: unknown): 'agent' | 'workload' | 'person';
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* must produce the full shape.
|
|
19
19
|
*/
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.CLI_HANDOFF_ERROR_DPOP_UNAVAILABLE = exports.CLI_HANDOFF_ERROR_DPOP_PROOF_REFUSED = exports.CLI_HANDOFF_DPOP_PROOF_PATH = exports.CLI_HANDOFF_ERROR_DPOP_REQUIRED = exports.CLI_HANDOFF_ERROR_BROKER_ONLY = exports.CLI_HANDOFF_TOKEN_ERROR_UNAVAILABLE = exports.CLI_HANDOFF_TOKEN_PATH = exports.CLI_HANDOFF_MODES = void 0;
|
|
21
|
+
exports.WORKLOAD_CLI_ID_PREFIX = exports.DELEGATED_AGENT_CLI_ID_PREFIX = exports.CLI_HANDOFF_ERROR_DPOP_UNAVAILABLE = exports.CLI_HANDOFF_ERROR_DPOP_PROOF_REFUSED = exports.CLI_HANDOFF_DPOP_PROOF_PATH = exports.CLI_HANDOFF_ERROR_DPOP_REQUIRED = exports.CLI_HANDOFF_ERROR_BROKER_ONLY = exports.CLI_HANDOFF_TOKEN_ERROR_UNAVAILABLE = exports.CLI_HANDOFF_TOKEN_PATH = exports.CLI_HANDOFF_MODES = void 0;
|
|
22
22
|
exports.parseCliHandoffDescriptor = parseCliHandoffDescriptor;
|
|
23
23
|
exports.normalizeHandoffModes = normalizeHandoffModes;
|
|
24
24
|
exports.advertisedHandoffModes = advertisedHandoffModes;
|
|
@@ -26,6 +26,7 @@ exports.descriptorOffersAccessToken = descriptorOffersAccessToken;
|
|
|
26
26
|
exports.descriptorOffersDpop = descriptorOffersDpop;
|
|
27
27
|
exports.parseCliHandoffTokenResponse = parseCliHandoffTokenResponse;
|
|
28
28
|
exports.parseCliHandoffDpopProofResponse = parseCliHandoffDpopProofResponse;
|
|
29
|
+
exports.classifyCliFamilyId = classifyCliFamilyId;
|
|
29
30
|
/**
|
|
30
31
|
* What a caller may redeem the descriptor secret for.
|
|
31
32
|
* - `refresh_family`: the legacy durable mint (90-day cli-scope family).
|
|
@@ -143,3 +144,15 @@ function parseCliHandoffDpopProofResponse(value) {
|
|
|
143
144
|
return null;
|
|
144
145
|
return { proof: v.proof };
|
|
145
146
|
}
|
|
147
|
+
/** Persisted credential families; deployed values must not change. */
|
|
148
|
+
exports.DELEGATED_AGENT_CLI_ID_PREFIX = 'oversky-daemon-agent-cli-';
|
|
149
|
+
exports.WORKLOAD_CLI_ID_PREFIX = 'oversky-daemon-workload-cli-';
|
|
150
|
+
function classifyCliFamilyId(id) {
|
|
151
|
+
if (typeof id !== 'string')
|
|
152
|
+
return 'person';
|
|
153
|
+
if (id.startsWith(exports.DELEGATED_AGENT_CLI_ID_PREFIX))
|
|
154
|
+
return 'agent';
|
|
155
|
+
if (id.startsWith(exports.WORKLOAD_CLI_ID_PREFIX))
|
|
156
|
+
return 'workload';
|
|
157
|
+
return 'person';
|
|
158
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** GitHub push diagnostics must never escape this parser as raw stderr. */
|
|
2
|
+
export declare const GITHUB_WORKFLOW_PERMISSION_REQUIRED = "github_workflow_permission_required";
|
|
3
|
+
export type GitHubPushRefusal = {
|
|
4
|
+
code: typeof GITHUB_WORKFLOW_PERMISSION_REQUIRED;
|
|
5
|
+
tokenKind: 'github_app' | 'oauth_app' | 'personal_access_token' | 'unknown';
|
|
6
|
+
paths: string[];
|
|
7
|
+
};
|
|
8
|
+
export declare function isWorkflowPath(value: unknown): boolean;
|
|
9
|
+
export declare function classifyGitHubPushRefusal(text: unknown): GitHubPushRefusal | null;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GITHUB_WORKFLOW_PERMISSION_REQUIRED = void 0;
|
|
4
|
+
exports.isWorkflowPath = isWorkflowPath;
|
|
5
|
+
exports.classifyGitHubPushRefusal = classifyGitHubPushRefusal;
|
|
6
|
+
/** GitHub push diagnostics must never escape this parser as raw stderr. */
|
|
7
|
+
exports.GITHUB_WORKFLOW_PERMISSION_REQUIRED = 'github_workflow_permission_required';
|
|
8
|
+
function workflowPath(value) {
|
|
9
|
+
if (typeof value !== 'string' || value.length > 240)
|
|
10
|
+
return null;
|
|
11
|
+
const path = value.replaceAll('\\', '/');
|
|
12
|
+
if (!/^\.github\/workflows\/[A-Za-z0-9_. /-]+$/.test(path))
|
|
13
|
+
return null;
|
|
14
|
+
const parts = path.split('/');
|
|
15
|
+
if (parts.some((part) => !part.trim() || part !== part.trim() || part === '.' || part === '..'))
|
|
16
|
+
return null;
|
|
17
|
+
return path;
|
|
18
|
+
}
|
|
19
|
+
function isWorkflowPath(value) {
|
|
20
|
+
return workflowPath(value) !== null;
|
|
21
|
+
}
|
|
22
|
+
function classifyGitHubPushRefusal(text) {
|
|
23
|
+
if (typeof text !== 'string')
|
|
24
|
+
return null;
|
|
25
|
+
// Bound parsing work. Git prints the rejection LAST, after any amount of
|
|
26
|
+
// progress output, so keep the tail; truncated diagnostics keep the generic refusal.
|
|
27
|
+
const input = text.slice(-64 * 1024);
|
|
28
|
+
const pattern = /refusing to allow (?:a|an) (GitHub App|OAuth App|Personal Access Token) to create or update workflow [`'"]([^`'"\r\n]+)[`'"] without [`'"]workflows?[`'"] (?:permission|scope)/gi;
|
|
29
|
+
const paths = [];
|
|
30
|
+
let tokenKind = 'unknown';
|
|
31
|
+
for (const match of input.matchAll(pattern)) {
|
|
32
|
+
const path = workflowPath(match[2]);
|
|
33
|
+
if (!path)
|
|
34
|
+
continue;
|
|
35
|
+
if (tokenKind === 'unknown') {
|
|
36
|
+
tokenKind =
|
|
37
|
+
match[1].toLowerCase() === 'github app'
|
|
38
|
+
? 'github_app'
|
|
39
|
+
: match[1].toLowerCase() === 'oauth app'
|
|
40
|
+
? 'oauth_app'
|
|
41
|
+
: 'personal_access_token';
|
|
42
|
+
}
|
|
43
|
+
if (!paths.includes(path))
|
|
44
|
+
paths.push(path);
|
|
45
|
+
if (paths.length === 10)
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
return paths.length ? { code: exports.GITHUB_WORKFLOW_PERMISSION_REQUIRED, tokenKind, paths } : null;
|
|
49
|
+
}
|
|
@@ -129,3 +129,7 @@ export interface CliHandoffDpopProofResponse {
|
|
|
129
129
|
proof: string;
|
|
130
130
|
}
|
|
131
131
|
export declare function parseCliHandoffDpopProofResponse(value: unknown): CliHandoffDpopProofResponse | null;
|
|
132
|
+
/** Persisted credential families; deployed values must not change. */
|
|
133
|
+
export declare const DELEGATED_AGENT_CLI_ID_PREFIX = "oversky-daemon-agent-cli-";
|
|
134
|
+
export declare const WORKLOAD_CLI_ID_PREFIX = "oversky-daemon-workload-cli-";
|
|
135
|
+
export declare function classifyCliFamilyId(id: unknown): 'agent' | 'workload' | 'person';
|