@integrity-labs/agt-cli 0.28.874 → 0.28.876

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.
Files changed (24) hide show
  1. package/dist/bin/agt.js +5 -5
  2. package/dist/{chunk-UG2N5V4P.js → chunk-4FPSI5P4.js} +4 -4
  3. package/dist/{chunk-SQ7PB5A6.js → chunk-CA46EUVN.js} +2 -2
  4. package/dist/{chunk-Q2OVEMUG.js → chunk-EARM456T.js} +92 -1
  5. package/dist/chunk-EARM456T.js.map +1 -0
  6. package/dist/{claude-pair-runtime-GRZ2EHHR.js → claude-pair-runtime-G3SEYGH6.js} +2 -2
  7. package/dist/lib/manager-worker.js +21 -15
  8. package/dist/lib/manager-worker.js.map +1 -1
  9. package/dist/mcp/direct-chat-channel.js +91 -0
  10. package/dist/mcp/index.js +91 -0
  11. package/dist/mcp/origami.js +91 -0
  12. package/dist/mcp/slack-channel.js +188 -5
  13. package/dist/mcp/telegram-channel.js +91 -0
  14. package/dist/{persistent-session-MG6FEYRY.js → persistent-session-XQG5H4KI.js} +3 -3
  15. package/dist/{responsiveness-probe-2OGWHDXE.js → responsiveness-probe-LA4VGH5W.js} +3 -3
  16. package/dist/{session-auth-dead-AHL6D3CM.js → session-auth-dead-DFLSWVAQ.js} +2 -2
  17. package/package.json +1 -1
  18. package/dist/chunk-Q2OVEMUG.js.map +0 -1
  19. /package/dist/{chunk-UG2N5V4P.js.map → chunk-4FPSI5P4.js.map} +0 -0
  20. /package/dist/{chunk-SQ7PB5A6.js.map → chunk-CA46EUVN.js.map} +0 -0
  21. /package/dist/{claude-pair-runtime-GRZ2EHHR.js.map → claude-pair-runtime-G3SEYGH6.js.map} +0 -0
  22. /package/dist/{persistent-session-MG6FEYRY.js.map → persistent-session-XQG5H4KI.js.map} +0 -0
  23. /package/dist/{responsiveness-probe-2OGWHDXE.js.map → responsiveness-probe-LA4VGH5W.js.map} +0 -0
  24. /package/dist/{session-auth-dead-AHL6D3CM.js.map → session-auth-dead-DFLSWVAQ.js.map} +0 -0
@@ -34161,6 +34161,97 @@ var INTEGRATION_REGISTRY = [
34161
34161
  ]
34162
34162
  }
34163
34163
  },
