@aiassesstech/sam 0.2.3 → 0.3.0

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.
Files changed (47) hide show
  1. package/dist/cli/runner.d.ts +1 -0
  2. package/dist/cli/runner.d.ts.map +1 -1
  3. package/dist/cli/runner.js +5 -1
  4. package/dist/cli/runner.js.map +1 -1
  5. package/dist/cli/setup.d.ts +1 -0
  6. package/dist/cli/setup.d.ts.map +1 -1
  7. package/dist/cli/setup.js +125 -2
  8. package/dist/cli/setup.js.map +1 -1
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +2 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/memory/direct-writer.d.ts +27 -0
  14. package/dist/memory/direct-writer.d.ts.map +1 -0
  15. package/dist/memory/direct-writer.js +74 -0
  16. package/dist/memory/direct-writer.js.map +1 -0
  17. package/dist/plugin.d.ts.map +1 -1
  18. package/dist/plugin.js +28 -10
  19. package/dist/plugin.js.map +1 -1
  20. package/dist/sandbox/sandbox-manager.d.ts +58 -0
  21. package/dist/sandbox/sandbox-manager.d.ts.map +1 -0
  22. package/dist/sandbox/sandbox-manager.js +373 -0
  23. package/dist/sandbox/sandbox-manager.js.map +1 -0
  24. package/dist/sandbox/types.d.ts +65 -0
  25. package/dist/sandbox/types.d.ts.map +1 -0
  26. package/dist/sandbox/types.js +14 -0
  27. package/dist/sandbox/types.js.map +1 -0
  28. package/dist/tools/sam-artifact.d.ts +43 -0
  29. package/dist/tools/sam-artifact.d.ts.map +1 -0
  30. package/dist/tools/sam-artifact.js +102 -0
  31. package/dist/tools/sam-artifact.js.map +1 -0
  32. package/dist/tools/sam-execute.d.ts +60 -0
  33. package/dist/tools/sam-execute.d.ts.map +1 -0
  34. package/dist/tools/sam-execute.js +109 -0
  35. package/dist/tools/sam-execute.js.map +1 -0
  36. package/dist/tools/sam-sandbox.d.ts +29 -0
  37. package/dist/tools/sam-sandbox.d.ts.map +1 -0
  38. package/dist/tools/sam-sandbox.js +83 -0
  39. package/dist/tools/sam-sandbox.js.map +1 -0
  40. package/dist/tools/sam-status.js +1 -1
  41. package/dist/tools/sam-test.d.ts +55 -0
  42. package/dist/tools/sam-test.d.ts.map +1 -0
  43. package/dist/tools/sam-test.js +191 -0
  44. package/dist/tools/sam-test.js.map +1 -0
  45. package/docker/Dockerfile +16 -0
  46. package/openclaw.plugin.json +1 -1
  47. package/package.json +2 -1
