@sandagent/runner-cli 0.2.9 → 0.2.10

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/README.md CHANGED
@@ -156,6 +156,32 @@ The CLI is designed to:
156
156
  3. Stream AI SDK UI messages directly to stdout
157
157
  4. Support both SSE stream and JSON output formats
158
158
 
159
+ ## 🐳 Docker Image Build
160
+
161
+ Build Docker images with agent templates baked in:
162
+
163
+ ```bash
164
+ # Build image
165
+ sandagent image build --name vikadata/sandagent-seo --tag 0.1.0 --template ./templates/seo-agent
166
+
167
+ # Build and push
168
+ sandagent image build --name vikadata/sandagent-seo --tag 0.1.0 --template ./templates/seo-agent --push
169
+
170
+ # Without template
171
+ sandagent image build --name vikadata/sandagent --tag 0.1.0
172
+ ```
173
+
174
+ ### Image Build Options
175
+
176
+ | Option | Description | Default |
177
+ |--------|-------------|---------|
178
+ | `--name <name>` | Full image name (e.g. `vikadata/sandagent-seo`) | `sandagent` |
179
+ | `--tag <tag>` | Image tag | `latest` |
180
+ | `--image <full>` | Full image name override (e.g. `myorg/myimage:v1`) | - |
181
+ | `--platform <plat>` | Build platform | `linux/amd64` |
182
+ | `--template <path>` | Path to agent template directory | - |
183
+ | `--push` | Push image to registry after build | `false` |
184
+
159
185
  ## Related Documentation
160
186
 
