Browse Source

Rename session goal to goal

Alvin Unreal 3 months ago
parent
commit
756f980815
11 changed files with 41 additions and 40 deletions
  1. 1 0
      .gitignore
  2. 1 1
      README.md
  3. 4 4
      docs/goal.md
  4. 1 1
      docs/interview.md
  5. 1 1
      docs/subtask.md
  6. 1 1
      docs/todo-continuation.md
  7. 4 4
      docs/tools.md
  8. 18 18
      src/hooks/goal/index.test.ts
  9. 2 2
      src/hooks/goal/index.ts
  10. 1 1
      src/hooks/index.ts
  11. 7 7
      src/index.ts

+ 1 - 0
.gitignore

@@ -56,6 +56,7 @@ GOAL.md
 GOALS.md
 PR-NOTES.md
 REVIEW.md
+!docs/goal.md
 docs/plans
 docs/superpowers
 

+ 1 - 1
README.md

@@ -503,7 +503,7 @@ Use this section as a map: start with installation, then jump to features, confi
 | **[V2 Background Orchestration](docs/v2-background-orchestration.md)** | Scheduler-first orchestrator model built around native background subagents |
 | **[Multiplexer Integration](docs/multiplexer-integration.md)** | Watch agents work live in Tmux or Zellij panes |
 | **[Session Management](docs/session-management.md)** | Reuse recent child-agent sessions with short aliases instead of starting over |
