@aiassesstech/sam 0.3.16 → 0.4.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 (49) hide show
  1. package/README.md +41 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/pipeline/types.d.ts +26 -0
  7. package/dist/pipeline/types.d.ts.map +1 -1
  8. package/dist/pipeline/types.js +9 -0
  9. package/dist/pipeline/types.js.map +1 -1
  10. package/dist/plugin.d.ts.map +1 -1
  11. package/dist/plugin.js +240 -11
  12. package/dist/plugin.js.map +1 -1
  13. package/dist/tools/engine-session-manager.d.ts +18 -0
  14. package/dist/tools/engine-session-manager.d.ts.map +1 -0
  15. package/dist/tools/engine-session-manager.js +29 -0
  16. package/dist/tools/engine-session-manager.js.map +1 -0
  17. package/dist/tools/sam-artifact.d.ts +2 -1
  18. package/dist/tools/sam-artifact.d.ts.map +1 -1
  19. package/dist/tools/sam-artifact.js +15 -2
  20. package/dist/tools/sam-artifact.js.map +1 -1
  21. package/dist/tools/sam-engineer-diff.d.ts +39 -0
  22. package/dist/tools/sam-engineer-diff.d.ts.map +1 -0
  23. package/dist/tools/sam-engineer-diff.js +61 -0
  24. package/dist/tools/sam-engineer-diff.js.map +1 -0
  25. package/dist/tools/sam-engineer-resume.d.ts +34 -0
  26. package/dist/tools/sam-engineer-resume.d.ts.map +1 -0
  27. package/dist/tools/sam-engineer-resume.js +91 -0
  28. package/dist/tools/sam-engineer-resume.js.map +1 -0
  29. package/dist/tools/sam-engineer-status.d.ts +34 -0
  30. package/dist/tools/sam-engineer-status.d.ts.map +1 -0
  31. package/dist/tools/sam-engineer-status.js +66 -0
  32. package/dist/tools/sam-engineer-status.js.map +1 -0
  33. package/dist/tools/sam-engineer-terminate.d.ts +41 -0
  34. package/dist/tools/sam-engineer-terminate.d.ts.map +1 -0
  35. package/dist/tools/sam-engineer-terminate.js +88 -0
  36. package/dist/tools/sam-engineer-terminate.js.map +1 -0
  37. package/dist/tools/sam-engineer.d.ts +60 -0
  38. package/dist/tools/sam-engineer.d.ts.map +1 -0
  39. package/dist/tools/sam-engineer.js +195 -0
  40. package/dist/tools/sam-engineer.js.map +1 -0
  41. package/dist/tools/sam-pipeline.d.ts.map +1 -1
  42. package/dist/tools/sam-pipeline.js +10 -0
  43. package/dist/tools/sam-pipeline.js.map +1 -1
  44. package/dist/tools/sam-status.d.ts +2 -1
  45. package/dist/tools/sam-status.d.ts.map +1 -1
  46. package/dist/tools/sam-status.js +11 -3
  47. package/dist/tools/sam-status.js.map +1 -1
  48. package/openclaw.plugin.json +62 -0
  49. package/package.json +3 -2
