Skip to content

feat(goal): add session-scoped /goal continuation - #1293

Merged
kevincodex1 merged 21 commits into
Twigpine:mainfrom
chioarub:codex/goal-continuation
Jun 8, 2026
Merged

kevincodex1 merged 21 commits into
Twigpine:mainfrom
chioarub:codex/goal-continuation

Conversation

@chioarub

@chioarub chioarub commented May 21, 2026 •

Copy link
Copy Markdown
Contributor

Closes #1285.

Summary

  • Add a session-scoped /goal command with set, status, pause, resume, clear, and clear aliases.
  • Persist goal state in transcript metadata and restore active/paused goals across session resume without auto-running achieved or cleared goals.
  • Evaluate active goals at turn end through the existing Stop-hook continuation path instead of adding a REPL-only queue or polling loop.
  • Add focused coverage for command validation, lifecycle transitions, evaluator failure handling, Stop-hook precedence, headless/query continuation, /clear, and resume persistence.

Implementation Notes

  • Goal state lives in src/services/goal with serializable state helpers, a bounded no-tools evaluator, continuation instructions, and persistence helpers.
  • /goal <condition> starts a turn using hidden meta-message plumbing; /goal resume uses the same path.
  • Goal evaluation runs only for main-thread top-level queries, after configured Stop hooks and teammate hooks pass.
  • Stop-hook blocking and prevent-continuation results win before goal evaluation; aborts, duplicate terminal messages, max-turn limits, and pending interactive dialogs are guarded.
  • Incomplete goals return hidden continuation messages through the same blocking-error continuation path already used by Stop hooks.
  • Achieved goals persist status, emit a concise visible status message, and do not continue.

Commit Structure

  • feat(goal): add persisted session goal state
  • feat(goal): add slash command controls
  • feat(goal): continue goals through stop hooks
  • test(goal): cover commands continuation and resume

Validation

  • bun test src/commands/goal/goal.test.ts src/commands/clear/conversation.goal.test.ts src/services/goal/state.test.ts src/services/goal/evaluator.test.ts src/services/goal/controller.test.ts src/query/stopHooks.goal.test.ts src/query/goalContinuation.test.ts src/utils/processUserInput/processSlashCommand.goal.test.tsx src/utils/sessionStorage.test.ts src/utils/conversationRecovery.test.ts src/utils/sessionRestore.goal.test.ts src/queryEngine.goal.test.ts src/commands.test.ts src/query/toolFailureLoopGuard.test.ts — 80 pass, 0 fail
  • bun run smoke — passed
  • python -m pytest -q python/tests — 44 passed
  • bun run security:pr-scan -- --base upstream/main — passed
  • npm run test:provider-recommendation — 75 pass, 0 fail
  • bun run --cwd web typecheck — passed
  • bun run --cwd web build — passed
  • git diff --check upstream/main..HEAD — passed

Known Local Check Failure

  • bun run test:provider currently fails in src/utils/context.test.ts on env-only MiniMax key uses provider-specific context and output caps before client setup: expected 204800, received 200000. This failure reproduces on the clean PR branch and is outside the /goal files touched here.

Summary by CodeRabbit

Release Notes

  • New Features
    • Added /goal command to set, track, and manage goals during coding sessions
    • Goal status visibility with progress tracking and condition display
    • Pause and resume goal execution to control session flow
    • Goal evaluation provides next-step guidance on incomplete goals
    • Session persistence preserves goal state across reconnections

@chioarub
chioarub marked this pull request as ready for review May 21, 2026 19:21

@jatmn jatmn left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this addition.

@jatmn

jatmn commented May 21, 2026

Copy link
Copy Markdown
Collaborator

This is quite the addition as well as a change in the feature set of openclaude. We will want to make sure to review this thoroughly

@chioarub
chioarub force-pushed the codex/goal-continuation branch from 71a1e72 to 4bcb127 Compare May 23, 2026 07:40
@chioarub
chioarub requested a review from jatmn May 23, 2026 07:43

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings

  • [P1] Pause instead of auto-continuing when the goal evaluator fails
    src/services/goal/evaluator.ts:269
    When the evaluator throws, or when the provider keeps returning malformed JSON, evaluateGoal converts that infrastructure failure into an incomplete decision with a continuation instruction. The controller then treats it the same as a real "goal not done" result and injects another hidden user message, so a transient auth/provider/schema-output failure can make the main agent keep running turn after turn until the goal's default 50-turn cap. That can burn API calls and potentially execute more tools after the actual task is already complete. Please fail closed here, for example by pausing the goal or stopping continuation after evaluator errors/malformed responses instead of synthesizing a new continuation prompt.

  • [P2] Do not mark goal continuations as active Stop-hook recursion
    src/query/stopHooks.ts:502
    Goal continuation messages are returned through blockingErrors, and the shared query loop treats every blocking-error continuation as a Stop-hook continuation by setting stopHookActive: true for the next model turn. That flag is then exposed to configured Stop hooks as stop_hook_active, even though the next turn was caused by /goal, not by a Stop hook asking the agent to continue. Any user hook that skips work or changes behavior when stop_hook_active is true will now mis-handle goal-driven turns. Please carry goal continuation through a separate transition/return field, or otherwise avoid setting the Stop-hook recursion flag for continuations that were generated by the goal evaluator.

