@autopilot-agent/core 0.1.0 → 0.2.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 (58) hide show
  1. package/README.md +55 -3
  2. package/dist/experimental/index.js +62 -59
  3. package/dist/experimental/index.mjs +62 -59
  4. package/dist/index.d.ts +14 -6
  5. package/dist/index.js +202 -198
  6. package/dist/index.mjs +202 -198
  7. package/dist/internal/agent-runtime.d.ts +13 -1
  8. package/dist/internal/kernel/completion-policy.d.ts +4 -0
  9. package/dist/internal/kernel/run-context.d.ts +8 -0
  10. package/dist/internal/tool-scheduler.d.ts +1 -0
  11. package/dist/internal/tools/builtins/open-preview-tool.d.ts +18 -0
  12. package/dist/internal/tools/builtins/run-command-tool.d.ts +2 -2
  13. package/dist/internal/tools/builtins/start-background-job-tool.d.ts +9 -0
  14. package/dist/internal/tools/builtins/todo-write-tool.d.ts +14 -0
  15. package/dist/internal/tools/mcp-runtime.d.ts +5 -0
  16. package/dist/internal/tools/normalized-tool-input.d.ts +1 -0
  17. package/dist/internal/tools/permissions/command-policy.d.ts +11 -0
  18. package/dist/internal/tools/permissions/external-execution-policy.d.ts +14 -0
  19. package/dist/internal/tools/permissions/mutation-policy.d.ts +7 -0
  20. package/dist/internal/tools/permissions/path-access-policy.d.ts +13 -0
  21. package/dist/internal/tools/permissions/workspace-path.d.ts +5 -0
  22. package/dist/internal/tools/policy-engine.d.ts +1 -0
  23. package/dist/internal/tools/process-utils.d.ts +11 -0
  24. package/dist/internal/tools/sandbox-policy-resolver.d.ts +2 -0
  25. package/dist/internal/tools/tool-executor.d.ts +2 -1
  26. package/dist/internal/tools/types.d.ts +66 -2
  27. package/dist/runtime/adapters/memory/memory-approval-store.d.ts +39 -0
  28. package/dist/runtime/adapters/memory/memory-file-mutation-store.d.ts +1 -1
  29. package/dist/runtime/application/approval-service.d.ts +69 -3
  30. package/dist/runtime/application/job-execution-facts.d.ts +2 -0
  31. package/dist/runtime/application/job-service-ownership.d.ts +5 -0
  32. package/dist/runtime/application/job-service.d.ts +9 -0
  33. package/dist/runtime/application/turn/turn-conversation-builder.d.ts +3 -3
  34. package/dist/runtime/application/turn/turn-runtime-config-resolver.d.ts +2 -2
  35. package/dist/runtime/application/undo-service.d.ts +4 -0
  36. package/dist/runtime/bootstrap/runtime-bootstrap-service.d.ts +2 -1
  37. package/dist/runtime/config/autopilot-settings.d.ts +9 -0
  38. package/dist/runtime/config/runtime-limits.d.ts +2 -4
  39. package/dist/runtime/domain/approval.d.ts +18 -0
  40. package/dist/runtime/domain/external-execution.d.ts +42 -0
  41. package/dist/runtime/domain/external-permissions.d.ts +32 -0
  42. package/dist/runtime/domain/frozen-run-config.d.ts +2 -0
  43. package/dist/runtime/domain/index.d.ts +6 -2
  44. package/dist/runtime/domain/job-service-url.d.ts +3 -0
  45. package/dist/runtime/domain/job.d.ts +18 -0
  46. package/dist/runtime/domain/sandbox-policy.d.ts +30 -0
  47. package/dist/runtime/domain/todo.d.ts +4 -0
  48. package/dist/runtime/ports/approval-store.d.ts +39 -1
  49. package/dist/runtime/ports/external-permission-projector.d.ts +14 -0
  50. package/dist/runtime/ports/file-mutation-store.d.ts +1 -1
  51. package/dist/runtime/ports/host-mutation-protection.d.ts +7 -0
  52. package/dist/runtime/ports/index.d.ts +7 -1
  53. package/dist/runtime/ports/sandbox-port.d.ts +1 -0
  54. package/dist/runtime/protocol/index.d.ts +1 -0
  55. package/dist/runtime/protocol/recoverable-turn-view.d.ts +1 -1
  56. package/dist/runtime/protocol/run-config.d.ts +3 -0
  57. package/dist/runtime/protocol/work-preview-capability.d.ts +23 -0
  58. package/package.json +1 -1
@@ -1,9 +1,11 @@
1
1
  import { type ChildProcess } from "node:child_process";
2
2
  import type { Job, JobListView, JobOutputView, JobPollResult, JobReadView, JobView, PollJobInput, StartJobInput } from "../domain";
3
+ import { type ManagedExecutionControl } from "../domain/sandbox-policy";
3
4
  import { type JobOwnerProbe, type JobStore, type ProjectStore, type SandboxPort, type SessionStore } from "../ports";
4
5
  import { AgentRuntimeError as RuntimeError } from "../protocol";
5
6
  import { BoundedOutputBuffer } from "../../internal/tools/process-utils";
6
7
  import { JobOutputProjector } from "./job-output-projection";
