@humwick/runner 0.130.5 → 0.130.6
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/agent-bin/humwick +2 -2
- package/agent-bin/humwick-browser +4 -0
- package/hooks/fff-search-redirect/fff-search-redirect.cjs +1 -1
- package/hooks/web-tools-redirect/web-tools-redirect.cjs +2 -2
- package/package.json +7 -10
- package/plugins/browser/skills/playwright-cli/SKILL.md +8 -6
- package/plugins/claude/.claude-plugin/plugin.json +3 -3
- package/plugins/claude/claude-statusline-probe.cjs +26 -16
- package/plugins/claude/hooks/gate-run-guard.provisioned.mjs +47 -17
- package/plugins/claude/hooks/gate-run-guard.sh +3 -3
- package/plugins/claude/hooks/gate-run-guard.ts +5 -5
- package/plugins/claude/hooks/kill-guard.sh +4 -4
- package/plugins/claude/hooks/kill-guard.ts +1 -1
- package/plugins/claude/hooks/permission-request.sh +1 -1
- package/plugins/claude/hooks/post-compact.sh +1 -1
- package/plugins/claude/hooks/post-tool-use.sh +3 -3
- package/plugins/claude/hooks/pre-compact.sh +2 -2
- package/plugins/claude/hooks/read-only-bash-guard.sh +4 -4
- package/plugins/claude/hooks/relay-status.sh +32 -32
- package/plugins/claude/hooks/session-end.sh +2 -2
- package/plugins/claude/hooks/session-start.sh +3 -3
- package/plugins/claude/hooks/shell-trust.ts +1 -1
- package/plugins/claude/hooks/stop-failure.sh +2 -2
- package/plugins/claude/hooks/stop.sh +6 -6
- package/plugins/claude/hooks/subagent-skill-policy.cjs +8 -6
- package/plugins/claude/hooks/subagent-stop.sh +3 -3
- package/plugins/claude/hooks/user-prompt-submit.sh +1 -1
- package/plugins/claude/hooks/wait-loop-guard.ts +3 -3
- package/plugins/claude/monitors/monitors.json +2 -2
- package/plugins/claude/monitors/relay-monitor.provisioned.mjs +96 -62
- package/plugins/claude/monitors/relay-monitor.ts +5 -5
- package/plugins/claude/skills/label/SKILL.md +3 -3
- package/plugins/claude/skills/message/SKILL.md +5 -5
- package/plugins/claude/skills/react/SKILL.md +1 -1
- package/plugins/claude/skills/read-message/SKILL.md +4 -4
- package/plugins/claude/skills/reply/SKILL.md +5 -5
- package/plugins/claude/skills/send-claimable/SKILL.md +5 -5
- package/plugins/claude/skills/slice-first/SKILL.md +5 -3
- package/plugins/claude/skills/slice-first/references/plan-recipe.md +30 -29
- package/plugins/claude/skills/status/SKILL.md +1 -1
- package/plugins/claude/skills/tags/SKILL.md +5 -5
- package/plugins/claude/skills/task/SKILL.md +10 -10
- package/plugins/claude-output-style/.claude-plugin/plugin.json +1 -1
- package/plugins/claude-output-style/output-styles/{agent-relay.md → humwick.md} +1 -1
- package/plugins/codex/skills/guide/SKILL.md +1 -1
- package/plugins/codex/skills/label/SKILL.md +3 -3
- package/plugins/codex/skills/message/SKILL.md +5 -5
- package/plugins/codex/skills/react/SKILL.md +1 -1
- package/plugins/codex/skills/read-message/SKILL.md +4 -4
- package/plugins/codex/skills/reply/SKILL.md +5 -5
- package/plugins/codex/skills/send-claimable/SKILL.md +5 -5
- package/plugins/codex/skills/slice-first/SKILL.md +5 -3
- package/plugins/codex/skills/slice-first/references/plan-recipe.md +30 -29
- package/plugins/codex/skills/status/SKILL.md +1 -1
- package/plugins/codex/skills/tags/SKILL.md +5 -5
- package/plugins/codex/skills/task/SKILL.md +11 -10
- package/src/adapter.ts +95 -92
- package/src/adapters/claude-api.ts +8 -11
- package/src/adapters/claude-context-command.ts +1 -1
- package/src/adapters/claude-credentials.ts +7 -3
- package/src/adapters/claude-delivery-lanes.ts +2 -2
- package/src/adapters/claude-delivery.ts +16 -16
- package/src/adapters/claude-effort.ts +2 -2
- package/src/adapters/claude-exit.ts +2 -2
- package/src/adapters/claude-headless-mirror.ts +18 -2
- package/src/adapters/claude-headless-refusal.ts +3 -3
- package/src/adapters/claude-headless.ts +11 -10
- package/src/adapters/claude-launch-exit.ts +1 -1
- package/src/adapters/claude-monitor-delivery-plan.ts +36 -16
- package/src/adapters/claude-permission.ts +5 -5
- package/src/adapters/claude-prompt-gates.ts +9 -9
- package/src/adapters/claude-prompt-hook.ts +2 -2
- package/src/adapters/claude-session-capture.ts +6 -6
- package/src/adapters/claude-session-probe.ts +25 -25
- package/src/adapters/claude-shutdown.ts +11 -11
- package/src/adapters/claude-status-detectors.ts +31 -31
- package/src/adapters/claude-subagents.ts +7 -7
- package/src/adapters/claude-submit-confirmation.ts +6 -6
- package/src/adapters/claude-tmux.ts +43 -43
- package/src/adapters/claude-token-usage-capture.ts +5 -5
- package/src/adapters/claude-tool-policy.ts +7 -7
- package/src/adapters/claude-transcript.ts +24 -24
- package/src/adapters/claude.ts +100 -100
- package/src/adapters/codex-agent-message-capture.ts +26 -63
- package/src/adapters/codex-app-server.ts +1 -1
- package/src/adapters/codex-client.ts +9 -9
- package/src/adapters/codex-effective-config.ts +1 -1
- package/src/adapters/codex-launch-config.ts +5 -5
- package/src/adapters/codex-rollout-context.ts +2 -2
- package/src/adapters/codex-skill-discovery.ts +1 -1
- package/src/adapters/codex-token-usage-capture.ts +16 -16
- package/src/adapters/codex-tool-output.ts +4 -4
- package/src/adapters/codex-version.ts +3 -3
- package/src/adapters/codex.ts +64 -64
- package/src/adapters/opencode-api.ts +1 -1
- package/src/adapters/opencode-context.ts +20 -22
- package/src/adapters/opencode-model-registry.ts +7 -7
- package/src/adapters/opencode-provider.ts +8 -8
- package/src/adapters/opencode-provisioning.ts +30 -0
- package/src/adapters/opencode-server-retry.ts +1 -1
- package/src/adapters/opencode-soft-steer.ts +5 -5
- package/src/adapters/opencode-spawn.ts +18 -14
- package/src/adapters/opencode-token-usage-capture.ts +12 -12
- package/src/adapters/opencode-tool-events.ts +15 -15
- package/src/adapters/opencode.ts +232 -232
- package/src/adapters/project-shell.ts +11 -11
- package/src/adapters/service-access.ts +6 -6
- package/src/adapters/tmux-offload.ts +9 -9
- package/src/adapters/tool-summary.ts +5 -5
- package/src/agent-redact.ts +1 -1
- package/src/agent-runner/commands/dispatch.ts +10 -10
- package/src/agent-runner/commands/lifecycle.ts +2 -2
- package/src/agent-runner/commands/prompt.ts +19 -19
- package/src/agent-runner/credentials.ts +5 -5
- package/src/agent-runner/inbox.ts +1 -1
- package/src/agent-runner/lifecycle-milestones.ts +3 -3
- package/src/agent-runner/lifecycle-phase.ts +2 -2
- package/src/agent-runner/liveness-exchange.ts +4 -10
- package/src/agent-runner/registration.ts +8 -8
- package/src/agent-runner/runner-context.ts +9 -14
- package/src/agent-runner/session-mirror.ts +12 -12
- package/src/agent-runner/task-claims.ts +2 -2
- package/src/agent-runner/token-usage-coverage.ts +1 -1
- package/src/agent-runner/turn-report.ts +12 -12
- package/src/api-budget-accounting.ts +3 -3
- package/src/area-memory.ts +6 -6
- package/src/artifact-path-materialize.ts +1 -1
- package/src/async-guard.ts +5 -5
- package/src/attachment-cache.ts +17 -22
- package/src/background-script-reconcile.ts +6 -6
- package/src/bounded-log.ts +1 -1
- package/src/busy-reconciler.ts +22 -22
- package/src/claim-tracker.ts +3 -3
- package/src/claude-settings.ts +8 -8
- package/src/claude-system-prompt.ts +1 -1
- package/src/claude-workspace-trust.ts +1 -1
- package/src/config.ts +62 -61
- package/src/context-boundary.ts +5 -5
- package/src/context-command.ts +3 -3
- package/src/control-server.ts +32 -32
- package/src/delivery-result.ts +2 -2
- package/src/effort-command.ts +2 -2
- package/src/empty-turn.ts +22 -14
- package/src/free-port.ts +1 -1
- package/src/gate-run-config.ts +3 -3
- package/src/host-asset-plan.ts +24 -17
- package/src/host-claude-config-worker.ts +2 -2
- package/src/host-sources.ts +2 -2
- package/src/index.ts +16 -16
- package/src/launch-assembly.ts +94 -96
- package/src/liveness.ts +15 -15
- package/src/logger.ts +3 -3
- package/src/mcp-outbox.ts +3 -3
- package/src/mcp-preflight.ts +2 -2
- package/src/mcp-source-selection.ts +2 -2
- package/src/mcp-tool-deferral.ts +1 -1
- package/src/mcp-vault-env.ts +2 -2
- package/src/message-body-config/config.ts +4 -4
- package/src/mid-turn-delivery.ts +2 -2
- package/src/native-memory-lever.ts +8 -8
- package/src/outbox.ts +15 -15
- package/src/pending-permission-store.ts +1 -1
- package/src/profile-home.ts +19 -19
- package/src/profile-projection.ts +26 -24
- package/src/project-instructions.ts +5 -5
- package/src/provider-auth-warning.ts +17 -0
- package/src/provider-double.ts +1 -1
- package/src/provider-hold.ts +3 -3
- package/src/provider-home-marker.ts +1 -1
- package/src/provider-home-tombstone.ts +1 -1
- package/src/provider-input-queue.ts +2 -2
- package/src/provider-integration.ts +15 -13
- package/src/provider-setup.ts +15 -3
- package/src/providers.ts +1 -1
- package/src/provisioning.ts +37 -40
- package/src/question-decision.ts +2 -2
- package/src/quota.ts +0 -6
- package/src/rate-limit.ts +24 -13
- package/src/refused-prompt-store.ts +2 -2
- package/src/relay-injection-events.ts +2 -2
- package/src/relay-instructions.ts +5 -5
- package/src/relay-mcp-proxy.long-turn-e2e.ts +13 -13
- package/src/relay-mcp-proxy.ts +57 -58
- package/src/relay-mcp.ts +55 -69
- package/src/reply-obligation-cache.ts +9 -9
- package/src/response-capture-report.ts +9 -9
- package/src/response-routing.ts +1 -1
- package/src/runner-core.ts +209 -222
- package/src/runner-exit.ts +1 -1
- package/src/runner-helpers.ts +10 -10
- package/src/runner-insights.ts +4 -2
- package/src/runner-mcp-proxy.ts +3 -3
- package/src/runner-spawn-config.ts +3 -3
- package/src/runtime-token-file.ts +1 -1
- package/src/runtime-token-remint.ts +1 -1
- package/src/service-access.ts +2 -2
- package/src/session-destroy.ts +1 -1
- package/src/session-insights.ts +1 -1
- package/src/session-scratch.ts +24 -37
- package/src/spawn-input.ts +6 -6
- package/src/startup-config-fetch.ts +4 -4
- package/src/subreaper.ts +3 -5
- package/src/test-run-dedup.ts +13 -13
- package/src/transcript-context.ts +2 -2
- package/src/transport-errors.ts +1 -1
- package/src/turn-opener.ts +1 -1
- package/src/turn-reconcile-event.ts +2 -2
- package/src/vault-proxy-hop.ts +2 -2
- package/src/web-tools.ts +2 -2
- package/agent-bin/agent-relay-browser +0 -10
- package/src/adapters/provider-quota-harvest.ts +0 -76
package/src/config.ts
CHANGED
|
@@ -21,7 +21,7 @@ interface ProviderConfig {
|
|
|
21
21
|
defaultTags: string[];
|
|
22
22
|
chatCaptureMode: "final" | "full";
|
|
23
23
|
reasoningCapture?: boolean;
|
|
24
|
-
//
|
|
24
|
+
// Phase A — optional: absent resolves through the OWNING adapter's default (codex
|
|
25
25
|
// adapter → steer, others → defer). `"defer"` is the operational kill switch for soft-steer.
|
|
26
26
|
activeTurnMessageDelivery?: ActiveTurnMessageDelivery;
|
|
27
27
|
headless: {
|
|
@@ -41,11 +41,11 @@ interface LoadedProviderConfig extends ProviderConfig {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
export function humwickHome(): string {
|
|
44
|
-
return relayEnv(process.env, "
|
|
44
|
+
return relayEnv(process.env, "HUMWICK_HOME") || join(homedir(), ".humwick");
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export function logDirFromEnv(): string | undefined {
|
|
48
|
-
return relayEnv(process.env, "
|
|
48
|
+
return relayEnv(process.env, "HUMWICK_LOG_DIR");
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
function providersDir(home = humwickHome()): string {
|
|
@@ -70,7 +70,7 @@ export function defaultProviderConfig(provider: string): ProviderConfig {
|
|
|
70
70
|
defaultTags: [],
|
|
71
71
|
chatCaptureMode: "final",
|
|
72
72
|
reasoningCapture: true,
|
|
73
|
-
//
|
|
73
|
+
// Phase A — deliberately NOT set here: absent resolves through the OWNING adapter's
|
|
74
74
|
// default (codex → steer, others → defer) at the steer policy seam, so this config module
|
|
75
75
|
// carries no provider-identity branch (lint:provider-contract).
|
|
76
76
|
headless: {
|
|
@@ -91,14 +91,14 @@ export function loadGlobalConfig(home = humwickHome()): GlobalRunnerConfig {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
function relayUrlFromEnv(): string | undefined {
|
|
94
|
-
return relayEnv(process.env, "
|
|
94
|
+
return relayEnv(process.env, "HUMWICK_URL");
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
//
|
|
97
|
+
// override for the Codex hooks version gate (finding 4). An explicit version string
|
|
98
98
|
// bypasses the `codex --version` probe: deterministic in tests, and an operator escape hatch
|
|
99
99
|
// when the probe can't run. Empty string means "assume supported".
|
|
100
100
|
export function codexVersionOverrideFromEnv(): string | undefined {
|
|
101
|
-
return relayEnv(process.env, "
|
|
101
|
+
return relayEnv(process.env, "HUMWICK_CODEX_VERSION");
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
function textEnvOrFile(name: string): string | undefined {
|
|
@@ -115,41 +115,41 @@ function textEnvOrFile(name: string): string | undefined {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
export function relayTokenFromEnv(): string | undefined {
|
|
118
|
-
return relayEnv(process.env, "
|
|
118
|
+
return relayEnv(process.env, "HUMWICK_TOKEN");
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
//
|
|
121
|
+
// escape hatch for the per-launch Claude folder-trust seed. Off by default: an
|
|
122
122
|
// unseeded launch wedges on CC's trust dialog until a human answers, so this exists only for
|
|
123
123
|
// an operator who deliberately wants relay to keep its hands off a shared config. Never set
|
|
124
124
|
// it to protect a test — tests point CLAUDE_CONFIG_DIR at a fixture instead
|
|
125
125
|
// (scripts/test-preload-provider-home.ts), so the production path stays exercised.
|
|
126
126
|
export function claudeTrustSeedDisabledFromEnv(): boolean {
|
|
127
|
-
return relayEnv(process.env, "
|
|
127
|
+
return relayEnv(process.env, "HUMWICK_TRUST_SEED_DISABLED") === "1";
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
//
|
|
130
|
+
// slice flag: launch Claude with `--effort` and accept mid-session effort switches.
|
|
131
131
|
export function effortSwitchEnabledFromEnv(): boolean {
|
|
132
|
-
return relayEnv(process.env, "
|
|
132
|
+
return relayEnv(process.env, "HUMWICK_EFFORT_SWITCH") === "1";
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
export function runtimeTokenProfileFromEnv(): string | undefined {
|
|
136
|
-
return relayEnv(process.env, "
|
|
136
|
+
return relayEnv(process.env, "HUMWICK_TOKEN_PROFILE");
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
export function runtimeTokenJtiFromEnv(): string | undefined {
|
|
140
|
-
return relayEnv(process.env, "
|
|
140
|
+
return relayEnv(process.env, "HUMWICK_TOKEN_JTI");
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
export function runtimeTokenExpiresAtFromEnv(): string | undefined {
|
|
144
|
-
return relayEnv(process.env, "
|
|
144
|
+
return relayEnv(process.env, "HUMWICK_TOKEN_EXPIRES_AT");
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
export function runtimeTokenFileFromEnv(): string | undefined {
|
|
148
|
-
return relayEnv(process.env, "
|
|
148
|
+
return relayEnv(process.env, "HUMWICK_TOKEN_FILE");
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
export function runtimeTokenExpiresAtFileFromEnv(): string | undefined {
|
|
152
|
-
return relayEnv(process.env, "
|
|
152
|
+
return relayEnv(process.env, "HUMWICK_TOKEN_EXPIRES_AT_FILE");
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
// Deadline for a freshly spawned runner's INITIAL relay registration. Reconnects after the
|
|
@@ -158,13 +158,13 @@ export function runtimeTokenExpiresAtFileFromEnv(): string | undefined {
|
|
|
158
158
|
// an unreachable relay) must EXIT instead of hanging `active` forever — a hung runner is
|
|
159
159
|
// invisible to the orchestrator's exit detection, so the spawn-parent is never notified.
|
|
160
160
|
export function registrationTimeoutMsFromEnv(): number {
|
|
161
|
-
const parsed = Number(relayEnv(process.env, "
|
|
161
|
+
const parsed = Number(relayEnv(process.env, "HUMWICK_REGISTRATION_TIMEOUT_MS"));
|
|
162
162
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : 60_000;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
export { NATIVE_SELF_RESUME_TIMEOUT_MS, MIN_NATIVE_SELF_RESUME_TIMEOUT_MS, nativeSelfResumeTimeoutMsFromEnv } from "@humwick/sdk";
|
|
166
166
|
|
|
167
|
-
//
|
|
167
|
+
// self-compact e2e test rig — one-shot forced context utilization. When set, the runner
|
|
168
168
|
// REPORTS a synthetic ContextState at this utilization (lifecycleState "working", source "estimate",
|
|
169
169
|
// confidence "estimated") so the server's REAL 10s lifecycle tick fires the REAL advisory + REAL
|
|
170
170
|
// forced clear-inject exactly once — the actual compaction path is never stubbed. Accepts a fraction
|
|
@@ -172,7 +172,7 @@ export { NATIVE_SELF_RESUME_TIMEOUT_MS, MIN_NATIVE_SELF_RESUME_TIMEOUT_MS, nativ
|
|
|
172
172
|
// >1 after normalization) → undefined = feature OFF, and the runner's context reporting is UNCHANGED.
|
|
173
173
|
// The strict one-shot LATCH lives in runner-core (heartbeatRuntimeMeta + handleCommand), not here.
|
|
174
174
|
export function forceContextPctFromEnv(): number | undefined {
|
|
175
|
-
const raw = relayEnv(process.env, "
|
|
175
|
+
const raw = relayEnv(process.env, "HUMWICK_FORCE_CONTEXT_PCT");
|
|
176
176
|
if (raw === undefined || raw.trim() === "") return undefined;
|
|
177
177
|
const parsed = Number(raw);
|
|
178
178
|
if (!Number.isFinite(parsed) || parsed <= 0) return undefined;
|
|
@@ -186,24 +186,24 @@ export function forceContextPctFromEnv(): number | undefined {
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
export function agentProfileNameFromEnv(): string | undefined {
|
|
189
|
-
return relayEnv(process.env, "
|
|
189
|
+
return relayEnv(process.env, "HUMWICK_AGENT_PROFILE");
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
/** Explicit launch policy is independent of whether the named profile still exists. */
|
|
193
193
|
export function harnessSubagentsFromEnv(env: Record<string, string | undefined> = process.env): boolean | undefined {
|
|
194
|
-
const value = relayEnv(env, "
|
|
194
|
+
const value = relayEnv(env, "HUMWICK_HARNESS_SUBAGENTS");
|
|
195
195
|
return value === "1" ? true : value === "0" ? false : undefined;
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
export function agentProfileJsonFromEnv(): string | undefined {
|
|
199
|
-
return textEnvOrFile("
|
|
199
|
+
return textEnvOrFile("HUMWICK_AGENT_PROFILE_JSON");
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
export function workspaceJsonFromEnv(): string | undefined {
|
|
203
|
-
return textEnvOrFile("
|
|
203
|
+
return textEnvOrFile("HUMWICK_WORKSPACE_JSON");
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
/**
|
|
206
|
+
/** the toolchain the orchestrator launched this runner on, reported at registration; the relay validates it. */
|
|
207
207
|
export function projectToolchainFromEnv(): ProjectToolchain | undefined {
|
|
208
208
|
try {
|
|
209
209
|
const parsed: unknown = JSON.parse(relayEnv(process.env, PROJECT_TOOLCHAIN_ENV) ?? "");
|
|
@@ -214,52 +214,52 @@ export function projectToolchainFromEnv(): ProjectToolchain | undefined {
|
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
export function relayInjectionEventsJsonFromEnv(): string | undefined {
|
|
217
|
-
return textEnvOrFile("
|
|
217
|
+
return textEnvOrFile("HUMWICK_INJECTION_EVENTS_JSON");
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
export function promptFromEnv(): string | undefined {
|
|
221
|
-
return textEnvOrFile("
|
|
221
|
+
return textEnvOrFile("HUMWICK_PROMPT");
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
export function systemPromptAppendFromEnv(): string | undefined {
|
|
225
|
-
return textEnvOrFile("
|
|
225
|
+
return textEnvOrFile("HUMWICK_SYSTEM_PROMPT_APPEND");
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
export function tmuxSessionFromEnv(): string | undefined {
|
|
229
|
-
return relayEnv(process.env, "
|
|
229
|
+
return relayEnv(process.env, "HUMWICK_TMUX_SESSION");
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
export function policyNameFromEnv(): string | undefined {
|
|
233
|
-
return relayEnv(process.env, "
|
|
233
|
+
return relayEnv(process.env, "HUMWICK_POLICY");
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
export function spawnRequestIdFromEnv(): string | undefined {
|
|
237
|
-
return relayEnv(process.env, "
|
|
237
|
+
return relayEnv(process.env, "HUMWICK_SPAWN_REQUEST_ID");
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
export function taskIdFromEnv(): number | undefined {
|
|
241
|
-
const parsed = Number(relayEnv(process.env, "
|
|
241
|
+
const parsed = Number(relayEnv(process.env, "HUMWICK_TASK_ID"));
|
|
242
242
|
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined;
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
export function automationIdFromEnv(): string | undefined {
|
|
246
|
-
return relayEnv(process.env, "
|
|
246
|
+
return relayEnv(process.env, "HUMWICK_AUTOMATION_ID");
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
export function automationRunIdFromEnv(): string | undefined {
|
|
250
|
-
return relayEnv(process.env, "
|
|
250
|
+
return relayEnv(process.env, "HUMWICK_AUTOMATION_RUN_ID");
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
export function lifecycleFromEnv(): string | undefined {
|
|
254
|
-
return relayEnv(process.env, "
|
|
254
|
+
return relayEnv(process.env, "HUMWICK_LIFECYCLE");
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
export function sessionDebugEnabled(): boolean {
|
|
258
|
-
return relayEnv(process.env, "
|
|
258
|
+
return relayEnv(process.env, "HUMWICK_SESSION_DEBUG") === "1";
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
export function logLevelFromEnv(): string | undefined {
|
|
262
|
-
return relayEnv(process.env, "
|
|
262
|
+
return relayEnv(process.env, "HUMWICK_LOG_LEVEL");
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
function envSwitchOn(name: string): boolean {
|
|
@@ -267,26 +267,26 @@ function envSwitchOn(name: string): boolean {
|
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
export function mcpProxyEnabledFromEnv(): boolean {
|
|
270
|
-
return envSwitchOn("
|
|
270
|
+
return envSwitchOn("HUMWICK_MCP_PROXY");
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
-
/**
|
|
273
|
+
/** rollback switch for agent-redact secret redaction hooks. */
|
|
274
274
|
export function redactionEnabledFromEnv(): boolean {
|
|
275
|
-
return envSwitchOn("
|
|
275
|
+
return envSwitchOn("HUMWICK_REDACT");
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
export function runnerInfoFileFromEnv(): string | undefined {
|
|
279
|
-
return relayEnv(process.env, "
|
|
279
|
+
return relayEnv(process.env, "HUMWICK_RUNNER_INFO_FILE");
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
-
//
|
|
282
|
+
// the owning orchestrator's state-home id, stamped onto each tmux session
|
|
283
283
|
// (@agent-relay-owner) so the wedged-session reaper only reaps sessions it owns.
|
|
284
284
|
export function tmuxOwnerIdFromEnv(): string | undefined {
|
|
285
|
-
return relayEnv(process.env, "
|
|
285
|
+
return relayEnv(process.env, "HUMWICK_TMUX_OWNER");
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
export function runnerOutboxDirFromEnv(): string | undefined {
|
|
289
|
-
return relayEnv(process.env, "
|
|
289
|
+
return relayEnv(process.env, "HUMWICK_RUNNER_OUTBOX_DIR");
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
export function runnerOutboxDirWithInfoFallback(): string | undefined {
|
|
@@ -297,25 +297,25 @@ export function runnerOutboxDirWithInfoFallback(): string | undefined {
|
|
|
297
297
|
}
|
|
298
298
|
|
|
299
299
|
export function capsFromEnv(): string | undefined {
|
|
300
|
-
return relayEnv(process.env, "
|
|
300
|
+
return relayEnv(process.env, "HUMWICK_CAPS");
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
export function tagsFromEnv(): string | undefined {
|
|
304
|
-
return relayEnv(process.env, "
|
|
304
|
+
return relayEnv(process.env, "HUMWICK_TAGS");
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
export function workspaceModeFromEnv(): string | undefined {
|
|
308
|
-
return relayEnv(process.env, "
|
|
308
|
+
return relayEnv(process.env, "HUMWICK_WORKSPACE_MODE");
|
|
309
309
|
}
|
|
310
310
|
|
|
311
311
|
export function orchestratorBaseDirFromEnv(): string | undefined {
|
|
312
|
-
return relayEnv(process.env, "
|
|
312
|
+
return relayEnv(process.env, "HUMWICK_ORCHESTRATOR_BASE_DIR");
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
/**
|
|
316
316
|
* The orchestrator stamps its stable Relay id on every managed runner. Central
|
|
317
317
|
* provider configuration is keyed by that id, rather than the mutable OS hostname
|
|
318
|
-
* (for example, orchestrator `
|
|
318
|
+
* (for example, orchestrator `worker-a` may report hostname `worker-a-1`). Interactive
|
|
319
319
|
* runners have no owner id and retain the hostname-scoped fallback.
|
|
320
320
|
*/
|
|
321
321
|
export function providerConfigHostFromEnv(): string {
|
|
@@ -326,7 +326,7 @@ export function providerConfigHostFromEnv(): string {
|
|
|
326
326
|
export function providerConfigLookupFromEnv(): { host: string; legacyHost?: string; managed: boolean } {
|
|
327
327
|
const managedHost = localOrchestratorIdFromEnv();
|
|
328
328
|
if (!managedHost) return { host: hostname(), managed: false };
|
|
329
|
-
const legacyHost = relayEnv(process.env, "
|
|
329
|
+
const legacyHost = relayEnv(process.env, "HUMWICK_ORCHESTRATOR_HOSTNAME")?.trim();
|
|
330
330
|
return {
|
|
331
331
|
host: managedHost,
|
|
332
332
|
...(legacyHost && legacyHost !== managedHost ? { legacyHost } : {}),
|
|
@@ -335,23 +335,23 @@ export function providerConfigLookupFromEnv(): { host: string; legacyHost?: stri
|
|
|
335
335
|
}
|
|
336
336
|
|
|
337
337
|
export function runnerLogFileFromEnv(): string | undefined {
|
|
338
|
-
return typeof relayEnv(process.env, "
|
|
338
|
+
return typeof relayEnv(process.env, "HUMWICK_LOG_FILE") === "string" ? relayEnv(process.env, "HUMWICK_LOG_FILE") : undefined;
|
|
339
339
|
}
|
|
340
340
|
|
|
341
341
|
export function orchestratorUrlFromEnv(): string | undefined {
|
|
342
|
-
return relayEnv(process.env, "
|
|
342
|
+
return relayEnv(process.env, "HUMWICK_ORCHESTRATOR_URL");
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
export function contextStateDirFromEnv(): string | undefined {
|
|
346
|
-
return relayEnv(process.env, "
|
|
346
|
+
return relayEnv(process.env, "HUMWICK_CONTEXT_STATE_DIR");
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
export function attachmentCacheDirFromEnv(): string | undefined {
|
|
350
|
-
return relayEnv(process.env, "
|
|
350
|
+
return relayEnv(process.env, "HUMWICK_ATTACHMENT_CACHE_DIR");
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
export function providerHomeRootFromEnv(): string {
|
|
354
|
-
return relayEnv(process.env, "
|
|
354
|
+
return relayEnv(process.env, "HUMWICK_PROVIDER_HOME_ROOT") || join(homedir(), ".humwick", "provider-homes");
|
|
355
355
|
}
|
|
356
356
|
|
|
357
357
|
export function loadProviderConfig(provider: string, home = humwickHome()): LoadedProviderConfig {
|
|
@@ -370,7 +370,7 @@ export function loadProviderConfig(provider: string, home = humwickHome()): Load
|
|
|
370
370
|
defaultTags: stringArray(raw.defaultTags) ?? defaults.defaultTags,
|
|
371
371
|
chatCaptureMode: enumValue(raw.chatCaptureMode, ["final", "full"]) ?? defaults.chatCaptureMode,
|
|
372
372
|
reasoningCapture: booleanValue(raw.reasoningCapture) ?? defaults.reasoningCapture,
|
|
373
|
-
//
|
|
373
|
+
// an invalid value falls back to absent, which the steer policy resolves through
|
|
374
374
|
// the owning adapter's default.
|
|
375
375
|
activeTurnMessageDelivery: enumValue(raw.activeTurnMessageDelivery, [...ACTIVE_TURN_MESSAGE_DELIVERY_VALUES]),
|
|
376
376
|
headless: {
|
|
@@ -399,7 +399,7 @@ export async function loadProviderConfigFromRelay(
|
|
|
399
399
|
attemptedKeys.push(legacyKey);
|
|
400
400
|
const legacy = await fetchProviderConfig(provider, opts.relayUrl, opts.token, legacyKey, retry);
|
|
401
401
|
if (legacy && legacy.version > 0) {
|
|
402
|
-
console.warn(`[
|
|
402
|
+
console.warn(`[humwick] central provider config ${key} is missing; using legacy hostname key ${legacyKey}. Migrate this row to ${key}.`);
|
|
403
403
|
return legacy.config;
|
|
404
404
|
}
|
|
405
405
|
if (!fetched && legacy) return legacy.config;
|
|
@@ -407,9 +407,9 @@ export async function loadProviderConfigFromRelay(
|
|
|
407
407
|
if (fetched) return fetched.config;
|
|
408
408
|
if (opts.managed) throw new Error(`central provider config missing for managed keys ${attemptedKeys.join(", ")}`);
|
|
409
409
|
} catch (error) {
|
|
410
|
-
//
|
|
410
|
+
// a local fallback can select a different, obsolete provider binary.
|
|
411
411
|
if (opts.managed) throw new Error(`Managed provider config ${key} could not be loaded: ${errMessage(error)}`);
|
|
412
|
-
console.warn(`[
|
|
412
|
+
console.warn(`[humwick] provider config relay read failed (${errMessage(error)}); using local fallback ${local.path}.`);
|
|
413
413
|
}
|
|
414
414
|
return local;
|
|
415
415
|
}
|
|
@@ -510,6 +510,7 @@ async function fetchProviderConfig(
|
|
|
510
510
|
retry?: Partial<StartupFetchDeps>,
|
|
511
511
|
): Promise<{ config: LoadedProviderConfig; version: number } | null> {
|
|
512
512
|
const url = new URL(`/api/settings/provider-config/${encodeURIComponent(key)}`, relayUrl);
|
|
513
|
+
url.searchParams.set("effectiveEnv", "true");
|
|
513
514
|
const { response: res, body } = await fetchStartupConfig(url, token, retry ? RUNNER_CONFIG_RETRY_TIMEOUT_MS : 0, retry);
|
|
514
515
|
if (res.status === 404) return null;
|
|
515
516
|
if (!res.ok) throw new Error(body?.error ? `${res.status}: ${body.error}` : `HTTP ${res.status}`);
|
|
@@ -517,7 +518,7 @@ async function fetchProviderConfig(
|
|
|
517
518
|
|| !isRecord(body.value) || !stringValue(body.value.command)) {
|
|
518
519
|
throw new Error(`invalid central provider config response for ${key}`);
|
|
519
520
|
}
|
|
520
|
-
// Version zero is the hub's resolved default, not a failed config read
|
|
521
|
+
// Version zero is the hub's resolved default, not a failed config read.
|
|
521
522
|
return { config: providerConfigFromValue(provider, body.value, `config:provider-config/${key}`), version: body.version! };
|
|
522
523
|
}
|
|
523
524
|
|
|
@@ -536,7 +537,7 @@ function providerConfigFromValue(provider: string, value: unknown, path: string)
|
|
|
536
537
|
defaultTags: stringArray(raw.defaultTags) ?? defaults.defaultTags,
|
|
537
538
|
chatCaptureMode: enumValue(raw.chatCaptureMode, ["final", "full"]) ?? defaults.chatCaptureMode,
|
|
538
539
|
reasoningCapture: booleanValue(raw.reasoningCapture) ?? defaults.reasoningCapture,
|
|
539
|
-
//
|
|
540
|
+
// an invalid value falls back to absent, which the steer policy resolves through
|
|
540
541
|
// the owning adapter's default.
|
|
541
542
|
activeTurnMessageDelivery: enumValue(raw.activeTurnMessageDelivery, [...ACTIVE_TURN_MESSAGE_DELIVERY_VALUES]),
|
|
542
543
|
headless: {
|
package/src/context-boundary.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { errMessage } from "@humwick/sdk";
|
|
|
2
2
|
import type { ProviderStatusUpdate } from "./adapter";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Relay lists the agent's reads when a provider context resets. A reset fact goes out only after
|
|
6
6
|
* every delivery settlement started before it, so each mark-read the old context started has committed or
|
|
7
7
|
* failed by then; a failed one leaves its message unread.
|
|
8
8
|
*/
|
|
@@ -22,7 +22,7 @@ export class DeliverySettlements {
|
|
|
22
22
|
|
|
23
23
|
export type ContextResetKind = "compact" | "clear";
|
|
24
24
|
|
|
25
|
-
/** A boundary command that gave up before its destructive input reached the provider
|
|
25
|
+
/** A boundary command that gave up before its destructive input reached the provider. */
|
|
26
26
|
export class ContextSubmitAborted extends Error {}
|
|
27
27
|
|
|
28
28
|
export interface ContextResetFact {
|
|
@@ -34,16 +34,16 @@ export interface ContextResetFact {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
37
|
+
* (docs/design/self-resume-carry.md) — one reset fact per genuine provider reset, waited for or not.
|
|
38
38
|
* Submitted destructive inputs stay in order until provider evidence settles one: a manual reset settles
|
|
39
39
|
* the oldest of its kind, an automatic one none. A timed-out command keeps input the provider holds.
|
|
40
40
|
*/
|
|
41
|
-
/** How long a reset the adapter confirmed may still be observed as its provider status
|
|
41
|
+
/** How long a reset the adapter confirmed may still be observed as its provider status. */
|
|
42
42
|
export const CONFIRMED_RESET_OBSERVE_WINDOW_MS = 60_000;
|
|
43
43
|
|
|
44
44
|
export class ContextResetReporter {
|
|
45
45
|
private readonly submitted: Array<{ commandId: string; kind: ContextResetKind }> = [];
|
|
46
|
-
/**
|
|
46
|
+
/** confirmed by the adapter before its provider status arrived: that status is the SAME reset. */
|
|
47
47
|
private readonly confirmedUnobserved: Array<{ commandId: string; kind: ContextResetKind; at: number }> = [];
|
|
48
48
|
|
|
49
49
|
/** `onUncommandedReset` runs at observation for a reset no boundary command caused (operator `/clear`, auto-compaction). */
|
package/src/context-command.ts
CHANGED
|
@@ -26,7 +26,7 @@ export class ClearInjectInboxFence {
|
|
|
26
26
|
const pending = this.pending;
|
|
27
27
|
if (pending?.commandId !== commandId) return;
|
|
28
28
|
pending.clearing = awaitingLateClear;
|
|
29
|
-
//
|
|
29
|
+
// the continuation backstop may never arrive; wake the inbox independently.
|
|
30
30
|
pending.timer = setTimeout(() => {
|
|
31
31
|
if (this.pending !== pending) return;
|
|
32
32
|
this.reset();
|
|
@@ -69,8 +69,8 @@ interface LateClearContinuation {
|
|
|
69
69
|
export function lateClearHookContent(recovery: LateClearContinuation): string {
|
|
70
70
|
if (recovery.content.length <= LATE_CLEAR_HOOK_MAX_CHARS) return recovery.content;
|
|
71
71
|
const fetch = recovery.fullContextMessageId
|
|
72
|
-
? `
|
|
73
|
-
: '
|
|
72
|
+
? `humwick_get_message #${recovery.fullContextMessageId} (CLI: humwick get-message ${recovery.fullContextMessageId})`
|
|
73
|
+
: 'humwick_recall with query "latest working state"';
|
|
74
74
|
return `A delayed /clear committed after its confirmation timed out. Your saved continuation exceeds the hook context limit. Retrieve it with ${fetch} before resuming work; the full continuation was not injected here.`;
|
|
75
75
|
}
|
|
76
76
|
|