Skip to content

feat(cos): split worktree and PR configs into independent settings#101

Closed
atomantic wants to merge 19 commits intomainfrom
cos/task-mn0ligpt/agent-4fd16660
Closed

feat(cos): split worktree and PR configs into independent settings#101
atomantic wants to merge 19 commits intomainfrom
cos/task-mn0ligpt/agent-4fd16660

Conversation

@atomantic
Copy link
Owner

Summary

  • Split the combined "Worktree + PR" toggle into two independent configs: useWorktree and openPR
  • Added defaultOpenPR app-level setting alongside existing defaultUseWorktree
  • When openPR is enabled, the system automatically pushes the branch and creates a PR on task completion
  • When only useWorktree is enabled (no PR), the worktree branch auto-merges to default branch on completion
  • Configs inherit from app defaults → task type overrides → individual task metadata

Behavior Matrix

useWorktree openPR Behavior
false false Commit directly to default branch
true false Work in worktree, auto-merge on completion
true true Work in worktree, push + create PR
false true Implies worktree — same as true/true

Changes

  • validation.js: Added openPR to allowed task metadata keys, defaultOpenPR to app schema
  • constants.js: Split AGENT_OPTIONS into separate Worktree and Open PR entries
  • EditAppModal.jsx: Two checkboxes (PR disabled when worktree unchecked)
  • TaskAddForm.jsx: Separate Worktree and Open PR checkboxes with dependency
  • subAgentSpawner.js: openPR-aware worktree decision, prompt instructions, and PR creation in cleanup path with parallelized push+branch-resolution
  • cos.js: applyAppWorktreeDefault handles both flags with proper cascading
  • taskSchedule.js: Updated feature-ideas and jira-sprint-manager defaults to include openPR: true
  • routes/cos.js: Pass openPR through task creation route

Test plan

  • All 1743 server tests pass
  • Verify new task form shows separate Worktree and Open PR checkboxes
  • Verify Open PR checkbox is disabled when Worktree is unchecked
  • Verify app settings show both default checkboxes
  • Test worktree-only mode auto-merges on completion
  • Test worktree+PR mode creates PR on completion

Copilot AI review requested due to automatic review settings March 21, 2026 17:37
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR splits the previously combined “Worktree + PR” behavior into two independent flags (useWorktree and openPR), adds an app-level default for PR creation, and wires the new flag through client UI, server validation, task creation, and agent completion cleanup behavior.

Changes:

  • Introduces openPR alongside useWorktree, including defaultOpenPR at the app configuration level.
  • Updates client forms/modals to display separate Worktree/Open PR checkboxes with dependency behavior.
  • Updates agent spawning/cleanup to treat openPR as implying worktree and to create PRs on successful completion.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
server/services/taskSchedule.js Enables openPR: true in taskMetadata defaults for selected scheduled task types.
server/services/subAgentSpawner.js Adds openPR handling in worktree decision logic, prompt text, and completion cleanup (push + PR creation).
server/services/cos.js Extends app-default application logic to include defaultOpenPR and openPR cascading.
server/routes/cos.js Passes openPR through the task creation route payload.
server/lib/validation.js Adds defaultOpenPR to app schema and openPR to allowed task metadata keys.
client/src/components/cos/constants.js Splits AGENT_OPTIONS entries into Worktree and Open PR.
client/src/components/cos/TaskAddForm.jsx Adds separate Worktree/Open PR toggles and submits openPR in task creation.
client/src/components/apps/EditAppModal.jsx Adds defaultOpenPR checkbox dependent on defaultUseWorktree.
Comments suppressed due to low confidence (1)

server/services/subAgentSpawner.js:1963

  • cleanupAgentWorktree now supports an openPR mode, but not all call sites pass that flag (e.g., the direct-spawn completion path still calls cleanupAgentWorktree(agentId, success) with no options). That means tasks with metadata.openPR=true can still be auto-merged instead of pushed/PR’d depending on how the agent was spawned. Please ensure all cleanupAgentWorktree invocations pass the task’s openPR (and description for PR title/body) so behavior is consistent across runner vs direct modes.
