@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.
- package/dist/index.js +571 -160
- 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
|
|
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`
|
|
1746
|
-
//
|
|
1747
|
-
//
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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 =
|
|
7126
|
+
const safe = path31.basename(basename);
|
|
6880
7127
|
if (!/^[A-Za-z0-9._-]+\.plan\.md$/i.test(safe)) return [];
|
|
6881
7128
|
return [
|
|
6882
|
-
|
|
6883
|
-
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
7349
|
-
|
|
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 ?
|
|
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 =
|
|
7625
|
-
const handoffPath =
|
|
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,
|
|
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
|
|
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
|
|
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(
|
|
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 =
|
|
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(
|
|
7790
|
-
const hasManifest = await fileExists(
|
|
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 =
|
|
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 =
|
|
7938
|
-
const root =
|
|
7939
|
-
return bin === root || bin.startsWith(`${root}${
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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(
|
|
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 =
|
|
8448
|
+
const relPath = path36.posix.join(CLAUDE_COMMANDS_DIR_REL, `${command.name}.md`);
|
|
8104
8449
|
const rendered = renderClaudeCommandAdapter(command);
|
|
8105
|
-
const abs =
|
|
8450
|
+
const abs = path36.join(rootDir, relPath);
|
|
8106
8451
|
if (!await fileExists(abs)) {
|
|
8107
|
-
await ensureDir(
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
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 =
|
|
8236
|
-
const githubDir =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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(
|
|
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 =
|
|
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(
|
|
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(
|
|
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 =
|
|
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
|
|
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 =
|
|
9071
|
+
const legacyPath = path40.join(projectRoot, LEGACY_ONBOARD_PATH);
|
|
8727
9072
|
if (!await fileExists(legacyPath)) return "absent";
|
|
8728
|
-
const namespacedPath =
|
|
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 =
|
|
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
|
|
9585
|
-
import { access as
|
|
9586
|
-
import
|
|
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
|
|
9619
|
-
return
|
|
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 =
|
|
9973
|
+
const sibling = path42.join(path42.dirname(startPath), "dashboard-data.mjs");
|
|
9629
9974
|
try {
|
|
9630
|
-
await
|
|
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 ??
|
|
9643
|
-
const 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
|
|
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
|
|
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
|
|
9973
|
-
import { promisify as
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
10037
|
-
const memoryDir =
|
|
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 =
|
|
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(
|
|
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:
|
|
10078
|
-
relativePath:
|
|
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(
|
|
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
|
|
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 =
|
|
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/
|
|
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
|
|
10182
|
-
import
|
|
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 =
|
|
11724
|
+
const rel = path46.join(".claude", "commands", `${m[1]}.md`);
|
|
11323
11725
|
try {
|
|
11324
|
-
await
|
|
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
|
|
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
|
|
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
|
|
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] ?
|
|
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(
|
|
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 =
|
|
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 ?
|
|
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 =
|
|
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:
|
|
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
|
|
11902
|
-
var CANONICAL_REL =
|
|
11903
|
-
var FALLBACK_REL =
|
|
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 =
|
|
11926
|
-
const fallbackPath =
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
12206
|
-
const stopFile =
|
|
12207
|
-
const logDir =
|
|
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: ${
|
|
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 =
|
|
12273
|
-
const relLog =
|
|
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 ${
|
|
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 =
|
|
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:
|
|
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
|
|
12489
|
-
import { defineCommand as
|
|
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
|
|
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
|
|
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 =
|
|
13026
|
+
const logDir = path53.join(root, ".cursor", "loop-logs");
|
|
12625
13027
|
await mkdir7(logDir, { recursive: true });
|
|
12626
|
-
return
|
|
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 =
|
|
13033
|
+
const resolvedHome = path54.resolve(home);
|
|
12632
13034
|
if (target === resolvedHome) return "~";
|
|
12633
|
-
const prefix = resolvedHome.endsWith(
|
|
12634
|
-
return target.startsWith(prefix) ? `~${
|
|
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 =
|
|
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: ${
|
|
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: ${
|
|
12698
|
-
console.log(`Log: ${
|
|
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 =
|
|
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 =
|
|
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
|
|
12831
|
-
var scanCommand =
|
|
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
|
|
13257
|
+
import path55 from "path";
|
|
12856
13258
|
import { confirm as confirm2, isCancel as isCancel2 } from "@clack/prompts";
|
|
12857
|
-
import { defineCommand as
|
|
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 =
|
|
12865
|
-
const npmGlobalBin =
|
|
12866
|
-
const npmrcPath =
|
|
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 =
|
|
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
|
|
13166
|
-
import { defineCommand as
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
|
13268
|
-
var updateCommand =
|
|
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
|
|
13437
|
-
import { defineCommand as
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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:
|
|
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 ?
|
|
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:
|
|
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 =
|
|
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":
|
|
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(
|
|
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: [
|
|
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 =
|
|
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,
|