@cydm/pie 2.7.7 → 2.7.8
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/builtin/extensions/ask-user/index.js +1 -1
- package/dist/builtin/extensions/plan-mode/index.js +1 -1
- package/dist/builtin/extensions/subagent/index.js +9 -3
- package/dist/builtin/extensions/todo/index.js +1 -1
- package/dist/chunks/{chunk-IU5L5DED.js → chunk-E6F4BTNN.js} +1 -1
- package/dist/chunks/{chunk-UPGEXDEQ.js → chunk-P22SYVGO.js} +6 -3
- package/dist/cli.js +435 -312
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
createAskUserCapability
|
|
4
|
-
} from "../../../chunks/chunk-
|
|
4
|
+
} from "../../../chunks/chunk-P22SYVGO.js";
|
|
5
5
|
import "../../../chunks/chunk-W5B3OXHQ.js";
|
|
6
6
|
import "../../../chunks/chunk-2FEDB5GR.js";
|
|
7
7
|
import "../../../chunks/chunk-XXGYUYXI.js";
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
isPlanModeSafeCommand,
|
|
9
9
|
markCompletedPlanSteps,
|
|
10
10
|
restoreExecutionState
|
|
11
|
-
} from "../../../chunks/chunk-
|
|
11
|
+
} from "../../../chunks/chunk-P22SYVGO.js";
|
|
12
12
|
import "../../../chunks/chunk-W5B3OXHQ.js";
|
|
13
13
|
import "../../../chunks/chunk-2FEDB5GR.js";
|
|
14
14
|
import {
|
|
@@ -4,12 +4,12 @@ import {
|
|
|
4
4
|
formatTransportLifecycle,
|
|
5
5
|
getConfigDir,
|
|
6
6
|
logTransportLifecycle
|
|
7
|
-
} from "../../../chunks/chunk-
|
|
7
|
+
} from "../../../chunks/chunk-E6F4BTNN.js";
|
|
8
8
|
import {
|
|
9
9
|
SUBAGENT_SESSION_RECORD_VERSION,
|
|
10
10
|
createSharedFileSystemTools,
|
|
11
11
|
createSubagentCapability
|
|
12
|
-
} from "../../../chunks/chunk-
|
|
12
|
+
} from "../../../chunks/chunk-P22SYVGO.js";
|
|
13
13
|
import "../../../chunks/chunk-W5B3OXHQ.js";
|
|
14
14
|
import "../../../chunks/chunk-2FEDB5GR.js";
|
|
15
15
|
import "../../../chunks/chunk-XXGYUYXI.js";
|
|
@@ -206,7 +206,13 @@ function createSubagentSessionStore(sessionsDir, log, deps) {
|
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
try {
|
|
209
|
-
|
|
209
|
+
let stat;
|
|
210
|
+
try {
|
|
211
|
+
stat = fs.statSync(lockPath);
|
|
212
|
+
} catch (statError) {
|
|
213
|
+
if (statError.code === "ENOENT") continue;
|
|
214
|
+
throw new Error(`Subagent session "${id}" is busy (session lease is unreadable).`);
|
|
215
|
+
}
|
|
210
216
|
let lockContent;
|
|
211
217
|
try {
|
|
212
218
|
lockContent = fs.readFileSync(lockPath, "utf8");
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
executeManageTodoList,
|
|
9
9
|
executionStateToTodos,
|
|
10
10
|
restoreExecutionState
|
|
11
|
-
} from "../../../chunks/chunk-
|
|
11
|
+
} from "../../../chunks/chunk-P22SYVGO.js";
|
|
12
12
|
import "../../../chunks/chunk-W5B3OXHQ.js";
|
|
13
13
|
import "../../../chunks/chunk-2FEDB5GR.js";
|
|
14
14
|
import "../../../chunks/chunk-XXGYUYXI.js";
|
|
@@ -2002,6 +2002,9 @@ function leadingHostContextBlock(message) {
|
|
|
2002
2002
|
if (!isHostContextBlock(first)) return void 0;
|
|
2003
2003
|
return first;
|
|
2004
2004
|
}
|
|
2005
|
+
function projectionSeparator(projectionText) {
|
|
2006
|
+
return projectionText.endsWith("\n") && !projectionText.endsWith("\n\n") ? "" : "\n\n";
|
|
2007
|
+
}
|
|
2005
2008
|
function projectHostEnvelopes(messages, registry, onProjection) {
|
|
2006
2009
|
let changed = false;
|
|
2007
2010
|
const next = [];
|
|
@@ -2015,12 +2018,11 @@ function projectHostEnvelopes(messages, registry, onProjection) {
|
|
|
2015
2018
|
onProjection?.(outcome);
|
|
2016
2019
|
const content = message.content;
|
|
2017
2020
|
const rest = content.slice(1);
|
|
2021
|
+
const separator = projectionSeparator(outcome.text);
|
|
2018
2022
|
const first = rest[0];
|
|
2019
2023
|
let projectedContent;
|
|
2020
2024
|
if (first && first.type === "text" && typeof first.text === "string") {
|
|
2021
|
-
const merged = first.text.trim().length > 0 ? `${outcome.text}
|
|
2022
|
-
|
|
2023
|
-
${first.text}` : outcome.text;
|
|
2025
|
+
const merged = first.text.trim().length > 0 ? `${outcome.text}${separator}${first.text}` : outcome.text;
|
|
2024
2026
|
projectedContent = [{ ...first, text: merged }, ...rest.slice(1)];
|
|
2025
2027
|
} else {
|
|
2026
2028
|
projectedContent = [{ type: "text", text: outcome.text }, ...rest];
|
|
@@ -19451,6 +19453,7 @@ export {
|
|
|
19451
19453
|
generateEntryId,
|
|
19452
19454
|
createHostEnvelopeProjectorRegistry,
|
|
19453
19455
|
projectHostEnvelopes,
|
|
19456
|
+
isHostContextBlock,
|
|
19454
19457
|
FileSessionStore,
|
|
19455
19458
|
createSessionManager,
|
|
19456
19459
|
prepareSessionCompaction,
|
package/dist/cli.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
logTransportLifecycle,
|
|
24
24
|
migrateConfigFromAgentDir,
|
|
25
25
|
truncateHeadTail
|
|
26
|
-
} from "./chunks/chunk-
|
|
26
|
+
} from "./chunks/chunk-E6F4BTNN.js";
|
|
27
27
|
import {
|
|
28
28
|
resolveCliProjectRoot
|
|
29
29
|
} from "./chunks/chunk-WLFOBECN.js";
|
|
@@ -72,6 +72,7 @@ import {
|
|
|
72
72
|
interactionAttentionResolution,
|
|
73
73
|
isCompactSummaryMessage,
|
|
74
74
|
isExtensionEnabled,
|
|
75
|
+
isHostContextBlock,
|
|
75
76
|
isToolAllowedInPlanMode,
|
|
76
77
|
maybeAdvanceTodoExecutionState,
|
|
77
78
|
modalityForReadFileUnderstandingKind,
|
|
@@ -87,7 +88,7 @@ import {
|
|
|
87
88
|
shouldPreserveExecutionStateForUserText,
|
|
88
89
|
supersedeExecutionState,
|
|
89
90
|
verifyPreparedCompactionCommit
|
|
90
|
-
} from "./chunks/chunk-
|
|
91
|
+
} from "./chunks/chunk-P22SYVGO.js";
|
|
91
92
|
import "./chunks/chunk-W5B3OXHQ.js";
|
|
92
93
|
import {
|
|
93
94
|
Deref,
|
|
@@ -56591,6 +56592,10 @@ function createExtensionContext(extension, cwd, uiContext, abortFn, isIdleFn, ha
|
|
|
56591
56592
|
if (!actions?.registerProvider) throw new Error("registerProvider is not available in this host mode");
|
|
56592
56593
|
return actions.registerProvider(name, config);
|
|
56593
56594
|
},
|
|
56595
|
+
registerHostEnvelopeProjector(projector) {
|
|
56596
|
+
if (!actions?.registerHostEnvelopeProjector) throw new Error("registerHostEnvelopeProjector is not available in this host mode");
|
|
56597
|
+
return actions.registerHostEnvelopeProjector(projector);
|
|
56598
|
+
},
|
|
56594
56599
|
async loginProvider(name) {
|
|
56595
56600
|
if (!actions?.loginProvider) throw new Error("loginProvider is not available in this host mode");
|
|
56596
56601
|
return actions.loginProvider(name);
|
|
@@ -64348,6 +64353,10 @@ var ExtensionRunner = class {
|
|
|
64348
64353
|
if (!runner.actions.registerProvider) throw new Error("registerProvider is not available in this host mode");
|
|
64349
64354
|
return runner.trackUnregisterHandle(runner.actions.registerProvider(name, config));
|
|
64350
64355
|
},
|
|
64356
|
+
registerHostEnvelopeProjector: (projector) => {
|
|
64357
|
+
if (!runner.actions.registerHostEnvelopeProjector) throw new Error("registerHostEnvelopeProjector is not available in this host mode");
|
|
64358
|
+
return runner.trackUnregisterHandle(runner.actions.registerHostEnvelopeProjector(projector));
|
|
64359
|
+
},
|
|
64351
64360
|
loginProvider: async (name) => {
|
|
64352
64361
|
if (!runner.actions.loginProvider) throw new Error("loginProvider is not available in this host mode");
|
|
64353
64362
|
return runner.actions.loginProvider(name);
|
|
@@ -76670,6 +76679,369 @@ function renderCompactionDiffPanel(target, stats) {
|
|
|
76670
76679
|
target.safeRequestRender();
|
|
76671
76680
|
}
|
|
76672
76681
|
|
|
76682
|
+
// src/runtime/runtime-mode-context.ts
|
|
76683
|
+
var RUNTIME_MODE_ENVELOPE_KIND = "pie.runtimeMode";
|
|
76684
|
+
var RUNTIME_MODE_ENVELOPE_VERSION = 1;
|
|
76685
|
+
function runtimeModeEnvelopeRegistry() {
|
|
76686
|
+
return sharedRuntimeModeRegistry ??= createHostEnvelopeProjectorRegistry([{
|
|
76687
|
+
kind: RUNTIME_MODE_ENVELOPE_KIND,
|
|
76688
|
+
version: RUNTIME_MODE_ENVELOPE_VERSION,
|
|
76689
|
+
project: (data) => buildRuntimeModeContext(runtimeModeStateFromEnvelope(data))
|
|
76690
|
+
}]);
|
|
76691
|
+
}
|
|
76692
|
+
var sharedRuntimeModeRegistry;
|
|
76693
|
+
function runtimeModeStateFromEnvelope(data) {
|
|
76694
|
+
return {
|
|
76695
|
+
planMode: data.planMode === "planning" ? "planning" : "off",
|
|
76696
|
+
yoloMode: data.yoloMode === true,
|
|
76697
|
+
filesystemScope: data.filesystemScope === "all" ? "all" : "workspace",
|
|
76698
|
+
pendingTransition: typeof data.pendingTransition === "string" ? data.pendingTransition : void 0,
|
|
76699
|
+
activeToolNames: Array.isArray(data.activeToolNames) ? data.activeToolNames.filter((name) => typeof name === "string") : [],
|
|
76700
|
+
planDisabledToolNames: Array.isArray(data.planDisabledToolNames) ? data.planDisabledToolNames.filter((name) => typeof name === "string") : [],
|
|
76701
|
+
currentDate: typeof data.currentDate === "string" ? data.currentDate : void 0,
|
|
76702
|
+
timeZone: typeof data.timeZone === "string" ? data.timeZone : void 0
|
|
76703
|
+
};
|
|
76704
|
+
}
|
|
76705
|
+
function runtimeModeEnvelopeData(state) {
|
|
76706
|
+
return {
|
|
76707
|
+
planMode: state.planMode,
|
|
76708
|
+
yoloMode: state.yoloMode,
|
|
76709
|
+
filesystemScope: state.filesystemScope,
|
|
76710
|
+
...state.pendingTransition ? { pendingTransition: state.pendingTransition } : {},
|
|
76711
|
+
activeToolNames: [...state.activeToolNames],
|
|
76712
|
+
planDisabledToolNames: [...state.planDisabledToolNames],
|
|
76713
|
+
...state.currentDate ? { currentDate: state.currentDate } : {},
|
|
76714
|
+
...state.timeZone ? { timeZone: state.timeZone } : {}
|
|
76715
|
+
};
|
|
76716
|
+
}
|
|
76717
|
+
function runtimeModeEnvelopeBlock(state) {
|
|
76718
|
+
return {
|
|
76719
|
+
type: "hostContext",
|
|
76720
|
+
kind: RUNTIME_MODE_ENVELOPE_KIND,
|
|
76721
|
+
version: RUNTIME_MODE_ENVELOPE_VERSION,
|
|
76722
|
+
data: runtimeModeEnvelopeData(state)
|
|
76723
|
+
};
|
|
76724
|
+
}
|
|
76725
|
+
function isAgentMessage(value) {
|
|
76726
|
+
return !!value && typeof value === "object" && "role" in value;
|
|
76727
|
+
}
|
|
76728
|
+
function prependRuntimeModeBlockToPrompt(input, block) {
|
|
76729
|
+
if (!block) return input;
|
|
76730
|
+
if (typeof input === "string") {
|
|
76731
|
+
return [{ ...block }, { type: "text", text: input }];
|
|
76732
|
+
}
|
|
76733
|
+
if (Array.isArray(input)) {
|
|
76734
|
+
if (input.length > 0 && isAgentMessage(input[0])) {
|
|
76735
|
+
return prependBlockToMessages(input, block);
|
|
76736
|
+
}
|
|
76737
|
+
return [block, ...input];
|
|
76738
|
+
}
|
|
76739
|
+
if (isAgentMessage(input)) {
|
|
76740
|
+
return prependBlockToMessages([input], block)[0];
|
|
76741
|
+
}
|
|
76742
|
+
return [block, ...input];
|
|
76743
|
+
}
|
|
76744
|
+
function prependBlockToMessages(messages, block) {
|
|
76745
|
+
const next = [...messages];
|
|
76746
|
+
let target = -1;
|
|
76747
|
+
for (let index = next.length - 1; index >= 0; index--) {
|
|
76748
|
+
if (next[index]?.role === "user") {
|
|
76749
|
+
target = index;
|
|
76750
|
+
break;
|
|
76751
|
+
}
|
|
76752
|
+
}
|
|
76753
|
+
if (target < 0) {
|
|
76754
|
+
next.push({ role: "user", content: [block], timestamp: Date.now() });
|
|
76755
|
+
return next;
|
|
76756
|
+
}
|
|
76757
|
+
const message = next[target];
|
|
76758
|
+
if (Array.isArray(message.content)) {
|
|
76759
|
+
next[target] = { ...message, content: [block, ...message.content] };
|
|
76760
|
+
} else if (typeof message.content === "string") {
|
|
76761
|
+
next[target] = { ...message, content: [block, { type: "text", text: message.content }] };
|
|
76762
|
+
} else {
|
|
76763
|
+
next.splice(target, 0, { role: "user", content: [block], timestamp: Date.now() });
|
|
76764
|
+
}
|
|
76765
|
+
return next;
|
|
76766
|
+
}
|
|
76767
|
+
var RUNTIME_MODE_CONTEXT_MARKER = "<runtime-mode-context>";
|
|
76768
|
+
var RUNTIME_MODE_CONTEXT_END_MARKER = "</runtime-mode-context>";
|
|
76769
|
+
function buildRuntimeModeContext(state) {
|
|
76770
|
+
const lines = [
|
|
76771
|
+
RUNTIME_MODE_CONTEXT_MARKER,
|
|
76772
|
+
"Current runtime mode:"
|
|
76773
|
+
];
|
|
76774
|
+
if (state.planMode === "planning") {
|
|
76775
|
+
lines.push(
|
|
76776
|
+
"- Plan mode: active (workspace read-only; plan_scratch permits session-local temporary drafts; submit the finished plan by calling plan_submit with the ordered steps for user approval)."
|
|
76777
|
+
);
|
|
76778
|
+
if (state.planDisabledToolNames.length > 0) {
|
|
76779
|
+
lines.push(
|
|
76780
|
+
`- Disabled this turn by plan mode (calls are denied): ${state.planDisabledToolNames.join(", ")}. Do not call them while planning.`
|
|
76781
|
+
);
|
|
76782
|
+
}
|
|
76783
|
+
} else {
|
|
76784
|
+
lines.push("- Plan mode: off.");
|
|
76785
|
+
}
|
|
76786
|
+
lines.push(
|
|
76787
|
+
`- YOLO mode: ${state.yoloMode ? "on (filesystem sandbox directory restrictions are disabled)" : "off (workspace/protected-path restrictions apply)"}.`,
|
|
76788
|
+
`- Filesystem scope: ${state.filesystemScope === "all" ? "all local paths may be passed directly to file tools when permitted" : "workspace paths and configured safe roots only"}.`
|
|
76789
|
+
);
|
|
76790
|
+
if (state.pendingTransition) {
|
|
76791
|
+
const transitionText = {
|
|
76792
|
+
entered_yolo: "YOLO mode was just enabled for this turn.",
|
|
76793
|
+
exited_yolo: "YOLO mode was just disabled; do not assume previous absolute-path access still applies.",
|
|
76794
|
+
entered_plan: "Plan mode was just enabled; analyze and plan without changing the workspace. Use plan_scratch for temporary drafts, then submit the finished plan by calling plan_submit with the ordered steps for user approval.",
|
|
76795
|
+
exited_plan: "Plan mode was just disabled; execution tools may be used when the task requires them."
|
|
76796
|
+
};
|
|
76797
|
+
lines.push(`- Transition: ${transitionText[state.pendingTransition]}`);
|
|
76798
|
+
}
|
|
76799
|
+
if (state.currentDate) {
|
|
76800
|
+
lines.push(`- Current date: ${state.currentDate}${state.timeZone ? ` (${state.timeZone})` : ""}.`);
|
|
76801
|
+
}
|
|
76802
|
+
if (state.activeToolNames.length > 0) {
|
|
76803
|
+
lines.push(`- Active tools: ${state.activeToolNames.join(", ")}.`);
|
|
76804
|
+
}
|
|
76805
|
+
lines.push(RUNTIME_MODE_CONTEXT_END_MARKER);
|
|
76806
|
+
return lines.join("\n");
|
|
76807
|
+
}
|
|
76808
|
+
function runtimeModeBlockKey(state) {
|
|
76809
|
+
return JSON.stringify({
|
|
76810
|
+
planMode: state.planMode,
|
|
76811
|
+
yoloMode: state.yoloMode,
|
|
76812
|
+
filesystemScope: state.filesystemScope,
|
|
76813
|
+
currentDate: state.currentDate ?? null,
|
|
76814
|
+
activeToolNames: state.activeToolNames,
|
|
76815
|
+
planDisabledToolNames: state.planDisabledToolNames
|
|
76816
|
+
});
|
|
76817
|
+
}
|
|
76818
|
+
function shouldInjectRuntimeModeBlock(lastKey, state) {
|
|
76819
|
+
if (lastKey === null) return true;
|
|
76820
|
+
return runtimeModeBlockKey(state) !== lastKey;
|
|
76821
|
+
}
|
|
76822
|
+
function runtimeModeTraceData(state) {
|
|
76823
|
+
return {
|
|
76824
|
+
yoloMode: state.yoloMode,
|
|
76825
|
+
planMode: state.planMode,
|
|
76826
|
+
filesystemScope: state.filesystemScope,
|
|
76827
|
+
pendingTransition: state.pendingTransition,
|
|
76828
|
+
currentDate: state.currentDate,
|
|
76829
|
+
timeZone: state.timeZone,
|
|
76830
|
+
activeToolCount: state.activeToolNames.length,
|
|
76831
|
+
planDisabledToolCount: state.planDisabledToolNames.length
|
|
76832
|
+
};
|
|
76833
|
+
}
|
|
76834
|
+
function currentDateInZone(timeZone) {
|
|
76835
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
76836
|
+
year: "numeric",
|
|
76837
|
+
month: "2-digit",
|
|
76838
|
+
day: "2-digit",
|
|
76839
|
+
timeZone
|
|
76840
|
+
}).formatToParts(/* @__PURE__ */ new Date());
|
|
76841
|
+
const part = (type) => parts.find((p) => p.type === type)?.value ?? "00";
|
|
76842
|
+
return `${part("year")}-${part("month")}-${part("day")}`;
|
|
76843
|
+
}
|
|
76844
|
+
var RUNTIME_MODE_BLOCK_START_MARKER = "<runtime-mode-context>";
|
|
76845
|
+
function leadingRuntimeBlock(text) {
|
|
76846
|
+
const withoutLeadingWhitespace = text.replace(/^[\t ]+/, "");
|
|
76847
|
+
if (!withoutLeadingWhitespace.startsWith(RUNTIME_MODE_BLOCK_START_MARKER)) return null;
|
|
76848
|
+
const markerStart = text.length - withoutLeadingWhitespace.length;
|
|
76849
|
+
const endIndex = text.indexOf(RUNTIME_MODE_CONTEXT_END_MARKER, markerStart);
|
|
76850
|
+
if (endIndex < 0) return null;
|
|
76851
|
+
const block = text.slice(markerStart, endIndex + RUNTIME_MODE_CONTEXT_END_MARKER.length);
|
|
76852
|
+
const rest = text.slice(endIndex + RUNTIME_MODE_CONTEXT_END_MARKER.length).replace(/^[\t ]*(?:\r?\n){0,2}/, "");
|
|
76853
|
+
return { block, rest };
|
|
76854
|
+
}
|
|
76855
|
+
function stripLeadingRuntimeBlock(text) {
|
|
76856
|
+
const leading = leadingRuntimeBlock(text);
|
|
76857
|
+
return leading ? { rest: leading.rest } : null;
|
|
76858
|
+
}
|
|
76859
|
+
function lastUserMessageCarriesEnvelopeBlock(messages, block) {
|
|
76860
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
76861
|
+
const message = messages[index];
|
|
76862
|
+
if (message?.role !== "user") continue;
|
|
76863
|
+
const content = message.content;
|
|
76864
|
+
if (!Array.isArray(content) || content.length === 0) return false;
|
|
76865
|
+
const first = content[0];
|
|
76866
|
+
return first?.type === "hostContext" && first.kind === block.kind && first.version === block.version && JSON.stringify(first.data) === JSON.stringify(block.data);
|
|
76867
|
+
}
|
|
76868
|
+
return false;
|
|
76869
|
+
}
|
|
76870
|
+
function refreshRuntimeModeBlockOnLastUserMessage(messages, block) {
|
|
76871
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
76872
|
+
const message = messages[i];
|
|
76873
|
+
if (message?.role !== "user") continue;
|
|
76874
|
+
const content = message.content;
|
|
76875
|
+
if (typeof content === "string") {
|
|
76876
|
+
const stripped = stripLeadingRuntimeBlock(content);
|
|
76877
|
+
const rest = stripped ? stripped.rest : content;
|
|
76878
|
+
if (!rest) {
|
|
76879
|
+
const copy2 = [...messages];
|
|
76880
|
+
copy2[i] = { ...message, content: [block] };
|
|
76881
|
+
return copy2;
|
|
76882
|
+
}
|
|
76883
|
+
const copy = [...messages];
|
|
76884
|
+
copy[i] = { ...message, content: [block, { type: "text", text: rest }] };
|
|
76885
|
+
return copy;
|
|
76886
|
+
}
|
|
76887
|
+
if (Array.isArray(content)) {
|
|
76888
|
+
const first = content[0];
|
|
76889
|
+
if (first?.type === "hostContext") {
|
|
76890
|
+
if (first === block) return messages;
|
|
76891
|
+
const copy2 = [...messages];
|
|
76892
|
+
const contentCopy = [...content];
|
|
76893
|
+
contentCopy[0] = block;
|
|
76894
|
+
copy2[i] = { ...message, content: contentCopy };
|
|
76895
|
+
return copy2;
|
|
76896
|
+
}
|
|
76897
|
+
let userBlocks = content;
|
|
76898
|
+
const firstText = content[0];
|
|
76899
|
+
if (firstText?.type === "text" && typeof firstText.text === "string") {
|
|
76900
|
+
const stripped = stripLeadingRuntimeBlock(firstText.text);
|
|
76901
|
+
if (stripped) {
|
|
76902
|
+
userBlocks = stripped.rest ? [{ type: "text", text: stripped.rest }, ...content.slice(1)] : content.slice(1);
|
|
76903
|
+
}
|
|
76904
|
+
}
|
|
76905
|
+
const copy = [...messages];
|
|
76906
|
+
copy[i] = { ...message, content: [block, ...userBlocks] };
|
|
76907
|
+
return copy;
|
|
76908
|
+
}
|
|
76909
|
+
return messages;
|
|
76910
|
+
}
|
|
76911
|
+
return messages;
|
|
76912
|
+
}
|
|
76913
|
+
var RuntimeModeBlockInjector = class {
|
|
76914
|
+
constructor(options) {
|
|
76915
|
+
this.options = options;
|
|
76916
|
+
}
|
|
76917
|
+
options;
|
|
76918
|
+
lastKey = null;
|
|
76919
|
+
/** Exact frozen envelope block, including its consumed one-shot transition. */
|
|
76920
|
+
lastFrozenBlock = null;
|
|
76921
|
+
/**
|
|
76922
|
+
* Request-view overlay. While active, the CURRENT block is re-derived on
|
|
76923
|
+
* every request from the live message snapshot and applied to the latest
|
|
76924
|
+
* user message. It is not cached into history and it ends only when a real
|
|
76925
|
+
* user message freezes the current block (see `nextBlock` + the transform),
|
|
76926
|
+
* so consecutive tool rounds after a compaction retry keep the fresh state
|
|
76927
|
+
* instead of losing it after one request.
|
|
76928
|
+
*/
|
|
76929
|
+
overlayActive = false;
|
|
76930
|
+
reset() {
|
|
76931
|
+
this.lastKey = null;
|
|
76932
|
+
this.lastFrozenBlock = null;
|
|
76933
|
+
this.overlayActive = true;
|
|
76934
|
+
}
|
|
76935
|
+
/**
|
|
76936
|
+
* Arm the request-view overlay without resetting the frozen-block key. Used
|
|
76937
|
+
* when the runtime shape changed while a turn is still running (compaction
|
|
76938
|
+
* checkpoint committed, plan approval, YOLO toggle inside a tool turn): the
|
|
76939
|
+
* next and subsequent model requests must see the current state even though
|
|
76940
|
+
* no new user message has been accepted yet.
|
|
76941
|
+
*/
|
|
76942
|
+
armRefresh() {
|
|
76943
|
+
this.overlayActive = true;
|
|
76944
|
+
}
|
|
76945
|
+
/**
|
|
76946
|
+
* Envelope block to prepend to the next user message, or null when
|
|
76947
|
+
* unchanged. Does NOT end the overlay: the block is only proof once the
|
|
76948
|
+
* message carrying it reaches the request transform.
|
|
76949
|
+
*/
|
|
76950
|
+
nextBlock() {
|
|
76951
|
+
return this.freshBlock();
|
|
76952
|
+
}
|
|
76953
|
+
/**
|
|
76954
|
+
* Current envelope block for a request that reuses existing history
|
|
76955
|
+
* (overflow retry after compaction, manual-compact continue, or the tool
|
|
76956
|
+
* rounds that follow a mid-turn mode change). Returns the same block for
|
|
76957
|
+
* every request until the latest user message itself carries that block;
|
|
76958
|
+
* then the overlay is retired and null is returned. Derivation is per
|
|
76959
|
+
* request from the given snapshot; no message array is cached.
|
|
76960
|
+
*/
|
|
76961
|
+
consumeRetryRefreshBlock(messages) {
|
|
76962
|
+
if (!this.overlayActive) return null;
|
|
76963
|
+
const state = this.options.getState();
|
|
76964
|
+
const block = runtimeModeEnvelopeBlock(state);
|
|
76965
|
+
const frozenCurrent = this.lastKey === runtimeModeBlockKey(state) ? this.lastFrozenBlock : null;
|
|
76966
|
+
if (messages && (lastUserMessageCarriesEnvelopeBlock(messages, block) || frozenCurrent !== null && lastUserMessageCarriesEnvelopeBlock(messages, frozenCurrent))) {
|
|
76967
|
+
this.overlayActive = false;
|
|
76968
|
+
return null;
|
|
76969
|
+
}
|
|
76970
|
+
return block;
|
|
76971
|
+
}
|
|
76972
|
+
freshBlock() {
|
|
76973
|
+
const state = this.options.getState();
|
|
76974
|
+
if (!shouldInjectRuntimeModeBlock(this.lastKey, state)) return null;
|
|
76975
|
+
this.lastKey = runtimeModeBlockKey(state);
|
|
76976
|
+
if (state.pendingTransition) this.options.consumeTransition();
|
|
76977
|
+
this.options.noteTrace(state);
|
|
76978
|
+
this.lastFrozenBlock = runtimeModeEnvelopeBlock(state);
|
|
76979
|
+
return this.lastFrozenBlock;
|
|
76980
|
+
}
|
|
76981
|
+
};
|
|
76982
|
+
|
|
76983
|
+
// src/runtime/host-envelope-registry.ts
|
|
76984
|
+
var sharedCliEnvelopeRegistry;
|
|
76985
|
+
function cliHostEnvelopeRegistry() {
|
|
76986
|
+
if (sharedCliEnvelopeRegistry) return sharedCliEnvelopeRegistry;
|
|
76987
|
+
sharedCliEnvelopeRegistry = createHostEnvelopeProjectorRegistry();
|
|
76988
|
+
for (const { kind, version } of runtimeModeEnvelopeRegistry().listPins()) {
|
|
76989
|
+
sharedCliEnvelopeRegistry.register({
|
|
76990
|
+
kind,
|
|
76991
|
+
version,
|
|
76992
|
+
project: (data) => runtimeModeEnvelopeRegistry().resolve(kind, version).project(data)
|
|
76993
|
+
});
|
|
76994
|
+
}
|
|
76995
|
+
return sharedCliEnvelopeRegistry;
|
|
76996
|
+
}
|
|
76997
|
+
function registerExternalHostEnvelopeProjector(projector) {
|
|
76998
|
+
cliHostEnvelopeRegistry().register(projector);
|
|
76999
|
+
return () => {
|
|
77000
|
+
};
|
|
77001
|
+
}
|
|
77002
|
+
function cliHostEnvelopeKinds() {
|
|
77003
|
+
return cliHostEnvelopeRegistry().listPins().map(({ kind, version }) => `${kind}@${version}`).sort();
|
|
77004
|
+
}
|
|
77005
|
+
function projectCliHostEnvelopes(messages) {
|
|
77006
|
+
return projectHostEnvelopes(messages, cliHostEnvelopeRegistry());
|
|
77007
|
+
}
|
|
77008
|
+
function isIntakeHostContextError(value) {
|
|
77009
|
+
return value.code !== void 0;
|
|
77010
|
+
}
|
|
77011
|
+
function intakeHostContextBlock(value) {
|
|
77012
|
+
if (!isHostContextBlock(value)) {
|
|
77013
|
+
return {
|
|
77014
|
+
ok: false,
|
|
77015
|
+
code: "host_context_invalid_shape",
|
|
77016
|
+
message: "hostContext must be { type: 'hostContext', kind: string, version: integer >= 1, data: object }"
|
|
77017
|
+
};
|
|
77018
|
+
}
|
|
77019
|
+
const block = value;
|
|
77020
|
+
const projector = cliHostEnvelopeRegistry().resolve(block.kind, block.version);
|
|
77021
|
+
if (!projector) {
|
|
77022
|
+
return {
|
|
77023
|
+
ok: false,
|
|
77024
|
+
code: "host_context_unknown_projector",
|
|
77025
|
+
message: `no projector for ${block.kind}@${block.version}; this build supports: ${cliHostEnvelopeKinds().join(", ")}`
|
|
77026
|
+
};
|
|
77027
|
+
}
|
|
77028
|
+
try {
|
|
77029
|
+
const text = projector.project(block.data);
|
|
77030
|
+
if (typeof text !== "string" || text.trim().length === 0) throw new Error("projector returned empty text");
|
|
77031
|
+
} catch (error) {
|
|
77032
|
+
return {
|
|
77033
|
+
ok: false,
|
|
77034
|
+
code: "host_context_unknown_projector",
|
|
77035
|
+
message: `projector for ${block.kind}@${block.version} rejected the data: ${error instanceof Error ? error.message : String(error)}`
|
|
77036
|
+
};
|
|
77037
|
+
}
|
|
77038
|
+
return { ok: true, block };
|
|
77039
|
+
}
|
|
77040
|
+
function intakeHostContextFailure(value) {
|
|
77041
|
+
const result = intakeHostContextBlock(value);
|
|
77042
|
+
return isIntakeHostContextError(result) ? { code: result.code, message: result.message } : void 0;
|
|
77043
|
+
}
|
|
77044
|
+
|
|
76673
77045
|
// src/commands/interactive-compact-command.ts
|
|
76674
77046
|
async function handleCompactCommand(host) {
|
|
76675
77047
|
if (host.submitLock || host.isProcessing || host.isCompacting) {
|
|
@@ -76723,7 +77095,7 @@ async function handleCompactCommand(host) {
|
|
|
76723
77095
|
if (beforeCompact?.summary) {
|
|
76724
77096
|
summary = beforeCompact.summary;
|
|
76725
77097
|
} else {
|
|
76726
|
-
summary = await createCompactionSummary(preparation.messages, compactOptions);
|
|
77098
|
+
summary = await createCompactionSummary(projectCliHostEnvelopes(preparation.messages), compactOptions);
|
|
76727
77099
|
}
|
|
76728
77100
|
const verified = verifyPreparedCompactionCommit({
|
|
76729
77101
|
preparation,
|
|
@@ -79386,7 +79758,7 @@ async function createCliAutoCompactionResult(params) {
|
|
|
79386
79758
|
systemPrompt: params.systemPrompt,
|
|
79387
79759
|
signal: params.context.signal
|
|
79388
79760
|
};
|
|
79389
|
-
const summary = await createCompactionSummary(params.context.messages, compactOptions);
|
|
79761
|
+
const summary = await createCompactionSummary(projectCliHostEnvelopes(params.context.messages), compactOptions);
|
|
79390
79762
|
if (params.context.signal?.aborted) {
|
|
79391
79763
|
return { aborted: true };
|
|
79392
79764
|
}
|
|
@@ -80604,307 +80976,6 @@ function createInteractiveAgentSessionController(host) {
|
|
|
80604
80976
|
});
|
|
80605
80977
|
}
|
|
80606
80978
|
|
|
80607
|
-
// src/runtime/runtime-mode-context.ts
|
|
80608
|
-
var RUNTIME_MODE_ENVELOPE_KIND = "pie.runtimeMode";
|
|
80609
|
-
var RUNTIME_MODE_ENVELOPE_VERSION = 1;
|
|
80610
|
-
function runtimeModeEnvelopeRegistry() {
|
|
80611
|
-
return sharedRuntimeModeRegistry ??= createHostEnvelopeProjectorRegistry([{
|
|
80612
|
-
kind: RUNTIME_MODE_ENVELOPE_KIND,
|
|
80613
|
-
version: RUNTIME_MODE_ENVELOPE_VERSION,
|
|
80614
|
-
project: (data) => buildRuntimeModeContext(runtimeModeStateFromEnvelope(data))
|
|
80615
|
-
}]);
|
|
80616
|
-
}
|
|
80617
|
-
var sharedRuntimeModeRegistry;
|
|
80618
|
-
function runtimeModeStateFromEnvelope(data) {
|
|
80619
|
-
return {
|
|
80620
|
-
planMode: data.planMode === "planning" ? "planning" : "off",
|
|
80621
|
-
yoloMode: data.yoloMode === true,
|
|
80622
|
-
filesystemScope: data.filesystemScope === "all" ? "all" : "workspace",
|
|
80623
|
-
pendingTransition: typeof data.pendingTransition === "string" ? data.pendingTransition : void 0,
|
|
80624
|
-
activeToolNames: Array.isArray(data.activeToolNames) ? data.activeToolNames.filter((name) => typeof name === "string") : [],
|
|
80625
|
-
planDisabledToolNames: Array.isArray(data.planDisabledToolNames) ? data.planDisabledToolNames.filter((name) => typeof name === "string") : [],
|
|
80626
|
-
currentDate: typeof data.currentDate === "string" ? data.currentDate : void 0,
|
|
80627
|
-
timeZone: typeof data.timeZone === "string" ? data.timeZone : void 0
|
|
80628
|
-
};
|
|
80629
|
-
}
|
|
80630
|
-
function runtimeModeEnvelopeData(state) {
|
|
80631
|
-
return {
|
|
80632
|
-
planMode: state.planMode,
|
|
80633
|
-
yoloMode: state.yoloMode,
|
|
80634
|
-
filesystemScope: state.filesystemScope,
|
|
80635
|
-
...state.pendingTransition ? { pendingTransition: state.pendingTransition } : {},
|
|
80636
|
-
activeToolNames: [...state.activeToolNames],
|
|
80637
|
-
planDisabledToolNames: [...state.planDisabledToolNames],
|
|
80638
|
-
...state.currentDate ? { currentDate: state.currentDate } : {},
|
|
80639
|
-
...state.timeZone ? { timeZone: state.timeZone } : {}
|
|
80640
|
-
};
|
|
80641
|
-
}
|
|
80642
|
-
function runtimeModeEnvelopeBlock(state) {
|
|
80643
|
-
return {
|
|
80644
|
-
type: "hostContext",
|
|
80645
|
-
kind: RUNTIME_MODE_ENVELOPE_KIND,
|
|
80646
|
-
version: RUNTIME_MODE_ENVELOPE_VERSION,
|
|
80647
|
-
data: runtimeModeEnvelopeData(state)
|
|
80648
|
-
};
|
|
80649
|
-
}
|
|
80650
|
-
function isAgentMessage(value) {
|
|
80651
|
-
return !!value && typeof value === "object" && "role" in value;
|
|
80652
|
-
}
|
|
80653
|
-
function prependRuntimeModeBlockToPrompt(input, block) {
|
|
80654
|
-
if (!block) return input;
|
|
80655
|
-
if (typeof input === "string") {
|
|
80656
|
-
return [{ ...block }, { type: "text", text: input }];
|
|
80657
|
-
}
|
|
80658
|
-
if (Array.isArray(input)) {
|
|
80659
|
-
if (input.length > 0 && isAgentMessage(input[0])) {
|
|
80660
|
-
return prependBlockToMessages(input, block);
|
|
80661
|
-
}
|
|
80662
|
-
return [block, ...input];
|
|
80663
|
-
}
|
|
80664
|
-
if (isAgentMessage(input)) {
|
|
80665
|
-
return prependBlockToMessages([input], block)[0];
|
|
80666
|
-
}
|
|
80667
|
-
return [block, ...input];
|
|
80668
|
-
}
|
|
80669
|
-
function prependBlockToMessages(messages, block) {
|
|
80670
|
-
const next = [...messages];
|
|
80671
|
-
let target = -1;
|
|
80672
|
-
for (let index = next.length - 1; index >= 0; index--) {
|
|
80673
|
-
if (next[index]?.role === "user") {
|
|
80674
|
-
target = index;
|
|
80675
|
-
break;
|
|
80676
|
-
}
|
|
80677
|
-
}
|
|
80678
|
-
if (target < 0) {
|
|
80679
|
-
next.push({ role: "user", content: [block], timestamp: Date.now() });
|
|
80680
|
-
return next;
|
|
80681
|
-
}
|
|
80682
|
-
const message = next[target];
|
|
80683
|
-
if (Array.isArray(message.content)) {
|
|
80684
|
-
next[target] = { ...message, content: [block, ...message.content] };
|
|
80685
|
-
} else if (typeof message.content === "string") {
|
|
80686
|
-
next[target] = { ...message, content: [block, { type: "text", text: message.content }] };
|
|
80687
|
-
} else {
|
|
80688
|
-
next.splice(target, 0, { role: "user", content: [block], timestamp: Date.now() });
|
|
80689
|
-
}
|
|
80690
|
-
return next;
|
|
80691
|
-
}
|
|
80692
|
-
var RUNTIME_MODE_CONTEXT_MARKER = "<runtime-mode-context>";
|
|
80693
|
-
var RUNTIME_MODE_CONTEXT_END_MARKER = "</runtime-mode-context>";
|
|
80694
|
-
function buildRuntimeModeContext(state) {
|
|
80695
|
-
const lines = [
|
|
80696
|
-
RUNTIME_MODE_CONTEXT_MARKER,
|
|
80697
|
-
"Current runtime mode:"
|
|
80698
|
-
];
|
|
80699
|
-
if (state.planMode === "planning") {
|
|
80700
|
-
lines.push(
|
|
80701
|
-
"- Plan mode: active (workspace read-only; plan_scratch permits session-local temporary drafts; submit the finished plan by calling plan_submit with the ordered steps for user approval)."
|
|
80702
|
-
);
|
|
80703
|
-
if (state.planDisabledToolNames.length > 0) {
|
|
80704
|
-
lines.push(
|
|
80705
|
-
`- Disabled this turn by plan mode (calls are denied): ${state.planDisabledToolNames.join(", ")}. Do not call them while planning.`
|
|
80706
|
-
);
|
|
80707
|
-
}
|
|
80708
|
-
} else {
|
|
80709
|
-
lines.push("- Plan mode: off.");
|
|
80710
|
-
}
|
|
80711
|
-
lines.push(
|
|
80712
|
-
`- YOLO mode: ${state.yoloMode ? "on (filesystem sandbox directory restrictions are disabled)" : "off (workspace/protected-path restrictions apply)"}.`,
|
|
80713
|
-
`- Filesystem scope: ${state.filesystemScope === "all" ? "all local paths may be passed directly to file tools when permitted" : "workspace paths and configured safe roots only"}.`
|
|
80714
|
-
);
|
|
80715
|
-
if (state.pendingTransition) {
|
|
80716
|
-
const transitionText = {
|
|
80717
|
-
entered_yolo: "YOLO mode was just enabled for this turn.",
|
|
80718
|
-
exited_yolo: "YOLO mode was just disabled; do not assume previous absolute-path access still applies.",
|
|
80719
|
-
entered_plan: "Plan mode was just enabled; analyze and plan without changing the workspace. Use plan_scratch for temporary drafts, then submit the finished plan by calling plan_submit with the ordered steps for user approval.",
|
|
80720
|
-
exited_plan: "Plan mode was just disabled; execution tools may be used when the task requires them."
|
|
80721
|
-
};
|
|
80722
|
-
lines.push(`- Transition: ${transitionText[state.pendingTransition]}`);
|
|
80723
|
-
}
|
|
80724
|
-
if (state.currentDate) {
|
|
80725
|
-
lines.push(`- Current date: ${state.currentDate}${state.timeZone ? ` (${state.timeZone})` : ""}.`);
|
|
80726
|
-
}
|
|
80727
|
-
if (state.activeToolNames.length > 0) {
|
|
80728
|
-
lines.push(`- Active tools: ${state.activeToolNames.join(", ")}.`);
|
|
80729
|
-
}
|
|
80730
|
-
lines.push(RUNTIME_MODE_CONTEXT_END_MARKER);
|
|
80731
|
-
return lines.join("\n");
|
|
80732
|
-
}
|
|
80733
|
-
function runtimeModeBlockKey(state) {
|
|
80734
|
-
return JSON.stringify({
|
|
80735
|
-
planMode: state.planMode,
|
|
80736
|
-
yoloMode: state.yoloMode,
|
|
80737
|
-
filesystemScope: state.filesystemScope,
|
|
80738
|
-
currentDate: state.currentDate ?? null,
|
|
80739
|
-
activeToolNames: state.activeToolNames,
|
|
80740
|
-
planDisabledToolNames: state.planDisabledToolNames
|
|
80741
|
-
});
|
|
80742
|
-
}
|
|
80743
|
-
function shouldInjectRuntimeModeBlock(lastKey, state) {
|
|
80744
|
-
if (lastKey === null) return true;
|
|
80745
|
-
return runtimeModeBlockKey(state) !== lastKey;
|
|
80746
|
-
}
|
|
80747
|
-
function runtimeModeTraceData(state) {
|
|
80748
|
-
return {
|
|
80749
|
-
yoloMode: state.yoloMode,
|
|
80750
|
-
planMode: state.planMode,
|
|
80751
|
-
filesystemScope: state.filesystemScope,
|
|
80752
|
-
pendingTransition: state.pendingTransition,
|
|
80753
|
-
currentDate: state.currentDate,
|
|
80754
|
-
timeZone: state.timeZone,
|
|
80755
|
-
activeToolCount: state.activeToolNames.length,
|
|
80756
|
-
planDisabledToolCount: state.planDisabledToolNames.length
|
|
80757
|
-
};
|
|
80758
|
-
}
|
|
80759
|
-
function currentDateInZone(timeZone) {
|
|
80760
|
-
const parts = new Intl.DateTimeFormat("en-US", {
|
|
80761
|
-
year: "numeric",
|
|
80762
|
-
month: "2-digit",
|
|
80763
|
-
day: "2-digit",
|
|
80764
|
-
timeZone
|
|
80765
|
-
}).formatToParts(/* @__PURE__ */ new Date());
|
|
80766
|
-
const part = (type) => parts.find((p) => p.type === type)?.value ?? "00";
|
|
80767
|
-
return `${part("year")}-${part("month")}-${part("day")}`;
|
|
80768
|
-
}
|
|
80769
|
-
var RUNTIME_MODE_BLOCK_START_MARKER = "<runtime-mode-context>";
|
|
80770
|
-
function leadingRuntimeBlock(text) {
|
|
80771
|
-
const withoutLeadingWhitespace = text.replace(/^[\t ]+/, "");
|
|
80772
|
-
if (!withoutLeadingWhitespace.startsWith(RUNTIME_MODE_BLOCK_START_MARKER)) return null;
|
|
80773
|
-
const markerStart = text.length - withoutLeadingWhitespace.length;
|
|
80774
|
-
const endIndex = text.indexOf(RUNTIME_MODE_CONTEXT_END_MARKER, markerStart);
|
|
80775
|
-
if (endIndex < 0) return null;
|
|
80776
|
-
const block = text.slice(markerStart, endIndex + RUNTIME_MODE_CONTEXT_END_MARKER.length);
|
|
80777
|
-
const rest = text.slice(endIndex + RUNTIME_MODE_CONTEXT_END_MARKER.length).replace(/^[\t ]*(?:\r?\n){0,2}/, "");
|
|
80778
|
-
return { block, rest };
|
|
80779
|
-
}
|
|
80780
|
-
function stripLeadingRuntimeBlock(text) {
|
|
80781
|
-
const leading = leadingRuntimeBlock(text);
|
|
80782
|
-
return leading ? { rest: leading.rest } : null;
|
|
80783
|
-
}
|
|
80784
|
-
function lastUserMessageCarriesEnvelopeBlock(messages, block) {
|
|
80785
|
-
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
80786
|
-
const message = messages[index];
|
|
80787
|
-
if (message?.role !== "user") continue;
|
|
80788
|
-
const content = message.content;
|
|
80789
|
-
if (!Array.isArray(content) || content.length === 0) return false;
|
|
80790
|
-
const first = content[0];
|
|
80791
|
-
return first?.type === "hostContext" && first.kind === block.kind && first.version === block.version && JSON.stringify(first.data) === JSON.stringify(block.data);
|
|
80792
|
-
}
|
|
80793
|
-
return false;
|
|
80794
|
-
}
|
|
80795
|
-
function refreshRuntimeModeBlockOnLastUserMessage(messages, block) {
|
|
80796
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
80797
|
-
const message = messages[i];
|
|
80798
|
-
if (message?.role !== "user") continue;
|
|
80799
|
-
const content = message.content;
|
|
80800
|
-
if (typeof content === "string") {
|
|
80801
|
-
const stripped = stripLeadingRuntimeBlock(content);
|
|
80802
|
-
const rest = stripped ? stripped.rest : content;
|
|
80803
|
-
if (!rest) {
|
|
80804
|
-
const copy2 = [...messages];
|
|
80805
|
-
copy2[i] = { ...message, content: [block] };
|
|
80806
|
-
return copy2;
|
|
80807
|
-
}
|
|
80808
|
-
const copy = [...messages];
|
|
80809
|
-
copy[i] = { ...message, content: [block, { type: "text", text: rest }] };
|
|
80810
|
-
return copy;
|
|
80811
|
-
}
|
|
80812
|
-
if (Array.isArray(content)) {
|
|
80813
|
-
const first = content[0];
|
|
80814
|
-
if (first?.type === "hostContext") {
|
|
80815
|
-
if (first === block) return messages;
|
|
80816
|
-
const copy2 = [...messages];
|
|
80817
|
-
const contentCopy = [...content];
|
|
80818
|
-
contentCopy[0] = block;
|
|
80819
|
-
copy2[i] = { ...message, content: contentCopy };
|
|
80820
|
-
return copy2;
|
|
80821
|
-
}
|
|
80822
|
-
let userBlocks = content;
|
|
80823
|
-
const firstText = content[0];
|
|
80824
|
-
if (firstText?.type === "text" && typeof firstText.text === "string") {
|
|
80825
|
-
const stripped = stripLeadingRuntimeBlock(firstText.text);
|
|
80826
|
-
if (stripped) {
|
|
80827
|
-
userBlocks = stripped.rest ? [{ type: "text", text: stripped.rest }, ...content.slice(1)] : content.slice(1);
|
|
80828
|
-
}
|
|
80829
|
-
}
|
|
80830
|
-
const copy = [...messages];
|
|
80831
|
-
copy[i] = { ...message, content: [block, ...userBlocks] };
|
|
80832
|
-
return copy;
|
|
80833
|
-
}
|
|
80834
|
-
return messages;
|
|
80835
|
-
}
|
|
80836
|
-
return messages;
|
|
80837
|
-
}
|
|
80838
|
-
var RuntimeModeBlockInjector = class {
|
|
80839
|
-
constructor(options) {
|
|
80840
|
-
this.options = options;
|
|
80841
|
-
}
|
|
80842
|
-
options;
|
|
80843
|
-
lastKey = null;
|
|
80844
|
-
/** Exact frozen envelope block, including its consumed one-shot transition. */
|
|
80845
|
-
lastFrozenBlock = null;
|
|
80846
|
-
/**
|
|
80847
|
-
* Request-view overlay. While active, the CURRENT block is re-derived on
|
|
80848
|
-
* every request from the live message snapshot and applied to the latest
|
|
80849
|
-
* user message. It is not cached into history and it ends only when a real
|
|
80850
|
-
* user message freezes the current block (see `nextBlock` + the transform),
|
|
80851
|
-
* so consecutive tool rounds after a compaction retry keep the fresh state
|
|
80852
|
-
* instead of losing it after one request.
|
|
80853
|
-
*/
|
|
80854
|
-
overlayActive = false;
|
|
80855
|
-
reset() {
|
|
80856
|
-
this.lastKey = null;
|
|
80857
|
-
this.lastFrozenBlock = null;
|
|
80858
|
-
this.overlayActive = true;
|
|
80859
|
-
}
|
|
80860
|
-
/**
|
|
80861
|
-
* Arm the request-view overlay without resetting the frozen-block key. Used
|
|
80862
|
-
* when the runtime shape changed while a turn is still running (compaction
|
|
80863
|
-
* checkpoint committed, plan approval, YOLO toggle inside a tool turn): the
|
|
80864
|
-
* next and subsequent model requests must see the current state even though
|
|
80865
|
-
* no new user message has been accepted yet.
|
|
80866
|
-
*/
|
|
80867
|
-
armRefresh() {
|
|
80868
|
-
this.overlayActive = true;
|
|
80869
|
-
}
|
|
80870
|
-
/**
|
|
80871
|
-
* Envelope block to prepend to the next user message, or null when
|
|
80872
|
-
* unchanged. Does NOT end the overlay: the block is only proof once the
|
|
80873
|
-
* message carrying it reaches the request transform.
|
|
80874
|
-
*/
|
|
80875
|
-
nextBlock() {
|
|
80876
|
-
return this.freshBlock();
|
|
80877
|
-
}
|
|
80878
|
-
/**
|
|
80879
|
-
* Current envelope block for a request that reuses existing history
|
|
80880
|
-
* (overflow retry after compaction, manual-compact continue, or the tool
|
|
80881
|
-
* rounds that follow a mid-turn mode change). Returns the same block for
|
|
80882
|
-
* every request until the latest user message itself carries that block;
|
|
80883
|
-
* then the overlay is retired and null is returned. Derivation is per
|
|
80884
|
-
* request from the given snapshot; no message array is cached.
|
|
80885
|
-
*/
|
|
80886
|
-
consumeRetryRefreshBlock(messages) {
|
|
80887
|
-
if (!this.overlayActive) return null;
|
|
80888
|
-
const state = this.options.getState();
|
|
80889
|
-
const block = runtimeModeEnvelopeBlock(state);
|
|
80890
|
-
const frozenCurrent = this.lastKey === runtimeModeBlockKey(state) ? this.lastFrozenBlock : null;
|
|
80891
|
-
if (messages && (lastUserMessageCarriesEnvelopeBlock(messages, block) || frozenCurrent !== null && lastUserMessageCarriesEnvelopeBlock(messages, frozenCurrent))) {
|
|
80892
|
-
this.overlayActive = false;
|
|
80893
|
-
return null;
|
|
80894
|
-
}
|
|
80895
|
-
return block;
|
|
80896
|
-
}
|
|
80897
|
-
freshBlock() {
|
|
80898
|
-
const state = this.options.getState();
|
|
80899
|
-
if (!shouldInjectRuntimeModeBlock(this.lastKey, state)) return null;
|
|
80900
|
-
this.lastKey = runtimeModeBlockKey(state);
|
|
80901
|
-
if (state.pendingTransition) this.options.consumeTransition();
|
|
80902
|
-
this.options.noteTrace(state);
|
|
80903
|
-
this.lastFrozenBlock = runtimeModeEnvelopeBlock(state);
|
|
80904
|
-
return this.lastFrozenBlock;
|
|
80905
|
-
}
|
|
80906
|
-
};
|
|
80907
|
-
|
|
80908
80979
|
// src/runtime/cache-retention.ts
|
|
80909
80980
|
function createCacheRetentionStreamFn(configured, getConfiguredRetention) {
|
|
80910
80981
|
const base = configured ?? ((model, context, options) => streamSimple(model, context, options));
|
|
@@ -81767,6 +81838,7 @@ async function loadInteractiveExtensions(host) {
|
|
|
81767
81838
|
host.noteRuntimeModeChanged("extension_register_provider");
|
|
81768
81839
|
return unregister;
|
|
81769
81840
|
},
|
|
81841
|
+
registerHostEnvelopeProjector: (projector) => registerExternalHostEnvelopeProjector(projector),
|
|
81770
81842
|
loginProvider: async (name) => {
|
|
81771
81843
|
const loggedIn = await loginExtensionProvider({
|
|
81772
81844
|
provider: name,
|
|
@@ -82249,7 +82321,7 @@ var InteractiveMode = class {
|
|
|
82249
82321
|
});
|
|
82250
82322
|
return projectHostEnvelopes(
|
|
82251
82323
|
structured,
|
|
82252
|
-
|
|
82324
|
+
cliHostEnvelopeRegistry(),
|
|
82253
82325
|
(outcome) => this.sessionTrace.noteRuntimeEvent(outcome.degraded ? "host_envelope_degraded" : "host_envelope_projected", outcome.audit)
|
|
82254
82326
|
);
|
|
82255
82327
|
}
|
|
@@ -83039,6 +83111,7 @@ async function loadPrintModeExtensions(params) {
|
|
|
83039
83111
|
setSessionName: (name) => params.sessionManager.setSessionName(name),
|
|
83040
83112
|
getSessionName: () => params.sessionManager.getSessionName(),
|
|
83041
83113
|
registerProvider: (name, config) => params.modelRegistry.registerProvider(name, config),
|
|
83114
|
+
registerHostEnvelopeProjector: (projector) => registerExternalHostEnvelopeProjector(projector),
|
|
83042
83115
|
loginProvider: (name) => loginExtensionProvider({
|
|
83043
83116
|
provider: name,
|
|
83044
83117
|
modelRegistry: params.modelRegistry,
|
|
@@ -83137,6 +83210,12 @@ async function runPrintMode(params) {
|
|
|
83137
83210
|
thinkingLevel: printThinkingLevel
|
|
83138
83211
|
},
|
|
83139
83212
|
apiKey: runtime.apiKey,
|
|
83213
|
+
// Print mode restores interactive sessions verbatim (AgentSessionController
|
|
83214
|
+
// loads stored history on construction). Those sessions carry persisted
|
|
83215
|
+
// hostContext facts; project them to model-visible text or the provider
|
|
83216
|
+
// converters reject the request (`Unprojected hostContext block`). The
|
|
83217
|
+
// persisted history is never rewritten — projection builds the wire view.
|
|
83218
|
+
transformContext: async (messages) => projectCliHostEnvelopes(messages),
|
|
83140
83219
|
// Body-free transport timeline for the main (print-mode) agent.
|
|
83141
83220
|
streamFn: createTransportDiagnosticsStreamFn(params.streamFn ?? streamSimple, logTransportLifecycle)
|
|
83142
83221
|
});
|
|
@@ -83380,14 +83459,17 @@ function parseInput(line) {
|
|
|
83380
83459
|
};
|
|
83381
83460
|
}
|
|
83382
83461
|
if (parsed.type === "sidechat.request" && typeof parsed.requestId === "string" && typeof parsed.prompt === "string") {
|
|
83462
|
+
if (parsed.hostContext !== void 0 && !isHostContextBlock(parsed.hostContext)) return null;
|
|
83383
83463
|
return {
|
|
83384
83464
|
type: "sidechat.request",
|
|
83385
83465
|
sessionId: typeof parsed.sessionId === "string" ? parsed.sessionId : void 0,
|
|
83386
83466
|
requestId: parsed.requestId,
|
|
83387
|
-
prompt: parsed.prompt
|
|
83467
|
+
prompt: parsed.prompt,
|
|
83468
|
+
hostContext: parsed.hostContext
|
|
83388
83469
|
};
|
|
83389
83470
|
}
|
|
83390
83471
|
if ((parsed.type === "turn.request" || parsed.type === "turn.input") && typeof parsed.turnId === "string" && typeof parsed.prompt === "string") {
|
|
83472
|
+
if (parsed.hostContext !== void 0 && !isHostContextBlock(parsed.hostContext)) return null;
|
|
83391
83473
|
const streamingBehavior = parsed.streamingBehavior;
|
|
83392
83474
|
if (streamingBehavior !== void 0 && streamingBehavior !== "steer" && streamingBehavior !== "followUp") {
|
|
83393
83475
|
return null;
|
|
@@ -83397,6 +83479,7 @@ function parseInput(line) {
|
|
|
83397
83479
|
sessionId: typeof parsed.sessionId === "string" ? parsed.sessionId : void 0,
|
|
83398
83480
|
turnId: parsed.turnId,
|
|
83399
83481
|
prompt: parsed.prompt,
|
|
83482
|
+
hostContext: parsed.hostContext,
|
|
83400
83483
|
streamingBehavior,
|
|
83401
83484
|
cwd: typeof parsed.cwd === "string" ? parsed.cwd : void 0,
|
|
83402
83485
|
metadata: isRecord3(parsed.metadata) ? parsed.metadata : void 0
|
|
@@ -83505,6 +83588,7 @@ async function loadJsonModeExtensions(params) {
|
|
|
83505
83588
|
getRuntimeTools: () => params.getAgent()?.state.tools ?? [],
|
|
83506
83589
|
resolveModelClass: (modelClass) => params.runtime.modelRegistry.resolveModelClass(modelClass),
|
|
83507
83590
|
resolveModelRef: (modelRef) => params.runtime.modelRegistry.resolveModelRef(modelRef),
|
|
83591
|
+
registerHostEnvelopeProjector: (projector) => registerExternalHostEnvelopeProjector(projector),
|
|
83508
83592
|
getMessages: () => params.getAgent()?.state.messages ?? [],
|
|
83509
83593
|
getSessionMetadata: () => ({ ...params.runtime.sessionManager.getActiveSession()?.metadata ?? {} }),
|
|
83510
83594
|
setSessionMetadata: (key, value) => {
|
|
@@ -83579,7 +83663,14 @@ async function runJsonEventsMode(params) {
|
|
|
83579
83663
|
const prewarmTimeoutMs = Number(process.env.PIE_JSON_EVENTS_PREWARM_TIMEOUT_MS || 1e4);
|
|
83580
83664
|
const sidechatTimeoutMs = Number(process.env.PIE_JSON_EVENTS_SIDECHAT_TIMEOUT_MS || 3e5);
|
|
83581
83665
|
await prewarmRuntime();
|
|
83582
|
-
writeEvent({
|
|
83666
|
+
writeEvent({
|
|
83667
|
+
type: "agent.ready",
|
|
83668
|
+
sessionId,
|
|
83669
|
+
// Capability broadcast: the envelope kinds THIS build can project at
|
|
83670
|
+
// intake (embedded external kinds included), so embedders can probe
|
|
83671
|
+
// before their first turn instead of learning mismatches from failures.
|
|
83672
|
+
capabilities: { hostContextKinds: cliHostEnvelopeKinds() }
|
|
83673
|
+
});
|
|
83583
83674
|
function trackSidechatPromise(promise) {
|
|
83584
83675
|
activeSidechatPromise = promise;
|
|
83585
83676
|
void promise.finally(() => {
|
|
@@ -83681,7 +83772,7 @@ async function runJsonEventsMode(params) {
|
|
|
83681
83772
|
timestamp: startedAt,
|
|
83682
83773
|
message: {
|
|
83683
83774
|
role: "user",
|
|
83684
|
-
content: message.prompt,
|
|
83775
|
+
content: message.hostContext ? [message.hostContext, { type: "text", text: message.prompt }] : message.prompt,
|
|
83685
83776
|
timestamp: startedAt
|
|
83686
83777
|
}
|
|
83687
83778
|
};
|
|
@@ -83894,6 +83985,11 @@ async function runJsonEventsMode(params) {
|
|
|
83894
83985
|
});
|
|
83895
83986
|
}
|
|
83896
83987
|
async function handleSidechat(message) {
|
|
83988
|
+
const hostContextFailure = validateIntakeHostContext(message);
|
|
83989
|
+
if (hostContextFailure) {
|
|
83990
|
+
writeSidechatFailure(message, hostContextFailure.message, hostContextFailure.code);
|
|
83991
|
+
return;
|
|
83992
|
+
}
|
|
83897
83993
|
if (isSessionMismatch(message)) {
|
|
83898
83994
|
writeSidechatFailure(message, sessionMismatchError(message.sessionId), "session_mismatch");
|
|
83899
83995
|
return;
|
|
@@ -83959,6 +84055,9 @@ async function runJsonEventsMode(params) {
|
|
|
83959
84055
|
messages: structuredClone(parent.state.messages)
|
|
83960
84056
|
},
|
|
83961
84057
|
apiKey: runtime.apiKey,
|
|
84058
|
+
// The sidechat snapshot clones the parent's stored history, including
|
|
84059
|
+
// persisted hostContext facts; project them like the main agent does.
|
|
84060
|
+
transformContext: async (messages) => projectCliHostEnvelopes(messages),
|
|
83962
84061
|
// Same body-free transport timeline as the main agent: a sidechat is
|
|
83963
84062
|
// an independent Responses request and previously had no record at all
|
|
83964
84063
|
// when it stalled. `streamSimple` matches the host default when the
|
|
@@ -83972,7 +84071,7 @@ async function runJsonEventsMode(params) {
|
|
|
83972
84071
|
}, sidechatTimeoutMs);
|
|
83973
84072
|
timer.unref?.();
|
|
83974
84073
|
try {
|
|
83975
|
-
await sideAgent.prompt(message
|
|
84074
|
+
await sideAgent.prompt(sidechatPromptBlocks(message));
|
|
83976
84075
|
} finally {
|
|
83977
84076
|
clearTimeout(timer);
|
|
83978
84077
|
}
|
|
@@ -84340,6 +84439,10 @@ async function runJsonEventsMode(params) {
|
|
|
84340
84439
|
thinkingLevel
|
|
84341
84440
|
},
|
|
84342
84441
|
apiKey: runtime.apiKey,
|
|
84442
|
+
// Restored interactive sessions carry persisted hostContext facts; project
|
|
84443
|
+
// them to model-visible text at the request boundary or the provider
|
|
84444
|
+
// converters reject the request (`Unprojected hostContext block`).
|
|
84445
|
+
transformContext: async (messages) => projectCliHostEnvelopes(messages),
|
|
84343
84446
|
// Body-free transport timeline for the main (JSON-events) agent.
|
|
84344
84447
|
streamFn: createJsonEventsTransportStreamFn(params.streamFn)
|
|
84345
84448
|
});
|
|
@@ -84473,7 +84576,27 @@ async function runJsonEventsMode(params) {
|
|
|
84473
84576
|
syncSessionModelMetadata(runtime.sessionManager, runtime.model, thinkingLevel);
|
|
84474
84577
|
}
|
|
84475
84578
|
}
|
|
84579
|
+
function promptInputFor(message) {
|
|
84580
|
+
return message.hostContext ? [message.hostContext, { type: "text", text: message.prompt }] : message.prompt;
|
|
84581
|
+
}
|
|
84582
|
+
function sidechatPromptBlocks(message) {
|
|
84583
|
+
return message.hostContext ? [message.hostContext, { type: "text", text: message.prompt }] : [{ type: "text", text: message.prompt }];
|
|
84584
|
+
}
|
|
84585
|
+
function validateIntakeHostContext(message) {
|
|
84586
|
+
return message.hostContext ? intakeHostContextFailure(message.hostContext) : void 0;
|
|
84587
|
+
}
|
|
84476
84588
|
async function runTurn(message) {
|
|
84589
|
+
const hostContextFailure = validateIntakeHostContext(message);
|
|
84590
|
+
if (hostContextFailure) {
|
|
84591
|
+
writeEvent({
|
|
84592
|
+
type: "turn.failed",
|
|
84593
|
+
sessionId,
|
|
84594
|
+
turnId: message.turnId,
|
|
84595
|
+
error: hostContextFailure.message,
|
|
84596
|
+
...hostContextFailure.code === "host_context_unknown_projector" ? { hostContextKinds: cliHostEnvelopeKinds() } : {}
|
|
84597
|
+
});
|
|
84598
|
+
return;
|
|
84599
|
+
}
|
|
84477
84600
|
if (isSessionMismatch(message)) {
|
|
84478
84601
|
writeEvent({
|
|
84479
84602
|
type: "turn.failed",
|
|
@@ -84571,7 +84694,7 @@ async function runJsonEventsMode(params) {
|
|
|
84571
84694
|
try {
|
|
84572
84695
|
trace?.notePendingUserText(message.prompt);
|
|
84573
84696
|
trace?.noteDispatchStart({ mode: "json-events" });
|
|
84574
|
-
await controller.prompt(message
|
|
84697
|
+
await controller.prompt(promptInputFor(message), { source: "json-events" });
|
|
84575
84698
|
trace?.noteDispatchSettled({ mode: "json-events" });
|
|
84576
84699
|
trace?.noteWaitForIdleStart({ mode: "json-events" });
|
|
84577
84700
|
await controller.waitForSettled();
|
|
@@ -84636,7 +84759,7 @@ async function runJsonEventsMode(params) {
|
|
|
84636
84759
|
mode: message.streamingBehavior,
|
|
84637
84760
|
turnId: message.turnId
|
|
84638
84761
|
});
|
|
84639
|
-
await activeController.prompt(message
|
|
84762
|
+
await activeController.prompt(promptInputFor(message), {
|
|
84640
84763
|
source: "json-events",
|
|
84641
84764
|
streamingBehavior: message.streamingBehavior,
|
|
84642
84765
|
displayText: message.prompt,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cydm/pie",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.8",
|
|
4
4
|
"description": "Pie AI Agent CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"test:skill-regressions": "node --test --import tsx test/bash-lifecycle.test.ts test/bash-powershell-display.test.ts test/skill-creator-runner.test.ts test/tui-use-contract.test.ts test/tui-use-runtime.test.ts test/browser-runtime.test.ts test/axi-stop-semantics.test.ts test/computer-use-axi.test.ts test/computer-evidence.test.ts test/interactive-lifecycle.test.ts",
|
|
21
21
|
"test:offline:post": "node --test --import tsx test/remote-model-catalog.test.ts",
|
|
22
22
|
"test:offline": "node ../../scripts/run-cli-offline.mjs",
|
|
23
|
-
"test:offline:main": "node --test --test-concurrency=4 --import tsx test/cli-attention.test.ts test/builtin-extensions.test.ts test/core-services.test.ts test/cli.test.ts test/cli-auto-compaction.test.ts test/execution-state-manager.test.ts test/queued-steer-execution-state.test.ts test/todo-steering-ownership.test.ts test/architecture-boundaries.test.ts test/attachment-resolver.test.ts test/kimi-attachment-provider.test.ts test/document-attachment-extension.test.ts test/auto-compact-overflow.test.ts test/auto-compaction-ui.test.ts test/hierarchical-command-system.test.ts test/mcp-adapter.test.ts test/herdr-agent-state.test.ts test/extensions-enablement.test.ts test/extension-selector-shortcuts.test.ts test/skill-tool-enablement.test.ts test/message-queue-unit.test.ts test/evals-harness.test.ts test/session-trace.test.ts test/json-events-sidechat-diagnostics.test.ts test/json-events-prewarm-shutdown.test.ts test/subagent-session-store.test.ts test/runtime-mode-context.test.ts test/tool-policy.test.ts test/retry-policy.test.ts test/yolo-command.test.ts test/footer-lifecycle.test.ts test/files-utils.test.ts test/source-size-guard.test.ts test/runtime-logger.test.ts test/release-readiness.test.ts test/package-artifacts.test.ts test/init-extension-contract.test.ts test/skills-runtime.test.ts test/skills-agents-discovery.test.ts test/skills-symlink.test.ts test/model-overrides.test.ts test/auth-storage.test.ts test/extension-register-provider.test.ts test/extension-reload.test.ts test/extension-terminal-input.test.ts test/extension-session-before-events.test.ts test/extension-widgets.test.ts test/extension-render-hint.test.ts test/extension-oauth-restore.test.ts test/cross-host-parity.test.ts test/tool-name-rendering.test.ts test/session-selector.test.ts test/tree-selector-pagination.test.ts test/context-report.test.ts test/context-signals.test.ts test/plan-cache-stability.test.ts test/cache-invalidation-trace.test.ts test/cache-retention.test.ts test/trace-report.test.ts test/boot-report.test.ts test/compaction-diff.test.ts test/entry-body-and-usage.test.ts test/session-control.test.ts test/terminal-title.test.ts test/interactive-controller-title.test.ts test/todo-title.terminal.test.ts test/host-envelope-dogfood.terminal.test.ts test/plan-mode-extension.test.ts test/rendered-page-reader.test.ts test/tools-registry.test.ts test/system-prompt-contract.test.ts test/bash-yolo.test.ts test/bash-contract.test.ts test/bash-confirm-pending.test.ts test/interaction-status-lifecycle.test.ts test/bash-process-group.test.ts test/bash-artifact-sink.test.ts test/direct-bash.test.ts test/terminal-bell.test.ts test/ctrl-d-exit.test.ts test/session-display-title.test.ts test/calm-mode.test.ts test/stream-render-throttle.test.ts test/message-display-resync.test.ts test/project-root.test.ts test/guard-advisory-context.test.ts test/clear-command-usage.test.ts test/daily-agent-smoke.terminal.test.ts test/slash-menu-toggles.terminal.test.ts test/cli-args.test.ts test/extensions-configured-paths.test.ts test/extensions-loader-path.test.ts test/file-picker.test.ts test/interrupt-recovery.test.ts test/mention-insert-regression.test.ts test/mention-picker-navigation.test.ts test/pie-unity-rpc-skill.test.ts test/skill-creator-scripts.test.ts test/interactive-compact-command.test.ts test/computer-use-broker.test.ts test/computer-use-review-regressions.test.ts test/computer-use-safety.test.ts ../../scripts/node-test-diagnostics.test.js ../../scripts/offline-test-runner.test.js",
|
|
23
|
+
"test:offline:main": "node --test --test-concurrency=4 --import tsx test/cli-attention.test.ts test/builtin-extensions.test.ts test/core-services.test.ts test/cli.test.ts test/cli-auto-compaction.test.ts test/execution-state-manager.test.ts test/queued-steer-execution-state.test.ts test/todo-steering-ownership.test.ts test/architecture-boundaries.test.ts test/attachment-resolver.test.ts test/kimi-attachment-provider.test.ts test/document-attachment-extension.test.ts test/auto-compact-overflow.test.ts test/auto-compaction-ui.test.ts test/hierarchical-command-system.test.ts test/mcp-adapter.test.ts test/herdr-agent-state.test.ts test/extensions-enablement.test.ts test/extension-selector-shortcuts.test.ts test/skill-tool-enablement.test.ts test/message-queue-unit.test.ts test/evals-harness.test.ts test/session-trace.test.ts test/json-events-sidechat-diagnostics.test.ts test/json-events-prewarm-shutdown.test.ts test/subagent-session-store.test.ts test/runtime-mode-context.test.ts test/tool-policy.test.ts test/retry-policy.test.ts test/yolo-command.test.ts test/footer-lifecycle.test.ts test/files-utils.test.ts test/source-size-guard.test.ts test/runtime-logger.test.ts test/release-readiness.test.ts test/package-artifacts.test.ts test/init-extension-contract.test.ts test/skills-runtime.test.ts test/skills-agents-discovery.test.ts test/skills-symlink.test.ts test/model-overrides.test.ts test/auth-storage.test.ts test/extension-register-provider.test.ts test/extension-reload.test.ts test/extension-terminal-input.test.ts test/extension-session-before-events.test.ts test/extension-widgets.test.ts test/extension-render-hint.test.ts test/extension-oauth-restore.test.ts test/cross-host-parity.test.ts test/tool-name-rendering.test.ts test/session-selector.test.ts test/tree-selector-pagination.test.ts test/context-report.test.ts test/context-signals.test.ts test/plan-cache-stability.test.ts test/cache-invalidation-trace.test.ts test/cache-retention.test.ts test/trace-report.test.ts test/boot-report.test.ts test/compaction-diff.test.ts test/entry-body-and-usage.test.ts test/session-control.test.ts test/terminal-title.test.ts test/interactive-controller-title.test.ts test/todo-title.terminal.test.ts test/host-envelope-dogfood.terminal.test.ts test/host-envelope-cross-mode.test.ts test/plan-mode-extension.test.ts test/rendered-page-reader.test.ts test/tools-registry.test.ts test/system-prompt-contract.test.ts test/bash-yolo.test.ts test/bash-contract.test.ts test/bash-confirm-pending.test.ts test/interaction-status-lifecycle.test.ts test/bash-process-group.test.ts test/bash-artifact-sink.test.ts test/direct-bash.test.ts test/terminal-bell.test.ts test/ctrl-d-exit.test.ts test/session-display-title.test.ts test/calm-mode.test.ts test/stream-render-throttle.test.ts test/message-display-resync.test.ts test/project-root.test.ts test/guard-advisory-context.test.ts test/clear-command-usage.test.ts test/daily-agent-smoke.terminal.test.ts test/slash-menu-toggles.terminal.test.ts test/cli-args.test.ts test/extensions-configured-paths.test.ts test/extensions-loader-path.test.ts test/file-picker.test.ts test/interrupt-recovery.test.ts test/mention-insert-regression.test.ts test/mention-picker-navigation.test.ts test/pie-unity-rpc-skill.test.ts test/skill-creator-scripts.test.ts test/interactive-compact-command.test.ts test/computer-use-broker.test.ts test/computer-use-review-regressions.test.ts test/computer-use-safety.test.ts ../../scripts/node-test-diagnostics.test.js ../../scripts/offline-test-runner.test.js",
|
|
24
24
|
"test:all": "npm run test:offline && npm run test:terminal:vitest",
|
|
25
25
|
"test:terminal:vitest": "vitest run test/mention-file-select.terminal.test.ts test/tool-partial-display.terminal.test.ts test/footer-plan-mode.test.ts test/viewport-position-final.test.ts test/resume-header.terminal.test.ts --no-file-parallelism",
|
|
26
26
|
"test:todo-tui": "node ../../scripts/run-with-env.mjs PIE_REAL_TODO_TUI=1 -- --test --import tsx test/todo-closure.terminal.test.ts",
|