@pellux/goodvibes-agent 1.4.1 → 1.4.2

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/docs/README.md CHANGED
@@ -12,7 +12,6 @@ These are the package-facing docs for the GoodVibes Agent `1.0.x` release line.
12
12
  - [Channels, Remote Access, and API](channels-remote-and-api.md)
13
13
  - [Providers and Routing](providers-and-routing.md)
14
14
  - [Voice and Live TTS](voice-and-live-tts.md)
15
- - [Project Planning](project-planning.md)
16
15
  - [Release And Publishing](release-and-publishing.md)
17
16
 
18
17
  ## Baseline
@@ -24,7 +24,6 @@ High-signal TUI routes:
24
24
  | `/model`, `/provider`, `/effort` | Inspect or change provider/model/reasoning routes. |
25
25
  | `/knowledge` | Use isolated Agent Knowledge. |
26
26
  | `/vibe`, `/memory`, `/notes`, `/personas`, `/skills`, `/routines` | Manage VIBE.md personality and Agent-local behavior libraries. |
27
- | `/plan`, `/workplan` | Planning and durable visible work tracking. |
28
27
  | `/approval`, `/automation`, `/schedule` | Read posture and run exact confirmed operator actions. |
29
28
  | `/channels`, `/notify`, `/qrcode` | Pair companions, inspect channel readiness, review delivery receipts, and send confirmed messages. |
30
29
  | `/media`, `/voice`, `/tts` | Inspect media/voice readiness, generate media, and run spoken turns. |
@@ -297,7 +296,6 @@ Routine promotion is an explicit scheduling route. Local routines stay local unt
297
296
  | `/paste` | Insert clipboard text or image into the prompt. |
298
297
  | `/personas` | Manage Agent-local personas. |
299
298
  | `/pin` | Pin a model to the favorites list. |
300
- | `/plan` | Inspect or seed Agent workspace planning state. |
301
299
  | `/prev-error` | Jump to the previous error message in the conversation. |
302
300
  | `/provider` | Switch provider or manage custom providers. |
303
301
  | `/qrcode` | Print companion pairing details and a QR code. |
@@ -327,7 +325,6 @@ Routine promotion is an explicit scheduling route. Local routines stay local unt
327
325
  | `/vibe` | Inspect, create, show, or import VIBE.md personality files. |
328
326
  | `/voice` | Review voice posture and portable voice metadata. |
329
327
  | `/welcome` | Open or print the Agent setup guide. |
330
- | `/workplan` | Track a persistent workspace-scoped work plan. |
331
328
 
332
329
  ## Related Docs
333
330
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "private": false,
5
5
  "description": "GoodVibes personal operator assistant TUI with a proactive Agent product brain, isolated Agent Knowledge, local profiles, routines, skills, personas, and explicit build delegation.",
6
6
  "type": "module",
