Commit graph

66 commits

Author SHA1 Message Date
Virgil
759bb9bcb7 feat(core-agent): add mcp and serve commands
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-31 11:10:27 +00:00
Virgil
7c8542d730 fix(ax): tighten remaining source examples
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-31 06:20:14 +00:00
Virgil
f0c903d8c3 fix(ax): replace typed service lookups with Core.Service
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-31 05:43:14 +00:00
Virgil
326c046d4e fix(ax): align remaining comments and names
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 23:01:42 +00:00
Virgil
40a26ca28c fix(ax): continue AX comment cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 22:30:05 +00:00
Virgil
9997e7aecc fix(ax): align comments with usage examples
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 21:58:24 +00:00
Virgil
3aa9760ead fix(ax): continue AX comment cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 21:52:40 +00:00
Virgil
e825550a90 fix(ax): continue AX naming cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 21:30:49 +00:00
Virgil
1cc8fb50e1 fix(ax): continue workspace naming cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 21:22:54 +00:00
Virgil
f11d1d47a1 fix(ax): continue AX naming cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 21:11:06 +00:00
Virgil
dc6f2e2073 fix(ax): resolve nested workspace discovery
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 20:12:39 +00:00
Virgil
4d278a5172 fix(ax): use declarative core options in core-agent
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 20:05:47 +00:00
Virgil
faf6b8b6fb fix(ax): unify home-path resolution
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 19:54:17 +01:00
Virgil
f7830371a2 fix(ax): clarify version usage and channel guard
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 18:19:49 +00:00
Virgil
459a353c6b fix(ax): move version injection to module root
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 16:40:53 +00:00
Virgil
44bfe6224e fix(ax): restore structured startup logging and contract comments
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 14:16:38 +00:00
Virgil
3d7ec7efce fix(ax): make core-agent startup explicit
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 00:00:33 +00:00
Virgil
07942b5d27 fix(ax): make core-agent bootstrap testable
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 22:26:12 +00:00
Virgil
364007d424 fix(ax): add missing examples and helper coverage
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 21:44:22 +00:00
Virgil
547f23a6f0 fix(ax): align core-agent CLI bootstrap
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 21:02:14 +00:00
Virgil
6ac195c2e6 fix(agentic): align workspace flow with AX design
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 20:15:58 +00:00
Snider
fe1892c9bb missing files from claude's work. 2026-03-27 17:55:06 +00:00
Snider
0fc6eeb4cc feat(runner): extract dispatch runner into independent Core service
Moves concurrency, queue drain, workspace lifecycle, and frozen state
from agentic/prep into pkg/runner/ — a standalone Core service that
communicates via IPC Actions only.

- runner.Register wires Actions: dispatch, status, start, stop, kill, poke
- runner.HandleIPCEvents catches AgentCompleted → ChannelPush + queue poke
- Agentic dispatch asks runner for permission via c.Action("runner.dispatch")
- Dispatch mutex moved to struct-level sync.Mutex (fixes core.Lock init race)
- Registry-based concurrency counting replaces disk scanning
- TrackWorkspace called on both queued and running status writes
- SpawnQueued message added for runner→agentic spawn requests
- ChannelPush message in core/mcp enables any service to push channel events
- 51 new tests covering runner service, queue, and config parsing

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 11:00:47 +00:00
Snider
537226bd4d feat: AX v0.8.0 upgrade — Core features + quality gates
AX Quality Gates (RFC-025):
- Eliminate os/exec from all test + production code (12+ files)
- Eliminate encoding/json from all test files (15 files, 66 occurrences)
- Eliminate os from all test files except TestMain (Go runtime contract)
- Eliminate path/filepath, net/url from all files
- String concat: 39 violations replaced with core.Concat()
- Test naming AX-7: 264 test functions renamed across all 6 packages
- Example test 1:1 coverage complete