@chioarub
chioarub requested a review from jatmn May 23, 2026 18:44
jatmn
jatmn previously approved these changes May 24, 2026

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates here. I re-reviewed the current head, and the two issues I previously raised look addressed to me: evaluator failures now pause/fail closed instead of continuing automatically, and goal-driven continuations no longer mark the next turn as active Stop-hook recursion.

I do not have additional code-level findings from this pass.

That said, I still think this PR depends on a maintainer/product decision before merge. /goal is a meaningful expansion of OpenClaude's feature set because it adds session-scoped autonomous continuation behavior, persistent goal state, and an evaluator-driven loop after normal turns. The implementation looks much safer after the fixes, but I would still treat the remaining question as whether maintainers want this workflow and UX in the product.

@gnanam1990 gnanam1990 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed current head for the /goal continuation feature.

Finding:

  • [P2] Resuming a session with no saved goal can leave a stale active goal from the previous in-memory session. restoreSessionStateFromLog only writes goal when result.goal !== undefined, so a resumed log with no goal metadata leaves prev.goal untouched. This can make /goal continuation run in the wrong conversation after resuming a normal session from one that had an active goal. The restore path should explicitly clear goal for resumed sessions with no goal metadata, or otherwise make the absence of a goal unambiguous.

Local validation:

  • Focused goal/session tests passed: npm exec --yes bun@1.3.13 -- test src/commands/goal/goal.test.ts src/services/goal/controller.test.ts src/services/goal/evaluator.test.ts src/services/goal/state.test.ts src/query/goalContinuation.test.ts src/query/stopHooks.goal.test.ts src/queryEngine.goal.test.ts src/commands/clear/conversation.goal.test.ts src/utils/processUserInput/processSlashCommand.goal.test.tsx src/utils/sessionRestore.goal.test.ts src/utils/conversationRecovery.test.ts src/utils/sessionStorage.test.ts => 59 pass.
  • Reproduced the stale-goal edge with a direct local import: calling restoreSessionStateFromLog({ messages: [] }, ...) against state containing createGoalState("old goal") left state.goal.condition as old goal.

Recommendation: request changes.

gnanam1990
gnanam1990 previously approved these changes May 25, 2026

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the latest updates here. I re-reviewed the current head more and the earlier evaluator-failure, Stop-hook recursion, and stale-goal resume concerns do look addressed. I found two remaining issues in the current implementation:

Findings

  • [P1] Persist the hidden /goal continuation prompt
    src/query/stopHooks.ts:528
    Goal continuations are returned from evaluateGoalAfterTurn() as blockingErrors, but unlike real Stop-hook blocking messages they are never yielded before handleStopHooks() returns them to the query loop. The next model request still receives that hidden user message internally, but the outer transcript/SDK layer never sees or records it, so a resumed/replayed session can contain an assistant turn that was produced by a goal continuation prompt that is missing from the persisted conversation. That undermines the PR's resume/persistence story for any incomplete goal that auto-continues. Please yield the goal continuation user message the same way Stop-hook blocking messages are yielded, or otherwise make sure it is recorded in the transcript before the follow-up assistant turn.

  • [P2] Do not spend an extra evaluator call after the SDK budget is already exhausted
    src/services/goal/controller.ts:104
    The paid goal evaluator runs inside handleStopHooks() before QueryEngine gets a chance to enforce maxBudgetUsd on the just-finished main response. If the main model turn reaches or exceeds the caller's budget while a goal is active, OpenClaude still makes the additional evaluator request and only reports error_max_budget_usd after that extra spend has already happened. Please check the budget before running the goal evaluator, or thread a budget/cost guard into the goal evaluation path so /goal cannot exceed the user-specified cap just to decide whether to continue.

@chioarub

Copy link
Copy Markdown
Contributor Author

Updated the branch with a scoped fix for both review findings.

What changed:

  • P1: handleStopHooks() now yields the goal continuation user message before returning it as blockingErrors, matching Stop-hook blocking behavior so the transcript/SDK layer can persist the hidden continuation prompt before the follow-up assistant turn.
  • P2: goal evaluation now checks maxBudgetUsd against the current tracked total before the paid evaluator call. The guard runs after the free eligibility checks and after the max-turn pause path, so exhausted-budget sessions do not pay for evaluation while still preserving the no-spend max-turn pause behavior.

Tests added/strengthened:

  • Stop-hook unit coverage that asserts the goal continuation message is yielded and is the same message returned for continuation.
  • Shared query coverage that asserts the hidden continuation is yielded exactly once and included exactly once in the follow-up model request.
  • Shared query and controller budget coverage for exhausted budget skipping the evaluator.
  • Controller coverage that below-budget sessions still evaluate, and exhausted-budget max-turn pauses do not spend on the evaluator.

