subharness 0.0.3 → 0.0.5
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 +39 -9
- package/dist/adapters/approval-context.d.ts +2 -0
- package/dist/adapters/approval-context.js +9 -0
- package/dist/adapters/approval-context.js.map +1 -0
- package/dist/adapters/approval-lifetime.d.ts +8 -0
- package/dist/adapters/approval-lifetime.js +50 -0
- package/dist/adapters/approval-lifetime.js.map +1 -0
- package/dist/adapters/claude-approvals.d.ts +4 -0
- package/dist/adapters/claude-approvals.js +32 -0
- package/dist/adapters/claude-approvals.js.map +1 -0
- package/dist/adapters/claude-permissions.js +1 -1
- package/dist/adapters/claude-permissions.js.map +1 -1
- package/dist/adapters/claude-process.d.ts +3 -0
- package/dist/adapters/claude-process.js +11 -1
- package/dist/adapters/claude-process.js.map +1 -1
- package/dist/adapters/claude-result.d.ts +2 -0
- package/dist/adapters/claude-result.js +22 -0
- package/dist/adapters/claude-result.js.map +1 -0
- package/dist/adapters/claude.js +60 -12
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/codex-approvals.d.ts +6 -0
- package/dist/adapters/codex-approvals.js +111 -0
- package/dist/adapters/codex-approvals.js.map +1 -0
- package/dist/adapters/codex.js +36 -3
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/copilot-permissions.d.ts +26 -0
- package/dist/adapters/copilot-permissions.js +121 -0
- package/dist/adapters/copilot-permissions.js.map +1 -0
- package/dist/adapters/copilot-tools.d.ts +12 -0
- package/dist/adapters/copilot-tools.js +61 -0
- package/dist/adapters/copilot-tools.js.map +1 -0
- package/dist/adapters/copilot.d.ts +108 -0
- package/dist/adapters/copilot.js +819 -0
- package/dist/adapters/copilot.js.map +1 -0
- package/dist/adapters/cursor-cli-approvals.d.ts +2 -0
- package/dist/adapters/cursor-cli-approvals.js +83 -0
- package/dist/adapters/cursor-cli-approvals.js.map +1 -0
- package/dist/adapters/cursor-cli-model.d.ts +4 -0
- package/dist/adapters/cursor-cli-model.js +64 -0
- package/dist/adapters/cursor-cli-model.js.map +1 -0
- package/dist/adapters/cursor-cli-session.d.ts +32 -0
- package/dist/adapters/cursor-cli-session.js +316 -0
- package/dist/adapters/cursor-cli-session.js.map +1 -0
- package/dist/adapters/cursor-cli-tools.d.ts +20 -0
- package/dist/adapters/cursor-cli-tools.js +181 -0
- package/dist/adapters/cursor-cli-tools.js.map +1 -0
- package/dist/adapters/cursor-cli.d.ts +2 -0
- package/dist/adapters/cursor-cli.js +306 -0
- package/dist/adapters/cursor-cli.js.map +1 -0
- package/dist/adapters/cursor-model.d.ts +7 -0
- package/dist/adapters/cursor-model.js +67 -0
- package/dist/adapters/cursor-model.js.map +1 -0
- package/dist/adapters/cursor-rpc.d.ts +42 -0
- package/dist/adapters/cursor-rpc.js +271 -0
- package/dist/adapters/cursor-rpc.js.map +1 -0
- package/dist/adapters/cursor-session.d.ts +4 -0
- package/dist/adapters/cursor-session.js +327 -0
- package/dist/adapters/cursor-session.js.map +1 -0
- package/dist/adapters/cursor-startup.d.ts +16 -0
- package/dist/adapters/cursor-startup.js +74 -0
- package/dist/adapters/cursor-startup.js.map +1 -0
- package/dist/adapters/cursor-tools.d.ts +11 -0
- package/dist/adapters/cursor-tools.js +49 -0
- package/dist/adapters/cursor-tools.js.map +1 -0
- package/dist/adapters/cursor.d.ts +6 -0
- package/dist/adapters/cursor.js +17 -0
- package/dist/adapters/cursor.js.map +1 -0
- package/dist/adapters/fx-approvals.d.ts +2 -0
- package/dist/adapters/fx-approvals.js +14 -0
- package/dist/adapters/fx-approvals.js.map +1 -0
- package/dist/adapters/fx-auth.d.ts +12 -2
- package/dist/adapters/fx-auth.js +51 -61
- package/dist/adapters/fx-auth.js.map +1 -1
- package/dist/adapters/fx-profile.d.ts +8 -0
- package/dist/adapters/fx-profile.js +101 -0
- package/dist/adapters/fx-profile.js.map +1 -0
- package/dist/adapters/fx-rpc.d.ts +2 -0
- package/dist/adapters/fx-rpc.js +30 -4
- package/dist/adapters/fx-rpc.js.map +1 -1
- package/dist/adapters/fx-status.d.ts +2 -0
- package/dist/adapters/fx-status.js +96 -0
- package/dist/adapters/fx-status.js.map +1 -0
- package/dist/adapters/fx.js +77 -30
- package/dist/adapters/fx.js.map +1 -1
- package/dist/adapters/opencode-access.d.ts +13 -0
- package/dist/adapters/opencode-access.js +76 -0
- package/dist/adapters/opencode-access.js.map +1 -0
- package/dist/adapters/opencode-config.d.ts +11 -0
- package/dist/adapters/opencode-config.js +238 -0
- package/dist/adapters/opencode-config.js.map +1 -0
- package/dist/adapters/opencode-http.d.ts +28 -0
- package/dist/adapters/opencode-http.js +297 -0
- package/dist/adapters/opencode-http.js.map +1 -0
- package/dist/adapters/opencode-tools.d.ts +19 -0
- package/dist/adapters/opencode-tools.js +127 -0
- package/dist/adapters/opencode-tools.js.map +1 -0
- package/dist/adapters/opencode.d.ts +2 -0
- package/dist/adapters/opencode.js +569 -0
- package/dist/adapters/opencode.js.map +1 -0
- package/dist/adapters/rpc.d.ts +3 -0
- package/dist/adapters/rpc.js +45 -4
- package/dist/adapters/rpc.js.map +1 -1
- package/dist/adapters/types.d.ts +7 -0
- package/dist/adapters/types.js.map +1 -1
- package/dist/approvals/schema.d.ts +4 -0
- package/dist/approvals/schema.js +70 -0
- package/dist/approvals/schema.js.map +1 -0
- package/dist/approvals/types.d.ts +47 -0
- package/dist/approvals/types.js +2 -0
- package/dist/approvals/types.js.map +1 -0
- package/dist/cli/args.d.ts +3 -2
- package/dist/cli/args.js +24 -3
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/dashboard-client.d.ts +5 -1
- package/dist/cli/dashboard-client.js +162 -15
- package/dist/cli/dashboard-client.js.map +1 -1
- package/dist/cli/dashboard-controller.d.ts +7 -0
- package/dist/cli/dashboard-controller.js +27 -0
- package/dist/cli/dashboard-controller.js.map +1 -0
- package/dist/cli/dashboard-detail-view.d.ts +16 -0
- package/dist/cli/dashboard-detail-view.js +162 -0
- package/dist/cli/dashboard-detail-view.js.map +1 -0
- package/dist/cli/dashboard-history-view.d.ts +29 -0
- package/dist/cli/dashboard-history-view.js +211 -0
- package/dist/cli/dashboard-history-view.js.map +1 -0
- package/dist/cli/dashboard-input.d.ts +14 -0
- package/dist/cli/dashboard-input.js +128 -0
- package/dist/cli/dashboard-input.js.map +1 -0
- package/dist/cli/dashboard-layout.d.ts +12 -1
- package/dist/cli/dashboard-layout.js +32 -30
- package/dist/cli/dashboard-layout.js.map +1 -1
- package/dist/cli/dashboard-renderer.d.ts +30 -2
- package/dist/cli/dashboard-renderer.js +125 -7
- package/dist/cli/dashboard-renderer.js.map +1 -1
- package/dist/cli/dashboard-style.d.ts +9 -0
- package/dist/cli/dashboard-style.js +36 -0
- package/dist/cli/dashboard-style.js.map +1 -0
- package/dist/cli/dashboard.d.ts +5 -3
- package/dist/cli/dashboard.js +102 -12
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +37 -12
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/input.d.ts +1 -0
- package/dist/cli/input.js +23 -17
- package/dist/cli/input.js.map +1 -1
- package/dist/cli/main.js +6 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/output.js +17 -1
- package/dist/cli/output.js.map +1 -1
- package/dist/config/access-provenance.d.ts +10 -0
- package/dist/config/access-provenance.js +31 -0
- package/dist/config/access-provenance.js.map +1 -0
- package/dist/config/access.d.ts +12 -2
- package/dist/config/access.js +125 -27
- package/dist/config/access.js.map +1 -1
- package/dist/config/loader.js +1 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/oidc.js +4 -2
- package/dist/config/oidc.js.map +1 -1
- package/dist/config/project.js +2 -1
- package/dist/config/project.js.map +1 -1
- package/dist/config/resolve-access.js +24 -10
- package/dist/config/resolve-access.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/process-diagnostics.d.ts +2 -0
- package/dist/process-diagnostics.js +11 -0
- package/dist/process-diagnostics.js.map +1 -0
- package/dist/runtime/access-errors.d.ts +4 -0
- package/dist/runtime/access-errors.js +25 -0
- package/dist/runtime/access-errors.js.map +1 -0
- package/dist/runtime/approval-registry.d.ts +27 -0
- package/dist/runtime/approval-registry.js +126 -0
- package/dist/runtime/approval-registry.js.map +1 -0
- package/dist/runtime/client.js +54 -14
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/coordinator.d.ts +17 -1
- package/dist/runtime/coordinator.js +124 -6
- package/dist/runtime/coordinator.js.map +1 -1
- package/dist/runtime/dashboard-sanitize.d.ts +2 -0
- package/dist/runtime/dashboard-sanitize.js +7 -0
- package/dist/runtime/dashboard-sanitize.js.map +1 -0
- package/dist/runtime/dashboard.d.ts +43 -1
- package/dist/runtime/dashboard.js +2 -3
- package/dist/runtime/dashboard.js.map +1 -1
- package/dist/runtime/definition.js +11 -1
- package/dist/runtime/definition.js.map +1 -1
- package/dist/runtime/select-native.d.ts +2 -1
- package/dist/runtime/select-native.js +28 -10
- package/dist/runtime/select-native.js.map +1 -1
- package/dist/runtime/service.js +24 -1
- package/dist/runtime/service.js.map +1 -1
- package/dist/runtime/types.d.ts +9 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/runtime/worker-approvals.d.ts +21 -0
- package/dist/runtime/worker-approvals.js +51 -0
- package/dist/runtime/worker-approvals.js.map +1 -0
- package/dist/runtime/worker-client.js +73 -20
- package/dist/runtime/worker-client.js.map +1 -1
- package/dist/runtime/worker-server.d.ts +2 -0
- package/dist/runtime/worker-server.js +39 -10
- package/dist/runtime/worker-server.js.map +1 -1
- package/dist/sdk/definitions.d.ts +4 -1
- package/dist/sdk/definitions.js +16 -2
- package/dist/sdk/definitions.js.map +1 -1
- package/dist/sdk/permission-validation.js +10 -1
- package/dist/sdk/permission-validation.js.map +1 -1
- package/dist/sdk/types.d.ts +29 -1
- package/dist/sdk/types.js.map +1 -1
- package/package.json +4 -1
- package/sdk/access-config.md +86 -4
- package/sdk/adapter-contract.md +7 -13
- package/sdk/additional-harnesses.md +43 -0
- package/sdk/agent-skill.md +7 -4
- package/sdk/agent.md +5 -3
- package/sdk/approvals.md +120 -0
- package/sdk/authentication.md +1 -1
- package/sdk/cli/dashboard-design.md +44 -4
- package/sdk/cli/dashboard-inspection.md +25 -0
- package/sdk/cli/index.md +20 -11
- package/sdk/cli/output.md +10 -4
- package/sdk/completion-notifications.md +2 -0
- package/sdk/config.md +1 -1
- package/sdk/copilot.md +53 -0
- package/sdk/cursor.md +68 -0
- package/sdk/diagnostics.md +29 -0
- package/sdk/distribution.md +53 -1
- package/sdk/evals.md +10 -4
- package/sdk/fx.md +51 -6
- package/sdk/harnesses.md +13 -13
- package/sdk/index.md +4 -2
- package/sdk/message-delivery.md +1 -1
- package/sdk/opencode.md +57 -0
- package/sdk/permissions.md +7 -5
- package/sdk/pr-integration.md +1 -1
- package/sdk/project-team.md +2 -0
- package/sdk/sessions.md +4 -1
- package/sdk/tools.md +1 -1
- package/sdk/v1-runtime.md +6 -6
package/sdk/permissions.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Native Permissions
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The Codex, Claude Code, and fx constructors accept optional native permission settings directly alongside model options. These settings configure the native session without modifying persistent native settings or creating a Subharness sandbox. OpenCode instead uses its isolated native ask policy, Copilot uses native manual permission mode, and neither exposes a public permission selector. Cursor exposes its documented SDK `sandboxMode` for API-key access; subscription ACP access rejects explicit sandbox settings and supports the documented once-only native approvals. Supported native tool approvals are surfaced to the caller through the [structured approval flow](approvals.md); an explicit valid caller decision is required before authorization. The installed harness evaluates the selected policy, and the external execution environment enforces its remaining restrictions.
|
|
4
4
|
|
|
5
5
|
Omitted settings preserve native configuration. Explicit settings remain fixed for session follow-ups. A child uses its own definition and native configuration; it does not inherit the parent's explicit permission options. Invalid definitions fail before execution. Unsupported or observably rejected explicit settings fail without fallback to another harness or permission policy.
|
|
6
6
|
|
|
@@ -21,6 +21,8 @@ codex({
|
|
|
21
21
|
|
|
22
22
|
`approvalPolicy: "never"` suppresses approval prompts; it does not grant operations blocked by the selected sandbox. `danger-full-access` removes Codex's native sandbox boundary, subject to external restrictions.
|
|
23
23
|
|
|
24
|
+
By default, `workspace-write` keeps `.git`, `.agents`, and `.codex` read-only inside the writable workspace. It also protects the Git directory named by a `.git` pointer file, even when that directory is inside the workspace; for a linked worktree, that directory is in the main checkout's Git directory and holds the worktree's index. Git index updates such as `git add` can therefore fail in ordinary checkouts and linked worktrees. subharness does not add writable roots or change the native policy to permit these operations.
|
|
25
|
+
|
|
24
26
|
## Claude Code
|
|
25
27
|
|
|
26
28
|
```ts
|
|
@@ -33,7 +35,7 @@ claudeCode({
|
|
|
33
35
|
|
|
34
36
|
`ClaudeCodeOptions` and `ClaudeCodeConfig` expose `permissionMode?: "default" | "acceptEdits" | "bypassPermissions" | "plan" | "dontAsk" | "auto"`, `allowedTools?: readonly string[]`, and `disallowedTools?: readonly string[]`. Rule arrays contain nonempty strings and are copied into immutable configuration. Unknown modes, non-string rules, and fields belonging to another harness are invalid definitions. An empty rule list adds no rules.
|
|
35
37
|
|
|
36
|
-
The adapter passes these settings to the native Agent SDK. Explicit allowed rules are combined with the existing rules for declared custom tools and exact child-launcher operations. Disallowed rules remain authoritative under native permission evaluation. Selecting `bypassPermissions` also supplies the native SDK's required explicit bypass enablement.
|
|
38
|
+
The adapter passes these settings to the native Agent SDK. Explicit allowed rules are combined with the existing rules for declared custom tools and exact child-launcher operations. Disallowed rules remain authoritative under native permission evaluation. Selecting `bypassPermissions` also supplies the native SDK's required explicit bypass enablement. Unresolved callbacks use the structured approval flow; the library never chooses an allow decision automatically.
|
|
37
39
|
|
|
38
40
|
Native permission mode and rule evaluation depend on the installed SDK, executable, and managed settings. Observable rejection or a reported different explicit mode is an error. A native initialization event that reports the active mode must agree with the explicit request. Startup success does not claim that every native rule or future command was verified. Diagnostics identify rejected options without exposing rule contents or tool arguments.
|
|
39
41
|
|
|
@@ -54,12 +56,12 @@ fx({
|
|
|
54
56
|
|
|
55
57
|
## Readiness and failures
|
|
56
58
|
|
|
57
|
-
`check` uses the same permission configuration as execution. Its success establishes startup readiness and only the native settings observable during startup. It does not execute a shell or child launcher, prove arbitrary tool access, or claim unobservable native policy values.
|
|
59
|
+
`check` uses the same permission configuration as execution. Its success establishes startup readiness and only the native settings observable during startup. It does not execute a shell or child launcher, prove arbitrary tool access, or claim unobservable native policy values. Startup-time interactive requests still fail with `INPUT_REQUIRED`. During execution, supported permission requests surface through the [structured approval flow](approvals.md), without changing native configuration.
|
|
58
60
|
|
|
59
|
-
|
|
61
|
+
For a surfaced permission request, the caller inspects the action and responds to its schema, then observes the original task. For an unsupported interaction or hard native denial, the caller reports the affected harness and operation and resolves that restriction before starting a new attempt. Retrying unchanged permission failures, broadening policy automatically, or silently selecting another harness is not a recovery strategy.
|
|
60
62
|
|
|
61
63
|
## Background delegation
|
|
62
64
|
|
|
63
65
|
The caller reads the Subharness skill and prefers one ordinary `subharness run <target>` through known host background-command controls. It continues independent work and later collects that hosted command's output, which already contains the first response or terminal outcome. When those controls are unavailable or uncertain, it uses `run --detach`, retains the returned task and session identifiers, continues other work, and later collects the result with `wait`. `status` is optional when a snapshot or additional state is needed. Shell `&` and an unobserved process do not replace managed task records. Both paths require collecting the result and confirming its terminal outcome before reporting completion; detached admission alone is not completion.
|
|
64
66
|
|
|
65
|
-
The native caller needs permission to execute the private launcher and reach the local coordinator. Each child needs permission for its own task. This remains true for
|
|
67
|
+
The native caller needs permission to execute the private launcher and reach the local coordinator. Each child needs permission for its own task. This remains true for all six native harnesses; no constructor option promises native desktop notifications or automatic chat reactivation. OpenCode and Copilot can surface supported active permission requests through the structured approval flow. Cursor subscription sessions also expose supported once-only ACP permissions. Other Cursor interactive requests fail with `INPUT_REQUIRED`.
|
package/sdk/pr-integration.md
CHANGED
|
@@ -22,7 +22,7 @@ After every mutation, the integrator reads GitHub state again. Merge success req
|
|
|
22
22
|
|
|
23
23
|
The report identifies merged, already merged, blocked, and unattempted entries, their reviewed heads, resulting merge commits when known, and exact blockers. It includes the observed final destination-branch SHA and command outcomes. The integrator writes a nonsecret progress journal only when the assignment names its path. It never exports credentials, dumps the environment, or claims local integration tests ran merely because hosted checks passed.
|
|
24
24
|
|
|
25
|
-
The caller supplies the existing native GitHub authentication and any explicitly authorized native network profile. Model billing continues to use the caller's selected access configuration. Permission failures are reported without bypasses or silent changes of execution route.
|
|
25
|
+
The caller supplies the existing native GitHub authentication and any explicitly authorized native network profile. Model billing continues to use the caller's selected access configuration. Permission failures are reported without bypasses or silent changes of execution route. Supported native permission requests use the [structured approval flow](approvals.md). A permission response does not expand the integrator's assigned merge authority. Unsupported host interactions can still produce `INPUT_REQUIRED`, as specified in the [adapter contract](adapter-contract.md).
|
|
26
26
|
|
|
27
27
|
The allowlist is an instruction-level delegation contract, not a GitHub token scope or a new runtime security boundary. The agent retains native tools; neither the model's instructions nor an API-domain allowlist mechanically limits a credential to those PRs. Native sandbox policy, credential scopes, and GitHub protections remain the enforcement boundaries.
|
|
28
28
|
|
package/sdk/project-team.md
CHANGED
|
@@ -21,6 +21,8 @@ Role instructions alone do not grant native capabilities or permissions. Browsin
|
|
|
21
21
|
|
|
22
22
|
The repository's Codex roles explicitly select `approvalPolicy: "never"`, `sandboxMode: "workspace-write"`, and `networkAccessEnabled: true` for local development and coordinator access. The reviewer selects Claude `permissionMode: "dontAsk"` with `Read`, `Glob`, `Grep`, and `Bash` allowed. Its read-only review responsibility remains an instruction; allowing Bash is not a filesystem read-only boundary. The fx roles explicitly select `permissionMode: "auto"`. These policies use [native permission options](permissions.md), preserve native restrictions, and do not guarantee that every operation is permitted. Protected paths and rejected automatic reviews can still require a lead-managed execution path.
|
|
23
23
|
|
|
24
|
+
Implementation roles return unstaged working-tree changes and verification evidence. Local Git staging and commits belong to the lead unless the assignment explicitly authorizes them. When an implementation task requires moving or deleting ordinary files, roles use filesystem operations; subsequent Git staging records the renames. By default, Codex workspace-write protects `.git`, `.agents`, and `.codex` inside the writable workspace. It also protects the Git directory named by a `.git` pointer file, even when that directory is inside the workspace; for a linked worktree, that directory is in the main checkout's Git directory and holds the worktree's index. A required change under those protected paths is reported with the exact operation, affected paths, and partial effects for lead-managed execution. A copied replacement does not complete a move while the original remains.
|
|
25
|
+
|
|
24
26
|
## Skills and task context
|
|
25
27
|
|
|
26
28
|
Repository skills live in `.agents/skills/<name>/SKILL.md`. The short index in `AGENTS.md` explains when each skill applies. Agents read only the relevant skill and supporting references for their current task. Skill contents are not concatenated into every agent's instructions.
|
package/sdk/sessions.md
CHANGED
|
@@ -10,6 +10,7 @@ Each `run` creates a new session; `send` creates follow-up tasks or steers the a
|
|
|
10
10
|
| --- | --- |
|
|
11
11
|
| `queued` | Admitted but not yet dispatched |
|
|
12
12
|
| `running` | Native startup or generation is active |
|
|
13
|
+
| `awaiting_approval` | A native operation is waiting for a structured permission answer |
|
|
13
14
|
| `waiting` | Between native turns while delegated work or result processing remains |
|
|
14
15
|
| `completed` | Native response and descendant completion boundary are satisfied |
|
|
15
16
|
| `failed` | Execution or cancellation failed; queue dispatch is paused |
|
|
@@ -24,8 +25,10 @@ Every complete response receives a response identifier and returns control to it
|
|
|
24
25
|
|
|
25
26
|
## Lifetime and recovery
|
|
26
27
|
|
|
27
|
-
The on-demand coordinator retains task records and native session workers beyond individual command exits. Task IDs resolve from other working directories using that coordinator.
|
|
28
|
+
The on-demand coordinator retains task records and native session workers beyond individual command exits. Task IDs resolve from other working directories using that coordinator. Task records remain available for its lifetime; they are not silently evicted. Settled permission-request records have a separate bounded retention policy defined in [Responding to Native Permission Requests](approvals.md).
|
|
28
29
|
|
|
29
30
|
Restarting the coordinator does not restore queues or automatically replay tasks. Native harness history can exist separately, but this version does not reconstruct library sessions from it. Unavailable identifiers return an error. `resume` is limited to supported native recovery of a retained failed task; it does not imply recovery after coordinator loss.
|
|
30
31
|
|
|
31
32
|
Cancellation, interrupt propagation, and queue behavior are defined in [Message Delivery](message-delivery.md). The detailed ownership and bounds are defined in the [runtime contract](v1-runtime.md).
|
|
33
|
+
|
|
34
|
+
Supported native permission requests follow [Responding to Native Permission Requests](approvals.md). Observing an approval returns control without completing or restarting the task.
|
package/sdk/tools.md
CHANGED
|
@@ -70,6 +70,6 @@ function toolResult(result: { readonly content: readonly ToolContent[] }): ToolR
|
|
|
70
70
|
|
|
71
71
|
`ToolResult` is an opaque value created by `toolResult`; callers must return it directly from `execute`. It is not a JSON transport format. Content must be nonempty, contain only the supported block fields, and include at most eight images. Image data is canonical padded standard base64 without a data-URL prefix. The decoded file signature must match its declared MIME type. Each encoded image is limited to 5 MiB; the complete rich result's JSON content is limited to 8 MiB, and combined text is limited to 1 MiB. Ordinary text and JSON results retain their 1 MiB limit.
|
|
72
72
|
|
|
73
|
-
The SDK validates rich results at the tool execution boundary. Malformed blocks report `TOOL_RESULT_INVALID`; exceeded limits report `TOOL_RESULT_TOO_LARGE`. Native adapters pass images as image content, never as base64 inside a text result
|
|
73
|
+
The SDK validates rich results at the tool execution boundary. Malformed blocks report `TOOL_RESULT_INVALID`; exceeded limits report `TOOL_RESULT_TOO_LARGE`. Native adapters pass images as image content, never as base64 inside a text result. Claude Code, fx, and OpenCode use MCP image blocks; Codex and Cursor SDK sessions use native image content items; Cursor subscription sessions use MCP image blocks. [Copilot](copilot.md) groups content by type in its native result envelope: text blocks are joined in their original text order, images retain their original image order as binary image results, and interleaving between the text and image groups is unavailable. Model-specific image support and lower native limits still apply; a text-only model cannot perform visual inspection. The [fx contract](fx.md) records a native image-tool crash affecting fx 0.0.9. The tool author controls which files are read. This helper does not grant filesystem access or fetch remote images.
|
|
74
74
|
|
|
75
75
|
Cancellation waits for already-admitted callbacks to settle. There is no cancellation signal in `execute(input)`, and completed effects are not rolled back. Streaming tool results and arbitrary external tool-definition objects are outside this API.
|
package/sdk/v1-runtime.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# V1 Runtime Contract
|
|
2
2
|
|
|
3
|
-
The first usable version supplies a TypeScript definition SDK and the `subharness` CLI with Codex, Claude Code,
|
|
3
|
+
The first usable version supplies a TypeScript definition SDK and the `subharness` CLI with Codex, Claude Code, fx, OpenCode, GitHub Copilot, and Cursor adapters. The library coordinates existing harnesses; it does not implement a model loop, sandbox, worktree manager, or native permission system.
|
|
4
4
|
|
|
5
5
|
## Package and definitions
|
|
6
6
|
|
|
7
|
-
The package is `subharness`, with the primary executable `subharness` and identical `agent` compatibility alias. Node.js 22.18 or newer is required. ESM exports include `agent`, `tool`, `toolResult`, `codex`, `claudeCode`, `fx`, and their definition/configuration types. The public SDK defines reusable specialists; direct CLI harness targets also execute without a definition. Execution in v1 uses the CLI. Definition objects have readonly configuration fields and no execution methods. They contain functions and schemas and are not a serialization format.
|
|
7
|
+
The package is `subharness`, with the primary executable `subharness` and identical `agent` compatibility alias. Node.js 22.18 or newer is required. ESM exports include `agent`, `tool`, `toolResult`, `codex`, `claudeCode`, `fx`, `opencode`, `copilot`, `cursor`, and their definition/configuration types. The public SDK defines reusable specialists; direct CLI harness targets also execute without a definition. Execution in v1 uses the CLI. Definition objects have readonly configuration fields and no execution methods. They contain functions and schemas and are not a serialization format.
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
import { agent, codex, claudeCode, tool } from "subharness";
|
|
@@ -20,7 +20,7 @@ Global definitions live in `~/.subharness/agents/`; repository definitions live
|
|
|
20
20
|
|
|
21
21
|
Definitions are trusted executable TypeScript. Loading a catalog evaluates its modules, so callers must trust the selected project and global definition files. Imports resolve relative to each definition through normal Node package resolution, with TypeScript loading supplied by the CLI. Missing imports, invalid exports, and duplicate names fail with the source filename. A session retains its loaded instructions, tools, and harness configuration for follow-ups; new sessions load current definition sources.
|
|
22
22
|
|
|
23
|
-
An omitted `--cwd` uses the command's working directory. `--prompt-file` paths resolve against the calling command's directory, independently of `--cwd`; files use UTF-8. Prompts must contain non-whitespace text and cannot exceed 1 MiB. One quoted positional prompt, `--prompt`, and `--prompt-file` are mutually exclusive. `--prompt-file -` reads bounded UTF-8 stdin to EOF and rejects a terminal input stream. Direct harness targets accept `--model`
|
|
23
|
+
An omitted `--cwd` uses the command's working directory. `--prompt-file` paths resolve against the calling command's directory, independently of `--cwd`; files use UTF-8. Prompts must contain non-whitespace text and cannot exceed 1 MiB. One quoted positional prompt, `--prompt`, and `--prompt-file` are mutually exclusive. `--prompt-file -` reads bounded UTF-8 stdin to EOF and rejects a terminal input stream. Direct harness targets accept `--model` for `run` and `check`. Codex, Claude Code, and fx also accept `--effort`; OpenCode, Copilot, and Cursor reject it. Specialist targets reject both overrides.
|
|
24
24
|
|
|
25
25
|
`run` and task-creating `send` commands accept `--detach` with every prompt source. The option ends the requesting command's observation immediately after successful admission, so the command returns exactly the existing `started` record and exits `0`. The service explicitly completes that observation response; it does not rely on a caller abandoning a response body. Admission errors keep their records and exit codes, while later failures remain available through `wait` and `status`. Interrupt delivery confirms affected execution has stopped before replacement admission even when detached. Steering rejects `--detach` with `INVALID_ARGUMENT`. The option is an observation request and is never retained as session configuration.
|
|
26
26
|
|
|
@@ -38,9 +38,9 @@ Closing a response-reading command does not cancel work. The coordinator retains
|
|
|
38
38
|
|
|
39
39
|
## Task states and responses
|
|
40
40
|
|
|
41
|
-
The coordinator supplies the terminal dashboard with a read-only snapshot of current session work followed by retained finished tasks, including failed active tasks that pause a queue. Each task appears at most once, and retained history is available to newly opened dashboards for the coordinator’s lifetime. The private snapshot includes an explicit finished-history and grouped-context capability markers so the CLI can reject older incompatible coordinators. It carries only session/task identity, selected harness, bounded prompt title, task state, canonical checkout/repository paths, and timestamps needed by the display; it excludes environment variables, credentials, definitions, transcripts, and native diagnostics. Reading it does not acknowledge responses or change task execution. Workers report the actual selected harness to the coordinator after native startup succeeds. Task timing records the first dispatch, latest failure, and terminal completion or confirmed-stop time without resetting on native continuations. Finished rows retain a fixed elapsed duration; recovery clears terminal timing for the resumed task. Snapshot observation adds no public SDK execution method or persistent history. The
|
|
41
|
+
The coordinator supplies the terminal dashboard with a read-only snapshot of current session work followed by retained finished tasks, including failed active tasks that pause a queue. Each task appears at most once, and retained history is available to newly opened dashboards for the coordinator’s lifetime. The private snapshot includes an explicit finished-history and grouped-context capability markers so the CLI can reject older incompatible coordinators. It carries only session/task identity, selected harness, bounded prompt title, task state, canonical checkout/repository paths, and timestamps needed by the display; it excludes environment variables, credentials, definitions, transcripts, and native diagnostics. Reading it does not acknowledge responses or change task execution. Workers report the actual selected harness to the coordinator after native startup succeeds. Task timing records the first dispatch, latest failure, and terminal completion or confirmed-stop time without resetting on native continuations. Finished rows retain a fixed elapsed duration; recovery clears terminal timing for the resumed task. Snapshot observation adds no public SDK execution method or persistent history. The inspector uses a separate authenticated, read-only session-history projection for retained work requests, stable admission ordinals, queue state and direct child sessions. Full prompt/response content is fetched only for the expanded request through the task-detail projection. It omits already-cached prompt and response text on refresh and never acknowledges delegated outcomes or changes execution. The private transport is defined in [Dashboard inspection](cli/dashboard-inspection.md); presentation is defined in [CLI](cli/index.md#live-dashboard).
|
|
42
42
|
|
|
43
|
-
Task states are `queued`, `running`, `waiting`, `completed`, `failed`, `cancelled`, and `interrupted`. `waiting` means the library task remains active between native turns while delegated work or child-result processing is pending. A native permission request is not a completed response. Terminal outcomes are `completed`, `failed`, `cancelled`, and `interrupted`.
|
|
43
|
+
Task states are `queued`, `running`, `waiting`, `awaiting_approval`, `completed`, `failed`, `cancelled`, and `interrupted`. `waiting` means the library task remains active between native turns while delegated work or child-result processing is pending. A native permission request is not a completed response. Terminal outcomes are `completed`, `failed`, `cancelled`, and `interrupted`.
|
|
44
44
|
|
|
45
45
|
Each complete native response has an opaque response identifier, text, and the task state at that response. `wait` without `--after` returns the first retained response in order, including one that arrived before the command started, or awaits it. Omission does not select the latest response or begin observation at the current time. `wait --after <response-id>` returns the next retained response after that cursor. If no selected response remains and the task is terminal, it returns the terminal outcome. Unknown response identifiers, including identifiers from another task, are errors. Multiple observers can independently read the same response.
|
|
46
46
|
|
|
@@ -60,7 +60,7 @@ New follow-up tasks in a child session belong to the currently invoking parent t
|
|
|
60
60
|
|
|
61
61
|
## Permissions and bounds
|
|
62
62
|
|
|
63
|
-
Adapters preserve native permission restrictions. Declaring subagents authorizes their invocation: Claude Code receives session-only native allow rules for the exact launcher and documented delegation operations, combined with permissions for declared custom tools. These delegation rules do not themselves change native modes, managed policy, or sandbox boundaries. Explicit constructor options separately select session-native permissions under [Native Permissions](permissions.md); persistent user/project settings are unchanged.
|
|
63
|
+
Adapters preserve native permission restrictions. Declaring subagents authorizes their invocation: Claude Code receives session-only native allow rules for the exact launcher and documented delegation operations, combined with permissions for declared custom tools. These delegation rules do not themselves change native modes, managed policy, or sandbox boundaries. Explicit constructor options separately select session-native permissions under [Native Permissions](permissions.md); persistent user/project settings are unchanged. Supported native approval requests remain open and surface through the [structured approval flow](approvals.md). The caller answers the request-specific schema with `respond`, then observes the original task. The permission callback never automatically approves the request. Unsupported input and startup-time interactions still fail with `INPUT_REQUIRED`. Hard native denials remain subject to the selected native policy.
|
|
64
64
|
|
|
65
65
|
Ordinary text/JSON tool results and complete responses are limited to 1 MiB. Rich tool results have the image and aggregate limits defined in [custom tools](tools.md). Oversized results produce explicit errors rather than silent truncation. `status` includes at most 4,000 characters of the latest response and marks truncation; `status --full` retrieves the complete latest response, while `wait` observes the first response or a subsequent response selected by a cursor. Delegation depth is limited to 8, and each session admits at most 100 pending tasks. Exceeding a bound fails admission without dropping existing work. No automatic task-duration deadline is imposed.
|
|
66
66
|
|