Core Features Adopted:
- Task Composition: agent.completion pipeline (QA → PR → Verify → Ingest → Poke)
- PerformAsync: completion pipeline runs with WaitGroup + progress tracking
- Config: agents.yaml loaded once, feature flags (auto-qa/pr/merge/ingest)
- Named Locks: c.Lock("drain") for queue serialisation
- Registry: workspace state with cross-package QUERY access
- QUERY: c.QUERY(WorkspaceQuery{Status: "running"}) for cross-service queries
- Action descriptions: 25+ Actions self-documenting
- Data mounts: prompts/tasks/flows/personas/workspaces via c.Data()
- Content Actions: agentic.prompt/task/flow/persona callable via IPC
- Drive endpoints: forge + brain registered with tokens
- Drive REST helpers: DriveGet/DrivePost/DriveDo for Drive-aware HTTP
- HandleIPCEvents: auto-discovered by WithService (no manual wiring)
- Entitlement: frozen-queue gate on write Actions
- CLI dispatch: workspace dispatch wired to real dispatch method
- CLI: --quiet/-q and --debug/-d global flags
- CLI: banner, version, check (with service/action/command counts), env
- main.go: minimal — 5 services + c.Run(), no os import
- cmd tests: 84.2% coverage (was 0%)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 06:38:02 +00:00
Snider
04f91ed6a0 feat: all commands in services — cmd/ has only main.go (97 lines) + update.go (24 lines)
- forge.go moved to pkg/agentic/commands_forge.go
- Uses s.forge directly (no newForgeClient())
- registerForgeCommands called in OnStartup
- main.go: 97 lines, zero command registration
- cmd/ total: 121 lines (was 650+)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 00:06:46 +00:00
Snider
72387dde91 feat: move workspace + process commands into services — main.go 98 lines
- ProcessRegister: proper factory in pkg/agentic
- Workspace commands (list/clean/dispatch): moved to agentic.registerWorkspaceCommands
- workspace.go deleted from cmd/
- main.go: 98 lines, just core.New + app commands + c.Run()

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 00:03:22 +00:00
Snider
b6f73dbdd2 feat: core.New() returns *Core — no unwrapping needed. main.go clean.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 21:50:19 +00:00
Snider
67658ec90c fix: imports forge.lthn.ai/core/mcp → dappco.re/go/mcp
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 21:40:04 +00:00
Snider
ae04bfd389 fix: use c.Run() void — handles os.Exit internally. 114 lines.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 21:36:19 +00:00
Snider
a31cea36a6 feat: use c.Run() — main.go down to 120 lines
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 21:33:00 +00:00
Snider
909bb3bb6c feat: services own their commands — main.go is 132 lines
Commands moved to their owning services:
- agentic: run/task, run/orchestrator, prep, status, prompt, extract
- mcp: mcp, serve (in core/mcp OnStartup)
- main.go: version, check, env (app-level only)

ServiceStartup before Cli().Run() — services register commands in OnStartup.
ServiceShutdown on exit.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 21:24:29 +00:00
Snider
4803f396d3 feat: use mcp.Register — MCP is a Core service
- core.New() includes mcp.Register — auto-discovers subsystems
- mcp/serve commands use c.Service("mcp") for typed retrieval
- ServiceStartup called once before Cli().Run()
- run/task and run/orchestrator registered by agentic.OnStartup
- Removed ServiceFor generics — c.Service() returns instances directly

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 21:16:20 +00:00
Snider
ea433b84de feat: all services registered in core.New() — no manual wiring
- process: registered as WithService in core.New()
- MCP: registered as WithName("mcp") in core.New(), retrieves
  agentic/monitor/brain via ServiceFor during construction
- Commands use ServiceFor to access services — no captured vars
- initMCP closure eliminated
- No service creation after core.New() completes

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 20:51:51 +00:00
Snider
919dcf963f feat: factories return instances — WithService handles registration
Register factories no longer call c.RegisterService() explicitly.
WithService auto-discovers name from package path and registers.
Eliminates double-registration error.

Uses WithOption("name", "core-agent") for Options struct.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 20:36:17 +00:00
Snider
adafee0f18 feat: use RegisterService + ServiceFor — proper instance lifecycle
- agentic.PrepSubsystem implements Startable/Stoppable
- monitor.Subsystem implements Startable/Stoppable (OnStartup/OnShutdown)
- Register factories use c.RegisterService() — auto-discovers interfaces
- Register factories return instances via Result.Value
- main.go uses ServiceFor[T]() instead of ConfigGet — typed retrieval
- No more c.Config().Set("x.instance") workaround

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 17:42:16 +00:00
Snider
4e69daf2da feat: replace initServices() with core.New() service conclave
Services are now registered during Core construction:
  core.New(
      core.WithService(agentic.Register),
      core.WithService(monitor.Register),
      core.WithService(brain.Register),
  )

- Remove initServices() closure — services created once in conclave
- Commands use c.ServiceStartup()/c.ServiceShutdown() for lifecycle
- Service instances retrieved via c.Config() for MCP tool registration
- run/orchestrator reduced to ServiceStartup + block + ServiceShutdown
- run/task uses conclave's agentic instance

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 16:33:04 +00:00
Snider
9f8a63ae21 feat: Register() factories + consume new core.New() API
Each package exposes Register(c *Core) Result for core.WithService():
- agentic.Register: creates PrepSubsystem, wires IPC handlers, lifecycle
- monitor.Register: creates Subsystem, wires IPC handler, lifecycle
- brain.Register: creates Direct, registers service

