Commit graph

35 commits

Author SHA1 Message Date
Snider
6e37bd22f0 feat: devops plugin, CLI commands, Codex dispatch fixes, AX sweep
DevOps plugin (5 skills):
- install-core-agent, repair-core-agent, merge-workspace,
  update-deps, clean-workspaces

CLI commands: version, check, extract for diagnostics.

Codex dispatch: --skip-git-repo-check, removed broken
--model-reasoning-effort, --sandbox workspace-write via
--full-auto. Workspace template extracts to wsDir not srcDir.

AX sweep (Codex-generated): sanitise.go extracted from prep/plan,
mirror.go JSON parsing via encoding/json, setup/config.go URL
parsing via net/url, strings/fmt imports eliminated from setup.

CODEX.md template updated with Env/Path patterns.
Review workspace template with audit-only PROMPT.md.
Marketplace updated with devops plugin.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 15:45:16 +00:00
Snider
9aac4c19dd refactor(monitor): adopt core helpers
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 13:40:14 +00:00
Snider
4f66eb4cca fix: resolve final AX audit findings
- cmd/main.go: keyed core.Result literals (go vet clean)
- pkg/brain/direct.go: compile-time mcp.Subsystem assertion
- pkg/monitor/monitor.go: compile-time Subsystem + CompletionNotifier assertions
- pkg/agentic/prep.go: alias stdlib io as goio
- pkg/agentic/remote_client.go: UK English (initialise/initialised)
- pkg/monitor/monitor_test.go: updated inbox tests for current contract

AX audit now returns 0 convention findings.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 06:42:42 +00:00
Snider
a0dc9c32e7 refactor: migrate core/agent to Core primitives — reference implementation
Phase 1: go-io/go-log → core.Fs{}, core.E(), core.Error/Info/Warn
Phase 2: strings/fmt → core.Contains, core.Sprintf, core.Split etc
Phase 3: embed.FS → core.Mount/core.Embed, core.Extract
Phase 4: cmd/main.go → core.Command(), c.Cli().Run(), no cli package

All packages migrated:
- pkg/lib (Codex): core.Mount, core.Extract, Result returns, AX comments
- pkg/setup (Codex): core.Fs, core.E, fixed missing lib helpers
- pkg/brain (Codex): Core primitives, AX comments
- pkg/monitor (Codex): Core string/logging primitives
- pkg/agentic (Codex): 20 files, Core primitives throughout
- cmd/main.go: pure Core CLI, no fmt/log/filepath/strings/cli

