Add Factory AI Droid agent integration#435
Conversation
Implement the agent.Agent interface for Factory AI Droid, including session lifecycle management, hook handling, and JSONL transcript parsing. Register the new agent in the agent registry and wire it into config detection, hooks, and summarization. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Entire-Checkpoint: 7fc7ad5b176b
The Droid transcript parser was using the shared Claude Code parser which
expects {"type":"assistant",...} but Droid uses {"type":"message","message":
{"role":"assistant",...}}. This caused ExtractModifiedFiles to skip all lines,
preventing checkpoint creation entirely.
- Add Droid-specific JSONL parser (ParseDroidTranscript) that normalizes the
envelope format by extracting message.role as Line.Type
- Wire Droid parser into all transcript analysis functions (lifecycle.go,
transcript.go) replacing shared transcript.ParseFromFileAtLine calls
- Remove TranscriptPreparer/sentinel flush code (Droid never writes hook
commands to JSONL, causing a 3s timeout on every turn-end)
- Add idempotent session-end handling for agents that fire SessionEnd twice
- Initialize session Phase to PhaseIdle in both strategies (was zero-value "")
- Update all test fixtures to use Droid JSONL format and add parser tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: fe59ba01b450
- Replace IIFE pattern in ExtractSummary with idiomatic sequential error handling - Remove single-use type aliases (assistantMessage, toolInput) in favor of direct transcript.AssistantMessage/transcript.ToolInput references - Simplify ExtractAllModifiedFilesFromTranscript dedup since ExtractModifiedFiles already returns deduplicated results - Consolidate makeWriteToolLine/makeEditToolLine into shared makeFileToolLine helper Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Entire-Checkpoint: 979a49177542
Cover agent detection, hook installation, session stubs, enable command smoke tests, and strategy composition for the factoryai-droid agent. Unit tests for the agent package are also included. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Entire-Checkpoint: 1a75b7499be8
There was a problem hiding this comment.
Pull request overview
This PR adds first-class support for the Factory AI Droid agent to Entire CLI, wiring it into agent registration, hook installation/handling, transcript parsing/analysis, and integration tests, while also improving session lifecycle robustness.
Changes:
- Register the
factoryai-droidagent (new agent type/name constants + agent package + CLI registration imports). - Add Factory Droid hook installation/uninstallation and transcript parsing/analyzers (including subagent-aware file/token extraction) with extensive tests.
- Improve session lifecycle handling (initialize session
Phase, and makeSessionEndhandling idempotent).
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| cmd/entire/cli/summarize/summarize.go | Treats Factory Droid as a supported agent type for condensed transcript generation (currently routed through Claude parsing). |
| cmd/entire/cli/strategy/manual_commit_session.go | Initializes new session state with an explicit Phase value. |
| cmd/entire/cli/strategy/auto_commit.go | Initializes new session state with an explicit Phase value. |
| cmd/entire/cli/lifecycle.go | Makes SessionEnd handling idempotent by skipping duplicate end events for already-ended sessions. |
| cmd/entire/cli/integration_test/setup_factoryai_hooks_test.go | Adds integration smoke tests verifying hook installation and preservation of existing Factory settings. |
| cmd/entire/cli/integration_test/hooks.go | Adds a Factory Droid hook runner and helpers for simulating hook flows in integration tests. |
| cmd/entire/cli/integration_test/agent_test.go | Adds integration tests for Factory Droid agent detection, hook installation, and helper/stub behaviors. |
| cmd/entire/cli/integration_test/agent_strategy_test.go | Adds end-to-end strategy composition tests for Factory Droid hooks → lifecycle → strategy checkpointing. |
| cmd/entire/cli/hooks_cmd.go | Ensures the Factory Droid agent package is imported so it’s registered for hook subcommands. |
| cmd/entire/cli/config.go | Ensures the Factory Droid agent package is imported so it’s registered for config/setup flows. |
| cmd/entire/cli/agent/registry.go | Adds AgentNameFactoryAIDroid and AgentTypeFactoryAIDroid constants. |
| cmd/entire/cli/agent/factoryaidroid/types.go | Introduces Factory settings schema types and transcript/tool constants used by the new agent. |
| cmd/entire/cli/agent/factoryaidroid/transcript.go | Implements Droid transcript parsing/normalization plus modified-file and token/subagent extraction logic. |
| cmd/entire/cli/agent/factoryaidroid/transcript_test.go | Adds unit tests for parsing, token usage calculations, and subagent-aware file extraction. |
| cmd/entire/cli/agent/factoryaidroid/lifecycle.go | Implements lifecycle hook parsing and transcript analyzer/token calculator interfaces for Factory Droid. |
| cmd/entire/cli/agent/factoryaidroid/lifecycle_test.go | Adds unit tests for lifecycle event parsing from hook payloads. |
| cmd/entire/cli/agent/factoryaidroid/hooks.go | Implements Factory hook install/uninstall/idempotency plus permissions deny-rule enforcement. |
| cmd/entire/cli/agent/factoryaidroid/hooks_test.go | Adds unit tests covering hook installation/uninstallation, idempotency, and preservation of user config. |
| cmd/entire/cli/agent/factoryaidroid/factoryaidroid.go | Implements the core agent.Agent integration and self-registration for Factory Droid. |
| cmd/entire/cli/agent/factoryaidroid/factoryaidroid_test.go | Adds unit tests for the Factory Droid agent’s basic behaviors and stubs. |
| CLAUDE.md | Updates docs to mention the factoryai-droid stub option for E2E_AGENT. |
…ipt parsing The condensation path re-extracted prompts from raw transcript bytes using a generic Claude Code parser, which failed for Droid's different JSONL envelope format. Added Droid-specific branches to extractUserPrompts(), calculateTokenUsage(), and BuildCondensedTranscriptFromBytes() that normalize via ParseDroidTranscriptFromBytes() before processing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Entire-Checkpoint: 3a9059b7db5a
Implement FactoryAIDroidRunner in the E2E test suite, enabling real end-to-end testing with the droid CLI. Uses API key auth (FACTORY_API_KEY), `droid exec` with --auto medium, and supports E2E_DROID_MODEL env var. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Entire-Checkpoint: 6ca3fe47e9d9
Replace the "not implemented" stub with the real session directory path (~/.factory/sessions/<sanitized-repo-path>/) so transcript restoration works for rewind, resume, and debug commands. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Entire-Checkpoint: 94658e608230
…transcript helper Fix exhaustive lint errors in explain.go by adding AgentTypeFactoryAIDroid to the JSONL-based switch cases in scopeTranscriptForCheckpoint and transcriptOffset. Extract inline Droid transcript parsing in summarize.go into a dedicated buildCondensedTranscriptFromDroid helper for consistency with other agent-specific parsers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Entire-Checkpoint: 0a6204bff3e9
Remove tests that only verify constants, one-liners, and unimplemented stubs (TestName, TestType, TestDescription, TestGetHookConfigPath, TestSupportsHooks, TestGetSessionID, TestReadSession, TestWriteSession, TestResolveSessionFile, TestFormatResumeCommand, TestChunkTranscript_SmallContent, TestReassembleTranscript_SingleChunk, TestReassembleTranscript_MultipleChunks). Add tests covering previously untested logic: - TestExtractPrompts (+ IDE tag stripping, offset support) - TestExtractSummary (+ tool_use skipping, empty transcript) - TestParseDroidTranscript_MalformedLines - TestCalculateTotalTokenUsageFromTranscript_WithSubagentFiles - TestGetHookNames (contract test for all 9 hook verbs) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Entire-Checkpoint: 4a6d15d9cb22
Enable session portability for Factory AI Droid by implementing ReadSession (parse JSONL transcript, extract modified files) and WriteSession (validate inputs, create directories, write NativeData). This unblocks TestE2E_ResumeInRelocatedRepo. Fix Droid E2E runner: set ENTIRE_TEST_TTY=0 to prevent prepare-commit-msg hook from blocking on TTY input during agent-initiated commits, and remove unsupported --enabled-tools flag. Add ENTIRE_TEST_DROID_PROJECT_DIR to all test hook environments. Update integration tests to verify the new implementations instead of checking for "not implemented" errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Entire-Checkpoint: 90b22e597d54
Entire-Checkpoint: 0bba4695156b
PR SummaryMedium Risk Overview Introduces hook lifecycle support that can install/uninstall Droid hook commands into Updates CLI/explain/summarize and manual-condensation codepaths to treat Droid as JSONL-but-non-Claude (proper offset counting, prompt extraction, token usage), and extends integration + e2e infrastructure with a Written by Cursor Bugbot for commit 1a02ae6. Configure here. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
| lines = lines[startOffset:] | ||
| } | ||
| return factoryaidroid.CalculateTokenUsage(lines) | ||
| } |
There was a problem hiding this comment.
Token usage offset mismatch for Droid transcripts
High Severity
calculateTokenUsage for Droid applies startOffset (a raw JSONL line number from countLines) as an index into the array returned by ParseDroidTranscriptFromBytes, which filters out non-message entries like session_start. Since the parsed array has fewer elements than total raw lines, the offset doesn't correspond to the correct position. When startOffset exceeds len(lines) (common with non-message lines present), the slicing condition is false and ALL tokens are counted, causing over-counting across checkpoints.
| buf.WriteByte('\n') | ||
| } | ||
| return buf.Bytes(), nil | ||
| } |
There was a problem hiding this comment.
Exported SerializeTranscript is unused in production code
Low Severity
SerializeTranscript in factoryaidroid is exported but never called from any production code — only from its own test. Additionally, it marshals the normalized transcript.Line format (type="user"/"assistant"), not the Droid envelope format ({"type":"message","id":"...","message":{...}}), so round-tripping through ParseDroidTranscriptFromBytes then SerializeTranscript would silently change the transcript format.


Summary
GetSessionDirto enable transcript restoration for rewind, resume, and debug commands (~/.factory/sessions/<sanitized-repo-path>/)Test plan
E2E_AGENT=factoryai-droid) for real Droid session testingmise run fmt && mise run lint && mise run test:ciall passing🤖 Generated with Claude Code
resolves #353