- Add ListHandlers map to AgentCoreConfig/agent struct; /skills and /tools
dispatch through it instead of reading local paths directly
- Add ReadPlanStep to AgentCoreConfig; wired by 9p/ directly from sess.plan
- Export NextUncheckedStep([]byte) as pure helper
- Fix prependOlliePath to use OLLIE_CFG_PATH/scripts/x/ instead of $OLLIE/x/
- Add OLLIE_CFG_PATH to EnsureDefaults and managed env var list
Session identity is now a numeric UID (starting at 10000) assigned at
creation and never changed. Session names can be renamed freely without
affecting the 9P identity.
- AgentCoreConfig.Uname carries the principal
- pushSessionEnv sets OLLIE_UNAME on the execute server
- startMount gated by WithMount() option (not env var)
- Close() uses context timeout to avoid hanging on fusermount
The execute server now starts ollie-9p-mount when OLLIE_SESSION_ID is
set, giving each agent session its own FUSE proxy that attaches to
olliesrv with Uname=session_id. Tools see the full namespace through
$OLLIE but all 9P operations carry the session's identity.
Close() tears down the mount on session destroy.
- Wire PlanFile from $OLLIE/s/{id}/plan into agentConfig so plan
re-injection is no longer dead code
- Add missing failureWindow/maxFailures/blockDuration constants
- Replace hand-rolled contains() with strings.Contains
- Fix rm -rf .. regex to match end-of-string and whitespace
- Add TestPlanReinjection covering periodic plan re-surfacing
- Add loop_maxsteps_helpers_test.go with mockResponse/newState/sequentialStream
- steps: independent, run in parallel when annotated safe, outputs
concatenated. No stdout chaining.
- pipe: explicit pipeline, sequential, stdout of each stage feeds
stdin of the next.
steps and pipe are mutually exclusive in a single execute_code call.
WrapCommand now returns an error instead of silently falling back to
unsandboxed execution when landrun is not in PATH. execute_code
propagates this as a hard failure.
Add {PLAN9} to test sandbox rwx list so plan9 binaries (cat, sleep,
grep, bc, sed) are accessible. Drop -q from bc invocation since
plan9 bc does not support it; -l alone works on both GNU and plan9.
Entries in the prompt array that contain a newline are now treated as
literal text instead of shell commands. This enables JIT agent configs
to embed identity text directly without escaping.
Also clarify that execute_code timeout is a top-level parameter, not
per-step, to prevent models from placing it in the wrong location.
- Add paths.ExpandHome() helper for tilde expansion
- Apply in NewAgentCore, SetCWD (agent + execute server), and hook runner
- Fixes 'chdir ~/path: no such file or directory' errors
- Add contract tests for tools.Server and tools.Dispatcher interfaces
(tools_test.go), covering all exported behavior including error paths.
pkg/tools coverage: 0% -> 100%.
- Add contract test for execute.Server (ListTools, CallTool), Decl
factory test, and executeElevated early-exit test. execute coverage:
68% -> 71%.
- Remove Close() from Server and Dispatcher interfaces and all
implementations/callers. These existed for MCP server cleanup which
has been removed.
- sandbox: remove dead code (DefaultConfig, Load/Save, LayeredConfig, Merge,
Version, SystemDefaults, validateName, ConfigPath, OpenSandbox); unexport
internal symbols; LoadSandbox now takes io.Reader; loadSandboxConfig owns
file opening; 83% package coverage via new sandbox_test.go
- backend: add BaseURL field to AnthropicBackend for testability; new
backend_test.go runs checkContract against all five implementations
(Ollama, OpenAI, Copilot, Anthropic, CodeWhisperer) via httptest servers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Allows wrapper scripts in ~/.config/ollie/scripts/x/ to shadow system
binaries transparently without modifying the user's shell environment.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove the elevation package and Elevator interface entirely. The
execute server now invokes x/elevate directly, with detection reduced
to a stat check. Decl() loses the elevator parameter.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove session-scoped env injection from frontend (s/{id}/env, -e/-env flags) — superseded
by per-invocation superpowers run-session in the elevator. Keep agentCore env map and
OLLIE_SESSION_ID propagation via pushSessionEnv.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New pkg/env package owns EnsureDefaults, Set, Get, All, Format
- BuildAgentEnv reverted to 3-arg signature (no initialEnv)
- agentCore.setEnv removed; pushSessionEnv handles OLLIE_SESSION_ID only
- execute.Server.SetEnv no longer calls os.Setenv (session-scoped only)
- !cmd handler sets OLLIE_SESSION_ID explicitly in subprocess env
- mcp/transport: seed cmd.Env from os.Environ() so MCP servers inherit PATH etc.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- execute_code now takes steps:[{code,language}|{tool,args}] instead of
a single code/language pair. Single-step calls return raw output;
multi-step calls run in parallel and return results under === step N ===
headers in submission order.
- execute_pipe stages may now include {parallel:[...]} to fan out
concurrently within a pipeline. Parallel outputs are concatenated in
submission order and fed as stdin to the next stage.
- Stage execution is now Go-level (stdin chaining) rather than a single
bash pipeline string, enabling parallel stages and tool/code mixing.
- CodeStep and resolveCodeStep are the shared primitives for both
execute_code and execute_pipe parallel stages.
- executeWithStdin added to Server for stdin chaining between stages.
- Tool steps use shebang detection; language field applies only to
inline code steps (default: bash).
- ListTools schemas and descriptions updated throughout.
- extractMCPResult: parse isError from MCP response so tool failures
are returned as Go errors and marked isErr=true in the loop
- CallTool: emit isError:true content block instead of bare {"error":...}
so the model sees tool failures as error results, not success
- SetEnv: call os.Setenv so OLLIE_SESSION_ID/OLLIE are in the process
env and inherited by sandboxed subprocesses
- NewAgentCore: inject session env into execute server at creation time,
not only on rename, so tools have OLLIE_SESSION_ID from the first call
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add TrustedToolsSetter interface and SetTrustedTools to execute.Server
- Add allowed(): trusted tools return true; untrusted with no Confirm
return false (deny by default). Confirm returns true=allow, consistent
with allowed() semantics throughout.
- BuildAgentEnv wires cfg.TrustedTools into the execute server
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace {{.Tools}} injection with ollie/t/idx (generated at session
start by rebuildToolsIdx); prompt now instructs grep-based discovery
- Replace {{.Skills}} injection with ollie/sk/idx (rebuildSkillsIdx);
same grep pattern
- Add {{.SessionID}} to system prompt identity line
- Expand filesystem section: full ollie/s/ layout, all session files,
ctl commands, s/idx cooperation pattern
- Fix execute_tool description: use ollie/t instead of physical ToolsPath()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
awk/sed/jq: exec.Command directly with program as arg — no shell, no escaping.
ed/expect/bc: exec.Command with cmd.Stdin — program piped without escaping.
execute_tool with file args: language switches to "bash" after injectArgs
since the resulting snippet is already a bash command.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
jq: filter as positional arg, file args appended, pipeline-safe.
expect: pipes script via printf '%s' $'...' | expect -.
bc: pipes via printf '%s' $'...' | bc -ql (quiet + math library).
All three use ANSI-C quoting consistently.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sed: sed -e $'...' inline, file args appended, pipeline-safe.
ed: pipes script via printf '%s' $'...' | ed -s [file].
detectLanguage now parses shebang command basename rather than
using strings.Contains, fixing potential false matches.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Uses gawk -e $'...' (ANSI-C quoting) consistently across Execute() and
pipelines. injectArgs for awk produces a bash snippet with file args
after --. No BEGIN block hacks needed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
loadEnvFile now strips " # ..." suffixes from values so inline comments
in ~/.config/ollie/env don't leak into environment variables. Also add
kiro to the supported-backends error message and fix two raw-string
backtick escaping errors in tool descriptions.
execute.Decl is now a function (func(workdir string) func() tools.Server)
rather than a var, making workdir an explicit dependency rather than
an implicit os.Getwd() call. execute.Server stores the workdir and
sets cmd.Dir accordingly; falls back to os.Getwd() if empty.
AgentCoreConfig gains WorkDir string, threaded into BuildAgentEnv and
the system prompt. The /agent switch uses s.workdir so the correct
directory is preserved across agent switches.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- execute.Decl and file.Decl: package-level func() tools.Server factories;
consumers reference them without calling directly
- tools.NewDispatcherFunc: builds a fresh Dispatcher per call by invoking
each registered Decl — used as AgentCoreConfig.NewDispatcher
- execute.Server: remove LogDir, WorkspaceBase, MaxOutputChars, and all
file-based logging (metrics.go deleted); New() takes no args
- Export AgentConfigPath, NewSessionID, DefaultAgentsDir, DefaultSessionsDir
from pkg/agent so frontends don't duplicate them
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>