34164
+ {
34165
+ id: "origami",
34166
+ name: "origami.chat",
34167
+ category: "crm",
34168
+ description: "Lead data + outbound: build and enrich lead lists, drive origami's AI worker from a natural-language brief, and read the tables it builds. Available on the platform-managed account, or with your own origami key.",
34169
+ // ENG-7423: origami migrates from a customer-key-only integration to a
34170
+ // PREMIUM one that ALSO keeps BYO — the Firecrawl / ADR-0055 model, with one
34171
+ // structural difference that drives most of the design.
34172
+ //
34173
+ // Firecrawl's premium tier is a single platform account key that every
34174
+ // customer's calls bill back to, and isolation is not a concern because a
34175
+ // scrape has no tenancy. origami is the opposite: it stores the customer's
34176
+ // LEAD LISTS, tables, chats and campaigns. Putting every customer on one
34177
+ // parent org would make every customer's data mutually readable, so the
34178
+ // managed tier gives each ORGANIZATION its own origami project (child org)
34179
+ // and mints a key BOUND to that project (`POST /account/keys` with
34180
+ // `project_id`, v3). See `packages/core/src/origami/provision.ts` for why a
34181
+ // bound key rather than the `x-origami-project` header — in short, the
34182
+ // header is a per-call assertion and the tool argument is deliberately
34183
+ // nullable, so under a shared parent an ordinary tool call could reach it.
34184
+ //
34185
+ // ── auth types, and the ENG-9235 trap this deliberately re-enters ─────────
34186
+ // Both are offered, unlike Firecrawl, which PARKED `api_key` down to
34187
+ // `['none']` because a 2+-auth-type wizard renders a picker that is not
34188
+ // entitlement-aware: a customer picks BYO, goes and fetches a vendor key,
34189
+ // and is then rejected with `byo_not_entitled_by_plan` (BYO on a premium def
34190
+ // needs `plans.byo_credentials`, enterprise-only today).
34191
+ //
34192
+ // origami cannot take that exit. BYO is the INCUMBENT here — every existing
34193
+ // install is a customer's own key — so dropping `api_key` would remove the
34194
+ // only mode its current customers use. The known gap is therefore accepted
34195
+ // and pointed at its owner: the picker will still let a non-entitled org
34196
+ // choose BYO and reject it afterwards. ENG-9236 (entitlement-aware wizard)
34197
+ // is the fix; until it lands the rejection is at least loud, specific, and
34198
+ // ahead of any charge.
34199
+ //
34200
+ // EXISTING installs are unaffected by that gate: the premium migration
34201
+ // backfills them to `credential_source='byo'` AND stamps
34202
+ // `config.byo_grandfathered_at`, which the call-time resolver honours in
34203
+ // place of the plan check. Grandfathering is per-install and set only by
34204
+ // that one migration — a NEW BYO install still needs the entitlement.
34205
+ //
34206
+ // KEEP IN LOCKSTEP with the `origami` rows in
34207
+ // packages/supabase/seeds/integration-definitions.json and
34208
+ // toolkit-definitions.json: those seeds carry their own auth types and are
34209
+ // what `db:catalog:seed` upserts on every prod deploy, so editing this array
34210
+ // alone changes nothing a customer can see.
34211
+ supported_auth_types: ["none", "api_key"],
34212
+ capabilities: [
34213
+ { id: "origami:read", name: "Read Lists & Runs", description: "Discover projects and tables, read built tables and rows, poll runs/batches, and check credit balance. Credit-free.", access: "read" },
34214
+ { id: "origami:write", name: "Enrich Leads", description: "Insert raw rows into an enrichment table (submit_enrichment). Consumes credits.", access: "write" },
34215
+ { id: "origami:agent", name: "Drive the AI Worker", description: "Create an origami agent, send follow-up runs, cancel a run, archive an agent. Consumes credits.", access: "write" }
34216
+ ],
34217
+ docs_url: "https://docs.origami.chat/v3/overview",
34218
+ // ENG-7423: premium (billable). origami bills internally in CREDITS, so the
34219
+ // integration is usage-priced on one meter whose unit is the vendor's own
34220
+ // billing unit. Priced at 2.0 c USD / 3.5 c AUD per credit by
34221
+ // `20260907000050_origami_credits_rate_card.sql`, against a retail cost of
34222
+ // 1.29-1.43 c/credit depending on which origami tier we hold.
34223
+ //
34224
+ // The note deliberately does NOT say "at cost". origami sells a
34225
+ // SUBSCRIPTION WITH AN INCLUDED BUNDLE while this meters PER CREDIT
34226
+ // CONSUMED, so a per-credit price recovers the subscription only at full
34227
+ // utilisation — around 72% of the bundle at this rate. Calling that "at
34228
+ // cost" in a customer-facing pricing string would be a claim about our
34229
+ // margin that is only true at one utilisation level we do not control.
34230
+ //
34231
+ // ONE meter, not one per tool, because of where the number comes from. Every
34232
+ // other premium integration meters at a server-side broker chokepoint, which
34233
+ // sees each call and can attribute it. origami's agent surface is a
34234
+ // host-resident stdio MCP server (ADR-0040) that calls origami.chat DIRECTLY
34235
+ // — the control plane never sees the tool call, so there is no per-operation
34236
+ // quantity to meter. What the control plane CAN see is the project's own
34237
+ // spend (`GET /account/projects/{id}` → `usage.spent`), which the credit
34238
+ // reconciler polls and meters as a delta. That is a per-project total, so it
34239
+ // can only ever be one meter; splitting it per tool would require the vendor
34240
+ // to break spend down by operation, which v3 does not expose.
34241
+ //
34242
+ // `unit_label` is set because the machine unit is the vendor's internal
34243
+ // billing unit rather than a thing the customer asked for — "(per credit)"
34244
+ // is the honest rendering, in the ADR-0053 cost-pass-through spirit.
34245
+ //
34246
+ // Only a MANAGED install is metered. A BYO install spends the customer's own
34247
+ // origami credits on their own bill (`isBilledInstall` → false), which is why
34248
+ // the reconciler polls only projects it provisioned.
34249
+ premium: {
34250
+ pricing: "usage",
34251
+ note: "Billed per origami credit the agent consumes. Bring your own origami key instead and usage is billed to you by origami directly.",
34252
+ meters: [{ event_type: "credits", unit: "credit", label: "origami credits", unit_label: "credit" }]
34253
+ }
34254
+ },
34164
34255
  {
34165
34256
  id: "ayrshare",
34166
34257
  name: "Ayrshare",
package/dist/mcp/index.js CHANGED
@@ -26735,6 +26735,97 @@ var INTEGRATION_REGISTRY = [
26735
26735
  ]
26736
26736
  }
26737
26737
  },