@@ -0,0 +1,60 @@
1
+ /**
2
+ * sam_execute — Execute code in the Docker sandbox
3
+ *
4
+ * Creates an ephemeral container, runs code with resource limits,
5
+ * captures output, extracts artifacts, destroys container.
6
+ * Writes memory file on completion.
7
+ */
8
+ import type { SandboxManager } from '../sandbox/sandbox-manager.js';
9
+ import type { SamMemory } from '../memory/sam-memory.js';
10
+ export declare function createExecuteTool(sandbox: SandboxManager, getMemory: () => SamMemory | null): {
11
+ name: string;
12
+ description: string;
13
+ parameters: {
14
+ type: "object";
15
+ properties: {
16
+ language: {
17
+ type: string;
18
+ enum: string[];
19
+ description: string;
20
+ };
21
+ code: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ files: {
26
+ type: string;
27
+ description: string;
28
+ items: {
29
+ type: string;
30
+ properties: {
31
+ filename: {
32
+ type: string;
33
+ };
34
+ content: {
35
+ type: string;
36
+ };
37
+ };
38
+ required: string[];
39
+ };
40
+ };
41
+ er_id: {
42
+ type: string;
43
+ description: string;
44
+ };
45
+ timeout_minutes: {
46
+ type: string;
47
+ description: string;
48
+ };
49
+ };
50
+ required: string[];
51
+ };
52
+ execute(_toolCallId: string, params: Record<string, unknown>): Promise<{
53
+ isError?: boolean | undefined;
54
+ content: {
55
+ type: string;
56
+ text: string;
57
+ }[];
58
+ }>;
59
+ };
60
+ //# sourceMappingURL=sam-execute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sam-execute.d.ts","sourceRoot":"","sources":["../../src/tools/sam-execute.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAwCpD,MAAM,EAAE;;yBAEjB,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;EA8DrE"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * sam_execute — Execute code in the Docker sandbox
3
+ *
4
+ * Creates an ephemeral container, runs code with resource limits,
5
+ * captures output, extracts artifacts, destroys container.
6
+ * Writes memory file on completion.
7
+ */
8
+ export function createExecuteTool(sandbox, getMemory) {
9
+ return {
10
+ name: 'sam_execute',
11
+ description: 'Execute code in the Docker sandbox. Supports nodejs, python, and bash. ' +
12
+ 'Provide code directly or with supporting files. Returns stdout, stderr, exit code, ' +
13
+ 'execution time, and list of created files.',
14
+ parameters: {
15
+ type: 'object',
16
+ properties: {
17
+ language: {
18
+ type: 'string',
19
+ enum: ['nodejs', 'python', 'bash'],
20
+ description: 'Language/runtime for execution',
21
+ },
22
+ code: {
23
+ type: 'string',
24
+ description: 'The code to execute',
25
+ },
26
+ files: {
27
+ type: 'array',
28
+ description: 'Additional files to place in /workspace before execution',
29
+ items: {
30
+ type: 'object',
31
+ properties: {
32
+ filename: { type: 'string' },
33
+ content: { type: 'string' },
34
+ },
35
+ required: ['filename', 'content'],
36
+ },
37
+ },
38
+ er_id: {
39
+ type: 'string',
40
+ description: 'Engineering Request ID to associate artifacts with',
41
+ },
42
+ timeout_minutes: {
43
+ type: 'number',
44
+ description: 'Execution timeout in minutes (default 10, max 30)',
45
+ },
46
+ },
47
+ required: ['language', 'code'],
48
+ },
49
+ async execute(_toolCallId, params) {
50
+ try {
51
+ const language = params.language;
52
+ const code = params.code;
53
+ const files = params.files ?? [];
54
+ const erId = params.er_id;
55
+ const timeoutMin = Math.min(params.timeout_minutes || 10, 30);
56
+ const timeoutMs = timeoutMin * 60 * 1000;
57
+ const result = await sandbox.execute(language, code, files, {
58
+ timeoutMs,
59
+ erId,
60
+ });
61
+ const memory = getMemory();
62
+ if (memory && erId) {
63
+ memory.writer?.write?.({
64
+ agent: 'sam',
65
+ type: 'sandbox-execution',
66
+ tags: ['engineering', 'sandbox', language, erId],
67
+ title: `Sandbox Execution: ${erId} — ${language}`,
68
+ body: `## Sandbox Execution\n\n` +
69
+ `**ER**: ${erId}\n` +
70
+ `**Language**: ${language}\n` +
71
+ `**Exit Code**: ${result.exitCode}\n` +
72
+ `**Duration**: ${result.executionTimeMs}ms\n` +
73
+ `**Timed Out**: ${result.timedOut}\n` +
74
+ `**Files Created**: ${result.filesCreated.length}\n`,
75
+ metadata: {
76
+ er_id: erId,
77
+ language,
78
+ exit_code: result.exitCode,
79
+ execution_time_ms: result.executionTimeMs,
80
+ },
81
+ }).catch(() => { });
82
+ }
83
+ return {
84
+ content: [{
85
+ type: 'text',
86
+ text: JSON.stringify({
87
+ exitCode: result.exitCode,
88
+ timedOut: result.timedOut,
89
+ executionTimeMs: result.executionTimeMs,
90
+ stdout: result.stdout.slice(0, 10_000),
91
+ stderr: result.stderr.slice(0, 10_000),
92
+ filesCreated: result.filesCreated,
93
+ ...(result.stdout.length > 10_000 ? { stdoutTruncated: true } : {}),
94
+ ...(result.stderr.length > 10_000 ? { stderrTruncated: true } : {}),
95
+ }, null, 2),
96
+ }],
97
+ ...(result.exitCode !== 0 ? { isError: true } : {}),
98
+ };
99
+ }
100
+ catch (err) {
101
+ return {
102
+ content: [{ type: 'text', text: `sam_execute error: ${err instanceof Error ? err.message : String(err)}` }],
103
+ isError: true,
104
+ };
105
+ }
106
+ },
107
+ };
108
+ }
109
+ //# sourceMappingURL=sam-execute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sam-execute.js","sourceRoot":"","sources":["../../src/tools/sam-execute.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * sam_sandbox — Manage sandbox lifecycle and configuration
3
+ *
4
+ * Actions: status, build, cleanup
5
+ */
6
+ import type { SandboxManager } from '../sandbox/sandbox-manager.js';
7
+ export declare function createSandboxTool(sandbox: SandboxManager): {
8
+ name: string;
9
+ description: string;
10
+ parameters: {
11
+ type: "object";
12
+ properties: {
13
+ action: {
14
+ type: string;
15
+ enum: string[];
16
+ description: string;
17
+ };
18
+ };
19
+ required: string[];
20
+ };
21
+ execute(_toolCallId: string, params: Record<string, unknown>): Promise<{
22
+ isError?: boolean | undefined;
23
+ content: {
24
+ type: string;
25
+ text: string;
26
+ }[];
27
+ }>;
28
+ };
29
+ //# sourceMappingURL=sam-sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sam-sandbox.d.ts","sourceRoot":"","sources":["../../src/tools/sam-sandbox.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc;;;;;;;;;;;;kBAiB3B,MAAM,EAAE;;yBAEP,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;EA6DrE"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * sam_sandbox — Manage sandbox lifecycle and configuration
3
+ *
4
+ * Actions: status, build, cleanup
5
+ */
6
+ export function createSandboxTool(sandbox) {
7
+ return {
8
+ name: 'sam_sandbox',
9
+ description: 'Manage the Docker sandbox. ' +
10
+ 'status: Docker availability, image, running containers, disk usage. ' +
11
+ 'build: Rebuild the sandbox Docker image. ' +
12
+ 'cleanup: Remove stale containers and old artifacts.',
13
+ parameters: {
14
+ type: 'object',
15
+ properties: {
16
+ action: {
17
+ type: 'string',
18
+ enum: ['status', 'build', 'cleanup'],
19
+ description: 'Sandbox management action',
20
+ },
21
+ },
22
+ required: ['action'],
23
+ },
24
+ async execute(_toolCallId, params) {
25
+ try {
26
+ const action = params.action;
27
+ if (action === 'status') {
28
+ const status = await sandbox.getStatus();
29
+ return {
30
+ content: [{
31
+ type: 'text',
32
+ text: JSON.stringify({
33
+ action: 'status',
34
+ docker: status.dockerAvailable ? 'available' : 'not found',
35
+ image: status.imageExists ? 'ready' : 'not built',
36
+ runningContainers: status.runningContainers,
37
+ artifactDiskUsageMb: status.artifactDiskUsageMb,
38
+ }, null, 2),
39
+ }],
40
+ };
41
+ }
42
+ if (action === 'build') {
43
+ const result = await sandbox.buildImage();
44
+ return {
45
+ content: [{
46
+ type: 'text',
47
+ text: JSON.stringify({
48
+ action: 'build',
49
+ success: result.success,
50
+ output: result.output.slice(0, 5_000),
51
+ }, null, 2),
52
+ }],
53
+ ...(result.success ? {} : { isError: true }),
54
+ };
55
+ }
56
+ if (action === 'cleanup') {
57
+ const result = await sandbox.cleanup();
58
+ return {
59
+ content: [{
60
+ type: 'text',
61
+ text: JSON.stringify({
62
+ action: 'cleanup',
63
+ containersRemoved: result.removed,
64
+ diskReclaimedMb: result.reclaimedMb,
65
+ }, null, 2),
66
+ }],
67
+ };
68
+ }
69
+ return {
70
+ content: [{ type: 'text', text: `Unknown action: ${action}` }],
71
+ isError: true,
72
+ };
73
+ }
74
+ catch (err) {
75
+ return {
76
+ content: [{ type: 'text', text: `sam_sandbox error: ${err instanceof Error ? err.message : String(err)}` }],
77
+ isError: true,
78
+ };
79
+ }
80
+ },
81
+ };
82
+ }
83
+ //# sourceMappingURL=sam-sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sam-sandbox.js","sourceRoot":"","sources":["../../src/tools/sam-sandbox.ts"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@ export function createStatusTool(pipeline, config, fleetBusStatus) {
16
16
  agent: {
17
17
  name: 'Sam',
18
18
  role: 'Chief Engineer',
19
- version: '0.2.3',
19
+ version: '0.3.0',
20
20
  internalName: 'SAM2',
21
21
  },
