@dadado/agent-kit-cli 5.13.4 → 5.14.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.
Files changed (2) hide show
  1. package/dist/index.js +571 -160
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { defineCommand as defineCommand23, runMain, showUsage } from "citty";
4
+ import { defineCommand as defineCommand24, runMain, showUsage } from "citty";
5
5
 
6
6
  // src/commands/add.ts
7
7
  import { defineCommand } from "citty";
@@ -355,7 +355,16 @@ var KNOWN_SHIPPED_OVERLAY_HASHES = /* @__PURE__ */ new Set([
355
355
  "ebf490086ea45a7b342b3ec7408c9a82b22031daaefddf4425b6e6e931f6d6c8",
356
356
  "3077e013297c7dd1e32eb2fa86e1ffa1de7d8740058652782bb8d391782eed71",
357
357
  "7e0fa1bb73c8b6f1358cae19477304d85edfb7d4d9a7faf37c00e0578ed79edf",
358
- "c5f4ddb5dcf5f40919bedce89870af99422c6f3c9d540ca1f7554a66eaa2f2a8"
358
+ "c5f4ddb5dcf5f40919bedce89870af99422c6f3c9d540ca1f7554a66eaa2f2a8",
359
+ "62b744c1cc00f54601579b164d198838395e6ed8e4bcff67fdf55e0e1d9a7d9e",
360
+ "b1d129c5648014b97e7e1a8577b21b17d35d0bf84494f8be7cc142d51eb1da49",
361
+ "d05dfe1f6405f9d04c0f0113dbd34decf59b75840fb1d916b4c51c8961211b5f",
362
+ "4377b06a6ee0e44ce4a8125a0eba8e4c512a249533221570ac426308ba282c50",
363
+ "9cb8284762a05b4b67f8eb4a06d981bf574b30b02c30d23639a92ddfdeb838fc",
364
+ "bc71bb9c93cb9a4aaba901537681cdb81a5f2a9fd1e6f740eb54bca25b7b878e",
365
+ "f502f374f1d25cb20448aeebe678caa17a3c9cd0c683aaf8073878dda72e5375",
366
+ "5fb839c42331b9298302c374334c358a73ec58bb5bb5a6942847f9e49c154b3c",
367
+ "1782bf44268490c9e5465aa890447f01b1bc88e426dd8968186c5c9a7493086e"
359
368
  ]);
360
369
 
361
370
  // src/lifecycle/paths.ts
@@ -1742,9 +1751,11 @@ var L0_ARTIFACTS = [
1742
1751
  source: ".cursor/commands/dogfood.md",
1743
1752
  target: ".cursor/commands/dogfood.md"
1744
1753
  },
1745
- // Factory-only: `.cursor/commands/public-issue-triage.md` is intentionally
1746
- // omitted from L0 (and excluded from public-sync). See ADR
1747
- // 2026-08-05_factory-only-public-issue-triage-command.md.
1754
+ // Factory-only: `.cursor/commands/public-issue-triage.md` and
1755
+ // `.cursor/commands/public-inbound-radar.md` are intentionally omitted from
1756
+ // L0 (and excluded from public-sync). See ADRs
1757
+ // 2026-08-05_factory-only-public-issue-triage-command.md and
1758
+ // 2026-09-24_public-inbound-radar.md.
1748
1759
  {
1749
1760
  source: ".cursor/commands/cursor-update-awareness.md",
1750
1761
  target: ".cursor/commands/cursor-update-awareness.md"
@@ -6766,7 +6777,7 @@ var handoffCommand = defineCommand9({
6766
6777
  });
6767
6778
 
6768
6779
  // src/commands/hook.ts
6769
- import path32 from "path";
6780
+ import path33 from "path";
6770
6781
  import { defineCommand as defineCommand10 } from "citty";
6771
6782
 
6772
6783
  // src/hooks/format-session-start.ts
@@ -6793,7 +6804,7 @@ function buildPreCompactUserMessage(payload = {}) {
6793
6804
  // src/hooks/session-start.ts
6794
6805
  import { spawn as spawn5 } from "child_process";
6795
6806
  import { readFile as readFile19, stat as stat4 } from "fs/promises";
6796
- import path31 from "path";
6807
+ import path32 from "path";
6797
6808
 
6798
6809
  // src/invariants/handoff-schema.ts
6799
6810
  var MACHINE_LIST_CHECKS = [
@@ -6834,9 +6845,245 @@ function validateHandoffText(text) {
6834
6845
  return warnings;
6835
6846
  }
6836
6847
 
6848
+ // src/lifecycle/public-inbound-radar.ts
6849
+ import { execFile as execFile6 } from "child_process";
6850
+ import { access as access7 } from "fs/promises";
6851
+ import path30 from "path";
6852
+ import { promisify as promisify6 } from "util";
6853
+ var execFileAsync5 = promisify6(execFile6);
6854
+ var PUBLIC_INBOUND_REPO = "agent-kit-startup/agent-kit";
6855
+ var DEFAULT_PREFS2 = {
6856
+ enabled: false,
6857
+ intervalDays: 7,
6858
+ lastCheckedAt: null
6859
+ };
6860
+ function emptySummary() {
6861
+ return { issues: 0, humanPullRequests: 0, dependabotPullRequests: 0, total: 0 };
6862
+ }
6863
+ function summarize(items) {
6864
+ const summary = emptySummary();
6865
+ for (const item of items) {
6866
+ summary.total += 1;
6867
+ if (item.class === "issue") summary.issues += 1;
6868
+ else if (item.class === "dependabot") summary.dependabotPullRequests += 1;
6869
+ else summary.humanPullRequests += 1;
6870
+ }
6871
+ return summary;
6872
+ }
6873
+ function labelNames(labels) {
6874
+ if (!Array.isArray(labels)) return [];
6875
+ return labels.map((entry) => typeof entry === "string" ? entry : entry?.name).filter((name) => typeof name === "string" && name.length > 0);
6876
+ }
6877
+ function isDependabotAuthor(login) {
6878
+ if (!login) return false;
6879
+ const normalized = login.toLowerCase();
6880
+ return normalized === "dependabot" || normalized === "dependabot[bot]" || normalized === "app/dependabot" || normalized.startsWith("dependabot") || normalized === "renovate" || normalized === "renovate[bot]";
6881
+ }
6882
+ function classifyInbound(kind, authorLogin) {
6883
+ if (kind === "issue") return "issue";
6884
+ return isDependabotAuthor(authorLogin) ? "dependabot" : "human-pr";
6885
+ }
6886
+ function readPublicInboundCheckPrefs(config) {
6887
+ if (!config || typeof config !== "object" || Array.isArray(config)) {
6888
+ return { ...DEFAULT_PREFS2 };
6889
+ }
6890
+ const raw = config.publicInboundCheck;
6891
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
6892
+ return { ...DEFAULT_PREFS2 };
6893
+ }
6894
+ const uc = raw;
6895
+ const intervalDays = typeof uc.intervalDays === "number" && Number.isInteger(uc.intervalDays) && uc.intervalDays >= 1 ? uc.intervalDays : DEFAULT_PREFS2.intervalDays;
6896
+ return {
6897
+ enabled: uc.enabled === true,
6898
+ intervalDays,
6899
+ lastCheckedAt: typeof uc.lastCheckedAt === "string" ? uc.lastCheckedAt : null
6900
+ };
6901
+ }
6902
+ async function stampPublicInboundCheck(cwd, checkedAt) {
6903
+ const existing = await loadContextConfig(cwd) ?? {};
6904
+ const prev = existing.publicInboundCheck && typeof existing.publicInboundCheck === "object" ? { ...existing.publicInboundCheck } : {};
6905
+ existing.publicInboundCheck = {
6906
+ ...DEFAULT_PREFS2,
6907
+ ...prev,
6908
+ lastCheckedAt: (checkedAt ?? /* @__PURE__ */ new Date()).toISOString()
6909
+ };
6910
+ await writeJson(contextConfigPath(cwd), existing);
6911
+ }
6912
+ function mapRows(kind, rows) {
6913
+ const items = [];
6914
+ for (const row of rows) {
6915
+ const number = typeof row.number === "number" ? row.number : Number(row.number);
6916
+ if (!Number.isFinite(number) || number <= 0) continue;
6917
+ const author = row.author?.login?.trim() || "unknown";
6918
+ const title = typeof row.title === "string" && row.title.trim() ? row.title.trim() : "(no title)";
6919
+ const updatedAt = typeof row.updatedAt === "string" && row.updatedAt.trim() ? row.updatedAt.trim() : "";
6920
+ const url = typeof row.url === "string" && row.url.trim() ? row.url.trim() : `https://github.com/${PUBLIC_INBOUND_REPO}/${kind === "issue" ? "issues" : "pull"}/${number}`;
6921
+ items.push({
6922
+ kind,
6923
+ class: classifyInbound(kind, author),
6924
+ number,
6925
+ title,
6926
+ author,
6927
+ updatedAt,
6928
+ url,
6929
+ labels: labelNames(row.labels),
6930
+ cite: `${PUBLIC_INBOUND_REPO}#${number}`
6931
+ });
6932
+ }
6933
+ return items;
6934
+ }
6935
+ async function defaultRunGh(args, options) {
6936
+ const { stdout } = await execFileAsync5("gh", args, {
6937
+ cwd: options?.cwd,
6938
+ encoding: "utf8",
6939
+ maxBuffer: 4 * 1024 * 1024,
6940
+ timeout: 3e4
6941
+ });
6942
+ return stdout;
6943
+ }
6944
+ async function ghAvailable(runGh, cwd) {
6945
+ try {
6946
+ await runGh(["--version"], { cwd });
6947
+ return true;
6948
+ } catch {
6949
+ return false;
6950
+ }
6951
+ }
6952
+ async function detectFactoryCheckout(cwd) {
6953
+ const root = path30.resolve(cwd);
6954
+ try {
6955
+ const { stdout } = await execFileAsync5("git", ["remote", "get-url", "origin"], {
6956
+ cwd: root,
6957
+ encoding: "utf8",
6958
+ timeout: 5e3
6959
+ });
6960
+ if (/agent-kit-dev/i.test(stdout)) return true;
6961
+ } catch {
6962
+ }
6963
+ return fileExists(path30.join(root, "dogfood", "README.md"));
6964
+ }
6965
+ async function listJson(runGh, cwd, resource) {
6966
+ const stdout = await runGh(
6967
+ [
6968
+ resource,
6969
+ "list",
6970
+ "--repo",
6971
+ PUBLIC_INBOUND_REPO,
6972
+ "--state",
6973
+ "open",
6974
+ "--limit",
6975
+ "100",
6976
+ "--json",
6977
+ "number,title,author,updatedAt,labels,url"
6978
+ ],
6979
+ { cwd }
6980
+ );
6981
+ const trimmed = stdout.trim();
6982
+ if (!trimmed) return [];
6983
+ const parsed = JSON.parse(trimmed);
6984
+ return Array.isArray(parsed) ? parsed : [];
6985
+ }
6986
+ function resultBase(status, message, factory, now2, items = []) {
6987
+ return {
6988
+ status,
6989
+ repo: PUBLIC_INBOUND_REPO,
6990
+ checkedAt: now2.toISOString(),
6991
+ factory,
6992
+ items,
6993
+ summary: summarize(items),
6994
+ message,
6995
+ mutateRecommended: false
6996
+ };
6997
+ }
6998
+ async function checkPublicInbound(cwd, options = {}) {
6999
+ const now2 = options.now?.() ?? /* @__PURE__ */ new Date();
7000
+ const runGh = options.runGh ?? defaultRunGh;
7001
+ const isFactory = options.isFactory ?? detectFactoryCheckout;
7002
+ const root = path30.resolve(cwd);
7003
+ try {
7004
+ await access7(root);
7005
+ } catch {
7006
+ return resultBase("error", `cwd unreadable: ${root}`, false, now2);
7007
+ }
7008
+ const factory = await isFactory(root);
7009
+ if (!factory) {
7010
+ return resultBase(
7011
+ "skipped-non-factory",
7012
+ "Factory-only check. Aborting outside agent-kit-dev / dogfood checkout.",
7013
+ false,
7014
+ now2
7015
+ );
7016
+ }
7017
+ if (options.respectPrefs) {
7018
+ const prefs = readPublicInboundCheckPrefs(await loadContextConfig(root));
7019
+ if (!prefs.enabled) {
7020
+ return resultBase(
7021
+ "skipped-disabled",
7022
+ "publicInboundCheck.enabled is false (opt-in). Set true in .cursor/context/config.json to nudge.",
7023
+ true,
7024
+ now2
7025
+ );
7026
+ }
7027
+ if (!intervalElapsed(prefs.lastCheckedAt, prefs.intervalDays)) {
7028
+ return resultBase(
7029
+ "skipped-interval",
7030
+ `Within publicInboundCheck.intervalDays (${prefs.intervalDays}); last check ${prefs.lastCheckedAt}.`,
7031
+ true,
7032
+ now2
7033
+ );
7034
+ }
7035
+ }
7036
+ if (options.offline) {
7037
+ return resultBase("skipped-offline", "Offline flag set; skipped GitHub fetch.", true, now2);
7038
+ }
7039
+ if (!await ghAvailable(runGh, root)) {
7040
+ return resultBase(
7041
+ "skipped-gh-missing",
7042
+ "gh CLI missing or not runnable; fail-open skip.",
7043
+ true,
7044
+ now2
7045
+ );
7046
+ }
7047
+ try {
7048
+ const [issueRows, prRows] = await Promise.all([
7049
+ listJson(runGh, root, "issue"),
7050
+ listJson(runGh, root, "pr")
7051
+ ]);
7052
+ const items = [...mapRows("issue", issueRows), ...mapRows("pull_request", prRows)].sort(
7053
+ (a, b) => b.number - a.number
7054
+ );
7055
+ const summary = summarize(items);
7056
+ const message = summary.total === 0 ? `No open issues or pull requests on ${PUBLIC_INBOUND_REPO}.` : `Open inbound on ${PUBLIC_INBOUND_REPO}: ${summary.issues} issue(s), ${summary.humanPullRequests} human PR(s), ${summary.dependabotPullRequests} Dependabot PR(s).`;
7057
+ const result = resultBase("ok", message, true, now2, items);
7058
+ if (options.stamp) {
7059
+ await stampPublicInboundCheck(root, now2);
7060
+ }
7061
+ return result;
7062
+ } catch (err) {
7063
+ const detail = err instanceof Error ? err.message : String(err);
7064
+ if (/ENOTFOUND|ECONNREFUSED|ETIMEDOUT|network|offline|Could not resolve/i.test(detail)) {
7065
+ return resultBase(
7066
+ "skipped-offline",
7067
+ `GitHub unreachable; fail-open skip (${detail}).`,
7068
+ true,
7069
+ now2
7070
+ );
7071
+ }
7072
+ return resultBase("error", `Public inbound check failed: ${detail}`, true, now2);
7073
+ }
7074
+ }
7075
+ function shouldEmitPublicInboundNudge(result) {
7076
+ if (!result || result.status !== "ok") return false;
7077
+ if (result.mutateRecommended === true) return false;
7078
+ const summary = result.summary;
7079
+ if (!summary || typeof summary !== "object") return false;
7080
+ const total = summary.total;
7081
+ return typeof total === "number" && total > 0;
7082
+ }
7083
+
6837
7084
  // src/plan-index/plan-index.ts
6838
7085
  import { readFile as readFile18, writeFile as writeFile8 } from "fs/promises";
6839
- import path30 from "path";
7086
+ import path31 from "path";
6840
7087
  var PLAN_INDEX_REL = ".cursor/context/plan-index.json";
6841
7088
  var NONE = /^(none|n\/a|empty|nil)$/i;
6842
7089
  var OPEN_STATUSES = /* @__PURE__ */ new Set(["pending", "in_progress"]);
@@ -6850,7 +7097,7 @@ function defaultPlanIndexIo() {
6850
7097
  }
6851
7098
  },
6852
7099
  async writeFile(absPath, body) {
6853
- await ensureDir(path30.dirname(absPath));
7100
+ await ensureDir(path31.dirname(absPath));
6854
7101
  await writeFile8(absPath, body, "utf8");
6855
7102
  }
6856
7103
  };