@@ -1,15 +1,7 @@
1
- - v1.4.0 was cut but its publish step never ran; v1.4.1 ships the same onboarding rebuild as the first publicly published version of the 1.4.x line. The fullscreen Agent workspace, Agent-local behavior, isolated Agent Knowledge, connected-host operator integration, explicit side-effect boundaries, and release hardening from 1.3.x all stay in force.
2
- - Fixed a release-evidence test that hardcoded a 1.3.0-specific phrase (`compact model-visible harness pass`) and prevented the v1.4.0 publish workflow from completing. The assertion now targets the stable required-theme `fullscreen Agent workspace`, so future release-notes rotations no longer break release CI.
3
- - Rebuilt the Agent Workspace onboarding modal so first-time users land in a focused ONBOARDING-only category list, no longer see HOME and post-onboarding categories competing for attention, and never get kicked out of the modal when activating a slash-command row.
4
- - Added typed `commandBehavior` (inline | compose | exit) on workspace actions so safe read-only commands can run inside the onboarding modal with their captured output rendered into the result pane, instead of forcing the modal closed to dispatch through the composer.
5
- - Guarded the new inline dispatch path so a missing `executeCommand` no longer clobbers `context.print`; the modal surfaces a clear "command unavailable" result and stays open.
6
- - Replaced release-engineering vocabulary (smoke history, receipt gaps, durable receipt, closeout policy, schema status, event cursor, publication guarantee, step history, repeated blocker, setup checkpoint summary) with a tight progress + single next-action summary in the onboarding right pane.
7
- - Closed a leak where channel-guide context lines could expose internal `userRoute` strings containing model-tool-call syntax; the channels guide now shows only human-readable labels.
8
- - Trimmed the user-facing setup checklist from fifteen items to thirteen by removing the `install-smoke` and `browser-pwa` release-engineering items; both remain available to model-facing routes but no longer appear in the onboarding flow.
9
- - Renamed the misleading `command` field on `AgentWorkspaceSetupChecklistItem` to `breadcrumb` so the field's purpose (UI navigation hint) no longer collides with the `kind: 'command'` action type.
10
- - Added clear verb-led row labels in the onboarding modal so users can see exactly what activating a row does: "Choose provider and model", "Edit MCP server", "Switch to <category>", "Run: <command>", "Open: <command>", "Finish setup", and so on, replacing generic labels like "Open option" and "Open guided form".
11
- - Added a sticky "Finish setup" footer row visible on every ONBOARDING category, colored green when prerequisites (provider/model, connected-host auth, runtime) are ready and warn-colored with the unmet items listed otherwise; the row is wired through the real activation path so pressing Enter triggers `completeOnboarding()`.
12
- - Added per-category readiness glyphs in the onboarding left pane: a green checkmark for categories whose mapped checklist items are all ready, a warn glyph for categories with blockers or recommended items, and no glyph for optional-only categories.
13
- - Relocated the diagnostic fields on `AgentSetupWizard` (smokeHistory, stepHistory, receiptGaps, closeout, checkpoint, repeatedBlocker) under a `_diagnostic` subkey so model-facing wizard mechanics are cleanly separated from user-facing wizard state, while preserving the existing model-tool surface.
14
- - Tightened `AgentWorkspaceCategory.group` and the workspace `_onlyGroup` filter to a literal union `AgentWorkspaceCategoryGroup`, so category-group typos fail at compile time instead of producing silent navigation bugs.
15
- - Added end-to-end acceptance tests for the new behavior: inline command dispatch keeps the workspace active and populates `lastActionResult` with captured output, first-run filter restricts the modal to ONBOARDING categories only, and the jargon allowlist guarantees no banned vocabulary leaks back into user-facing copy.
1
+ - v1.4.2 continues the stable 1.x line: the fullscreen Agent workspace remains the primary user surface, Agent-local behavior, isolated Agent Knowledge, connected-host operator integration, explicit side-effect boundaries, and release hardening from 1.3.x and 1.4.x all stay in force; 1.4.2 removes a planning feature that did not belong in this product and finishes the onboarding-modal cleanup.
2
+ - Removed the project planning subsystem entirely. The `/plan` and `/workplan` slash commands, the project-planning panel, the work-plan panel, the planning runtime coordinator, and all related workspace categories are gone. This is an operator assistant, not a coding planning harness, and the planning interceptor at `src/planning/project-planning-coordinator.ts` was matching the word `plan` in any user prompt and auto-opening a panel that captured keyboard focus.
3
+ - Stopped the onboarding modal from exiting the user mid-flow. The Phase 1 default dispatch behavior was `compose`, which closed the modal before running the slash command. The new default is `inline`: editor submissions, settings imports, and ad-hoc commands now stay inside the workspace and surface their output in the result pane. Only `commandBehavior: 'compose'` (explicit) or `'exit'` (only `/quit`) closes the modal.
4
+ - Forced the consistent Setting/Default/Current 3-column table layout on every ONBOARDING category. Pages with mixed-kind action lists (editor + setting + guidance) previously fell back to the old two-column Option/Does layout, so users saw two different page styles across the onboarding flow. Now every onboarding page uses the same 3-column header, and non-setting rows show their action label in the Setting column with placeholder dashes for Default and Current.
5
+ - Removed every onboarding workspace row that referenced the deleted planning feature: `personal-ops-workplan`, `personal-ops-workplan-add`, `workplan`, `workplan-show`, `workplan-add`, `workplan-status`, `workplan-delete`, `workplan-clear-completed`, `planning-status`, `planning-mode`, `planning-explain`, `planning-list`, `plan-seed`, `plan-show`, `plan-approve`, `plan-override`, `plan-clear`. Help overlay and docs cleaned of `/plan` and `/workplan` mentions.
6
+ - Trimmed the agent-boundary docs test that previously asserted on the deleted 1.2.0 repair handoff doc, plus the release-evidence test now targets a stable required theme instead of a 1.3.0-specific phrase.
7
+ - Test suite: 7601 pass / 0 fail / 19 skip across 548 files.
@@ -174,8 +174,6 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
174
174
  { id: 'personal-ops-calendar', label: 'Calendar workflows', detail: 'Calendar agenda and conflict checks use workflow cards with reviewed connector routes; reminders stay on confirmed schedules.', kind: 'guidance', safety: 'safe' },
175
175
  { id: 'personal-ops-notes', label: 'Scratchpad notes', detail: 'Open Agent-local notes for source triage, decisions, and handoff context.', targetCategoryId: 'notes', kind: 'workspace', safety: 'safe' },
176
176
  { id: 'personal-ops-note-create', label: 'Create note', detail: 'Capture temporary context as an Agent-local scratchpad note.', editorKind: 'note', kind: 'editor', safety: 'safe' },
177
- { id: 'personal-ops-workplan', label: 'Review work plan', detail: 'Open the visible work-plan route for user-facing task tracking.', targetCategoryId: 'work', kind: 'workspace', safety: 'safe' },
178
- { id: 'personal-ops-workplan-add', label: 'Add work item', detail: 'Create one visible work-plan item instead of hiding the task in background state.', editorKind: 'workplan-add', kind: 'editor', safety: 'safe' },
179
177
  { id: 'personal-ops-host-tasks', label: 'Host tasks', detail: 'Inspect connected-host task state without creating, retrying, or mutating tasks.', command: '/tasks list', kind: 'command', safety: 'read-only' },
180
178
  { id: 'personal-ops-reminder', label: 'Create reminder', detail: 'Create one connected reminder schedule with real timing, optional delivery target, and explicit confirmation.', editorKind: 'reminder-schedule', kind: 'editor', safety: 'safe' },
181
179
  { id: 'personal-ops-routines', label: 'Routine library', detail: 'Open repeatable workflows and schedule-promotion readiness.', targetCategoryId: 'routines', kind: 'workspace', safety: 'safe' },