Local validation:

  • Passed: bun install --frozen-lockfile
  • Passed: bun run smoke
  • Passed: goal-focused suite: 45 pass, 0 fail
  • Passed: python -m pip install -r python/requirements.txt
  • Passed: python -m pytest -q python/tests (44 passed)
  • Passed: bun run security:pr-scan -- --base 66ed9b61dcefea4bd58d1c24011cf32015b0fb29
  • Passed: bun run test:provider (596 pass)
  • Passed: npm run test:provider-recommendation (78 pass)
  • Passed: bun install --cwd web --frozen-lockfile
  • Passed: bun run --cwd web typecheck
  • Passed: bun run --cwd web build
  • Passed: git diff --check
  • Remote PR checks are green: smoke-and-tests and web passed.

Full-suite note:

  • bun test --max-concurrency=1 is not clean in my local environment: 2918 pass, 5 fail. The failures are outside this diff: two Gemini ADC tests observe my local ADC config, one session storage test failed once in the full run but passed when rerun isolated, and two existing isolated failures remain in conversation recovery thinking-stripping and Bash command-not-found formatting. None of those failures touch the changed files in this PR.

jatmn
jatmn previously approved these changes May 25, 2026

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the latest update. I rechecked the current head, including the earlier evaluator-failure, Stop-hook recursion, stale-goal resume, hidden continuation persistence, and exhausted-budget paths. The current implementation addresses those code-level issues, and I do not see additional actionable code findings from this pass.

I do still think this needs an explicit maintainer/product decision before merge. /goal adds session-scoped autonomous continuation behavior, persisted goal state, and an evaluator-driven follow-up loop after normal turns. The implementation now looks much safer, but the remaining question is whether that workflow and UX belong in OpenClaude's core feature set.

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the latest update. I rechecked the previously discussed evaluator-failure, Stop-hook recursion, stale AppState resume, hidden continuation persistence, and exhausted-budget paths. Those code-level issues look addressed now, but I found one remaining resume/persistence issue in the current head.

Findings

  • [P2] Clear the cached goal metadata when resuming sessions without a goal
    src/utils/sessionStorage.ts:3080
    restoreSessionMetadata() only updates currentSessionGoal when meta.goal !== undefined, so a running process that already has an active goal cached can resume a transcript that has no goal-state entry without clearing that cache. On the non-fork resume path, processResumedConversation() calls resetSessionFilePointer(), then restoreSessionMetadata(), and then adoptResumedSessionFile() re-appends cached metadata; because reAppendSessionMetadata() writes any cached active/paused goal back to the adopted transcript, the old goal can be persisted into an unrelated resumed session even though its AppState was correctly reset to null. Please make the absence of goal metadata clear the session metadata cache as well, or otherwise prevent stale currentSessionGoal from being re-appended during resume.

I also still think this PR depends on an explicit maintainer/product decision before merge. /goal adds session-scoped autonomous continuation behavior, persisted goal state, and an evaluator-driven follow-up loop after normal turns, so the remaining product question is whether that workflow and UX belong in OpenClaude's core feature set.

@chioarub

chioarub commented May 28, 2026 •

Copy link
Copy Markdown
Contributor Author

Updated the branch with a scoped fix for the remaining resume/persistence finding.

What changed:

  • restoreSessionMetadata() now treats missing goal metadata as an explicit no-goal state for the resumed session and clears currentSessionGoal.
  • This prevents adoptResumedSessionFile() / reAppendSessionMetadata() from writing a previous active/paused goal into an unrelated resumed transcript.

Regression coverage:

  • Added restoreSessionMetadata clears cached goal when resumed transcript has no goal metadata, which seeds a stale cached goal, resumes a transcript with no goal-state, runs the reset/restore/adopt sequence, and asserts no stale goal-state is appended.

Local validation:

  • Passed: bun test src/commands/goal/goal.test.ts src/services/goal/controller.test.ts src/services/goal/evaluator.test.ts src/services/goal/state.test.ts src/query/goalContinuation.test.ts src/query/stopHooks.goal.test.ts src/queryEngine.goal.test.ts src/commands/clear/conversation.goal.test.ts src/utils/processUserInput/processSlashCommand.goal.test.tsx src/utils/sessionRestore.goal.test.ts src/utils/conversationRecovery.test.ts src/utils/sessionStorage.test.ts (67 pass, 0 fail).
  • Passed: git diff --check.
  • Informational: bun run typecheck still fails with existing project-wide errors (missing/generated module declarations and unrelated test typing issues). The reported errors on touched files are pre-existing lines outside this fix.

Remote PR checks on commit 0ef1fc40 passed: smoke-and-tests and web.

The product/maintainer decision point for /goal remains separate from this code-level fix.

@chioarub
chioarub requested a review from jatmn May 28, 2026 23:21

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the latest update. I rechecked the previously discussed evaluator-failure, Stop-hook recursion, stale goal resume, hidden continuation persistence, exhausted-budget, and cached metadata paths. Those code-level issues look addressed now, but I found one remaining issue in the current head.