26738
+ {
26739
+ id: "origami",
26740
+ name: "origami.chat",
26741
+ category: "crm",
26742
+ description: "Lead data + outbound: build and enrich lead lists, drive origami's AI worker from a natural-language brief, and read the tables it builds. Available on the platform-managed account, or with your own origami key.",
26743
+ // ENG-7423: origami migrates from a customer-key-only integration to a
26744
+ // PREMIUM one that ALSO keeps BYO — the Firecrawl / ADR-0055 model, with one
26745
+ // structural difference that drives most of the design.
26746
+ //
26747
+ // Firecrawl's premium tier is a single platform account key that every
26748
+ // customer's calls bill back to, and isolation is not a concern because a
26749
+ // scrape has no tenancy. origami is the opposite: it stores the customer's
26750
+ // LEAD LISTS, tables, chats and campaigns. Putting every customer on one
26751
+ // parent org would make every customer's data mutually readable, so the
26752
+ // managed tier gives each ORGANIZATION its own origami project (child org)
26753
+ // and mints a key BOUND to that project (`POST /account/keys` with
26754
+ // `project_id`, v3). See `packages/core/src/origami/provision.ts` for why a
26755
+ // bound key rather than the `x-origami-project` header — in short, the
26756
+ // header is a per-call assertion and the tool argument is deliberately
26757
+ // nullable, so under a shared parent an ordinary tool call could reach it.
26758
+ //
26759
+ // ── auth types, and the ENG-9235 trap this deliberately re-enters ─────────
26760
+ // Both are offered, unlike Firecrawl, which PARKED `api_key` down to
26761
+ // `['none']` because a 2+-auth-type wizard renders a picker that is not
26762
+ // entitlement-aware: a customer picks BYO, goes and fetches a vendor key,
26763
+ // and is then rejected with `byo_not_entitled_by_plan` (BYO on a premium def
26764
+ // needs `plans.byo_credentials`, enterprise-only today).
26765
+ //
26766
+ // origami cannot take that exit. BYO is the INCUMBENT here — every existing
26767
+ // install is a customer's own key — so dropping `api_key` would remove the
26768
+ // only mode its current customers use. The known gap is therefore accepted
26769
+ // and pointed at its owner: the picker will still let a non-entitled org
26770
+ // choose BYO and reject it afterwards. ENG-9236 (entitlement-aware wizard)
26771
+ // is the fix; until it lands the rejection is at least loud, specific, and
26772
+ // ahead of any charge.
26773
+ //
26774
+ // EXISTING installs are unaffected by that gate: the premium migration
26775
+ // backfills them to `credential_source='byo'` AND stamps
26776
+ // `config.byo_grandfathered_at`, which the call-time resolver honours in
26777
+ // place of the plan check. Grandfathering is per-install and set only by
26778
+ // that one migration — a NEW BYO install still needs the entitlement.
26779
+ //
26780
+ // KEEP IN LOCKSTEP with the `origami` rows in
26781
+ // packages/supabase/seeds/integration-definitions.json and
26782
+ // toolkit-definitions.json: those seeds carry their own auth types and are
26783
+ // what `db:catalog:seed` upserts on every prod deploy, so editing this array
26784
+ // alone changes nothing a customer can see.
26785
+ supported_auth_types: ["none", "api_key"],
26786
+ capabilities: [
26787
+ { id: "origami:read", name: "Read Lists & Runs", description: "Discover projects and tables, read built tables and rows, poll runs/batches, and check credit balance. Credit-free.", access: "read" },
26788
+ { id: "origami:write", name: "Enrich Leads", description: "Insert raw rows into an enrichment table (submit_enrichment). Consumes credits.", access: "write" },
26789
+ { id: "origami:agent", name: "Drive the AI Worker", description: "Create an origami agent, send follow-up runs, cancel a run, archive an agent. Consumes credits.", access: "write" }
26790
+ ],
26791
+ docs_url: "https://docs.origami.chat/v3/overview",
26792
+ // ENG-7423: premium (billable). origami bills internally in CREDITS, so the
26793
+ // integration is usage-priced on one meter whose unit is the vendor's own
26794
+ // billing unit. Priced at 2.0 c USD / 3.5 c AUD per credit by
26795
+ // `20260907000050_origami_credits_rate_card.sql`, against a retail cost of
26796
+ // 1.29-1.43 c/credit depending on which origami tier we hold.
26797
+ //
26798
+ // The note deliberately does NOT say "at cost". origami sells a
26799
+ // SUBSCRIPTION WITH AN INCLUDED BUNDLE while this meters PER CREDIT
26800
+ // CONSUMED, so a per-credit price recovers the subscription only at full
26801
+ // utilisation — around 72% of the bundle at this rate. Calling that "at
26802
+ // cost" in a customer-facing pricing string would be a claim about our
26803
+ // margin that is only true at one utilisation level we do not control.
26804
+ //
26805
+ // ONE meter, not one per tool, because of where the number comes from. Every
26806
+ // other premium integration meters at a server-side broker chokepoint, which
26807
+ // sees each call and can attribute it. origami's agent surface is a
26808
+ // host-resident stdio MCP server (ADR-0040) that calls origami.chat DIRECTLY
26809
+ // — the control plane never sees the tool call, so there is no per-operation
26810
+ // quantity to meter. What the control plane CAN see is the project's own
26811
+ // spend (`GET /account/projects/{id}` → `usage.spent`), which the credit
26812
+ // reconciler polls and meters as a delta. That is a per-project total, so it
26813
+ // can only ever be one meter; splitting it per tool would require the vendor
26814
+ // to break spend down by operation, which v3 does not expose.
26815
+ //
26816
+ // `unit_label` is set because the machine unit is the vendor's internal
26817
+ // billing unit rather than a thing the customer asked for — "(per credit)"
26818
+ // is the honest rendering, in the ADR-0053 cost-pass-through spirit.
26819
+ //
26820
+ // Only a MANAGED install is metered. A BYO install spends the customer's own
26821
+ // origami credits on their own bill (`isBilledInstall` → false), which is why
26822
+ // the reconciler polls only projects it provisioned.
26823
+ premium: {
26824
+ pricing: "usage",
26825
+ note: "Billed per origami credit the agent consumes. Bring your own origami key instead and usage is billed to you by origami directly.",
26826
+ meters: [{ event_type: "credits", unit: "credit", label: "origami credits", unit_label: "credit" }]
26827
+ }
26828
+ },
26738
26829
  {
26739
26830
  id: "ayrshare",
26740
26831
  name: "Ayrshare",
@@ -40866,6 +40866,97 @@ var INTEGRATION_REGISTRY = [
40866
40866
  ]
40867
40867
  }
40868
40868
  },
