orion-super-agent-dev 0.1.19 → 0.1.20
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/out/brains/darwin-arm64/orion-brain +0 -0
- package/out/brains/darwin-x64/orion-brain +0 -0
- package/out/brains/linux-arm64/orion-brain +0 -0
- package/out/brains/linux-x64/orion-brain +0 -0
- package/out/brains/win32-x64/orion-brain.exe +0 -0
- package/out/main.js +1016 -333
- package/package.json +1 -1
package/out/main.js
CHANGED
|
@@ -25517,14 +25517,14 @@ var require_templates = __commonJS({
|
|
|
25517
25517
|
}
|
|
25518
25518
|
return results;
|
|
25519
25519
|
}
|
|
25520
|
-
function buildStyle(
|
|
25520
|
+
function buildStyle(chalk6, styles3) {
|
|
25521
25521
|
const enabled = {};
|
|
25522
25522
|
for (const layer of styles3) {
|
|
25523
25523
|
for (const style of layer.styles) {
|
|
25524
25524
|
enabled[style[0]] = layer.inverse ? null : style.slice(1);
|
|
25525
25525
|
}
|
|
25526
25526
|
}
|
|
25527
|
-
let current2 =
|
|
25527
|
+
let current2 = chalk6;
|
|
25528
25528
|
for (const [styleName, styles4] of Object.entries(enabled)) {
|
|
25529
25529
|
if (!Array.isArray(styles4)) {
|
|
25530
25530
|
continue;
|
|
@@ -25536,7 +25536,7 @@ var require_templates = __commonJS({
|
|
|
25536
25536
|
}
|
|
25537
25537
|
return current2;
|
|
25538
25538
|
}
|
|
25539
|
-
module2.exports = (
|
|
25539
|
+
module2.exports = (chalk6, temporary) => {
|
|
25540
25540
|
const styles3 = [];
|
|
25541
25541
|
const chunks = [];
|
|
25542
25542
|
let chunk = [];
|
|
@@ -25546,13 +25546,13 @@ var require_templates = __commonJS({
|
|
|
25546
25546
|
} else if (style) {
|
|
25547
25547
|
const string = chunk.join("");
|
|
25548
25548
|
chunk = [];
|
|
25549
|
-
chunks.push(styles3.length === 0 ? string : buildStyle(
|
|
25549
|
+
chunks.push(styles3.length === 0 ? string : buildStyle(chalk6, styles3)(string));
|
|
25550
25550
|
styles3.push({ inverse, styles: parseStyle(style) });
|
|
25551
25551
|
} else if (close) {
|
|
25552
25552
|
if (styles3.length === 0) {
|
|
25553
25553
|
throw new Error("Found extraneous } in Chalk template literal");
|
|
25554
25554
|
}
|
|
25555
|
-
chunks.push(buildStyle(
|
|
25555
|
+
chunks.push(buildStyle(chalk6, styles3)(chunk.join("")));
|
|
25556
25556
|
chunk = [];
|
|
25557
25557
|
styles3.pop();
|
|
25558
25558
|
} else {
|
|
@@ -25600,16 +25600,16 @@ var require_source = __commonJS({
|
|
|
25600
25600
|
}
|
|
25601
25601
|
};
|
|
25602
25602
|
var chalkFactory = (options) => {
|
|
25603
|
-
const
|
|
25604
|
-
applyOptions(
|
|
25605
|
-
|
|
25606
|
-
Object.setPrototypeOf(
|
|
25607
|
-
Object.setPrototypeOf(
|
|
25608
|
-
|
|
25603
|
+
const chalk7 = {};
|
|
25604
|
+
applyOptions(chalk7, options);
|
|
25605
|
+
chalk7.template = (...arguments_2) => chalkTag(chalk7.template, ...arguments_2);
|
|
25606
|
+
Object.setPrototypeOf(chalk7, Chalk.prototype);
|
|
25607
|
+
Object.setPrototypeOf(chalk7.template, chalk7);
|
|
25608
|
+
chalk7.template.constructor = () => {
|
|
25609
25609
|
throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
|
|
25610
25610
|
};
|
|
25611
|
-
|
|
25612
|
-
return
|
|
25611
|
+
chalk7.template.Instance = ChalkClass;
|
|
25612
|
+
return chalk7.template;
|
|
25613
25613
|
};
|
|
25614
25614
|
function Chalk(options) {
|
|
25615
25615
|
return chalkFactory(options);
|
|
@@ -25720,7 +25720,7 @@ var require_source = __commonJS({
|
|
|
25720
25720
|
return openAll + string + closeAll;
|
|
25721
25721
|
};
|
|
25722
25722
|
var template;
|
|
25723
|
-
var chalkTag = (
|
|
25723
|
+
var chalkTag = (chalk7, ...strings) => {
|
|
25724
25724
|
const [firstString] = strings;
|
|
25725
25725
|
if (!isArray(firstString) || !isArray(firstString.raw)) {
|
|
25726
25726
|
return strings.join(" ");
|
|
@@ -25736,14 +25736,14 @@ var require_source = __commonJS({
|
|
|
25736
25736
|
if (template === void 0) {
|
|
25737
25737
|
template = require_templates();
|
|
25738
25738
|
}
|
|
25739
|
-
return template(
|
|
25739
|
+
return template(chalk7, parts2.join(""));
|
|
25740
25740
|
};
|
|
25741
25741
|
Object.defineProperties(Chalk.prototype, styles3);
|
|
25742
|
-
var
|
|
25743
|
-
|
|
25744
|
-
|
|
25745
|
-
|
|
25746
|
-
module2.exports =
|
|
25742
|
+
var chalk6 = Chalk();
|
|
25743
|
+
chalk6.supportsColor = stdoutColor;
|
|
25744
|
+
chalk6.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
25745
|
+
chalk6.stderr.supportsColor = stderrColor;
|
|
25746
|
+
module2.exports = chalk6;
|
|
25747
25747
|
}
|
|
25748
25748
|
});
|
|
25749
25749
|
|
|
@@ -29033,6 +29033,36 @@ var require_atomicWrite = __commonJS({
|
|
|
29033
29033
|
}
|
|
29034
29034
|
});
|
|
29035
29035
|
|
|
29036
|
+
// ../packages/orion-client-core/dist/duetPlanners.js
|
|
29037
|
+
var require_duetPlanners = __commonJS({
|
|
29038
|
+
"../packages/orion-client-core/dist/duetPlanners.js"(exports2) {
|
|
29039
|
+
"use strict";
|
|
29040
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
29041
|
+
exports2.DUET_PLANNER_LABELS = exports2.DUET_PLANNER_PROVIDERS = exports2.DUET_PLANNER_DEFAULT = exports2.DUET_EXECUTOR_DEFAULT_ID = exports2.DUET_PLANNER_IDS = void 0;
|
|
29042
|
+
exports2.isDuetPlanner = isDuetPlanner2;
|
|
29043
|
+
exports2.resolveDuetPlanner = resolveDuetPlanner2;
|
|
29044
|
+
exports2.DUET_PLANNER_IDS = ["claude-fable-5", "claude-opus-5"];
|
|
29045
|
+
exports2.DUET_EXECUTOR_DEFAULT_ID = "claude-sonnet-5";
|
|
29046
|
+
exports2.DUET_PLANNER_DEFAULT = "claude-fable-5";
|
|
29047
|
+
exports2.DUET_PLANNER_PROVIDERS = ["claude_code", "anthropic"];
|
|
29048
|
+
exports2.DUET_PLANNER_LABELS = {
|
|
29049
|
+
"claude-fable-5": "Claude Fable 5",
|
|
29050
|
+
"claude-opus-5": "Claude Opus 5"
|
|
29051
|
+
};
|
|
29052
|
+
function isDuetPlanner2(model) {
|
|
29053
|
+
return !!model && exports2.DUET_PLANNER_IDS.includes(model);
|
|
29054
|
+
}
|
|
29055
|
+
function resolveDuetPlanner2(id, models) {
|
|
29056
|
+
for (const provider of exports2.DUET_PLANNER_PROVIDERS) {
|
|
29057
|
+
if (models.some((m2) => m2.id === id && (m2.provider ?? "") === provider)) {
|
|
29058
|
+
return { provider, model: id };
|
|
29059
|
+
}
|
|
29060
|
+
}
|
|
29061
|
+
return { provider: exports2.DUET_PLANNER_PROVIDERS[0], model: id };
|
|
29062
|
+
}
|
|
29063
|
+
}
|
|
29064
|
+
});
|
|
29065
|
+
|
|
29036
29066
|
// ../packages/orion-client-core/dist/settingsPaths.js
|
|
29037
29067
|
var require_settingsPaths = __commonJS({
|
|
29038
29068
|
"../packages/orion-client-core/dist/settingsPaths.js"(exports2) {
|
|
@@ -29091,6 +29121,405 @@ var require_settingsPaths = __commonJS({
|
|
|
29091
29121
|
}
|
|
29092
29122
|
});
|
|
29093
29123
|
|
|
29124
|
+
// ../packages/orion-client-core/dist/duetMode.js
|
|
29125
|
+
var require_duetMode = __commonJS({
|
|
29126
|
+
"../packages/orion-client-core/dist/duetMode.js"(exports2) {
|
|
29127
|
+
"use strict";
|
|
29128
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m2, k, k2) {
|
|
29129
|
+
if (k2 === void 0) k2 = k;
|
|
29130
|
+
var desc = Object.getOwnPropertyDescriptor(m2, k);
|
|
29131
|
+
if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
|
|
29132
|
+
desc = { enumerable: true, get: function() {
|
|
29133
|
+
return m2[k];
|
|
29134
|
+
} };
|
|
29135
|
+
}
|
|
29136
|
+
Object.defineProperty(o, k2, desc);
|
|
29137
|
+
} : function(o, m2, k, k2) {
|
|
29138
|
+
if (k2 === void 0) k2 = k;
|
|
29139
|
+
o[k2] = m2[k];
|
|
29140
|
+
});
|
|
29141
|
+
var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v2) {
|
|
29142
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v2 });
|
|
29143
|
+
} : function(o, v2) {
|
|
29144
|
+
o["default"] = v2;
|
|
29145
|
+
});
|
|
29146
|
+
var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ function() {
|
|
29147
|
+
var ownKeys = function(o) {
|
|
29148
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
29149
|
+
var ar = [];
|
|
29150
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
29151
|
+
return ar;
|
|
29152
|
+
};
|
|
29153
|
+
return ownKeys(o);
|
|
29154
|
+
};
|
|
29155
|
+
return function(mod2) {
|
|
29156
|
+
if (mod2 && mod2.__esModule) return mod2;
|
|
29157
|
+
var result = {};
|
|
29158
|
+
if (mod2 != null) {
|
|
29159
|
+
for (var k = ownKeys(mod2), i2 = 0; i2 < k.length; i2++) if (k[i2] !== "default") __createBinding(result, mod2, k[i2]);
|
|
29160
|
+
}
|
|
29161
|
+
__setModuleDefault(result, mod2);
|
|
29162
|
+
return result;
|
|
29163
|
+
};
|
|
29164
|
+
}();
|
|
29165
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
29166
|
+
exports2.DUET_EXECUTOR_INFO = exports2.DUET_EXECUTOR_DEFAULT_LABEL = void 0;
|
|
29167
|
+
exports2.clearDuetExecutorCache = clearDuetExecutorCache;
|
|
29168
|
+
exports2.loadDuetExecutor = loadDuetExecutor2;
|
|
29169
|
+
exports2.setDuetExecutor = setDuetExecutor2;
|
|
29170
|
+
exports2.duetExecutorSource = duetExecutorSource;
|
|
29171
|
+
exports2.duetExecutorWireForSegment = duetExecutorWireForSegment;
|
|
29172
|
+
exports2.prewarmDuetExecutor = prewarmDuetExecutor;
|
|
29173
|
+
var fs14 = __importStar(__require("node:fs/promises"));
|
|
29174
|
+
var os8 = __importStar(__require("node:os"));
|
|
29175
|
+
var path13 = __importStar(__require("node:path"));
|
|
29176
|
+
var atomicWrite_js_1 = require_atomicWrite();
|
|
29177
|
+
var duetPlanners_js_1 = require_duetPlanners();
|
|
29178
|
+
var settingsPaths_js_1 = require_settingsPaths();
|
|
29179
|
+
exports2.DUET_EXECUTOR_DEFAULT_LABEL = "Claude Sonnet 5";
|
|
29180
|
+
exports2.DUET_EXECUTOR_INFO = {
|
|
29181
|
+
/** The choice's snake_case key on the segment body. */
|
|
29182
|
+
wireKey: "duet_executor",
|
|
29183
|
+
label: "Duet executor",
|
|
29184
|
+
description: "Runs the approved plan in Duet mode. Planning stays on the session's model; execution hands off to this one (Claude Sonnet 5 unless changed)."
|
|
29185
|
+
};
|
|
29186
|
+
var MAX_MODEL_LEN = 128;
|
|
29187
|
+
var MAX_PROVIDER_LEN = 64;
|
|
29188
|
+
var MAX_EFFORT_LEN = 24;
|
|
29189
|
+
var MAX_WINDOW = 5e7;
|
|
29190
|
+
function toChoice(raw) {
|
|
29191
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
29192
|
+
return null;
|
|
29193
|
+
const value = raw;
|
|
29194
|
+
const model = typeof value.model === "string" ? value.model.trim() : "";
|
|
29195
|
+
if (model === "" || model.length > MAX_MODEL_LEN)
|
|
29196
|
+
return null;
|
|
29197
|
+
const provider = typeof value.provider === "string" ? value.provider.trim() : "";
|
|
29198
|
+
if (provider.length > MAX_PROVIDER_LEN)
|
|
29199
|
+
return null;
|
|
29200
|
+
const rawEffort = typeof value.effort === "string" ? value.effort.trim() : "";
|
|
29201
|
+
if (rawEffort.length > MAX_EFFORT_LEN)
|
|
29202
|
+
return null;
|
|
29203
|
+
const windowRaw = typeof value.contextWindow === "number" ? value.contextWindow : 0;
|
|
29204
|
+
const contextWindow = Number.isInteger(windowRaw) && windowRaw >= 1 && windowRaw <= MAX_WINDOW ? windowRaw : void 0;
|
|
29205
|
+
return {
|
|
29206
|
+
provider,
|
|
29207
|
+
model,
|
|
29208
|
+
...rawEffort !== "" ? { effort: rawEffort } : {},
|
|
29209
|
+
...contextWindow !== void 0 ? { contextWindow } : {}
|
|
29210
|
+
};
|
|
29211
|
+
}
|
|
29212
|
+
async function readTier(file) {
|
|
29213
|
+
if (file === null)
|
|
29214
|
+
return null;
|
|
29215
|
+
let parsed;
|
|
29216
|
+
try {
|
|
29217
|
+
parsed = JSON.parse(await fs14.readFile(file, "utf8"));
|
|
29218
|
+
} catch {
|
|
29219
|
+
return null;
|
|
29220
|
+
}
|
|
29221
|
+
return toChoice(parsed?.duetExecutor);
|
|
29222
|
+
}
|
|
29223
|
+
var DUET_EXECUTOR_CACHE_TTL_MS = 5e3;
|
|
29224
|
+
var cache3 = /* @__PURE__ */ new Map();
|
|
29225
|
+
var refreshing = /* @__PURE__ */ new Map();
|
|
29226
|
+
function cacheKeyFor(home, ws) {
|
|
29227
|
+
return `${home}\0${ws ?? ""}`;
|
|
29228
|
+
}
|
|
29229
|
+
function clearDuetExecutorCache() {
|
|
29230
|
+
cache3.clear();
|
|
29231
|
+
refreshing.clear();
|
|
29232
|
+
}
|
|
29233
|
+
async function mergeTiers(home, ws) {
|
|
29234
|
+
let merged = null;
|
|
29235
|
+
for (const tier of ["user", "project", "local"]) {
|
|
29236
|
+
const choice = await readTier((0, settingsPaths_js_1.settingsFilePath)(tier, { homeDir: home, workspaceRoot: ws }));
|
|
29237
|
+
if (choice !== null)
|
|
29238
|
+
merged = choice;
|
|
29239
|
+
}
|
|
29240
|
+
return merged;
|
|
29241
|
+
}
|
|
29242
|
+
async function loadDuetExecutor2(opts = {}) {
|
|
29243
|
+
const home = opts.homeDir ?? os8.homedir();
|
|
29244
|
+
const ws = opts.workspaceRoot ?? null;
|
|
29245
|
+
const cacheKey = cacheKeyFor(home, ws);
|
|
29246
|
+
const hit = cache3.get(cacheKey);
|
|
29247
|
+
const now2 = Date.now();
|
|
29248
|
+
if (hit !== void 0 && now2 - hit.at < DUET_EXECUTOR_CACHE_TTL_MS)
|
|
29249
|
+
return hit.choice;
|
|
29250
|
+
const merged = await mergeTiers(home, ws);
|
|
29251
|
+
cache3.set(cacheKey, { at: now2, choice: merged });
|
|
29252
|
+
return merged;
|
|
29253
|
+
}
|
|
29254
|
+
async function setDuetExecutor2(choice, opts = {}) {
|
|
29255
|
+
const file = (0, settingsPaths_js_1.settingsFilePath)("user", opts);
|
|
29256
|
+
if (file === null)
|
|
29257
|
+
throw new Error("no user settings file");
|
|
29258
|
+
let root2 = {};
|
|
29259
|
+
try {
|
|
29260
|
+
const parsed = JSON.parse(await fs14.readFile(file, "utf8"));
|
|
29261
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
29262
|
+
root2 = parsed;
|
|
29263
|
+
}
|
|
29264
|
+
} catch {
|
|
29265
|
+
}
|
|
29266
|
+
const validated = choice === void 0 ? null : toChoice(choice);
|
|
29267
|
+
if (validated === null)
|
|
29268
|
+
delete root2.duetExecutor;
|
|
29269
|
+
else
|
|
29270
|
+
root2.duetExecutor = validated;
|
|
29271
|
+
await fs14.mkdir(path13.dirname(file), { recursive: true });
|
|
29272
|
+
await (0, atomicWrite_js_1.atomicWriteFile)(file, `${JSON.stringify(root2, null, 2)}
|
|
29273
|
+
`);
|
|
29274
|
+
clearDuetExecutorCache();
|
|
29275
|
+
}
|
|
29276
|
+
async function duetExecutorSource(opts = {}) {
|
|
29277
|
+
const home = opts.homeDir ?? os8.homedir();
|
|
29278
|
+
const ws = opts.workspaceRoot ?? null;
|
|
29279
|
+
let source2 = null;
|
|
29280
|
+
for (const tier of ["user", "project", "local"]) {
|
|
29281
|
+
const choice = await readTier((0, settingsPaths_js_1.settingsFilePath)(tier, { homeDir: home, workspaceRoot: ws }));
|
|
29282
|
+
if (choice !== null)
|
|
29283
|
+
source2 = tier;
|
|
29284
|
+
}
|
|
29285
|
+
return source2;
|
|
29286
|
+
}
|
|
29287
|
+
function revalidate(home, ws, cacheKey) {
|
|
29288
|
+
if (refreshing.has(cacheKey))
|
|
29289
|
+
return;
|
|
29290
|
+
const refresh = (async () => {
|
|
29291
|
+
const merged = await mergeTiers(home, ws);
|
|
29292
|
+
cache3.set(cacheKey, { at: Date.now(), choice: merged });
|
|
29293
|
+
})();
|
|
29294
|
+
refreshing.set(cacheKey, refresh.catch(() => {
|
|
29295
|
+
}).finally(() => {
|
|
29296
|
+
refreshing.delete(cacheKey);
|
|
29297
|
+
}));
|
|
29298
|
+
}
|
|
29299
|
+
function duetExecutorWireForSegment(workspaceRoot) {
|
|
29300
|
+
try {
|
|
29301
|
+
const home = os8.homedir();
|
|
29302
|
+
const ws = workspaceRoot ?? null;
|
|
29303
|
+
const cacheKey = cacheKeyFor(home, ws);
|
|
29304
|
+
const hit = cache3.get(cacheKey);
|
|
29305
|
+
if (hit === void 0 || Date.now() - hit.at >= DUET_EXECUTOR_CACHE_TTL_MS) {
|
|
29306
|
+
revalidate(home, ws, cacheKey);
|
|
29307
|
+
}
|
|
29308
|
+
if (hit === void 0 || hit.choice === null) {
|
|
29309
|
+
return { provider: duetPlanners_js_1.DUET_PLANNER_PROVIDERS[0], model: duetPlanners_js_1.DUET_EXECUTOR_DEFAULT_ID };
|
|
29310
|
+
}
|
|
29311
|
+
return {
|
|
29312
|
+
provider: hit.choice.provider,
|
|
29313
|
+
model: hit.choice.model,
|
|
29314
|
+
// Wire spelling is snake_case, like every other segment-body key.
|
|
29315
|
+
...hit.choice.effort !== void 0 ? { effort: hit.choice.effort } : {},
|
|
29316
|
+
...hit.choice.contextWindow !== void 0 ? { context_window: hit.choice.contextWindow } : {}
|
|
29317
|
+
};
|
|
29318
|
+
} catch {
|
|
29319
|
+
return void 0;
|
|
29320
|
+
}
|
|
29321
|
+
}
|
|
29322
|
+
async function prewarmDuetExecutor(workspaceRoot) {
|
|
29323
|
+
try {
|
|
29324
|
+
await loadDuetExecutor2({ workspaceRoot: workspaceRoot ?? null });
|
|
29325
|
+
} catch {
|
|
29326
|
+
}
|
|
29327
|
+
}
|
|
29328
|
+
}
|
|
29329
|
+
});
|
|
29330
|
+
|
|
29331
|
+
// ../packages/orion-client-core/dist/duetPlan.js
|
|
29332
|
+
var require_duetPlan = __commonJS({
|
|
29333
|
+
"../packages/orion-client-core/dist/duetPlan.js"(exports2) {
|
|
29334
|
+
"use strict";
|
|
29335
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
29336
|
+
exports2.DUET_PLAN_MAX_FAILURES = exports2.DUET_ESCALATION_THRESHOLD = exports2.DUET_REPLAN_CAPABILITY = exports2.DUET_REPLAN_TOOL = exports2.DUET_PLAN_GRANTS = exports2.DUET_PLAN_MAX_VERSION = exports2.DUET_PLAN_MAX_LEN = void 0;
|
|
29337
|
+
exports2.createStandingPlan = createStandingPlan3;
|
|
29338
|
+
exports2.duetPlanWireForSegment = duetPlanWireForSegment;
|
|
29339
|
+
exports2.highRiskRequest = highRiskRequest;
|
|
29340
|
+
exports2.explicitPlanRequest = explicitPlanRequest;
|
|
29341
|
+
exports2.willRouteToExecution = willRouteToExecution2;
|
|
29342
|
+
exports2.invalidateStandingPlan = invalidateStandingPlan2;
|
|
29343
|
+
exports2.duetReplanCommandNote = duetReplanCommandNote2;
|
|
29344
|
+
exports2.duetReplanResult = duetReplanResult2;
|
|
29345
|
+
exports2.duetReplanFollowupPrompt = duetReplanFollowupPrompt2;
|
|
29346
|
+
exports2.recordDuetTurnOutcome = recordDuetTurnOutcome;
|
|
29347
|
+
exports2.foldDuetTurnEnd = foldDuetTurnEnd2;
|
|
29348
|
+
exports2.duetPhaseLine = duetPhaseLine2;
|
|
29349
|
+
exports2.DUET_PLAN_MAX_LEN = 65536;
|
|
29350
|
+
exports2.DUET_PLAN_MAX_VERSION = 1e4;
|
|
29351
|
+
exports2.DUET_PLAN_GRANTS = ["default", "workspace_write"];
|
|
29352
|
+
function createStandingPlan3(plan, previous, grantedPermission = "workspace_write") {
|
|
29353
|
+
const trimmed = plan.trim();
|
|
29354
|
+
if (trimmed === "" || trimmed.length > exports2.DUET_PLAN_MAX_LEN)
|
|
29355
|
+
return null;
|
|
29356
|
+
const version = Math.min((previous?.version ?? 0) + 1, exports2.DUET_PLAN_MAX_VERSION);
|
|
29357
|
+
return {
|
|
29358
|
+
plan: trimmed,
|
|
29359
|
+
version,
|
|
29360
|
+
standing: true,
|
|
29361
|
+
grantedPermission,
|
|
29362
|
+
planningFailures: 0,
|
|
29363
|
+
executorFailures: 0,
|
|
29364
|
+
scopeChanged: false,
|
|
29365
|
+
architectureDecisionRequired: false,
|
|
29366
|
+
userNegativeFeedback: false,
|
|
29367
|
+
escalated: false
|
|
29368
|
+
};
|
|
29369
|
+
}
|
|
29370
|
+
function duetPlanWireForSegment(record) {
|
|
29371
|
+
if (!record?.standing)
|
|
29372
|
+
return void 0;
|
|
29373
|
+
const plan = record.plan.trim();
|
|
29374
|
+
if (plan === "" || plan.length > exports2.DUET_PLAN_MAX_LEN)
|
|
29375
|
+
return void 0;
|
|
29376
|
+
if (record.version < 1 || record.version > exports2.DUET_PLAN_MAX_VERSION)
|
|
29377
|
+
return void 0;
|
|
29378
|
+
if (!exports2.DUET_PLAN_GRANTS.includes(record.grantedPermission))
|
|
29379
|
+
return void 0;
|
|
29380
|
+
return {
|
|
29381
|
+
standing: true,
|
|
29382
|
+
plan,
|
|
29383
|
+
version: record.version,
|
|
29384
|
+
granted_permission: record.grantedPermission,
|
|
29385
|
+
planning_failures: record.planningFailures,
|
|
29386
|
+
executor_failures: record.executorFailures,
|
|
29387
|
+
scope_changed: record.scopeChanged,
|
|
29388
|
+
architecture_decision_required: record.architectureDecisionRequired,
|
|
29389
|
+
user_negative_feedback: record.userNegativeFeedback,
|
|
29390
|
+
escalated: record.escalated
|
|
29391
|
+
};
|
|
29392
|
+
}
|
|
29393
|
+
var EXPLICIT_PLAN_WORDS = [
|
|
29394
|
+
"replan",
|
|
29395
|
+
"re-plan",
|
|
29396
|
+
"redesign",
|
|
29397
|
+
"re-design",
|
|
29398
|
+
"rethink",
|
|
29399
|
+
"re-think",
|
|
29400
|
+
"architect",
|
|
29401
|
+
// The architect-family nouns: a "short architectural change" must replan even under
|
|
29402
|
+
// a valid standing plan (the high-risk list only fires with NO plan).
|
|
29403
|
+
"architecture",
|
|
29404
|
+
"architectural",
|
|
29405
|
+
"new plan",
|
|
29406
|
+
"change the plan",
|
|
29407
|
+
"different approach",
|
|
29408
|
+
// The imperative plan/design shapes (bare "plan"/"design" are everyday words —
|
|
29409
|
+
// "the plan is working", "design doc" — so only request shapes match).
|
|
29410
|
+
"plan this",
|
|
29411
|
+
"plan the",
|
|
29412
|
+
"plan out",
|
|
29413
|
+
"make a plan",
|
|
29414
|
+
"write a plan",
|
|
29415
|
+
"design a",
|
|
29416
|
+
"design the",
|
|
29417
|
+
"design this"
|
|
29418
|
+
];
|
|
29419
|
+
var HIGH_RISK_WORDS = [
|
|
29420
|
+
"migration",
|
|
29421
|
+
"migrate",
|
|
29422
|
+
"security",
|
|
29423
|
+
"auth",
|
|
29424
|
+
"authentication",
|
|
29425
|
+
"production",
|
|
29426
|
+
"deploy",
|
|
29427
|
+
"deployment",
|
|
29428
|
+
"database",
|
|
29429
|
+
"schema",
|
|
29430
|
+
"architecture",
|
|
29431
|
+
"infrastructure",
|
|
29432
|
+
"rewrite"
|
|
29433
|
+
];
|
|
29434
|
+
function highRiskRequest(text) {
|
|
29435
|
+
const lower = text.toLowerCase();
|
|
29436
|
+
return HIGH_RISK_WORDS.some((word) => containsWord(lower, word));
|
|
29437
|
+
}
|
|
29438
|
+
function explicitPlanRequest(text) {
|
|
29439
|
+
const lower = text.toLowerCase();
|
|
29440
|
+
if (EXPLICIT_PLAN_WORDS.some((word) => containsWord(lower, word)))
|
|
29441
|
+
return true;
|
|
29442
|
+
const lead = lower.trimStart();
|
|
29443
|
+
return lead.startsWith("plan ") || lead.startsWith("design ");
|
|
29444
|
+
}
|
|
29445
|
+
function containsWord(lower, word) {
|
|
29446
|
+
let start2 = 0;
|
|
29447
|
+
for (; ; ) {
|
|
29448
|
+
const at = lower.indexOf(word, start2);
|
|
29449
|
+
if (at < 0)
|
|
29450
|
+
return false;
|
|
29451
|
+
const end = at + word.length;
|
|
29452
|
+
const beforeOk = at === 0 || !/[a-z0-9]/i.test(lower[at - 1] ?? "");
|
|
29453
|
+
const afterOk = !/[a-z0-9]/i.test(lower[end] ?? "");
|
|
29454
|
+
if (beforeOk && afterOk)
|
|
29455
|
+
return true;
|
|
29456
|
+
start2 = end;
|
|
29457
|
+
}
|
|
29458
|
+
}
|
|
29459
|
+
function willRouteToExecution2(record, text) {
|
|
29460
|
+
if (explicitPlanRequest(text))
|
|
29461
|
+
return false;
|
|
29462
|
+
if (duetPlanWireForSegment(record) === void 0)
|
|
29463
|
+
return !highRiskRequest(text);
|
|
29464
|
+
if (record.scopeChanged || record.architectureDecisionRequired)
|
|
29465
|
+
return false;
|
|
29466
|
+
if (record.planningFailures >= 2)
|
|
29467
|
+
return false;
|
|
29468
|
+
if (record.userNegativeFeedback)
|
|
29469
|
+
return false;
|
|
29470
|
+
return true;
|
|
29471
|
+
}
|
|
29472
|
+
exports2.DUET_REPLAN_TOOL = "request_replan";
|
|
29473
|
+
exports2.DUET_REPLAN_CAPABILITY = "duet_replan";
|
|
29474
|
+
function invalidateStandingPlan2(record) {
|
|
29475
|
+
if (!record?.standing)
|
|
29476
|
+
return record ?? null;
|
|
29477
|
+
return { ...record, scopeChanged: true };
|
|
29478
|
+
}
|
|
29479
|
+
function duetReplanCommandNote2(hadPlan) {
|
|
29480
|
+
return hadPlan ? "Standing plan invalidated \u2014 the next Duet request runs the planner." : 'No standing plan is active \u2014 ask for a plan (e.g. "plan this out") to run the planner.';
|
|
29481
|
+
}
|
|
29482
|
+
function duetReplanResult2(hadPlan) {
|
|
29483
|
+
return hadPlan ? "Standing plan invalidated. The planning model takes over on an automatic follow-up turn as soon as you finish \u2014 summarize where you stopped and why the plan no longer fits, then end the turn." : "No standing plan is active. The planning model takes over on an automatic follow-up turn as soon as you finish \u2014 summarize what this task needs and why, then end the turn.";
|
|
29484
|
+
}
|
|
29485
|
+
function duetReplanFollowupPrompt2(reason) {
|
|
29486
|
+
const trimmed = reason.trim().replace(/\s+/g, " ");
|
|
29487
|
+
const capped = trimmed.length > 500 ? `${trimmed.slice(0, 499)}\u2026` : trimmed;
|
|
29488
|
+
const cause = capped === "" ? "the executor reported the approved plan no longer fits" : `the executor reported the approved plan no longer fits: ${capped}`;
|
|
29489
|
+
return `Re-plan this task \u2014 ${cause}. Review the summary above, investigate what changed, and produce a fresh plan.`;
|
|
29490
|
+
}
|
|
29491
|
+
exports2.DUET_ESCALATION_THRESHOLD = 2;
|
|
29492
|
+
exports2.DUET_PLAN_MAX_FAILURES = 1e3;
|
|
29493
|
+
function recordDuetTurnOutcome(record, outcome) {
|
|
29494
|
+
if (!record?.standing)
|
|
29495
|
+
return record ?? null;
|
|
29496
|
+
if (outcome.ok) {
|
|
29497
|
+
if (!outcome.executionLeg)
|
|
29498
|
+
return record;
|
|
29499
|
+
return { ...record, executorFailures: 0, escalated: false };
|
|
29500
|
+
}
|
|
29501
|
+
if (outcome.executionLeg) {
|
|
29502
|
+
const executorFailures = Math.min(record.executorFailures + 1, exports2.DUET_PLAN_MAX_FAILURES);
|
|
29503
|
+
return {
|
|
29504
|
+
...record,
|
|
29505
|
+
executorFailures,
|
|
29506
|
+
escalated: executorFailures >= exports2.DUET_ESCALATION_THRESHOLD
|
|
29507
|
+
};
|
|
29508
|
+
}
|
|
29509
|
+
return { ...record, planningFailures: Math.min(record.planningFailures + 1, exports2.DUET_PLAN_MAX_FAILURES) };
|
|
29510
|
+
}
|
|
29511
|
+
function foldDuetTurnEnd2(record, executionLeg, outcome) {
|
|
29512
|
+
if (outcome === "cancelled")
|
|
29513
|
+
return record ?? null;
|
|
29514
|
+
return recordDuetTurnOutcome(record, { executionLeg, ok: outcome === "completed" });
|
|
29515
|
+
}
|
|
29516
|
+
function duetPhaseLine2(phase, opts) {
|
|
29517
|
+
const base = phase === "planning" ? "Planning" : "Executing";
|
|
29518
|
+
return phase === "executing" && opts?.escalated ? `${base} \xB7 escalated` : base;
|
|
29519
|
+
}
|
|
29520
|
+
}
|
|
29521
|
+
});
|
|
29522
|
+
|
|
29094
29523
|
// ../packages/orion-client-core/dist/interimModels.js
|
|
29095
29524
|
var require_interimModels = __commonJS({
|
|
29096
29525
|
"../packages/orion-client-core/dist/interimModels.js"(exports2) {
|
|
@@ -31547,6 +31976,8 @@ var require_segmentDriver = __commonJS({
|
|
|
31547
31976
|
exports2.runToolBatch = runToolBatch;
|
|
31548
31977
|
var node_events_1 = __require("node:events");
|
|
31549
31978
|
var os8 = __importStar(__require("node:os"));
|
|
31979
|
+
var duetMode_js_1 = require_duetMode();
|
|
31980
|
+
var duetPlan_js_1 = require_duetPlan();
|
|
31550
31981
|
var interimModels_js_1 = require_interimModels();
|
|
31551
31982
|
var repoIdentity_js_1 = require_repoIdentity();
|
|
31552
31983
|
var memoryIndex_js_1 = require_memoryIndex();
|
|
@@ -31894,6 +32325,12 @@ var require_segmentDriver = __commonJS({
|
|
|
31894
32325
|
if (orionResources !== void 0)
|
|
31895
32326
|
body2.orion_resources = orionResources;
|
|
31896
32327
|
const interimModels = (0, interimModels_js_1.interimModelsWireForSegment)(start2.routing?.workspaceRoot);
|
|
32328
|
+
const duetExecutor = start2.routing?.mode === "duet" ? (0, duetMode_js_1.duetExecutorWireForSegment)(start2.routing?.workspaceRoot) : void 0;
|
|
32329
|
+
if (duetExecutor !== void 0)
|
|
32330
|
+
body2.duet_executor = duetExecutor;
|
|
32331
|
+
const duetPlan = start2.routing?.mode === "duet" ? (0, duetPlan_js_1.duetPlanWireForSegment)(start2.duetPlan) : void 0;
|
|
32332
|
+
if (duetPlan !== void 0)
|
|
32333
|
+
body2.duet_plan = duetPlan;
|
|
31897
32334
|
if (interimModels !== void 0)
|
|
31898
32335
|
body2.interim_models = interimModels;
|
|
31899
32336
|
const repoIdentity = (0, repoIdentity_js_1.repoIdentityForSegment)(start2.routing?.workspaceRoot);
|
|
@@ -36205,7 +36642,7 @@ var require_agentManager = __commonJS({
|
|
|
36205
36642
|
worktree = await this.createWorktree(parentSessionId, agentId);
|
|
36206
36643
|
}
|
|
36207
36644
|
const model = str(params.model) || resolveModelPreference(def.model, routing.model) || routing.model;
|
|
36208
|
-
const readOnly = routing.mode === "plan" || routing.mode === "ask";
|
|
36645
|
+
const readOnly = routing.mode === "plan" || routing.mode === "ask" || routing.mode === "duet";
|
|
36209
36646
|
const sessionId = await this.transport.startSession({
|
|
36210
36647
|
provider: routing.provider,
|
|
36211
36648
|
model,
|
|
@@ -49589,8 +50026,9 @@ var require_codebaseIndex = __commonJS({
|
|
|
49589
50026
|
"../packages/orion-client-core/dist/codebaseIndex.js"(exports2) {
|
|
49590
50027
|
"use strict";
|
|
49591
50028
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
49592
|
-
exports2.WorkspaceIndexStore = exports2.CONTENT_PROBE_DEADLINE_MS = exports2.DEFAULT_RETRIEVAL_MODE = void 0;
|
|
50029
|
+
exports2.WorkspaceIndexStore = exports2.CONTENT_PROBE_DEADLINE_MS = exports2.RETRIEVAL_TOGGLE_ENABLED = exports2.DEFAULT_RETRIEVAL_MODE = void 0;
|
|
49593
50030
|
exports2.normalizeRetrievalMode = normalizeRetrievalMode4;
|
|
50031
|
+
exports2.effectiveRetrievalMode = effectiveRetrievalMode;
|
|
49594
50032
|
var contentChunkIndex_1 = require_contentChunkIndex();
|
|
49595
50033
|
var linkExpansion_1 = require_linkExpansion();
|
|
49596
50034
|
var pathIndex_1 = require_pathIndex();
|
|
@@ -49737,6 +50175,12 @@ var require_codebaseIndex = __commonJS({
|
|
|
49737
50175
|
return value;
|
|
49738
50176
|
return fallback;
|
|
49739
50177
|
}
|
|
50178
|
+
exports2.RETRIEVAL_TOGGLE_ENABLED = false;
|
|
50179
|
+
function effectiveRetrievalMode(value) {
|
|
50180
|
+
if (!exports2.RETRIEVAL_TOGGLE_ENABLED)
|
|
50181
|
+
return "enhanced";
|
|
50182
|
+
return normalizeRetrievalMode4(value);
|
|
50183
|
+
}
|
|
49740
50184
|
exports2.CONTENT_PROBE_DEADLINE_MS = 600;
|
|
49741
50185
|
async function boundedAll(promises2, deadlineMs) {
|
|
49742
50186
|
if (promises2.length === 0)
|
|
@@ -59842,7 +60286,7 @@ ${notes.join("\n\n")}`;
|
|
|
59842
60286
|
});
|
|
59843
60287
|
this.readState.record(readKey2, meta2, range2);
|
|
59844
60288
|
const mode2 = readContextMode(params);
|
|
59845
|
-
const retrievalMode2 = this.getRetrievalMode(sessionId);
|
|
60289
|
+
const retrievalMode2 = (0, codebaseIndex_1.effectiveRetrievalMode)(this.getRetrievalMode(sessionId));
|
|
59846
60290
|
this.logRetrievalTool({
|
|
59847
60291
|
sessionId,
|
|
59848
60292
|
tool: "read_file",
|
|
@@ -59873,7 +60317,7 @@ ${notes.join("\n\n")}`;
|
|
|
59873
60317
|
});
|
|
59874
60318
|
this.readState.record(readKey, meta, range);
|
|
59875
60319
|
const mode = readContextMode(params);
|
|
59876
|
-
const retrievalMode = this.getRetrievalMode(sessionId);
|
|
60320
|
+
const retrievalMode = (0, codebaseIndex_1.effectiveRetrievalMode)(this.getRetrievalMode(sessionId));
|
|
59877
60321
|
this.logRetrievalTool({
|
|
59878
60322
|
sessionId,
|
|
59879
60323
|
tool: "read_file",
|
|
@@ -59889,7 +60333,7 @@ ${notes.join("\n\n")}`;
|
|
|
59889
60333
|
if (!this.codebaseIndex) {
|
|
59890
60334
|
return NO_INDEX_GUIDANCE;
|
|
59891
60335
|
}
|
|
59892
|
-
const retrievalMode = this.getRetrievalMode(sessionId);
|
|
60336
|
+
const retrievalMode = (0, codebaseIndex_1.effectiveRetrievalMode)(this.getRetrievalMode(sessionId));
|
|
59893
60337
|
this.logRetrievalTool({
|
|
59894
60338
|
sessionId,
|
|
59895
60339
|
tool: "search_codebase",
|
|
@@ -59915,7 +60359,7 @@ ${notes.join("\n\n")}`;
|
|
|
59915
60359
|
if (!this.codebaseIndex) {
|
|
59916
60360
|
return NO_INDEX_GUIDANCE;
|
|
59917
60361
|
}
|
|
59918
|
-
const retrievalMode = this.getRetrievalMode(sessionId);
|
|
60362
|
+
const retrievalMode = (0, codebaseIndex_1.effectiveRetrievalMode)(this.getRetrievalMode(sessionId));
|
|
59919
60363
|
this.logRetrievalTool({
|
|
59920
60364
|
sessionId,
|
|
59921
60365
|
tool: "trace_codebase",
|
|
@@ -64306,7 +64750,8 @@ var require_manager = __commonJS({
|
|
|
64306
64750
|
return `A work-graph run (${parent.activeRunId}) is already active in this conversation. Use work_run_status to watch it, work_run_amend to change it, or work_run_stop to end it.`;
|
|
64307
64751
|
}
|
|
64308
64752
|
const plan = params.plan;
|
|
64309
|
-
const
|
|
64753
|
+
const mode = parent.hooks.chatMode?.();
|
|
64754
|
+
const readOnly = mode === "plan" || mode === "duet";
|
|
64310
64755
|
const result = (0, validate_js_1.validateWorkPlan)(plan, parent.hooks.knownPersonas?.() ?? [], { readOnly });
|
|
64311
64756
|
if (!result.valid) {
|
|
64312
64757
|
return `The plan was REJECTED by the validator. Fix these and resubmit:
|
|
@@ -67038,6 +67483,9 @@ var require_dist = __commonJS({
|
|
|
67038
67483
|
__exportStar(require_segmentDriver(), exports2);
|
|
67039
67484
|
__exportStar(require_customProviders(), exports2);
|
|
67040
67485
|
__exportStar(require_interimModels(), exports2);
|
|
67486
|
+
__exportStar(require_duetMode(), exports2);
|
|
67487
|
+
__exportStar(require_duetPlan(), exports2);
|
|
67488
|
+
__exportStar(require_duetPlanners(), exports2);
|
|
67041
67489
|
__exportStar(require_repoIdentity(), exports2);
|
|
67042
67490
|
__exportStar(require_customProviderModels(), exports2);
|
|
67043
67491
|
__exportStar(require_cron(), exports2);
|
|
@@ -83690,8 +84138,8 @@ var Box2 = Box_default;
|
|
|
83690
84138
|
var ScrollBox2 = ScrollBox_default;
|
|
83691
84139
|
|
|
83692
84140
|
// src/main.tsx
|
|
83693
|
-
var import_client_core42 = __toESM(require_dist(), 1);
|
|
83694
84141
|
var import_client_core43 = __toESM(require_dist(), 1);
|
|
84142
|
+
var import_client_core44 = __toESM(require_dist(), 1);
|
|
83695
84143
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
83696
84144
|
import * as os7 from "os";
|
|
83697
84145
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
@@ -84057,7 +84505,9 @@ var darkTheme = {
|
|
|
84057
84505
|
diffAddBg: "#225c2b",
|
|
84058
84506
|
diffRemoveBg: "#7a2936",
|
|
84059
84507
|
autoAccept: "#3fb950",
|
|
84060
|
-
planMode: "#38bdf8"
|
|
84508
|
+
planMode: "#38bdf8",
|
|
84509
|
+
duetMode: "#a78bfa",
|
|
84510
|
+
activeChoice: "#a78bfa"
|
|
84061
84511
|
};
|
|
84062
84512
|
var lightTheme = {
|
|
84063
84513
|
name: "orion-light",
|
|
@@ -84108,7 +84558,9 @@ var lightTheme = {
|
|
|
84108
84558
|
diffAddBg: "#a6f3b0",
|
|
84109
84559
|
diffRemoveBg: "#ffc9d0",
|
|
84110
84560
|
autoAccept: "#15803d",
|
|
84111
|
-
planMode: "#267f99"
|
|
84561
|
+
planMode: "#267f99",
|
|
84562
|
+
duetMode: "#7c3aed",
|
|
84563
|
+
activeChoice: "#7c3aed"
|
|
84112
84564
|
};
|
|
84113
84565
|
var THEMES = {
|
|
84114
84566
|
"orion-dark": darkTheme,
|
|
@@ -86078,13 +86530,28 @@ var ATTACH_MIME = {
|
|
|
86078
86530
|
".webp": "image/webp",
|
|
86079
86531
|
".pdf": "application/pdf"
|
|
86080
86532
|
};
|
|
86081
|
-
var MODES = ["code", "plan", "ask"];
|
|
86533
|
+
var MODES = ["code", "plan", "ask", "duet"];
|
|
86082
86534
|
var PERMS = ["read_only", "default", "workspace_write", "full_access"];
|
|
86083
86535
|
function applyMode(ctx, mode) {
|
|
86084
86536
|
const sid = ctx.sessionId();
|
|
86085
86537
|
if (!sid) return;
|
|
86086
86538
|
ctx.appStore.setState((s) => ({ ...s, mode }));
|
|
86087
86539
|
void ctx.bridge.rpc("set_mode", { session_id: sid, mode });
|
|
86540
|
+
if (mode === "duet" && !(0, import_client_core16.isDuetPlanner)(ctx.appStore.getState().model)) {
|
|
86541
|
+
void (async () => {
|
|
86542
|
+
let models = [];
|
|
86543
|
+
try {
|
|
86544
|
+
const res = await ctx.bridge.rpc(
|
|
86545
|
+
"list_models",
|
|
86546
|
+
{ provider: "all" }
|
|
86547
|
+
);
|
|
86548
|
+
models = res.models ?? [];
|
|
86549
|
+
} catch {
|
|
86550
|
+
}
|
|
86551
|
+
const planner = (0, import_client_core16.resolveDuetPlanner)(import_client_core16.DUET_PLANNER_DEFAULT, models);
|
|
86552
|
+
await applyModel(ctx, sid, planner.model, planner.provider);
|
|
86553
|
+
})().catch(() => void 0);
|
|
86554
|
+
}
|
|
86088
86555
|
}
|
|
86089
86556
|
function applyPermissionMode(ctx, mode) {
|
|
86090
86557
|
const sid = ctx.sessionId();
|
|
@@ -86095,6 +86562,9 @@ function applyPermissionMode(ctx, mode) {
|
|
|
86095
86562
|
function cycleModePosture(ctx) {
|
|
86096
86563
|
const st2 = ctx.appStore.getState();
|
|
86097
86564
|
if (st2.mode === "plan") {
|
|
86565
|
+
applyMode(ctx, "duet");
|
|
86566
|
+
applyPermissionMode(ctx, "read_only");
|
|
86567
|
+
} else if (st2.mode === "duet") {
|
|
86098
86568
|
applyMode(ctx, "code");
|
|
86099
86569
|
applyPermissionMode(ctx, "workspace_write");
|
|
86100
86570
|
} else if (st2.permissionMode === "full_access") {
|
|
@@ -86140,7 +86610,7 @@ async function applyModel(ctx, sid, modelId, provider, label, contextWindow) {
|
|
|
86140
86610
|
}
|
|
86141
86611
|
ctx.print(`Model set to ${lbl}${provider ? ` \xB7 ${providerLabel(provider)}` : ""}`);
|
|
86142
86612
|
}
|
|
86143
|
-
async function
|
|
86613
|
+
async function openPlatformModelPicker(ctx, opts) {
|
|
86144
86614
|
let models = [];
|
|
86145
86615
|
try {
|
|
86146
86616
|
const res = await ctx.bridge.rpc("list_models", {
|
|
@@ -86149,13 +86619,16 @@ async function openInterimModelPicker(ctx, slot, workspaceRoot) {
|
|
|
86149
86619
|
models = res.models ?? [];
|
|
86150
86620
|
} catch {
|
|
86151
86621
|
}
|
|
86152
|
-
const
|
|
86153
|
-
const active = config[slot.key];
|
|
86622
|
+
const active = opts.active;
|
|
86154
86623
|
const options = [
|
|
86155
86624
|
{
|
|
86156
|
-
label:
|
|
86157
|
-
value: "
|
|
86158
|
-
|
|
86625
|
+
label: opts.defaultLabel,
|
|
86626
|
+
value: "__default",
|
|
86627
|
+
// "(reset)" when something else is active — the row is an ACTION (go back to
|
|
86628
|
+
// the default), and a bare default label beside a current choice reads like a
|
|
86629
|
+
// status line claiming nothing is selected.
|
|
86630
|
+
hint: active ? "(reset)" : "(active)",
|
|
86631
|
+
accent: active === void 0
|
|
86159
86632
|
}
|
|
86160
86633
|
];
|
|
86161
86634
|
const providerOf = {};
|
|
@@ -86173,37 +86646,49 @@ async function openInterimModelPicker(ctx, slot, workspaceRoot) {
|
|
|
86173
86646
|
modelOf[key] = m2.id;
|
|
86174
86647
|
labelOf[key] = m2.label ?? formatModelName(m2.id);
|
|
86175
86648
|
const isActive = active !== void 0 && active.model === m2.id && active.provider === prov;
|
|
86176
|
-
options.push({ label: m2.label ?? m2.id, value: key, hint: isActive ? "(active)" : m2.id });
|
|
86649
|
+
options.push({ label: m2.label ?? m2.id, value: key, hint: isActive ? "(active)" : m2.id, accent: isActive });
|
|
86177
86650
|
}
|
|
86651
|
+
const currentLabel = active ? labelOf[`${active.provider}/${active.model}`] ?? formatModelName(active.model) : opts.defaultLabel;
|
|
86178
86652
|
ctx.appStore.setState((s) => ({
|
|
86179
86653
|
...s,
|
|
86180
86654
|
activeDialog: {
|
|
86181
86655
|
kind: "select",
|
|
86182
|
-
title: `${
|
|
86656
|
+
title: `${opts.title} \xB7 current: ${currentLabel}`,
|
|
86183
86657
|
options,
|
|
86184
86658
|
onSelect: (value) => {
|
|
86185
86659
|
ctx.appStore.setState((s2) => ({ ...s2, activeDialog: null }));
|
|
86186
86660
|
if (!value) return;
|
|
86187
86661
|
void (async () => {
|
|
86188
|
-
if (value === "
|
|
86189
|
-
|
|
86190
|
-
|
|
86191
|
-
|
|
86192
|
-
|
|
86193
|
-
|
|
86194
|
-
|
|
86195
|
-
|
|
86196
|
-
|
|
86197
|
-
|
|
86662
|
+
if (value === "__default") {
|
|
86663
|
+
ctx.print(await opts.save(void 0, opts.defaultLabel));
|
|
86664
|
+
} else if (modelOf[value] !== void 0) {
|
|
86665
|
+
ctx.print(
|
|
86666
|
+
await opts.save(
|
|
86667
|
+
{ provider: providerOf[value] ?? "", model: modelOf[value] },
|
|
86668
|
+
labelOf[value] ?? modelOf[value]
|
|
86669
|
+
)
|
|
86670
|
+
);
|
|
86671
|
+
}
|
|
86198
86672
|
})().catch(
|
|
86199
|
-
(e) => ctx.print(
|
|
86200
|
-
`Could not save the interim-model choice: ${e instanceof Error ? e.message : String(e)}`
|
|
86201
|
-
)
|
|
86673
|
+
(e) => ctx.print(`${opts.saveErrorPrefix}: ${e instanceof Error ? e.message : String(e)}`)
|
|
86202
86674
|
);
|
|
86203
86675
|
}
|
|
86204
86676
|
}
|
|
86205
86677
|
}));
|
|
86206
86678
|
}
|
|
86679
|
+
async function openInterimModelPicker(ctx, slot, workspaceRoot) {
|
|
86680
|
+
const config = await (0, import_client_core16.loadInterimModels)({ workspaceRoot });
|
|
86681
|
+
await openPlatformModelPicker(ctx, {
|
|
86682
|
+
title: `${slot.label} \u2014 select a model`,
|
|
86683
|
+
defaultLabel: import_client_core16.INTERIM_DEFAULT_LABEL,
|
|
86684
|
+
active: config[slot.key],
|
|
86685
|
+
save: async (pick, label) => {
|
|
86686
|
+
await (0, import_client_core16.setInterimModel)(slot.key, pick);
|
|
86687
|
+
return pick === void 0 ? `${slot.label} reset to the primary active model` : `${slot.label} model set to ${label}`;
|
|
86688
|
+
},
|
|
86689
|
+
saveErrorPrefix: "Could not save the interim-model choice"
|
|
86690
|
+
});
|
|
86691
|
+
}
|
|
86207
86692
|
function promptReasoning(ctx, sid, modelLabel, reasoning) {
|
|
86208
86693
|
const levels = reasoning.levels.filter((l3) => l3 !== "off");
|
|
86209
86694
|
if (levels.length === 0) return;
|
|
@@ -86547,30 +87032,95 @@ function registerBuiltins(registry) {
|
|
|
86547
87032
|
if (m2.reasoning && m2.reasoning.levels?.length) reasoningOf[key] = m2.reasoning;
|
|
86548
87033
|
if (m2.context_window && m2.context_window > 0) windowOf[key] = m2.context_window;
|
|
86549
87034
|
}
|
|
87035
|
+
const duet = ctx.appStore.getState().mode === "duet";
|
|
87036
|
+
const duetExecutor = duet ? await (0, import_client_core16.loadDuetExecutor)({ workspaceRoot: ctx.config?.workspaceRoot }).catch(() => null) : null;
|
|
86550
87037
|
const opts = [];
|
|
87038
|
+
if (duet) {
|
|
87039
|
+
const plannerLabel = models.find((m2) => m2.id === current2)?.label ?? import_client_core16.DUET_PLANNER_LABELS[current2] ?? formatModelName(current2);
|
|
87040
|
+
opts.push({ label: "Plan \u2014 ", value: "__sep_plan", separator: true, accentSuffix: plannerLabel });
|
|
87041
|
+
for (const id of import_client_core16.DUET_PLANNER_IDS) {
|
|
87042
|
+
let entry;
|
|
87043
|
+
for (const prov2 of import_client_core16.DUET_PLANNER_PROVIDERS) {
|
|
87044
|
+
entry = models.find((m2) => m2.id === id && (m2.provider ?? "") === prov2);
|
|
87045
|
+
if (entry) break;
|
|
87046
|
+
}
|
|
87047
|
+
const prov = entry?.provider ?? import_client_core16.DUET_PLANNER_PROVIDERS[0];
|
|
87048
|
+
const label = entry?.label ?? import_client_core16.DUET_PLANNER_LABELS[id] ?? formatModelName(id);
|
|
87049
|
+
const key = `${prov}/${id}`;
|
|
87050
|
+
modelOf[`plan|${key}`] = id;
|
|
87051
|
+
providerOf[`plan|${key}`] = prov;
|
|
87052
|
+
labelOf[`plan|${key}`] = label;
|
|
87053
|
+
if (entry?.reasoning?.levels?.length) reasoningOf[`plan|${key}`] = entry.reasoning;
|
|
87054
|
+
if (entry?.context_window) windowOf[`plan|${key}`] = entry.context_window;
|
|
87055
|
+
opts.push({
|
|
87056
|
+
label,
|
|
87057
|
+
value: `plan|${key}`,
|
|
87058
|
+
// Role-tagged: the search filter flattens sections away, and a planner
|
|
87059
|
+
// can also appear in the executor catalog with an identical label —
|
|
87060
|
+
// the hint is what keeps the two rows tellable apart.
|
|
87061
|
+
hint: current2 === id ? "planner (active)" : "planner",
|
|
87062
|
+
accent: current2 === id
|
|
87063
|
+
});
|
|
87064
|
+
}
|
|
87065
|
+
const executorLabel = duetExecutor ? models.find(
|
|
87066
|
+
(m2) => m2.id === duetExecutor.model && ((m2.provider ?? "") === duetExecutor.provider || duetExecutor.provider === "")
|
|
87067
|
+
)?.label ?? duetExecutor.model : import_client_core16.DUET_EXECUTOR_DEFAULT_LABEL;
|
|
87068
|
+
opts.push({ label: "Executor \u2014 ", value: "__sep_exec", separator: true, accentSuffix: executorLabel });
|
|
87069
|
+
opts.push({
|
|
87070
|
+
label: `Default \u2014 ${import_client_core16.DUET_EXECUTOR_DEFAULT_LABEL}`,
|
|
87071
|
+
value: "exec|__default",
|
|
87072
|
+
hint: duetExecutor === null ? "(active)" : "(reset)",
|
|
87073
|
+
accent: duetExecutor === null
|
|
87074
|
+
});
|
|
87075
|
+
}
|
|
86551
87076
|
let lastProvider;
|
|
86552
87077
|
for (const m2 of models) {
|
|
86553
87078
|
const prov = m2.provider ?? currentProvider;
|
|
86554
87079
|
if (prov !== lastProvider) {
|
|
86555
|
-
opts.push({
|
|
87080
|
+
opts.push({
|
|
87081
|
+
label: duet ? ` ${providerLabel(prov)}` : providerLabel(prov),
|
|
87082
|
+
value: `__sep_${prov}`,
|
|
87083
|
+
separator: true
|
|
87084
|
+
});
|
|
86556
87085
|
lastProvider = prov;
|
|
86557
87086
|
}
|
|
86558
|
-
const active = m2.id === current2 && prov === currentProvider;
|
|
87087
|
+
const active = duet ? !!duetExecutor && duetExecutor.model === m2.id && (duetExecutor.provider === prov || duetExecutor.provider === "") : m2.id === current2 && prov === currentProvider;
|
|
86559
87088
|
opts.push({
|
|
86560
87089
|
label: m2.label ?? m2.id,
|
|
86561
|
-
value: `${prov}/${m2.id}`,
|
|
86562
|
-
hint: active ? "(active)" : m2.id
|
|
87090
|
+
value: duet ? `exec|${prov}/${m2.id}` : `${prov}/${m2.id}`,
|
|
87091
|
+
hint: active ? "(active)" : m2.id,
|
|
87092
|
+
accent: active
|
|
86563
87093
|
});
|
|
86564
87094
|
}
|
|
86565
87095
|
ctx.appStore.setState((s) => ({
|
|
86566
87096
|
...s,
|
|
86567
87097
|
activeDialog: {
|
|
86568
87098
|
kind: "model",
|
|
86569
|
-
title: "Select a model",
|
|
87099
|
+
title: duet ? "Select models \u2014 Plan \xB7 Executor" : "Select a model",
|
|
86570
87100
|
options: opts,
|
|
86571
87101
|
onSelect: (v2) => {
|
|
86572
87102
|
ctx.appStore.setState((s2) => ({ ...s2, activeDialog: null }));
|
|
86573
87103
|
if (!v2) return;
|
|
87104
|
+
if (v2 === "exec|__default") {
|
|
87105
|
+
void (0, import_client_core16.setDuetExecutor)(void 0).then(
|
|
87106
|
+
() => ctx.print(
|
|
87107
|
+
`Duet executor reset \u2014 approved plans execute on ${import_client_core16.DUET_EXECUTOR_DEFAULT_LABEL} (default)`
|
|
87108
|
+
)
|
|
87109
|
+
).catch(
|
|
87110
|
+
(e) => ctx.print(`Could not save the Duet executor: ${e instanceof Error ? e.message : String(e)}`)
|
|
87111
|
+
);
|
|
87112
|
+
return;
|
|
87113
|
+
}
|
|
87114
|
+
if (v2.startsWith("exec|")) {
|
|
87115
|
+
const key = v2.slice("exec|".length);
|
|
87116
|
+
const slash = key.indexOf("/");
|
|
87117
|
+
const provider = key.slice(0, slash);
|
|
87118
|
+
const id = key.slice(slash + 1);
|
|
87119
|
+
void (0, import_client_core16.setDuetExecutor)({ provider, model: id }).then(() => ctx.print(`Duet executor set to ${labelOf[key] ?? formatModelName(id)}`)).catch(
|
|
87120
|
+
(e) => ctx.print(`Could not save the Duet executor: ${e instanceof Error ? e.message : String(e)}`)
|
|
87121
|
+
);
|
|
87122
|
+
return;
|
|
87123
|
+
}
|
|
86574
87124
|
const modelId = modelOf[v2] ?? v2;
|
|
86575
87125
|
void applyModel(ctx, sid, modelId, providerOf[v2], labelOf[v2], windowOf[v2]).then(() => {
|
|
86576
87126
|
const r2 = reasoningOf[v2];
|
|
@@ -86649,6 +87199,27 @@ function registerBuiltins(registry) {
|
|
|
86649
87199
|
}));
|
|
86650
87200
|
}
|
|
86651
87201
|
},
|
|
87202
|
+
{
|
|
87203
|
+
kind: "local",
|
|
87204
|
+
name: "duet-executor",
|
|
87205
|
+
aliases: ["executor", "auto-executor"],
|
|
87206
|
+
description: "Choose the model that executes approved plans in Duet mode",
|
|
87207
|
+
keywords: ["model", "auto", "duet", "plan", "execute"],
|
|
87208
|
+
run: async (_args, ctx) => {
|
|
87209
|
+
const workspaceRoot = ctx.config?.workspaceRoot;
|
|
87210
|
+
const active = await (0, import_client_core16.loadDuetExecutor)({ workspaceRoot });
|
|
87211
|
+
await openPlatformModelPicker(ctx, {
|
|
87212
|
+
title: `${import_client_core16.DUET_EXECUTOR_INFO.label} \u2014 select a model`,
|
|
87213
|
+
defaultLabel: import_client_core16.DUET_EXECUTOR_DEFAULT_LABEL,
|
|
87214
|
+
active: active ?? void 0,
|
|
87215
|
+
save: async (pick, label) => {
|
|
87216
|
+
await (0, import_client_core16.setDuetExecutor)(pick);
|
|
87217
|
+
return pick === void 0 ? `Duet executor reset \u2014 approved plans execute on ${import_client_core16.DUET_EXECUTOR_DEFAULT_LABEL} (default)` : `Duet executor set to ${label}`;
|
|
87218
|
+
},
|
|
87219
|
+
saveErrorPrefix: "Could not save the Duet executor"
|
|
87220
|
+
});
|
|
87221
|
+
}
|
|
87222
|
+
},
|
|
86652
87223
|
{
|
|
86653
87224
|
kind: "local",
|
|
86654
87225
|
name: "endpoint",
|
|
@@ -86800,17 +87371,17 @@ Use one: /endpoint use <name> [model] \xB7 remove: /endpoint remove <name>`
|
|
|
86800
87371
|
{
|
|
86801
87372
|
kind: "local",
|
|
86802
87373
|
name: "mode",
|
|
86803
|
-
description: "Set mode (code|plan|ask)",
|
|
87374
|
+
description: "Set mode (code|plan|ask|duet)",
|
|
86804
87375
|
argumentHint: "<mode>",
|
|
86805
87376
|
run: async (args2, ctx) => {
|
|
86806
87377
|
const sid = ctx.sessionId();
|
|
86807
|
-
const
|
|
87378
|
+
const typed = args2.trim().toLowerCase();
|
|
87379
|
+
const mode = typed === "auto" ? "duet" : typed;
|
|
86808
87380
|
if (!sid || !MODES.includes(mode)) {
|
|
86809
|
-
ctx.print("Usage: /mode code|plan|ask");
|
|
87381
|
+
ctx.print("Usage: /mode code|plan|ask|duet (auto = duet)");
|
|
86810
87382
|
return;
|
|
86811
87383
|
}
|
|
86812
|
-
|
|
86813
|
-
ctx.appStore.setState((s) => ({ ...s, mode }));
|
|
87384
|
+
applyMode(ctx, mode);
|
|
86814
87385
|
ctx.print(`Mode set to ${mode}`);
|
|
86815
87386
|
}
|
|
86816
87387
|
},
|
|
@@ -87038,22 +87609,27 @@ Use one: /endpoint use <name> [model] \xB7 remove: /endpoint remove <name>`
|
|
|
87038
87609
|
if (requested !== "off") ctx.print(`Index mode: ${requested}`);
|
|
87039
87610
|
}
|
|
87040
87611
|
},
|
|
87041
|
-
|
|
87042
|
-
|
|
87043
|
-
|
|
87044
|
-
|
|
87045
|
-
|
|
87046
|
-
|
|
87047
|
-
|
|
87048
|
-
|
|
87049
|
-
|
|
87050
|
-
|
|
87051
|
-
|
|
87052
|
-
|
|
87053
|
-
|
|
87054
|
-
|
|
87055
|
-
|
|
87056
|
-
|
|
87612
|
+
// ORION: `/retrieval` is hidden while enhanced retrieval is always on. The
|
|
87613
|
+
// command is kept intact — flipping RETRIEVAL_TOGGLE_ENABLED back to true in
|
|
87614
|
+
// orion-client-core restores it in this list with no other change.
|
|
87615
|
+
...import_client_core14.RETRIEVAL_TOGGLE_ENABLED ? [
|
|
87616
|
+
{
|
|
87617
|
+
kind: "local",
|
|
87618
|
+
name: "retrieval",
|
|
87619
|
+
description: "Toggle enhanced retrieval",
|
|
87620
|
+
argumentHint: "[default|enhanced|toggle]",
|
|
87621
|
+
run: (args2, ctx) => {
|
|
87622
|
+
const current2 = (0, import_client_core14.normalizeRetrievalMode)(ctx.appStore.getState().retrievalMode, "default");
|
|
87623
|
+
const requested = args2.trim();
|
|
87624
|
+
if (!requested || requested.toLowerCase() === "status") {
|
|
87625
|
+
return ctx.printInfo(retrievalView(current2));
|
|
87626
|
+
}
|
|
87627
|
+
const next = parseRetrievalModeArg(requested, current2);
|
|
87628
|
+
if (!next) return ctx.print("Usage: /retrieval [default|enhanced|toggle]");
|
|
87629
|
+
applyRetrievalMode(ctx, next);
|
|
87630
|
+
}
|
|
87631
|
+
}
|
|
87632
|
+
] : [],
|
|
87057
87633
|
{
|
|
87058
87634
|
kind: "local",
|
|
87059
87635
|
name: "theme",
|
|
@@ -88326,6 +88902,8 @@ function initialAppState(partial) {
|
|
|
88326
88902
|
error: null,
|
|
88327
88903
|
pendingPermissions: [],
|
|
88328
88904
|
pendingPlanApproval: null,
|
|
88905
|
+
duetExecutionStarted: false,
|
|
88906
|
+
duetPlan: null,
|
|
88329
88907
|
pendingAskUser: null,
|
|
88330
88908
|
pendingWorkPlan: null,
|
|
88331
88909
|
pendingFeedback: null,
|
|
@@ -88416,9 +88994,44 @@ function resumedRouting(current2, saved) {
|
|
|
88416
88994
|
};
|
|
88417
88995
|
}
|
|
88418
88996
|
|
|
88419
|
-
// src/
|
|
88997
|
+
// src/components/messages/duetPhaseNote.ts
|
|
88998
|
+
var import_chalk3 = __toESM(require_source(), 1);
|
|
88420
88999
|
var import_client_core19 = __toESM(require_dist(), 1);
|
|
88421
89000
|
|
|
89001
|
+
// src/components/design-system/GradientText.tsx
|
|
89002
|
+
var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
|
|
89003
|
+
var GRAD_FROM = [183, 148, 246];
|
|
89004
|
+
var GRAD_TO = [230, 218, 252];
|
|
89005
|
+
var hex2 = (v2) => Math.max(0, Math.min(255, Math.round(v2))).toString(16).padStart(2, "0");
|
|
89006
|
+
function gradientAt(t) {
|
|
89007
|
+
const c3 = Math.max(0, Math.min(1, t));
|
|
89008
|
+
return `#${hex2(GRAD_FROM[0] + (GRAD_TO[0] - GRAD_FROM[0]) * c3)}${hex2(
|
|
89009
|
+
GRAD_FROM[1] + (GRAD_TO[1] - GRAD_FROM[1]) * c3
|
|
89010
|
+
)}${hex2(GRAD_FROM[2] + (GRAD_TO[2] - GRAD_FROM[2]) * c3)}`;
|
|
89011
|
+
}
|
|
89012
|
+
function GradientText({
|
|
89013
|
+
text,
|
|
89014
|
+
wrap: wrap2
|
|
89015
|
+
}) {
|
|
89016
|
+
const chars = [...text];
|
|
89017
|
+
const last = Math.max(1, chars.length - 1);
|
|
89018
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text2, { wrap: wrap2, children: chars.map((ch, i2) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text2, { color: gradientAt(i2 / last), children: ch }, i2)) });
|
|
89019
|
+
}
|
|
89020
|
+
|
|
89021
|
+
// src/components/messages/duetPhaseNote.ts
|
|
89022
|
+
function duetPhaseNoteText(phase, opts) {
|
|
89023
|
+
const line = (0, import_client_core19.duetPhaseLine)(phase, opts);
|
|
89024
|
+
const sep4 = line.indexOf(" \xB7 ");
|
|
89025
|
+
const verb = [...sep4 === -1 ? line : line.slice(0, sep4)];
|
|
89026
|
+
const last = Math.max(1, verb.length - 1);
|
|
89027
|
+
const styled = verb.map((ch, i2) => import_chalk3.default.hex(gradientAt(i2 / last))(ch)).join("");
|
|
89028
|
+
const lifted = `\x1B[22m${styled}\x1B[2m`;
|
|
89029
|
+
return sep4 === -1 ? lifted : lifted + line.slice(sep4);
|
|
89030
|
+
}
|
|
89031
|
+
|
|
89032
|
+
// src/events/renderLane.ts
|
|
89033
|
+
var import_client_core20 = __toESM(require_dist(), 1);
|
|
89034
|
+
|
|
88422
89035
|
// src/services/persistence.ts
|
|
88423
89036
|
import * as path9 from "path";
|
|
88424
89037
|
import * as fs10 from "fs";
|
|
@@ -88736,12 +89349,12 @@ function renderLane(transcript, app, ev) {
|
|
|
88736
89349
|
}
|
|
88737
89350
|
case "file_modified":
|
|
88738
89351
|
if (d2.memory === true) {
|
|
88739
|
-
const label = d2.memory_tier === "working" ? `Recursive learning \xB7 ${(0,
|
|
89352
|
+
const label = d2.memory_tier === "working" ? `Recursive learning \xB7 ${(0, import_client_core20.memorySlug)(String(d2.path ?? ""))}` : `Memory updated \xB7 ${(0, import_client_core20.memorySlug)(String(d2.path ?? ""))}`;
|
|
88740
89353
|
transcript.setState((s) => appendNote(s, label));
|
|
88741
89354
|
break;
|
|
88742
89355
|
}
|
|
88743
89356
|
if (d2.scratch === true) {
|
|
88744
|
-
const label = typeof d2.scratch_path === "string" && d2.scratch_path ? d2.scratch_path : (0,
|
|
89357
|
+
const label = typeof d2.scratch_path === "string" && d2.scratch_path ? d2.scratch_path : (0, import_client_core20.scratchLabel)(String(d2.path ?? ""));
|
|
88745
89358
|
transcript.setState(
|
|
88746
89359
|
(s) => appendNote(s, `Scratch \xB7 ${label}`, {
|
|
88747
89360
|
insertions: typeof d2.insertions === "number" ? d2.insertions : 0,
|
|
@@ -88758,7 +89371,7 @@ function renderLane(transcript, app, ev) {
|
|
|
88758
89371
|
deletions: typeof d2.deletions === "number" ? d2.deletions : 0,
|
|
88759
89372
|
deleted: d2.deleted === true,
|
|
88760
89373
|
affectedFiles: Array.isArray(d2.affected_files) ? d2.affected_files.filter((p) => typeof p === "string") : void 0,
|
|
88761
|
-
trust: (0,
|
|
89374
|
+
trust: (0, import_client_core20.parseTrust)(d2.trust)
|
|
88762
89375
|
})
|
|
88763
89376
|
);
|
|
88764
89377
|
break;
|
|
@@ -88825,7 +89438,7 @@ function renderLane(transcript, app, ev) {
|
|
|
88825
89438
|
break;
|
|
88826
89439
|
}
|
|
88827
89440
|
case "input_guard": {
|
|
88828
|
-
const card = (0,
|
|
89441
|
+
const card = (0, import_client_core20.parseInputGuardEvent)(d2);
|
|
88829
89442
|
if (card) transcript.setState((s) => appendInputGuard(s, card));
|
|
88830
89443
|
break;
|
|
88831
89444
|
}
|
|
@@ -88858,7 +89471,7 @@ function renderLane(transcript, app, ev) {
|
|
|
88858
89471
|
break;
|
|
88859
89472
|
case "compaction_complete": {
|
|
88860
89473
|
app.setState((s) => s.status === "streaming" ? { ...s, statusText: "thinking\u2026" } : s);
|
|
88861
|
-
const compaction = (0,
|
|
89474
|
+
const compaction = (0, import_client_core20.parseUserCompaction)(d2);
|
|
88862
89475
|
if (compaction) transcript.setState((s) => appendCompaction(s, compaction));
|
|
88863
89476
|
break;
|
|
88864
89477
|
}
|
|
@@ -88916,7 +89529,7 @@ function renderLane(transcript, app, ev) {
|
|
|
88916
89529
|
// …and the parked ask future
|
|
88917
89530
|
}));
|
|
88918
89531
|
} else {
|
|
88919
|
-
const quota = (0,
|
|
89532
|
+
const quota = (0, import_client_core20.parseQuotaRefusal)(d2);
|
|
88920
89533
|
transcript.setState(
|
|
88921
89534
|
(s) => quota ? appendQuota(applyTurnError(s, data), quota) : applyTurnError(s, data)
|
|
88922
89535
|
);
|
|
@@ -88978,7 +89591,7 @@ function isOutOfBandEvent(event) {
|
|
|
88978
89591
|
}
|
|
88979
89592
|
|
|
88980
89593
|
// src/state/steerLifecycle.ts
|
|
88981
|
-
var
|
|
89594
|
+
var import_client_core21 = __toESM(require_dist(), 1);
|
|
88982
89595
|
function drainSteersForSegment(app, transcript) {
|
|
88983
89596
|
const steers = app.getState().queuedMessages.filter((q2) => q2.kind === "steer");
|
|
88984
89597
|
if (steers.length === 0) return [];
|
|
@@ -89010,7 +89623,7 @@ function settleSteerQueue(deps2) {
|
|
|
89010
89623
|
if (deps2.isBusy()) return;
|
|
89011
89624
|
const leftovers = deps2.app.getState().queuedMessages.filter((q2) => q2.kind === "steer");
|
|
89012
89625
|
if (leftovers.length === 0) return;
|
|
89013
|
-
const prompt = (0,
|
|
89626
|
+
const prompt = (0, import_client_core21.promoteLeftoverSteers)(leftovers.map((q2) => q2.text));
|
|
89014
89627
|
deps2.app.setState((s) => ({
|
|
89015
89628
|
...s,
|
|
89016
89629
|
queuedMessages: s.queuedMessages.filter((q2) => q2.kind !== "steer")
|
|
@@ -89097,7 +89710,7 @@ function makeGoalRunTurn(deps2) {
|
|
|
89097
89710
|
}
|
|
89098
89711
|
|
|
89099
89712
|
// src/events/boundaryHandlers.ts
|
|
89100
|
-
var
|
|
89713
|
+
var import_client_core22 = __toESM(require_dist(), 1);
|
|
89101
89714
|
var import_client_ui_core4 = __toESM(require_dist2(), 1);
|
|
89102
89715
|
function createBoundaryHandlers(deps2) {
|
|
89103
89716
|
const {
|
|
@@ -89117,7 +89730,7 @@ function createBoundaryHandlers(deps2) {
|
|
|
89117
89730
|
onEvent,
|
|
89118
89731
|
runTool: (req, s, ctx) => executor.run(req, s, ctx),
|
|
89119
89732
|
onPermission: async (req) => {
|
|
89120
|
-
const addDirCandidate = req.reason_code === "outside_working_directories" && typeof req.blocked_path === "string" ? await (0,
|
|
89733
|
+
const addDirCandidate = req.reason_code === "outside_working_directories" && typeof req.blocked_path === "string" ? await (0, import_client_core22.directoryForBlockedPath)(req.blocked_path) : void 0;
|
|
89121
89734
|
if (bridge.isTurboModeEnabledForSession(sid)) {
|
|
89122
89735
|
if (fullyAutomatic && req.reason_code === "protected_path") {
|
|
89123
89736
|
return { decision: "deny", auto: true };
|
|
@@ -89205,7 +89818,7 @@ function createBoundaryHandlers(deps2) {
|
|
|
89205
89818
|
// a human at it. Only a genuinely UNATTENDED run (headless: no UI to draw a card on) gets
|
|
89206
89819
|
// the standing instruction, because there a card would wait forever.
|
|
89207
89820
|
onAskUser: (req) => {
|
|
89208
|
-
if (unattended) return Promise.resolve((0,
|
|
89821
|
+
if (unattended) return Promise.resolve((0, import_client_core22.answerAll)(req, import_client_core22.ASK_NO_INTERACTIVE_USER));
|
|
89209
89822
|
appStore.setState((s) => ({
|
|
89210
89823
|
...s,
|
|
89211
89824
|
pendingAskUser: { requestId: req.request_id, request: req, sessionId: sid }
|
|
@@ -89262,6 +89875,23 @@ function createBoundaryHandlers(deps2) {
|
|
|
89262
89875
|
const resolve5 = planResolvers.get(requestId);
|
|
89263
89876
|
planResolvers.delete(requestId);
|
|
89264
89877
|
resolve5?.({ decision });
|
|
89878
|
+
if (appStore.getState().mode === "duet") {
|
|
89879
|
+
const approved = decision === "auto" || decision === "manual";
|
|
89880
|
+
const pendingPlanText = appStore.getState().pendingPlanApproval?.plan ?? "";
|
|
89881
|
+
appStore.setState((s) => ({
|
|
89882
|
+
...s,
|
|
89883
|
+
pendingPlanApproval: null,
|
|
89884
|
+
...approved ? { duetExecutionStarted: true } : {},
|
|
89885
|
+
// A STANDING grant (auto-accept, human by construction — this resolver IS the
|
|
89886
|
+
// card) mints/refreshes the standing plan: the record routed planning reads on
|
|
89887
|
+
// following turns. Manual approve stays per-turn.
|
|
89888
|
+
...decision === "auto" ? { duetPlan: (0, import_client_core22.createStandingPlan)(pendingPlanText, s.duetPlan) ?? s.duetPlan } : {}
|
|
89889
|
+
}));
|
|
89890
|
+
if (approved) {
|
|
89891
|
+
deps2.duetExecutingNote?.();
|
|
89892
|
+
}
|
|
89893
|
+
return;
|
|
89894
|
+
}
|
|
89265
89895
|
if (decision === "auto") {
|
|
89266
89896
|
appStore.setState((s) => ({
|
|
89267
89897
|
...s,
|
|
@@ -89297,7 +89927,7 @@ function ringBell(out2 = process.stdout) {
|
|
|
89297
89927
|
}
|
|
89298
89928
|
|
|
89299
89929
|
// src/services/loopService.ts
|
|
89300
|
-
var
|
|
89930
|
+
var import_client_core23 = __toESM(require_dist(), 1);
|
|
89301
89931
|
import { promises as fs11 } from "fs";
|
|
89302
89932
|
import { dirname as dirname5, join as join9 } from "path";
|
|
89303
89933
|
function loopSchedulePersistence(path13) {
|
|
@@ -89328,18 +89958,18 @@ var LoopService = class {
|
|
|
89328
89958
|
started = false;
|
|
89329
89959
|
constructor(deps2) {
|
|
89330
89960
|
this.deps = deps2;
|
|
89331
|
-
this.approvals = new
|
|
89332
|
-
this.runs = new
|
|
89333
|
-
this.runner = new
|
|
89961
|
+
this.approvals = new import_client_core23.LoopApprovalStore(deps2.workspaceRoot);
|
|
89962
|
+
this.runs = new import_client_core23.LoopRunStore(deps2.workspaceRoot);
|
|
89963
|
+
this.runner = new import_client_core23.LoopRunner({
|
|
89334
89964
|
transport: deps2.transport,
|
|
89335
89965
|
tools: deps2.tools,
|
|
89336
89966
|
store: this.runs,
|
|
89337
|
-
leases: new
|
|
89967
|
+
leases: new import_client_core23.LoopLeaseStore(deps2.workspaceRoot),
|
|
89338
89968
|
baseRouting: deps2.baseRouting,
|
|
89339
|
-
anchorResolver: () => new
|
|
89969
|
+
anchorResolver: () => new import_client_core23.FilesystemAnchorResolver(deps2.workspaceRoot),
|
|
89340
89970
|
notify: deps2.notify
|
|
89341
89971
|
});
|
|
89342
|
-
this.schedule = new
|
|
89972
|
+
this.schedule = new import_client_core23.LoopSchedule({
|
|
89343
89973
|
persistence: loopSchedulePersistence(deps2.schedulePath),
|
|
89344
89974
|
onFire: (name2) => void this.fire(name2),
|
|
89345
89975
|
isBusy: deps2.isBusy
|
|
@@ -89361,11 +89991,11 @@ var LoopService = class {
|
|
|
89361
89991
|
}
|
|
89362
89992
|
/** Re-read the declaration files and re-reconcile what is scheduled. */
|
|
89363
89993
|
async reload() {
|
|
89364
|
-
const { decls, issues } = await (0,
|
|
89994
|
+
const { decls, issues } = await (0, import_client_core23.loadLoopDecls)(this.deps.workspaceRoot);
|
|
89365
89995
|
this.decls = decls;
|
|
89366
89996
|
this.issues = issues;
|
|
89367
89997
|
this.approvals.invalidate();
|
|
89368
|
-
await this.schedule.syncFromDecls(await (0,
|
|
89998
|
+
await this.schedule.syncFromDecls(await (0, import_client_core23.withApprovalStatus)(decls.values(), this.approvals));
|
|
89369
89999
|
void this.runner.sweepDanglingParks();
|
|
89370
90000
|
}
|
|
89371
90001
|
/** Problems found while loading declarations — shown in `/loops` so a typo is visible
|
|
@@ -89375,7 +90005,7 @@ var LoopService = class {
|
|
|
89375
90005
|
}
|
|
89376
90006
|
/** Everything `/loops` renders. */
|
|
89377
90007
|
async rows() {
|
|
89378
|
-
const entries = await (0,
|
|
90008
|
+
const entries = await (0, import_client_core23.withApprovalStatus)(this.decls.values(), this.approvals);
|
|
89379
90009
|
const nextFire = await this.schedule.nextFireTimes();
|
|
89380
90010
|
const active = new Set(this.runner.activeRuns().map((r2) => r2.loop));
|
|
89381
90011
|
const rows = [];
|
|
@@ -89515,13 +90145,13 @@ var import_react27 = __toESM(require_react(), 1);
|
|
|
89515
90145
|
var import_react23 = __toESM(require_react(), 1);
|
|
89516
90146
|
|
|
89517
90147
|
// src/components/messages/UserText.tsx
|
|
89518
|
-
var
|
|
90148
|
+
var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
|
|
89519
90149
|
function UserText({
|
|
89520
90150
|
text,
|
|
89521
90151
|
pending = false
|
|
89522
90152
|
}) {
|
|
89523
90153
|
const theme = useTheme();
|
|
89524
|
-
return /* @__PURE__ */ (0,
|
|
90154
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Box2, { marginTop: 1, flexDirection: "row", paddingRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Box2, { flexGrow: 1, flexShrink: 1, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
89525
90155
|
Text2,
|
|
89526
90156
|
{
|
|
89527
90157
|
backgroundColor: pending ? void 0 : theme.userBg,
|
|
@@ -89538,22 +90168,22 @@ function UserText({
|
|
|
89538
90168
|
}
|
|
89539
90169
|
|
|
89540
90170
|
// src/components/messages/UserCommand.tsx
|
|
89541
|
-
var
|
|
90171
|
+
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
89542
90172
|
function UserCommand({ name: name2, args: args2 }) {
|
|
89543
90173
|
const theme = useTheme();
|
|
89544
90174
|
const content = `/${[name2, args2].filter(Boolean).join(" ")}`;
|
|
89545
|
-
return /* @__PURE__ */ (0,
|
|
89546
|
-
/* @__PURE__ */ (0,
|
|
90175
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Box2, { marginTop: 1, flexDirection: "row", paddingRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Box2, { flexGrow: 1, flexShrink: 1, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Text2, { backgroundColor: theme.userBg, wrap: "wrap", children: [
|
|
90176
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Text2, { color: theme.dim, children: [
|
|
89547
90177
|
glyphs.user,
|
|
89548
90178
|
" "
|
|
89549
90179
|
] }),
|
|
89550
|
-
/* @__PURE__ */ (0,
|
|
90180
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text2, { color: theme.user, children: content })
|
|
89551
90181
|
] }) }) });
|
|
89552
90182
|
}
|
|
89553
90183
|
|
|
89554
90184
|
// src/components/markdown/Markdown.tsx
|
|
89555
90185
|
var import_react19 = __toESM(require_react(), 1);
|
|
89556
|
-
var
|
|
90186
|
+
var import_chalk5 = __toESM(require_source(), 1);
|
|
89557
90187
|
var import_strip_ansi3 = __toESM(require_strip_ansi(), 1);
|
|
89558
90188
|
var import_string_width2 = __toESM(require_string_width(), 1);
|
|
89559
90189
|
|
|
@@ -90797,7 +91427,7 @@ var Vt = b.parse;
|
|
|
90797
91427
|
var Yt = x.lex;
|
|
90798
91428
|
|
|
90799
91429
|
// src/components/markdown/format.ts
|
|
90800
|
-
var
|
|
91430
|
+
var import_chalk4 = __toESM(require_source(), 1);
|
|
90801
91431
|
var import_strip_ansi2 = __toESM(require_strip_ansi(), 1);
|
|
90802
91432
|
var import_string_width = __toESM(require_string_width(), 1);
|
|
90803
91433
|
|
|
@@ -104668,26 +105298,6 @@ function highlightCode(code, lang) {
|
|
|
104668
105298
|
return result;
|
|
104669
105299
|
}
|
|
104670
105300
|
|
|
104671
|
-
// src/components/design-system/GradientText.tsx
|
|
104672
|
-
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
104673
|
-
var GRAD_FROM = [183, 148, 246];
|
|
104674
|
-
var GRAD_TO = [230, 218, 252];
|
|
104675
|
-
var hex2 = (v2) => Math.max(0, Math.min(255, Math.round(v2))).toString(16).padStart(2, "0");
|
|
104676
|
-
function gradientAt(t) {
|
|
104677
|
-
const c3 = Math.max(0, Math.min(1, t));
|
|
104678
|
-
return `#${hex2(GRAD_FROM[0] + (GRAD_TO[0] - GRAD_FROM[0]) * c3)}${hex2(
|
|
104679
|
-
GRAD_FROM[1] + (GRAD_TO[1] - GRAD_FROM[1]) * c3
|
|
104680
|
-
)}${hex2(GRAD_FROM[2] + (GRAD_TO[2] - GRAD_FROM[2]) * c3)}`;
|
|
104681
|
-
}
|
|
104682
|
-
function GradientText({
|
|
104683
|
-
text,
|
|
104684
|
-
wrap: wrap2
|
|
104685
|
-
}) {
|
|
104686
|
-
const chars = [...text];
|
|
104687
|
-
const last = Math.max(1, chars.length - 1);
|
|
104688
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text2, { wrap: wrap2, children: chars.map((ch, i2) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text2, { color: gradientAt(i2 / last), children: ch }, i2)) });
|
|
104689
|
-
}
|
|
104690
|
-
|
|
104691
105301
|
// src/components/markdown/format.ts
|
|
104692
105302
|
var EOL = "\n";
|
|
104693
105303
|
var BLOCKQUOTE_BAR = "\u2502";
|
|
@@ -104700,13 +105310,13 @@ function configureMarked() {
|
|
|
104700
105310
|
function gradientHeading(text) {
|
|
104701
105311
|
const chars = [...text];
|
|
104702
105312
|
const last = Math.max(1, chars.length - 1);
|
|
104703
|
-
return chars.map((ch, i2) =>
|
|
105313
|
+
return chars.map((ch, i2) => import_chalk4.default.hex(gradientAt(i2 / last))(ch)).join("");
|
|
104704
105314
|
}
|
|
104705
105315
|
function highlightToAnsi(code, lang, theme) {
|
|
104706
105316
|
return highlightCode(code, lang).map(
|
|
104707
105317
|
(spans) => spans.map((s) => {
|
|
104708
105318
|
const c3 = synColor(theme, s.kind);
|
|
104709
|
-
return c3 ?
|
|
105319
|
+
return c3 ? import_chalk4.default.hex(c3)(s.text) : s.text;
|
|
104710
105320
|
}).join("")
|
|
104711
105321
|
).join(EOL);
|
|
104712
105322
|
}
|
|
@@ -104772,23 +105382,23 @@ function formatToken(token, theme, listDepth = 0, orderedListNumber = null, pare
|
|
|
104772
105382
|
switch (token.type) {
|
|
104773
105383
|
case "blockquote": {
|
|
104774
105384
|
const inner = kids(token);
|
|
104775
|
-
const bar =
|
|
104776
|
-
return inner.split(EOL).map((line) => (0, import_strip_ansi2.default)(line).trim() ? `${bar} ${
|
|
105385
|
+
const bar = import_chalk4.default.hex(theme.dim)(BLOCKQUOTE_BAR);
|
|
105386
|
+
return inner.split(EOL).map((line) => (0, import_strip_ansi2.default)(line).trim() ? `${bar} ${import_chalk4.default.italic(line)}` : line).join(EOL);
|
|
104777
105387
|
}
|
|
104778
105388
|
case "code": {
|
|
104779
105389
|
const t = token;
|
|
104780
105390
|
return highlightToAnsi(t.text, t.lang ?? "", theme) + EOL;
|
|
104781
105391
|
}
|
|
104782
105392
|
case "codespan":
|
|
104783
|
-
return
|
|
105393
|
+
return import_chalk4.default.hex(theme.assistant)(token.text);
|
|
104784
105394
|
case "em":
|
|
104785
|
-
return
|
|
105395
|
+
return import_chalk4.default.italic(kids(token, 0, null, parent));
|
|
104786
105396
|
case "strong":
|
|
104787
|
-
return
|
|
105397
|
+
return import_chalk4.default.bold(kids(token, 0, null, parent));
|
|
104788
105398
|
case "heading": {
|
|
104789
105399
|
const t = token;
|
|
104790
105400
|
const grad = gradientHeading((0, import_strip_ansi2.default)(kids(token)));
|
|
104791
|
-
const styled = t.depth === 1 ?
|
|
105401
|
+
const styled = t.depth === 1 ? import_chalk4.default.bold.italic.underline(grad) : import_chalk4.default.bold(grad);
|
|
104792
105402
|
return styled + EOL + EOL;
|
|
104793
105403
|
}
|
|
104794
105404
|
case "hr":
|
|
@@ -104798,7 +105408,7 @@ function formatToken(token, theme, listDepth = 0, orderedListNumber = null, pare
|
|
|
104798
105408
|
case "link": {
|
|
104799
105409
|
const t = token;
|
|
104800
105410
|
if (t.href.startsWith("mailto:")) return t.href.replace(/^mailto:/, "");
|
|
104801
|
-
const text =
|
|
105411
|
+
const text = import_chalk4.default.hex(theme.assistant).underline(kids(token, 0, null, token));
|
|
104802
105412
|
const plain = (0, import_strip_ansi2.default)(text);
|
|
104803
105413
|
return plain && plain !== t.href ? hyperlink(t.href, text) : hyperlink(t.href);
|
|
104804
105414
|
}
|
|
@@ -104897,7 +105507,7 @@ function MarkdownTable({ token, width }) {
|
|
|
104897
105507
|
borderBottom: false,
|
|
104898
105508
|
borderRight: last,
|
|
104899
105509
|
justifyContent: justify(token.align?.[i2], !!bold),
|
|
104900
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text2, { wrap: "wrap", children: bold ?
|
|
105510
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text2, { wrap: "wrap", children: bold ? import_chalk5.default.bold(ansi) : ansi })
|
|
104901
105511
|
},
|
|
104902
105512
|
i2
|
|
104903
105513
|
);
|
|
@@ -105615,7 +106225,7 @@ function QuotaWarning({ refusal }) {
|
|
|
105615
106225
|
|
|
105616
106226
|
// src/components/tools/SubAgentTree.tsx
|
|
105617
106227
|
var import_react22 = __toESM(require_react(), 1);
|
|
105618
|
-
var
|
|
106228
|
+
var import_client_core24 = __toESM(require_dist(), 1);
|
|
105619
106229
|
var import_client_ui_core8 = __toESM(require_dist2(), 1);
|
|
105620
106230
|
var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
|
|
105621
106231
|
function agentLabel(agent) {
|
|
@@ -105627,7 +106237,7 @@ var rowMeta = import_client_ui_core8.subagentRowMeta;
|
|
|
105627
106237
|
function rowStatus(agent) {
|
|
105628
106238
|
if (agent.phase === "finished") {
|
|
105629
106239
|
if (agent.status === "failed") return "Failed";
|
|
105630
|
-
const took = agent.endedAt ? ` (${(0,
|
|
106240
|
+
const took = agent.endedAt ? ` (${(0, import_client_core24.formatElapsed)(agent.endedAt - agent.startedAt)})` : "";
|
|
105631
106241
|
return `Done${took}`;
|
|
105632
106242
|
}
|
|
105633
106243
|
const last = agent.activity?.[agent.activity.length - 1];
|
|
@@ -105860,7 +106470,7 @@ function OrionRing() {
|
|
|
105860
106470
|
|
|
105861
106471
|
// src/services/version.ts
|
|
105862
106472
|
function tuiVersion() {
|
|
105863
|
-
return "0.1.
|
|
106473
|
+
return "0.1.20".length > 0 ? "0.1.20" : null;
|
|
105864
106474
|
}
|
|
105865
106475
|
|
|
105866
106476
|
// src/components/layout/WelcomeCard.tsx
|
|
@@ -106199,11 +106809,11 @@ function PlanCard({ plan }) {
|
|
|
106199
106809
|
|
|
106200
106810
|
// src/components/tools/SubAgentCard.tsx
|
|
106201
106811
|
var import_react29 = __toESM(require_react(), 1);
|
|
106202
|
-
var
|
|
106812
|
+
var import_client_core25 = __toESM(require_dist(), 1);
|
|
106203
106813
|
var import_client_ui_core10 = __toESM(require_dist2(), 1);
|
|
106204
106814
|
var import_jsx_runtime42 = __toESM(require_jsx_runtime(), 1);
|
|
106205
106815
|
function SubAgentCard({ agent, now: now2 }) {
|
|
106206
|
-
const elapsed = (0,
|
|
106816
|
+
const elapsed = (0, import_client_core25.formatElapsed)((now2 ?? Date.now()) - agent.startedAt);
|
|
106207
106817
|
const metrics = [elapsed, (0, import_client_ui_core10.subagentTokenLabel)(agent.contextTokens)].filter(Boolean).join(" \xB7 ");
|
|
106208
106818
|
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(Box2, { flexDirection: "row", children: [
|
|
106209
106819
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Box2, { flexShrink: 0, marginRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ThemedText, { colorKey: "dim", children: glyphs.subagent }) }),
|
|
@@ -106452,7 +107062,7 @@ function Autocomplete({
|
|
|
106452
107062
|
}
|
|
106453
107063
|
|
|
106454
107064
|
// src/components/input/ContextSuggestions.tsx
|
|
106455
|
-
var
|
|
107065
|
+
var import_client_core26 = __toESM(require_dist(), 1);
|
|
106456
107066
|
var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
|
|
106457
107067
|
var MAX_VISIBLE3 = 12;
|
|
106458
107068
|
function ContextSuggestions({
|
|
@@ -106488,12 +107098,13 @@ function ContextSuggestions({
|
|
|
106488
107098
|
] });
|
|
106489
107099
|
}
|
|
106490
107100
|
function mentionPrefix(value, cursor) {
|
|
106491
|
-
return (0,
|
|
107101
|
+
return (0, import_client_core26.findFileMentionQuery)(value, cursor)?.query ?? null;
|
|
106492
107102
|
}
|
|
106493
107103
|
|
|
106494
107104
|
// src/services/posture.ts
|
|
106495
107105
|
function postureOf(mode, permissionMode, fullyAutomatic = false) {
|
|
106496
107106
|
if (mode === "plan") return { label: `${glyphs.planMode} plan mode`, colorKey: "planMode" };
|
|
107107
|
+
if (mode === "duet") return { label: `${glyphs.planMode} duet mode`, colorKey: "duetMode" };
|
|
106497
107108
|
if (permissionMode === "full_access" && !fullyAutomatic)
|
|
106498
107109
|
return { label: `${glyphs.acceptEdits} accept edits`, colorKey: "autoAccept" };
|
|
106499
107110
|
return { label: "normal", colorKey: "accent" };
|
|
@@ -106617,7 +107228,7 @@ function pushEntry(entries, text, limit = HISTORY_LIMIT) {
|
|
|
106617
107228
|
}
|
|
106618
107229
|
|
|
106619
107230
|
// src/components/input/PromptInput.tsx
|
|
106620
|
-
var
|
|
107231
|
+
var import_client_core27 = __toESM(require_dist(), 1);
|
|
106621
107232
|
|
|
106622
107233
|
// src/keybindings/match.ts
|
|
106623
107234
|
function matchKeypress(input, key) {
|
|
@@ -107090,7 +107701,7 @@ function PromptInput({
|
|
|
107090
107701
|
(0, import_react30.useEffect)(() => () => notifyMenuRef.current?.(false), []);
|
|
107091
107702
|
(0, import_react30.useEffect)(() => {
|
|
107092
107703
|
for (const path13 of pickedMentions.current) {
|
|
107093
|
-
if (!value.includes(`${
|
|
107704
|
+
if (!value.includes(`${import_client_core27.FILE_MENTION_LEADER}${path13}`)) pickedMentions.current.delete(path13);
|
|
107094
107705
|
}
|
|
107095
107706
|
}, [value]);
|
|
107096
107707
|
(0, import_react30.useEffect)(() => {
|
|
@@ -107122,9 +107733,9 @@ function PromptInput({
|
|
|
107122
107733
|
const completeMenu = (idx) => {
|
|
107123
107734
|
if (menuFiles) {
|
|
107124
107735
|
const pick = fileSuggestions[Math.min(idx, fileSuggestions.length - 1)];
|
|
107125
|
-
const at2 = (0,
|
|
107736
|
+
const at2 = (0, import_client_core27.findFileMentionQuery)(value, cursor);
|
|
107126
107737
|
if (!at2) return;
|
|
107127
|
-
const next = (0,
|
|
107738
|
+
const next = (0, import_client_core27.insertFileMention)(value, at2, pick);
|
|
107128
107739
|
pickedMentions.current.add(pick);
|
|
107129
107740
|
setValue2(next.text);
|
|
107130
107741
|
setCursor(next.caret);
|
|
@@ -107454,7 +108065,7 @@ function PromptInput({
|
|
|
107454
108065
|
...pasteTokenRanges(value),
|
|
107455
108066
|
// A picked `@file` is a recognized token too, and wears the same colour — the
|
|
107456
108067
|
// IDE and the Power App paint theirs the same way.
|
|
107457
|
-
...(0,
|
|
108068
|
+
...(0, import_client_core27.scanFileMentionRanges)(value, pickedMentions.current)
|
|
107458
108069
|
].sort((a, b2) => a.start - b2.start);
|
|
107459
108070
|
const colored = (text, offset) => tokenRanges.length === 0 ? text : segmentSlice(text, offset, tokenRanges).map(
|
|
107460
108071
|
(seg2, i2) => seg2.token ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Text2, { color: SLASH_TOKEN_COLOR, children: seg2.text }, `${offset}-${i2}`) : seg2.text
|
|
@@ -107610,7 +108221,7 @@ function IndexIndicator({
|
|
|
107610
108221
|
}
|
|
107611
108222
|
|
|
107612
108223
|
// src/components/status/StatusBar.tsx
|
|
107613
|
-
var
|
|
108224
|
+
var import_client_core28 = __toESM(require_dist(), 1);
|
|
107614
108225
|
var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1);
|
|
107615
108226
|
var PERM_SHORT = {
|
|
107616
108227
|
read_only: "read-only",
|
|
@@ -107642,6 +108253,7 @@ function StatusBar({
|
|
|
107642
108253
|
const nodeFor = (seg2) => {
|
|
107643
108254
|
switch (seg2) {
|
|
107644
108255
|
case "model": {
|
|
108256
|
+
if (mode === "duet") return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, children: "Orion Hybrid" });
|
|
107645
108257
|
const showLvl = reasoning && reasoning.toLowerCase() !== "none";
|
|
107646
108258
|
const lvl = showLvl ? effortLabel(reasoning) : "";
|
|
107647
108259
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, children: displayModel(model, modelLabel) + (lvl ? ` ${lvl}` : "") });
|
|
@@ -107649,14 +108261,14 @@ function StatusBar({
|
|
|
107649
108261
|
case "provider":
|
|
107650
108262
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, children: providerLabel(provider) });
|
|
107651
108263
|
case "mode":
|
|
107652
|
-
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, children: mode.charAt(0).toUpperCase() + mode.slice(1) });
|
|
108264
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, children: mode === "duet" ? "Duet" : mode.charAt(0).toUpperCase() + mode.slice(1) });
|
|
107653
108265
|
case "perm":
|
|
107654
108266
|
case "permission":
|
|
107655
108267
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, children: PERM_SHORT[perm] ?? perm });
|
|
107656
108268
|
case "persona":
|
|
107657
108269
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, children: persona });
|
|
107658
108270
|
case "tier":
|
|
107659
|
-
return accountTier ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, children: (0,
|
|
108271
|
+
return accountTier ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, children: (0, import_client_core28.planLabel)(accountTier) }) : null;
|
|
107660
108272
|
case "workrun":
|
|
107661
108273
|
return workRun ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemedText, { dim: true, children: `graph ${workRun.phasesDone}/${workRun.phasesTotal}` }) : null;
|
|
107662
108274
|
case "cost":
|
|
@@ -107965,7 +108577,7 @@ function FeedbackPrompt({
|
|
|
107965
108577
|
var import_react35 = __toESM(require_react(), 1);
|
|
107966
108578
|
var import_client_ui_core13 = __toESM(require_dist2(), 1);
|
|
107967
108579
|
var import_client_ui_core14 = __toESM(require_dist2(), 1);
|
|
107968
|
-
var
|
|
108580
|
+
var import_client_core29 = __toESM(require_dist(), 1);
|
|
107969
108581
|
|
|
107970
108582
|
// src/components/dialogs/SelectList.tsx
|
|
107971
108583
|
var import_react34 = __toESM(require_react(), 1);
|
|
@@ -108047,12 +108659,18 @@ function SelectList({
|
|
|
108047
108659
|
view.slice(start2, end).map((o, vi) => {
|
|
108048
108660
|
const i2 = start2 + vi;
|
|
108049
108661
|
const ordinal = numbered && !o.separator ? `${selectable.indexOf(i2) + 1}. ` : "";
|
|
108050
|
-
return o.separator ? /* @__PURE__ */ (0, import_jsx_runtime52.
|
|
108662
|
+
return o.separator ? /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Box2, { marginTop: i2 > start2 ? 1 : 0, flexDirection: "row", children: [
|
|
108663
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { dim: true, bold: true, children: o.label }),
|
|
108664
|
+
o.accentSuffix ? (
|
|
108665
|
+
// The header's CURRENT value, in the same accent the active row wears.
|
|
108666
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ThemedText, { colorKey: "activeChoice", bold: true, children: o.accentSuffix })
|
|
108667
|
+
) : null
|
|
108668
|
+
] }, `sep-${i2}`) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Box2, { flexDirection: "row", marginRight: columns ? 3 : 0, children: i2 === safeIdx ? (
|
|
108051
108669
|
// Selected row: the slogan's purple→lavender gradient (matches the
|
|
108052
108670
|
// typing-/ menu); the hint rides the same ramp.
|
|
108053
108671
|
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(GradientText, { text: `\u276F ${ordinal}${o.label}${o.hint ? ` ${o.hint}` : ""}` })
|
|
108054
108672
|
) : /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
|
|
108055
|
-
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(ThemedText, { children: [
|
|
108673
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(ThemedText, { colorKey: o.accent ? "activeChoice" : void 0, children: [
|
|
108056
108674
|
" ",
|
|
108057
108675
|
ordinal,
|
|
108058
108676
|
o.label
|
|
@@ -108215,12 +108833,12 @@ function PermissionPrompt({
|
|
|
108215
108833
|
label: "Don't ask again for",
|
|
108216
108834
|
value: stage.draft,
|
|
108217
108835
|
error: (() => {
|
|
108218
|
-
const verdict = (0,
|
|
108836
|
+
const verdict = (0, import_client_core29.validateRule)(stage.draft);
|
|
108219
108837
|
return verdict.ok ? null : verdict.reason;
|
|
108220
108838
|
})(),
|
|
108221
108839
|
onChange: (draft) => setStage({ ...stage, draft }),
|
|
108222
108840
|
onSubmit: () => {
|
|
108223
|
-
if (!(0,
|
|
108841
|
+
if (!(0, import_client_core29.validateRule)(stage.draft).ok) return;
|
|
108224
108842
|
setStage({
|
|
108225
108843
|
kind: "pick-destination",
|
|
108226
108844
|
rule: stage.draft,
|
|
@@ -108808,7 +109426,7 @@ function EndpointsPanel({
|
|
|
108808
109426
|
|
|
108809
109427
|
// src/components/dialogs/PermissionRulesPanel.tsx
|
|
108810
109428
|
var import_react37 = __toESM(require_react(), 1);
|
|
108811
|
-
var
|
|
109429
|
+
var import_client_core30 = __toESM(require_dist(), 1);
|
|
108812
109430
|
var import_client_ui_core15 = __toESM(require_dist2(), 1);
|
|
108813
109431
|
var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
|
|
108814
109432
|
function PermissionRulesPanel({
|
|
@@ -108823,7 +109441,7 @@ function PermissionRulesPanel({
|
|
|
108823
109441
|
if (stage.kind === "add-rule") {
|
|
108824
109442
|
if (key.escape) return setStage({ kind: "list" });
|
|
108825
109443
|
if (key.return) {
|
|
108826
|
-
if ((0,
|
|
109444
|
+
if ((0, import_client_core30.validateRule)(stage.draft).ok) setStage({ kind: "add-behavior", rule: stage.draft });
|
|
108827
109445
|
return;
|
|
108828
109446
|
}
|
|
108829
109447
|
if (key.backspace || key.delete)
|
|
@@ -108835,7 +109453,7 @@ function PermissionRulesPanel({
|
|
|
108835
109453
|
if (input.toLowerCase() === "a") setStage({ kind: "add-rule", draft: "" });
|
|
108836
109454
|
});
|
|
108837
109455
|
if (stage.kind === "add-rule") {
|
|
108838
|
-
const verdict = (0,
|
|
109456
|
+
const verdict = (0, import_client_core30.validateRule)(stage.draft);
|
|
108839
109457
|
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
|
|
108840
109458
|
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { bold: true, children: "Add a permission rule" }),
|
|
108841
109459
|
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ThemedText, { colorKey: "toolArgs", children: `[ ${stage.draft}\u2588 ]` }),
|
|
@@ -108961,7 +109579,7 @@ function PlanApprovalPrompt({
|
|
|
108961
109579
|
|
|
108962
109580
|
// src/components/dialogs/WorkPlanApprovalPrompt.tsx
|
|
108963
109581
|
var import_react39 = __toESM(require_react(), 1);
|
|
108964
|
-
var
|
|
109582
|
+
var import_client_core31 = __toESM(require_dist(), 1);
|
|
108965
109583
|
var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
|
|
108966
109584
|
function WorkPlanApprovalPrompt({
|
|
108967
109585
|
pending,
|
|
@@ -108982,11 +109600,11 @@ function WorkPlanApprovalPrompt({
|
|
|
108982
109600
|
if (c3 === "y") onRespond(requestId, true);
|
|
108983
109601
|
else if (c3 === "n" || key.escape) onRespond(requestId, false);
|
|
108984
109602
|
});
|
|
108985
|
-
const worktreeCandidates = (0,
|
|
109603
|
+
const worktreeCandidates = (0, import_client_core31.planWorktreeCount)(plan);
|
|
108986
109604
|
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
|
|
108987
109605
|
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Box2, { flexDirection: "row", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { colorKey: "planMode", bold: true, children: "Work graph \u2014 run this plan in the background?" }) }),
|
|
108988
109606
|
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Box2, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { dim: true, children: plan.goal }) }),
|
|
108989
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Box2, { flexDirection: "column", marginTop: 1, marginLeft: 2, children: (0,
|
|
109607
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Box2, { flexDirection: "column", marginTop: 1, marginLeft: 2, children: (0, import_client_core31.planFlowLines)(plan).map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { colorKey: "planMode", children: line }, index)) }),
|
|
108990
109608
|
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Box2, { marginTop: 1, flexDirection: "column", children: plan.phases.map((phase) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(PhaseRow, { phase }, phase.id)) }),
|
|
108991
109609
|
worktreeCandidates > 0 && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Box2, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { dim: true, children: `${worktreeCandidates} isolated worktree${worktreeCandidates === 1 ? "" : "s"} will be created; changed ones are kept for review.` }) }),
|
|
108992
109610
|
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Box2, { marginTop: 1, flexDirection: "row", children: [
|
|
@@ -109002,8 +109620,8 @@ function PhaseRow({ phase }) {
|
|
|
109002
109620
|
const heading = phase.title && phase.title !== phase.id ? `${phase.id} \u2014 ${phase.title}` : phase.id;
|
|
109003
109621
|
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Box2, { flexDirection: "column", marginLeft: 2, marginTop: 1, children: [
|
|
109004
109622
|
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { bold: true, children: heading }),
|
|
109005
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Box2, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { dim: true, children: (0,
|
|
109006
|
-
phase.gate && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Box2, { marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { colorKey: "planMode", children: `gate: ${phase.gate.cmd}${(0,
|
|
109623
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Box2, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { dim: true, children: (0, import_client_core31.phaseTraits)(phase).join(" \xB7 ") }) }),
|
|
109624
|
+
phase.gate && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Box2, { marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ThemedText, { colorKey: "planMode", children: `gate: ${phase.gate.cmd}${(0, import_client_core31.gateRetrySuffix)(phase.gate)}` }) })
|
|
109007
109625
|
] });
|
|
109008
109626
|
}
|
|
109009
109627
|
|
|
@@ -109163,7 +109781,7 @@ function HooksBrowser({
|
|
|
109163
109781
|
|
|
109164
109782
|
// src/components/dialogs/PluginManager.tsx
|
|
109165
109783
|
var import_react41 = __toESM(require_react(), 1);
|
|
109166
|
-
var
|
|
109784
|
+
var import_client_core32 = __toESM(require_dist(), 1);
|
|
109167
109785
|
var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
|
|
109168
109786
|
function pluginId(p) {
|
|
109169
109787
|
return p.id ?? p.name ?? "";
|
|
@@ -109238,7 +109856,7 @@ function PluginManager({
|
|
|
109238
109856
|
{
|
|
109239
109857
|
dialog: {
|
|
109240
109858
|
kind: "confirm",
|
|
109241
|
-
title: `${
|
|
109859
|
+
title: `${import_client_core32.PLUGIN_TRUST_NOTICE}
|
|
109242
109860
|
|
|
109243
109861
|
Install "${view.id}" from "${view.catalog}" (${scope} scope)?`,
|
|
109244
109862
|
options: [],
|
|
@@ -109562,7 +110180,7 @@ function ModalFrame({ children }) {
|
|
|
109562
110180
|
}
|
|
109563
110181
|
|
|
109564
110182
|
// src/components/dialogs/UsageMetricsPanel.tsx
|
|
109565
|
-
var
|
|
110183
|
+
var import_client_core33 = __toESM(require_dist(), 1);
|
|
109566
110184
|
var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1);
|
|
109567
110185
|
function compactInt(value) {
|
|
109568
110186
|
if (value >= 1e6) return `${(value / 1e6).toFixed(1)}m`;
|
|
@@ -109577,7 +110195,7 @@ function tokenLine(s) {
|
|
|
109577
110195
|
`out ${compactInt(t.output_tokens ?? 0)}`,
|
|
109578
110196
|
`visible ${compactInt(t.visible_output_tokens ?? 0)}`,
|
|
109579
110197
|
`reason ${compactInt(t.reasoning_tokens ?? 0)}`,
|
|
109580
|
-
`cache ${compactInt((0,
|
|
110198
|
+
`cache ${compactInt((0, import_client_core33.cacheHitTokens)(t))}`,
|
|
109581
110199
|
// `read`/`write`, not `hit`: this is the cache READ share. A write-heavy turn reads 0% while
|
|
109582
110200
|
// still paying the 1.25x-2x write premium, so both rates are shown.
|
|
109583
110201
|
`read ${Math.round(s.cacheHitPercent)}%`,
|
|
@@ -109586,7 +110204,7 @@ function tokenLine(s) {
|
|
|
109586
110204
|
].join(" \xB7 ");
|
|
109587
110205
|
}
|
|
109588
110206
|
function topRows(group, limit = 4) {
|
|
109589
|
-
return Object.entries(group).sort((a, b2) => (0,
|
|
110207
|
+
return Object.entries(group).sort((a, b2) => (0, import_client_core33.meteredTokens)(b2[1].tokens) - (0, import_client_core33.meteredTokens)(a[1].tokens) || b2[1].calls - a[1].calls).slice(0, limit);
|
|
109590
110208
|
}
|
|
109591
110209
|
function topContextRows(group, limit = 5) {
|
|
109592
110210
|
return Object.entries(group).filter(([, value]) => value > 0).sort((a, b2) => b2[1] - a[1]).slice(0, limit);
|
|
@@ -109672,11 +110290,11 @@ function BreakdownRows({
|
|
|
109672
110290
|
}) {
|
|
109673
110291
|
const rows = topRows(group);
|
|
109674
110292
|
if (rows.length === 0) return null;
|
|
109675
|
-
const max = Math.max(...rows.map(([, item]) => (0,
|
|
110293
|
+
const max = Math.max(...rows.map(([, item]) => (0, import_client_core33.meteredTokens)(item.tokens)), 1);
|
|
109676
110294
|
return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
|
|
109677
110295
|
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(ThemedText, { bold: true, children: title }),
|
|
109678
110296
|
rows.map(([key, item], index) => {
|
|
109679
|
-
const tokens = (0,
|
|
110297
|
+
const tokens = (0, import_client_core33.meteredTokens)(item.tokens);
|
|
109680
110298
|
return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(BarRow, { label: key, value: tokens, max, tone: index, children: [
|
|
109681
110299
|
item.calls,
|
|
109682
110300
|
" calls \xB7 in ",
|
|
@@ -109809,10 +110427,10 @@ function RecentTurns({ rows }) {
|
|
|
109809
110427
|
function DailyRows({ summary }) {
|
|
109810
110428
|
const rows = summary.daily.slice(-5);
|
|
109811
110429
|
if (rows.length === 0) return null;
|
|
109812
|
-
const max = Math.max(...rows.map((day) => (0,
|
|
110430
|
+
const max = Math.max(...rows.map((day) => (0, import_client_core33.meteredTokens)(day.tokens)), 1);
|
|
109813
110431
|
return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
|
|
109814
110432
|
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(ThemedText, { bold: true, children: "Daily history" }),
|
|
109815
|
-
rows.map((day, index) => /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(BarRow, { label: day.date, value: (0,
|
|
110433
|
+
rows.map((day, index) => /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(BarRow, { label: day.date, value: (0, import_client_core33.meteredTokens)(day.tokens), max, tone: index, children: [
|
|
109816
110434
|
day.calls,
|
|
109817
110435
|
" calls \xB7 in ",
|
|
109818
110436
|
compactInt(day.tokens.input_tokens ?? 0),
|
|
@@ -109962,7 +110580,7 @@ function PendingAttachments({ items: all }) {
|
|
|
109962
110580
|
}
|
|
109963
110581
|
|
|
109964
110582
|
// src/components/layout/ReplFooter.tsx
|
|
109965
|
-
var
|
|
110583
|
+
var import_client_core34 = __toESM(require_dist(), 1);
|
|
109966
110584
|
var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
|
|
109967
110585
|
function ReplFooter({
|
|
109968
110586
|
appStore,
|
|
@@ -110007,7 +110625,7 @@ function ReplFooter({
|
|
|
110007
110625
|
const indexPhase = useStoreSelector(appStore, (s) => s.indexPhase);
|
|
110008
110626
|
const indexBadgeText = useStoreSelector(
|
|
110009
110627
|
appStore,
|
|
110010
|
-
(s) => (0,
|
|
110628
|
+
(s) => (0, import_client_core34.formatIndexBadge)({
|
|
110011
110629
|
mode: s.indexMode,
|
|
110012
110630
|
phase: s.indexPhase,
|
|
110013
110631
|
percent: s.indexPercent,
|
|
@@ -110199,7 +110817,7 @@ function FullscreenLayout({
|
|
|
110199
110817
|
|
|
110200
110818
|
// src/components/dialogs/AgentsDashboard.tsx
|
|
110201
110819
|
var import_react47 = __toESM(require_react(), 1);
|
|
110202
|
-
var
|
|
110820
|
+
var import_client_core35 = __toESM(require_dist(), 1);
|
|
110203
110821
|
var import_client_ui_core17 = __toESM(require_dist2(), 1);
|
|
110204
110822
|
var import_strip_ansi4 = __toESM(require_strip_ansi(), 1);
|
|
110205
110823
|
var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -110316,11 +110934,11 @@ function AgentsDashboard({
|
|
|
110316
110934
|
setEvents((prev) => [...prev, ...fresh]);
|
|
110317
110935
|
}
|
|
110318
110936
|
setPollError(null);
|
|
110319
|
-
if (!(0,
|
|
110937
|
+
if (!(0, import_client_core35.isTerminal)(job.status)) timer = setTimeout(tick, POLL_MS);
|
|
110320
110938
|
} catch (e) {
|
|
110321
110939
|
if (cancelled) return;
|
|
110322
|
-
setPollError((0,
|
|
110323
|
-
if (latest && (0,
|
|
110940
|
+
setPollError((0, import_client_core35.formatMissionsError)(e));
|
|
110941
|
+
if (latest && (0, import_client_core35.isTerminal)(latest.status)) return;
|
|
110324
110942
|
timer = setTimeout(tick, POLL_MS);
|
|
110325
110943
|
}
|
|
110326
110944
|
};
|
|
@@ -110348,7 +110966,7 @@ function AgentsDashboard({
|
|
|
110348
110966
|
cancelled = true;
|
|
110349
110967
|
};
|
|
110350
110968
|
}, [detailId, branchName]);
|
|
110351
|
-
const liveSessionId = detailJob && !(0,
|
|
110969
|
+
const liveSessionId = detailJob && !(0, import_client_core35.isTerminal)(detailJob.status) && detailJob.session_id ? detailJob.session_id : null;
|
|
110352
110970
|
(0, import_react47.useEffect)(() => {
|
|
110353
110971
|
if (!liveSessionId) return;
|
|
110354
110972
|
liveIdRef.current = 0;
|
|
@@ -110357,16 +110975,16 @@ function AgentsDashboard({
|
|
|
110357
110975
|
setLiveFrames(0);
|
|
110358
110976
|
const nextId = () => liveIdRef.current += 1;
|
|
110359
110977
|
const sub = panelRef.current.watch(liveSessionId, (env3) => {
|
|
110360
|
-
if ((0,
|
|
110978
|
+
if ((0, import_client_core35.desktopFrameOf)(env3) !== null) {
|
|
110361
110979
|
setLiveFrames((n) => n + 1);
|
|
110362
110980
|
return;
|
|
110363
110981
|
}
|
|
110364
|
-
const chunk = (0,
|
|
110982
|
+
const chunk = (0, import_client_core35.terminalChunkOf)(env3);
|
|
110365
110983
|
if (chunk !== null) {
|
|
110366
|
-
setLiveTerm((tail) => (0,
|
|
110984
|
+
setLiveTerm((tail) => (0, import_client_core35.appendTerminalTail)(tail, (0, import_strip_ansi4.default)(chunk)));
|
|
110367
110985
|
return;
|
|
110368
110986
|
}
|
|
110369
|
-
setLiveItems((prev) => (0,
|
|
110987
|
+
setLiveItems((prev) => (0, import_client_core35.applyLiveThreadEvent)(prev, env3, nextId));
|
|
110370
110988
|
});
|
|
110371
110989
|
return () => sub.dispose();
|
|
110372
110990
|
}, [liveSessionId]);
|
|
@@ -110398,7 +111016,7 @@ function AgentsDashboard({
|
|
|
110398
111016
|
const runAction = (action) => {
|
|
110399
111017
|
setBusy(true);
|
|
110400
111018
|
setError(null);
|
|
110401
|
-
void action().catch((e) => setError((0,
|
|
111019
|
+
void action().catch((e) => setError((0, import_client_core35.formatMissionsError)(e))).finally(() => setBusy(false));
|
|
110402
111020
|
};
|
|
110403
111021
|
const submitMessage = (id) => {
|
|
110404
111022
|
const text = messageText.trim();
|
|
@@ -110414,7 +111032,7 @@ function AgentsDashboard({
|
|
|
110414
111032
|
setMessaging(false);
|
|
110415
111033
|
setMessageNote("Follow-up started.");
|
|
110416
111034
|
setScreen({ kind: "detail", id: created.job_id });
|
|
110417
|
-
}).catch((e) => setMessageNote((0,
|
|
111035
|
+
}).catch((e) => setMessageNote((0, import_client_core35.formatMissionsError)(e))).finally(() => setBusy(false));
|
|
110418
111036
|
return;
|
|
110419
111037
|
}
|
|
110420
111038
|
if (detailJob?.status === "needs_human_input") {
|
|
@@ -110424,7 +111042,7 @@ function AgentsDashboard({
|
|
|
110424
111042
|
setMessageText("");
|
|
110425
111043
|
setMessaging(false);
|
|
110426
111044
|
setMessageNote("Resumed.");
|
|
110427
|
-
}).catch((e) => setMessageNote((0,
|
|
111045
|
+
}).catch((e) => setMessageNote((0, import_client_core35.formatMissionsError)(e))).finally(() => setBusy(false));
|
|
110428
111046
|
return;
|
|
110429
111047
|
}
|
|
110430
111048
|
if (!text) {
|
|
@@ -110437,7 +111055,7 @@ function AgentsDashboard({
|
|
|
110437
111055
|
setMessageText("");
|
|
110438
111056
|
setMessaging(false);
|
|
110439
111057
|
setMessageNote(res.delivered ? "Sent to the agent." : "Queued for the next phase.");
|
|
110440
|
-
}).catch((e) => setMessageNote((0,
|
|
111058
|
+
}).catch((e) => setMessageNote((0, import_client_core35.formatMissionsError)(e))).finally(() => setBusy(false));
|
|
110441
111059
|
};
|
|
110442
111060
|
const tokenHost = tokenStatus?.host || "github.com";
|
|
110443
111061
|
const startConnect = () => {
|
|
@@ -110518,7 +111136,7 @@ function AgentsDashboard({
|
|
|
110518
111136
|
setTokenInput(false);
|
|
110519
111137
|
setTokenDraft("");
|
|
110520
111138
|
setTokenNote("Token saved.");
|
|
110521
|
-
}).catch((e) => setTokenNote((0,
|
|
111139
|
+
}).catch((e) => setTokenNote((0, import_client_core35.formatMissionsError)(e))).finally(() => setTokenBusy(false));
|
|
110522
111140
|
};
|
|
110523
111141
|
const submitJiraStep = () => {
|
|
110524
111142
|
if (!jiraInput) return;
|
|
@@ -110547,7 +111165,7 @@ function AgentsDashboard({
|
|
|
110547
111165
|
);
|
|
110548
111166
|
setJiraInput(null);
|
|
110549
111167
|
setJiraNote("Jira connected \u2014 the launch form's Ticket field is live.");
|
|
110550
|
-
}).catch((e) => setJiraNote((0,
|
|
111168
|
+
}).catch((e) => setJiraNote((0, import_client_core35.formatMissionsError)(e))).finally(() => setJiraBusy(false));
|
|
110551
111169
|
};
|
|
110552
111170
|
const removeJira = () => {
|
|
110553
111171
|
if (jiraBusy) return;
|
|
@@ -110556,7 +111174,7 @@ function AgentsDashboard({
|
|
|
110556
111174
|
void panel.clearTicketConnection().then(() => {
|
|
110557
111175
|
setJiraStatus((p) => p ? { ...p, configured: false, base_url: null, hint: null } : p);
|
|
110558
111176
|
setJiraNote("Jira connection removed.");
|
|
110559
|
-
}).catch((e) => setJiraNote((0,
|
|
111177
|
+
}).catch((e) => setJiraNote((0, import_client_core35.formatMissionsError)(e))).finally(() => setJiraBusy(false));
|
|
110560
111178
|
};
|
|
110561
111179
|
const removeToken = () => {
|
|
110562
111180
|
if (tokenBusy) return;
|
|
@@ -110565,7 +111183,7 @@ function AgentsDashboard({
|
|
|
110565
111183
|
void panel.clearToken().then(() => {
|
|
110566
111184
|
setTokenStatus((p) => p ? { ...p, configured: false, hint: null } : p);
|
|
110567
111185
|
setTokenNote("Token removed.");
|
|
110568
|
-
}).catch((e) => setTokenNote((0,
|
|
111186
|
+
}).catch((e) => setTokenNote((0, import_client_core35.formatMissionsError)(e))).finally(() => setTokenBusy(false));
|
|
110569
111187
|
};
|
|
110570
111188
|
const submitLaunch = () => {
|
|
110571
111189
|
const repo_url = form.repo_url.trim();
|
|
@@ -110585,7 +111203,7 @@ function AgentsDashboard({
|
|
|
110585
111203
|
setForm(EMPTY_FORM);
|
|
110586
111204
|
setField(0);
|
|
110587
111205
|
setScreen({ kind: "list" });
|
|
110588
|
-
}).catch((e) => setError((0,
|
|
111206
|
+
}).catch((e) => setError((0, import_client_core35.formatMissionsError)(e))).finally(() => setBusy(false));
|
|
110589
111207
|
};
|
|
110590
111208
|
use_input_default((input, key) => {
|
|
110591
111209
|
if (busy) return;
|
|
@@ -110624,14 +111242,14 @@ function AgentsDashboard({
|
|
|
110624
111242
|
return;
|
|
110625
111243
|
}
|
|
110626
111244
|
if (key.escape || input === "q") return setScreen({ kind: "list" });
|
|
110627
|
-
if (input === "m" && job && (!(0,
|
|
111245
|
+
if (input === "m" && job && (!(0, import_client_core35.isTerminal)(job.status) || job.status === "complete")) {
|
|
110628
111246
|
setMessageNote(null);
|
|
110629
111247
|
return setMessaging(true);
|
|
110630
111248
|
}
|
|
110631
|
-
if (input === "i" && job && !(0,
|
|
111249
|
+
if (input === "i" && job && !(0, import_client_core35.isTerminal)(job.status) && job.status !== "needs_human_input") {
|
|
110632
111250
|
return runAction(() => panel.interrupt(screen.id).then(() => void 0));
|
|
110633
111251
|
}
|
|
110634
|
-
if (input === "c" && job && !(0,
|
|
111252
|
+
if (input === "c" && job && !(0, import_client_core35.isTerminal)(job.status)) {
|
|
110635
111253
|
return runAction(() => panel.cancel(screen.id));
|
|
110636
111254
|
}
|
|
110637
111255
|
if (input === "r") return runAction(() => panel.refresh().then(() => void 0));
|
|
@@ -110704,7 +111322,7 @@ function AgentsDashboard({
|
|
|
110704
111322
|
setError(null);
|
|
110705
111323
|
return setScreen({ kind: "detail", id: here.id });
|
|
110706
111324
|
}
|
|
110707
|
-
if (input === "c" && !(0,
|
|
111325
|
+
if (input === "c" && !(0, import_client_core35.isTerminal)(here.status)) {
|
|
110708
111326
|
return runAction(() => panel.cancel(here.id));
|
|
110709
111327
|
}
|
|
110710
111328
|
});
|
|
@@ -110731,7 +111349,7 @@ function AgentsDashboard({
|
|
|
110731
111349
|
// point. This MUST match the `m`-key gate (which allows complete): if the
|
|
110732
111350
|
// key opens messaging but the render gate stays !isTerminal, the user types
|
|
110733
111351
|
// blind and errors never paint.
|
|
110734
|
-
live: !!(detailJob && (!(0,
|
|
111352
|
+
live: !!(detailJob && (!(0, import_client_core35.isTerminal)(detailJob.status) || detailJob.status === "complete")),
|
|
110735
111353
|
messaging,
|
|
110736
111354
|
text: messageText,
|
|
110737
111355
|
note: messageNote,
|
|
@@ -110783,10 +111401,10 @@ function footerHint(screen, job, messaging, conn) {
|
|
|
110783
111401
|
}
|
|
110784
111402
|
if (parked) return "m resume \xB7 c cancel \xB7 r refresh \xB7 q back";
|
|
110785
111403
|
if (job?.status === "complete") return "m follow-up \xB7 r refresh \xB7 q back";
|
|
110786
|
-
const steer = job && !(0,
|
|
111404
|
+
const steer = job && !(0, import_client_core35.isTerminal)(job.status) ? "m message \xB7 i interrupt \xB7 c cancel \xB7 " : "";
|
|
110787
111405
|
return `${steer}r refresh \xB7 q back`;
|
|
110788
111406
|
}
|
|
110789
|
-
const cancel = job && !(0,
|
|
111407
|
+
const cancel = job && !(0, import_client_core35.isTerminal)(job.status) ? "c cancel \xB7 " : "";
|
|
110790
111408
|
return `\u2191/\u2193 move \xB7 enter open \xB7 n new \xB7 s connections \xB7 ${cancel}r refresh \xB7 q close`;
|
|
110791
111409
|
}
|
|
110792
111410
|
function ConnectionsView({
|
|
@@ -110920,7 +111538,7 @@ function JobDetailView({
|
|
|
110920
111538
|
composer
|
|
110921
111539
|
}) {
|
|
110922
111540
|
if (!job) return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(ThemedText, { dim: true, children: "Job not found." });
|
|
110923
|
-
const terminal = (0,
|
|
111541
|
+
const terminal = (0, import_client_core35.isTerminal)(job.status);
|
|
110924
111542
|
return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(Box2, { flexDirection: "column", children: [
|
|
110925
111543
|
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: jobTitle(job) }),
|
|
110926
111544
|
/* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
|
|
@@ -111160,7 +111778,7 @@ function Root({
|
|
|
111160
111778
|
|
|
111161
111779
|
// src/components/layout/SignInScreen.tsx
|
|
111162
111780
|
var import_react51 = __toESM(require_react(), 1);
|
|
111163
|
-
var
|
|
111781
|
+
var import_client_core36 = __toESM(require_dist(), 1);
|
|
111164
111782
|
|
|
111165
111783
|
// src/components/layout/splash/Splash.tsx
|
|
111166
111784
|
var import_react50 = __toESM(require_react(), 1);
|
|
@@ -111546,7 +112164,7 @@ function SignInScreen({
|
|
|
111546
112164
|
setUrl(null);
|
|
111547
112165
|
setError(null);
|
|
111548
112166
|
try {
|
|
111549
|
-
await (0,
|
|
112167
|
+
await (0, import_client_core36.signInViaBrowser)(
|
|
111550
112168
|
session,
|
|
111551
112169
|
{ accountsUrl, accountsApiUrl, client: "tui" },
|
|
111552
112170
|
{
|
|
@@ -111655,16 +112273,16 @@ function SignInCard({
|
|
|
111655
112273
|
}
|
|
111656
112274
|
|
|
111657
112275
|
// src/services/presenceHost.ts
|
|
111658
|
-
var
|
|
112276
|
+
var import_client_core37 = __toESM(require_dist(), 1);
|
|
111659
112277
|
function startTuiPresence(opts) {
|
|
111660
|
-
const registry = opts.registry ?? new
|
|
112278
|
+
const registry = opts.registry ?? new import_client_core37.PresenceRegistry({ clientType: "tui" });
|
|
111661
112279
|
let currentSid = null;
|
|
111662
112280
|
let lastStatus = "idle";
|
|
111663
112281
|
const statusFromApp = (s) => s.pendingPermissions.length > 0 ? "waiting" : s.status === "streaming" ? "busy" : "idle";
|
|
111664
112282
|
const stampGit = () => {
|
|
111665
112283
|
if (!opts.workspaceRoot || !currentSid) return;
|
|
111666
112284
|
const sid = currentSid;
|
|
111667
|
-
void (0,
|
|
112285
|
+
void (0, import_client_core37.getGitInfo)(opts.workspaceRoot).then((info2) => {
|
|
111668
112286
|
if (sid !== currentSid) return;
|
|
111669
112287
|
registry.updateSession(sid, {
|
|
111670
112288
|
gitRoot: info2.gitRoot ?? void 0,
|
|
@@ -111700,11 +112318,11 @@ function startTuiPresence(opts) {
|
|
|
111700
112318
|
ownSessionId: currentSid ?? void 0,
|
|
111701
112319
|
fresh: true
|
|
111702
112320
|
});
|
|
111703
|
-
return peers.map((p) => `${(0,
|
|
112321
|
+
return peers.map((p) => `${(0, import_client_core37.describePeer)(p)} \u2014 ${p.session.status}`);
|
|
111704
112322
|
},
|
|
111705
112323
|
async liveElsewhere(sessionId) {
|
|
111706
112324
|
const peer = await registry.isSessionLiveElsewhere(sessionId);
|
|
111707
|
-
return peer ? (0,
|
|
112325
|
+
return peer ? (0, import_client_core37.describePeer)(peer) : null;
|
|
111708
112326
|
},
|
|
111709
112327
|
dispose() {
|
|
111710
112328
|
unsubscribe();
|
|
@@ -111714,7 +112332,7 @@ function startTuiPresence(opts) {
|
|
|
111714
112332
|
}
|
|
111715
112333
|
|
|
111716
112334
|
// src/services/remoteControlHost.ts
|
|
111717
|
-
var
|
|
112335
|
+
var import_client_core38 = __toESM(require_dist(), 1);
|
|
111718
112336
|
import os5 from "os";
|
|
111719
112337
|
var REMOTE_DENIED = /* @__PURE__ */ new Set([
|
|
111720
112338
|
// Session/process-scoped.
|
|
@@ -111764,17 +112382,17 @@ function flattenInfoView(view) {
|
|
|
111764
112382
|
function startTuiRemoteControl(opts) {
|
|
111765
112383
|
let currentSid = null;
|
|
111766
112384
|
const stateFromApp = (s) => s.pendingPermissions.length > 0 || s.pendingPlanApproval !== null || s.pendingAskUser !== null ? "needs_you" : s.status === "streaming" ? "running" : "idle";
|
|
111767
|
-
const requireCurrent = (sessionId) => sessionId === currentSid ? null : (0,
|
|
112385
|
+
const requireCurrent = (sessionId) => sessionId === currentSid ? null : (0, import_client_core38.rcRefuse)("unknown_session", "this terminal is on a different session");
|
|
111768
112386
|
const deliverText = (text, attachments) => {
|
|
111769
112387
|
if (opts.appStore.getState().status === "streaming") {
|
|
111770
112388
|
if (attachments !== void 0 && attachments.length > 0) {
|
|
111771
|
-
return (0,
|
|
112389
|
+
return (0, import_client_core38.rcRefusePhotosMidTurn)();
|
|
111772
112390
|
}
|
|
111773
112391
|
opts.verbs.steer(text);
|
|
111774
|
-
return
|
|
112392
|
+
return import_client_core38.RC_OK;
|
|
111775
112393
|
}
|
|
111776
112394
|
const sent = attachments !== void 0 && attachments.length > 0 ? opts.verbs.send(text, attachments) : opts.verbs.send(text);
|
|
111777
|
-
return sent ?
|
|
112395
|
+
return sent ? import_client_core38.RC_OK : (0, import_client_core38.rcRefuse)("signed_out", "sign in on this machine first");
|
|
111778
112396
|
};
|
|
111779
112397
|
const commandCatalog = () => opts.commands === void 0 ? [] : opts.commands.registry.all().filter((command) => !REMOTE_DENIED.has(command.name)).map((command) => ({
|
|
111780
112398
|
name: command.name,
|
|
@@ -111783,15 +112401,15 @@ function startTuiRemoteControl(opts) {
|
|
|
111783
112401
|
}));
|
|
111784
112402
|
const runRemoteCommand = async (text) => {
|
|
111785
112403
|
const wired = opts.commands;
|
|
111786
|
-
if (wired === void 0) return (0,
|
|
112404
|
+
if (wired === void 0) return (0, import_client_core38.rcRefuse)("unsupported", "commands are not wired");
|
|
111787
112405
|
const parsed = wired.registry.parse(text);
|
|
111788
|
-
if (parsed === null) return (0,
|
|
112406
|
+
if (parsed === null) return (0, import_client_core38.rcRefuse)("unsupported", "unknown command");
|
|
111789
112407
|
const { command, args: args2 } = parsed;
|
|
111790
112408
|
if (REMOTE_DENIED.has(command.name)) {
|
|
111791
|
-
return (0,
|
|
112409
|
+
return (0, import_client_core38.rcRefuse)("unsupported", "this command runs at the terminal only");
|
|
111792
112410
|
}
|
|
111793
112411
|
if (REMOTE_ARG_REQUIRED.has(command.name) && args2.trim() === "") {
|
|
111794
|
-
return (0,
|
|
112412
|
+
return (0, import_client_core38.rcRefuse)(
|
|
111795
112413
|
"unsupported",
|
|
111796
112414
|
`add a value: /${command.name} ${command.argumentHint ?? "<value>"}`
|
|
111797
112415
|
);
|
|
@@ -111817,11 +112435,11 @@ function startTuiRemoteControl(opts) {
|
|
|
111817
112435
|
try {
|
|
111818
112436
|
await command.run(args2, ctx);
|
|
111819
112437
|
} catch (error) {
|
|
111820
|
-
return (0,
|
|
112438
|
+
return (0, import_client_core38.rcRefuse)("internal", error instanceof Error ? error.message : String(error));
|
|
111821
112439
|
}
|
|
111822
112440
|
return { ok: true, ...lines.length > 0 ? { output: lines.join("\n") } : {} };
|
|
111823
112441
|
};
|
|
111824
|
-
const host = (0,
|
|
112442
|
+
const host = (0, import_client_core38.createRemoteControlHost)({
|
|
111825
112443
|
clientType: "tui",
|
|
111826
112444
|
bridge: opts.bridge,
|
|
111827
112445
|
machineId: os5.hostname(),
|
|
@@ -111853,18 +112471,18 @@ function startTuiRemoteControl(opts) {
|
|
|
111853
112471
|
const refusal = requireCurrent(sessionId);
|
|
111854
112472
|
if (refusal) return refusal;
|
|
111855
112473
|
opts.verbs.deliverAgentMessage(message);
|
|
111856
|
-
return
|
|
112474
|
+
return import_client_core38.RC_OK;
|
|
111857
112475
|
},
|
|
111858
112476
|
resolvePermission: (sessionId, requestId, decision) => {
|
|
111859
112477
|
const refusal = requireCurrent(sessionId);
|
|
111860
112478
|
if (refusal) return refusal;
|
|
111861
|
-
return opts.verbs.resolvePermission(requestId, decision, sessionId) ?
|
|
112479
|
+
return opts.verbs.resolvePermission(requestId, decision, sessionId) ? import_client_core38.RC_OK : (0, import_client_core38.rcRefuse)("no_pending_permission", "that prompt was already answered");
|
|
111862
112480
|
},
|
|
111863
112481
|
interrupt: (sessionId) => {
|
|
111864
112482
|
const refusal = requireCurrent(sessionId);
|
|
111865
112483
|
if (refusal) return refusal;
|
|
111866
112484
|
opts.verbs.interrupt();
|
|
111867
|
-
return
|
|
112485
|
+
return import_client_core38.RC_OK;
|
|
111868
112486
|
},
|
|
111869
112487
|
runCommand: (sessionId, text) => {
|
|
111870
112488
|
const refusal = requireCurrent(sessionId);
|
|
@@ -111876,14 +112494,14 @@ function startTuiRemoteControl(opts) {
|
|
|
111876
112494
|
if (refusal) return refusal;
|
|
111877
112495
|
const ok2 = await opts.verbs.setModel(
|
|
111878
112496
|
model,
|
|
111879
|
-
effort === void 0 ? void 0 : (0,
|
|
112497
|
+
effort === void 0 ? void 0 : (0, import_client_core38.rcEffortToLocal)(effort)
|
|
111880
112498
|
);
|
|
111881
|
-
return ok2 ?
|
|
112499
|
+
return ok2 ? import_client_core38.RC_OK : (0, import_client_core38.rcRefuse)("internal", "couldn't switch the model");
|
|
111882
112500
|
},
|
|
111883
112501
|
setMode: (sessionId, mode) => {
|
|
111884
112502
|
const refusal = requireCurrent(sessionId);
|
|
111885
112503
|
if (refusal) return refusal;
|
|
111886
|
-
return opts.verbs.setMode(mode) ?
|
|
112504
|
+
return opts.verbs.setMode(mode) ? import_client_core38.RC_OK : (0, import_client_core38.rcRefuse)("internal", "couldn't switch permissions");
|
|
111887
112505
|
},
|
|
111888
112506
|
committedMessages: (sessionId) => sessionId === currentSid ? opts.committedMessages() : [],
|
|
111889
112507
|
// Cards parked before anyone was watching: replayed at the end of an attach
|
|
@@ -111894,7 +112512,7 @@ function startTuiRemoteControl(opts) {
|
|
|
111894
112512
|
const now2 = Date.now() / 1e3;
|
|
111895
112513
|
return [
|
|
111896
112514
|
...app.pendingPermissions.map(
|
|
111897
|
-
(parked) => (0,
|
|
112515
|
+
(parked) => (0, import_client_core38.parkedPermissionEvent)(
|
|
111898
112516
|
sessionId,
|
|
111899
112517
|
{
|
|
111900
112518
|
requestId: parked.data.request_id,
|
|
@@ -111909,7 +112527,7 @@ function startTuiRemoteControl(opts) {
|
|
|
111909
112527
|
// The other two parked-decision cards ride the backfill tail the same way —
|
|
111910
112528
|
// a phone arriving mid-plan (or mid-question) has something to answer.
|
|
111911
112529
|
...app.pendingPlanApproval !== null ? [
|
|
111912
|
-
(0,
|
|
112530
|
+
(0, import_client_core38.parkedPlanApprovalEvent)(
|
|
111913
112531
|
sessionId,
|
|
111914
112532
|
{
|
|
111915
112533
|
requestId: app.pendingPlanApproval.requestId,
|
|
@@ -111919,7 +112537,7 @@ function startTuiRemoteControl(opts) {
|
|
|
111919
112537
|
)
|
|
111920
112538
|
] : [],
|
|
111921
112539
|
...app.pendingAskUser !== null ? [
|
|
111922
|
-
(0,
|
|
112540
|
+
(0, import_client_core38.parkedAskUserEvent)(
|
|
111923
112541
|
sessionId,
|
|
111924
112542
|
{
|
|
111925
112543
|
requestId: app.pendingAskUser.requestId,
|
|
@@ -111933,7 +112551,7 @@ function startTuiRemoteControl(opts) {
|
|
|
111933
112551
|
resolvePlanApproval: (sessionId, requestId, approved) => {
|
|
111934
112552
|
const refusal = requireCurrent(sessionId);
|
|
111935
112553
|
if (refusal) return refusal;
|
|
111936
|
-
return opts.verbs.resolvePlanApproval(requestId, approved, sessionId) ?
|
|
112554
|
+
return opts.verbs.resolvePlanApproval(requestId, approved, sessionId) ? import_client_core38.RC_OK : (0, import_client_core38.rcRefuse)("no_pending_permission", "that plan was already answered");
|
|
111937
112555
|
},
|
|
111938
112556
|
answerQuestions: (sessionId, requestId, answers) => {
|
|
111939
112557
|
const refusal = requireCurrent(sessionId);
|
|
@@ -111942,7 +112560,7 @@ function startTuiRemoteControl(opts) {
|
|
|
111942
112560
|
requestId,
|
|
111943
112561
|
answers,
|
|
111944
112562
|
sessionId
|
|
111945
|
-
) ?
|
|
112563
|
+
) ? import_client_core38.RC_OK : (0, import_client_core38.rcRefuse)("no_pending_permission", "those questions were already answered");
|
|
111946
112564
|
}
|
|
111947
112565
|
}
|
|
111948
112566
|
});
|
|
@@ -111967,7 +112585,7 @@ function startTuiRemoteControl(opts) {
|
|
|
111967
112585
|
host.updateSession(currentSid, {
|
|
111968
112586
|
...model !== void 0 ? { model } : {},
|
|
111969
112587
|
mode: app.permissionMode,
|
|
111970
|
-
effort: (0,
|
|
112588
|
+
effort: (0, import_client_core38.rcEffortToWire)(app.reasoning)
|
|
111971
112589
|
});
|
|
111972
112590
|
}
|
|
111973
112591
|
const next = stateFromApp(app);
|
|
@@ -112001,7 +112619,7 @@ function startTuiRemoteControl(opts) {
|
|
|
112001
112619
|
...app.sessionTitle !== "" ? { title: app.sessionTitle } : {},
|
|
112002
112620
|
...lastModel !== void 0 ? { model: lastModel } : {},
|
|
112003
112621
|
mode: lastMode,
|
|
112004
|
-
effort: (0,
|
|
112622
|
+
effort: (0, import_client_core38.rcEffortToWire)(lastEffort)
|
|
112005
112623
|
});
|
|
112006
112624
|
},
|
|
112007
112625
|
status: () => host.status(),
|
|
@@ -112042,19 +112660,19 @@ function appendHistory(text) {
|
|
|
112042
112660
|
}
|
|
112043
112661
|
|
|
112044
112662
|
// src/services/indexer.ts
|
|
112045
|
-
var
|
|
112663
|
+
var import_client_core40 = __toESM(require_dist(), 1);
|
|
112046
112664
|
|
|
112047
112665
|
// src/services/nodeFileSource.ts
|
|
112048
|
-
var
|
|
112666
|
+
var import_client_core39 = __toESM(require_dist(), 1);
|
|
112049
112667
|
|
|
112050
112668
|
// src/services/indexer.ts
|
|
112051
112669
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
112052
112670
|
import * as fs13 from "fs";
|
|
112053
112671
|
import * as path11 from "path";
|
|
112054
|
-
var INDEX_WATCH_INCLUDE = `**/*.{${
|
|
112055
|
-
var EXCLUDE = "{" + [...
|
|
112672
|
+
var INDEX_WATCH_INCLUDE = `**/*.{${import_client_core40.INDEX_FILE_EXTENSIONS.join(",")}}`;
|
|
112673
|
+
var EXCLUDE = "{" + [...import_client_core40.IGNORE_DIRS].map((d2) => `**/${d2}/**`).join(",") + "}";
|
|
112056
112674
|
function createIndexer(bridge, workspaceRoot, store, onStatus, onFileEvent, options = {}) {
|
|
112057
|
-
const fileSource = new
|
|
112675
|
+
const fileSource = new import_client_core39.NodeFileSource(workspaceRoot, {
|
|
112058
112676
|
watchInclude: INDEX_WATCH_INCLUDE,
|
|
112059
112677
|
watchExclude: EXCLUDE
|
|
112060
112678
|
});
|
|
@@ -112070,9 +112688,9 @@ function createIndexer(bridge, workspaceRoot, store, onStatus, onFileEvent, opti
|
|
|
112070
112688
|
setFileCount: (n) => onStatus?.("orion.index.files", n)
|
|
112071
112689
|
};
|
|
112072
112690
|
const workerScriptPath = options.workerScriptPath ?? bundledIndexWorkerPath();
|
|
112073
|
-
const controller = new
|
|
112074
|
-
initialMode: (0,
|
|
112075
|
-
create: (defer) => new
|
|
112691
|
+
const controller = new import_client_core40.IndexModeController({
|
|
112692
|
+
initialMode: (0, import_client_core40.normalizeIndexMode)(options.mode, "on"),
|
|
112693
|
+
create: (defer) => new import_client_core40.ProcessWorkspaceIndexer({
|
|
112076
112694
|
getRoot: () => workspaceRoot,
|
|
112077
112695
|
indexConfig,
|
|
112078
112696
|
progress,
|
|
@@ -112081,7 +112699,7 @@ function createIndexer(bridge, workspaceRoot, store, onStatus, onFileEvent, opti
|
|
|
112081
112699
|
rgPath: options.rgPath ?? null,
|
|
112082
112700
|
deferBuildUntilFirstQuery: defer,
|
|
112083
112701
|
fallback: {
|
|
112084
|
-
indexer: new
|
|
112702
|
+
indexer: new import_client_core40.WorkspaceIndexer(bridge, fileSource, indexConfig, progress, grammarDir, store),
|
|
112085
112703
|
reader: store
|
|
112086
112704
|
},
|
|
112087
112705
|
log: (message, error) => {
|
|
@@ -112090,7 +112708,7 @@ function createIndexer(bridge, workspaceRoot, store, onStatus, onFileEvent, opti
|
|
|
112090
112708
|
}
|
|
112091
112709
|
})
|
|
112092
112710
|
});
|
|
112093
|
-
const safety = (0,
|
|
112711
|
+
const safety = (0, import_client_core40.classifyWorkspaceRootForIndexing)(workspaceRoot);
|
|
112094
112712
|
if (!safety.safe) {
|
|
112095
112713
|
onStatus?.("orion.index.state", "idle");
|
|
112096
112714
|
onStatus?.("orion.index.percent", 0);
|
|
@@ -112229,7 +112847,7 @@ function shouldAutoApprove(fullyAutomatic, configAutoApprove) {
|
|
|
112229
112847
|
}
|
|
112230
112848
|
|
|
112231
112849
|
// src/headless/runHeadless.ts
|
|
112232
|
-
var
|
|
112850
|
+
var import_client_core41 = __toESM(require_dist(), 1);
|
|
112233
112851
|
var import_client_ui_core18 = __toESM(require_dist2(), 1);
|
|
112234
112852
|
import * as os6 from "os";
|
|
112235
112853
|
import { randomUUID } from "crypto";
|
|
@@ -112274,7 +112892,7 @@ function extractFinalAssistantText(data) {
|
|
|
112274
112892
|
}
|
|
112275
112893
|
async function runGoalLoop(deps2) {
|
|
112276
112894
|
let turns = 0;
|
|
112277
|
-
const runner = new
|
|
112895
|
+
const runner = new import_client_core41.GoalRunner({
|
|
112278
112896
|
// An explicit `--max-turns` overrides; without one this run takes the same default
|
|
112279
112897
|
// ceiling every other host does. An unattended fleet is the LAST place that should be
|
|
112280
112898
|
// the only caller running unbounded.
|
|
@@ -112292,7 +112910,7 @@ async function runHeadless(flags2) {
|
|
|
112292
112910
|
const config = loadConfig();
|
|
112293
112911
|
if (flags2.workspace) config.workspaceRoot = flags2.workspace;
|
|
112294
112912
|
const secrets = createSecretStore();
|
|
112295
|
-
const session = (0,
|
|
112913
|
+
const session = (0, import_client_core41.createAgentSession)(secrets, config);
|
|
112296
112914
|
const signedIn = await session.isSignedIn();
|
|
112297
112915
|
if (!signedIn && !process.env.ORION_AUTH_TOKEN) {
|
|
112298
112916
|
throw new Error(
|
|
@@ -112317,15 +112935,15 @@ async function runHeadless(flags2) {
|
|
|
112317
112935
|
reasoning: flags2.reasoning ?? ""
|
|
112318
112936
|
});
|
|
112319
112937
|
const authToken = async () => await session.currentAccessToken() ?? process.env.ORION_AUTH_TOKEN ?? null;
|
|
112320
|
-
const bridge = new
|
|
112938
|
+
const bridge = new import_client_core41.OrionBridge(
|
|
112321
112939
|
() => config.apiUrl,
|
|
112322
112940
|
authToken,
|
|
112323
|
-
|
|
112941
|
+
import_client_core41.nodeEmitterFactory,
|
|
112324
112942
|
() => session.refresh().then(() => true, () => false)
|
|
112325
112943
|
);
|
|
112326
|
-
const brain = (0,
|
|
112944
|
+
const brain = (0, import_client_core41.createHostBrain)({
|
|
112327
112945
|
topology: config.brainTopology,
|
|
112328
|
-
resolveBinary: () => (0,
|
|
112946
|
+
resolveBinary: () => (0, import_client_core41.resolveBrainBinary)({
|
|
112329
112947
|
configPath: config.brainPath,
|
|
112330
112948
|
env: process.env,
|
|
112331
112949
|
bundledCandidates: bundledBrainCandidates()
|
|
@@ -112336,19 +112954,19 @@ async function runHeadless(flags2) {
|
|
|
112336
112954
|
renewBearer: async () => await session.currentFreshAccessToken() ?? process.env.ORION_AUTH_TOKEN ?? null,
|
|
112337
112955
|
log: (message, error) => console.error(`[orion-brain] ${message}${error ? `: ${String(error)}` : ""}`)
|
|
112338
112956
|
});
|
|
112339
|
-
const turnTransport = (0,
|
|
112957
|
+
const turnTransport = (0, import_client_core41.createTurnTransport)({
|
|
112340
112958
|
mode: config.brain,
|
|
112341
112959
|
bridge,
|
|
112342
|
-
makeLocal: () => new
|
|
112960
|
+
makeLocal: () => new import_client_core41.LocalBrainTransport({
|
|
112343
112961
|
// Proactive freshness for the segment-holding bearer (the interactive TUI's twin).
|
|
112344
112962
|
authToken: async () => await session.currentFreshAccessToken() ?? process.env.ORION_AUTH_TOKEN ?? null,
|
|
112345
112963
|
gatewayUrl: () => config.apiUrl,
|
|
112346
112964
|
connect: () => brain.connect()
|
|
112347
112965
|
})
|
|
112348
112966
|
});
|
|
112349
|
-
const codebaseIndexFallback = new
|
|
112350
|
-
const ripgrep = new
|
|
112351
|
-
bundledCandidates: () => (0,
|
|
112967
|
+
const codebaseIndexFallback = new import_client_core41.WorkspaceIndexStore();
|
|
112968
|
+
const ripgrep = new import_client_core41.NodeRipgrepLocator({
|
|
112969
|
+
bundledCandidates: () => (0, import_client_core41.vscodeRipgrepCandidates)((specifier) => __require.resolve(specifier))
|
|
112352
112970
|
});
|
|
112353
112971
|
const indexer = createIndexer(bridge, config.workspaceRoot, codebaseIndexFallback, void 0, void 0, {
|
|
112354
112972
|
rgPath: ripgrep.locate(),
|
|
@@ -112358,13 +112976,13 @@ async function runHeadless(flags2) {
|
|
|
112358
112976
|
mode: "on-demand"
|
|
112359
112977
|
});
|
|
112360
112978
|
void indexer.start().catch(() => void 0);
|
|
112361
|
-
const permissionStore = new
|
|
112979
|
+
const permissionStore = new import_client_core41.PermissionSettingsStore({ workspaceRoot: config.workspaceRoot });
|
|
112362
112980
|
await permissionStore.load();
|
|
112363
|
-
const executor = new
|
|
112981
|
+
const executor = new import_client_core41.ToolExecutor(
|
|
112364
112982
|
() => config.workspaceRoot,
|
|
112365
112983
|
() => appStore.getState().permissionMode,
|
|
112366
112984
|
secrets,
|
|
112367
|
-
new
|
|
112985
|
+
new import_client_core41.NullLspProvider(),
|
|
112368
112986
|
ripgrep,
|
|
112369
112987
|
nullFrameSinkFactory,
|
|
112370
112988
|
fallbackBrowserConfig,
|
|
@@ -112387,7 +113005,7 @@ async function runHeadless(flags2) {
|
|
|
112387
113005
|
workspaceRoot: config.workspaceRoot,
|
|
112388
113006
|
homeDir: os6.homedir()
|
|
112389
113007
|
});
|
|
112390
|
-
const sandboxAvailable = (0,
|
|
113008
|
+
const sandboxAvailable = (0, import_client_core41.probeSandboxAvailable)();
|
|
112391
113009
|
await (0, import_client_core8.refreshEndpointRouting)(appStore.getState().provider, {
|
|
112392
113010
|
workspaceRoot: config.workspaceRoot
|
|
112393
113011
|
});
|
|
@@ -112421,7 +113039,7 @@ async function runHeadless(flags2) {
|
|
|
112421
113039
|
const onEvent = (ev) => {
|
|
112422
113040
|
lastEvent = ev;
|
|
112423
113041
|
};
|
|
112424
|
-
const outcome = await (0,
|
|
113042
|
+
const outcome = await (0, import_client_core41.driveTurn)(
|
|
112425
113043
|
turnTransport,
|
|
112426
113044
|
{
|
|
112427
113045
|
sessionId,
|
|
@@ -112431,7 +113049,7 @@ async function runHeadless(flags2) {
|
|
|
112431
113049
|
routing: routing(),
|
|
112432
113050
|
clientCapabilities: [],
|
|
112433
113051
|
drainQueuedInput: () => [],
|
|
112434
|
-
getOrionResources: () => (0,
|
|
113052
|
+
getOrionResources: () => (0, import_client_core41.buildOrionSnapshot)(config.workspaceRoot, void 0, sessionId),
|
|
112435
113053
|
getFileHistoryManifest: () => executor.fileHistoryManifest(sessionId)
|
|
112436
113054
|
},
|
|
112437
113055
|
{
|
|
@@ -112463,7 +113081,7 @@ async function runHeadless(flags2) {
|
|
|
112463
113081
|
}
|
|
112464
113082
|
|
|
112465
113083
|
// src/services/feedbackGate.ts
|
|
112466
|
-
var
|
|
113084
|
+
var import_client_core42 = __toESM(require_dist(), 1);
|
|
112467
113085
|
var import_client_ui_core19 = __toESM(require_dist2(), 1);
|
|
112468
113086
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
112469
113087
|
var TuiFeedbackGate = class {
|
|
@@ -112513,7 +113131,7 @@ var TuiFeedbackGate = class {
|
|
|
112513
113131
|
model: routing.model,
|
|
112514
113132
|
provider: routing.provider
|
|
112515
113133
|
});
|
|
112516
|
-
void (0,
|
|
113134
|
+
void (0, import_client_core42.sendFeedbackImpression)(this.deps.submit, "shown", "tui");
|
|
112517
113135
|
}
|
|
112518
113136
|
/** The user rated. Snapshot the transcript SYNCHRONOUSLY (before any await), then
|
|
112519
113137
|
* scrub + assemble + send off the interactive path. Idempotent per requestId. */
|
|
@@ -112536,8 +113154,8 @@ var TuiFeedbackGate = class {
|
|
|
112536
113154
|
model: meta.model,
|
|
112537
113155
|
provider: meta.provider
|
|
112538
113156
|
});
|
|
112539
|
-
const { conversation, truncated } = (0,
|
|
112540
|
-
void (0,
|
|
113157
|
+
const { conversation, truncated } = (0, import_client_core42.scrubFeedbackConversation)(snapshot);
|
|
113158
|
+
void (0, import_client_core42.sendFeedbackSubmission)(this.deps.submit, {
|
|
112541
113159
|
...body2,
|
|
112542
113160
|
conversation,
|
|
112543
113161
|
conversation_truncated: truncated
|
|
@@ -112566,7 +113184,7 @@ var TuiFeedbackGate = class {
|
|
|
112566
113184
|
now2
|
|
112567
113185
|
);
|
|
112568
113186
|
this.safeSave((0, import_client_ui_core19.feedbackScalarsFromState)(state));
|
|
112569
|
-
void (0,
|
|
113187
|
+
void (0, import_client_core42.sendFeedbackImpression)(this.deps.submit, "dismissed", "tui");
|
|
112570
113188
|
}
|
|
112571
113189
|
return true;
|
|
112572
113190
|
}
|
|
@@ -112580,7 +113198,7 @@ var TuiFeedbackGate = class {
|
|
|
112580
113198
|
|
|
112581
113199
|
// src/main.tsx
|
|
112582
113200
|
var import_jsx_runtime77 = __toESM(require_jsx_runtime(), 1);
|
|
112583
|
-
var SANDBOX_AVAILABLE = (0,
|
|
113201
|
+
var SANDBOX_AVAILABLE = (0, import_client_core43.probeSandboxAvailable)();
|
|
112584
113202
|
async function main() {
|
|
112585
113203
|
let headlessFlags = null;
|
|
112586
113204
|
try {
|
|
@@ -112603,6 +113221,17 @@ async function main() {
|
|
|
112603
113221
|
let altScreen = { active: false, dispose: () => void 0 };
|
|
112604
113222
|
const firstRun = ensureConfigFile();
|
|
112605
113223
|
const config = loadConfig();
|
|
113224
|
+
let pendingDuetReplan = null;
|
|
113225
|
+
const beginDuetPhase = (text) => {
|
|
113226
|
+
const s = appStore.getState();
|
|
113227
|
+
if (s.mode !== "duet") return;
|
|
113228
|
+
const routed = (0, import_client_core44.willRouteToExecution)(s.duetPlan, text);
|
|
113229
|
+
if (routed) appStore.setState((st2) => ({ ...st2, duetExecutionStarted: true }));
|
|
113230
|
+
const escalated = routed && (s.duetPlan?.escalated ?? false);
|
|
113231
|
+
transcriptStore.setState(
|
|
113232
|
+
(st2) => appendNote(st2, duetPhaseNoteText(routed ? "executing" : "planning", { escalated }))
|
|
113233
|
+
);
|
|
113234
|
+
};
|
|
112606
113235
|
const bindings = loadBindings();
|
|
112607
113236
|
const flags2 = parseLaunchFlags(process.argv.slice(2));
|
|
112608
113237
|
const resumeId = flags2.resumeId;
|
|
@@ -112632,8 +113261,8 @@ async function main() {
|
|
|
112632
113261
|
}
|
|
112633
113262
|
});
|
|
112634
113263
|
void (0, import_client_core8.refreshEndpointRouting)(config.provider, { workspaceRoot: config.workspaceRoot });
|
|
112635
|
-
void (0,
|
|
112636
|
-
void (0,
|
|
113264
|
+
void (0, import_client_core44.prewarmInterimModels)(config.workspaceRoot);
|
|
113265
|
+
void (0, import_client_core44.prewarmRepoIdentity)(config.workspaceRoot);
|
|
112637
113266
|
const setSessionTitle = (title) => {
|
|
112638
113267
|
appStore.setState((s) => s.sessionTitle === title ? s : { ...s, sessionTitle: title });
|
|
112639
113268
|
};
|
|
@@ -112657,8 +113286,8 @@ async function main() {
|
|
|
112657
113286
|
}
|
|
112658
113287
|
});
|
|
112659
113288
|
const secrets = createSecretStore();
|
|
112660
|
-
const session = (0,
|
|
112661
|
-
const outcomes = new
|
|
113289
|
+
const session = (0, import_client_core44.createAgentSession)(secrets, config);
|
|
113290
|
+
const outcomes = new import_client_core44.OutcomeReporter({
|
|
112662
113291
|
apiBaseUrl: () => config.accountsApiUrl,
|
|
112663
113292
|
accessToken: () => session.currentAccessToken()
|
|
112664
113293
|
});
|
|
@@ -112710,10 +113339,10 @@ async function main() {
|
|
|
112710
113339
|
}
|
|
112711
113340
|
}
|
|
112712
113341
|
const authToken = async () => await session.currentAccessToken() ?? process.env.ORION_AUTH_TOKEN ?? null;
|
|
112713
|
-
const bridge = new
|
|
113342
|
+
const bridge = new import_client_core43.OrionBridge(
|
|
112714
113343
|
() => config.apiUrl,
|
|
112715
113344
|
authToken,
|
|
112716
|
-
|
|
113345
|
+
import_client_core44.nodeEmitterFactory,
|
|
112717
113346
|
// Seamless refresh: a 401 coalesces ONE refresh through the AgentSession (single-flight), so a
|
|
112718
113347
|
// token cycling mid-chat never logs the user out. `refreshAndSyncGate` also re-syncs the cached
|
|
112719
113348
|
// gate flag so a definitively-revoked session re-gates the chat cleanly (no stale "signed in").
|
|
@@ -112721,9 +113350,9 @@ async function main() {
|
|
|
112721
113350
|
);
|
|
112722
113351
|
let brainInstance;
|
|
112723
113352
|
const brain = () => {
|
|
112724
|
-
brainInstance ??= (0,
|
|
113353
|
+
brainInstance ??= (0, import_client_core44.createHostBrain)({
|
|
112725
113354
|
topology: config.brainTopology,
|
|
112726
|
-
resolveBinary: () => (0,
|
|
113355
|
+
resolveBinary: () => (0, import_client_core44.resolveBrainBinary)({
|
|
112727
113356
|
configPath: config.brainPath,
|
|
112728
113357
|
env: process.env,
|
|
112729
113358
|
bundledCandidates: bundledBrainCandidates()
|
|
@@ -112738,10 +113367,10 @@ async function main() {
|
|
|
112738
113367
|
});
|
|
112739
113368
|
return brainInstance;
|
|
112740
113369
|
};
|
|
112741
|
-
const turnTransport = (0,
|
|
113370
|
+
const turnTransport = (0, import_client_core44.createTurnTransport)({
|
|
112742
113371
|
mode: config.brain,
|
|
112743
113372
|
bridge,
|
|
112744
|
-
makeLocal: () => new
|
|
113373
|
+
makeLocal: () => new import_client_core44.LocalBrainTransport({
|
|
112745
113374
|
// Proactive freshness: the brain holds this bearer for a whole segment and cannot
|
|
112746
113375
|
// ride the bridge's reactive 401-refresh — so validate-or-refresh before hand-off.
|
|
112747
113376
|
authToken: async () => await session.currentFreshAccessToken() ?? process.env.ORION_AUTH_TOKEN ?? null,
|
|
@@ -112749,14 +113378,14 @@ async function main() {
|
|
|
112749
113378
|
connect: () => brain().connect()
|
|
112750
113379
|
})
|
|
112751
113380
|
});
|
|
112752
|
-
const codebaseIndexFallback = new
|
|
112753
|
-
const ripgrep = new
|
|
113381
|
+
const codebaseIndexFallback = new import_client_core43.WorkspaceIndexStore();
|
|
113382
|
+
const ripgrep = new import_client_core44.NodeRipgrepLocator({
|
|
112754
113383
|
// Bundled-first rg: ships as an optionalDependency of this package, so an
|
|
112755
113384
|
// `npm i -g` user gets fast search with nothing else installed. Resolved
|
|
112756
113385
|
// from THIS package's node_modules via require.resolve (nested and hoisted
|
|
112757
113386
|
// layouts both work); absent (install offline / postinstall failed) → the
|
|
112758
113387
|
// locator falls through to PATH + well-known paths exactly as before.
|
|
112759
|
-
bundledCandidates: () => (0,
|
|
113388
|
+
bundledCandidates: () => (0, import_client_core44.vscodeRipgrepCandidates)((specifier) => __require.resolve(specifier))
|
|
112760
113389
|
});
|
|
112761
113390
|
const indexer = createIndexer(
|
|
112762
113391
|
bridge,
|
|
@@ -112788,21 +113417,21 @@ async function main() {
|
|
|
112788
113417
|
);
|
|
112789
113418
|
void indexer.start().catch(() => void 0);
|
|
112790
113419
|
initIndexModeService({ appStore, setMode: (m2) => indexer.setMode(m2) });
|
|
112791
|
-
const permissionStore = new
|
|
113420
|
+
const permissionStore = new import_client_core44.PermissionSettingsStore({ workspaceRoot: config.workspaceRoot });
|
|
112792
113421
|
await permissionStore.load();
|
|
112793
|
-
const executor = new
|
|
113422
|
+
const executor = new import_client_core43.ToolExecutor(
|
|
112794
113423
|
() => config.workspaceRoot,
|
|
112795
113424
|
// The session's EFFECTIVE mode — the same turbo⇒full_access law the wire rides
|
|
112796
113425
|
// (`currentRouting`), never the bare store mode: the executor's membership
|
|
112797
113426
|
// backstop must agree with the gate that already ruled on each call. Loop-run
|
|
112798
113427
|
// sessions never enable turbo on the bridge, so they keep the configured mode
|
|
112799
113428
|
// their own wire rides.
|
|
112800
|
-
(sessionId2) => (0,
|
|
113429
|
+
(sessionId2) => (0, import_client_core44.effectiveWirePermissionMode)(
|
|
112801
113430
|
sessionId2 !== void 0 && bridge.isTurboModeEnabledForSession(sessionId2),
|
|
112802
113431
|
appStore.getState().permissionMode
|
|
112803
113432
|
),
|
|
112804
113433
|
secrets,
|
|
112805
|
-
new
|
|
113434
|
+
new import_client_core44.NullLspProvider(),
|
|
112806
113435
|
ripgrep,
|
|
112807
113436
|
nullFrameSinkFactory,
|
|
112808
113437
|
fallbackBrowserConfig,
|
|
@@ -112925,11 +113554,11 @@ async function main() {
|
|
|
112925
113554
|
}
|
|
112926
113555
|
renderLane(transcriptStore, appStore, ev);
|
|
112927
113556
|
if (ev.event === "usage_recorded") {
|
|
112928
|
-
(0,
|
|
113557
|
+
(0, import_client_core43.recordTurnMetrics)({
|
|
112929
113558
|
app: "tui",
|
|
112930
113559
|
sessionId,
|
|
112931
113560
|
workspaceRoot: currentRouting().workspaceRoot,
|
|
112932
|
-
turn: (0,
|
|
113561
|
+
turn: (0, import_client_core43.turnMetricsFromUsageRecorded)(ev.data ?? {})
|
|
112933
113562
|
});
|
|
112934
113563
|
}
|
|
112935
113564
|
if (ev.event === "file_modified") {
|
|
@@ -112953,7 +113582,7 @@ async function main() {
|
|
|
112953
113582
|
sessionSub = bridge.onSessionEvent(sid, onSessionStreamEvent);
|
|
112954
113583
|
};
|
|
112955
113584
|
let goalRunner = null;
|
|
112956
|
-
const cronController = new
|
|
113585
|
+
const cronController = new import_client_core44.CronController({
|
|
112957
113586
|
submitTurn: (prompt) => sendTurn(prompt, "\u27F3 scheduled", void 0, "system"),
|
|
112958
113587
|
isBusy: () => appStore.getState().status === "streaming",
|
|
112959
113588
|
persistence: fileCronPersistence(config.workspaceRoot)
|
|
@@ -113134,6 +113763,17 @@ async function main() {
|
|
|
113134
113763
|
);
|
|
113135
113764
|
}
|
|
113136
113765
|
});
|
|
113766
|
+
registry.register({
|
|
113767
|
+
name: "replan",
|
|
113768
|
+
description: "Duet: invalidate the standing plan (the next request runs the planner)",
|
|
113769
|
+
argumentHint: "",
|
|
113770
|
+
kind: "local",
|
|
113771
|
+
run: (_args, ctx) => {
|
|
113772
|
+
const flagged = (0, import_client_core44.invalidateStandingPlan)(ctx.appStore.getState().duetPlan);
|
|
113773
|
+
if (flagged) ctx.appStore.setState((s) => ({ ...s, duetPlan: flagged }));
|
|
113774
|
+
ctx.print((0, import_client_core44.duetReplanCommandNote)(flagged !== null));
|
|
113775
|
+
}
|
|
113776
|
+
});
|
|
113137
113777
|
const getCompletions = (input) => {
|
|
113138
113778
|
if (input.startsWith("/")) skillSlash.ensureFresh();
|
|
113139
113779
|
return registry.complete(input).map((c3) => ({
|
|
@@ -113149,8 +113789,8 @@ async function main() {
|
|
|
113149
113789
|
const anywhere = new Set(
|
|
113150
113790
|
registry.all().filter((c3) => c3.source === "skill").map((c3) => c3.name)
|
|
113151
113791
|
);
|
|
113152
|
-
const ranges = (0,
|
|
113153
|
-
const lead = (0,
|
|
113792
|
+
const ranges = (0, import_client_core44.scanSlashTokenRanges)(v2, anywhere);
|
|
113793
|
+
const lead = (0, import_client_core44.matchSlashToken)(v2);
|
|
113154
113794
|
if (lead && !anywhere.has(lead.name) && registry.get(lead.name)) {
|
|
113155
113795
|
const start2 = v2.indexOf("/");
|
|
113156
113796
|
ranges.unshift({ start: start2, end: start2 + lead.name.length + 1 });
|
|
@@ -113159,7 +113799,7 @@ async function main() {
|
|
|
113159
113799
|
return ranges;
|
|
113160
113800
|
};
|
|
113161
113801
|
let fileEntries = [];
|
|
113162
|
-
void new
|
|
113802
|
+
void new import_client_core39.NodeFileSource(config.workspaceRoot).findFiles("**/*", "{**/node_modules/**,**/.git/**,**/dist/**,**/build/**}", 5e3).then((abs) => {
|
|
113163
113803
|
fileEntries = withDirectories(
|
|
113164
113804
|
abs.map((p) => path12.relative(config.workspaceRoot, p).split(path12.sep).join("/"))
|
|
113165
113805
|
);
|
|
@@ -113186,7 +113826,7 @@ async function main() {
|
|
|
113186
113826
|
if (turn && streaming && !turn.cancelRequested && turn.phase === "stream") {
|
|
113187
113827
|
turn.cancelRequested = true;
|
|
113188
113828
|
outcomes.report({ kind: "cancel_context", kept_edits: turn.hadEdits });
|
|
113189
|
-
turn.disposeFallback = (0,
|
|
113829
|
+
turn.disposeFallback = (0, import_client_core44.armGracefulCancel)({
|
|
113190
113830
|
controller: turn.abort,
|
|
113191
113831
|
sendCancel: () => turnTransport.cancelTurn(turn.sessionId)
|
|
113192
113832
|
});
|
|
@@ -113214,6 +113854,9 @@ async function main() {
|
|
|
113214
113854
|
});
|
|
113215
113855
|
};
|
|
113216
113856
|
const boundary = createBoundaryHandlers({
|
|
113857
|
+
duetExecutingNote: () => {
|
|
113858
|
+
transcriptStore.setState((s) => appendNote(s, duetPhaseNoteText("executing")));
|
|
113859
|
+
},
|
|
113217
113860
|
bridge,
|
|
113218
113861
|
executor,
|
|
113219
113862
|
appStore,
|
|
@@ -113242,7 +113885,7 @@ async function main() {
|
|
|
113242
113885
|
};
|
|
113243
113886
|
const heldAgentReports = [];
|
|
113244
113887
|
let inboundPeerHop = null;
|
|
113245
|
-
const agentManager = new
|
|
113888
|
+
const agentManager = new import_client_core44.AgentManager((0, import_client_core44.brainAwareAgentTransport)(bridge, turnTransport), executor, async () => {
|
|
113246
113889
|
const result = await bridge.rpc("list_personas", {});
|
|
113247
113890
|
return result.personas ?? [];
|
|
113248
113891
|
});
|
|
@@ -113252,8 +113895,8 @@ async function main() {
|
|
|
113252
113895
|
agentManager.attachOutcomeSink((outcome) => {
|
|
113253
113896
|
oVaultSessions.for(outcome.parentSessionId, currentRouting().workspaceRoot)?.recordSiblingOutcome(outcome);
|
|
113254
113897
|
});
|
|
113255
|
-
void (0,
|
|
113256
|
-
const workGraphManager = new
|
|
113898
|
+
void (0, import_client_core44.loadAgentDefs)(config.workspaceRoot).then((defs) => agentManager.prime(defs));
|
|
113899
|
+
const workGraphManager = new import_client_core44.WorkGraphManager({ agents: agentManager, tools: executor });
|
|
113257
113900
|
workGraphManager.registerTools(executor);
|
|
113258
113901
|
const workPlanApproval = new WorkPlanApprovalBridge();
|
|
113259
113902
|
function rejectPendingWorkPlan() {
|
|
@@ -113276,7 +113919,7 @@ async function main() {
|
|
|
113276
113919
|
workRunTicker = setInterval(() => {
|
|
113277
113920
|
const record = liveRunRecord;
|
|
113278
113921
|
if (!record) return stopWorkRunTicker();
|
|
113279
|
-
const view = (0,
|
|
113922
|
+
const view = (0, import_client_core44.buildRunGraphView)(record, agentManager.agentsFor(sessionId), Date.now(), tuiFlowBudget());
|
|
113280
113923
|
appStore.setState(
|
|
113281
113924
|
(s) => s.workRun ? { ...s, workRun: { ...s.workRun, view } } : s
|
|
113282
113925
|
);
|
|
@@ -113287,8 +113930,10 @@ async function main() {
|
|
|
113287
113930
|
workGraphManager.attachParent(sid, {
|
|
113288
113931
|
workspaceRoot: () => currentRouting().workspaceRoot ?? config.workspaceRoot,
|
|
113289
113932
|
knownPersonas: () => agentManager.knownTypes(),
|
|
113290
|
-
// Plan mode switches submit to the read-only doctrine (inert graphs, no approval
|
|
113291
|
-
|
|
113933
|
+
// Plan mode switches submit to the read-only doctrine (inert graphs, no approval
|
|
113934
|
+
// card). LEG mode: duet's planning leg is the same read-only doctrine, and its
|
|
113935
|
+
// execution leg is not (mirrors the IDE/Power App).
|
|
113936
|
+
chatMode: () => legMode(),
|
|
113292
113937
|
requestApproval: (plan) => workPlanApproval.request(
|
|
113293
113938
|
plan,
|
|
113294
113939
|
(pending) => appStore.setState((s) => ({ ...s, pendingWorkPlan: pending }))
|
|
@@ -113300,11 +113945,11 @@ async function main() {
|
|
|
113300
113945
|
const status = appStore.getState().status;
|
|
113301
113946
|
if (status !== "idle" && status !== "error") return;
|
|
113302
113947
|
if (heldAgentReports.length === 0) return;
|
|
113303
|
-
sendTurn(
|
|
113948
|
+
sendTurn(import_client_core44.SUBAGENT_WAKE_PROMPT, void 0, void 0, "system");
|
|
113304
113949
|
},
|
|
113305
113950
|
onRunUpdate: (record) => {
|
|
113306
113951
|
liveRunRecord = record;
|
|
113307
|
-
const view = (0,
|
|
113952
|
+
const view = (0, import_client_core44.buildRunGraphView)(record, agentManager.agentsFor(sessionId), Date.now(), tuiFlowBudget());
|
|
113308
113953
|
if (view.live) {
|
|
113309
113954
|
startWorkRunTicker();
|
|
113310
113955
|
appStore.setState((s) => ({
|
|
@@ -113343,9 +113988,12 @@ async function main() {
|
|
|
113343
113988
|
attachWorkGraphParent(sessionId);
|
|
113344
113989
|
const attachAgentParent = (sid) => {
|
|
113345
113990
|
agentManager.attachParent(sid, {
|
|
113346
|
-
|
|
113991
|
+
// LEG mode overrides the session's raw mode for the spawn capture: a duet parent's
|
|
113992
|
+
// children are read-only planners during the planning leg and ordinary coders during
|
|
113993
|
+
// execution — never "duet" agents themselves (mirrors the IDE/Power App).
|
|
113994
|
+
routing: () => ({ ...currentRouting(), mode: legMode() }),
|
|
113347
113995
|
clientCapabilities: () => [
|
|
113348
|
-
...(0,
|
|
113996
|
+
...(0, import_client_core43.platformCapabilities)(),
|
|
113349
113997
|
...appStore.getState().subagentsEnabled ? ["subagents"] : []
|
|
113350
113998
|
],
|
|
113351
113999
|
transcript: () => transcriptStore.getState().messages,
|
|
@@ -113354,7 +114002,7 @@ async function main() {
|
|
|
113354
114002
|
const status = appStore.getState().status;
|
|
113355
114003
|
if (status !== "idle" && status !== "error") return;
|
|
113356
114004
|
if (heldAgentReports.length === 0) return;
|
|
113357
|
-
sendTurn(
|
|
114005
|
+
sendTurn(import_client_core44.SUBAGENT_WAKE_PROMPT, void 0, void 0, "system");
|
|
113358
114006
|
},
|
|
113359
114007
|
onLifecycle: (ev) => onRenderEvent({
|
|
113360
114008
|
event: "agent_lifecycle",
|
|
@@ -113390,7 +114038,7 @@ async function main() {
|
|
|
113390
114038
|
timestamp: Date.now(),
|
|
113391
114039
|
data
|
|
113392
114040
|
}),
|
|
113393
|
-
getOrionResources: () => (0,
|
|
114041
|
+
getOrionResources: () => (0, import_client_core43.buildOrionSnapshot)(config.workspaceRoot, void 0, sid),
|
|
113394
114042
|
// Full-dose source for review-persona children (lesson dosing) — the same
|
|
113395
114043
|
// attention payload the parent turn itself ships.
|
|
113396
114044
|
oVaultAttention: () => {
|
|
@@ -113418,6 +114066,11 @@ async function main() {
|
|
|
113418
114066
|
attachWorkGraphParent(newSid);
|
|
113419
114067
|
};
|
|
113420
114068
|
attachAgentParent(sessionId);
|
|
114069
|
+
const legMode = () => {
|
|
114070
|
+
const a = appStore.getState();
|
|
114071
|
+
if (a.mode !== "duet") return a.mode;
|
|
114072
|
+
return a.duetExecutionStarted ? "code" : "plan";
|
|
114073
|
+
};
|
|
113421
114074
|
const currentRouting = () => {
|
|
113422
114075
|
const a = appStore.getState();
|
|
113423
114076
|
const custom = (0, import_client_core8.endpointRoutingFor)(a.provider);
|
|
@@ -113430,7 +114083,7 @@ async function main() {
|
|
|
113430
114083
|
// the /turbo-toggle vs --fully-automatic gap: the flag already overrides the
|
|
113431
114084
|
// store mode at launch (launchPermissionMode); the toggle now buys the same
|
|
113432
114085
|
// backend posture, so no ask is ever born and batch-mates stop deferring.
|
|
113433
|
-
permissionMode: (0,
|
|
114086
|
+
permissionMode: (0, import_client_core44.effectiveWirePermissionMode)(
|
|
113434
114087
|
bridge.isTurboModeEnabledForSession(sessionId),
|
|
113435
114088
|
a.permissionMode
|
|
113436
114089
|
),
|
|
@@ -113450,8 +114103,8 @@ async function main() {
|
|
|
113450
114103
|
sandboxAvailable: SANDBOX_AVAILABLE
|
|
113451
114104
|
};
|
|
113452
114105
|
};
|
|
113453
|
-
const oVaultSessions = new
|
|
113454
|
-
oVaultSessions.syncRunner = new
|
|
114106
|
+
const oVaultSessions = new import_client_core43.OVaultSessions(() => process.env.ORION_OVAULT_CAPTURE !== "0");
|
|
114107
|
+
oVaultSessions.syncRunner = new import_client_core43.OVaultSyncRunner({
|
|
113455
114108
|
auth: {
|
|
113456
114109
|
apiBaseUrl: () => config.accountsApiUrl,
|
|
113457
114110
|
accessToken: () => session.currentAccessToken(),
|
|
@@ -113509,7 +114162,7 @@ async function main() {
|
|
|
113509
114162
|
return;
|
|
113510
114163
|
}
|
|
113511
114164
|
}
|
|
113512
|
-
if (lastTurnComplete?.sessionId === sid && Date.now() - lastTurnComplete.at <
|
|
114165
|
+
if (lastTurnComplete?.sessionId === sid && Date.now() - lastTurnComplete.at < import_client_core44.REPHRASE_WINDOW_MS) {
|
|
113513
114166
|
outcomes.report({ kind: "rephrase" });
|
|
113514
114167
|
}
|
|
113515
114168
|
triggerSecurityCapabilitiesRefresh(bridge, appStore);
|
|
@@ -113527,10 +114180,11 @@ async function main() {
|
|
|
113527
114180
|
};
|
|
113528
114181
|
try {
|
|
113529
114182
|
const peerAgents = await presence.registry.peersForWire(sid).catch(() => []);
|
|
113530
|
-
const outcome = await (0,
|
|
114183
|
+
const outcome = await (0, import_client_core43.driveTurn)(
|
|
113531
114184
|
turnTransport,
|
|
113532
114185
|
{
|
|
113533
114186
|
sessionId: sid,
|
|
114187
|
+
duetPlan: appStore.getState().mode === "duet" ? appStore.getState().duetPlan : null,
|
|
113534
114188
|
...start2.skill ? { skill: start2.skill } : { text: start2.text ?? "" },
|
|
113535
114189
|
...start2.attachments && start2.attachments.length > 0 ? { attachments: start2.attachments } : {},
|
|
113536
114190
|
// Replay the COMMITTED transcript (the pre-submit snapshot — NOT the live
|
|
@@ -113548,10 +114202,13 @@ async function main() {
|
|
|
113548
114202
|
// `workgraph` rides the same switch as the fan-out family: a work graph IS a
|
|
113549
114203
|
// fan-out (its phases are sub-agents), so turning sub-agents off must hide both.
|
|
113550
114204
|
clientCapabilities: [
|
|
113551
|
-
...(0,
|
|
114205
|
+
...(0, import_client_core43.platformCapabilities)(),
|
|
113552
114206
|
...appStore.getState().subagentsEnabled ? ["scheduling", "subagents", "workgraph"] : ["scheduling"],
|
|
113553
114207
|
// This terminal can RECEIVE a peer message, so it may also address them.
|
|
113554
|
-
"agent_messaging"
|
|
114208
|
+
"agent_messaging",
|
|
114209
|
+
// This host owns a standing-plan record and can clear it, so Duet's
|
|
114210
|
+
// `request_replan` may be offered (further leg-gated backend-side).
|
|
114211
|
+
import_client_core44.DUET_REPLAN_CAPABILITY
|
|
113555
114212
|
],
|
|
113556
114213
|
extraBody: {
|
|
113557
114214
|
...appStore.getState().subagentsEnabled ? agentManager.parentExtraBody() : {},
|
|
@@ -113568,7 +114225,7 @@ async function main() {
|
|
|
113568
114225
|
// Ship the `.orion` snapshot so the backend's begin-turn loaders read
|
|
113569
114226
|
// config / sub-agent defs / skills / hooks / memory / plugins from the
|
|
113570
114227
|
// body — no live client-read channel in the stateless segment model.
|
|
113571
|
-
getOrionResources: () => (0,
|
|
114228
|
+
getOrionResources: () => (0, import_client_core43.buildOrionSnapshot)(currentRouting().workspaceRoot, void 0, sid),
|
|
113572
114229
|
getFileHistoryManifest: () => executor.fileHistoryManifest(sid),
|
|
113573
114230
|
// Lesson-recall anchors: the TUI has no editor attention, so recently-touched
|
|
113574
114231
|
// paths from the capture observer are the attention set.
|
|
@@ -113578,7 +114235,7 @@ async function main() {
|
|
|
113578
114235
|
return { active: null, open: [], touched, related: executor.oVaultRelatedPaths?.(touched) ?? [] };
|
|
113579
114236
|
}
|
|
113580
114237
|
},
|
|
113581
|
-
(0,
|
|
114238
|
+
(0, import_client_core43.withOVault)(
|
|
113582
114239
|
{
|
|
113583
114240
|
...boundary.makeHandlers(sid, ac.signal, onEvent),
|
|
113584
114241
|
// Stops the driver from POSTING the next segment when the user cancelled at a
|
|
@@ -113590,7 +114247,7 @@ async function main() {
|
|
|
113590
114247
|
onToolResult: (payload) => {
|
|
113591
114248
|
if (payload.terminal_savings) {
|
|
113592
114249
|
terminalSavings.push(payload.terminal_savings);
|
|
113593
|
-
(0,
|
|
114250
|
+
(0, import_client_core43.recordTurnMetrics)({
|
|
113594
114251
|
app: "tui",
|
|
113595
114252
|
sessionId: sid,
|
|
113596
114253
|
workspaceRoot: currentRouting().workspaceRoot,
|
|
@@ -113624,12 +114281,12 @@ async function main() {
|
|
|
113624
114281
|
settleOutcome = "completed";
|
|
113625
114282
|
lastTurnComplete = { sessionId: sid, at: Date.now() };
|
|
113626
114283
|
const data = outcome.event.data ?? {};
|
|
113627
|
-
endSettle = { kind: "complete", finalText: (0,
|
|
113628
|
-
(0,
|
|
114284
|
+
endSettle = { kind: "complete", finalText: (0, import_client_core44.finalAssistantTextFromWire)(data.messages) };
|
|
114285
|
+
(0, import_client_core43.recordTurnMetrics)({
|
|
113629
114286
|
app: "tui",
|
|
113630
114287
|
sessionId: sid,
|
|
113631
114288
|
workspaceRoot: currentRouting().workspaceRoot,
|
|
113632
|
-
turn: (0,
|
|
114289
|
+
turn: (0, import_client_core43.turnMetricsFromComplete)(data),
|
|
113633
114290
|
terminalSavings
|
|
113634
114291
|
});
|
|
113635
114292
|
void oVaultSessions.reflectorFor(sid, currentRouting().workspaceRoot, bridge)?.run("turn_complete").finally(
|
|
@@ -113673,12 +114330,26 @@ async function main() {
|
|
|
113673
114330
|
} finally {
|
|
113674
114331
|
turn.disposeFallback?.();
|
|
113675
114332
|
if (currentTurn === turn) {
|
|
114333
|
+
const st2 = appStore.getState();
|
|
114334
|
+
if (st2.duetPlan && st2.mode === "duet") {
|
|
114335
|
+
const folded = (0, import_client_core44.foldDuetTurnEnd)(st2.duetPlan, st2.duetExecutionStarted, settleOutcome);
|
|
114336
|
+
appStore.setState((s2) => ({ ...s2, duetPlan: folded }));
|
|
114337
|
+
}
|
|
113676
114338
|
settleSteerQueue({
|
|
113677
114339
|
app: appStore,
|
|
113678
114340
|
isBusy: () => currentTurn !== null || goalRunner !== null,
|
|
113679
114341
|
send: sendTurn,
|
|
113680
114342
|
runCommand: routeInput
|
|
113681
114343
|
});
|
|
114344
|
+
const replanReason = pendingDuetReplan;
|
|
114345
|
+
pendingDuetReplan = null;
|
|
114346
|
+
if (replanReason !== null && settleOutcome === "completed" && appStore.getState().mode === "duet") {
|
|
114347
|
+
setTimeout(() => {
|
|
114348
|
+
sendTurn((0, import_client_core44.duetReplanFollowupPrompt)(replanReason), void 0, void 0, "system", {
|
|
114349
|
+
ifBusy: "decline"
|
|
114350
|
+
});
|
|
114351
|
+
}, 0);
|
|
114352
|
+
}
|
|
113682
114353
|
}
|
|
113683
114354
|
if (currentTurn === turn) currentTurn = null;
|
|
113684
114355
|
fireTurnEnd();
|
|
@@ -113718,6 +114389,8 @@ async function main() {
|
|
|
113718
114389
|
status: "streaming",
|
|
113719
114390
|
statusText: "thinking\u2026",
|
|
113720
114391
|
error: null,
|
|
114392
|
+
duetExecutionStarted: false,
|
|
114393
|
+
// a fresh turn plans again — the leg record is per-turn
|
|
113721
114394
|
// A REMOTE send brought its own photos — the local user's pasted ones belong to
|
|
113722
114395
|
// whatever they are still typing and must survive it. Only a local send consumes
|
|
113723
114396
|
// them (it just did, via prunePastedImages above).
|
|
@@ -113730,6 +114403,7 @@ async function main() {
|
|
|
113730
114403
|
// the last await ended; still-running children keep their rows.
|
|
113731
114404
|
subAgents: s.subAgents.filter((a) => a.phase !== "finished")
|
|
113732
114405
|
}));
|
|
114406
|
+
beginDuetPhase(text);
|
|
113733
114407
|
void runTurn({ text, attachments, origin, onTurnEnd: opts?.onTurnEnd }, snapshot);
|
|
113734
114408
|
return "started";
|
|
113735
114409
|
};
|
|
@@ -113753,6 +114427,8 @@ async function main() {
|
|
|
113753
114427
|
status: "streaming",
|
|
113754
114428
|
statusText: "running skill\u2026",
|
|
113755
114429
|
error: null,
|
|
114430
|
+
duetExecutionStarted: false,
|
|
114431
|
+
// a fresh turn plans again — the leg record is per-turn
|
|
113756
114432
|
turnOutputTokens: 0,
|
|
113757
114433
|
// reset the live meter before turn_started arrives
|
|
113758
114434
|
scrollBack: 0,
|
|
@@ -113760,14 +114436,21 @@ async function main() {
|
|
|
113760
114436
|
// Sweep SETTLED fleet rows (matches sendTurn) — a skill turn is a turn.
|
|
113761
114437
|
subAgents: s.subAgents.filter((a) => a.phase !== "finished")
|
|
113762
114438
|
}));
|
|
114439
|
+
beginDuetPhase("");
|
|
113763
114440
|
void runTurn({ skill: { name: name2, args: args2 } }, snapshot);
|
|
113764
114441
|
};
|
|
113765
114442
|
cronController.start();
|
|
113766
114443
|
executor.registerHostTool("schedule_task", makeScheduleTaskHandler(cronController));
|
|
114444
|
+
executor.registerHostTool(import_client_core44.DUET_REPLAN_TOOL, async (params) => {
|
|
114445
|
+
const flagged = (0, import_client_core44.invalidateStandingPlan)(appStore.getState().duetPlan);
|
|
114446
|
+
if (flagged) appStore.setState((s) => ({ ...s, duetPlan: flagged }));
|
|
114447
|
+
pendingDuetReplan = typeof params.reason === "string" ? params.reason : "";
|
|
114448
|
+
return (0, import_client_core44.duetReplanResult)(flagged !== null);
|
|
114449
|
+
});
|
|
113767
114450
|
const loopService = new LoopService({
|
|
113768
114451
|
workspaceRoot: config.workspaceRoot,
|
|
113769
|
-
schedulePath: loopSchedulePathFor((0,
|
|
113770
|
-
transport: (0,
|
|
114452
|
+
schedulePath: loopSchedulePathFor((0, import_client_core44.runsRootFor)("loops", config.workspaceRoot)),
|
|
114453
|
+
transport: (0, import_client_core44.brainAwareAgentTransport)(bridge, turnTransport),
|
|
113771
114454
|
tools: executor,
|
|
113772
114455
|
// The CONFIGURED mode rides here deliberately, not the turbo-effective one
|
|
113773
114456
|
// (currentRouting applies the turbo→full_access law): a loop is standing
|
|
@@ -113814,12 +114497,12 @@ async function main() {
|
|
|
113814
114497
|
}));
|
|
113815
114498
|
return;
|
|
113816
114499
|
}
|
|
113817
|
-
const runner = new
|
|
114500
|
+
const runner = new import_client_core44.GoalRunner({ runTurn: runGoalTurn });
|
|
113818
114501
|
goalRunner = runner;
|
|
113819
114502
|
transcriptStore.setState((s) => appendNote(s, `Goal started \u2014 working until complete: ${goal}`));
|
|
113820
114503
|
void runner.run(goal).then((reason) => {
|
|
113821
114504
|
if (goalRunner === runner) goalRunner = null;
|
|
113822
|
-
transcriptStore.setState((s) => appendNote(s, (0,
|
|
114505
|
+
transcriptStore.setState((s) => appendNote(s, (0, import_client_core44.describeGoalEnd)(reason)));
|
|
113823
114506
|
settleSteerQueue({
|
|
113824
114507
|
app: appStore,
|
|
113825
114508
|
isBusy: () => currentTurn !== null || goalRunner !== null,
|
|
@@ -113859,10 +114542,10 @@ async function main() {
|
|
|
113859
114542
|
steer: (text) => enqueueMachineSteer(text),
|
|
113860
114543
|
deliverAgentMessage: (message) => {
|
|
113861
114544
|
inboundPeerHop = Math.max(inboundPeerHop ?? 0, message.hop);
|
|
113862
|
-
heldAgentReports.push((0,
|
|
114545
|
+
heldAgentReports.push((0, import_client_core44.formatAgentMessage)(message));
|
|
113863
114546
|
const status = appStore.getState().status;
|
|
113864
114547
|
if (status !== "idle" && status !== "error") return;
|
|
113865
|
-
sendTurn((0,
|
|
114548
|
+
sendTurn((0, import_client_core44.peerMessageWakePrompt)(message), void 0, void 0, "system");
|
|
113866
114549
|
},
|
|
113867
114550
|
resolvePermission: (requestId, decision, sid) => {
|
|
113868
114551
|
const pending = appStore.getState().pendingPermissions.some((p) => p.data.request_id === requestId);
|
|
@@ -114025,25 +114708,25 @@ async function main() {
|
|
|
114025
114708
|
defaultApiUrl: config.apiUrl,
|
|
114026
114709
|
entries,
|
|
114027
114710
|
add: async (entry) => {
|
|
114028
|
-
await (0,
|
|
114029
|
-
(0,
|
|
114030
|
-
panel(await (0,
|
|
114711
|
+
await (0, import_client_core44.saveCustomProvider)(entry, "user", opts);
|
|
114712
|
+
(0, import_client_core44.clearEndpointCatalog)(entry.baseUrl);
|
|
114713
|
+
panel(await (0, import_client_core44.loadCustomProviders)(opts));
|
|
114031
114714
|
},
|
|
114032
114715
|
remove: async (name2) => {
|
|
114033
114716
|
for (const tier of ["user", "project", "local"]) {
|
|
114034
|
-
if (await (0,
|
|
114717
|
+
if (await (0, import_client_core44.removeCustomProvider)(name2, tier, opts)) break;
|
|
114035
114718
|
}
|
|
114036
114719
|
(0, import_client_core8.clearEndpointRouting)();
|
|
114037
|
-
(0,
|
|
114038
|
-
panel(await (0,
|
|
114720
|
+
(0, import_client_core44.clearEndpointCatalog)();
|
|
114721
|
+
panel(await (0, import_client_core44.loadCustomProviders)(opts));
|
|
114039
114722
|
},
|
|
114040
|
-
probe: (baseUrl, apiKey) => (0,
|
|
114723
|
+
probe: (baseUrl, apiKey) => (0, import_client_core44.probeModels)(baseUrl, apiKey),
|
|
114041
114724
|
// A saved endpoint's models come from the CACHED catalog — opening one costs no
|
|
114042
114725
|
// network, so limits stay editable long after the endpoint was added.
|
|
114043
114726
|
modelsOf: (entry) => (0, import_client_core8.endpointModelViews)(entry),
|
|
114044
114727
|
updateModels: async (name2, update) => {
|
|
114045
114728
|
await (0, import_client_core8.updateCustomProviderModels)(name2, update, "user", opts);
|
|
114046
|
-
panel(await (0,
|
|
114729
|
+
panel(await (0, import_client_core44.loadCustomProviders)(opts));
|
|
114047
114730
|
},
|
|
114048
114731
|
use: async (name2, model) => {
|
|
114049
114732
|
const provider = `custom:${name2}`;
|
|
@@ -114061,7 +114744,7 @@ async function main() {
|
|
|
114061
114744
|
}
|
|
114062
114745
|
}
|
|
114063
114746
|
}));
|
|
114064
|
-
void (0,
|
|
114747
|
+
void (0, import_client_core44.loadCustomProviders)(opts).then(panel);
|
|
114065
114748
|
}
|
|
114066
114749
|
};
|
|
114067
114750
|
const routeInput = (text) => routeChatInput(text, {
|
|
@@ -114070,7 +114753,7 @@ async function main() {
|
|
|
114070
114753
|
addMemory: (note) => void addMemoryLine(note),
|
|
114071
114754
|
resolveCommand: async (line) => {
|
|
114072
114755
|
let parsed = registry.parse(line);
|
|
114073
|
-
if (!parsed && (0,
|
|
114756
|
+
if (!parsed && (0, import_client_core44.matchSlashToken)(line)) {
|
|
114074
114757
|
await skillSlash.refresh().catch(() => void 0);
|
|
114075
114758
|
parsed = registry.parse(line);
|
|
114076
114759
|
}
|