@integrity-labs/agt-cli 0.28.1165 → 0.28.1167

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 (31) hide show
  1. package/dist/bin/agt.js +6 -6
  2. package/dist/{chunk-TNPLCJIG.js → chunk-7IAJXJ7C.js} +315 -36
  3. package/dist/chunk-7IAJXJ7C.js.map +1 -0
  4. package/dist/{chunk-MBNPMML4.js → chunk-7WXWT4PA.js} +5 -5
  5. package/dist/{chunk-FGPPJKJ5.js → chunk-AJTF72A2.js} +3 -3
  6. package/dist/{chunk-ZDHCIJL6.js → chunk-AV4KD3HE.js} +2 -2
  7. package/dist/{chunk-T7NKHOJF.js → chunk-IV2UENRG.js} +10 -2
  8. package/dist/chunk-IV2UENRG.js.map +1 -0
  9. package/dist/{claude-code-updater-EM3AY2PR.js → claude-code-updater-WD4NNWY5.js} +5 -3
  10. package/dist/{claude-pair-runtime-P45H3GNC.js → claude-pair-runtime-JWXVVSSG.js} +3 -3
  11. package/dist/lib/manager-worker.js +40 -27
  12. package/dist/lib/manager-worker.js.map +1 -1
  13. package/dist/mcp/direct-chat-channel.js +763 -484
  14. package/dist/mcp/index.js +616 -337
  15. package/dist/mcp/origami.js +604 -325
  16. package/dist/mcp/slack-channel.js +613 -334
  17. package/dist/mcp/telegram-channel.js +604 -325
  18. package/dist/{persistent-session-KSV7RIQQ.js → persistent-session-LKJVSRHX.js} +4 -4
  19. package/dist/{responsiveness-probe-XVYYSQQN.js → responsiveness-probe-ZEK2TD5E.js} +4 -4
  20. package/dist/{session-auth-dead-KMMDVC5E.js → session-auth-dead-TSARKC55.js} +3 -3
  21. package/package.json +1 -1
  22. package/dist/chunk-T7NKHOJF.js.map +0 -1
  23. package/dist/chunk-TNPLCJIG.js.map +0 -1
  24. /package/dist/{chunk-MBNPMML4.js.map → chunk-7WXWT4PA.js.map} +0 -0
  25. /package/dist/{chunk-FGPPJKJ5.js.map → chunk-AJTF72A2.js.map} +0 -0
  26. /package/dist/{chunk-ZDHCIJL6.js.map → chunk-AV4KD3HE.js.map} +0 -0
  27. /package/dist/{claude-code-updater-EM3AY2PR.js.map → claude-code-updater-WD4NNWY5.js.map} +0 -0
  28. /package/dist/{claude-pair-runtime-P45H3GNC.js.map → claude-pair-runtime-JWXVVSSG.js.map} +0 -0
  29. /package/dist/{persistent-session-KSV7RIQQ.js.map → persistent-session-LKJVSRHX.js.map} +0 -0
  30. /package/dist/{responsiveness-probe-XVYYSQQN.js.map → responsiveness-probe-ZEK2TD5E.js.map} +0 -0
  31. /package/dist/{session-auth-dead-KMMDVC5E.js.map → session-auth-dead-TSARKC55.js.map} +0 -0
package/dist/bin/agt.js CHANGED
@@ -40,17 +40,17 @@ import {
40
40
  success,
41
41
  table,
42
42
  warn
43
- } from "../chunk-MBNPMML4.js";
43
+ } from "../chunk-7WXWT4PA.js";
44
44
  import {
45
45
  getProjectDir,
46
46
  isSessionResumeDisabled,
47
47
  readDirectChatSessionState
48
- } from "../chunk-FGPPJKJ5.js";
48
+ } from "../chunk-AJTF72A2.js";
49
49
  import {
50
50
  markDailySessionSpawn,
51
51
  sessionFileExists,
52
52
  sessionTranscriptDir
53
- } from "../chunk-ZDHCIJL6.js";
53
+ } from "../chunk-AV4KD3HE.js";
54
54
  import "../chunk-B6UYVEMD.js";
55
55
  import "../chunk-OAWK4OBN.js";
56
56
  import "../chunk-XWVM4KPK.js";