@@ -6876,11 +7123,11 @@ function collectNamedPlanBasenames(named) {
6876
7123
  return out;
6877
7124
  }
6878
7125
  function namedPlanCandidatePaths(root, basename) {
6879
- const safe = path30.basename(basename);
7126
+ const safe = path31.basename(basename);
6880
7127
  if (!/^[A-Za-z0-9._-]+\.plan\.md$/i.test(safe)) return [];
6881
7128
  return [
6882
- path30.join(root, ".cursor", "plans", safe),
6883
- path30.join(root, ".cursor", "plans", "archive", safe)
7129
+ path31.join(root, ".cursor", "plans", safe),
7130
+ path31.join(root, ".cursor", "plans", "archive", safe)
6884
7131
  ];
6885
7132
  }
6886
7133
  function classifyPlanRole(file, named, openTodos) {
@@ -6912,7 +7159,7 @@ function parsePlanFrontmatter2(raw) {
6912
7159
  return { name, todos };
6913
7160
  }
6914
7161
  async function buildPlanIndex(root, io = defaultPlanIndexIo(), now2 = () => /* @__PURE__ */ new Date()) {
6915
- const handoffPath = path30.join(root, HANDOFF_REL);
7162
+ const handoffPath = path31.join(root, HANDOFF_REL);
6916
7163
  const handoffText = await io.readFile(handoffPath) ?? "";
6917
7164
  const named = extractHandoffNamedPlans(handoffText);
6918
7165
  const plans = [];
@@ -6941,7 +7188,7 @@ async function buildPlanIndex(root, io = defaultPlanIndexIo(), now2 = () => /* @
6941
7188
  }
6942
7189
  async function writePlanIndex(root, io = defaultPlanIndexIo(), now2 = () => /* @__PURE__ */ new Date()) {
6943
7190
  const index = await buildPlanIndex(root, io, now2);
6944
- const dest = path30.join(root, PLAN_INDEX_REL);
7191
+ const dest = path31.join(root, PLAN_INDEX_REL);
6945
7192
  const write = io.writeFile ?? defaultPlanIndexIo().writeFile;
6946
7193
  if (write) {
6947
7194
  await write(dest, `${JSON.stringify(index, null, 2)}
@@ -7200,6 +7447,11 @@ var CURSOR_AWARENESS_NUDGE = `## Cursor product-update awareness
7200
7447
  Advisory gaps vs \`docs/cursor-native-audit.md\` (check-only; no apply; no Field Reports).
7201
7448
 
7202
7449
  Run \`/cursor-update-awareness\` (or \`agent-kit cursor-awareness --check\`) and confirm routing via Ask \u2192 \`/backlog-add\` or \`/dogfood\`.`;
7450
+ var PUBLIC_INBOUND_NUDGE = `## Public inbound radar
7451
+
7452
+ Open issues or pull requests on \`agent-kit-startup/agent-kit\` (inspect-only; no merge/close).
7453
+
7454
+ Run \`/public-inbound-radar\` (or \`agent-kit public-inbound-radar --json\`) and confirm routing via Ask \u2192 \`/backlog-add\`, Memory WRITE, \`/dogfood\`, \`/public-issue-triage\`, or Dismiss. Dependabot is one batch.`;
7203
7455
 
7204
7456
  // src/hooks/session-start.ts
7205
7457
  var NONE_PLACEHOLDERS = /* @__PURE__ */ new Set(["none", "n/a", "empty", "nil"]);
@@ -7272,7 +7524,7 @@ function extractUnprocessedDogfoodLine(line) {
7272
7524
  return raw;
7273
7525
  }
7274
7526
  async function l0Present(root) {
7275
- return await fileExists(path31.join(root, MANIFEST_RELATIVE_PATH)) || await fileExists(path31.join(root, ".cursor", "commands", "agent-kit-onboard.md")) || await fileExists(path31.join(root, ".cursor", "commands", "start-project.md"));
7527
+ return await fileExists(path32.join(root, MANIFEST_RELATIVE_PATH)) || await fileExists(path32.join(root, ".cursor", "commands", "agent-kit-onboard.md")) || await fileExists(path32.join(root, ".cursor", "commands", "start-project.md"));
7276
7528
  }
7277
7529
  function checkLabelAndRecommendation(check2) {
7278
7530
  const checkId = check2.id;
@@ -7311,7 +7563,7 @@ function unresolvedReadinessChecks(data) {
7311
7563
  return { essential, nonessential };
7312
7564
  }
7313
7565
  async function readinessSection(root) {
7314
- const snapshotPath = path31.join(root, READINESS_SNAPSHOT_RELATIVE_PATH);
7566
+ const snapshotPath = path32.join(root, READINESS_SNAPSHOT_RELATIVE_PATH);
7315
7567
  let data;
7316
7568
  try {
7317
7569
  data = JSON.parse(await readFile19(snapshotPath, "utf8"));
@@ -7345,8 +7597,8 @@ Optional readiness item: \`${first.id}\`. ${first.recommendation} This does not
7345
7597
  }
7346
7598
  async function dogfoodInboxSection(root) {
7347
7599
  const candidateReadmes = [
7348
- path31.join(root, "dogfood", "README.md"),
7349
- path31.join(root, ".cursor", "dogfood", "README.md")
7600
+ path32.join(root, "dogfood", "README.md"),
7601
+ path32.join(root, ".cursor", "dogfood", "README.md")
7350
7602
  ];
7351
7603
  for (const readme of candidateReadmes) {
7352
7604
  if (!await fileExists(readme)) continue;
@@ -7528,6 +7780,97 @@ async function cursorAwarenessSection(root, deps = {}) {
7528
7780
  if (!shouldEmitCursorAwarenessNudge(result)) return null;
7529
7781
  return CURSOR_AWARENESS_NUDGE;
7530
7782
  }
7783
+ var PUBLIC_INBOUND_SPAWN_TIMEOUT_MS = 3e4;
7784
+ async function loadPublicInboundCheckPrefs(root) {
7785
+ const data = await loadContextConfig(root);
7786
+ if (!data) return null;
7787
+ const uc = data.publicInboundCheck;
7788
+ if (!uc || typeof uc !== "object" || uc.enabled !== true) {
7789
+ return null;
7790
+ }
7791
+ return uc;
7792
+ }
7793
+ function runPublicInboundJson(root) {
7794
+ return new Promise((resolve3) => {
7795
+ const child = spawn5(
7796
+ process.execPath,
7797
+ [
7798
+ process.argv[1] ?? "",
7799
+ "public-inbound-radar",
7800
+ "--json",
7801
+ "--respect-prefs",
7802
+ "--stamp",
7803
+ "--cwd",
7804
+ root
7805
+ ],
7806
+ { stdio: ["ignore", "pipe", "ignore"], timeout: PUBLIC_INBOUND_SPAWN_TIMEOUT_MS }
7807
+ );
7808
+ let out = "";
7809
+ child.stdout?.on("data", (chunk) => {
7810
+ out += chunk.toString("utf8");
7811
+ });
7812
+ child.on("error", () => resolve3(null));
7813
+ child.on("close", () => {
7814
+ try {
7815
+ const parsed = JSON.parse(out.trim());
7816
+ resolve3(parsed && typeof parsed === "object" ? parsed : null);
7817
+ } catch {
7818
+ resolve3(null);
7819
+ }
7820
+ });
7821
+ });
7822
+ }
7823
+ async function publicInboundSection(root, deps = {}) {
7824
+ if (await loadPublicInboundCheckPrefs(root) === null) return null;
7825
+ const spawnFn = deps.spawnFn ?? spawn5;
7826
+ const runFallback = deps.runFallback ?? runPublicInboundJson;
7827
+ const result = await new Promise((resolve3) => {
7828
+ let settled = false;
7829
+ let fallbackStarted = false;
7830
+ const finish = (value) => {
7831
+ if (settled) return;
7832
+ settled = true;
7833
+ resolve3(value);
7834
+ };
7835
+ const startFallback = () => {
7836
+ if (settled || fallbackStarted) return;
7837
+ fallbackStarted = true;
7838
+ void runFallback(root).then(finish);
7839
+ };
7840
+ const child = spawnFn(
7841
+ "agent-kit",
7842
+ ["public-inbound-radar", "--json", "--respect-prefs", "--stamp", "--cwd", root],
7843
+ {
7844
+ stdio: ["ignore", "pipe", "ignore"],
7845
+ timeout: PUBLIC_INBOUND_SPAWN_TIMEOUT_MS,
7846
+ shell: false
7847
+ }
7848
+ );
7849
+ let out = "";
7850
+ child.stdout?.on("data", (chunk) => {
7851
+ out += chunk.toString("utf8");
7852
+ });
7853
+ child.on("error", () => {
7854
+ startFallback();
7855
+ });
7856
+ child.on("close", (code) => {
7857
+ if (settled || fallbackStarted) return;
7858
+ if (code !== 0 && !out.trim()) {
7859
+ startFallback();
7860
+ return;
7861
+ }
7862
+ try {
7863
+ finish(JSON.parse(out.trim()));
7864
+ } catch {
7865
+ startFallback();
7866
+ }
7867
+ });
7868
+ });
7869
+ if (!shouldEmitPublicInboundNudge(result)) {
7870
+ return null;
7871
+ }
7872
+ return PUBLIC_INBOUND_NUDGE;
7873
+ }
7531
7874
  var AUDIT_SESSION_NS_PREFIX = "agent-kit-audit-";
7532
7875
  var AUDIT_SESSION_LIST_TIMEOUT_MS = 2e3;
7533
7876
  function runAuditSessionCommand(cmd, args) {
@@ -7573,7 +7916,7 @@ function parseScreenDetachedAuditSessions(listing) {
7573
7916
  const [, pid, name, marker] = m;
7574
7917
  if (!name || !name.startsWith(AUDIT_SESSION_NS_PREFIX)) continue;
7575
7918
  if (marker && /[Aa]ttached/.test(marker)) continue;
7576
- entries.push({ name, socketPath: sockdir ? path31.join(sockdir, `${pid}.${name}`) : null });
7919
+ entries.push({ name, socketPath: sockdir ? path32.join(sockdir, `${pid}.${name}`) : null });
7577
7920
  }
7578
7921
  return entries;
7579
7922
  }
@@ -7621,8 +7964,8 @@ ${sessions.length} detached \`agent-kit-audit-*\` PTY ${noun} on this host (${ol
7621
7964
  }
7622
7965
  }
7623
7966
  async function buildSessionStartAdditionalContext(rootDir, _payload = {}) {
7624
- const root = path31.resolve(rootDir);
7625
- const handoffPath = path31.join(root, HANDOFF_REL);
7967
+ const root = path32.resolve(rootDir);
7968
+ const handoffPath = path32.join(root, HANDOFF_REL);
7626
7969
  const handoffFull = await readFull(handoffPath);
7627
7970
  const handoff = capHandoffExcerpt(handoffFull);
7628
7971
  const parts = [HARD_RULES];
@@ -7636,6 +7979,8 @@ async function buildSessionStartAdditionalContext(rootDir, _payload = {}) {
7636
7979
  if (updateNudge) parts.push(updateNudge);
7637
7980
  const cursorNudge = await cursorAwarenessSection(root);
7638
7981
  if (cursorNudge) parts.push(cursorNudge);
7982
+ const inboundNudge = await publicInboundSection(root);
7983
+ if (inboundNudge) parts.push(inboundNudge);
7639
7984
  const auditSessions = await detachedAuditSessionsSection().catch(() => null);
7640
7985
  if (auditSessions) parts.push(auditSessions);
7641
7986
  const formatWarnings = validateHandoffText(handoffFull);
@@ -7689,7 +8034,7 @@ async function runSessionStartHook(cwd, formatArg, deps = {}) {
7689
8034
  const readStdin = deps.readStdin ?? readStdinJson;
7690
8035
  const buildContext = deps.buildContext ?? buildSessionStartAdditionalContext;
7691
8036
  const payload = await readStdin();
7692
- const root = resolveSessionRoot(payload, path32.resolve(cwd));
8037
+ const root = resolveSessionRoot(payload, path33.resolve(cwd));
7693
8038
  const out = await buildContext(root, payload);
7694
8039
  return formatSessionStartOutput(out.additional_context, format);
7695
8040
  } catch {
@@ -7742,12 +8087,12 @@ import { defineCommand as defineCommand12 } from "citty";
7742
8087
 
7743
8088
  // src/lifecycle/path-cli.ts
7744
8089
  import { spawn as spawn6 } from "child_process";
7745
- import path34 from "path";
8090
+ import path35 from "path";
7746
8091
 
7747
8092
  // src/utils/terminal.ts
7748
8093
  import { readdir as readdir8 } from "fs/promises";
7749
8094
  import { homedir as homedir3 } from "os";
7750
- import path33 from "path";
8095
+ import path34 from "path";
7751
8096
  import { confirm, isCancel } from "@clack/prompts";
7752
8097
  function isNonInteractive() {
7753
8098
  if (process.env.CI === "true" || process.env.CI === "1") return true;
@@ -7771,14 +8116,14 @@ async function findNestedRepoChildren(resolved) {
7771
8116
  if (!entry.isDirectory()) continue;
7772
8117
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
7773
8118
  scanned += 1;
7774
- if (await fileExists(path33.join(resolved, entry.name, ".git"))) {
8119
+ if (await fileExists(path34.join(resolved, entry.name, ".git"))) {
7775
8120
  nested.push(entry.name);
7776
8121
  }
7777
8122
  }
7778
8123
  return nested;
7779
8124
  }
7780
8125
  async function validateProjectRoot(resolved) {
7781
- const home = path33.resolve(homedir3());
8126
+ const home = path34.resolve(homedir3());
7782
8127
  if (resolved === "/" || resolved === home) {
7783
8128
  return {
7784
8129
  ok: false,
@@ -7786,8 +8131,8 @@ async function validateProjectRoot(resolved) {
7786
8131
  recovery: "Change into a project directory and re-run. Agent Kit installs per project."
7787
8132
  };
7788
8133
  }
7789
- const hasGit = await fileExists(path33.join(resolved, ".git"));
7790
- const hasManifest = await fileExists(path33.join(resolved, MANIFEST_RELATIVE_PATH));
8134
+ const hasGit = await fileExists(path34.join(resolved, ".git"));
8135
+ const hasManifest = await fileExists(path34.join(resolved, MANIFEST_RELATIVE_PATH));
7791
8136
  if (!hasGit && !hasManifest) {
7792
8137
  return {
7793
8138
  ok: false,
@@ -7820,7 +8165,7 @@ async function validateProjectRoot(resolved) {
7820
8165
  return { ok: true };
7821
8166
  }
7822
8167
  async function confirmProjectRoot(cwd, opts) {
7823
- const resolved = path33.resolve(cwd);
8168
+ const resolved = path34.resolve(cwd);
7824
8169
  if (opts.forceRoot) {
7825
8170
  return resolved;
7826
8171
  }
@@ -7934,9 +8279,9 @@ function npxPinned(runtimeVersion, subcommand) {
7934
8279
  return `npx -y ${pinnedCliSpec(runtimeVersion)} ${subcommand}`;
7935
8280
  }
7936
8281
  function isBinUnderPrefix(binPath, prefix) {
7937
- const bin = path34.resolve(binPath);
7938
- const root = path34.resolve(prefix);
7939
- return bin === root || bin.startsWith(`${root}${path34.sep}`);
8282
+ const bin = path35.resolve(binPath);
8283
+ const root = path35.resolve(prefix);
8284
+ return bin === root || bin.startsWith(`${root}${path35.sep}`);
7940
8285
  }
7941
8286
  function pathCliStatus(env, runtimeVersion) {
7942
8287
  if (!env.binOnPath || !env.binPath) return "missing";
@@ -8034,17 +8379,17 @@ async function syncPathCliToRuntime(options = {}) {
8034
8379
  }
8035
8380
 
8036
8381
  // src/commands/install.ts
8037
- import path40 from "path";
8382
+ import path41 from "path";
8038
8383
  import { defineCommand as defineCommand11 } from "citty";
8039
8384
  import { bold, cyan as cyan3, green as green2, options as koloristOptions2 } from "kolorist";
8040
8385
 
8041
8386
  // src/generator/personalization.ts
8042
8387
  import { readFile as readFile21, writeFile as writeFile12 } from "fs/promises";
8043
- import path38 from "path";
8388
+ import path39 from "path";
8044
8389
 
8045
8390
  // src/generator/claude-command-adapters.ts
8046
8391
  import { readFile as readFile20, readdir as readdir9, writeFile as writeFile9 } from "fs/promises";
8047
- import path35 from "path";
8392
+ import path36 from "path";
8048
8393
  var CURSOR_COMMANDS_DIR_REL = ".cursor/commands";
8049
8394
  var CLAUDE_COMMANDS_DIR_REL = ".claude/commands";
8050
8395
  var RESERVED_ADAPTER_NAMES = /* @__PURE__ */ new Set(["agent-kit"]);
@@ -8073,7 +8418,7 @@ Adapter rules (Claude Code CLI):
8073
8418
  `;
8074
8419
  }
8075
8420
  async function discoverInstalledCommands(rootDir) {
8076
- const dir = path35.join(rootDir, CURSOR_COMMANDS_DIR_REL);
8421
+ const dir = path36.join(rootDir, CURSOR_COMMANDS_DIR_REL);
8077
8422
  let entries;
8078
8423
  try {
8079
8424
  entries = (await readdir9(dir)).filter((f) => f.endsWith(".md"));
@@ -8085,7 +8430,7 @@ async function discoverInstalledCommands(rootDir) {
8085
8430
  const name = file.slice(0, -3);
8086
8431
  if (RESERVED_ADAPTER_NAMES.has(name)) continue;
8087
8432
  try {
8088
- const raw = await readFile20(path35.join(dir, file), "utf8");
8433
+ const raw = await readFile20(path36.join(dir, file), "utf8");
8089
8434
  const parsed = parseCommandFrontmatter(name, raw);
8090
8435
  if (parsed) commands.push(parsed);
8091
8436
  } catch {
@@ -8100,11 +8445,11 @@ async function generateClaudeCommandAdapters(rootDir) {
8100
8445
  const results = [];
8101
8446
  let ledgerDirty = false;
8102
8447
  for (const command of commands) {
8103
- const relPath = path35.posix.join(CLAUDE_COMMANDS_DIR_REL, `${command.name}.md`);
8448
+ const relPath = path36.posix.join(CLAUDE_COMMANDS_DIR_REL, `${command.name}.md`);
8104
8449
  const rendered = renderClaudeCommandAdapter(command);
8105
- const abs = path35.join(rootDir, relPath);
8450
+ const abs = path36.join(rootDir, relPath);
8106
8451
  if (!await fileExists(abs)) {
8107
- await ensureDir(path35.dirname(abs));
8452
+ await ensureDir(path36.dirname(abs));
8108
8453
  await writeFile9(abs, rendered, "utf8");
8109
8454
  ledger.hashes[relPath] = contentHash(rendered);
8110
8455
  ledgerDirty = true;
@@ -8135,7 +8480,7 @@ async function generateClaudeCommandAdapters(rootDir) {
8135
8480
 
8136
8481
  // src/generator/claude-kit-load.ts
8137
8482
  import { writeFile as writeFile10 } from "fs/promises";
8138
- import path36 from "path";
8483
+ import path37 from "path";
8139
8484
  var CLAUDE_MD_REL = "CLAUDE.md";
8140
8485
  var AGENT_KIT_COMMAND_REL = ".claude/commands/agent-kit.md";
8141
8486
  function renderClaudeMd() {
@@ -8191,11 +8536,11 @@ Non-goals: not audits / \`/plan-external-review\`, not a second tick dialect (\`
8191
8536
  `;
8192
8537
  }
8193
8538
  async function writeUnlessExists(rootDir, relativePath, content) {
8194
- const target = path36.join(rootDir, relativePath);
8539
+ const target = path37.join(rootDir, relativePath);
8195
8540
  if (await fileExists(target)) {
8196
8541
  return { relativePath, status: "skipped-customized" };
8197
8542
  }
8198
- await ensureDir(path36.dirname(target));
8543
+ await ensureDir(path37.dirname(target));
8199
8544
  await writeFile10(target, content, "utf8");
8200
8545
  return { relativePath, status: "applied" };
8201
8546
  }
@@ -8208,7 +8553,7 @@ async function generateClaudeKitLoadArtifacts(rootDir) {
8208
8553
 
8209
8554
  // src/generator/vscode.ts
8210
8555
  import { writeFile as writeFile11 } from "fs/promises";
8211
- import path37 from "path";
8556
+ import path38 from "path";
8212
8557
 
8213
8558
  // src/generator/platform.ts
8214
8559
  function gitProviderLabel(profile) {
@@ -8232,10 +8577,10 @@ function prTerminology(profile) {
8232
8577
  // src/generator/vscode.ts
8233
8578
  async function generateVSCodeArtifacts(profile) {
8234
8579
  const results = [];
8235
- const vscodeDir = path37.join(profile.rootDir, ".vscode");
8236
- const githubDir = path37.join(profile.rootDir, ".github");
8580
+ const vscodeDir = path38.join(profile.rootDir, ".vscode");
8581
+ const githubDir = path38.join(profile.rootDir, ".github");
8237
8582
  await Promise.all([ensureDir(vscodeDir), ensureDir(githubDir)]);
8238
- const settingsPath = path37.join(vscodeDir, "settings.json");
8583
+ const settingsPath = path38.join(vscodeDir, "settings.json");
8239
8584
  if (await fileExists(settingsPath)) {
8240
8585
  results.push({ relativePath: ".vscode/settings.json", status: "skipped-customized" });
8241
8586
  } else {
@@ -8259,7 +8604,7 @@ async function generateVSCodeArtifacts(profile) {
8259
8604
  }
8260
8605
  const provider = gitProviderLabel(profile);
8261
8606
  const prTerm = prTerminology(profile);
8262
- const copilotPath = path37.join(githubDir, "copilot-instructions.md");
8607
+ const copilotPath = path38.join(githubDir, "copilot-instructions.md");
8263
8608
  if (await fileExists(copilotPath)) {
8264
8609
  results.push({ relativePath: ".github/copilot-instructions.md", status: "skipped-customized" });
8265
8610
  } else {
@@ -8277,7 +8622,7 @@ async function generateVSCodeArtifacts(profile) {
8277
8622
  results.push({ relativePath: ".github/copilot-instructions.md", status: "applied" });
8278
8623
  }
8279
8624
  if (profile.ide.plan === "vscode-pro") {
8280
- const securityPath = path37.join(vscodeDir, "security-review.agent.md");
8625
+ const securityPath = path38.join(vscodeDir, "security-review.agent.md");
8281
8626
  if (await fileExists(securityPath)) {
8282
8627
  results.push({
8283
8628
  relativePath: ".vscode/security-review.agent.md",
@@ -8489,7 +8834,7 @@ function renderProjectContext(profile, skillItems = []) {
8489
8834
  `;
8490
8835
  }
8491
8836
  async function createOwnedFile(rootDir, relativePath, content, evidence) {
8492
- const target = path38.join(rootDir, relativePath);
8837
+ const target = path39.join(rootDir, relativePath);
8493
8838
  if (await fileExists(target)) {
8494
8839
  return {
8495
8840
  kind: "file",
@@ -8499,7 +8844,7 @@ async function createOwnedFile(rootDir, relativePath, content, evidence) {
8499
8844
  evidence
8500
8845
  };
8501
8846
  }
8502
- await ensureDir(path38.dirname(target));
8847
+ await ensureDir(path39.dirname(target));
8503
8848
  await writeFile12(target, content, "utf8");
8504
8849
  return {
8505
8850
  kind: "file",
@@ -8516,7 +8861,7 @@ async function packTargets(registryRoot, packId) {
8516
8861
  async function existingTargets(projectRoot, targets) {
8517
8862
  const checks = await Promise.all(
8518
8863
  targets.map(
8519
- async (target) => await fileExists(path38.join(projectRoot, target)) ? target : null
8864
+ async (target) => await fileExists(path39.join(projectRoot, target)) ? target : null
8520
8865
  )
8521
8866
  );
8522
8867
  return checks.filter((target) => target !== null);
@@ -8538,14 +8883,14 @@ async function applyPersonalization(input) {
8538
8883
  componentResults.push({ ...item, status: "unavailable" });
8539
8884
  continue;
8540
8885
  }
8541
- const target = path38.posix.join(
8886
+ const target = path39.posix.join(
8542
8887
  ".cursor",
8543
8888
  "skills",
8544
8889
  skill.path.includes("/core/") ? "core" : "community",
8545
8890
  skill.id,
8546
8891
  "SKILL.md"
8547
8892
  );
8548
- if (await fileExists(path38.join(input.rootDir, target))) {
8893
+ if (await fileExists(path39.join(input.rootDir, target))) {
8549
8894
  componentResults.push({ ...item, status: "skipped-customized", path: target });
8550
8895
  protectedPaths.add(target);
8551
8896
  continue;
@@ -8690,7 +9035,7 @@ async function applyPersonalization(input) {
8690
9035
  protectedPaths: [...protectedPaths].sort(),
8691
9036
  ...claudeSessionStartInstructions ? { claudeSessionStartInstructions } : {}
8692
9037
  };
8693
- await writeJson(path38.join(input.rootDir, RESULT_PATH), result);
9038
+ await writeJson(path39.join(input.rootDir, RESULT_PATH), result);
8694
9039
  return {
8695
9040
  result,
8696
9041
  manifest: {
@@ -8708,7 +9053,7 @@ async function applyPersonalization(input) {
8708
9053
  };
8709
9054
  }
8710
9055
  async function readRepositoryProfile(rootDir) {
8711
- const target = path38.join(rootDir, REPOSITORY_PROFILE_REL);
9056
+ const target = path39.join(rootDir, REPOSITORY_PROFILE_REL);
8712
9057
  if (!await fileExists(target)) return null;
8713
9058
  return JSON.parse(await readFile21(target, "utf8"));
8714
9059
  }
@@ -8716,16 +9061,16 @@ async function readRepositoryProfile(rootDir) {
8716
9061
  // src/lifecycle/onboard-migration.ts
8717
9062
  import { createHash as createHash4 } from "crypto";
8718
9063
  import { readFile as readFile22, unlink } from "fs/promises";
8719
- import path39 from "path";
9064
+ import path40 from "path";
8720
9065
  var LEGACY_ONBOARD_PATH = ".cursor/commands/onboard.md";
8721
9066
  var NAMESPACED_ONBOARD_PATH = ".cursor/commands/agent-kit-onboard.md";
8722
9067
  var MANAGED_LEGACY_HASHES = /* @__PURE__ */ new Set([
8723
9068
  "b274a68941813f19b185893cb7c5561dff027f53270890029992f208e24992fe"
8724
9069
  ]);
8725
9070
  async function migrateLegacyOnboardCommand(projectRoot, managedHashes = MANAGED_LEGACY_HASHES) {
8726
- const legacyPath = path39.join(projectRoot, LEGACY_ONBOARD_PATH);
9071
+ const legacyPath = path40.join(projectRoot, LEGACY_ONBOARD_PATH);
8727
9072
  if (!await fileExists(legacyPath)) return "absent";
8728
- const namespacedPath = path39.join(projectRoot, NAMESPACED_ONBOARD_PATH);
9073
+ const namespacedPath = path40.join(projectRoot, NAMESPACED_ONBOARD_PATH);
8729
9074
  if (!await fileExists(namespacedPath)) return "preserved-customized";
8730
9075
  const content = await readFile22(legacyPath);
8731
9076
  const hash = createHash4("sha256").update(content).digest("hex");
@@ -8876,7 +9221,7 @@ async function printPostInstallSummary(result) {
8876
9221
  printInstallEpilogue(sync.env, { runtimeVersion: KIT_VERSION });
8877
9222
  }
8878
9223
  async function performInstall(options) {
8879
- const projectRoot = path40.resolve(options.cwd);
9224
+ const projectRoot = path41.resolve(options.cwd);
8880
9225
  const packs = parsePackList(options.pack);
8881
9226
  const existing = await loadAgentKitManifest(projectRoot);
8882
9227
  const registry = await resolveRegistryFromCli({
@@ -9581,9 +9926,9 @@ function renderMcLive(view, opts = {}) {
9581
9926
  }
9582
9927
 
9583
9928
  // src/mission-control/snapshot.ts
9584
- import { execFile as execFile6 } from "child_process";
9585
- import { access as access7 } from "fs/promises";
9586
- import path41 from "path";
9929
+ import { execFile as execFile7 } from "child_process";
9930
+ import { access as access8 } from "fs/promises";
9931
+ import path42 from "path";
9587
9932
 
9588
9933
  // ../../dashboard/lib/live-refresh.mjs
9589
9934
  import { join, resolve as resolve2 } from "path";
@@ -9615,8 +9960,8 @@ function dataScriptTimeoutMs(env = process.env) {
9615
9960
  async function firstExisting2(candidates) {
9616
9961
  for (const candidate2 of candidates) {
9617
9962
  try {
9618
- await access7(candidate2);
9619
- return path41.resolve(candidate2);
9963
+ await access8(candidate2);
9964
+ return path42.resolve(candidate2);
9620
9965
  } catch {
9621
9966
  }
9622
9967
  }
@@ -9625,9 +9970,9 @@ async function firstExisting2(candidates) {
9625
9970
  async function findDashboardDataScript(cwd, env = process.env, options = {}) {
9626
9971
  const startPath = await findDashboardStart(cwd, env, options);
9627
9972
  if (startPath) {
9628
- const sibling = path41.join(path41.dirname(startPath), "dashboard-data.mjs");
9973
+ const sibling = path42.join(path42.dirname(startPath), "dashboard-data.mjs");
9629
9974
  try {
9630
- await access7(sibling);
9975
+ await access8(sibling);
9631
9976
  return sibling;
9632
9977
  } catch {
9633
9978
  }
@@ -9639,8 +9984,8 @@ async function findDashboardDataScript(cwd, env = process.env, options = {}) {
9639
9984
  async function loadDashboardSnapshot(opts) {
9640
9985
  const env = opts.env ?? process.env;
9641
9986
  const timeout = dataScriptTimeoutMs(env);
9642
- const run = opts.execFileFn ?? execFile6;
9643
- const snapshotRoot = path41.resolve(opts.snapshotRoot);
9987
+ const run = opts.execFileFn ?? execFile7;
9988
+ const snapshotRoot = path42.resolve(opts.snapshotRoot);
9644
9989
  return new Promise((resolve3) => {
9645
9990
  run(
9646
9991
  process.execPath,
@@ -9963,20 +10308,20 @@ var missionControlCommand = defineCommand13({
9963
10308
  });
9964
10309
 
9965
10310
  // src/commands/monitors.ts
9966
- import path43 from "path";
10311
+ import path44 from "path";
9967
10312
  import { defineCommand as defineCommand14 } from "citty";
9968
10313
 
9969
10314
  // src/invariants/monitors-untriaged.ts
9970
- import { execFile as execFile7 } from "child_process";
10315
+ import { execFile as execFile8 } from "child_process";
9971
10316
  import { readFile as readFile23, readdir as readdir10, stat as stat5 } from "fs/promises";
9972
- import path42 from "path";
9973
- import { promisify as promisify6 } from "util";
10317
+ import path43 from "path";
10318
+ import { promisify as promisify7 } from "util";
9974
10319
 
9975
10320
  // src/invariants/triage-heading.ts
9976
10321
  var TRIAGE_HEADING_RE = /^#{2,6}\s+(?:Triage note|Follow-?up plan|Residuals plan)\b/im;
9977
10322
 
9978
10323
  // src/invariants/monitors-untriaged.ts
9979
- var execFileAsync5 = promisify6(execFile7);
10324
+ var execFileAsync6 = promisify7(execFile8);
9980
10325
  var CITE4 = "agent-kit monitors --untriaged (ADR 2026-07-27_plan-review-triage-untriaged-not-mtime; never newest-mtime-wins)";
9981
10326
  function hasOpenGaps(content) {
9982
10327
  if (/###\s+Still open[^\n]*\n+(?:\s*\n)*(?:None\.|none\.|\*None\*)/i.test(content)) {
@@ -10002,7 +10347,7 @@ async function listMonitorFiles(memoryDir) {
10002
10347
  async function gitFreshMonitorNames(rootDir) {
10003
10348
  const names = /* @__PURE__ */ new Set();
10004
10349
  try {
10005
- const { stdout } = await execFileAsync5(
10350
+ const { stdout } = await execFileAsync6(
10006
10351
  "git",
10007
10352
  ["status", "--porcelain", "--", ".cursor/memory"],
10008
10353
  { cwd: rootDir, maxBuffer: 2 * 1024 * 1024 }
@@ -10010,7 +10355,7 @@ async function gitFreshMonitorNames(rootDir) {
10010
10355
  for (const line of stdout.split("\n")) {
10011
10356
  if (!line.trim()) continue;
10012
10357
  const file = line.slice(3).trim().replace(/^.* -> /, "");
10013
- const base = path42.basename(file);
10358
+ const base = path43.basename(file);
10014
10359
  if (base.startsWith("plan-monitor-") && base.endsWith(".md")) {
10015
10360
  names.add(base);
10016
10361
  }
@@ -10033,13 +10378,13 @@ function monitorSlugFromName(fileName) {
10033
10378
  return fileName.replace(/^plan-monitor-/, "").replace(/\.md$/, "").toLowerCase();
10034
10379
  }
10035
10380
  async function selectUntriagedMonitors(rootDir) {
10036
- const root = path42.resolve(rootDir);
10037
- const memoryDir = path42.join(root, ".cursor", "memory");
10381
+ const root = path43.resolve(rootDir);
10382
+ const memoryDir = path43.join(root, ".cursor", "memory");
10038
10383
  const allNames = await listMonitorFiles(memoryDir);
10039
10384
  const selectionOrder = ["git-fresh", "handoff-aligned", "untriaged-scan"];
10040
10385
  const byName = /* @__PURE__ */ new Map();
10041
10386
  for (const name of allNames) {
10042
- const abs = path42.join(memoryDir, name);
10387
+ const abs = path43.join(memoryDir, name);
10043
10388
  try {
10044
10389
  const [content, st] = await Promise.all([readFile23(abs, "utf8"), stat5(abs)]);
10045
10390
  byName.set(name, { content, mtimeMs: st.mtimeMs });
@@ -10054,7 +10399,7 @@ async function selectUntriagedMonitors(rootDir) {
10054
10399
  const gitFreshSet = [...gitFresh].filter(untriaged).sort();
10055
10400
  let handoff = "";
10056
10401
  try {
10057
- handoff = await readFile23(path42.join(root, ".cursor", "HANDOFF.md"), "utf8");
10402
+ handoff = await readFile23(path43.join(root, ".cursor", "HANDOFF.md"), "utf8");
10058
10403
  } catch {
10059
10404
  handoff = "";
10060
10405
  }
@@ -10074,8 +10419,8 @@ async function selectUntriagedMonitors(rootDir) {
10074
10419
  const row = byName.get(name);
10075
10420
  if (!row) continue;
10076
10421
  entries.push({
10077
- path: path42.join(memoryDir, name),
10078
- relativePath: path42.relative(root, path42.join(memoryDir, name)).split(path42.sep).join("/"),
10422
+ path: path43.join(memoryDir, name),
10423
+ relativePath: path43.relative(root, path43.join(memoryDir, name)).split(path43.sep).join("/"),
10079
10424
  mtimeMs: row.mtimeMs,
10080
10425
  hasTriageHeading: false,
10081
10426
  hasOpenGaps: hasOpenGaps(row.content),
@@ -10121,7 +10466,7 @@ var monitorsCommand = defineCommand14({
10121
10466
  process.exitCode = 2;
10122
10467
  return;
10123
10468
  }
10124
- const result = await selectUntriagedMonitors(path43.resolve(args.cwd));
10469
+ const result = await selectUntriagedMonitors(path44.resolve(args.cwd));
10125
10470
  if (args.json) {
10126
10471
  console.log(JSON.stringify(result, null, 2));
10127
10472
  return;
@@ -10137,7 +10482,7 @@ var monitorsCommand = defineCommand14({
10137
10482
  });
10138
10483
 
10139
10484
  // src/commands/plan-index.ts
10140
- import path44 from "path";
10485
+ import path45 from "path";
10141
10486
  import { defineCommand as defineCommand15 } from "citty";
10142
10487
  var planIndexCommand = defineCommand15({
10143
10488
  meta: {
@@ -10156,7 +10501,7 @@ var planIndexCommand = defineCommand15({
10156
10501
  }
10157
10502
  },
10158
10503
  async run({ args }) {
10159
- const root = path44.resolve(args.cwd);
10504
+ const root = path45.resolve(args.cwd);
10160
10505
  const index = await writePlanIndex(root);
10161
10506
  if (args.json) {
10162
10507
  console.log(JSON.stringify(index, null, 2));
@@ -10171,15 +10516,72 @@ var planIndexCommand = defineCommand15({
10171
10516
  }
10172
10517
  });
10173
10518
 
10174
- // src/commands/run-plan.ts
10175
- import path51 from "path";
10519
+ // src/commands/public-inbound-radar.ts
10176
10520
  import { defineCommand as defineCommand16 } from "citty";
10521
+ var publicInboundRadarCommand = defineCommand16({
10522
+ meta: {
10523
+ name: "public-inbound-radar",
10524
+ description: "Factory-only: list open public issues/PRs on agent-kit-startup/agent-kit (read-only JSON)."
10525
+ },
10526
+ args: {
10527
+ cwd: {
10528
+ type: "string",
10529
+ default: process.cwd()
10530
+ },
10531
+ json: {
10532
+ type: "boolean",
10533
+ description: "Print machine-readable JSON (default true for scripting)",
10534
+ default: true
10535
+ },
10536
+ offline: {
10537
+ type: "boolean",
10538
+ description: "Skip GitHub fetch; fail-open skipped-offline",
10539
+ default: false
10540
+ },
10541
+ "respect-prefs": {
10542
+ type: "boolean",
10543
+ description: "Honor publicInboundCheck.enabled and intervalDays from .cursor/context/config.json",
10544
+ default: false
10545
+ },
10546
+ stamp: {
10547
+ type: "boolean",
10548
+ description: "Persist publicInboundCheck.lastCheckedAt after an ok check",
10549
+ default: false
10550
+ }
10551
+ },
10552
+ async run({ args }) {
10553
+ const result = await checkPublicInbound(args.cwd, {
10554
+ offline: Boolean(args.offline),
10555
+ respectPrefs: Boolean(args["respect-prefs"]),
10556
+ stamp: Boolean(args.stamp)
10557
+ });
10558
+ if (args.json) {
10559
+ console.log(JSON.stringify(result, null, 2));
10560
+ } else {
10561
+ const line = `[${result.status}] ${result.message}`;
10562
+ if (result.status === "error") logger.error(line);
10563
+ else if (result.status.startsWith("skipped-")) logger.warn(line);
10564
+ else logger.info(line);
10565
+ for (const item of result.items.slice(0, 20)) {
10566
+ logger.info(`- ${item.class} ${item.cite}: ${item.title} (@${item.author})`);
10567
+ }
10568
+ if (result.items.length > 20) {
10569
+ logger.info(`\u2026 and ${result.items.length - 20} more (use --json)`);
10570
+ }
10571
+ }
10572
+ if (result.status === "error") process.exitCode = 2;
10573
+ }
10574
+ });
10575
+
10576
+ // src/commands/run-plan.ts
10577
+ import path52 from "path";
10578
+ import { defineCommand as defineCommand17 } from "citty";
10177
10579
 
10178
10580
  // src/plan-loop/backends.ts
10179
10581
  import { execFileSync as execFileSync2, spawn as spawn7 } from "child_process";
10180
10582
  import { createWriteStream } from "fs";
10181
- import { access as access8 } from "fs/promises";
10182
- import path45 from "path";
10583
+ import { access as access9 } from "fs/promises";
10584
+ import path46 from "path";
10183
10585
  import { StringDecoder as StringDecoder3 } from "string_decoder";
10184
10586
 
10185
10587
  // src/plan-loop/hitl-relay.ts
@@ -11319,9 +11721,9 @@ function claudeHeadlessArgs(opts = {}) {
11319
11721
  async function missingClaudeAdapter(workspace, prompt) {
11320
11722
  const m = /^\/([A-Za-z0-9][A-Za-z0-9_-]*)/.exec(prompt.trimStart());
11321
11723
  if (!m?.[1]) return null;
11322
- const rel = path45.join(".claude", "commands", `${m[1]}.md`);
11724
+ const rel = path46.join(".claude", "commands", `${m[1]}.md`);
11323
11725
  try {
11324
- await access8(path45.join(workspace, rel));
11726
+ await access9(path46.join(workspace, rel));
11325
11727
  return null;
11326
11728
  } catch {
11327
11729
  return rel;
@@ -11444,15 +11846,15 @@ async function detectAgentBackend(requested, whichFn = whichBinary) {
11444
11846
 
11445
11847
  // src/plan-loop/run-loop.ts
11446
11848
  import { mkdir as mkdir6, readFile as readFile27, rm as rm2, unlink as unlink2 } from "fs/promises";
11447
- import path50 from "path";
11849
+ import path51 from "path";
11448
11850
 
11449
11851
  // src/mission-control/live-run.ts
11450
11852
  import { readFile as readFile25 } from "fs/promises";
11451
- import path47 from "path";
11853
+ import path48 from "path";
11452
11854
 
11453
11855
  // src/plan-loop/plan-state.ts
11454
11856
  import { readFile as readFile24, readdir as readdir11 } from "fs/promises";
11455
- import path46 from "path";
11857
+ import path47 from "path";
11456
11858
  function countPendingTodos(raw) {
11457
11859
  const lines = raw.split(/\r?\n/);
11458
11860
  let inFront = 0;
@@ -11480,7 +11882,7 @@ function countPendingTodos(raw) {
11480
11882
  async function findActivePlanFile(plansDir) {
11481
11883
  if (!await fileExists(plansDir)) return null;
11482
11884
  const files = (await readdir11(plansDir)).filter((f) => f.endsWith(".plan.md")).sort();
11483
- return files[0] ? path46.join(plansDir, files[0]) : null;
11885
+ return files[0] ? path47.join(plansDir, files[0]) : null;
11484
11886
  }
11485
11887
  async function readPlan(planPath) {
11486
11888
  return readFile24(planPath, "utf8");
@@ -11668,7 +12070,7 @@ function firstWord(raw) {
11668
12070
  }
11669
12071
  async function readLiveMission(root, io = defaultMissionIo()) {
11670
12072
  const mission = emptyLiveMission();
11671
- const handoff = await io.readFile(path47.join(root, ".cursor", "HANDOFF.md")) ?? "";
12073
+ const handoff = await io.readFile(path48.join(root, ".cursor", "HANDOFF.md")) ?? "";
11672
12074
  const named = extractHandoffNamedPlans(handoff);
11673
12075
  mission.mode = firstWord(MODE_RE.exec(handoff)?.[1]);
11674
12076
  let cursorIndex = null;
@@ -11704,13 +12106,13 @@ async function readLiveMission(root, io = defaultMissionIo()) {
11704
12106
  state: finished || cursor !== null && i < cursor ? "done" : i === cursor ? "current" : "pending"
11705
12107
  }));
11706
12108
  }
11707
- const plansDir = path47.join(root, ".cursor", "plans");
12109
+ const plansDir = path48.join(root, ".cursor", "plans");
11708
12110
  const planBase = (mission.queue && !finished ? mission.queue.current : null) ?? named.active;
11709
- const planPath = planBase ? path47.join(plansDir, planBase) : await io.findActivePlan(plansDir);
12111
+ const planPath = planBase ? path48.join(plansDir, planBase) : await io.findActivePlan(plansDir);
11710
12112
  if (planPath) {
11711
12113
  const raw = await io.readFile(planPath);
11712
12114
  if (raw !== null) {
11713
- mission.planFile = path47.basename(planPath);
12115
+ mission.planFile = path48.basename(planPath);
11714
12116
  const { todos } = parsePlanFrontmatter2(raw);
11715
12117
  const open = todos.filter((t) => t.status !== "cancelled");
11716
12118
  mission.todos = {
@@ -11761,7 +12163,7 @@ async function withLiveTui(opts, run) {
11761
12163
  columns,
11762
12164
  now: now2,
11763
12165
  backend: opts.backend,
11764
- logPath: path47.relative(opts.root, opts.logPath) || opts.logPath
12166
+ logPath: path48.relative(opts.root, opts.logPath) || opts.logPath
11765
12167
  });
11766
12168
  opts.onFeed?.(feed);
11767
12169
  const missionLoader = opts.missionLoader ?? createLiveMissionLoader(opts.root, { now: now2 });
@@ -11898,9 +12300,9 @@ async function withLiveTui(opts, run) {
11898
12300
 
11899
12301
  // src/plan-loop/external-review.ts
11900
12302
  import { spawn as spawn8 } from "child_process";
11901
- import path48 from "path";
11902
- var CANONICAL_REL = path48.join(".cursor", "scripts", "plan-external-review.sh");
11903
- var FALLBACK_REL = path48.join("scripts", "plan-external-review.sh");
12303
+ import path49 from "path";
12304
+ var CANONICAL_REL = path49.join(".cursor", "scripts", "plan-external-review.sh");
12305
+ var FALLBACK_REL = path49.join("scripts", "plan-external-review.sh");
11904
12306
  function isPlanExhaustedReason(reason) {
11905
12307
  const r = reason.trim().toLowerCase();
11906
12308
  if (!r) return false;
@@ -11922,8 +12324,8 @@ async function armExternalPlanReview(root, options = {}) {
11922
12324
  const existsFn = options.existsFn ?? fileExists;
11923
12325
  const log = options.log ?? ((line) => console.log(line));
11924
12326
  const force = options.force === true;
11925
- const canonicalPath = path48.join(root, CANONICAL_REL);
11926
- const fallbackPath = path48.join(root, FALLBACK_REL);
12327
+ const canonicalPath = path49.join(root, CANONICAL_REL);
12328
+ const fallbackPath = path49.join(root, FALLBACK_REL);
11927
12329
  let scriptPath = null;
11928
12330
  let scriptRel = CANONICAL_REL;
11929
12331
  if (await existsFn(canonicalPath)) {
@@ -11976,7 +12378,7 @@ async function armExternalPlanReview(root, options = {}) {
11976
12378
  }
11977
12379
 
11978
12380
  // src/plan-loop/persona-banners.ts
11979
- import path49 from "path";
12381
+ import path50 from "path";
11980
12382
  import {
11981
12383
  blue,
11982
12384
  cyan as cyan4,
@@ -12012,7 +12414,7 @@ function resolveColor(name, fallback) {
12012
12414
  async function resolveCliPersonaId(root) {
12013
12415
  try {
12014
12416
  const cfg = await readJson(
12015
- path49.join(root, ".cursor", "context", "config.json")
12417
+ path50.join(root, ".cursor", "context", "config.json")
12016
12418
  );
12017
12419
  const modes = cfg?.agentPersona?.modes ?? cfg?.workspaceSkin?.modes;
12018
12420
  const id = modes?.[CLI_RUN_PLAN_MODE];
@@ -12023,7 +12425,7 @@ async function resolveCliPersonaId(root) {
12023
12425
  }
12024
12426
  async function loadPersonaPack(root, personaId) {
12025
12427
  try {
12026
- const personaPath = path49.join(root, "registry", "personas", "core", personaId, "persona.json");
12428
+ const personaPath = path50.join(root, "registry", "personas", "core", personaId, "persona.json");
12027
12429
  const pack = await readJson(personaPath);
12028
12430
  if (!pack || typeof pack.id !== "string") return null;
12029
12431
  return pack;
@@ -12202,9 +12604,9 @@ function sleep(ms) {
12202
12604
  return new Promise((r) => setTimeout(r, ms));
12203
12605
  }
12204
12606
  async function runPlanLoop(opts) {
12205
- const plansDir = path50.join(opts.root, ".cursor", "plans");
12206
- const stopFile = path50.join(opts.root, ".cursor", "loop.stop");
12207
- const logDir = path50.join(opts.root, ".cursor", "loop-logs");
12607
+ const plansDir = path51.join(opts.root, ".cursor", "plans");
12608
+ const stopFile = path51.join(opts.root, ".cursor", "loop.stop");
12609
+ const logDir = path51.join(opts.root, ".cursor", "loop-logs");
12208
12610
  const planPath = await findActivePlanFile(plansDir);
12209
12611
  if (!planPath) {
12210
12612
  logger.error("No active plan in .cursor/plans/");
@@ -12225,7 +12627,7 @@ async function runPlanLoop(opts) {
12225
12627
  try {
12226
12628
  const persona = await loadCliRunPlanPersona(opts.root);
12227
12629
  const banners = createPersonaBannerPrinter(persona);
12228
- console.log(`Active plan: ${path50.basename(planPath)}`);
12630
+ console.log(`Active plan: ${path51.basename(planPath)}`);
12229
12631
  console.log(`Pending to-dos: ${await pending()} | max ticks: ${opts.maxTicks}`);
12230
12632
  console.log(`Backend: ${opts.backend.id}`);
12231
12633
  if (persona) {
@@ -12269,8 +12671,8 @@ async function runPlanLoop(opts) {
12269
12671
  planExhausted = true;
12270
12672
  break;
12271
12673
  }
12272
- const logPath = path50.join(logDir, `tick-${stamp()}.log`);
12273
- const relLog = path50.relative(opts.root, logPath);
12674
+ const logPath = path51.join(logDir, `tick-${stamp()}.log`);
12675
+ const relLog = path51.relative(opts.root, logPath);
12274
12676
  console.log("");
12275
12677
  const tickLine = `=== tick ${tick}/${opts.maxTicks} - pending: ${before} - log: ${relLog} ===`;
12276
12678
  if (banners) banners.tickStart(tickLine);
@@ -12378,7 +12780,7 @@ async function runPlanLoop(opts) {
12378
12780
  const finishDetail = `after ${tick} tick(s); pending: ${pendingNow}`;
12379
12781
  if (banners) banners.phaseComplete(finishDetail);
12380
12782
  console.log(
12381
- `Loop finished after ${tick} tick(s). Pending now: ${pendingNow}. Logs in ${path50.relative(opts.root, logDir)}/`
12783
+ `Loop finished after ${tick} tick(s). Pending now: ${pendingNow}. Logs in ${path51.relative(opts.root, logDir)}/`
12382
12784
  );
12383
12785
  if (planExhausted || shouldArmExternalPlanReview({ pending: pendingNow, stopReason })) {
12384
12786
  await armExternalPlanReview(opts.root);
@@ -12390,7 +12792,7 @@ async function runPlanLoop(opts) {
12390
12792
  }
12391
12793
 
12392
12794
  // src/commands/run-plan.ts
12393
- var runPlanCommand = defineCommand16({
12795
+ var runPlanCommand = defineCommand17({
12394
12796
  meta: {
12395
12797
  name: "run-plan",
12396
12798
  description: "Headless continuous plan runner (one fresh agent per tick). Never git-prod."
@@ -12470,7 +12872,7 @@ var runPlanCommand = defineCommand16({
12470
12872
  return;
12471
12873
  }
12472
12874
  const code = await runPlanLoop({
12473
- root: path51.resolve(args.cwd),
12875
+ root: path52.resolve(args.cwd),
12474
12876
  maxTicks,
12475
12877
  sleepSeconds,
12476
12878
  model: args.model ? String(args.model) : void 0,
@@ -12485,12 +12887,12 @@ var runPlanCommand = defineCommand16({
12485
12887
 
12486
12888
  // src/commands/run.ts
12487
12889
  import { homedir as homedir4 } from "os";
12488
- import path53 from "path";
12489
- import { defineCommand as defineCommand17 } from "citty";
12890
+ import path54 from "path";
12891
+ import { defineCommand as defineCommand18 } from "citty";
12490
12892
 
12491
12893
  // src/plan-loop/dispatch.ts
12492
12894
  import { mkdir as mkdir7, readFile as readFile28 } from "fs/promises";
12493
- import path52 from "path";
12895
+ import path53 from "path";
12494
12896
  var RUN_CATALOG = [
12495
12897
  "run-plan",
12496
12898
  "run-plan-all",
@@ -12533,7 +12935,7 @@ function rewriteRootArgvToRun(argv) {
12533
12935
  return next;
12534
12936
  }
12535
12937
  function commandMarkdownPath(root, name) {
12536
- return path52.join(root, ".cursor", "commands", `${normalizeSlashName(name)}.md`);
12938
+ return path53.join(root, ".cursor", "commands", `${normalizeSlashName(name)}.md`);
12537
12939
  }
12538
12940
  function buildDispatchPrompt(commandBody) {
12539
12941
  return [
@@ -12621,20 +13023,20 @@ async function runHeadlessDispatch(opts) {
12621
13023
  });
12622
13024
  }
12623
13025
  async function ensureDispatchLogPath(root) {
12624
- const logDir = path52.join(root, ".cursor", "loop-logs");
13026
+ const logDir = path53.join(root, ".cursor", "loop-logs");
12625
13027
  await mkdir7(logDir, { recursive: true });
12626
- return path52.join(logDir, `run-${stamp2()}.log`);
13028
+ return path53.join(logDir, `run-${stamp2()}.log`);
12627
13029
  }
12628
13030
 
12629
13031
  // src/commands/run.ts
12630
13032
  function displayPath(target, home = homedir4()) {
12631
- const resolvedHome = path53.resolve(home);
13033
+ const resolvedHome = path54.resolve(home);
12632
13034
  if (target === resolvedHome) return "~";
12633
- const prefix = resolvedHome.endsWith(path53.sep) ? resolvedHome : `${resolvedHome}${path53.sep}`;
12634
- return target.startsWith(prefix) ? `~${path53.sep}${target.slice(prefix.length)}` : target;
13035
+ const prefix = resolvedHome.endsWith(path54.sep) ? resolvedHome : `${resolvedHome}${path54.sep}`;
13036
+ return target.startsWith(prefix) ? `~${path54.sep}${target.slice(prefix.length)}` : target;
12635
13037
  }
12636
13038
  async function executeRun(input) {
12637
- const root = path53.resolve(input.cwd);
13039
+ const root = path54.resolve(input.cwd);
12638
13040
  const slash = normalizeSlashName(input.slash);
12639
13041
  if (!slash) {
12640
13042
  return { exitCode: 1, error: "Provide a slash: agent-kit run <slash>" };
@@ -12685,7 +13087,7 @@ async function executeRun(input) {
12685
13087
  const stdout = [
12686
13088
  "--dry-run: no agent will be started.",
12687
13089
  `Slash: ${slash}`,
12688
- `Command file: ${path53.relative(root, file.path)}`,
13090
+ `Command file: ${path54.relative(root, file.path)}`,
12689
13091
  `Backend: ${detected.id} (${displayPath(detected.bin)})`,
12690
13092
  "Prompt:",
12691
13093
  prompt
@@ -12694,8 +13096,8 @@ async function executeRun(input) {
12694
13096
  }
12695
13097
  const logPath = await ensureDispatchLogPath(root);
12696
13098
  console.log(`Dispatch: ${slash} via ${detected.id}`);
12697
- console.log(`Command file: ${path53.relative(root, file.path)}`);
12698
- console.log(`Log: ${path53.relative(root, logPath)}`);
13099
+ console.log(`Command file: ${path54.relative(root, file.path)}`);
13100
+ console.log(`Log: ${path54.relative(root, logPath)}`);
12699
13101
  try {
12700
13102
  const dispatch = {
12701
13103
  backendId: detected.id,
@@ -12798,7 +13200,7 @@ async function runSlashCli(slash, args) {
12798
13200
  }
12799
13201
  process.exitCode = result.exitCode;
12800
13202
  }
12801
- var runCommand = defineCommand17({
13203
+ var runCommand = defineCommand18({
12802
13204
  meta: {
12803
13205
  name: "run",
12804
13206
  description: "Start one headless session from an L0 slash file. Numbered-list HITL answered from the terminal (claude backend). Never git-prod."
@@ -12815,7 +13217,7 @@ var runCommand = defineCommand17({
12815
13217
  await runSlashCli(String(args.slash ?? ""), args);
12816
13218
  }
12817
13219
  });
12818
- var runPlanAllCommand = defineCommand17({
13220
+ var runPlanAllCommand = defineCommand18({
12819
13221
  meta: {
12820
13222
  name: "run-plan-all",
12821
13223
  description: "Headless /run-plan-all queue from the L0 file. Numbered-list HITL answered from the terminal (claude backend). Never git-prod."
@@ -12827,8 +13229,8 @@ var runPlanAllCommand = defineCommand17({
12827
13229
  });
12828
13230
 
12829
13231
  // src/commands/scan.ts
12830
- import { defineCommand as defineCommand18 } from "citty";
12831
- var scanCommand = defineCommand18({
13232
+ import { defineCommand as defineCommand19 } from "citty";
13233
+ var scanCommand = defineCommand19({
12832
13234
  meta: {
12833
13235
  name: "scan",
12834
13236
  description: "Scan the repository and print the detected profile."
@@ -12852,18 +13254,18 @@ var scanCommand = defineCommand18({
12852
13254
  import { spawn as spawn9 } from "child_process";
12853
13255
  import { appendFile as appendFile2, mkdir as mkdir8, readFile as readFile29, writeFile as writeFile13 } from "fs/promises";
12854
13256
  import { homedir as homedir5 } from "os";
12855
- import path54 from "path";
13257
+ import path55 from "path";
12856
13258
  import { confirm as confirm2, isCancel as isCancel2 } from "@clack/prompts";
12857
- import { defineCommand as defineCommand19 } from "citty";
13259
+ import { defineCommand as defineCommand20 } from "citty";
12858
13260
  import { cyan as cyan5, green as green4, yellow as yellow3 } from "kolorist";
12859
13261
  var NPM_GLOBAL_DIR_NAME = ".npm-global";
12860
13262
  var SETUP_GLOBAL_MARKER = "# agent-kit setup-global";
12861
13263
  function planSetupGlobalSteps(env, options = {}) {
12862
13264
  const homeDir = options.homeDir ?? homedir5();
12863
13265
  const packageSpec = options.packageSpec ?? pinnedCliSpec();
12864
- const npmGlobalDir = path54.join(homeDir, NPM_GLOBAL_DIR_NAME);
12865
- const npmGlobalBin = path54.join(npmGlobalDir, "bin");
12866
- const npmrcPath = path54.join(homeDir, ".npmrc");
13266
+ const npmGlobalDir = path55.join(homeDir, NPM_GLOBAL_DIR_NAME);
13267
+ const npmGlobalBin = path55.join(npmGlobalDir, "bin");
13268
+ const npmrcPath = path55.join(homeDir, ".npmrc");
12867
13269
  const npmrcPrefixValue = `~/${NPM_GLOBAL_DIR_NAME}`;
12868
13270
  const pathExportLine = `export PATH="${npmGlobalBin}:$PATH"`;
12869
13271
  const shellProfile = env.shellProfile;
@@ -13133,7 +13535,7 @@ ${verifyStep.title}`);
13133
13535
  }
13134
13536
  return { exitCode: 0, mutated, outcome: "completed", env, plan };
13135
13537
  }
13136
- var setupGlobalCommand = defineCommand19({
13538
+ var setupGlobalCommand = defineCommand20({
13137
13539
  meta: {
13138
13540
  name: "setup-global",
13139
13541
  description: "Self-heal a root-owned npm prefix: relocate to ~/.npm-global, fix PATH, reinstall globally."
@@ -13162,8 +13564,8 @@ var setupGlobalCommand = defineCommand19({
13162
13564
  });
13163
13565
 
13164
13566
  // src/commands/status.ts
13165
- import path55 from "path";
13166
- import { defineCommand as defineCommand20 } from "citty";
13567
+ import path56 from "path";
13568
+ import { defineCommand as defineCommand21 } from "citty";
13167
13569
  function profileStatus(profile) {
13168
13570
  if (!profile) return { origin: "none", evidence: [], profile: null };
13169
13571
  if ("detection" in profile && profile.detection && typeof profile.detection === "object") {
@@ -13176,7 +13578,7 @@ function profileStatus(profile) {
13176
13578
  }
13177
13579
  return { origin: "legacy-wizard", evidence: [], profile };
13178
13580
  }
13179
- var statusCommand = defineCommand20({
13581
+ var statusCommand = defineCommand21({
13180
13582
  meta: {
13181
13583
  name: "status",
13182
13584
  description: "Show installed kit version, manifest, and optional profile."
@@ -13193,11 +13595,11 @@ var statusCommand = defineCommand20({
13193
13595
  }
13194
13596
  },
13195
13597
  async run({ args }) {
13196
- const rootDir = path55.resolve(args.cwd);
13598
+ const rootDir = path56.resolve(args.cwd);
13197
13599
  const [manifest, rawProfile, scan, env] = await Promise.all([
13198
13600
  loadAgentKitManifest(rootDir),
13199
13601
  readJson(
13200
- path55.join(rootDir, ".cursor", "agent-kit.config.json")
13602
+ path56.join(rootDir, ".cursor", "agent-kit.config.json")
13201
13603
  ),
13202
13604
  runScanner(rootDir),
13203
13605
  assessEnvironment()
@@ -13264,8 +13666,8 @@ var statusCommand = defineCommand20({
13264
13666
  });
13265
13667
 
13266
13668
  // src/commands/update.ts
13267
- import { defineCommand as defineCommand21 } from "citty";
13268
- var updateCommand = defineCommand21({
13669
+ import { defineCommand as defineCommand22 } from "citty";
13670
+ var updateCommand = defineCommand22({
13269
13671
  meta: {
13270
13672
  name: "update",
13271
13673
  description: "Re-apply L0/packs/skills from the registry (never overwrites L3). --check = notify-only."
@@ -13433,8 +13835,8 @@ ${err.recovery}
13433
13835
 
13434
13836
  // src/commands/validate.ts
13435
13837
  import { readFile as readFile30 } from "fs/promises";
13436
- import path56 from "path";
13437
- import { defineCommand as defineCommand22 } from "citty";
13838
+ import path57 from "path";
13839
+ import { defineCommand as defineCommand23 } from "citty";
13438
13840
 
13439
13841
  // src/invariants/plan-schema.ts
13440
13842
  var CITE5 = "agent-kit validate plan (.cursor/context/templates/plan.md)";
@@ -13480,7 +13882,7 @@ function validatePlanFrontmatterText(text) {
13480
13882
  // src/commands/validate.ts
13481
13883
  async function resolveEditedPath(cwd, explicit) {
13482
13884
  if (explicit) {
13483
- const filePath2 = path56.resolve(cwd, explicit);
13885
+ const filePath2 = path57.resolve(cwd, explicit);
13484
13886
  try {
13485
13887
  return { filePath: filePath2, content: await readFile30(filePath2, "utf8") };
13486
13888
  } catch {
@@ -13490,7 +13892,7 @@ async function resolveEditedPath(cwd, explicit) {
13490
13892
  const payload = await readStdinJson();
13491
13893
  const rel = typeof payload.file_path === "string" && payload.file_path || typeof payload.path === "string" && payload.path || typeof payload.file === "string" && payload.file || "";
13492
13894
  if (!rel) return null;
13493
- const filePath = path56.isAbsolute(rel) ? rel : path56.resolve(cwd, rel);
13895
+ const filePath = path57.isAbsolute(rel) ? rel : path57.resolve(cwd, rel);
13494
13896
  try {
13495
13897
  return { filePath, content: await readFile30(filePath, "utf8") };
13496
13898
  } catch {
@@ -13504,13 +13906,13 @@ function isPlanPath(filePath) {
13504
13906
  const norm = filePath.replace(/\\/g, "/");
13505
13907
  return norm.includes("/.cursor/plans/") && norm.endsWith(".plan.md");
13506
13908
  }
13507
- var validateCommand = defineCommand22({
13909
+ var validateCommand = defineCommand23({
13508
13910
  meta: {
13509
13911
  name: "validate",
13510
13912
  description: "Advisory validators for HANDOFF / plan frontmatter (hook adapter)."
13511
13913
  },
13512
13914
  subCommands: {
13513
- handoff: defineCommand22({
13915
+ handoff: defineCommand23({
13514
13916
  meta: { name: "handoff", description: "Validate HANDOFF machine fields" },
13515
13917
  args: {
13516
13918
  cwd: { type: "string", default: process.cwd() },
@@ -13520,7 +13922,7 @@ var validateCommand = defineCommand22({
13520
13922
  async run({ args }) {
13521
13923
  const cwd = typeof args.cwd === "string" ? args.cwd : process.cwd();
13522
13924
  const fileArg = typeof args.file === "string" ? args.file : void 0;
13523
- const filePath = fileArg ? path56.resolve(cwd, fileArg) : path56.join(path56.resolve(cwd), ".cursor", "HANDOFF.md");
13925
+ const filePath = fileArg ? path57.resolve(cwd, fileArg) : path57.join(path57.resolve(cwd), ".cursor", "HANDOFF.md");
13524
13926
  let content = "";
13525
13927
  try {
13526
13928
  content = await readFile30(filePath, "utf8");
@@ -13538,7 +13940,7 @@ var validateCommand = defineCommand22({
13538
13940
  console.log(JSON.stringify({ ok: warnings.length === 0, warnings }));
13539
13941
  }
13540
13942
  }),
13541
- plan: defineCommand22({
13943
+ plan: defineCommand23({
13542
13944
  meta: { name: "plan", description: "Validate plan frontmatter" },
13543
13945
  args: {
13544
13946
  cwd: { type: "string", default: process.cwd() },
@@ -13553,7 +13955,7 @@ var validateCommand = defineCommand22({
13553
13955
  process.exitCode = 2;
13554
13956
  return;
13555
13957
  }
13556
- const filePath = path56.resolve(cwd, fileArg);
13958
+ const filePath = path57.resolve(cwd, fileArg);
13557
13959
  let content = "";
13558
13960
  try {
13559
13961
  content = await readFile30(filePath, "utf8");
@@ -13565,7 +13967,7 @@ var validateCommand = defineCommand22({
13565
13967
  console.log(JSON.stringify({ ok: warnings.length === 0, warnings }));
13566
13968
  }
13567
13969
  }),
13568
- "after-edit": defineCommand22({
13970
+ "after-edit": defineCommand23({
13569
13971
  meta: {
13570
13972
  name: "after-edit",
13571
13973
  description: "Advisory afterFileEdit: annotate HANDOFF/plan issues (never block)"
@@ -13575,7 +13977,7 @@ var validateCommand = defineCommand22({
13575
13977
  },
13576
13978
  async run({ args }) {
13577
13979
  const cwd = typeof args.cwd === "string" ? args.cwd : process.cwd();
13578
- const resolved = await resolveEditedPath(path56.resolve(cwd));
13980
+ const resolved = await resolveEditedPath(path57.resolve(cwd));
13579
13981
  if (!resolved) {
13580
13982
  console.log(JSON.stringify({}));
13581
13983
  return;
@@ -13726,7 +14128,15 @@ var CLI_HELP_GROUPS = [
13726
14128
  {
13727
14129
  id: "integrity",
13728
14130
  title: "INTEGRITY",
13729
- commands: ["validate", "guard", "hook", "cursor-awareness", "diff", "contribute"]
14131
+ commands: [
14132
+ "validate",
14133
+ "guard",
14134
+ "hook",
14135
+ "cursor-awareness",
14136
+ "public-inbound-radar",
14137
+ "diff",
14138
+ "contribute"
14139
+ ]
13730
14140
  }
13731
14141
  ];
13732
14142
  async function resolveCommandMeta(meta) {
@@ -13794,7 +14204,7 @@ async function renderGroupedRootHelp(cmd) {
13794
14204
  var rewrittenArgv = rewriteRootArgvToRun(process.argv.slice(2));
13795
14205
  process.argv.length = 2;
13796
14206
  process.argv.push(...rewrittenArgv);
13797
- var main = defineCommand23({
14207
+ var main = defineCommand24({
13798
14208
  meta: {
13799
14209
  name: "agent-kit",
13800
14210
  description: "HITL framework for AI-assisted IDEs (Mission Kit family)",
@@ -13810,6 +14220,7 @@ var main = defineCommand23({
13810
14220
  status: statusCommand,
13811
14221
  update: updateCommand,
13812
14222
  "cursor-awareness": cursorAwarenessCommand,
14223
+ "public-inbound-radar": publicInboundRadarCommand,
13813
14224
  diff: diffCommand,
13814
14225
  contribute: contributeCommand,
13815
14226
  handoff: handoffCommand,