22
22
  pipeline: summary,
@@ -0,0 +1,55 @@
1
+ /**
2
+ * sam_test — Run test suites in the Docker sandbox
3
+ *
4
+ * Supports vitest, jest, pytest, and custom test commands.
5
+ * Parses structured results from test output.
6
+ */
7
+ import type { SandboxManager } from '../sandbox/sandbox-manager.js';
8
+ import type { SamMemory } from '../memory/sam-memory.js';
9
+ export declare function createTestTool(sandbox: SandboxManager, getMemory: () => SamMemory | null): {
10
+ name: string;
11
+ description: string;
12
+ parameters: {
13
+ type: "object";
14
+ properties: {
15
+ framework: {
16
+ type: string;
17
+ enum: string[];
18
+ description: string;
19
+ };
20
+ files: {
21
+ type: string;
22
+ description: string;
23
+ items: {
24
+ type: string;
25
+ properties: {
26
+ filename: {
27
+ type: string;
28
+ };
29
+ content: {
30
+ type: string;
31
+ };
32
+ };
33
+ required: string[];
34
+ };
35
+ };
36
+ command: {
37
+ type: string;
38
+ description: string;
39
+ };
40
+ er_id: {
41
+ type: string;
42
+ description: string;
43
+ };
44
+ };
45
+ required: string[];
46
+ };
47
+ execute(_toolCallId: string, params: Record<string, unknown>): Promise<{
48
+ isError?: boolean | undefined;
49
+ content: {
50
+ type: string;
51
+ text: string;
52
+ }[];
53
+ }>;
54
+ };
55
+ //# sourceMappingURL=sam-test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sam-test.d.ts","sourceRoot":"","sources":["../../src/tools/sam-test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAoBzD,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoC/C,MAAM,EAAE;;yBAEnB,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;EAwFrE"}
@@ -0,0 +1,191 @@
1
+ /**
2
+ * sam_test — Run test suites in the Docker sandbox
3
+ *
4
+ * Supports vitest, jest, pytest, and custom test commands.
5
+ * Parses structured results from test output.
6
+ */
7
+ const FRAMEWORK_COMMANDS = {
8
+ vitest: {
9
+ install: 'npm init -y && npm install vitest --save-dev',
10
+ run: 'npx vitest run --reporter=json 2>/dev/null || npx vitest run',
11
+ language: 'nodejs',
12
+ },
13
+ jest: {
14
+ install: 'npm init -y && npm install jest --save-dev',
15
+ run: 'npx jest --json 2>/dev/null || npx jest',
16
+ language: 'nodejs',
17
+ },
18
+ pytest: {
19
+ install: 'pip3 install --user pytest',
20
+ run: 'python3 -m pytest -v',
21
+ language: 'python',
22
+ },
23
+ };
24
+ export function createTestTool(sandbox, getMemory) {
25
+ return {
26
+ name: 'sam_test',
27
+ description: 'Run test suites in the Docker sandbox. ' +
28
+ 'Supports vitest, jest, pytest, or custom commands. ' +
29
+ 'Returns passed/failed/skipped counts and failure details.',
30
+ parameters: {
31
+ type: 'object',
32
+ properties: {
33
+ framework: {
34
+ type: 'string',
35
+ enum: ['vitest', 'jest', 'pytest', 'custom'],
36
+ description: 'Test framework to use',
37
+ },
38
+ files: {
39
+ type: 'array',
40
+ description: 'Source and test files to place in /workspace',
41
+ items: {
42
+ type: 'object',
43
+ properties: {
44
+ filename: { type: 'string' },
45
+ content: { type: 'string' },
46
+ },
47
+ required: ['filename', 'content'],
48
+ },
49
+ },
50
+ command: {
51
+ type: 'string',
52
+ description: 'Custom test command (required when framework is "custom")',
53
+ },
54
+ er_id: {
55
+ type: 'string',
56
+ description: 'Engineering Request ID',
57
+ },
58
+ },
59
+ required: ['framework', 'files'],
60
+ },
61
+ async execute(_toolCallId, params) {
62
+ try {
63
+ const framework = params.framework;
64
+ const files = params.files;
65
+ const customCommand = params.command;
66
+ const erId = params.er_id;
67
+ let code;
68
+ let language;
69
+ if (framework === 'custom') {
70
+ if (!customCommand) {
71
+ return {
72
+ content: [{ type: 'text', text: 'Custom framework requires a "command" parameter' }],
73
+ isError: true,
74
+ };
75
+ }
76
+ code = customCommand;
77
+ language = 'bash';
78
+ }
79
+ else {
80
+ const fw = FRAMEWORK_COMMANDS[framework];
81
+ if (!fw) {
82
+ return {
83
+ content: [{ type: 'text', text: `Unknown framework: ${framework}` }],
84
+ isError: true,
85
+ };
86
+ }
87
+ code = `cd /workspace && ${fw.install} 2>/dev/null && ${fw.run}`;
88
+ language = 'bash';
89
+ }
90
+ const result = await sandbox.execute(language, code, files, {
91
+ timeoutMs: 10 * 60 * 1000,
92
+ networkEnabled: true,
93
+ erId,
94
+ });
95
+ const testResult = parseTestOutput(result.stdout, result.stderr, framework);
96
+ const memory = getMemory();
97
+ if (memory && erId) {
98
+ memory.writer?.write?.({
99
+ agent: 'sam',
100
+ type: 'test-execution',
101
+ tags: ['engineering', 'test', framework, erId],
102
+ title: `Test Execution: ${erId} — ${framework}`,
103
+ body: `## Test Results\n\n` +
104
+ `**Framework**: ${framework}\n` +
105
+ `**Passed**: ${testResult.passed}\n` +
106
+ `**Failed**: ${testResult.failed}\n` +
107
+ `**Skipped**: ${testResult.skipped}\n` +
108
+ `**Duration**: ${result.executionTimeMs}ms\n` +
109
+ `**Exit Code**: ${result.exitCode}\n`,
110
+ metadata: {
111
+ er_id: erId,
112
+ framework,
113
+ passed: testResult.passed,
114
+ failed: testResult.failed,
115
+ skipped: testResult.skipped,
116
+ },
117
+ }).catch(() => { });
118
+ }
119
+ return {
120
+ content: [{
121
+ type: 'text',
122
+ text: JSON.stringify({
123
+ framework,
124
+ passed: testResult.passed,
125
+ failed: testResult.failed,
126
+ skipped: testResult.skipped,
127
+ failureDetails: testResult.failureDetails.slice(0, 20),
128
+ executionTimeMs: result.executionTimeMs,
129
+ exitCode: result.exitCode,
130
+ output: (result.stdout + result.stderr).slice(0, 10_000),
131
+ }, null, 2),
132
+ }],
133
+ ...(testResult.failed > 0 ? { isError: true } : {}),
134
+ };
135
+ }
136
+ catch (err) {
137
+ return {
138
+ content: [{ type: 'text', text: `sam_test error: ${err instanceof Error ? err.message : String(err)}` }],
139
+ isError: true,
140
+ };
141
+ }
142
+ },
143
+ };
144
+ }
145
+ function parseTestOutput(stdout, stderr, framework) {
146
+ const combined = stdout + '\n' + stderr;
147
+ // Try JSON parse for vitest/jest
148
+ if (framework === 'vitest' || framework === 'jest') {
149
+ try {
150
+ const json = JSON.parse(stdout);
151
+ if (json.numPassedTests !== undefined) {
152
+ return {
153
+ passed: json.numPassedTests ?? 0,
154
+ failed: json.numFailedTests ?? 0,
155
+ skipped: json.numPendingTests ?? 0,
156
+ failureDetails: (json.testResults ?? [])
157
+ .flatMap((r) => (r.assertionResults ?? []).filter((a) => a.status === 'failed'))
158
+ .map((a) => ({ testName: a.fullName ?? a.title ?? 'unknown', error: (a.failureMessages ?? []).join('\n') })),
159
+ };
160
+ }
161
+ }
162
+ catch { /* fall through to regex */ }
163
+ }
164
+ // Regex fallback
165
+ let passed = 0, failed = 0, skipped = 0;
166
+ const failureDetails = [];
167
+ // vitest/jest pattern: "Tests X passed (Y)"
168
+ const vitestMatch = combined.match(/Tests\s+(\d+)\s+passed/);
169
+ if (vitestMatch)
170
+ passed = parseInt(vitestMatch[1]);
171
+ const vitestFail = combined.match(/Tests\s+(\d+)\s+failed/);
172
+ if (vitestFail)
173
+ failed = parseInt(vitestFail[1]);
174
+ // pytest pattern: "X passed, Y failed"
175
+ const pytestMatch = combined.match(/(\d+)\s+passed/);
176
+ if (pytestMatch && !vitestMatch)
177
+ passed = parseInt(pytestMatch[1]);
178
+ const pytestFail = combined.match(/(\d+)\s+failed/);
179
+ if (pytestFail && !vitestFail)
180
+ failed = parseInt(pytestFail[1]);
181
+ const skipMatch = combined.match(/(\d+)\s+skipped/);
182
+ if (skipMatch)
183
+ skipped = parseInt(skipMatch[1]);
184
+ // Extract FAIL lines as failure details
185
+ const failLines = combined.match(/FAIL\s+.+/g) ?? [];
186
+ for (const line of failLines.slice(0, 20)) {
187
+ failureDetails.push({ testName: line.replace(/^FAIL\s+/, ''), error: 'See full output' });
188
+ }
189
+ return { passed, failed, skipped, failureDetails };
190
+ }
191
+ //# sourceMappingURL=sam-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sam-test.js","sourceRoot":"","sources":["../../src/tools/sam-test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ FROM node:20-slim
2
+
3
+ RUN apt-get update && apt-get install -y \
4
+ python3 python3-pip python3-venv \
5
+ git curl jq \
6
+ && rm -rf /var/lib/apt/lists/*
7
+
8
+ RUN useradd -m -s /bin/bash builder
9
+
10
+ WORKDIR /workspace
11
+ RUN chown builder:builder /workspace
12
+
13
+ RUN mkdir -p /artifacts && chown builder:builder /artifacts
14
+
15
+ USER builder
16
+ CMD ["/bin/bash"]
@@ -2,7 +2,7 @@
2
2
  "id": "sam",
3
3
  "name": "Sam — Chief Engineer",
4
4
  "description": "Chief Engineer plugin — engineering pipeline management, Docker sandbox execution, autonomous build/test/deliver lifecycle, fleet-bus communications, and searchable engineering memory.",
5
- "version": "0.2.3",
5
+ "version": "0.3.0",
6
6
  "entry": "dist/plugin.js",
7
7
  "configSchema": {
8
8
  "type": "object",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiassesstech/sam",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Sam — Chief Engineer plugin for OpenClaw. Engineering pipeline, Docker sandbox, autonomous execution, fleet-bus communications.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -17,6 +17,7 @@
17
17
  "dist",
18
18
  "agent",
19
19
  "openclaw.plugin.json",
20
+ "docker",
20
21
  "README.md",
21
22
  "LICENSE"
22
23
  ],