@integrity-labs/agt-cli 0.28.527 → 0.28.529
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/dist/bin/agt.js +4 -4
- package/dist/{chunk-HIHBCJWG.js → chunk-MKSL2EQU.js} +173 -4
- package/dist/chunk-MKSL2EQU.js.map +1 -0
- package/dist/{chunk-Z4P4VEDU.js → chunk-Q4XGKOHZ.js} +251 -13
- package/dist/chunk-Q4XGKOHZ.js.map +1 -0
- package/dist/{claude-pair-runtime-V7PPPPU5.js → claude-pair-runtime-TC2TTMIJ.js} +2 -2
- package/dist/lib/manager-worker.js +336 -137
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/augmented-help-kb.js +21231 -0
- package/dist/mcp/direct-chat-channel.js +99 -7
- package/dist/mcp/origami.js +74 -0
- package/dist/mcp/slack-channel.js +99 -7
- package/dist/mcp/telegram-channel.js +99 -7
- package/dist/{persistent-session-C7ETZOWH.js → persistent-session-T4IY7AJU.js} +2 -2
- package/dist/{responsiveness-probe-WHA7YNFM.js → responsiveness-probe-WYGR4B2F.js} +22 -2
- package/dist/{responsiveness-probe-WHA7YNFM.js.map → responsiveness-probe-WYGR4B2F.js.map} +1 -1
- package/package.json +3 -2
- package/dist/chunk-HIHBCJWG.js.map +0 -1
- package/dist/chunk-Z4P4VEDU.js.map +0 -1
- /package/dist/{claude-pair-runtime-V7PPPPU5.js.map → claude-pair-runtime-TC2TTMIJ.js.map} +0 -0
- /package/dist/{persistent-session-C7ETZOWH.js.map → persistent-session-T4IY7AJU.js.map} +0 -0
package/dist/bin/agt.js
CHANGED
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
success,
|
|
41
41
|
table,
|
|
42
42
|
warn
|
|
43
|
-
} from "../chunk-
|
|
43
|
+
} from "../chunk-MKSL2EQU.js";
|
|
44
44
|
import {
|
|
45
45
|
AnchorSessionClient,
|
|
46
46
|
CHANNEL_REGISTRY,
|
|
@@ -71,7 +71,7 @@ import {
|
|
|
71
71
|
requiredMcpWildcard,
|
|
72
72
|
resolveChannels,
|
|
73
73
|
serializeManifestForSlackCli
|
|
74
|
-
} from "../chunk-
|
|
74
|
+
} from "../chunk-Q4XGKOHZ.js";
|
|
75
75
|
import "../chunk-XWVM4KPK.js";
|
|
76
76
|
|
|
77
77
|
// src/bin/agt.ts
|
|
@@ -4834,7 +4834,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
4834
4834
|
import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
|
|
4835
4835
|
import chalk18 from "chalk";
|
|
4836
4836
|
import ora16 from "ora";
|
|
4837
|
-
var cliVersion = true ? "0.28.
|
|
4837
|
+
var cliVersion = true ? "0.28.529" : "dev";
|
|
4838
4838
|
async function fetchLatestVersion() {
|
|
4839
4839
|
const host2 = getHost();
|
|
4840
4840
|
if (!host2) return null;
|
|
@@ -6006,7 +6006,7 @@ function handleError(err) {
|
|
|
6006
6006
|
}
|
|
6007
6007
|
|
|
6008
6008
|
// src/bin/agt.ts
|
|
6009
|
-
var cliVersion2 = true ? "0.28.
|
|
6009
|
+
var cliVersion2 = true ? "0.28.529" : "dev";
|
|
6010
6010
|
var program = new Command();
|
|
6011
6011
|
program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
|
|
6012
6012
|
program.hook("preAction", async (thisCommand, actionCommand) => {
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
resolveConnectivityProbe,
|
|
43
43
|
worseConnectivityOutcome,
|
|
44
44
|
wrapScheduledTaskPrompt
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-Q4XGKOHZ.js";
|
|
46
46
|
import {
|
|
47
47
|
parsePsRows
|
|
48
48
|
} from "./chunk-XWVM4KPK.js";
|
|
@@ -2313,6 +2313,7 @@ function provisionStopHook(codeName) {
|
|
|
2313
2313
|
"exit 0"
|
|
2314
2314
|
].join("\n") + "\n";
|
|
2315
2315
|
writeFileSync3(ghostHookPath, ghostHookScript, { mode: 493 });
|
|
2316
|
+
const backlogHookPath = provisionBacklogPullHook(codeName);
|
|
2316
2317
|
const settingsPath = join2(claudeDir, "settings.local.json");
|
|
2317
2318
|
let settings = {};
|
|
2318
2319
|
try {
|
|
@@ -2324,7 +2325,8 @@ function provisionStopHook(codeName) {
|
|
|
2324
2325
|
{
|
|
2325
2326
|
hooks: [
|
|
2326
2327
|
{ type: "command", command: hookScriptPath },
|
|
2327
|
-
{ type: "command", command: ghostHookPath }
|
|
2328
|
+
{ type: "command", command: ghostHookPath },
|
|
2329
|
+
{ type: "command", command: backlogHookPath }
|
|
2328
2330
|
]
|
|
2329
2331
|
}
|
|
2330
2332
|
];
|
|
@@ -2417,6 +2419,138 @@ function provisionIsolationHook(codeName, agentId) {
|
|
|
2417
2419
|
settings["hooks"] = hooks;
|
|
2418
2420
|
writeFileSync3(settingsPath, JSON.stringify(settings, null, 2));
|
|
2419
2421
|
}
|
|
2422
|
+
function provisionBacklogPullHook(codeName) {
|
|
2423
|
+
const projectDir = getProjectDir(codeName);
|
|
2424
|
+
const claudeDir = join2(projectDir, ".claude");
|
|
2425
|
+
mkdirSync2(claudeDir, { recursive: true });
|
|
2426
|
+
const hookScriptPath = join2(claudeDir, "agt-backlog-pull-hook.sh");
|
|
2427
|
+
const hookScript = `#!/usr/bin/env bash
|
|
2428
|
+
# Auto-generated by Augmented (CS-1549) \u2014 Stop hook: don't end a turn idle
|
|
2429
|
+
# beside a non-empty backlog. Fail-open on every path; blocks at most once per
|
|
2430
|
+
# distinct backlog item so it can never wedge a session.
|
|
2431
|
+
set -uo pipefail
|
|
2432
|
+
trap 'exit 0' ERR
|
|
2433
|
+
|
|
2434
|
+
INPUT="$(cat 2>/dev/null || true)"
|
|
2435
|
+
[ -n "$INPUT" ] || INPUT="\${CLAUDE_HOOK_INPUT:-}"
|
|
2436
|
+
[ -n "$INPUT" ] || exit 0
|
|
2437
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
2438
|
+
command -v curl >/dev/null 2>&1 || exit 0
|
|
2439
|
+
|
|
2440
|
+
# Never re-block a turn that Claude Code is already replaying because a hook
|
|
2441
|
+
# blocked it. Without this two Stop hooks can ping-pong.
|
|
2442
|
+
STOP_ACTIVE="$(printf '%s' "$INPUT" | jq -r '.stop_hook_active // false' 2>/dev/null || echo false)"
|
|
2443
|
+
# ENG-4660 form. \`[ test ] && exit 0\` is safe here only because this script omits
|
|
2444
|
+
# \`set -e\` and the list is not last; adding either re-creates the silent non-zero
|
|
2445
|
+
# hook exit. Use the explicit form both other Stop hooks were converted to.
|
|
2446
|
+
if [ "$STOP_ACTIVE" = "true" ]; then exit 0; fi
|
|
2447
|
+
|
|
2448
|
+
# CodeRabbit on #4134, and the finding that most undermines this hook:
|
|
2449
|
+
# stop_hook_active alone is NOT enough. On the FIRST Stop event Claude Code runs
|
|
2450
|
+
# all three commands in the same hook group, with stop_hook_active=false for
|
|
2451
|
+
# every one of them. So if ghost-reply blocks, this hook still runs, still burns
|
|
2452
|
+
# its one-shot ledger entry, and its reason is never the one shown - the backlog
|
|
2453
|
+
# nudge is consumed unseen, and that item can never nudge again.
|
|
2454
|
+
#
|
|
2455
|
+
# Standing down whenever a channel reply is OWED fixes it, and matches the
|
|
2456
|
+
# ordering documented at the Stop registration: an unanswered person beats an
|
|
2457
|
+
# unpulled card. Cheap - a directory test, and it runs before either curl.
|
|
2458
|
+
CWD_IN="$(printf '%s' "$INPUT" | jq -r '.cwd // empty' 2>/dev/null || true)"
|
|
2459
|
+
if [ -n "$CWD_IN" ]; then
|
|
2460
|
+
OWED_BASE="$(dirname "$CWD_IN")"
|
|
2461
|
+
for d in telegram-pending-inbound slack-pending-inbound direct-chat-pending-inbound msteams-pending-inbound/.markers; do
|
|
2462
|
+
if [ -d "$OWED_BASE/$d" ] && [ -n "$(ls -A "$OWED_BASE/$d" 2>/dev/null || true)" ]; then
|
|
2463
|
+
echo "agt-backlog-pull-hook: standing down, a channel reply is owed" >&2
|
|
2464
|
+
exit 0
|
|
2465
|
+
fi
|
|
2466
|
+
done
|
|
2467
|
+
fi
|
|
2468
|
+
|
|
2469
|
+
# Identity. AGT_AGENT_ID is NOT exported into the parent claude's env (see
|
|
2470
|
+
# ENG-4823), so .mcp.json is the reliable source \u2014 the manager writes it
|
|
2471
|
+
# literally into every augmented MCP server's env block.
|
|
2472
|
+
PROJECT_DIR="\${CLAUDE_PROJECT_DIR:-$PWD}"
|
|
2473
|
+
AGENT_ID="\${AGT_AGENT_ID:-}"
|
|
2474
|
+
if [ -z "$AGENT_ID" ] && [ -f "$PROJECT_DIR/.mcp.json" ]; then
|
|
2475
|
+
AGENT_ID="$(jq -r '[.mcpServers[]?.env?.AGT_AGENT_ID // empty] | map(select(. != "")) | .[0] // empty' "$PROJECT_DIR/.mcp.json" 2>/dev/null || true)"
|
|
2476
|
+
fi
|
|
2477
|
+
HOST="\${AGT_HOST:-}"
|
|
2478
|
+
KEY="\${AGT_API_KEY:-}"
|
|
2479
|
+
[ -n "$AGENT_ID" ] && [ -n "$HOST" ] && [ -n "$KEY" ] || exit 0
|
|
2480
|
+
|
|
2481
|
+
JWT="$(curl -sf --connect-timeout 2 --max-time 5 -X POST "\${HOST}/host/exchange" -H 'Content-Type: application/json' -d "$(jq -n --arg k "$KEY" '{api_key:$k}')" 2>/dev/null | jq -r '.token // empty' 2>/dev/null || true)"
|
|
2482
|
+
[ -n "$JWT" ] || exit 0
|
|
2483
|
+
|
|
2484
|
+
BOARD="$(curl -sf --connect-timeout 2 --max-time 5 -X POST "\${HOST}/host/my-kanban" -H 'Content-Type: application/json' -H "Authorization: Bearer $JWT" -d "$(jq -n --arg a "$AGENT_ID" '{agent_id:$a}')" 2>/dev/null || true)"
|
|
2485
|
+
[ -n "$BOARD" ] || exit 0
|
|
2486
|
+
|
|
2487
|
+
# The counts that matter. \`waiting\` is deliberately NOT counted as work: a card
|
|
2488
|
+
# parked on a PR review or a human is someone else's work in progress, and
|
|
2489
|
+
# treating it as load is the exact loophole CS-1549 names. \`needs_attention\` is
|
|
2490
|
+
# excluded from the pullable set because the reaper parks stalled cards there
|
|
2491
|
+
# for a human \u2014 pulling one would just re-stall it.
|
|
2492
|
+
COUNTS="$(printf '%s' "$BOARD" | jq -c '
|
|
2493
|
+
(.items // []) as $i
|
|
2494
|
+
| {
|
|
2495
|
+
in_progress: ([$i[] | select(.status == "in_progress")] | length),
|
|
2496
|
+
todo: ([$i[] | select(.status == "todo")] | length),
|
|
2497
|
+
pullable: [$i[] | select(.status == "backlog")]
|
|
2498
|
+
}
|
|
2499
|
+
| {in_progress, todo, n: ($i | length), top: (.pullable | first), count: (.pullable | length)}
|
|
2500
|
+
' 2>/dev/null || true)"
|
|
2501
|
+
[ -n "$COUNTS" ] || exit 0
|
|
2502
|
+
|
|
2503
|
+
IN_PROGRESS="$(printf '%s' "$COUNTS" | jq -r '.in_progress // 0')"
|
|
2504
|
+
TODO="$(printf '%s' "$COUNTS" | jq -r '.todo // 0')"
|
|
2505
|
+
BACKLOG_N="$(printf '%s' "$COUNTS" | jq -r '.count // 0')"
|
|
2506
|
+
TOP_ID="$(printf '%s' "$COUNTS" | jq -r '.top.id // empty')"
|
|
2507
|
+
TOP_TITLE="$(printf '%s' "$COUNTS" | jq -r '.top.title // empty')"
|
|
2508
|
+
|
|
2509
|
+
# Only fire when the agent is genuinely idle beside pullable work.
|
|
2510
|
+
[ "$IN_PROGRESS" = "0" ] || exit 0
|
|
2511
|
+
[ "$TODO" = "0" ] || exit 0
|
|
2512
|
+
[ "$BACKLOG_N" -gt 0 ] 2>/dev/null || exit 0
|
|
2513
|
+
[ -n "$TOP_ID" ] || exit 0
|
|
2514
|
+
|
|
2515
|
+
# Ledger: at most one block per distinct top-of-backlog item. If the agent
|
|
2516
|
+
# declines and states a reason, the turn ends and this item never blocks again \u2014
|
|
2517
|
+
# a NEW top item re-arms it. This is the override: it needs no approval rail,
|
|
2518
|
+
# and the stated reason lands in the transcript where it is reviewable.
|
|
2519
|
+
LEDGER_DIR="\${HOME:-/tmp}/.augmented/.backlog-pull/\${AGENT_ID}"
|
|
2520
|
+
mkdir -p "$LEDGER_DIR" 2>/dev/null || exit 0
|
|
2521
|
+
SAFE_ID="$(printf '%s' "$TOP_ID" | tr -c 'A-Za-z0-9_.-' '_')"
|
|
2522
|
+
LEDGER="$LEDGER_DIR/$SAFE_ID"
|
|
2523
|
+
# ATOMIC acquire (CodeRabbit on #4134). A [ -e ] test then a : > write is a TOCTOU:
|
|
2524
|
+
# two concurrent Stop events can both observe no entry and both block. noclobber
|
|
2525
|
+
# makes create-if-absent one atomic operation - what every other ledger in this
|
|
2526
|
+
# file already uses. A failure means either "already claimed" or "unwritable";
|
|
2527
|
+
# both must NOT block, so either way exit 0.
|
|
2528
|
+
if ! ( set -o noclobber; : > "$LEDGER" ) 2>/dev/null; then exit 0; fi
|
|
2529
|
+
|
|
2530
|
+
# Bound the ledger: one file per backlog item forever grows without limit on a
|
|
2531
|
+
# long-lived agent. Keep the newest 200. A pruned entry can at worst re-nudge
|
|
2532
|
+
# about an item that is still genuinely unpulled - the safe direction.
|
|
2533
|
+
LEDGER_N="$(ls -1 "$LEDGER_DIR" 2>/dev/null | wc -l | tr -d ' ')"
|
|
2534
|
+
if [ "\${LEDGER_N:-0}" -gt 200 ] 2>/dev/null; then
|
|
2535
|
+
ls -1t "$LEDGER_DIR" 2>/dev/null | tail -n +201 | while IFS= read -r stale; do
|
|
2536
|
+
rm -f "$LEDGER_DIR/$stale" 2>/dev/null || true
|
|
2537
|
+
done
|
|
2538
|
+
fi
|
|
2539
|
+
|
|
2540
|
+
echo "agt-backlog-pull-hook: FIRED backlog=\${BACKLOG_N} top=\${TOP_ID}" >&2
|
|
2541
|
+
|
|
2542
|
+
REASON="You are ending this turn with nothing in progress and nothing in todo, while \${BACKLOG_N} item(s) sit in your backlog. That is idle, not busy \u2014 cards in \\\`waiting\\\` are parked on someone else, so they are not your work in progress.
|
|
2543
|
+
|
|
2544
|
+
Pull the top item now: kanban_move(\\"\${TOP_ID}\\", \\"in_progress\\") \u2014 \\"\${TOP_TITLE}\\" \u2014 and start it.
|
|
2545
|
+
|
|
2546
|
+
If you genuinely should not pull it, say so in one line and why (it is deliberately parked, it is ambiguous and you have asked a specific question, or you are mid-flight on long-running external work). Then end the turn \u2014 this will not ask you again about this item."
|
|
2547
|
+
|
|
2548
|
+
jq -cn --arg r "$REASON" '{decision:"block", reason:$r}'
|
|
2549
|
+
exit 0
|
|
2550
|
+
`;
|
|
2551
|
+
writeFileSync3(hookScriptPath, hookScript, { mode: 493 });
|
|
2552
|
+
return hookScriptPath;
|
|
2553
|
+
}
|
|
2420
2554
|
function provisionAutoKanbanProgressHook(codeName) {
|
|
2421
2555
|
const projectDir = getProjectDir(codeName);
|
|
2422
2556
|
const claudeDir = join2(projectDir, ".claude");
|
|
@@ -3539,6 +3673,20 @@ function buildMcpJson(input) {
|
|
|
3539
3673
|
}
|
|
3540
3674
|
};
|
|
3541
3675
|
}
|
|
3676
|
+
const hasHelpKb = input.integrations?.some((i) => i.definition_id === "augmented-help-kb") ?? false;
|
|
3677
|
+
if (hasHelpKb) {
|
|
3678
|
+
const localHelpKbMcpPath = join2(getHomeDir(), ".augmented", "_mcp", "augmented-help-kb.js");
|
|
3679
|
+
mcpServers["augmented-help-kb"] = {
|
|
3680
|
+
command: "node",
|
|
3681
|
+
args: [localHelpKbMcpPath],
|
|
3682
|
+
env: {
|
|
3683
|
+
AGT_HOST: "${AGT_HOST}",
|
|
3684
|
+
AGT_AGENT_ID: input.agent.agent_id,
|
|
3685
|
+
AGT_RUN_ID: "${AGT_RUN_ID}",
|
|
3686
|
+
AGT_API_KEY: "${AGT_API_KEY}"
|
|
3687
|
+
}
|
|
3688
|
+
};
|
|
3689
|
+
}
|
|
3542
3690
|
const origamiIntegration = input.integrations?.find((i) => i.definition_id === "origami");
|
|
3543
3691
|
if (origamiIntegration?.stdioMcp === true && origamiIntegration.id) {
|
|
3544
3692
|
const localOrigamiMcpPath = join2(getHomeDir(), ".augmented", "_mcp", "origami.js");
|
|
@@ -4747,6 +4895,20 @@ ${sections}`
|
|
|
4747
4895
|
}
|
|
4748
4896
|
});
|
|
4749
4897
|
}
|
|
4898
|
+
const hasHelpKb = integrations.some((i) => i.definition_id === "augmented-help-kb");
|
|
4899
|
+
if (hasHelpKb) {
|
|
4900
|
+
const localHelpKbMcpPath = join2(getHomeDir(), ".augmented", "_mcp", "augmented-help-kb.js");
|
|
4901
|
+
this.writeMcpServer(codeName, "augmented-help-kb", {
|
|
4902
|
+
command: "node",
|
|
4903
|
+
args: [localHelpKbMcpPath],
|
|
4904
|
+
env: {
|
|
4905
|
+
AGT_HOST: "${AGT_HOST}",
|
|
4906
|
+
AGT_AGENT_ID: resolveBrokerAgentId(codeName) ?? agentId ?? "",
|
|
4907
|
+
AGT_RUN_ID: "${AGT_RUN_ID}",
|
|
4908
|
+
AGT_API_KEY: "${AGT_API_KEY}"
|
|
4909
|
+
}
|
|
4910
|
+
});
|
|
4911
|
+
}
|
|
4750
4912
|
const origamiStdio = integrations.find((i) => i.definition_id === "origami");
|
|
4751
4913
|
const origamiStdioAgentId = resolveBrokerAgentId(codeName) ?? agentId;
|
|
4752
4914
|
const origamiStdioExpected = Boolean(origamiStdio?.stdioMcp === true && origamiStdio.id);
|
|
@@ -4774,6 +4936,11 @@ ${sections}`
|
|
|
4774
4936
|
"xero-broker",
|
|
4775
4937
|
"augmented-admin",
|
|
4776
4938
|
"augmented-support",
|
|
4939
|
+
// ENG-8332: the help-KB stdio server. In the universe so that REVOKING
|
|
4940
|
+
// the integration actually removes the entry - without this the docs
|
|
4941
|
+
// surface would keep binding after the grant was taken away, which is
|
|
4942
|
+
// the same reads-healthy-but-isn't shape as ENG-5277.
|
|
4943
|
+
"augmented-help-kb",
|
|
4777
4944
|
// ENG-7358: the dedicated origami stdio server. In the universe so
|
|
4778
4945
|
// that removing the integration OR flipping the catalog stdio_mcp
|
|
4779
4946
|
// flag back (rollback) prunes the entry symmetrically.
|
|
@@ -4837,6 +5004,8 @@ ${sections}`
|
|
|
4837
5004
|
expectedKeys.add("augmented-admin");
|
|
4838
5005
|
if (hasSupport)
|
|
4839
5006
|
expectedKeys.add("augmented-support");
|
|
5007
|
+
if (hasHelpKb)
|
|
5008
|
+
expectedKeys.add("augmented-help-kb");
|
|
4840
5009
|
if (origamiStdioExpected)
|
|
4841
5010
|
expectedKeys.add("origami");
|
|
4842
5011
|
for (const integration of integrations) {
|
|
@@ -5317,7 +5486,7 @@ function exchangeFailureKind(err) {
|
|
|
5317
5486
|
}
|
|
5318
5487
|
|
|
5319
5488
|
// src/lib/api-client.ts
|
|
5320
|
-
var agtCliVersion = true ? "0.28.
|
|
5489
|
+
var agtCliVersion = true ? "0.28.529" : "dev";
|
|
5321
5490
|
var lastConfigHash = null;
|
|
5322
5491
|
function setConfigHash(hash) {
|
|
5323
5492
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -8629,4 +8798,4 @@ export {
|
|
|
8629
8798
|
managerInstallSystemUnitCommand,
|
|
8630
8799
|
managerUninstallSystemUnitCommand
|
|
8631
8800
|
};
|
|
8632
|
-
//# sourceMappingURL=chunk-
|
|
8801
|
+
//# sourceMappingURL=chunk-MKSL2EQU.js.map
|