Remaining stdlib: path/filepath (Core doesn't wrap OS paths),
fmt.Sscanf/strings.Map (no Core equivalent).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 06:13:41 +00:00
Snider
deaa06a54d refactor(pkg): migrate go-io/go-log to Core primitives
Replace separate go-io (coreio) and go-log (coreerr) packages with
Core's built-in Fs and error/logging functions. This is the reference
implementation for how all Core ecosystem packages should migrate.

Changes:
- coreio.Local.Read/Write/EnsureDir/Delete/IsFile → core.Fs methods
- coreerr.E() → core.E(), coreerr.Info/Warn/Error → core.Info/Warn/Error
- (value, error) return pattern → core.Result pattern (r.OK, r.Value)
- go-io and go-log moved from direct to indirect deps in go.mod
- Added AX usage-example comments on key public types
- Added newFs("/") helper for unrestricted filesystem access

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 03:41:07 +00:00
Snider
c6490c175a refactor: migrate imports to dappco.re paths + bump mcp to v0.4.0
Update all go-* imports from forge.lthn.ai to dappco.re/go/core/*.
Bump mcp to v0.4.0 (Options{} struct API).
Versions: core v0.5.0, io v0.2.0, log v0.1.0, process v0.3.0,
ws v0.3.0, ai v0.2.0, webview v0.2.0, i18n v0.2.0.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 01:27:48 +00:00
Snider
2d58145e65 test(monitor): add unit tests for completions, inbox, lifecycle
Cover checkCompletions, checkInbox, syncRepos, loop, Poke,
Start/Shutdown, New, initSyncTimestamp, and agentStatusResource.
Mock HTTP endpoints with httptest, use t.TempDir for workspace
scanning, and create fake status.json files for completions.

Also fix dispatch.go build error (removed unsupported RunOptions
fields: KillGroup, Timeout, GracePeriod).

Coverage: 23.2% → 86.5%

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 00:45:43 +00:00
Snider
5393828ac6 feat(monitor): include message content in inbox channel events
Some checks failed
CI / test (push) Failing after 3s
inbox.message events now include full message objects (id, from,
subject, content) so recipients can read messages inline without
calling agent_inbox. Charon's messages arrive directly in session.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 20:08:13 +00:00
Snider
0fda800e8b chore(monitor): remove debug logging from check cycle
Some checks failed
CI / test (push) Failing after 3s
Debug channel events and stderr logging removed — monitor runs
silently unless something actually happens. Only real events
(agent.complete, inbox.message, harvest.complete) fire now.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 19:42:38 +00:00
Snider
5a234c1179 fix(monitor): seed completions on startup, suppress initial flood
Some checks failed
CI / test (push) Failing after 3s
Both checkCompletions and checkInbox now seed on first run —
existing workspaces and messages are recorded without firing
channel events. Only genuinely new events trigger notifications.

Tests updated to pre-seed flags and filter debug events.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 19:38:03 +00:00
Snider
36dc76cce1 feat(monitor): ID-based inbox detection + channels fully working
Some checks failed
CI / test (push) Failing after 3s
Track inbox by highest message ID instead of unread count. Fixes:
- API pagination limit (max 20) no longer causes missed notifications
- Restart no longer floods with all existing unread messages (seeded)
- Each new message fires exactly once regardless of read state

Added MONITOR_INTERVAL env override and debugChannel helper for
faster iteration during channel development.

All three channel types confirmed working:
- agent.complete: workspace status changes
- inbox.message: new messages by ID tracking
- monitor.debug: real-time debug trace

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 19:31:11 +00:00
Snider
1e9278fd9d feat(monitor): channels working — inbox uses {data:[...]} + debug events
Some checks failed
CI / test (push) Failing after 3s
Fixed inbox API response parsing: {data:[...]} not {messages:[...]}.
Added debugChannel helper for real-time debug events via channels.
MONITOR_INTERVAL env override for faster iteration.

Channels confirmed working:
- agent.complete: workspace status changes
- inbox.message: unread message notifications
- monitor.debug: debug trace events

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 19:24:07 +00:00
Snider
b5dcdd1261 fix(monitor): inbox API returns {data:[...]} not {messages:[...]}
Some checks failed
CI / test (push) Failing after 3s
The MCP agent_inbox tool wraps the response as {messages:[...]},
but the raw API returns {data:[...]}. The monitor calls the raw
API directly, so it needs to parse {data:[...]}.

Verified with curl against live API. Removed debug channel events.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 19:17:53 +00:00
Snider
6da52aa60f fix: Codex round 8 — remote success propagation + stale question cleanup
Some checks failed
CI / test (push) Failing after 3s
Medium: remote dispatch now propagates inner dispatchOut.Success
instead of hardcoding true.

Low: updateStatus clears stale question field when new state
has no question, preventing leftover rejection messages.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 17:46:04 +00:00
Snider
40d2b0db16 fix: address Codex round 7 — path traversal + dispatch check
Some checks failed
CI / test (push) Failing after 2s
High/Security: sanitise input.Repo via filepath.Base to prevent
path traversal in workspace prep (../escape from CODE_PATH).

High/Security: sanitise repo.Repo from API response in syncRepos
to prevent path traversal via crafted checkin responses.

Medium: dispatchFixFromQueue now returns error, review_queue checks
success before recording fix_dispatched.

Known issues updated with async bridge provider findings.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 17:25:23 +00:00
Snider
5b39e13a6e fix: address Codex round 6 findings — 2 high, 3 medium, 1 low
Some checks failed
CI / test (push) Failing after 3s
High: workspace names use UnixNano to prevent same-second collisions
High: sync only pulls the branch the server reported (was pulling current)

Medium: drainQueue serialised via mutex to prevent concurrent over-dispatch
Medium: remote_status checks JSON-RPC error field before reporting success
Medium: dead agent PIDs without output log marked failed, not completed

Low: detectLanguage uses ordered slice instead of map for deterministic results

Also: URL-encoded agent names in messaging, monitor inbox, and sync endpoints.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 17:10:43 +00:00
Snider
66220021c9 fix: address Codex round 5 findings — 2 high, 5 medium, 4 low
Some checks failed
CI / test (push) Failing after 3s
High: clean stale BLOCKED.md before spawn (prevents stuck workspaces)
High: agentic_create_pr pushes to Forge URL, not local origin

Medium: watch treats merged/ready-for-review as terminal states
Medium: scan paginates org repos (was limited to first 50)
Medium: agent_conversation URL-encodes agent names (injection fix)

Low: inbox/sync/monitor URL-encode agent names in query strings
Low: pullWiki closes response body on non-200 (connection leak)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 16:53:55 +00:00
Snider
e4f94eaaab fix: address Codex round 4 findings
Some checks failed
CI / test (push) Failing after 3s
High: Codex review now sets working directory (was missing)
Medium: harvest skip-branch check uses defaultBranch() not just "main"
Medium: dry_run reads PROMPT.md from src/ (was reading wrong path)
Low: agent prompt says "current directory" not "parent directory"
Low: queue prompt matches dispatch prompt

Finding 1 (inbox messages vs data) verified as false positive —
API returns {messages:[...]}, confirmed against live endpoint.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 16:36:26 +00:00
Snider
67249fa78f fix: address Codex round 3 findings — 5 high, 4 medium, 1 low
Some checks failed
CI / test (push) Failing after 3s
High: prep creates workspace dir before clone (was missing)
High: auto_pr detects default branch instead of hardcoding main
High: mirror gh pr commands now use --repo for correct targeting
High: syncRepos HTTP client has 15s timeout (was no timeout)
High: sync timestamp only advances when all repos were pulled

Medium: rebaseBranch uses detected default branch
Medium: scan URL-encodes labels to prevent injection
Medium: recall MinConfidence forwarding (acknowledged, API-level)
Medium: recall tags preservation (acknowledged, API-level)

Low: harvest pushBranch uses coreerr.E instead of fmt.Errorf

Shared gitDefaultBranch helper added to agentic/paths.go.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 16:22:18 +00:00
Snider
026b31edf7 fix: address Codex round 2 mediums
Some checks failed
CI / test (push) Failing after 3s
- harvest: message says 'ready-for-review' not 'pushed'
- sync: timestamp advanced after pulls, not before
- sync: accepts main/master/reported branch, not just main
- inbox: checks CORE_BRAIN_KEY env before falling back to file
- inbox: parses 'from' not 'from_agent', 'messages' not 'data'
- queue: strips variant suffix for rate limit lookup (claude:opus → claude)
- review_queue: respects ReviewQueueInput.Reviewer instead of hardcoding coderabbit
- tests: updated to match real API response structure

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 16:05:59 +00:00
Snider
98ce071b13 fix: address Codex round 2 findings — 3 verified highs
Some checks failed
CI / test (push) Failing after 3s
High: harvest no longer hardcodes 'main' — detects default branch
via symbolic-ref/rev-parse fallback. Repos with master/other
default branches are now harvested correctly.

High: empty task no longer produces invalid 'agent/' branch name.
Falls back to issue-N or work-timestamp. Branch creation errors
are now surfaced instead of silently ignored.

High: PHP verification no longer returns passed:true when no test
runner exists. Untested PHP repos correctly fail verification.

(brain/direct.go findings 5-6 verified as false positives — API
returns top-level keys, not {data: ...} envelope)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 15:59:48 +00:00
Snider
422777580b fix: address Codex review findings — 2 high, 3 medium
Some checks failed
CI / test (push) Failing after 3s
High: Fix missed-notification bug — track completions by workspace
name instead of count, so harvest status rewrites don't suppress
future notifications. Also tracks blocked/failed terminal states.

High: Safety gate fail-closed — check ALL changed files (not just
added), reject on git diff failure instead of proceeding.

Medium: emitCompletionEvent now passes actual status (completed,
failed, blocked) instead of hardcoding "completed".

Medium/AX: Harvest no longer auto-pushes to source repos. Sets
status to ready-for-review only — pushing happens during explicit
review, not silently in the background.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 15:31:29 +00:00
Snider
8eb2430486 test(monitor): add unit tests for completions, inbox, lifecycle
Coverage: 23.2% → 86.5%
Tests for checkCompletions, checkInbox, monitor loop,
Poke, New, Start/Shutdown. Uses httptest for API mocking.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 13:49:23 +00:00
Snider
4d0bd3ad38 test(monitor): add harvest and channel notification tests
15 tests covering:
- Branch detection, unpushed commit counting, file counting
- Safety checks: binary rejection, large file rejection
- Workspace harvesting: happy path, skip running, skip main, reject binary
- Channel event emission via mock notifier
- Status file updates

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 13:21:23 +00:00
Snider
2f10c7d368 feat(agent): wire channel notifications into monitor
- Monitor pushes agent.complete, inbox.message, harvest.complete
  events via ChannelSend instead of temp files
- Remove /tmp/claude-inbox-notify file write (channels replace it)
- Update mcp.New() to use Options{} struct
- Wire mcpSvc as ChannelNotifier after creation

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 12:56:24 +00:00
Snider
21f234aa7c refactor: flatten go/ subdir, migrate to dappco.re/go/agent, restore process service
- Module path: dappco.re/go/agent
- Core import: dappco.re/go/core v0.4.7
- Process service re-enabled with new Core API
- Plugin bumped to v0.11.0
- Directory flattened from go/ to root

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 11:10:44 +00:00
Snider
be1130f470 agent updates 2026-03-21 11:10:44 +00:00
Snider
8c1625873c refactor: simplify internals — consolidate, deduplicate, fix bugs
Simplifier pass (-38 lines):
- Consolidate status update branches in spawnAgent (3 → 1 write)
- Remove 6 duplicate defer resp.Body.Close() calls
- Fix nil err reference in non-200 error paths (scan.go, pr.go)
- Remove redundant plansDir() and workspaceRoot() wrappers
- Simplify countRunningByAgent to use baseAgent() helper
- Extract markMerged in verify.go to remove duplication
- Clean imports and remove dead code

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 19:35:15 +00:00
Snider
e66ea0512b fix: address re-review findings — nil pointer, races, curl, clone error
Important:
- Fix nil pointer dereference on resp.StatusCode when err!=nil (8 sites)
- Replace curl shell-out with net/http in monitor inbox check
- Handle clone failure in prep.go (was silently swallowed)
- Use GitHubOrg() instead of hardcoded "dAppCore"

Medium:
- Fix JSONL append race (read+write → os.OpenFile O_APPEND)
- Remove dead google/mcp/ directory

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 19:27:44 +00:00
Snider
6d04c893b7 fix: address all code review findings (medium + low)
- os.ReadFile/WriteFile → coreio.Local in monitor and remote packages
- Deduplicate agentName() → shared agentic.AgentName()
- Deduplicate workspaceRoot() → shared agentic.WorkspaceRoot()
- fileExists uses IsFile() instead of reading whole file
- Fix SPDX-Licence → SPDX-License typo
- Remove time.Now import hack
- Fix hardcoded PR #1 in review queue

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 19:19:04 +00:00
Snider
4832827da7 fix: address code review findings (critical + high)
Critical:
- Fix token leaked in URL query string (getLabelID) — now uses Authorization header
- Fix unchecked type assertion panic in parseMessages — safe toInt() helper

High:
- Remove dead canDispatch() function
- Remove time.Now import hack from mirror.go
- Remove invalid --no-force git flag from mirror.go
- Tidy go.mod (remove unused deps from deleted packages)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 19:12:06 +00:00
Snider
e677d15bdd fix: remove hardcoded paths, gitignore binaries
- Add paths.go with WorkspaceRoot(), CoreRoot(), PlansRoot()
- All workspace paths now check CORE_WORKSPACE env var first
- Fallback: ~/Code/.core/workspace (works on any machine)
- Remove committed core-agent and mcp binaries from tracking
- Add .gitignore for compiled binaries

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 18:13:44 +00:00
Snider
90b03191b2 feat(agent): v0.2.0 — HTTP daemon, remote dispatch, review queue, verify+merge
Major additions:
- core-agent serve: persistent HTTP daemon with PID file, health check, registry
- agentic_dispatch_remote: dispatch tasks to remote agents (Charon) over MCP HTTP
- agentic_status_remote: check remote agent workspace status
- agentic_mirror: sync Forge repos to GitHub mirrors with file count limits
- agentic_review_queue: CodeRabbit/Codex review queue with rate-limit awareness
- verify.go: auto-verify (run tests) + auto-merge + retry with rebase + needs-review label
- monitor sync: checkin API integration for cross-agent repo sync
- PostToolUse inbox notification hook (check-notify.sh)

Dispatch improvements:
- --dangerously-skip-permissions (CLI flag changed)
- proc.CloseStdin() after spawn (Claude CLI stdin pipe fix)
- GOWORK=off in agent env and verify
- Exit code / BLOCKED.md / failure detection
- Monitor poke for instant notifications

New agent types:
- coderabbit: CodeRabbit CLI review (--plain --base)
- codex:review: OpenAI Codex review mode

Integrations:
- CODEX.md: OpenAI Codex conventions file
- Gemini extension: points at core-agent MCP (not Node server)
- Codex config: core-agent MCP server added
- GitHub webhook handler + CodeRabbit KPI tables (PHP)
- Forgejo provider for uptelligence webhooks
- Agent checkin endpoint for repo sync

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 17:45:04 +00:00
Snider
ccfd68ca1a feat: fire resource subscription notification on agent status change
Monitor now calls Server.ResourceUpdated() for status://agents when
agent completions or inbox changes are detected. Clients subscribed
to this resource get notified automatically via MCP protocol.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 05:52:12 +00:00
Snider
0ca253fe68 feat: add monitor subsystem — background ecosystem watcher
Runs every 2 minutes while MCP server is active:
- Checks for newly completed agent workspaces
- Checks inbox for unread messages
- Pushes notifications via ServerSession.Log() to connected clients

Also registers status://agents resource for on-demand workspace status.

The MCP connection is bidirectional — monitor uses it to actively
notify rather than waiting for tool calls.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 05:37:57 +00:00