@integrity-labs/agt-cli 0.28.424 → 0.28.426
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-CWIWI2ZX.js → chunk-HXP4I5QZ.js} +228 -2
- package/dist/chunk-HXP4I5QZ.js.map +1 -0
- package/dist/{chunk-2QBY2QVX.js → chunk-XDODHW3I.js} +3 -3
- package/dist/{claude-pair-runtime-PAP4BS3I.js → claude-pair-runtime-OONIISXX.js} +2 -2
- package/dist/lib/manager-worker.js +104 -22
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +80 -0
- package/dist/mcp/origami.js +80 -0
- package/dist/mcp/slack-channel.js +80 -0
- package/dist/mcp/telegram-channel.js +80 -0
- package/dist/{persistent-session-O7OCNB6B.js → persistent-session-AKMSEWFL.js} +2 -2
- package/dist/{responsiveness-probe-R5FWKHPI.js → responsiveness-probe-FAIPVVYA.js} +2 -2
- package/dist/responsiveness-probe-FAIPVVYA.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-CWIWI2ZX.js.map +0 -1
- package/dist/responsiveness-probe-R5FWKHPI.js.map +0 -1
- /package/dist/{chunk-2QBY2QVX.js.map → chunk-XDODHW3I.js.map} +0 -0
- /package/dist/{claude-pair-runtime-PAP4BS3I.js.map → claude-pair-runtime-OONIISXX.js.map} +0 -0
- /package/dist/{persistent-session-O7OCNB6B.js.map → persistent-session-AKMSEWFL.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-XDODHW3I.js";
|
|
44
44
|
import {
|
|
45
45
|
AnchorSessionClient,
|
|
46
46
|
CHANNEL_REGISTRY,
|
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
renderTemplate,
|
|
71
71
|
resolveChannels,
|
|
72
72
|
serializeManifestForSlackCli
|
|
73
|
-
} from "../chunk-
|
|
73
|
+
} from "../chunk-HXP4I5QZ.js";
|
|
74
74
|
import "../chunk-XWVM4KPK.js";
|
|
75
75
|
|
|
76
76
|
// src/bin/agt.ts
|
|
@@ -4829,7 +4829,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
4829
4829
|
import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
|
|
4830
4830
|
import chalk18 from "chalk";
|
|
4831
4831
|
import ora16 from "ora";
|
|
4832
|
-
var cliVersion = true ? "0.28.
|
|
4832
|
+
var cliVersion = true ? "0.28.426" : "dev";
|
|
4833
4833
|
async function fetchLatestVersion() {
|
|
4834
4834
|
const host2 = getHost();
|
|
4835
4835
|
if (!host2) return null;
|
|
@@ -6001,7 +6001,7 @@ function handleError(err) {
|
|
|
6001
6001
|
}
|
|
6002
6002
|
|
|
6003
6003
|
// src/bin/agt.ts
|
|
6004
|
-
var cliVersion2 = true ? "0.28.
|
|
6004
|
+
var cliVersion2 = true ? "0.28.426" : "dev";
|
|
6005
6005
|
var program = new Command();
|
|
6006
6006
|
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");
|
|
6007
6007
|
program.hook("preAction", async (thisCommand, actionCommand) => {
|
|
@@ -5902,6 +5902,86 @@ var INTEGRATION_REGISTRY = [
|
|
|
5902
5902
|
]
|
|
5903
5903
|
}
|
|
5904
5904
|
},
|
|
5905
|
+
{
|
|
5906
|
+
// Social Scraping: a PREMIUM, platform-managed integration on the Deck /
|
|
5907
|
+
// Firecrawl / X-Search model (ADR-0031, epic ENG-6920; ADR-0053). Backed by
|
|
5908
|
+
// Apify, but deliberately NOT surfaced as an "Apify" integration - the
|
|
5909
|
+
// integration is what a customer picks, and Apify is a vendor, not a job.
|
|
5910
|
+
// Splitting by job also means opt-in, rate card and monthly budget are keyed
|
|
5911
|
+
// per definition, so an org can take Local Business Data without taking the
|
|
5912
|
+
// pricier, more ToS-sensitive social scraping.
|
|
5913
|
+
//
|
|
5914
|
+
// Augmented holds ONE Apify account whose token (APIFY_API_TOKEN, read
|
|
5915
|
+
// from SSM - the API Lambda env is at the 4KB cap) every customer run bills
|
|
5916
|
+
// back to, so the key is a single platform-held secret, NOT a per-agent
|
|
5917
|
+
// credential. Auth type is `none` - customers never enter a key. Tools run on
|
|
5918
|
+
// a brokered-REST lane (apify-brokers.ts) so each run is metered at one
|
|
5919
|
+
// chokepoint and gated on a per-org monthly USD cap + the per-org premium
|
|
5920
|
+
// opt-in.
|
|
5921
|
+
//
|
|
5922
|
+
// "PPE-only" is guaranteed by a curated allowlist: the broker only ever runs
|
|
5923
|
+
// Actors on it, so a rental / pay-per-usage Actor can never surprise-bill the
|
|
5924
|
+
// shared account. (Apify's x402 rail enforces PPE-only at the payment layer;
|
|
5925
|
+
// we are on the account-key rail - Option A in the spike.) See
|
|
5926
|
+
// docs/design/apify-premium-option-a-ppe-allowlist.md.
|
|
5927
|
+
//
|
|
5928
|
+
// No `installable` here on purpose: this is a seed integration
|
|
5929
|
+
// (integration-definitions.json), so the seed catalog already makes it
|
|
5930
|
+
// picker-visible. This registry entry exists ONLY to carry the `premium`
|
|
5931
|
+
// descriptor that `isPremiumDefinition` reads - which arms the per-org opt-in
|
|
5932
|
+
// gate, the priced acknowledgement modal, and the admin pricing tab.
|
|
5933
|
+
id: "social-scraping",
|
|
5934
|
+
name: "Social Scraping",
|
|
5935
|
+
category: "social",
|
|
5936
|
+
description: "Pull public posts and videos from TikTok, Instagram and YouTube - captions, media, engagement counts and URLs - for brand, competitor and campaign research. Augmented Team manages the scraping account for you; there is no key to enter.",
|
|
5937
|
+
supported_auth_types: ["none"],
|
|
5938
|
+
capabilities: [
|
|
5939
|
+
{ id: "social-scraping:scrape", name: "Scrape Social Posts", description: "Scrape public TikTok, Instagram and YouTube content (social_scrape_tiktok, social_scrape_instagram, social_scrape_youtube).", access: "write" },
|
|
5940
|
+
{ id: "social-scraping:status", name: "Check Scrape Runs", description: "Poll a running scrape for status + results (social_scrape_status).", access: "read" }
|
|
5941
|
+
],
|
|
5942
|
+
docs_url: "https://docs.apify.com/api/v2",
|
|
5943
|
+
beta: true,
|
|
5944
|
+
// Premium (billable). The upstream pay-per-event cost is per-Actor and
|
|
5945
|
+
// VARIABLE (each Actor's creator sets its own event prices), unlike X-Search's
|
|
5946
|
+
// fixed per-post price. So we meter the ACTUAL cost charged to us for each
|
|
5947
|
+
// run, as a pass-through: `units` = the run's `usageTotalUsd` in whole US
|
|
5948
|
+
// cents (the physical unit `usd_cent`), and the rate card prices each cent at
|
|
5949
|
+
// a managed markup (1.5x USD). This keeps margin safe across cheap and
|
|
5950
|
+
// expensive scrapes alike. `event_type` must match what the broker writes to
|
|
5951
|
+
// integration_usage_events. Until the rate row is seeded a run prices at 0
|
|
5952
|
+
// (budget gate inert) - the rate-card migration ships in the same PR.
|
|
5953
|
+
premium: {
|
|
5954
|
+
pricing: "usage",
|
|
5955
|
+
note: "Billed per result on the upstream pay-per-event cost of each scrape, at a managed markup.",
|
|
5956
|
+
meters: [{ event_type: "actor_run", unit: "usd_cent" }]
|
|
5957
|
+
}
|
|
5958
|
+
},
|
|
5959
|
+
{
|
|
5960
|
+
// Local Business Data: the second Apify-backed premium integration (ADR-0053).
|
|
5961
|
+
// Same platform-held account, same pass-through metering model, but a separate
|
|
5962
|
+
// definition so its opt-in, rate card and monthly budget are independent of
|
|
5963
|
+
// Social Scraping's - see the note on that entry for why the split exists.
|
|
5964
|
+
//
|
|
5965
|
+
// Distinct from Firecrawl on purpose: Firecrawl covers generic web
|
|
5966
|
+
// scrape/crawl/search, and we deliberately do NOT ship an Apify-backed
|
|
5967
|
+
// duplicate of that. This is the local-places job Firecrawl does not do.
|
|
5968
|
+
id: "local-business-data",
|
|
5969
|
+
name: "Local Business Data",
|
|
5970
|
+
category: "knowledge",
|
|
5971
|
+
description: "Find local businesses on Google Maps and pull their public listing details - name, address, phone, website, category, rating and review count - for local market research, competitor lists and lead research. Augmented Team manages the data account for you; there is no key to enter.",
|
|
5972
|
+
supported_auth_types: ["none"],
|
|
5973
|
+
capabilities: [
|
|
5974
|
+
{ id: "local-business-data:search", name: "Search Local Businesses", description: "Search Google Maps for businesses and return their public listing details (local_business_search).", access: "write" },
|
|
5975
|
+
{ id: "local-business-data:status", name: "Check Searches", description: "Poll a running search for status + results (local_business_search_status).", access: "read" }
|
|
5976
|
+
],
|
|
5977
|
+
docs_url: "https://docs.apify.com/api/v2",
|
|
5978
|
+
beta: true,
|
|
5979
|
+
premium: {
|
|
5980
|
+
pricing: "usage",
|
|
5981
|
+
note: "Billed per place returned on the upstream pay-per-event cost of each search, at a managed markup.",
|
|
5982
|
+
meters: [{ event_type: "actor_run", unit: "usd_cent" }]
|
|
5983
|
+
}
|
|
5984
|
+
},
|
|
5905
5985
|
{
|
|
5906
5986
|
// Seed-catalog toolkit (composed by the ultimate-app-coder bundle). Registered
|
|
5907
5987
|
// here only so the manager's ensureToolkitCli installs the binary via the
|
|
@@ -10364,8 +10444,150 @@ var TurnOutcomeTracker = class {
|
|
|
10364
10444
|
}
|
|
10365
10445
|
};
|
|
10366
10446
|
|
|
10447
|
+
// src/lib/busy-bucket-ledger.ts
|
|
10448
|
+
var BUCKET_MS = 6e4;
|
|
10449
|
+
var MAX_ACCRUAL_SPAN_MS = 10 * 6e4;
|
|
10450
|
+
var MAX_RETAINED_BUCKETS = 240;
|
|
10451
|
+
var BILL_WHOLE_MINUTES = true;
|
|
10452
|
+
var MIN_BILLABLE_MS = 100;
|
|
10453
|
+
function bucketStartMs(atMs) {
|
|
10454
|
+
return Math.floor(atMs / BUCKET_MS) * BUCKET_MS;
|
|
10455
|
+
}
|
|
10456
|
+
var BusyBucketLedger = class {
|
|
10457
|
+
state = /* @__PURE__ */ new Map();
|
|
10458
|
+
entry(codeName) {
|
|
10459
|
+
let cur = this.state.get(codeName);
|
|
10460
|
+
if (!cur) {
|
|
10461
|
+
cur = { buckets: /* @__PURE__ */ new Map(), openSince: null };
|
|
10462
|
+
this.state.set(codeName, cur);
|
|
10463
|
+
}
|
|
10464
|
+
return cur;
|
|
10465
|
+
}
|
|
10466
|
+
/**
|
|
10467
|
+
* Credit occupancy for the span [fromMs, toMs), splitting it across every
|
|
10468
|
+
* minute bucket it covers. Safe to call with any ordering — a reversed or
|
|
10469
|
+
* zero-length span is a no-op rather than a negative credit.
|
|
10470
|
+
*/
|
|
10471
|
+
accrueSpan(codeName, fromMs, toMs) {
|
|
10472
|
+
if (!Number.isFinite(fromMs) || !Number.isFinite(toMs)) return;
|
|
10473
|
+
if (toMs <= fromMs) return;
|
|
10474
|
+
const start = Math.max(fromMs, toMs - MAX_ACCRUAL_SPAN_MS);
|
|
10475
|
+
const led = this.entry(codeName);
|
|
10476
|
+
for (let b = bucketStartMs(start); b < toMs; b += BUCKET_MS) {
|
|
10477
|
+
const overlap = Math.min(toMs, b + BUCKET_MS) - Math.max(start, b);
|
|
10478
|
+
if (overlap <= 0) continue;
|
|
10479
|
+
const prev = led.buckets.get(b) ?? 0;
|
|
10480
|
+
led.buckets.set(b, Math.min(BUCKET_MS, prev + overlap));
|
|
10481
|
+
}
|
|
10482
|
+
this.evict(led);
|
|
10483
|
+
}
|
|
10484
|
+
/** The agent started doing work. Idempotent while already occupied. */
|
|
10485
|
+
open(codeName, atMs) {
|
|
10486
|
+
const led = this.entry(codeName);
|
|
10487
|
+
if (led.openSince == null) led.openSince = atMs;
|
|
10488
|
+
}
|
|
10489
|
+
/**
|
|
10490
|
+
* Accrue everything owed up to `nowMs` WITHOUT ending the occupancy. This is
|
|
10491
|
+
* what makes a long turn fill every bucket it spans: each probe pass ticks,
|
|
10492
|
+
* banking the elapsed slice and moving the watermark forward.
|
|
10493
|
+
*/
|
|
10494
|
+
tick(codeName, nowMs) {
|
|
10495
|
+
const led = this.state.get(codeName);
|
|
10496
|
+
if (!led || led.openSince == null) return;
|
|
10497
|
+
if (nowMs <= led.openSince) return;
|
|
10498
|
+
this.accrueSpan(codeName, led.openSince, nowMs);
|
|
10499
|
+
led.openSince = nowMs;
|
|
10500
|
+
}
|
|
10501
|
+
/** The agent stopped doing work. Banks the final slice. */
|
|
10502
|
+
close(codeName, atMs) {
|
|
10503
|
+
const led = this.state.get(codeName);
|
|
10504
|
+
if (!led || led.openSince == null) return;
|
|
10505
|
+
this.accrueSpan(codeName, led.openSince, atMs);
|
|
10506
|
+
led.openSince = null;
|
|
10507
|
+
}
|
|
10508
|
+
/**
|
|
10509
|
+
* Take every CLOSED bucket for reporting, removing it from the ledger.
|
|
10510
|
+
*
|
|
10511
|
+
* Only closed buckets — a bucket whose minute has not yet elapsed is still
|
|
10512
|
+
* accruing, and reporting it early would send a partial value that the next
|
|
10513
|
+
* drain would have to correct. The open bucket stays and is drained once it
|
|
10514
|
+
* closes.
|
|
10515
|
+
*
|
|
10516
|
+
* DESTRUCTIVE, deliberately: this is the same read-and-reset contract as the
|
|
10517
|
+
* watchdog give-up counters, and it carries the same obligation — the caller
|
|
10518
|
+
* MUST `credit()` the result back if the POST fails, or a transient 5xx
|
|
10519
|
+
* permanently deletes billable occupancy that cannot be reconstructed.
|
|
10520
|
+
*/
|
|
10521
|
+
drainClosed(codeName, nowMs) {
|
|
10522
|
+
const led = this.state.get(codeName);
|
|
10523
|
+
if (!led) return [];
|
|
10524
|
+
this.tick(codeName, nowMs);
|
|
10525
|
+
const openBucket = bucketStartMs(nowMs);
|
|
10526
|
+
const out = [];
|
|
10527
|
+
for (const [b, ms] of [...led.buckets].sort((x, y) => x[0] - y[0])) {
|
|
10528
|
+
if (b >= openBucket) continue;
|
|
10529
|
+
led.buckets.delete(b);
|
|
10530
|
+
if (ms < MIN_BILLABLE_MS) continue;
|
|
10531
|
+
const seconds = BILL_WHOLE_MINUTES ? 60 : Math.min(60, Math.ceil(ms / 1e3));
|
|
10532
|
+
out.push({ bucket: new Date(b).toISOString(), seconds });
|
|
10533
|
+
}
|
|
10534
|
+
return out;
|
|
10535
|
+
}
|
|
10536
|
+
/**
|
|
10537
|
+
* Put drained buckets back after a failed POST. Merges rather than replaces,
|
|
10538
|
+
* so occupancy accrued since the drain is preserved.
|
|
10539
|
+
*/
|
|
10540
|
+
credit(codeName, buckets) {
|
|
10541
|
+
if (buckets.length === 0) return;
|
|
10542
|
+
const led = this.entry(codeName);
|
|
10543
|
+
for (const b of buckets) {
|
|
10544
|
+
const at = Date.parse(b.bucket);
|
|
10545
|
+
if (!Number.isFinite(at)) continue;
|
|
10546
|
+
const key = bucketStartMs(at);
|
|
10547
|
+
const prev = led.buckets.get(key) ?? 0;
|
|
10548
|
+
led.buckets.set(key, Math.min(BUCKET_MS, prev + b.seconds * 1e3));
|
|
10549
|
+
}
|
|
10550
|
+
this.evict(led);
|
|
10551
|
+
}
|
|
10552
|
+
/** Agents currently holding reportable state. */
|
|
10553
|
+
trackedAgents() {
|
|
10554
|
+
return [...this.state.keys()];
|
|
10555
|
+
}
|
|
10556
|
+
/**
|
|
10557
|
+
* Drop everything for an agent. Called from the same teardown that resets
|
|
10558
|
+
* turn health, so a fresh session is not born holding the dead one's
|
|
10559
|
+
* occupancy.
|
|
10560
|
+
*/
|
|
10561
|
+
reset(codeName) {
|
|
10562
|
+
this.state.delete(codeName);
|
|
10563
|
+
}
|
|
10564
|
+
evict(led) {
|
|
10565
|
+
if (led.buckets.size <= MAX_RETAINED_BUCKETS) return;
|
|
10566
|
+
const ordered = [...led.buckets.keys()].sort((a, b) => a - b);
|
|
10567
|
+
for (const k of ordered.slice(0, led.buckets.size - MAX_RETAINED_BUCKETS)) {
|
|
10568
|
+
led.buckets.delete(k);
|
|
10569
|
+
}
|
|
10570
|
+
}
|
|
10571
|
+
};
|
|
10572
|
+
var sharedBusyBuckets = new BusyBucketLedger();
|
|
10573
|
+
|
|
10367
10574
|
// src/lib/opencode-activity-tracker.ts
|
|
10368
10575
|
var OpencodeActivityTracker = class {
|
|
10576
|
+
/**
|
|
10577
|
+
* ENG-8116: the same lifecycle also drives the duration ledger. opencode is
|
|
10578
|
+
* the runtime that can measure occupancy EXACTLY — beginTurn/endTurn bracket
|
|
10579
|
+
* real work — so the spans go straight in rather than being inferred from a
|
|
10580
|
+
* file mtime the way Claude Code's have to be.
|
|
10581
|
+
*
|
|
10582
|
+
* Kept inside this class deliberately, rather than having callers poke both:
|
|
10583
|
+
* the lifecycle discipline that makes occupancy correct (the `finally`, the
|
|
10584
|
+
* live-session guard) already lives at one call site, and a second one to
|
|
10585
|
+
* keep in sync is exactly how a leaked in-flight count would bill an idle
|
|
10586
|
+
* agent around the clock.
|
|
10587
|
+
*/
|
|
10588
|
+
constructor(ledger = sharedBusyBuckets) {
|
|
10589
|
+
this.ledger = ledger;
|
|
10590
|
+
}
|
|
10369
10591
|
state = /* @__PURE__ */ new Map();
|
|
10370
10592
|
entry(codeName) {
|
|
10371
10593
|
let cur = this.state.get(codeName);
|
|
@@ -10376,8 +10598,9 @@ var OpencodeActivityTracker = class {
|
|
|
10376
10598
|
return cur;
|
|
10377
10599
|
}
|
|
10378
10600
|
/** A turn has been dispatched to the serve. Call BEFORE awaiting it. */
|
|
10379
|
-
beginTurn(codeName) {
|
|
10601
|
+
beginTurn(codeName, now = Date.now()) {
|
|
10380
10602
|
this.entry(codeName).inFlight += 1;
|
|
10603
|
+
this.ledger.open(codeName, now);
|
|
10381
10604
|
}
|
|
10382
10605
|
/**
|
|
10383
10606
|
* A dispatched turn has resolved. Call in a `finally`, so a throw cannot
|
|
@@ -10391,6 +10614,7 @@ var OpencodeActivityTracker = class {
|
|
|
10391
10614
|
const cur = this.entry(codeName);
|
|
10392
10615
|
cur.inFlight = Math.max(0, cur.inFlight - 1);
|
|
10393
10616
|
if (counted) cur.lastActiveAt = now;
|
|
10617
|
+
if (cur.inFlight === 0) this.ledger.close(codeName, now);
|
|
10394
10618
|
}
|
|
10395
10619
|
/**
|
|
10396
10620
|
* Seconds since this agent was last doing work, or null if it never has been
|
|
@@ -10414,6 +10638,7 @@ var OpencodeActivityTracker = class {
|
|
|
10414
10638
|
*/
|
|
10415
10639
|
reset(codeName) {
|
|
10416
10640
|
this.state.delete(codeName);
|
|
10641
|
+
this.ledger.reset(codeName);
|
|
10417
10642
|
}
|
|
10418
10643
|
};
|
|
10419
10644
|
|
|
@@ -12688,6 +12913,7 @@ export {
|
|
|
12688
12913
|
sha256,
|
|
12689
12914
|
hashFile,
|
|
12690
12915
|
execFilePromiseLong,
|
|
12916
|
+
sharedBusyBuckets,
|
|
12691
12917
|
readProvisionedOpencodeModel,
|
|
12692
12918
|
startOpencodeSession,
|
|
12693
12919
|
readOpencodePaneLogTail,
|
|
@@ -12745,4 +12971,4 @@ export {
|
|
|
12745
12971
|
stopAllSessionsAndWait,
|
|
12746
12972
|
getProjectDir
|
|
12747
12973
|
};
|
|
12748
|
-
//# sourceMappingURL=chunk-
|
|
12974
|
+
//# sourceMappingURL=chunk-HXP4I5QZ.js.map
|