@pellux/goodvibes-tui 2.0.15 → 2.0.17
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
CHANGED
|
@@ -4,6 +4,30 @@ All notable changes to GoodVibes TUI.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [2.0.17] - 2026-08-21
|
|
8
|
+
|
|
9
|
+
### Changes
|
|
10
|
+
|
|
11
|
+
- **The bundled daemon is current again.** The daemon dependency moves to
|
|
12
|
+
1.28.22 (sdk 2.0.20 inside), so an install of this TUI no longer nests a
|
|
13
|
+
daemon built against the previous platform runtime. 2.0.16 shipped hours
|
|
14
|
+
earlier with the daemon still at 1.28.21; this release exists to correct
|
|
15
|
+
that.
|
|
16
|
+
|
|
17
|
+
## [2.0.16] - 2026-08-21
|
|
18
|
+
|
|
19
|
+
### Changes
|
|
20
|
+
|
|
21
|
+
- **The Planning panel drives the real planning command.** The modal invoked
|
|
22
|
+
`/project-plan`, a command that does not exist; it now runs the registered
|
|
23
|
+
planning command, and a guard test resolves every command the panels emit
|
|
24
|
+
against the live command registry so a phantom fails the build.
|
|
25
|
+
- Platform runtime 2.0.20: the pin rides the payments boot-recovery sdk
|
|
26
|
+
cycle. No TUI code change was needed for it; the reusable-workflow and
|
|
27
|
+
toolchain pins repoint to the 2.0.20 release commit.
|
|
28
|
+
- Docs verified against the code: install steps match a tested clean
|
|
29
|
+
install, and term enumerations became code-verified tables.
|
|
30
|
+
|
|
7
31
|
## [2.0.15] - 2026-08-21
|
|
8
32
|
|
|
9
33
|
### Changes
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
GoodVibes is a terminal console for coding and operations work with an AI model. You run `goodvibes` in a project directory and get a full-screen terminal app where you talk to a model that can read and edit your files, run shell commands, search the web, and hand work off to background agents, asking your permission before anything that writes or executes.
|
|
8
8
|
|
|
9
|
-
It talks to many model providers (OpenAI, Anthropic, Gemini, Bedrock, Copilot, OpenRouter and other OpenAI-compatible gateways, plus local servers like Ollama and LM Studio that
|
|
9
|
+
It talks to many model providers (OpenAI, Anthropic, Gemini, Bedrock, Copilot, OpenRouter and other OpenAI-compatible gateways, plus local servers like Ollama and LM Studio that `/scan` finds on your machine and LAN), keeps its settings, sessions, and secrets on your own machine, and shows you the token count and running cost of every turn. Alongside the conversation, panels turn background work into live control rooms: running agents, git state, diffs, tokens, cost.
|
|
10
10
|
|
|
11
11
|
<img src="docs/assets/splash.png" alt="GoodVibes starting up in a terminal: a glitch-art GOODVIBES wordmark in cyan-to-magenta gradient, the version and tagline beneath it, the active model and tool count, the working directory, a line offering to resume the last session, and a hint line reading Ctrl+P panels / ? help / F2 fleet. A status footer shows mode, token usage, context usage, and the daemon and web listener addresses." width="900">
|
|
12
12
|
|
|
@@ -25,11 +25,11 @@ Or install from the npm registry with [Bun](https://bun.sh):
|
|
|
25
25
|
|
|
26
26
|
```sh
|
|
27
27
|
bun add -g @pellux/goodvibes-tui
|
|
28
|
-
bun pm trust -g @pellux/goodvibes-tui goodvibes-daemon
|
|
28
|
+
bun pm trust -g @pellux/goodvibes-tui @pellux/goodvibes-daemon
|
|
29
29
|
goodvibes
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
Bun blocks lifecycle scripts for untrusted global packages, so the second line lets both postinstalls run: `@pellux/goodvibes-tui`'s own, which places the TUI binary, and
|
|
32
|
+
Bun blocks lifecycle scripts for untrusted global packages, so the second line lets both postinstalls run: `@pellux/goodvibes-tui`'s own, which places the TUI binary, and `@pellux/goodvibes-daemon`'s, which places the daemon binary (both names must be the full scoped names). `@pellux/goodvibes-daemon` is a real dependency of this package, so one install brings both commands. No other dependency needs trusting for the install to work. If you skip that step, the `goodvibes` launcher still self-heals on first run by fetching and checksum-verifying its own binary. `npm install -g @pellux/goodvibes-tui` also works when `bun` is already on `PATH`.
|
|
33
33
|
|
|
34
34
|
Then point it at a model. An environment variable is the fastest path:
|
|
35
35
|
|
|
@@ -57,7 +57,7 @@ The footer keeps an honest running total: fresh input tokens separated from cach
|
|
|
57
57
|
|
|
58
58
|
<img src="docs/assets/workspace-trust.png" alt="A modal titled New workspace, choose a trust level, offering two options: Trust this workspace, full capability, all tools may run; and Keep restricted, read-only, explore safely, writes and commands are denied until trusted. Navigation hints read Up/Down Navigate, Enter Choose, Esc Close." width="820">
|
|
59
59
|
|
|
60
|
-
The first time you open a directory, GoodVibes asks how much it is allowed to do there. Restricted is read-only
|
|
60
|
+
The first time you open a directory, GoodVibes asks how much it is allowed to do there. Restricted is read-only. The model can look around, but writes and commands are refused until you trust the workspace.
|
|
61
61
|
|
|
62
62
|
<img src="docs/assets/permission-prompt.png" alt="An execution approval prompt. A header reads EXECUTE, Shell Execution Approval, one more waiting. Fields list the requesting session, the tool exec, the full command mkdir -p build, the working directory, a Risk line reading HIGH write in red, the surface and radius, a summary, the decision class, the effects: process execution, filesystem mutation, possible network access, a reviewer checklist, and the raw tool arguments. Below, four numbered remember options scope an approval to this exact command, to every mkdir command, to every exec call in this project, or to the rest of the session in memory only. The action line reads: Y Allow once, 1-4 Allow and remember, N Deny, or type a reason to deny." width="900">
|
|
63
63
|
|
|
@@ -70,7 +70,7 @@ Four other modes are available when prompting is not what you want:
|
|
|
70
70
|
- `allow-all` approves everything
|
|
71
71
|
- `custom` takes per-tool `allow` / `prompt` / `deny` overrides
|
|
72
72
|
|
|
73
|
-
`Shift+Tab` cycles the four session postures: normal, accept-edits, plan, and auto. `/plan` toggles plan mode directly.
|
|
73
|
+
`Shift+Tab` cycles the four session postures: normal (the `prompt` mode), accept-edits, plan, and auto (the `allow-all` mode). `/plan` toggles plan mode directly.
|
|
74
74
|
|
|
75
75
|
### Models and providers
|
|
76
76
|
|
|
@@ -109,7 +109,7 @@ Press `?` for a searchable, categorized list of every slash command with its arg
|
|
|
109
109
|
| `Esc` | Leave the current mode: search, command, or modal |
|
|
110
110
|
| `Ctrl+C` | Clear input, cancel a running turn. Press twice to quit |
|
|
111
111
|
|
|
112
|
-
Most bindings are customizable in `~/.goodvibes/tui/keybindings.json`, and `/keybindings` shows what is currently bound. Five keys are fixed and stay out of that file: `F2
|
|
112
|
+
Most bindings are customizable in `~/.goodvibes/tui/keybindings.json`, and `/keybindings` shows what is currently bound. Five keys are fixed and stay out of that file: `F2` (Fleet), `Shift+Tab` (permission-mode cycle), `Esc` (leave the current mode), `?` (help), and `@` (file picker). The full reference is in [docs/tools-and-commands.md](docs/tools-and-commands.md).
|
|
113
113
|
|
|
114
114
|
---
|
|
115
115
|
|
|
@@ -165,18 +165,27 @@ Edit them live with `/settings` or the fullscreen `/config` workspace rather tha
|
|
|
165
165
|
| `display.showThinking` | `false` | Show model thinking traces |
|
|
166
166
|
| `behavior.autoCompactThreshold` | `80` | Context percentage before auto-compact runs |
|
|
167
167
|
| `helper.enabled` | `false` | Route grunt work to a cheaper helper model |
|
|
168
|
-
| `daemon.enabled` | `true` |
|
|
168
|
+
| `daemon.enabled` | `true` | Adopt a local session daemon on loopback; off makes no adoption attempt |
|
|
169
169
|
|
|
170
170
|
The wider key table, the permission modes, and the hand-edited TUI namespaces (checkpoint root guard, scriptable statusline, session behavior, launch-time self-update) are in [docs/configuration.md](docs/configuration.md).
|
|
171
171
|
|
|
172
172
|
### Where things are stored
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
174
|
+
Everything lives in plain files, split between the per-user `~/.goodvibes/tui/` tree and the project's own `.goodvibes/` directory:
|
|
175
|
+
|
|
176
|
+
| Path | What lives there |
|
|
177
|
+
| --- | --- |
|
|
178
|
+
| `~/.goodvibes/tui/settings.json` | Global settings |
|
|
179
|
+
| `.goodvibes/tui/settings.json` | Project settings overriding the global layer |
|
|
180
|
+
| `~/.goodvibes/tui/secrets.enc` or `.goodvibes/tui/secrets.enc` | Encrypted secrets, global or per project |
|
|
181
|
+
| `~/.goodvibes/tui/providers/*.json` | Custom provider definitions, hot-reloaded |
|
|
182
|
+
| `~/.goodvibes/tui/keybindings.json` | Keybinding overrides |
|
|
183
|
+
| `.goodvibes/tui/services.json` | The service registry |
|
|
184
|
+
| `.goodvibes/tui/automation-*.json` | Scheduled jobs and the rest of the automation store |
|
|
185
|
+
| `.goodvibes/agents/*.md` | Agent archetypes |
|
|
186
|
+
| `.goodvibes/mcp.json` | MCP server definitions |
|
|
187
|
+
| `.goodvibes/hooks.json` | Hooks and hook chains |
|
|
188
|
+
| `.goodvibes/` (rest) | Sessions, artifacts, and other project runtime state in the working directory |
|
|
180
189
|
|
|
181
190
|
---
|
|
182
191
|
|
|
@@ -204,10 +213,10 @@ bun run dev
|
|
|
204
213
|
| Command | Does |
|
|
205
214
|
| --- | --- |
|
|
206
215
|
| `bun run dev` | Run the TUI from source |
|
|
207
|
-
| `bun test` | Run the suite through the parallel per-file runner |
|
|
216
|
+
| `bun run test` | Run the suite through the parallel per-file runner |
|
|
208
217
|
| `bun run build` | Compile `src/main.ts` into `dist/goodvibes` |
|
|
209
218
|
|
|
210
|
-
The compiled binary is the TUI entrypoint.
|
|
219
|
+
The compiled binary is the TUI entrypoint. With `daemon.enabled` on (the default) it adopts a running standalone GoodVibes daemon over loopback, and when a daemon is installed as a service but stopped, it starts that service once and waits for it to come online. It never embeds or constructs a daemon of its own. The control plane, HTTP listener (`danger.httpListener`), and web surface are all hosted by the daemon; the TUI configures them and reports their bindings.
|
|
211
220
|
|
|
212
221
|
Tests live under `src/test/`, mirroring the source tree, and cover contract, security, release-gate, runtime, renderer, panel, integration, and anti-regression cases. Several gates run alongside them in CI: byte-exact golden renderer frames, performance budgets for startup and frame composition and line production (`scripts/perf-baseline.json`), and architecture rules for import cycles, layer boundaries, source-file size, and unused renderer exports (`scripts/check-architecture.ts`).
|
|
213
222
|
|
|
@@ -237,10 +246,10 @@ src/
|
|
|
237
246
|
├── config/ settings layering, surface roots, secrets, credential availability
|
|
238
247
|
├── permissions/ approval cards, hunk selection, sandbox exec gate
|
|
239
248
|
├── cli/ flag parsing, management verbs, doctor, launch-time self-update
|
|
240
|
-
├── tools/, mcp
|
|
241
|
-
├── audio/, export/
|
|
242
|
-
├── verification/,
|
|
243
|
-
├── utils/,
|
|
249
|
+
├── tools/, mcp/ TUI-local tool guards, MCP runtime reload
|
|
250
|
+
├── audio/, export/ voice capture, wake word, playback and speech routing; gist upload
|
|
251
|
+
├── verification/, widget/ live verifier and its ledger, the terminal widget module
|
|
252
|
+
├── utils/, scripts/ formatting and clipboard helpers, message processing script
|
|
244
253
|
└── test/ the suite, mirroring the tree above
|
|
245
254
|
```
|
|
246
255
|
|
package/docs/README.md
CHANGED
|
@@ -8,13 +8,13 @@ This directory contains the current product documentation for `goodvibes-tui`.
|
|
|
8
8
|
Installation, first-run setup, provider configuration, common paths, and basic run/build flows.
|
|
9
9
|
|
|
10
10
|
- [Configuration reference](configuration.md)
|
|
11
|
-
The layered settings model,
|
|
11
|
+
The layered settings model, a curated key-settings table, permission modes and the policy/trust system, plus the TUI-owned namespaces you add by hand to settings.json, covering the checkpoint root guard, the scriptable statusline, session behavior, notification alert classes, and launch-time self-update.
|
|
12
12
|
|
|
13
13
|
- [Deployment and services](deployment-and-services.md)
|
|
14
14
|
TUI-only mode, compiled binary behavior, adopting or autostarting the daemon, the in-process HTTP listener, inbound TLS, outbound trust configuration, control-plane entrypoints, the service registry and secret references, profiles and setup transfer, and integration helpers.
|
|
15
15
|
|
|
16
16
|
- [Remote access: a home server setup](remote-access.md)
|
|
17
|
-
Step-by-step continuity setup
|
|
17
|
+
Step-by-step continuity setup covering the daemon on an always-on box, webui from any browser, TUI over SSH, Tailscale for reachability and TLS, and validation with `goodvibes doctor`.
|
|
18
18
|
|
|
19
19
|
- [Providers and routing](providers-and-routing.md)
|
|
20
20
|
Native providers, compatible/gateway providers, local discovery, synthetic failover, search providers, voice providers, and media providers.
|
|
@@ -38,13 +38,13 @@ This directory contains the current product documentation for `goodvibes-tui`.
|
|
|
38
38
|
Omnichannel surfaces, reply routing, remote peers, node-host contracts, and the daemon/control-plane HTTP + streaming surfaces.
|
|
39
39
|
|
|
40
40
|
- [Session durability](session-durability.md)
|
|
41
|
-
Two-layer durability
|
|
41
|
+
Two-layer durability, combining post-turn snapshots plus periodic recovery files with the fsync-per-record transcript journal replayed at every resume seam.
|
|
42
42
|
|
|
43
43
|
- [Share command](share-command.md)
|
|
44
44
|
`/share` session export to HTML/JSON/Markdown with redaction, upload, clipboard, and open options.
|
|
45
45
|
|
|
46
46
|
- [CLI flags](cli-flags.md)
|
|
47
|
-
Global flags reference
|
|
47
|
+
Global flags reference covering session lifecycle (`--continue`, `--resume`, `--fork`), the `-y`/`--non-interactive` commit gate for plugin bundle installs, output format consolidation, the `--host` alias, and all other startup and command-specific flags.
|
|
48
48
|
|
|
49
49
|
- [Commands reference](commands-reference.md)
|
|
50
50
|
The generated, categorized list of every slash command, its arguments, and its description. It is the same list `?` renders in the product.
|
|
@@ -74,4 +74,4 @@ This directory contains the current product documentation for `goodvibes-tui`.
|
|
|
74
74
|
Checked-in operator and peer contract manifests plus canonical knowledge GraphQL and SQL artifacts for release-gate and SDK extraction work.
|
|
75
75
|
|
|
76
76
|
- [GitHub Action](github-action.md)
|
|
77
|
-
The `run-goodvibes` composite action
|
|
77
|
+
The `run-goodvibes` composite action, which installs a pinned, checksum-verified release in CI and runs a non-interactive command or prompt against a workspace.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-tui",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.17",
|
|
4
4
|
"description": "Terminal-native GoodVibes client for coding, operations, knowledge and channel workflows; a pure client of the GoodVibes daemon.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/main.ts",
|
|
@@ -96,11 +96,11 @@
|
|
|
96
96
|
"@anthropic-ai/bedrock-sdk": "^0.29.1",
|
|
97
97
|
"@anthropic-ai/sdk": "^0.92.0",
|
|
98
98
|
"@ast-grep/napi": "^0.42.0",
|
|
99
|
-
"@pellux/goodvibes-sdk": "2.0.
|
|
100
|
-
"@pellux/goodvibes-terminal-shell": "2.0.
|
|
99
|
+
"@pellux/goodvibes-sdk": "2.0.20",
|
|
100
|
+
"@pellux/goodvibes-terminal-shell": "2.0.20",
|
|
101
101
|
"bash-language-server": "^5.6.0",
|
|
102
102
|
"fuse.js": "^7.1.0",
|
|
103
|
-
"@pellux/goodvibes-daemon": "1.28.
|
|
103
|
+
"@pellux/goodvibes-daemon": "1.28.22",
|
|
104
104
|
"graphql": "^16.13.2",
|
|
105
105
|
"jszip": "^3.10.1",
|
|
106
106
|
"node-edge-tts": "^1.2.10",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
"zustand": "^5.0.12"
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
|
-
"@pellux/goodvibes-toolchain": "2.0.
|
|
124
|
+
"@pellux/goodvibes-toolchain": "2.0.20",
|
|
125
125
|
"@types/bun": "^1.3.10",
|
|
126
126
|
"typescript": "^5.9.3"
|
|
127
127
|
},
|
|
@@ -9,7 +9,7 @@ import { openModalCommand, requirePlanManager, requireSessionLineageTracker } fr
|
|
|
9
9
|
import { togglePlanMode, permissionModeLabel, type PermissionModeValue } from '../../core/permission-mode.ts';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* Single-token verbs that look like a `/plan` subcommand but are not real ones.
|
|
12
|
+
* Single-token verbs that look like a `/project-plan` subcommand but are not real ones.
|
|
13
13
|
* A lone one of these is refused rather than seeded as a goal, so a stray verb
|
|
14
14
|
* can never overwrite the project goal with itself.
|
|
15
15
|
*
|
|
@@ -165,7 +165,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
165
165
|
if (args[0] === 'show') {
|
|
166
166
|
const id = args[1];
|
|
167
167
|
if (!id) {
|
|
168
|
-
ctx.print('Usage: /plan show <plan-id>');
|
|
168
|
+
ctx.print('Usage: /project-plan show <plan-id>');
|
|
169
169
|
return;
|
|
170
170
|
}
|
|
171
171
|
const plans = planManager.list();
|
|
@@ -178,16 +178,16 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
178
178
|
return;
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
// /plan dismiss, archive the current plan. Dismisses the active
|
|
181
|
+
// /project-plan dismiss, archive the current plan. Dismisses the active
|
|
182
182
|
// execution plan (ExecutionPlanManager.dismiss, honest per-state) AND
|
|
183
183
|
// deactivates the project-planning interview state shown in the modal so a
|
|
184
|
-
// later /plan <goal> starts fresh. Mid-execution is refused outright.
|
|
184
|
+
// later /project-plan <goal> starts fresh. Mid-execution is refused outright.
|
|
185
185
|
if (args[0] === 'dismiss') {
|
|
186
186
|
const dismissal = planManager.dismiss(ctx.session.runtime.sessionId);
|
|
187
187
|
if (dismissal.outcome === 'requires-cancel') {
|
|
188
188
|
ctx.print(
|
|
189
189
|
`Plan "${dismissal.blockedBy?.title ?? 'active plan'}" is mid-execution and was not dismissed. ` +
|
|
190
|
-
`Run /workstream cancel to stop it first, then /plan dismiss.`,
|
|
190
|
+
`Run /workstream cancel to stop it first, then /project-plan dismiss.`,
|
|
191
191
|
);
|
|
192
192
|
return;
|
|
193
193
|
}
|
|
@@ -213,7 +213,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
213
213
|
if (dismissal.outcome === 'dismissed') {
|
|
214
214
|
ctx.print(
|
|
215
215
|
`Dismissed plan "${dismissal.plan?.title ?? 'active plan'}" ` +
|
|
216
|
-
`(archived as dismissed; retained in /plan list; /plan <goal> starts fresh).${planningNote}`,
|
|
216
|
+
`(archived as dismissed; retained in /project-plan list; /project-plan <goal> starts fresh).${planningNote}`,
|
|
217
217
|
);
|
|
218
218
|
} else if (planningNote) {
|
|
219
219
|
ctx.print(`No active execution plan to dismiss.${planningNote}`);
|
|
@@ -223,7 +223,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
223
223
|
return;
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
// /plan answer <n|question-id> <text>, record a real answer to an
|
|
226
|
+
// /project-plan answer <n|question-id> <text>, record a real answer to an
|
|
227
227
|
// open planning question (moves open → answered, consumed on next refine).
|
|
228
228
|
if (args[0] === 'answer') {
|
|
229
229
|
if (!projectPlanningService || !projectId) {
|
|
@@ -233,7 +233,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
233
233
|
const ref = args[1];
|
|
234
234
|
const answerText = args.slice(2).join(' ').trim();
|
|
235
235
|
if (!ref || !answerText) {
|
|
236
|
-
ctx.print('Usage: /plan answer <question-number|question-id> <your answer>');
|
|
236
|
+
ctx.print('Usage: /project-plan answer <question-number|question-id> <your answer>');
|
|
237
237
|
return;
|
|
238
238
|
}
|
|
239
239
|
const asNum = Number(ref);
|
|
@@ -243,7 +243,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
243
243
|
const answerResult = await projectPlanningService.answerQuestion({ projectId, ...selector, answer: answerText });
|
|
244
244
|
if (!answerResult.answered) {
|
|
245
245
|
if (answerResult.reason === 'no-state') {
|
|
246
|
-
ctx.print('No project planning state exists yet. Seed it with /plan <goal>.');
|
|
246
|
+
ctx.print('No project planning state exists yet. Seed it with /project-plan <goal>.');
|
|
247
247
|
} else if (answerResult.reason === 'question-not-found') {
|
|
248
248
|
const open = answerResult.openQuestions;
|
|
249
249
|
const listing = open.length > 0
|
|
@@ -251,7 +251,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
251
251
|
: ' (no open questions)';
|
|
252
252
|
ctx.print(`No open question matched "${ref}". Open questions:\n${listing}`);
|
|
253
253
|
} else {
|
|
254
|
-
ctx.print('Usage: /plan answer <question-number|question-id> <your answer>');
|
|
254
|
+
ctx.print('Usage: /project-plan answer <question-number|question-id> <your answer>');
|
|
255
255
|
}
|
|
256
256
|
return;
|
|
257
257
|
}
|
|
@@ -273,8 +273,8 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
273
273
|
// corrupting the goal.
|
|
274
274
|
if (args.length === 1 && PSEUDO_SUBCOMMAND_VERBS.has(args[0].toLowerCase())) {
|
|
275
275
|
ctx.print(
|
|
276
|
-
`Unknown /plan subcommand "${args[0]}": did you mean panel, approve, list, show, or status? ` +
|
|
277
|
-
`To seed a planning goal, use /plan <a real sentence describing the change>.`,
|
|
276
|
+
`Unknown /project-plan subcommand "${args[0]}": did you mean panel, approve, list, show, or status? ` +
|
|
277
|
+
`To seed a planning goal, use /project-plan <a real sentence describing the change>.`,
|
|
278
278
|
);
|
|
279
279
|
return;
|
|
280
280
|
}
|
|
@@ -289,7 +289,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
289
289
|
state: {
|
|
290
290
|
goal: taskDescription,
|
|
291
291
|
knownContext: [
|
|
292
|
-
`Workspace planning was seeded from the TUI /plan command.`,
|
|
292
|
+
`Workspace planning was seeded from the TUI /project-plan command.`,
|
|
293
293
|
],
|
|
294
294
|
metadata: {
|
|
295
295
|
active: true,
|
|
@@ -219,11 +219,11 @@ class PlanningModalSurface implements ConfigModalSurface {
|
|
|
219
219
|
|
|
220
220
|
onAction(id: string, ctx: ConfigModalActionContext): void {
|
|
221
221
|
if (id === 'refresh') { this.refresh(); ctx.setStatus('Reloading project planning state…'); return; }
|
|
222
|
-
if (id === 'approve') { void ctx.executeCommand?.('plan', ['approve']); ctx.setStatus('Dispatched /plan approve.'); return; }
|
|
222
|
+
if (id === 'approve') { void ctx.executeCommand?.('project-plan', ['approve']); ctx.setStatus('Dispatched /project-plan approve.'); return; }
|
|
223
223
|
if (id === 'dismiss') {
|
|
224
224
|
// First-class, confirmed (host two-press) mutating dismiss.
|
|
225
|
-
void ctx.executeCommand?.('plan', ['dismiss']);
|
|
226
|
-
ctx.setStatus('Dispatched /plan dismiss.');
|
|
225
|
+
void ctx.executeCommand?.('project-plan', ['dismiss']);
|
|
226
|
+
ctx.setStatus('Dispatched /project-plan dismiss.');
|
|
227
227
|
ctx.close();
|
|
228
228
|
return;
|
|
229
229
|
}
|
|
@@ -232,18 +232,18 @@ class PlanningModalSurface implements ConfigModalSurface {
|
|
|
232
232
|
if (!question || actions.length === 0) return;
|
|
233
233
|
const action = ctx.row ? actions.find((a) => a.id === ctx.row!.id) : undefined;
|
|
234
234
|
if (!action || action.disabled) { ctx.print('Choose an answer option.'); return; }
|
|
235
|
-
if (action.kind === 'approve') { void ctx.executeCommand?.('plan', ['approve']); ctx.setStatus('Dispatched /plan approve.'); return; }
|
|
235
|
+
if (action.kind === 'approve') { void ctx.executeCommand?.('project-plan', ['approve']); ctx.setStatus('Dispatched /project-plan approve.'); return; }
|
|
236
236
|
|
|
237
237
|
const answerText = action.answer.trim();
|
|
238
238
|
if (!answerText) { ctx.print('Choose a non-empty answer, or type an answer for the custom row.'); return; }
|
|
239
239
|
|
|
240
|
-
// A canned answer to a REAL open question records structurally via /plan answer.
|
|
240
|
+
// A canned answer to a REAL open question records structurally via /project-plan answer.
|
|
241
241
|
const isOpenQuestion = this.snapshot?.state?.openQuestions.some(
|
|
242
242
|
(q) => q.id === question.id && (q.status ?? 'open') === 'open',
|
|
243
243
|
) ?? false;
|
|
244
244
|
if (action.id !== 'custom' && isOpenQuestion) {
|
|
245
|
-
void ctx.executeCommand?.('plan', ['answer', question.id, ...answerText.split(/\s+/)]);
|
|
246
|
-
ctx.setStatus('Dispatched /plan answer for the current question.');
|
|
245
|
+
void ctx.executeCommand?.('project-plan', ['answer', question.id, ...answerText.split(/\s+/)]);
|
|
246
|
+
ctx.setStatus('Dispatched /project-plan answer for the current question.');
|
|
247
247
|
return;
|
|
248
248
|
}
|
|
249
249
|
|