@skrr-ai/cli 0.1.127 → 0.1.128
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base-command.d.ts +23 -0
- package/dist/base-command.js +72 -0
- package/dist/commands/agents/chat.js +7 -0
- package/dist/commands/commitments/action-history.js +1 -1
- package/dist/commands/commitments/cases.js +3 -3
- package/dist/commands/commitments/check-now.d.ts +10 -2
- package/dist/commands/commitments/check-now.js +53 -3
- package/dist/commands/commitments/create.d.ts +6 -14
- package/dist/commands/commitments/create.js +61 -6
- package/dist/commands/commitments/doctor.js +3 -1
- package/dist/commands/commitments/effective-policy.d.ts +11 -1
- package/dist/commands/commitments/effective-policy.js +84 -4
- package/dist/commands/commitments/hypotheses.js +12 -12
- package/dist/commands/commitments/next-tick.js +5 -0
- package/dist/commands/commitments/observations.js +18 -17
- package/dist/commands/commitments/pack/list.js +2 -1
- package/dist/commands/commitments/pack/plan.d.ts +6 -0
- package/dist/commands/commitments/pack/plan.js +19 -0
- package/dist/commands/commitments/preflight.d.ts +19 -0
- package/dist/commands/commitments/preflight.js +108 -10
- package/dist/commands/commitments/trigger-status.js +8 -0
- package/dist/commands/commitments/update.d.ts +1 -0
- package/dist/commands/commitments/update.js +45 -4
- package/dist/commands/commitments/wake-capabilities.js +13 -0
- package/dist/commands/compass/archive.js +4 -0
- package/dist/commands/compass/commitments.js +15 -1
- package/dist/commands/compass/create.js +11 -3
- package/dist/commands/compass/effective-policy.d.ts +1 -0
- package/dist/commands/compass/effective-policy.js +8 -7
- package/dist/commands/compass/revert.d.ts +8 -0
- package/dist/commands/compass/revert.js +25 -1
- package/dist/commands/compass/revisions.d.ts +2 -0
- package/dist/commands/compass/revisions.js +18 -2
- package/dist/commands/compass/tactic.d.ts +5 -3
- package/dist/commands/compass/tactic.js +8 -7
- package/dist/commands/compass/update.js +19 -3
- package/dist/commands/followups/act.js +1 -1
- package/dist/commands/followups/cancel.js +13 -0
- package/dist/commands/followups/observability.js +20 -1
- package/dist/commands/followups/plans/create.js +12 -1
- package/dist/commands/followups/show.js +13 -0
- package/dist/commands/followups/watch.js +1 -1
- package/dist/commands/goals/planner-config.d.ts +11 -0
- package/dist/commands/goals/planner-config.js +16 -0
- package/dist/commands/machines/update.d.ts +5 -3
- package/dist/commands/machines/update.js +70 -9
- package/dist/commands/northstars/create.js +3 -1
- package/dist/commands/northstars/governance/configure.d.ts +4 -0
- package/dist/commands/northstars/governance/configure.js +75 -9
- package/dist/commands/northstars/intents/decide.d.ts +6 -0
- package/dist/commands/northstars/intents/decide.js +69 -15
- package/dist/commands/northstars/intents/list.d.ts +2 -1
- package/dist/commands/northstars/intents/list.js +15 -5
- package/dist/commands/northstars/intents.d.ts +26 -0
- package/dist/commands/northstars/intents.js +49 -0
- package/dist/commands/northstars/list.d.ts +1 -0
- package/dist/commands/northstars/list.js +24 -3
- package/dist/commands/northstars/recommendations/list.d.ts +1 -1
- package/dist/commands/northstars/recommendations/list.js +3 -3
- package/dist/commands/northstars/recommendations.d.ts +19 -0
- package/dist/commands/northstars/recommendations.js +42 -0
- package/dist/commands/northstars/review-now.d.ts +1 -0
- package/dist/commands/northstars/review-now.js +10 -4
- package/dist/commands/northstars/reviews.d.ts +1 -0
- package/dist/commands/northstars/reviews.js +19 -3
- package/dist/commands/northstars/update.js +8 -1
- package/dist/commands/proposals/list.js +11 -2
- package/dist/commands/proposals/show.js +9 -1
- package/dist/commands/spaces/auto-executor/preview.d.ts +14 -1
- package/dist/commands/spaces/auto-executor/preview.js +35 -1
- package/dist/commands/spaces/auto-executor/run.d.ts +17 -0
- package/dist/commands/spaces/auto-executor/run.js +60 -2
- package/dist/commands/spaces/files/upload.js +1 -2
- package/dist/commands/spaces/index.js +23 -0
- package/dist/generated/agent-guides.json +69 -69
- package/dist/lib/agentic-stream.d.ts +9 -0
- package/dist/lib/agentic-stream.js +14 -0
- package/dist/lib/command-miss.js +11 -2
- package/dist/lib/commitment-attention-copy.d.ts +96 -0
- package/dist/lib/commitment-attention-copy.js +209 -0
- package/dist/lib/commitment-loop-status.d.ts +6 -0
- package/dist/lib/commitment-loop-status.js +16 -6
- package/dist/lib/commitments.d.ts +88 -0
- package/dist/lib/commitments.js +188 -0
- package/dist/lib/compass-body-help.d.ts +20 -0
- package/dist/lib/compass-body-help.js +61 -0
- package/dist/lib/compass-refusals.d.ts +35 -0
- package/dist/lib/compass-refusals.js +50 -0
- package/dist/lib/compasses.d.ts +80 -4
- package/dist/lib/compasses.js +232 -12
- package/dist/lib/followups.d.ts +22 -1
- package/dist/lib/followups.js +21 -1
- package/dist/lib/format.d.ts +11 -0
- package/dist/lib/format.js +29 -0
- package/dist/lib/initiatives.d.ts +9 -2
- package/dist/lib/initiatives.js +13 -2
- package/dist/lib/machines.d.ts +14 -1
- package/dist/lib/machines.js +24 -0
- package/dist/lib/northstars.d.ts +158 -24
- package/dist/lib/northstars.js +538 -26
- package/dist/lib/proposal-decision-command.js +21 -1
- package/dist/lib/proposals.d.ts +26 -1
- package/dist/lib/proposals.js +163 -0
- package/dist/lib/rate-limit-retry.d.ts +5 -0
- package/dist/lib/rate-limit-retry.js +19 -0
- package/dist/lib/roles.d.ts +1 -1
- package/dist/lib/space-charter.js +9 -0
- package/dist/lib/task-asset-upload.js +1 -2
- package/dist/lib/triggers.d.ts +1 -1
- package/dist/lib/triggers.js +11 -3
- package/dist/node_modules/@skrr-ai/data-provider/index.js +6504 -6493
- package/oclif.manifest.json +350 -34
- package/package.json +4 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseCommand } from '../../../base-command';
|
|
2
2
|
/**
|
|
3
|
-
* `skrr northstars recommendations <id>` — the deterministic reviewer's
|
|
3
|
+
* `skrr northstars recommendations list <id>` — the deterministic reviewer's
|
|
4
4
|
* user-facing suggestions.
|
|
5
5
|
*
|
|
6
6
|
* These are NOT the same thing as management intents. A recommendation is
|
|
@@ -5,7 +5,7 @@ const core_1 = require("@oclif/core");
|
|
|
5
5
|
const base_command_1 = require("../../../base-command");
|
|
6
6
|
const northstars_1 = require("../../../lib/northstars");
|
|
7
7
|
/**
|
|
8
|
-
* `skrr northstars recommendations <id>` — the deterministic reviewer's
|
|
8
|
+
* `skrr northstars recommendations list <id>` — the deterministic reviewer's
|
|
9
9
|
* user-facing suggestions.
|
|
10
10
|
*
|
|
11
11
|
* These are NOT the same thing as management intents. A recommendation is
|
|
@@ -16,8 +16,8 @@ const northstars_1 = require("../../../lib/northstars");
|
|
|
16
16
|
class NorthstarsRecommendationsList extends base_command_1.BaseCommand {
|
|
17
17
|
static description = "List a northstar's deterministic portfolio recommendations";
|
|
18
18
|
static examples = [
|
|
19
|
-
'<%= config.bin %> northstars recommendations nst_abc123',
|
|
20
|
-
'<%= config.bin %> northstars recommendations nst_abc123 --status open',
|
|
19
|
+
'<%= config.bin %> northstars recommendations list nst_abc123',
|
|
20
|
+
'<%= config.bin %> northstars recommendations list nst_abc123 --status open',
|
|
21
21
|
];
|
|
22
22
|
static args = {
|
|
23
23
|
northstarId: core_1.Args.string({ ignoreStdin: true, description: 'Northstar ID', required: true }),
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import NorthstarsRecommendationsList from './recommendations/list';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr northstars recommendations <northstar-id>` — the topic's default: list them.
|
|
4
|
+
*
|
|
5
|
+
* Same reasoning as `northstars intents`: the help examples showed this form and it was
|
|
6
|
+
* answered with "is not a command". Listing is read-only, so it is the safe default;
|
|
7
|
+
* `recommendations apply` and `recommendations dismiss` still resolve to their own
|
|
8
|
+
* commands (the longest command id wins). With no northstar id it prints the topic help.
|
|
9
|
+
*/
|
|
10
|
+
export default class NorthstarsRecommendations extends NorthstarsRecommendationsList {
|
|
11
|
+
static description: string;
|
|
12
|
+
static examples: string[];
|
|
13
|
+
static args: typeof NorthstarsRecommendationsList.args;
|
|
14
|
+
static flags: {
|
|
15
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
status: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
};
|
|
18
|
+
run(): Promise<void>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const core_1 = require("@oclif/core");
|
|
7
|
+
const list_1 = __importDefault(require("./recommendations/list"));
|
|
8
|
+
/**
|
|
9
|
+
* `skrr northstars recommendations <northstar-id>` — the topic's default: list them.
|
|
10
|
+
*
|
|
11
|
+
* Same reasoning as `northstars intents`: the help examples showed this form and it was
|
|
12
|
+
* answered with "is not a command". Listing is read-only, so it is the safe default;
|
|
13
|
+
* `recommendations apply` and `recommendations dismiss` still resolve to their own
|
|
14
|
+
* commands (the longest command id wins). With no northstar id it prints the topic help.
|
|
15
|
+
*/
|
|
16
|
+
class NorthstarsRecommendations extends list_1.default {
|
|
17
|
+
static description = "List a northstar's recommendations; subcommands: list, apply, dismiss (`recommendations <id>` is `recommendations list <id>`)";
|
|
18
|
+
static examples = [
|
|
19
|
+
'<%= config.bin %> northstars recommendations nst_abc123',
|
|
20
|
+
'<%= config.bin %> northstars recommendations nst_abc123 --status open',
|
|
21
|
+
'<%= config.bin %> northstars recommendations list nst_abc123',
|
|
22
|
+
'<%= config.bin %> northstars recommendations apply nst_abc123 <rec-id>',
|
|
23
|
+
];
|
|
24
|
+
// Own, not inherited (see `northstars intents`).
|
|
25
|
+
static args = {
|
|
26
|
+
northstarId: core_1.Args.string({
|
|
27
|
+
ignoreStdin: true,
|
|
28
|
+
description: 'Northstar ID (omit to see the subcommands)',
|
|
29
|
+
required: false,
|
|
30
|
+
}),
|
|
31
|
+
};
|
|
32
|
+
static flags = list_1.default.flags;
|
|
33
|
+
async run() {
|
|
34
|
+
const { args } = await this.parse(NorthstarsRecommendations);
|
|
35
|
+
if (!args.northstarId) {
|
|
36
|
+
await this.config.runCommand('help', ['northstars', 'recommendations']);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
await super.run();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.default = NorthstarsRecommendations;
|
|
@@ -23,6 +23,7 @@ class NorthstarsReviewNow extends base_command_1.BaseCommand {
|
|
|
23
23
|
};
|
|
24
24
|
static flags = {
|
|
25
25
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
26
|
+
wide: northstars_1.northstarWideFlag,
|
|
26
27
|
};
|
|
27
28
|
async run() {
|
|
28
29
|
this.requireAuth();
|
|
@@ -44,18 +45,23 @@ class NorthstarsReviewNow extends base_command_1.BaseCommand {
|
|
|
44
45
|
if (review) {
|
|
45
46
|
this.log(`Review ${String(review.id)} (${String(review.status)})`);
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
-
this.log(`Allocations ${allocations} commitment(s) re-budgeted`);
|
|
48
|
+
this.log((0, northstars_1.describeReviewAllocations)(result));
|
|
49
49
|
this.log(`Applied ${String(result.appliedIntents ?? 0)} intent(s)`);
|
|
50
50
|
if (governanceRun) {
|
|
51
51
|
this.log(governanceRun.reserved
|
|
52
52
|
? `Agent run ${String(governanceRun.runId)} reserved — results land asynchronously`
|
|
53
|
-
: `Agent run not started
|
|
53
|
+
: `Agent run not started: ${(0, northstars_1.describeNorthstarReason)(typeof governanceRun.reason === 'string' ? governanceRun.reason : undefined)}`);
|
|
54
54
|
}
|
|
55
55
|
const intents = review?.intents ?? [];
|
|
56
|
+
// An intent budget that cut the review short must not read as "nothing to report".
|
|
57
|
+
const snapshot = review?.deterministicSnapshot;
|
|
58
|
+
const governance = result.governance;
|
|
59
|
+
const budgetNote = (0, northstars_1.intentBudgetNote)(snapshot?.truncatedIntents, governance?.maxIntentsPerReview);
|
|
60
|
+
if (budgetNote)
|
|
61
|
+
this.log(budgetNote);
|
|
56
62
|
if (intents.length) {
|
|
57
63
|
this.log('');
|
|
58
|
-
(0, northstars_1.renderIntentList)(intents, (line) => this.log(line));
|
|
64
|
+
(0, northstars_1.renderIntentList)(intents, (line) => this.log(line), { wide: flags.wide });
|
|
59
65
|
}
|
|
60
66
|
}
|
|
61
67
|
}
|
|
@@ -18,6 +18,7 @@ export default class NorthstarsReviews extends BaseCommand {
|
|
|
18
18
|
limit: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
19
|
status: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
20
|
review: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
21
|
+
wide: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
21
22
|
};
|
|
22
23
|
run(): Promise<void>;
|
|
23
24
|
}
|
|
@@ -29,6 +29,7 @@ class NorthstarsReviews extends base_command_1.BaseCommand {
|
|
|
29
29
|
options: [...northstars_1.NORTHSTAR_REVIEW_STATUSES],
|
|
30
30
|
}),
|
|
31
31
|
review: core_1.Flags.string({ description: 'Show ONE review in full, including its intents' }),
|
|
32
|
+
wide: northstars_1.northstarWideFlag,
|
|
32
33
|
};
|
|
33
34
|
async run() {
|
|
34
35
|
this.requireAuth();
|
|
@@ -53,14 +54,20 @@ class NorthstarsReviews extends base_command_1.BaseCommand {
|
|
|
53
54
|
if (review.autonomousRunId)
|
|
54
55
|
this.log(`Agent run ${review.autonomousRunId}`);
|
|
55
56
|
if (review.reason)
|
|
56
|
-
this.log(`Reason ${review.reason}`);
|
|
57
|
+
this.log(`Reason ${(0, northstars_1.describeReviewReason)(review.reason)}`);
|
|
57
58
|
const snapshot = review.deterministicSnapshot;
|
|
58
59
|
if (snapshot) {
|
|
59
60
|
this.log(`Health ${String(snapshot.health ?? '—')}`);
|
|
60
61
|
this.log(`Allocations written ${String(snapshot.allocationsWritten ?? 0)}`);
|
|
61
62
|
}
|
|
63
|
+
// A review the intent budget cut short is not a review with nothing to say.
|
|
64
|
+
const budgetNote = (0, northstars_1.intentBudgetNote)(snapshot?.truncatedIntents, snapshot?.intentCounts?.total);
|
|
65
|
+
if (budgetNote)
|
|
66
|
+
this.log(budgetNote);
|
|
62
67
|
this.log('');
|
|
63
|
-
(
|
|
68
|
+
if (budgetNote && (review.intents ?? []).length === 0)
|
|
69
|
+
return;
|
|
70
|
+
(0, northstars_1.renderIntentList)(review.intents ?? [], (line) => this.log(line), { wide: flags.wide });
|
|
64
71
|
return;
|
|
65
72
|
}
|
|
66
73
|
let response;
|
|
@@ -77,7 +84,16 @@ class NorthstarsReviews extends base_command_1.BaseCommand {
|
|
|
77
84
|
this.log(JSON.stringify(response, null, 2));
|
|
78
85
|
return;
|
|
79
86
|
}
|
|
80
|
-
|
|
87
|
+
const rows = response.data ?? [];
|
|
88
|
+
(0, northstars_1.renderReviewList)(rows, (line) => this.log(line));
|
|
89
|
+
const footer = (0, northstars_1.listFooter)({
|
|
90
|
+
shown: rows.length,
|
|
91
|
+
hasMore: response.has_more === true,
|
|
92
|
+
limit: flags.limit ?? 20,
|
|
93
|
+
max: 100,
|
|
94
|
+
});
|
|
95
|
+
if (footer)
|
|
96
|
+
this.log(footer);
|
|
81
97
|
}
|
|
82
98
|
}
|
|
83
99
|
exports.default = NorthstarsReviews;
|
|
@@ -32,7 +32,10 @@ class NorthstarsUpdate extends base_command_1.BaseCommand {
|
|
|
32
32
|
tier: core_1.Flags.string({ description: 'Priority tier', options: [...northstars_1.NORTHSTAR_PRIORITY_TIERS] }),
|
|
33
33
|
weight: core_1.Flags.integer({ description: 'Priority weight (0..100)', min: 0, max: 100 }),
|
|
34
34
|
'total-weight': core_1.Flags.integer({ description: 'Attention budget total weight', min: 0 }),
|
|
35
|
-
'max-active': core_1.Flags.integer({
|
|
35
|
+
'max-active': core_1.Flags.integer({
|
|
36
|
+
description: 'Soft cap on active commitments (0 = no cap)',
|
|
37
|
+
min: 0,
|
|
38
|
+
}),
|
|
36
39
|
goal: core_1.Flags.string({ description: 'Goal ID (repeatable; replaces the list)', multiple: true }),
|
|
37
40
|
agent: core_1.Flags.string({
|
|
38
41
|
description: 'Agent ID (repeatable; replaces the list)',
|
|
@@ -109,6 +112,10 @@ class NorthstarsUpdate extends base_command_1.BaseCommand {
|
|
|
109
112
|
return;
|
|
110
113
|
}
|
|
111
114
|
this.log(`Updated ${northstar.id} — ${northstar.title} (${northstar.status}, v${northstar.version})`);
|
|
115
|
+
// 0 is stored, and a review treats it as "no cap": say so here, not only in `show` (OSK-21252).
|
|
116
|
+
if (flags['max-active'] !== undefined) {
|
|
117
|
+
this.log(`Attention max active ${(0, northstars_1.describeMaxActive)(northstar.attentionBudget?.maxActiveCommitments ?? flags['max-active'])}`);
|
|
118
|
+
}
|
|
112
119
|
}
|
|
113
120
|
}
|
|
114
121
|
exports.default = NorthstarsUpdate;
|
|
@@ -31,12 +31,21 @@ function emptyPageLines(narrowed, nextCursor) {
|
|
|
31
31
|
* server could not read for this viewer is in `--json`), never "none".
|
|
32
32
|
*/
|
|
33
33
|
function aboutFor(row) {
|
|
34
|
-
|
|
34
|
+
const named = [row.commitmentTitle, row.agent?.name].filter(Boolean).join(' · ');
|
|
35
|
+
if (named)
|
|
36
|
+
return named;
|
|
37
|
+
// A Northstar intent that targets no commitment (a proposal to start one) is about its northstar.
|
|
38
|
+
const northstarId = row.decisionContext?.northstarId;
|
|
39
|
+
return northstarId ? `northstar ${northstarId}` : '—';
|
|
35
40
|
}
|
|
36
41
|
/** A snoozed proposal reads `proposed` in its disposition; the wake time is what tells them apart. */
|
|
37
42
|
function noteFor(row) {
|
|
38
43
|
if (row.sourceStatus === 'snoozed' && row.snoozedUntil)
|
|
39
44
|
return `snoozed until ${row.snoozedUntil}`;
|
|
45
|
+
// The inbox files a policy refusal under `discarded`; for a Northstar intent say what it was.
|
|
46
|
+
const intent = (0, proposals_1.northstarIntentNote)(row);
|
|
47
|
+
if (intent)
|
|
48
|
+
return intent;
|
|
40
49
|
if (!row.canDecide && row.undecidableReason && row.undecidableReason !== 'settled')
|
|
41
50
|
return data_provider_1.PROPOSAL_UNDECIDABLE_TEXT[row.undecidableReason];
|
|
42
51
|
return '—';
|
|
@@ -86,7 +95,7 @@ class ProposalsList extends base_command_1.BaseCommand {
|
|
|
86
95
|
}
|
|
87
96
|
(0, format_1.renderTable)(result.data.map((row) => ({
|
|
88
97
|
id: row.id,
|
|
89
|
-
title: row
|
|
98
|
+
title: (0, proposals_1.proposalTitleFor)(row),
|
|
90
99
|
about: aboutFor(row),
|
|
91
100
|
disposition: row.disposition,
|
|
92
101
|
// Most proposals carry no estimate; "unknown" read as a failure to determine one (OSK-15377).
|
|
@@ -22,7 +22,7 @@ class ProposalsShow extends base_command_1.BaseCommand {
|
|
|
22
22
|
static flags = { json: core_1.Flags.boolean() };
|
|
23
23
|
async run() {
|
|
24
24
|
this.requireAuth();
|
|
25
|
-
const { args } = await this.parse(ProposalsShow);
|
|
25
|
+
const { args, flags } = await this.parse(ProposalsShow);
|
|
26
26
|
const ref = (0, proposals_1.resolveProposalRef)(args.kind, args.id, this.config?.bin);
|
|
27
27
|
if ('error' in ref) {
|
|
28
28
|
this.failWithCliError({
|
|
@@ -48,6 +48,14 @@ class ProposalsShow extends base_command_1.BaseCommand {
|
|
|
48
48
|
}
|
|
49
49
|
this.handleApiError(error);
|
|
50
50
|
}
|
|
51
|
+
// A Northstar intent reads as words unless --json asks for the document; every other kind still
|
|
52
|
+
// prints its full JSON, so a script that reads it does not change.
|
|
53
|
+
const lines = flags.json ? null : (0, proposals_1.renderNorthstarIntentView)(result);
|
|
54
|
+
if (lines) {
|
|
55
|
+
for (const line of lines)
|
|
56
|
+
this.log(line);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
51
59
|
this.log(JSON.stringify(result, null, 2));
|
|
52
60
|
}
|
|
53
61
|
}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
import { type SpaceAutoExecutorRefillState } from '@skrr-ai/data-provider';
|
|
1
|
+
import { type SpaceAutoExecutorPreviewResponse, type SpaceAutoExecutorRefillState } from '@skrr-ai/data-provider';
|
|
2
2
|
import { BaseCommand } from '../../../base-command';
|
|
3
|
+
type PreviewSpace = SpaceAutoExecutorPreviewResponse['space'];
|
|
4
|
+
/**
|
|
5
|
+
* "Can start" is a capacity figure, not a forecast. Printed bare next to a disabled autopilot
|
|
6
|
+
* it read as "one task will start now" (dogfooded: `Autopilot: disabled` / `Can start: 1 now`).
|
|
7
|
+
*/
|
|
8
|
+
export declare function canStartLine(space: Pick<PreviewSpace, 'autoExecuteEnabled'>, startsAvailable: number | null): string;
|
|
9
|
+
/**
|
|
10
|
+
* Whether unattended work may run in the Space at all. Turning the board off does not revoke the
|
|
11
|
+
* principal and a revoked one keeps a disabled board silent, so the two have to be told apart.
|
|
12
|
+
* Returns null for a server that predates the field, so an old API prints no claim.
|
|
13
|
+
*/
|
|
14
|
+
export declare function principalLine(space: Pick<PreviewSpace, 'executionPrincipal'>, spaceRef: string): string | null;
|
|
3
15
|
export default class SpacesAutoExecutorPreview extends BaseCommand {
|
|
4
16
|
static description: string;
|
|
5
17
|
static examples: string[];
|
|
@@ -18,3 +30,4 @@ export default class SpacesAutoExecutorPreview extends BaseCommand {
|
|
|
18
30
|
* not report it; `null` is one that could not read it, and says so.
|
|
19
31
|
*/
|
|
20
32
|
export declare function refillLines(refill: SpaceAutoExecutorRefillState | null | undefined): string[];
|
|
33
|
+
export {};
|
|
@@ -1,10 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.canStartLine = canStartLine;
|
|
4
|
+
exports.principalLine = principalLine;
|
|
3
5
|
exports.refillLines = refillLines;
|
|
4
6
|
const core_1 = require("@oclif/core");
|
|
5
7
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
6
8
|
const base_command_1 = require("../../../base-command");
|
|
7
9
|
const space_output_1 = require("../../../lib/space-output");
|
|
10
|
+
/**
|
|
11
|
+
* "Can start" is a capacity figure, not a forecast. Printed bare next to a disabled autopilot
|
|
12
|
+
* it read as "one task will start now" (dogfooded: `Autopilot: disabled` / `Can start: 1 now`).
|
|
13
|
+
*/
|
|
14
|
+
function canStartLine(space, startsAvailable) {
|
|
15
|
+
const capacity = (0, data_provider_1.formatLimit)(startsAvailable);
|
|
16
|
+
return space.autoExecuteEnabled
|
|
17
|
+
? `Can start: ${capacity} now`
|
|
18
|
+
: `Can start: nothing — autopilot is off (capacity ${capacity})`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Whether unattended work may run in the Space at all. Turning the board off does not revoke the
|
|
22
|
+
* principal and a revoked one keeps a disabled board silent, so the two have to be told apart.
|
|
23
|
+
* Returns null for a server that predates the field, so an old API prints no claim.
|
|
24
|
+
*/
|
|
25
|
+
function principalLine(space, spaceRef) {
|
|
26
|
+
const principal = space.executionPrincipal;
|
|
27
|
+
if (principal === undefined)
|
|
28
|
+
return null;
|
|
29
|
+
if (principal === null) {
|
|
30
|
+
return ('Principal: none — nothing may run unattended here. A Space owner sets one with ' +
|
|
31
|
+
`\`skrr spaces auto-executor update ${spaceRef} --enabled\`.`);
|
|
32
|
+
}
|
|
33
|
+
if (principal.status === 'active')
|
|
34
|
+
return `Principal: active (version ${principal.version})`;
|
|
35
|
+
return (`Principal: revoked${principal.revokeReason ? ` (${principal.revokeReason.replace(/_/g, ' ')})` : ''} — ` +
|
|
36
|
+
`nothing may run unattended here until a Space owner sets it again with ` +
|
|
37
|
+
`\`skrr spaces auto-executor update ${spaceRef} --enabled\`.`);
|
|
38
|
+
}
|
|
8
39
|
class SpacesAutoExecutorPreview extends base_command_1.BaseCommand {
|
|
9
40
|
static description = 'Preview what a space auto-executor run would do';
|
|
10
41
|
static examples = [
|
|
@@ -47,7 +78,10 @@ class SpacesAutoExecutorPreview extends base_command_1.BaseCommand {
|
|
|
47
78
|
const { capacity } = plan;
|
|
48
79
|
this.log(`Running: ${(0, data_provider_1.formatRunningCapacity)(capacity.activeCount, capacity.maxActiveTasks)}` +
|
|
49
80
|
(capacity.maxActiveTasks === null ? ' (no concurrency cap)' : ''));
|
|
50
|
-
this.log(
|
|
81
|
+
this.log(canStartLine(space, capacity.startsAvailable));
|
|
82
|
+
const principal = principalLine(space, spaceRef);
|
|
83
|
+
if (principal)
|
|
84
|
+
this.log(principal);
|
|
51
85
|
if (capacity.budget && !capacity.budget.unlimited) {
|
|
52
86
|
this.log(`Budget: ${capacity.budget.consumedStarts}/${capacity.budget.maxStarts} starts used this round`);
|
|
53
87
|
}
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
/** What `auto-execute-now` answered: `fired: false` carries the reason nothing started. */
|
|
3
|
+
type RunNowAnswer = {
|
|
4
|
+
fired?: boolean;
|
|
5
|
+
reason?: string;
|
|
6
|
+
runId?: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Why a manual run did not start, in words, and whether that is a refusal or just "already busy".
|
|
10
|
+
* The route answers 200 with `fired: false` and a `reason`; printing "Triggered" for it told an
|
|
11
|
+
* owner a run had started when nothing had (a Space with no execution principal never runs).
|
|
12
|
+
* `busy` is the normal "one is already in flight" answer, not a failure.
|
|
13
|
+
*/
|
|
14
|
+
export declare function describeRunNotStarted(answer: RunNowAnswer, spaceRef: string): {
|
|
15
|
+
message: string;
|
|
16
|
+
busy: boolean;
|
|
17
|
+
};
|
|
2
18
|
export default class SpacesAutoExecutorRun extends BaseCommand {
|
|
3
19
|
static description: string;
|
|
4
20
|
static args: {
|
|
@@ -9,3 +25,4 @@ export default class SpacesAutoExecutorRun extends BaseCommand {
|
|
|
9
25
|
};
|
|
10
26
|
run(): Promise<void>;
|
|
11
27
|
}
|
|
28
|
+
export {};
|
|
@@ -1,9 +1,52 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.describeRunNotStarted = describeRunNotStarted;
|
|
3
4
|
const core_1 = require("@oclif/core");
|
|
4
5
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
6
|
const base_command_1 = require("../../../base-command");
|
|
6
7
|
const space_output_1 = require("../../../lib/space-output");
|
|
8
|
+
/**
|
|
9
|
+
* Why a manual run did not start, in words, and whether that is a refusal or just "already busy".
|
|
10
|
+
* The route answers 200 with `fired: false` and a `reason`; printing "Triggered" for it told an
|
|
11
|
+
* owner a run had started when nothing had (a Space with no execution principal never runs).
|
|
12
|
+
* `busy` is the normal "one is already in flight" answer, not a failure.
|
|
13
|
+
*/
|
|
14
|
+
function describeRunNotStarted(answer, spaceRef) {
|
|
15
|
+
switch (answer.reason) {
|
|
16
|
+
case 'principal_missing_or_revoked':
|
|
17
|
+
return {
|
|
18
|
+
busy: false,
|
|
19
|
+
message: `Nothing ran: this Space has no active execution principal, so nothing may run unattended in it. ` +
|
|
20
|
+
`A Space owner sets one with \`skrr spaces auto-executor update ${spaceRef} --enabled\`.`,
|
|
21
|
+
};
|
|
22
|
+
case 'no_lead_agent':
|
|
23
|
+
return {
|
|
24
|
+
busy: false,
|
|
25
|
+
message: `Nothing ran: this Space has no lead agent to run its board. ` +
|
|
26
|
+
`Set one with \`skrr spaces update ${spaceRef} --lead-agent <agent-id>\`.`,
|
|
27
|
+
};
|
|
28
|
+
case 'space_not_found':
|
|
29
|
+
return { busy: false, message: `Nothing ran: Space ${spaceRef} was not found.` };
|
|
30
|
+
case 'disabled':
|
|
31
|
+
return {
|
|
32
|
+
busy: false,
|
|
33
|
+
message: `Nothing ran: auto-execution is turned off for this Space. ` +
|
|
34
|
+
`Turn it on with \`skrr spaces auto-executor update ${spaceRef} --enabled\`.`,
|
|
35
|
+
};
|
|
36
|
+
case 'active_orchestration':
|
|
37
|
+
case 'lock_held':
|
|
38
|
+
return {
|
|
39
|
+
busy: true,
|
|
40
|
+
message: `A run is already in flight for this Space${answer.runId ? ` (${answer.runId})` : ''}; ` +
|
|
41
|
+
`it carries this request, so no second one was started.`,
|
|
42
|
+
};
|
|
43
|
+
default:
|
|
44
|
+
return {
|
|
45
|
+
busy: false,
|
|
46
|
+
message: `Nothing ran${answer.reason ? ` (${answer.reason})` : ''}: the server did not start a run.`,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
7
50
|
class SpacesAutoExecutorRun extends base_command_1.BaseCommand {
|
|
8
51
|
static description = 'Run a space auto-executor immediately';
|
|
9
52
|
static args = {
|
|
@@ -21,10 +64,25 @@ class SpacesAutoExecutorRun extends base_command_1.BaseCommand {
|
|
|
21
64
|
catch (err) {
|
|
22
65
|
this.handleApiError(err);
|
|
23
66
|
}
|
|
24
|
-
|
|
67
|
+
const answer = (result ?? {});
|
|
68
|
+
const notStarted = answer.fired === false ? describeRunNotStarted(answer, spaceRef) : undefined;
|
|
69
|
+
if (flags.json) {
|
|
25
70
|
this.log(JSON.stringify((0, space_output_1.withSpacePerspectiveUrl)(this.cliConfig.baseURL, spaceRef, 'execution', { result }), null, 2));
|
|
26
|
-
|
|
71
|
+
// The payload above already says `fired: false`; the exit status says it too, so a
|
|
72
|
+
// script that only checks `$?` is not told a refusal succeeded.
|
|
73
|
+
if (notStarted && !notStarted.busy)
|
|
74
|
+
this.exit(1);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (!notStarted) {
|
|
27
78
|
this.log(`Triggered auto-executor for space ${spaceRef}.`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (notStarted.busy) {
|
|
82
|
+
this.log(notStarted.message);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
this.error(notStarted.message, { exit: 1 });
|
|
28
86
|
}
|
|
29
87
|
}
|
|
30
88
|
exports.default = SpacesAutoExecutorRun;
|
|
@@ -35,7 +35,6 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
const fs = __importStar(require("node:fs"));
|
|
37
37
|
const path = __importStar(require("node:path"));
|
|
38
|
-
const node_buffer_1 = require("node:buffer");
|
|
39
38
|
const node_crypto_1 = require("node:crypto");
|
|
40
39
|
const core_1 = require("@oclif/core");
|
|
41
40
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
@@ -86,7 +85,7 @@ class SpacesFilesUpload extends base_command_1.BaseCommand {
|
|
|
86
85
|
formData.append('spaceId', spaceRef);
|
|
87
86
|
if (flags.folder)
|
|
88
87
|
formData.append('folder_id', flags.folder);
|
|
89
|
-
formData.append('file', new
|
|
88
|
+
formData.append('file', new Blob([bytes], { type: (0, file_mime_1.mimeTypeForFilename)(filename) }), filename);
|
|
90
89
|
let uploaded;
|
|
91
90
|
try {
|
|
92
91
|
uploaded = await data_provider_1.dataService.uploadFile(formData);
|
|
@@ -46,6 +46,29 @@ const PERSPECTIVES = [
|
|
|
46
46
|
],
|
|
47
47
|
url: '/spaces/<space-id>/schedule',
|
|
48
48
|
},
|
|
49
|
+
{
|
|
50
|
+
perspective: 'loops',
|
|
51
|
+
purpose: "The Space's standing loops (weekly review, curator, goal advance). No command lists them: read their cycles from the notebook",
|
|
52
|
+
commands: [
|
|
53
|
+
'spaces notebook <space-id> --kinds loop_cycle',
|
|
54
|
+
'commitments pack plan --pack space_review --space <space-id>',
|
|
55
|
+
'spaces loops migrate <space-id> --from heartbeats',
|
|
56
|
+
'spaces loops release <space-id> --commitment <id>',
|
|
57
|
+
],
|
|
58
|
+
url: '/spaces/<space-id>/loops',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
perspective: 'notebook',
|
|
62
|
+
purpose: 'Task results, loop cycles, hypothesis verdicts, journal entries and reports, newest first',
|
|
63
|
+
commands: ['spaces notebook <space-id>'],
|
|
64
|
+
url: '/spaces/<space-id>/notebook',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
perspective: 'proposals',
|
|
68
|
+
purpose: 'Writes held for approval, loop action bundles and Memory proposals; how unattended writes are governed',
|
|
69
|
+
commands: ['spaces proposals list <space-id>', 'spaces write-policy show <space-id>'],
|
|
70
|
+
url: '/spaces/<space-id>/proposals',
|
|
71
|
+
},
|
|
49
72
|
{
|
|
50
73
|
perspective: 'actions',
|
|
51
74
|
purpose: 'Agent actions and space custom actions',
|