@autopilot-harness/cli 0.1.0 → 0.2.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/README.md +1 -1
- package/assets/autopilot-harness-hook.mjs +292 -39
- package/assets/vendor/runtime.mjs +397 -15
- package/dist/assets/autopilot-harness-hook.mjs +292 -39
- package/dist/assets/vendor/runtime.mjs +397 -15
- package/dist/bin.js +6 -3
- package/dist/bin.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/init/claude-settings-merge.d.ts +56 -0
- package/dist/init/claude-settings-merge.d.ts.map +1 -0
- package/dist/init/claude-settings-merge.js +347 -0
- package/dist/init/claude-settings-merge.js.map +1 -0
- package/dist/init/hooks-merge.d.ts +12 -0
- package/dist/init/hooks-merge.d.ts.map +1 -1
- package/dist/init/hooks-merge.js +55 -1
- package/dist/init/hooks-merge.js.map +1 -1
- package/dist/init/install.d.ts +4 -1
- package/dist/init/install.d.ts.map +1 -1
- package/dist/init/install.js +258 -83
- package/dist/init/install.js.map +1 -1
- package/dist/init/platforms.d.ts +5 -0
- package/dist/init/platforms.d.ts.map +1 -1
- package/dist/init/platforms.js +17 -0
- package/dist/init/platforms.js.map +1 -1
- package/dist/init/types.d.ts +1 -1
- package/dist/init/types.js +1 -1
- package/dist/init/wizard-helpers.d.ts.map +1 -1
- package/dist/init/wizard-helpers.js +21 -10
- package/dist/init/wizard-helpers.js.map +1 -1
- package/dist/status-doctor.d.ts.map +1 -1
- package/dist/status-doctor.js +132 -56
- package/dist/status-doctor.js.map +1 -1
- package/dist/uninstall.d.ts.map +1 -1
- package/dist/uninstall.js +163 -5
- package/dist/uninstall.js.map +1 -1
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +100 -2
- package/dist/upgrade.js.map +1 -1
- package/dist/vendor-entry.d.ts +4 -1
- package/dist/vendor-entry.d.ts.map +1 -1
- package/dist/vendor-entry.js +6 -2
- package/dist/vendor-entry.js.map +1 -1
- package/package.json +5 -4
|
@@ -1748,7 +1748,27 @@ function getLens(roundIndex, confirmRounds) {
|
|
|
1748
1748
|
}
|
|
1749
1749
|
|
|
1750
1750
|
// ../core/src/review-scope.ts
|
|
1751
|
-
|
|
1751
|
+
var MAX_SESSION_PLATFORM_CHARS = 64;
|
|
1752
|
+
function normalizeSessionPlatform(raw) {
|
|
1753
|
+
if (typeof raw !== "string") return "cursor";
|
|
1754
|
+
if (raw.includes("\0")) return "cursor";
|
|
1755
|
+
const trimmed = raw.trim();
|
|
1756
|
+
if (!trimmed) return "cursor";
|
|
1757
|
+
if (trimmed.length > MAX_SESSION_PLATFORM_CHARS) return "cursor";
|
|
1758
|
+
if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/i.test(trimmed)) return "cursor";
|
|
1759
|
+
return trimmed.toLowerCase();
|
|
1760
|
+
}
|
|
1761
|
+
function resolveSessionPlatform(optsPlatform, fallback = "cursor") {
|
|
1762
|
+
const fb = normalizeSessionPlatform(fallback);
|
|
1763
|
+
if (optsPlatform === void 0 || optsPlatform === null) return fb;
|
|
1764
|
+
if (typeof optsPlatform !== "string") return fb;
|
|
1765
|
+
const raw = optsPlatform.trim();
|
|
1766
|
+
if (!raw) return fb;
|
|
1767
|
+
const n = normalizeSessionPlatform(optsPlatform);
|
|
1768
|
+
if (n === "cursor" && raw.toLowerCase() !== "cursor") return fb;
|
|
1769
|
+
return n;
|
|
1770
|
+
}
|
|
1771
|
+
function ensureAmbientReviewSession(store, conversationId, projectRoot, reviewScope, platform) {
|
|
1752
1772
|
if (reviewScope !== "project") return false;
|
|
1753
1773
|
if (!store.isConversationIdOk(conversationId)) return false;
|
|
1754
1774
|
const root = normalizeProjectRoot(store.projectRoot) ?? normalizeProjectRoot(projectRoot);
|
|
@@ -1763,6 +1783,7 @@ function ensureAmbientReviewSession(store, conversationId, projectRoot, reviewSc
|
|
|
1763
1783
|
if (!fresh || fresh.paused !== 0 || !(fresh.phase === "done" || fresh.phase === "idle" && fresh.armed === 0)) {
|
|
1764
1784
|
return { commit: false, value: void 0 };
|
|
1765
1785
|
}
|
|
1786
|
+
const host2 = resolveSessionPlatform(platform, fresh.platform);
|
|
1766
1787
|
store.upsertSession({
|
|
1767
1788
|
conversation_id: conversationId,
|
|
1768
1789
|
project_root: root,
|
|
@@ -1770,14 +1791,26 @@ function ensureAmbientReviewSession(store, conversationId, projectRoot, reviewSc
|
|
|
1770
1791
|
phase: "idle",
|
|
1771
1792
|
armed: 1,
|
|
1772
1793
|
paused: 0,
|
|
1773
|
-
paused_reason: null
|
|
1794
|
+
paused_reason: null,
|
|
1795
|
+
platform: host2
|
|
1774
1796
|
});
|
|
1775
1797
|
store.neutralizeReviewChain(conversationId);
|
|
1776
1798
|
return { commit: true, value: void 0 };
|
|
1777
1799
|
});
|
|
1800
|
+
} else {
|
|
1801
|
+
const host2 = resolveSessionPlatform(platform, existing.platform);
|
|
1802
|
+
if (host2 !== existing.platform) {
|
|
1803
|
+
store.upsertSession({
|
|
1804
|
+
conversation_id: conversationId,
|
|
1805
|
+
project_root: existing.project_root,
|
|
1806
|
+
code_root: existing.code_root,
|
|
1807
|
+
platform: host2
|
|
1808
|
+
});
|
|
1809
|
+
}
|
|
1778
1810
|
}
|
|
1779
1811
|
return true;
|
|
1780
1812
|
}
|
|
1813
|
+
const host = normalizeSessionPlatform(platform);
|
|
1781
1814
|
store.exclusiveWrite(() => {
|
|
1782
1815
|
if (store.getSession(conversationId)) {
|
|
1783
1816
|
return { commit: false, value: void 0 };
|
|
@@ -1786,7 +1819,7 @@ function ensureAmbientReviewSession(store, conversationId, projectRoot, reviewSc
|
|
|
1786
1819
|
conversation_id: conversationId,
|
|
1787
1820
|
project_root: root,
|
|
1788
1821
|
code_root: root,
|
|
1789
|
-
platform:
|
|
1822
|
+
platform: host,
|
|
1790
1823
|
phase: "idle",
|
|
1791
1824
|
armed: 1,
|
|
1792
1825
|
paused: 0,
|
|
@@ -2365,7 +2398,8 @@ var ReviewEngine = class {
|
|
|
2365
2398
|
this.store,
|
|
2366
2399
|
input.conversationId,
|
|
2367
2400
|
this.config.projectRoot,
|
|
2368
|
-
this.config.reviewScope
|
|
2401
|
+
this.config.reviewScope,
|
|
2402
|
+
input.platform
|
|
2369
2403
|
);
|
|
2370
2404
|
session = this.store.getSession(input.conversationId);
|
|
2371
2405
|
}
|
|
@@ -3943,6 +3977,10 @@ function applyOn(store, conversationId, projectRoot, opts) {
|
|
|
3943
3977
|
};
|
|
3944
3978
|
}
|
|
3945
3979
|
const trackId = opts?.slug ?? session?.track_id ?? "_pending";
|
|
3980
|
+
const platform = resolveSessionPlatform(
|
|
3981
|
+
opts?.platform,
|
|
3982
|
+
session?.platform ?? "cursor"
|
|
3983
|
+
);
|
|
3946
3984
|
if (session?.phase === "done") {
|
|
3947
3985
|
const s2 = store.upsertSession({
|
|
3948
3986
|
conversation_id: conversationId,
|
|
@@ -3953,7 +3991,7 @@ function applyOn(store, conversationId, projectRoot, opts) {
|
|
|
3953
3991
|
paused: 0,
|
|
3954
3992
|
paused_reason: null,
|
|
3955
3993
|
track_id: opts?.slug ?? session.track_id,
|
|
3956
|
-
platform
|
|
3994
|
+
platform
|
|
3957
3995
|
});
|
|
3958
3996
|
return { ok: true, session: s2 };
|
|
3959
3997
|
}
|
|
@@ -3961,7 +3999,7 @@ function applyOn(store, conversationId, projectRoot, opts) {
|
|
|
3961
3999
|
conversation_id: conversationId,
|
|
3962
4000
|
project_root: projectRoot,
|
|
3963
4001
|
code_root: projectRoot,
|
|
3964
|
-
platform
|
|
4002
|
+
platform,
|
|
3965
4003
|
phase: "planning",
|
|
3966
4004
|
armed: 0,
|
|
3967
4005
|
paused: 0,
|
|
@@ -4645,14 +4683,25 @@ function isChecklistPathAllowed(projectRoot, checklistPath) {
|
|
|
4645
4683
|
return isLexicallyInsideProject(root, checklistPath);
|
|
4646
4684
|
}
|
|
4647
4685
|
}
|
|
4648
|
-
function ensureSession(store, conversationId, projectRoot) {
|
|
4686
|
+
function ensureSession(store, conversationId, projectRoot, platform) {
|
|
4649
4687
|
const existing = store.getSession(conversationId);
|
|
4650
|
-
if (existing)
|
|
4688
|
+
if (existing) {
|
|
4689
|
+
const want = resolveSessionPlatform(platform, existing.platform);
|
|
4690
|
+
if (want !== existing.platform) {
|
|
4691
|
+
return store.upsertSession({
|
|
4692
|
+
conversation_id: conversationId,
|
|
4693
|
+
project_root: existing.project_root,
|
|
4694
|
+
code_root: existing.code_root,
|
|
4695
|
+
platform: want
|
|
4696
|
+
});
|
|
4697
|
+
}
|
|
4698
|
+
return existing;
|
|
4699
|
+
}
|
|
4651
4700
|
return store.upsertSession({
|
|
4652
4701
|
conversation_id: conversationId,
|
|
4653
4702
|
project_root: projectRoot,
|
|
4654
4703
|
code_root: projectRoot,
|
|
4655
|
-
platform:
|
|
4704
|
+
platform: normalizeSessionPlatform(platform),
|
|
4656
4705
|
phase: "idle",
|
|
4657
4706
|
armed: 0,
|
|
4658
4707
|
paused: 0,
|
|
@@ -4755,7 +4804,12 @@ function applyRun(store, conversationId, projectRoot, opts) {
|
|
|
4755
4804
|
return { ok: false, userMessage: "Invalid plans directory." };
|
|
4756
4805
|
}
|
|
4757
4806
|
const concurrencyMode = opts?.config?.concurrencyMode ?? "one_executor";
|
|
4758
|
-
const session = ensureSession(
|
|
4807
|
+
const session = ensureSession(
|
|
4808
|
+
store,
|
|
4809
|
+
conversationId,
|
|
4810
|
+
projectRoot,
|
|
4811
|
+
opts?.platform
|
|
4812
|
+
);
|
|
4759
4813
|
const resolved = resolveRunSlug(
|
|
4760
4814
|
store,
|
|
4761
4815
|
session,
|
|
@@ -4886,7 +4940,12 @@ function applyReplan(store, conversationId, projectRoot, opts) {
|
|
|
4886
4940
|
if (!plansDir) {
|
|
4887
4941
|
return { ok: false, userMessage: "Invalid plans directory." };
|
|
4888
4942
|
}
|
|
4889
|
-
const session = ensureSession(
|
|
4943
|
+
const session = ensureSession(
|
|
4944
|
+
store,
|
|
4945
|
+
conversationId,
|
|
4946
|
+
projectRoot,
|
|
4947
|
+
opts?.platform
|
|
4948
|
+
);
|
|
4890
4949
|
let slug = opts?.slug ?? session.track_id;
|
|
4891
4950
|
if (slug && slug !== "_pending" && !isSafeTrackSlug(slug)) {
|
|
4892
4951
|
return {
|
|
@@ -5030,12 +5089,14 @@ function applyTrackPick(store, conversationId, projectRoot, pick, opts) {
|
|
|
5030
5089
|
if (pending === "replan") {
|
|
5031
5090
|
return applyReplan(store, conversationId, projectRoot, {
|
|
5032
5091
|
slug,
|
|
5033
|
-
config: opts?.config
|
|
5092
|
+
config: opts?.config,
|
|
5093
|
+
platform: opts?.platform
|
|
5034
5094
|
});
|
|
5035
5095
|
}
|
|
5036
5096
|
return applyRun(store, conversationId, projectRoot, {
|
|
5037
5097
|
slug,
|
|
5038
|
-
config: opts?.config
|
|
5098
|
+
config: opts?.config,
|
|
5099
|
+
platform: opts?.platform
|
|
5039
5100
|
});
|
|
5040
5101
|
}
|
|
5041
5102
|
|
|
@@ -5237,13 +5298,35 @@ function isAutopilotIgnoredPath(relativePath, patterns) {
|
|
|
5237
5298
|
}
|
|
5238
5299
|
return ignored;
|
|
5239
5300
|
}
|
|
5301
|
+
function realpathForCompare(absPath) {
|
|
5302
|
+
try {
|
|
5303
|
+
return fs10.realpathSync(absPath);
|
|
5304
|
+
} catch {
|
|
5305
|
+
}
|
|
5306
|
+
let dir = path8.dirname(absPath);
|
|
5307
|
+
const base = path8.basename(absPath);
|
|
5308
|
+
const missing = [];
|
|
5309
|
+
for (; ; ) {
|
|
5310
|
+
try {
|
|
5311
|
+
const realDir = fs10.realpathSync(dir);
|
|
5312
|
+
return path8.join(realDir, ...missing, base);
|
|
5313
|
+
} catch {
|
|
5314
|
+
const parent = path8.dirname(dir);
|
|
5315
|
+
if (parent === dir) return absPath;
|
|
5316
|
+
missing.unshift(path8.basename(dir));
|
|
5317
|
+
dir = parent;
|
|
5318
|
+
}
|
|
5319
|
+
}
|
|
5320
|
+
}
|
|
5240
5321
|
function toProjectRelativePath(filePath, projectRoot) {
|
|
5241
5322
|
const posix = filePath.replace(/\\/g, "/");
|
|
5242
5323
|
if (!projectRoot?.trim()) {
|
|
5243
5324
|
return normalizeRelativePath(posix);
|
|
5244
5325
|
}
|
|
5245
|
-
const root = path8.resolve(projectRoot);
|
|
5246
|
-
const abs =
|
|
5326
|
+
const root = realpathForCompare(path8.resolve(projectRoot));
|
|
5327
|
+
const abs = realpathForCompare(
|
|
5328
|
+
path8.isAbsolute(posix) ? path8.resolve(posix) : path8.resolve(root, posix)
|
|
5329
|
+
);
|
|
5247
5330
|
const rel = path8.relative(root, abs);
|
|
5248
5331
|
if (rel.startsWith("..") || path8.isAbsolute(rel)) {
|
|
5249
5332
|
return "";
|
|
@@ -5506,6 +5589,300 @@ function handleStop(engine, payload) {
|
|
|
5506
5589
|
return { followup_message: action.message, loop: true };
|
|
5507
5590
|
}
|
|
5508
5591
|
|
|
5592
|
+
// ../ports/claude-code/src/index.ts
|
|
5593
|
+
var CLAUDE_PLATFORM = "claude-code";
|
|
5594
|
+
function sid(p) {
|
|
5595
|
+
return (p.session_id ?? p.sessionId ?? p.conversation_id ?? p.conversationId ?? "").trim();
|
|
5596
|
+
}
|
|
5597
|
+
function loopCountFromStopHookActive(payload) {
|
|
5598
|
+
const active = payload.stop_hook_active ?? payload.stopHookActive;
|
|
5599
|
+
return active === true ? 1 : 0;
|
|
5600
|
+
}
|
|
5601
|
+
function collectClaudeStopErrorText(payload) {
|
|
5602
|
+
if (!payload || typeof payload !== "object") return "";
|
|
5603
|
+
const MAX_CHARS = 8192;
|
|
5604
|
+
const parts = [];
|
|
5605
|
+
try {
|
|
5606
|
+
const push = (value) => {
|
|
5607
|
+
if (typeof value === "string" && value.trim()) {
|
|
5608
|
+
parts.push(value);
|
|
5609
|
+
return;
|
|
5610
|
+
}
|
|
5611
|
+
if (Array.isArray(value)) {
|
|
5612
|
+
for (const item of value.slice(0, 8)) {
|
|
5613
|
+
if (typeof item === "string" && item.trim()) parts.push(item);
|
|
5614
|
+
}
|
|
5615
|
+
return;
|
|
5616
|
+
}
|
|
5617
|
+
if (value && typeof value === "object") {
|
|
5618
|
+
const o = value;
|
|
5619
|
+
for (const key of [
|
|
5620
|
+
"message",
|
|
5621
|
+
"error",
|
|
5622
|
+
"name",
|
|
5623
|
+
"stack",
|
|
5624
|
+
"detail",
|
|
5625
|
+
"title"
|
|
5626
|
+
]) {
|
|
5627
|
+
const nested = o[key];
|
|
5628
|
+
if (typeof nested === "string" && nested.trim()) parts.push(nested);
|
|
5629
|
+
}
|
|
5630
|
+
}
|
|
5631
|
+
};
|
|
5632
|
+
push(payload.error);
|
|
5633
|
+
push(payload.message);
|
|
5634
|
+
push(payload.status_message);
|
|
5635
|
+
push(payload.reason);
|
|
5636
|
+
push(payload.detail);
|
|
5637
|
+
push(payload.title);
|
|
5638
|
+
} catch {
|
|
5639
|
+
return "";
|
|
5640
|
+
}
|
|
5641
|
+
const joined = parts.join("\n");
|
|
5642
|
+
return joined.length > MAX_CHARS ? joined.slice(0, MAX_CHARS) : joined;
|
|
5643
|
+
}
|
|
5644
|
+
function normalizeClaudeStopStatus(payload, opts) {
|
|
5645
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
5646
|
+
return opts?.status ?? "completed";
|
|
5647
|
+
}
|
|
5648
|
+
const statusRaw = String(payload.status ?? "").toLowerCase().trim();
|
|
5649
|
+
const errText = collectClaudeStopErrorText(payload);
|
|
5650
|
+
if (statusRaw === "aborted" || statusRaw === "cancelled" || statusRaw === "canceled") {
|
|
5651
|
+
return "aborted";
|
|
5652
|
+
}
|
|
5653
|
+
if (opts?.status === "aborted") return "aborted";
|
|
5654
|
+
if (statusRaw === "error" || statusRaw === "failed") {
|
|
5655
|
+
if (isUserAbortText(errText)) return "aborted";
|
|
5656
|
+
return "error";
|
|
5657
|
+
}
|
|
5658
|
+
if (opts?.status === "error") {
|
|
5659
|
+
if (isUserAbortText(errText)) return "aborted";
|
|
5660
|
+
return "error";
|
|
5661
|
+
}
|
|
5662
|
+
if (opts?.status === "completed") return "completed";
|
|
5663
|
+
const hookName = String(
|
|
5664
|
+
payload.hook_event_name ?? payload.hookEventName ?? ""
|
|
5665
|
+
).trim();
|
|
5666
|
+
if (/^stopfailure$/i.test(hookName)) {
|
|
5667
|
+
if (isUserAbortText(errText)) return "aborted";
|
|
5668
|
+
return "error";
|
|
5669
|
+
}
|
|
5670
|
+
if (!statusRaw && isUserAbortText(errText)) return "aborted";
|
|
5671
|
+
return "completed";
|
|
5672
|
+
}
|
|
5673
|
+
function blockReason(message, fallback) {
|
|
5674
|
+
const m = typeof message === "string" ? message.trim() : "";
|
|
5675
|
+
return m || fallback;
|
|
5676
|
+
}
|
|
5677
|
+
function filePathFromClaudeEdit(payload) {
|
|
5678
|
+
const input = payload.tool_input ?? payload.toolInput ?? {};
|
|
5679
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) return "";
|
|
5680
|
+
const candidates = [
|
|
5681
|
+
input.file_path,
|
|
5682
|
+
input.filePath,
|
|
5683
|
+
input.notebook_path,
|
|
5684
|
+
input.notebookPath,
|
|
5685
|
+
input.path
|
|
5686
|
+
];
|
|
5687
|
+
for (const c of candidates) {
|
|
5688
|
+
if (typeof c === "string" && c.trim()) return c.trim();
|
|
5689
|
+
}
|
|
5690
|
+
return "";
|
|
5691
|
+
}
|
|
5692
|
+
function isClaudeEditTool(toolName) {
|
|
5693
|
+
const n = toolName.trim();
|
|
5694
|
+
return n === "Edit" || n === "Write" || n === "NotebookEdit";
|
|
5695
|
+
}
|
|
5696
|
+
function stampClaudePlatform(store, conversationId, projectRoot) {
|
|
5697
|
+
const session = store.getSession(conversationId);
|
|
5698
|
+
if (!session || session.platform === CLAUDE_PLATFORM) return;
|
|
5699
|
+
store.upsertSession({
|
|
5700
|
+
conversation_id: conversationId,
|
|
5701
|
+
project_root: session.project_root || projectRoot,
|
|
5702
|
+
code_root: session.code_root || projectRoot,
|
|
5703
|
+
platform: CLAUDE_PLATFORM
|
|
5704
|
+
});
|
|
5705
|
+
}
|
|
5706
|
+
function handleUserPromptSubmit(store, payload, projectRoot, portConfig) {
|
|
5707
|
+
const conversationId = sid(payload);
|
|
5708
|
+
if (!conversationId) return {};
|
|
5709
|
+
const prompt = typeof payload.prompt === "string" ? payload.prompt : "";
|
|
5710
|
+
try {
|
|
5711
|
+
store.clearPendingFollowupIf(
|
|
5712
|
+
conversationId,
|
|
5713
|
+
isRecoverOrStuckFollowupMessage
|
|
5714
|
+
);
|
|
5715
|
+
} catch {
|
|
5716
|
+
}
|
|
5717
|
+
const session = store.getSession(conversationId);
|
|
5718
|
+
const trigger = parseTrigger({
|
|
5719
|
+
prompt,
|
|
5720
|
+
conversationId,
|
|
5721
|
+
projectRoot,
|
|
5722
|
+
pendingAction: session?.pending_action
|
|
5723
|
+
});
|
|
5724
|
+
const actionConfig = portConfig?.phaseActions;
|
|
5725
|
+
const gateFallback = "Autopilot rejected this prompt. Check `npx autopilot-harness status`.";
|
|
5726
|
+
if (trigger) {
|
|
5727
|
+
if (trigger.kind === "off") {
|
|
5728
|
+
applyOff(store, conversationId);
|
|
5729
|
+
stampClaudePlatform(store, conversationId, projectRoot);
|
|
5730
|
+
return {};
|
|
5731
|
+
}
|
|
5732
|
+
if (trigger.kind === "on") {
|
|
5733
|
+
const result = applyOn(store, conversationId, projectRoot, {
|
|
5734
|
+
initialBrief: trigger.initialBrief,
|
|
5735
|
+
slug: trigger.slug,
|
|
5736
|
+
platform: CLAUDE_PLATFORM
|
|
5737
|
+
});
|
|
5738
|
+
if (!result.ok) {
|
|
5739
|
+
stampClaudePlatform(store, conversationId, projectRoot);
|
|
5740
|
+
return {
|
|
5741
|
+
decision: "block",
|
|
5742
|
+
reason: blockReason(result.userMessage, gateFallback)
|
|
5743
|
+
};
|
|
5744
|
+
}
|
|
5745
|
+
return {};
|
|
5746
|
+
}
|
|
5747
|
+
if (trigger.kind === "resume") {
|
|
5748
|
+
const result = applyResume(store, conversationId, {
|
|
5749
|
+
slug: trigger.slug
|
|
5750
|
+
});
|
|
5751
|
+
if (!result.ok) {
|
|
5752
|
+
stampClaudePlatform(store, conversationId, projectRoot);
|
|
5753
|
+
return {
|
|
5754
|
+
decision: "block",
|
|
5755
|
+
reason: blockReason(result.userMessage, gateFallback)
|
|
5756
|
+
};
|
|
5757
|
+
}
|
|
5758
|
+
stampClaudePlatform(store, conversationId, projectRoot);
|
|
5759
|
+
return {};
|
|
5760
|
+
}
|
|
5761
|
+
if (trigger.kind === "resume_review") {
|
|
5762
|
+
applyResumeReview(store, conversationId);
|
|
5763
|
+
stampClaudePlatform(store, conversationId, projectRoot);
|
|
5764
|
+
return {};
|
|
5765
|
+
}
|
|
5766
|
+
if (trigger.kind === "run") {
|
|
5767
|
+
const result = applyRun(store, conversationId, projectRoot, {
|
|
5768
|
+
slug: trigger.slug,
|
|
5769
|
+
config: actionConfig,
|
|
5770
|
+
platform: CLAUDE_PLATFORM
|
|
5771
|
+
});
|
|
5772
|
+
if (!result.ok) {
|
|
5773
|
+
stampClaudePlatform(store, conversationId, projectRoot);
|
|
5774
|
+
return {
|
|
5775
|
+
decision: "block",
|
|
5776
|
+
reason: blockReason(result.userMessage, gateFallback)
|
|
5777
|
+
};
|
|
5778
|
+
}
|
|
5779
|
+
return {};
|
|
5780
|
+
}
|
|
5781
|
+
if (trigger.kind === "replan") {
|
|
5782
|
+
const result = applyReplan(store, conversationId, projectRoot, {
|
|
5783
|
+
slug: trigger.slug,
|
|
5784
|
+
config: actionConfig,
|
|
5785
|
+
platform: CLAUDE_PLATFORM
|
|
5786
|
+
});
|
|
5787
|
+
if (!result.ok) {
|
|
5788
|
+
stampClaudePlatform(store, conversationId, projectRoot);
|
|
5789
|
+
return {
|
|
5790
|
+
decision: "block",
|
|
5791
|
+
reason: blockReason(result.userMessage, gateFallback)
|
|
5792
|
+
};
|
|
5793
|
+
}
|
|
5794
|
+
return {};
|
|
5795
|
+
}
|
|
5796
|
+
if (trigger.kind === "track_pick" && trigger.trackPick) {
|
|
5797
|
+
const result = applyTrackPick(
|
|
5798
|
+
store,
|
|
5799
|
+
conversationId,
|
|
5800
|
+
projectRoot,
|
|
5801
|
+
trigger.trackPick,
|
|
5802
|
+
{ config: actionConfig, platform: CLAUDE_PLATFORM }
|
|
5803
|
+
);
|
|
5804
|
+
if (!result.ok) {
|
|
5805
|
+
stampClaudePlatform(store, conversationId, projectRoot);
|
|
5806
|
+
return {
|
|
5807
|
+
decision: "block",
|
|
5808
|
+
reason: blockReason(result.userMessage, gateFallback)
|
|
5809
|
+
};
|
|
5810
|
+
}
|
|
5811
|
+
return {};
|
|
5812
|
+
}
|
|
5813
|
+
return {};
|
|
5814
|
+
}
|
|
5815
|
+
if (!isHarnessFollowupMessage(prompt)) {
|
|
5816
|
+
store.clearChainPending(conversationId);
|
|
5817
|
+
}
|
|
5818
|
+
stampClaudePlatform(store, conversationId, projectRoot);
|
|
5819
|
+
return {};
|
|
5820
|
+
}
|
|
5821
|
+
function handlePostToolUse(store, payload, projectRoot) {
|
|
5822
|
+
const conversationId = sid(payload);
|
|
5823
|
+
const toolName = String(payload.tool_name ?? payload.toolName ?? "").trim();
|
|
5824
|
+
if (!conversationId || !isClaudeEditTool(toolName)) return;
|
|
5825
|
+
const filePath = filePathFromClaudeEdit(payload);
|
|
5826
|
+
if (!filePath) return;
|
|
5827
|
+
if (!isProductCodeEdit(filePath, { projectRoot })) return;
|
|
5828
|
+
const cfg = loadProjectReviewConfig(projectRoot);
|
|
5829
|
+
if (cfg.reviewScope === "project") {
|
|
5830
|
+
ensureAmbientReviewSession(
|
|
5831
|
+
store,
|
|
5832
|
+
conversationId,
|
|
5833
|
+
projectRoot,
|
|
5834
|
+
cfg.reviewScope,
|
|
5835
|
+
CLAUDE_PLATFORM
|
|
5836
|
+
);
|
|
5837
|
+
}
|
|
5838
|
+
stampClaudePlatform(store, conversationId, projectRoot);
|
|
5839
|
+
const session = store.getSession(conversationId);
|
|
5840
|
+
const checklistPath = session?.checklist_path?.trim() ?? "";
|
|
5841
|
+
let checklistSnap = null;
|
|
5842
|
+
if (checklistPath) {
|
|
5843
|
+
try {
|
|
5844
|
+
checklistSnap = parseChecklist(checklistPath, { projectRoot });
|
|
5845
|
+
} catch {
|
|
5846
|
+
}
|
|
5847
|
+
}
|
|
5848
|
+
store.markCodeEdited(conversationId, (chain) => {
|
|
5849
|
+
const fromPending = parseAdvanceNextItemId(chain.pending_followup);
|
|
5850
|
+
if (checklistSnap) {
|
|
5851
|
+
if (fromPending && effectiveReviewingItemId(checklistSnap, fromPending)) {
|
|
5852
|
+
return fromPending;
|
|
5853
|
+
}
|
|
5854
|
+
return firstUnchecked(checklistSnap)?.id ?? null;
|
|
5855
|
+
}
|
|
5856
|
+
return fromPending;
|
|
5857
|
+
});
|
|
5858
|
+
}
|
|
5859
|
+
function handleStop2(engine, payload, opts) {
|
|
5860
|
+
const conversationId = sid(payload);
|
|
5861
|
+
if (!conversationId) return {};
|
|
5862
|
+
const status = normalizeClaudeStopStatus(payload, opts);
|
|
5863
|
+
const transcriptRaw = payload.transcript_path ?? payload.transcriptPath;
|
|
5864
|
+
const transcriptPath = typeof transcriptRaw === "string" && transcriptRaw.trim() ? transcriptRaw.trim() : void 0;
|
|
5865
|
+
const action = engine.handleStop({
|
|
5866
|
+
conversationId,
|
|
5867
|
+
status,
|
|
5868
|
+
loopCount: loopCountFromStopHookActive(payload),
|
|
5869
|
+
transcriptPath,
|
|
5870
|
+
platform: CLAUDE_PLATFORM
|
|
5871
|
+
});
|
|
5872
|
+
if (!action?.message) return {};
|
|
5873
|
+
const reason = blockReason(action.message, "Autopilot followup");
|
|
5874
|
+
if (!action.loop) {
|
|
5875
|
+
return { continue: false, stopReason: reason };
|
|
5876
|
+
}
|
|
5877
|
+
return {
|
|
5878
|
+
decision: "block",
|
|
5879
|
+
reason
|
|
5880
|
+
};
|
|
5881
|
+
}
|
|
5882
|
+
function handleStopFailure(engine, payload) {
|
|
5883
|
+
return handleStop2(engine, payload, { status: "error" });
|
|
5884
|
+
}
|
|
5885
|
+
|
|
5509
5886
|
// src/vendor-entry.ts
|
|
5510
5887
|
function createConfiguredReviewEngine2(store, projectRoot) {
|
|
5511
5888
|
const cfg = loadProjectReviewConfig(projectRoot);
|
|
@@ -5519,6 +5896,11 @@ export {
|
|
|
5519
5896
|
getLatestSchemaVersion,
|
|
5520
5897
|
handleAfterFileEdit,
|
|
5521
5898
|
handleBeforeSubmitPrompt,
|
|
5899
|
+
handleStop2 as handleClaudeStop,
|
|
5900
|
+
handleStop as handleCursorStop,
|
|
5901
|
+
handlePostToolUse,
|
|
5522
5902
|
handleStop,
|
|
5903
|
+
handleStopFailure,
|
|
5904
|
+
handleUserPromptSubmit,
|
|
5523
5905
|
loadProjectReviewConfig
|
|
5524
5906
|
};
|