8
+ import { type JobServiceOwnershipProbe } from "./job-service-ownership";
7
9
  export interface JobService {
8
10
  start(input: StartJobInput): Promise<Job>;
9
11
  poll(input: PollJobInput): Promise<JobPollResult>;
@@ -42,6 +44,10 @@ export interface SessionJobService {
42
44
  jobId: string;
43
45
  source: "agent" | "host";
44
46
  }): Promise<JobView>;
47
+ verifyServiceOwnership(input: {
48
+ jobId: string;
49
+ serviceUrl: string;
50
+ }): Promise<"owned" | "unowned" | "unverifiable">;
45
51
  }
46
52
  export interface InternalJobService extends JobService {
47
53
  withSessionLock<T>(sessionId: string, operation: () => Promise<T>): Promise<T>;
@@ -54,6 +60,7 @@ export interface CreateJobServiceOptions {
54
60
  runtimeInstanceId?: string;
55
61
  hostProcessId?: number;
56
62
  now?: () => number;
63
+ serviceProbe?: JobServiceOwnershipProbe;
57
64
  }
58
65
  interface ActiveJob {
59
66
  child: ChildProcess;
@@ -68,6 +75,7 @@ interface ActiveJob {
68
75
  transitionTail: Promise<void>;
69
76
  closeResult?: {
70
77
  exitCode: number | null;
78
+ signal?: NodeJS.Signals | null;
71
79
  };
72
80
  initialized: boolean;
73
81
  projectorFlushed: boolean;
@@ -78,6 +86,7 @@ interface ActiveJob {
78
86
  sandboxExecution?: {
79
87
  port: SandboxPort;
80
88
  executionId: string;
89
+ control?: ManagedExecutionControl;
81
90
  };
82
91
  }
83
92
  export declare class ProcessManager {
@@ -5,9 +5,9 @@ import type { RuntimePorts } from "../../ports";
5
5
  export interface TurnConversationBuilder {
6
6
  buildInitialMessages(input: StartTurnInput): AgentMessage[];
7
7
  refreshContext(capabilities: RunConfig, content: string | undefined): Promise<void>;
8
- getLatestCompletedTurn(sessionId: string): Promise<Turn | undefined>;
9
- buildCanonicalSessionMessages(latestCompleted: Turn | undefined, initial: AgentMessage[]): Promise<AgentMessage[]>;
10
- inheritPreviousUsageAnchor(sessionId: string, latestCompleted: Turn | undefined, canonical: AgentMessage[], initial: AgentMessage[]): Promise<AgentCheckpoint["usageAnchor"]>;
8
+ getConversationBaselineTurn(sessionId: string): Promise<Turn | undefined>;
9
+ buildCanonicalSessionMessages(baseline: Turn | undefined, initial: AgentMessage[]): Promise<AgentMessage[]>;
10
+ inheritPreviousUsageAnchor(sessionId: string, baseline: Turn | undefined, canonical: AgentMessage[], initial: AgentMessage[]): Promise<AgentCheckpoint["usageAnchor"]>;
11
11
  injectTodoSnapshot(sessionId: string, todoChainId: string, messages: AgentMessage[]): Promise<AgentMessage[]>;
12
12
  }
13
13
  export declare function createTurnConversationBuilder(ports: RuntimePorts): TurnConversationBuilder;
@@ -2,7 +2,7 @@ import type { AgentOptions } from "../../../internal/agent-runtime";
2
2
  import type { ModelSampler } from "../../../internal/kernel/model-sampler";
3
3
  import type { ResolvedCredential, FrozenRunConfig } from "../../domain";
4
4
  import type { RuntimePorts } from "../../ports";
5
- import type { ApprovalService } from "../approval-service";
5
+ import type { ApprovalService, InternalApprovalService } from "../approval-service";
6
6
  import type { InputInboxService } from "../input-inbox-service";
7
7
  import type { JobService } from "../job-service";
8
8
  import type { RunConfig } from "../../protocol";
@@ -11,7 +11,7 @@ import type { UserQuestionService } from "../user-question-service";
11
11
  export interface TurnRuntimeConfigResolverDependencies {
12
12
  ports: RuntimePorts;
13
13
  defaultRunConfig: RunConfig;
14
- approvalService?: ApprovalService;
14
+ approvalService?: ApprovalService & Partial<InternalApprovalService>;
15
15
  inputInboxService?: InputInboxService;
16
16
  jobService?: JobService;
17
17
  userQuestionService?: UserQuestionService;
@@ -1,5 +1,9 @@
1
1
  import type { FileMutation } from "../domain";
2
2
  import type { RuntimePorts } from "../ports";
3
+ export declare function resolveFileMutationTarget(workspaceRoot: string, mutationPath: string): Promise<{
4
+ absolutePath: string;
5
+ exists: boolean;
6
+ }>;
3
7
  export interface UndoPreview {
4
8
  status: "available" | "unavailable";
5
9
  turnId?: string;
@@ -1,7 +1,7 @@
1
1
  import type { AgentRuntime } from "../public";
2
2
  import type { RuntimePorts } from "../ports";
3
3
  import type { WorkspaceAdapter } from "../ports/workspace-adapter";
4
- import type { RunConfig, McpCapability, WebCapability } from "../protocol";
4
+ import type { RunConfig, McpCapability, WebCapability, WorkPreviewCapability } from "../protocol";
5
5
  import type { AgentContextSnapshot } from "../../internal/agent-context";
6
6
  import type { AgentSkillsCapability } from "../../internal/tools/builtins/skill-tool";
7
7
  import type { AgentInputInboxCapability } from "../../internal/agent-runtime";
@@ -17,6 +17,7 @@ export interface CapabilityLoader {
17
17
  loadSkills?(workspaceRoot: string): Promise<AgentSkillsCapability | undefined> | AgentSkillsCapability | undefined;
18
18
  loadContext?(workspaceRoot: string, query?: string): Promise<AgentContextSnapshot> | AgentContextSnapshot;
19
19
  loadInputInbox?(workspaceRoot: string): Promise<AgentInputInboxCapability> | AgentInputInboxCapability;
20
+ loadWorkPreview?(workspaceRoot: string): Promise<WorkPreviewCapability | undefined> | WorkPreviewCapability | undefined;
20
21
  }
21
22
  export interface BootstrapEvent {
22
23
  phase: "safe" | "trust" | "runtime" | "ready" | "error";
@@ -43,7 +43,14 @@ export interface ResolvedSandboxSettings {
43
43
  deniedRead: readonly string[];
44
44
  deniedWrite: readonly string[];
45
45
  }
46
+ export interface ResolvedExternalPermissionSettings {
47
+ allow: readonly string[];
48
+ deny: readonly string[];
49
+ ask: readonly string[];
50
+ readonly restricted?: boolean;
51
+ }
46
52
  export interface ResolvedAutopilotSettings {
53
+ maxTurns?: number;
47
54
  modelRef?: ModelRef;
48
55
  visionModelRef?: ModelRef | false;
49
56
  modelSource?: "environment" | "settings";
@@ -58,7 +65,9 @@ export interface ResolvedAutopilotSettings {
58
65
  webSearchDisabled?: boolean;
59
66
  rag: ResolvedRagSettings;
60
67
  sandbox: ResolvedSandboxSettings;
68
+ permissions: ResolvedExternalPermissionSettings;
61
69
  diagnostics: readonly SettingsDiagnostic[];
62
70
  }
63
71
  export declare function normalizeProviderBaseUrl(value: unknown): string | undefined;
72
+ export declare function isExternalPermissionDiagnostic(diagnostic: SettingsDiagnostic): boolean;
64
73
  export declare function resolveAutopilotSettings(sources: readonly AutopilotSettingsSource[]): ResolvedAutopilotSettings;
@@ -1,6 +1,6 @@
1
1
  export interface LimitConfig {
2
2
  defaultValue?: number;
3
- hardLimit: number;
3
+ hardLimit?: number;
4
4
  requestOverride?: number;
5
5
  }
6
6
  export interface ResolvedAgentRuntimeLimits {
@@ -8,11 +8,10 @@ export interface ResolvedAgentRuntimeLimits {
8
8
  maxToolRetries: number;
9
9
  }
10
10
  export interface AgentRuntimeSafetyLimits {
11
- maxDurationMs: number;
11
+ maxDurationMs?: number;
12
12
  maxTotalTokens?: number;
13
13
  }
14
14
  export interface AgentRuntimeSafetyHardLimits {
15
- maxDurationMs: number;
16
15
  maxTotalTokens: number;
17
16
  }
18
17
  export declare function resolveLimitConfig(config: LimitConfig & {
@@ -24,7 +23,6 @@ export declare const AGENT_RUNTIME_LIMIT_DEFAULTS: {
24
23
  readonly maxToolRetries: number;
25
24
  };
26
25
  export declare const AGENT_RUNTIME_LIMIT_HARD_LIMITS: {
27
- readonly maxSteps: 100;
28
26
  readonly maxToolRetries: 10;
29
27
  };
30
28
  export declare const AGENT_RUNTIME_SAFETY_DEFAULTS: AgentRuntimeSafetyLimits;
@@ -1,4 +1,5 @@
1
1
  import type { ToolApprovalDecision, ToolRisk } from "../../internal/tools/types";
2
+ import type { ExternalExecutionTarget } from "./external-execution";
2
3
  export interface ApprovalDecision {
3
4
  approvalId: string;
4
5
  turnId: string;
@@ -6,9 +7,21 @@ export interface ApprovalDecision {
6
7
  callId: string;
7
8
  toolName: string;
8
9
  normalizedInputHash: string;
10
+ constraint?: string;
11
+ expiresAt?: string;
9
12
  decision: ToolApprovalDecision;
13
+ projection?: "synced" | "pending";
10
14
  createdAt: string;
11
15
  }
16
+ export interface TaskFileTarget {
17
+ path: string;
18
+ operation: "create" | "edit";
19
+ }
20
+ export declare const TASK_FILE_SET_CONSTRAINT = "task-files:v1";
21
+ export declare const TASK_EXTERNAL_FILE_SET_CONSTRAINT = "task-ext-files:v1";
22
+ export declare function isTaskFileSetConstraint(constraint: string | undefined): boolean;
23
+ export declare function isExternalTaskFileSetConstraint(constraint: string | undefined): boolean;
24
+ export declare function isTaskFileSetDeclarationConstraint(constraint: string | undefined): boolean;
12
25
  export interface PersistentGrant {
13
26
  scope: "allow_session" | "allow_workspace";
14
27
  workspaceRoot?: string;
@@ -16,6 +29,11 @@ export interface PersistentGrant {
16
29
  toolName: string;
17
30
  constraint: string;
18
31
  risk?: ToolRisk;
32
+ externalRule?: string;
33
+ executionTarget?: ExternalExecutionTarget;
34
+ projection?: "synced" | "pending";
35
+ turnId?: string;
36
+ taskFiles?: TaskFileTarget[];
19
37
  createdAt: string;
20
38
  }
21
39
  export interface SubmitApprovalInput {
@@ -0,0 +1,42 @@
1
+ export declare const EXTERNAL_EXECUTION_CONSTRAINT_PREFIX = "ext-exec-file:v1:";
2
+ export interface ExternalExecutionTarget {
3
+ schemaVersion: 1;
4
+ canonicalTarget: string;
5
+ canonicalWorkspace: string;
6
+ scope: "file";
7
+ operation: "write";
8
+ commandDigest: string;
9
+ }
10
+ export interface ExternalExecutionApproval {
11
+ recordType: "external_execution_request";
12
+ sessionId: string;
13
+ turnId: string;
14
+ approvalId: string;
15
+ callId: string;
16
+ toolName: string;
17
+ normalizedInputHash: string;
18
+ constraint: string;
19
+ expiresAt: string;
20
+ target: ExternalExecutionTarget;
21
+ }
22
+ export interface ExternalExecutionAuthorization {
23
+ lifetime: "allow_once" | "allow_session" | "allow_workspace";
24
+ sessionId: string;
25
+ canonicalWorkspace: string;
26
+ approvalId?: string;
27
+ expiresAt?: string;
28
+ }
29
+ export interface ExternalWriteCapability extends ExternalExecutionAuthorization {
30
+ schemaVersion: 1;
31
+ target: ExternalExecutionTarget;
32
+ toolName: string;
33
+ callId: string;
34
+ normalizedInputHash: string;
35
+ executionId: string;
36
+ constraint: string;
37
+ capabilityDigest: string;
38
+ }
39
+ export declare function comparablePath(value: string): string;
40
+ export declare function computeExternalExecutionConstraint(toolName: string, target: ExternalExecutionTarget): string;
41
+ export declare function isExternalExecutionConstraint(value: string | undefined): boolean;
42
+ export declare function matchesExternalExecutionTarget(toolName: string, constraint: string, target: ExternalExecutionTarget | undefined): boolean;
@@ -0,0 +1,32 @@
1
+ export declare const EXTERNAL_FILE_CONSTRAINT_PREFIX = "ext-file:";
2
+ export type ExternalFileOperation = "Read" | "Write" | "Edit";
3
+ export interface ParsedExternalPermissionRule {
4
+ operation: ExternalFileOperation;
5
+ target: string;
6
+ recursive: boolean;
7
+ }
8
+ export declare function isExternalFileConstraint(constraint: string | undefined): boolean;
9
+ export declare function externalFileConstraintTarget(constraint: string | undefined): string | undefined;
10
+ export declare function formatExternalFileRule(toolName: string, constraint: string): string;
11
+ export interface ExternalFileApproval {
12
+ recordType: "external_file_request";
13
+ sessionId: string;
14
+ turnId: string;
15
+ approvalId: string;
16
+ callId: string;
17
+ toolName: string;
18
+ normalizedInputHash: string;
19
+ constraint: string;
20
+ expiresAt: string;
21
+ }
22
+ export declare function normalizeComparablePath(target: string): string;
23
+ export declare function parseExternalPermissionRule(rule: string): ParsedExternalPermissionRule | null;
24
+ export declare function isValidExternalPermissionRule(rule: string): boolean;
25
+ export declare function externalRuleCoversRule(denyRule: string, grantRule: string): boolean;
26
+ export interface ExternalRestrictionSnapshot {
27
+ allow: readonly string[];
28
+ deny: readonly string[];
29
+ ask?: readonly string[];
30
+ restricted?: boolean;
31
+ }
32
+ export declare function classifyExternalRestriction(snapshot: ExternalRestrictionSnapshot, toolName: string, constraint: string): "allow" | "ask" | "deny";
@@ -10,6 +10,7 @@ export interface FrozenRunConfig {
10
10
  workContextVersion?: 1;
11
11
  capabilityCeiling?: import("./product-mode").CapabilityCeiling;
12
12
  chatAttachmentGrants?: readonly import("../protocol/chat-capability").ChatAttachmentGrant[];
13
+ workPreviewEnabled?: boolean;
13
14
  modelRef?: ModelRef;
14
15
  reasoningProfile?: ReasoningProfile;
15
16
  credentialRef?: CredentialRef;
@@ -29,4 +30,5 @@ export interface FrozenRunConfig {
29
30
  sandboxTempRoot?: string;
30
31
  sandboxPolicyDigest?: string;
31
32
  sandboxPolicyVersion?: 1;
33
+ processExecution?: "sandbox" | "host";
32
34
  }
@@ -3,13 +3,17 @@ export type { ModelRef, ReasoningEffort } from "./model-ref";
3
3
  export type { ReasoningProfile } from "./reasoning-profile";
4
4
  export type { SessionRunConfig } from "./session-run-config";
5
5
  export type { FrozenRunConfig } from "./frozen-run-config";
6
- export type { SandboxMode, SandboxEnforcement, SandboxPolicy, SandboxCapabilityReport, SandboxExecutionRequest, SandboxPreparedCommand, SandboxErrorCode } from "./sandbox-policy";
6
+ export type { SandboxMode, SandboxEnforcement, SandboxPolicy, SandboxCapabilityReport, SandboxExecutionRequest, SandboxPreparedCommand, SandboxErrorCode, ManagedExecutionControl, ManagedExecutionChannel } from "./sandbox-policy";
7
+ export type { ExternalExecutionTarget, ExternalExecutionApproval, ExternalExecutionAuthorization, ExternalWriteCapability } from "./external-execution";
7
8
  export { SANDBOX_ERROR_CODES, SANDBOX_POLICY_VERSION, isSandboxPolicyDenialCode, isSandboxAvailabilityFailureCode, resolveSandboxMode, computeSandboxPolicyDigest } from "./sandbox-policy";
8
9
  export type { Turn, TurnStatus } from "./turn";
9
10
  export { JOB_RECORD_VERSION } from "./job";
10
- export type { Job, JobStatus, JobOwner, JobOwnerLiveness, JobControlState, JobLastControl, JobView, JobListView, JobReadView, JobOutputSnapshot, JobSafeOutputSnapshot, JobSafeOutputStreamSnapshot, JobSafeOutputStreamView, JobOutputView, JobSandboxSummary, StartJobInput, PollJobInput, JobPollResult } from "./job";
11
+ export { normalizeJobServiceUrl, jobServicePort, sameServiceOrigin } from "./job-service-url";
12
+ export type { Job, JobStatus, JobOwner, JobOwnerLiveness, JobControlState, JobExecutionFacts, JobLastControl, JobView, JobListView, JobReadView, JobOutputSnapshot, JobSafeOutputSnapshot, JobSafeOutputStreamSnapshot, JobSafeOutputStreamView, JobOutputView, JobSandboxSummary, StartJobInput, PollJobInput, JobPollResult } from "./job";
11
13
  export type { FileMutation, FileMutationOperation, FileMutationStatus, PrepareFileMutationInput, UndoTransaction } from "./file-mutation";
12
14
  export type { Project, CreateProjectInput } from "./project";
15
+ export { EXTERNAL_FILE_CONSTRAINT_PREFIX, isExternalFileConstraint, externalFileConstraintTarget, formatExternalFileRule, parseExternalPermissionRule, isValidExternalPermissionRule, externalRuleCoversRule } from "./external-permissions";
16
+ export type { ExternalFileOperation, ParsedExternalPermissionRule, ExternalFileApproval } from "./external-permissions";
13
17
  export type { ApprovalDecision, PersistentGrant, SubmitApprovalInput, FindPersistentGrantInput, } from "./approval";
14
18
  export type { UserQuestionOption, UserQuestionItem, UserQuestionAnswerItem, UserQuestionRequest, UserQuestionAnswer, StoredUserQuestion, } from "./user-question";
15
19
  export type { TodoStatus, TodoItem, TodoCounts, TodoSnapshot, TodoWriteResult, } from "./todo";
@@ -0,0 +1,3 @@
1
+ export declare function normalizeJobServiceUrl(value: string): string | undefined;
2
+ export declare function jobServicePort(serviceUrl: string): number | undefined;
3
+ export declare function sameServiceOrigin(left: string, right: string): boolean;
@@ -32,6 +32,12 @@ export interface JobOutputView {
32
32
  stderr: JobSafeOutputStreamView;
33
33
  }
34
34
  export type JobControlState = "owned" | "foreign_owner" | "owner_unknown" | "terminal";
35
+ export interface JobExecutionFacts {
36
+ phase: "wrapper_spawn_failed" | "wrapper_running" | "wrapper_exit" | "target_spawn_error_reported" | "host_spawn_failed" | "host_running";
37
+ targetState: "unknown" | "not_started";
38
+ signal?: string;
39
+ win32Code?: string;
40
+ }
35
41
  export interface JobLastControl {
36
42
  action: "stop";
37
43
  source: "agent" | "host" | "legacy_api";
@@ -47,11 +53,13 @@ export interface JobView {
47
53
  updatedAt: number;
48
54
  finishedAt?: number;
49
55
  exitCode?: number;
56
+ execution?: JobExecutionFacts;
50
57
  failureCode?: Job["failureCode"];
51
58
  stdoutBytes: number;
52
59
  stderrBytes: number;
53
60
  outputTruncated: boolean;
54
61
  lastControl?: JobLastControl;
62
+ serviceUrl?: string;
55
63
  }
56
64
  export interface JobListView {
57
65
  jobs: JobView[];
@@ -80,6 +88,7 @@ export interface JobSandboxSummary {
80
88
  mode: SandboxMode;
81
89
  policyDigest: string;
82
90
  policyVersion: number;
91
+ execution?: "host";
83
92
  }
84
93
  export interface Job {
85
94
  jobRecordVersion?: typeof JOB_RECORD_VERSION;
@@ -97,13 +106,17 @@ export interface Job {
97
106
  updatedAt: number;
98
107
  finishedAt?: number;
99
108
  exitCode?: number;
109
+ execution?: JobExecutionFacts;
100
110
  failureCode?: "JOB_SPAWN_FAILED" | "JOB_STOP_FAILED" | "JOB_STOP_TIMEOUT" | "JOB_STORAGE_FAILED";
101
111
  lastControl?: JobLastControl;
102
112
  output: JobOutputSnapshot;
103
113
  safeOutput?: JobSafeOutputSnapshot;
104
114
  sandbox?: JobSandboxSummary;
115
+ serviceUrl?: string;
105
116
  }
106
117
  export interface StartJobInput {
118
+ externalWriteTarget?: string;
119
+ toolCallId?: string;
107
120
  signal?: AbortSignal;
108
121
  workspaceId: string;
109
122
  workspaceRoot: string;
@@ -112,9 +125,14 @@ export interface StartJobInput {
112
125
  program: string;
113
126
  args: string[];
114
127
  cwd: string;
128
+ serviceUrl?: string;
115
129
  sandbox: {
130
+ execution?: "sandboxed";
116
131
  port: SandboxPort;
117
132
  policy: SandboxPolicy;
133
+ } | {
134
+ execution: "host";
135
+ policy: SandboxPolicy;
118
136
  };
119
137
  }
120
138
  export interface PollJobInput {
@@ -1,3 +1,4 @@
1
+ import type { ExternalWriteCapability } from "./external-execution";
1
2
  export type SandboxMode = "read-only" | "workspace-write" | "danger-full-access";
2
3
  export type SandboxEnforcement = "full" | "partial" | "unavailable";
3
4
  export interface SandboxPolicy {
@@ -7,6 +8,7 @@ export interface SandboxPolicy {
7
8
  allowedDomains: readonly string[];
8
9
  deniedRead: readonly string[];
9
10
  deniedWrite: readonly string[];
11
+ externalWriteCapability?: ExternalWriteCapability;
10
12
  }
11
13
  export interface SandboxCapabilityReport {
12
14
  platform: "macos" | "windows" | "linux" | "unknown";
@@ -23,6 +25,19 @@ export interface SandboxExecutionRequest {
23
25
  args: readonly string[];
24
26
  cwd: string;
25
27
  policy: SandboxPolicy;
28
+ managed?: boolean;
29
+ }
30
+ export interface ManagedExecutionChannel {
31
+ incoming: AsyncIterable<Uint8Array>;
32
+ send(bytes: Uint8Array): void;
33
+ close(): void;
34
+ }
35
+ export interface ManagedExecutionControl {
36
+ protocolVersion: 1;
37
+ bind(channel: ManagedExecutionChannel): void;
38
+ stop(): Promise<{
39
+ evidence: "container_empty";
40
+ }>;
26
41
  }
27
42
  export interface SandboxPreparedCommand {
28
43
  executionId: string;
@@ -30,6 +45,7 @@ export interface SandboxPreparedCommand {
30
45
  args: readonly string[];
31
46
  env: Record<string, string>;
32
47
  enforcement: SandboxEnforcement;
48
+ control?: ManagedExecutionControl;
33
49
  }
34
50
  export declare const SANDBOX_ERROR_CODES: {
35
51
  readonly UNAVAILABLE: "SANDBOX_UNAVAILABLE";
@@ -43,9 +59,23 @@ export type SandboxErrorCode = (typeof SANDBOX_ERROR_CODES)[keyof typeof SANDBOX
43
59
  export declare function isSandboxPolicyDenialCode(code: string): boolean;
44
60
  export declare function isSandboxAvailabilityFailureCode(code: string): boolean;
45
61
  export declare const SANDBOX_POLICY_VERSION = 1;
62
+ export declare const NO_SANDBOX_EXEC_CONSTRAINT = "no-sandbox-exec:v1";
63
+ export declare function isNoSandboxExecConstraint(constraint: string | undefined): boolean;
64
+ export interface SandboxDegradeApproval {
65
+ recordType: "sandbox_degrade_request";
66
+ sessionId: string;
67
+ turnId: string;
68
+ approvalId: string;
69
+ callId: string;
70
+ toolName: string;
71
+ normalizedInputHash: string;
72
+ constraint: string;
73
+ expiresAt: string;
74
+ }
46
75
  export declare function resolveSandboxMode(value: unknown): SandboxMode;
47
76
  export declare function computeSandboxPolicyDigest(input: {
48
77
  mode: SandboxMode;
49
78
  workspaceRoot?: string;
50
79
  tempRoot?: string;
80
+ externalWriteCapability?: ExternalWriteCapability;
51
81
  }): string;
@@ -17,4 +17,8 @@ export interface TodoSnapshot {
17
17
  export interface TodoWriteResult {
18
18
  todos: TodoItem[];
19
19
  counts: TodoCounts;
20
+ fileTargets?: Array<{
21
+ path: string;
22
+ operation: "create" | "edit";
23
+ }>;
20
24
  }
@@ -1,5 +1,8 @@
1
1
  import type { ToolRisk } from "../../internal/tools/types";
2
- import type { ApprovalDecision, PersistentGrant } from "../domain/approval";
2
+ import type { ApprovalDecision, PersistentGrant, TaskFileTarget } from "../domain/approval";
3
+ import type { ExternalExecutionApproval, ExternalExecutionTarget } from "../domain/external-execution";
4
+ import type { ExternalFileApproval } from "../domain/external-permissions";
5
+ import type { SandboxDegradeApproval } from "../domain/sandbox-policy";
3
6
  export interface GetApprovalDecisionInput {
4
7
  sessionId: string;
5
8
  turnId: string;
@@ -18,8 +21,36 @@ export interface SavePersistentGrantInput {
18
21
  toolName: string;
19
22
  constraint: string;
20
23
  risk?: ToolRisk;
24
+ externalRule?: string;
25
+ executionTarget?: ExternalExecutionTarget;
26
+ turnId?: string;
27
+ taskFiles?: TaskFileTarget[];
28
+ projection?: "synced" | "pending";
21
29
  }
22
30
  export interface ApprovalStore {
31
+ saveExecutionApproval?(request: ExternalExecutionApproval): Promise<boolean>;
32
+ getExecutionApproval?(input: GetApprovalDecisionInput): Promise<ExternalExecutionApproval | null>;
33
+ consumeExecutionApproval?(input: GetApprovalDecisionInput & {
34
+ constraint: string;
35
+ callId: string;
36
+ normalizedInputHash: string;
37
+ now: string;
38
+ }): Promise<boolean>;
39
+ saveFileApproval?(request: ExternalFileApproval): Promise<boolean>;
40
+ getFileApproval?(input: GetApprovalDecisionInput): Promise<ExternalFileApproval | null>;
41
+ consumeFileApproval?(input: GetApprovalDecisionInput & {
42
+ constraint: string;
43
+ callId: string;
44
+ normalizedInputHash: string;
45
+ now: string;
46
+ }): Promise<boolean>;
47
+ saveDegradeApproval?(request: SandboxDegradeApproval): Promise<boolean>;
48
+ consumeDegradeApproval?(input: GetApprovalDecisionInput & {
49
+ constraint: string;
50
+ callId: string;
51
+ normalizedInputHash: string;
52
+ now: string;
53
+ }): Promise<boolean>;
23
54
  getDecision(input: GetApprovalDecisionInput): Promise<ApprovalDecision | null>;
24
55
  saveDecision(decision: ApprovalDecision): Promise<boolean>;
25
56
  getPersistentGrant(input: GetPersistentGrantInput): Promise<PersistentGrant | null>;
@@ -28,4 +59,11 @@ export interface ApprovalStore {
28
59
  }): Promise<PersistentGrant>;
29
60
  deletePersistentGrant(input: GetPersistentGrantInput): Promise<boolean>;
30
61
  deleteBySession(sessionId: string): Promise<void>;
62
+ listPersistentGrants(input: {
63
+ workspaceRoot?: string;
64
+ sessionId?: string;
65
+ }): Promise<PersistentGrant[]>;
66
+ setGrantProjection(input: GetPersistentGrantInput & {
67
+ projection: "synced" | "pending";
68
+ }): Promise<PersistentGrant | null>;
31
69
  }
@@ -0,0 +1,14 @@
1
+ export interface ExternalPermissionSnapshot {
2
+ allow: readonly string[];
3
+ deny: readonly string[];
4
+ ask?: readonly string[];
5
+ restricted?: boolean;
6
+ }
7
+ export interface ExternalPermissionProjector {
8
+ project(input: {
9
+ workspaceRoot: string;
10
+ rule: string;
11
+ action: "add" | "remove";
12
+ }): Promise<void>;
13
+ read(workspaceRoot: string): Promise<ExternalPermissionSnapshot>;
14
+ }
@@ -7,5 +7,5 @@ export interface FileMutationStore {
7
7
  saveUndoTransaction(transaction: UndoTransaction): Promise<void>;
8
8
  listUndoTransactions(sessionId: string): Promise<UndoTransaction[]>;
9
9
  deleteBySession(sessionId: string): Promise<void>;
10
- withWorkspaceLock<T>(workspaceRoot: string, operation: () => Promise<T>): Promise<T>;
10
+ withWorkspaceLock<T>(workspaceRoot: string, operation: () => Promise<T>, canonicalTargets?: readonly string[]): Promise<T>;
11
11
  }
@@ -0,0 +1,7 @@
1
+ export interface ProtectedMutationTarget {
2
+ path: string;
3
+ scope: "file" | "directory";
4
+ }
5
+ export interface HostMutationProtection {
6
+ getProtectedTargets(workspaceRoot: string): Promise<readonly ProtectedMutationTarget[]>;
7
+ }
@@ -16,12 +16,17 @@ import type { FileMutationStore } from "./file-mutation-store";
16
16
  import type { SessionResourceStore } from "./session-resource-store";
17
17
  import type { UserQuestionStore } from "./user-question-store";
18
18
  import type { SandboxPort } from "./sandbox-port";
19
- export type { SessionStore, CheckpointStore, TranscriptStore, CredentialStore, ProjectStore, EventSink, Clock, WorkspaceAdapter, WorkspaceInfo, TurnStore, ApprovalStore, InputInbox, LeaseStore, JobStore, JobOwnerProbe, FileMutationStore, SessionResourceStore, UserQuestionStore };
19
+ import type { ExternalPermissionProjector } from "./external-permission-projector";
20
+ import type { HostMutationProtection } from "./host-mutation-protection";
21
+ export type { HostMutationProtection, ProtectedMutationTarget } from "./host-mutation-protection";
22
+ export type { SessionStore, CheckpointStore, TranscriptStore, CredentialStore, ProjectStore, EventSink, Clock, WorkspaceAdapter, WorkspaceInfo, TurnStore, ApprovalStore, InputInbox, LeaseStore, JobStore, JobOwnerProbe, FileMutationStore, SessionResourceStore, UserQuestionStore, ExternalPermissionProjector };
23
+ export type { ExternalPermissionSnapshot } from "./external-permission-projector";
20
24
  export type { JobStoreWriteCondition } from "./job-store";
21
25
  export type { GetUserQuestionInput, SaveUserQuestionAnswerInput, SaveUserQuestionAnswerResult } from "./user-question-store";
22
26
  export type { SandboxPort } from "./sandbox-port";
23
27
  export { SandboxPortError, createUnavailableSandboxPort } from "./sandbox-port";
24
28
  export interface RuntimePorts {
29
+ hostMutationProtection?: HostMutationProtection;
25
30
  sessionStore: SessionStore;
26
31
  checkpointStore: CheckpointStore;
27
32
  transcriptStore: TranscriptStore;
@@ -40,4 +45,5 @@ export interface RuntimePorts {
40
45
  sessionResourceStore: SessionResourceStore;
41
46
  userQuestionStore: UserQuestionStore;
42
47
  sandboxPort: SandboxPort;
48
+ externalPermissionProjector?: ExternalPermissionProjector;
43
49
  }
@@ -4,6 +4,7 @@ export declare class SandboxPortError extends Error {
4
4
  constructor(code: string, message: string);
5
5
  }
6
6
  export interface SandboxPort {
7
+ readonly execution?: "host";
7
8
  status(): Promise<SandboxCapabilityReport>;
8
9
  setup(): Promise<SandboxCapabilityReport>;
9
10
  prepare(request: SandboxExecutionRequest): Promise<SandboxPreparedCommand>;
@@ -13,6 +13,7 @@ export type { McpCapability, McpServerConfig } from "./mcp-capability";
13
13
  export { parseMcpConfig, getMcpServerConfigHash, getMcpServerGrantConstraint } from "./mcp-capability";
14
14
  export { WebFetchCapabilityError, WebSearchCapabilityError } from "./web-capability";
15
15
  export type { WebCapability, WebFetchCapability, WebFetchCapabilityErrorCode, WebFetchResult, WebSearchCapability, WebSearchCapabilityErrorCode, WebSearchResult, WebSearchSource } from "./web-capability";
16
+ export type { WorkPreviewCapability, WorkPreviewPrepareRequest, WorkPreviewPrepareResult, WorkPreviewOpenWhen } from "./work-preview-capability";
16
17
  export type { CompactTurnInput, CompactTurnResult } from "./compact-turn-input";
17
18
  export type { AgentTerminationBudget, AgentTerminationReason, AgentTerminationView, RecoverableTurnStatus, RecoverableApprovalView, RecoverableTurnView } from "./recoverable-turn-view";
18
19
  export { sanitizeAgentTerminationView } from "./recoverable-turn-view";
@@ -1,5 +1,5 @@
1
1
  export type RecoverableTurnStatus = "running" | "awaiting_approval" | "awaiting_user_input" | "interrupted_recoverable" | "limit_reached" | "completed" | "failed";
2
- export type AgentTerminationReason = "runtime_budget" | "token_budget" | "repeated_tool_calls" | "stale_lease" | "turn_limit_reached";
2
+ export type AgentTerminationReason = "runtime_budget" | "token_budget" | "repeated_tool_calls" | "write_verification" | "stale_lease" | "turn_limit_reached";
3
3
  export interface AgentTerminationBudget {
4
4
  used: number;
5
5
  limit: number;
@@ -7,6 +7,7 @@ import type { ModelSampler } from "../../internal/kernel/model-sampler";
7
7
  import type { ModelSamplerFactory } from "../provider/model-sampler-factory";
8
8
  import type { McpCapability } from "./mcp-capability";
9
9
  import type { WebCapability } from "./web-capability";
10
+ import type { WorkPreviewCapability } from "./work-preview-capability";
10
11
  import type { SessionRunConfig } from "../domain/session-run-config";
11
12
  import type { FrozenRunConfig } from "../domain/frozen-run-config";
12
13
  import type { ModelRef } from "../domain/model-ref";
@@ -48,6 +49,8 @@ export interface RunConfig {
48
49
  rag?: RagCapability;
49
50
  web?: WebCapability;
50
51
  webLoader?: () => Promise<WebCapability | undefined>;
52
+ workPreview?: WorkPreviewCapability;
53
+ workPreviewLoader?: () => Promise<WorkPreviewCapability | undefined>;
51
54
  databaseSearch?: DatabaseSearchCapability;
52
55
  databaseSearchPolicy?: DatabaseSearchPolicy;
53
56
  ragSourcePolicy?: RagSourcePolicy;
@@ -0,0 +1,23 @@
1
+ export type WorkPreviewOpenWhen = "now" | "after_turn";
2
+ export interface WorkPreviewPrepareRequest {
3
+ url: string;
4
+ jobId?: string;
5
+ openWhen: WorkPreviewOpenWhen;
6
+ workspaceId: string;
7
+ sessionId: string;
8
+ turnId: string;
9
+ callId: string;
10
+ signal?: AbortSignal;
11
+ }
12
+ export interface WorkPreviewPrepareResult {
13
+ previewId: string;
14
+ hostLabel: string;
15
+ copyUrl: string;
16
+ openWhen: WorkPreviewOpenWhen;
17
+ state: "prepared";
18
+ jobId?: string;
19
+ autoOpen?: boolean;
20
+ }
21
+ export interface WorkPreviewCapability {
22
+ preparePreview(request: WorkPreviewPrepareRequest): Promise<WorkPreviewPrepareResult>;
23
+ }