161
187
  - [Claude Agent SDK](https://platform.claude.com/docs/agent-sdk/typescript)
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=build-image.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-image.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/build-image.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,145 @@
1
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
+ // Mock child_process so we never actually run docker
5
+ vi.mock("node:child_process", () => ({
6
+ execSync: vi.fn((cmd) => {
7
+ // docker info check — pretend docker is running
8
+ if (cmd === "docker info")
9
+ return Buffer.from("");
10
+ // Record the command for assertions
11
+ return Buffer.from("");
12
+ }),
13
+ }));
14
+ import { execSync } from "node:child_process";
15
+ import { buildImage } from "../build-image.js";
16
+ const mockedExecSync = vi.mocked(execSync);
17
+ const TEST_DIR = join(process.cwd(), ".test-build-image");
18
+ const BUILD_CONTEXT = join(TEST_DIR, ".docker-staging");
19
+ beforeEach(() => {
20
+ mkdirSync(TEST_DIR, { recursive: true });
21
+ mockedExecSync.mockClear();
22
+ });
23
+ afterEach(() => {
24
+ rmSync(TEST_DIR, { recursive: true, force: true });
25
+ rmSync(BUILD_CONTEXT, { recursive: true, force: true });
26
+ // Also clean up the default build context location
27
+ rmSync(join(process.cwd(), ".docker-staging"), {
28
+ recursive: true,
29
+ force: true,
30
+ });
31
+ });
32
+ describe("buildImage", () => {
33
+ it("builds a plain image without template", async () => {
34
+ await buildImage({
35
+ name: "myorg/sandagent",
36
+ tag: "0.1.0",
37
+ platform: "linux/amd64",
38
+ push: false,
39
+ });
40
+ // Should have called docker info + docker build
41
+ const calls = mockedExecSync.mock.calls.map((c) => c[0]);
42
+ expect(calls.some((c) => c === "docker info")).toBe(true);
43
+ expect(calls.some((c) => c.includes("docker build"))).toBe(true);
44
+ // docker build should reference the correct image name
45
+ const buildCmd = calls.find((c) => c.includes("docker build"));
46
+ expect(buildCmd).toContain("-t myorg/sandagent:0.1.0");
47
+ expect(buildCmd).toContain("--platform=linux/amd64");
48
+ // Should NOT have called docker push
49
+ expect(calls.some((c) => c.includes("docker push"))).toBe(false);
50
+ });
51
+ it("generates Dockerfile in build context", async () => {
52
+ await buildImage({
53
+ name: "myorg/sandagent",
54
+ tag: "1.0.0",
55
+ platform: "linux/amd64",
56
+ push: false,
57
+ });
58
+ const contextDir = join(process.cwd(), ".docker-staging");
59
+ const dockerfilePath = join(contextDir, "Dockerfile");
60
+ expect(existsSync(dockerfilePath)).toBe(true);
61
+ const content = readFileSync(dockerfilePath, "utf8");
62
+ expect(content).toContain("FROM node:20-slim");
63
+ expect(content).toContain("@sandagent/runner-cli");
64
+ expect(content).toContain('CMD ["sleep", "infinity"]');
65
+ });
66
+ it("uses --image override when provided", async () => {
67
+ await buildImage({
68
+ name: "sandagent",
69
+ tag: "latest",
70
+ image: "custom/image:v2",
71
+ platform: "linux/amd64",
72
+ push: false,
73
+ });
74
+ const calls = mockedExecSync.mock.calls.map((c) => c[0]);
75
+ const buildCmd = calls.find((c) => c.includes("docker build"));
76
+ expect(buildCmd).toContain("-t custom/image:v2");
77
+ });
78
+ it("builds with template and injects COPY instructions", async () => {
79
+ // Create a fake template directory
80
+ const templateDir = join(TEST_DIR, "my-agent");
81
+ mkdirSync(templateDir, { recursive: true });
82
+ writeFileSync(join(templateDir, "CLAUDE.md"), "# My Agent");
83
+ const claudeDir = join(templateDir, ".claude");
84
+ mkdirSync(claudeDir, { recursive: true });
85
+ writeFileSync(join(claudeDir, "settings.json"), '{"max_tokens": 4096}');
86
+ await buildImage({
87
+ name: "myorg/sandagent",
88
+ tag: "0.1.0",
89
+ platform: "linux/amd64",
90
+ template: templateDir,
91
+ push: false,
92
+ });
93
+ // Image name should include template name
94
+ const calls = mockedExecSync.mock.calls.map((c) => c[0]);
95
+ const buildCmd = calls.find((c) => c.includes("docker build"));
96
+ expect(buildCmd).toContain("-t myorg/sandagent:0.1.0");
97
+ // Generated Dockerfile should have template COPY lines
98
+ const contextDir = join(process.cwd(), ".docker-staging");
99
+ const dockerfile = readFileSync(join(contextDir, "Dockerfile"), "utf8");
100
+ expect(dockerfile).toContain("COPY templates/my-agent/CLAUDE.md");
101
+ expect(dockerfile).toContain("COPY templates/my-agent/.claude");
102
+ expect(dockerfile).toContain("mkdir -p /opt/sandagent/templates");
103
+ // Template files should be copied into build context
104
+ expect(existsSync(join(contextDir, "templates", "my-agent", "CLAUDE.md"))).toBe(true);
105
+ expect(existsSync(join(contextDir, "templates", "my-agent", ".claude", "settings.json"))).toBe(true);
106
+ });
107
+ it("pushes when --push is set", async () => {
108
+ await buildImage({
109
+ name: "myorg/sandagent",
110
+ tag: "0.1.0",
111
+ platform: "linux/amd64",
112
+ push: true,
113
+ });
114
+ const calls = mockedExecSync.mock.calls.map((c) => c[0]);
115
+ expect(calls.some((c) => c.includes("docker push"))).toBe(true);
116
+ expect(calls.some((c) => c.includes("docker push myorg/sandagent:0.1.0"))).toBe(true);
117
+ });
118
+ it("fails push when name has no namespace", async () => {
119
+ const mockExit = vi.spyOn(process, "exit").mockImplementation(() => {
120
+ throw new Error("process.exit");
121
+ });
122
+ const mockError = vi.spyOn(console, "error").mockImplementation(() => { });
123
+ await expect(buildImage({
124
+ name: "sandagent",
125
+ tag: "0.1.0",
126
+ platform: "linux/amd64",
127
+ push: true,
128
+ })).rejects.toThrow("process.exit");
129
+ expect(mockError).toHaveBeenCalledWith(expect.stringContaining("--push requires --name to include namespace"));
130
+ mockExit.mockRestore();
131
+ mockError.mockRestore();
132
+ });
133
+ it("does not push when --push is false", async () => {
134
+ await buildImage({
135
+ name: "myorg/sandagent",
136
+ tag: "0.1.0",
137
+ platform: "linux/amd64",
138
+ push: false,
139
+ });
140
+ const calls = mockedExecSync.mock.calls.map((c) => c[0]);
141
+ expect(calls.some((c) => c.includes("docker push"))).toBe(false);
142
+ expect(calls.some((c) => c.includes("docker tag"))).toBe(false);
143
+ });
144
+ });
145
+ //# sourceMappingURL=build-image.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-image.test.js","sourceRoot":"","sources":["../../src/__tests__/build-image.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface BuildImageOptions {
2
+ /** Image name, e.g. "vikadata/sandagent-seo" */
3
+ name: string;
4
+ /** Image tag, e.g. "0.1.0" */
5
+ tag: string;
6
+ /** Full image override, e.g. "myorg/myimage:v1" */
7
+ image?: string;
8
+ /** Docker platform (default: linux/amd64) */
9
+ platform: string;
10
+ /** Path to agent template directory to bake into the image */
11
+ template?: string;
12
+ /** Push image to registry after build */
13
+ push: boolean;
14
+ }
15
+ export declare function buildImage(opts: BuildImageOptions): Promise<void>;
16
+ //# sourceMappingURL=build-image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-image.d.ts","sourceRoot":"","sources":["../src/build-image.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,IAAI,EAAE,OAAO,CAAC;CACf;AA2ED,wBAAsB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiEvE"}
@@ -0,0 +1,114 @@
1
+ import { execSync } from "node:child_process";
2
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync, } from "node:fs";
3
+ import { basename, dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ // ---------------------------------------------------------------------------
6
+ // Helpers
7
+ // ---------------------------------------------------------------------------
8
+ function getPackageRoot() {
9
+ const thisDir = dirname(fileURLToPath(import.meta.url));
10
+ return resolve(thisDir, "..");
11
+ }
12
+ function getShippedDockerfile() {
13
+ // Look for Dockerfile in several locations:
14
+ // 1. Package root (apps/runner-cli/Dockerfile) — shipped with npm package
15
+ // 2. docker/sandagent-claude/Dockerfile — monorepo development
16
+ const packageRoot = getPackageRoot();
17
+ const candidates = [
18
+ join(packageRoot, "Dockerfile"),
19
+ resolve(packageRoot, "..", "..", "docker", "sandagent-claude", "Dockerfile"),
20
+ ];
21
+ for (const p of candidates) {
22
+ if (existsSync(p))
23
+ return p;
24
+ }
25
+ console.error(`❌ Dockerfile not found. Searched:\n${candidates.map((c) => ` ${c}`).join("\n")}`);
26
+ process.exit(1);
27
+ }
28
+ function run(cmd, cwd) {
29
+ execSync(cmd, { stdio: "inherit", cwd });
30
+ }
31
+ function ensureDocker() {
32
+ try {
33
+ execSync("docker info", { stdio: "ignore" });
34
+ }
35
+ catch {
36
+ console.error("❌ Docker is not running. Please start Docker first.");
37
+ process.exit(1);
38
+ }
39
+ }
40
+ function resolveTemplatePath(template) {
41
+ const abs = resolve(process.cwd(), template);
42
+ if (!existsSync(abs)) {
43
+ console.error(`❌ Template directory not found: ${abs}`);
44
+ process.exit(1);
45
+ }
46
+ return abs;
47
+ }
48
+ function copyDirSync(src, dest) {
49
+ mkdirSync(dest, { recursive: true });
50
+ for (const entry of readdirSync(src)) {
51
+ const srcPath = join(src, entry);
52
+ const destPath = join(dest, entry);
53
+ if (statSync(srcPath).isDirectory()) {
54
+ copyDirSync(srcPath, destPath);
55
+ }
56
+ else {
57
+ copyFileSync(srcPath, destPath);
58
+ }
59
+ }
60
+ }
61
+ // ---------------------------------------------------------------------------
62
+ // Build (and optionally push)
63
+ // ---------------------------------------------------------------------------
64
+ export async function buildImage(opts) {
65
+ const templatePath = opts.template
66
+ ? resolveTemplatePath(opts.template)
67
+ : null;
68
+ const templateName = templatePath ? basename(templatePath) : null;
69
+ const localImage = opts.image ?? `${opts.name}:${opts.tag}`;
70
+ console.log("📦 SandAgent Docker Image Builder");
71
+ console.log("========================");
72
+ console.log(` Image: ${localImage}`);
73
+ console.log(` Platform: ${opts.platform}`);
74
+ console.log(` Template: ${templateName ?? "(none)"}`);
75
+ console.log(` Push: ${opts.push}`);
76
+ console.log("");
77
+ ensureDocker();
78
+ const buildContext = join(process.cwd(), ".docker-staging");
79
+ mkdirSync(buildContext, { recursive: true });
80
+ let dockerfile = readFileSync(getShippedDockerfile(), "utf8");
81
+ if (templatePath && templateName) {
82
+ const destDir = join(buildContext, "templates", templateName);
83
+ mkdirSync(destDir, { recursive: true });
84
+ const claudeMd = join(templatePath, "CLAUDE.md");
85
+ if (existsSync(claudeMd))
86
+ copyFileSync(claudeMd, join(destDir, "CLAUDE.md"));
87
+ const claudeDir = join(templatePath, ".claude");
88
+ if (existsSync(claudeDir))
89
+ copyDirSync(claudeDir, join(destDir, ".claude"));
90
+ let copyLines = "\n# Template files\nRUN mkdir -p /opt/sandagent/templates";
91
+ if (existsSync(join(destDir, "CLAUDE.md"))) {
92
+ copyLines += `\nCOPY templates/${templateName}/CLAUDE.md /opt/sandagent/templates/CLAUDE.md`;
93
+ }
94
+ if (existsSync(join(destDir, ".claude"))) {
95
+ copyLines += `\nCOPY templates/${templateName}/.claude /opt/sandagent/templates/.claude`;
96
+ }
97
+ dockerfile = dockerfile.replace(/^CMD /m, `${copyLines}\n\nCMD `);
98
+ console.log("🧩 Injected template files into Dockerfile");
99
+ }
100
+ writeFileSync(join(buildContext, "Dockerfile"), dockerfile);
101
+ console.log("🐳 Building Docker image...");
102
+ run(`docker build --platform=${opts.platform} -t ${localImage} -f ${join(buildContext, "Dockerfile")} ${buildContext}`);
103
+ console.log(`\n✅ Image built: ${localImage}`);
104
+ if (!opts.push)
105
+ return;
106
+ if (!localImage.includes("/")) {
107
+ console.error("❌ --push requires --name to include namespace (e.g. vikadata/sandagent-seo)");
108
+ process.exit(1);
109
+ }
110
+ console.log("🚀 Pushing image...");
111
+ run(`docker push ${localImage}`);
112
+ console.log(`\n✅ Image pushed: ${localImage}`);
113
+ }
114
+ //# sourceMappingURL=build-image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-image.js","sourceRoot":"","sources":["../src/build-image.ts"],"names":[],"mappings":"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"}
package/dist/bundle.mjs CHANGED
@@ -3,9 +3,136 @@
3
3
  // src/cli.ts
4
4
  import { parseArgs } from "node:util";
5
5
 
6
+ // src/build-image.ts
7
+ import { execSync } from "node:child_process";
8
+ import {
9
+ copyFileSync,
10
+ existsSync,
11
+ mkdirSync,
12
+ readFileSync,
13
+ readdirSync,
14
+ statSync,
15
+ writeFileSync
16
+ } from "node:fs";
17
+ import { basename, dirname, join, resolve } from "node:path";
18
+ import { fileURLToPath } from "node:url";
19
+ function getPackageRoot() {
20
+ const thisDir = dirname(fileURLToPath(import.meta.url));
21
+ return resolve(thisDir, "..");
22
+ }
23
+ function getShippedDockerfile() {
24
+ const packageRoot = getPackageRoot();
25
+ const candidates = [
26
+ join(packageRoot, "Dockerfile"),
27
+ resolve(
28
+ packageRoot,
29
+ "..",
30
+ "..",
31
+ "docker",
32
+ "sandagent-claude",
33
+ "Dockerfile"
34
+ )
35
+ ];
36
+ for (const p of candidates) {
37
+ if (existsSync(p)) return p;
38
+ }
39
+ console.error(
40
+ `\u274C Dockerfile not found. Searched:
41
+ ${candidates.map((c) => ` ${c}`).join("\n")}`
42
+ );
43
+ process.exit(1);
44
+ }
45
+ function run(cmd, cwd) {
46
+ execSync(cmd, { stdio: "inherit", cwd });
47
+ }
48
+ function ensureDocker() {
49
+ try {
50
+ execSync("docker info", { stdio: "ignore" });
51
+ } catch {
52
+ console.error("\u274C Docker is not running. Please start Docker first.");
53
+ process.exit(1);
54
+ }
55
+ }
56
+ function resolveTemplatePath(template) {
57
+ const abs = resolve(process.cwd(), template);
58
+ if (!existsSync(abs)) {
59
+ console.error(`\u274C Template directory not found: ${abs}`);
60
+ process.exit(1);
61
+ }
62
+ return abs;
63
+ }
64
+ function copyDirSync(src, dest) {
65
+ mkdirSync(dest, { recursive: true });
66
+ for (const entry of readdirSync(src)) {
67
+ const srcPath = join(src, entry);
68
+ const destPath = join(dest, entry);
69
+ if (statSync(srcPath).isDirectory()) {
70
+ copyDirSync(srcPath, destPath);
71
+ } else {
72
+ copyFileSync(srcPath, destPath);
73
+ }
74
+ }
75
+ }
76
+ async function buildImage(opts) {
77
+ const templatePath = opts.template ? resolveTemplatePath(opts.template) : null;
78
+ const templateName = templatePath ? basename(templatePath) : null;
79
+ const localImage = opts.image ?? `${opts.name}:${opts.tag}`;
80
+ console.log("\u{1F4E6} SandAgent Docker Image Builder");
81
+ console.log("========================");
82
+ console.log(` Image: ${localImage}`);
83
+ console.log(` Platform: ${opts.platform}`);
84
+ console.log(` Template: ${templateName ?? "(none)"}`);
85
+ console.log(` Push: ${opts.push}`);
86
+ console.log("");
87
+ ensureDocker();
88
+ const buildContext = join(process.cwd(), ".docker-staging");
89
+ mkdirSync(buildContext, { recursive: true });
90
+ let dockerfile = readFileSync(getShippedDockerfile(), "utf8");
91
+ if (templatePath && templateName) {
92
+ const destDir = join(buildContext, "templates", templateName);
93
+ mkdirSync(destDir, { recursive: true });
94
+ const claudeMd = join(templatePath, "CLAUDE.md");
95
+ if (existsSync(claudeMd))
96
+ copyFileSync(claudeMd, join(destDir, "CLAUDE.md"));
97
+ const claudeDir = join(templatePath, ".claude");
98
+ if (existsSync(claudeDir)) copyDirSync(claudeDir, join(destDir, ".claude"));
99
+ let copyLines = "\n# Template files\nRUN mkdir -p /opt/sandagent/templates";
100
+ if (existsSync(join(destDir, "CLAUDE.md"))) {
101
+ copyLines += `
102
+ COPY templates/${templateName}/CLAUDE.md /opt/sandagent/templates/CLAUDE.md`;
103
+ }
104
+ if (existsSync(join(destDir, ".claude"))) {
105
+ copyLines += `
106
+ COPY templates/${templateName}/.claude /opt/sandagent/templates/.claude`;
107
+ }
108
+ dockerfile = dockerfile.replace(/^CMD /m, `${copyLines}
109
+
110
+ CMD `);
111
+ console.log("\u{1F9E9} Injected template files into Dockerfile");
112
+ }
113
+ writeFileSync(join(buildContext, "Dockerfile"), dockerfile);
114
+ console.log("\u{1F433} Building Docker image...");
115
+ run(
116
+ `docker build --platform=${opts.platform} -t ${localImage} -f ${join(buildContext, "Dockerfile")} ${buildContext}`
117
+ );
118
+ console.log(`
119
+ \u2705 Image built: ${localImage}`);
120
+ if (!opts.push) return;
121
+ if (!localImage.includes("/")) {
122
+ console.error(
123
+ "\u274C --push requires --name to include namespace (e.g. vikadata/sandagent-seo)"
124
+ );
125
+ process.exit(1);
126
+ }
127
+ console.log("\u{1F680} Pushing image...");
128
+ run(`docker push ${localImage}`);
129
+ console.log(`
130
+ \u2705 Image pushed: ${localImage}`);
131
+ }
132
+
6
133
  // ../../packages/runner-claude/dist/ai-sdk-stream.js
7
134
  import { writeFile } from "node:fs/promises";
8
- import { join } from "node:path";
135
+ import { join as join2 } from "node:path";
9
136
  var UNKNOWN_TOOL_NAME = "unknown-tool";
10
137
  function formatDataStream(data) {
11
138
  return `data: ${JSON.stringify(data)}
@@ -233,7 +360,7 @@ var AISDKStreamConverter = class {
233
360
  } finally {
234
361
  if (debugMessages.length > 0 && process.env.DEBUG === "true") {
235
362
  const debugDir = options?.cwd ?? process.cwd();
236
- const debugFile = join(debugDir, `claude-message-stream-debug.json`);
363
+ const debugFile = join2(debugDir, `claude-message-stream-debug.json`);
237
364
  writeFile(debugFile, JSON.stringify(debugMessages, null, 2), "utf-8").catch((writeError) => {
238
365
  console.error(`[AISDKStream] Failed to write debug file:`, writeError);
239
366
  });
@@ -286,7 +413,7 @@ function createCanUseToolCallback(claudeOptions) {
286
413
  }
287
414
  } catch {
288
415
  }
289
- await new Promise((resolve) => setTimeout(resolve, 500));
416
+ await new Promise((resolve2) => setTimeout(resolve2, 500));
290
417
  }
291
418
  try {
292
419
  fs.unlinkSync(approvalFile);
@@ -506,7 +633,7 @@ Documentation: https://platform.claude.com/docs/en/agent-sdk/typescript-v2-previ
506
633
  id: textId,
507
634
  delta: word + " "
508
635
  });
509
- await new Promise((resolve) => setTimeout(resolve, 20));
636
+ await new Promise((resolve2) => setTimeout(resolve2, 20));
510
637
  }
511
638
  yield formatDataStream({ type: "text-end", id: textId });
512
639
  yield formatDataStream({
@@ -594,14 +721,41 @@ async function runAgent(options) {
594
721
  }
595
722
 
596
723
  // src/cli.ts
597
- function parseCliArgs() {
724
+ function getSubcommand() {
725
+ for (let i = 2; i < process.argv.length; i++) {
726
+ const a = process.argv[i];
727
+ if (a === "--") break;
728
+ if (!a.startsWith("-")) return a;
729
+ }
730
+ return void 0;
731
+ }
732
+ function getSubSubcommand() {
733
+ let found = 0;
734
+ for (let i = 2; i < process.argv.length; i++) {
735
+ const a = process.argv[i];
736
+ if (a === "--") break;
737
+ if (!a.startsWith("-")) {
738
+ found++;
739
+ if (found === 2) return a;
740
+ }
741
+ }
742
+ return void 0;
743
+ }
744
+ function argsAfterPositionals(n) {
745
+ let found = 0;
746
+ for (let i = 2; i < process.argv.length; i++) {
747
+ if (!process.argv[i].startsWith("-") && process.argv[i] !== "--") {
748
+ found++;
749
+ if (found === n) return process.argv.slice(i + 1);
750
+ }
751
+ }
752
+ return [];
753
+ }
754
+ function parseRunArgs() {
598
755
  const { values, positionals } = parseArgs({
756
+ args: argsAfterPositionals(1),
599
757
  options: {
600
- runner: {
601
- type: "string",
602
- short: "r",
603
- default: "claude"
604
- },
758
+ runner: { type: "string", short: "r", default: "claude" },
605
759
  model: {
606
760
  type: "string",
607
761
  short: "m",
@@ -612,49 +766,26 @@ function parseCliArgs() {
612
766
  short: "c",
613
767
  default: process.env.SANDAGENT_WORKSPACE ?? process.cwd()
614
768
  },
615
- "system-prompt": {
616
- type: "string",
617
- short: "s"
618
- },
619
- "max-turns": {
620
- type: "string",
621
- short: "t"
622
- },
623
- "allowed-tools": {
624
- type: "string",
625
- short: "a"
626
- },
627
- resume: {
628
- type: "string",
629
- short: "r"
630
- },
631
- "output-format": {
632
- type: "string",
633
- short: "o"
634
- },
635
- help: {
636
- type: "boolean",
637
- short: "h"
638
- }
769
+ "system-prompt": { type: "string", short: "s" },
770
+ "max-turns": { type: "string", short: "t" },
771
+ "allowed-tools": { type: "string", short: "a" },
772
+ resume: { type: "string" },
773
+ "output-format": { type: "string", short: "o" },
774
+ help: { type: "boolean", short: "h" }
639
775
  },
640
776
  allowPositionals: true,
641
777
  strict: true
642
778
  });
643
779
  if (values.help) {
644
- printHelp();
780
+ printRunHelp();
645
781
  process.exit(0);
646
782
  }
647
- if (positionals[0] !== "run") {
648
- console.error('Error: Expected "run" command');
649
- console.error('Usage: sandagent run [options] -- "<user input>"');
650
- process.exit(1);
651
- }
652
783
  const dashIndex = process.argv.indexOf("--");
653
784
  let userInput = "";
654
785
  if (dashIndex !== -1 && dashIndex < process.argv.length - 1) {
655
786
  userInput = process.argv.slice(dashIndex + 1).join(" ");
656
- } else if (positionals.length > 1) {
657
- userInput = positionals.slice(1).join(" ");
787
+ } else if (positionals.length > 0) {
788
+ userInput = positionals.join(" ");
658
789
  }
659
790
  if (!userInput) {
660
791
  console.error("Error: User input is required");
@@ -687,57 +818,156 @@ function parseCliArgs() {
687
818
  userInput
688
819
  };
689
820
  }
690
- function printHelp() {
821
+ function parseImageBuildArgs() {
822
+ const { values } = parseArgs({
823
+ args: argsAfterPositionals(2),
824
+ options: {
825
+ name: { type: "string", default: "sandagent" },
826
+ tag: { type: "string", default: "latest" },
827
+ image: { type: "string" },
828
+ platform: { type: "string", default: "linux/amd64" },
829
+ template: { type: "string" },
830
+ push: { type: "boolean", default: false },
831
+ help: { type: "boolean", short: "h" }
832
+ },
833
+ allowPositionals: false,
834
+ strict: true
835
+ });
836
+ if (values.help) {
837
+ printImageBuildHelp();
838
+ process.exit(0);
839
+ }
840
+ return {
841
+ name: values.name,
842
+ tag: values.tag,
843
+ image: values.image,
844
+ platform: values.platform,
845
+ template: values.template,
846
+ push: values.push ?? false
847
+ };
848
+ }
849
+ function printRunHelp() {
691
850
  console.log(`
692
- \u{1F916} SandAgent Runner CLI
851
+ \u{1F916} SandAgent Runner CLI \u2014 run
693
852
 
694
- Like gemini-cli or claude-code - runs locally in your terminal.
695
- Streams AI SDK UI messages directly to stdout.
853
+ Runs an agent locally in your terminal, streaming AI SDK UI messages to stdout.
696
854
 
697
855
  Usage:
698
856
  sandagent run [options] -- "<user input>"
699
857
 
700
858
  Options:
701
- -r, --runner <runner> Runner to use: claude, codex, copilot (default: claude)
702
- -m, --model <model> Model to use (default: claude-sonnet-4-20250514)
703
- -c, --cwd <path> Working directory (default: current directory)
859
+ -r, --runner <runner> Runner: claude, codex, copilot (default: claude)
860
+ -m, --model <model> Model (default: claude-sonnet-4-20250514)
861
+ -c, --cwd <path> Working directory (default: cwd)
704
862
  -s, --system-prompt <prompt> Custom system prompt
705
- -t, --max-turns <n> Maximum conversation turns
706
- -a, --allowed-tools <tools> Comma-separated list of allowed tools
707
- -r, --resume <session-id> Resume a previous session
708
- -o, --output-format <format> Output format (default: stream)
709
- Available: text, json(single result), stream-json(realtime streaming), stream(ai sdk ui sse format)
710
- -h, --help Show this help message
863
+ -t, --max-turns <n> Max conversation turns
864
+ -a, --allowed-tools <tools> Comma-separated allowed tools
865
+ --resume <session-id> Resume a previous session
866
+ -o, --output-format <fmt> text | json | stream-json | stream (default: stream)
867
+ -h, --help Show this help
868
+
869
+ Environment:
870
+ ANTHROPIC_API_KEY Anthropic API key (required)
871
+ SANDAGENT_WORKSPACE Default workspace path
872
+ `);
873
+ }
874
+ function printImageBuildHelp() {
875
+ console.log(`
876
+ \u{1F433} SandAgent Runner CLI \u2014 image build
877
+
878
+ Build (and optionally push) a SandAgent Docker image.
879
+ The image includes Claude Agent SDK + runner-cli pre-installed.
711
880
 
712
- Environment Variables:
713
- ANTHROPIC_API_KEY Anthropic API key (required)
714
- SANDAGENT_WORKSPACE Default workspace path
715
- SANDAGENT_LOG_LEVEL Logging level (debug, info, warn, error)
881
+ Usage:
882
+ sandagent image build [options]
883
+
884
+ Options:
885
+ --name <name> Image name, e.g. vikadata/sandagent-seo (default: sandagent)
886
+ --tag <tag> Image tag (default: latest)
887
+ --image <full> Full image name override (e.g. myorg/myimage:v1)
888
+ --platform <plat> Build platform (default: linux/amd64)
889
+ --template <path> Path to agent template directory to bake into the image
890
+ --push Push image to registry after build
891
+ -h, --help Show this help
716
892
 
717
893
  Examples:
718
- # Run with default settings
719
- sandagent run -- "Create a hello world script"
894
+ sandagent image build --name vikadata/sandagent-seo --tag 0.1.0
895
+ sandagent image build --name vikadata/sandagent-seo --tag 0.1.0 --template ./templates/seo-agent
896
+ sandagent image build --name vikadata/sandagent-seo --tag 0.1.0 --template ./templates/seo-agent --push
897
+ `);
898
+ }
899
+ function printImageHelp() {
900
+ console.log(`
901
+ \u{1F433} SandAgent Runner CLI \u2014 image
720
902
 
721
- # Run with custom system prompt
722
- sandagent run --system-prompt "You are a coding assistant" -- "Build a REST API with Express"
903
+ Manage SandAgent Docker images.
723
904
 
724
- # Specify working directory
725
- sandagent run --cwd ./my-project -- "Fix the bug in main.ts"
905
+ Usage:
906
+ sandagent image <subcommand> [options]
907
+
908
+ Subcommands:
909
+ build Build (and optionally push) a Docker image
910
+
911
+ Run "sandagent image build --help" for build options.
912
+ `);
913
+ }
914
+ function printGlobalHelp() {
915
+ console.log(`
916
+ \u{1F916} SandAgent Runner CLI
917
+
918
+ Usage:
919
+ sandagent <command> [options]
920
+
921
+ Commands:
922
+ run Run an agent locally (streams AI SDK UI messages to stdout)
923
+ image build Build a SandAgent Docker image (with optional --push)
924
+
925
+ Run "sandagent <command> --help" for command-specific options.
726
926
  `);
727
927
  }
728
928
  async function main() {
729
- const args = parseCliArgs();
730
- process.chdir(args.cwd);
731
- await runAgent({
732
- runner: args.runner,
733
- model: args.model,
734
- userInput: args.userInput,
735
- systemPrompt: args.systemPrompt,
736
- maxTurns: args.maxTurns,
737
- allowedTools: args.allowedTools,
738
- resume: args.resume,
739
- outputFormat: args.outputFormat
740
- });
929
+ const sub = getSubcommand();
930
+ if (!sub || sub === "--help" || sub === "-h") {
931
+ printGlobalHelp();
932
+ process.exit(0);
933
+ }
934
+ switch (sub) {
935
+ case "run": {
936
+ const args = parseRunArgs();
937
+ process.chdir(args.cwd);
938
+ await runAgent({
939
+ runner: args.runner,
940
+ model: args.model,
941
+ userInput: args.userInput,
942
+ systemPrompt: args.systemPrompt,
943
+ maxTurns: args.maxTurns,
944
+ allowedTools: args.allowedTools,
945
+ resume: args.resume,
946
+ outputFormat: args.outputFormat
947
+ });
948
+ break;
949
+ }
950
+ case "image": {
951
+ const subSub = getSubSubcommand();
952
+ if (!subSub || subSub === "--help" || subSub === "-h") {
953
+ printImageHelp();
954
+ process.exit(0);
955
+ }
956
+ if (subSub === "build") {
957
+ const args = parseImageBuildArgs();
958
+ await buildImage(args);
959
+ } else {
960
+ console.error(`Unknown image subcommand: ${subSub}`);
961
+ printImageHelp();
962
+ process.exit(1);
963
+ }
964
+ break;
965
+ }
966
+ default:
967
+ console.error(`Unknown command: ${sub}`);
968
+ printGlobalHelp();
969
+ process.exit(1);
970
+ }
741
971
  }
742
972
  main().catch((error) => {
743
973
  console.error("Fatal error:", error.message);
package/dist/cli.d.ts CHANGED
@@ -2,14 +2,9 @@
2
2
  /**
3
3
  * SandAgent Runner CLI
4
4
  *
5
- * Like gemini-cli or claude-code - runs locally in your terminal.
6
- * Streams AI SDK UI messages directly to stdout.
7
- *
8
- * Usage:
9
- * sandagent run [options] -- "<user input>"
10
- *
11
- * The CLI is designed to be executed in a specific working directory
12
- * and outputs AI SDK UI messages directly.
5
+ * Subcommands:
6
+ * sandagent run [options] -- "<user input>" Run an agent locally
7
+ * sandagent image build [options] Build (and optionally push) a Docker image
13
8
  */
14
9
  export {};
15
10
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;GAWG"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG"}
package/dist/cli.js CHANGED
@@ -2,25 +2,59 @@
2
2
  /**
3
3
  * SandAgent Runner CLI
4
4
  *
5
- * Like gemini-cli or claude-code - runs locally in your terminal.
6
- * Streams AI SDK UI messages directly to stdout.
7
- *
8
- * Usage:
9
- * sandagent run [options] -- "<user input>"
10
- *
11
- * The CLI is designed to be executed in a specific working directory
12
- * and outputs AI SDK UI messages directly.
5
+ * Subcommands:
6
+ * sandagent run [options] -- "<user input>" Run an agent locally
7
+ * sandagent image build [options] Build (and optionally push) a Docker image
13
8
  */
14
9
  import { parseArgs } from "node:util";
10
+ import { buildImage } from "./build-image.js";
15
11
  import { runAgent } from "./runner.js";
16
- function parseCliArgs() {
12
+ // ---------------------------------------------------------------------------
13
+ // Shared helpers
14
+ // ---------------------------------------------------------------------------
15
+ /** Get the first positional arg (top-level subcommand). */
16
+ function getSubcommand() {
17
+ for (let i = 2; i < process.argv.length; i++) {
18
+ const a = process.argv[i];
19
+ if (a === "--")
20
+ break;
21
+ if (!a.startsWith("-"))
22
+ return a;
23
+ }
24
+ return undefined;
25
+ }
26
+ /** Get the second positional arg (sub-subcommand, e.g. "build" in "image build"). */
27
+ function getSubSubcommand() {
28
+ let found = 0;
29
+ for (let i = 2; i < process.argv.length; i++) {
30
+ const a = process.argv[i];
31
+ if (a === "--")
32
+ break;
33
+ if (!a.startsWith("-")) {
34
+ found++;
35
+ if (found === 2)
36
+ return a;
37
+ }
38
+ }
39
+ return undefined;
40
+ }
41
+ /** Slice process.argv to args after N positionals. */
42
+ function argsAfterPositionals(n) {
43
+ let found = 0;
44
+ for (let i = 2; i < process.argv.length; i++) {
45
+ if (!process.argv[i].startsWith("-") && process.argv[i] !== "--") {
46
+ found++;
47
+ if (found === n)
48
+ return process.argv.slice(i + 1);
49
+ }
50
+ }
51
+ return [];
52
+ }
53
+ function parseRunArgs() {
17
54
  const { values, positionals } = parseArgs({
55
+ args: argsAfterPositionals(1),
18
56
  options: {
19
- runner: {
20
- type: "string",
21
- short: "r",
22
- default: "claude",
23
- },
57
+ runner: { type: "string", short: "r", default: "claude" },
24
58
  model: {
25
59
  type: "string",
26
60
  short: "m",
@@ -31,65 +65,38 @@ function parseCliArgs() {
31
65
  short: "c",
32
66
  default: process.env.SANDAGENT_WORKSPACE ?? process.cwd(),
33
67
  },
34
- "system-prompt": {
35
- type: "string",
36
- short: "s",
37
- },
38
- "max-turns": {
39
- type: "string",
40
- short: "t",
41
- },
42
- "allowed-tools": {
43
- type: "string",
44
- short: "a",
45
- },
46
- resume: {
47
- type: "string",
48
- short: "r",
49
- },
50
- "output-format": {
51
- type: "string",
52
- short: "o",
53
- },
54
- help: {
55
- type: "boolean",
56
- short: "h",
57
- },
68
+ "system-prompt": { type: "string", short: "s" },
69
+ "max-turns": { type: "string", short: "t" },
70
+ "allowed-tools": { type: "string", short: "a" },
71
+ resume: { type: "string" },
72
+ "output-format": { type: "string", short: "o" },
73
+ help: { type: "boolean", short: "h" },
58
74
  },
59
75
  allowPositionals: true,
60
76
  strict: true,
61
77
  });
62
78
  if (values.help) {
63
- printHelp();
79
+ printRunHelp();
64
80
  process.exit(0);
65
81
  }
66
- // Check for "run" command
67
- if (positionals[0] !== "run") {
68
- console.error('Error: Expected "run" command');
69
- console.error('Usage: sandagent run [options] -- "<user input>"');
70
- process.exit(1);
71
- }
72
- // Get user input from positionals after "--"
73
82
  const dashIndex = process.argv.indexOf("--");
74
83
  let userInput = "";
75
84
  if (dashIndex !== -1 && dashIndex < process.argv.length - 1) {
76
85
  userInput = process.argv.slice(dashIndex + 1).join(" ");
77
86
  }
78
- else if (positionals.length > 1) {
79
- userInput = positionals.slice(1).join(" ");
87
+ else if (positionals.length > 0) {
88
+ userInput = positionals.join(" ");
80
89
  }
81
90
  if (!userInput) {
82
91
  console.error("Error: User input is required");
83
92
  console.error('Usage: sandagent run [options] -- "<user input>"');
84
93
  process.exit(1);
85
94
  }
86
- // Validate runner
87
95
  const runner = values.runner;
88
96
  if (!["claude", "codex", "copilot"].includes(runner)) {
89
97
  console.error('Error: --runner must be one of: "claude", "codex", "copilot"');
90
98
  process.exit(1);
91
99
  }
92
- // Validate output-format
93
100
  const outputFormat = values["output-format"];
94
101
  if (outputFormat &&
95
102
  !["text", "json", "stream-json", "stream"].includes(outputFormat)) {
@@ -110,62 +117,165 @@ function parseCliArgs() {
110
117
  userInput,
111
118
  };
112
119
  }
113
- function printHelp() {
120
+ function parseImageBuildArgs() {
121
+ const { values } = parseArgs({
122
+ args: argsAfterPositionals(2),
123
+ options: {
124
+ name: { type: "string", default: "sandagent" },
125
+ tag: { type: "string", default: "latest" },
126
+ image: { type: "string" },
127
+ platform: { type: "string", default: "linux/amd64" },
128
+ template: { type: "string" },
129
+ push: { type: "boolean", default: false },
130
+ help: { type: "boolean", short: "h" },
131
+ },
132
+ allowPositionals: false,
133
+ strict: true,
134
+ });
135
+ if (values.help) {
136
+ printImageBuildHelp();
137
+ process.exit(0);
138
+ }
139
+ return {
140
+ name: values.name,
141
+ tag: values.tag,
142
+ image: values.image,
143
+ platform: values.platform,
144
+ template: values.template,
145
+ push: values.push ?? false,
146
+ };
147
+ }
148
+ // ---------------------------------------------------------------------------
149
+ // Help text
150
+ // ---------------------------------------------------------------------------
151
+ function printRunHelp() {
114
152
  console.log(`
115
- 🤖 SandAgent Runner CLI
153
+ 🤖 SandAgent Runner CLI — run
116
154
 
117
- Like gemini-cli or claude-code - runs locally in your terminal.
118
- Streams AI SDK UI messages directly to stdout.
155
+ Runs an agent locally in your terminal, streaming AI SDK UI messages to stdout.
119
156
 
120
157
  Usage:
121
158
  sandagent run [options] -- "<user input>"
122
159
 
123
160
  Options:
124
- -r, --runner <runner> Runner to use: claude, codex, copilot (default: claude)
125
- -m, --model <model> Model to use (default: claude-sonnet-4-20250514)
126
- -c, --cwd <path> Working directory (default: current directory)
161
+ -r, --runner <runner> Runner: claude, codex, copilot (default: claude)
162
+ -m, --model <model> Model (default: claude-sonnet-4-20250514)
163
+ -c, --cwd <path> Working directory (default: cwd)
127
164
  -s, --system-prompt <prompt> Custom system prompt
128
- -t, --max-turns <n> Maximum conversation turns
129
- -a, --allowed-tools <tools> Comma-separated list of allowed tools
130
- -r, --resume <session-id> Resume a previous session
131
- -o, --output-format <format> Output format (default: stream)
132
- Available: text, json(single result), stream-json(realtime streaming), stream(ai sdk ui sse format)
133
- -h, --help Show this help message
165
+ -t, --max-turns <n> Max conversation turns
166
+ -a, --allowed-tools <tools> Comma-separated allowed tools
167
+ --resume <session-id> Resume a previous session
168
+ -o, --output-format <fmt> text | json | stream-json | stream (default: stream)
169
+ -h, --help Show this help
170
+
171
+ Environment:
172
+ ANTHROPIC_API_KEY Anthropic API key (required)
173
+ SANDAGENT_WORKSPACE Default workspace path
174
+ `);
175
+ }
176
+ function printImageBuildHelp() {
177
+ console.log(`
178
+ 🐳 SandAgent Runner CLI — image build
134
179
 
135
- Environment Variables:
136
- ANTHROPIC_API_KEY Anthropic API key (required)
137
- SANDAGENT_WORKSPACE Default workspace path
138
- SANDAGENT_LOG_LEVEL Logging level (debug, info, warn, error)
180
+ Build (and optionally push) a SandAgent Docker image.
181
+ The image includes Claude Agent SDK + runner-cli pre-installed.
182
+
183
+ Usage:
184
+ sandagent image build [options]
185
+
186
+ Options:
187
+ --name <name> Image name, e.g. vikadata/sandagent-seo (default: sandagent)
188
+ --tag <tag> Image tag (default: latest)
189
+ --image <full> Full image name override (e.g. myorg/myimage:v1)
190
+ --platform <plat> Build platform (default: linux/amd64)
191
+ --template <path> Path to agent template directory to bake into the image
192
+ --push Push image to registry after build
193
+ -h, --help Show this help
139
194
 
140
195
  Examples:
141
- # Run with default settings
142
- sandagent run -- "Create a hello world script"
196
+ sandagent image build --name vikadata/sandagent-seo --tag 0.1.0
197
+ sandagent image build --name vikadata/sandagent-seo --tag 0.1.0 --template ./templates/seo-agent
198
+ sandagent image build --name vikadata/sandagent-seo --tag 0.1.0 --template ./templates/seo-agent --push
199
+ `);
200
+ }
201
+ function printImageHelp() {
202
+ console.log(`
203
+ 🐳 SandAgent Runner CLI — image
143
204
 
144
- # Run with custom system prompt
145
- sandagent run --system-prompt "You are a coding assistant" -- "Build a REST API with Express"
205
+ Manage SandAgent Docker images.
146
206
 
147
- # Specify working directory
148
- sandagent run --cwd ./my-project -- "Fix the bug in main.ts"
207
+ Usage:
208
+ sandagent image <subcommand> [options]
209
+
210
+ Subcommands:
211
+ build Build (and optionally push) a Docker image
212
+
213
+ Run "sandagent image build --help" for build options.
149
214
  `);
150
215
  }
216
+ function printGlobalHelp() {
217
+ console.log(`
218
+ 🤖 SandAgent Runner CLI
219
+
220
+ Usage:
221
+ sandagent <command> [options]
222
+
223
+ Commands:
224
+ run Run an agent locally (streams AI SDK UI messages to stdout)
225
+ image build Build a SandAgent Docker image (with optional --push)
226
+
227
+ Run "sandagent <command> --help" for command-specific options.
228
+ `);
229
+ }
230
+ // ---------------------------------------------------------------------------
231
+ // Main
232
+ // ---------------------------------------------------------------------------
151
233
  async function main() {
152
- const args = parseCliArgs();
153
- // Change to the specified working directory
154
- process.chdir(args.cwd);
155
- // Run the agent and stream output to stdout
156
- await runAgent({
157
- runner: args.runner,
158
- model: args.model,
159
- userInput: args.userInput,
160
- systemPrompt: args.systemPrompt,
161
- maxTurns: args.maxTurns,
162
- allowedTools: args.allowedTools,
163
- resume: args.resume,
164
- outputFormat: args.outputFormat,
165
- });
234
+ const sub = getSubcommand();
235
+ if (!sub || sub === "--help" || sub === "-h") {
236
+ printGlobalHelp();
237
+ process.exit(0);
238
+ }
239
+ switch (sub) {
240
+ case "run": {
241
+ const args = parseRunArgs();
242
+ process.chdir(args.cwd);
243
+ await runAgent({
244
+ runner: args.runner,
245
+ model: args.model,
246
+ userInput: args.userInput,
247
+ systemPrompt: args.systemPrompt,
248
+ maxTurns: args.maxTurns,
249
+ allowedTools: args.allowedTools,
250
+ resume: args.resume,
251
+ outputFormat: args.outputFormat,
252
+ });
253
+ break;
254
+ }
255
+ case "image": {
256
+ const subSub = getSubSubcommand();
257
+ if (!subSub || subSub === "--help" || subSub === "-h") {
258
+ printImageHelp();
259
+ process.exit(0);
260
+ }
261
+ if (subSub === "build") {
262
+ const args = parseImageBuildArgs();
263
+ await buildImage(args);
264
+ }
265
+ else {
266
+ console.error(`Unknown image subcommand: ${subSub}`);
267
+ printImageHelp();
268
+ process.exit(1);
269
+ }
270
+ break;
271
+ }
272
+ default:
273
+ console.error(`Unknown command: ${sub}`);
274
+ printGlobalHelp();
275
+ process.exit(1);
276
+ }
166
277
  }
167
278
  main().catch((error) => {
168
- // Errors go to stderr, not stdout
169
279
  console.error("Fatal error:", error.message);
170
280
  process.exit(1);
171
281
  });
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { runAgent, type RunAgentOptions } from "./runner.js";
2
+ export { buildImage, type BuildImageOptions } from "./build-image.js";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { runAgent } from "./runner.js";
2
+ export { buildImage } from "./build-image.js";
2
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,UAAU,EAA0B,MAAM,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sandagent/runner-cli",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
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": {
@@ -16,7 +16,8 @@
16
16
  }
17
17
  },
18
18
  "files": [
19
- "dist"
19
+ "dist",
20
+ "Dockerfile"
20
21
  ],
21
22
  "repository": {
22
23
  "type": "git",