40869
+ {
40870
+ id: "origami",
40871
+ name: "origami.chat",
40872
+ category: "crm",
40873
+ description: "Lead data + outbound: build and enrich lead lists, drive origami's AI worker from a natural-language brief, and read the tables it builds. Available on the platform-managed account, or with your own origami key.",
40874
+ // ENG-7423: origami migrates from a customer-key-only integration to a
40875
+ // PREMIUM one that ALSO keeps BYO — the Firecrawl / ADR-0055 model, with one
40876
+ // structural difference that drives most of the design.
40877
+ //
40878
+ // Firecrawl's premium tier is a single platform account key that every
40879
+ // customer's calls bill back to, and isolation is not a concern because a
40880
+ // scrape has no tenancy. origami is the opposite: it stores the customer's
40881
+ // LEAD LISTS, tables, chats and campaigns. Putting every customer on one
40882
+ // parent org would make every customer's data mutually readable, so the
40883
+ // managed tier gives each ORGANIZATION its own origami project (child org)
40884
+ // and mints a key BOUND to that project (`POST /account/keys` with
40885
+ // `project_id`, v3). See `packages/core/src/origami/provision.ts` for why a
40886
+ // bound key rather than the `x-origami-project` header — in short, the
40887
+ // header is a per-call assertion and the tool argument is deliberately
40888
+ // nullable, so under a shared parent an ordinary tool call could reach it.
40889
+ //
40890
+ // ── auth types, and the ENG-9235 trap this deliberately re-enters ─────────
40891
+ // Both are offered, unlike Firecrawl, which PARKED `api_key` down to
40892
+ // `['none']` because a 2+-auth-type wizard renders a picker that is not
40893
+ // entitlement-aware: a customer picks BYO, goes and fetches a vendor key,
40894
+ // and is then rejected with `byo_not_entitled_by_plan` (BYO on a premium def
40895
+ // needs `plans.byo_credentials`, enterprise-only today).
40896
+ //
40897
+ // origami cannot take that exit. BYO is the INCUMBENT here — every existing
40898
+ // install is a customer's own key — so dropping `api_key` would remove the
40899
+ // only mode its current customers use. The known gap is therefore accepted
40900
+ // and pointed at its owner: the picker will still let a non-entitled org
40901
+ // choose BYO and reject it afterwards. ENG-9236 (entitlement-aware wizard)
40902
+ // is the fix; until it lands the rejection is at least loud, specific, and
40903
+ // ahead of any charge.
40904
+ //
40905
+ // EXISTING installs are unaffected by that gate: the premium migration
40906
+ // backfills them to `credential_source='byo'` AND stamps
40907
+ // `config.byo_grandfathered_at`, which the call-time resolver honours in
40908
+ // place of the plan check. Grandfathering is per-install and set only by
40909
+ // that one migration — a NEW BYO install still needs the entitlement.
40910
+ //
40911
+ // KEEP IN LOCKSTEP with the `origami` rows in
40912
+ // packages/supabase/seeds/integration-definitions.json and
40913
+ // toolkit-definitions.json: those seeds carry their own auth types and are
40914
+ // what `db:catalog:seed` upserts on every prod deploy, so editing this array
40915
+ // alone changes nothing a customer can see.
40916
+ supported_auth_types: ["none", "api_key"],
40917
+ capabilities: [
40918
+ { id: "origami:read", name: "Read Lists & Runs", description: "Discover projects and tables, read built tables and rows, poll runs/batches, and check credit balance. Credit-free.", access: "read" },
40919
+ { id: "origami:write", name: "Enrich Leads", description: "Insert raw rows into an enrichment table (submit_enrichment). Consumes credits.", access: "write" },
40920
+ { id: "origami:agent", name: "Drive the AI Worker", description: "Create an origami agent, send follow-up runs, cancel a run, archive an agent. Consumes credits.", access: "write" }
40921
+ ],
40922
+ docs_url: "https://docs.origami.chat/v3/overview",
40923
+ // ENG-7423: premium (billable). origami bills internally in CREDITS, so the
40924
+ // integration is usage-priced on one meter whose unit is the vendor's own
40925
+ // billing unit. Priced at 2.0 c USD / 3.5 c AUD per credit by
40926
+ // `20260907000050_origami_credits_rate_card.sql`, against a retail cost of
40927
+ // 1.29-1.43 c/credit depending on which origami tier we hold.
40928
+ //
40929
+ // The note deliberately does NOT say "at cost". origami sells a
40930
+ // SUBSCRIPTION WITH AN INCLUDED BUNDLE while this meters PER CREDIT
40931
+ // CONSUMED, so a per-credit price recovers the subscription only at full
40932
+ // utilisation — around 72% of the bundle at this rate. Calling that "at
40933
+ // cost" in a customer-facing pricing string would be a claim about our
40934
+ // margin that is only true at one utilisation level we do not control.
40935
+ //
40936
+ // ONE meter, not one per tool, because of where the number comes from. Every
40937
+ // other premium integration meters at a server-side broker chokepoint, which
40938
+ // sees each call and can attribute it. origami's agent surface is a
40939
+ // host-resident stdio MCP server (ADR-0040) that calls origami.chat DIRECTLY
40940
+ // — the control plane never sees the tool call, so there is no per-operation
40941
+ // quantity to meter. What the control plane CAN see is the project's own
40942
+ // spend (`GET /account/projects/{id}` → `usage.spent`), which the credit
40943
+ // reconciler polls and meters as a delta. That is a per-project total, so it
40944
+ // can only ever be one meter; splitting it per tool would require the vendor
40945
+ // to break spend down by operation, which v3 does not expose.
40946
+ //
40947
+ // `unit_label` is set because the machine unit is the vendor's internal
40948
+ // billing unit rather than a thing the customer asked for — "(per credit)"
40949
+ // is the honest rendering, in the ADR-0053 cost-pass-through spirit.
40950
+ //
40951
+ // Only a MANAGED install is metered. A BYO install spends the customer's own
40952
+ // origami credits on their own bill (`isBilledInstall` → false), which is why
40953
+ // the reconciler polls only projects it provisioned.
40954
+ premium: {
40955
+ pricing: "usage",
40956
+ note: "Billed per origami credit the agent consumes. Bring your own origami key instead and usage is billed to you by origami directly.",
40957
+ meters: [{ event_type: "credits", unit: "credit", label: "origami credits", unit_label: "credit" }]
40958
+ }
40959
+ },
40869
40960
  {
40870
40961
  id: "ayrshare",
40871
40962
  name: "Ayrshare",
@@ -22960,8 +22960,20 @@ function richTextToString(node, depth = 0) {
22960
22960
  else if (type === "rich_text_table_row") parts.push(children.join(" | "));
22961
22961
  else if (type === "rich_text_list") {
22962
22962
  parts.push(children.map((c) => `- ${c}`).join("\n"));
22963
- } else if (type === "rich_text_quote" || type === "rich_text_preformatted") {
22964
- parts.push(children.join("\n"));
22963
+ } else if (type === "rich_text_quote") {
22964
+ parts.push(
22965
+ children.join("\n").split("\n").map((l) => `> ${l}`).join("\n")
22966
+ );
22967
+ } else if (type === "rich_text_preformatted") {
22968
+ const body = children.join("\n");
22969
+ const longestRun = Math.max(
22970
+ 0,
22971
+ ...[...body.matchAll(/`+/g)].map((m) => m[0].length)
22972
+ );
22973
+ const fence = "`".repeat(Math.max(3, longestRun + 1));
22974
+ parts.push(`${fence}
22975
+ ${body}
22976
+ ${fence}`);
22965
22977
  } else parts.push(children.join(""));
22966
22978
  }
22967
22979
  return parts.join("").trim();
@@ -30374,7 +30386,7 @@ function isAppMentionEcho(evt, botUserId2) {
30374
30386
  return false;
30375
30387
  if (evt.channel?.startsWith("D"))
30376
30388
  return false;
30377
- return typeof evt.text === "string" && evt.text.includes(`<@${botUserId2}>`);
30389
+ return typeof evt.text === "string" && mentionsUser(evt.text, botUserId2);
30378
30390
  }
30379
30391
  function slackInboundDedupId(evt) {
30380
30392
  if (!evt.channel || !evt.ts)
@@ -30382,12 +30394,82 @@ function slackInboundDedupId(evt) {
30382
30394
  return `${evt.channel}:${evt.ts}:${evt.type ?? "unknown"}`;
30383
30395
  }
30384
30396
  function decideSlackEngagement(input) {
30385
- const isExplicitMention = input.type === "app_mention" || !!input.botUserId && input.text.includes(`<@${input.botUserId}>`);
30397
+ const isExplicitMention = input.type === "app_mention" || !!input.botUserId && mentionsUser(input.text, input.botUserId);
30386
30398
  return !(input.isAutoFollowed && !isExplicitMention);
30387
30399
  }
30388
30400
  function decideMarkerArm(input) {
30401
+ if (input.addressesAnotherAgent && !input.shouldEngage)
30402
+ return false;
30389
30403
  return input.shouldEngage || input.isAutoFollowed && input.botPostedInThread;
30390
30404
  }
30405
+ var MENTION_AT_START = /^<@([A-Z0-9]+)(?:\|[^>]*)?>/;
30406
+ function mentionsUser(text, userId) {
30407
+ if (!userId)
30408
+ return false;
30409
+ const escaped = userId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
30410
+ return new RegExp(`<@${escaped}[|>]`).test(text);
30411
+ }
30412
+ var GREETING_PREFIX = /^(?:hey|hi|hello|yo|ok|okay|cc|thanks|thx|morning|afternoon)\b[\s,:!.-]*/i;
30413
+ var ADDRESSEE_SEPARATOR = /^(?:[\s,:;]+|and\b|&|\+)+/i;
30414
+ var BLOCKQUOTE_PREFIX = /^(?:&gt;|>)/;
30415
+ function addressRegion(text) {
30416
+ let fenceLen = 0;
30417
+ for (const rawLine of text.split("\n")) {
30418
+ const line = rawLine.trim();
30419
+ const run = /^`{3,}/.exec(line)?.[0].length ?? 0;
30420
+ if (run > 0) {
30421
+ if (fenceLen === 0)
30422
+ fenceLen = run;
30423
+ else if (run >= fenceLen)
30424
+ fenceLen = 0;
30425
+ continue;
30426
+ }
30427
+ if (fenceLen > 0)
30428
+ continue;
30429
+ if (BLOCKQUOTE_PREFIX.test(line))
30430
+ continue;
30431
+ if (line.length === 0)
30432
+ continue;
30433
+ return line;
30434
+ }
30435
+ return "";
30436
+ }
30437
+ function leadingAddresseeIds(text) {
30438
+ let rest = addressRegion(text);
30439
+ const greeting = GREETING_PREFIX.exec(rest);
30440
+ if (greeting)
30441
+ rest = rest.slice(greeting[0].length);
30442
+ const ids = [];
30443
+ for (; ; ) {
30444
+ const m = MENTION_AT_START.exec(rest);
30445
+ const id = m?.[1];
30446
+ if (!m || !id)
30447
+ break;
30448
+ const after = rest.slice(m[0].length);
30449
+ if (/^['’]/.test(after))
30450
+ break;
30451
+ ids.push(id);
30452
+ if (after.length === 0)
30453
+ break;
30454
+ const sep2 = ADDRESSEE_SEPARATOR.exec(after);
30455
+ if (!sep2)
30456
+ break;
30457
+ rest = after.slice(sep2[0].length);
30458
+ }
30459
+ return ids;
30460
+ }
30461
+ function addressesAnotherRegisteredAgent(text, botUserId2, registeredAgentIds) {
30462
+ if (!botUserId2)
30463
+ return false;
30464
+ if (!registeredAgentIds || registeredAgentIds.size === 0)
30465
+ return false;
30466
+ if (mentionsUser(text, botUserId2))
30467
+ return false;
30468
+ const addressees = leadingAddresseeIds(text);
30469
+ if (addressees.includes(botUserId2))
30470
+ return false;
30471
+ return addressees.some((id) => id !== botUserId2 && registeredAgentIds.has(id));
30472
+ }
30391
30473
  function decideSlackAckReaction(input) {
30392
30474
  return Boolean(input.channel && input.ts);
30393
30475
  }
@@ -35014,6 +35096,97 @@ var INTEGRATION_REGISTRY = [
35014
35096
  ]
35015
35097
  }
35016
35098
  },
35099
+ {
35100
+ id: "origami",
35101
+ name: "origami.chat",
35102
+ category: "crm",
35103
+ description: "Lead data + outbound: build and enrich lead lists, drive origami's AI worker from a natural-language brief, and read the tables it builds. Available on the platform-managed account, or with your own origami key.",
35104
+ // ENG-7423: origami migrates from a customer-key-only integration to a
35105
+ // PREMIUM one that ALSO keeps BYO — the Firecrawl / ADR-0055 model, with one
35106
+ // structural difference that drives most of the design.
35107
+ //
35108
+ // Firecrawl's premium tier is a single platform account key that every
35109
+ // customer's calls bill back to, and isolation is not a concern because a
35110
+ // scrape has no tenancy. origami is the opposite: it stores the customer's
35111
+ // LEAD LISTS, tables, chats and campaigns. Putting every customer on one
35112
+ // parent org would make every customer's data mutually readable, so the
35113
+ // managed tier gives each ORGANIZATION its own origami project (child org)
35114
+ // and mints a key BOUND to that project (`POST /account/keys` with
35115
+ // `project_id`, v3). See `packages/core/src/origami/provision.ts` for why a
35116
+ // bound key rather than the `x-origami-project` header — in short, the
35117
+ // header is a per-call assertion and the tool argument is deliberately
35118
+ // nullable, so under a shared parent an ordinary tool call could reach it.
35119
+ //
35120
+ // ── auth types, and the ENG-9235 trap this deliberately re-enters ─────────
35121
+ // Both are offered, unlike Firecrawl, which PARKED `api_key` down to
35122
+ // `['none']` because a 2+-auth-type wizard renders a picker that is not
35123
+ // entitlement-aware: a customer picks BYO, goes and fetches a vendor key,
35124
+ // and is then rejected with `byo_not_entitled_by_plan` (BYO on a premium def
35125
+ // needs `plans.byo_credentials`, enterprise-only today).
35126
+ //
35127
+ // origami cannot take that exit. BYO is the INCUMBENT here — every existing
35128
+ // install is a customer's own key — so dropping `api_key` would remove the
35129
+ // only mode its current customers use. The known gap is therefore accepted
35130
+ // and pointed at its owner: the picker will still let a non-entitled org
35131
+ // choose BYO and reject it afterwards. ENG-9236 (entitlement-aware wizard)
35132
+ // is the fix; until it lands the rejection is at least loud, specific, and
35133
+ // ahead of any charge.
35134
+ //
35135
+ // EXISTING installs are unaffected by that gate: the premium migration
35136
+ // backfills them to `credential_source='byo'` AND stamps
35137
+ // `config.byo_grandfathered_at`, which the call-time resolver honours in
35138
+ // place of the plan check. Grandfathering is per-install and set only by
35139
+ // that one migration — a NEW BYO install still needs the entitlement.
35140
+ //
35141
+ // KEEP IN LOCKSTEP with the `origami` rows in
35142
+ // packages/supabase/seeds/integration-definitions.json and
35143
+ // toolkit-definitions.json: those seeds carry their own auth types and are
35144
+ // what `db:catalog:seed` upserts on every prod deploy, so editing this array
35145
+ // alone changes nothing a customer can see.
35146
+ supported_auth_types: ["none", "api_key"],
35147
+ capabilities: [
35148
+ { id: "origami:read", name: "Read Lists & Runs", description: "Discover projects and tables, read built tables and rows, poll runs/batches, and check credit balance. Credit-free.", access: "read" },
35149
+ { id: "origami:write", name: "Enrich Leads", description: "Insert raw rows into an enrichment table (submit_enrichment). Consumes credits.", access: "write" },
35150
+ { id: "origami:agent", name: "Drive the AI Worker", description: "Create an origami agent, send follow-up runs, cancel a run, archive an agent. Consumes credits.", access: "write" }
35151
+ ],
35152
+ docs_url: "https://docs.origami.chat/v3/overview",
35153
+ // ENG-7423: premium (billable). origami bills internally in CREDITS, so the
35154
+ // integration is usage-priced on one meter whose unit is the vendor's own
35155
+ // billing unit. Priced at 2.0 c USD / 3.5 c AUD per credit by
35156
+ // `20260907000050_origami_credits_rate_card.sql`, against a retail cost of
35157
+ // 1.29-1.43 c/credit depending on which origami tier we hold.
35158
+ //
35159
+ // The note deliberately does NOT say "at cost". origami sells a
35160
+ // SUBSCRIPTION WITH AN INCLUDED BUNDLE while this meters PER CREDIT
35161
+ // CONSUMED, so a per-credit price recovers the subscription only at full
35162
+ // utilisation — around 72% of the bundle at this rate. Calling that "at
35163
+ // cost" in a customer-facing pricing string would be a claim about our
35164
+ // margin that is only true at one utilisation level we do not control.
35165
+ //
35166
+ // ONE meter, not one per tool, because of where the number comes from. Every
35167
+ // other premium integration meters at a server-side broker chokepoint, which
35168
+ // sees each call and can attribute it. origami's agent surface is a
35169
+ // host-resident stdio MCP server (ADR-0040) that calls origami.chat DIRECTLY
35170
+ // — the control plane never sees the tool call, so there is no per-operation
35171
+ // quantity to meter. What the control plane CAN see is the project's own
35172
+ // spend (`GET /account/projects/{id}` → `usage.spent`), which the credit
35173
+ // reconciler polls and meters as a delta. That is a per-project total, so it
35174
+ // can only ever be one meter; splitting it per tool would require the vendor
35175
+ // to break spend down by operation, which v3 does not expose.
35176
+ //
35177
+ // `unit_label` is set because the machine unit is the vendor's internal
35178
+ // billing unit rather than a thing the customer asked for — "(per credit)"
35179
+ // is the honest rendering, in the ADR-0053 cost-pass-through spirit.
35180
+ //
35181
+ // Only a MANAGED install is metered. A BYO install spends the customer's own
35182
+ // origami credits on their own bill (`isBilledInstall` → false), which is why
35183
+ // the reconciler polls only projects it provisioned.
35184
+ premium: {
35185
+ pricing: "usage",
35186
+ note: "Billed per origami credit the agent consumes. Bring your own origami key instead and usage is billed to you by origami directly.",
35187
+ meters: [{ event_type: "credits", unit: "credit", label: "origami credits", unit_label: "credit" }]
35188
+ }
35189
+ },
35017
35190
  {
35018
35191
  id: "ayrshare",
35019
35192
  name: "Ayrshare",
@@ -48992,7 +49165,17 @@ async function connectSocketMode() {
48992
49165
  });
48993
49166
  const participantEntry = threadKey ? trackedThreads.get(threadKey) : void 0;
48994
49167
  const botPostedInThread = participantEntry?.bot_posted === true || participantEntry?.involvement === "started";
48995
- const armMarker = decideMarkerArm({ shouldEngage, isAutoFollowed, botPostedInThread });
49168
+ const addressesAnotherAgent = addressesAnotherRegisteredAgent(
49169
+ text,
49170
+ botUserId,
49171
+ SLACK_SENDER_POLICY.registeredAgentSlackUserIds
49172
+ );
49173
+ const armMarker = decideMarkerArm({
49174
+ shouldEngage,
49175
+ isAutoFollowed,
49176
+ botPostedInThread,
49177
+ addressesAnotherAgent
49178
+ });
48996
49179
  const ackProbe = process.env.TMUX && AGENT_CODE_NAME ? probeAgentSessionCached(AGENT_CODE_NAME) : { tmux: "unknown", claude: "unknown" };
48997
49180
  let paneLogFreshAgeMs = null;
48998
49181
  if (SLACK_AGENT_DIR) {
@@ -35146,6 +35146,97 @@ var INTEGRATION_REGISTRY = [
35146
35146
  ]
35147
35147
  }
35148
35148
  },
35149
+ {
35150
+ id: "origami",
35151
+ name: "origami.chat",
35152
+ category: "crm",
35153
+ description: "Lead data + outbound: build and enrich lead lists, drive origami's AI worker from a natural-language brief, and read the tables it builds. Available on the platform-managed account, or with your own origami key.",
35154
+ // ENG-7423: origami migrates from a customer-key-only integration to a
35155
+ // PREMIUM one that ALSO keeps BYO — the Firecrawl / ADR-0055 model, with one
35156
+ // structural difference that drives most of the design.
35157
+ //
35158
+ // Firecrawl's premium tier is a single platform account key that every
35159
+ // customer's calls bill back to, and isolation is not a concern because a
35160
+ // scrape has no tenancy. origami is the opposite: it stores the customer's
35161
+ // LEAD LISTS, tables, chats and campaigns. Putting every customer on one
35162
+ // parent org would make every customer's data mutually readable, so the
35163
+ // managed tier gives each ORGANIZATION its own origami project (child org)
35164
+ // and mints a key BOUND to that project (`POST /account/keys` with
35165
+ // `project_id`, v3). See `packages/core/src/origami/provision.ts` for why a
35166
+ // bound key rather than the `x-origami-project` header — in short, the
35167
+ // header is a per-call assertion and the tool argument is deliberately
35168
+ // nullable, so under a shared parent an ordinary tool call could reach it.
35169
+ //
35170
+ // ── auth types, and the ENG-9235 trap this deliberately re-enters ─────────
35171
+ // Both are offered, unlike Firecrawl, which PARKED `api_key` down to
35172
+ // `['none']` because a 2+-auth-type wizard renders a picker that is not
35173
+ // entitlement-aware: a customer picks BYO, goes and fetches a vendor key,
35174
+ // and is then rejected with `byo_not_entitled_by_plan` (BYO on a premium def
35175
+ // needs `plans.byo_credentials`, enterprise-only today).
35176
+ //
35177
+ // origami cannot take that exit. BYO is the INCUMBENT here — every existing
35178
+ // install is a customer's own key — so dropping `api_key` would remove the
35179
+ // only mode its current customers use. The known gap is therefore accepted
35180
+ // and pointed at its owner: the picker will still let a non-entitled org
35181
+ // choose BYO and reject it afterwards. ENG-9236 (entitlement-aware wizard)
35182
+ // is the fix; until it lands the rejection is at least loud, specific, and
35183
+ // ahead of any charge.
35184
+ //
35185
+ // EXISTING installs are unaffected by that gate: the premium migration
35186
+ // backfills them to `credential_source='byo'` AND stamps
35187
+ // `config.byo_grandfathered_at`, which the call-time resolver honours in
35188
+ // place of the plan check. Grandfathering is per-install and set only by
35189
+ // that one migration — a NEW BYO install still needs the entitlement.
35190
+ //
35191
+ // KEEP IN LOCKSTEP with the `origami` rows in
35192
+ // packages/supabase/seeds/integration-definitions.json and
35193
+ // toolkit-definitions.json: those seeds carry their own auth types and are
35194
+ // what `db:catalog:seed` upserts on every prod deploy, so editing this array
35195
+ // alone changes nothing a customer can see.
35196
+ supported_auth_types: ["none", "api_key"],
35197
+ capabilities: [
35198
+ { id: "origami:read", name: "Read Lists & Runs", description: "Discover projects and tables, read built tables and rows, poll runs/batches, and check credit balance. Credit-free.", access: "read" },
35199
+ { id: "origami:write", name: "Enrich Leads", description: "Insert raw rows into an enrichment table (submit_enrichment). Consumes credits.", access: "write" },
35200
+ { id: "origami:agent", name: "Drive the AI Worker", description: "Create an origami agent, send follow-up runs, cancel a run, archive an agent. Consumes credits.", access: "write" }
35201
+ ],
35202
+ docs_url: "https://docs.origami.chat/v3/overview",
35203
+ // ENG-7423: premium (billable). origami bills internally in CREDITS, so the
35204
+ // integration is usage-priced on one meter whose unit is the vendor's own
35205
+ // billing unit. Priced at 2.0 c USD / 3.5 c AUD per credit by
35206
+ // `20260907000050_origami_credits_rate_card.sql`, against a retail cost of
35207
+ // 1.29-1.43 c/credit depending on which origami tier we hold.
35208
+ //
35209
+ // The note deliberately does NOT say "at cost". origami sells a
35210
+ // SUBSCRIPTION WITH AN INCLUDED BUNDLE while this meters PER CREDIT
35211
+ // CONSUMED, so a per-credit price recovers the subscription only at full
35212
+ // utilisation — around 72% of the bundle at this rate. Calling that "at
35213
+ // cost" in a customer-facing pricing string would be a claim about our
35214
+ // margin that is only true at one utilisation level we do not control.
35215
+ //
35216
+ // ONE meter, not one per tool, because of where the number comes from. Every
35217
+ // other premium integration meters at a server-side broker chokepoint, which
35218
+ // sees each call and can attribute it. origami's agent surface is a
35219
+ // host-resident stdio MCP server (ADR-0040) that calls origami.chat DIRECTLY
35220
+ // — the control plane never sees the tool call, so there is no per-operation
35221
+ // quantity to meter. What the control plane CAN see is the project's own
35222
+ // spend (`GET /account/projects/{id}` → `usage.spent`), which the credit
35223
+ // reconciler polls and meters as a delta. That is a per-project total, so it
35224
+ // can only ever be one meter; splitting it per tool would require the vendor
35225
+ // to break spend down by operation, which v3 does not expose.
35226
+ //
35227
+ // `unit_label` is set because the machine unit is the vendor's internal
35228
+ // billing unit rather than a thing the customer asked for — "(per credit)"
35229
+ // is the honest rendering, in the ADR-0053 cost-pass-through spirit.
35230
+ //
35231
+ // Only a MANAGED install is metered. A BYO install spends the customer's own
35232
+ // origami credits on their own bill (`isBilledInstall` → false), which is why
35233
+ // the reconciler polls only projects it provisioned.
35234
+ premium: {
35235
+ pricing: "usage",
35236
+ note: "Billed per origami credit the agent consumes. Bring your own origami key instead and usage is billed to you by origami directly.",
35237
+ meters: [{ event_type: "credits", unit: "credit", label: "origami credits", unit_label: "credit" }]
35238
+ }
35239
+ },
35149
35240
  {
35150
35241
  id: "ayrshare",
35151
35242
  name: "Ayrshare",
@@ -54,8 +54,8 @@ import {
54
54
  writeDirectChatSessionState,
55
55
  writeEgressAllowlist,
56
56
  writePersistentClaudeWrapper
57
- } from "./chunk-SQ7PB5A6.js";
58
- import "./chunk-Q2OVEMUG.js";
57
+ } from "./chunk-CA46EUVN.js";
58
+ import "./chunk-EARM456T.js";
59
59
  import "./chunk-XWVM4KPK.js";
60
60
  export {
61
61
  EGRESS_BASELINE_DOMAINS,
@@ -114,4 +114,4 @@ export {
114
114
  writeEgressAllowlist,
115
115
  writePersistentClaudeWrapper
116
116
  };
117
- //# sourceMappingURL=persistent-session-MG6FEYRY.js.map
117
+ //# sourceMappingURL=persistent-session-XQG5H4KI.js.map