2026-03-24 21:24:29 +00:00
// SPDX-License-Identifier: EUPL-1.2
2026-03-30 21:58:24 +00:00
// c := core.New(core.WithOption("name", "core-agent"))
// registerApplicationCommands(c)
2026-03-24 21:24:29 +00:00
package agentic
import (
"context"
"dappco.re/go/agent/pkg/lib"
core "dappco.re/go/core"
2026-04-01 22:30:20 +00:00
"gopkg.in/yaml.v3"
2026-03-24 21:24:29 +00:00
)
2026-03-30 21:52:40 +00:00
// c.Command("run/task", core.Command{Description: "Run a single task end-to-end", Action: s.cmdRunTask})
// c.Command("prep", core.Command{Description: "Prepare a workspace: clone repo, build prompt", Action: s.cmdPrep})
2026-03-24 21:24:29 +00:00
func ( s * PrepSubsystem ) registerCommands ( ctx context . Context ) {
2026-03-30 21:41:45 +00:00
s . startupContext = ctx
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
c := s . Core ( )
2026-03-29 23:37:28 +00:00
c . Command ( "run/task" , core . Command { Description : "Run a single task end-to-end" , Action : s . cmdRunTask } )
2026-04-02 06:47:34 +00:00
c . Command ( "agentic:run/task" , core . Command { Description : "Run a single task end-to-end" , Action : s . cmdRunTask } )
2026-04-01 22:30:20 +00:00
c . Command ( "run/flow" , core . Command { Description : "Show a flow definition from disk or the embedded library" , Action : s . cmdRunFlow } )
2026-04-02 06:47:34 +00:00
c . Command ( "agentic:run/flow" , core . Command { Description : "Show a flow definition from disk or the embedded library" , Action : s . cmdRunFlow } )
2026-04-01 22:36:39 +00:00
c . Command ( "flow/preview" , core . Command { Description : "Preview a flow definition with optional variable substitution" , Action : s . cmdFlowPreview } )
c . Command ( "agentic:flow/preview" , core . Command { Description : "Preview a flow definition with optional variable substitution" , Action : s . cmdFlowPreview } )
2026-04-01 20:34:04 +00:00
c . Command ( "dispatch/sync" , core . Command { Description : "Dispatch a single task synchronously and block until it completes" , Action : s . cmdDispatchSync } )
2026-04-02 06:47:34 +00:00
c . Command ( "agentic:dispatch/sync" , core . Command { Description : "Dispatch a single task synchronously and block until it completes" , Action : s . cmdDispatchSync } )
2026-03-29 23:37:28 +00:00
c . Command ( "run/orchestrator" , core . Command { Description : "Run the queue orchestrator (standalone, no MCP)" , Action : s . cmdOrchestrator } )
2026-04-02 06:47:34 +00:00
c . Command ( "agentic:run/orchestrator" , core . Command { Description : "Run the queue orchestrator (standalone, no MCP)" , Action : s . cmdOrchestrator } )
2026-04-01 13:42:31 +00:00
c . Command ( "dispatch" , core . Command { Description : "Dispatch queued agents" , Action : s . cmdDispatch } )
2026-04-01 19:45:13 +00:00
c . Command ( "agentic:dispatch" , core . Command { Description : "Dispatch queued agents" , Action : s . cmdDispatch } )
2026-04-01 14:05:18 +00:00
c . Command ( "dispatch/start" , core . Command { Description : "Start the dispatch queue runner" , Action : s . cmdDispatchStart } )
2026-04-02 02:56:21 +00:00
c . Command ( "agentic:dispatch/start" , core . Command { Description : "Start the dispatch queue runner" , Action : s . cmdDispatchStart } )
2026-04-01 14:05:18 +00:00
c . Command ( "dispatch/shutdown" , core . Command { Description : "Freeze the dispatch queue gracefully" , Action : s . cmdDispatchShutdown } )
2026-04-02 02:56:21 +00:00
c . Command ( "agentic:dispatch/shutdown" , core . Command { Description : "Freeze the dispatch queue gracefully" , Action : s . cmdDispatchShutdown } )
2026-04-01 14:05:18 +00:00
c . Command ( "dispatch/shutdown-now" , core . Command { Description : "Hard stop the dispatch queue and kill running agents" , Action : s . cmdDispatchShutdownNow } )
2026-04-02 02:56:21 +00:00
c . Command ( "agentic:dispatch/shutdown-now" , core . Command { Description : "Hard stop the dispatch queue and kill running agents" , Action : s . cmdDispatchShutdownNow } )
2026-04-02 03:36:31 +00:00
c . Command ( "poke" , core . Command { Description : "Drain the dispatch queue immediately" , Action : s . cmdPoke } )
c . Command ( "agentic:poke" , core . Command { Description : "Drain the dispatch queue immediately" , Action : s . cmdPoke } )
2026-03-25 00:54:07 +00:00
c . Command ( "prep" , core . Command { Description : "Prepare a workspace: clone repo, build prompt" , Action : s . cmdPrep } )
2026-04-01 13:02:15 +00:00
c . Command ( "prep-workspace" , core . Command { Description : "Prepare a workspace: clone repo, build prompt" , Action : s . cmdPrep } )
2026-04-01 19:45:13 +00:00
c . Command ( "agentic:prep-workspace" , core . Command { Description : "Prepare a workspace: clone repo, build prompt" , Action : s . cmdPrep } )
2026-04-01 20:59:52 +00:00
c . Command ( "resume" , core . Command { Description : "Resume a blocked or completed workspace" , Action : s . cmdResume } )
c . Command ( "agentic:resume" , core . Command { Description : "Resume a blocked or completed workspace" , Action : s . cmdResume } )
2026-04-01 10:40:28 +00:00
c . Command ( "generate" , core . Command { Description : "Generate content from a prompt using the platform content pipeline" , Action : s . cmdGenerate } )
2026-04-01 19:36:44 +00:00
c . Command ( "agentic:generate" , core . Command { Description : "Generate content from a prompt using the platform content pipeline" , Action : s . cmdGenerate } )
2026-04-02 02:51:10 +00:00
c . Command ( "content/generate" , core . Command { Description : "Generate content from a prompt using the platform content pipeline" , Action : s . cmdGenerate } )
c . Command ( "agentic:content/generate" , core . Command { Description : "Generate content from a prompt using the platform content pipeline" , Action : s . cmdGenerate } )
2026-04-02 05:39:01 +00:00
c . Command ( "content/schema/generate" , core . Command { Description : "Generate SEO schema JSON-LD for article, FAQ, or how-to content" , Action : s . cmdContentSchemaGenerate } )
c . Command ( "agentic:content/schema/generate" , core . Command { Description : "Generate SEO schema JSON-LD for article, FAQ, or how-to content" , Action : s . cmdContentSchemaGenerate } )
2026-04-01 22:07:42 +00:00
c . Command ( "complete" , core . Command { Description : "Run the completion pipeline (QA → PR → Verify → Commit → Ingest → Poke)" , Action : s . cmdComplete } )
2026-04-02 04:19:00 +00:00
c . Command ( "agentic:complete" , core . Command { Description : "Run the completion pipeline (QA → PR → Verify → Commit → Ingest → Poke)" , Action : s . cmdComplete } )
2026-04-01 11:44:26 +00:00
c . Command ( "scan" , core . Command { Description : "Scan Forge repos for actionable issues" , Action : s . cmdScan } )
2026-04-01 19:45:13 +00:00
c . Command ( "agentic:scan" , core . Command { Description : "Scan Forge repos for actionable issues" , Action : s . cmdScan } )
2026-04-01 19:11:02 +00:00
c . Command ( "mirror" , core . Command { Description : "Mirror Forge repos to GitHub" , Action : s . cmdMirror } )
2026-04-01 19:45:13 +00:00
c . Command ( "agentic:mirror" , core . Command { Description : "Mirror Forge repos to GitHub" , Action : s . cmdMirror } )
2026-04-01 11:15:04 +00:00
c . Command ( "brain/ingest" , core . Command { Description : "Bulk ingest memories into OpenBrain" , Action : s . cmdBrainIngest } )
2026-04-01 19:48:56 +00:00
c . Command ( "brain:ingest" , core . Command { Description : "Bulk ingest memories into OpenBrain" , Action : s . cmdBrainIngest } )
2026-04-01 21:14:02 +00:00
c . Command ( "brain/recall" , core . Command { Description : "Recall memories from OpenBrain" , Action : s . cmdBrainRecall } )
c . Command ( "brain:recall" , core . Command { Description : "Recall memories from OpenBrain" , Action : s . cmdBrainRecall } )
2026-04-02 02:05:37 +00:00
c . Command ( "brain/remember" , core . Command { Description : "Store a memory in OpenBrain" , Action : s . cmdBrainRemember } )
c . Command ( "brain:remember" , core . Command { Description : "Store a memory in OpenBrain" , Action : s . cmdBrainRemember } )
2026-04-02 03:41:13 +00:00
c . Command ( "brain/seed-memory" , core . Command { Description : "Import markdown memories into OpenBrain from a project memory file or directory" , Action : s . cmdBrainSeedMemory } )
c . Command ( "brain:seed-memory" , core . Command { Description : "Import markdown memories into OpenBrain from a project memory file or directory" , Action : s . cmdBrainSeedMemory } )
2026-04-01 11:54:44 +00:00
c . Command ( "brain/list" , core . Command { Description : "List memories in OpenBrain" , Action : s . cmdBrainList } )
2026-04-01 19:53:16 +00:00
c . Command ( "brain:list" , core . Command { Description : "List memories in OpenBrain" , Action : s . cmdBrainList } )
2026-04-01 18:10:23 +00:00
c . Command ( "brain/forget" , core . Command { Description : "Forget a memory in OpenBrain" , Action : s . cmdBrainForget } )
2026-04-01 19:53:16 +00:00
c . Command ( "brain:forget" , core . Command { Description : "Forget a memory in OpenBrain" , Action : s . cmdBrainForget } )
2026-04-01 12:33:57 +00:00
c . Command ( "lang/detect" , core . Command { Description : "Detect the primary language for a repository or workspace" , Action : s . cmdLangDetect } )
c . Command ( "lang/list" , core . Command { Description : "List supported language identifiers" , Action : s . cmdLangList } )
2026-04-02 00:01:23 +00:00
c . Command ( "epic" , core . Command { Description : "Create sub-issues from an epic plan" , Action : s . cmdEpic } )
c . Command ( "agentic:epic" , core . Command { Description : "Create sub-issues from an epic plan" , Action : s . cmdEpic } )
2026-04-02 02:24:40 +00:00
c . Command ( "plan-cleanup" , core . Command { Description : "Archive old completed plans and delete stale archives past the retention period" , Action : s . cmdPlanCleanup } )
c . Command ( "agentic:plan-cleanup" , core . Command { Description : "Archive old completed plans and delete stale archives past the retention period" , Action : s . cmdPlanCleanup } )
2026-04-01 11:36:47 +00:00
c . Command ( "pr-manage" , core . Command { Description : "Manage open PRs (merge, close, review)" , Action : s . cmdPRManage } )
2026-04-01 19:45:13 +00:00
c . Command ( "agentic:pr-manage" , core . Command { Description : "Manage open PRs (merge, close, review)" , Action : s . cmdPRManage } )
2026-04-01 18:04:39 +00:00
c . Command ( "review-queue" , core . Command { Description : "Process the CodeRabbit review queue" , Action : s . cmdReviewQueue } )
2026-04-01 20:25:39 +00:00
c . Command ( "agentic:review-queue" , core . Command { Description : "Process the CodeRabbit review queue" , Action : s . cmdReviewQueue } )
2026-03-25 00:54:07 +00:00
c . Command ( "status" , core . Command { Description : "List agent workspace statuses" , Action : s . cmdStatus } )
2026-04-01 22:41:20 +00:00
c . Command ( "agentic:status" , core . Command { Description : "List agent workspace statuses" , Action : s . cmdStatus } )
2026-03-25 00:54:07 +00:00
c . Command ( "prompt" , core . Command { Description : "Build and display an agent prompt for a repo" , Action : s . cmdPrompt } )
2026-04-02 05:22:43 +00:00
c . Command ( "agentic:prompt" , core . Command { Description : "Build and display an agent prompt for a repo" , Action : s . cmdPrompt } )
2026-04-01 23:01:28 +00:00
c . Command ( "prompt_version" , core . Command { Description : "Read the current prompt snapshot for a workspace" , Action : s . cmdPromptVersion } )
c . Command ( "agentic:prompt_version" , core . Command { Description : "Read the current prompt snapshot for a workspace" , Action : s . cmdPromptVersion } )
2026-04-01 21:20:44 +00:00
c . Command ( "prompt/version" , core . Command { Description : "Read the current prompt snapshot for a workspace" , Action : s . cmdPromptVersion } )
c . Command ( "agentic:prompt/version" , core . Command { Description : "Read the current prompt snapshot for a workspace" , Action : s . cmdPromptVersion } )
2026-04-02 05:44:39 +00:00
c . Command ( "extract" , core . Command { Description : "Extract data from agent output or scaffold a workspace template" , Action : s . cmdExtract } )
2026-04-02 06:47:34 +00:00
c . Command ( "agentic:extract" , core . Command { Description : "Extract data from agent output or scaffold a workspace template" , Action : s . cmdExtract } )
2026-04-01 11:09:41 +00:00
s . registerPlanCommands ( )
2026-04-02 02:45:26 +00:00
s . registerCommitCommands ( )
2026-04-01 19:28:56 +00:00
s . registerSessionCommands ( )
2026-04-02 06:05:31 +00:00
s . registerPhaseCommands ( )
2026-04-01 11:20:14 +00:00
s . registerTaskCommands ( )
2026-04-02 03:02:37 +00:00
s . registerSprintCommands ( )
2026-04-02 00:42:55 +00:00
s . registerStateCommands ( )
2026-04-01 12:33:57 +00:00
s . registerLanguageCommands ( )
2026-04-01 23:43:08 +00:00
s . registerSetupCommands ( )
2026-03-25 00:54:07 +00:00
}
2026-03-24 21:24:29 +00:00
2026-03-30 21:58:24 +00:00
// ctx := s.commandContext()
2026-03-29 23:37:28 +00:00
func ( s * PrepSubsystem ) commandContext ( ) context . Context {
2026-03-30 21:41:45 +00:00
if s . startupContext != nil {
return s . startupContext
2026-03-29 23:37:28 +00:00
}
return context . Background ( )
}
2026-03-30 21:11:06 +00:00
func ( s * PrepSubsystem ) cmdRunTask ( options core . Options ) core . Result {
2026-04-01 20:34:04 +00:00
return s . runDispatchSync ( s . commandContext ( ) , options , "run task" , "agentic.runTask" )
2026-03-25 00:54:07 +00:00
}
2026-03-24 21:24:29 +00:00
2026-04-01 22:30:20 +00:00
func ( s * PrepSubsystem ) cmdRunFlow ( options core . Options ) core . Result {
2026-04-01 22:36:39 +00:00
return s . runFlowCommand ( options , "run flow" )
}
func ( s * PrepSubsystem ) cmdFlowPreview ( options core . Options ) core . Result {
return s . runFlowCommand ( options , "flow preview" )
}
func ( s * PrepSubsystem ) runFlowCommand ( options core . Options , commandLabel string ) core . Result {
2026-04-01 22:30:20 +00:00
flowPath := optionStringValue ( options , "_arg" , "path" , "slug" )
if flowPath == "" {
2026-04-01 22:57:37 +00:00
core . Print ( nil , "usage: core-agent %s <path-or-slug> [--dry-run] [--var=key=value] [--vars='{\"key\":\"value\"}'] [--variables='{\"key\":\"value\"}']" , commandLabel )
2026-04-01 22:30:20 +00:00
return core . Result { Value : core . E ( "agentic.cmdRunFlow" , "flow path or slug is required" , nil ) , OK : false }
}
2026-04-01 22:36:39 +00:00
dryRun := optionBoolValue ( options , "dry_run" , "dry-run" )
2026-04-01 22:57:37 +00:00
variables := optionStringMapValue ( options , "var" , "vars" , "variables" )
2026-04-01 22:36:39 +00:00
flowResult := readFlowDocument ( flowPath , variables )
2026-04-01 22:30:20 +00:00
if ! flowResult . OK {
core . Print ( nil , "error: %v" , flowResult . Value )
return core . Result { Value : flowResult . Value , OK : false }
}
document , ok := flowResult . Value . ( flowRunDocument )
if ! ok {
err := core . E ( "agentic.cmdRunFlow" , "invalid flow definition" , nil )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
output := FlowRunOutput {
Success : true ,
Source : document . Source ,
Name : document . Definition . Name ,
Description : document . Definition . Description ,
Steps : len ( document . Definition . Steps ) ,
Parsed : document . Parsed ,
}
core . Print ( nil , "flow: %s" , document . Source )
2026-04-01 22:36:39 +00:00
if dryRun {
core . Print ( nil , "dry-run: true" )
}
if len ( variables ) > 0 {
core . Print ( nil , "vars: %d" , len ( variables ) )
}
2026-04-01 22:30:20 +00:00
if document . Parsed {
if document . Definition . Name != "" {
core . Print ( nil , "name: %s" , document . Definition . Name )
}
if document . Definition . Description != "" {
core . Print ( nil , "desc: %s" , document . Definition . Description )
}
if len ( document . Definition . Steps ) == 0 {
core . Print ( nil , "steps: 0" )
return core . Result { Value : output , OK : true }
}
core . Print ( nil , "steps: %d" , len ( document . Definition . Steps ) )
2026-04-02 02:31:53 +00:00
resolvedSteps := s . printFlowSteps ( document , "" , variables , map [ string ] bool { document . Source : true } )
output . ResolvedSteps = resolvedSteps
if resolvedSteps != len ( document . Definition . Steps ) {
core . Print ( nil , "resolved steps: %d" , resolvedSteps )
2026-04-01 22:30:20 +00:00
}
return core . Result { Value : output , OK : true }
}
if document . Content != "" {
core . Print ( nil , "content: %d chars" , len ( document . Content ) )
}
return core . Result { Value : output , OK : true }
}
2026-04-01 20:34:04 +00:00
func ( s * PrepSubsystem ) cmdDispatchSync ( options core . Options ) core . Result {
return s . runDispatchSync ( s . commandContext ( ) , options , "dispatch sync" , "agentic.runDispatchSync" )
}
func ( s * PrepSubsystem ) runDispatchSync ( ctx context . Context , options core . Options , commandLabel , errorName string ) core . Result {
2026-03-30 21:11:06 +00:00
repo := options . String ( "repo" )
agent := options . String ( "agent" )
task := options . String ( "task" )
2026-03-30 21:37:15 +00:00
issueValue := options . String ( "issue" )
2026-03-30 21:11:06 +00:00
org := options . String ( "org" )
2026-03-25 00:54:07 +00:00
if repo == "" || task == "" {
2026-04-01 20:34:04 +00:00
core . Print ( nil , "usage: core-agent %s --repo=<repo> --task=\"...\" --agent=codex [--issue=N] [--org=core]" , commandLabel )
return core . Result { Value : core . E ( errorName , "repo and task are required" , nil ) , OK : false }
2026-03-25 00:54:07 +00:00
}
if agent == "" {
agent = "codex"
}
if org == "" {
org = "core"
}
2026-03-31 06:12:53 +00:00
issue := parseIntString ( issueValue )
2026-03-25 00:54:07 +00:00
2026-04-01 20:34:04 +00:00
core . Print ( nil , "core-agent %s" , commandLabel )
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
core . Print ( nil , " repo: %s/%s" , org , repo )
core . Print ( nil , " agent: %s" , agent )
2026-03-25 00:54:07 +00:00
if issue > 0 {
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
core . Print ( nil , " issue: #%d" , issue )
2026-03-25 00:54:07 +00:00
}
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
core . Print ( nil , " task: %s" , task )
core . Print ( nil , "" )
2026-03-25 00:54:07 +00:00
result := s . DispatchSync ( ctx , DispatchSyncInput {
Org : org , Repo : repo , Agent : agent , Task : task , Issue : issue ,
2026-03-24 21:24:29 +00:00
} )
2026-03-25 00:54:07 +00:00
if ! result . OK {
2026-03-30 22:40:28 +00:00
failureError := result . Error
if failureError == nil {
2026-04-01 20:34:04 +00:00
failureError = core . E ( errorName , "dispatch failed" , nil )
2026-03-30 19:07:45 +00:00
}
2026-03-30 22:40:28 +00:00
core . Print ( nil , "FAILED: %v" , failureError )
return core . Result { Value : failureError , OK : false }
2026-03-25 00:54:07 +00:00
}
2026-03-24 21:24:29 +00:00
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
core . Print ( nil , "DONE: %s" , result . Status )
2026-03-25 00:54:07 +00:00
if result . PRURL != "" {
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
core . Print ( nil , " PR: %s" , result . PRURL )
2026-03-25 00:54:07 +00:00
}
return core . Result { OK : true }
}
2026-03-24 21:24:29 +00:00
2026-03-29 23:37:28 +00:00
func ( s * PrepSubsystem ) cmdOrchestrator ( _ core . Options ) core . Result {
2026-04-01 13:42:31 +00:00
return s . runDispatchLoop ( "orchestrator" )
}
func ( s * PrepSubsystem ) cmdDispatch ( _ core . Options ) core . Result {
return s . runDispatchLoop ( "dispatch" )
}
2026-04-01 14:05:18 +00:00
func ( s * PrepSubsystem ) cmdDispatchStart ( _ core . Options ) core . Result {
_ , output , err := s . dispatchStart ( s . commandContext ( ) , nil , ShutdownInput { } )
if err != nil {
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
if output . Message != "" {
core . Print ( nil , "%s" , output . Message )
}
return core . Result { Value : output , OK : true }
}
func ( s * PrepSubsystem ) cmdDispatchShutdown ( _ core . Options ) core . Result {
_ , output , err := s . shutdownGraceful ( s . commandContext ( ) , nil , ShutdownInput { } )
if err != nil {
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
if output . Message != "" {
core . Print ( nil , "%s" , output . Message )
}
return core . Result { Value : output , OK : true }
}
func ( s * PrepSubsystem ) cmdDispatchShutdownNow ( _ core . Options ) core . Result {
_ , output , err := s . shutdownNow ( s . commandContext ( ) , nil , ShutdownInput { } )
if err != nil {
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
if output . Message != "" {
core . Print ( nil , "%s" , output . Message )
}
if output . Running > 0 || output . Queued > 0 {
core . Print ( nil , "running: %d" , output . Running )
core . Print ( nil , "queued: %d" , output . Queued )
}
return core . Result { Value : output , OK : true }
}
2026-04-02 03:36:31 +00:00
func ( s * PrepSubsystem ) cmdPoke ( _ core . Options ) core . Result {
s . Poke ( )
core . Print ( nil , "queue poke requested" )
return core . Result { OK : true }
}
2026-04-01 13:42:31 +00:00
func ( s * PrepSubsystem ) runDispatchLoop ( label string ) core . Result {
2026-03-29 23:37:28 +00:00
ctx := s . commandContext ( )
2026-04-01 13:42:31 +00:00
core . Print ( nil , "core-agent %s running (pid %s)" , label , core . Env ( "PID" ) )
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
core . Print ( nil , " workspace: %s" , WorkspaceRoot ( ) )
core . Print ( nil , " watching queue, draining on 30s tick + completion poke" )
2026-03-24 21:24:29 +00:00
2026-03-25 00:54:07 +00:00
<- ctx . Done ( )
2026-04-01 13:42:31 +00:00
core . Print ( nil , "%s shutting down" , label )
2026-03-25 00:54:07 +00:00
return core . Result { OK : true }
}
2026-03-24 21:24:29 +00:00
2026-03-30 21:11:06 +00:00
func ( s * PrepSubsystem ) cmdPrep ( options core . Options ) core . Result {
repo := options . String ( "_arg" )
2026-03-25 00:54:07 +00:00
if repo == "" {
2026-04-01 23:52:25 +00:00
core . Print ( nil , "usage: core-agent prep <repo> --issue=N|--pr=N|--branch=X --task=\"...\" [--plan-template=bug-fix] [--variables='{\"key\":\"value\"}']" )
2026-03-30 19:07:45 +00:00
return core . Result { Value : core . E ( "agentic.cmdPrep" , "repo is required" , nil ) , OK : false }
2026-03-25 00:54:07 +00:00
}
2026-04-01 23:52:25 +00:00
prepInput := prepInputFromCommandOptions ( options )
prepInput . Repo = repo
2026-03-25 00:54:07 +00:00
2026-03-30 21:11:06 +00:00
if prepInput . Issue == 0 && prepInput . PR == 0 && prepInput . Branch == "" && prepInput . Tag == "" {
prepInput . Branch = "dev"
2026-03-25 00:54:07 +00:00
}
2026-03-31 06:12:53 +00:00
_ , prepOutput , err := s . PrepareWorkspace ( context . Background ( ) , prepInput )
2026-03-25 00:54:07 +00:00
if err != nil {
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
2026-03-30 21:37:15 +00:00
core . Print ( nil , "workspace: %s" , prepOutput . WorkspaceDir )
core . Print ( nil , "repo: %s" , prepOutput . RepoDir )
core . Print ( nil , "branch: %s" , prepOutput . Branch )
2026-04-01 18:28:42 +00:00
if prepOutput . PromptVersion != "" {
core . Print ( nil , "prompt: %s" , prepOutput . PromptVersion )
}
2026-03-30 21:37:15 +00:00
core . Print ( nil , "resumed: %v" , prepOutput . Resumed )
core . Print ( nil , "memories: %d" , prepOutput . Memories )
core . Print ( nil , "consumers: %d" , prepOutput . Consumers )
if prepOutput . Prompt != "" {
2026-03-25 00:54:07 +00:00
core . Print ( nil , "" )
2026-03-30 21:37:15 +00:00
core . Print ( nil , "--- prompt (%d chars) ---" , len ( prepOutput . Prompt ) )
core . Print ( nil , "%s" , prepOutput . Prompt )
2026-03-25 00:54:07 +00:00
}
return core . Result { OK : true }
}
2026-03-24 21:24:29 +00:00
2026-04-01 20:59:52 +00:00
func ( s * PrepSubsystem ) cmdResume ( options core . Options ) core . Result {
workspace := optionStringValue ( options , "workspace" , "_arg" )
if workspace == "" {
core . Print ( nil , "usage: core-agent resume <workspace> [--answer=\"...\"] [--agent=codex] [--dry-run]" )
return core . Result { Value : core . E ( "agentic.cmdResume" , "workspace is required" , nil ) , OK : false }
}
_ , output , err := s . resume ( s . commandContext ( ) , nil , ResumeInput {
Workspace : workspace ,
Answer : optionStringValue ( options , "answer" ) ,
Agent : optionStringValue ( options , "agent" ) ,
DryRun : optionBoolValue ( options , "dry_run" , "dry-run" ) ,
} )
if err != nil {
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
core . Print ( nil , "workspace: %s" , output . Workspace )
core . Print ( nil , "agent: %s" , output . Agent )
if output . PID > 0 {
core . Print ( nil , "pid: %d" , output . PID )
}
if output . OutputFile != "" {
core . Print ( nil , "output: %s" , output . OutputFile )
}
if output . Prompt != "" {
core . Print ( nil , "" )
core . Print ( nil , "--- prompt (%d chars) ---" , len ( output . Prompt ) )
core . Print ( nil , "%s" , output . Prompt )
}
return core . Result { Value : output , OK : true }
}
2026-04-01 10:40:28 +00:00
func ( s * PrepSubsystem ) cmdGenerate ( options core . Options ) core . Result {
prompt := optionStringValue ( options , "prompt" , "_arg" )
2026-04-01 10:54:49 +00:00
briefID := optionStringValue ( options , "brief_id" , "brief-id" )
template := optionStringValue ( options , "template" )
if prompt == "" && ( briefID == "" || template == "" ) {
core . Print ( nil , "usage: core-agent generate --prompt=\"Draft a release note\" [--brief-id=brief_1 --template=help-article] [--provider=claude] [--config='{\"max_tokens\":4000}']" )
return core . Result { Value : core . E ( "agentic.cmdGenerate" , "prompt or brief-id/template is required" , nil ) , OK : false }
2026-04-01 10:40:28 +00:00
}
result := s . handleContentGenerate ( s . commandContext ( ) , core . NewOptions (
core . Option { Key : "prompt" , Value : prompt } ,
2026-04-01 10:54:49 +00:00
core . Option { Key : "brief_id" , Value : briefID } ,
core . Option { Key : "template" , Value : template } ,
2026-04-01 10:40:28 +00:00
core . Option { Key : "provider" , Value : options . String ( "provider" ) } ,
core . Option { Key : "config" , Value : options . String ( "config" ) } ,
) )
if ! result . OK {
err := commandResultError ( "agentic.cmdGenerate" , result )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
output , ok := result . Value . ( ContentGenerateOutput )
if ! ok {
err := core . E ( "agentic.cmdGenerate" , "invalid content generate output" , nil )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
if output . Result . Provider != "" {
core . Print ( nil , "provider: %s" , output . Result . Provider )
}
if output . Result . Model != "" {
core . Print ( nil , "model: %s" , output . Result . Model )
}
if output . Result . Status != "" {
core . Print ( nil , "status: %s" , output . Result . Status )
}
if output . Result . Content != "" {
core . Print ( nil , "content: %s" , output . Result . Content )
}
if output . Result . InputTokens > 0 || output . Result . OutputTokens > 0 {
core . Print ( nil , "tokens: %d in / %d out" , output . Result . InputTokens , output . Result . OutputTokens )
}
return core . Result { OK : true }
}
2026-04-02 05:39:01 +00:00
func ( s * PrepSubsystem ) cmdContentSchemaGenerate ( options core . Options ) core . Result {
schemaType := optionStringValue ( options , "schema_type" , "schema-type" , "type" , "kind" )
title := optionStringValue ( options , "title" , "headline" )
if schemaType == "" || title == "" {
core . Print ( nil , "usage: core-agent content schema generate --type=howto --title=\"Set up the workspace\" [--description=\"...\"] [--url=\"https://example.test/setup\"] [--author=\"Virgil\"] [--questions='[{\"question\":\"...\",\"answer\":\"...\"}]'] [--steps='[{\"name\":\"...\",\"text\":\"...\"}]']" )
return core . Result { Value : core . E ( "agentic.cmdContentSchemaGenerate" , "schema type and title are required" , nil ) , OK : false }
}
result := s . handleContentSchemaGenerate ( s . commandContext ( ) , core . NewOptions (
core . Option { Key : "schema_type" , Value : schemaType } ,
core . Option { Key : "title" , Value : title } ,
core . Option { Key : "description" , Value : optionStringValue ( options , "description" ) } ,
core . Option { Key : "url" , Value : optionStringValue ( options , "url" , "link" ) } ,
core . Option { Key : "author" , Value : optionStringValue ( options , "author" ) } ,
core . Option { Key : "published_at" , Value : optionStringValue ( options , "published_at" , "published-at" , "date_published" ) } ,
core . Option { Key : "modified_at" , Value : optionStringValue ( options , "modified_at" , "modified-at" , "date_modified" ) } ,
core . Option { Key : "language" , Value : optionStringValue ( options , "language" , "in_language" , "in-language" ) } ,
core . Option { Key : "image" , Value : optionStringValue ( options , "image" , "image_url" , "image-url" ) } ,
core . Option { Key : "questions" , Value : optionAnyValue ( options , "questions" , "faq" ) } ,
core . Option { Key : "steps" , Value : optionAnyValue ( options , "steps" ) } ,
) )
if ! result . OK {
err := commandResultError ( "agentic.cmdContentSchemaGenerate" , result )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
output , ok := result . Value . ( ContentSchemaOutput )
if ! ok {
err := core . E ( "agentic.cmdContentSchemaGenerate" , "invalid content schema output" , nil )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
core . Print ( nil , "schema type: %s" , output . SchemaType )
core . Print ( nil , "schema json: %s" , output . SchemaJSON )
return core . Result { Value : output , OK : true }
}
2026-04-01 13:38:03 +00:00
func ( s * PrepSubsystem ) cmdComplete ( options core . Options ) core . Result {
result := s . handleComplete ( s . commandContext ( ) , options )
if ! result . OK {
err := commandResultError ( "agentic.cmdComplete" , result )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
return result
}
2026-04-01 11:44:26 +00:00
func ( s * PrepSubsystem ) cmdScan ( options core . Options ) core . Result {
result := s . handleScan ( s . commandContext ( ) , core . NewOptions (
core . Option { Key : "org" , Value : optionStringValue ( options , "org" ) } ,
core . Option { Key : "labels" , Value : optionStringSliceValue ( options , "labels" ) } ,
core . Option { Key : "limit" , Value : optionIntValue ( options , "limit" ) } ,
) )
if ! result . OK {
err := commandResultError ( "agentic.cmdScan" , result )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
output , ok := result . Value . ( ScanOutput )
if ! ok {
err := core . E ( "agentic.cmdScan" , "invalid scan output" , nil )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
core . Print ( nil , "count: %d" , output . Count )
for _ , issue := range output . Issues {
if len ( issue . Labels ) > 0 {
core . Print ( nil , " %s#%d %s [%s]" , issue . Repo , issue . Number , issue . Title , core . Join ( "," , issue . Labels ... ) )
continue
}
core . Print ( nil , " %s#%d %s" , issue . Repo , issue . Number , issue . Title )
}
return core . Result { Value : output , OK : true }
}
2026-04-01 19:11:02 +00:00
func ( s * PrepSubsystem ) cmdMirror ( options core . Options ) core . Result {
result := s . handleMirror ( s . commandContext ( ) , core . NewOptions (
core . Option { Key : "repo" , Value : optionStringValue ( options , "repo" , "_arg" ) } ,
core . Option { Key : "dry_run" , Value : optionBoolValue ( options , "dry_run" , "dry-run" ) } ,
core . Option { Key : "max_files" , Value : optionIntValue ( options , "max_files" , "max-files" ) } ,
) )
if ! result . OK {
err := commandResultError ( "agentic.cmdMirror" , result )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
output , ok := result . Value . ( MirrorOutput )
if ! ok {
err := core . E ( "agentic.cmdMirror" , "invalid mirror output" , nil )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
core . Print ( nil , "count: %d" , output . Count )
for _ , item := range output . Synced {
core . Print ( nil , " %s commits=%d files=%d" , item . Repo , item . CommitsAhead , item . FilesChanged )
if item . PRURL != "" {
core . Print ( nil , " pr: %s" , item . PRURL )
}
if item . Skipped != "" {
core . Print ( nil , " %s" , item . Skipped )
}
}
for _ , skipped := range output . Skipped {
core . Print ( nil , "skipped: %s" , skipped )
}
return core . Result { Value : output , OK : true }
}
2026-04-01 11:54:44 +00:00
func ( s * PrepSubsystem ) cmdBrainList ( options core . Options ) core . Result {
result := s . Core ( ) . Action ( "brain.list" ) . Run ( s . commandContext ( ) , core . NewOptions (
core . Option { Key : "project" , Value : optionStringValue ( options , "project" ) } ,
core . Option { Key : "type" , Value : optionStringValue ( options , "type" ) } ,
core . Option { Key : "agent_id" , Value : optionStringValue ( options , "agent_id" , "agent" ) } ,
core . Option { Key : "limit" , Value : optionIntValue ( options , "limit" ) } ,
) )
if ! result . OK {
err := commandResultError ( "agentic.cmdBrainList" , result )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
payload , ok := result . Value . ( map [ string ] any )
if ! ok {
jsonResult := core . JSONMarshalString ( result . Value )
if jsonResult == "" {
err := core . E ( "agentic.cmdBrainList" , "invalid brain list output" , nil )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
var decoded any
if parseResult := core . JSONUnmarshalString ( jsonResult , & decoded ) ; ! parseResult . OK {
err , _ := parseResult . Value . ( error )
if err == nil {
err = core . E ( "agentic.cmdBrainList" , "invalid brain list output" , nil )
}
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
payload , ok = decoded . ( map [ string ] any )
if ! ok {
err := core . E ( "agentic.cmdBrainList" , "invalid brain list output" , nil )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
}
output := brainListOutputFromPayload ( payload )
core . Print ( nil , "count: %d" , output . Count )
if len ( output . Memories ) == 0 {
core . Print ( nil , "no memories" )
return core . Result { Value : output , OK : true }
}
for _ , memory := range output . Memories {
if memory . Project != "" || memory . AgentID != "" || memory . Confidence != 0 {
core . Print ( nil , " %s %-12s %s %s %.2f" , memory . ID , memory . Type , memory . Project , memory . AgentID , memory . Confidence )
} else {
core . Print ( nil , " %s %-12s" , memory . ID , memory . Type )
}
2026-04-02 02:39:59 +00:00
if memory . SupersedesCount > 0 {
core . Print ( nil , " supersedes: %d" , memory . SupersedesCount )
}
2026-04-02 05:11:48 +00:00
if memory . DeletedAt != "" {
core . Print ( nil , " deleted_at: %s" , memory . DeletedAt )
}
2026-04-01 11:54:44 +00:00
if memory . Content != "" {
core . Print ( nil , " %s" , memory . Content )
}
}
return core . Result { Value : output , OK : true }
}
2026-04-02 02:05:37 +00:00
// result := c.Command("brain/remember").Run(ctx, core.NewOptions(
//
// core.Option{Key: "content", Value: "Use named actions."},
// core.Option{Key: "type", Value: "convention"},
//
// ))
func ( s * PrepSubsystem ) cmdBrainRemember ( options core . Options ) core . Result {
content := optionStringValue ( options , "content" , "_arg" )
memoryType := optionStringValue ( options , "type" )
if core . Trim ( content ) == "" || memoryType == "" {
core . Print ( nil , "usage: core-agent brain remember <content> --type=observation [--tags=architecture,convention] [--project=agent] [--confidence=0.8] [--supersedes=mem-123] [--expires-in=24]" )
return core . Result { Value : core . E ( "agentic.cmdBrainRemember" , "content and type are required" , nil ) , OK : false }
}
result := s . Core ( ) . Action ( "brain.remember" ) . Run ( s . commandContext ( ) , core . NewOptions (
core . Option { Key : "content" , Value : content } ,
core . Option { Key : "type" , Value : memoryType } ,
core . Option { Key : "tags" , Value : optionStringSliceValue ( options , "tags" ) } ,
core . Option { Key : "project" , Value : optionStringValue ( options , "project" ) } ,
core . Option { Key : "confidence" , Value : optionStringValue ( options , "confidence" ) } ,
core . Option { Key : "supersedes" , Value : optionStringValue ( options , "supersedes" ) } ,
core . Option { Key : "expires_in" , Value : optionIntValue ( options , "expires_in" , "expires-in" ) } ,
) )
if ! result . OK {
err := commandResultError ( "agentic.cmdBrainRemember" , result )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
jsonResult := core . JSONMarshalString ( result . Value )
if jsonResult == "" {
err := core . E ( "agentic.cmdBrainRemember" , "invalid brain remember output" , nil )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
var decoded map [ string ] any
if parseResult := core . JSONUnmarshalString ( jsonResult , & decoded ) ; ! parseResult . OK {
err := core . E ( "agentic.cmdBrainRemember" , "invalid brain remember output" , nil )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
memoryID := stringValue ( decoded [ "memoryId" ] )
if memoryID == "" {
memoryID = stringValue ( decoded [ "memory_id" ] )
}
core . Print ( nil , "remembered: %s" , memoryID )
if timestamp := stringValue ( decoded [ "timestamp" ] ) ; timestamp != "" {
core . Print ( nil , "timestamp: %s" , timestamp )
}
return core . Result { Value : decoded , OK : true }
}
2026-04-01 21:14:02 +00:00
// result := c.Command("brain/recall").Run(ctx, core.NewOptions(
//
// core.Option{Key: "query", Value: "workspace handoff context"},
//
// ))
func ( s * PrepSubsystem ) cmdBrainRecall ( options core . Options ) core . Result {
query := optionStringValue ( options , "query" , "_arg" )
if query == "" {
core . Print ( nil , "usage: core-agent brain recall <query> [--top-k=10] [--project=agent] [--type=architecture] [--agent=virgil] [--min-confidence=0.7]" )
return core . Result { Value : core . E ( "agentic.cmdBrainRecall" , "query is required" , nil ) , OK : false }
}
result := s . Core ( ) . Action ( "brain.recall" ) . Run ( s . commandContext ( ) , core . NewOptions (
core . Option { Key : "query" , Value : query } ,
core . Option { Key : "top_k" , Value : optionIntValue ( options , "top_k" , "top-k" ) } ,
core . Option { Key : "project" , Value : optionStringValue ( options , "project" ) } ,
core . Option { Key : "type" , Value : optionStringValue ( options , "type" ) } ,
core . Option { Key : "agent_id" , Value : optionStringValue ( options , "agent_id" , "agent" ) } ,
core . Option { Key : "min_confidence" , Value : optionStringValue ( options , "min_confidence" , "min-confidence" ) } ,
) )
if ! result . OK {
err := commandResultError ( "agentic.cmdBrainRecall" , result )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
output , ok := brainRecallOutputFromResult ( result . Value )
if ! ok {
err := core . E ( "agentic.cmdBrainRecall" , "invalid brain recall output" , nil )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
core . Print ( nil , "count: %d" , output . Count )
if len ( output . Memories ) == 0 {
core . Print ( nil , "no memories" )
return core . Result { Value : output , OK : true }
}
for _ , memory := range output . Memories {
if memory . Project != "" || memory . AgentID != "" || memory . Confidence != 0 {
core . Print ( nil , " %s %-12s %s %s %.2f" , memory . ID , memory . Type , memory . Project , memory . AgentID , memory . Confidence )
} else {
core . Print ( nil , " %s %-12s" , memory . ID , memory . Type )
}
if memory . Content != "" {
core . Print ( nil , " %s" , memory . Content )
}
}
return core . Result { Value : output , OK : true }
}
2026-04-01 18:10:23 +00:00
// result := c.Command("brain/forget").Run(ctx, core.NewOptions(core.Option{Key: "_arg", Value: "mem-1"}))
func ( s * PrepSubsystem ) cmdBrainForget ( options core . Options ) core . Result {
id := optionStringValue ( options , "id" , "_arg" )
if id == "" {
core . Print ( nil , "usage: core-agent brain forget <memory-id> [--reason=\"superseded\"]" )
return core . Result { Value : core . E ( "agentic.cmdBrainForget" , "memory id is required" , nil ) , OK : false }
}
result := s . Core ( ) . Action ( "brain.forget" ) . Run ( s . commandContext ( ) , core . NewOptions (
core . Option { Key : "id" , Value : id } ,
core . Option { Key : "reason" , Value : optionStringValue ( options , "reason" ) } ,
) )
if ! result . OK {
err := commandResultError ( "agentic.cmdBrainForget" , result )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
core . Print ( nil , "forgotten: %s" , id )
if reason := optionStringValue ( options , "reason" ) ; reason != "" {
core . Print ( nil , "reason: %s" , reason )
}
return core . Result { Value : result . Value , OK : true }
}
2026-04-01 21:14:02 +00:00
type brainRecallOutput struct {
Count int ` json:"count" `
Memories [ ] brainRecallMemory ` json:"memories" `
}
type brainRecallMemory struct {
ID string ` json:"id" `
Type string ` json:"type" `
Content string ` json:"content" `
Project string ` json:"project" `
AgentID string ` json:"agent_id" `
Confidence float64 ` json:"confidence" `
2026-04-02 05:11:48 +00:00
DeletedAt string ` json:"deleted_at,omitempty" `
2026-04-01 21:14:02 +00:00
Tags [ ] string ` json:"tags" `
}
func brainRecallOutputFromResult ( value any ) ( brainRecallOutput , bool ) {
switch typed := value . ( type ) {
case brainRecallOutput :
return typed , true
case * brainRecallOutput :
if typed == nil {
return brainRecallOutput { } , false
}
return * typed , true
default :
jsonResult := core . JSONMarshalString ( value )
if jsonResult == "" {
return brainRecallOutput { } , false
}
var output brainRecallOutput
if parseResult := core . JSONUnmarshalString ( jsonResult , & output ) ; ! parseResult . OK {
return brainRecallOutput { } , false
}
return output , true
}
}
2026-04-01 13:26:08 +00:00
func ( s * PrepSubsystem ) cmdStatus ( options core . Options ) core . Result {
2026-03-30 21:22:54 +00:00
workspaceRoot := WorkspaceRoot ( )
2026-03-30 21:37:15 +00:00
filesystem := s . Core ( ) . Fs ( )
listResult := filesystem . List ( workspaceRoot )
2026-03-30 21:11:06 +00:00
if ! listResult . OK {
2026-03-30 21:22:54 +00:00
core . Print ( nil , "no workspaces found at %s" , workspaceRoot )
2026-03-25 00:54:07 +00:00
return core . Result { OK : true }
}
2026-03-29 21:19:37 +00:00
statusFiles := WorkspaceStatusPaths ( )
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
if len ( statusFiles ) == 0 {
2026-03-25 00:54:07 +00:00
core . Print ( nil , "no workspaces" )
return core . Result { OK : true }
}
2026-04-01 13:26:08 +00:00
requestedWorkspace := optionStringValue ( options , "workspace" , "_arg" )
requestedStatus := optionStringValue ( options , "status" )
limit := optionIntValue ( options , "limit" )
matched := 0
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
for _ , sf := range statusFiles {
2026-04-01 13:11:48 +00:00
workspaceDir := core . PathDir ( sf )
workspaceName := WorkspaceName ( workspaceDir )
2026-04-01 13:26:08 +00:00
if ! statusInputMatchesWorkspace ( requestedWorkspace , workspaceDir , workspaceName ) {
continue
}
2026-04-01 13:11:48 +00:00
result := ReadStatusResult ( workspaceDir )
workspaceStatus , ok := workspaceStatusValue ( result )
if ! ok {
continue
}
2026-04-01 13:26:08 +00:00
if ! statusInputMatchesStatus ( requestedStatus , workspaceStatus . Status ) {
continue
}
2026-04-01 13:11:48 +00:00
core . Print ( nil , " %-8s %-8s %-10s %s" , workspaceStatus . Status , workspaceStatus . Agent , workspaceStatus . Repo , workspaceName )
if workspaceStatus . Question != "" {
core . Print ( nil , " question: %s" , workspaceStatus . Question )
}
2026-04-01 13:26:08 +00:00
matched ++
if limit > 0 && matched >= limit {
break
}
2026-03-25 00:54:07 +00:00
}
return core . Result { OK : true }
}
2026-03-24 21:24:29 +00:00
2026-03-30 21:11:06 +00:00
func ( s * PrepSubsystem ) cmdPrompt ( options core . Options ) core . Result {
repo := options . String ( "_arg" )
2026-03-25 00:54:07 +00:00
if repo == "" {
2026-04-01 23:52:25 +00:00
core . Print ( nil , "usage: core-agent prompt <repo> --task=\"...\" [--plan-template=bug-fix] [--variables='{\"key\":\"value\"}']" )
2026-03-30 19:07:45 +00:00
return core . Result { Value : core . E ( "agentic.cmdPrompt" , "repo is required" , nil ) , OK : false }
2026-03-25 00:54:07 +00:00
}
2026-04-01 23:52:25 +00:00
prepInput := prepInputFromCommandOptions ( options )
prepInput . Repo = repo
if prepInput . Org == "" {
prepInput . Org = "core"
2026-03-25 00:54:07 +00:00
}
2026-04-01 23:52:25 +00:00
if prepInput . Task == "" {
prepInput . Task = "Review and report findings"
2026-03-25 00:54:07 +00:00
}
2026-04-01 23:52:25 +00:00
repoPath := core . JoinPath ( HomeDir ( ) , "Code" , prepInput . Org , prepInput . Repo )
2026-03-25 00:54:07 +00:00
2026-03-31 06:12:53 +00:00
prompt , memories , consumers := s . BuildPrompt ( context . Background ( ) , prepInput , "dev" , repoPath )
2026-03-25 00:54:07 +00:00
core . Print ( nil , "memories: %d" , memories )
core . Print ( nil , "consumers: %d" , consumers )
core . Print ( nil , "" )
core . Print ( nil , "%s" , prompt )
return core . Result { OK : true }
}
2026-03-24 21:24:29 +00:00
2026-04-01 23:52:25 +00:00
func prepInputFromCommandOptions ( options core . Options ) PrepInput {
commandOptions := core . NewOptions ( options . Items ( ) ... )
if commandOptions . String ( "repo" ) == "" {
if repo := optionStringValue ( options , "_arg" ) ; repo != "" {
commandOptions . Set ( "repo" , repo )
}
}
return prepInputFromOptions ( commandOptions )
}
2026-04-01 21:20:44 +00:00
func ( s * PrepSubsystem ) cmdPromptVersion ( options core . Options ) core . Result {
workspace := optionStringValue ( options , "workspace" , "_arg" )
if workspace == "" {
core . Print ( nil , "usage: core-agent prompt version <workspace>" )
return core . Result { Value : core . E ( "agentic.cmdPromptVersion" , "workspace is required" , nil ) , OK : false }
}
result := s . handlePromptVersion ( s . commandContext ( ) , core . NewOptions (
core . Option { Key : "workspace" , Value : workspace } ,
) )
if ! result . OK {
err := commandResultError ( "agentic.cmdPromptVersion" , result )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
output , ok := result . Value . ( PromptVersionOutput )
if ! ok {
err := core . E ( "agentic.cmdPromptVersion" , "invalid prompt version output" , nil )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
core . Print ( nil , "workspace: %s" , output . Workspace )
core . Print ( nil , "hash: %s" , output . Snapshot . Hash )
if output . Snapshot . CreatedAt != "" {
core . Print ( nil , "created: %s" , output . Snapshot . CreatedAt )
}
core . Print ( nil , "chars: %d" , len ( output . Snapshot . Content ) )
return core . Result { Value : output , OK : true }
}
2026-03-30 21:11:06 +00:00
func ( s * PrepSubsystem ) cmdExtract ( options core . Options ) core . Result {
2026-04-02 05:44:39 +00:00
sourcePath := optionStringValue ( options , "source" , "input" , "file" )
2026-03-30 21:11:06 +00:00
templateName := options . String ( "_arg" )
if templateName == "" {
templateName = "default"
2026-03-25 00:54:07 +00:00
}
2026-03-30 21:11:06 +00:00
target := options . String ( "target" )
2026-04-02 05:44:39 +00:00
if sourcePath == "" && fs . Exists ( templateName ) && fs . IsFile ( templateName ) {
sourcePath = templateName
templateName = ""
}
if sourcePath != "" {
readResult := fs . Read ( sourcePath )
if ! readResult . OK {
err , _ := readResult . Value . ( error )
if err == nil {
err = core . E ( "agentic.cmdExtract" , core . Concat ( "read agent output " , sourcePath ) , nil )
}
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
extracted := extractAgentOutputContent ( readResult . Value . ( string ) )
if extracted == "" {
err := core . E ( "agentic.cmdExtract" , "agent output did not contain extractable content" , nil )
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
if target != "" {
if writeResult := fs . WriteMode ( target , extracted , 0644 ) ; ! writeResult . OK {
err , _ := writeResult . Value . ( error )
if err == nil {
err = core . E ( "agentic.cmdExtract" , core . Concat ( "write extracted output " , target ) , nil )
}
core . Print ( nil , "error: %v" , err )
return core . Result { Value : err , OK : false }
}
core . Print ( nil , "written: %s" , target )
} else {
core . Print ( nil , "%s" , extracted )
}
return core . Result { Value : extracted , OK : true }
}
2026-03-25 00:54:07 +00:00
if target == "" {
2026-03-30 18:52:15 +00:00
target = core . JoinPath ( WorkspaceRoot ( ) , "test-extract" )
2026-03-25 00:54:07 +00:00
}
2026-03-30 21:11:06 +00:00
workspaceData := & lib . WorkspaceData {
2026-03-25 00:54:07 +00:00
Repo : "test-repo" ,
Branch : "dev" ,
Task : "test extraction" ,
Agent : "codex" ,
}
2026-03-30 21:11:06 +00:00
core . Print ( nil , "extracting template %q to %s" , templateName , target )
if result := lib . ExtractWorkspace ( templateName , target , workspaceData ) ; ! result . OK {
2026-03-30 19:14:14 +00:00
if err , ok := result . Value . ( error ) ; ok {
2026-03-30 21:11:06 +00:00
return core . Result { Value : core . E ( "agentic.cmdExtract" , core . Concat ( "extract workspace template " , templateName ) , err ) , OK : false }
2026-03-30 19:14:14 +00:00
}
2026-03-30 21:11:06 +00:00
return core . Result { Value : core . E ( "agentic.cmdExtract" , core . Concat ( "extract workspace template " , templateName ) , nil ) , OK : false }
2026-03-25 00:54:07 +00:00
}
2026-03-30 21:37:15 +00:00
filesystem := s . Core ( ) . Fs ( )
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
paths := core . PathGlob ( core . JoinPath ( target , "*" ) )
for _ , p := range paths {
name := core . PathBase ( p )
marker := " "
2026-03-30 21:37:15 +00:00
if filesystem . IsDir ( p ) {
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
marker = "/"
2026-03-25 00:54:07 +00:00
}
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
core . Print ( nil , " %s%s" , name , marker )
2026-03-25 00:54:07 +00:00
}
core . Print ( nil , "done" )
return core . Result { OK : true }
}
2026-03-24 21:24:29 +00:00
2026-04-02 05:44:39 +00:00
func extractAgentOutputContent ( content string ) string {
trimmed := core . Trim ( content )
if trimmed == "" {
return ""
}
if core . HasPrefix ( trimmed , "{" ) || core . HasPrefix ( trimmed , "[" ) {
return trimmed
}
blocks := core . Split ( content , "```" )
for index := 1 ; index < len ( blocks ) ; index += 2 {
block := core . Trim ( blocks [ index ] )
if block == "" {
continue
}
lines := core . SplitN ( block , "\n" , 2 )
if len ( lines ) == 2 {
language := core . Trim ( lines [ 0 ] )
body := core . Trim ( lines [ 1 ] )
if language != "" && ! core . Contains ( language , " " ) && body != "" {
block = body
}
}
block = core . Trim ( block )
if block != "" {
return block
}
}
return ""
}
2026-03-31 06:12:53 +00:00
// parseIntString("issue-42") // 42
func parseIntString ( s string ) int {
2026-03-25 00:54:07 +00:00
n := 0
for _ , ch := range s {
if ch >= '0' && ch <= '9' {
n = n * 10 + int ( ch - '0' )
}
}
return n
2026-03-24 21:24:29 +00:00
}
2026-04-01 11:54:44 +00:00
2026-04-01 22:30:20 +00:00
type FlowRunOutput struct {
2026-04-02 02:31:53 +00:00
Success bool ` json:"success" `
Source string ` json:"source,omitempty" `
Name string ` json:"name,omitempty" `
Description string ` json:"description,omitempty" `
Steps int ` json:"steps,omitempty" `
ResolvedSteps int ` json:"resolved_steps,omitempty" `
Parsed bool ` json:"parsed,omitempty" `
2026-04-01 22:30:20 +00:00
}
type flowDefinition struct {
Name string ` yaml:"name" `
Description string ` yaml:"description" `
Steps [ ] flowDefinitionStep ` yaml:"steps" `
}
type flowDefinitionStep struct {
Name string ` yaml:"name" `
Run string ` yaml:"run" `
Flow string ` yaml:"flow" `
Agent string ` yaml:"agent" `
Prompt string ` yaml:"prompt" `
Template string ` yaml:"template" `
Timeout string ` yaml:"timeout" `
When string ` yaml:"when" `
Output string ` yaml:"output" `
Gate string ` yaml:"gate" `
Parallel [ ] flowDefinitionStep ` yaml:"parallel" `
}
type flowRunDocument struct {
Source string
Content string
Parsed bool
Definition flowDefinition
}
2026-04-01 22:36:39 +00:00
func readFlowDocument ( path string , variables map [ string ] string ) core . Result {
2026-04-01 22:30:20 +00:00
if readResult := fs . Read ( path ) ; readResult . OK {
2026-04-01 22:36:39 +00:00
content := applyTemplateVariables ( readResult . Value . ( string ) , variables )
2026-04-01 22:30:20 +00:00
definition , err := parseFlowDefinition ( content )
if err != nil {
if flowInputLooksYaml ( path ) {
return core . Result { Value : err , OK : false }
}
return core . Result { Value : flowRunDocument {
Source : path ,
Content : content ,
Parsed : false ,
} , OK : true }
}
return core . Result { Value : flowRunDocument {
Source : path ,
Content : content ,
Parsed : true ,
Definition : definition ,
} , OK : true }
}
flowResult := lib . Flow ( flowSlugFromPath ( path ) )
if ! flowResult . OK {
if err , ok := flowResult . Value . ( error ) ; ok {
return core . Result { Value : core . E ( "agentic.cmdRunFlow" , core . Concat ( "flow not found: " , path ) , err ) , OK : false }
}
return core . Result { Value : core . E ( "agentic.cmdRunFlow" , core . Concat ( "flow not found: " , path ) , nil ) , OK : false }
}
2026-04-01 22:36:39 +00:00
content := applyTemplateVariables ( flowResult . Value . ( string ) , variables )
2026-04-01 22:30:20 +00:00
definition , err := parseFlowDefinition ( content )
if err != nil {
return core . Result { Value : flowRunDocument {
Source : core . Concat ( "embedded:" , flowSlugFromPath ( path ) ) ,
Content : content ,
Parsed : false ,
} , OK : true }
}
return core . Result { Value : flowRunDocument {
Source : core . Concat ( "embedded:" , flowSlugFromPath ( path ) ) ,
Content : content ,
Parsed : true ,
Definition : definition ,
} , OK : true }
}
func parseFlowDefinition ( content string ) ( flowDefinition , error ) {
var definition flowDefinition
if err := yaml . Unmarshal ( [ ] byte ( content ) , & definition ) ; err != nil {
return flowDefinition { } , core . E ( "agentic.parseFlowDefinition" , "invalid flow definition" , err )
}
if definition . Name == "" || len ( definition . Steps ) == 0 {
return flowDefinition { } , core . E ( "agentic.parseFlowDefinition" , "invalid flow definition" , nil )
}
return definition , nil
}
func flowInputLooksYaml ( path string ) bool {
return core . HasSuffix ( path , ".yaml" ) || core . HasSuffix ( path , ".yml" )
}
func flowSlugFromPath ( path string ) string {
slug := core . PathBase ( path )
for _ , suffix := range [ ] string { ".yaml" , ".yml" , ".md" } {
slug = core . TrimSuffix ( slug , suffix )
}
return slug
}
func flowStepSummary ( step flowDefinitionStep ) string {
label := core . Trim ( step . Name )
if label == "" {
label = core . Trim ( step . Flow )
}
if label == "" {
label = core . Trim ( step . Agent )
}
if label == "" {
label = core . Trim ( step . Run )
}
if label == "" {
label = "step"
}
switch {
case step . Flow != "" :
return core . Concat ( label , ": flow " , step . Flow )
case step . Agent != "" :
return core . Concat ( label , ": agent " , step . Agent )
case step . Run != "" :
return core . Concat ( label , ": run " , step . Run )
case step . Gate != "" :
return core . Concat ( label , ": gate " , step . Gate )
default :
return label
}
}
2026-04-02 02:31:53 +00:00
func ( s * PrepSubsystem ) printFlowSteps ( document flowRunDocument , indent string , variables map [ string ] string , visited map [ string ] bool ) int {
total := 0
for index , step := range document . Definition . Steps {
core . Print ( nil , "%s%d. %s" , indent , index + 1 , flowStepSummary ( step ) )
total ++
if step . Flow != "" {
resolved := s . resolveFlowReference ( document . Source , step . Flow , variables )
if ! resolved . OK {
continue
}
nested , ok := resolved . Value . ( flowRunDocument )
if ! ok || nested . Source == "" {
continue
}
if visited [ nested . Source ] {
core . Print ( nil , "%s cycle: %s" , indent , nested . Source )
continue
}
core . Print ( nil , "%s resolved: %s" , indent , nested . Source )
visited [ nested . Source ] = true
total += s . printFlowSteps ( nested , core . Concat ( indent , " " ) , variables , visited )
delete ( visited , nested . Source )
}
if len ( step . Parallel ) > 0 {
core . Print ( nil , "%s parallel:" , indent )
for parallelIndex , parallelStep := range step . Parallel {
core . Print ( nil , "%s %d. %s" , indent , parallelIndex + 1 , flowStepSummary ( parallelStep ) )
}
}
}
return total
}
func ( s * PrepSubsystem ) resolveFlowReference ( baseSource , reference string , variables map [ string ] string ) core . Result {
trimmedReference := core . Trim ( reference )
if trimmedReference == "" {
return core . Result { Value : core . E ( "agentic.resolveFlowReference" , "flow reference is required" , nil ) , OK : false }
}
candidates := [ ] string { trimmedReference }
if root := flowRootPath ( baseSource ) ; root != "" {
candidate := core . JoinPath ( root , trimmedReference )
if candidate != trimmedReference {
candidates = append ( candidates , candidate )
}
}
repoCandidate := core . JoinPath ( "pkg" , "lib" , "flow" , trimmedReference )
if repoCandidate != trimmedReference {
candidates = append ( candidates , repoCandidate )
}
for _ , candidate := range candidates {
result := readFlowDocument ( candidate , variables )
if result . OK {
return result
}
err , ok := result . Value . ( error )
if ! ok || ! core . Contains ( err . Error ( ) , "flow not found:" ) {
return result
}
}
return core . Result { Value : core . E ( "agentic.resolveFlowReference" , core . Concat ( "flow not found: " , trimmedReference ) , nil ) , OK : false }
}
func flowRootPath ( source string ) string {
trimmed := core . Trim ( core . Replace ( source , "\\" , "/" ) )
if trimmed == "" {
return ""
}
segments := core . Split ( trimmed , "/" )
for index := 0 ; index + 2 < len ( segments ) ; index ++ {
if segments [ index ] == "pkg" && segments [ index + 1 ] == "lib" && segments [ index + 2 ] == "flow" {
return core . JoinPath ( segments [ : index + 3 ] ... )
}
}
dir := core . PathDir ( trimmed )
if dir != "" {
return dir
}
return ""
}
2026-04-01 11:54:44 +00:00
type brainListOutput struct {
Count int ` json:"count" `
Memories [ ] brainListOutputEntry ` json:"memories" `
}
type brainListOutputEntry struct {
2026-04-02 02:39:59 +00:00
ID string ` json:"id" `
Type string ` json:"type" `
Content string ` json:"content" `
Project string ` json:"project" `
AgentID string ` json:"agent_id" `
Confidence float64 ` json:"confidence" `
SupersedesCount int ` json:"supersedes_count,omitempty" `
2026-04-02 05:11:48 +00:00
DeletedAt string ` json:"deleted_at,omitempty" `
2026-04-02 02:39:59 +00:00
Tags [ ] string ` json:"tags" `
2026-04-01 11:54:44 +00:00
}
func brainListOutputFromPayload ( payload map [ string ] any ) brainListOutput {
output := brainListOutput { }
switch count := payload [ "count" ] . ( type ) {
case float64 :
output . Count = int ( count )
case int :
output . Count = count
}
if memories , ok := payload [ "memories" ] . ( [ ] any ) ; ok {
for _ , item := range memories {
entryMap , ok := item . ( map [ string ] any )
if ! ok {
continue
}
entry := brainListOutputEntry {
ID : brainListStringValue ( entryMap [ "id" ] ) ,
Type : brainListStringValue ( entryMap [ "type" ] ) ,
Content : brainListStringValue ( entryMap [ "content" ] ) ,
Project : brainListStringValue ( entryMap [ "project" ] ) ,
AgentID : brainListStringValue ( entryMap [ "agent_id" ] ) ,
}
switch confidence := entryMap [ "confidence" ] . ( type ) {
case float64 :
entry . Confidence = confidence
case int :
entry . Confidence = float64 ( confidence )
}
if entry . Confidence == 0 {
switch confidence := entryMap [ "score" ] . ( type ) {
case float64 :
entry . Confidence = confidence
case int :
entry . Confidence = float64 ( confidence )
}
}
2026-04-02 02:39:59 +00:00
switch supersedesCount := entryMap [ "supersedes_count" ] . ( type ) {
case float64 :
entry . SupersedesCount = int ( supersedesCount )
case int :
entry . SupersedesCount = supersedesCount
}
2026-04-02 05:11:48 +00:00
entry . DeletedAt = brainListStringValue ( entryMap [ "deleted_at" ] )
2026-04-01 11:54:44 +00:00
if tags , ok := entryMap [ "tags" ] . ( [ ] any ) ; ok {
for _ , tag := range tags {
entry . Tags = append ( entry . Tags , brainListStringValue ( tag ) )
}
}
output . Memories = append ( output . Memories , entry )
}
}
if output . Count == 0 {
output . Count = len ( output . Memories )
}
return output
}
func brainListStringValue ( value any ) string {
switch typed := value . ( type ) {
case string :
return typed
case int :
return core . Sprint ( typed )
case int64 :
return core . Sprint ( typed )
case float64 :
return core . Sprint ( typed )
}
return ""
}