@dadado/agent-kit-cli 5.13.4 → 5.14.0
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 +565 -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,10 @@ 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"
|
|
359
362
|
]);
|
|
360
363
|
|
|
361
364
|
// src/lifecycle/paths.ts
|
|
@@ -1742,9 +1745,11 @@ var L0_ARTIFACTS = [
|
|
|
1742
1745
|
source: ".cursor/commands/dogfood.md",
|
|
1743
1746
|
target: ".cursor/commands/dogfood.md"
|
|
1744
1747
|
},
|
|
1745
|
-
// Factory-only: `.cursor/commands/public-issue-triage.md`
|
|
1746
|
-
//
|
|
1747
|
-
//
|
|
1748
|
+
// Factory-only: `.cursor/commands/public-issue-triage.md` and
|
|
1749
|
+
// `.cursor/commands/public-inbound-radar.md` are intentionally omitted from
|
|
1750
|
+
// L0 (and excluded from public-sync). See ADRs
|
|
1751
|
+
// 2026-08-05_factory-only-public-issue-triage-command.md and
|
|
1752
|
+
// 2026-09-24_public-inbound-radar.md.
|
|
1748
1753
|
{
|
|
1749
1754
|
source: ".cursor/commands/cursor-update-awareness.md",
|
|
1750
1755
|
target: ".cursor/commands/cursor-update-awareness.md"
|
|
@@ -6766,7 +6771,7 @@ var handoffCommand = defineCommand9({
|
|
|
6766
6771
|
});
|
|
6767
6772
|
|
|
6768
6773
|
// src/commands/hook.ts
|
|
6769
|
-
import
|
|
6774
|
+
import path33 from "path";
|
|
6770
6775
|
import { defineCommand as defineCommand10 } from "citty";
|
|
6771
6776
|
|
|
6772
6777
|
// src/hooks/format-session-start.ts
|
|
@@ -6793,7 +6798,7 @@ function buildPreCompactUserMessage(payload = {}) {
|
|
|
6793
6798
|
// src/hooks/session-start.ts
|
|
6794
6799
|
import { spawn as spawn5 } from "child_process";
|
|
6795
6800
|
import { readFile as readFile19, stat as stat4 } from "fs/promises";
|
|
6796
|
-
import
|
|
6801
|
+
import path32 from "path";
|
|
6797
6802
|
|
|
6798
6803
|
// src/invariants/handoff-schema.ts
|
|
6799
6804
|
var MACHINE_LIST_CHECKS = [
|
|
@@ -6834,9 +6839,245 @@ function validateHandoffText(text) {
|
|
|
6834
6839
|
return warnings;
|
|
6835
6840
|
}
|
|
6836
6841
|
|
|
6842
|
+
// src/lifecycle/public-inbound-radar.ts
|
|
6843
|
+
import { execFile as execFile6 } from "child_process";
|
|
6844
|
+
import { access as access7 } from "fs/promises";
|
|
6845
|
+
import path30 from "path";
|
|
6846
|
+
import { promisify as promisify6 } from "util";
|
|
6847
|
+
var execFileAsync5 = promisify6(execFile6);
|
|
6848
|
+
var PUBLIC_INBOUND_REPO = "agent-kit-startup/agent-kit";
|
|
6849
|
+
var DEFAULT_PREFS2 = {
|
|
6850
|
+
enabled: false,
|
|
6851
|
+
intervalDays: 7,
|
|
6852
|
+
lastCheckedAt: null
|
|
6853
|
+
};
|
|
6854
|
+
function emptySummary() {
|
|
6855
|
+
return { issues: 0, humanPullRequests: 0, dependabotPullRequests: 0, total: 0 };
|
|
6856
|
+
}
|
|
6857
|
+
function summarize(items) {
|
|
6858
|
+
const summary = emptySummary();
|
|
6859
|
+
for (const item of items) {
|
|
6860
|
+
summary.total += 1;
|
|
6861
|
+
if (item.class === "issue") summary.issues += 1;
|
|
6862
|
+
else if (item.class === "dependabot") summary.dependabotPullRequests += 1;
|
|
6863
|
+
else summary.humanPullRequests += 1;
|
|
6864
|
+
}
|
|
6865
|
+
return summary;
|
|
6866
|
+
}
|
|
6867
|
+
function labelNames(labels) {
|
|
6868
|
+
if (!Array.isArray(labels)) return [];
|
|
6869
|
+
return labels.map((entry) => typeof entry === "string" ? entry : entry?.name).filter((name) => typeof name === "string" && name.length > 0);
|
|
6870
|
+
}
|
|
6871
|
+
function isDependabotAuthor(login) {
|
|
6872
|
+
if (!login) return false;
|
|
6873
|
+
const normalized = login.toLowerCase();
|
|
6874
|
+
return normalized === "dependabot" || normalized === "dependabot[bot]" || normalized === "app/dependabot" || normalized.startsWith("dependabot") || normalized === "renovate" || normalized === "renovate[bot]";
|
|
6875
|
+
}
|
|
6876
|
+
function classifyInbound(kind, authorLogin) {
|
|
6877
|
+
if (kind === "issue") return "issue";
|
|
6878
|
+
return isDependabotAuthor(authorLogin) ? "dependabot" : "human-pr";
|
|
6879
|
+
}
|
|
6880
|
+
function readPublicInboundCheckPrefs(config) {
|
|
6881
|
+
if (!config || typeof config !== "object" || Array.isArray(config)) {
|
|
6882
|
+
return { ...DEFAULT_PREFS2 };
|
|
6883
|
+
}
|
|
6884
|
+
const raw = config.publicInboundCheck;
|
|
6885
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
6886
|
+
return { ...DEFAULT_PREFS2 };
|
|
6887
|
+
}
|
|
6888
|
+
const uc = raw;
|
|
6889
|
+
const intervalDays = typeof uc.intervalDays === "number" && Number.isInteger(uc.intervalDays) && uc.intervalDays >= 1 ? uc.intervalDays : DEFAULT_PREFS2.intervalDays;
|
|
6890
|
+
return {
|
|
6891
|
+
enabled: uc.enabled === true,
|
|
6892
|
+
intervalDays,
|
|
6893
|
+
lastCheckedAt: typeof uc.lastCheckedAt === "string" ? uc.lastCheckedAt : null
|
|
6894
|
+
};
|
|
6895
|
+
}
|
|
6896
|
+
async function stampPublicInboundCheck(cwd, checkedAt) {
|
|
6897
|
+
const existing = await loadContextConfig(cwd) ?? {};
|
|
6898
|
+
const prev = existing.publicInboundCheck && typeof existing.publicInboundCheck === "object" ? { ...existing.publicInboundCheck } : {};
|
|
6899
|
+
existing.publicInboundCheck = {
|
|
6900
|
+
...DEFAULT_PREFS2,
|
|
6901
|
+
...prev,
|
|
6902
|
+
lastCheckedAt: (checkedAt ?? /* @__PURE__ */ new Date()).toISOString()
|
|
6903
|
+
};
|
|
6904
|
+
await writeJson(contextConfigPath(cwd), existing);
|
|
6905
|
+
}
|
|
6906
|
+
function mapRows(kind, rows) {
|
|
6907
|
+
const items = [];
|
|
6908
|
+
for (const row of rows) {
|
|
6909
|
+
const number = typeof row.number === "number" ? row.number : Number(row.number);
|
|
6910
|
+
if (!Number.isFinite(number) || number <= 0) continue;
|
|
6911
|
+
const author = row.author?.login?.trim() || "unknown";
|
|
6912
|
+
const title = typeof row.title === "string" && row.title.trim() ? row.title.trim() : "(no title)";
|
|
6913
|
+
const updatedAt = typeof row.updatedAt === "string" && row.updatedAt.trim() ? row.updatedAt.trim() : "";
|
|
6914
|
+
const url = typeof row.url === "string" && row.url.trim() ? row.url.trim() : `https://github.com/${PUBLIC_INBOUND_REPO}/${kind === "issue" ? "issues" : "pull"}/${number}`;
|
|
6915
|
+
items.push({
|
|
6916
|
+
kind,
|
|
6917
|
+
class: classifyInbound(kind, author),
|
|
6918
|
+
number,
|
|
6919
|
+
title,
|
|
6920
|
+
author,
|
|
6921
|
+
updatedAt,
|
|
6922
|
+
url,
|
|
6923
|
+
labels: labelNames(row.labels),
|
|
6924
|
+
cite: `${PUBLIC_INBOUND_REPO}#${number}`
|
|
6925
|
+
});
|
|
6926
|
+
}
|
|
6927
|
+
return items;
|
|
6928
|
+
}
|
|
6929
|
+
async function defaultRunGh(args, options) {
|
|
6930
|
+
const { stdout } = await execFileAsync5("gh", args, {
|
|
6931
|
+
cwd: options?.cwd,
|
|
6932
|
+
encoding: "utf8",
|
|
6933
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
6934
|
+
timeout: 3e4
|
|
6935
|
+
});
|
|
6936
|
+
return stdout;
|
|
6937
|
+
}
|
|
6938
|
+
async function ghAvailable(runGh, cwd) {
|
|
6939
|
+
try {
|
|
6940
|
+
await runGh(["--version"], { cwd });
|
|
6941
|
+
return true;
|
|
6942
|
+
} catch {
|
|
6943
|
+
return false;
|
|
6944
|
+
}
|
|
6945
|
+
}
|
|
6946
|
+
async function detectFactoryCheckout(cwd) {
|
|
6947
|
+
const root = path30.resolve(cwd);
|
|
6948
|
+
try {
|
|
6949
|
+
const { stdout } = await execFileAsync5("git", ["remote", "get-url", "origin"], {
|
|
6950
|
+
cwd: root,
|
|
6951
|
+
encoding: "utf8",
|
|
6952
|
+
timeout: 5e3
|
|
6953
|
+
});
|
|
6954
|
+
if (/agent-kit-dev/i.test(stdout)) return true;
|
|
6955
|
+
} catch {
|
|
6956
|
+
}
|
|
6957
|
+
return fileExists(path30.join(root, "dogfood", "README.md"));
|
|
6958
|
+
}
|
|
6959
|
+
async function listJson(runGh, cwd, resource) {
|
|
6960
|
+
const stdout = await runGh(
|
|
6961
|
+
[
|
|
6962
|
+
resource,
|
|
6963
|
+
"list",
|
|
6964
|
+
"--repo",
|
|
6965
|
+
PUBLIC_INBOUND_REPO,
|
|
6966
|
+
"--state",
|
|
6967
|
+
"open",
|
|
6968
|
+
"--limit",
|
|
6969
|
+
"100",
|
|
6970
|
+
"--json",
|
|
6971
|
+
"number,title,author,updatedAt,labels,url"
|
|
6972
|
+
],
|
|
6973
|
+
{ cwd }
|
|
6974
|
+
);
|
|
6975
|
+
const trimmed = stdout.trim();
|
|
6976
|
+
if (!trimmed) return [];
|
|
6977
|
+
const parsed = JSON.parse(trimmed);
|
|
6978
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
6979
|
+
}
|
|
6980
|
+
function resultBase(status, message, factory, now2, items = []) {
|
|
6981
|
+
return {
|
|
6982
|
+
status,
|
|
6983
|
+
repo: PUBLIC_INBOUND_REPO,
|
|
6984
|
+
checkedAt: now2.toISOString(),
|
|
6985
|
+
factory,
|
|
6986
|
+
items,
|
|
6987
|
+
summary: summarize(items),
|
|
6988
|
+
message,
|
|
6989
|
+
mutateRecommended: false
|
|
6990
|
+
};
|
|
6991
|
+
}
|
|
6992
|
+
async function checkPublicInbound(cwd, options = {}) {
|
|
6993
|
+
const now2 = options.now?.() ?? /* @__PURE__ */ new Date();
|
|
6994
|
+
const runGh = options.runGh ?? defaultRunGh;
|
|
6995
|
+
const isFactory = options.isFactory ?? detectFactoryCheckout;
|
|
6996
|
+
const root = path30.resolve(cwd);
|
|
6997
|
+
try {
|
|
6998
|
+
await access7(root);
|
|
6999
|
+
} catch {
|
|
7000
|
+
return resultBase("error", `cwd unreadable: ${root}`, false, now2);
|
|
7001
|
+
}
|
|
7002
|
+
const factory = await isFactory(root);
|
|
7003
|
+
if (!factory) {
|
|
7004
|
+
return resultBase(
|
|
7005
|
+
"skipped-non-factory",
|
|
7006
|
+
"Factory-only check. Aborting outside agent-kit-dev / dogfood checkout.",
|
|
7007
|
+
false,
|
|
7008
|
+
now2
|
|
7009
|
+
);
|
|
7010
|
+
}
|
|
7011
|
+
if (options.respectPrefs) {
|
|
7012
|
+
const prefs = readPublicInboundCheckPrefs(await loadContextConfig(root));
|
|
7013
|
+
if (!prefs.enabled) {
|
|
7014
|
+
return resultBase(
|
|
7015
|
+
"skipped-disabled",
|
|
7016
|
+
"publicInboundCheck.enabled is false (opt-in). Set true in .cursor/context/config.json to nudge.",
|
|
7017
|
+
true,
|
|
7018
|
+
now2
|
|
7019
|
+
);
|
|
7020
|
+
}
|
|
7021
|
+
if (!intervalElapsed(prefs.lastCheckedAt, prefs.intervalDays)) {
|
|
7022
|
+
return resultBase(
|
|
7023
|
+
"skipped-interval",
|
|
7024
|
+
`Within publicInboundCheck.intervalDays (${prefs.intervalDays}); last check ${prefs.lastCheckedAt}.`,
|
|
7025
|
+
true,
|
|
7026
|
+
now2
|
|
7027
|
+
);
|
|
7028
|
+
}
|
|
7029
|
+
}
|
|
7030
|
+
if (options.offline) {
|
|
7031
|
+
return resultBase("skipped-offline", "Offline flag set; skipped GitHub fetch.", true, now2);
|
|
7032
|
+
}
|
|
7033
|
+
if (!await ghAvailable(runGh, root)) {
|
|
7034
|
+
return resultBase(
|
|
7035
|
+
"skipped-gh-missing",
|
|
7036
|
+
"gh CLI missing or not runnable; fail-open skip.",
|
|
7037
|
+
true,
|
|
7038
|
+
now2
|
|
7039
|
+
);
|
|
7040
|
+
}
|
|
7041
|
+
try {
|
|
7042
|
+
const [issueRows, prRows] = await Promise.all([
|
|
7043
|
+
listJson(runGh, root, "issue"),
|
|
7044
|
+
listJson(runGh, root, "pr")
|
|
7045
|
+
]);
|
|
7046
|
+
const items = [...mapRows("issue", issueRows), ...mapRows("pull_request", prRows)].sort(
|
|
7047
|
+
(a, b) => b.number - a.number
|
|
7048
|
+
);
|
|
7049
|
+
const summary = summarize(items);
|
|
7050
|
+
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).`;
|
|
7051
|
+
const result = resultBase("ok", message, true, now2, items);
|
|
7052
|
+
if (options.stamp) {
|
|
7053
|
+
await stampPublicInboundCheck(root, now2);
|
|
7054
|
+
}
|
|
7055
|
+
return result;
|
|
7056
|
+
} catch (err) {
|
|
7057
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
7058
|
+
if (/ENOTFOUND|ECONNREFUSED|ETIMEDOUT|network|offline|Could not resolve/i.test(detail)) {
|
|
7059
|
+
return resultBase(
|
|
7060
|
+
"skipped-offline",
|
|
7061
|
+
`GitHub unreachable; fail-open skip (${detail}).`,
|
|
7062
|
+
true,
|
|
7063
|
+
now2
|
|
7064
|
+
);
|
|
7065
|
+
}
|
|
7066
|
+
return resultBase("error", `Public inbound check failed: ${detail}`, true, now2);
|
|
7067
|
+
}
|
|
7068
|
+
}
|
|
7069
|
+
function shouldEmitPublicInboundNudge(result) {
|
|
7070
|
+
if (!result || result.status !== "ok") return false;
|
|
7071
|
+
if (result.mutateRecommended === true) return false;
|
|
7072
|
+
const summary = result.summary;
|
|
7073
|
+
if (!summary || typeof summary !== "object") return false;
|
|
7074
|
+
const total = summary.total;
|
|
7075
|
+
return typeof total === "number" && total > 0;
|
|
7076
|
+
}
|
|
7077
|
+
|
|
6837
7078
|
// src/plan-index/plan-index.ts
|
|
6838
7079
|
import { readFile as readFile18, writeFile as writeFile8 } from "fs/promises";
|
|
6839
|
-
import
|
|
7080
|
+
import path31 from "path";
|
|
6840
7081
|
var PLAN_INDEX_REL = ".cursor/context/plan-index.json";
|
|
6841
7082
|
var NONE = /^(none|n\/a|empty|nil)$/i;
|
|
6842
7083
|
var OPEN_STATUSES = /* @__PURE__ */ new Set(["pending", "in_progress"]);
|
|
@@ -6850,7 +7091,7 @@ function defaultPlanIndexIo() {
|
|
|
6850
7091
|
}
|
|
6851
7092
|
},
|
|
6852
7093
|
async writeFile(absPath, body) {
|
|
6853
|
-
await ensureDir(
|
|
7094
|
+
await ensureDir(path31.dirname(absPath));
|
|
6854
7095
|
await writeFile8(absPath, body, "utf8");
|
|
6855
7096
|
}
|
|
6856
7097
|
};
|
|
@@ -6876,11 +7117,11 @@ function collectNamedPlanBasenames(named) {
|
|
|
6876
7117
|
return out;
|
|
6877
7118
|
}
|
|
6878
7119
|
function namedPlanCandidatePaths(root, basename) {
|
|
6879
|
-
const safe =
|
|
7120
|
+
const safe = path31.basename(basename);
|
|
6880
7121
|
if (!/^[A-Za-z0-9._-]+\.plan\.md$/i.test(safe)) return [];
|
|
6881
7122
|
return [
|
|
6882
|
-
|
|
6883
|
-
|
|
7123
|
+
path31.join(root, ".cursor", "plans", safe),
|
|
7124
|
+
path31.join(root, ".cursor", "plans", "archive", safe)
|
|
6884
7125
|
];
|
|
6885
7126
|
}
|
|
6886
7127
|
function classifyPlanRole(file, named, openTodos) {
|
|
@@ -6912,7 +7153,7 @@ function parsePlanFrontmatter2(raw) {
|
|
|
6912
7153
|
return { name, todos };
|
|
6913
7154
|
}
|
|
6914
7155
|
async function buildPlanIndex(root, io = defaultPlanIndexIo(), now2 = () => /* @__PURE__ */ new Date()) {
|
|
6915
|
-
const handoffPath =
|
|
7156
|
+
const handoffPath = path31.join(root, HANDOFF_REL);
|
|
6916
7157
|
const handoffText = await io.readFile(handoffPath) ?? "";
|
|
6917
7158
|
const named = extractHandoffNamedPlans(handoffText);
|
|
6918
7159
|
const plans = [];
|
|
@@ -6941,7 +7182,7 @@ async function buildPlanIndex(root, io = defaultPlanIndexIo(), now2 = () => /* @
|
|
|
6941
7182
|
}
|
|
6942
7183
|
async function writePlanIndex(root, io = defaultPlanIndexIo(), now2 = () => /* @__PURE__ */ new Date()) {
|
|
6943
7184
|
const index = await buildPlanIndex(root, io, now2);
|
|
6944
|
-
const dest =
|
|
7185
|
+
const dest = path31.join(root, PLAN_INDEX_REL);
|
|
6945
7186
|
const write = io.writeFile ?? defaultPlanIndexIo().writeFile;
|
|
6946
7187
|
if (write) {
|
|
6947
7188
|
await write(dest, `${JSON.stringify(index, null, 2)}
|
|
@@ -7200,6 +7441,11 @@ var CURSOR_AWARENESS_NUDGE = `## Cursor product-update awareness
|
|
|
7200
7441
|
Advisory gaps vs \`docs/cursor-native-audit.md\` (check-only; no apply; no Field Reports).
|
|
7201
7442
|
|
|
7202
7443
|
Run \`/cursor-update-awareness\` (or \`agent-kit cursor-awareness --check\`) and confirm routing via Ask \u2192 \`/backlog-add\` or \`/dogfood\`.`;
|
|
7444
|
+
var PUBLIC_INBOUND_NUDGE = `## Public inbound radar
|
|
7445
|
+
|
|
7446
|
+
Open issues or pull requests on \`agent-kit-startup/agent-kit\` (inspect-only; no merge/close).
|
|
7447
|
+
|
|
7448
|
+
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
7449
|
|
|
7204
7450
|
// src/hooks/session-start.ts
|
|
7205
7451
|
var NONE_PLACEHOLDERS = /* @__PURE__ */ new Set(["none", "n/a", "empty", "nil"]);
|
|
@@ -7272,7 +7518,7 @@ function extractUnprocessedDogfoodLine(line) {
|
|
|
7272
7518
|
return raw;
|
|
7273
7519
|
}
|
|
7274
7520
|
async function l0Present(root) {
|
|
7275
|
-
return await fileExists(
|
|
7521
|
+
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
7522
|
}
|
|
7277
7523
|
function checkLabelAndRecommendation(check2) {
|
|
7278
7524
|
const checkId = check2.id;
|
|
@@ -7311,7 +7557,7 @@ function unresolvedReadinessChecks(data) {
|
|
|
7311
7557
|
return { essential, nonessential };
|
|
7312
7558
|
}
|
|
7313
7559
|
async function readinessSection(root) {
|
|
7314
|
-
const snapshotPath =
|
|
7560
|
+
const snapshotPath = path32.join(root, READINESS_SNAPSHOT_RELATIVE_PATH);
|
|
7315
7561
|
let data;
|
|
7316
7562
|
try {
|
|
7317
7563
|
data = JSON.parse(await readFile19(snapshotPath, "utf8"));
|
|
@@ -7345,8 +7591,8 @@ Optional readiness item: \`${first.id}\`. ${first.recommendation} This does not
|
|
|
7345
7591
|
}
|
|
7346
7592
|
async function dogfoodInboxSection(root) {
|
|
7347
7593
|
const candidateReadmes = [
|
|
7348
|
-
|
|
7349
|
-
|
|
7594
|
+
path32.join(root, "dogfood", "README.md"),
|
|
7595
|
+
path32.join(root, ".cursor", "dogfood", "README.md")
|
|
7350
7596
|
];
|
|
7351
7597
|
for (const readme of candidateReadmes) {
|
|
7352
7598
|
if (!await fileExists(readme)) continue;
|
|
@@ -7528,6 +7774,97 @@ async function cursorAwarenessSection(root, deps = {}) {
|
|
|
7528
7774
|
if (!shouldEmitCursorAwarenessNudge(result)) return null;
|
|
7529
7775
|
return CURSOR_AWARENESS_NUDGE;
|
|
7530
7776
|
}
|
|
7777
|
+
var PUBLIC_INBOUND_SPAWN_TIMEOUT_MS = 3e4;
|
|
7778
|
+
async function loadPublicInboundCheckPrefs(root) {
|
|
7779
|
+
const data = await loadContextConfig(root);
|
|
7780
|
+
if (!data) return null;
|
|
7781
|
+
const uc = data.publicInboundCheck;
|
|
7782
|
+
if (!uc || typeof uc !== "object" || uc.enabled !== true) {
|
|
7783
|
+
return null;
|
|
7784
|
+
}
|
|
7785
|
+
return uc;
|
|
7786
|
+
}
|
|
7787
|
+
function runPublicInboundJson(root) {
|
|
7788
|
+
return new Promise((resolve3) => {
|
|
7789
|
+
const child = spawn5(
|
|
7790
|
+
process.execPath,
|
|
7791
|
+
[
|
|
7792
|
+
process.argv[1] ?? "",
|
|
7793
|
+
"public-inbound-radar",
|
|
7794
|
+
"--json",
|
|
7795
|
+
"--respect-prefs",
|
|
7796
|
+
"--stamp",
|
|
7797
|
+
"--cwd",
|
|
7798
|
+
root
|
|
7799
|
+
],
|
|
7800
|
+
{ stdio: ["ignore", "pipe", "ignore"], timeout: PUBLIC_INBOUND_SPAWN_TIMEOUT_MS }
|
|
7801
|
+
);
|
|
7802
|
+
let out = "";
|
|
7803
|
+
child.stdout?.on("data", (chunk) => {
|
|
7804
|
+
out += chunk.toString("utf8");
|
|
7805
|
+
});
|
|
7806
|
+
child.on("error", () => resolve3(null));
|
|
7807
|
+
child.on("close", () => {
|
|
7808
|
+
try {
|
|
7809
|
+
const parsed = JSON.parse(out.trim());
|
|
7810
|
+
resolve3(parsed && typeof parsed === "object" ? parsed : null);
|
|
7811
|
+
} catch {
|
|
7812
|
+
resolve3(null);
|
|
7813
|
+
}
|
|
7814
|
+
});
|
|
7815
|
+
});
|
|
7816
|
+
}
|
|
7817
|
+
async function publicInboundSection(root, deps = {}) {
|
|
7818
|
+
if (await loadPublicInboundCheckPrefs(root) === null) return null;
|
|
7819
|
+
const spawnFn = deps.spawnFn ?? spawn5;
|
|
7820
|
+
const runFallback = deps.runFallback ?? runPublicInboundJson;
|
|
7821
|
+
const result = await new Promise((resolve3) => {
|
|
7822
|
+
let settled = false;
|
|
7823
|
+
let fallbackStarted = false;
|
|
7824
|
+
const finish = (value) => {
|
|
7825
|
+
if (settled) return;
|
|
7826
|
+
settled = true;
|
|
7827
|
+
resolve3(value);
|
|
7828
|
+
};
|
|
7829
|
+
const startFallback = () => {
|
|
7830
|
+
if (settled || fallbackStarted) return;
|
|
7831
|
+
fallbackStarted = true;
|
|
7832
|
+
void runFallback(root).then(finish);
|
|
7833
|
+
};
|
|
7834
|
+
const child = spawnFn(
|
|
7835
|
+
"agent-kit",
|
|
7836
|
+
["public-inbound-radar", "--json", "--respect-prefs", "--stamp", "--cwd", root],
|
|
7837
|
+
{
|
|
7838
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
7839
|
+
timeout: PUBLIC_INBOUND_SPAWN_TIMEOUT_MS,
|
|
7840
|
+
shell: false
|
|
7841
|
+
}
|
|
7842
|
+
);
|
|
7843
|
+
let out = "";
|
|
7844
|
+
child.stdout?.on("data", (chunk) => {
|
|
7845
|
+
out += chunk.toString("utf8");
|
|
7846
|
+
});
|
|
7847
|
+
child.on("error", () => {
|
|
7848
|
+
startFallback();
|
|
7849
|
+
});
|
|
7850
|
+
child.on("close", (code) => {
|
|
7851
|
+
if (settled || fallbackStarted) return;
|
|
7852
|
+
if (code !== 0 && !out.trim()) {
|
|
7853
|
+
startFallback();
|
|
7854
|
+
return;
|
|
7855
|
+
}
|
|
7856
|
+
try {
|
|
7857
|
+
finish(JSON.parse(out.trim()));
|
|
7858
|
+
} catch {
|
|
7859
|
+
startFallback();
|
|
7860
|
+
}
|
|
7861
|
+
});
|
|
7862
|
+
});
|
|
7863
|
+
if (!shouldEmitPublicInboundNudge(result)) {
|
|
7864
|
+
return null;
|
|
7865
|
+
}
|
|
7866
|
+
return PUBLIC_INBOUND_NUDGE;
|
|
7867
|
+
}
|
|
7531
7868
|
var AUDIT_SESSION_NS_PREFIX = "agent-kit-audit-";
|
|
7532
7869
|
var AUDIT_SESSION_LIST_TIMEOUT_MS = 2e3;
|
|
7533
7870
|
function runAuditSessionCommand(cmd, args) {
|
|
@@ -7573,7 +7910,7 @@ function parseScreenDetachedAuditSessions(listing) {
|
|
|
7573
7910
|
const [, pid, name, marker] = m;
|
|
7574
7911
|
if (!name || !name.startsWith(AUDIT_SESSION_NS_PREFIX)) continue;
|
|
7575
7912
|
if (marker && /[Aa]ttached/.test(marker)) continue;
|
|
7576
|
-
entries.push({ name, socketPath: sockdir ?
|
|
7913
|
+
entries.push({ name, socketPath: sockdir ? path32.join(sockdir, `${pid}.${name}`) : null });
|
|
7577
7914
|
}
|
|
7578
7915
|
return entries;
|
|
7579
7916
|
}
|
|
@@ -7621,8 +7958,8 @@ ${sessions.length} detached \`agent-kit-audit-*\` PTY ${noun} on this host (${ol
|
|
|
7621
7958
|
}
|
|
7622
7959
|
}
|
|
7623
7960
|
async function buildSessionStartAdditionalContext(rootDir, _payload = {}) {
|
|
7624
|
-
const root =
|
|
7625
|
-
const handoffPath =
|
|
7961
|
+
const root = path32.resolve(rootDir);
|
|
7962
|
+
const handoffPath = path32.join(root, HANDOFF_REL);
|
|
7626
7963
|
const handoffFull = await readFull(handoffPath);
|
|
7627
7964
|
const handoff = capHandoffExcerpt(handoffFull);
|
|
7628
7965
|
const parts = [HARD_RULES];
|
|
@@ -7636,6 +7973,8 @@ async function buildSessionStartAdditionalContext(rootDir, _payload = {}) {
|
|
|
7636
7973
|
if (updateNudge) parts.push(updateNudge);
|
|
7637
7974
|
const cursorNudge = await cursorAwarenessSection(root);
|
|
7638
7975
|
if (cursorNudge) parts.push(cursorNudge);
|
|
7976
|
+
const inboundNudge = await publicInboundSection(root);
|
|
7977
|
+
if (inboundNudge) parts.push(inboundNudge);
|
|
7639
7978
|
const auditSessions = await detachedAuditSessionsSection().catch(() => null);
|
|
7640
7979
|
if (auditSessions) parts.push(auditSessions);
|
|
7641
7980
|
const formatWarnings = validateHandoffText(handoffFull);
|
|
@@ -7689,7 +8028,7 @@ async function runSessionStartHook(cwd, formatArg, deps = {}) {
|
|
|
7689
8028
|
const readStdin = deps.readStdin ?? readStdinJson;
|
|
7690
8029
|
const buildContext = deps.buildContext ?? buildSessionStartAdditionalContext;
|
|
7691
8030
|
const payload = await readStdin();
|
|
7692
|
-
const root = resolveSessionRoot(payload,
|
|
8031
|
+
const root = resolveSessionRoot(payload, path33.resolve(cwd));
|
|
7693
8032
|
const out = await buildContext(root, payload);
|
|
7694
8033
|
return formatSessionStartOutput(out.additional_context, format);
|
|
7695
8034
|
} catch {
|
|
@@ -7742,12 +8081,12 @@ import { defineCommand as defineCommand12 } from "citty";
|
|
|
7742
8081
|
|
|
7743
8082
|
// src/lifecycle/path-cli.ts
|
|
7744
8083
|
import { spawn as spawn6 } from "child_process";
|
|
7745
|
-
import
|
|
8084
|
+
import path35 from "path";
|
|
7746
8085
|
|
|
7747
8086
|
// src/utils/terminal.ts
|
|
7748
8087
|
import { readdir as readdir8 } from "fs/promises";
|
|
7749
8088
|
import { homedir as homedir3 } from "os";
|
|
7750
|
-
import
|
|
8089
|
+
import path34 from "path";
|
|
7751
8090
|
import { confirm, isCancel } from "@clack/prompts";
|
|
7752
8091
|
function isNonInteractive() {
|
|
7753
8092
|
if (process.env.CI === "true" || process.env.CI === "1") return true;
|
|
@@ -7771,14 +8110,14 @@ async function findNestedRepoChildren(resolved) {
|
|
|
7771
8110
|
if (!entry.isDirectory()) continue;
|
|
7772
8111
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
7773
8112
|
scanned += 1;
|
|
7774
|
-
if (await fileExists(
|
|
8113
|
+
if (await fileExists(path34.join(resolved, entry.name, ".git"))) {
|
|
7775
8114
|
nested.push(entry.name);
|
|
7776
8115
|
}
|
|
7777
8116
|
}
|
|
7778
8117
|
return nested;
|
|
7779
8118
|
}
|
|
7780
8119
|
async function validateProjectRoot(resolved) {
|
|
7781
|
-
const home =
|
|
8120
|
+
const home = path34.resolve(homedir3());
|
|
7782
8121
|
if (resolved === "/" || resolved === home) {
|
|
7783
8122
|
return {
|
|
7784
8123
|
ok: false,
|
|
@@ -7786,8 +8125,8 @@ async function validateProjectRoot(resolved) {
|
|
|
7786
8125
|
recovery: "Change into a project directory and re-run. Agent Kit installs per project."
|
|
7787
8126
|
};
|
|
7788
8127
|
}
|
|
7789
|
-
const hasGit = await fileExists(
|
|
7790
|
-
const hasManifest = await fileExists(
|
|
8128
|
+
const hasGit = await fileExists(path34.join(resolved, ".git"));
|
|
8129
|
+
const hasManifest = await fileExists(path34.join(resolved, MANIFEST_RELATIVE_PATH));
|
|
7791
8130
|
if (!hasGit && !hasManifest) {
|
|
7792
8131
|
return {
|
|
7793
8132
|
ok: false,
|
|
@@ -7820,7 +8159,7 @@ async function validateProjectRoot(resolved) {
|
|
|
7820
8159
|
return { ok: true };
|
|
7821
8160
|
}
|
|
7822
8161
|
async function confirmProjectRoot(cwd, opts) {
|
|
7823
|
-
const resolved =
|
|
8162
|
+
const resolved = path34.resolve(cwd);
|
|
7824
8163
|
if (opts.forceRoot) {
|
|
7825
8164
|
return resolved;
|
|
7826
8165
|
}
|
|
@@ -7934,9 +8273,9 @@ function npxPinned(runtimeVersion, subcommand) {
|
|
|
7934
8273
|
return `npx -y ${pinnedCliSpec(runtimeVersion)} ${subcommand}`;
|
|
7935
8274
|
}
|
|
7936
8275
|
function isBinUnderPrefix(binPath, prefix) {
|
|
7937
|
-
const bin =
|
|
7938
|
-
const root =
|
|
7939
|
-
return bin === root || bin.startsWith(`${root}${
|
|
8276
|
+
const bin = path35.resolve(binPath);
|
|
8277
|
+
const root = path35.resolve(prefix);
|
|
8278
|
+
return bin === root || bin.startsWith(`${root}${path35.sep}`);
|
|
7940
8279
|
}
|
|
7941
8280
|
function pathCliStatus(env, runtimeVersion) {
|
|
7942
8281
|
if (!env.binOnPath || !env.binPath) return "missing";
|
|
@@ -8034,17 +8373,17 @@ async function syncPathCliToRuntime(options = {}) {
|
|
|
8034
8373
|
}
|
|
8035
8374
|
|
|
8036
8375
|
// src/commands/install.ts
|
|
8037
|
-
import
|
|
8376
|
+
import path41 from "path";
|
|
8038
8377
|
import { defineCommand as defineCommand11 } from "citty";
|
|
8039
8378
|
import { bold, cyan as cyan3, green as green2, options as koloristOptions2 } from "kolorist";
|
|
8040
8379
|
|
|
8041
8380
|
// src/generator/personalization.ts
|
|
8042
8381
|
import { readFile as readFile21, writeFile as writeFile12 } from "fs/promises";
|
|
8043
|
-
import
|
|
8382
|
+
import path39 from "path";
|
|
8044
8383
|
|
|
8045
8384
|
// src/generator/claude-command-adapters.ts
|
|
8046
8385
|
import { readFile as readFile20, readdir as readdir9, writeFile as writeFile9 } from "fs/promises";
|
|
8047
|
-
import
|
|
8386
|
+
import path36 from "path";
|
|
8048
8387
|
var CURSOR_COMMANDS_DIR_REL = ".cursor/commands";
|
|
8049
8388
|
var CLAUDE_COMMANDS_DIR_REL = ".claude/commands";
|
|
8050
8389
|
var RESERVED_ADAPTER_NAMES = /* @__PURE__ */ new Set(["agent-kit"]);
|
|
@@ -8073,7 +8412,7 @@ Adapter rules (Claude Code CLI):
|
|
|
8073
8412
|
`;
|
|
8074
8413
|
}
|
|
8075
8414
|
async function discoverInstalledCommands(rootDir) {
|
|
8076
|
-
const dir =
|
|
8415
|
+
const dir = path36.join(rootDir, CURSOR_COMMANDS_DIR_REL);
|
|
8077
8416
|
let entries;
|
|
8078
8417
|
try {
|
|
8079
8418
|
entries = (await readdir9(dir)).filter((f) => f.endsWith(".md"));
|
|
@@ -8085,7 +8424,7 @@ async function discoverInstalledCommands(rootDir) {
|
|
|
8085
8424
|
const name = file.slice(0, -3);
|
|
8086
8425
|
if (RESERVED_ADAPTER_NAMES.has(name)) continue;
|
|
8087
8426
|
try {
|
|
8088
|
-
const raw = await readFile20(
|
|
8427
|
+
const raw = await readFile20(path36.join(dir, file), "utf8");
|
|
8089
8428
|
const parsed = parseCommandFrontmatter(name, raw);
|
|
8090
8429
|
if (parsed) commands.push(parsed);
|
|
8091
8430
|
} catch {
|
|
@@ -8100,11 +8439,11 @@ async function generateClaudeCommandAdapters(rootDir) {
|
|
|
8100
8439
|
const results = [];
|
|
8101
8440
|
let ledgerDirty = false;
|
|
8102
8441
|
for (const command of commands) {
|
|
8103
|
-
const relPath =
|
|
8442
|
+
const relPath = path36.posix.join(CLAUDE_COMMANDS_DIR_REL, `${command.name}.md`);
|
|
8104
8443
|
const rendered = renderClaudeCommandAdapter(command);
|
|
8105
|
-
const abs =
|
|
8444
|
+
const abs = path36.join(rootDir, relPath);
|
|
8106
8445
|
if (!await fileExists(abs)) {
|
|
8107
|
-
await ensureDir(
|
|
8446
|
+
await ensureDir(path36.dirname(abs));
|
|
8108
8447
|
await writeFile9(abs, rendered, "utf8");
|
|
8109
8448
|
ledger.hashes[relPath] = contentHash(rendered);
|
|
8110
8449
|
ledgerDirty = true;
|
|
@@ -8135,7 +8474,7 @@ async function generateClaudeCommandAdapters(rootDir) {
|
|
|
8135
8474
|
|
|
8136
8475
|
// src/generator/claude-kit-load.ts
|
|
8137
8476
|
import { writeFile as writeFile10 } from "fs/promises";
|
|
8138
|
-
import
|
|
8477
|
+
import path37 from "path";
|
|
8139
8478
|
var CLAUDE_MD_REL = "CLAUDE.md";
|
|
8140
8479
|
var AGENT_KIT_COMMAND_REL = ".claude/commands/agent-kit.md";
|
|
8141
8480
|
function renderClaudeMd() {
|
|
@@ -8191,11 +8530,11 @@ Non-goals: not audits / \`/plan-external-review\`, not a second tick dialect (\`
|
|
|
8191
8530
|
`;
|
|
8192
8531
|
}
|
|
8193
8532
|
async function writeUnlessExists(rootDir, relativePath, content) {
|
|
8194
|
-
const target =
|
|
8533
|
+
const target = path37.join(rootDir, relativePath);
|
|
8195
8534
|
if (await fileExists(target)) {
|
|
8196
8535
|
return { relativePath, status: "skipped-customized" };
|
|
8197
8536
|
}
|
|
8198
|
-
await ensureDir(
|
|
8537
|
+
await ensureDir(path37.dirname(target));
|
|
8199
8538
|
await writeFile10(target, content, "utf8");
|
|
8200
8539
|
return { relativePath, status: "applied" };
|
|
8201
8540
|
}
|
|
@@ -8208,7 +8547,7 @@ async function generateClaudeKitLoadArtifacts(rootDir) {
|
|
|
8208
8547
|
|
|
8209
8548
|
// src/generator/vscode.ts
|
|
8210
8549
|
import { writeFile as writeFile11 } from "fs/promises";
|
|
8211
|
-
import
|
|
8550
|
+
import path38 from "path";
|
|
8212
8551
|
|
|
8213
8552
|
// src/generator/platform.ts
|
|
8214
8553
|
function gitProviderLabel(profile) {
|
|
@@ -8232,10 +8571,10 @@ function prTerminology(profile) {
|
|
|
8232
8571
|
// src/generator/vscode.ts
|
|
8233
8572
|
async function generateVSCodeArtifacts(profile) {
|
|
8234
8573
|
const results = [];
|
|
8235
|
-
const vscodeDir =
|
|
8236
|
-
const githubDir =
|
|
8574
|
+
const vscodeDir = path38.join(profile.rootDir, ".vscode");
|
|
8575
|
+
const githubDir = path38.join(profile.rootDir, ".github");
|
|
8237
8576
|
await Promise.all([ensureDir(vscodeDir), ensureDir(githubDir)]);
|
|
8238
|
-
const settingsPath =
|
|
8577
|
+
const settingsPath = path38.join(vscodeDir, "settings.json");
|
|
8239
8578
|
if (await fileExists(settingsPath)) {
|
|
8240
8579
|
results.push({ relativePath: ".vscode/settings.json", status: "skipped-customized" });
|
|
8241
8580
|
} else {
|
|
@@ -8259,7 +8598,7 @@ async function generateVSCodeArtifacts(profile) {
|
|
|
8259
8598
|
}
|
|
8260
8599
|
const provider = gitProviderLabel(profile);
|
|
8261
8600
|
const prTerm = prTerminology(profile);
|
|
8262
|
-
const copilotPath =
|
|
8601
|
+
const copilotPath = path38.join(githubDir, "copilot-instructions.md");
|
|
8263
8602
|
if (await fileExists(copilotPath)) {
|
|
8264
8603
|
results.push({ relativePath: ".github/copilot-instructions.md", status: "skipped-customized" });
|
|
8265
8604
|
} else {
|
|
@@ -8277,7 +8616,7 @@ async function generateVSCodeArtifacts(profile) {
|
|
|
8277
8616
|
results.push({ relativePath: ".github/copilot-instructions.md", status: "applied" });
|
|
8278
8617
|
}
|
|
8279
8618
|
if (profile.ide.plan === "vscode-pro") {
|
|
8280
|
-
const securityPath =
|
|
8619
|
+
const securityPath = path38.join(vscodeDir, "security-review.agent.md");
|
|
8281
8620
|
if (await fileExists(securityPath)) {
|
|
8282
8621
|
results.push({
|
|
8283
8622
|
relativePath: ".vscode/security-review.agent.md",
|
|
@@ -8489,7 +8828,7 @@ function renderProjectContext(profile, skillItems = []) {
|
|
|
8489
8828
|
`;
|
|
8490
8829
|
}
|
|
8491
8830
|
async function createOwnedFile(rootDir, relativePath, content, evidence) {
|
|
8492
|
-
const target =
|
|
8831
|
+
const target = path39.join(rootDir, relativePath);
|
|
8493
8832
|
if (await fileExists(target)) {
|
|
8494
8833
|
return {
|
|
8495
8834
|
kind: "file",
|
|
@@ -8499,7 +8838,7 @@ async function createOwnedFile(rootDir, relativePath, content, evidence) {
|
|
|
8499
8838
|
evidence
|
|
8500
8839
|
};
|
|
8501
8840
|
}
|
|
8502
|
-
await ensureDir(
|
|
8841
|
+
await ensureDir(path39.dirname(target));
|
|
8503
8842
|
await writeFile12(target, content, "utf8");
|
|
8504
8843
|
return {
|
|
8505
8844
|
kind: "file",
|
|
@@ -8516,7 +8855,7 @@ async function packTargets(registryRoot, packId) {
|
|
|
8516
8855
|
async function existingTargets(projectRoot, targets) {
|
|
8517
8856
|
const checks = await Promise.all(
|
|
8518
8857
|
targets.map(
|
|
8519
|
-
async (target) => await fileExists(
|
|
8858
|
+
async (target) => await fileExists(path39.join(projectRoot, target)) ? target : null
|
|
8520
8859
|
)
|
|
8521
8860
|
);
|
|
8522
8861
|
return checks.filter((target) => target !== null);
|
|
@@ -8538,14 +8877,14 @@ async function applyPersonalization(input) {
|
|
|
8538
8877
|
componentResults.push({ ...item, status: "unavailable" });
|
|
8539
8878
|
continue;
|
|
8540
8879
|
}
|
|
8541
|
-
const target =
|
|
8880
|
+
const target = path39.posix.join(
|
|
8542
8881
|
".cursor",
|
|
8543
8882
|
"skills",
|
|
8544
8883
|
skill.path.includes("/core/") ? "core" : "community",
|
|
8545
8884
|
skill.id,
|
|
8546
8885
|
"SKILL.md"
|
|
8547
8886
|
);
|
|
8548
|
-
if (await fileExists(
|
|
8887
|
+
if (await fileExists(path39.join(input.rootDir, target))) {
|
|
8549
8888
|
componentResults.push({ ...item, status: "skipped-customized", path: target });
|
|
8550
8889
|
protectedPaths.add(target);
|
|
8551
8890
|
continue;
|
|
@@ -8690,7 +9029,7 @@ async function applyPersonalization(input) {
|
|
|
8690
9029
|
protectedPaths: [...protectedPaths].sort(),
|
|
8691
9030
|
...claudeSessionStartInstructions ? { claudeSessionStartInstructions } : {}
|
|
8692
9031
|
};
|
|
8693
|
-
await writeJson(
|
|
9032
|
+
await writeJson(path39.join(input.rootDir, RESULT_PATH), result);
|
|
8694
9033
|
return {
|
|
8695
9034
|
result,
|
|
8696
9035
|
manifest: {
|
|
@@ -8708,7 +9047,7 @@ async function applyPersonalization(input) {
|
|
|
8708
9047
|
};
|
|
8709
9048
|
}
|
|
8710
9049
|
async function readRepositoryProfile(rootDir) {
|
|
8711
|
-
const target =
|
|
9050
|
+
const target = path39.join(rootDir, REPOSITORY_PROFILE_REL);
|
|
8712
9051
|
if (!await fileExists(target)) return null;
|
|
8713
9052
|
return JSON.parse(await readFile21(target, "utf8"));
|
|
8714
9053
|
}
|
|
@@ -8716,16 +9055,16 @@ async function readRepositoryProfile(rootDir) {
|
|
|
8716
9055
|
// src/lifecycle/onboard-migration.ts
|
|
8717
9056
|
import { createHash as createHash4 } from "crypto";
|
|
8718
9057
|
import { readFile as readFile22, unlink } from "fs/promises";
|
|
8719
|
-
import
|
|
9058
|
+
import path40 from "path";
|
|
8720
9059
|
var LEGACY_ONBOARD_PATH = ".cursor/commands/onboard.md";
|
|
8721
9060
|
var NAMESPACED_ONBOARD_PATH = ".cursor/commands/agent-kit-onboard.md";
|
|
8722
9061
|
var MANAGED_LEGACY_HASHES = /* @__PURE__ */ new Set([
|
|
8723
9062
|
"b274a68941813f19b185893cb7c5561dff027f53270890029992f208e24992fe"
|
|
8724
9063
|
]);
|
|
8725
9064
|
async function migrateLegacyOnboardCommand(projectRoot, managedHashes = MANAGED_LEGACY_HASHES) {
|
|
8726
|
-
const legacyPath =
|
|
9065
|
+
const legacyPath = path40.join(projectRoot, LEGACY_ONBOARD_PATH);
|
|
8727
9066
|
if (!await fileExists(legacyPath)) return "absent";
|
|
8728
|
-
const namespacedPath =
|
|
9067
|
+
const namespacedPath = path40.join(projectRoot, NAMESPACED_ONBOARD_PATH);
|
|
8729
9068
|
if (!await fileExists(namespacedPath)) return "preserved-customized";
|
|
8730
9069
|
const content = await readFile22(legacyPath);
|
|
8731
9070
|
const hash = createHash4("sha256").update(content).digest("hex");
|
|
@@ -8876,7 +9215,7 @@ async function printPostInstallSummary(result) {
|
|
|
8876
9215
|
printInstallEpilogue(sync.env, { runtimeVersion: KIT_VERSION });
|
|
8877
9216
|
}
|
|
8878
9217
|
async function performInstall(options) {
|
|
8879
|
-
const projectRoot =
|
|
9218
|
+
const projectRoot = path41.resolve(options.cwd);
|
|
8880
9219
|
const packs = parsePackList(options.pack);
|
|
8881
9220
|
const existing = await loadAgentKitManifest(projectRoot);
|
|
8882
9221
|
const registry = await resolveRegistryFromCli({
|
|
@@ -9581,9 +9920,9 @@ function renderMcLive(view, opts = {}) {
|
|
|
9581
9920
|
}
|
|
9582
9921
|
|
|
9583
9922
|
// src/mission-control/snapshot.ts
|
|
9584
|
-
import { execFile as
|
|
9585
|
-
import { access as
|
|
9586
|
-
import
|
|
9923
|
+
import { execFile as execFile7 } from "child_process";
|
|
9924
|
+
import { access as access8 } from "fs/promises";
|
|
9925
|
+
import path42 from "path";
|
|
9587
9926
|
|
|
9588
9927
|
// ../../dashboard/lib/live-refresh.mjs
|
|
9589
9928
|
import { join, resolve as resolve2 } from "path";
|
|
@@ -9615,8 +9954,8 @@ function dataScriptTimeoutMs(env = process.env) {
|
|
|
9615
9954
|
async function firstExisting2(candidates) {
|
|
9616
9955
|
for (const candidate2 of candidates) {
|
|
9617
9956
|
try {
|
|
9618
|
-
await
|
|
9619
|
-
return
|
|
9957
|
+
await access8(candidate2);
|
|
9958
|
+
return path42.resolve(candidate2);
|
|
9620
9959
|
} catch {
|
|
9621
9960
|
}
|
|
9622
9961
|
}
|
|
@@ -9625,9 +9964,9 @@ async function firstExisting2(candidates) {
|
|
|
9625
9964
|
async function findDashboardDataScript(cwd, env = process.env, options = {}) {
|
|
9626
9965
|
const startPath = await findDashboardStart(cwd, env, options);
|
|
9627
9966
|
if (startPath) {
|
|
9628
|
-
const sibling =
|
|
9967
|
+
const sibling = path42.join(path42.dirname(startPath), "dashboard-data.mjs");
|
|
9629
9968
|
try {
|
|
9630
|
-
await
|
|
9969
|
+
await access8(sibling);
|
|
9631
9970
|
return sibling;
|
|
9632
9971
|
} catch {
|
|
9633
9972
|
}
|
|
@@ -9639,8 +9978,8 @@ async function findDashboardDataScript(cwd, env = process.env, options = {}) {
|
|
|
9639
9978
|
async function loadDashboardSnapshot(opts) {
|
|
9640
9979
|
const env = opts.env ?? process.env;
|
|
9641
9980
|
const timeout = dataScriptTimeoutMs(env);
|
|
9642
|
-
const run = opts.execFileFn ??
|
|
9643
|
-
const snapshotRoot =
|
|
9981
|
+
const run = opts.execFileFn ?? execFile7;
|
|
9982
|
+
const snapshotRoot = path42.resolve(opts.snapshotRoot);
|
|
9644
9983
|
return new Promise((resolve3) => {
|
|
9645
9984
|
run(
|
|
9646
9985
|
process.execPath,
|
|
@@ -9963,20 +10302,20 @@ var missionControlCommand = defineCommand13({
|
|
|
9963
10302
|
});
|
|
9964
10303
|
|
|
9965
10304
|
// src/commands/monitors.ts
|
|
9966
|
-
import
|
|
10305
|
+
import path44 from "path";
|
|
9967
10306
|
import { defineCommand as defineCommand14 } from "citty";
|
|
9968
10307
|
|
|
9969
10308
|
// src/invariants/monitors-untriaged.ts
|
|
9970
|
-
import { execFile as
|
|
10309
|
+
import { execFile as execFile8 } from "child_process";
|
|
9971
10310
|
import { readFile as readFile23, readdir as readdir10, stat as stat5 } from "fs/promises";
|
|
9972
|
-
import
|
|
9973
|
-
import { promisify as
|
|
10311
|
+
import path43 from "path";
|
|
10312
|
+
import { promisify as promisify7 } from "util";
|
|
9974
10313
|
|
|
9975
10314
|
// src/invariants/triage-heading.ts
|
|
9976
10315
|
var TRIAGE_HEADING_RE = /^#{2,6}\s+(?:Triage note|Follow-?up plan|Residuals plan)\b/im;
|
|
9977
10316
|
|
|
9978
10317
|
// src/invariants/monitors-untriaged.ts
|
|
9979
|
-
var
|
|
10318
|
+
var execFileAsync6 = promisify7(execFile8);
|
|
9980
10319
|
var CITE4 = "agent-kit monitors --untriaged (ADR 2026-07-27_plan-review-triage-untriaged-not-mtime; never newest-mtime-wins)";
|
|
9981
10320
|
function hasOpenGaps(content) {
|
|
9982
10321
|
if (/###\s+Still open[^\n]*\n+(?:\s*\n)*(?:None\.|none\.|\*None\*)/i.test(content)) {
|
|
@@ -10002,7 +10341,7 @@ async function listMonitorFiles(memoryDir) {
|
|
|
10002
10341
|
async function gitFreshMonitorNames(rootDir) {
|
|
10003
10342
|
const names = /* @__PURE__ */ new Set();
|
|
10004
10343
|
try {
|
|
10005
|
-
const { stdout } = await
|
|
10344
|
+
const { stdout } = await execFileAsync6(
|
|
10006
10345
|
"git",
|
|
10007
10346
|
["status", "--porcelain", "--", ".cursor/memory"],
|
|
10008
10347
|
{ cwd: rootDir, maxBuffer: 2 * 1024 * 1024 }
|
|
@@ -10010,7 +10349,7 @@ async function gitFreshMonitorNames(rootDir) {
|
|
|
10010
10349
|
for (const line of stdout.split("\n")) {
|
|
10011
10350
|
if (!line.trim()) continue;
|
|
10012
10351
|
const file = line.slice(3).trim().replace(/^.* -> /, "");
|
|
10013
|
-
const base =
|
|
10352
|
+
const base = path43.basename(file);
|
|
10014
10353
|
if (base.startsWith("plan-monitor-") && base.endsWith(".md")) {
|
|
10015
10354
|
names.add(base);
|
|
10016
10355
|
}
|
|
@@ -10033,13 +10372,13 @@ function monitorSlugFromName(fileName) {
|
|
|
10033
10372
|
return fileName.replace(/^plan-monitor-/, "").replace(/\.md$/, "").toLowerCase();
|
|
10034
10373
|
}
|
|
10035
10374
|
async function selectUntriagedMonitors(rootDir) {
|
|
10036
|
-
const root =
|
|
10037
|
-
const memoryDir =
|
|
10375
|
+
const root = path43.resolve(rootDir);
|
|
10376
|
+
const memoryDir = path43.join(root, ".cursor", "memory");
|
|
10038
10377
|
const allNames = await listMonitorFiles(memoryDir);
|
|
10039
10378
|
const selectionOrder = ["git-fresh", "handoff-aligned", "untriaged-scan"];
|
|
10040
10379
|
const byName = /* @__PURE__ */ new Map();
|
|
10041
10380
|
for (const name of allNames) {
|
|
10042
|
-
const abs =
|
|
10381
|
+
const abs = path43.join(memoryDir, name);
|
|
10043
10382
|
try {
|
|
10044
10383
|
const [content, st] = await Promise.all([readFile23(abs, "utf8"), stat5(abs)]);
|
|
10045
10384
|
byName.set(name, { content, mtimeMs: st.mtimeMs });
|
|
@@ -10054,7 +10393,7 @@ async function selectUntriagedMonitors(rootDir) {
|
|
|
10054
10393
|
const gitFreshSet = [...gitFresh].filter(untriaged).sort();
|
|
10055
10394
|
let handoff = "";
|
|
10056
10395
|
try {
|
|
10057
|
-
handoff = await readFile23(
|
|
10396
|
+
handoff = await readFile23(path43.join(root, ".cursor", "HANDOFF.md"), "utf8");
|
|
10058
10397
|
} catch {
|
|
10059
10398
|
handoff = "";
|
|
10060
10399
|
}
|
|
@@ -10074,8 +10413,8 @@ async function selectUntriagedMonitors(rootDir) {
|
|
|
10074
10413
|
const row = byName.get(name);
|
|
10075
10414
|
if (!row) continue;
|
|
10076
10415
|
entries.push({
|
|
10077
|
-
path:
|
|
10078
|
-
relativePath:
|
|
10416
|
+
path: path43.join(memoryDir, name),
|
|
10417
|
+
relativePath: path43.relative(root, path43.join(memoryDir, name)).split(path43.sep).join("/"),
|
|
10079
10418
|
mtimeMs: row.mtimeMs,
|
|
10080
10419
|
hasTriageHeading: false,
|
|
10081
10420
|
hasOpenGaps: hasOpenGaps(row.content),
|
|
@@ -10121,7 +10460,7 @@ var monitorsCommand = defineCommand14({
|
|
|
10121
10460
|
process.exitCode = 2;
|
|
10122
10461
|
return;
|
|
10123
10462
|
}
|
|
10124
|
-
const result = await selectUntriagedMonitors(
|
|
10463
|
+
const result = await selectUntriagedMonitors(path44.resolve(args.cwd));
|
|
10125
10464
|
if (args.json) {
|
|
10126
10465
|
console.log(JSON.stringify(result, null, 2));
|
|
10127
10466
|
return;
|
|
@@ -10137,7 +10476,7 @@ var monitorsCommand = defineCommand14({
|
|
|
10137
10476
|
});
|
|
10138
10477
|
|
|
10139
10478
|
// src/commands/plan-index.ts
|
|
10140
|
-
import
|
|
10479
|
+
import path45 from "path";
|
|
10141
10480
|
import { defineCommand as defineCommand15 } from "citty";
|
|
10142
10481
|
var planIndexCommand = defineCommand15({
|
|
10143
10482
|
meta: {
|
|
@@ -10156,7 +10495,7 @@ var planIndexCommand = defineCommand15({
|
|
|
10156
10495
|
}
|
|
10157
10496
|
},
|
|
10158
10497
|
async run({ args }) {
|
|
10159
|
-
const root =
|
|
10498
|
+
const root = path45.resolve(args.cwd);
|
|
10160
10499
|
const index = await writePlanIndex(root);
|
|
10161
10500
|
if (args.json) {
|
|
10162
10501
|
console.log(JSON.stringify(index, null, 2));
|
|
@@ -10171,15 +10510,72 @@ var planIndexCommand = defineCommand15({
|
|
|
10171
10510
|
}
|
|
10172
10511
|
});
|
|
10173
10512
|
|
|
10174
|
-
// src/commands/
|
|
10175
|
-
import path51 from "path";
|
|
10513
|
+
// src/commands/public-inbound-radar.ts
|
|
10176
10514
|
import { defineCommand as defineCommand16 } from "citty";
|
|
10515
|
+
var publicInboundRadarCommand = defineCommand16({
|
|
10516
|
+
meta: {
|
|
10517
|
+
name: "public-inbound-radar",
|
|
10518
|
+
description: "Factory-only: list open public issues/PRs on agent-kit-startup/agent-kit (read-only JSON)."
|
|
10519
|
+
},
|
|
10520
|
+
args: {
|
|
10521
|
+
cwd: {
|
|
10522
|
+
type: "string",
|
|
10523
|
+
default: process.cwd()
|
|
10524
|
+
},
|
|
10525
|
+
json: {
|
|
10526
|
+
type: "boolean",
|
|
10527
|
+
description: "Print machine-readable JSON (default true for scripting)",
|
|
10528
|
+
default: true
|
|
10529
|
+
},
|
|
10530
|
+
offline: {
|
|
10531
|
+
type: "boolean",
|
|
10532
|
+
description: "Skip GitHub fetch; fail-open skipped-offline",
|
|
10533
|
+
default: false
|
|
10534
|
+
},
|
|
10535
|
+
"respect-prefs": {
|
|
10536
|
+
type: "boolean",
|
|
10537
|
+
description: "Honor publicInboundCheck.enabled and intervalDays from .cursor/context/config.json",
|
|
10538
|
+
default: false
|
|
10539
|
+
},
|
|
10540
|
+
stamp: {
|
|
10541
|
+
type: "boolean",
|
|
10542
|
+
description: "Persist publicInboundCheck.lastCheckedAt after an ok check",
|
|
10543
|
+
default: false
|
|
10544
|
+
}
|
|
10545
|
+
},
|
|
10546
|
+
async run({ args }) {
|
|
10547
|
+
const result = await checkPublicInbound(args.cwd, {
|
|
10548
|
+
offline: Boolean(args.offline),
|
|
10549
|
+
respectPrefs: Boolean(args["respect-prefs"]),
|
|
10550
|
+
stamp: Boolean(args.stamp)
|
|
10551
|
+
});
|
|
10552
|
+
if (args.json) {
|
|
10553
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10554
|
+
} else {
|
|
10555
|
+
const line = `[${result.status}] ${result.message}`;
|
|
10556
|
+
if (result.status === "error") logger.error(line);
|
|
10557
|
+
else if (result.status.startsWith("skipped-")) logger.warn(line);
|
|
10558
|
+
else logger.info(line);
|
|
10559
|
+
for (const item of result.items.slice(0, 20)) {
|
|
10560
|
+
logger.info(`- ${item.class} ${item.cite}: ${item.title} (@${item.author})`);
|
|
10561
|
+
}
|
|
10562
|
+
if (result.items.length > 20) {
|
|
10563
|
+
logger.info(`\u2026 and ${result.items.length - 20} more (use --json)`);
|
|
10564
|
+
}
|
|
10565
|
+
}
|
|
10566
|
+
if (result.status === "error") process.exitCode = 2;
|
|
10567
|
+
}
|
|
10568
|
+
});
|
|
10569
|
+
|
|
10570
|
+
// src/commands/run-plan.ts
|
|
10571
|
+
import path52 from "path";
|
|
10572
|
+
import { defineCommand as defineCommand17 } from "citty";
|
|
10177
10573
|
|
|
10178
10574
|
// src/plan-loop/backends.ts
|
|
10179
10575
|
import { execFileSync as execFileSync2, spawn as spawn7 } from "child_process";
|
|
10180
10576
|
import { createWriteStream } from "fs";
|
|
10181
|
-
import { access as
|
|
10182
|
-
import
|
|
10577
|
+
import { access as access9 } from "fs/promises";
|
|
10578
|
+
import path46 from "path";
|
|
10183
10579
|
import { StringDecoder as StringDecoder3 } from "string_decoder";
|
|
10184
10580
|
|
|
10185
10581
|
// src/plan-loop/hitl-relay.ts
|
|
@@ -11319,9 +11715,9 @@ function claudeHeadlessArgs(opts = {}) {
|
|
|
11319
11715
|
async function missingClaudeAdapter(workspace, prompt) {
|
|
11320
11716
|
const m = /^\/([A-Za-z0-9][A-Za-z0-9_-]*)/.exec(prompt.trimStart());
|
|
11321
11717
|
if (!m?.[1]) return null;
|
|
11322
|
-
const rel =
|
|
11718
|
+
const rel = path46.join(".claude", "commands", `${m[1]}.md`);
|
|
11323
11719
|
try {
|
|
11324
|
-
await
|
|
11720
|
+
await access9(path46.join(workspace, rel));
|
|
11325
11721
|
return null;
|
|
11326
11722
|
} catch {
|
|
11327
11723
|
return rel;
|
|
@@ -11444,15 +11840,15 @@ async function detectAgentBackend(requested, whichFn = whichBinary) {
|
|
|
11444
11840
|
|
|
11445
11841
|
// src/plan-loop/run-loop.ts
|
|
11446
11842
|
import { mkdir as mkdir6, readFile as readFile27, rm as rm2, unlink as unlink2 } from "fs/promises";
|
|
11447
|
-
import
|
|
11843
|
+
import path51 from "path";
|
|
11448
11844
|
|
|
11449
11845
|
// src/mission-control/live-run.ts
|
|
11450
11846
|
import { readFile as readFile25 } from "fs/promises";
|
|
11451
|
-
import
|
|
11847
|
+
import path48 from "path";
|
|
11452
11848
|
|
|
11453
11849
|
// src/plan-loop/plan-state.ts
|
|
11454
11850
|
import { readFile as readFile24, readdir as readdir11 } from "fs/promises";
|
|
11455
|
-
import
|
|
11851
|
+
import path47 from "path";
|
|
11456
11852
|
function countPendingTodos(raw) {
|
|
11457
11853
|
const lines = raw.split(/\r?\n/);
|
|
11458
11854
|
let inFront = 0;
|
|
@@ -11480,7 +11876,7 @@ function countPendingTodos(raw) {
|
|
|
11480
11876
|
async function findActivePlanFile(plansDir) {
|
|
11481
11877
|
if (!await fileExists(plansDir)) return null;
|
|
11482
11878
|
const files = (await readdir11(plansDir)).filter((f) => f.endsWith(".plan.md")).sort();
|
|
11483
|
-
return files[0] ?
|
|
11879
|
+
return files[0] ? path47.join(plansDir, files[0]) : null;
|
|
11484
11880
|
}
|
|
11485
11881
|
async function readPlan(planPath) {
|
|
11486
11882
|
return readFile24(planPath, "utf8");
|
|
@@ -11668,7 +12064,7 @@ function firstWord(raw) {
|
|
|
11668
12064
|
}
|
|
11669
12065
|
async function readLiveMission(root, io = defaultMissionIo()) {
|
|
11670
12066
|
const mission = emptyLiveMission();
|
|
11671
|
-
const handoff = await io.readFile(
|
|
12067
|
+
const handoff = await io.readFile(path48.join(root, ".cursor", "HANDOFF.md")) ?? "";
|
|
11672
12068
|
const named = extractHandoffNamedPlans(handoff);
|
|
11673
12069
|
mission.mode = firstWord(MODE_RE.exec(handoff)?.[1]);
|
|
11674
12070
|
let cursorIndex = null;
|
|
@@ -11704,13 +12100,13 @@ async function readLiveMission(root, io = defaultMissionIo()) {
|
|
|
11704
12100
|
state: finished || cursor !== null && i < cursor ? "done" : i === cursor ? "current" : "pending"
|
|
11705
12101
|
}));
|
|
11706
12102
|
}
|
|
11707
|
-
const plansDir =
|
|
12103
|
+
const plansDir = path48.join(root, ".cursor", "plans");
|
|
11708
12104
|
const planBase = (mission.queue && !finished ? mission.queue.current : null) ?? named.active;
|
|
11709
|
-
const planPath = planBase ?
|
|
12105
|
+
const planPath = planBase ? path48.join(plansDir, planBase) : await io.findActivePlan(plansDir);
|
|
11710
12106
|
if (planPath) {
|
|
11711
12107
|
const raw = await io.readFile(planPath);
|
|
11712
12108
|
if (raw !== null) {
|
|
11713
|
-
mission.planFile =
|
|
12109
|
+
mission.planFile = path48.basename(planPath);
|
|
11714
12110
|
const { todos } = parsePlanFrontmatter2(raw);
|
|
11715
12111
|
const open = todos.filter((t) => t.status !== "cancelled");
|
|
11716
12112
|
mission.todos = {
|
|
@@ -11761,7 +12157,7 @@ async function withLiveTui(opts, run) {
|
|
|
11761
12157
|
columns,
|
|
11762
12158
|
now: now2,
|
|
11763
12159
|
backend: opts.backend,
|
|
11764
|
-
logPath:
|
|
12160
|
+
logPath: path48.relative(opts.root, opts.logPath) || opts.logPath
|
|
11765
12161
|
});
|
|
11766
12162
|
opts.onFeed?.(feed);
|
|
11767
12163
|
const missionLoader = opts.missionLoader ?? createLiveMissionLoader(opts.root, { now: now2 });
|
|
@@ -11898,9 +12294,9 @@ async function withLiveTui(opts, run) {
|
|
|
11898
12294
|
|
|
11899
12295
|
// src/plan-loop/external-review.ts
|
|
11900
12296
|
import { spawn as spawn8 } from "child_process";
|
|
11901
|
-
import
|
|
11902
|
-
var CANONICAL_REL =
|
|
11903
|
-
var FALLBACK_REL =
|
|
12297
|
+
import path49 from "path";
|
|
12298
|
+
var CANONICAL_REL = path49.join(".cursor", "scripts", "plan-external-review.sh");
|
|
12299
|
+
var FALLBACK_REL = path49.join("scripts", "plan-external-review.sh");
|
|
11904
12300
|
function isPlanExhaustedReason(reason) {
|
|
11905
12301
|
const r = reason.trim().toLowerCase();
|
|
11906
12302
|
if (!r) return false;
|
|
@@ -11922,8 +12318,8 @@ async function armExternalPlanReview(root, options = {}) {
|
|
|
11922
12318
|
const existsFn = options.existsFn ?? fileExists;
|
|
11923
12319
|
const log = options.log ?? ((line) => console.log(line));
|
|
11924
12320
|
const force = options.force === true;
|
|
11925
|
-
const canonicalPath =
|
|
11926
|
-
const fallbackPath =
|
|
12321
|
+
const canonicalPath = path49.join(root, CANONICAL_REL);
|
|
12322
|
+
const fallbackPath = path49.join(root, FALLBACK_REL);
|
|
11927
12323
|
let scriptPath = null;
|
|
11928
12324
|
let scriptRel = CANONICAL_REL;
|
|
11929
12325
|
if (await existsFn(canonicalPath)) {
|
|
@@ -11976,7 +12372,7 @@ async function armExternalPlanReview(root, options = {}) {
|
|
|
11976
12372
|
}
|
|
11977
12373
|
|
|
11978
12374
|
// src/plan-loop/persona-banners.ts
|
|
11979
|
-
import
|
|
12375
|
+
import path50 from "path";
|
|
11980
12376
|
import {
|
|
11981
12377
|
blue,
|
|
11982
12378
|
cyan as cyan4,
|
|
@@ -12012,7 +12408,7 @@ function resolveColor(name, fallback) {
|
|
|
12012
12408
|
async function resolveCliPersonaId(root) {
|
|
12013
12409
|
try {
|
|
12014
12410
|
const cfg = await readJson(
|
|
12015
|
-
|
|
12411
|
+
path50.join(root, ".cursor", "context", "config.json")
|
|
12016
12412
|
);
|
|
12017
12413
|
const modes = cfg?.agentPersona?.modes ?? cfg?.workspaceSkin?.modes;
|
|
12018
12414
|
const id = modes?.[CLI_RUN_PLAN_MODE];
|
|
@@ -12023,7 +12419,7 @@ async function resolveCliPersonaId(root) {
|
|
|
12023
12419
|
}
|
|
12024
12420
|
async function loadPersonaPack(root, personaId) {
|
|
12025
12421
|
try {
|
|
12026
|
-
const personaPath =
|
|
12422
|
+
const personaPath = path50.join(root, "registry", "personas", "core", personaId, "persona.json");
|
|
12027
12423
|
const pack = await readJson(personaPath);
|
|
12028
12424
|
if (!pack || typeof pack.id !== "string") return null;
|
|
12029
12425
|
return pack;
|
|
@@ -12202,9 +12598,9 @@ function sleep(ms) {
|
|
|
12202
12598
|
return new Promise((r) => setTimeout(r, ms));
|
|
12203
12599
|
}
|
|
12204
12600
|
async function runPlanLoop(opts) {
|
|
12205
|
-
const plansDir =
|
|
12206
|
-
const stopFile =
|
|
12207
|
-
const logDir =
|
|
12601
|
+
const plansDir = path51.join(opts.root, ".cursor", "plans");
|
|
12602
|
+
const stopFile = path51.join(opts.root, ".cursor", "loop.stop");
|
|
12603
|
+
const logDir = path51.join(opts.root, ".cursor", "loop-logs");
|
|
12208
12604
|
const planPath = await findActivePlanFile(plansDir);
|
|
12209
12605
|
if (!planPath) {
|
|
12210
12606
|
logger.error("No active plan in .cursor/plans/");
|
|
@@ -12225,7 +12621,7 @@ async function runPlanLoop(opts) {
|
|
|
12225
12621
|
try {
|
|
12226
12622
|
const persona = await loadCliRunPlanPersona(opts.root);
|
|
12227
12623
|
const banners = createPersonaBannerPrinter(persona);
|
|
12228
|
-
console.log(`Active plan: ${
|
|
12624
|
+
console.log(`Active plan: ${path51.basename(planPath)}`);
|
|
12229
12625
|
console.log(`Pending to-dos: ${await pending()} | max ticks: ${opts.maxTicks}`);
|
|
12230
12626
|
console.log(`Backend: ${opts.backend.id}`);
|
|
12231
12627
|
if (persona) {
|
|
@@ -12269,8 +12665,8 @@ async function runPlanLoop(opts) {
|
|
|
12269
12665
|
planExhausted = true;
|
|
12270
12666
|
break;
|
|
12271
12667
|
}
|
|
12272
|
-
const logPath =
|
|
12273
|
-
const relLog =
|
|
12668
|
+
const logPath = path51.join(logDir, `tick-${stamp()}.log`);
|
|
12669
|
+
const relLog = path51.relative(opts.root, logPath);
|
|
12274
12670
|
console.log("");
|
|
12275
12671
|
const tickLine = `=== tick ${tick}/${opts.maxTicks} - pending: ${before} - log: ${relLog} ===`;
|
|
12276
12672
|
if (banners) banners.tickStart(tickLine);
|
|
@@ -12378,7 +12774,7 @@ async function runPlanLoop(opts) {
|
|
|
12378
12774
|
const finishDetail = `after ${tick} tick(s); pending: ${pendingNow}`;
|
|
12379
12775
|
if (banners) banners.phaseComplete(finishDetail);
|
|
12380
12776
|
console.log(
|
|
12381
|
-
`Loop finished after ${tick} tick(s). Pending now: ${pendingNow}. Logs in ${
|
|
12777
|
+
`Loop finished after ${tick} tick(s). Pending now: ${pendingNow}. Logs in ${path51.relative(opts.root, logDir)}/`
|
|
12382
12778
|
);
|
|
12383
12779
|
if (planExhausted || shouldArmExternalPlanReview({ pending: pendingNow, stopReason })) {
|
|
12384
12780
|
await armExternalPlanReview(opts.root);
|
|
@@ -12390,7 +12786,7 @@ async function runPlanLoop(opts) {
|
|
|
12390
12786
|
}
|
|
12391
12787
|
|
|
12392
12788
|
// src/commands/run-plan.ts
|
|
12393
|
-
var runPlanCommand =
|
|
12789
|
+
var runPlanCommand = defineCommand17({
|
|
12394
12790
|
meta: {
|
|
12395
12791
|
name: "run-plan",
|
|
12396
12792
|
description: "Headless continuous plan runner (one fresh agent per tick). Never git-prod."
|
|
@@ -12470,7 +12866,7 @@ var runPlanCommand = defineCommand16({
|
|
|
12470
12866
|
return;
|
|
12471
12867
|
}
|
|
12472
12868
|
const code = await runPlanLoop({
|
|
12473
|
-
root:
|
|
12869
|
+
root: path52.resolve(args.cwd),
|
|
12474
12870
|
maxTicks,
|
|
12475
12871
|
sleepSeconds,
|
|
12476
12872
|
model: args.model ? String(args.model) : void 0,
|
|
@@ -12485,12 +12881,12 @@ var runPlanCommand = defineCommand16({
|
|
|
12485
12881
|
|
|
12486
12882
|
// src/commands/run.ts
|
|
12487
12883
|
import { homedir as homedir4 } from "os";
|
|
12488
|
-
import
|
|
12489
|
-
import { defineCommand as
|
|
12884
|
+
import path54 from "path";
|
|
12885
|
+
import { defineCommand as defineCommand18 } from "citty";
|
|
12490
12886
|
|
|
12491
12887
|
// src/plan-loop/dispatch.ts
|
|
12492
12888
|
import { mkdir as mkdir7, readFile as readFile28 } from "fs/promises";
|
|
12493
|
-
import
|
|
12889
|
+
import path53 from "path";
|
|
12494
12890
|
var RUN_CATALOG = [
|
|
12495
12891
|
"run-plan",
|
|
12496
12892
|
"run-plan-all",
|
|
@@ -12533,7 +12929,7 @@ function rewriteRootArgvToRun(argv) {
|
|
|
12533
12929
|
return next;
|
|
12534
12930
|
}
|
|
12535
12931
|
function commandMarkdownPath(root, name) {
|
|
12536
|
-
return
|
|
12932
|
+
return path53.join(root, ".cursor", "commands", `${normalizeSlashName(name)}.md`);
|
|
12537
12933
|
}
|
|
12538
12934
|
function buildDispatchPrompt(commandBody) {
|
|
12539
12935
|
return [
|
|
@@ -12621,20 +13017,20 @@ async function runHeadlessDispatch(opts) {
|
|
|
12621
13017
|
});
|
|
12622
13018
|
}
|
|
12623
13019
|
async function ensureDispatchLogPath(root) {
|
|
12624
|
-
const logDir =
|
|
13020
|
+
const logDir = path53.join(root, ".cursor", "loop-logs");
|
|
12625
13021
|
await mkdir7(logDir, { recursive: true });
|
|
12626
|
-
return
|
|
13022
|
+
return path53.join(logDir, `run-${stamp2()}.log`);
|
|
12627
13023
|
}
|
|
12628
13024
|
|
|
12629
13025
|
// src/commands/run.ts
|
|
12630
13026
|
function displayPath(target, home = homedir4()) {
|
|
12631
|
-
const resolvedHome =
|
|
13027
|
+
const resolvedHome = path54.resolve(home);
|
|
12632
13028
|
if (target === resolvedHome) return "~";
|
|
12633
|
-
const prefix = resolvedHome.endsWith(
|
|
12634
|
-
return target.startsWith(prefix) ? `~${
|
|
13029
|
+
const prefix = resolvedHome.endsWith(path54.sep) ? resolvedHome : `${resolvedHome}${path54.sep}`;
|
|
13030
|
+
return target.startsWith(prefix) ? `~${path54.sep}${target.slice(prefix.length)}` : target;
|
|
12635
13031
|
}
|
|
12636
13032
|
async function executeRun(input) {
|
|
12637
|
-
const root =
|
|
13033
|
+
const root = path54.resolve(input.cwd);
|
|
12638
13034
|
const slash = normalizeSlashName(input.slash);
|
|
12639
13035
|
if (!slash) {
|
|
12640
13036
|
return { exitCode: 1, error: "Provide a slash: agent-kit run <slash>" };
|
|
@@ -12685,7 +13081,7 @@ async function executeRun(input) {
|
|
|
12685
13081
|
const stdout = [
|
|
12686
13082
|
"--dry-run: no agent will be started.",
|
|
12687
13083
|
`Slash: ${slash}`,
|
|
12688
|
-
`Command file: ${
|
|
13084
|
+
`Command file: ${path54.relative(root, file.path)}`,
|
|
12689
13085
|
`Backend: ${detected.id} (${displayPath(detected.bin)})`,
|
|
12690
13086
|
"Prompt:",
|
|
12691
13087
|
prompt
|
|
@@ -12694,8 +13090,8 @@ async function executeRun(input) {
|
|
|
12694
13090
|
}
|
|
12695
13091
|
const logPath = await ensureDispatchLogPath(root);
|
|
12696
13092
|
console.log(`Dispatch: ${slash} via ${detected.id}`);
|
|
12697
|
-
console.log(`Command file: ${
|
|
12698
|
-
console.log(`Log: ${
|
|
13093
|
+
console.log(`Command file: ${path54.relative(root, file.path)}`);
|
|
13094
|
+
console.log(`Log: ${path54.relative(root, logPath)}`);
|
|
12699
13095
|
try {
|
|
12700
13096
|
const dispatch = {
|
|
12701
13097
|
backendId: detected.id,
|
|
@@ -12798,7 +13194,7 @@ async function runSlashCli(slash, args) {
|
|
|
12798
13194
|
}
|
|
12799
13195
|
process.exitCode = result.exitCode;
|
|
12800
13196
|
}
|
|
12801
|
-
var runCommand =
|
|
13197
|
+
var runCommand = defineCommand18({
|
|
12802
13198
|
meta: {
|
|
12803
13199
|
name: "run",
|
|
12804
13200
|
description: "Start one headless session from an L0 slash file. Numbered-list HITL answered from the terminal (claude backend). Never git-prod."
|
|
@@ -12815,7 +13211,7 @@ var runCommand = defineCommand17({
|
|
|
12815
13211
|
await runSlashCli(String(args.slash ?? ""), args);
|
|
12816
13212
|
}
|
|
12817
13213
|
});
|
|
12818
|
-
var runPlanAllCommand =
|
|
13214
|
+
var runPlanAllCommand = defineCommand18({
|
|
12819
13215
|
meta: {
|
|
12820
13216
|
name: "run-plan-all",
|
|
12821
13217
|
description: "Headless /run-plan-all queue from the L0 file. Numbered-list HITL answered from the terminal (claude backend). Never git-prod."
|
|
@@ -12827,8 +13223,8 @@ var runPlanAllCommand = defineCommand17({
|
|
|
12827
13223
|
});
|
|
12828
13224
|
|
|
12829
13225
|
// src/commands/scan.ts
|
|
12830
|
-
import { defineCommand as
|
|
12831
|
-
var scanCommand =
|
|
13226
|
+
import { defineCommand as defineCommand19 } from "citty";
|
|
13227
|
+
var scanCommand = defineCommand19({
|
|
12832
13228
|
meta: {
|
|
12833
13229
|
name: "scan",
|
|
12834
13230
|
description: "Scan the repository and print the detected profile."
|
|
@@ -12852,18 +13248,18 @@ var scanCommand = defineCommand18({
|
|
|
12852
13248
|
import { spawn as spawn9 } from "child_process";
|
|
12853
13249
|
import { appendFile as appendFile2, mkdir as mkdir8, readFile as readFile29, writeFile as writeFile13 } from "fs/promises";
|
|
12854
13250
|
import { homedir as homedir5 } from "os";
|
|
12855
|
-
import
|
|
13251
|
+
import path55 from "path";
|
|
12856
13252
|
import { confirm as confirm2, isCancel as isCancel2 } from "@clack/prompts";
|
|
12857
|
-
import { defineCommand as
|
|
13253
|
+
import { defineCommand as defineCommand20 } from "citty";
|
|
12858
13254
|
import { cyan as cyan5, green as green4, yellow as yellow3 } from "kolorist";
|
|
12859
13255
|
var NPM_GLOBAL_DIR_NAME = ".npm-global";
|
|
12860
13256
|
var SETUP_GLOBAL_MARKER = "# agent-kit setup-global";
|
|
12861
13257
|
function planSetupGlobalSteps(env, options = {}) {
|
|
12862
13258
|
const homeDir = options.homeDir ?? homedir5();
|
|
12863
13259
|
const packageSpec = options.packageSpec ?? pinnedCliSpec();
|
|
12864
|
-
const npmGlobalDir =
|
|
12865
|
-
const npmGlobalBin =
|
|
12866
|
-
const npmrcPath =
|
|
13260
|
+
const npmGlobalDir = path55.join(homeDir, NPM_GLOBAL_DIR_NAME);
|
|
13261
|
+
const npmGlobalBin = path55.join(npmGlobalDir, "bin");
|
|
13262
|
+
const npmrcPath = path55.join(homeDir, ".npmrc");
|
|
12867
13263
|
const npmrcPrefixValue = `~/${NPM_GLOBAL_DIR_NAME}`;
|
|
12868
13264
|
const pathExportLine = `export PATH="${npmGlobalBin}:$PATH"`;
|
|
12869
13265
|
const shellProfile = env.shellProfile;
|
|
@@ -13133,7 +13529,7 @@ ${verifyStep.title}`);
|
|
|
13133
13529
|
}
|
|
13134
13530
|
return { exitCode: 0, mutated, outcome: "completed", env, plan };
|
|
13135
13531
|
}
|
|
13136
|
-
var setupGlobalCommand =
|
|
13532
|
+
var setupGlobalCommand = defineCommand20({
|
|
13137
13533
|
meta: {
|
|
13138
13534
|
name: "setup-global",
|
|
13139
13535
|
description: "Self-heal a root-owned npm prefix: relocate to ~/.npm-global, fix PATH, reinstall globally."
|
|
@@ -13162,8 +13558,8 @@ var setupGlobalCommand = defineCommand19({
|
|
|
13162
13558
|
});
|
|
13163
13559
|
|
|
13164
13560
|
// src/commands/status.ts
|
|
13165
|
-
import
|
|
13166
|
-
import { defineCommand as
|
|
13561
|
+
import path56 from "path";
|
|
13562
|
+
import { defineCommand as defineCommand21 } from "citty";
|
|
13167
13563
|
function profileStatus(profile) {
|
|
13168
13564
|
if (!profile) return { origin: "none", evidence: [], profile: null };
|
|
13169
13565
|
if ("detection" in profile && profile.detection && typeof profile.detection === "object") {
|
|
@@ -13176,7 +13572,7 @@ function profileStatus(profile) {
|
|
|
13176
13572
|
}
|
|
13177
13573
|
return { origin: "legacy-wizard", evidence: [], profile };
|
|
13178
13574
|
}
|
|
13179
|
-
var statusCommand =
|
|
13575
|
+
var statusCommand = defineCommand21({
|
|
13180
13576
|
meta: {
|
|
13181
13577
|
name: "status",
|
|
13182
13578
|
description: "Show installed kit version, manifest, and optional profile."
|
|
@@ -13193,11 +13589,11 @@ var statusCommand = defineCommand20({
|
|
|
13193
13589
|
}
|
|
13194
13590
|
},
|
|
13195
13591
|
async run({ args }) {
|
|
13196
|
-
const rootDir =
|
|
13592
|
+
const rootDir = path56.resolve(args.cwd);
|
|
13197
13593
|
const [manifest, rawProfile, scan, env] = await Promise.all([
|
|
13198
13594
|
loadAgentKitManifest(rootDir),
|
|
13199
13595
|
readJson(
|
|
13200
|
-
|
|
13596
|
+
path56.join(rootDir, ".cursor", "agent-kit.config.json")
|
|
13201
13597
|
),
|
|
13202
13598
|
runScanner(rootDir),
|
|
13203
13599
|
assessEnvironment()
|
|
@@ -13264,8 +13660,8 @@ var statusCommand = defineCommand20({
|
|
|
13264
13660
|
});
|
|
13265
13661
|
|
|
13266
13662
|
// src/commands/update.ts
|
|
13267
|
-
import { defineCommand as
|
|
13268
|
-
var updateCommand =
|
|
13663
|
+
import { defineCommand as defineCommand22 } from "citty";
|
|
13664
|
+
var updateCommand = defineCommand22({
|
|
13269
13665
|
meta: {
|
|
13270
13666
|
name: "update",
|
|
13271
13667
|
description: "Re-apply L0/packs/skills from the registry (never overwrites L3). --check = notify-only."
|
|
@@ -13433,8 +13829,8 @@ ${err.recovery}
|
|
|
13433
13829
|
|
|
13434
13830
|
// src/commands/validate.ts
|
|
13435
13831
|
import { readFile as readFile30 } from "fs/promises";
|
|
13436
|
-
import
|
|
13437
|
-
import { defineCommand as
|
|
13832
|
+
import path57 from "path";
|
|
13833
|
+
import { defineCommand as defineCommand23 } from "citty";
|
|
13438
13834
|
|
|
13439
13835
|
// src/invariants/plan-schema.ts
|
|
13440
13836
|
var CITE5 = "agent-kit validate plan (.cursor/context/templates/plan.md)";
|
|
@@ -13480,7 +13876,7 @@ function validatePlanFrontmatterText(text) {
|
|
|
13480
13876
|
// src/commands/validate.ts
|
|
13481
13877
|
async function resolveEditedPath(cwd, explicit) {
|
|
13482
13878
|
if (explicit) {
|
|
13483
|
-
const filePath2 =
|
|
13879
|
+
const filePath2 = path57.resolve(cwd, explicit);
|
|
13484
13880
|
try {
|
|
13485
13881
|
return { filePath: filePath2, content: await readFile30(filePath2, "utf8") };
|
|
13486
13882
|
} catch {
|
|
@@ -13490,7 +13886,7 @@ async function resolveEditedPath(cwd, explicit) {
|
|
|
13490
13886
|
const payload = await readStdinJson();
|
|
13491
13887
|
const rel = typeof payload.file_path === "string" && payload.file_path || typeof payload.path === "string" && payload.path || typeof payload.file === "string" && payload.file || "";
|
|
13492
13888
|
if (!rel) return null;
|
|
13493
|
-
const filePath =
|
|
13889
|
+
const filePath = path57.isAbsolute(rel) ? rel : path57.resolve(cwd, rel);
|
|
13494
13890
|
try {
|
|
13495
13891
|
return { filePath, content: await readFile30(filePath, "utf8") };
|
|
13496
13892
|
} catch {
|
|
@@ -13504,13 +13900,13 @@ function isPlanPath(filePath) {
|
|
|
13504
13900
|
const norm = filePath.replace(/\\/g, "/");
|
|
13505
13901
|
return norm.includes("/.cursor/plans/") && norm.endsWith(".plan.md");
|
|
13506
13902
|
}
|
|
13507
|
-
var validateCommand =
|
|
13903
|
+
var validateCommand = defineCommand23({
|
|
13508
13904
|
meta: {
|
|
13509
13905
|
name: "validate",
|
|
13510
13906
|
description: "Advisory validators for HANDOFF / plan frontmatter (hook adapter)."
|
|
13511
13907
|
},
|
|
13512
13908
|
subCommands: {
|
|
13513
|
-
handoff:
|
|
13909
|
+
handoff: defineCommand23({
|
|
13514
13910
|
meta: { name: "handoff", description: "Validate HANDOFF machine fields" },
|
|
13515
13911
|
args: {
|
|
13516
13912
|
cwd: { type: "string", default: process.cwd() },
|
|
@@ -13520,7 +13916,7 @@ var validateCommand = defineCommand22({
|
|
|
13520
13916
|
async run({ args }) {
|
|
13521
13917
|
const cwd = typeof args.cwd === "string" ? args.cwd : process.cwd();
|
|
13522
13918
|
const fileArg = typeof args.file === "string" ? args.file : void 0;
|
|
13523
|
-
const filePath = fileArg ?
|
|
13919
|
+
const filePath = fileArg ? path57.resolve(cwd, fileArg) : path57.join(path57.resolve(cwd), ".cursor", "HANDOFF.md");
|
|
13524
13920
|
let content = "";
|
|
13525
13921
|
try {
|
|
13526
13922
|
content = await readFile30(filePath, "utf8");
|
|
@@ -13538,7 +13934,7 @@ var validateCommand = defineCommand22({
|
|
|
13538
13934
|
console.log(JSON.stringify({ ok: warnings.length === 0, warnings }));
|
|
13539
13935
|
}
|
|
13540
13936
|
}),
|
|
13541
|
-
plan:
|
|
13937
|
+
plan: defineCommand23({
|
|
13542
13938
|
meta: { name: "plan", description: "Validate plan frontmatter" },
|
|
13543
13939
|
args: {
|
|
13544
13940
|
cwd: { type: "string", default: process.cwd() },
|
|
@@ -13553,7 +13949,7 @@ var validateCommand = defineCommand22({
|
|
|
13553
13949
|
process.exitCode = 2;
|
|
13554
13950
|
return;
|
|
13555
13951
|
}
|
|
13556
|
-
const filePath =
|
|
13952
|
+
const filePath = path57.resolve(cwd, fileArg);
|
|
13557
13953
|
let content = "";
|
|
13558
13954
|
try {
|
|
13559
13955
|
content = await readFile30(filePath, "utf8");
|
|
@@ -13565,7 +13961,7 @@ var validateCommand = defineCommand22({
|
|
|
13565
13961
|
console.log(JSON.stringify({ ok: warnings.length === 0, warnings }));
|
|
13566
13962
|
}
|
|
13567
13963
|
}),
|
|
13568
|
-
"after-edit":
|
|
13964
|
+
"after-edit": defineCommand23({
|
|
13569
13965
|
meta: {
|
|
13570
13966
|
name: "after-edit",
|
|
13571
13967
|
description: "Advisory afterFileEdit: annotate HANDOFF/plan issues (never block)"
|
|
@@ -13575,7 +13971,7 @@ var validateCommand = defineCommand22({
|
|
|
13575
13971
|
},
|
|
13576
13972
|
async run({ args }) {
|
|
13577
13973
|
const cwd = typeof args.cwd === "string" ? args.cwd : process.cwd();
|
|
13578
|
-
const resolved = await resolveEditedPath(
|
|
13974
|
+
const resolved = await resolveEditedPath(path57.resolve(cwd));
|
|
13579
13975
|
if (!resolved) {
|
|
13580
13976
|
console.log(JSON.stringify({}));
|
|
13581
13977
|
return;
|
|
@@ -13726,7 +14122,15 @@ var CLI_HELP_GROUPS = [
|
|
|
13726
14122
|
{
|
|
13727
14123
|
id: "integrity",
|
|
13728
14124
|
title: "INTEGRITY",
|
|
13729
|
-
commands: [
|
|
14125
|
+
commands: [
|
|
14126
|
+
"validate",
|
|
14127
|
+
"guard",
|
|
14128
|
+
"hook",
|
|
14129
|
+
"cursor-awareness",
|
|
14130
|
+
"public-inbound-radar",
|
|
14131
|
+
"diff",
|
|
14132
|
+
"contribute"
|
|
14133
|
+
]
|
|
13730
14134
|
}
|
|
13731
14135
|
];
|
|
13732
14136
|
async function resolveCommandMeta(meta) {
|
|
@@ -13794,7 +14198,7 @@ async function renderGroupedRootHelp(cmd) {
|
|
|
13794
14198
|
var rewrittenArgv = rewriteRootArgvToRun(process.argv.slice(2));
|
|
13795
14199
|
process.argv.length = 2;
|
|
13796
14200
|
process.argv.push(...rewrittenArgv);
|
|
13797
|
-
var main =
|
|
14201
|
+
var main = defineCommand24({
|
|
13798
14202
|
meta: {
|
|
13799
14203
|
name: "agent-kit",
|
|
13800
14204
|
description: "HITL framework for AI-assisted IDEs (Mission Kit family)",
|
|
@@ -13810,6 +14214,7 @@ var main = defineCommand23({
|
|
|
13810
14214
|
status: statusCommand,
|
|
13811
14215
|
update: updateCommand,
|
|
13812
14216
|
"cursor-awareness": cursorAwarenessCommand,
|
|
14217
|
+
"public-inbound-radar": publicInboundRadarCommand,
|
|
13813
14218
|
diff: diffCommand,
|
|
13814
14219
|
contribute: contributeCommand,
|
|
13815
14220
|
handoff: handoffCommand,
|