@adhdev/daemon-core 0.9.4 → 0.9.5
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/config/chat-history.d.ts +4 -3
- package/dist/daemon/dev-auto-implement.d.ts +6 -0
- package/dist/index.js +137 -179
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +137 -179
- package/dist/index.mjs.map +1 -1
- package/dist/providers/contracts.d.ts +111 -0
- package/dist/providers/provider-session-id.d.ts +6 -2
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/commands/cli-manager.ts +19 -10
- package/src/commands/stream-commands.ts +2 -3
- package/src/config/chat-history.ts +33 -32
- package/src/config/state-store.ts +6 -14
- package/src/daemon/dev-auto-implement.ts +36 -45
- package/src/providers/cli-provider-instance.ts +34 -69
- package/src/providers/contracts.ts +115 -0
- package/src/providers/provider-schema.ts +5 -0
- package/src/providers/provider-session-id.ts +17 -15
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* - Auto-rotation (delete files older than 30 days)
|
|
9
9
|
* - Async/non-blocking (no impact on chat collection)
|
|
10
10
|
*/
|
|
11
|
+
import type { ProviderHistoryBehavior } from '../providers/contracts.js';
|
|
11
12
|
export declare const SAVED_HISTORY_ROLLUP_THRESHOLD_BYTES: number;
|
|
12
13
|
interface HistoryMessage {
|
|
13
14
|
ts: string;
|
|
@@ -75,7 +76,7 @@ export declare class ChatHistoryWriter {
|
|
|
75
76
|
}): void;
|
|
76
77
|
writeSessionStart(agentType: string, historySessionId: string, workspace: string, instanceId?: string): void;
|
|
77
78
|
promoteHistorySession(agentType: string, previousHistorySessionId: string, nextHistorySessionId: string): void;
|
|
78
|
-
compactHistorySession(agentType: string, historySessionId: string): void;
|
|
79
|
+
compactHistorySession(agentType: string, historySessionId: string, historyBehavior?: ProviderHistoryBehavior): void;
|
|
79
80
|
/** Called when agent session is explicitly changed */
|
|
80
81
|
onSessionChange(agentType: string): void;
|
|
81
82
|
/** Delete history files older than 30 days */
|
|
@@ -91,14 +92,14 @@ export declare class ChatHistoryWriter {
|
|
|
91
92
|
* the newest N messages are skipped so older-history pagination can avoid
|
|
92
93
|
* duplicating the live transcript tail already shown in the UI.
|
|
93
94
|
*/
|
|
94
|
-
export declare function readChatHistory(agentType: string, offset?: number, limit?: number, historySessionId?: string, excludeRecentCount?: number): {
|
|
95
|
+
export declare function readChatHistory(agentType: string, offset?: number, limit?: number, historySessionId?: string, excludeRecentCount?: number, historyBehavior?: ProviderHistoryBehavior): {
|
|
95
96
|
messages: HistoryMessage[];
|
|
96
97
|
hasMore: boolean;
|
|
97
98
|
};
|
|
98
99
|
export declare function listSavedHistorySessions(agentType: string, options?: {
|
|
99
100
|
offset?: number;
|
|
100
101
|
limit?: number;
|
|
101
|
-
}): {
|
|
102
|
+
}, historyBehavior?: ProviderHistoryBehavior): {
|
|
102
103
|
sessions: SavedHistorySessionSummary[];
|
|
103
104
|
hasMore: boolean;
|
|
104
105
|
};
|
|
@@ -23,6 +23,12 @@ type CliExerciseVerification = {
|
|
|
23
23
|
fixtureName?: string;
|
|
24
24
|
fixtureNames?: string[];
|
|
25
25
|
};
|
|
26
|
+
export declare function shouldScheduleAutoStopOnQuiet(options: {
|
|
27
|
+
verification?: unknown;
|
|
28
|
+
autoImpl?: {
|
|
29
|
+
autoStopOnQuiet?: boolean;
|
|
30
|
+
} | null;
|
|
31
|
+
}): boolean;
|
|
26
32
|
export declare function getDefaultAutoImplReference(ctx: DevServerContext, category: string, type: string): string;
|
|
27
33
|
export declare function resolveAutoImplReference(ctx: DevServerContext, category: string, requestedReference: string | undefined, targetType: string): string | null;
|
|
28
34
|
export declare function getLatestScriptVersionDir(scriptsDir: string): string | null;
|
package/dist/index.js
CHANGED
|
@@ -4604,31 +4604,6 @@ function getSavedProviderSessions(state, filters) {
|
|
|
4604
4604
|
var import_fs2 = require("fs");
|
|
4605
4605
|
var import_path2 = require("path");
|
|
4606
4606
|
init_config();
|
|
4607
|
-
|
|
4608
|
-
// src/providers/provider-session-id.ts
|
|
4609
|
-
var HERMES_SESSION_ID_RE = /^\d{8}_\d{6}_[a-z0-9]+$/i;
|
|
4610
|
-
var CLAUDE_SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
4611
|
-
function normalizeProviderSessionId(providerType, providerSessionId) {
|
|
4612
|
-
const normalizedProviderType = typeof providerType === "string" ? providerType.trim() : "";
|
|
4613
|
-
const normalizedId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
|
|
4614
|
-
if (!normalizedId) return "";
|
|
4615
|
-
const lowered = normalizedId.toLowerCase();
|
|
4616
|
-
if (lowered === "undefined" || lowered === "null") return "";
|
|
4617
|
-
if (normalizedProviderType === "hermes-cli" && !HERMES_SESSION_ID_RE.test(normalizedId)) {
|
|
4618
|
-
return "";
|
|
4619
|
-
}
|
|
4620
|
-
if (normalizedProviderType === "claude-cli" && !CLAUDE_SESSION_ID_RE.test(normalizedId)) {
|
|
4621
|
-
return "";
|
|
4622
|
-
}
|
|
4623
|
-
return normalizedId;
|
|
4624
|
-
}
|
|
4625
|
-
function isLegacyVolatileSessionReadKey(key) {
|
|
4626
|
-
const normalizedKey = typeof key === "string" ? key.trim() : "";
|
|
4627
|
-
if (!normalizedKey) return false;
|
|
4628
|
-
return normalizedKey.startsWith("provider:codex:vscode-webview://");
|
|
4629
|
-
}
|
|
4630
|
-
|
|
4631
|
-
// src/config/state-store.ts
|
|
4632
4607
|
var DEFAULT_STATE = {
|
|
4633
4608
|
recentActivity: [],
|
|
4634
4609
|
savedProviderSessions: [],
|
|
@@ -4647,31 +4622,24 @@ function normalizeState(raw) {
|
|
|
4647
4622
|
const parsed = isPlainObject2(raw) ? raw : {};
|
|
4648
4623
|
const recentActivity = (Array.isArray(parsed.recentActivity) ? parsed.recentActivity : []).filter((entry) => {
|
|
4649
4624
|
if (!isPlainObject2(entry)) return false;
|
|
4650
|
-
|
|
4651
|
-
typeof entry.providerType === "string" ? entry.providerType : "",
|
|
4652
|
-
typeof entry.providerSessionId === "string" ? entry.providerSessionId : ""
|
|
4653
|
-
);
|
|
4654
|
-
if (typeof entry.providerSessionId === "string" && !normalizedId) return false;
|
|
4625
|
+
if (typeof entry.providerSessionId === "string" && !entry.providerSessionId.trim()) return false;
|
|
4655
4626
|
return true;
|
|
4656
4627
|
});
|
|
4657
4628
|
const savedProviderSessions = (Array.isArray(parsed.savedProviderSessions) ? parsed.savedProviderSessions : []).filter((entry) => {
|
|
4658
4629
|
if (!isPlainObject2(entry)) return false;
|
|
4659
|
-
return !!
|
|
4660
|
-
typeof entry.providerType === "string" ? entry.providerType : "",
|
|
4661
|
-
typeof entry.providerSessionId === "string" ? entry.providerSessionId : ""
|
|
4662
|
-
);
|
|
4630
|
+
return typeof entry.providerSessionId === "string" && !!entry.providerSessionId.trim();
|
|
4663
4631
|
});
|
|
4664
4632
|
const sessionReads = Object.fromEntries(
|
|
4665
|
-
Object.entries(isPlainObject2(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([
|
|
4633
|
+
Object.entries(isPlainObject2(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([, value]) => typeof value === "number" && Number.isFinite(value))
|
|
4666
4634
|
);
|
|
4667
4635
|
const sessionReadMarkers = Object.fromEntries(
|
|
4668
|
-
Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([
|
|
4636
|
+
Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([, value]) => typeof value === "string")
|
|
4669
4637
|
);
|
|
4670
4638
|
const sessionNotificationDismissals = Object.fromEntries(
|
|
4671
|
-
Object.entries(isPlainObject2(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {}).filter(([
|
|
4639
|
+
Object.entries(isPlainObject2(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {}).filter(([, value]) => typeof value === "string" && value.length > 0)
|
|
4672
4640
|
);
|
|
4673
4641
|
const sessionNotificationUnreadOverrides = Object.fromEntries(
|
|
4674
|
-
Object.entries(isPlainObject2(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([
|
|
4642
|
+
Object.entries(isPlainObject2(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([, value]) => typeof value === "string" && value.length > 0)
|
|
4675
4643
|
);
|
|
4676
4644
|
return {
|
|
4677
4645
|
recentActivity,
|
|
@@ -6763,16 +6731,24 @@ var savedHistorySessionCache = /* @__PURE__ */ new Map();
|
|
|
6763
6731
|
var savedHistoryFileSummaryCache = /* @__PURE__ */ new Map();
|
|
6764
6732
|
var savedHistoryBackgroundRefresh = /* @__PURE__ */ new Set();
|
|
6765
6733
|
var savedHistoryRollupInFlight = /* @__PURE__ */ new Set();
|
|
6766
|
-
var CODEX_STARTER_PROMPT_RE = /^(?:[›❯]\s*)?(?:Find and fix a bug in @filename|Improve documentation in @filename|Write tests for @filename|Explain this codebase|Summarize recent commits|Implement \{feature\}|Use \/skills(?: to list available skills)?|Run \/review on my current changes)$/i;
|
|
6767
6734
|
function normalizeHistoryComparable(text) {
|
|
6768
6735
|
return String(text || "").replace(/\s+/g, " ").trim();
|
|
6769
6736
|
}
|
|
6770
|
-
function cleanupHistoryContent(agentType, role, content) {
|
|
6737
|
+
function cleanupHistoryContent(agentType, role, content, historyBehavior) {
|
|
6771
6738
|
let value = String(content || "").replace(/\r\n/g, "\n").trim();
|
|
6772
6739
|
if (!value) return "";
|
|
6773
|
-
if (
|
|
6774
|
-
const
|
|
6775
|
-
|
|
6740
|
+
if (role === "assistant" && historyBehavior?.filterAssistantPatterns?.length) {
|
|
6741
|
+
const filters = historyBehavior.filterAssistantPatterns.map((p) => {
|
|
6742
|
+
try {
|
|
6743
|
+
return new RegExp(p, "i");
|
|
6744
|
+
} catch {
|
|
6745
|
+
return null;
|
|
6746
|
+
}
|
|
6747
|
+
}).filter(Boolean);
|
|
6748
|
+
if (filters.length > 0) {
|
|
6749
|
+
const filtered = value.split("\n").filter((line) => !filters.some((re) => re.test(line.trim()))).join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
6750
|
+
value = filtered;
|
|
6751
|
+
}
|
|
6776
6752
|
}
|
|
6777
6753
|
return value;
|
|
6778
6754
|
}
|
|
@@ -6789,8 +6765,8 @@ function isAdjacentHistoryDuplicate(agentType, previous, next) {
|
|
|
6789
6765
|
if (!previous || !next) return false;
|
|
6790
6766
|
return buildHistoryMessageSignature(agentType, previous) === buildHistoryMessageSignature(agentType, next);
|
|
6791
6767
|
}
|
|
6792
|
-
function collapseReplayAssistantTurns(
|
|
6793
|
-
if (
|
|
6768
|
+
function collapseReplayAssistantTurns(messages, historyBehavior) {
|
|
6769
|
+
if (!historyBehavior?.collapseConsecutiveAssistantTurns) return messages;
|
|
6794
6770
|
const collapsed = [];
|
|
6795
6771
|
let sawAssistantSinceLastUser = false;
|
|
6796
6772
|
for (const message of messages) {
|
|
@@ -6895,16 +6871,12 @@ function listHistoryFiles(dir, historySessionId) {
|
|
|
6895
6871
|
return true;
|
|
6896
6872
|
}).sort().reverse();
|
|
6897
6873
|
}
|
|
6898
|
-
function normalizeSavedHistorySessionId(
|
|
6899
|
-
|
|
6900
|
-
if (!normalizedId) return "";
|
|
6901
|
-
const strictProviderId = normalizeProviderSessionId(agentType, normalizedId);
|
|
6902
|
-
if (strictProviderId) return strictProviderId;
|
|
6903
|
-
return agentType === "hermes-cli" ? "" : normalizedId;
|
|
6874
|
+
function normalizeSavedHistorySessionId(historySessionId) {
|
|
6875
|
+
return String(historySessionId || "").trim();
|
|
6904
6876
|
}
|
|
6905
|
-
function extractSavedHistorySessionIdFromFile(
|
|
6877
|
+
function extractSavedHistorySessionIdFromFile(file) {
|
|
6906
6878
|
const match = file.match(/^([A-Za-z0-9_-]+)_\d{4}-\d{2}-\d{2}\.jsonl$/);
|
|
6907
|
-
return normalizeSavedHistorySessionId(
|
|
6879
|
+
return normalizeSavedHistorySessionId(match?.[1] || "");
|
|
6908
6880
|
}
|
|
6909
6881
|
function buildSavedHistoryFileSignatureMap(dir, files) {
|
|
6910
6882
|
return new Map(files.map((file) => {
|
|
@@ -7083,7 +7055,7 @@ function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
|
|
|
7083
7055
|
}
|
|
7084
7056
|
}
|
|
7085
7057
|
function updateSavedHistoryIndexForSessionStart(agentType, dir, file, historySessionId, workspace) {
|
|
7086
|
-
const normalizedSessionId = normalizeSavedHistorySessionId(
|
|
7058
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
7087
7059
|
const normalizedWorkspace = String(workspace || "").trim();
|
|
7088
7060
|
if (!normalizedSessionId || !normalizedWorkspace) return;
|
|
7089
7061
|
persistSavedHistoryFileSummaryEntry(agentType, dir, file, (currentSummary) => ({
|
|
@@ -7098,7 +7070,7 @@ function updateSavedHistoryIndexForSessionStart(agentType, dir, file, historySes
|
|
|
7098
7070
|
}));
|
|
7099
7071
|
}
|
|
7100
7072
|
function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, historySessionId, messages) {
|
|
7101
|
-
const normalizedSessionId = normalizeSavedHistorySessionId(
|
|
7073
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || "");
|
|
7102
7074
|
if (!normalizedSessionId || messages.length === 0) return;
|
|
7103
7075
|
persistSavedHistoryFileSummaryEntry(agentType, dir, file, (currentSummary) => {
|
|
7104
7076
|
const nextSummary = {
|
|
@@ -7135,8 +7107,8 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
|
|
|
7135
7107
|
return nextSummary;
|
|
7136
7108
|
});
|
|
7137
7109
|
}
|
|
7138
|
-
function computeSavedHistoryFileSummary(
|
|
7139
|
-
const historySessionId = extractSavedHistorySessionIdFromFile(
|
|
7110
|
+
function computeSavedHistoryFileSummary(dir, file) {
|
|
7111
|
+
const historySessionId = extractSavedHistorySessionIdFromFile(file);
|
|
7140
7112
|
if (!historySessionId) return null;
|
|
7141
7113
|
const filePath = path7.join(dir, file);
|
|
7142
7114
|
const content = fs3.readFileSync(filePath, "utf-8");
|
|
@@ -7230,7 +7202,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
|
|
|
7230
7202
|
const cached = savedHistoryFileSummaryCache.get(filePath);
|
|
7231
7203
|
const persisted = persistedEntries.get(file);
|
|
7232
7204
|
const reusableEntry = cached?.signature === signature ? cached : persisted?.signature === signature ? persisted : null;
|
|
7233
|
-
const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(
|
|
7205
|
+
const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(dir, file);
|
|
7234
7206
|
const nextEntry = reusableEntry || {
|
|
7235
7207
|
signature,
|
|
7236
7208
|
summary: fileSummary
|
|
@@ -7528,7 +7500,7 @@ var ChatHistoryWriter = class {
|
|
|
7528
7500
|
} catch {
|
|
7529
7501
|
}
|
|
7530
7502
|
}
|
|
7531
|
-
compactHistorySession(agentType, historySessionId) {
|
|
7503
|
+
compactHistorySession(agentType, historySessionId, historyBehavior) {
|
|
7532
7504
|
const sessionId = String(historySessionId || "").trim();
|
|
7533
7505
|
if (!sessionId) return;
|
|
7534
7506
|
try {
|
|
@@ -7566,7 +7538,7 @@ var ChatHistoryWriter = class {
|
|
|
7566
7538
|
dedupedAdjacent.push(entry);
|
|
7567
7539
|
if (entry.role !== "system") lastTurn = entry;
|
|
7568
7540
|
}
|
|
7569
|
-
const collapsed = collapseReplayAssistantTurns(
|
|
7541
|
+
const collapsed = collapseReplayAssistantTurns(dedupedAdjacent, historyBehavior);
|
|
7570
7542
|
if (collapsed.length === 0) {
|
|
7571
7543
|
fs3.unlinkSync(filePath);
|
|
7572
7544
|
continue;
|
|
@@ -7615,7 +7587,7 @@ var ChatHistoryWriter = class {
|
|
|
7615
7587
|
return name.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
7616
7588
|
}
|
|
7617
7589
|
};
|
|
7618
|
-
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0) {
|
|
7590
|
+
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
|
|
7619
7591
|
try {
|
|
7620
7592
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
7621
7593
|
const dir = path7.join(HISTORY_DIR, sanitized);
|
|
@@ -7650,7 +7622,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
7650
7622
|
chronological.push(message);
|
|
7651
7623
|
if (message.role !== "system") lastTurn = message;
|
|
7652
7624
|
}
|
|
7653
|
-
const collapsed = collapseReplayAssistantTurns(
|
|
7625
|
+
const collapsed = collapseReplayAssistantTurns(chronological, historyBehavior);
|
|
7654
7626
|
const boundedLimit = Math.max(1, limit);
|
|
7655
7627
|
const boundedOffset = Math.max(0, offset);
|
|
7656
7628
|
const boundedExclude = Math.max(0, Math.min(excludeRecentCount, collapsed.length));
|
|
@@ -7663,7 +7635,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
7663
7635
|
return { messages: [], hasMore: false };
|
|
7664
7636
|
}
|
|
7665
7637
|
}
|
|
7666
|
-
function listSavedHistorySessions(agentType, options = {}) {
|
|
7638
|
+
function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
7667
7639
|
try {
|
|
7668
7640
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
7669
7641
|
const dir = path7.join(HISTORY_DIR, sanitized);
|
|
@@ -7794,7 +7766,7 @@ function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
|
|
|
7794
7766
|
}
|
|
7795
7767
|
}
|
|
7796
7768
|
function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
|
|
7797
|
-
const normalizedSessionId = normalizeSavedHistorySessionId(
|
|
7769
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
7798
7770
|
if (!normalizedSessionId) return false;
|
|
7799
7771
|
try {
|
|
7800
7772
|
const sessionFilePath = path7.join(os5.homedir(), ".hermes", "sessions", `session_${normalizedSessionId}.json`);
|
|
@@ -7943,7 +7915,7 @@ function extractClaudeUserContentParts(content) {
|
|
|
7943
7915
|
return parts;
|
|
7944
7916
|
}
|
|
7945
7917
|
function rebuildClaudeSavedHistoryFromNativeProject(historySessionId, workspace) {
|
|
7946
|
-
const normalizedSessionId = normalizeSavedHistorySessionId(
|
|
7918
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
7947
7919
|
if (!normalizedSessionId) return false;
|
|
7948
7920
|
try {
|
|
7949
7921
|
const transcriptPath = resolveClaudeProjectTranscriptPath(normalizedSessionId, workspace);
|
|
@@ -12109,7 +12081,8 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
12109
12081
|
}
|
|
12110
12082
|
const managed = runtimeSessionId ? h.agentStream?.getManagedSession(runtimeSessionId) : null;
|
|
12111
12083
|
const targetSessionId = managed?.cdpSessionId || null;
|
|
12112
|
-
const
|
|
12084
|
+
const DEFAULT_IDE_LEVEL_SCRIPTS = ["listModes", "setMode", "listModels", "setModel"];
|
|
12085
|
+
const IDE_LEVEL_SCRIPTS = provider.ideLevelScripts ?? DEFAULT_IDE_LEVEL_SCRIPTS;
|
|
12113
12086
|
if (IDE_LEVEL_SCRIPTS.includes(scriptName)) {
|
|
12114
12087
|
if (targetSessionId) {
|
|
12115
12088
|
try {
|
|
@@ -12834,6 +12807,25 @@ var import_node_module = require("module");
|
|
|
12834
12807
|
init_contracts();
|
|
12835
12808
|
init_provider_cli_adapter();
|
|
12836
12809
|
init_logger();
|
|
12810
|
+
|
|
12811
|
+
// src/providers/provider-session-id.ts
|
|
12812
|
+
function normalizeProviderSessionId(provider, providerSessionId) {
|
|
12813
|
+
const normalizedId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
|
|
12814
|
+
if (!normalizedId) return "";
|
|
12815
|
+
const lowered = normalizedId.toLowerCase();
|
|
12816
|
+
if (lowered === "undefined" || lowered === "null") return "";
|
|
12817
|
+
const sessionIdPattern = provider?.sessionIdPattern;
|
|
12818
|
+
if (sessionIdPattern) {
|
|
12819
|
+
try {
|
|
12820
|
+
const re = new RegExp(sessionIdPattern, "i");
|
|
12821
|
+
if (!re.test(normalizedId)) return "";
|
|
12822
|
+
} catch {
|
|
12823
|
+
}
|
|
12824
|
+
}
|
|
12825
|
+
return normalizedId;
|
|
12826
|
+
}
|
|
12827
|
+
|
|
12828
|
+
// src/providers/cli-provider-instance.ts
|
|
12837
12829
|
init_chat_message_normalization();
|
|
12838
12830
|
function normalizePersistableCliHistoryContent(content) {
|
|
12839
12831
|
return flattenContent(content).replace(/\s+/g, " ").trim();
|
|
@@ -12990,32 +12982,10 @@ var CliProviderInstance = class {
|
|
|
12990
12982
|
}
|
|
12991
12983
|
async onTick() {
|
|
12992
12984
|
if (this.providerSessionId) return;
|
|
12993
|
-
if (this.
|
|
12994
|
-
let probedSessionId = null;
|
|
12985
|
+
if (this.provider.resume?.skipProbeOnNewSession && this.launchMode === "new") return;
|
|
12995
12986
|
const probeConfig = this.provider.sessionProbe;
|
|
12996
|
-
if (probeConfig)
|
|
12997
|
-
|
|
12998
|
-
} else {
|
|
12999
|
-
if (this.type === "opencode-cli") {
|
|
13000
|
-
probedSessionId = this.probeSessionIdFromConfig({
|
|
13001
|
-
dbPath: "~/.local/share/opencode/opencode.db",
|
|
13002
|
-
query: "select id from session where directory in ({dirs}) and time_created >= ? and time_archived is null order by time_updated desc limit 1",
|
|
13003
|
-
timestampFormat: "unix_ms"
|
|
13004
|
-
});
|
|
13005
|
-
} else if (this.type === "codex-cli") {
|
|
13006
|
-
probedSessionId = this.probeSessionIdFromConfig({
|
|
13007
|
-
dbPath: "~/.codex/state_5.sqlite",
|
|
13008
|
-
query: "select id from threads where cwd in ({dirs}) and updated_at >= ? and archived = 0 order by updated_at desc limit 1",
|
|
13009
|
-
timestampFormat: "unix_s"
|
|
13010
|
-
});
|
|
13011
|
-
} else if (this.type === "goose-cli") {
|
|
13012
|
-
probedSessionId = this.probeSessionIdFromConfig({
|
|
13013
|
-
dbPath: "~/.local/share/goose/sessions/sessions.db",
|
|
13014
|
-
query: "select id from sessions where working_dir in ({dirs}) and created_at >= ? order by updated_at desc limit 1",
|
|
13015
|
-
timestampFormat: "iso"
|
|
13016
|
-
});
|
|
13017
|
-
}
|
|
13018
|
-
}
|
|
12987
|
+
if (!probeConfig) return;
|
|
12988
|
+
const probedSessionId = this.probeSessionIdFromConfig(probeConfig);
|
|
13019
12989
|
if (probedSessionId) {
|
|
13020
12990
|
this.promoteProviderSessionId(probedSessionId);
|
|
13021
12991
|
}
|
|
@@ -13067,7 +13037,7 @@ var CliProviderInstance = class {
|
|
|
13067
13037
|
const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
13068
13038
|
const visibleStatus = parseErrorMessage ? "error" : autoApproveActive ? "generating" : adapterStatus.status;
|
|
13069
13039
|
const parsedProviderSessionId = normalizeProviderSessionId(
|
|
13070
|
-
this.
|
|
13040
|
+
this.provider,
|
|
13071
13041
|
typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId : ""
|
|
13072
13042
|
);
|
|
13073
13043
|
if (parsedProviderSessionId) {
|
|
@@ -13357,7 +13327,7 @@ var CliProviderInstance = class {
|
|
|
13357
13327
|
applyProviderResponse(data, options) {
|
|
13358
13328
|
if (!data || typeof data !== "object") return;
|
|
13359
13329
|
const patchedProviderSessionId = normalizeProviderSessionId(
|
|
13360
|
-
this.
|
|
13330
|
+
this.provider,
|
|
13361
13331
|
typeof data.providerSessionId === "string" ? data.providerSessionId : ""
|
|
13362
13332
|
);
|
|
13363
13333
|
if (patchedProviderSessionId) {
|
|
@@ -13595,52 +13565,39 @@ ${effect.notification.body || ""}`.trim();
|
|
|
13595
13565
|
}
|
|
13596
13566
|
syncCanonicalSavedHistoryIfNeeded() {
|
|
13597
13567
|
if (!this.providerSessionId) return false;
|
|
13598
|
-
|
|
13599
|
-
|
|
13600
|
-
|
|
13601
|
-
|
|
13602
|
-
|
|
13568
|
+
const canonicalHistory = this.provider.canonicalHistory;
|
|
13569
|
+
if (!canonicalHistory) return false;
|
|
13570
|
+
try {
|
|
13571
|
+
let rebuilt = false;
|
|
13572
|
+
if (canonicalHistory.format === "hermes-json") {
|
|
13573
|
+
const watchPath = canonicalHistory.watchPath.replace(/^~/, os11.homedir()).replace("{{sessionId}}", this.providerSessionId);
|
|
13574
|
+
if (!fs5.existsSync(watchPath)) return false;
|
|
13575
|
+
const stat = fs5.statSync(watchPath);
|
|
13603
13576
|
if (stat.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
|
|
13604
|
-
|
|
13605
|
-
if (
|
|
13606
|
-
|
|
13607
|
-
|
|
13608
|
-
|
|
13609
|
-
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13613
|
-
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
}
|
|
13620
|
-
|
|
13621
|
-
try {
|
|
13622
|
-
const rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
|
|
13623
|
-
if (!rebuilt) return false;
|
|
13624
|
-
const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
|
|
13625
|
-
this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
|
|
13626
|
-
role: message.role,
|
|
13627
|
-
content: message.content,
|
|
13628
|
-
kind: message.kind,
|
|
13629
|
-
senderName: message.senderName,
|
|
13630
|
-
receivedAt: message.receivedAt
|
|
13631
|
-
}));
|
|
13632
|
-
return true;
|
|
13633
|
-
} catch {
|
|
13634
|
-
return false;
|
|
13635
|
-
}
|
|
13577
|
+
rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
|
|
13578
|
+
if (rebuilt) this.lastCanonicalHermesSyncMtimeMs = stat.mtimeMs;
|
|
13579
|
+
} else if (canonicalHistory.format === "claude-jsonl") {
|
|
13580
|
+
rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
|
|
13581
|
+
}
|
|
13582
|
+
if (!rebuilt) return false;
|
|
13583
|
+
const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
|
|
13584
|
+
this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
|
|
13585
|
+
role: message.role,
|
|
13586
|
+
content: message.content,
|
|
13587
|
+
kind: message.kind,
|
|
13588
|
+
senderName: message.senderName,
|
|
13589
|
+
receivedAt: message.receivedAt
|
|
13590
|
+
}));
|
|
13591
|
+
return true;
|
|
13592
|
+
} catch {
|
|
13593
|
+
return false;
|
|
13636
13594
|
}
|
|
13637
|
-
return false;
|
|
13638
13595
|
}
|
|
13639
13596
|
restorePersistedHistoryFromCurrentSession() {
|
|
13640
13597
|
if (!this.providerSessionId) return;
|
|
13641
13598
|
this.syncCanonicalSavedHistoryIfNeeded();
|
|
13642
|
-
this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
|
|
13643
|
-
const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
|
|
13599
|
+
this.historyWriter.compactHistorySession(this.type, this.providerSessionId, this.provider.historyBehavior);
|
|
13600
|
+
const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
|
|
13644
13601
|
this.historyWriter.seedSessionHistory(
|
|
13645
13602
|
this.type,
|
|
13646
13603
|
restoredHistory.messages,
|
|
@@ -14881,14 +14838,15 @@ function expandResumeArgs(template, sessionId) {
|
|
|
14881
14838
|
if (!Array.isArray(template) || template.length === 0) return void 0;
|
|
14882
14839
|
return template.map((part) => part === "{{id}}" ? sessionId : part);
|
|
14883
14840
|
}
|
|
14884
|
-
function
|
|
14885
|
-
const resumeIndex = args.findIndex((arg) => arg
|
|
14841
|
+
function readSubcommandSessionId(args, subcommands) {
|
|
14842
|
+
const resumeIndex = args.findIndex((arg) => subcommands.includes(arg));
|
|
14886
14843
|
if (resumeIndex < 0) return void 0;
|
|
14887
14844
|
const candidate = args[resumeIndex + 1];
|
|
14888
14845
|
if (!candidate || candidate.startsWith("-")) return void 0;
|
|
14889
14846
|
return candidate;
|
|
14890
14847
|
}
|
|
14891
|
-
function detectExplicitProviderSessionId(
|
|
14848
|
+
function detectExplicitProviderSessionId(provider, args) {
|
|
14849
|
+
const resume = provider?.resume;
|
|
14892
14850
|
const explicitResumeId = readArgValue(args, ["--resume", "-r"]);
|
|
14893
14851
|
if (explicitResumeId) {
|
|
14894
14852
|
return { providerSessionId: explicitResumeId, launchMode: "resume" };
|
|
@@ -14902,19 +14860,20 @@ function detectExplicitProviderSessionId(normalizedType, args) {
|
|
|
14902
14860
|
}
|
|
14903
14861
|
const explicitSessionId = readArgValue(args, ["--session-id"]);
|
|
14904
14862
|
if (explicitSessionId) {
|
|
14905
|
-
if (
|
|
14863
|
+
if (resume?.sessionIdIsNewByDefault && !hasArg(args, ["--resume", "-r"])) {
|
|
14906
14864
|
return { launchMode: "manual" };
|
|
14907
14865
|
}
|
|
14908
|
-
const isResume =
|
|
14866
|
+
const isResume = resume?.sessionIdIsNewByDefault ? hasArg(args, ["--resume", "-r"]) : hasArg(args, ["--continue"]) || hasArg(args, ["--resume", "-r"]);
|
|
14909
14867
|
return {
|
|
14910
14868
|
providerSessionId: explicitSessionId,
|
|
14911
14869
|
launchMode: isResume ? "resume" : "new"
|
|
14912
14870
|
};
|
|
14913
14871
|
}
|
|
14914
|
-
|
|
14915
|
-
|
|
14916
|
-
|
|
14917
|
-
|
|
14872
|
+
const subcommands = resume?.sessionIdFromSubcommand;
|
|
14873
|
+
if (Array.isArray(subcommands) && subcommands.length > 0) {
|
|
14874
|
+
const subcommandSessionId = readSubcommandSessionId(args, subcommands);
|
|
14875
|
+
if (subcommandSessionId) {
|
|
14876
|
+
return { providerSessionId: subcommandSessionId, launchMode: "resume" };
|
|
14918
14877
|
}
|
|
14919
14878
|
}
|
|
14920
14879
|
return { launchMode: "manual" };
|
|
@@ -14931,7 +14890,7 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
|
|
|
14931
14890
|
if (!resume?.supported) {
|
|
14932
14891
|
return { cliArgs: baseArgs, launchMode: "manual" };
|
|
14933
14892
|
}
|
|
14934
|
-
const explicit = detectExplicitProviderSessionId(
|
|
14893
|
+
const explicit = detectExplicitProviderSessionId(provider, baseArgs || []);
|
|
14935
14894
|
if (explicit.providerSessionId) {
|
|
14936
14895
|
return {
|
|
14937
14896
|
cliArgs: baseArgs,
|
|
@@ -14939,6 +14898,12 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
|
|
|
14939
14898
|
launchMode: explicit.launchMode
|
|
14940
14899
|
};
|
|
14941
14900
|
}
|
|
14901
|
+
if (explicit.launchMode === "manual" && hasArg(baseArgs || [], ["--session-id"])) {
|
|
14902
|
+
return {
|
|
14903
|
+
cliArgs: baseArgs,
|
|
14904
|
+
launchMode: "manual"
|
|
14905
|
+
};
|
|
14906
|
+
}
|
|
14942
14907
|
if (requestedResumeSessionId) {
|
|
14943
14908
|
if (resume.sessionIdFormat === "uuid" && !isUuid(requestedResumeSessionId)) {
|
|
14944
14909
|
throw new Error(`Invalid ${provider?.displayName || provider?.name || normalizedType} session ID: ${requestedResumeSessionId}`);
|
|
@@ -15643,6 +15608,11 @@ var KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
|
|
|
15643
15608
|
"resume",
|
|
15644
15609
|
"sessionProbe",
|
|
15645
15610
|
"approvalPositiveHints",
|
|
15611
|
+
"sessionIdPattern",
|
|
15612
|
+
"historyBehavior",
|
|
15613
|
+
"canonicalHistory",
|
|
15614
|
+
"autoFixProfile",
|
|
15615
|
+
"ideLevelScripts",
|
|
15646
15616
|
"scripts",
|
|
15647
15617
|
"vscodeCommands",
|
|
15648
15618
|
"inputMethod",
|
|
@@ -22972,20 +22942,13 @@ function tryKillAutoImplProcess(processRef, signal) {
|
|
|
22972
22942
|
} catch {
|
|
22973
22943
|
}
|
|
22974
22944
|
}
|
|
22945
|
+
function shouldScheduleAutoStopOnQuiet(options) {
|
|
22946
|
+
return !!options.verification && options.autoImpl?.autoStopOnQuiet === true;
|
|
22947
|
+
}
|
|
22975
22948
|
function getDefaultAutoImplReference(ctx, category, type) {
|
|
22976
|
-
|
|
22977
|
-
|
|
22978
|
-
|
|
22979
|
-
if (category === "extension") {
|
|
22980
|
-
const preferred = ["claude-code-vscode", "codex", "cline", "roo-code"];
|
|
22981
|
-
for (const ref of preferred) {
|
|
22982
|
-
if (ref === type) continue;
|
|
22983
|
-
if (ctx.providerLoader.resolve(ref) || ctx.providerLoader.getMeta(ref)) return ref;
|
|
22984
|
-
}
|
|
22985
|
-
const all = ctx.providerLoader.getAll();
|
|
22986
|
-
const fb = all.find((p) => p.category === "extension" && p.type !== type);
|
|
22987
|
-
if (fb?.type) return fb.type;
|
|
22988
|
-
}
|
|
22949
|
+
const all = ctx.providerLoader.getAll();
|
|
22950
|
+
const sameCategoryOther = all.find((p) => p.category === category && p.type !== type);
|
|
22951
|
+
if (sameCategoryOther?.type) return sameCategoryOther.type;
|
|
22989
22952
|
return "antigravity";
|
|
22990
22953
|
}
|
|
22991
22954
|
function resolveAutoImplReference(ctx, category, requestedReference, targetType) {
|
|
@@ -23303,37 +23266,33 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
23303
23266
|
return;
|
|
23304
23267
|
}
|
|
23305
23268
|
const command = spawn4.command;
|
|
23269
|
+
const autoImpl = spawn4.autoImpl;
|
|
23306
23270
|
const interactiveFlags = ["--yolo", "--interactive", "-i"];
|
|
23307
23271
|
const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
|
|
23308
23272
|
let shellCmd;
|
|
23309
23273
|
const isWin = os19.platform() === "win32";
|
|
23310
23274
|
const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
|
|
23311
|
-
|
|
23312
|
-
|
|
23275
|
+
const promptMode = autoImpl?.promptMode ?? "stdin";
|
|
23276
|
+
const extraArgs = autoImpl?.extraArgs ?? [];
|
|
23277
|
+
const rawMetaPrompt = autoImpl?.metaPrompt ? autoImpl.metaPrompt.replace("{{promptFile}}", promptFile) : `Read the file at ${promptFile} and follow ALL the instructions in it exactly. Do not ask questions, just execute.`;
|
|
23278
|
+
if (promptMode === "flag") {
|
|
23279
|
+
const flag = autoImpl?.promptFlag ?? "-p";
|
|
23280
|
+
const args = [...baseArgs, ...extraArgs];
|
|
23313
23281
|
if (model) args.push("--model", model);
|
|
23314
23282
|
const escapedArgs = args.map(escapeArg).join(" ");
|
|
23315
|
-
|
|
23316
|
-
|
|
23317
|
-
|
|
23318
|
-
const args = [...baseArgs
|
|
23319
|
-
|
|
23320
|
-
|
|
23321
|
-
const metaPrompt = `Read the file at ${promptFile} and follow ALL the instructions in it exactly. Do not ask questions, just execute.`;
|
|
23322
|
-
shellCmd = `${command} ${escapedArgs} -p ${escapeArg(metaPrompt)}`;
|
|
23323
|
-
} else if (command === "codex") {
|
|
23324
|
-
const args = ["exec", ...baseArgs];
|
|
23325
|
-
if (!args.includes("--dangerously-bypass-approvals-and-sandbox")) {
|
|
23326
|
-
args.push("--dangerously-bypass-approvals-and-sandbox");
|
|
23327
|
-
}
|
|
23328
|
-
if (!args.includes("--skip-git-repo-check")) {
|
|
23329
|
-
args.push("--skip-git-repo-check");
|
|
23283
|
+
shellCmd = `${command} ${escapedArgs} ${flag} ${escapeArg(rawMetaPrompt)}`;
|
|
23284
|
+
} else if (promptMode === "subcommand") {
|
|
23285
|
+
const subcommand = autoImpl?.subcommand ?? "";
|
|
23286
|
+
const args = subcommand ? [subcommand, ...baseArgs] : [...baseArgs];
|
|
23287
|
+
for (const extra of extraArgs) {
|
|
23288
|
+
if (!args.includes(extra)) args.push(extra);
|
|
23330
23289
|
}
|
|
23331
23290
|
if (model) args.push("--model", model);
|
|
23332
23291
|
const escapedArgs = args.map(escapeArg).join(" ");
|
|
23333
|
-
|
|
23334
|
-
shellCmd = `${command} ${escapedArgs} ${escapeArg(metaPrompt)}`;
|
|
23292
|
+
shellCmd = `${command} ${escapedArgs} ${escapeArg(rawMetaPrompt)}`;
|
|
23335
23293
|
} else {
|
|
23336
|
-
const
|
|
23294
|
+
const args = [...baseArgs, ...extraArgs];
|
|
23295
|
+
const escapedArgs = args.map(escapeArg).join(" ");
|
|
23337
23296
|
if (isWin) {
|
|
23338
23297
|
shellCmd = `type "${promptFile}" | ${command} ${escapedArgs}`;
|
|
23339
23298
|
} else {
|
|
@@ -23368,8 +23327,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
23368
23327
|
stdio: ["pipe", "pipe", "pipe"],
|
|
23369
23328
|
env: {
|
|
23370
23329
|
...process.env,
|
|
23371
|
-
...spawn4.env || {}
|
|
23372
|
-
...command === "gemini" ? { SANDBOX: "1", GEMINI_CLI_NO_RELAUNCH: "1" } : {}
|
|
23330
|
+
...spawn4.env || {}
|
|
23373
23331
|
}
|
|
23374
23332
|
});
|
|
23375
23333
|
child.on("error", (err2) => {
|
|
@@ -23431,7 +23389,7 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
23431
23389
|
}
|
|
23432
23390
|
};
|
|
23433
23391
|
const scheduleAutoStopForVerification = () => {
|
|
23434
|
-
if (!verification
|
|
23392
|
+
if (!shouldScheduleAutoStopOnQuiet({ verification, autoImpl }) || completionSignalSeen || autoStopIssued) return;
|
|
23435
23393
|
const elapsed = Date.now() - spawnedAt;
|
|
23436
23394
|
if (elapsed < 3e4) return;
|
|
23437
23395
|
clearAutoStopTimer();
|