Summary
Add a one-shot, non-interactive CLI invocation mode to agentloop. Currently start-cli.ts always enters the interactive readline REPL. This feature adds a new entry point src/start-oneshot.ts (or extends start-cli.ts) that parses subcommands and flags from process.argv, runs a single operation, prints the result to stdout, and exits — making agentloop scriptable and composable in pipelines and CI workflows.
Motivation
- Scripting & automation: Allow shell scripts, Makefiles, and CI steps to call
agentloop without any interactive session.
- Tool testing: Developers can directly invoke individual tools (e.g.
websearch, web-fetch) from the command line without wiring up a full agent loop.
- Bun binary compatibility: A one-shot mode is a natural fit for a compiled native binary (see related issue on Bun
--compile).
Proposed CLI Design
Entry point
npx tsx src/start-oneshot.ts <command> [options]
# or, after binary compilation:
agentloop <command> [options]
Commands
agent — Run the full agentic loop once and exit
agentloop agent [options]
Options:
-s, --system <text> Override the system prompt
-u, --user <text> User prompt / task (required)
-p, --profile <name> Agent profile to activate (e.g. coder, planner)
--stream Stream output tokens to stdout
--json Output result as JSON { output: string }
Examples:
# Simple one-shot query
agentloop agent -u "What files are in the src directory?"
# Override system prompt
agentloop agent -s "You are a concise assistant." -u "Summarise the README"
# Use a specific profile and stream output
agentloop agent --profile coder --stream -u "Refactor src/config.ts to use zod"
# Machine-readable output
agentloop agent --json -u "List all exported functions in src/index.ts"
websearch — Invoke the web-search tool directly
agentloop websearch [options]
Options:
-q, --query <text> Search query (required)
-n, --max-results <n> Maximum results to return (default: 5)
--json Output raw JSON result array
Example:
agentloop websearch -q "LangChain tool calling best practices" -n 3
agentloop websearch --query "Bun compile native binary" --json
web-fetch — Invoke the web-fetch tool directly
agentloop web-fetch [options]
Options:
-u, --url <url> URL to fetch (required)
--json Output raw JSON { title, markdown, ... }
agentloop list [tools|agentprofiles|...]
lists all built-in, discovered, configured active capabilities
Future tool subcommands (extensible pattern)
Any registered tool could be exposed as a subcommand following the same pattern:
agentloop <tool-name> [--<param> <value> ...]
Implementation Notes
- New file:
src/start-oneshot.ts — parse process.argv using Node's built-in util.parseArgs (no extra dependency) or minimist.
agent command: call agentExecutor.invoke(userPrompt, profileName) (already exported from src/index.ts), print result.output to stdout, exit 0. For --stream, use agentExecutor.stream(...).
- Tool subcommands (
websearch, web-fetch, …): call toolRegistry.get(toolName).invoke(args) directly — no LLM involved. ensureInitialized() must be called first to load the tool registry.
--json flag: write JSON.stringify(result) to stdout instead of plain text — useful for piping into jq.
--system flag: pass the value as a prefix to the system prompt or inject it into getSystemPrompt() as an override.
- Exit codes:
0 on success, 1 on error. Errors printed to stderr.
- Add a
package.json script: "oneshot": "npx tsx src/start-oneshot.ts".
Acceptance Criteria
Summary
Add a one-shot, non-interactive CLI invocation mode to
agentloop. Currentlystart-cli.tsalways enters the interactive readline REPL. This feature adds a new entry pointsrc/start-oneshot.ts(or extendsstart-cli.ts) that parses subcommands and flags fromprocess.argv, runs a single operation, prints the result tostdout, and exits — makingagentloopscriptable and composable in pipelines and CI workflows.Motivation
agentloopwithout any interactive session.websearch,web-fetch) from the command line without wiring up a full agent loop.--compile).Proposed CLI Design
Entry point
Commands
agent— Run the full agentic loop once and exitExamples:
websearch— Invoke the web-search tool directlyExample:
web-fetch— Invoke the web-fetch tool directlyagentloop list [tools|agentprofiles|...]
lists all built-in, discovered, configured active capabilities
Future tool subcommands (extensible pattern)
Any registered tool could be exposed as a subcommand following the same pattern:
Implementation Notes
src/start-oneshot.ts— parseprocess.argvusing Node's built-inutil.parseArgs(no extra dependency) orminimist.agentcommand: callagentExecutor.invoke(userPrompt, profileName)(already exported fromsrc/index.ts), printresult.outputtostdout, exit0. For--stream, useagentExecutor.stream(...).websearch,web-fetch, …): calltoolRegistry.get(toolName).invoke(args)directly — no LLM involved.ensureInitialized()must be called first to load the tool registry.--jsonflag: writeJSON.stringify(result)tostdoutinstead of plain text — useful for piping intojq.--systemflag: pass the value as a prefix to the system prompt or inject it intogetSystemPrompt()as an override.0on success,1on error. Errors printed tostderr.package.jsonscript:"oneshot": "npx tsx src/start-oneshot.ts".Acceptance Criteria
agentloop agent -u "..."runs the agent loop once and exits with the response onstdoutagentloop agent -s "..." -u "..."applies the custom system prompt overrideagentloop agent --profile coder -u "..."activates the named agent profileagentloop agent --stream -u "..."streams tokens tostdoutagentloop agent --json -u "..."outputs{ "output": "..." }as JSONagentloop websearch -q "..."invokes the web-search tool directly and prints resultsagentloop web-fetch -u "..."invokes the web-fetch tool directly and prints markdown1-x) and long (--xxx) formsREADME.md/docs/getting-started.mdupdated with one-shot usage examples