main.go updated for core.New() returning Result.
Ready for core.New(WithService(agentic.Register)) pattern.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 16:23:44 +00:00
Snider
cdb29a2f75 feat(ipc): replace CompletionNotifier callbacks with Core IPC messages
Phase 3 of Core DI migration:
- Remove CompletionNotifier interface from pkg/agentic
- dispatch.go emits messages.AgentStarted/AgentCompleted via c.ACTION()
- monitor registers IPC handlers in SetCore() — handleAgentStarted/handleAgentCompleted
- Remove circular callback wiring (SetCompletionNotifier) from main.go
- Export ReadStatus for cross-package use
- Update run/orchestrator to use SetCore() instead of SetCompletionNotifier()

Services now communicate through typed messages, not direct references.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 14:46:59 +00:00
Snider
bb88604045 feat(core): wire Core framework into agentic + monitor subsystems
Phase 2 of Core DI migration:
- Add *core.Core field + SetCore() to PrepSubsystem and monitor.Subsystem
- Register agentic/monitor/brain as Core services with lifecycle hooks
- Mark SetCompletionNotifier and SetNotifier as deprecated (removed in Phase 3)
- Fix monitor test to match actual event names
- initServices() now wires Core refs before legacy callbacks

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 14:44:53 +00:00
Snider
dba621c108 feat(update): version injection via ldflags, park update command
- var version set by build ldflags (-X dappco.re/go/agent.version=X)
- Channel detection (stable/prerelease/dev) from version string
- Update command parked until version moves to module root
- Add Makefile with build/install/test targets + VERSION support

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-23 16:50:54 +00:00
Snider
50c06dc4df chore: align binary version with plugin (0.15.0)
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-23 16:09:25 +00:00
Snider
9bdd47d9d5 feat(agent): v0.3.0 — dispatch control, run task CLI, quiet notifications, spark pool
- Add agentic_dispatch_start / shutdown / shutdown_now MCP tools
- Queue frozen by default, CORE_AGENT_DISPATCH=1 to auto-start
- Add run task CLI command — single task e2e (prep → spawn → wait)
- Add DispatchSync for blocking dispatch without MCP
- Quiet notifications — only agent.failed and queue.drained events
- Remove duplicate notification paths (direct callback + polling loop)
- codex-spark gets separate concurrency pool (baseAgent routing)
- Rate-limit backoff detection (3 fast failures → 30min pause)
- Review agent uses exec with sandbox bypass (not codex review)
- Bump: core-agent 0.3.0, core plugin 0.15.0, devops plugin 0.2.0

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-23 16:08:08 +00:00
Snider
6d4b92737e feat(agent): background runner, slim status, Docker dispatch, stopwatch, CLI fixes
- Add background queue runner (runner.go) — 30s tick + poke on completion
- drainQueue now loops to fill all slots per tick
- Add run orchestrator command — standalone queue runner without MCP
- Slim agentic_status — stats only, blocked workspaces listed
- Docker containerised dispatch — all agents run in core-dev container
- Forge stopwatch start/stop on issue when agent starts/completes
- issue create supports --milestone, --assignee, --ref
- Auto-PR targets dev branch (not main)
- PR body includes Closes #N for issue-linked work
- CLI usage strings use spaces not slashes
- Review agent uses exec with sandbox bypass (not codex review subcommand)
- Local model support via codex --oss with socat Ollama proxy

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-23 12:53:33 +00:00
Snider
f416948660 feat: workspace CLI commands — list, clean, dispatch stub
workspace/list shows all workspaces with status/agent/repo.
workspace/clean removes completed/failed/blocked/merged workspaces.
workspace/dispatch stub for future CLI-driven dispatch.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 15:45:16 +00:00
Snider
bfe70871a2 feat: Forge CLI commands — issue, PR, and repo operations
New commands via go-forge library:
  issue/get, issue/list, issue/comment
  pr/get, pr/list, pr/merge
  repo/get, repo/list

Enables CLI-driven Forge interaction for dispatch automation.
Agent can now read issues, create PRs, merge, and list repos
without MCP.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 15:45:16 +00:00
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
98baa1b08f feat: inline tests + Fs zero-value fix + coverage 76.9% → 82.3%
Move all tests from tests/ to package root for proper coverage.
Fix Fs zero-value: path() and validatePath() default empty root
to "/" so &Fs{} works without New().

New tests: PathGlob, PathIsAbs, CleanPath, Cli.SetOutput,
ServiceShutdown, Core.Context, Fs zero-value, Fs protected
delete, Command lifecycle with implementation, error formatting
branches, PerformAsync completion/no-handler/after-shutdown,
Extract with templates, Embed path traversal.

Coverage: 76.9% → 82.3% (23 test files, 82 new test cases).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 15:45:04 +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
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