@@ -84,7 +84,7 @@ import {
84
84
  requiredMcpWildcard,
85
85
  resolveChannels,
86
86
  serializeManifestForSlackCli
87
- } from "../chunk-TNPLCJIG.js";
87
+ } from "../chunk-7IAJXJ7C.js";
88
88
  import "../chunk-EL5MWGGH.js";
89
89
  import "../chunk-DGUM43GV.js";
90
90
 
@@ -5513,7 +5513,7 @@ import { execFileSync, execSync } from "child_process";
5513
5513
  import { existsSync as existsSync11, realpathSync as realpathSync2 } from "fs";
5514
5514
  import chalk18 from "chalk";
5515
5515
  import ora16 from "ora";
5516
- var cliVersion = true ? "0.28.1165" : "dev";
5516
+ var cliVersion = true ? "0.28.1167" : "dev";
5517
5517
  async function fetchLatestVersion() {
5518
5518
  const host2 = getHost();
5519
5519
  if (!host2) return null;
@@ -6773,7 +6773,7 @@ function handleError(err) {
6773
6773
  }
6774
6774
 
6775
6775
  // src/bin/agt.ts
6776
- var cliVersion2 = true ? "0.28.1165" : "dev";
6776
+ var cliVersion2 = true ? "0.28.1167" : "dev";
6777
6777
  var program = new Command();
6778
6778
  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");
6779
6779
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -1227,8 +1227,8 @@ function effectiveMailRuleEnforcement(g) {
1227
1227
  }
1228
1228
  function renderGuardrailBullet(g) {
1229
1229
  const lines = [];
1230
- const header = `- **${g.displayName}** (${g.category}, from ${g.source})`;
1231
- lines.push(header);
1230
+ const header2 = `- **${g.displayName}** (${g.category}, from ${g.source})`;
1231
+ lines.push(header2);
1232
1232
  if (g.description?.trim()) {
1233
1233
  lines.push(` ${g.description.trim()}`);
1234
1234
  }
@@ -1327,12 +1327,12 @@ function requireApprovalHowLines(g, level, holds) {
1327
1327
  ];
1328
1328
  }
1329
1329
  function renderAdvisoryGuardrailBullet(g, emailHold) {
1330
- const [header, ...rest] = renderGuardrailBullet(g).split("\n");
1330
+ const [header2, ...rest] = renderGuardrailBullet(g).split("\n");
1331
1331
  const level = g.enforcement === "warn" || g.enforcement === "log" ? g.enforcement : "enforce";
1332
1332
  const isRequireApproval = g.definitionId === REQUIRE_APPROVAL_FOR_ACTIONS_DEF;
1333
1333
  const how = isRequireApproval && level !== "log" ? requireApprovalHowLines(g, level, emailHold) : [];
1334
1334
  const levelLine = isRequireApproval && level === "enforce" ? REQUIRE_APPROVAL_ENFORCE_LEVEL_LINE : ADVISORY_LEVEL_LINE[level];
1335
- return [header, ` ${levelLine}`, ...how, ...rest].join("\n");
1335
+ return [header2, ` ${levelLine}`, ...how, ...rest].join("\n");
1336
1336
  }
1337
1337
  var REQUIRE_APPROVAL_ENFORCE_LEVEL_LINE = "Level: enforce \u2014 never take these actions without approval; get it as described below.";
1338
1338
  function renderOverriddenGuardrailBullet(g) {
@@ -2477,6 +2477,15 @@ var INTEGRATION_REGISTRY = [
2477
2477
  // successor at the same cost to us); Sunburst is seeded at 4x.
2478
2478
  { event_type: "gpt_image_2_5_flare", unit: "image" },
2479
2479
  { event_type: "gpt_image_2_5_sunburst", unit: "image" },
2480
+ // CS-2360: quality medium/high price on their own rows (more image-output
2481
+ // tokens at the same per-token rate). `low` stays on the two meters above.
2482
+ // The handler refuses a medium/high render until its meter has a rate
2483
+ // card row in BOTH USD and AUD. Size does not change the meter: the rate
2484
+ // is set on the worst case (landscape/portrait).
2485
+ { event_type: "gpt_image_2_5_flare_medium", unit: "image", label: "Flare, medium quality" },
2486
+ { event_type: "gpt_image_2_5_flare_high", unit: "image", label: "Flare, high quality" },
2487
+ { event_type: "gpt_image_2_5_sunburst_medium", unit: "image", label: "Sunburst, medium quality" },
2488
+ { event_type: "gpt_image_2_5_sunburst_high", unit: "image", label: "Sunburst, high quality" },
2480
2489
  // CS-1940: an edit also records one of these with units = the number of
2481
2490
  // reference images. Declared here (obi-wan 3a515eaf41b0) because the admin
2482
2491
  // pricing route only accepts a price for a declared meter, and the org
@@ -14498,10 +14507,10 @@ function parseExtraHeaders(raw) {
14498
14507
  const colon = trimmed.indexOf(":");
14499
14508
  if (colon <= 0)
14500
14509
  continue;
14501
- const header = trimmed.slice(0, colon).trim();
14510
+ const header2 = trimmed.slice(0, colon).trim();
14502
14511
  const varName = trimmed.slice(colon + 1).trim();
14503
- if (header && varName)
14504
- out.push({ header, varName });
14512
+ if (header2 && varName)
14513
+ out.push({ header: header2, varName });
14505
14514
  }
14506
14515
  return out;
14507
14516
  }
@@ -14520,8 +14529,8 @@ function buildForwardHeaders(token, authHeader, extras, readVar) {
14520
14529
  headers[authHeader] = token;
14521
14530
  else
14522
14531
  headers["Authorization"] = `Bearer ${token}`;
14523
- for (const { header, varName } of extras) {
14524
- headers[header] = readVar(varName) ?? "";
14532
+ for (const { header: header2, varName } of extras) {
14533
+ headers[header2] = readVar(varName) ?? "";
14525
14534
  }
14526
14535
  return headers;
14527
14536
  }
@@ -16783,7 +16792,7 @@ function truncate(text, max) {
16783
16792
  }
16784
16793
  function resolvePreset(config) {
16785
16794
  const name = config["preset"];
16786
- const base = typeof name === "string" && name in WEBHOOK_PRESETS ? WEBHOOK_PRESETS[name] : WEBHOOK_PRESETS.generic;
16795
+ const base = typeof name === "string" && Object.prototype.hasOwnProperty.call(WEBHOOK_PRESETS, name) ? WEBHOOK_PRESETS[name] : WEBHOOK_PRESETS.generic;
16787
16796
  const dedup = config["dedup_path"];
16788
16797
  const type = config["event_type_path"];
16789
16798
  const payload = config["payload_path"];
@@ -16794,35 +16803,47 @@ function resolvePreset(config) {
16794
16803
  ...typeof payload === "string" && payload ? { payloadPath: payload } : {}
16795
16804
  };
16796
16805
  }
16797
- function validateWebhookConfig(input) {
16798
- const out = {};
16806
+ function validateOperatorText(input, out) {
16799
16807
  const name = input["name"];
16800
16808
  if (name !== void 0) {
16801
16809
  if (typeof name !== "string")
16802
- return { ok: false, error: "name must be a string" };
16810
+ return "name must be a string";
16803
16811
  const trimmed = name.trim();
16804
16812
  if (trimmed.length > WEBHOOK_NAME_MAX_CHARS) {
16805
- return { ok: false, error: `name must be at most ${WEBHOOK_NAME_MAX_CHARS} characters` };
16813
+ return `name must be at most ${WEBHOOK_NAME_MAX_CHARS} characters`;
16806
16814
  }
16807
16815
  if (trimmed)
16808
16816
  out["name"] = trimmed;
16809
16817
  }
16810
16818
  const instruction = input["instruction"];
16811
16819
  if (typeof instruction !== "string" || !instruction.trim()) {
16812
- return {
16813
- ok: false,
16814
- error: "instruction is required: tell the agent what to do when an event arrives"
16815
- };
16820
+ return "instruction is required: tell the agent what to do when an event arrives";
16816
16821
  }
16817
16822
  if (instruction.trim().length > WEBHOOK_INSTRUCTION_MAX_CHARS) {
16818
- return {
16819
- ok: false,
16820
- error: `instruction must be at most ${WEBHOOK_INSTRUCTION_MAX_CHARS} characters`
16821
- };
16823
+ return `instruction must be at most ${WEBHOOK_INSTRUCTION_MAX_CHARS} characters`;
16822
16824
  }
16823
16825
  out["instruction"] = instruction.trim();
16826
+ return null;
16827
+ }
16828
+ function validateRateCapConfig(input, out) {
16829
+ const cap = input["max_events_per_hour"];
16830
+ if (cap !== void 0 && cap !== null) {
16831
+ if (typeof cap !== "number" || !Number.isInteger(cap) || cap < 1 || cap > WEBHOOK_MAX_RATE_CAP) {
16832
+ return `max_events_per_hour must be an integer from 1 to ${WEBHOOK_MAX_RATE_CAP}`;
16833
+ }
16834
+ out["max_events_per_hour"] = cap;
16835
+ } else {
16836
+ out["max_events_per_hour"] = WEBHOOK_DEFAULT_RATE_CAP;
16837
+ }
16838
+ return null;
16839
+ }
16840
+ function validateWebhookConfig(input) {
16841
+ const out = {};
16842
+ const textError = validateOperatorText(input, out);
16843
+ if (textError)
16844
+ return { ok: false, error: textError };
16824
16845
  const preset = input["preset"] ?? "generic";
16825
- if (typeof preset !== "string" || !(preset in WEBHOOK_PRESETS)) {
16846
+ if (typeof preset !== "string" || !Object.prototype.hasOwnProperty.call(WEBHOOK_PRESETS, preset)) {
16826
16847
  return {
16827
16848
  ok: false,
16828
16849
  error: `preset must be one of: ${Object.keys(WEBHOOK_PRESETS).join(", ")}`
@@ -16838,18 +16859,9 @@ function validateWebhookConfig(input) {
16838
16859
  }
16839
16860
  out[key] = v;
16840
16861
  }
16841
- const cap = input["max_events_per_hour"];
16842
- if (cap !== void 0 && cap !== null) {
16843
- if (typeof cap !== "number" || !Number.isInteger(cap) || cap < 1 || cap > WEBHOOK_MAX_RATE_CAP) {
16844
- return {
16845
- ok: false,
16846
- error: `max_events_per_hour must be an integer from 1 to ${WEBHOOK_MAX_RATE_CAP}`
16847
- };
16848
- }
16849
- out["max_events_per_hour"] = cap;
16850
- } else {
16851
- out["max_events_per_hour"] = WEBHOOK_DEFAULT_RATE_CAP;
16852
- }
16862
+ const capError = validateRateCapConfig(input, out);
16863
+ if (capError)
16864
+ return { ok: false, error: capError };
16853
16865
  return { ok: true, config: out };
16854
16866
  }
16855
16867
  function webhookRateCap(trigger) {
@@ -16912,6 +16924,273 @@ var webhookTriggerAdapter = {
16912
16924
  };
16913
16925
  registerTriggerSource(webhookTriggerAdapter);
16914
16926
 
16927
+ // ../../packages/core/dist/triggers/adapters/github.js
16928
+ var GITHUB_TRIGGER_PROVIDER = "github";
16929
+ var GITHUB_MAX_BODY_BYTES = 5 * 1024 * 1024;
16930
+ var GITHUB_SIGNATURE_HEADER = "x-hub-signature-256";
16931
+ var GITHUB_EVENT_HEADER = "x-github-event";
16932
+ var GITHUB_DELIVERY_HEADER = "x-github-delivery";
16933
+ var GITHUB_EVENT_RULES = {
16934
+ pull_request: { actions: ["closed", "dequeued", "labeled"] },
16935
+ pull_request_review: { actions: ["submitted"] },
16936
+ check_suite: { actions: ["completed"] },
16937
+ issues: { actions: ["opened", "closed"] },
16938
+ issue_comment: { actions: ["created"] }
16939
+ };
16940
+ var GITHUB_WEBHOOK_EVENTS = Object.keys(GITHUB_EVENT_RULES);
16941
+ var REPO_FULL_NAME = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,38})\/[A-Za-z0-9._-]{1,100}$/;
16942
+ var LOGIN = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,38})(?:\[bot\])?$/;
16943
+ var LABEL_TOKEN = /^[A-Za-z0-9][A-Za-z0-9._:/+-]{0,49}$/;
16944
+ var SHA = /^[0-9a-f]{40}$/;
16945
+ var GUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
16946
+ var REASON_TOKEN = /^(?=.{1,40}$)[a-z]+(?:_[a-z]+){0,3}$/;
16947
+ var APP_SLUG = /^[a-z0-9][a-z0-9-]{0,99}$/;
16948
+ var REVIEW_STATES = /* @__PURE__ */ new Set(["approved", "changes_requested", "commented", "dismissed"]);
16949
+ var CHECK_CONCLUSIONS = /* @__PURE__ */ new Set([
16950
+ "success",
16951
+ "failure",
16952
+ "neutral",
16953
+ "cancelled",
16954
+ "timed_out",
16955
+ "action_required",
16956
+ "stale",
16957
+ "skipped",
16958
+ "startup_failure"
16959
+ ]);
16960
+ var ISSUE_STATE_REASONS = /* @__PURE__ */ new Set(["completed", "not_planned", "reopened", "duplicate"]);
16961
+ function asDict(v) {
16962
+ return v !== null && typeof v === "object" && !Array.isArray(v) ? v : null;
16963
+ }
16964
+ function str(v) {
16965
+ return typeof v === "string" && v.length > 0 ? v : null;
16966
+ }
16967
+ function shaped(v, re) {
16968
+ const s = str(v);
16969
+ return s !== null && re.test(s) ? s : null;
16970
+ }
16971
+ function posInt(v) {
16972
+ return typeof v === "number" && Number.isInteger(v) && v > 0 ? v : null;
16973
+ }
16974
+ function header(headers, name) {
16975
+ const v = headers[name] ?? headers[name.toLowerCase()];
16976
+ return typeof v === "string" && v.length > 0 ? v : null;
16977
+ }
16978
+ function inSet(v, set) {
16979
+ const s = str(v)?.toLowerCase() ?? null;
16980
+ return s !== null && set.has(s) ? s : null;
16981
+ }
16982
+ function extractGithubFacts(event, payload) {
16983
+ const rule = Object.hasOwn(GITHUB_EVENT_RULES, event) ? GITHUB_EVENT_RULES[event] : void 0;
16984
+ if (!rule)
16985
+ return null;
16986
+ const root = asDict(payload);
16987
+ if (!root)
16988
+ return null;
16989
+ const rawAction = str(root["action"]);
16990
+ const action = rule.actions.find((a) => a === rawAction);
16991
+ if (!action)
16992
+ return null;
16993
+ const repo = shaped(asDict(root["repository"])?.["full_name"], REPO_FULL_NAME);
16994
+ if (!repo)
16995
+ return null;
16996
+ const sender = shaped(asDict(root["sender"])?.["login"], LOGIN);
16997
+ const base = `https://github.com/${repo}`;
16998
+ const details = [];
16999
+ if (event === "pull_request") {
17000
+ const pr = asDict(root["pull_request"]);
17001
+ const n2 = pr ? posInt(pr["number"]) : null;
17002
+ if (!pr || n2 === null)
17003
+ return null;
17004
+ let summary;
17005
+ if (action === "closed") {
17006
+ if (pr["merged"] !== true)
17007
+ return null;
17008
+ details.push(["Outcome", "merged"]);
17009
+ const mergedBy = shaped(asDict(pr["merged_by"])?.["login"], LOGIN);
17010
+ if (mergedBy)
17011
+ details.push(["Merged by", mergedBy]);
17012
+ summary = `PR #${n2} merged in ${repo}`;
17013
+ } else if (action === "dequeued") {
17014
+ const reasonRaw = str(root["reason"])?.toLowerCase().replace(/-/g, "_") ?? null;
17015
+ const reason = reasonRaw && REASON_TOKEN.test(reasonRaw) ? reasonRaw : "unknown";
17016
+ details.push(["Removed from merge queue, reason", reason]);
17017
+ if (pr["merged"] === true)
17018
+ details.push(["Merged", "yes"]);
17019
+ summary = `PR #${n2} removed from the merge queue in ${repo}`;
17020
+ } else {
17021
+ const label = shaped(asDict(root["label"])?.["name"], LABEL_TOKEN);
17022
+ details.push(["Label", label ?? "(name withheld: not a plain token)"]);
17023
+ summary = `PR #${n2} labeled in ${repo}`;
17024
+ }
17025
+ const state = str(pr["state"]);
17026
+ if (state === "open" || state === "closed")
17027
+ details.unshift(["State", state]);
17028
+ return {
17029
+ event,
17030
+ action,
17031
+ repo,
17032
+ subject: `Pull request: #${n2}`,
17033
+ url: `${base}/pull/${n2}`,
17034
+ sender,
17035
+ details,
17036
+ summary
17037
+ };
17038
+ }
17039
+ if (event === "pull_request_review") {
17040
+ const pr = asDict(root["pull_request"]);
17041
+ const n2 = pr ? posInt(pr["number"]) : null;
17042
+ if (n2 === null)
17043
+ return null;
17044
+ const review = asDict(root["review"]);
17045
+ const state = inSet(review?.["state"], REVIEW_STATES);
17046
+ details.push(["Review state", state ?? "unknown"]);
17047
+ const reviewId = review ? posInt(review["id"]) : null;
17048
+ return {
17049
+ event,
17050
+ action,
17051
+ repo,
17052
+ subject: `Pull request: #${n2}`,
17053
+ url: reviewId ? `${base}/pull/${n2}#pullrequestreview-${reviewId}` : `${base}/pull/${n2}`,
17054
+ sender,
17055
+ details,
17056
+ summary: `Review ${state ?? "submitted"} on PR #${n2} in ${repo}`
17057
+ };
17058
+ }
17059
+ if (event === "check_suite") {
17060
+ const suite = asDict(root["check_suite"]);
17061
+ if (!suite)
17062
+ return null;
17063
+ const conclusion = inSet(suite["conclusion"], CHECK_CONCLUSIONS);
17064
+ details.push(["Conclusion", conclusion ?? "unknown"]);
17065
+ const app = shaped(asDict(suite["app"])?.["slug"], APP_SLUG);
17066
+ if (app)
17067
+ details.push(["App", app]);
17068
+ const sha = shaped(str(suite["head_sha"])?.toLowerCase(), SHA);
17069
+ if (sha)
17070
+ details.push(["Head commit", sha]);
17071
+ const prs = Array.isArray(suite["pull_requests"]) ? suite["pull_requests"].map((p2) => posInt(asDict(p2)?.["number"])).filter((x) => x !== null).slice(0, 10) : [];
17072
+ if (prs.length > 0)
17073
+ details.push(["Pull requests", prs.map((x) => `#${x}`).join(", ")]);
17074
+ return {
17075
+ event,
17076
+ action,
17077
+ repo,
17078
+ subject: null,
17079
+ url: sha ? `${base}/commit/${sha}` : base,
17080
+ sender,
17081
+ details,
17082
+ summary: `Check suite ${conclusion ?? "completed"} in ${repo}${prs.length > 0 ? ` (PR #${prs[0]})` : ""}`
17083
+ };
17084
+ }
17085
+ if (event === "issues") {
17086
+ const issue2 = asDict(root["issue"]);
17087
+ const n2 = issue2 ? posInt(issue2["number"]) : null;
17088
+ if (!issue2 || n2 === null)
17089
+ return null;
17090
+ if (action === "closed") {
17091
+ const reason = inSet(issue2["state_reason"], ISSUE_STATE_REASONS);
17092
+ if (reason)
17093
+ details.push(["Close reason", reason]);
17094
+ }
17095
+ return {
17096
+ event,
17097
+ action,
17098
+ repo,
17099
+ subject: `Issue: #${n2}`,
17100
+ url: `${base}/issues/${n2}`,
17101
+ sender,
17102
+ details,
17103
+ summary: `Issue #${n2} ${action} in ${repo}`
17104
+ };
17105
+ }
17106
+ const issue = asDict(root["issue"]);
17107
+ const n = issue ? posInt(issue["number"]) : null;
17108
+ if (!issue || n === null)
17109
+ return null;
17110
+ const onPr = asDict(issue["pull_request"]) !== null;
17111
+ const commentId = posInt(asDict(root["comment"])?.["id"]);
17112
+ details.push(["Comment on", onPr ? "pull request" : "issue"]);
17113
+ return {
17114
+ event,
17115
+ action,
17116
+ repo,
17117
+ subject: `${onPr ? "Pull request" : "Issue"}: #${n}`,
17118
+ url: commentId ? `${base}/issues/${n}#issuecomment-${commentId}` : `${base}/issues/${n}`,
17119
+ sender,
17120
+ details,
17121
+ summary: `New comment on ${onPr ? "PR" : "issue"} #${n} in ${repo}`
17122
+ };
17123
+ }
17124
+ function githubDedupKey(event, rawBody) {
17125
+ return `gh:body:${stableHash(`${event}
17126
+ ${rawBody}`)}`;
17127
+ }
17128
+ function buildGithubEvent(req, now = /* @__PURE__ */ new Date()) {
17129
+ const event = header(req.headers, GITHUB_EVENT_HEADER);
17130
+ if (!event)
17131
+ return null;
17132
+ const facts = extractGithubFacts(event, req.body);
17133
+ if (!facts)
17134
+ return null;
17135
+ const raw = req.rawBody ?? JSON.stringify(req.body ?? null);
17136
+ const delivery = header(req.headers, GITHUB_DELIVERY_HEADER);
17137
+ const deliveryGuid = delivery && GUID.test(delivery.toLowerCase()) ? delivery.toLowerCase() : null;
17138
+ const lines = [`GitHub event: ${facts.event} (${facts.action})`, `Repository: ${facts.repo}`];
17139
+ if (facts.subject)
17140
+ lines.push(facts.subject);
17141
+ for (const [k, v] of facts.details)
17142
+ lines.push(`${k}: ${v}`);
17143
+ if (facts.url)
17144
+ lines.push(`URL: ${facts.url}`);
17145
+ if (facts.sender)
17146
+ lines.push(`Sender: ${facts.sender}`);
17147
+ if (deliveryGuid)
17148
+ lines.push(`Delivery: ${deliveryGuid}`);
17149
+ lines.push("", "Titles, descriptions, comment text and commit messages are deliberately not included. Read them with your GitHub tools if you need them.");
17150
+ return {
17151
+ provider: GITHUB_TRIGGER_PROVIDER,
17152
+ occurredAt: now.toISOString(),
17153
+ dedupKey: githubDedupKey(facts.event, raw),
17154
+ sourceTrust: "untrusted",
17155
+ title: facts.summary,
17156
+ body: lines.join("\n"),
17157
+ // Ledger copy only (team-readable event log), never the prompt. Bounded
17158
+ // like the generic source; never headers (the signature rides there).
17159
+ raw: raw.length <= WEBHOOK_RAW_MAX_CHARS ? req.body : { truncated: true, bytes: raw.length, head: raw.slice(0, WEBHOOK_RAW_MAX_CHARS) },
17160
+ meaningful: true
17161
+ };
17162
+ }
17163
+ function validateGithubConfig(input) {
17164
+ const out = {};
17165
+ const textError = validateOperatorText(input, out);
17166
+ if (textError)
17167
+ return { ok: false, error: textError };
17168
+ const capError = validateRateCapConfig(input, out);
17169
+ if (capError)
17170
+ return { ok: false, error: capError };
17171
+ return { ok: true, config: out };
17172
+ }
17173
+ var githubTriggerAdapter = {
17174
+ provider: GITHUB_TRIGGER_PROVIDER,
17175
+ kind: "webhook",
17176
+ webhookAuth: "hmac",
17177
+ hmac: { signatureHeader: GITHUB_SIGNATURE_HEADER, signaturePrefix: "sha256=", algorithm: "sha256" },
17178
+ webhookEvents: [...GITHUB_WEBHOOK_EVENTS],
17179
+ // One trigger per repository or org hook, each with its own secret and instruction.
17180
+ multiInstance: true,
17181
+ maxBodyBytes: GITHUB_MAX_BODY_BYTES,
17182
+ validateConfig: validateGithubConfig,
17183
+ // Same breaker, same config key, same defaults as the generic source.
17184
+ rateCapPerHour: (trigger) => webhookRateCap(trigger),
17185
+ // Minted only on the human, agent.edit-gated route (as for `webhook`).
17186
+ operatorInstruction: true,
17187
+ ingest(req) {
17188
+ const event = buildGithubEvent(req);
17189
+ return event ? [event] : [];
17190
+ }
17191
+ };
17192
+ registerTriggerSource(githubTriggerAdapter);
17193
+
16915
17194
  // ../../packages/core/dist/restart/breaker-thresholds.js
16916
17195
  var RESTART_BREAKER_PROVISIONING_MAX = 5;
16917
17196
  var RESTART_BREAKER_PROVISIONING_WINDOW_MS = 18e5;
@@ -17119,4 +17398,4 @@ export {
17119
17398
  forcedUpdatePendingForMs,
17120
17399
  isForcedUpdatePastDeadline
17121
17400
  };
17122
- //# sourceMappingURL=chunk-TNPLCJIG.js.map
17401
+ //# sourceMappingURL=chunk-7IAJXJ7C.js.map