@aragon-agent/cli 0.6.44 → 0.6.46
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/CHANGELOG.md +44 -0
- package/README.md +120 -2
- package/dist/agent/controller.d.ts +69 -0
- package/dist/agent/controller.js +224 -11
- package/dist/agent/governance-view.d.ts +40 -0
- package/dist/agent/governance-view.js +40 -0
- package/dist/agent/governance-wiring.d.ts +162 -0
- package/dist/agent/governance-wiring.js +470 -0
- package/dist/agent/invocation-card.d.ts +77 -0
- package/dist/agent/invocation-card.js +169 -0
- package/dist/agent/plan-prompt.d.ts +7 -0
- package/dist/agent/plan-prompt.js +2 -1
- package/dist/agent/prompt-options.d.ts +6 -0
- package/dist/agent/queued-messages.d.ts +3 -0
- package/dist/agent/queued-messages.js +4 -1
- package/dist/agent/reducer.d.ts +38 -1
- package/dist/agent/reducer.js +57 -12
- package/dist/agent/system-prompt.d.ts +19 -0
- package/dist/agent/system-prompt.js +9 -1
- package/dist/cli.js +45 -1
- package/dist/commands/builtins.js +22 -4
- package/dist/commands/governance-command.d.ts +35 -0
- package/dist/commands/governance-command.js +304 -0
- package/dist/commands/governance-runs-table.d.ts +40 -0
- package/dist/commands/governance-runs-table.js +130 -0
- package/dist/commands/index-build.d.ts +8 -0
- package/dist/commands/index-build.js +11 -0
- package/dist/commands/registry.d.ts +35 -0
- package/dist/commands/registry.js +20 -7
- package/dist/commands/skills.js +36 -2
- package/dist/commands/subagent-command.js +3 -1
- package/dist/commands/team-command.d.ts +6 -0
- package/dist/commands/team-command.js +40 -3
- package/dist/config/app-paths.d.ts +10 -0
- package/dist/config/app-paths.js +12 -0
- package/dist/config/cli-commands.d.ts +18 -0
- package/dist/config/cli-commands.js +47 -1
- package/dist/config/env.d.ts +2 -1
- package/dist/config/env.js +10 -1
- package/dist/config/governance-config.d.ts +125 -0
- package/dist/config/governance-config.js +164 -0
- package/dist/config/governance-launch.d.ts +71 -0
- package/dist/config/governance-launch.js +58 -0
- package/dist/config/load.d.ts +15 -0
- package/dist/config/load.js +26 -1
- package/dist/config/model-profile-store.d.ts +4 -2
- package/dist/config/schema.d.ts +22 -0
- package/dist/config/schema.js +6 -0
- package/dist/config/store.js +14 -1
- package/dist/config/ui-state.d.ts +11 -0
- package/dist/config/ui-state.js +11 -0
- package/dist/diagnostics/doctor.js +20 -0
- package/dist/governance/card-normalize.d.ts +24 -0
- package/dist/governance/card-normalize.js +76 -0
- package/dist/governance/copy.d.ts +109 -0
- package/dist/governance/copy.js +223 -0
- package/dist/governance/engine/aftermath.d.ts +49 -0
- package/dist/governance/engine/aftermath.js +134 -0
- package/dist/governance/engine/artifact-persist.d.ts +35 -0
- package/dist/governance/engine/artifact-persist.js +86 -0
- package/dist/governance/engine/budget.d.ts +52 -0
- package/dist/governance/engine/budget.js +112 -0
- package/dist/governance/engine/cards.d.ts +18 -0
- package/dist/governance/engine/cards.js +186 -0
- package/dist/governance/engine/digest.d.ts +32 -0
- package/dist/governance/engine/digest.js +63 -0
- package/dist/governance/engine/engine-core.d.ts +219 -0
- package/dist/governance/engine/engine-core.js +562 -0
- package/dist/governance/engine/engine.d.ts +68 -0
- package/dist/governance/engine/engine.js +314 -0
- package/dist/governance/engine/estimate.d.ts +38 -0
- package/dist/governance/engine/estimate.js +46 -0
- package/dist/governance/engine/inspector.d.ts +16 -0
- package/dist/governance/engine/inspector.js +396 -0
- package/dist/governance/engine/integration.d.ts +35 -0
- package/dist/governance/engine/integration.js +220 -0
- package/dist/governance/engine/lifecycle.d.ts +29 -0
- package/dist/governance/engine/lifecycle.js +656 -0
- package/dist/governance/engine/pause.d.ts +56 -0
- package/dist/governance/engine/pause.js +107 -0
- package/dist/governance/engine/phase-members.d.ts +15 -0
- package/dist/governance/engine/phase-members.js +34 -0
- package/dist/governance/engine/phase-planner.d.ts +53 -0
- package/dist/governance/engine/phase-planner.js +282 -0
- package/dist/governance/engine/rebuild.d.ts +27 -0
- package/dist/governance/engine/rebuild.js +57 -0
- package/dist/governance/engine/report.d.ts +66 -0
- package/dist/governance/engine/report.js +220 -0
- package/dist/governance/engine/run-digest.d.ts +20 -0
- package/dist/governance/engine/run-digest.js +42 -0
- package/dist/governance/engine/spec-builder.d.ts +117 -0
- package/dist/governance/engine/spec-builder.js +321 -0
- package/dist/governance/engine/stage-runner.d.ts +22 -0
- package/dist/governance/engine/stage-runner.js +664 -0
- package/dist/governance/engine/start-input.d.ts +19 -0
- package/dist/governance/engine/start-input.js +111 -0
- package/dist/governance/engine/state-machine.d.ts +101 -0
- package/dist/governance/engine/state-machine.js +586 -0
- package/dist/governance/engine/submission-queries.d.ts +42 -0
- package/dist/governance/engine/submission-queries.js +97 -0
- package/dist/governance/engine/submission-render.d.ts +12 -0
- package/dist/governance/engine/submission-render.js +92 -0
- package/dist/governance/engine/submissions.d.ts +27 -0
- package/dist/governance/engine/submissions.js +455 -0
- package/dist/governance/engine/visibility.d.ts +104 -0
- package/dist/governance/engine/visibility.js +223 -0
- package/dist/governance/governed-dispatch.d.ts +19 -0
- package/dist/governance/governed-dispatch.js +17 -0
- package/dist/governance/limits.d.ts +107 -0
- package/dist/governance/limits.js +131 -0
- package/dist/governance/posture-transition.d.ts +38 -0
- package/dist/governance/posture-transition.js +44 -0
- package/dist/governance/posture.d.ts +35 -0
- package/dist/governance/posture.js +59 -0
- package/dist/governance/profiles.d.ts +48 -0
- package/dist/governance/profiles.js +140 -0
- package/dist/governance/prompts/orchestrator-block.d.ts +40 -0
- package/dist/governance/prompts/orchestrator-block.js +128 -0
- package/dist/governance/prompts/plan-addendum.d.ts +22 -0
- package/dist/governance/prompts/plan-addendum.js +60 -0
- package/dist/governance/prompts/refusals.d.ts +48 -0
- package/dist/governance/prompts/refusals.js +82 -0
- package/dist/governance/prompts/role-blocks.d.ts +40 -0
- package/dist/governance/prompts/role-blocks.js +255 -0
- package/dist/governance/report-reader.d.ts +31 -0
- package/dist/governance/report-reader.js +57 -0
- package/dist/governance/roles.d.ts +83 -0
- package/dist/governance/roles.js +142 -0
- package/dist/governance/rules/claims.d.ts +83 -0
- package/dist/governance/rules/claims.js +250 -0
- package/dist/governance/rules/elimination.d.ts +66 -0
- package/dist/governance/rules/elimination.js +105 -0
- package/dist/governance/rules/events-table.d.ts +46 -0
- package/dist/governance/rules/events-table.js +94 -0
- package/dist/governance/rules/failure-analysis.d.ts +28 -0
- package/dist/governance/rules/failure-analysis.js +93 -0
- package/dist/governance/rules/ledger-replay.d.ts +53 -0
- package/dist/governance/rules/ledger-replay.js +53 -0
- package/dist/governance/rules/ledger-state.d.ts +85 -0
- package/dist/governance/rules/ledger-state.js +175 -0
- package/dist/governance/rules/ledger.d.ts +228 -0
- package/dist/governance/rules/ledger.js +560 -0
- package/dist/governance/rules/rca.d.ts +68 -0
- package/dist/governance/rules/rca.js +220 -0
- package/dist/governance/rules/settlement.d.ts +129 -0
- package/dist/governance/rules/settlement.js +363 -0
- package/dist/governance/rules/suspicion.d.ts +66 -0
- package/dist/governance/rules/suspicion.js +169 -0
- package/dist/governance/store/artifacts.d.ts +81 -0
- package/dist/governance/store/artifacts.js +173 -0
- package/dist/governance/store/atomic.d.ts +79 -0
- package/dist/governance/store/atomic.js +119 -0
- package/dist/governance/store/events-log.d.ts +35 -0
- package/dist/governance/store/events-log.js +86 -0
- package/dist/governance/store/run-lock.d.ts +51 -0
- package/dist/governance/store/run-lock.js +122 -0
- package/dist/governance/store/run-store.d.ts +229 -0
- package/dist/governance/store/run-store.js +644 -0
- package/dist/governance/store/scoreboard-export.d.ts +53 -0
- package/dist/governance/store/scoreboard-export.js +65 -0
- package/dist/governance/tools/child-tools.d.ts +31 -0
- package/dist/governance/tools/child-tools.js +65 -0
- package/dist/governance/tools/guard.d.ts +71 -0
- package/dist/governance/tools/guard.js +194 -0
- package/dist/governance/tools/inspector-tools.d.ts +63 -0
- package/dist/governance/tools/inspector-tools.js +424 -0
- package/dist/governance/tools/lead-tools.d.ts +42 -0
- package/dist/governance/tools/lead-tools.js +226 -0
- package/dist/governance/tools/normalize-util.d.ts +101 -0
- package/dist/governance/tools/normalize-util.js +230 -0
- package/dist/governance/tools/scan-incomplete.d.ts +79 -0
- package/dist/governance/tools/scan-incomplete.js +486 -0
- package/dist/governance/tools/shared-tools.d.ts +44 -0
- package/dist/governance/tools/shared-tools.js +125 -0
- package/dist/governance/tools/submit-normalizers.d.ts +28 -0
- package/dist/governance/tools/submit-normalizers.js +474 -0
- package/dist/governance/tools/submit-tools.d.ts +26 -0
- package/dist/governance/tools/submit-tools.js +171 -0
- package/dist/governance/types.d.ts +661 -0
- package/dist/governance/types.js +27 -0
- package/dist/session/persist.js +10 -0
- package/dist/session/validate-session.js +36 -3
- package/dist/team/forced-mode.d.ts +19 -0
- package/dist/team/forced-mode.js +42 -20
- package/dist/team/runtime.d.ts +8 -0
- package/dist/team/runtime.js +9 -0
- package/dist/team/subagent.d.ts +23 -0
- package/dist/team/subagent.js +14 -3
- package/dist/team/types.d.ts +6 -0
- package/dist/tools/index.d.ts +30 -7
- package/dist/tools/index.js +14 -0
- package/dist/tools/plan-tools.d.ts +14 -2
- package/dist/tools/plan-tools.js +5 -2
- package/dist/ui/App.js +170 -31
- package/dist/ui/BottomStatusRow.js +1 -1
- package/dist/ui/Composer.d.ts +7 -1
- package/dist/ui/Composer.js +9 -6
- package/dist/ui/GovernancePanel.d.ts +50 -0
- package/dist/ui/GovernancePanel.js +77 -0
- package/dist/ui/GovernanceRun.d.ts +18 -0
- package/dist/ui/GovernanceRun.js +11 -0
- package/dist/ui/StatusBar.d.ts +15 -2
- package/dist/ui/StatusBar.js +10 -4
- package/dist/ui/Transcript.js +7 -1
- package/dist/ui/entries/GovernanceCard.d.ts +30 -0
- package/dist/ui/entries/GovernanceCard.js +32 -0
- package/dist/ui/entries/InvocationCard.d.ts +20 -0
- package/dist/ui/entries/InvocationCard.js +32 -0
- package/dist/ui/governance-copy.d.ts +69 -0
- package/dist/ui/governance-copy.js +104 -0
- package/dist/ui/governance-status.d.ts +145 -0
- package/dist/ui/governance-status.js +326 -0
- package/dist/ui/interaction-copy.d.ts +4 -0
- package/dist/ui/interaction-copy.js +5 -0
- package/dist/ui/interaction-hints.d.ts +17 -0
- package/dist/ui/interaction-hints.js +14 -2
- package/dist/ui/layout/governance-board.d.ts +121 -0
- package/dist/ui/layout/governance-board.js +382 -0
- package/dist/ui/layout/governance-card.d.ts +53 -0
- package/dist/ui/layout/governance-card.js +134 -0
- package/dist/ui/layout/governance-chip.d.ts +38 -0
- package/dist/ui/layout/governance-chip.js +64 -0
- package/dist/ui/layout/governance-panel.d.ts +85 -0
- package/dist/ui/layout/governance-panel.js +358 -0
- package/dist/ui/layout/governance-roster.d.ts +65 -0
- package/dist/ui/layout/governance-roster.js +275 -0
- package/dist/ui/layout/invocation-card.d.ts +41 -0
- package/dist/ui/layout/invocation-card.js +91 -0
- package/dist/ui/layout/status-detail-layout.js +3 -3
- package/dist/ui/layout/status-layout.d.ts +5 -2
- package/dist/ui/layout/status-layout.js +10 -6
- package/dist/ui/layout/virtual-window.js +22 -1
- package/dist/ui/overlays/GovernanceBoardOverlay.d.ts +41 -0
- package/dist/ui/overlays/GovernanceBoardOverlay.js +76 -0
- package/dist/ui/overlays/GovernanceSettingsPage.d.ts +48 -0
- package/dist/ui/overlays/GovernanceSettingsPage.js +93 -0
- package/dist/ui/overlays/HelpOverlay.js +4 -3
- package/dist/ui/overlays/QuestionOverlay.d.ts +9 -1
- package/dist/ui/overlays/QuestionOverlay.js +4 -2
- package/dist/ui/overlays/SettingsScreen.d.ts +7 -0
- package/dist/ui/overlays/SettingsScreen.js +21 -1
- package/dist/ui/overlays/governance-settings.d.ts +79 -0
- package/dist/ui/overlays/governance-settings.js +140 -0
- package/dist/ui/overlays/model-profile-state.d.ts +6 -1
- package/dist/ui/overlays/model-profile-state.js +10 -0
- package/dist/ui/palettes.d.ts +17 -0
- package/dist/ui/palettes.js +9 -0
- package/dist/ui/scrollback/live-preview.js +2 -0
- package/dist/ui/scrollback/settled-boundary.js +3 -0
- package/dist/ui/shortcuts.js +2 -2
- package/dist/ui/theme.d.ts +7 -0
- package/dist/ui/theme.js +1 -0
- package/dist/ui/transcript-text.js +13 -1
- package/dist/ui/use-wheel-routing.js +3 -1
- package/package.json +2 -2
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invocation cards (tui-invocation-cards): what a transcript shows INSTEAD of the
|
|
3
|
+
* system prompt a command submitted on the user's behalf.
|
|
4
|
+
*
|
|
5
|
+
* Pure and total: no IO, no React, no Ink, nothing but `import type`. ASCII ONLY -
|
|
6
|
+
* `src/agent/**` new files sit inside the `glyphs.test.ts` scan scope.
|
|
7
|
+
*
|
|
8
|
+
* ONE CONSTRUCTOR (I-3). `buildInvocationCard` is the only function that turns raw
|
|
9
|
+
* command-layer material into a card, `App.submitMessage` is its only caller, and
|
|
10
|
+
* `sanitizeInvocationCard` (the session-load path) shares its normaliser so a card
|
|
11
|
+
* written today and a card read back tomorrow cannot drift apart.
|
|
12
|
+
*
|
|
13
|
+
* ORDER IS REDACT -> NORMALISE -> LIMIT, and it is the load-bearing part (I-6). Cut
|
|
14
|
+
* first and a secret that straddles the cut leaves a prefix shorter than the
|
|
15
|
+
* redaction patterns' minimum length: the half-key sails through into the
|
|
16
|
+
* transcript, the session file and the exit replay.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* The renderer, the height estimate and the loader all read THESE numbers (I-4).
|
|
20
|
+
* A card's height is a function of its data and these limits, so it is bounded:
|
|
21
|
+
* header + `inputMaxLines` + hidden tail + note.
|
|
22
|
+
*/
|
|
23
|
+
export const INVOCATION_LIMITS = {
|
|
24
|
+
commandLineMaxChars: 2000,
|
|
25
|
+
inputMaxChars: 480,
|
|
26
|
+
inputMaxLines: 8,
|
|
27
|
+
nameMaxChars: 64,
|
|
28
|
+
factsMax: 5,
|
|
29
|
+
factMaxChars: 28,
|
|
30
|
+
noteMaxChars: 140,
|
|
31
|
+
};
|
|
32
|
+
const VARIANTS = ['skill', 'team', 'todo', 'govern'];
|
|
33
|
+
// C0 except TAB (\x09) and LF (\x0a), then DEL and C1 (which includes the 8-bit CSI
|
|
34
|
+
// \x9b). Matches the range `QueueOverlay` strips, so the card is no more permissive.
|
|
35
|
+
// eslint-disable-next-line no-control-regex
|
|
36
|
+
const CONTROL_CHARS = /[\x00-\x08\x0b-\x1f\x7f-\x9f]/g;
|
|
37
|
+
const CAP_MARK = '...';
|
|
38
|
+
/** Cut at a code-point boundary: a surrogate pair is never split. */
|
|
39
|
+
function sliceCodePoints(text, count) {
|
|
40
|
+
if (count <= 0)
|
|
41
|
+
return '';
|
|
42
|
+
if (text.length <= count)
|
|
43
|
+
return text;
|
|
44
|
+
let end = count;
|
|
45
|
+
const last = text.charCodeAt(end - 1);
|
|
46
|
+
// A high surrogate at the cut would orphan its low half.
|
|
47
|
+
if (last >= 0xd800 && last <= 0xdbff)
|
|
48
|
+
end -= 1;
|
|
49
|
+
return text.slice(0, end);
|
|
50
|
+
}
|
|
51
|
+
function countCodePoints(text) {
|
|
52
|
+
let count = 0;
|
|
53
|
+
for (const _ of text)
|
|
54
|
+
count += 1;
|
|
55
|
+
return count;
|
|
56
|
+
}
|
|
57
|
+
/** CRLF and bare CR to LF (a bare CR returns Ink's cursor to column 0), then strip controls. */
|
|
58
|
+
function normalizeText(text) {
|
|
59
|
+
return text.replace(/\r\n?/g, '\n').replace(CONTROL_CHARS, '');
|
|
60
|
+
}
|
|
61
|
+
function capCommandLine(text) {
|
|
62
|
+
const max = INVOCATION_LIMITS.commandLineMaxChars;
|
|
63
|
+
if (text.length <= max)
|
|
64
|
+
return text;
|
|
65
|
+
return sliceCodePoints(text, max - CAP_MARK.length) + CAP_MARK;
|
|
66
|
+
}
|
|
67
|
+
function capInput(text) {
|
|
68
|
+
const trimmed = text.trim();
|
|
69
|
+
if (trimmed === '')
|
|
70
|
+
return { input: '', hidden: 0 };
|
|
71
|
+
const lines = trimmed.split('\n');
|
|
72
|
+
let kept = lines.length > INVOCATION_LIMITS.inputMaxLines
|
|
73
|
+
? lines.slice(0, INVOCATION_LIMITS.inputMaxLines).join('\n') : trimmed;
|
|
74
|
+
kept = sliceCodePoints(kept, INVOCATION_LIMITS.inputMaxChars).trimEnd();
|
|
75
|
+
return { input: kept, hidden: countCodePoints(trimmed) - countCodePoints(kept) };
|
|
76
|
+
}
|
|
77
|
+
function capSingleLine(text, max) {
|
|
78
|
+
const flat = text.replace(/\s+/g, ' ').trim();
|
|
79
|
+
if (countCodePoints(flat) <= max)
|
|
80
|
+
return flat;
|
|
81
|
+
return sliceCodePoints(flat, max - CAP_MARK.length) + CAP_MARK;
|
|
82
|
+
}
|
|
83
|
+
function capFacts(facts) {
|
|
84
|
+
return facts
|
|
85
|
+
.map((fact) => capSingleLine(fact, INVOCATION_LIMITS.factMaxChars))
|
|
86
|
+
.filter((fact) => fact !== '')
|
|
87
|
+
.slice(0, INVOCATION_LIMITS.factsMax);
|
|
88
|
+
}
|
|
89
|
+
function capNote(note) {
|
|
90
|
+
if (note === undefined)
|
|
91
|
+
return undefined;
|
|
92
|
+
const capped = capSingleLine(note, INVOCATION_LIMITS.noteMaxChars);
|
|
93
|
+
return capped === '' ? undefined : capped;
|
|
94
|
+
}
|
|
95
|
+
/** Shared by the write path and the load path so the two cannot diverge. */
|
|
96
|
+
function assemble(parts) {
|
|
97
|
+
const { input, hidden } = capInput(normalizeText(parts.input));
|
|
98
|
+
const note = capNote(normalizeText(parts.note ?? ''));
|
|
99
|
+
return {
|
|
100
|
+
variant: parts.variant,
|
|
101
|
+
name: capSingleLine(normalizeText(parts.name), INVOCATION_LIMITS.nameMaxChars),
|
|
102
|
+
commandLine: capCommandLine(normalizeText(parts.commandLine).trim()),
|
|
103
|
+
input,
|
|
104
|
+
inputHidden: hidden,
|
|
105
|
+
facts: capFacts(parts.facts.map(normalizeText)),
|
|
106
|
+
...(note !== undefined ? { note } : {}),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Total, never throws. `redact` is injected (the same closure `Command:` echo uses) so
|
|
111
|
+
* this module depends on nothing; the default is the identity for tests and the loader.
|
|
112
|
+
*/
|
|
113
|
+
export function buildInvocationCard(input, redact = (text) => text) {
|
|
114
|
+
const scrub = (text) => {
|
|
115
|
+
if (text === undefined)
|
|
116
|
+
return '';
|
|
117
|
+
try {
|
|
118
|
+
return redact(text);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return '';
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
return assemble({
|
|
125
|
+
variant: input.variant,
|
|
126
|
+
name: scrub(input.name),
|
|
127
|
+
commandLine: scrub(input.commandLine),
|
|
128
|
+
input: scrub(input.input),
|
|
129
|
+
facts: (input.facts ?? []).map((fact) => scrub(fact)),
|
|
130
|
+
note: input.note === undefined ? undefined : scrub(input.note),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function asString(value) {
|
|
134
|
+
return typeof value === 'string' ? value : null;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Session-load path: `null` for anything that is not a plausible card, so the caller
|
|
138
|
+
* drops the field and the entry degrades to a plain user message (I-7). Re-derives
|
|
139
|
+
* `inputHidden` from nothing - it trusts the stored count only when it is a sane integer.
|
|
140
|
+
*/
|
|
141
|
+
export function sanitizeInvocationCard(value) {
|
|
142
|
+
if (typeof value !== 'object' || value === null)
|
|
143
|
+
return null;
|
|
144
|
+
const raw = value;
|
|
145
|
+
const variant = VARIANTS.find((candidate) => candidate === raw.variant);
|
|
146
|
+
const commandLine = asString(raw.commandLine);
|
|
147
|
+
if (variant === undefined || commandLine === null)
|
|
148
|
+
return null;
|
|
149
|
+
const name = asString(raw.name) ?? '';
|
|
150
|
+
const input = asString(raw.input) ?? '';
|
|
151
|
+
const facts = Array.isArray(raw.facts)
|
|
152
|
+
? raw.facts.filter((fact) => typeof fact === 'string') : [];
|
|
153
|
+
const note = asString(raw.note) ?? undefined;
|
|
154
|
+
const card = assemble({ variant, name, commandLine, input, facts, note });
|
|
155
|
+
// A stored card that was already capped must keep its recorded `inputHidden`; the
|
|
156
|
+
// re-cap above can only ever add to it.
|
|
157
|
+
const stored = raw.inputHidden;
|
|
158
|
+
const storedHidden = typeof stored === 'number' && Number.isInteger(stored) && stored > 0
|
|
159
|
+
? Math.min(stored, 10_000_000) : 0;
|
|
160
|
+
return { ...card, inputHidden: Math.max(card.inputHidden, storedHidden) };
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Emergency kill switch (`ARAGON_NO_INVOCATION_CARDS=1`): every command and the App fall
|
|
164
|
+
* back to the pre-card behaviour. Read at call time, not import time, so a test (or a
|
|
165
|
+
* wrapper script) that sets the variable after load is honoured.
|
|
166
|
+
*/
|
|
167
|
+
export function invocationCardsEnabled(env = process.env) {
|
|
168
|
+
return env.ARAGON_NO_INVOCATION_CARDS !== '1';
|
|
169
|
+
}
|
|
@@ -12,5 +12,12 @@ export declare const PLAN_MODE_BLOCK_VERSION = "v3-2026-10-26";
|
|
|
12
12
|
export interface PlanModeBlockOptions {
|
|
13
13
|
/** False under `-p` / piped stdin: no overlay can be rendered, so no tools. */
|
|
14
14
|
interactive: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* PLAN+GOVERN's interview addendum (governance-mode 6.3). Appended INSIDE the block,
|
|
17
|
+
* just before the closing tag, and only for an interactive block: a governed team needs
|
|
18
|
+
* a human to interview. Absent leaves the block byte-identical, so
|
|
19
|
+
* `PLAN_MODE_BLOCK_VERSION` does not move.
|
|
20
|
+
*/
|
|
21
|
+
governAddendum?: string;
|
|
15
22
|
}
|
|
16
23
|
export declare function buildPlanModeBlock(options: PlanModeBlockOptions): string;
|
|
@@ -42,7 +42,7 @@ const HEADLESS_PARAGRAPH = [
|
|
|
42
42
|
' write the finished plan as your final message in markdown.',
|
|
43
43
|
].join('\n');
|
|
44
44
|
export function buildPlanModeBlock(options) {
|
|
45
|
-
const { interactive } = options;
|
|
45
|
+
const { interactive, governAddendum } = options;
|
|
46
46
|
// NO ROUND COUNT APPEARS HERE, and none may be reintroduced: the number used
|
|
47
47
|
// to be substituted from `planModeMaxAskRounds`, which meant the prompt itself
|
|
48
48
|
// told the model it would run out. "3-5 questions" was also wrong against a
|
|
@@ -95,6 +95,7 @@ export function buildPlanModeBlock(options) {
|
|
|
95
95
|
'- Never invent a path. Cite files you have read.',
|
|
96
96
|
...verdictRule,
|
|
97
97
|
interactive ? SUPERSEDE_PARAGRAPH : HEADLESS_PARAGRAPH,
|
|
98
|
+
...(interactive && governAddendum ? ['', governAddendum] : []),
|
|
98
99
|
'</plan_mode>',
|
|
99
100
|
].join('\n');
|
|
100
101
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { InvocationCardInput } from './invocation-card.js';
|
|
1
2
|
/** Explicit TUI task boundary; omission retains legacy programmatic behavior. */
|
|
2
3
|
export interface PromptOptions {
|
|
3
4
|
todoPolicy?: 'new-task' | 'continue';
|
|
@@ -5,6 +6,11 @@ export interface PromptOptions {
|
|
|
5
6
|
/** History recording is independent of whether this message continues a plan. */
|
|
6
7
|
export interface SubmitMessageOptions extends PromptOptions {
|
|
7
8
|
userInitiated?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Raw material for the transcript card. `submitMessage` builds the card exactly once
|
|
11
|
+
* (redact -> normalise -> limit); the payload sent to the model is unaffected.
|
|
12
|
+
*/
|
|
13
|
+
invocation?: InvocationCardInput;
|
|
8
14
|
}
|
|
9
15
|
/** Startup outcome only; engine events still describe the result of the run. */
|
|
10
16
|
export type PromptOutcome = {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { Entry } from './reducer.js';
|
|
2
|
+
import type { InvocationCard } from './invocation-card.js';
|
|
2
3
|
/** Full user text retained until Core acknowledges its opaque ID. */
|
|
3
4
|
export interface PendingSteering {
|
|
4
5
|
readonly queueId: string;
|
|
5
6
|
readonly text: string;
|
|
7
|
+
/** Carried so the `queued -> user` rewrite keeps the card (tui-invocation-cards). */
|
|
8
|
+
readonly invocation?: InvocationCard;
|
|
6
9
|
}
|
|
7
10
|
/** Hide only active pending entries, using the same projection for measurement and paint. */
|
|
8
11
|
export declare function selectTranscriptEntries(entries: Entry[], pending: readonly PendingSteering[]): Entry[];
|
|
@@ -13,7 +13,10 @@ export function reconcileSteeringReceipt(options) {
|
|
|
13
13
|
if (!ids.size)
|
|
14
14
|
return { entries: options.entries, pending: [...options.pending], changed: false };
|
|
15
15
|
const entries = mergePendingEntries(options.entries, options.pending).map((entry) => entry.kind === 'queued' && ids.has(entry.queueId ?? '')
|
|
16
|
-
? {
|
|
16
|
+
? {
|
|
17
|
+
id: entry.id, kind: 'user', text: entry.text,
|
|
18
|
+
...(entry.invocation ? { invocation: entry.invocation } : {}),
|
|
19
|
+
} : entry);
|
|
17
20
|
return { entries, pending: options.pending.filter((item) => !ids.has(item.queueId)), changed: true };
|
|
18
21
|
}
|
|
19
22
|
/** Supplement trimmed/cleared history for save and exit without deduplicating text. */
|
package/dist/agent/reducer.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* synthesizes a generic error notice (a swallowed throw is never a no-op).
|
|
12
12
|
*/
|
|
13
13
|
import type { PendingSteering } from './queued-messages.js';
|
|
14
|
+
import type { InvocationCard } from './invocation-card.js';
|
|
14
15
|
import type { AgentEvent, ModelCost, ToolResult, TokenUsage } from '@aragon-agent/core';
|
|
15
16
|
import type { AgentMode } from './agent-mode.js';
|
|
16
17
|
import type { DispatchOutcome, SubagentRun, SubagentSpec, TeamSnapshot } from '../team/types.js';
|
|
@@ -21,9 +22,11 @@ import type { JobKind, ServiceSnapshot, ServiceStatus } from '../proc/types.js';
|
|
|
21
22
|
import type { RetryPhase } from './retry-view.js';
|
|
22
23
|
import type { FilePatch } from '../tools/patch.js';
|
|
23
24
|
import type { TaskSummaryView } from '../fast/task-summary-types.js';
|
|
25
|
+
import type { GovernanceCardData, GovernanceSnapshot } from '../governance/types.js';
|
|
26
|
+
import type { Posture } from '../governance/posture.js';
|
|
24
27
|
export type NoticeLevel = 'info' | 'warn' | 'error';
|
|
25
28
|
export type ToastLevel = NoticeLevel | 'success';
|
|
26
|
-
export type Overlay = null | 'settings' | 'model' | 'help' | 'queue' | 'confirm' | 'question' | 'plan' | 'kit' | 'prompts' | 'prompt-pick' | 'agents'
|
|
29
|
+
export type Overlay = null | 'settings' | 'model' | 'help' | 'queue' | 'confirm' | 'question' | 'plan' | 'kit' | 'prompts' | 'prompt-pick' | 'agents' | 'governance'
|
|
27
30
|
/**
|
|
28
31
|
* tui-shortcut-drawer-and-task-summary §4.5: the keyboard drawer (`Ctrl+G` /
|
|
29
32
|
* `/keys`). A single field, so the drawer and `/help` cannot both hold the
|
|
@@ -45,6 +48,7 @@ export type Entry = {
|
|
|
45
48
|
id: string;
|
|
46
49
|
kind: 'user';
|
|
47
50
|
text: string;
|
|
51
|
+
invocation?: InvocationCard;
|
|
48
52
|
}
|
|
49
53
|
/**
|
|
50
54
|
* A message submitted while a run was in flight (tui-shift-enter-copy-queue
|
|
@@ -61,6 +65,7 @@ export type Entry = {
|
|
|
61
65
|
kind: 'queued';
|
|
62
66
|
text: string;
|
|
63
67
|
queueId?: string;
|
|
68
|
+
invocation?: InvocationCard;
|
|
64
69
|
} | {
|
|
65
70
|
id: string;
|
|
66
71
|
kind: 'assistant';
|
|
@@ -140,6 +145,11 @@ export type Entry = {
|
|
|
140
145
|
kind: 'notice';
|
|
141
146
|
level: NoticeLevel;
|
|
142
147
|
text: string;
|
|
148
|
+
} | {
|
|
149
|
+
id: string;
|
|
150
|
+
kind: 'governance';
|
|
151
|
+
at: number;
|
|
152
|
+
card: GovernanceCardData;
|
|
143
153
|
} | {
|
|
144
154
|
id: string;
|
|
145
155
|
kind: 'team';
|
|
@@ -372,6 +382,20 @@ export interface ViewState {
|
|
|
372
382
|
agentMode: AgentMode;
|
|
373
383
|
/** Set only by a DEFERRED `plan -> build`; drives the `PLAN -> BUILD` readout. */
|
|
374
384
|
pendingAgentMode: AgentMode | null;
|
|
385
|
+
/**
|
|
386
|
+
* The user-visible posture and its deferred twin (governance-mode 4.3). Written in the
|
|
387
|
+
* SAME dispatch as `agentMode` / `pendingAgentMode` and only from what the controller
|
|
388
|
+
* adopted, so the badge and the gate cannot diverge. `agentMode` keeps gating.
|
|
389
|
+
*/
|
|
390
|
+
posture: Posture;
|
|
391
|
+
pendingPosture: Posture | null;
|
|
392
|
+
/**
|
|
393
|
+
* The live governed-run snapshot, or `null` when there is no run.
|
|
394
|
+
*
|
|
395
|
+
* NEVER PERSISTED, like `team`: `/save` writes `entries` (the settlement cards are the
|
|
396
|
+
* history) and a resumed session has no live run to show.
|
|
397
|
+
*/
|
|
398
|
+
governance: GovernanceSnapshot | null;
|
|
375
399
|
/**
|
|
376
400
|
* The live team roster, or `null` when no dispatch is running.
|
|
377
401
|
*
|
|
@@ -486,6 +510,7 @@ export declare function initialViewState(seed?: ViewStateSeed): ViewState;
|
|
|
486
510
|
export type ViewAction = {
|
|
487
511
|
type: 'submit';
|
|
488
512
|
text: string;
|
|
513
|
+
invocation?: InvocationCard;
|
|
489
514
|
}
|
|
490
515
|
/**
|
|
491
516
|
* `controller.steer` was accepted; append the persistent queue marker
|
|
@@ -496,6 +521,7 @@ export type ViewAction = {
|
|
|
496
521
|
type: 'steerQueued';
|
|
497
522
|
queueId: string;
|
|
498
523
|
text: string;
|
|
524
|
+
invocation?: InvocationCard;
|
|
499
525
|
} | {
|
|
500
526
|
type: 'steeringAccepted';
|
|
501
527
|
ids: readonly string[];
|
|
@@ -622,6 +648,17 @@ export type ViewAction = {
|
|
|
622
648
|
type: 'setAgentMode';
|
|
623
649
|
mode: AgentMode;
|
|
624
650
|
pending: AgentMode | null;
|
|
651
|
+
posture?: Posture;
|
|
652
|
+
pendingPosture?: Posture | null;
|
|
653
|
+
} | {
|
|
654
|
+
type: 'govSnapshot';
|
|
655
|
+
snapshot: GovernanceSnapshot;
|
|
656
|
+
} | {
|
|
657
|
+
type: 'govEnd';
|
|
658
|
+
} | {
|
|
659
|
+
type: 'governanceCard';
|
|
660
|
+
card: GovernanceCardData;
|
|
661
|
+
at?: number;
|
|
625
662
|
} | {
|
|
626
663
|
type: 'teamStart';
|
|
627
664
|
dispatchId: string;
|
package/dist/agent/reducer.js
CHANGED
|
@@ -15,6 +15,8 @@ import { reconcileSteeringReceipt } from './queued-messages.js';
|
|
|
15
15
|
import { emptyContextUsage } from '../compaction/meter.js';
|
|
16
16
|
import { addUsage, computeCost } from './usage.js';
|
|
17
17
|
import { ENTRY_LIMITS, appendBounded, entryRetain, trimEntries } from './entry-limits.js';
|
|
18
|
+
import { isGovernedDispatch } from '../governance/governed-dispatch.js';
|
|
19
|
+
import { adoptPosture, foldGovernanceSnapshot } from './governance-view.js';
|
|
18
20
|
/** Default auto-dismiss window for a toast. */
|
|
19
21
|
export const DEFAULT_TOAST_TTL_MS = 2500;
|
|
20
22
|
/**
|
|
@@ -62,6 +64,9 @@ export function initialViewState(seed = {}) {
|
|
|
62
64
|
// `controller.getAgentMode()` so `--plan` renders on the first frame.
|
|
63
65
|
agentMode: 'build',
|
|
64
66
|
pendingAgentMode: null,
|
|
67
|
+
posture: 'build',
|
|
68
|
+
pendingPosture: null,
|
|
69
|
+
governance: null,
|
|
65
70
|
team: null,
|
|
66
71
|
todos: null,
|
|
67
72
|
retry: null,
|
|
@@ -479,7 +484,10 @@ export function viewReducer(state, action) {
|
|
|
479
484
|
switch (action.type) {
|
|
480
485
|
case 'submit': {
|
|
481
486
|
const { id, seq } = nextId(state);
|
|
482
|
-
const entry = {
|
|
487
|
+
const entry = {
|
|
488
|
+
id, kind: 'user', text: action.text,
|
|
489
|
+
...(action.invocation ? { invocation: action.invocation } : {}),
|
|
490
|
+
};
|
|
483
491
|
return {
|
|
484
492
|
...state,
|
|
485
493
|
seq,
|
|
@@ -502,7 +510,10 @@ export function viewReducer(state, action) {
|
|
|
502
510
|
if (state.seenSteeringIds.has(action.queueId))
|
|
503
511
|
return state;
|
|
504
512
|
const { id, seq } = nextId(state);
|
|
505
|
-
const entry = {
|
|
513
|
+
const entry = {
|
|
514
|
+
id, kind: 'queued', queueId: action.queueId, text: action.text,
|
|
515
|
+
...(action.invocation ? { invocation: action.invocation } : {}),
|
|
516
|
+
};
|
|
506
517
|
// NOTHING ELSE RESETS. This is not a new turn -- `turnProduced`,
|
|
507
518
|
// `errorNoticed` and `aborted` describe the run that is still in
|
|
508
519
|
// flight, and clearing them here would let the next `runEnd` failure
|
|
@@ -510,7 +521,10 @@ export function viewReducer(state, action) {
|
|
|
510
521
|
return {
|
|
511
522
|
...state, seq, ...appendEntry(state, state.entries, entry),
|
|
512
523
|
seenSteeringIds: new Set([...state.seenSteeringIds, action.queueId]),
|
|
513
|
-
pendingSteering: [...state.pendingSteering, {
|
|
524
|
+
pendingSteering: [...state.pendingSteering, {
|
|
525
|
+
queueId: action.queueId, text: action.text,
|
|
526
|
+
...(action.invocation ? { invocation: action.invocation } : {}),
|
|
527
|
+
}],
|
|
514
528
|
};
|
|
515
529
|
}
|
|
516
530
|
case 'steeringAccepted': {
|
|
@@ -904,6 +918,9 @@ export function viewReducer(state, action) {
|
|
|
904
918
|
// those three.
|
|
905
919
|
status: 'idle',
|
|
906
920
|
team: null,
|
|
921
|
+
// The live run snapshot goes with the conversation it was shown in (the run itself
|
|
922
|
+
// survives on disk and announces itself again on its next event).
|
|
923
|
+
governance: null,
|
|
907
924
|
fastEntryId: undefined,
|
|
908
925
|
turnProduced: false,
|
|
909
926
|
errorNoticed: false,
|
|
@@ -931,7 +948,24 @@ export function viewReducer(state, action) {
|
|
|
931
948
|
// `controller.setAgentMode()` reported it ADOPTED, so this reducer has no
|
|
932
949
|
// deferral logic of its own to get out of step with (§3.1 / R-P7).
|
|
933
950
|
case 'setAgentMode':
|
|
934
|
-
return {
|
|
951
|
+
return {
|
|
952
|
+
...state,
|
|
953
|
+
agentMode: action.mode,
|
|
954
|
+
pendingAgentMode: action.pending,
|
|
955
|
+
...adoptPosture(state.posture, action),
|
|
956
|
+
};
|
|
957
|
+
// --- Governance (governance-mode 14.4) -------------------------------------
|
|
958
|
+
case 'govSnapshot': {
|
|
959
|
+
const governance = foldGovernanceSnapshot(state.governance, action.snapshot);
|
|
960
|
+
return governance === state.governance ? state : { ...state, governance };
|
|
961
|
+
}
|
|
962
|
+
case 'govEnd':
|
|
963
|
+
return state.governance === null ? state : { ...state, governance: null };
|
|
964
|
+
case 'governanceCard': {
|
|
965
|
+
const { id, seq } = nextId(state);
|
|
966
|
+
const entry = { id, kind: 'governance', at: action.at ?? Date.now(), card: action.card };
|
|
967
|
+
return { ...state, seq, ...appendEntry(state, state.entries, entry) };
|
|
968
|
+
}
|
|
935
969
|
case 'toggleThinking':
|
|
936
970
|
return { ...state, thinkingVisible: !state.thinkingVisible };
|
|
937
971
|
case 'pushToast': {
|
|
@@ -976,19 +1010,26 @@ export function viewReducer(state, action) {
|
|
|
976
1010
|
aborted: false,
|
|
977
1011
|
active: true,
|
|
978
1012
|
};
|
|
1013
|
+
const team = {
|
|
1014
|
+
dispatchId: action.dispatchId,
|
|
1015
|
+
active: true,
|
|
1016
|
+
runs,
|
|
1017
|
+
requested: action.requested,
|
|
1018
|
+
startedAt: Date.now(),
|
|
1019
|
+
messageCount: 0,
|
|
1020
|
+
};
|
|
1021
|
+
// A GOVERNED DISPATCH LEAVES NO TRANSCRIPT CARD (RV-3): a run is 10-20 dispatches,
|
|
1022
|
+
// and a `TeamCard` for each would bury the conversation. The live snapshot is still
|
|
1023
|
+
// written - the legion panel and `/agents` read it - and with no `teamEntryId`,
|
|
1024
|
+
// `teamUpdate` / `teamEnd` already pass `entries` through untouched.
|
|
1025
|
+
if (isGovernedDispatch(action.specs))
|
|
1026
|
+
return { ...state, team };
|
|
979
1027
|
return {
|
|
980
1028
|
...state,
|
|
981
1029
|
seq,
|
|
982
1030
|
...appendEntry(state, state.entries, entry),
|
|
983
1031
|
teamEntryId: id,
|
|
984
|
-
team
|
|
985
|
-
dispatchId: action.dispatchId,
|
|
986
|
-
active: true,
|
|
987
|
-
runs,
|
|
988
|
-
requested: action.requested,
|
|
989
|
-
startedAt: Date.now(),
|
|
990
|
-
messageCount: 0,
|
|
991
|
-
},
|
|
1032
|
+
team,
|
|
992
1033
|
};
|
|
993
1034
|
}
|
|
994
1035
|
case 'teamUpdate': {
|
|
@@ -1476,6 +1517,10 @@ export function viewReducer(state, action) {
|
|
|
1476
1517
|
// restored entries BEFORE this branch runs.
|
|
1477
1518
|
taskSummary: null,
|
|
1478
1519
|
taskSummaryPending: false,
|
|
1520
|
+
// Same rule for a live governed run: `/resume` adopts another conversation, and
|
|
1521
|
+
// a snapshot of the old one's run must not be drawn over it. Settlement cards
|
|
1522
|
+
// arrive with the restored `entries`.
|
|
1523
|
+
governance: null,
|
|
1479
1524
|
};
|
|
1480
1525
|
}
|
|
1481
1526
|
// --- Background services (§3.10 / D-11) -----------------------------
|
|
@@ -159,6 +159,25 @@ export interface SystemPromptParams {
|
|
|
159
159
|
* own appended instructions still come last and still win.
|
|
160
160
|
*/
|
|
161
161
|
structuredResultBlock?: string;
|
|
162
|
+
/**
|
|
163
|
+
* The rendered `<governance_mode>` block (the Orchestrator's rules), or `''`
|
|
164
|
+
* (governance-mode 6.1). Spliced AFTER the plan block and BEFORE `teamBlock`, and
|
|
165
|
+
* conditional like every block above: governance off produces the pre-feature prompt
|
|
166
|
+
* BYTE FOR BYTE. The caller omits `teamBlock` / `forcedTeamBlock` in GOVERN with gate
|
|
167
|
+
* mode `build`, because `task` is refused there and advertising it would describe a
|
|
168
|
+
* refused capability.
|
|
169
|
+
*/
|
|
170
|
+
governBlock?: string;
|
|
171
|
+
/**
|
|
172
|
+
* The rendered `<governance_role>` block of a governed CHILD, or `''`. Spliced after
|
|
173
|
+
* `subagentBlock`. Never set together with `governBlock`.
|
|
174
|
+
*/
|
|
175
|
+
governanceRoleBlock?: string;
|
|
176
|
+
/**
|
|
177
|
+
* PLAN+GOVERN's interview addendum (governance-mode 6.3), placed inside `<plan_mode>`.
|
|
178
|
+
* Only read when `agentMode` is `'plan'`; absent leaves the plan block unchanged.
|
|
179
|
+
*/
|
|
180
|
+
governAddendum?: string;
|
|
162
181
|
}
|
|
163
182
|
/** Describe the active shell so the model does not emit incompatible syntax. */
|
|
164
183
|
export declare function describeShell(): {
|
|
@@ -33,7 +33,10 @@ export function buildSystemPrompt(params) {
|
|
|
33
33
|
const skillsBlock = params.skillsBlock ?? '';
|
|
34
34
|
const hasSkills = skillsBlock.length > 0;
|
|
35
35
|
const planBlock = params.agentMode === 'plan'
|
|
36
|
-
? buildPlanModeBlock({
|
|
36
|
+
? buildPlanModeBlock({
|
|
37
|
+
interactive: params.planInteractive !== false,
|
|
38
|
+
...(params.governAddendum ? { governAddendum: params.governAddendum } : {}),
|
|
39
|
+
})
|
|
37
40
|
: '';
|
|
38
41
|
// `''` when the caller has no candidates or the feature is off — which is what
|
|
39
42
|
// keeps this block's absence byte-identical to the pre-feature prompt (I-T1).
|
|
@@ -41,6 +44,8 @@ export function buildSystemPrompt(params) {
|
|
|
41
44
|
const teamBlock = params.teamBlock ?? '';
|
|
42
45
|
const forcedTeamBlock = params.forcedTeamBlock ?? '';
|
|
43
46
|
const subagentBlock = params.subagentBlock ?? '';
|
|
47
|
+
const governBlock = params.governBlock ?? '';
|
|
48
|
+
const governanceRoleBlock = params.governanceRoleBlock ?? '';
|
|
44
49
|
const todoBlock = params.todoBlock ?? '';
|
|
45
50
|
const fastBlock = params.fastBlock ?? '';
|
|
46
51
|
const backgroundBlock = params.backgroundBlock ?? '';
|
|
@@ -66,12 +71,15 @@ export function buildSystemPrompt(params) {
|
|
|
66
71
|
// (whose step 1 defers to it). Conditional like every other optional block.
|
|
67
72
|
...(skillTriageBlock ? ['', skillTriageBlock] : []),
|
|
68
73
|
...(planBlock ? ['', planBlock] : []),
|
|
74
|
+
// AFTER the plan block it extends and BEFORE `<team_mode>` (governance-mode 6.1).
|
|
75
|
+
...(governBlock ? ['', governBlock] : []),
|
|
69
76
|
...(teamBlock ? ['', teamBlock] : []),
|
|
70
77
|
// IMMEDIATELY AFTER `<team_mode>`: "can" then "must". BEFORE the subagent
|
|
71
78
|
// block, because a child reading an order to dispatch would be ordered to use
|
|
72
79
|
// a tool it does not have (§3.6).
|
|
73
80
|
...(forcedTeamBlock ? ['', forcedTeamBlock] : []),
|
|
74
81
|
...(subagentBlock ? ['', subagentBlock] : []),
|
|
82
|
+
...(governanceRoleBlock ? ['', governanceRoleBlock] : []),
|
|
75
83
|
...(todoBlock ? ['', todoBlock] : []),
|
|
76
84
|
...(fastBlock ? ['', fastBlock] : []),
|
|
77
85
|
...(backgroundBlock ? ['', backgroundBlock] : []),
|
package/dist/cli.js
CHANGED
|
@@ -25,7 +25,8 @@ import { formatMigrationNotice, migrateLegacyState } from './config/migrate-lega
|
|
|
25
25
|
import { formatHomeMigrationNotice, migrateToHome } from './config/migrate-home.js';
|
|
26
26
|
import { migrateStateOutOfConfig } from './config/migrate-state-out-of-config.js';
|
|
27
27
|
import { runHistoryCommand } from './config/history-commands.js';
|
|
28
|
-
import {
|
|
28
|
+
import { checkGovernanceCommandLine } from './config/governance-launch.js';
|
|
29
|
+
import { COMPACTION_CONFIG_SET_KEYS, FAST_CONFIG_SET_KEYS, LOG_CONFIG_SET_KEYS, RETRY_CONFIG_SET_KEYS, TEAM_CONFIG_SET_KEYS, GOVERNANCE_CONFIG_SET_KEYS, JOBS_CONFIG_SET_KEYS, TASK_SUMMARY_CONFIG_SET_KEYS, UPDATE_CONFIG_SET_KEYS, applyCompactionConfigSet, applyFastConfigSet, applyLogConfigSet, applyRetryConfigSet, applyTeamConfigSet, applyGovernanceConfigSet, applyJobsConfigSet, applyTaskSummaryConfigSet, applyUpdateConfigSet, runConfigEdit, runConfigGet, runConfigHome, runConfigList, warnIfRedactionDisabled, } from './config/cli-commands.js';
|
|
29
30
|
import { attachAgentEvents, attachTeamEvents, installLogging, setScreenRestore, setSignalTerminator, } from './logging/install.js';
|
|
30
31
|
import { getLogger } from './logging/logger.js';
|
|
31
32
|
import { runLogsCommand } from './logging/cli-commands.js';
|
|
@@ -230,6 +231,12 @@ function toFlags(opts) {
|
|
|
230
231
|
// reports nothing, does nothing, and leaves compaction armed.
|
|
231
232
|
compaction: opts.compaction,
|
|
232
233
|
compactionThreshold: opts.compactionThreshold,
|
|
234
|
+
// Site three of three for the governance flags. `--no-governance` is declared alone, so
|
|
235
|
+
// commander defaults `opts.governance` to `true` when it is absent; only an explicit
|
|
236
|
+
// `false` is forwarded, which keeps silence from reading as an override.
|
|
237
|
+
govern: opts.govern,
|
|
238
|
+
planGovern: opts.planGovern,
|
|
239
|
+
governance: opts.governance === false ? false : undefined,
|
|
233
240
|
// Site three of three for `--resume` / `--save` -- ELEVEN features, one trap
|
|
234
241
|
// (`mouse` P1-2, `team` P1-4, `todo` C-9, render L4, retry, fast, update,
|
|
235
242
|
// compaction, now session identity). A flag needs the `.option()`
|
|
@@ -1599,6 +1606,11 @@ const CONFIG_SET_KEYS = new Set([
|
|
|
1599
1606
|
// membership set accepts a write that never happens - the two halves the static
|
|
1600
1607
|
// guard in `config.test.ts` exists to pair up.
|
|
1601
1608
|
...TASK_SUMMARY_CONFIG_SET_KEYS,
|
|
1609
|
+
// `governance.*` keys are handled by `applyGovernanceConfigSet`, same reasoning again
|
|
1610
|
+
// (governance-mode 11.1): without this line they fall through to `Unknown config key`,
|
|
1611
|
+
// and without the matching case in `runConfigSet` the membership set accepts a write
|
|
1612
|
+
// that never happens.
|
|
1613
|
+
...GOVERNANCE_CONFIG_SET_KEYS,
|
|
1602
1614
|
]);
|
|
1603
1615
|
/**
|
|
1604
1616
|
* `aragon config set maxTokens <n|auto|default>`.
|
|
@@ -1771,6 +1783,15 @@ function runConfigSetValue(key, value) {
|
|
|
1771
1783
|
process.stdout.write(`Set ${key} = ${String(merged.taskSummary[field])}\n`);
|
|
1772
1784
|
return;
|
|
1773
1785
|
}
|
|
1786
|
+
const governancePatch = applyGovernanceConfigSet(key, value);
|
|
1787
|
+
if (governancePatch) {
|
|
1788
|
+
// Echoed from the STORED value, like every section above: `config set
|
|
1789
|
+
// governance.maxRework 9` prints 5, which is what the read path will report.
|
|
1790
|
+
const merged = updatePersistedConfig(governancePatch);
|
|
1791
|
+
const field = key.slice('governance.'.length);
|
|
1792
|
+
process.stdout.write(`Set ${key} = ${String(merged.governance[field])}\n`);
|
|
1793
|
+
return;
|
|
1794
|
+
}
|
|
1774
1795
|
const patch = {};
|
|
1775
1796
|
switch (key) {
|
|
1776
1797
|
case 'provider':
|
|
@@ -2188,6 +2209,13 @@ function buildProgram() {
|
|
|
2188
2209
|
.option('--compaction', 'Compact the conversation when the context window fills (the default)')
|
|
2189
2210
|
.option('--no-compaction', 'Never compact; a full context window ends the run as before')
|
|
2190
2211
|
.option('--compaction-threshold <n>', 'Occupancy that triggers compaction for this run: 0.9 or 90% (0.5-0.95)')
|
|
2212
|
+
// Governance mode (governance-mode 11.2). `--govern` and `--plan-govern` only pick the
|
|
2213
|
+
// starting posture, so neither is a persisted pair. `--no-governance` is deliberately
|
|
2214
|
+
// negative-only: it can only ever switch the feature off, and `toFlags` forwards it only
|
|
2215
|
+
// when explicitly given. The rules between them live in `validateGovernanceLaunch`.
|
|
2216
|
+
.option('--govern', 'Start in GOVERN posture (a governed team of dev / review / test roles)')
|
|
2217
|
+
.option('--plan-govern', 'Start in PLAN+GOVERN posture (clarify and plan first, then govern)')
|
|
2218
|
+
.option('--no-governance', 'Disable governance mode for this launch (not persisted)')
|
|
2191
2219
|
.option('--no-skills', 'Disable the skill system entirely (no catalog, no skill tools)')
|
|
2192
2220
|
.option('--skill <name>', 'Force-load a skill at Level 2 for this run (repeatable)', (value, previous = []) => [...previous, value])
|
|
2193
2221
|
.option('--skills-yes', 'Approve skill installs for this run (CI / headless)')
|
|
@@ -2251,6 +2279,22 @@ function buildProgram() {
|
|
|
2251
2279
|
}
|
|
2252
2280
|
void runInteractive(flags, { initialPrompt: prompt });
|
|
2253
2281
|
});
|
|
2282
|
+
// The governance flag rules (governance-mode 11.2), checked for EVERY command because the
|
|
2283
|
+
// flags are root-level options and `exec` reads them through `toFlags(program.opts())`.
|
|
2284
|
+
// A `preAction` hook runs before the root action as well as before each subcommand, so one
|
|
2285
|
+
// place covers `aragon -p`, piped input and `aragon exec`.
|
|
2286
|
+
program.hook('preAction', (root, action) => {
|
|
2287
|
+
const check = checkGovernanceCommandLine(root.opts(), {
|
|
2288
|
+
commandName: action.name(),
|
|
2289
|
+
isRootAction: action === root,
|
|
2290
|
+
stdinIsTty: !!process.stdin.isTTY,
|
|
2291
|
+
stdoutIsTty: !!process.stdout.isTTY,
|
|
2292
|
+
});
|
|
2293
|
+
if (check.ok)
|
|
2294
|
+
return;
|
|
2295
|
+
process.stderr.write(`${check.message}\n`);
|
|
2296
|
+
process.exit(2);
|
|
2297
|
+
});
|
|
2254
2298
|
// aragon config [set <key> <value> | path]
|
|
2255
2299
|
const configCmd = program
|
|
2256
2300
|
.command('config')
|