async function cleanupAgentWorktree(agentId, success, { openPR = false, description = null } = {}) {
  const { getAgent: getAgentState } = await import('./cos.js');
  const agentState = await getAgentState(agentId).catch(() => null);
  if (!agentState?.metadata?.isWorktree) return;
  // Skip cleanup for persistent feature agent worktrees (they survive across runs)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings March 21, 2026 18:05
Split the combined "Worktree + PR" toggle into two separate configs:
- useWorktree: work in an isolated git worktree on a feature branch
- openPR: open a pull request to the default branch (implies worktree)

Behavior matrix:
- Neither: commit directly to default branch
- Worktree only: work in worktree, auto-merge on completion
- Open PR (implies worktree): work in worktree, push + create PR

App-level defaults (defaultUseWorktree, defaultOpenPR) cascade into
manual and scheduled task metadata with per-task override support.
- Fall back to auto-merge when push fails (prevents commit loss)
- Fix conflicting prompt: system auto-creates PR, agent no longer told to
- Coerce openPR+useWorktree state in TaskAddForm (openPR implies worktree)
- applyAppWorktreeDefault only fills unset fields, respects task-type metadata
- Add 17 unit tests for isTruthyMeta, worktree flag resolution, and app defaults
…thy bugs

Boolean flags (useWorktree, openPR, simplify, reviewLoop) from request body
can arrive as strings like 'false' which are truthy in JavaScript. Added
explicit boolean coercion in the route layer via a toBool helper, and changed
the service layer to use strict === checks that persist both true and false
values in metadata (so app-level defaults don't override explicit user intent).
… in tests

Export isTruthyMeta from subAgentSpawner.js and applyAppWorktreeDefault
from cos.js so tests import the real functions rather than maintaining
drift-prone inline copies. Addresses Copilot review PRRT_kwDOQx8jQ8515lKk.
… auto-merging

When push fails in openPR mode, the caller opted for PR-based delivery.
Falling back to auto-merge into the local default branch is unexpected.
Instead, preserve the worktree and branch so the user can investigate
and retry the push manually.

Addresses review thread PRRT_kwDOQx8jQ8515lKs
reviewLoop requires a PR to exist during the agent's run, but openPR creates
the PR after the agent exits. Disable reviewLoop checkbox when openPR is checked,
gate review loop prompt section on !willOpenPR, and update description to clarify.
@atomantic atomantic force-pushed the cos/task-mn0ligpt/agent-4fd16660 branch from 5e687d6 to 74b9b61 Compare March 21, 2026 18:06
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (1)

server/services/subAgentSpawner.js:2669

  • simplify is checked via truthiness (task.metadata?.simplify), but task metadata values parsed from TASKS.md are strings. If simplify is ever persisted as false, it will be read as 'false' (truthy) and this section will still be enabled. Use the same boolean coercion helper as worktree/PR flags (e.g. isTruthyMeta / toBoolMeta) for simplify/reviewLoop checks.
  const digitalTwinSection = await getDigitalTwinForPrompt({
    maxTokens: config.digitalTwin?.maxContextTokens || config.soul?.maxContextTokens || 2000
  }).catch(err => {
    console.log(`⚠️ Digital twin context retrieval failed: ${err.message}`);
    return null;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Only persist true to TASKS.md metadata (not false) to avoid 'false' string
  being truthy when parsed back
- Add isFalsyMeta helper for symmetric string coercion
- Apply toBool to createJiraTicket in routes
- Send boolean values directly from TaskAddForm (not || undefined)
- Fix stale comment about auto-merge fallback
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…event partial updates overwriting stored values

Zod's .default(false) on archived, defaultUseWorktree, and defaultOpenPR
caused appUpdateSchema (appSchema.partial()) to inject false for omitted
fields, silently overwriting stored true values during partial updates.
- Clear reviewLoop state when app with defaultOpenPR is selected
- Respect explicit openPR:true in applyAppWorktreeDefault cascade
- Handle createPR non-throwing failures in openPR cleanup path
Copilot AI review requested due to automatic review settings March 21, 2026 18:29
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Enforce openPR→useWorktree invariant in toggleAppMetadataOverride and ScheduleTab
- Normalize EditAppModal state so defaultOpenPR implies defaultUseWorktree
- Add 16 unit tests for cleanupAgentWorktree openPR path
- Export cleanupAgentWorktree for testability
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Preserve worktree when createPR throws (was incorrectly falling through)
- Keep explicit false overrides in ScheduleTab metadata (filter !== undefined)
- Handle string 'false' in applyAppWorktreeDefault invariant checks
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Strip newlines/whitespace from task description before using as PR title
- Remove unused useWorktreeWasSetByTaskType variable
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Normalize openPR→useWorktree invariant bidirectionally (openPR:true forces
  useWorktree:true instead of being silently cleared)
- Fix toggleAppMetadataOverride rule ordering to respect user's toggle intent
- Propagate openPR flag in direct-spawn completion path
- Use isTruthyMeta for simplify/reviewLoop prompt checks
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…antics

- addTask persists both true and false for useWorktree/openPR/simplify/reviewLoop
  so users can explicitly override app defaults (isTruthyMeta/isFalsyMeta handle
  string round-trip from TASKS.md)
- ScheduleTab toggleMetadataField keeps only true entries (false = inherit default)
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

The task parser lowercased all metadata keys and the serializer capitalized
the first character, so openPR→OpenPR→openpr on round-trip. This broke
camelCase keys like openPR, useWorktree, reviewLoop after reload.

Now both serializer and parser preserve the original key casing.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Lowercase first character of parsed keys to handle legacy Title-Case keys
(Context→context, App→app) while preserving camelCase keys (openPR, useWorktree).
Adds test for camelCase key preservation.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- PR targets baseBranch (not devBranch) since worktrees are created from it
- Prompt says "source branch" instead of "default branch" for auto-merge
- Updated taskParser docstring for metadata key format
@atomantic atomantic closed this Mar 21, 2026
@atomantic atomantic deleted the cos/task-mn0ligpt/agent-4fd16660 branch March 21, 2026 20:23
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.

2 participants