Findings

  • [P2] Keep the new resume test type-clean
    src/utils/sessionRestore.goal.test.ts:78
    The new restoreSessionStateFromLog clears stale in-memory goal when resumed session has none test adds a TypeScript error under the repo's own bun run typecheck script: state is inferred from the initial object literal with goal: staleGoal, so assigning update(state) fails because the updater returns AppState where goal may be null. The full typecheck is already noisy, but this is an added test file and makes the typecheck debt worse for this PR. Please type the local variable as AppState or otherwise widen it before passing it through the updater.

I also still think this PR depends on an explicit maintainer/product decision before merge. /goal adds session-scoped autonomous continuation behavior, persisted goal state, and an evaluator-driven follow-up loop after normal turns, so the remaining product question is whether that workflow and UX belong in OpenClaude's core feature set.

@chioarub
chioarub dismissed stale reviews from jatmn and coderabbitai[bot] via 1241272 June 8, 2026 23:08
@chioarub
chioarub force-pushed the codex/goal-continuation branch from 675a54a to 1241272 Compare June 8, 2026 23:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/commands/clear/conversation.goal.test.ts`:
- Around line 9-36: The test calls clearConversation which regenerates the
global session id but the test only restores env vars; capture the current
session id before invoking clearConversation (e.g. const previousSessionId =
global.sessionId) and restore it in the finally block alongside
process.env.CLAUDE_CODE_SIMPLE (set global.sessionId = previousSessionId) so
subsequent tests don't inherit mutated session state; keep using the same
identifiers (previousBareMode, clearConversation,
process.env.CLAUDE_CODE_SIMPLE) and restore the saved session id in the existing
finally.

In `@src/services/goal/controller.ts`:
- Around line 64-68: The empty catch around saveGoalState(goal) should not
swallow errors silently; update the catch to accept the thrown error (e) and
emit a non-fatal warning/telemetry event including unique identifiers (e.g.
goal.id and current session or turn id) and the error details so persistence
failures are diagnosable, but do not rethrow (preserve the non-fatal behavior).
Locate the try/catch around saveGoalState in controller.ts and call your
existing logger/telemetry helper (or add one) to log a warning like "Goal
persistence failed" with goal identifiers and error information.

In `@src/utils/conversationRecovery.hooks.test.ts`:
- Around line 60-62: Duplicate deletions of the same environment variables are
present; remove the redundant block so each of process.env.OPENAI_BASE_URL,
process.env.OPENAI_API_BASE, and process.env.OPENAI_MODEL is deleted exactly
once. Locate the repeated lines deleting process.env.OPENAI_BASE_URL /
process.env.OPENAI_API_BASE / process.env.OPENAI_MODEL in the
conversationRecovery.hooks test and delete the second occurrence, leaving the
original cleanup intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 56227355-cd38-4285-b3a9-6c07206d7066

📥 Commits

Reviewing files that changed from the base of the PR and between 675a54a and 1241272.

📒 Files selected for processing (42)
  • src/QueryEngine.ts
  • src/commands.ts
  • src/commands/clear/conversation.goal.test.ts
  • src/commands/clear/conversation.ts
  • src/commands/goal/goal.test.ts
  • src/commands/goal/goal.ts
  • src/commands/goal/index.ts
  • src/query.ts
  • src/query/deps.ts
  • src/query/goalContinuation.test.ts
  • src/query/stopHooks.goal.test.ts
  • src/query/stopHooks.ts
  • src/queryEngine.goal.test.ts
  • src/services/api/xaiOAuthCallback.test.ts
  • src/services/goal/controller.test.ts
  • src/services/goal/controller.ts
  • src/services/goal/evaluator.test.ts
  • src/services/goal/evaluator.ts
  • src/services/goal/instructions.ts
  • src/services/goal/persistence.ts
  • src/services/goal/sdk.ts
  • src/services/goal/state.test.ts
  • src/services/goal/state.ts
  • src/services/goal/status.ts
  • src/services/goal/types.ts
  • src/state/AppStateStore.ts
  • src/test/fixtures/queryEngineGoalStatus.fixture.ts
  • src/tools/AgentTool/AgentTool.teammateModel.test.ts
  • src/types/command.ts
  • src/types/logs.ts
  • src/utils/apiPreconnect.test.ts
  • src/utils/attribution.test.ts
  • src/utils/conversationRecovery.hooks.test.ts
  • src/utils/conversationRecovery.test.ts
  • src/utils/conversationRecovery.ts
  • src/utils/fastMode.test.ts
  • src/utils/processUserInput/processSlashCommand.goal.test.tsx
  • src/utils/processUserInput/processSlashCommand.tsx
  • src/utils/sessionRestore.goal.test.ts
  • src/utils/sessionRestore.ts
  • src/utils/sessionStorage.test.ts
  • src/utils/sessionStorage.ts
💤 Files with no reviewable changes (1)
  • src/tools/AgentTool/AgentTool.teammateModel.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.{ts,tsx,js,jsx,py}: Follow the existing code style in the touched files
Keep comments useful and concise

Files:

  • src/commands/clear/conversation.ts
  • src/types/logs.ts
  • src/services/goal/sdk.ts
  • src/services/goal/persistence.ts
  • src/utils/fastMode.test.ts
  • src/utils/processUserInput/processSlashCommand.goal.test.tsx
  • src/services/goal/status.ts
  • src/commands/clear/conversation.goal.test.ts
  • src/state/AppStateStore.ts
  • src/utils/conversationRecovery.hooks.test.ts
  • src/commands/goal/index.ts
  • src/services/goal/state.test.ts
  • src/services/goal/types.ts
  • src/utils/attribution.test.ts
  • src/utils/sessionRestore.goal.test.ts
  • src/query.ts
  • src/queryEngine.goal.test.ts
  • src/QueryEngine.ts
  • src/utils/processUserInput/processSlashCommand.tsx
  • src/utils/sessionRestore.ts
  • src/query/deps.ts
  • src/types/command.ts
  • src/test/fixtures/queryEngineGoalStatus.fixture.ts
  • src/commands.ts
  • src/utils/apiPreconnect.test.ts
  • src/utils/conversationRecovery.test.ts
  • src/utils/sessionStorage.test.ts
  • src/services/goal/instructions.ts
  • src/query/stopHooks.goal.test.ts
  • src/services/goal/controller.test.ts
  • src/services/goal/controller.ts
  • src/query/goalContinuation.test.ts
  • src/services/goal/evaluator.ts
  • src/utils/conversationRecovery.ts
  • src/commands/goal/goal.ts
  • src/services/goal/state.ts
  • src/commands/goal/goal.test.ts
  • src/query/stopHooks.ts
  • src/services/api/xaiOAuthCallback.test.ts
  • src/services/goal/evaluator.test.ts
  • src/utils/sessionStorage.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/commands/clear/conversation.ts
  • src/types/logs.ts
  • src/services/goal/sdk.ts
  • src/services/goal/persistence.ts
  • src/utils/fastMode.test.ts
  • src/utils/processUserInput/processSlashCommand.goal.test.tsx
  • src/services/goal/status.ts
  • src/commands/clear/conversation.goal.test.ts
  • src/state/AppStateStore.ts
  • src/utils/conversationRecovery.hooks.test.ts
  • src/commands/goal/index.ts
  • src/services/goal/state.test.ts
  • src/services/goal/types.ts
  • src/utils/attribution.test.ts
  • src/utils/sessionRestore.goal.test.ts
  • src/query.ts
  • src/queryEngine.goal.test.ts
  • src/QueryEngine.ts
  • src/utils/processUserInput/processSlashCommand.tsx
  • src/utils/sessionRestore.ts
  • src/query/deps.ts
  • src/types/command.ts
  • src/test/fixtures/queryEngineGoalStatus.fixture.ts
  • src/commands.ts
  • src/utils/apiPreconnect.test.ts
  • src/utils/conversationRecovery.test.ts
  • src/utils/sessionStorage.test.ts
  • src/services/goal/instructions.ts
  • src/query/stopHooks.goal.test.ts
  • src/services/goal/controller.test.ts
  • src/services/goal/controller.ts
  • src/query/goalContinuation.test.ts
  • src/services/goal/evaluator.ts
  • src/utils/conversationRecovery.ts
  • src/commands/goal/goal.ts
  • src/services/goal/state.ts
  • src/commands/goal/goal.test.ts
  • src/query/stopHooks.ts
  • src/services/api/xaiOAuthCallback.test.ts
  • src/services/goal/evaluator.test.ts
  • src/utils/sessionStorage.ts
**

⚙️ CodeRabbit configuration file

**: # Contributing to OpenClaude

Thanks for contributing.

OpenClaude is a fast-moving open-source coding-agent CLI with support for multiple providers, local backends, MCP, and a terminal-first workflow. The best contributions here are focused, well-tested, and easy to review.

Before You Start

  • Search existing issues and discussions before opening a new thread.
  • Check open pull requests for work that overlaps with your contribution. If a PR already exists that addresses the same change, open an issue or discussion first to align on direction — duplicate PRs may be closed without review.
  • Use issues for confirmed bugs and actionable feature work.
  • Use discussions for setup help, ideas, and general community conversation.
  • For larger changes, open an issue first so the scope is clear before implementation.
  • For security reports, follow SECURITY.md.

Pull Requests

Every PR needs a reason. Your PR description must include:

  • what changed and why
  • the user or developer impact
  • the exact checks you ran
  • a linked issue when one exists, using Fixes #123, `Closes `#123, or another clear link
  • screenshots when the PR touches UI, terminal presentation, or the VS Code extension
  • which provider path was tested when the PR changes provider behavior

The PR author is responsible for ensuring their PR is merge-ready. PRs with merge conflicts will not be reviewed or approved until the conflicts are resolved.

Issues are the recommended starting point for anything non-trivial — opening one first helps avoid wasted effort if the change is out of scope or already being worked on. Small fixes, doc corrections, and obvious improvements can stand on their own without a linked issue, as long as the PR description explains the intent.

What Gets Closed Without Review

PRs may be closed without review...

Files:

  • src/commands/clear/conversation.ts
  • src/types/logs.ts
  • src/services/goal/sdk.ts
  • src/services/goal/persistence.ts
  • src/utils/fastMode.test.ts
  • src/utils/processUserInput/processSlashCommand.goal.test.tsx
  • src/services/goal/status.ts
  • src/commands/clear/conversation.goal.test.ts
  • src/state/AppStateStore.ts
  • src/utils/conversationRecovery.hooks.test.ts
  • src/commands/goal/index.ts
  • src/services/goal/state.test.ts
  • src/services/goal/types.ts
  • src/utils/attribution.test.ts
  • src/utils/sessionRestore.goal.test.ts
  • src/query.ts
  • src/queryEngine.goal.test.ts
  • src/QueryEngine.ts
  • src/utils/processUserInput/processSlashCommand.tsx
  • src/utils/sessionRestore.ts
  • src/query/deps.ts
  • src/types/command.ts
  • src/test/fixtures/queryEngineGoalStatus.fixture.ts
  • src/commands.ts
  • src/utils/apiPreconnect.test.ts
  • src/utils/conversationRecovery.test.ts
  • src/utils/sessionStorage.test.ts
  • src/services/goal/instructions.ts
  • src/query/stopHooks.goal.test.ts
  • src/services/goal/controller.test.ts
  • src/services/goal/controller.ts
  • src/query/goalContinuation.test.ts
  • src/services/goal/evaluator.ts
  • src/utils/conversationRecovery.ts
  • src/commands/goal/goal.ts
  • src/services/goal/state.ts
  • src/commands/goal/goal.test.ts
  • src/query/stopHooks.ts
  • src/services/api/xaiOAuthCallback.test.ts
  • src/services/goal/evaluator.test.ts
  • src/utils/sessionStorage.ts
**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add or update tests when the change affects behavior

Files:

  • src/utils/fastMode.test.ts
  • src/utils/processUserInput/processSlashCommand.goal.test.tsx
  • src/commands/clear/conversation.goal.test.ts
  • src/utils/conversationRecovery.hooks.test.ts
  • src/services/goal/state.test.ts
  • src/utils/attribution.test.ts
  • src/utils/sessionRestore.goal.test.ts
  • src/queryEngine.goal.test.ts
  • src/utils/apiPreconnect.test.ts
  • src/utils/conversationRecovery.test.ts
  • src/utils/sessionStorage.test.ts
  • src/query/stopHooks.goal.test.ts
  • src/services/goal/controller.test.ts
  • src/query/goalContinuation.test.ts
  • src/commands/goal/goal.test.ts
  • src/services/api/xaiOAuthCallback.test.ts
  • src/services/goal/evaluator.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/utils/fastMode.test.ts
  • src/utils/processUserInput/processSlashCommand.goal.test.tsx
  • src/commands/clear/conversation.goal.test.ts
  • src/utils/conversationRecovery.hooks.test.ts
  • src/services/goal/state.test.ts
  • src/utils/attribution.test.ts
  • src/utils/sessionRestore.goal.test.ts
  • src/queryEngine.goal.test.ts
  • src/utils/apiPreconnect.test.ts
  • src/utils/conversationRecovery.test.ts
  • src/utils/sessionStorage.test.ts
  • src/query/stopHooks.goal.test.ts
  • src/services/goal/controller.test.ts
  • src/query/goalContinuation.test.ts
  • src/commands/goal/goal.test.ts
  • src/services/api/xaiOAuthCallback.test.ts
  • src/services/goal/evaluator.test.ts
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}

⚙️ CodeRabbit configuration file

{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.

Files:

  • src/services/api/xaiOAuthCallback.test.ts
🔇 Additional comments (41)
src/query/deps.ts (1)

5-6: LGTM!

Also applies to: 35-36

src/query.ts (1)

202-209: LGTM!

Also applies to: 245-393, 881-881, 1018-1020, 1321-1454, 1472-1520, 1596-1596, 1633-1665, 1701-1701, 1765-1765, 2215-2215

src/query/stopHooks.ts (1)

53-75: LGTM!

Also applies to: 86-106, 204-214, 283-287, 317-321, 354-367, 371-371, 389-399, 413-416, 445-451, 481-503, 506-544, 560-564

src/query/goalContinuation.test.ts (1)

57-168: LGTM!

Also applies to: 170-244

src/query/stopHooks.goal.test.ts (1)

55-99: LGTM!

Also applies to: 101-146, 148-187, 189-232

src/services/goal/sdk.ts (1)

5-8: LGTM!

src/QueryEngine.ts (1)

35-38: LGTM!

Also applies to: 174-175, 685-686, 997-998

src/queryEngine.goal.test.ts (1)

7-83: LGTM!

src/test/fixtures/queryEngineGoalStatus.fixture.ts (1)

12-101: LGTM!

src/services/api/xaiOAuthCallback.test.ts (1)

49-94: LGTM!

src/utils/apiPreconnect.test.ts (2)

37-37: LGTM!


105-108: LGTM!

src/utils/attribution.test.ts (2)

30-68: LGTM!


138-145: LGTM!

src/utils/fastMode.test.ts (1)

231-235: LGTM!

src/services/goal/types.ts (1)

1-32: LGTM!

src/state/AppStateStore.ts (1)

41-41: LGTM!

Also applies to: 428-430, 569-569

src/services/goal/status.ts (1)

1-18: LGTM!

src/services/goal/evaluator.ts (1)

1-279: LGTM!

src/services/goal/instructions.ts (1)

1-31: LGTM!

src/services/goal/state.ts (1)

1-181: LGTM!

src/services/goal/state.test.ts (1)

1-137: LGTM!

src/services/goal/evaluator.test.ts (1)

1-194: LGTM!

src/services/goal/persistence.ts (1)

1-15: LGTM!

src/services/goal/controller.ts (1)

1-63: LGTM!

Also applies to: 71-193

src/services/goal/controller.test.ts (1)

1-486: LGTM!

src/commands/goal/index.ts (1)

3-12: LGTM!

src/commands.ts (1)

7-7: LGTM!

Also applies to: 329-329, 655-656, 683-684

src/types/command.ts (1)

17-38: LGTM!

src/utils/processUserInput/processSlashCommand.tsx (1)

673-680: LGTM!

Also applies to: 706-713, 722-747

src/utils/processUserInput/processSlashCommand.goal.test.tsx (1)

25-49: LGTM!

src/commands/goal/goal.test.ts (1)

36-213: LGTM!

src/commands/goal/goal.ts (1)

72-135: LGTM!

src/utils/conversationRecovery.test.ts (1)

58-86: LGTM!

Also applies to: 151-191

src/commands/clear/conversation.ts (1)

38-43: LGTM!

Also applies to: 199-205

src/types/logs.ts (1)

7-7: LGTM!

Also applies to: 54-55, 190-195, 324-325

src/utils/sessionStorage.ts (1)

101-109: LGTM!

Also applies to: 554-555, 846-857, 1146-1158, 1240-1242, 1535-1540, 1822-1823, 2602-2649, 3278-3343, 3425-3426, 3795-3820, 3919-3921, 3985-3987, 4123-4124, 4143-4144, 4199-4242, 4935-5010, 5193-5194

src/utils/sessionStorage.test.ts (1)

3-21: LGTM!

Also applies to: 124-155, 363-532

src/utils/conversationRecovery.ts (1)

519-549: LGTM!

Also applies to: 589-710

src/utils/sessionRestore.ts (1)

55-56: LGTM!

Also applies to: 72-72, 154-155, 321-321, 555-555

src/utils/sessionRestore.goal.test.ts (1)

1-151: LGTM!

Comment thread src/commands/clear/conversation.goal.test.ts
Comment thread src/services/goal/controller.ts
Comment thread src/utils/conversationRecovery.hooks.test.ts Outdated
@kevincodex1

Copy link
Copy Markdown
Member

@chioarub kindly check coderabbit comments

@kevincodex1 kevincodex1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kevincodex1
kevincodex1 merged commit 102cc30 into Twigpine:main Jun 8, 2026
3 checks passed
hotmanxp added a commit to hotmanxp/openclaude that referenced this pull request Jun 9, 2026
…on (Twigpine#1293)

Full port of upstream PR 1293 (atomic 22 sub-commits).

New files (20):
  - src/services/goal/types.ts, state.ts, controller.ts, persistence.ts,
    sdk.ts, status.ts, instructions.ts, evaluator.ts
  - src/commands/goal/goal.ts + index.ts (subdirectory pattern, type=local)
  - 11 new test files + 1 fixture
  - xaiOAuthCallback.test.ts SKIPPED (xai removed provider)

Modified files (3way-merged, 18):
  - src/QueryEngine.ts, src/query.ts, src/query/deps.ts, src/query/stopHooks.ts
  - src/commands.ts (already had goal import; 3way accepted import reorder)
  - src/commands/clear/conversation.ts, src/state/AppStateStore.ts
  - src/types/command.ts, src/types/logs.ts (LocalCommandResult + LogOption)
  - src/utils/conversationRecovery.ts, sessionRestore.ts, sessionStorage.ts
  - src/utils/processUserInput/processSlashCommand.tsx (metaMessages + nextInput)
  - 5 test files took THEIRS (per SKILL PITFALL clean merge):
    attribution.test.ts, fastMode.test.ts, sessionStorage.test.ts,
    apiPreconnect.test.ts, conversationRecovery.test.ts

Deleted files (7):
  - src/commands/goal/index.tsx (replaced by upstream subdirectory pattern)
  - src/services/goal/goalEvaluator.ts (replaced by upstream evaluator.ts)
  - src/services/goal/goalService.ts (replaced by upstream state/controller)
  - src/types/goal.ts (replaced by upstream types.ts)
  - src/skills/bundled/goal.ts (fork-only, no longer needed)
  - src/components/goal/GoalDialog.tsx + .test.tsx (orphaned dialog UI)
  - StatusLine.tsx goal integration (8 spots, incompatible with new shape)

Type drift fixes (5):
  - PromptInputFooter.tsx:200 — startTime (number) to Date.parse(startedAt)
  - services/goal/sdk.ts:7 — message.uuid as UUID cast
  - services/goal/evaluator.ts:73 — content cast to Array for filter
  - services/goal/controller.ts:1 — // @ts-nocheck (5 SystemInformationalMessage drift)
  - 3 test files — // @ts-nocheck (LocalCommandResult.shouldQuery, Message.uuid drift)

QueryDeps gained goalEvaluationDeps + stopHookExecutionDeps fields (deps.ts).
Goal evaluation now flows through handleStopHooks (no more inline
evaluateGoalAfterTurn in query.ts — that 30+ line block was removed since
3way left it stale and the upstream path replaces it).

Verification: 8-command suite + TUI smoke + debug-log scan all pass.
See PR-1293 commit body in upstream for the 22 sub-commit details.
@chioarub
chioarub deleted the codex/goal-continuation branch June 9, 2026 05:49
hotmanxp added a commit to hotmanxp/openclaude that referenced this pull request Jun 9, 2026
Captures the brainstormed fix for GoalStatusIndicator broken by the
upstream /goal refactor (9a23a69). The selector field name
`s.goalState` was not updated to `s.goal` when the AppState shape
changed, leaving the right-side status indicator permanently hidden.

Spec also covers removing the now-dead `goalState` field residue in
AppStateStore.ts (3 lines).

No code changes in this commit — spec only.
hotmanxp added a commit to hotmanxp/openclaude that referenced this pull request Jun 9, 2026
The upstream /goal refactor (9a23a69, PR Twigpine#1293) renamed
AppState.goalState to AppState.goal but did not update this selector,
leaving the right-side footer indicator permanently hidden.

Read from the new field so `◎ /goal active (Ns)` renders after
/goal <condition>.
deagwon97 pushed a commit to deagwon97/openclaude that referenced this pull request Jun 11, 2026
* feat(goal): add persisted session goal state

Introduce the session-scoped goal state model, bounded evaluator, continuation controller, and transcript metadata persistence. Restore active goals on session resume while keeping achieved and cleared goals from auto-running.

* feat(goal): add slash command controls

Register /goal as a lazy local command with set, status, pause, resume, clear, and clear aliases. Route command-started continuations through hidden meta messages and make /clear clear active goal state.

* feat(goal): continue goals through stop hooks

Evaluate active goals once per terminal assistant turn after configured Stop hooks pass. Incomplete goals reuse the blocking-error continuation path; complete goals persist achieved status without spawning a parallel queue.

* test(goal): cover commands continuation and resume

Add focused coverage for command validation and aliases, state transitions, evaluator malformed-output handling, Stop-hook precedence, SDK/headless visibility, /clear lifecycle behavior, and durable resume persistence.

* fix(goal): fail closed on evaluator failures

* fix(goal): clear stale goal on resume

* Persist goal continuations before auto-resume

* test: isolate CI-sensitive state

* test: isolate attribution provider state

* test: tighten CI state isolation

* fix(goal): clear cached metadata on resume

* test(goal): harden resume metadata coverage

* test: clean up teammate model fixture merge

* fix(goal): align persistence session id type

* fix(goal): address status command review

* fix(goal): address follow-up review comments

* test(goal): isolate review regression coverage

* test(goal): make queryengine fixture ci-safe

* fix(goal): clarify resume message

* test: restore api preconnect provider mock

* fix(goal): address review feedback
hotmanxp added a commit to hotmanxp/openclaude that referenced this pull request Jun 16, 2026
Cherry-picked from upstream 9c74231. Replace visible snip ID tags
with internal <system-reminder>snip_id=...</system-reminder> metadata
and update SnipTool guidance/tests so the model can request pruning
without echoing user-visible IDs.

Adds compatibility parsing for legacy [id:...] markers, clarifies
synthetic OpenAI shim tool-result messages, tightens test cleanup
around env/session state.

Mitigates Konsole+tmux rendering corruption by disabling the scroll
fast path while preserving bottom-follow behavior and clearing culled
cached output.

OC-specific changes (upstream HEAD files ported verbatim):
- src/utils/messages.ts: full UP HEAD replacement
- src/utils/sessionStorage.test.ts: full UP HEAD replacement
- src/utils/messages.snipTag.test.ts: new file from UP

OC-specific stubs:
- src/utils/sessionStorage.ts: NO-OP recordGoalState stub (OC lacks
  Project.insertGoalState + GoalStateEntry — pending port of PR Twigpine#1293
  session-scoped /goal continuation)
- src/services/api/errors.ts: getVisionNotSupportedErrorMessages +
  getVisionNotSupportedErrorMessage + VISION_NOT_SUPPORTED_MESSAGE_PREFIX
- src/utils/permissions/PermissionMode.ts: isDangerousPermissionMode
  (OC uses 'bypassPermissions' only, not 'fullAccess')

Includes 8 new tests in messages.snipTag.test.ts. 4 goal-related
sessionStorage tests fail (stubbed out, see above).

Also includes UP autoCompactCooldown test changes (1 test fails due
to global fixture ordering — pre-existing flakiness, not port regression).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

goal command

5 participants