-| **[Session Goal](docs/session-goal.md)** | Pin a session objective with `/goal` so todos, delegation, and verification stay aligned |
+| **[Goal](docs/goal.md)** | Pin an objective with `/goal` so todos, delegation, and verification stay aligned |
 | **[Todo Continuation](docs/todo-continuation.md)** | Auto-continue orchestrator sessions with cooldowns and safety checks |
 | **[Preset Switching](docs/preset-switching.md)** | Switch agent model presets at runtime with `/preset` |
 | **[Custom Agents](docs/configuration.md#custom-agents)** | Define your own specialists with custom prompts, models, MCP access, and Orchestrator delegation rules |

+ 4 - 4
docs/session-goal.md → docs/goal.md

@@ -1,4 +1,4 @@
-# Session Goal
+# Goal
 
 `/goal` pins a session-scoped objective so long work keeps a clear north star.
 
@@ -9,15 +9,15 @@ but you do not want a separate project-management system.
 
 | Command | Description |
 |---------|-------------|
-| `/goal <objective>` | Set the current session goal |
+| `/goal <objective>` | Set the current goal |
 | `/goal` | Show the active goal and how it relates to todos and auto-continuation |
-| `/goal clear` | Clear the current session goal |
+| `/goal clear` | Clear the current goal |
 | `/goal from <interview>` | Set the goal from an existing interview markdown spec |
 
 Examples:
 
 ```text
-/goal Add lightweight session goals. Done when UX, docs, and tests are complete.
+/goal Add lightweight goals. Done when UX, docs, and tests are complete.
 /goal from kanban-design-tool
 /goal clear
 ```

+ 1 - 1
docs/interview.md

@@ -42,7 +42,7 @@ You can also resume by basename if it exists in the configured output folder:
 /interview kanban-design-tool
 ```
 
-Promote an interview spec into the current session goal:
+Promote an interview spec into the current goal:
 
 ```text
 /goal from kanban-design-tool

+ 1 - 1
docs/subtask.md

@@ -48,7 +48,7 @@ Keep the request narrow. A good subtask has a clear finish line.
 In tmux or zellij, the subtask appears like other child-agent work because it is
 a real child session. Existing depth limits and pane cleanup handling apply.
 
-If the parent session has an active [Session Goal](session-goal.md), the worker inherits
+If the parent session has an active [Goal](goal.md), the worker inherits
 it as context. The explicit subtask request still defines the worker's scope.
 
 ## Worker scope

+ 1 - 1
docs/todo-continuation.md

@@ -2,7 +2,7 @@
 
 Auto-continue the orchestrator when it stops with incomplete todos. Opt-in only — nothing resumes automatically unless you enable it.
 
-If a [Session Goal](session-goal.md) is active, auto-continuation resumes under that
+If a [Goal](goal.md) is active, auto-continuation resumes under that
 goal, but the goal does not trigger continuation by itself. Only incomplete
 todos do.
 

+ 4 - 4
docs/tools.md

@@ -73,16 +73,16 @@ Auto-continue has its own guide now:
 
 ---
 
-## Session Goal
+## Goal
 
-Pin a session-scoped objective that keeps planning, todos, delegation, and
+Pin a goal that keeps planning, todos, delegation, and
 verification aligned.
 
 | Command | Description |
 |---------|-------------|
-| `/goal <objective>` | Set the current session goal |
+| `/goal <objective>` | Set the current goal |
 | `/goal` | Show the active goal |
 | `/goal clear` | Clear the active goal |
 | `/goal from <interview>` | Promote an interview markdown spec into the active goal |
 
-See [Session Goal](session-goal.md) for the full workflow.
+See [Goal](goal.md) for the full workflow.

+ 18 - 18
src/hooks/session-goal/index.test.ts → src/hooks/goal/index.test.ts

@@ -2,20 +2,20 @@ import { describe, expect, test } from 'bun:test';
 import { mkdir, mkdtemp, writeFile } from 'node:fs/promises';
 import { tmpdir } from 'node:os';
 import path from 'node:path';
-import { createSessionGoalHook } from './index';
+import { createGoalHook } from './index';
 
 function createHook(directory = '.') {
-  return createSessionGoalHook(
-    { directory } as Parameters<typeof createSessionGoalHook>[0],
+  return createGoalHook(
+    { directory } as Parameters<typeof createGoalHook>[0],
     { interview: { outputFolder: 'interview' } } as Parameters<
-      typeof createSessionGoalHook
+      typeof createGoalHook
     >[1],
     { getAgentName: () => 'orchestrator' },
   );
 }
 
-describe('createSessionGoalHook', () => {
-  test('sets and shows a manual session goal', async () => {
+describe('createGoalHook', () => {
+  test('sets and shows a manual goal', async () => {
     const hook = createHook();
     const output = { parts: [] as Array<{ type: string; text?: string }> };
 
@@ -61,9 +61,9 @@ describe('createSessionGoalHook', () => {
   });
 
   test('inherits parent goal for child sessions', async () => {
-    const hook = createSessionGoalHook(
-      { directory: '.' } as Parameters<typeof createSessionGoalHook>[0],
-      {} as Parameters<typeof createSessionGoalHook>[1],
+    const hook = createGoalHook(
+      { directory: '.' } as Parameters<typeof createGoalHook>[0],
+      {} as Parameters<typeof createGoalHook>[1],
       { getAgentName: () => 'explorer' },
     );
     await hook.handleCommandExecuteBefore(
@@ -87,9 +87,9 @@ describe('createSessionGoalHook', () => {
   });
 
   test('child sessions resolve updated parent goal live', async () => {
-    const hook = createSessionGoalHook(
-      { directory: '.' } as Parameters<typeof createSessionGoalHook>[0],
-      {} as Parameters<typeof createSessionGoalHook>[1],
+    const hook = createGoalHook(
+      { directory: '.' } as Parameters<typeof createGoalHook>[0],
+      {} as Parameters<typeof createGoalHook>[1],
       { getAgentName: () => 'explorer' },
     );
     await hook.handleCommandExecuteBefore(
@@ -115,9 +115,9 @@ describe('createSessionGoalHook', () => {
   });
 
   test('grandchild sessions inherit the root goal', async () => {
-    const hook = createSessionGoalHook(
-      { directory: '.' } as Parameters<typeof createSessionGoalHook>[0],
-      {} as Parameters<typeof createSessionGoalHook>[1],
+    const hook = createGoalHook(
+      { directory: '.' } as Parameters<typeof createGoalHook>[0],
+      {} as Parameters<typeof createGoalHook>[1],
       { getAgentName: () => 'explorer' },
     );
     await hook.handleCommandExecuteBefore(
@@ -146,9 +146,9 @@ describe('createSessionGoalHook', () => {
   });
 
   test('child sessions stop inheriting after parent goal is cleared', async () => {
-    const hook = createSessionGoalHook(
-      { directory: '.' } as Parameters<typeof createSessionGoalHook>[0],
-      {} as Parameters<typeof createSessionGoalHook>[1],
+    const hook = createGoalHook(
+      { directory: '.' } as Parameters<typeof createGoalHook>[0],
+      {} as Parameters<typeof createGoalHook>[1],
       { getAgentName: () => 'explorer' },
     );
     await hook.handleCommandExecuteBefore(

+ 2 - 2
src/hooks/session-goal/index.ts → src/hooks/goal/index.ts

@@ -103,7 +103,7 @@ function resolveGoal(
   }
 }
 
-export function createSessionGoalHook(
+export function createGoalHook(
   ctx: PluginInput,
   config: PluginConfig,
   options?: { getAgentName?: (sessionID: string) => string | undefined },
@@ -133,7 +133,7 @@ export function createSessionGoalHook(
       if (commandConfig?.[COMMAND_NAME]) return;
       if (!opencodeConfig.command) opencodeConfig.command = {};
       (opencodeConfig.command as Record<string, unknown>)[COMMAND_NAME] = {
-        template: 'Set or show the current session goal',
+        template: 'Set or show the current goal',
         description:
           'Pin a session objective that keeps todos, delegation, and verification aligned',
       };

+ 1 - 1
src/hooks/index.ts

@@ -8,10 +8,10 @@ export {
   ForegroundFallbackManager,
   isRateLimitError,
 } from './foreground-fallback';
+export { createGoalHook } from './goal';
 export { processImageAttachments } from './image-hook';
 export { createJsonErrorRecoveryHook } from './json-error-recovery';
 export { createPhaseReminderHook } from './phase-reminder';
 export { createPostFileToolNudgeHook } from './post-file-tool-nudge';
-export { createSessionGoalHook } from './session-goal';
 export { createTaskSessionManagerHook } from './task-session-manager';
 export { createTodoContinuationHook } from './todo-continuation';

+ 7 - 7
src/index.ts

@@ -22,10 +22,10 @@ import {
   createChatHeadersHook,
   createDelegateTaskRetryHook,
   createFilterAvailableSkillsHook,
+  createGoalHook,
   createJsonErrorRecoveryHook,
   createPhaseReminderHook,
   createPostFileToolNudgeHook,
-  createSessionGoalHook,
   createTaskSessionManagerHook,
   createTodoContinuationHook,
   ForegroundFallbackManager,
@@ -139,7 +139,7 @@ const OhMyOpenCodeLite: Plugin = async (ctx) => {
   let jsonErrorRecoveryHook: ReturnType<typeof createJsonErrorRecoveryHook>;
   let foregroundFallback: ForegroundFallbackManager;
   let todoContinuationHook: ReturnType<typeof createTodoContinuationHook>;
-  let sessionGoalHook: ReturnType<typeof createSessionGoalHook>;
+  let goalHook: ReturnType<typeof createGoalHook>;
   let taskSessionManagerHook: ReturnType<typeof createTaskSessionManagerHook>;
   let backgroundJobBoard: BackgroundJobBoard;
   let interviewManager: ReturnType<typeof createInterviewManager>;
@@ -314,7 +314,7 @@ const OhMyOpenCodeLite: Plugin = async (ctx) => {
       autoEnableThreshold: config.todoContinuation?.autoEnableThreshold ?? 4,
       backgroundJobBoard,
     });
-    sessionGoalHook = createSessionGoalHook(ctx, config, {
+    goalHook = createGoalHook(ctx, config, {
       getAgentName: (sessionID) => sessionAgentMap.get(sessionID),
     });
     taskSessionManagerHook = createTaskSessionManagerHook(ctx, {
@@ -743,7 +743,7 @@ const OhMyOpenCodeLite: Plugin = async (ctx) => {
       }
 
       interviewManager.registerCommand(opencodeConfig);
-      sessionGoalHook.registerCommand(opencodeConfig);
+      goalHook.registerCommand(opencodeConfig);
       presetManager.registerCommand(opencodeConfig);
       subtaskCommandManager.registerCommand(opencodeConfig);
     },
@@ -806,7 +806,7 @@ const OhMyOpenCodeLite: Plugin = async (ctx) => {
       // Todo-continuation: auto-continue orchestrator on incomplete todos
       await todoContinuationHook.handleEvent(input);
 
-      sessionGoalHook.handleEvent(
+      goalHook.handleEvent(
         input as {
           event: { type: string; properties?: Record<string, unknown> };
         },
@@ -972,7 +972,7 @@ const OhMyOpenCodeLite: Plugin = async (ctx) => {
         output as { parts: Array<{ type: string; text?: string }> },
       );
 
-      await sessionGoalHook.handleCommandExecuteBefore(
+      await goalHook.handleCommandExecuteBefore(
         input as {
           command: string;
           sessionID: string;
@@ -1052,7 +1052,7 @@ const OhMyOpenCodeLite: Plugin = async (ctx) => {
         }
       }
 
-      sessionGoalHook.handleSystemTransform(input, output);
+      goalHook.handleSystemTransform(input, output);
 
       // Collapse to single system message for provider compatibility.
       // Some providers (e.g. Qwen via VLLM/DashScope) reject multiple