@integrity-labs/agt-cli 0.27.150-test.15 → 0.27.150

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.
@@ -10,7 +10,7 @@ import {
10
10
  registerFramework,
11
11
  resolveAvatarEnvUrl,
12
12
  wrapScheduledTaskPrompt
13
- } from "./chunk-WOOYOAPG.js";
13
+ } from "./chunk-A75AOK6E.js";
14
14
 
15
15
  // ../../packages/core/dist/integrations/registry.js
16
16
  var INTEGRATION_REGISTRY = [
@@ -3386,43 +3386,32 @@ acknowledge before you start.
3386
3386
  - **FAST (< 60s):** handle inline. Reply via the channel tool
3387
3387
  (slack.reply / telegram.reply / directchat.reply) and end your turn.
3388
3388
 
3389
- - **SLOW (\u2265 60s):** acknowledge, dispatch to background, stay responsive.
3389
+ - **SLOW (\u2265 60s):** acknowledge first, then handle inline.
3390
3390
  1. Send a one-line acknowledgement via the channel tool \u2014 short, warm,
3391
3391
  and tell the user you'll come back. Example shape (don't copy verbatim,
3392
3392
  match your voice): "On it \u2014 this'll take a minute or two, I'll ping
3393
3393
  when it's done."
3394
- 2. Dispatch the work to a background sub-agent: the Agent tool with
3395
- \`subagent_type: general-purpose\` AND \`run_in_background: true\`.
3396
- Put EVERYTHING the worker needs in the dispatch prompt \u2014 the user's
3397
- full request, relevant thread context, which integrations/tools to
3398
- use, and the exact shape of result you want back. The worker inherits
3399
- your full MCP tool surface but NOT your conversation context.
3400
- 3. End your turn after dispatching. This is the point: you stay free to
3401
- answer other messages while the worker grinds. Do NOT wait, poll, or
3402
- dispatch the same work synchronously \u2014 a synchronous dispatch blocks
3403
- your turn and defeats the purpose.
3404
- 4. When the worker's completion notification arrives (it lands
3405
- automatically as a system message), read its result and reply via the
3406
- channel tool (\`slack.reply\` / \`telegram.reply\` / \`directchat.reply\`)
3407
- to the same thread / chat / conversation you acknowledged in step 1.
3408
- **You post the substantive reply \u2014 the worker has no channel tools.**
3409
- 5. If the completion notification reports a failure or an unusable
3410
- result, tell the user what happened and either re-dispatch with a
3411
- better prompt or handle it inline \u2014 never go silent.
3412
-
3413
- > **Why background dispatch (and why \`general-purpose\`):** validated
3414
- > 2026-06-10 on Claude Code 2.1.170 (ENG-6274 spike,
3415
- > \`docs/spikes/ENG-6274-run-in-background-dispatch.md\`): background
3416
- > dispatch returns immediately, your turn ends, inbound messages get
3417
- > answered in seconds while the worker runs, and the completion arrives
3418
- > as a notification you handle like any other turn. Use
3419
- > \`subagent_type: general-purpose\` (inherit-all tools) \u2014 NOT
3420
- > \`channel-message-handler\` or \`augmented-worker\` \u2014 until ENG-6273
3421
- > re-verifies on this host that the upstream allowlist bug
3422
- > ([anthropics/claude-code#64909](https://github.com/anthropics/claude-code/issues/64909),
3423
- > empirically 0/6 MCP tools in named sub-agents on 2026-06-03) is fixed
3424
- > at the fleet's pinned Claude Code version. \`general-purpose\` escapes
3425
- > that bug by construction either way.
3394
+ 2. Do the work yourself in this same session. Use whatever tools you
3395
+ need (MCP, skills, file reads, etc.) \u2014 your parent session has the
3396
+ full MCP surface bound.
3397
+ 3. Reply with the result via the channel tool (\`slack.reply\` /
3398
+ \`telegram.reply\` / \`directchat.reply\`), addressing the same thread
3399
+ / chat / conversation you acknowledged in step 1.
3400
+
3401
+ > **Why inline and not sub-agent dispatch right now:** there is an
3402
+ > upstream Claude Code bug
3403
+ > ([anthropics/claude-code#64909](https://github.com/anthropics/claude-code/issues/64909))
3404
+ > where sub-agents dispatched via the Task tool with an explicit
3405
+ > \`tools:\` allowlist (which is the shape \`channel-message-handler\`
3406
+ > uses) get an **empty MCP tool registry** \u2014 every \`mcp__*\` call
3407
+ > returns "No such tool available", including the channel reply tools.
3408
+ > Dispatching a slow channel reply to \`channel-message-handler\` will
3409
+ > therefore silently fail to land: you'd post the one-line ack, the
3410
+ > sub-agent would do the analysis fine, but its \`slack.reply\` call
3411
+ > would error and the user would never see the substantive reply.
3412
+ > Empirically confirmed 2026-06-03 with a 6-tool probe: 0/6 MCP tools
3413
+ > bound inside \`channel-message-handler\`. Until Anthropic ships the
3414
+ > fix, handling slow channel replies inline is the only working path.
3426
3415
 
3427
3416
  **Why this triage decision still matters more than any other instruction
3428
3417
  below:** if you skip the acknowledgement and just dive into slow work
@@ -3444,29 +3433,25 @@ For background tool work that **isn't** a channel reply \u2014 multi-step data
3444
3433
  pulls, CRM enrichments, research workflows, cross-MCP orchestration \u2014 use
3445
3434
  \`subagent_type: general-purpose\` (Anthropic's built-in). It inherits the
3446
3435
  full MCP tool surface from this session and reliably binds every
3447
- \`mcp__*\` server you have available. For anything expected to take more
3448
- than a minute, add \`run_in_background: true\` so your turn ends and you
3449
- stay responsive; the completion notification brings you the result.
3450
- Don't background-dispatch trivial work \u2014 each dispatch is a fresh
3451
- context and costs real tokens.
3436
+ \`mcp__*\` server you have available.
3452
3437
 
3453
3438
  **Why not \`augmented-worker\` for now:** there is an upstream Claude Code
3454
3439
  bug ([anthropics/claude-code#64909](https://github.com/anthropics/claude-code/issues/64909))
3455
3440
  where sub-agents with an explicit \`tools:\` allowlist get an empty MCP
3456
3441
  tool registry \u2014 every \`mcp__*\` call returns "No such tool available."
3457
3442
  \`general-purpose\` uses \`tools: *\` (inherit-all) and escapes the bug.
3458
- The fix appears to have shipped upstream (verified locally on Claude Code
3459
- 2.1.170, 2026-06-10 \u2014 ENG-6269 spike); once ENG-6273 re-verifies it on
3460
- this host's pinned version, \`augmented-worker\` becomes preferred again
3461
- (restricted tool surface for safety + working MCP binding) and
3462
- \`channel-message-handler\` returns as a dispatch target. Until then,
3463
- \`general-purpose\` only.
3443
+ Once Anthropic ships the fix, \`augmented-worker\` becomes preferred again
3444
+ (restricted tool surface for safety + working MCP binding); the dispatch
3445
+ recommendation here will flip back automatically.
3464
3446
 
3465
3447
  For slow **channel** replies, see \xA7 FIRST ACTION above \u2014 those are
3466
- dispatched as background \`general-purpose\` workers and **you** post the
3467
- result back to the channel when the completion notification arrives
3468
- (\`channel-message-handler\` is not yet the dispatch target for the same
3469
- ENG-6273-pending reason).
3448
+ currently handled inline (not dispatched) because \`channel-message-handler\`
3449
+ shares the explicit-allowlist shape and so suffers the same upstream
3450
+ bug. Empirically confirmed 2026-06-03 on agt-aws-1 with a 6-tool probe:
3451
+ 0/6 MCP tools bound inside \`channel-message-handler\` (matching the
3452
+ \`augmented-worker\` result). When Anthropic ships the upstream fix, both
3453
+ named sub-agents will work again and the FIRST ACTION triage will switch
3454
+ back to dispatch.
3470
3455
 
3471
3456
  ${activeTasksSection}${personalitySection}## Identity
3472
3457
 
@@ -4896,6 +4881,111 @@ function provisionOrientHook(codeName) {
4896
4881
  settings["hooks"] = hooks;
4897
4882
  writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
4898
4883
  }
4884
+ function provisionSessionStateHook(codeName) {
4885
+ const projectDir = getProjectDir(codeName);
4886
+ const claudeDir = join4(projectDir, ".claude");
4887
+ mkdirSync4(claudeDir, { recursive: true });
4888
+ const homeDir = getHomeDir3();
4889
+ const agentDir = join4(homeDir, ".augmented", codeName);
4890
+ const hookScriptPath = join4(claudeDir, "agt-session-state-hook.sh");
4891
+ const hookScript = `#!/usr/bin/env bash
4892
+ # Auto-generated by Augmented (ENG-6233 / ENG-6268) \u2014 SessionStart session-state
4893
+ # recorder. Writes the model + session origin (which only the agent's own
4894
+ # Claude Code session knows) to session-state.json, which the channel servers
4895
+ # read back for the /status command. Best-effort, silent; every path exits 0 so
4896
+ # it can NEVER block or fail session start.
4897
+ # Canonical source: packages/claudecode-plugin-augmented/hooks/session-state.sh
4898
+
4899
+ # Best-effort: any unexpected error just exits clean.
4900
+ trap 'exit 0' ERR
4901
+
4902
+ # Hook input (stdin canonical; CLAUDE_HOOK_INPUT kept as a fallback).
4903
+ INPUT="$(cat 2>/dev/null || true)"
4904
+ [ -n "$INPUT" ] || INPUT="\${CLAUDE_HOOK_INPUT:-}"
4905
+ [ -n "$INPUT" ] || exit 0
4906
+ command -v jq >/dev/null 2>&1 || exit 0
4907
+
4908
+ # Identity / state dir are baked at provision time.
4909
+ CODE_NAME="${codeName}"
4910
+ STATE_DIR="${agentDir}"
4911
+ mkdir -p "$STATE_DIR" 2>/dev/null || exit 0
4912
+
4913
+ # Pull the fields we surface from the SessionStart payload.
4914
+ SESSION_ID="$(printf '%s' "$INPUT" | jq -r '.session_id // empty' 2>/dev/null || true)"
4915
+ SOURCE="$(printf '%s' "$INPUT" | jq -r '.source // empty' 2>/dev/null || true)"
4916
+ MODEL="$(printf '%s' "$INPUT" | jq -r '.model // empty' 2>/dev/null || true)"
4917
+ CWD="$(printf '%s' "$INPUT" | jq -r '.cwd // empty' 2>/dev/null || true)"
4918
+ [ -n "$CWD" ] || CWD="\${CLAUDE_PROJECT_DIR:-$PWD}"
4919
+
4920
+ # Channels: the channel MCP servers wired in the project .mcp.json. The adapter
4921
+ # writes each channel as a bare server id \u2014 slack / telegram / msteams (the
4922
+ # DEV_CHANNEL_SERVER_IDS set) plus direct-chat \u2014 NOT a "<name>-channel" key, so
4923
+ # match that allowlist and exclude the non-channel servers (augmented,
4924
+ # cloud-broker, composio_*). The "-channel" suffix only names the bundled .js
4925
+ # asset, never the .mcp.json key (verified against a live host, ENG-6268).
4926
+ CHANNELS_JSON='[]'
4927
+ if [ -f "$CWD/.mcp.json" ]; then
4928
+ CHANNELS_JSON="$(jq -c '
4929
+ ["slack","telegram","msteams","direct-chat"] as $ch
4930
+ | [ (.mcpServers // {} | keys[]) | select(. as $k | $ch | index($k)) ]
4931
+ ' "$CWD/.mcp.json" 2>/dev/null || echo '[]')"
4932
+ [ -n "$CHANNELS_JSON" ] || CHANNELS_JSON='[]'
4933
+ fi
4934
+
4935
+ # Environment: best-effort from the agent's CLAUDE.md frontmatter (CHARTER.md
4936
+ # maps to CLAUDE.md for the Claude Code adapter; the frontmatter carries
4937
+ # environment: dev|stage|prod). Missing / unreadable -> omitted.
4938
+ ENVIRONMENT=""
4939
+ if [ -f "$CWD/CLAUDE.md" ]; then
4940
+ ENVIRONMENT="$(grep -m1 -E '^environment:[[:space:]]*' "$CWD/CLAUDE.md" 2>/dev/null | sed -E 's/^environment:[[:space:]]*//; s/[[:space:]]*$//' || true)"
4941
+ fi
4942
+
4943
+ # Seconds->millis keeps this portable across GNU (Linux hosts) and BSD (macOS
4944
+ # dev) date; second granularity is plenty for "started 12m ago".
4945
+ RECORDED_AT="$(date +%s)000"
4946
+
4947
+ # Write atomically (temp + rename) so a concurrent reader never sees a
4948
+ # half-written file.
4949
+ OUT="$STATE_DIR/session-state.json"
4950
+ TMP="$OUT.$$.tmp"
4951
+ if jq -nc --arg session_id "$SESSION_ID" --arg source "$SOURCE" --arg model "$MODEL" --arg cwd "$CWD" --arg environment "$ENVIRONMENT" --argjson channels "$CHANNELS_JSON" --argjson recorded_at "$RECORDED_AT" '{
4952
+ session_id: $session_id,
4953
+ source: $source,
4954
+ model: $model,
4955
+ cwd: $cwd,
4956
+ channels: $channels,
4957
+ recorded_at: $recorded_at
4958
+ }
4959
+ | if $environment == "" then . else . + { environment: $environment } end' > "$TMP" 2>/dev/null; then
4960
+ mv -f "$TMP" "$OUT" 2>/dev/null || rm -f "$TMP" 2>/dev/null || true
4961
+ else
4962
+ rm -f "$TMP" 2>/dev/null || true
4963
+ fi
4964
+
4965
+ exit 0
4966
+ `;
4967
+ writeFileSync5(hookScriptPath, hookScript, { mode: 493 });
4968
+ const settingsPath = join4(claudeDir, "settings.local.json");
4969
+ let settings = {};
4970
+ try {
4971
+ settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
4972
+ } catch {
4973
+ }
4974
+ const hooks = settings["hooks"] ?? {};
4975
+ const existingSessionStart = Array.isArray(hooks["SessionStart"]) ? [...hooks["SessionStart"]] : [];
4976
+ const alreadyRegistered = existingSessionStart.some((entry) => {
4977
+ const entryHooks = entry.hooks;
4978
+ return Array.isArray(entryHooks) && entryHooks.some((h) => typeof h === "object" && h !== null && h.type === "command" && h.command === hookScriptPath);
4979
+ });
4980
+ if (!alreadyRegistered) {
4981
+ existingSessionStart.push({
4982
+ hooks: [{ type: "command", command: hookScriptPath }]
4983
+ });
4984
+ }
4985
+ hooks["SessionStart"] = existingSessionStart;
4986
+ settings["hooks"] = hooks;
4987
+ writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
4988
+ }
4899
4989
  function modifyJsonConfig(filePath, fn) {
4900
4990
  let originalContent;
4901
4991
  let config;
@@ -7851,6 +7941,7 @@ export {
7851
7941
  provisionIsolationHook,
7852
7942
  provisionAutoKanbanProgressHook,
7853
7943
  provisionOrientHook,
7944
+ provisionSessionStateHook,
7854
7945
  setJsonMode,
7855
7946
  isJsonMode,
7856
7947
  jsonOutput,
@@ -7881,4 +7972,4 @@ export {
7881
7972
  managerInstallSystemUnitCommand,
7882
7973
  managerUninstallSystemUnitCommand
7883
7974
  };
7884
- //# sourceMappingURL=chunk-24FTY53Z.js.map
7975
+ //# sourceMappingURL=chunk-CUHP2SVW.js.map