package/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # @aiassesstech/sam
2
+
3
+ Sam — Chief Engineer plugin for OpenClaw. Engineering pipeline management, Docker sandbox execution, autonomous code execution, and fleet-bus communications.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @aiassesstech/sam
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ ```bash
14
+ npx @aiassesstech/sam setup --model anthropic/claude-haiku-4-5
15
+ ```
16
+
17
+ ## Tools
18
+
19
+ | Tool | Description |
20
+ |------|-------------|
21
+ | `sam_status` | Current agent state, pipeline summary, sandbox/fleet status |
22
+ | `sam_pipeline` | View engineering pipeline with filters (active/blocked/complete) |
23
+ | `sam_request` | Create, update, or close Engineering Requests |
24
+ | `sam_report` | Generate summary, detailed, or debt reports |
25
+ | `sam_execute` | Run code in Docker sandbox (Node.js, Python, bash) |
26
+ | `sam_sandbox` | Manage sandbox lifecycle (status, build, cleanup) |
27
+ | `sam_test` | Run test suites in sandbox (vitest, jest, pytest, custom) |
28
+ | `sam_artifact` | List, package, and clean up build artifacts |
29
+ | `sam_fleet_task_status` | Report ER status to Jessie via fleet-bus |
30
+ | `sam_fleet_task_complete` | Report ER completion with artifact reference |
31
+
32
+ ## Architecture
33
+
34
+ - **PipelineManager** — Engineering Request lifecycle (INTAKE → ANALYSIS → BUILD → SELF-REVIEW → ARCHIE-REVIEW → DELIVERED)
35
+ - **SandboxManager** — Docker container lifecycle with resource limits
36
+ - **DirectMemoryWriter** — Filesystem-based memory persistence (compatible with Mighty Mark vector search)
37
+ - **Fleet-bus integration** — Cross-agent task coordination with Jessie
38
+
39
+ ## Repository
40
+
41
+ Part of the [compsi](https://github.com/spehargreg/compsi) monorepo — `packages/sam/`.
package/dist/index.d.ts CHANGED
@@ -8,4 +8,5 @@ export type { PipelineStage, EngineeringRequest, PipelineData, SamStatusResult,
8
8
  export { PIPELINE_STAGES, STAGE_ORDER, DEFAULT_CONFIG } from './pipeline/types.js';
9
9
  export type { FleetContext } from './tools/sam-fleet-tools.js';
10
10
  export type { MemoryWriterLike } from './memory/sam-memory.js';
11
+ export { EngineSessionManager } from './tools/engine-session-manager.js';
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,aAAa,EACb,UAAU,EACV,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEnF,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,aAAa,EACb,UAAU,EACV,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEnF,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC"}
package/dist/index.js CHANGED
@@ -5,4 +5,5 @@ export { SamMemory } from './memory/sam-memory.js';
5
5
  export { DirectMemoryWriter } from './memory/direct-writer.js';
6
6
  export { SandboxManager } from './sandbox/sandbox-manager.js';
7
7
  export { PIPELINE_STAGES, STAGE_ORDER, DEFAULT_CONFIG } from './pipeline/types.js';
8
+ export { EngineSessionManager } from './tools/engine-session-manager.js';
8
9
  //# 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,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAa9D,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAa9D,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAInF,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC"}
@@ -19,6 +19,12 @@ export interface EngineeringRequest {
19
19
  deliveredAt?: string;
20
20
  buildAttempts: number;
21
21
  notes: string[];
22
+ engineSessionId?: string;
23
+ engineTurnCount?: number;
24
+ engineCostUsd?: number;
25
+ engineAuditHead?: string;
26
+ engineWorktreePath?: string;
27
+ engineLastGrilloVerdict?: 'allow' | 'allow_with_comment' | 'block';
22
28
  }
23
29
  export interface PipelineData {
24
30
  version: number;
@@ -44,6 +50,13 @@ export interface SamStatusResult {
44
50
  status: 'unavailable' | 'available' | 'busy';
45
51
  };
46
52
  fleetBus: 'connected' | 'observer' | 'standalone';
53
+ engine?: {
54
+ status: 'disabled' | 'enabled' | 'active';
55
+ activeSessions: number;
56
+ activeErIds: string[];
57
+ model: string;
58
+ grilloFailMode: string;
59
+ };
47
60
  }
48
61
  export interface PipelineFilter {
49
62
  filter?: 'all' | 'active' | 'blocked' | 'complete';
@@ -68,6 +81,19 @@ export interface SamPluginConfig {
68
81
  artifactRetentionDays: number;
69
82
  telegramToken?: string;
70
83
  telegramChatId?: string;
84
+ engineEnabled: boolean;
85
+ anthropicApiKey?: string;
86
+ engineModel?: string;
87
+ worktreeBasePath?: string;
88
+ maxBudgetUsd?: number;
89
+ maxBudgetTokens?: number;
90
+ maxIterations?: number;
91
+ sessionTimeoutMs?: number;
92
+ grilloFailMode?: 'fail_closed' | 'fail_open';
93
+ jessieResponseTimeoutMs?: number;
94
+ grilloEndpoint?: string;
95
+ noahEndpoint?: string;
96
+ jessieEndpoint?: string;
71
97
  }
72
98
  export declare const DEFAULT_CONFIG: SamPluginConfig;
73
99
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,aAAa,GACrB,QAAQ,GACR,UAAU,GACV,OAAO,GACP,aAAa,GACb,eAAe,GACf,WAAW,CAAC;AAEhB,eAAO,MAAM,eAAe,EAAE,SAAS,aAAa,EAO1C,CAAC;AAEX,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAOrD,CAAC;AAIF,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAID,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE;QACP,MAAM,EAAE,aAAa,GAAG,WAAW,GAAG,MAAM,CAAC;KAC9C,CAAC;IACF,QAAQ,EAAE,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;CACnD;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;CACpD;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;CACxC;AAID,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,cAAc,EAAE,eAM5B,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"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"}
@@ -26,5 +26,14 @@ export const DEFAULT_CONFIG = {
26
26
  sandboxImage: 'sam-sandbox:latest',
27
27
  artifactDir: '.sam-artifacts',
28
28
  artifactRetentionDays: 7,
29
+ engineEnabled: false,
30
+ engineModel: 'claude-sonnet-4-6',
31
+ worktreeBasePath: '/root/sam/worktrees',
32
+ maxBudgetUsd: 10.0,
33
+ maxBudgetTokens: 500_000,
34
+ maxIterations: 50,
35
+ sessionTimeoutMs: 1_800_000,
36
+ grilloFailMode: 'fail_closed',
37
+ jessieResponseTimeoutMs: 1_800_000,
29
38
  };
30
39
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,QAAQ;IACR,UAAU;IACV,OAAO;IACP,aAAa;IACb,eAAe;IACf,WAAW;CACH,CAAC;AAEX,MAAM,CAAC,MAAM,WAAW,GAAkC;IACxD,QAAQ,EAAE,CAAC;IACX,UAAU,EAAE,CAAC;IACb,OAAO,EAAE,CAAC;IACV,aAAa,EAAE,CAAC;IAChB,eAAe,EAAE,CAAC;IAClB,WAAW,EAAE,CAAC;CACf,CAAC;AA+EF,MAAM,CAAC,MAAM,cAAc,GAAoB;IAC7C,OAAO,EAAE,WAAW;IACpB,cAAc,EAAE,KAAK;IACrB,YAAY,EAAE,oBAAoB;IAClC,WAAW,EAAE,gBAAgB;IAC7B,qBAAqB,EAAE,CAAC;CACzB,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,QAAQ;IACR,UAAU;IACV,OAAO;IACP,aAAa;IACb,eAAe;IACf,WAAW;CACH,CAAC;AAEX,MAAM,CAAC,MAAM,WAAW,GAAkC;IACxD,QAAQ,EAAE,CAAC;IACX,UAAU,EAAE,CAAC;IACb,OAAO,EAAE,CAAC;IACV,aAAa,EAAE,CAAC;IAChB,eAAe,EAAE,CAAC;IAClB,WAAW,EAAE,CAAC;CACf,CAAC;AA6GF,MAAM,CAAC,MAAM,cAAc,GAAoB;IAC7C,OAAO,EAAE,WAAW;IACpB,cAAc,EAAE,KAAK;IACrB,YAAY,EAAE,oBAAoB;IAClC,WAAW,EAAE,gBAAgB;IAC7B,qBAAqB,EAAE,CAAC;IACxB,aAAa,EAAE,KAAK;IACpB,WAAW,EAAE,mBAAmB;IAChC,gBAAgB,EAAE,qBAAqB;IACvC,YAAY,EAAE,IAAI;IAClB,eAAe,EAAE,OAAO;IACxB,aAAa,EAAE,EAAE;IACjB,gBAAgB,EAAE,SAAS;IAC3B,cAAc,EAAE,aAAa;IAC7B,uBAAuB,EAAE,SAAS;CACnC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAyFH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,GAAG,QA+WxC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA4GH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,GAAG,QAucxC"}
package/dist/plugin.js CHANGED
@@ -34,6 +34,12 @@ import { createExecuteTool } from './tools/sam-execute.js';
34
34
  import { createSandboxTool } from './tools/sam-sandbox.js';
35
35
  import { createTestTool } from './tools/sam-test.js';
36
36
  import { createArtifactTool } from './tools/sam-artifact.js';
37
+ import { createEngineerTool } from './tools/sam-engineer.js';
38
+ import { createEngineerStatusTool } from './tools/sam-engineer-status.js';
39
+ import { createEngineerDiffTool } from './tools/sam-engineer-diff.js';
40
+ import { createEngineerResumeTool } from './tools/sam-engineer-resume.js';
41
+ import { createEngineerTerminateTool } from './tools/sam-engineer-terminate.js';
42
+ import { EngineSessionManager } from './tools/engine-session-manager.js';
37
43
  import { SamMemory } from './memory/sam-memory.js';
38
44
  import { SandboxManager } from './sandbox/sandbox-manager.js';
39
45
  import { DEFAULT_CONFIG } from './pipeline/types.js';
@@ -75,6 +81,19 @@ function resolveConfig(api) {
75
81
  artifactRetentionDays: raw.artifactRetentionDays ?? DEFAULT_CONFIG.artifactRetentionDays,
76
82
  telegramToken: raw.telegramToken,
77
83
  telegramChatId: raw.telegramChatId,
84
+ engineEnabled: raw.engineEnabled ?? DEFAULT_CONFIG.engineEnabled,
85
+ anthropicApiKey: raw.anthropicApiKey,
86
+ engineModel: raw.engineModel ?? DEFAULT_CONFIG.engineModel,
87
+ worktreeBasePath: raw.worktreeBasePath ?? DEFAULT_CONFIG.worktreeBasePath,
88
+ maxBudgetUsd: raw.maxBudgetUsd ?? DEFAULT_CONFIG.maxBudgetUsd,
89
+ maxBudgetTokens: raw.maxBudgetTokens ?? DEFAULT_CONFIG.maxBudgetTokens,
90
+ maxIterations: raw.maxIterations ?? DEFAULT_CONFIG.maxIterations,
91
+ sessionTimeoutMs: raw.sessionTimeoutMs ?? DEFAULT_CONFIG.sessionTimeoutMs,
92
+ grilloFailMode: raw.grilloFailMode ?? DEFAULT_CONFIG.grilloFailMode,
93
+ jessieResponseTimeoutMs: raw.jessieResponseTimeoutMs ?? DEFAULT_CONFIG.jessieResponseTimeoutMs,
94
+ grilloEndpoint: raw.grilloEndpoint,
95
+ noahEndpoint: raw.noahEndpoint,
96
+ jessieEndpoint: raw.jessieEndpoint,
78
97
  };
79
98
  }
80
99
  // ── Tool Registration Helper ─────────────────────────────────────
@@ -105,6 +124,14 @@ export default function register(api) {
105
124
  let validatedToolFactory = null;
106
125
  let validationSchemas = {};
107
126
  let validationBusinessRules = {};
127
+ // Engine Bridge (Phase 3) — session manager + deferred bridge loader
128
+ const engineSessions = new EngineSessionManager();
129
+ let bridgeLoader = null;
130
+ if (cfg.engineEnabled) {
131
+ const bridgeMod = '@aiassesstech/sam-engine-bridge';
132
+ bridgeLoader = () => import(bridgeMod);
133
+ console.log(`[sam] Engine bridge enabled — model: ${cfg.engineModel}, grilloFailMode: ${cfg.grilloFailMode}`);
134
+ }
108
135
  const getFleetBusStatus = () => fleetBusState;
109
136
  function validationErrorResponse(message) {
110
137
  return {
@@ -112,7 +139,7 @@ export default function register(api) {
112
139
  isError: true,
113
140
  };
114
141
  }
115
- const ENFORCE_TOOLS = new Set(['sam_execute', 'sam_sandbox']);
142
+ const ENFORCE_TOOLS = new Set(['sam_execute', 'sam_sandbox', 'sam_engineer']);
116
143
  let alertBus = null;
117
144
  const fleetAlertingMod = '@aiassesstech/fleet-alerting';
118
145
  import(fleetAlertingMod)
@@ -137,7 +164,7 @@ export default function register(api) {
137
164
  return { ok: true, params: result };
138
165
  }
139
166
  // ── Phase 1: Management Tools (always available) ────────────
140
- const statusTool = createStatusTool(pipeline, cfg, getFleetBusStatus);
167
+ const statusTool = createStatusTool(pipeline, cfg, getFleetBusStatus, engineSessions);
141
168
  const origStatusExec = statusTool.execute.bind(statusTool);
142
169
  statusTool.execute = async function (_toolCallId, params) {
143
170
  const v = await validateToolParams('sam_status', _toolCallId, params);
@@ -207,7 +234,7 @@ export default function register(api) {
207
234
  return origTestExec(_toolCallId, v.params);
208
235
  };
209
236
  registerTool(api, testTool);
210
- const artifactTool = createArtifactTool(sandbox);
237
+ const artifactTool = createArtifactTool(sandbox, engineSessions);
211
238
  const origArtifactExec = artifactTool.execute.bind(artifactTool);
212
239
  artifactTool.execute = async function (_toolCallId, params) {
213
240
  const v = await validateToolParams('sam_artifact', _toolCallId, params);
@@ -239,6 +266,54 @@ export default function register(api) {
239
266
  };
240
267
  registerTool(api, fleetTaskCompleteTool);
241
268
  console.log('[sam] Fleet tools registered: sam_fleet_task_status, sam_fleet_task_complete (fleet context pending)');
269
+ // ── Phase 4: Engine Tools (always registered, engine checked at call time) ───
270
+ // Per rule 155: unconditional registration — availability checked in execute().
271
+ const engineerTool = createEngineerTool(pipeline, cfg, engineSessions, () => samMemory, bridgeLoader);
272
+ const origEngineerExec = engineerTool.execute.bind(engineerTool);
273
+ engineerTool.execute = async function (_toolCallId, params) {
274
+ const v = await validateToolParams('sam_engineer', _toolCallId, params);
275
+ if (!v.ok)
276
+ return validationErrorResponse(v.message);
277
+ return origEngineerExec(_toolCallId, v.params);
278
+ };
279
+ registerTool(api, engineerTool);
280
+ const engineerStatusTool = createEngineerStatusTool(engineSessions);
281
+ const origEngStatusExec = engineerStatusTool.execute.bind(engineerStatusTool);
282
+ engineerStatusTool.execute = async function (_toolCallId, params) {
283
+ const v = await validateToolParams('sam_engineer_status', _toolCallId, params);
284
+ if (!v.ok)
285
+ return validationErrorResponse(v.message);
286
+ return origEngStatusExec(_toolCallId, v.params);
287
+ };
288
+ registerTool(api, engineerStatusTool);
289
+ const engineerDiffTool = createEngineerDiffTool(engineSessions);
290
+ const origEngDiffExec = engineerDiffTool.execute.bind(engineerDiffTool);
291
+ engineerDiffTool.execute = async function (_toolCallId, params) {
292
+ const v = await validateToolParams('sam_engineer_diff', _toolCallId, params);
293
+ if (!v.ok)
294
+ return validationErrorResponse(v.message);
295
+ return origEngDiffExec(_toolCallId, v.params);
296
+ };
297
+ registerTool(api, engineerDiffTool);
298
+ const engineerResumeTool = createEngineerResumeTool(pipeline, engineSessions);
299
+ const origEngResumeExec = engineerResumeTool.execute.bind(engineerResumeTool);
300
+ engineerResumeTool.execute = async function (_toolCallId, params) {
301
+ const v = await validateToolParams('sam_engineer_resume', _toolCallId, params);
302
+ if (!v.ok)
303
+ return validationErrorResponse(v.message);
304
+ return origEngResumeExec(_toolCallId, v.params);
305
+ };
306
+ registerTool(api, engineerResumeTool);
307
+ const engineerTerminateTool = createEngineerTerminateTool(pipeline, engineSessions, () => samMemory);
308
+ const origEngTermExec = engineerTerminateTool.execute.bind(engineerTerminateTool);
309
+ engineerTerminateTool.execute = async function (_toolCallId, params) {
310
+ const v = await validateToolParams('sam_engineer_terminate', _toolCallId, params);
311
+ if (!v.ok)
312
+ return validationErrorResponse(v.message);
313
+ return origEngTermExec(_toolCallId, v.params);
314
+ };
315
+ registerTool(api, engineerTerminateTool);
316
+ console.log(`[sam] Engine tools registered: sam_engineer, sam_engineer_status, sam_engineer_diff, sam_engineer_resume, sam_engineer_terminate (engine=${cfg.engineEnabled ? 'active' : 'inactive'})`);
242
317
  // ── Command: /sam ──────────────────────────────────────────
243
318
  api.registerCommand({
244
319
  name: 'sam',
@@ -249,14 +324,20 @@ export default function register(api) {
249
324
  text: '# Sam — Chief Engineer\n\n' +
250
325
  'Use Sam\'s tools for engineering pipeline management:\n\n' +
251
326
  '**Pipeline Management:**\n' +
252
- '- **sam_status** — Current state: active ERs, sandbox, fleet-bus\n' +
327
+ '- **sam_status** — Current state: active ERs, sandbox, fleet-bus, engine\n' +
253
328
  '- **sam_pipeline** — Full engineering pipeline view with filters\n' +
254
329
  '- **sam_request** — Create, update, or close Engineering Requests\n' +
255
330
  '- **sam_report** — Engineering reports (summary, detailed, debt)\n\n' +
256
- '**Fleet Communications (Phase 2):**\n' +
331
+ '**Autonomous Engineering Engine:**\n' +
332
+ '- **sam_engineer** — Start/continue an autonomous engineering session for an ER\n' +
333
+ '- **sam_engineer_status** — Session state, cost, files changed, Grillo verdicts\n' +
334
+ '- **sam_engineer_diff** — Git diff from the engine\'s worktree\n' +
335
+ '- **sam_engineer_resume** — Resume a paused session with optional new guidance\n' +
336
+ '- **sam_engineer_terminate** — Hard stop a session (commits in-flight work)\n\n' +
337
+ '**Fleet Communications:**\n' +
257
338
  '- **sam_fleet_task_status** — Report ER stage change to Jessie\n' +
258
339
  '- **sam_fleet_task_complete** — Signal ER completion to Jessie\n\n' +
259
- '**Sandbox (Phase 3):**\n' +
340
+ '**Sandbox:**\n' +
260
341
  '- **sam_execute** — Run code in Docker sandbox\n' +
261
342
  '- **sam_sandbox** — Manage sandbox lifecycle\n' +
262
343
  '- **sam_test** — Run test suites in sandbox\n' +
@@ -280,7 +361,7 @@ export default function register(api) {
280
361
  // ── Prompt Shield Integration (Behavioral Validation) ───────────
281
362
  const promptShieldMod = '@aiassesstech/prompt-shield';
282
363
  import(promptShieldMod)
283
- .then(({ createValidatedToolHandler, sam_execute: samExecuteSchema, SAM_EXECUTE_BUSINESS_RULES, sam_sandbox: samSandboxSchema, sam_status: samStatusSchema, sam_pipeline: samPipelineSchema, sam_request: samRequestSchema, sam_report: samReportSchema, sam_test: samTestSchema, sam_artifact: samArtifactSchema, sam_fleet_task_status: samFleetTaskStatusSchema, sam_fleet_task_complete: samFleetTaskCompleteSchema, }) => {
364
+ .then(({ createValidatedToolHandler, sam_execute: samExecuteSchema, SAM_EXECUTE_BUSINESS_RULES, sam_sandbox: samSandboxSchema, sam_status: samStatusSchema, sam_pipeline: samPipelineSchema, sam_request: samRequestSchema, sam_report: samReportSchema, sam_test: samTestSchema, sam_artifact: samArtifactSchema, sam_fleet_task_status: samFleetTaskStatusSchema, sam_fleet_task_complete: samFleetTaskCompleteSchema, sam_engineer: samEngineerSchema, SAM_ENGINEER_BUSINESS_RULES, sam_engineer_status: samEngineerStatusSchema, sam_engineer_diff: samEngineerDiffSchema, sam_engineer_resume: samEngineerResumeSchema, sam_engineer_terminate: samEngineerTerminateSchema, }) => {
284
365
  validatedToolFactory = createValidatedToolHandler;
285
366
  validationSchemas = {
286
367
  sam_execute: samExecuteSchema,
@@ -293,11 +374,17 @@ export default function register(api) {
293
374
  sam_artifact: samArtifactSchema,
294
375
  sam_fleet_task_status: samFleetTaskStatusSchema,
295
376
  sam_fleet_task_complete: samFleetTaskCompleteSchema,
377
+ sam_engineer: samEngineerSchema,
378
+ sam_engineer_status: samEngineerStatusSchema,
379
+ sam_engineer_diff: samEngineerDiffSchema,
380
+ sam_engineer_resume: samEngineerResumeSchema,
381
+ sam_engineer_terminate: samEngineerTerminateSchema,
296
382
  };
297
383
  validationBusinessRules = {
298
384
  sam_execute: SAM_EXECUTE_BUSINESS_RULES,
385
+ sam_engineer: SAM_ENGINEER_BUSINESS_RULES,
299
386
  };
300
- console.log('[sam] Behavioral validation active: 10 tools (sam_execute/sam_sandbox enforce, rest monitor)');
387
+ console.log('[sam] Behavioral validation active: 15 tools (sam_execute/sam_sandbox/sam_engineer enforce, rest monitor)');
301
388
  })
302
389
  .catch(() => {
303
390
  console.warn('[sam] Prompt shield unavailable — behavioral validation disabled');
@@ -325,6 +412,9 @@ export default function register(api) {
325
412
  'task/assign',
326
413
  'task/cancel',
327
414
  'task/priority_change',
415
+ 'task/budget-request',
416
+ 'task/escalation',
417
+ 'task/redirect',
328
418
  'veto/issue',
329
419
  'fleet/ping',
330
420
  'fleet/pong',
@@ -343,11 +433,20 @@ export default function register(api) {
343
433
  else if (method === 'task/priority_change') {
344
434
  await handleTaskPriorityChange(msg, pipeline, fleetContext);
345
435
  }
436
+ else if (method === 'task/budget-request') {
437
+ await handleBudgetRequest(msg, pipeline, fleetContext, engineSessions);
438
+ }
439
+ else if (method === 'task/escalation') {
440
+ await handleEscalation(msg, pipeline, fleetContext, engineSessions);
441
+ }
442
+ else if (method === 'task/redirect') {
443
+ await handleRedirect(msg, pipeline, fleetContext, engineSessions);
444
+ }
346
445
  else if (method === 'veto/issue') {
347
446
  await handleVetoIssue(msg, pipeline, samMemory);
348
447
  }
349
448
  else if (method === 'fleet/ping') {
350
- await handleFleetPing(msg, pipeline, cfg, fleetContext);
449
+ await handleFleetPing(msg, pipeline, cfg, fleetContext, engineSessions);
351
450
  }
352
451
  },
353
452
  });
@@ -367,6 +466,8 @@ export default function register(api) {
367
466
  'sam_status', 'sam_pipeline', 'sam_request', 'sam_report',
368
467
  'sam_execute', 'sam_sandbox', 'sam_test', 'sam_artifact',
369
468
  'sam_fleet_task_status', 'sam_fleet_task_complete',
469
+ 'sam_engineer', 'sam_engineer_status', 'sam_engineer_diff',
470
+ 'sam_engineer_resume', 'sam_engineer_terminate',
370
471
  ].join(', ');
371
472
  let capturedWorkspaceDir = null;
372
473
  api.registerHook("agent:bootstrap", async (event) => {
@@ -556,7 +657,7 @@ async function handleTaskPriorityChange(msg, pipeline, fleet) {
556
657
  console.error(`[sam] Failed to handle task/priority_change: ${err}`);
557
658
  }
558
659
  }
559
- async function handleFleetPing(msg, pipeline, cfg, fleet) {
660
+ async function handleFleetPing(msg, pipeline, cfg, fleet, engineSessions) {
560
661
  const summary = pipeline.getSummary();
561
662
  try {
562
663
  await fleet.fleetSend(fleet.bus, fleet.transport, {
@@ -565,11 +666,13 @@ async function handleFleetPing(msg, pipeline, cfg, fleet) {
565
666
  params: {
566
667
  agentId: 'sam',
567
668
  currentStatus: 'active',
568
- toolCount: 12,
669
+ toolCount: 15,
569
670
  pendingTasks: summary.active,
570
671
  activeERs: summary.active,
571
672
  blockedERs: summary.blocked,
572
673
  sandboxStatus: cfg.sandboxEnabled ? 'available' : 'unavailable',
674
+ engineStatus: cfg.engineEnabled ? 'enabled' : 'disabled',
675
+ activeEngineSessions: engineSessions?.activeCount() ?? 0,
573
676
  memoryUsageMB: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
574
677
  uptimeMs: process.uptime() * 1000,
575
678
  },
@@ -580,4 +683,130 @@ async function handleFleetPing(msg, pipeline, cfg, fleet) {
580
683
  console.error(`[sam] Failed to send fleet/pong: ${err}`);
581
684
  }
582
685
  }
686
+ // ── Engine-related Fleet Inbound Handlers ────────────────────────
687
+ async function handleBudgetRequest(msg, pipeline, fleet, engineSessions) {
688
+ const p = msg.params ?? {};
689
+ const erId = p.taskId ?? p.er_id;
690
+ if (!erId) {
691
+ console.warn('[sam] task/budget-request received without taskId — ignoring');
692
+ return;
693
+ }
694
+ const session = engineSessions.get(erId);
695
+ if (!session) {
696
+ await fleet.fleetSend(fleet.bus, fleet.transport, {
697
+ to: msg.from ?? 'jessie',
698
+ method: 'task/status',
699
+ params: {
700
+ taskId: erId,
701
+ agentId: 'sam',
702
+ status: 'no_session',
703
+ details: `No active engine session for ${erId}`,
704
+ },
705
+ correlationId: msg.id,
706
+ });
707
+ return;
708
+ }
709
+ try {
710
+ const usage = await session.getUsage();
711
+ await fleet.fleetSend(fleet.bus, fleet.transport, {
712
+ to: msg.from ?? 'jessie',
713
+ method: 'task/status',
714
+ params: {
715
+ taskId: erId,
716
+ agentId: 'sam',
717
+ status: 'budget_report',
718
+ usage: {
719
+ totalInputTokens: usage.totalInputTokens,
720
+ totalOutputTokens: usage.totalOutputTokens,
721
+ totalCostUsd: usage.totalCostUsdCents / 100,
722
+ turns: usage.turnCount,
723
+ },
724
+ },
725
+ correlationId: msg.id,
726
+ });
727
+ }
728
+ catch (err) {
729
+ console.error(`[sam] Failed to handle task/budget-request for ${erId}: ${err}`);
730
+ }
731
+ }
732
+ async function handleEscalation(msg, pipeline, fleet, engineSessions) {
733
+ const p = msg.params ?? {};
734
+ const erId = p.taskId ?? p.er_id;
735
+ const action = p.action ?? 'terminate';
736
+ const reason = p.reason ?? 'Escalation from fleet';
737
+ if (!erId) {
738
+ console.warn('[sam] task/escalation received without taskId — ignoring');
739
+ return;
740
+ }
741
+ const session = engineSessions.get(erId);
742
+ if (!session) {
743
+ console.warn(`[sam] task/escalation for ${erId} but no active session`);
744
+ return;
745
+ }
746
+ try {
747
+ if (action === 'terminate') {
748
+ await session.terminate();
749
+ engineSessions.delete(erId);
750
+ await pipeline.handleRequest({
751
+ action: 'update',
752
+ er_id: erId,
753
+ blocker: `ESCALATION TERMINATED: ${reason}`,
754
+ notes: `Engine terminated via fleet escalation from ${msg.from}: ${reason}`,
755
+ }).catch(() => { });
756
+ await fleet.fleetSend(fleet.bus, fleet.transport, {
757
+ to: msg.from ?? 'jessie',
758
+ method: 'task/complete',
759
+ params: {
760
+ taskId: erId,
761
+ success: false,
762
+ result: `Terminated via escalation: ${reason}`,
763
+ status: 'terminated',
764
+ },
765
+ correlationId: msg.id,
766
+ });
767
+ }
768
+ console.log(`[sam] Escalation handled for ${erId}: ${action} — ${reason}`);
769
+ }
770
+ catch (err) {
771
+ console.error(`[sam] Failed to handle task/escalation for ${erId}: ${err}`);
772
+ }
773
+ }
774
+ async function handleRedirect(msg, pipeline, fleet, engineSessions) {
775
+ const p = msg.params ?? {};
776
+ const erId = p.taskId ?? p.er_id;
777
+ const newGuidance = p.guidance ?? p.instructions ?? 'Redirect received — adjust approach.';
778
+ if (!erId) {
779
+ console.warn('[sam] task/redirect received without taskId — ignoring');
780
+ return;
781
+ }
782
+ const session = engineSessions.get(erId);
783
+ if (!session) {
784
+ console.warn(`[sam] task/redirect for ${erId} but no active session`);
785
+ return;
786
+ }
787
+ try {
788
+ const result = await session.sendTurn(newGuidance);
789
+ await pipeline.handleRequest({
790
+ action: 'update',
791
+ er_id: erId,
792
+ notes: `[redirect] from ${msg.from}: ${newGuidance.slice(0, 100)}`,
793
+ }).catch(() => { });
794
+ await fleet.fleetSend(fleet.bus, fleet.transport, {
795
+ to: msg.from ?? 'jessie',
796
+ method: 'task/status',
797
+ params: {
798
+ taskId: erId,
799
+ agentId: 'sam',
800
+ status: result.success ? 'completed' : 'in_progress',
801
+ details: `Redirect processed: ${result.iterations} iterations, ${result.toolCalls.length} tool calls`,
802
+ success: result.success,
803
+ },
804
+ correlationId: msg.id,
805
+ });
806
+ console.log(`[sam] Redirect processed for ${erId} from ${msg.from}`);
807
+ }
808
+ catch (err) {
809
+ console.error(`[sam] Failed to handle task/redirect for ${erId}: ${err}`);
810
+ }
811
+ }
583
812
  //# sourceMappingURL=plugin.js.map