@@ -658,18 +656,12 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
658
656
  id: 'work',
659
657
  group: 'OPERATIONS',
660
658
  label: 'Work & Approvals',
661
- summary: 'Visible task state, work plan, and approval posture.',
662
- detail: 'Use this workspace to inspect active operator state and update visible work-plan items from confirmed TUI forms.',
659
+ summary: 'Visible task state and approval posture.',
660
+ detail: 'Use this workspace to inspect active operator state and approval posture.',
663
661
  actions: [
664
- { id: 'workplan', label: 'Review work plan', detail: 'Print a concise work plan summary in the main Agent transcript.', command: '/workplan list', kind: 'command', safety: 'read-only' },
665
- { id: 'work-autonomy-queue', label: 'Autonomy queue', detail: 'Inspect visible work-plan, host-task, approval, automation, schedule, routine, and delegation queue cards.', kind: 'guidance', safety: 'read-only' },
662
+ { id: 'work-autonomy-queue', label: 'Autonomy queue', detail: 'Inspect visible host-task, approval, automation, schedule, routine, and delegation queue cards.', kind: 'guidance', safety: 'read-only' },
666
663
  { id: 'work-background-processes', label: 'Background processes', detail: 'Inspect tracked local background processes, bounded output tails, visible monitor routes, and lifecycle controls with execution action:"processes".', kind: 'guidance', safety: 'read-only' },
667
664
  { id: 'work-process-capabilities', label: 'Process capabilities', detail: 'Inspect process parity for start/list/poll/wait/log/kill/write, PTY, and sudo before choosing a local execution route.', kind: 'guidance', safety: 'read-only' },
668
- { id: 'workplan-show', label: 'Show work plan detail', detail: 'Open a read-only form for the detailed work plan view.', editorKind: 'workplan-show', kind: 'editor', safety: 'read-only' },
669
- { id: 'workplan-add', label: 'Add work item', detail: 'Open a form that creates one visible work plan item from the Agent workspace.', editorKind: 'workplan-add', kind: 'editor', safety: 'safe' },
670
- { id: 'workplan-status', label: 'Update work item status', detail: 'Open a form that updates one work plan item to pending, active, blocked, done, failed, or cancelled.', editorKind: 'workplan-status', kind: 'editor', safety: 'safe' },
671
- { id: 'workplan-delete', label: 'Remove work item', detail: 'Open a confirmed form before removing one work plan item.', editorKind: 'workplan-delete', kind: 'editor', safety: 'safe' },
672
- { id: 'workplan-clear-completed', label: 'Clear completed work', detail: 'Open a confirmed form before clearing completed and cancelled work plan items.', editorKind: 'workplan-clear-completed', kind: 'editor', safety: 'safe' },
673
665
  { id: 'conversation-export', label: 'Export conversation', detail: 'Open a confirmed form that exports the current Agent conversation to a workspace file.', editorKind: 'conversation-export', kind: 'editor', safety: 'safe' },
674
666
  { id: 'conversation-review', label: 'Review transcript', detail: 'Inspect current transcript structure without changing the conversation.', command: '/conversation review', kind: 'command', safety: 'read-only' },
675
667
  { id: 'conversation-composer', label: 'Composer posture', detail: 'Inspect current composer mode, pending approval posture, and context warning state.', command: '/conversation composer', kind: 'command', safety: 'read-only' },
@@ -690,15 +682,6 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
690
682
  { id: 'session-export-saved', label: 'Export saved session', detail: 'Open a form that prints one saved-session transcript as markdown or text.', editorKind: 'session-export-saved', kind: 'editor', safety: 'read-only' },
691
683
  { id: 'session-search', label: 'Search saved sessions', detail: 'Open a form that searches saved Agent sessions.', editorKind: 'session-search', kind: 'editor', safety: 'read-only' },
692
684
  { id: 'session-delete', label: 'Delete saved session', detail: 'Open a confirmed form before deleting one saved Agent session.', editorKind: 'session-delete', kind: 'editor', safety: 'safe' },
693
- { id: 'planning-status', label: 'Planning status', detail: 'Inspect current Agent planning readiness, mode, and next question without seeding or approving planning state.', command: '/plan status', kind: 'command', safety: 'read-only' },
694
- { id: 'planning-mode', label: 'Planning mode', detail: 'Inspect current planner mode and runtime strategy without changing it.', command: '/plan mode', kind: 'command', safety: 'read-only' },
695
- { id: 'planning-explain', label: 'Explain planner', detail: 'Explain planner state and readiness without approving or changing it.', command: '/plan explain', kind: 'command', safety: 'read-only' },
696
- { id: 'planning-list', label: 'Saved plans', detail: 'List saved Agent execution plans without changing current planning state.', command: '/plan list', kind: 'command', safety: 'read-only' },
697
- { id: 'plan-seed', label: 'Seed planning goal', detail: 'Open a form that seeds current planning state from a concrete Agent operating goal.', editorKind: 'plan-seed', kind: 'editor', safety: 'safe' },
698
- { id: 'plan-show', label: 'Show saved plan', detail: 'Open a plan-id form for read-only saved plan detail.', editorKind: 'plan-show', kind: 'editor', safety: 'read-only' },
699
- { id: 'plan-approve', label: 'Approve planning state', detail: 'Open a confirmation form before approving current planning state for execution.', editorKind: 'plan-approve', kind: 'editor', safety: 'safe' },
700
- { id: 'plan-override', label: 'Override planning strategy', detail: 'Open a confirmation form before changing planner strategy.', editorKind: 'plan-override', kind: 'editor', safety: 'safe' },
701
- { id: 'plan-clear', label: 'Clear planning state', detail: 'Open a confirmation form before clearing planner state.', editorKind: 'plan-clear', kind: 'editor', safety: 'safe' },
702
685
  { id: 'tasks-list', label: 'Host tasks', detail: 'Inspect connected-host task state without creating, retrying, or mutating tasks.', command: '/tasks list', kind: 'command', safety: 'read-only' },
703
686
  { id: 'tasks-filter', label: 'Filter host tasks', detail: 'Open a status/kind form for read-only connected-host task filtering.', editorKind: 'task-list-filter', kind: 'editor', safety: 'read-only' },
704
687
  { id: 'task-show', label: 'Inspect host task', detail: 'Open a task-id form for read-only connected-host task metadata.', editorKind: 'task-show', kind: 'editor', safety: 'read-only' },
@@ -6,7 +6,6 @@ import { knowledgeCommand } from './commands/knowledge.ts';
6
6
  import { registerShellCoreCommands } from './commands/shell-core.ts';
7
7
  import { registerConfigCommand } from './commands/config.ts';
8
8
  import { registerSessionWorkflowCommands } from './commands/session-workflow.ts';
9
- import { registerPlanningRuntimeCommands } from './commands/planning-runtime.ts';
10
9
  import { registerScheduleRuntimeCommands } from './commands/schedule-runtime.ts';
11
10
  import { registerOperatorRuntimeCommands } from './commands/operator-runtime.ts';
12
11
  import { registerNotifyRuntimeCommands } from './commands/notify-runtime.ts';
@@ -27,7 +26,6 @@ import { registerConversationRuntimeCommands } from './commands/conversation-run
27
26
  import { registerQrcodeRuntimeCommands } from './commands/qrcode-runtime.ts';
28
27
  import { registerOnboardingRuntimeCommands } from './commands/onboarding-runtime.ts';
29
28
  import { registerTtsRuntimeCommands } from './commands/tts-runtime.ts';
30
- import { registerWorkPlanRuntimeCommands } from './commands/work-plan-runtime.ts';
31
29
  import { registerAgentWorkspaceRuntimeCommands } from './commands/agent-workspace-runtime.ts';
32
30
  import { registerAgentRuntimeProfileRuntimeCommands } from './commands/agent-runtime-profile-runtime.ts';
33
31
  import { registerDelegationRuntimeCommands } from './commands/delegation-runtime.ts';
@@ -90,10 +88,8 @@ export function registerBuiltinCommands(registry: CommandRegistry): void {
90
88
  registerQrcodeRuntimeCommands(registry);
91
89
  registerOnboardingRuntimeCommands(registry);
92
90
  registerTtsRuntimeCommands(registry);
93
- registerWorkPlanRuntimeCommands(registry);
94
91
  registerLocalRuntimeCommands(registry);
95
92
  registerSessionWorkflowCommands(registry);
96
- registerPlanningRuntimeCommands(registry);
97
93
  registerScheduleRuntimeCommands(registry);
98
94
  registerSessionContentCommands(registry);
99
95
  registerAgentMemoryCommand(registry);
@@ -397,7 +397,10 @@ export class InputHandler {
397
397
  }
398
398
 
399
399
  public dispatchAgentWorkspaceCommand(command: string, context: CommandContext, behavior?: 'inline' | 'compose' | 'exit'): void {
400
- const resolved = behavior ?? 'compose';
400
+ // Default to 'inline' so editor submissions stay inside the workspace modal.
401
+ // Closing the modal mid-flow (the old 'compose' default) traps users in the
402
+ // wrong context and was the primary symptom of the broken onboarding flow.
403
+ const resolved = behavior ?? 'inline';
401
404
  const { name, args } = parseSlashCommand(command);
402
405
  if (!name) return;
403
406
  if (resolved === 'exit') {
package/src/main.ts CHANGED
@@ -54,7 +54,6 @@ import { applyInitialTuiCliState, formatFatalStartupErrorForLog, formatFatalStar
54
54
  import { wireSpokenTurnRuntime } from './audio/spoken-turn-wiring.ts';
55
55
  import { attachSpokenTurnModelRouting, createSpokenTurnInputOptions } from './audio/spoken-turn-model-routing.ts';
56
56
  import { allowTerminalWrite, installTuiTerminalOutputGuard } from './runtime/terminal-output-guard.ts';
57
- import { ProjectPlanningCoordinator } from './planning/project-planning-coordinator.ts';
58
57
  import { buildCommandArgsHint } from './input/command-args-hint.ts';
59
58
  import { GOODVIBES_AGENT_PAIRING_SURFACE } from './config/surface.ts';
60
59
 
@@ -262,18 +261,6 @@ async function main() {
262
261
  configManager,
263
262
  notify: (message) => { systemMessageRouter.high(message); render(); },
264
263
  }));
265
- const projectPlanningCoordinator = new ProjectPlanningCoordinator({
266
- service: ctx.services.projectPlanningService,
267
- projectId: ctx.services.projectPlanningProjectId,
268
- workingDirectory: workingDir,
269
- notify: (message) => { systemMessageRouter.high(message); render(); },
270
- openPanel: () => {
271
- panelManager.open('project-planning');
272
- panelManager.show();
273
- render();
274
- },
275
- });
276
-
277
264
  const submitInput = (text: string, content?: ContentPart[], options: { readonly spokenOutput?: boolean } = {}) => {
278
265
  input.clearModalStack();
279
266
  scrollLocked = true; // Re-lock on user input
@@ -308,33 +295,7 @@ async function main() {
308
295
  }
309
296
  if (processedText || content) {
310
297
  void (async () => {
311
- let inputOptions = options.spokenOutput ? createSpokenTurnInputOptions() : undefined;
312
- if (!options.spokenOutput && processedText) {
313
- try {
314
- const planning = await projectPlanningCoordinator.prepareTurn(processedText);
315
- if (planning) {
316
- if (planning.handledLocally) {
317
- systemMessageRouter.high(planning.statusMessage);
318
- render();
319
- return;
320
- }
321
- conversation.addSystemMessage(planning.systemMessage);
322
- inputOptions = {
323
- origin: {
324
- source: 'project-planning',
325
- surface: GOODVIBES_AGENT_PAIRING_SURFACE,
326
- metadata: {
327
- projectId: ctx.services.projectPlanningProjectId,
328
- knowledgeSpaceId: planning.state.knowledgeSpaceId,
329
- readiness: planning.evaluation.readiness,
330
- },
331
- },
332
- };
333
- }
334
- } catch (err) {
335
- systemMessageRouter.high(`[Planning] ${summarizeError(err)}`);
336
- }
337
- }
298
+ const inputOptions = options.spokenOutput ? createSpokenTurnInputOptions() : undefined;
338
299
  if (options.spokenOutput && processedText) {
339
300
  spokenTurns.submitNextTurn(processedText);
340
301
  }
@@ -3,8 +3,6 @@ import { ContextVisualizerPanel } from '../context-visualizer-panel.ts';
3
3
  import { ThinkingPanel } from '../thinking-panel.ts';
4
4
  import { ToolInspectorPanel } from '../tool-inspector-panel.ts';
5
5
  import { SchedulePanel } from '../schedule-panel.ts';
6
- import { ProjectPlanningPanel } from '../project-planning-panel.ts';
7
- import { WorkPlanPanel } from '../work-plan-panel.ts';
8
6
  import type { ResolvedBuiltinPanelDeps } from './shared.ts';
9
7
  import { requireAutomationManager, requireUiServices } from './shared.ts';
10
8
 
@@ -49,32 +47,6 @@ export function registerAgentPanels(manager: PanelManager, deps: ResolvedBuiltin
49
47
  ),
50
48
  });
51
49
 
52
- manager.registerType({
53
- id: 'work-plan',
54
- name: 'Work Plan',
55
- icon: 'L',
56
- category: 'agent',
57
- description: 'Persistent workspace checklist for multi-step work and cross-session task tracking',
58
- preload: true,
59
- factory: () => new WorkPlanPanel(deps.workPlanStore),
60
- });
61
-
62
- manager.registerType({
63
- id: 'project-planning',
64
- name: 'Planning',
65
- icon: 'P',
66
- category: 'agent',
67
- description: 'Passive project planning artifacts: readiness, questions, decisions, language, task graph, and agent handoff metadata',
68
- preload: true,
69
- factory: () => new ProjectPlanningPanel({
70
- service: deps.projectPlanningService,
71
- projectId: deps.projectPlanningProjectId,
72
- requestRender: deps.requestRender,
73
- submitAnswer: deps.submitPlanningAnswer,
74
- dismissPlanning: deps.dismissPlanning,
75
- }),
76
- });
77
-
78
50
  manager.registerType({
79
51
  id: 'schedule',
80
52
  name: 'Schedule',
@@ -392,10 +392,13 @@ function onboardingActionColumns(workspace: AgentWorkspace, action: AgentWorkspa
392
392
  currentValue: '(unknown)',
393
393
  };
394
394
  }
395
+ // Non-setting rows keep the 3-column layout but use placeholders for Default and Current,
396
+ // since those concepts only make sense for actual settings. The action label carries
397
+ // the meaning of the row.
395
398
  return {
396
- setting: onboardingActionLabel(workspace, action),
397
- defaultValue: '',
398
- currentValue: '',
399
+ setting: action.label,
400
+ defaultValue: '',
401
+ currentValue: '',
399
402
  };
400
403
  }
401
404
 
@@ -418,9 +421,12 @@ function actionMetaLine(workspace: AgentWorkspace, category: AgentWorkspaceCateg
418
421
  }
419
422
 
420
423
  function shouldRenderOnboardingSettingsTable(actions: readonly AgentWorkspaceAction[]): boolean {
421
- // Exclude the synthetic finish footer row it is not a setting and must not block table mode.
424
+ // Always use the Setting/Default/Current 3-column layout on ONBOARDING pages so the
425
+ // user gets a consistent visual structure across every category, even ones that mix
426
+ // settings with editors, guidance, or pickers. Non-setting rows fill Default/Current
427
+ // with placeholders via onboardingActionColumns().
422
428
  const nonFinish = actions.filter((a) => a.kind !== 'onboarding-complete');
423
- return nonFinish.length > 0 && nonFinish.every((action) => action.kind === 'setting');
429
+ return nonFinish.length > 0;
424
430
  }
425
431
 
426
432
  function editorContextLines(editor: AgentWorkspaceLocalEditor, snapshot: AgentWorkspaceRuntimeSnapshot | null): ContextLine[] {
@@ -22,7 +22,6 @@ const FEATURED_HELP_COMMANDS: Array<[name: string, argHint: string, desc: string
22
22
  ['personas', '', 'Manage serial Agent operating personas'],
23
23
  ['skills', '', 'Manage Agent-local skills and bundles'],
24
24
  ['routines', '', 'Manage reusable main-conversation routines'],
25
- ['workplan', '', 'Inspect shared work-plan state'],
26
25
  ['approval', '', 'Review and explicitly act on approvals'],
27
26
  ['automation', '', 'Run confirmed connected-host automation actions'],
28
27
  ['schedule', 'remind', 'Create confirmed reminders or inspect schedules'],
@@ -202,7 +201,6 @@ export function renderHelpOverlay(
202
201
  'personas',
203
202
  'skills',
204
203
  'routines',
205
- 'workplan',
206
204
  'approval',
207
205
  'schedule',
208
206
  'delegate',
package/src/version.ts CHANGED
@@ -6,7 +6,7 @@ import { join } from 'node:path';
6
6
  // The prebuild script updates the fallback value before compilation.
7
7
  // Uses import.meta.dir (Bun) to locate package.json relative to this file,
8
8
  // which is correct regardless of the process working directory.
9
- let _version = '1.4.1';
9
+ let _version = '1.4.2';
10
10
  try {
11
11
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
12
12
  readonly version?: unknown;
@@ -1,81 +0,0 @@
1
- # Project Planning
2
-
3
- GoodVibes Agent owns the active planning loop for operator work. Planning is part of the Agent main conversation, not a hidden execution flow and not a default knowledge query.
4
-
5
- ## Boundary
6
-
7
- The Agent owns:
8
-
9
- - natural-language planning intent detection in the main terminal conversation;
10
- - one-question-at-a-time clarification;
11
- - the Agent-owned planning loop;
12
- - transcript-first planning summaries and the Agent operator workspace planning state;
13
- - explicit execution approval;
14
- - delegation metadata when work needs GoodVibes TUI.
15
-
16
- The connected-host runtime owns durable storage and route contracts:
17
-
18
- - planning namespaces such as `project:<projectId>`;
19
- - readiness evaluation and next-question hints;
20
- - decision records;
21
- - task, dependency, verification, and assignment metadata;
22
- - read-only public operator methods.
23
-
24
- Other surfaces can store or inspect planning artifacts, but conversation control stays in Agent. Agent planning state is not default knowledge, another product segment, or arbitrary knowledge data.
25
-
26
- ## Agent Behavior
27
-
28
- The Agent derives a stable `projectId` from the workspace path and passes it to the connected-host planning service. Planning artifacts are stored under the matching planning namespace so unrelated workspaces do not share state.
29
-
30
- Normal conversation can start planning when the user asks for an execution strategy, dependency graph, verification gates, or delegation handoff. The Agent then:
31
-
32
- - prints a concise planning summary in the main transcript;
33
- - persists the current planning state through public connected-host runtime routes;
34
- - records active open questions and user answers;
35
- - calls readiness evaluation for gaps and the suggested next question;
36
- - asks one focused question instead of executing prematurely.
37
-
38
- The planning loop can be paused with natural language such as "stop planning" or "pause planning".
39
-
40
- ## Planning View
41
-
42
- The planning view is transcript-first. It shows:
43
-
44
- - workspace project id and planning namespace;
45
- - readiness and approval state;
46
- - goal, scope, known context, and current next question;
47
- - blocking or advisory readiness gaps;
48
- - task graph and verification gates;
49
- - delegation candidates;
50
- - durable decisions;
51
- - project language and ambiguity resolutions.
52
-
53
- Keyboard behavior stays in the main Agent TUI: predictable prompt editing, scroll, submit, dismiss, and return-to-chat behavior.
54
-
55
- ## `/plan`
56
-
57
- `/plan` remains a command workspace for inspection and seeding:
58
-
59
- - `/plan` prints current planning readiness and the next planning question;
60
- - `/plan panel` is guidance-only in Agent and points back to `/plan status` or `/plan list`;
61
- - `/plan approve` records explicit execution approval;
62
- - `/plan <goal>` seeds Agent workspace planning state;
63
- - `/plan list` and `/plan show <id>` inspect older execution-plan records.
64
-
65
- Use natural language such as "pause planning" or "stop planning" when planning should pause and normal chat should continue.
66
-
67
- ## Work Plan
68
-
69
- The work-plan tracker is for concrete, durable task state after work becomes actionable. It is separate from the planning interview loop.
70
-
71
- Use `/workplan` when the work already has tasks and needs status tracking. Use `/delegate` when explicit build/fix/review work should go to GoodVibes TUI; include the original ask, delegation reason, success evidence, workspace/worktree hint, priority, and explicit review intent.
72
-
73
- The model can keep the same visible work plan current with `agent_work_plan`. Approved items can be dispatched through confirmed `agent_work_plan action:"dispatch_agents"` into visible `agent` spawn or batch-spawn calls, with linked-agent receipts written back to the plan and post-dispatch next routes for orchestration, work-plan detail, agent inspect/wait/message/cancel, and closeout. Those linked receipts and matching remote-runner artifacts appear in `agent_harness mode:"agent_orchestration"` closeout cards with exact work-plan and artifact review routes. It can also inspect planning/work-plan visibility through `agent_harness` workspace and panel metadata, and inspect explicit build-delegation posture with `delegation action:"status|routes|route"`; destructive work-plan changes, agent dispatch, and delegated submissions still require explicit user request and confirmation.
74
-
75
- ## Agent Knowledge Boundary
76
-
77
- Planning may link to Agent Knowledge evidence, but it must not query or ingest through default knowledge. Source-backed facts for Agent belong under:
78
-
79
- ```text
80
- /api/goodvibes-agent/knowledge/*
81
- ```
@@ -1,215 +0,0 @@
1
- import type {
2
- ProjectPlanningEvaluation,
3
- ProjectPlanningQuestion,
4
- ProjectPlanningService,
5
- ProjectPlanningState,
6
- } from '@pellux/goodvibes-sdk/platform/knowledge';
7
- import type { CommandRegistry } from '../command-registry.ts';
8
- import { requirePlanManager, requireSessionLineageTracker } from './runtime-services.ts';
9
- import { requireYesFlag, stripYesFlag } from './confirmation.ts';
10
-
11
- function recordNextQuestion(
12
- state: Partial<ProjectPlanningState>,
13
- question: ProjectPlanningQuestion | undefined,
14
- ): Partial<ProjectPlanningState> {
15
- if (!question) return state;
16
- const answered = new Set((state.answeredQuestions ?? []).map((entry) => entry.id));
17
- if (answered.has(question.id)) return state;
18
- const openQuestions = [...(state.openQuestions ?? [])];
19
- const existingIndex = openQuestions.findIndex((entry) => entry.id === question.id);
20
- const normalized = { ...question, status: question.status ?? 'open' } satisfies ProjectPlanningQuestion;
21
- if (existingIndex >= 0) openQuestions[existingIndex] = normalized;
22
- else openQuestions.unshift(normalized);
23
- return { ...state, openQuestions };
24
- }
25
-
26
- async function persistEvaluatedNextQuestion(
27
- service: ProjectPlanningService,
28
- projectId: string,
29
- state: ProjectPlanningState,
30
- evaluation: ProjectPlanningEvaluation,
31
- ): Promise<{ state: ProjectPlanningState; evaluation: ProjectPlanningEvaluation }> {
32
- if (!evaluation.nextQuestion) return { state, evaluation };
33
- if (state.openQuestions.some((question) => question.id === evaluation.nextQuestion?.id)) {
34
- return { state, evaluation };
35
- }
36
- const withQuestion = recordNextQuestion(evaluation.state ?? state, evaluation.nextQuestion);
37
- const saved = await service.upsertState({ projectId, state: withQuestion });
38
- const nextState = saved.state ?? state;
39
- const nextEvaluation = await service.evaluate({ projectId, state: nextState });
40
- return { state: nextState, evaluation: nextEvaluation };
41
- }
42
-
43
- function formatNextQuestion(question: ProjectPlanningQuestion | undefined): string {
44
- if (!question) return 'No next question recorded.';
45
- const lines = [`Next question: ${question.prompt}`];
46
- if (question.recommendedAnswer) lines.push(`Recommended answer: ${question.recommendedAnswer}`);
47
- lines.push('Answer in the main prompt or review planning state with /plan status.');
48
- return lines.join('\n');
49
- }
50
-
51
- export function registerPlanningRuntimeCommands(registry: CommandRegistry): void {
52
- registry.register({
53
- name: 'plan',
54
- description: 'Inspect or seed Agent workspace planning state',
55
- usage: '[approve --yes | list | show <id> | mode | explain | override <strategy> --yes | status | clear --yes | <planning goal>]',
56
- argsHint: '[approve|status|list|<goal>]',
57
- async handler(args, ctx) {
58
- const planManager = requirePlanManager(ctx);
59
- const sessionLineageTracker = requireSessionLineageTracker(ctx);
60
- const plannerSubs = ['mode', 'explain', 'override', 'status', 'clear'];
61
- if (args.length > 0 && plannerSubs.includes(args[0].toLowerCase())) {
62
- const parsed = stripYesFlag(args);
63
- const subcommand = parsed.rest[0]?.toLowerCase() ?? '';
64
- if ((subcommand === 'override' || subcommand === 'clear') && !parsed.yes) {
65
- requireYesFlag(ctx, `${subcommand} planner state`, `/plan ${subcommand}${subcommand === 'override' ? ' <strategy>' : ''} --yes`);
66
- return;
67
- }
68
- const result = ctx.ops.planRuntime
69
- ? ctx.ops.planRuntime(parsed.rest[0] ?? args[0], parsed.rest.slice(1))
70
- : { ok: false, output: 'Plan runtime route is not available in this runtime.' };
71
- ctx.print(result.output);
72
- return;
73
- }
74
-
75
- const projectPlanningService = ctx.workspace.projectPlanningService;
76
- const projectId = ctx.workspace.projectPlanningProjectId;
77
-
78
- if (args.length === 0) {
79
- if (projectPlanningService && projectId) {
80
- const [status, stateResult] = await Promise.all([
81
- projectPlanningService.status({ projectId }),
82
- projectPlanningService.getState({ projectId }),
83
- ]);
84
- const initialEvaluation = await projectPlanningService.evaluate({
85
- projectId,
86
- ...(stateResult.state ? { state: stateResult.state } : {}),
87
- });
88
- const { evaluation } = stateResult.state
89
- ? await persistEvaluatedNextQuestion(projectPlanningService, projectId, stateResult.state, initialEvaluation)
90
- : { evaluation: initialEvaluation };
91
- const planningNamespace = String(
92
- status[['knowledge', 'SpaceId'].join('') as keyof typeof status] ?? `project:${status.projectId}`,
93
- );
94
- ctx.print(
95
- `Project planning: ${evaluation.readiness}\n` +
96
- `Project: ${status.projectId}\n` +
97
- `Planning namespace: ${planningNamespace}\n` +
98
- `Artifacts: ${status.counts.states} state, ${status.counts.decisions} decisions, ${status.counts.languageArtifacts} language\n` +
99
- formatNextQuestion(evaluation.nextQuestion),
100
- );
101
- return;
102
- }
103
- const active = planManager.getActive(ctx.session.runtime.sessionId);
104
- if (!active) {
105
- ctx.print('No active execution plan.');
106
- return;
107
- }
108
- const summary = planManager.getSummary(active);
109
- ctx.print(`Active plan: "${active.title}" [${active.status.toUpperCase()}]\n${summary}`);
110
- return;
111
- }
112
-
113
- if (args[0] === 'panel') {
114
- ctx.print('Use /plan status or /plan list for compact command output. Open Agent Workspace -> Work -> Planning status or Saved plans for the workspace view.');
115
- return;
116
- }
117
-
118
- if (args[0] === 'approve') {
119
- const parsed = stripYesFlag(args);
120
- if (!parsed.yes) {
121
- requireYesFlag(ctx, 'approve project planning state for execution', '/plan approve --yes');
122
- return;
123
- }
124
- if (!projectPlanningService || !projectId) {
125
- ctx.print('Project planning service is not available in this runtime.');
126
- return;
127
- }
128
- const current = await projectPlanningService.getState({ projectId });
129
- if (!current.state) {
130
- ctx.print('No project planning state exists to approve.');
131
- return;
132
- }
133
- const result = await projectPlanningService.upsertState({
134
- projectId,
135
- state: {
136
- ...current.state,
137
- executionApproved: true,
138
- metadata: {
139
- ...(current.state.metadata ?? {}),
140
- approvedFrom: 'plan-command',
141
- approvedAt: Date.now(),
142
- },
143
- },
144
- });
145
- const evaluation = await projectPlanningService.evaluate({ projectId });
146
- ctx.print(`Project planning approved. Readiness: ${evaluation.readiness}. State: ${result.state?.id ?? 'current'}.`);
147
- return;
148
- }
149
-
150
- if (args[0] === 'list') {
151
- const plans = planManager.list();
152
- if (plans.length === 0) {
153
- ctx.print('No plans found.');
154
- return;
155
- }
156
- ctx.print(`Plans (${plans.length}):\n${plans.map((plan) => {
157
- const marker = plan.status === 'active' ? '▶' : ' ';
158
- return ` ${marker} ${plan.id.slice(0, 8)} [${plan.status.padEnd(8)}] ${plan.title}`;
159
- }).join('\n')}`);
160
- return;
161
- }
162
-
163
- if (args[0] === 'show') {
164
- const id = args[1];
165
- if (!id) {
166
- ctx.print('Usage: /plan show <plan-id>');
167
- return;
168
- }
169
- const plans = planManager.list();
170
- const plan = plans.find((entry) => entry.id === id || entry.id.startsWith(id));
171
- if (!plan) {
172
- ctx.print(`Plan not found: ${id}`);
173
- return;
174
- }
175
- ctx.print(planManager.toMarkdown(plan));
176
- return;
177
- }
178
-
179
- const taskDescription = args.join(' ');
180
- if (!projectPlanningService || !projectId) {
181
- ctx.print('Project planning service is not available in this runtime.');
182
- return;
183
- }
184
- const result = await projectPlanningService.upsertState({
185
- projectId,
186
- state: {
187
- goal: taskDescription,
188
- knownContext: [
189
- `Workspace planning was seeded from the Agent /plan command.`,
190
- ],
191
- metadata: {
192
- active: true,
193
- owner: 'agent',
194
- source: 'plan-command',
195
- lastPromptAt: Date.now(),
196
- },
197
- },
198
- });
199
- const initialEvaluation = await projectPlanningService.evaluate({
200
- projectId,
201
- ...(result.state ? { state: result.state } : {}),
202
- });
203
- const { state, evaluation } = result.state
204
- ? await persistEvaluatedNextQuestion(projectPlanningService, projectId, result.state, initialEvaluation)
205
- : { state: result.state, evaluation: initialEvaluation };
206
- sessionLineageTracker.setOriginalTask(taskDescription.slice(0, 200));
207
-
208
- ctx.print(
209
- `Project planning seeded: "${state?.goal ?? taskDescription}"\n` +
210
- `Readiness: ${evaluation.readiness}\n` +
211
- formatNextQuestion(evaluation.nextQuestion),
212
- );
213
- },
214
- });
215
- }