@humwick/runner 0.130.4 → 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/LICENSE +661 -167
- 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 +8 -11
- 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.provisioned.mjs +1 -1
- package/plugins/claude/hooks/kill-guard.sh +4 -4
- package/plugins/claude/hooks/kill-guard.ts +2 -2
- 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 +3 -3
- 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 +3 -3
- 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 +3 -3
- 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/plugins/claude/skills/disconnect/SKILL.md +0 -16
- package/plugins/claude/skills/pair/SKILL.md +0 -30
- package/plugins/codex/skills/disconnect/SKILL.md +0 -15
- package/plugins/codex/skills/pair/SKILL.md +0 -29
- package/src/adapters/provider-quota-harvest.ts +0 -76
|
@@ -1,20 +1,36 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// sdk/src/env.ts
|
|
3
|
-
function
|
|
4
|
-
return name
|
|
3
|
+
function relayEnv(env, name) {
|
|
4
|
+
return env?.[name];
|
|
5
5
|
}
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
|
|
7
|
+
// sdk/src/types/guards.ts
|
|
8
|
+
function isRecord(value) {
|
|
9
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8
10
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
|
|
12
|
+
// sdk/src/stored-names.ts
|
|
13
|
+
var STORED_NAMES = {
|
|
14
|
+
source: "humwick",
|
|
15
|
+
profileKey: "humwick",
|
|
16
|
+
channelSchema: "humwick.channel.v1",
|
|
17
|
+
reactionSchema: "humwick.reaction.v1",
|
|
18
|
+
connectorSchema: "humwick.connector.v1",
|
|
19
|
+
bundledSource: "humwick-bundled",
|
|
20
|
+
bundledSeed: "humwick-bundled-seed",
|
|
21
|
+
qaSeed: "humwick-qa-skill-seed",
|
|
22
|
+
callmuxSeed: "humwick-shared-callmux-seed",
|
|
23
|
+
taskCommentMarker: "humwick:task-comment"
|
|
24
|
+
};
|
|
25
|
+
var SHARED_PROFILE_CAPABILITIES = {
|
|
26
|
+
instructions: `${STORED_NAMES.source}.instructions`,
|
|
27
|
+
mcp: `${STORED_NAMES.source}.mcp`,
|
|
28
|
+
hooks: `${STORED_NAMES.source}.hooks`,
|
|
29
|
+
skills: `${STORED_NAMES.source}.skills`,
|
|
30
|
+
plugins: `${STORED_NAMES.source}.plugins`
|
|
31
|
+
};
|
|
32
|
+
function readHumwickRecord(value) {
|
|
33
|
+
return isRecord(value?.humwick) ? value.humwick : undefined;
|
|
18
34
|
}
|
|
19
35
|
|
|
20
36
|
// sdk/src/types/users.ts
|
|
@@ -42,17 +58,12 @@ function heldForSender(message) {
|
|
|
42
58
|
return typeof heldFor === "string" && heldFor ? heldFor : undefined;
|
|
43
59
|
}
|
|
44
60
|
|
|
45
|
-
// sdk/src/types/guards.ts
|
|
46
|
-
function isRecord(value) {
|
|
47
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
61
|
// runner/src/message-body-config/config.ts
|
|
51
62
|
function monitorDeliveryMaxCharsFromEnv() {
|
|
52
|
-
return relayEnv(process.env, "
|
|
63
|
+
return relayEnv(process.env, "HUMWICK_MONITOR_DELIVERY_MAX_CHARS");
|
|
53
64
|
}
|
|
54
65
|
function monitorDeliveryLineMaxCharsFromEnv() {
|
|
55
|
-
return relayEnv(process.env, "
|
|
66
|
+
return relayEnv(process.env, "HUMWICK_MONITOR_DELIVERY_LINE_MAX_CHARS");
|
|
56
67
|
}
|
|
57
68
|
// runner/src/relay-instructions.ts
|
|
58
69
|
import { existsSync } from "fs";
|
|
@@ -81,8 +92,8 @@ function lines(...parts) {
|
|
|
81
92
|
return parts.join(`
|
|
82
93
|
`);
|
|
83
94
|
}
|
|
84
|
-
var RELAY_RUN_STANDING_INSTRUCTIONS = lines("## Long-running commands", "Run commands that may print secrets (ssh to hosts, reading env/config files, secret tooling) through `
|
|
85
|
-
var RELAY_REPLY_INSTRUCTIONS = 'Reply to an agent\'s Relay message with `
|
|
95
|
+
var RELAY_RUN_STANDING_INSTRUCTIONS = lines("## Long-running commands", "Run commands that may print secrets (ssh to hosts, reading env/config files, secret tooling) through `humwick_run`, never raw Bash/shell tools. Relay masks stdout/stderr before storing logs or returning output, even on a nonzero exit; masker failures withhold output. Inspect exitCode, signal and timedOut. Reference secret files or variables; never paste secret literals into the command.", "Run long commands, gates, builds and tests through `humwick_run` with `waitMs: 0`, then END YOUR TURN and wait for Relay's completion wake (finish, failure or timeout). If it returns queued or still-running, end your turn too.", "Waiting for a condition (epoch closes, deploy finishes, land merges, service healthy, file appears) is also a long command: start ONE detached `humwick_run` whose command is a poll loop with a deadline (e.g. `timeout 30m bash -c 'until <check>; do sleep 20; done'`), then END YOUR TURN with no text. Never check once per turn, sleep in the foreground, or keep the turn alive with Monitor/until loops: every turn end is forwarded to your parent as a message.", "A detached wait is exempt from periodic progress-update instructions, including updates every 60 seconds. Never poll with `humwick_run{runId}`, `write_stdin`, sleep, ps or tail. Resume on the completion notification and check the reported exit status; missing output or exit status is not a pass.", "This rule overrides older profile, working-state, compaction or recovery guidance that recommends raw exec sessions or polling for long commands. Do not edit the worktree while validation is running.");
|
|
96
|
+
var RELAY_REPLY_INSTRUCTIONS = 'Reply to an agent\'s Relay message with `humwick_reply` (messageId, body). CLI fallback: `humwick /reply <messageId> "<your reply>"`. Your turn response reaches the human user automatically: never send the user a Relay message to answer them. Send one reply per batch to the latest relevant message. Send no status-only confirmations.';
|
|
86
97
|
var REPOSITORY_SEARCH_FALLBACK = "Use available tools for repository search. If MCP search tools are missing or fail, use shell search (rg, grep, or find) and continue; never stall on a missing tool.";
|
|
87
98
|
var AGENT_CORE_TEMPLATE_SLUG = "relay.agent-core";
|
|
88
99
|
var TEMP_DIR_TEMPLATE_SLUG = "relay.temp-dir";
|
|
@@ -92,7 +103,7 @@ var RUNNER_PROMPT_TEMPLATE_DEFAULTS = [
|
|
|
92
103
|
slug: TEMP_DIR_TEMPLATE_SLUG,
|
|
93
104
|
category: "runner",
|
|
94
105
|
title: "Private Temp Dir",
|
|
95
|
-
description: "Shown to every session with Relay context: the agent's TMPDIR is private and reaped
|
|
106
|
+
description: "Shown to every session with Relay context: the agent's TMPDIR is private and reaped.",
|
|
96
107
|
template: TEMP_DIR_RULE,
|
|
97
108
|
defaultTemplate: TEMP_DIR_RULE,
|
|
98
109
|
variables: []
|
|
@@ -119,7 +130,7 @@ var RUNNER_PROMPT_TEMPLATE_DEFAULTS = [
|
|
|
119
130
|
slug: "relay.web.fetch",
|
|
120
131
|
category: "runner",
|
|
121
132
|
title: "URL Reader Steer (local first)",
|
|
122
|
-
description: "The page-reader capability: {{tools}} is local; {{fallback}} is keyless Jina. Replaces the old Jina-first steer
|
|
133
|
+
description: "The page-reader capability: {{tools}} is local; {{fallback}} is keyless Jina. Replaces the old Jina-first steer.",
|
|
123
134
|
template: "Read a known URL: use the self-hosted page reader {{tools}} first. Use max_length (default 5000 characters) and start_index to read large pages in chunks; respect robots.txt refusals. Only if it fails or returns unusable JS-heavy content, use keyless Jina {{fallback}} with url only (no question or API key). Jina shares a low per-IP limit across the fleet; if it also fails, use the built-in fetch once. Never retry in a loop or use readers to search.",
|
|
124
135
|
defaultTemplate: "Read a known URL: use the self-hosted page reader {{tools}} first. Use max_length (default 5000 characters) and start_index to read large pages in chunks; respect robots.txt refusals. Only if it fails or returns unusable JS-heavy content, use keyless Jina {{fallback}} with url only (no question or API key). Jina shares a low per-IP limit across the fleet; if it also fails, use the built-in fetch once. Never retry in a loop or use readers to search.",
|
|
125
136
|
variables: ["tools", "fallback"]
|
|
@@ -146,8 +157,8 @@ var RUNNER_PROMPT_TEMPLATE_DEFAULTS = [
|
|
|
146
157
|
category: "runner",
|
|
147
158
|
title: "Claude Relay Manual",
|
|
148
159
|
description: "Bundled CLAUDE.md relay manual written into provisioned Claude homes.",
|
|
149
|
-
template: lines("#
|
|
150
|
-
defaultTemplate: lines("#
|
|
160
|
+
template: lines("# Humwick", "", "- Relay messages can come from people, channels, or agents. Read the body and do the work.", "- For a truncated delivery stub, fetch its body with `humwick_get_message` (messageId) or `humwick get-message <messageId>`.", "- Do not reply to pure info, passive acknowledgements, or reactions without an action request. Never reply or react to a notification-class message; act on it if relevant.", "- If a provider permission prompt holds your current tool call and Relay tools still work, tell your coordinator which tool is held. Do not depend on this report for rescue: a prompt on the Relay call itself can block reporting.", "- Use `humwick /react <messageId> <emoji>` for lightweight acknowledgement, approval, thanks, praise, a completed handoff, or an FYI\u2014not questions, tasks, bugs, or textual results. \uD83D\uDC4D to your question approves proceeding; \uD83D\uDC4D to completed status means no further action.", "- Use `humwick /status --json` for identity and `humwick /guide` for command details."),
|
|
161
|
+
defaultTemplate: lines("# Humwick", "", "- Relay messages can come from people, channels, or agents. Read the body and do the work.", "- For a truncated delivery stub, fetch its body with `humwick_get_message` (messageId) or `humwick get-message <messageId>`.", "- Do not reply to pure info, passive acknowledgements, or reactions without an action request. Never reply or react to a notification-class message; act on it if relevant.", "- If a provider permission prompt holds your current tool call and Relay tools still work, tell your coordinator which tool is held. Do not depend on this report for rescue: a prompt on the Relay call itself can block reporting.", "- Use `humwick /react <messageId> <emoji>` for lightweight acknowledgement, approval, thanks, praise, a completed handoff, or an FYI\u2014not questions, tasks, bugs, or textual results. \uD83D\uDC4D to your question approves proceeding; \uD83D\uDC4D to completed status means no further action.", "- Use `humwick /status --json` for identity and `humwick /guide` for command details."),
|
|
151
162
|
variables: []
|
|
152
163
|
},
|
|
153
164
|
{
|
|
@@ -155,8 +166,8 @@ var RUNNER_PROMPT_TEMPLATE_DEFAULTS = [
|
|
|
155
166
|
category: "runner",
|
|
156
167
|
title: "Claude Relay Context",
|
|
157
168
|
description: "One-line relay context note for Claude sessions.",
|
|
158
|
-
template: "[
|
|
159
|
-
defaultTemplate: "[
|
|
169
|
+
template: "[humwick] Relay is available. Follow the Humwick rules in CLAUDE.md when present, or run humwick /guide.",
|
|
170
|
+
defaultTemplate: "[humwick] Relay is available. Follow the Humwick rules in CLAUDE.md when present, or run humwick /guide.",
|
|
160
171
|
variables: []
|
|
161
172
|
},
|
|
162
173
|
{
|
|
@@ -164,8 +175,8 @@ var RUNNER_PROMPT_TEMPLATE_DEFAULTS = [
|
|
|
164
175
|
category: "runner",
|
|
165
176
|
title: "Claude Relay Context (Read Only)",
|
|
166
177
|
description: "Read-only relay context note for Claude sessions.",
|
|
167
|
-
template: lines("[
|
|
168
|
-
defaultTemplate: lines("[
|
|
178
|
+
template: lines("[humwick] Relay is available. Follow the Humwick rules in CLAUDE.md when present, or run humwick /guide.", "", "This Claude session is running with restricted read-only Relay permissions. Do not invoke Humwick skills. Use the CLI for Relay actions."),
|
|
179
|
+
defaultTemplate: lines("[humwick] Relay is available. Follow the Humwick rules in CLAUDE.md when present, or run humwick /guide.", "", "This Claude session is running with restricted read-only Relay permissions. Do not invoke Humwick skills. Use the CLI for Relay actions."),
|
|
169
180
|
variables: []
|
|
170
181
|
},
|
|
171
182
|
{
|
|
@@ -173,8 +184,8 @@ var RUNNER_PROMPT_TEMPLATE_DEFAULTS = [
|
|
|
173
184
|
category: "runner",
|
|
174
185
|
title: "Codex Relay Context",
|
|
175
186
|
description: "Relay context note injected into Codex sessions.",
|
|
176
|
-
template: "[
|
|
177
|
-
defaultTemplate: "[
|
|
187
|
+
template: "[humwick] Relay is available. Identity and capabilities are in `## Humwick Identity`; tool access follows those capabilities. Details: `humwick /guide`.",
|
|
188
|
+
defaultTemplate: "[humwick] Relay is available. Identity and capabilities are in `## Humwick Identity`; tool access follows those capabilities. Details: `humwick /guide`.",
|
|
178
189
|
variables: []
|
|
179
190
|
},
|
|
180
191
|
{
|
|
@@ -182,8 +193,8 @@ var RUNNER_PROMPT_TEMPLATE_DEFAULTS = [
|
|
|
182
193
|
category: "runner",
|
|
183
194
|
title: "OpenCode Relay Context",
|
|
184
195
|
description: "Relay context note injected into OpenCode sessions.",
|
|
185
|
-
template: "[
|
|
186
|
-
defaultTemplate: "[
|
|
196
|
+
template: "[humwick] Relay messages can come from people, channels, or agents: read each message and do its work. Fetch a truncated delivery with `humwick get-message <messageId>`. Use `humwick /react <messageId> <emoji>` only for lightweight acknowledgement. Run `humwick /status --json` for identity and `humwick /guide` for command details.",
|
|
197
|
+
defaultTemplate: "[humwick] Relay messages can come from people, channels, or agents: read each message and do its work. Fetch a truncated delivery with `humwick get-message <messageId>`. Use `humwick /react <messageId> <emoji>` only for lightweight acknowledgement. Run `humwick /status --json` for identity and `humwick /guide` for command details.",
|
|
187
198
|
variables: []
|
|
188
199
|
},
|
|
189
200
|
{
|
|
@@ -191,8 +202,8 @@ var RUNNER_PROMPT_TEMPLATE_DEFAULTS = [
|
|
|
191
202
|
category: "runner",
|
|
192
203
|
title: "Runner Workspace Lifecycle Note",
|
|
193
204
|
description: "Lifecycle note injected by the runner for isolated workspaces.",
|
|
194
|
-
template: lines("[
|
|
195
|
-
defaultTemplate: lines("[
|
|
205
|
+
template: lines("[humwick] You are in worktree branch {{branch}}, based on {{baseRef}}, not main. Other agents land to {{baseRef}}; it moving is normal.", "While iterating, run only affected tests via the project command when available; the full gate runs automatically at land/merge.", "Commit here; pushing your own branch and rebasing before delivery are allowed. Never push to main or {{baseRef}}; never rebase or rewrite history after a `complete` delivery has armed a land. Do not merge, resolve conflicts, or enter the main checkout. Relay/steward own those and may rebase in background. When done, self-report the configured validation result through `humwick_task_deliver` with `complete`, summary, commits, and passing `typecheck` + `test` gates when the diff touches code/test/config paths. It skips code gates for empty/docs-only diffs, rebases onto {{baseRef}}, lands, and pushes.", "Accepted delivery means status becomes `ready`: NORMAL, healthy handoff, not a stall. Stop your turn; do not poll. Clean rebases auto-merge about every two minutes; a steward appears only when deterministic landing fails. Relay wakes `landed-success` or `landed-failure`; on success it keeps this worktree on its current post-land branch, and the next delivery rebases it against the latest base. `humwick workspace status` shows the next step."),
|
|
206
|
+
defaultTemplate: lines("[humwick] You are in worktree branch {{branch}}, based on {{baseRef}}, not main. Other agents land to {{baseRef}}; it moving is normal.", "While iterating, run only affected tests via the project command when available; the full gate runs automatically at land/merge.", "Commit here; pushing your own branch and rebasing before delivery are allowed. Never push to main or {{baseRef}}; never rebase or rewrite history after a `complete` delivery has armed a land. Do not merge, resolve conflicts, or enter the main checkout. Relay/steward own those and may rebase in background. When done, self-report the configured validation result through `humwick_task_deliver` with `complete`, summary, commits, and passing `typecheck` + `test` gates when the diff touches code/test/config paths. It skips code gates for empty/docs-only diffs, rebases onto {{baseRef}}, lands, and pushes.", "Accepted delivery means status becomes `ready`: NORMAL, healthy handoff, not a stall. Stop your turn; do not poll. Clean rebases auto-merge about every two minutes; a steward appears only when deterministic landing fails. Relay wakes `landed-success` or `landed-failure`; on success it keeps this worktree on its current post-land branch, and the next delivery rebases it against the latest base. `humwick workspace status` shows the next step."),
|
|
196
207
|
variables: ["branch", "baseRef"]
|
|
197
208
|
},
|
|
198
209
|
{
|
|
@@ -200,8 +211,8 @@ var RUNNER_PROMPT_TEMPLATE_DEFAULTS = [
|
|
|
200
211
|
category: "runner",
|
|
201
212
|
title: "Runner Workspace Deps Symlink Note",
|
|
202
213
|
description: "Symlinked node_modules caveat injected by the runner.",
|
|
203
|
-
template: "[
|
|
204
|
-
defaultTemplate: "[
|
|
214
|
+
template: "[humwick] Isolated workspace: this is a git worktree, and its node_modules are SYMLINKED from the main checkout \u2014 dependencies are already installed and ready to use. Do NOT run a clean dependency install (`bun install` / `npm install` / `pnpm install`): it writes through the symlink and mutates the main checkout's shared node_modules. Build caches written under node_modules are shared too. If typecheck/build fails on a missing module (a dependency added to the base AFTER this worktree was created), run `humwick workspace deps` \u2014 it re-provisions only the stale dirs with a real isolated install, safely, without touching the shared node_modules. If you genuinely need to change dependencies in isolation, ask the host to spawn with HUMWICK_WORKSPACE_DEPS=install.",
|
|
215
|
+
defaultTemplate: "[humwick] Isolated workspace: this is a git worktree, and its node_modules are SYMLINKED from the main checkout \u2014 dependencies are already installed and ready to use. Do NOT run a clean dependency install (`bun install` / `npm install` / `pnpm install`): it writes through the symlink and mutates the main checkout's shared node_modules. Build caches written under node_modules are shared too. If typecheck/build fails on a missing module (a dependency added to the base AFTER this worktree was created), run `humwick workspace deps` \u2014 it re-provisions only the stale dirs with a real isolated install, safely, without touching the shared node_modules. If you genuinely need to change dependencies in isolation, ask the host to spawn with HUMWICK_WORKSPACE_DEPS=install.",
|
|
205
216
|
variables: []
|
|
206
217
|
},
|
|
207
218
|
{
|
|
@@ -209,8 +220,8 @@ var RUNNER_PROMPT_TEMPLATE_DEFAULTS = [
|
|
|
209
220
|
category: "runner",
|
|
210
221
|
title: "Runner Workspace Deps Command Note",
|
|
211
222
|
description: "Repository-command dependency provisioning note injected by the runner.",
|
|
212
|
-
template: "[
|
|
213
|
-
defaultTemplate: "[
|
|
223
|
+
template: "[humwick] Isolated workspace: dependencies were provisioned by the repository command `{{installCommand}}`; node_modules is real, not shared with the main checkout. If dependencies drift, run `{{installCommand}}` yourself from the worktree root (or `humwick workspace deps` to ask Relay to rerun it).",
|
|
224
|
+
defaultTemplate: "[humwick] Isolated workspace: dependencies were provisioned by the repository command `{{installCommand}}`; node_modules is real, not shared with the main checkout. If dependencies drift, run `{{installCommand}}` yourself from the worktree root (or `humwick workspace deps` to ask Relay to rerun it).",
|
|
214
225
|
variables: ["installCommand"]
|
|
215
226
|
},
|
|
216
227
|
{
|
|
@@ -218,8 +229,8 @@ var RUNNER_PROMPT_TEMPLATE_DEFAULTS = [
|
|
|
218
229
|
category: "runner",
|
|
219
230
|
title: "Runner Workspace Deps None Note",
|
|
220
231
|
description: "Missing dependency provisioning caveat injected by the runner.",
|
|
221
|
-
template: "[
|
|
222
|
-
defaultTemplate: "[
|
|
232
|
+
template: "[humwick] Isolated workspace: dependencies were not provisioned (HUMWICK_WORKSPACE_DEPS=none). You may need to install node_modules before typecheck/test/build work.",
|
|
233
|
+
defaultTemplate: "[humwick] Isolated workspace: dependencies were not provisioned (HUMWICK_WORKSPACE_DEPS=none). You may need to install node_modules before typecheck/test/build work.",
|
|
223
234
|
variables: []
|
|
224
235
|
},
|
|
225
236
|
{
|
|
@@ -227,8 +238,8 @@ var RUNNER_PROMPT_TEMPLATE_DEFAULTS = [
|
|
|
227
238
|
category: "runner",
|
|
228
239
|
title: "Runner Workspace Symlink Note",
|
|
229
240
|
description: "Write-through symlink caveat injected by the runner.",
|
|
230
|
-
template: "[
|
|
231
|
-
defaultTemplate: "[
|
|
241
|
+
template: "[humwick] Isolated workspace: these untracked paths are SYMLINKED from the main checkout: {{linked}}. They resolve to the real files in main, so editing or deleting them writes THROUGH to main \u2014 treat them as read-only unless you intend to change main.",
|
|
242
|
+
defaultTemplate: "[humwick] Isolated workspace: these untracked paths are SYMLINKED from the main checkout: {{linked}}. They resolve to the real files in main, so editing or deleting them writes THROUGH to main \u2014 treat them as read-only unless you intend to change main.",
|
|
232
243
|
variables: []
|
|
233
244
|
}
|
|
234
245
|
];
|
|
@@ -266,7 +277,7 @@ function resolveRelayContext(input) {
|
|
|
266
277
|
return { available: text.length > 0, text };
|
|
267
278
|
}
|
|
268
279
|
function webToolsSteer(names, claude) {
|
|
269
|
-
return names.map((name) => name === "brave" ? `Web search: use ${claude ? "web_search on the
|
|
280
|
+
return names.map((name) => name === "brave" ? `Web search: use ${claude ? "web_search on the humwick MCP server (load with ToolSearch)" : "web_search on the humwick MCP server"}. Relay tries Tavily, then budget-capped Brave. If the monthly cap is reached, report it; do not retry in a loop.` : renderRunnerTemplate("relay.web.fetch", {
|
|
270
281
|
tools: webToolSteerRefs(name, claude),
|
|
271
282
|
fallback: webToolSteerRefs(name, claude, true)
|
|
272
283
|
})).join(`
|
|
@@ -305,7 +316,7 @@ function workspaceSymlinksNote(linked) {
|
|
|
305
316
|
return renderRunnerTemplate("workspace.symlinks", { linked: linked.join(", ") });
|
|
306
317
|
}
|
|
307
318
|
function workspaceDepsNoteFromEnv(env = process.env) {
|
|
308
|
-
const json = relayEnv(env, "
|
|
319
|
+
const json = relayEnv(env, "HUMWICK_WORKSPACE_JSON");
|
|
309
320
|
if (!json)
|
|
310
321
|
return "";
|
|
311
322
|
try {
|
|
@@ -366,8 +377,8 @@ function attachmentLabel(ref) {
|
|
|
366
377
|
}
|
|
367
378
|
function attachmentCacheMetadata(ref) {
|
|
368
379
|
const metadata = isRecord(ref.metadata) ? ref.metadata : undefined;
|
|
369
|
-
const
|
|
370
|
-
return
|
|
380
|
+
const humwick = readHumwickRecord(metadata);
|
|
381
|
+
return humwick;
|
|
371
382
|
}
|
|
372
383
|
function isMemoryInjection(message) {
|
|
373
384
|
return isRecord(message.payload) && message.payload.memoryInjection === true;
|
|
@@ -430,10 +441,10 @@ function providerAttachmentText(message) {
|
|
|
430
441
|
const canFetchMessage = isPersistedRelayMessage(message);
|
|
431
442
|
const guidance = !canFetchMessage ? [] : hasLocalPaths ? [
|
|
432
443
|
"Use the local path above when inspecting the attachment.",
|
|
433
|
-
`Read attachment details:
|
|
444
|
+
`Read attachment details: humwick get-message ${message.id} --json`
|
|
434
445
|
] : [
|
|
435
|
-
`Read attachment details:
|
|
436
|
-
`Fetch content: curl -fsS -H "X-
|
|
446
|
+
`Read attachment details: humwick get-message ${message.id} --json`,
|
|
447
|
+
`Fetch content: curl -fsS -H "X-Humwick-Token: $HUMWICK_TOKEN" "$HUMWICK_URL/api/artifacts/<artifactId>/content" -o <filename>`
|
|
437
448
|
];
|
|
438
449
|
return [
|
|
439
450
|
"Attachments:",
|
|
@@ -539,7 +550,7 @@ function spillMustKeepSection(section, spillDir, reserved) {
|
|
|
539
550
|
const bracket = `[${boundLabel(label, MAX_DISPLAY_LABEL_CHARS)} \u2014 spilled to disk, read it now]`;
|
|
540
551
|
const references = [
|
|
541
552
|
`Full content (byte-exact): ${filePath}`,
|
|
542
|
-
`File: ${fileName} \u2014 in your session scratch tmp dir ($
|
|
553
|
+
`File: ${fileName} \u2014 in your session scratch tmp dir ($HUMWICK_SCRATCH_DIR)`,
|
|
543
554
|
`File: ${fileName} (scratch dir)`,
|
|
544
555
|
`File: ${fileName}`
|
|
545
556
|
];
|
|
@@ -556,6 +567,26 @@ ${reference}`;
|
|
|
556
567
|
spilled: false
|
|
557
568
|
};
|
|
558
569
|
}
|
|
570
|
+
function readableEvent(items, reserved) {
|
|
571
|
+
const texts = items.map((item) => item.text);
|
|
572
|
+
let totalChars = texts.reduce((sum, text) => sum + text.length, Math.max(0, texts.length - 1) * 2);
|
|
573
|
+
for (let i = 0;i < items.length; i++) {
|
|
574
|
+
const item = items[i];
|
|
575
|
+
if (!item.stub)
|
|
576
|
+
continue;
|
|
577
|
+
for (const candidate of [item.full, item.preview]) {
|
|
578
|
+
if (candidate === undefined)
|
|
579
|
+
continue;
|
|
580
|
+
const otherChars = totalChars - texts[i].length;
|
|
581
|
+
if (!fitsMonitorDelivery(candidate, { reserved: reserved + otherChars }))
|
|
582
|
+
continue;
|
|
583
|
+
texts[i] = candidate;
|
|
584
|
+
totalChars = otherChars + candidate.length;
|
|
585
|
+
break;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
return { events: items.length ? [{ text: join(texts), messageIds: idsOf(items) }] : [] };
|
|
589
|
+
}
|
|
559
590
|
function packWithDeferredNotice(items, reserved) {
|
|
560
591
|
let kept = [];
|
|
561
592
|
const DEFERRED_NOTICE_BUDGET = 100;
|
|
@@ -587,7 +618,7 @@ function planClaudeMonitorDelivery(sections, options = {}) {
|
|
|
587
618
|
const rendered = sections.map((section) => ({ ...section, text: section.stub ?? section.full }));
|
|
588
619
|
const allStubbed = join(rendered.map((section) => section.text));
|
|
589
620
|
if (fitsMonitorDelivery(allStubbed, { reserved })) {
|
|
590
|
-
return
|
|
621
|
+
return readableEvent(rendered, reserved);
|
|
591
622
|
}
|
|
592
623
|
const mustKeep = rendered.filter((section) => !section.stub && section.kind !== "disposable");
|
|
593
624
|
const optional = rendered.filter((section) => section.stub || section.kind === "disposable");
|
|
@@ -619,7 +650,7 @@ function planClaudeMonitorDelivery(sections, options = {}) {
|
|
|
619
650
|
chunk = withSubstitute;
|
|
620
651
|
}
|
|
621
652
|
}
|
|
622
|
-
return
|
|
653
|
+
return readableEvent(chunk, reserved);
|
|
623
654
|
}
|
|
624
655
|
|
|
625
656
|
// runner/src/adapters/claude-delivery.ts
|
|
@@ -646,7 +677,7 @@ function formatMessage(message, relaySurface) {
|
|
|
646
677
|
const rawBody = relaySurface ? message.body : stripRelayScaffolding(message.body);
|
|
647
678
|
if (isMemoryContext) {
|
|
648
679
|
return [
|
|
649
|
-
`[
|
|
680
|
+
`[humwick ${isSelfResumeInjection(message) ? "self-resume continuation" : "context"} from ${message.from}]`,
|
|
650
681
|
providerAttachmentText(message),
|
|
651
682
|
`${subject}${rawBody}`
|
|
652
683
|
].filter(Boolean).join(`
|
|
@@ -706,17 +737,20 @@ function taskDeliverableSummary(message) {
|
|
|
706
737
|
lines.push(clampToLine(`Next: ${nextAction}`));
|
|
707
738
|
return lines.length > 0 ? lines : undefined;
|
|
708
739
|
}
|
|
709
|
-
function stubMessage(message) {
|
|
740
|
+
function stubMessage(message, includePreview = false) {
|
|
710
741
|
const gist = message.subject ? `Subject: ${clampToLine(message.subject)}` : firstSentence(message.body);
|
|
742
|
+
const preview = includePreview ? truncateToCaps(message.body, 400, monitorDeliveryLineMaxChars()) : "";
|
|
711
743
|
const summary = taskDeliverableSummary(message);
|
|
712
744
|
const fetchTarget = message.messageType === "final-turn" && message.sourceMessageId ? message.sourceMessageId : message.id;
|
|
713
745
|
const finalTurn = message.messageType === "final-turn" ? " | final turn" : "";
|
|
714
746
|
return [
|
|
715
747
|
receivesTurnResponseAutomatically(message.from) ? undefined : `[relay message #${message.id} from ${providerSenderLabel(message)}${finalTurn}]`,
|
|
716
|
-
gist || undefined,
|
|
748
|
+
message.subject || !preview ? gist || undefined : undefined,
|
|
717
749
|
...summary ?? [],
|
|
718
750
|
message.threadId !== undefined ? `Thread: #${message.threadId}` : undefined,
|
|
719
|
-
|
|
751
|
+
preview ? `Body preview (${preview.length} of ${message.body.length} chars):
|
|
752
|
+
${preview}` : undefined,
|
|
753
|
+
`Over monitor size limit \u2014 full ${message.messageType === "final-turn" ? "turn" : "message"}: humwick_get_message #${fetchTarget} (CLI: humwick get-message ${fetchTarget})`
|
|
720
754
|
].filter(Boolean).join(`
|
|
721
755
|
`);
|
|
722
756
|
}
|
|
@@ -726,7 +760,7 @@ function claudeMonitorDeliveryPlan(messages, options = {}) {
|
|
|
726
760
|
const sections = uniqueMessages.map((message) => ({
|
|
727
761
|
id: isPersistedRelayMessage(message) ? message.id : undefined,
|
|
728
762
|
full: formatMessage(message, relaySurface),
|
|
729
|
-
...isStubbable(message) ? { stub: stubMessage(message) } : { kind: nonStubbableSectionKind(message), label: nonStubbableSectionLabel(message) }
|
|
763
|
+
...isStubbable(message) ? { stub: stubMessage(message), preview: stubMessage(message, true) } : { kind: nonStubbableSectionKind(message), label: nonStubbableSectionLabel(message) }
|
|
730
764
|
}));
|
|
731
765
|
if (relaySurface && uniqueMessages.length > 0 && uniqueMessages.every((message) => isNotificationMessage(message) && !receivesTurnResponseAutomatically(message.from))) {
|
|
732
766
|
sections.push({ id: undefined, full: NOTIFICATION_NUDGE, kind: "disposable", label: "notification" });
|
|
@@ -740,7 +774,7 @@ function claudeMonitorDeliveryPlan(messages, options = {}) {
|
|
|
740
774
|
}
|
|
741
775
|
|
|
742
776
|
// runner/plugins/claude/monitors/relay-monitor.ts
|
|
743
|
-
var port = relayEnv(process.env, "
|
|
777
|
+
var port = relayEnv(process.env, "HUMWICK_RUNNER_PORT");
|
|
744
778
|
if (!port)
|
|
745
779
|
process.exit(0);
|
|
746
780
|
var firstDelivery = true;
|
|
@@ -752,7 +786,7 @@ ws.onmessage = (event) => {
|
|
|
752
786
|
const messages = payload.messages;
|
|
753
787
|
let reservedChars = 0;
|
|
754
788
|
if (firstDelivery) {
|
|
755
|
-
const contextBlock = relayEnv(process.env, "
|
|
789
|
+
const contextBlock = relayEnv(process.env, "HUMWICK_APPROVAL") === "read-only" ? claudeReadOnlyRelayContext() : claudeRelayContext();
|
|
756
790
|
const wsNote = workspaceDepsNoteFromEnv();
|
|
757
791
|
const prefix = [contextBlock, wsNote].filter(Boolean).join(`
|
|
758
792
|
|
|
@@ -765,7 +799,7 @@ ws.onmessage = (event) => {
|
|
|
765
799
|
const plan = claudeMonitorDeliveryPlan(messages, {
|
|
766
800
|
reservedChars,
|
|
767
801
|
monitorLimited: true,
|
|
768
|
-
spillDir: relayEnv(process.env, "
|
|
802
|
+
spillDir: relayEnv(process.env, "HUMWICK_SCRATCH_DIR")
|
|
769
803
|
});
|
|
770
804
|
if (plan.events[0])
|
|
771
805
|
console.log(plan.events[0].text);
|
|
@@ -3,7 +3,7 @@ import type { Message } from "@humwick/sdk";
|
|
|
3
3
|
import { claudeMonitorDeliveryPlan } from "../../../src/adapters/claude-delivery";
|
|
4
4
|
import { claudeReadOnlyRelayContext, claudeRelayContext, workspaceDepsNoteFromEnv } from "../../../src/relay-instructions";
|
|
5
5
|
|
|
6
|
-
const port = relayEnv(process.env, "
|
|
6
|
+
const port = relayEnv(process.env, "HUMWICK_RUNNER_PORT");
|
|
7
7
|
if (!port) process.exit(0);
|
|
8
8
|
|
|
9
9
|
let firstDelivery = true;
|
|
@@ -13,13 +13,13 @@ ws.onmessage = (event) => {
|
|
|
13
13
|
const payload = parsePayload(String(event.data));
|
|
14
14
|
if (!payload || payload.type !== "message.deliver" || !Array.isArray(payload.messages)) return;
|
|
15
15
|
const messages = payload.messages as Message[];
|
|
16
|
-
//
|
|
16
|
+
// the once-per-session context/workspace block is logged in the same synchronous tick as
|
|
17
17
|
// the message, so the harness batches both into ONE monitor event under a single size cap. Track
|
|
18
18
|
// the prefix length and hand it to the composer as reservedChars, so the over-limit stub gate
|
|
19
19
|
// accounts for the prefix and the first message can't be silently truncated behind it.
|
|
20
20
|
let reservedChars = 0;
|
|
21
21
|
if (firstDelivery) {
|
|
22
|
-
const contextBlock = relayEnv(process.env, "
|
|
22
|
+
const contextBlock = relayEnv(process.env, "HUMWICK_APPROVAL") === "read-only" ? claudeReadOnlyRelayContext() : claudeRelayContext();
|
|
23
23
|
const wsNote = workspaceDepsNoteFromEnv();
|
|
24
24
|
const prefix = [contextBlock, wsNote].filter(Boolean).join("\n\n");
|
|
25
25
|
console.log(prefix);
|
|
@@ -30,12 +30,12 @@ ws.onmessage = (event) => {
|
|
|
30
30
|
const plan = claudeMonitorDeliveryPlan(messages, {
|
|
31
31
|
reservedChars,
|
|
32
32
|
monitorLimited: true,
|
|
33
|
-
//
|
|
33
|
+
// an over-cap must-keep section (memory context, self-resume continuation) is spilled
|
|
34
34
|
// byte-exact to the session scratch dir and represented by a small pointer instead of ever
|
|
35
35
|
// being raw-emitted for the harness to truncate. There is no supported way to emit more than
|
|
36
36
|
// one Monitor event per delivery cycle (the harness coalesces same-tick stdout into one
|
|
37
37
|
// event), so the pointer — not chunking — is what keeps the content loss-free.
|
|
38
|
-
spillDir: relayEnv(process.env, "
|
|
38
|
+
spillDir: relayEnv(process.env, "HUMWICK_SCRATCH_DIR"),
|
|
39
39
|
});
|
|
40
40
|
if (plan.events[0]) console.log(plan.events[0].text);
|
|
41
41
|
ws.send(JSON.stringify({
|
|
@@ -10,14 +10,14 @@ allowed-tools: [Bash]
|
|
|
10
10
|
Run:
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
|
|
13
|
+
humwick /label $ARGUMENTS
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
Examples:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
humwick /label backend-fixer
|
|
20
|
+
humwick /label --clear
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
Report the new label or current label briefly.
|
|
@@ -9,12 +9,12 @@ allowed-tools: [Bash]
|
|
|
9
9
|
|
|
10
10
|
⚠️ **SECURITY — never inline the message body in the shell command.** A body with
|
|
11
11
|
markdown backticks `` `like this` `` or `$(...)` would be shell-executed (command
|
|
12
|
-
substitution) before `
|
|
12
|
+
substitution) before `humwick` sees it — a command-injection vector,
|
|
13
13
|
since the body may quote another agent's or a user's text. **Feed the body through
|
|
14
14
|
stdin via a quoted heredoc** (the `'RELAY_EOF'` quotes disable all expansion):
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
|
|
17
|
+
humwick /message <target> --stdin <<'RELAY_EOF'
|
|
18
18
|
Your message text. Backticks `bun run release` and $(anything) are delivered
|
|
19
19
|
verbatim and are NOT executed.
|
|
20
20
|
RELAY_EOF
|
|
@@ -24,17 +24,17 @@ Targets (the `<target>` positional) can be an agent id, `tag:`, `policy:`, `cap:
|
|
|
24
24
|
`broadcast`:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
|
|
27
|
+
humwick /message codex --stdin <<'RELAY_EOF'
|
|
28
28
|
Can you look at that failing action?
|
|
29
29
|
RELAY_EOF
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
humwick /message tag:backend --stdin <<'RELAY_EOF'
|
|
32
32
|
Does anyone see the regression?
|
|
33
33
|
RELAY_EOF
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
For a message you have already staged in a file, use `--body-file PATH` instead.
|
|
37
37
|
|
|
38
|
-
**Do NOT** build `
|
|
38
|
+
**Do NOT** build `humwick /message <target> "…body…"` with the body inside quotes.
|
|
39
39
|
|
|
40
40
|
Report the sent message id briefly.
|
|
@@ -10,15 +10,15 @@ allowed-tools: [Bash]
|
|
|
10
10
|
Run:
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
|
|
13
|
+
humwick get-message $ARGUMENTS
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
Useful forms:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
humwick get-message 206
|
|
20
|
+
humwick get-message 206 --json
|
|
21
|
+
humwick get-message 206 --body
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
Use `--body` when you only need the complete message text. Use `--json` when attachments, metadata, or thread context matter.
|
|
@@ -9,15 +9,15 @@ allowed-tools: [Bash]
|
|
|
9
9
|
|
|
10
10
|
⚠️ **SECURITY — never inline the reply body in the shell command.** Your shell runs
|
|
11
11
|
the command you type, so a body containing markdown backticks `` `like this` `` or
|
|
12
|
-
`$(...)` would be executed as a shell command *before* `
|
|
13
|
-
(command substitution). This is a real command-injection vector
|
|
12
|
+
`$(...)` would be executed as a shell command *before* `humwick` ever sees it
|
|
13
|
+
(command substitution). This is a real command-injection vector: the body may
|
|
14
14
|
quote another agent's or a user's text. **Always feed the body through stdin via a
|
|
15
15
|
quoted heredoc**, which disables all shell expansion and delivers the body verbatim.
|
|
16
16
|
|
|
17
17
|
Run (safe — quoted `'RELAY_EOF'` delimiter means no expansion, no substitution):
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
|
|
20
|
+
humwick /reply <messageId> --stdin <<'RELAY_EOF'
|
|
21
21
|
Your reply text here. Backticks `bun run release` and $(anything) are delivered
|
|
22
22
|
verbatim and are NOT executed.
|
|
23
23
|
RELAY_EOF
|
|
@@ -29,7 +29,7 @@ The server auto-routes the reply to the original sender and inherits the channel
|
|
|
29
29
|
For a reply you have already staged in a file, use `--body-file` instead:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
|
|
32
|
+
humwick /reply <messageId> --body-file $TMPDIR/reply.md
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
The relay creates that per-session scratch dir for you (git-ignored locally), so
|
|
@@ -37,7 +37,7 @@ staging there never pollutes the working tree and never collides with other agen
|
|
|
37
37
|
No cleanup needed — the dir is reaped when your session ends. Oversized replies are
|
|
38
38
|
automatically uploaded as an Humwick artifact and sent as an attached concise reply.
|
|
39
39
|
|
|
40
|
-
**Do NOT** build `
|
|
40
|
+
**Do NOT** build `humwick /reply <id> "…body…"` with the body inside quotes — the
|
|
41
41
|
heredoc `--stdin` form above is the only safe way to pass free text.
|
|
42
42
|
|
|
43
43
|
Do not send a separate Relay follow-up that only confirms the reply was sent. The CLI
|
|
@@ -9,12 +9,12 @@ allowed-tools: [Bash]
|
|
|
9
9
|
|
|
10
10
|
⚠️ **SECURITY — never inline the work-item body in the shell command.** A body with
|
|
11
11
|
markdown backticks `` `like this` `` or `$(...)` would be shell-executed (command
|
|
12
|
-
substitution) before `
|
|
12
|
+
substitution) before `humwick` sees it — a command-injection vector.
|
|
13
13
|
**Feed the body through stdin via a quoted heredoc** (the `'RELAY_EOF'` quotes disable
|
|
14
14
|
all expansion, delivering the body verbatim):
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
|
|
17
|
+
humwick /send-claimable <target> --stdin <<'RELAY_EOF'
|
|
18
18
|
Describe the work item here. Backticks `bun run release` and $(anything) are
|
|
19
19
|
delivered verbatim and are NOT executed.
|
|
20
20
|
RELAY_EOF
|
|
@@ -23,17 +23,17 @@ RELAY_EOF
|
|
|
23
23
|
Targets can be an agent id, `tag:`, `cap:`, or `policy:`:
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
|
|
26
|
+
humwick /send-claimable tag:backend --stdin <<'RELAY_EOF'
|
|
27
27
|
Fix the failing API test
|
|
28
28
|
RELAY_EOF
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
humwick /send-claimable cap:review --stdin <<'RELAY_EOF'
|
|
31
31
|
Review the migration patch
|
|
32
32
|
RELAY_EOF
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
For a work item you have already staged in a file, use `--body-file PATH` instead.
|
|
36
36
|
|
|
37
|
-
**Do NOT** build `
|
|
37
|
+
**Do NOT** build `humwick /send-claimable <target> "…body…"` with the body inside quotes.
|
|
38
38
|
|
|
39
39
|
Report the sent claimable message id briefly.
|
|
@@ -6,7 +6,7 @@ description: Frame and prove a thin end-to-end feature slice before planning har
|
|
|
6
6
|
# Slice first
|
|
7
7
|
|
|
8
8
|
Use the current project's instructions and configured validation/deployment gates,
|
|
9
|
-
including its “How to validate in THIS project” brief or
|
|
9
|
+
including its “How to validate in THIS project” brief or the project’s `land-gates.json`.
|
|
10
10
|
Choose the proof's location and runtime in that project; no particular repo is required.
|
|
11
11
|
|
|
12
12
|
| Stage | Required result |
|
|
@@ -19,8 +19,10 @@ Choose the proof's location and runtime in that project; no particular repo is r
|
|
|
19
19
|
|
|
20
20
|
Coordinator owns stages, scope ledger and budget; record stage decisions on the spec
|
|
21
21
|
Task. Changing the bar or exceeding the budget needs operator approval. A blocked
|
|
22
|
-
slice returns to frame. Never
|
|
23
|
-
|
|
22
|
+
slice returns to frame. Never spawn harden builders before the slice Task is `done`
|
|
23
|
+
with a passing `slice-proof` verdict. Relay holds the slice Task's dependents (plan
|
|
24
|
+
nodes, Task dependencies) while its proof is open or failed; a builder you spawn by
|
|
25
|
+
hand is not held.
|
|
24
26
|
|
|
25
27
|
Design writes proof then spec, no full design. Builder declares each slice shortcut
|
|
26
28
|
in delivery risks. QA reproduces independently. Review blocks only on the stage's
|