@integrity-labs/agt-cli 0.15.0 → 0.15.1
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 +3 -3
- package/dist/{chunk-WB3T6XIV.js → chunk-7QE6SJQB.js} +165 -11
- package/dist/chunk-7QE6SJQB.js.map +1 -0
- package/dist/{chunk-4CZUEGNQ.js → chunk-IEVDKEIT.js} +6 -1
- package/dist/chunk-IEVDKEIT.js.map +1 -0
- package/dist/lib/manager-worker.js +127 -22
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-GBQ3VQK3.js → persistent-session-ALP5DGFI.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-4CZUEGNQ.js.map +0 -1
- package/dist/chunk-WB3T6XIV.js.map +0 -1
- /package/dist/{persistent-session-GBQ3VQK3.js.map → persistent-session-ALP5DGFI.js.map} +0 -0
package/dist/bin/agt.js
CHANGED
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
success,
|
|
46
46
|
table,
|
|
47
47
|
warn
|
|
48
|
-
} from "../chunk-
|
|
48
|
+
} from "../chunk-7QE6SJQB.js";
|
|
49
49
|
|
|
50
50
|
// src/bin/agt.ts
|
|
51
51
|
import { join as join9 } from "path";
|
|
@@ -3402,7 +3402,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
3402
3402
|
import { existsSync as existsSync4, realpathSync } from "fs";
|
|
3403
3403
|
import chalk17 from "chalk";
|
|
3404
3404
|
import ora15 from "ora";
|
|
3405
|
-
var cliVersion = true ? "0.15.
|
|
3405
|
+
var cliVersion = true ? "0.15.1" : "dev";
|
|
3406
3406
|
async function fetchLatestVersion() {
|
|
3407
3407
|
const host2 = getHost();
|
|
3408
3408
|
if (!host2) return null;
|
|
@@ -3851,7 +3851,7 @@ function handleError(err) {
|
|
|
3851
3851
|
}
|
|
3852
3852
|
|
|
3853
3853
|
// src/bin/agt.ts
|
|
3854
|
-
var cliVersion2 = true ? "0.15.
|
|
3854
|
+
var cliVersion2 = true ? "0.15.1" : "dev";
|
|
3855
3855
|
var program = new Command();
|
|
3856
3856
|
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");
|
|
3857
3857
|
program.hook("preAction", (thisCommand) => {
|
|
@@ -533,6 +533,45 @@ function getIntegration(id) {
|
|
|
533
533
|
return integrationMap.get(id);
|
|
534
534
|
}
|
|
535
535
|
|
|
536
|
+
// ../../packages/core/dist/provisioning/hook-env.js
|
|
537
|
+
function augmentedHookPath(currentPath) {
|
|
538
|
+
const extras = [
|
|
539
|
+
"/home/linuxbrew/.linuxbrew/bin",
|
|
540
|
+
"/opt/homebrew/bin",
|
|
541
|
+
"/usr/local/bin",
|
|
542
|
+
"/usr/bin",
|
|
543
|
+
"/bin"
|
|
544
|
+
];
|
|
545
|
+
const seen = /* @__PURE__ */ new Set();
|
|
546
|
+
const parts = [];
|
|
547
|
+
const push = (p) => {
|
|
548
|
+
if (!p || seen.has(p))
|
|
549
|
+
return;
|
|
550
|
+
seen.add(p);
|
|
551
|
+
parts.push(p);
|
|
552
|
+
};
|
|
553
|
+
for (const p of (currentPath ?? "").split(":"))
|
|
554
|
+
push(p);
|
|
555
|
+
for (const p of extras)
|
|
556
|
+
push(p);
|
|
557
|
+
return parts.join(":");
|
|
558
|
+
}
|
|
559
|
+
function extractCommandNotFound(stderr) {
|
|
560
|
+
if (!stderr)
|
|
561
|
+
return null;
|
|
562
|
+
const SAFE_CMD = /^[A-Za-z][A-Za-z0-9._-]{0,63}$/;
|
|
563
|
+
for (const line of stderr.split(/\r?\n/)) {
|
|
564
|
+
const m = line.match(/^(?:bash|sh): (?:line \d+: )?([^:\s]+): command not found$/);
|
|
565
|
+
if (m?.[1]) {
|
|
566
|
+
const rawCmd = m[1].trim();
|
|
567
|
+
const cmd = rawCmd.split("/").pop() ?? rawCmd;
|
|
568
|
+
if (SAFE_CMD.test(cmd))
|
|
569
|
+
return cmd;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return null;
|
|
573
|
+
}
|
|
574
|
+
|
|
536
575
|
// ../../packages/core/dist/provisioning/frameworks/openclaw/index.js
|
|
537
576
|
import { execFile, spawn } from "child_process";
|
|
538
577
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync2, unlinkSync as unlinkSync2, chmodSync as chmodSync2, renameSync as renameSync2, symlinkSync } from "fs";
|
|
@@ -1924,6 +1963,9 @@ ${entry.content}`
|
|
|
1924
1963
|
maxBuffer: 1024 * 1024,
|
|
1925
1964
|
env: {
|
|
1926
1965
|
...process.env,
|
|
1966
|
+
// ENG-4510: prepend canonical brew + system bin dirs so hooks
|
|
1967
|
+
// resolve binaries when the manager runs under a minimal PATH.
|
|
1968
|
+
PATH: augmentedHookPath(process.env.PATH),
|
|
1927
1969
|
AGENT_CODE_NAME: ctx.codeName,
|
|
1928
1970
|
AGENT_DIR: agentDir,
|
|
1929
1971
|
AGENT_PROJECT_DIR: projectDir,
|
|
@@ -2683,26 +2725,109 @@ are defined in \`CHARTER.md\`.
|
|
|
2683
2725
|
**When in doubt, create a task.** Err on the side of tracking work rather than
|
|
2684
2726
|
doing it silently. Any work that takes more than ~30 seconds should be a kanban task.
|
|
2685
2727
|
|
|
2728
|
+
But: **clarify before you commit.** A vague task on the board is worse than
|
|
2729
|
+
no task \u2014 it bakes in the wrong scope and forces a rename later. If the
|
|
2730
|
+
request is fuzzy, ask one or two sharp questions FIRST and create the task
|
|
2731
|
+
once you understand what's actually being asked for.
|
|
2732
|
+
|
|
2686
2733
|
When you receive a request via any channel (Slack, Telegram, direct chat):
|
|
2687
2734
|
|
|
2688
2735
|
1. **First, check if the request is exempt** \u2014 the following do NOT need a task:
|
|
2689
2736
|
- One-line answers, yes/no questions, or simple factual lookups (under ~30 seconds)
|
|
2690
2737
|
- No-action acknowledgments: "thanks", "got it", "acknowledged", "will do", or other confirmations that require no further work
|
|
2691
|
-
2. **If not exempt,
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2738
|
+
2. **If not exempt, check if the request is clear enough to scope a sharp task title.**
|
|
2739
|
+
Ask yourself: "Could I write a one-line task title right now that another
|
|
2740
|
+
teammate would understand without asking me anything?"
|
|
2741
|
+
- **If yes** \u2192 continue to step 3.
|
|
2742
|
+
- **If no** \u2192 reply with **at most two** clarifying questions in the channel
|
|
2743
|
+
thread. Do NOT create the kanban task yet \u2014 it would be wrong by the
|
|
2744
|
+
time you came back. When you ask, also state the default you'll
|
|
2745
|
+
assume if they don't reply (e.g. "If you don't say, I'll go with the
|
|
2746
|
+
standard VP-eyes-on overview"). Once they reply (or you've waited
|
|
2747
|
+
long enough to act on the default), pick up at step 3.
|
|
2748
|
+
3. **Create the kanban task** with kanban.add. Title should be specific
|
|
2749
|
+
enough to be self-explanatory \u2014 "Pull Linear ENG sprint velocity for
|
|
2750
|
+
this fortnight" beats "Linear stats".
|
|
2751
|
+
4. Reply in the channel thread: "On it \u2014 tracking here: ${kanbanUrl ?? "my kanban board"}" (include the created task title)
|
|
2752
|
+
5. Move the task to in_progress with kanban.move
|
|
2753
|
+
6. Do the work
|
|
2754
|
+
7. Mark done with kanban.done including a result summary
|
|
2755
|
+
8. Reply in the channel thread with the result
|
|
2756
|
+
|
|
2757
|
+
Everything that isn't exempt gets a task \u2014 but only after the request is
|
|
2758
|
+
clear. Don't bury a clarifying question underneath a "tracking here" reply;
|
|
2759
|
+
ask the question alone, no kanban link, and let the user answer before
|
|
2760
|
+
anything goes on the board.
|
|
2699
2761
|
|
|
2700
2762
|
When asked about existing work, tasks, or what you've been doing \u2014 call kanban.list
|
|
2701
2763
|
first to load your recent board state. This gives you context about completed and
|
|
2702
2764
|
in-progress items so you can answer accurately.
|
|
2703
2765
|
|
|
2704
2766
|
${memorySection}
|
|
2705
|
-
${reportsToSection}${teamSection}${peopleSection}${integrationsSection}${knowledgeSection}##
|
|
2767
|
+
${reportsToSection}${teamSection}${peopleSection}${integrationsSection}${knowledgeSection}## Dashboards
|
|
2768
|
+
|
|
2769
|
+
You can publish your own dashboards inside the Augmented console. They are
|
|
2770
|
+
**first-class platform artifacts** \u2014 KPI tiles, charts, refresh-on-demand \u2014
|
|
2771
|
+
and replace any urge to write static HTML and host it elsewhere (GitHub
|
|
2772
|
+
Pages, public buckets, screenshots in chat).
|
|
2773
|
+
|
|
2774
|
+
**When the user asks for a dashboard, do this \u2014 never anything else:**
|
|
2775
|
+
|
|
2776
|
+
1. Plan a small set of widgets (KPI tiles for headlines, area/line for
|
|
2777
|
+
trends, bar for comparisons, donut for proportions).
|
|
2778
|
+
2. For each widget write \`{id, kind, title, prompt, schema}\`. The
|
|
2779
|
+
\`prompt\` is what future-you reads on every refresh; the \`schema\` is
|
|
2780
|
+
the JSON Schema your output must match.
|
|
2781
|
+
3. Call **\`dashboards.upsert\`** to register the dashboard. Set
|
|
2782
|
+
\`title\` and \`description\` so a teammate can find it later.
|
|
2783
|
+
4. Optionally call **\`dashboards.request_refresh\`** to populate the
|
|
2784
|
+
first snapshot. Otherwise widgets render "never refreshed" until cron
|
|
2785
|
+
fires or a user clicks \u21BB.
|
|
2786
|
+
|
|
2787
|
+
**Refresh loop \u2014 run whenever invoked:**
|
|
2788
|
+
|
|
2789
|
+
1. Call **\`dashboards.pending_refreshes\`**. Returns widgets queued for
|
|
2790
|
+
refresh with \`{slug, widget_id, kind, prompt, schema}\`.
|
|
2791
|
+
2. For each: read the prompt \u2192 use your tools (kanban, knowledge, your
|
|
2792
|
+
integrations) to gather data \u2192 format to match the schema exactly \u2192
|
|
2793
|
+
call **\`dashboards.persist_widget\`** with the result.
|
|
2794
|
+
3. Server validates against the schema; invalid output is rejected.
|
|
2795
|
+
|
|
2796
|
+
**If you don't see \`dashboards.upsert\` in your tool list, STOP and ask
|
|
2797
|
+
the user.** The console dashboards system is the canonical surface, but
|
|
2798
|
+
the tool may not yet be deployed in your environment. In that case:
|
|
2799
|
+
|
|
2800
|
+
> "I don't see the dashboards platform tool in my session. Do you want me
|
|
2801
|
+
> to wait until it's deployed, or build a one-off (static HTML, screenshot,
|
|
2802
|
+
> CSV) for now?"
|
|
2803
|
+
|
|
2804
|
+
Do NOT silently fall back to writing Python pipelines, Chart.js HTML,
|
|
2805
|
+
headless-Chrome screenshots, or any other bespoke rendering path. Those
|
|
2806
|
+
are dead-ends \u2014 they live on disk for one session, can't be refreshed,
|
|
2807
|
+
and don't show up in the console where teammates look. Ask first; let
|
|
2808
|
+
the user decide whether the gap is worth a workaround.
|
|
2809
|
+
|
|
2810
|
+
**Rules:**
|
|
2811
|
+
|
|
2812
|
+
- **Always quote the full URL when you tell the user a dashboard is live.**
|
|
2813
|
+
\`dashboards.upsert\` returns the absolute URL \u2014 paste that link verbatim,
|
|
2814
|
+
never a relative path like "/dashboards" or "in the console". Bad:
|
|
2815
|
+
"live in the console under /dashboards". Good:
|
|
2816
|
+
"live at ${consoleUrl ? consoleUrl + "/dashboards/<id>" : "<console>/dashboards/<id>"}".
|
|
2817
|
+
The same rule applies to \`dashboards.show\` and \`dashboards.list\` \u2014
|
|
2818
|
+
surface the URL they returned so a teammate can click straight through.
|
|
2819
|
+
- Never invent figures. If a tool returned nothing, persist zeros / empty
|
|
2820
|
+
arrays \u2014 don't fabricate plausible-looking numbers.
|
|
2821
|
+
- Don't write a dashboard to any other destination (GitHub Pages, S3, a
|
|
2822
|
+
shared markdown doc, a Telegram \`sendPhoto\`, a one-off /tmp file)
|
|
2823
|
+
unless the user explicitly asks for one of those formats. The console
|
|
2824
|
+
is the answer.
|
|
2825
|
+
- One LLM call per widget on refresh \u2014 don't bundle widgets into a
|
|
2826
|
+
single prompt; you'll lose schema strictness.
|
|
2827
|
+
- See \`.claude/skills/dashboards/SKILL.md\` (if installed) for the
|
|
2828
|
+
canonical kpi/area/line/bar/donut JSON Schemas you can copy.
|
|
2829
|
+
|
|
2830
|
+
## Development Workflow
|
|
2706
2831
|
|
|
2707
2832
|
### Repository Management
|
|
2708
2833
|
|
|
@@ -3136,6 +3261,10 @@ function buildMcpJson(input) {
|
|
|
3136
3261
|
AGT_API_KEY: process.env["AGT_API_KEY"] ?? "",
|
|
3137
3262
|
AGT_AGENT_ID: input.agent.agent_id,
|
|
3138
3263
|
AGT_AGENT_CODE_NAME: input.agent.code_name,
|
|
3264
|
+
// Console origin so the MCP bridge can build absolute URLs (e.g.
|
|
3265
|
+
// dashboard links) in tool replies. Falls back to NEXT_PUBLIC_APP_URL
|
|
3266
|
+
// / AGT_CONSOLE_URL — same chain consoleUrl uses for kanban links.
|
|
3267
|
+
AGT_APP_URL: process.env["AGT_APP_URL"] ?? process.env["NEXT_PUBLIC_APP_URL"] ?? process.env["AGT_CONSOLE_URL"] ?? "",
|
|
3139
3268
|
// Include PATH/HOME so the MCP subprocess can resolve binaries
|
|
3140
3269
|
PATH: process.env["PATH"] ?? "",
|
|
3141
3270
|
HOME: process.env["HOME"] ?? ""
|
|
@@ -3862,6 +3991,11 @@ ${sections}`
|
|
|
3862
3991
|
maxBuffer: 1024 * 1024,
|
|
3863
3992
|
env: {
|
|
3864
3993
|
...process.env,
|
|
3994
|
+
// ENG-4510: prepend canonical brew + system bin dirs so hooks
|
|
3995
|
+
// resolve binaries (npm, npx, qmd, xurl, …) when the manager is
|
|
3996
|
+
// spawned from cloud-init with a minimal PATH. Otherwise hooks
|
|
3997
|
+
// exit 127 ("command not found") on fresh prod EC2 hosts.
|
|
3998
|
+
PATH: augmentedHookPath(process.env.PATH),
|
|
3865
3999
|
AGENT_CODE_NAME: ctx.codeName,
|
|
3866
4000
|
AGENT_DIR: agentRootDir,
|
|
3867
4001
|
AGENT_PROJECT_DIR: projectDir,
|
|
@@ -3976,7 +4110,16 @@ These credentials are pre-loaded. Reference them by their environment variable n
|
|
|
3976
4110
|
|
|
3977
4111
|
The only things that don't need a task: one-line answers, yes/no questions, simple factual lookups you can answer in under 30 seconds, or no-action acknowledgments ("thanks", "got it", "acknowledged", "will do") that require no further work. Everything else gets a task.
|
|
3978
4112
|
|
|
3979
|
-
The cost of an unnecessary task is near zero. The cost of invisible work is confusion, duplication, and lost context
|
|
4113
|
+
The cost of an unnecessary task is near zero. The cost of invisible work is confusion, duplication, and lost context.
|
|
4114
|
+
|
|
4115
|
+
**Always confirm task creation back to the requester via the same channel they reached you on.** When you create a kanban task in response to a Slack/direct-chat/email/etc. message, your *next* action MUST be to call that channel's send/reply tool with:
|
|
4116
|
+
|
|
4117
|
+
(a) a one-line acknowledgment of what you'll do, and
|
|
4118
|
+
(b) **the full kanban deep link URL** \u2014 quote it verbatim from the kanban tool's response, including the \`https://\` prefix and the full path (use the exact \`https://...\` URL the tool emits \u2014 do not invent or rewrite it). Identifiers, short slugs, or "see kanban" references are not acceptable substitutes \u2014 the user must be able to click straight through.
|
|
4119
|
+
|
|
4120
|
+
The kanban tools include the deep-link URL in their response. Locate the full URL in the tool result text (or in its \`details\` payload) and copy it verbatim into your channel reply, regardless of the surrounding sentence shape. The user has no way to see your kanban unless you give them the link \u2014 silent task creation feels like you ignored them.
|
|
4121
|
+
|
|
4122
|
+
**Your turn is not finished until you reply on the channel.** If a user contacted you via a channel tool, you must end the turn by calling that channel's reply tool. Do not just emit assistant text and stop \u2014 text emitted without a channel-reply tool call is invisible to the user. This applies to every reply, not only kanban acknowledgments: confirmation questions, status updates, results, and final answers all need to go through the channel tool.`);
|
|
3980
4123
|
return sections.join("\n\n");
|
|
3981
4124
|
}
|
|
3982
4125
|
function stripFrontmatter(content) {
|
|
@@ -4933,6 +5076,14 @@ function looksLikeNotesOnly(remainder) {
|
|
|
4933
5076
|
return lines.every((line) => NON_DELIVERABLE_REMAINDER_PATTERNS.some((pattern) => pattern.test(line)));
|
|
4934
5077
|
}
|
|
4935
5078
|
|
|
5079
|
+
// ../../packages/core/dist/types/kanban.js
|
|
5080
|
+
function formatActorId(kind, id) {
|
|
5081
|
+
return `${kind}:${id}`;
|
|
5082
|
+
}
|
|
5083
|
+
function isSelfCompletion(event) {
|
|
5084
|
+
return event.last_actor_id === formatActorId("agent", event.agent_id);
|
|
5085
|
+
}
|
|
5086
|
+
|
|
4936
5087
|
// ../../packages/core/dist/schemas/validators.js
|
|
4937
5088
|
import Ajv2020 from "ajv/dist/2020.js";
|
|
4938
5089
|
import addFormats from "ajv-formats";
|
|
@@ -6893,6 +7044,7 @@ export {
|
|
|
6893
7044
|
getChannel,
|
|
6894
7045
|
getAllChannelIds,
|
|
6895
7046
|
getIntegration,
|
|
7047
|
+
extractCommandNotFound,
|
|
6896
7048
|
provisionStopHook,
|
|
6897
7049
|
provisionIsolationHook,
|
|
6898
7050
|
setJsonMode,
|
|
@@ -6912,6 +7064,8 @@ export {
|
|
|
6912
7064
|
warn,
|
|
6913
7065
|
info,
|
|
6914
7066
|
table,
|
|
7067
|
+
formatActorId,
|
|
7068
|
+
isSelfCompletion,
|
|
6915
7069
|
resolveChannels,
|
|
6916
7070
|
SLACK_SCOPE_CATEGORY_LABELS,
|
|
6917
7071
|
getDefaultSlackScopes,
|
|
@@ -6939,4 +7093,4 @@ export {
|
|
|
6939
7093
|
managerStopCommand,
|
|
6940
7094
|
managerStatusCommand
|
|
6941
7095
|
};
|
|
6942
|
-
//# sourceMappingURL=chunk-
|
|
7096
|
+
//# sourceMappingURL=chunk-7QE6SJQB.js.map
|