@sandagent/runner-cli 0.1.2-beta.1 → 0.1.2-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -16,6 +16,11 @@ import { runAgent } from "./runner.js";
16
16
  function parseCliArgs() {
17
17
  const { values, positionals } = parseArgs({
18
18
  options: {
19
+ runner: {
20
+ type: "string",
21
+ short: "r",
22
+ default: "claude",
23
+ },
19
24
  model: {
20
25
  type: "string",
21
26
  short: "m",
@@ -81,6 +86,12 @@ function parseCliArgs() {
81
86
  console.error('Usage: sandagent run [options] -- "<user input>"');
82
87
  process.exit(1);
83
88
  }
89
+ // Validate runner
90
+ const runner = values.runner;
91
+ if (!["claude", "codex", "copilot"].includes(runner)) {
92
+ console.error('Error: --runner must be one of: "claude", "codex", "copilot"');
93
+ process.exit(1);
94
+ }
84
95
  // Validate output-format
85
96
  const outputFormat = values["output-format"];
86
97
  if (outputFormat &&
@@ -89,6 +100,7 @@ function parseCliArgs() {
89
100
  process.exit(1);
90
101
  }
91
102
  return {
103
+ runner,
92
104
  model: values.model,
93
105
  cwd: values.cwd,
94
106
  systemPrompt: values["system-prompt"],
@@ -113,6 +125,7 @@ Usage:
113
125
  sandagent run [options] -- "<user input>"
114
126
 
115
127
  Options:
128
+ -r, --runner <runner> Runner to use: claude, codex, copilot (default: claude)
116
129
  -m, --model <model> Model to use (default: claude-sonnet-4-20250514)
117
130
  -c, --cwd <path> Working directory (default: current directory)
118
131
  -s, --system-prompt <prompt> Custom system prompt
@@ -145,6 +158,7 @@ async function main() {
145
158
  process.chdir(args.cwd);
146
159
  // Run the agent and stream output to stdout
147
160
  await runAgent({
161
+ runner: args.runner,
148
162
  model: args.model,
149
163
  userInput: args.userInput,
150
164
  systemPrompt: args.systemPrompt,
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAcvC,SAAS,YAAY;IACnB,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;QACxC,OAAO,EAAE;YACP,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,GAAG;gBACV,OAAO,EAAE,0BAA0B;aACpC;YACD,GAAG,EAAE;gBACH,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,GAAG;gBACV,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,EAAE;aAC1D;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,GAAG;aACX;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,GAAG;aACX;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,GAAG;aACX;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,GAAG;aACX;YACD,cAAc,EAAE;gBACd,IAAI,EAAE,QAAQ;aACf;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,GAAG;aACX;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,GAAG;aACX;SACF;QACD,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE,IAAI;KACb,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,0BAA0B;IAC1B,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,6CAA6C;IAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,SAAS,GAAG,EAAE,CAAC;IAEnB,IAAI,SAAS,KAAK,CAAC,CAAC,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1D,CAAC;SAAM,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,yBAAyB;IACzB,MAAM,YAAY,GAAG,MAAM,CAAC,eAAe,CAA6B,CAAC;IACzE,IACE,YAAY;QACZ,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,EACjE,CAAC;QACD,OAAO,CAAC,KAAK,CACX,gFAAgF,CACjF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAM;QACpB,GAAG,EAAE,MAAM,CAAC,GAAI;QAChB,YAAY,EAAE,MAAM,CAAC,eAAe,CAAC;QACrC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC;YAC3B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC;YAC1C,CAAC,CAAC,SAAS;QACb,YAAY,EAAE,MAAM,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtE,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,WAAW,EAAE,MAAM,CAAC,cAAc,CAAC;QACnC,YAAY,EAAG,YAA6B,IAAI,QAAQ;QACxD,SAAS;KACV,CAAC;AACJ,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCb,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;IAE5B,4CAA4C;IAC5C,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAExB,4CAA4C;IAC5C,MAAM,QAAQ,CAAC;QACb,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;KAChC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,kCAAkC;IAClC,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/runner.d.ts CHANGED
@@ -4,6 +4,8 @@ import { type BaseRunnerOptions } from "@sandagent/runner-claude";
4
4
  * Extends BaseRunnerOptions with CLI-specific fields
5
5
  */
6
6
  export interface RunAgentOptions extends BaseRunnerOptions {
7
+ /** Which runner to use: claude, codex, copilot */
8
+ runner: string;
7
9
  /** User input/task */
8
10
  userInput: string;
9
11
  /** Template to use (e.g., "default", "coder", "analyst", "researcher") */
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAGvB,MAAM,0BAA0B,CAAC;AAElC;;;GAGG;AACH,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA4CtE"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAGvB,MAAM,0BAA0B,CAAC;AAElC;;;GAGG;AACH,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAkEtE"}
package/dist/runner.js CHANGED
@@ -15,28 +15,45 @@ export async function runAgent(options) {
15
15
  // Create an AbortController to handle process signals
16
16
  const abortController = new AbortController();
17
17
  // Handle SIGTERM and SIGINT signals
18
- const signalHandler = () => {
18
+ const signalHandler = async () => {
19
19
  console.error("[Runner] Received termination signal, stopping...");
20
+ // Note: abort() synchronously triggers all abort event listeners,
20
21
  abortController.abort();
21
- console.error("[Runner] AbortController.abort() called");
22
+ console.error("[Runner] AbortController.abort() completed (listeners triggered)");
22
23
  };
23
24
  process.on("SIGTERM", signalHandler);
24
25
  process.on("SIGINT", signalHandler);
25
26
  console.error("[Runner] Signal handlers registered");
26
27
  try {
27
- // Build runner options - cwd is already set by cli.ts via process.chdir()
28
- const runnerOptions = {
29
- model: options.model,
30
- systemPrompt: options.systemPrompt,
31
- maxTurns: options.maxTurns,
32
- allowedTools: options.allowedTools,
33
- resume: options.resume,
34
- approvalDir: options.approvalDir,
35
- outputFormat: options.outputFormat,
36
- };
37
- const runner = createClaudeRunner(runnerOptions);
28
+ // Select the appropriate runner based on options.runner
29
+ let runner;
30
+ switch (options.runner) {
31
+ case "claude": {
32
+ // Build runner options - cwd is already set by cli.ts via process.chdir()
33
+ const runnerOptions = {
34
+ model: options.model,
35
+ systemPrompt: options.systemPrompt,
36
+ maxTurns: options.maxTurns,
37
+ allowedTools: options.allowedTools,
38
+ resume: options.resume,
39
+ approvalDir: options.approvalDir,
40
+ outputFormat: options.outputFormat,
41
+ abortController: abortController,
42
+ };
43
+ runner = createClaudeRunner(runnerOptions);
44
+ break;
45
+ }
46
+ case "codex":
47
+ // TODO: Implement Codex runner
48
+ throw new Error("Codex runner not yet implemented. Use --runner=claude for now.");
49
+ case "copilot":
50
+ // TODO: Implement Copilot runner
51
+ throw new Error("Copilot runner not yet implemented. Use --runner=claude for now.");
52
+ default:
53
+ throw new Error(`Unknown runner: ${options.runner}. Supported runners: claude, codex, copilot`);
54
+ }
38
55
  // Stream AI SDK UI messages to stdout
39
- for await (const chunk of runner.run(options.userInput, abortController.signal)) {
56
+ for await (const chunk of runner.run(options.userInput)) {
40
57
  // Write directly to stdout without modification
41
58
  // This ensures the stream is a valid AI SDK UI stream
42
59
  process.stdout.write(chunk);
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAalC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAwB;IACrD,sDAAsD;IACtD,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAE9C,oCAAoC;IACpC,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,eAAe,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC3D,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAEpC,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAErD,IAAI,CAAC;QACH,0EAA0E;QAC1E,MAAM,aAAa,GAAwB;YACzC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,YAAY,EAAE,OAAO,CAAC,YAAY;SACnC,CAAC;QAEF,MAAM,MAAM,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;QAEjD,sCAAsC;QACtC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,GAAG,CAClC,OAAO,CAAC,SAAS,EACjB,eAAe,CAAC,MAAM,CACvB,EAAE,CAAC;YACF,gDAAgD;YAChD,sDAAsD;YACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;YAAS,CAAC;QACT,2BAA2B;QAC3B,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACvC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAelC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAwB;IACrD,sDAAsD;IACtD,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAE9C,oCAAoC;IACpC,MAAM,aAAa,GAAG,KAAK,IAAI,EAAE;QAC/B,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,kEAAkE;QAClE,eAAe,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CACX,kEAAkE,CACnE,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAEpC,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAErD,IAAI,CAAC;QACH,wDAAwD;QACxD,IAAI,MAAyD,CAAC;QAE9D,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;YACvB,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,0EAA0E;gBAC1E,MAAM,aAAa,GAAwB;oBACzC,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,YAAY,EAAE,OAAO,CAAC,YAAY;oBAClC,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;oBAClC,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,WAAW,EAAE,OAAO,CAAC,WAAW;oBAChC,YAAY,EAAE,OAAO,CAAC,YAAY;oBAClC,eAAe,EAAE,eAAe;iBACjC,CAAC;gBACF,MAAM,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;gBAC3C,MAAM;YACR,CAAC;YACD,KAAK,OAAO;gBACV,+BAA+B;gBAC/B,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;YACJ,KAAK,SAAS;gBACZ,iCAAiC;gBACjC,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;YACJ;gBACE,MAAM,IAAI,KAAK,CACb,mBAAmB,OAAO,CAAC,MAAM,6CAA6C,CAC/E,CAAC;QACN,CAAC;QAED,sCAAsC;QACtC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YACxD,gDAAgD;YAChD,sDAAsD;YACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;YAAS,CAAC;QACT,2BAA2B;QAC3B,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACvC,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sandagent/runner-cli",
3
- "version": "0.1.2-beta.1",
3
+ "version": "0.1.2-beta.3",
4
4
  "description": "SandAgent Runner CLI - Like gemini-cli or claude-code, runs in your local terminal with AI SDK UI streaming",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,28 +18,43 @@
18
18
  "files": [
19
19
  "dist"
20
20
  ],
21
- "scripts": {
22
- "build": "tsc && pnpm bundle",
23
- "build:bundle": "tsc && pnpm bundle",
24
- "bundle": "esbuild src/cli.ts --bundle --platform=node --format=esm --outfile=dist/bundle.mjs",
25
- "dev": "tsc --watch",
26
- "clean": "rm -rf dist",
27
- "typecheck": "tsc --noEmit",
28
- "lint": "echo 'no lint configured'",
29
- "test": "vitest run --passWithNoTests"
30
- },
31
21
  "repository": {
32
22
  "type": "git",
33
23
  "url": "https://github.com/vikadata/sandagent.git",
34
24
  "directory": "apps/runner-cli"
35
25
  },
36
26
  "license": "Apache-2.0",
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "tag": "beta"
30
+ },
31
+ "engines": {
32
+ "node": ">=20.0.0"
33
+ },
34
+ "keywords": [
35
+ "cli",
36
+ "agent",
37
+ "sandagent",
38
+ "runner",
39
+ "claude",
40
+ "anthropic"
41
+ ],
37
42
  "dependencies": {},
38
43
  "devDependencies": {
39
- "@sandagent/runner-claude": "workspace:*",
40
44
  "@types/node": "^20.10.0",
41
45
  "esbuild": "^0.27.2",
42
46
  "typescript": "^5.3.0",
43
- "vitest": "^1.6.1"
47
+ "vitest": "^1.6.1",
48
+ "@sandagent/runner-claude": "0.1.0"
49
+ },
50
+ "scripts": {
51
+ "build": "tsc && pnpm bundle",
52
+ "build:bundle": "tsc && pnpm bundle",
53
+ "bundle": "esbuild src/cli.ts --bundle --platform=node --format=esm --outfile=dist/bundle.mjs",
54
+ "dev": "tsc --watch",
55
+ "clean": "rm -rf dist",
56
+ "typecheck": "tsc --noEmit",
57
+ "lint": "echo 'no lint configured'",
58
+ "test": "vitest run --passWithNoTests"
44
59
  }
45
- }
60
+ }
package/dist/bundle.js DELETED
@@ -1,377 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/cli.ts
4
- import { parseArgs } from "node:util";
5
-
6
- // src/runner.ts
7
- import * as fs from "node:fs";
8
- import * as path from "node:path";
9
-
10
- // ../../packages/runner-claude/dist/claude-runner.js
11
- var OPTIONAL_MODULES = {
12
- "claude-agent-sdk": "@anthropic-ai/claude-agent-sdk"
13
- };
14
- function createClaudeRunner(options) {
15
- return {
16
- async *run(userInput) {
17
- const apiKey = process.env.ANTHROPIC_API_KEY;
18
- if (!apiKey) {
19
- console.error("[SandAgent] Warning: ANTHROPIC_API_KEY not set. Using mock response.\nTo use the real Claude Agent SDK:\n1. Set ANTHROPIC_API_KEY environment variable\n2. Install the SDK: npm install @anthropic-ai/claude-agent-sdk");
20
- yield* runMockAgent(options, userInput);
21
- return;
22
- }
23
- const sdk = await loadClaudeAgentSDK();
24
- if (sdk) {
25
- yield* runWithClaudeAgentSDK(sdk, options, userInput);
26
- } else {
27
- console.error("[SandAgent] Warning: @anthropic-ai/claude-agent-sdk not installed. Using mock response.\nInstall the SDK: npm install @anthropic-ai/claude-agent-sdk");
28
- yield* runMockAgent(options, userInput);
29
- }
30
- }
31
- };
32
- }
33
- async function loadClaudeAgentSDK() {
34
- try {
35
- const modulePath = OPTIONAL_MODULES["claude-agent-sdk"];
36
- const module = await import(
37
- /* webpackIgnore: true */
38
- modulePath
39
- );
40
- return module;
41
- } catch {
42
- return null;
43
- }
44
- }
45
- async function* runWithClaudeAgentSDK(sdk, options, userInput) {
46
- const sdkOptions = {
47
- model: options.model,
48
- systemPrompt: options.systemPrompt,
49
- maxTurns: options.maxTurns,
50
- allowedTools: options.allowedTools,
51
- cwd: options.cwd,
52
- env: options.env
53
- };
54
- try {
55
- for await (const message of sdk.query({
56
- prompt: userInput,
57
- options: sdkOptions
58
- })) {
59
- const chunks = convertSDKMessageToAISDKUI(message);
60
- for (const chunk of chunks) {
61
- yield chunk;
62
- }
63
- }
64
- yield `d:{"finishReason":"stop"}
65
- `;
66
- } catch (error) {
67
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
68
- yield `3:${JSON.stringify(errorMessage)}
69
- `;
70
- yield `d:{"finishReason":"error"}
71
- `;
72
- }
73
- }
74
- function convertSDKMessageToAISDKUI(message) {
75
- const chunks = [];
76
- switch (message.type) {
77
- case "system":
78
- if (message.subtype === "init") {
79
- chunks.push(`0:${JSON.stringify(`[System initialized: ${message.model ?? "unknown model"}]
80
- `)}
81
- `);
82
- }
83
- break;
84
- case "assistant":
85
- const assistantMsg = message;
86
- if (assistantMsg.message) {
87
- chunks.push(`0:${JSON.stringify(assistantMsg.message)}
88
- `);
89
- }
90
- break;
91
- case "tool_use":
92
- const toolUseMsg = message;
93
- chunks.push(`9:${JSON.stringify({
94
- toolCallId: toolUseMsg.tool_use_id,
95
- toolName: toolUseMsg.tool_name,
96
- args: toolUseMsg.tool_input
97
- })}
98
- `);
99
- break;
100
- case "tool_result":
101
- const toolResultMsg = message;
102
- chunks.push(`a:${JSON.stringify({
103
- toolCallId: toolResultMsg.tool_use_id,
104
- result: toolResultMsg.output
105
- })}
106
- `);
107
- break;
108
- case "result":
109
- const resultMsg = message;
110
- if (resultMsg.is_error && resultMsg.errors) {
111
- chunks.push(`3:${JSON.stringify(resultMsg.errors.join(", "))}
112
- `);
113
- }
114
- break;
115
- default:
116
- break;
117
- }
118
- return chunks;
119
- }
120
- async function* runMockAgent(options, userInput) {
121
- const response = `I received your request: "${userInput}"
122
-
123
- Model: ${options.model}
124
-
125
- This is a mock response because:
126
- - ANTHROPIC_API_KEY is not set, OR
127
- - @anthropic-ai/claude-agent-sdk is not installed
128
-
129
- To use the real Claude Agent SDK:
130
- 1. Set ANTHROPIC_API_KEY environment variable
131
- 2. Install the SDK: npm install @anthropic-ai/claude-agent-sdk
132
-
133
- Documentation: https://platform.claude.com/docs/en/agent-sdk/typescript-v2-preview`;
134
- const words = response.split(" ");
135
- for (const word of words) {
136
- yield `0:${JSON.stringify(word + " ")}
137
- `;
138
- await new Promise((resolve2) => setTimeout(resolve2, 20));
139
- }
140
- yield `d:{"finishReason":"stop"}
141
- `;
142
- }
143
-
144
- // src/runner.ts
145
- function findTemplatesDir() {
146
- const envPath = process.env.SANDAGENT_TEMPLATES_DIR;
147
- if (envPath && fs.existsSync(envPath)) {
148
- return envPath;
149
- }
150
- const sandboxPath = "/sandagent/templates";
151
- if (fs.existsSync(sandboxPath)) {
152
- return sandboxPath;
153
- }
154
- const devPath = path.resolve(__dirname, "../../../templates");
155
- if (fs.existsSync(devPath)) {
156
- return devPath;
157
- }
158
- return null;
159
- }
160
- function loadTemplate(templateName) {
161
- const templatesDir = findTemplatesDir();
162
- if (!templatesDir) {
163
- return {};
164
- }
165
- const templateDir = path.join(templatesDir, templateName);
166
- if (!fs.existsSync(templateDir)) {
167
- if (templateName !== "default") {
168
- console.error(
169
- `Warning: Template "${templateName}" not found, using default`
170
- );
171
- return loadTemplate("default");
172
- }
173
- return {};
174
- }
175
- let systemPrompt;
176
- let settings;
177
- const claudeMdPath = path.join(templateDir, "CLAUDE.md");
178
- if (fs.existsSync(claudeMdPath)) {
179
- systemPrompt = fs.readFileSync(claudeMdPath, "utf-8");
180
- }
181
- const settingsPath = path.join(templateDir, ".claude", "settings.json");
182
- if (fs.existsSync(settingsPath)) {
183
- try {
184
- const settingsContent = fs.readFileSync(settingsPath, "utf-8");
185
- settings = JSON.parse(settingsContent);
186
- } catch (error) {
187
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
188
- console.error(
189
- `Warning: Failed to parse ${settingsPath}: ${errorMessage}`
190
- );
191
- }
192
- }
193
- const skillsDir = path.join(templateDir, "skills");
194
- if (fs.existsSync(skillsDir)) {
195
- try {
196
- const skillFiles = fs.readdirSync(skillsDir).filter((f) => f.endsWith(".md"));
197
- if (skillFiles.length > 0) {
198
- const skillsContent = skillFiles.map((file) => {
199
- const content = fs.readFileSync(
200
- path.join(skillsDir, file),
201
- "utf-8"
202
- );
203
- return `
204
- ---
205
-
206
- ${content}`;
207
- }).join("\n");
208
- if (systemPrompt) {
209
- systemPrompt += `
210
-
211
- ## Skills
212
- ${skillsContent}`;
213
- }
214
- }
215
- } catch (error) {
216
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
217
- console.error(
218
- `Warning: Failed to load skills from ${skillsDir}: ${errorMessage}`
219
- );
220
- }
221
- }
222
- return { systemPrompt, settings };
223
- }
224
- async function runAgent(options) {
225
- const template = loadTemplate(options.template ?? "default");
226
- const runnerOptions = {
227
- model: options.model,
228
- // Explicit system prompt overrides template
229
- systemPrompt: options.systemPrompt ?? template.systemPrompt,
230
- // Explicit maxTurns overrides template
231
- maxTurns: options.maxTurns ?? template.settings?.max_turns,
232
- // Explicit allowedTools overrides template
233
- allowedTools: options.allowedTools ?? template.settings?.allowed_tools
234
- };
235
- const runner = createClaudeRunner(runnerOptions);
236
- for await (const chunk of runner.run(options.userInput)) {
237
- process.stdout.write(chunk);
238
- }
239
- }
240
-
241
- // src/cli.ts
242
- function parseCliArgs() {
243
- const { values, positionals } = parseArgs({
244
- options: {
245
- model: {
246
- type: "string",
247
- short: "m",
248
- default: "claude-sonnet-4-20250514"
249
- },
250
- cwd: {
251
- type: "string",
252
- short: "c",
253
- default: process.env.SANDAGENT_WORKSPACE ?? process.cwd()
254
- },
255
- template: {
256
- type: "string",
257
- short: "T",
258
- default: process.env.SANDAGENT_TEMPLATE ?? "default"
259
- },
260
- "system-prompt": {
261
- type: "string",
262
- short: "s"
263
- },
264
- "max-turns": {
265
- type: "string",
266
- short: "t"
267
- },
268
- "allowed-tools": {
269
- type: "string",
270
- short: "a"
271
- },
272
- help: {
273
- type: "boolean",
274
- short: "h"
275
- }
276
- },
277
- allowPositionals: true,
278
- strict: true
279
- });
280
- if (values.help) {
281
- printHelp();
282
- process.exit(0);
283
- }
284
- if (positionals[0] !== "run") {
285
- console.error('Error: Expected "run" command');
286
- console.error('Usage: sandagent run [options] -- "<user input>"');
287
- process.exit(1);
288
- }
289
- const dashIndex = process.argv.indexOf("--");
290
- let userInput = "";
291
- if (dashIndex !== -1 && dashIndex < process.argv.length - 1) {
292
- userInput = process.argv.slice(dashIndex + 1).join(" ");
293
- } else if (positionals.length > 1) {
294
- userInput = positionals.slice(1).join(" ");
295
- }
296
- if (!userInput) {
297
- console.error("Error: User input is required");
298
- console.error('Usage: sandagent run [options] -- "<user input>"');
299
- process.exit(1);
300
- }
301
- return {
302
- model: values.model,
303
- cwd: values.cwd,
304
- template: values.template,
305
- systemPrompt: values["system-prompt"],
306
- maxTurns: values["max-turns"] ? Number.parseInt(values["max-turns"], 10) : void 0,
307
- allowedTools: values["allowed-tools"]?.split(",").map((t) => t.trim()),
308
- userInput
309
- };
310
- }
311
- function printHelp() {
312
- console.log(`
313
- \u{1F916} SandAgent Runner CLI
314
-
315
- Like gemini-cli or claude-code - runs locally in your terminal.
316
- Streams AI SDK UI messages directly to stdout.
317
-
318
- Usage:
319
- sandagent run [options] -- "<user input>"
320
-
321
- # Or run from a template directory:
322
- cd templates/coder
323
- sandagent run -- "Build a REST API"
324
-
325
- Options:
326
- -m, --model <model> Model to use (default: claude-sonnet-4-20250514)
327
- -c, --cwd <path> Working directory (default: current directory)
328
- -T, --template <name> Template to use (default: default)
329
- Available: default, coder, analyst, researcher
330
- -s, --system-prompt <prompt> Custom system prompt (overrides template)
331
- -t, --max-turns <n> Maximum conversation turns
332
- -a, --allowed-tools <tools> Comma-separated list of allowed tools
333
- -h, --help Show this help message
334
-
335
- Environment Variables:
336
- ANTHROPIC_API_KEY Anthropic API key (required)
337
- SANDAGENT_WORKSPACE Default workspace path
338
- SANDAGENT_TEMPLATE Default template to use
339
- SANDAGENT_LOG_LEVEL Logging level (debug, info, warn, error)
340
-
341
- Templates:
342
- default General-purpose assistant
343
- coder Optimized for software development
344
- analyst Optimized for data analysis
345
- researcher Optimized for research tasks
346
-
347
- Examples:
348
- # Run with default template
349
- sandagent run -- "Create a hello world script"
350
-
351
- # Run from a template directory (recommended)
352
- cd templates/coder
353
- sandagent run -- "Build a REST API with Express"
354
-
355
- # Use a specific template
356
- sandagent run --template analyst -- "Analyze sales.csv"
357
-
358
- # Specify working directory
359
- sandagent run --cwd ./my-project -- "Fix the bug in main.ts"
360
- `);
361
- }
362
- async function main() {
363
- const args = parseCliArgs();
364
- process.chdir(args.cwd);
365
- await runAgent({
366
- model: args.model,
367
- template: args.template,
368
- userInput: args.userInput,
369
- systemPrompt: args.systemPrompt,
370
- maxTurns: args.maxTurns,
371
- allowedTools: args.allowedTools
372
- });
373
- }
374
- main().catch((error) => {
375
- console.error("Fatal error:", error.message);
376
- process.exit(1);
377
- });