feat(daemon): add fixed repo mode for agents#3154
Open
lucccf wants to merge 18 commits into
Open
Conversation
…ectories Add four new agent fields: fixed_repo_enabled, fixed_repo_paths, vcs_type, and cleanup_script. When enabled, the agent works directly in a local directory instead of going through bare clone → worktree checkout. This supports large repos, non-git VCS (p4/svn), and non-VCS directories where the per-task worktree model is impractical. - DB: migration 108 adds four columns to the agent table - Server: agent create/update handlers accept and return new fields - Daemon: handleTask selects an idle path, acquires an exclusive lock, and injects MULTICA_WORK_DIR into the agent environment - CLAUDE.md: inject ## Fixed Repository and ## VCS guidance sections - CLI: agent create/update gain --fixed-repo-* flags - /repo/checkout: returns a clear error when called by a fixed-repo agent - GC: skips fixed-repo paths (they are not managed by the daemon) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…able leak - Move InjectRuntimeConfig call after if/else block, deduplicating fixed-repo and normal branches. Use taskLog consistently for logging. - Add default branch to writeVCSGuidance for unknown VCS types. - Delete lock entry from map on unlock to prevent unbounded growth. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@lucccf is attempting to deploy a commit to the IndexLabs Team on Vercel. A member of the Team first needs to authorize it. |
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The sqlc-generated agent.sql.go had SQL string constants with only 22 columns (up to thinking_level) while the Scan calls expected 26 fields (including fixed_repo_enabled, fixed_repo_paths, vcs_type, cleanup_script). This caused "number of field descriptions must equal number of destinations, got 22 and 26" errors in CI handler tests. Regenerated with sqlc v1.31.1 against the full migration set including 108_agent_fixed_repo. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The sqlc-generated INSERT now explicitly lists all 20 columns (including the 4 new fixed_repo fields), so the DB column defaults no longer apply. The onboarding shim and agent template paths were missing these fields, causing NOT NULL constraint violations. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
JSON omitempty leaves []string as nil when the field is absent from the request body. pgx translates nil slice to NULL, which violates the NOT NULL constraint. Add defaultSlice helper to coerce nil → empty slice. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The default switch case produced output for empty vcs_type ("").
Add an explicit empty-string case that produces no output.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…vars - Add init_script field (migration 109, handler, daemon, CLI) symmetric to cleanup_script - Replace tryLock with waitAndLock: tasks block in dispatched state until a path frees - Enhance script env vars: MULTICA_TASK_ID, AGENT_ID, AGENT_NAME, VCS_TYPE Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add init_script assertions to all 6 fixed repo handler test cases - Add waitAndLock test for partially available paths (skips locked, takes free) - Add waitAndLock test for multiple waiters competing for one path Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…efaults - Fix brace nesting in runAgentUpdate where --init-script was only processed when --cleanup-script was also passed - Add explicit InitScript: "" to CreateAgentFromTemplate and BootstrapOnboardingRuntime for consistency with other fixed repo fields Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
tryLock is one-shot — goroutines that fail to acquire just exit. Added spin-retry with runtime.Gosched() so all 10 goroutines eventually succeed serially, matching the test assertion. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Validate vcs_type against whitelist (git, p4, svn, none) in CreateAgent and UpdateAgent handlers, returning 400 on invalid values - Shorten agent update "no fields" error to point to --help instead of listing every flag inline Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
63660a8 to
1d22ad0
Compare
- Add fixed_repo_enabled, fixed_repo_paths, vcs_type, init_script, cleanup_script to Agent and UpdateAgentRequest TypeScript types - New FixedRepoSection component with Switch toggle and config dialog - Dialog includes VCS type dropdown, path list with add/remove, init/cleanup script inputs - i18n strings for en and zh-Hans - Wire into agent detail inspector between Properties and Details - Update test fixtures with new Agent type fields Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add fixed_repo_enabled, fixed_repo_paths, vcs_type, init_script, cleanup_script to AgentSchema to match the new Agent TypeScript type. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
e1486d5 to
e5993f5
Compare
- Fix Select onValueChange type to handle null from Base UI Select - Add fixed_repo fields to Agent mock fixtures in 4 test files Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add unit tests for the FixedRepoSection component covering readonly mode, edit mode, dialog interactions, path add/remove, and save behavior. Fix missing Agent type fields in web test helpers fixture. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Use @multica/core/i18n/react for I18nProvider and inline TEST_RESOURCES, matching the pattern used by other inspector tests. Remove unused imports. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Switch from userEvent to fireEvent for reliable jsdom interaction - Add afterEach cleanup to prevent DOM leakage between tests - Use Enter key for path addition instead of finding plus button - Remove Select interaction test (Base UI portal not testable in jsdom) - Add jsdom environment directive Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds a "fixed repo" mode that lets agents work in pre-existing local directories instead of per-task worktrees. Currently, every task goes through bare clone → worktree checkout, which fails for large monorepos, non-git VCS (Perforce, SVN), non-GitHub repos, and unversioned directories.
When an agent is configured with
fixed_repo_enabled, the daemon selects an idle local path, locks it, injects VCS-aware guidance, and lets the agent work in-place — zero clone overhead.Resolves #3153.
Type of Change
Changes Made
Database:
agenttable (fixed_repo_enabled,fixed_repo_paths,vcs_type,cleanup_script)init_scriptcolumn (entry hook, symmetric tocleanup_script)CreateAgent/UpdateAgentSQL queries with COALESCE-based partial updateHandler (API):
init_script) toCreateAgentRequest/UpdateAgentRequest/AgentResponsestructsUpdateAgentuses pointer fields (*bool,*string) for patch semantics — omitted fields are not changedvcs_typewhitelist validation (git, p4, svn, none) returning 400 on invalid valuesDaemon (task execution):
fixedRepoLockTablewithtryLock/unlockandwaitAndLockfor path-level exclusive accesswaitAndLockblocks indispatchedstate until a path frees (channel notification) instead of failing the taskrunTaskbranches onAgent.FixedRepoEnabled: fixed-repo path skipsexecenv.Prepare/Reuse, uses selected path directlyinit_script_failed(5-minute timeout)MULTICA_WORK_DIR,MULTICA_TASK_ID,MULTICA_AGENT_ID,MULTICA_AGENT_NAME,MULTICA_VCS_TYPEMULTICA_WORK_DIR+MULTICA_FIXED_REPOenv vars into agent environmentfixedRepoTasksmap for/repo/checkoutgateHealth endpoint (repo checkout gate):
/repo/checkoutreturns 400 for fixed-repo tasks with a clear error messageAgent brief injection:
writeVCSGuidancefunction injects VCS-specific rules (git/p4/svn) with safety constraintsCLI:
--fixed-repo-enabled,--fixed-repo-path(repeatable),--vcs-type,--cleanup-script,--init-scriptflags toagent createandagent update--helpUI (agent detail inspector):
FixedRepoSectioncomponent in inspector between Properties and DetailsTests:
fixed_repo_lock_test.go: exclusive locking, concurrent contention, unknown path handling,waitAndLockblocking/unblock/cancel, multi-path selection, multiple waiter competitionagent_fixed_repo_test.go: request/response JSON round-trip for all fixed repo fields (includinginit_script)runtime_config_test.go: VCS guidance output verification, fixed repo brief sectionHow to Test
Manual (requires daemon + agent runtime):
/data/repos/projectMULTICA_WORK_DIRis set in agent environmentmultica repo checkoutreturns 400 during the taskUI testing:
Checklist
fixed_repo_enabled=false(default) preserves existing behaviorAI Disclosure
AI tool used: Claude Code (Claude Opus 4.7)