@skrr-ai/cli 0.1.106 → 0.1.108
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/commands/agents/operating-plan.js +1 -1
- package/dist/commands/commitments/doctor.js +2 -1
- package/dist/commands/proposals/list.d.ts +7 -0
- package/dist/commands/proposals/list.js +11 -0
- package/dist/lib/commitment-product.js +19 -1
- package/dist/lib/commitments.d.ts +10 -2
- package/dist/lib/commitments.js +21 -10
- package/dist/node_modules/@skrr-ai/data-provider/index.js +7256 -7232
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
|
@@ -44,7 +44,7 @@ class AgentOperatingPlan extends base_command_1.BaseCommand {
|
|
|
44
44
|
this.log(` Evaluation: ${w.status} — ${w.reason}${w.nextAt ? `; next ${w.nextAt}` : ''}`);
|
|
45
45
|
this.log(` Next intervention: ${r.lifecycle !== 'active' ? 'inactive; requires activation' : r.nextIntervention?.nextAt || r.nextIntervention?.status || 'not recorded'}`);
|
|
46
46
|
if (r.blocker)
|
|
47
|
-
this.log(` Blocker: ${r.blocker.code} — ${r.blocker.remediation || ''}`);
|
|
47
|
+
this.log(` Blocker: ${r.blocker.code} — ${r.blocker.remediation || r.blocker.detail || ''}`);
|
|
48
48
|
}
|
|
49
49
|
for (const line of (0, operating_plan_loops_1.planningLoopLines)(plan.planning.loops, plan.planning.todos.length))
|
|
50
50
|
this.log(line);
|
|
@@ -16,7 +16,8 @@ function doctorVerdict(input) {
|
|
|
16
16
|
const lifecycle = /^status_([a-z_]+)$/.exec(String(blocker.code));
|
|
17
17
|
return {
|
|
18
18
|
verdict: lifecycle ? lifecycle[1] : blocker.code === 'deleted' ? 'deleted' : 'blocked',
|
|
19
|
-
|
|
19
|
+
// A typed blocker carries no remedy, only what happened (OSK-16230).
|
|
20
|
+
next: String(blocker.remediation || blocker.detail || 'Inspect the Commitment'),
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
if (operatingState.status === 'waiting_approval') {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ProposalView } from '@skrr-ai/data-provider';
|
|
1
2
|
import { BaseCommand } from '../../base-command';
|
|
2
3
|
/**
|
|
3
4
|
* What an empty page means. With a filter AND a next cursor it does NOT mean "none": the inbox reads a
|
|
@@ -6,6 +7,12 @@ import { BaseCommand } from '../../base-command';
|
|
|
6
7
|
* Without a cursor the inbox is exhausted and "none" is true.
|
|
7
8
|
*/
|
|
8
9
|
export declare function emptyPageLines(narrowed: boolean, nextCursor: string | null | undefined): string[];
|
|
10
|
+
/**
|
|
11
|
+
* What the row is ABOUT: the Commitment and the Agent behind it, in the order the web inbox shows them. 51 distinct titles covered 747 decidable
|
|
12
|
+
* initiatives, so the title alone could not tell two rows apart (OSK-15378). A dash is "not named" (an id the
|
|
13
|
+
* server could not read for this viewer is in `--json`), never "none".
|
|
14
|
+
*/
|
|
15
|
+
export declare function aboutFor(row: ProposalView): string;
|
|
9
16
|
export default class ProposalsList extends BaseCommand {
|
|
10
17
|
static description: string;
|
|
11
18
|
static flags: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.emptyPageLines = emptyPageLines;
|
|
4
|
+
exports.aboutFor = aboutFor;
|
|
4
5
|
const core_1 = require("@oclif/core");
|
|
5
6
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
6
7
|
const base_command_1 = require("../../base-command");
|
|
@@ -23,6 +24,14 @@ function emptyPageLines(narrowed, nextCursor) {
|
|
|
23
24
|
]
|
|
24
25
|
: ['No proposals on this page; the cursor below continues.'];
|
|
25
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* What the row is ABOUT: the Commitment and the Agent behind it, in the order the web inbox shows them. 51 distinct titles covered 747 decidable
|
|
29
|
+
* initiatives, so the title alone could not tell two rows apart (OSK-15378). A dash is "not named" (an id the
|
|
30
|
+
* server could not read for this viewer is in `--json`), never "none".
|
|
31
|
+
*/
|
|
32
|
+
function aboutFor(row) {
|
|
33
|
+
return [row.commitmentTitle, row.agent?.name].filter(Boolean).join(' · ') || '—';
|
|
34
|
+
}
|
|
26
35
|
/** A snoozed proposal reads `proposed` in its disposition; the wake time is what tells them apart. */
|
|
27
36
|
function noteFor(row) {
|
|
28
37
|
if (row.sourceStatus === 'snoozed' && row.snoozedUntil)
|
|
@@ -77,6 +86,7 @@ class ProposalsList extends base_command_1.BaseCommand {
|
|
|
77
86
|
(0, format_1.renderTable)(result.data.map((row) => ({
|
|
78
87
|
id: row.id,
|
|
79
88
|
title: row.title,
|
|
89
|
+
about: aboutFor(row),
|
|
80
90
|
disposition: row.disposition,
|
|
81
91
|
// Most proposals carry no estimate; "unknown" read as a failure to determine one (OSK-15377).
|
|
82
92
|
basis: row.economics?.basis || '—',
|
|
@@ -85,6 +95,7 @@ class ProposalsList extends base_command_1.BaseCommand {
|
|
|
85
95
|
})), [
|
|
86
96
|
{ key: 'id', header: 'PROPOSAL', verbatim: true },
|
|
87
97
|
{ key: 'title', header: 'TITLE' },
|
|
98
|
+
{ key: 'about', header: 'ABOUT', maxWidth: 48 },
|
|
88
99
|
{ key: 'disposition', header: 'DISPOSITION' },
|
|
89
100
|
{ key: 'basis', header: 'BASIS' },
|
|
90
101
|
{ key: 'deadline', header: 'DEADLINE' },
|
|
@@ -58,13 +58,31 @@ function renderExecutionReceipt(receipt, log, verbose = false) {
|
|
|
58
58
|
log(` ${evidence.label}: ${location}`);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
+
// "Next" names an action only when the receipt has one. A reason that only
|
|
62
|
+
// restates what happened (a typed blocker's summary, which servers before
|
|
63
|
+
// OSK-16429 sent as the reason) is narrative, not something to do: the actor
|
|
64
|
+
// is printed without it and the narrative stays with the blocker.
|
|
65
|
+
const narrative = [receipt.summary, receipt.blocker?.summary].filter(Boolean);
|
|
66
|
+
const action = receipt.nextActor?.reason && !narrative.includes(receipt.nextActor.reason)
|
|
67
|
+
? receipt.nextActor.reason
|
|
68
|
+
: '';
|
|
61
69
|
if (receipt.nextActor)
|
|
62
|
-
log(`Next: ${receipt.nextActor.label || receipt.nextActor.kind}${
|
|
70
|
+
log(`Next: ${receipt.nextActor.label || receipt.nextActor.kind}${action ? ` — ${action}` : ''}`);
|
|
63
71
|
if (receipt.blocker) {
|
|
64
72
|
log(`Blocker: ${receipt.blocker.code}`);
|
|
73
|
+
// The headline already carries a typed blocker's summary; say it again only
|
|
74
|
+
// when it differs.
|
|
75
|
+
if (receipt.blocker.summary && receipt.blocker.summary !== receipt.summary)
|
|
76
|
+
log(` Detail: ${receipt.blocker.summary}`);
|
|
65
77
|
for (const evidenceRef of receipt.blocker.evidenceRefs || [])
|
|
66
78
|
log(` Evidence: ${evidenceRef}`);
|
|
67
79
|
}
|
|
80
|
+
// A source gap beside this episode, not the reason it stopped (OSK-16230).
|
|
81
|
+
if (receipt.standingBlocker) {
|
|
82
|
+
log(`Standing: ${receipt.standingBlocker.code} — ${receipt.standingBlocker.summary} (${receipt.standingBlocker.owner.label})`);
|
|
83
|
+
for (const evidenceRef of receipt.standingBlocker.evidenceRefs || [])
|
|
84
|
+
log(` Evidence: ${evidenceRef}`);
|
|
85
|
+
}
|
|
68
86
|
if (verbose)
|
|
69
87
|
log(`Diagnostics:\n${JSON.stringify({ id: receipt.id, revision: receipt.revision, evidence: receipt.evidence, diagnostics: receipt.diagnostics }, null, 2)}`);
|
|
70
88
|
}
|
|
@@ -818,8 +818,16 @@ export declare function describeOperation(operation: string | null | undefined,
|
|
|
818
818
|
* already composed sat only in `--json` and `doctor` (OSK-16212). Nothing is
|
|
819
819
|
* printed while the operation is ready or working, where a fix would contradict
|
|
820
820
|
* the line above it.
|
|
821
|
-
|
|
822
|
-
|
|
821
|
+
*
|
|
822
|
+
* Returns one or two lines. `Fix:` only when the blocker carries an action; a
|
|
823
|
+
* typed blocker an agent returned carries only what happened, which printed
|
|
824
|
+
* under "Fix:" read as a remedy nobody wrote (OSK-16230). That narrative is
|
|
825
|
+
* labelled `Blocker:` instead, and no remedy is made up for it.
|
|
826
|
+
*/
|
|
827
|
+
export declare function describeOperationFix(commitment: CommitmentView, operation: string | null | undefined): Array<{
|
|
828
|
+
label: 'Fix' | 'Blocker';
|
|
829
|
+
text: string;
|
|
830
|
+
}>;
|
|
823
831
|
/**
|
|
824
832
|
* Who stopped a Commitment, and when and why, in one line. The server stores it as `stoppedBy`;
|
|
825
833
|
* `show` printed neither (OSK-15423), so a Commitment you paused did not say you had.
|
package/dist/lib/commitments.js
CHANGED
|
@@ -955,20 +955,32 @@ function describeOperation(operation, reason) {
|
|
|
955
955
|
* already composed sat only in `--json` and `doctor` (OSK-16212). Nothing is
|
|
956
956
|
* printed while the operation is ready or working, where a fix would contradict
|
|
957
957
|
* the line above it.
|
|
958
|
+
*
|
|
959
|
+
* Returns one or two lines. `Fix:` only when the blocker carries an action; a
|
|
960
|
+
* typed blocker an agent returned carries only what happened, which printed
|
|
961
|
+
* under "Fix:" read as a remedy nobody wrote (OSK-16230). That narrative is
|
|
962
|
+
* labelled `Blocker:` instead, and no remedy is made up for it.
|
|
958
963
|
*/
|
|
959
964
|
function describeOperationFix(commitment, operation) {
|
|
960
965
|
if (operation === 'ready' || operation === 'working')
|
|
961
|
-
return
|
|
966
|
+
return [];
|
|
962
967
|
const blocker = commitment.firstActionableBlocker;
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
const
|
|
968
|
+
if (!blocker)
|
|
969
|
+
return [];
|
|
970
|
+
const remediation = typeof blocker.remediation === 'string' ? blocker.remediation.trim() : '';
|
|
971
|
+
const detail = typeof blocker.detail === 'string' ? blocker.detail.trim() : '';
|
|
972
|
+
const who = typeof blocker.ownerLabel === 'string' && blocker.ownerLabel
|
|
967
973
|
? blocker.ownerLabel
|
|
968
|
-
: typeof blocker
|
|
974
|
+
: typeof blocker.owner === 'string' && blocker.owner
|
|
969
975
|
? blocker.owner
|
|
970
976
|
: '';
|
|
971
|
-
|
|
977
|
+
const lines = [];
|
|
978
|
+
// The detail is shown only when the fix does not already say it.
|
|
979
|
+
if (detail && detail !== remediation)
|
|
980
|
+
lines.push({ label: 'Blocker', text: `${detail}${!remediation && who ? ` (${who})` : ''}` });
|
|
981
|
+
if (remediation)
|
|
982
|
+
lines.push({ label: 'Fix', text: `${remediation}${who ? ` (${who})` : ''}` });
|
|
983
|
+
return lines;
|
|
972
984
|
}
|
|
973
985
|
/**
|
|
974
986
|
* Who stopped a Commitment, and when and why, in one line. The server stores it as `stoppedBy`;
|
|
@@ -1082,9 +1094,8 @@ scheduleIssues) {
|
|
|
1082
1094
|
log(`Assessment: ${assessment?.label ?? 'Unknown'}`);
|
|
1083
1095
|
log(`Evidence: ${assessment?.evidence ?? 'unavailable'}`);
|
|
1084
1096
|
log(`Operation: ${describeOperation(assessment?.operation, assessment?.operationReason)}`);
|
|
1085
|
-
const
|
|
1086
|
-
|
|
1087
|
-
log(` Fix: ${fix}`);
|
|
1097
|
+
for (const line of describeOperationFix(commitment, assessment?.operation))
|
|
1098
|
+
log(` ${line.label}: ${line.text}`);
|
|
1088
1099
|
if (commitment.state?.lastCheckedAt)
|
|
1089
1100
|
log(`Checked: ${commitment.state.lastCheckedAt}`);
|
|
1090
1101
|
if (typeof commitment.state?.consecutiveUnresolvedChecks === 'number') {
|