@wrongstack/cli 1.0.4 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{acp-AB54FWM2.js → acp-A5EQEXQO.js} +69 -11
- package/dist/{auth-WDMSNZ3S.js → auth-3K6EN5JP.js} +3 -3
- package/dist/boot/container-wiring.d.ts +2 -0
- package/dist/boot/short-circuit-desktop.d.ts +1 -0
- package/dist/{chunk-VUVOMXWP.js → chunk-3VXYY5JC.js} +8 -1
- package/dist/{chunk-U6PGWDMZ.js → chunk-4OLAZIIN.js} +2 -2
- package/dist/{chunk-I7V2OYVH.js → chunk-5EA6OTLJ.js} +3 -6
- package/dist/{chunk-O4A3HHKD.js → chunk-672UXYL3.js} +2 -2
- package/dist/{chunk-ONOT5OJ2.js → chunk-FSZ5QU3M.js} +2 -2
- package/dist/{chunk-KNMIBKLV.js → chunk-JY52HWL6.js} +47 -1
- package/dist/{chunk-BIWE22O5.js → chunk-RLCKKLJA.js} +8 -8
- package/dist/{chunk-VFCJOWJB.js → chunk-RMQNCHGO.js} +8 -7
- package/dist/{chunk-3I5ZJXM5.js → chunk-XIZZ2EXG.js} +161 -62
- package/dist/{cli-context-WFC3BNGM.js → cli-context-TIAP6YQK.js} +95 -15
- package/dist/cli-context.d.ts +2 -0
- package/dist/{cli-main-GU3YZLMO.js → cli-main-AKJHDSHX.js} +1111 -721
- package/dist/config-doctor.d.ts +1 -1
- package/dist/execute-deps.d.ts +3 -1
- package/dist/{execution-RAZDDQFC.js → execution-FJE27VQ6.js} +105 -28
- package/dist/{hq-5XHEIIH6.js → hq-G5PCP325.js} +8 -6
- package/dist/hq-command-controller.d.ts +15 -0
- package/dist/hq-server/auth-state.d.ts +6 -0
- package/dist/hq-server/auth.d.ts +10 -1
- package/dist/hq-server/routes/auth/common.d.ts +34 -0
- package/dist/hq-server/routes/auth/password-routes.d.ts +4 -2
- package/dist/hq-server/types.d.ts +18 -0
- package/dist/{hq-server-CNUTBWTK.js → hq-server-G3VVVMIG.js} +3 -3
- package/dist/index.js +8 -5
- package/dist/input-reader.d.ts +2 -2
- package/dist/{mcp-HOMLC4WE.js → mcp-FX7TKPTV.js} +10 -8
- package/dist/mcp-serve.d.ts +31 -0
- package/dist/{modeldiag-46CMWUNM.js → modeldiag-CJSFHZ3J.js} +55 -31
- package/dist/permission-prompt-mirror.d.ts +70 -0
- package/dist/permission-prompt.d.ts +10 -1
- package/dist/{providers-models-6MOGAOVK.js → providers-models-LFNZ5WI7.js} +2 -2
- package/dist/{short-circuit-flags-YDMLAQ5R.js → short-circuit-flags-RAT6UZVI.js} +2 -2
- package/dist/slash-commands/subagent-models.d.ts +4 -0
- package/dist/subagent-models/panel-service.d.ts +28 -0
- package/dist/subcommands/handlers/modeldiag-test.d.ts +7 -0
- package/dist/{subcommands-7N4RIK6H.js → subcommands-VFVUTYAV.js} +2 -2
- package/dist/webui-server/prefs-seeding.d.ts +8 -0
- package/dist/{webui-server-OBV5JYJV.js → webui-server-3NYXBZHX.js} +36 -12
- package/dist/wiring/hq-telemetry.d.ts +7 -0
- package/package.json +28 -28
package/dist/config-doctor.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export interface PluginSchemaInfo {
|
|
|
47
47
|
* every theme change), and a phantom `agents` entry (that field is nested
|
|
48
48
|
* under `acp`, never top-level) waved a stray top-level `agents` block
|
|
49
49
|
* through. Add a field to `Config` and `tsc` now names it here. */
|
|
50
|
-
declare const KNOWN_TOP_LEVEL_KEYS: readonly ['version', 'activeProfile', 'provider', 'model', 'apiKey', 'baseUrl', 'maxConcurrent', 'uiLocale', 'themePreset', 'providers', 'models', 'modelMatrix', 'modelTiers', 'favoriteModels', 'favoriteModelsOnly', 'modelAvailabilitySchedule', 'context', 'tools', 'mcpServers', 'acp', 'fallbackModels', 'fallbackBridge', 'fallbackProfiles', 'fallbackProfile', 'fallbackAuto', 'fallbackMaxLastResortCandidates', 'fallbackStickiness', 'fallbackGateSeconds', 'hooks', 'plugins', 'pluginManager', 'log', 'features', 'Sage', 'skills', 'yolo', 'nextPrediction', 'cwd', 'autonomy', 'hints', 'debugStream', 'configScope', 'indexing', 'circuitBreaker', 'adaptiveConcurrency', 'launch', 'session', 'chronicle', 'modelRuntime', 'systemPrompt', 'hq', 'fleet', 'brain', 'sync', 'cloudSync', 'git', 'extensions'];
|
|
50
|
+
declare const KNOWN_TOP_LEVEL_KEYS: readonly ['version', 'activeProfile', 'provider', 'model', 'apiKey', 'baseUrl', 'maxConcurrent', 'uiLocale', 'themePreset', 'providers', 'models', 'modelMatrix', 'modelTiers', 'favoriteModels', 'disabledModels', 'favoriteModelsOnly', 'modelAvailabilitySchedule', 'context', 'tools', 'mcpServers', 'acp', 'fallbackModels', 'fallbackBridge', 'fallbackProfiles', 'fallbackProfile', 'fallbackAuto', 'fallbackMaxLastResortCandidates', 'fallbackStickiness', 'fallbackGateSeconds', 'hooks', 'plugins', 'pluginManager', 'log', 'features', 'Sage', 'skills', 'yolo', 'nextPrediction', 'cwd', 'autonomy', 'hints', 'debugStream', 'configScope', 'indexing', 'circuitBreaker', 'adaptiveConcurrency', 'launch', 'session', 'chronicle', 'modelRuntime', 'systemPrompt', 'hq', 'fleet', 'brain', 'sync', 'cloudSync', 'git', 'extensions'];
|
|
51
51
|
/** Compile-time `never` assertion: instantiating it with a non-empty union
|
|
52
52
|
* fails and the TS error text spells out the offending key names. */
|
|
53
53
|
type AssertNever<T extends never> = T;
|
package/dist/execute-deps.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type { BrainAutoRisk } from '@wrongstack/core/execution';
|
|
|
14
14
|
import type { JournalEntry } from '@wrongstack/core/goal';
|
|
15
15
|
import type { EventBus } from '@wrongstack/core/kernel';
|
|
16
16
|
import type { SlashCommandRegistry } from '@wrongstack/core/registry';
|
|
17
|
+
import type { StatuslineDensities, StatuslineLines } from '@wrongstack/core/statusline';
|
|
17
18
|
import type { QueueStore } from '@wrongstack/core/storage';
|
|
18
19
|
import type { AttachmentStore, AutonomyStage, Config, ConfigStore, MemoryPort, Message, ModelsRegistry, ModeStore, PromptLoader, ProviderConfig, ResolvedProvider, SessionEvent, SessionStore, SessionWriter, SkillLoader, TokenCounter } from '@wrongstack/core/types';
|
|
19
20
|
import type { WstackPaths } from '@wrongstack/core/utils';
|
|
@@ -25,7 +26,6 @@ import type { ReadlineInputReader } from './input-reader.js';
|
|
|
25
26
|
import type { LiveSettingsInput } from './live-settings-input.js';
|
|
26
27
|
import type { TerminalRenderer } from './renderer.js';
|
|
27
28
|
import type { AutonomyMode } from './services/autonomy-mode.js';
|
|
28
|
-
import type { StatuslineDensities, StatuslineLines } from '@wrongstack/core/statusline';
|
|
29
29
|
import type { StatuslineConfigKey } from './services/statusline-config.js';
|
|
30
30
|
import type { SessionStats } from './session-stats.js';
|
|
31
31
|
import type { UpdateInfo } from './update-check.js';
|
|
@@ -163,6 +163,8 @@ interface ProviderDeps {
|
|
|
163
163
|
tools?: boolean | undefined;
|
|
164
164
|
vision?: boolean | undefined;
|
|
165
165
|
reasoning?: boolean | undefined;
|
|
166
|
+
/** Documented reasoning-effort levels (drives the picker strip). */
|
|
167
|
+
effortLevels?: readonly string[] | undefined;
|
|
166
168
|
maxContext?: number | undefined;
|
|
167
169
|
maxOutput?: number | undefined;
|
|
168
170
|
inputCost?: number | undefined;
|
|
@@ -212,7 +212,7 @@ async function runWebUIDispatch(ctx) {
|
|
|
212
212
|
const isSimpleUi = !isSessionChild && flags["simpleui"] === true;
|
|
213
213
|
agent.disableInteractiveConfirmation();
|
|
214
214
|
renderer.setSilent(true);
|
|
215
|
-
const { runWebUI } = await import("./webui-server-
|
|
215
|
+
const { runWebUI } = await import("./webui-server-3NYXBZHX.js");
|
|
216
216
|
const flagValue = (names) => {
|
|
217
217
|
for (const name of names) {
|
|
218
218
|
if (!Object.hasOwn(flags, name)) continue;
|
|
@@ -1255,10 +1255,13 @@ async function onSDDOutput(output) {
|
|
|
1255
1255
|
|
|
1256
1256
|
// src/boot/tui-session-resume.ts
|
|
1257
1257
|
import * as path7 from "node:path";
|
|
1258
|
-
import {
|
|
1258
|
+
import {
|
|
1259
|
+
restoreSessionSubagentModelPlan,
|
|
1260
|
+
restoreSessionSubagentPolicy
|
|
1261
|
+
} from "@wrongstack/core/coordination";
|
|
1259
1262
|
import { attachTodosCheckpoint, loadTodosCheckpoint } from "@wrongstack/core/storage";
|
|
1260
1263
|
import { projectLastRequestTokens } from "@wrongstack/core/types/session-timeline";
|
|
1261
|
-
import { sessionScopedPath as sessionScopedPath2 } from "@wrongstack/core/utils";
|
|
1264
|
+
import { sessionScopedPath as sessionScopedPath2, toErrorMessage } from "@wrongstack/core/utils";
|
|
1262
1265
|
var RESERVATION_WINDOW_MS = 6e4;
|
|
1263
1266
|
var RESERVATION_RENEW_MS = 2e4;
|
|
1264
1267
|
function messageText(content) {
|
|
@@ -1288,7 +1291,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1288
1291
|
};
|
|
1289
1292
|
const warnings = [];
|
|
1290
1293
|
const warn = (label, err) => {
|
|
1291
|
-
warnings.push(`${label}: ${
|
|
1294
|
+
warnings.push(`${label}: ${toErrorMessage(err)}`);
|
|
1292
1295
|
};
|
|
1293
1296
|
let stage = "start";
|
|
1294
1297
|
const setStage = (next) => {
|
|
@@ -1309,7 +1312,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1309
1312
|
throw new TypeError("@wrongstack/tui does not export replaySessionMessages");
|
|
1310
1313
|
}
|
|
1311
1314
|
} catch (err) {
|
|
1312
|
-
return fail(stage,
|
|
1315
|
+
return fail(stage, toErrorMessage(err));
|
|
1313
1316
|
}
|
|
1314
1317
|
setStage("resolve_id");
|
|
1315
1318
|
let canonicalSessionId = sessionId;
|
|
@@ -1323,11 +1326,11 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1323
1326
|
level: "error",
|
|
1324
1327
|
event: "execution.resume_id_resolve_failed",
|
|
1325
1328
|
sessionId,
|
|
1326
|
-
message:
|
|
1329
|
+
message: toErrorMessage(err),
|
|
1327
1330
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1328
1331
|
})
|
|
1329
1332
|
);
|
|
1330
|
-
return fail(stage,
|
|
1333
|
+
return fail(stage, toErrorMessage(err));
|
|
1331
1334
|
}
|
|
1332
1335
|
const previousSessionId = agent.ctx.session?.id;
|
|
1333
1336
|
let hydrated;
|
|
@@ -1369,7 +1372,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1369
1372
|
level: "warn",
|
|
1370
1373
|
event: "execution.resume_reservation_renew_failed",
|
|
1371
1374
|
sessionId: canonicalSessionId,
|
|
1372
|
-
message:
|
|
1375
|
+
message: toErrorMessage(err),
|
|
1373
1376
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1374
1377
|
})
|
|
1375
1378
|
);
|
|
@@ -1425,6 +1428,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1425
1428
|
try {
|
|
1426
1429
|
agent.ctx.state.replaceMessages(resumed.data.messages);
|
|
1427
1430
|
restoreSessionSubagentPolicy(agent.ctx, resumed.data.events, resumed.data.subagentsAllowed);
|
|
1431
|
+
restoreSessionSubagentModelPlan(agent.ctx, resumed.data.events);
|
|
1428
1432
|
} catch (err) {
|
|
1429
1433
|
agent.ctx.session = oldWriter;
|
|
1430
1434
|
agent.ctx.state.replaceMessages(oldMessages);
|
|
@@ -1441,7 +1445,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1441
1445
|
JSON.stringify({
|
|
1442
1446
|
level: "error",
|
|
1443
1447
|
event: "execution.resume_journal_flush_failed",
|
|
1444
|
-
message:
|
|
1448
|
+
message: toErrorMessage(err),
|
|
1445
1449
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1446
1450
|
})
|
|
1447
1451
|
);
|
|
@@ -1498,7 +1502,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1498
1502
|
event: "execution.resume_model_restore_failed",
|
|
1499
1503
|
provider: targetProviderId,
|
|
1500
1504
|
model: targetModel,
|
|
1501
|
-
message:
|
|
1505
|
+
message: toErrorMessage(err),
|
|
1502
1506
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1503
1507
|
})
|
|
1504
1508
|
);
|
|
@@ -1526,7 +1530,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1526
1530
|
JSON.stringify({
|
|
1527
1531
|
level: "error",
|
|
1528
1532
|
event: "execution.session_end_append_failed",
|
|
1529
|
-
message:
|
|
1533
|
+
message: toErrorMessage(err),
|
|
1530
1534
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1531
1535
|
})
|
|
1532
1536
|
);
|
|
@@ -1539,7 +1543,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1539
1543
|
JSON.stringify({
|
|
1540
1544
|
level: "error",
|
|
1541
1545
|
event: "execution.session_close_failed",
|
|
1542
|
-
message:
|
|
1546
|
+
message: toErrorMessage(err),
|
|
1543
1547
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1544
1548
|
})
|
|
1545
1549
|
);
|
|
@@ -1580,7 +1584,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1580
1584
|
level: "error",
|
|
1581
1585
|
event: "execution.resume_identity_rollback_failed",
|
|
1582
1586
|
sessionId: previousSessionId,
|
|
1583
|
-
message:
|
|
1587
|
+
message: toErrorMessage(rollbackErr),
|
|
1584
1588
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1585
1589
|
})
|
|
1586
1590
|
);
|
|
@@ -1602,7 +1606,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1602
1606
|
JSON.stringify({
|
|
1603
1607
|
level: "error",
|
|
1604
1608
|
event: "execution.resume_post_swap_rollback_failed",
|
|
1605
|
-
message:
|
|
1609
|
+
message: toErrorMessage(rollbackErr),
|
|
1606
1610
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1607
1611
|
})
|
|
1608
1612
|
);
|
|
@@ -1613,7 +1617,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1613
1617
|
JSON.stringify({
|
|
1614
1618
|
level: "error",
|
|
1615
1619
|
event: "execution.resume_opened_writer_close_failed",
|
|
1616
|
-
message:
|
|
1620
|
+
message: toErrorMessage(closeErr),
|
|
1617
1621
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1618
1622
|
})
|
|
1619
1623
|
);
|
|
@@ -1631,7 +1635,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1631
1635
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1632
1636
|
})
|
|
1633
1637
|
);
|
|
1634
|
-
const message =
|
|
1638
|
+
const message = toErrorMessage(err);
|
|
1635
1639
|
if (err instanceof Error && err.name === "SessionOwnershipConflictError") {
|
|
1636
1640
|
return fail(stage, message);
|
|
1637
1641
|
}
|
|
@@ -1670,7 +1674,7 @@ async function resumeSession(ctx, sessionId) {
|
|
|
1670
1674
|
level: "error",
|
|
1671
1675
|
event: "execution.resume_readonly_render_failed",
|
|
1672
1676
|
sessionId: canonicalSessionId,
|
|
1673
|
-
message:
|
|
1677
|
+
message: toErrorMessage(renderErr),
|
|
1674
1678
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1675
1679
|
})
|
|
1676
1680
|
);
|
|
@@ -3203,6 +3207,75 @@ var FleetStatusLine = class {
|
|
|
3203
3207
|
}
|
|
3204
3208
|
};
|
|
3205
3209
|
|
|
3210
|
+
// src/subagent-models/panel-service.ts
|
|
3211
|
+
import {
|
|
3212
|
+
emptySubagentModelPlan,
|
|
3213
|
+
formatSubagentSlot,
|
|
3214
|
+
getSessionSubagentModelPlan,
|
|
3215
|
+
setSessionSubagentModelPlan,
|
|
3216
|
+
subagentSlotOccupancy
|
|
3217
|
+
} from "@wrongstack/core/coordination";
|
|
3218
|
+
function currentPlan(sessionId) {
|
|
3219
|
+
return getSessionSubagentModelPlan(sessionId) ?? emptySubagentModelPlan();
|
|
3220
|
+
}
|
|
3221
|
+
function createSubagentModelsPanelHost(deps) {
|
|
3222
|
+
const write = async (mutate) => {
|
|
3223
|
+
const ctx = deps.getContext();
|
|
3224
|
+
if (!ctx?.session) return "No active session \u2014 the plan cannot be saved.";
|
|
3225
|
+
const plan = structuredClone(currentPlan(ctx.session.id));
|
|
3226
|
+
mutate(plan);
|
|
3227
|
+
try {
|
|
3228
|
+
await setSessionSubagentModelPlan(ctx, plan);
|
|
3229
|
+
return null;
|
|
3230
|
+
} catch (err) {
|
|
3231
|
+
return err instanceof Error ? err.message : String(err);
|
|
3232
|
+
}
|
|
3233
|
+
};
|
|
3234
|
+
return {
|
|
3235
|
+
snapshot() {
|
|
3236
|
+
const sessionId = deps.getContext()?.session?.id;
|
|
3237
|
+
const plan = currentPlan(sessionId);
|
|
3238
|
+
const occupancy = subagentSlotOccupancy(sessionId);
|
|
3239
|
+
const session = deps.getSessionTarget?.();
|
|
3240
|
+
return {
|
|
3241
|
+
enabled: plan.enabled,
|
|
3242
|
+
lock: plan.lock,
|
|
3243
|
+
followSessionModel: plan.followSessionModel === true,
|
|
3244
|
+
sessionTarget: session?.provider ? `${session.provider}/${session.model ?? "?"}` : session?.model ?? "",
|
|
3245
|
+
lanes: plan.slots.map((slot, i) => ({
|
|
3246
|
+
target: formatSubagentSlot(slot),
|
|
3247
|
+
busy: occupancy[i]?.subagentIds.length ?? 0,
|
|
3248
|
+
...slot.label ? { label: slot.label } : {}
|
|
3249
|
+
})),
|
|
3250
|
+
roles: Object.entries(plan.roles ?? {}).map(([role, slot]) => ({ role, target: formatSubagentSlot(slot) })).sort((a, b) => a.role.localeCompare(b.role))
|
|
3251
|
+
};
|
|
3252
|
+
},
|
|
3253
|
+
setLane(index, target) {
|
|
3254
|
+
return write((plan) => {
|
|
3255
|
+
if (index < 0 || index >= plan.slots.length) return;
|
|
3256
|
+
const slot = {};
|
|
3257
|
+
if (target.provider) slot.provider = target.provider;
|
|
3258
|
+
if (target.model) slot.model = target.model;
|
|
3259
|
+
if (target.tier) slot.tier = target.tier;
|
|
3260
|
+
if (target.fallbackProfile) slot.fallbackProfile = target.fallbackProfile;
|
|
3261
|
+
if (target.label) slot.label = target.label;
|
|
3262
|
+
plan.slots[index] = slot;
|
|
3263
|
+
});
|
|
3264
|
+
},
|
|
3265
|
+
clearLane(index) {
|
|
3266
|
+
return write((plan) => {
|
|
3267
|
+
if (index < 0 || index >= plan.slots.length) return;
|
|
3268
|
+
plan.slots[index] = {};
|
|
3269
|
+
});
|
|
3270
|
+
},
|
|
3271
|
+
toggle(field) {
|
|
3272
|
+
return write((plan) => {
|
|
3273
|
+
plan[field] = plan[field] !== true;
|
|
3274
|
+
});
|
|
3275
|
+
}
|
|
3276
|
+
};
|
|
3277
|
+
}
|
|
3278
|
+
|
|
3206
3279
|
// src/chimera-work-registry.ts
|
|
3207
3280
|
function createChimeraWorkRegistry() {
|
|
3208
3281
|
const pending = /* @__PURE__ */ new Set();
|
|
@@ -4592,7 +4665,7 @@ import {
|
|
|
4592
4665
|
color as color11,
|
|
4593
4666
|
estimateRequestTokensCalibrated as estimateRequestTokensCalibrated2,
|
|
4594
4667
|
hasOpenTodos as hasOpenTodos2,
|
|
4595
|
-
toErrorMessage as
|
|
4668
|
+
toErrorMessage as toErrorMessage4
|
|
4596
4669
|
} from "@wrongstack/core/utils";
|
|
4597
4670
|
import { readClipboardImage, routeImagesForModel } from "@wrongstack/runtime";
|
|
4598
4671
|
import { createAutoProceedLoopGuard } from "@wrongstack/tools/auto-proceed-loop-guard";
|
|
@@ -4820,11 +4893,11 @@ function registerReplClient(opts) {
|
|
|
4820
4893
|
|
|
4821
4894
|
// src/repl-eternal-loop.ts
|
|
4822
4895
|
import { goalFilePath as goalFilePath2, summarizeUsage } from "@wrongstack/core/goal";
|
|
4823
|
-
import { color as color8, toErrorMessage as
|
|
4896
|
+
import { color as color8, toErrorMessage as toErrorMessage3 } from "@wrongstack/core/utils";
|
|
4824
4897
|
|
|
4825
4898
|
// src/repl-goal-banner.ts
|
|
4826
4899
|
import { goalFilePath, loadGoal } from "@wrongstack/core/goal";
|
|
4827
|
-
import { color as color7, expectDefined, toErrorMessage } from "@wrongstack/core/utils";
|
|
4900
|
+
import { color as color7, expectDefined, toErrorMessage as toErrorMessage2 } from "@wrongstack/core/utils";
|
|
4828
4901
|
async function loadGoalSafe(opts) {
|
|
4829
4902
|
if (!opts.projectRoot) return null;
|
|
4830
4903
|
try {
|
|
@@ -4858,7 +4931,7 @@ async function renderGoalBanner(opts) {
|
|
|
4858
4931
|
try {
|
|
4859
4932
|
await opts.slashRegistry.dispatch("/autonomy eternal", opts.agent.ctx);
|
|
4860
4933
|
} catch (err) {
|
|
4861
|
-
opts.renderer.writeError(`Auto-resume failed: ${
|
|
4934
|
+
opts.renderer.writeError(`Auto-resume failed: ${toErrorMessage2(err)}`);
|
|
4862
4935
|
}
|
|
4863
4936
|
} else {
|
|
4864
4937
|
opts.renderer.write(
|
|
@@ -4934,7 +5007,7 @@ async function runReplEternalLoop(opts, onInterruptsReset) {
|
|
|
4934
5007
|
return true;
|
|
4935
5008
|
}
|
|
4936
5009
|
} catch (err) {
|
|
4937
|
-
opts.renderer.writeError(`[eternal] ${
|
|
5010
|
+
opts.renderer.writeError(`[eternal] ${toErrorMessage3(err)}`);
|
|
4938
5011
|
}
|
|
4939
5012
|
await new Promise((resolve4) => setTimeout(resolve4, 250));
|
|
4940
5013
|
return true;
|
|
@@ -5005,7 +5078,7 @@ async function runReplEternalLoop(opts, onInterruptsReset) {
|
|
|
5005
5078
|
return true;
|
|
5006
5079
|
}
|
|
5007
5080
|
} catch (err) {
|
|
5008
|
-
opts.renderer.writeError(`[parallel] ${
|
|
5081
|
+
opts.renderer.writeError(`[parallel] ${toErrorMessage3(err)}`);
|
|
5009
5082
|
}
|
|
5010
5083
|
await new Promise((resolve4) => setTimeout(resolve4, 250));
|
|
5011
5084
|
return true;
|
|
@@ -5245,7 +5318,7 @@ ${lines.join("\n")}
|
|
|
5245
5318
|
if (res?.message) opts.renderer.write(`${res.message}
|
|
5246
5319
|
`);
|
|
5247
5320
|
} catch (err) {
|
|
5248
|
-
opts.renderer.writeError(
|
|
5321
|
+
opts.renderer.writeError(toErrorMessage4(err));
|
|
5249
5322
|
}
|
|
5250
5323
|
continue;
|
|
5251
5324
|
}
|
|
@@ -5337,7 +5410,7 @@ ${color11.dim(taskList2)}
|
|
|
5337
5410
|
}
|
|
5338
5411
|
}
|
|
5339
5412
|
} catch (err) {
|
|
5340
|
-
opts.renderer.writeError(
|
|
5413
|
+
opts.renderer.writeError(toErrorMessage4(err));
|
|
5341
5414
|
}
|
|
5342
5415
|
continue;
|
|
5343
5416
|
}
|
|
@@ -5616,7 +5689,7 @@ ${color11.dim(lines)}
|
|
|
5616
5689
|
}
|
|
5617
5690
|
}
|
|
5618
5691
|
} catch (err) {
|
|
5619
|
-
opts.renderer.writeError(
|
|
5692
|
+
opts.renderer.writeError(toErrorMessage4(err));
|
|
5620
5693
|
} finally {
|
|
5621
5694
|
activeCtrl = void 0;
|
|
5622
5695
|
}
|
|
@@ -5642,7 +5715,7 @@ async function pasteClipboardImage(builder, opts) {
|
|
|
5642
5715
|
opts.renderer.write(color11.dim(` \u21B3 ${placeholder} (PNG ${kb}KB)
|
|
5643
5716
|
`));
|
|
5644
5717
|
} catch (err) {
|
|
5645
|
-
opts.renderer.writeError(`Clipboard image error: ${
|
|
5718
|
+
opts.renderer.writeError(`Clipboard image error: ${toErrorMessage4(err)}`);
|
|
5646
5719
|
}
|
|
5647
5720
|
}
|
|
5648
5721
|
|
|
@@ -6554,6 +6627,10 @@ async function execute(deps) {
|
|
|
6554
6627
|
getBrainData,
|
|
6555
6628
|
onBrainRiskLevel,
|
|
6556
6629
|
brainPanelHost: brainRuntime ? createBrainPanelHost({ brainRuntime }) : void 0,
|
|
6630
|
+
subagentModelsHost: createSubagentModelsPanelHost({
|
|
6631
|
+
getContext: () => agent.ctx,
|
|
6632
|
+
getSessionTarget: () => ({ provider: config.provider, model: config.model })
|
|
6633
|
+
}),
|
|
6557
6634
|
getShadowData,
|
|
6558
6635
|
onShadowStart,
|
|
6559
6636
|
onShadowStop,
|
|
@@ -6840,4 +6917,4 @@ export {
|
|
|
6840
6917
|
execute,
|
|
6841
6918
|
resolveReviewerFallbackModels
|
|
6842
6919
|
};
|
|
6843
|
-
//# sourceMappingURL=execution-
|
|
6920
|
+
//# sourceMappingURL=execution-FJE27VQ6.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
normalizeHqPublicOrigin,
|
|
9
9
|
resolveAuditActor
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5EA6OTLJ.js";
|
|
11
11
|
import {
|
|
12
12
|
parseHqIpAllowlist
|
|
13
13
|
} from "./chunk-Q7E3BPDU.js";
|
|
@@ -62,7 +62,7 @@ var hqCmd = async (args, deps) => {
|
|
|
62
62
|
return 1;
|
|
63
63
|
};
|
|
64
64
|
async function startServer(deps) {
|
|
65
|
-
const { startHqServer } = await import("./hq-server-
|
|
65
|
+
const { startHqServer } = await import("./hq-server-G3VVVMIG.js");
|
|
66
66
|
const dataDir = resolveDataDir(deps);
|
|
67
67
|
const flags = deps.flags ?? {};
|
|
68
68
|
const rawPublicUrl = typeof flags["hq-public-url"] === "string" ? flags["hq-public-url"] : process.env.WRONGSTACK_HQ_PUBLIC_URL;
|
|
@@ -357,7 +357,9 @@ async function computeAuditHashField(dataDir, warn) {
|
|
|
357
357
|
return hash !== void 0 ? { contentHash: hash } : {};
|
|
358
358
|
}
|
|
359
359
|
var TOKEN_CAPABILITIES = {
|
|
360
|
-
|
|
360
|
+
// `control.approve` is grantable but never default — see
|
|
361
|
+
// DEFAULT_TOKEN_CAPABILITIES below.
|
|
362
|
+
browser: ["control.enqueue", "control.approve"],
|
|
361
363
|
client: ["telemetry.publish", "control.execute"]
|
|
362
364
|
};
|
|
363
365
|
var DEFAULT_TOKEN_CAPABILITIES = {
|
|
@@ -727,7 +729,7 @@ function printHelp(deps) {
|
|
|
727
729
|
`
|
|
728
730
|
);
|
|
729
731
|
deps.renderer.write(
|
|
730
|
-
` --capabilities <csv> Token grants (browser: control.enqueue; client: telemetry.publish,control.execute).
|
|
732
|
+
` --capabilities <csv> Token grants (browser: control.enqueue,control.approve; client: telemetry.publish,control.execute).
|
|
731
733
|
`
|
|
732
734
|
);
|
|
733
735
|
deps.renderer.write(
|
|
@@ -785,7 +787,7 @@ function printTokenHelp(deps) {
|
|
|
785
787
|
`
|
|
786
788
|
);
|
|
787
789
|
deps.renderer.write(
|
|
788
|
-
` --capabilities <csv> Comma-separated capability grants (browser: control.enqueue; client: telemetry.publish,control.execute).
|
|
790
|
+
` --capabilities <csv> Comma-separated capability grants (browser: control.enqueue,control.approve; client: telemetry.publish,control.execute).
|
|
789
791
|
`
|
|
790
792
|
);
|
|
791
793
|
deps.renderer.write(
|
|
@@ -827,4 +829,4 @@ export {
|
|
|
827
829
|
hqCmd,
|
|
828
830
|
resolveAuditActor
|
|
829
831
|
};
|
|
830
|
-
//# sourceMappingURL=hq-
|
|
832
|
+
//# sourceMappingURL=hq-G5PCP325.js.map
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import type { RemoteMailbox } from '@wrongstack/core/coordination';
|
|
19
19
|
import type { HqPublisherCommandResult } from '@wrongstack/core/hq';
|
|
20
|
+
import type { UserInputResponse } from '@wrongstack/core/types';
|
|
20
21
|
/**
|
|
21
22
|
* Mutable holder for the command dispatch targets. Each field is populated
|
|
22
23
|
* lazily as the corresponding subsystem comes online (director on
|
|
@@ -68,6 +69,20 @@ export interface HqCommandController {
|
|
|
68
69
|
ownsSession?: ((sessionId: string) => boolean) | undefined;
|
|
69
70
|
/** Whether raw shell execution is explicitly opted-in by the operator. */
|
|
70
71
|
allowRunCommand: () => boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Answer a permission prompt that is live on this host.
|
|
74
|
+
*
|
|
75
|
+
* Returns false when the prompt is no longer pending — it was answered at
|
|
76
|
+
* the keyboard, aborted, or timed out. HQ mirrors prompts rather than owning
|
|
77
|
+
* them, so losing the race is the normal case and must be reported back
|
|
78
|
+
* instead of silently swallowed.
|
|
79
|
+
*
|
|
80
|
+
* Bound to the process-wide approval registry
|
|
81
|
+
* (`createApprovalRegistry` in `@wrongstack/core/hq`), which is the only
|
|
82
|
+
* holder of the resolver closures.
|
|
83
|
+
*/
|
|
84
|
+
resolveApproval?: ((toolUseId: string, decision: 'yes' | 'no' | 'always' | 'deny', sessionId?: string | undefined) => boolean) | undefined;
|
|
85
|
+
resolveUserInput?: ((requestId: string, response: UserInputResponse, sessionId?: string | undefined) => boolean) | undefined;
|
|
71
86
|
/** Apply a lifecycle transition through the project's Kanban IPC client. */
|
|
72
87
|
kanbanTransition?: ((input: {
|
|
73
88
|
boardId: string;
|
|
@@ -6,6 +6,12 @@ export interface HqAuthState {
|
|
|
6
6
|
tokenStats(): NonNullable<HqSnapshot['totals']['tokenStats']>;
|
|
7
7
|
}
|
|
8
8
|
interface HqAuthStateOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The server's `requireBrowserAuth` option, stamped onto the state so every
|
|
11
|
+
* `hqAuthRequired(mutableAuth)` gate observes it without having to be handed
|
|
12
|
+
* it separately. See the field's doc on `HqRouterMutableAuth`.
|
|
13
|
+
*/
|
|
14
|
+
requireBrowserAuth?: boolean | undefined;
|
|
9
15
|
/**
|
|
10
16
|
* Invoked after every {@link HqAuthState.apply}, with the freshly projected
|
|
11
17
|
* `mutableAuth`. The server wires this to the WS-010 exposure re-assessment
|
package/dist/hq-server/auth.d.ts
CHANGED
|
@@ -38,7 +38,16 @@ export type HqBrowserAuthResult = HqBrowserAuthContext | HqCookieAuthContext | u
|
|
|
38
38
|
* inline style is not script execution.
|
|
39
39
|
*/
|
|
40
40
|
export declare function setHqSecurityHeaders(res: http.ServerResponse): void;
|
|
41
|
-
export declare function hasTrustedBrowserOrigin(req: http.IncomingMessage, boundHost?: string, boundPort?: number, trustedPublicOrigins?: ReadonlySet<string>, allowFileOrigin?: boolean
|
|
41
|
+
export declare function hasTrustedBrowserOrigin(req: http.IncomingMessage, boundHost?: string, boundPort?: number, trustedPublicOrigins?: ReadonlySet<string>, allowFileOrigin?: boolean,
|
|
42
|
+
/**
|
|
43
|
+
* Whether this surface has any credential configured — pass
|
|
44
|
+
* `hqAuthRequired(mutableAuth, requireBrowserAuth)`.
|
|
45
|
+
*
|
|
46
|
+
* Defaults to `false`, the STRICT side, deliberately: a caller that forgets
|
|
47
|
+
* to wire it gets the tighter rule rather than the looser one. That is the
|
|
48
|
+
* opposite of how the WS-077 gates drifted.
|
|
49
|
+
*/
|
|
50
|
+
credentialedSurface?: boolean): boolean;
|
|
42
51
|
export declare function serializeHqSessionCookie(sessionId: string, secret: string): string;
|
|
43
52
|
export declare function parseHqSessionCookie(value: string, secret: string): string | undefined;
|
|
44
53
|
export declare function parseCookieHeader(cookieHeader: string | undefined): Record<string, string>;
|
|
@@ -1,7 +1,41 @@
|
|
|
1
1
|
import type * as http from 'node:http';
|
|
2
2
|
import { type HqAuthFile } from '@wrongstack/core/hq';
|
|
3
3
|
import { type HqBrowserAuthResult } from '../../auth.js';
|
|
4
|
+
import type { LoginAttemptStore } from '../../login-attempt-store.js';
|
|
4
5
|
import type { HqRouterMutableAuth, HqSessionEntry } from '../../types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Record a failed second-factor confirmation and return the new failure count.
|
|
8
|
+
*
|
|
9
|
+
* Shared by every route that verifies a factor outside `/api/login`
|
|
10
|
+
* (totp/disable, password change). Kept here rather than copied per route: the
|
|
11
|
+
* whole point is that each of those routes feeds the SAME per-IP counter, so a
|
|
12
|
+
* attacker cannot get a fresh budget by switching endpoints.
|
|
13
|
+
*/
|
|
14
|
+
export declare function recordVerifyFailure(loginAttempts: LoginAttemptStore, clientIp: string): number;
|
|
15
|
+
/** Outcome of {@link consumeTotpCode}. */
|
|
16
|
+
export type TotpConsumeResult = 'ok' | 'invalid' | 'replayed';
|
|
17
|
+
/**
|
|
18
|
+
* Verify a TOTP code AND burn it, so it cannot be presented a second time.
|
|
19
|
+
*
|
|
20
|
+
* A TOTP code stays valid for its whole time step plus the verification
|
|
21
|
+
* window — roughly 90 seconds. Without a single-use record, one observed code
|
|
22
|
+
* can be replayed at a *different* endpoint for as long as that window lasts.
|
|
23
|
+
* That is not theoretical here: `/api/login/verify` advanced
|
|
24
|
+
* `totpLastUsedCounter` and the other two verification sites
|
|
25
|
+
* (`totp/disable`, `auth/password`) called the counter-less `verifyTotp`, so a
|
|
26
|
+
* code already spent on a login replayed into removing 2FA outright or
|
|
27
|
+
* rotating the password and cookie secret.
|
|
28
|
+
*
|
|
29
|
+
* Kept in this module for the same reason as {@link recordVerifyFailure}: the
|
|
30
|
+
* property only holds if EVERY site that verifies a code shares one counter.
|
|
31
|
+
* A route that verifies a TOTP code by any other means is a bug —
|
|
32
|
+
* `hq-totp-single-use.test.ts` enumerates the call sites to keep it that way.
|
|
33
|
+
*
|
|
34
|
+
* The counter is advanced in memory first and persisted best-effort, matching
|
|
35
|
+
* the pre-existing behaviour at `/api/login/verify`: a failed write must not
|
|
36
|
+
* turn a consumed code back into an unconsumed one for this process.
|
|
37
|
+
*/
|
|
38
|
+
export declare function consumeTotpCode(code: string, mutableAuth: HqRouterMutableAuth, dataDir: string, applyAuthFile: ApplyHqAuthFile): Promise<TotpConsumeResult>;
|
|
5
39
|
export declare function isLoopbackRequest(req: http.IncomingMessage): boolean;
|
|
6
40
|
export declare const HQ_AUTH_ADMIN_CAPABILITY = "auth.admin";
|
|
7
41
|
export declare function callerCanAdministerAuth(auth: HqBrowserAuthResult): boolean;
|
|
@@ -3,7 +3,9 @@ import type { LoginAttemptStore } from '../../login-attempt-store.js';
|
|
|
3
3
|
import type { HqRouterMutableAuth, HqSessionEntry } from '../../types.js';
|
|
4
4
|
import { type ApplyHqAuthFile } from './common.js';
|
|
5
5
|
export declare function handleApiAuthStatus(req: http.IncomingMessage, res: http.ServerResponse, url: URL, mutableAuth: HqRouterMutableAuth, sessions: Map<string, HqSessionEntry>, requireBrowserAuth: boolean | undefined, trustedPublicOrigins: Set<string>, secureCookies: boolean | undefined): Promise<void>;
|
|
6
|
-
export declare function handleApiLogin(req: http.IncomingMessage, res: http.ServerResponse, mutableAuth: HqRouterMutableAuth, sessions: Map<string, HqSessionEntry>, loginAttempts: LoginAttemptStore, secureCookies: boolean | undefined, trustedProxyHops: number,
|
|
6
|
+
export declare function handleApiLogin(req: http.IncomingMessage, res: http.ServerResponse, mutableAuth: HqRouterMutableAuth, sessions: Map<string, HqSessionEntry>, loginAttempts: LoginAttemptStore, secureCookies: boolean | undefined, trustedProxyHops: number,
|
|
7
|
+
/** Where `auth.json` lives — needed to persist a transparent KDF upgrade. */
|
|
8
|
+
dataDir: string, sessionCapabilities?: string[]): Promise<void>;
|
|
7
9
|
export declare function handleApiLogout(req: http.IncomingMessage, res: http.ServerResponse, mutableAuth: HqRouterMutableAuth, sessions: Map<string, HqSessionEntry>, secureCookies: boolean | undefined): Promise<void>;
|
|
8
|
-
export declare function handleApiPassword(req: http.IncomingMessage, res: http.ServerResponse, mutableAuth: HqRouterMutableAuth, sessions: Map<string, HqSessionEntry>, dataDir: string, secureCookies: boolean | undefined, requireBrowserAuth: boolean | undefined, applyAuthFile: ApplyHqAuthFile): Promise<void>;
|
|
10
|
+
export declare function handleApiPassword(req: http.IncomingMessage, res: http.ServerResponse, mutableAuth: HqRouterMutableAuth, sessions: Map<string, HqSessionEntry>, dataDir: string, secureCookies: boolean | undefined, requireBrowserAuth: boolean | undefined, applyAuthFile: ApplyHqAuthFile, loginAttempts: LoginAttemptStore, trustedProxyHops: number): Promise<void>;
|
|
9
11
|
//# sourceMappingURL=password-routes.d.ts.map
|
|
@@ -103,6 +103,24 @@ export interface HqRouterMutableAuth {
|
|
|
103
103
|
* the surface fails closed instead of opening up.
|
|
104
104
|
*/
|
|
105
105
|
requireAuthFloor?: boolean | undefined;
|
|
106
|
+
/**
|
|
107
|
+
* The server's `requireBrowserAuth` option, carried on the state rather than
|
|
108
|
+
* passed to every gate.
|
|
109
|
+
*
|
|
110
|
+
* `hqAuthRequired` takes it as an optional second argument, and five gates
|
|
111
|
+
* called it with one — `command-handlers`, three in `mailbox-handlers`, and
|
|
112
|
+
* `mailbox-gateway-manager` — so a public relay did not raise the auth
|
|
113
|
+
* requirement on those routes. That is the WS-077 drift class the helper's
|
|
114
|
+
* own docstring warns about, recurring on the same routes. Holding the value
|
|
115
|
+
* on the state makes the one-argument call correct instead of incomplete.
|
|
116
|
+
*
|
|
117
|
+
* Required, not optional, and deliberately so. Optional would mean a second
|
|
118
|
+
* construction site could omit it and every one-argument gate would silently
|
|
119
|
+
* read `undefined` — the same drift this field exists to end, one level down.
|
|
120
|
+
* With `exactOptionalPropertyTypes` the compiler now makes every builder say
|
|
121
|
+
* what it means, including `undefined`.
|
|
122
|
+
*/
|
|
123
|
+
requireBrowserAuth: boolean | undefined;
|
|
106
124
|
}
|
|
107
125
|
/**
|
|
108
126
|
* Session record stored in the server-side `sessions` Map.
|
|
@@ -10,9 +10,9 @@ import {
|
|
|
10
10
|
readLocalSubagentTranscript,
|
|
11
11
|
sanitizeApiError,
|
|
12
12
|
startHqServer
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-XIZZ2EXG.js";
|
|
14
14
|
import "./chunk-HXJYHAR4.js";
|
|
15
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-5EA6OTLJ.js";
|
|
16
16
|
import "./chunk-Q7E3BPDU.js";
|
|
17
17
|
export {
|
|
18
18
|
DEFAULT_HOST,
|
|
@@ -27,4 +27,4 @@ export {
|
|
|
27
27
|
sanitizeApiError,
|
|
28
28
|
startHqServer
|
|
29
29
|
};
|
|
30
|
-
//# sourceMappingURL=hq-server-
|
|
30
|
+
//# sourceMappingURL=hq-server-G3VVVMIG.js.map
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
applyNodeEnvDefault,
|
|
4
4
|
applySessionShellDefault
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-672UXYL3.js";
|
|
6
6
|
import {
|
|
7
7
|
CLI_VERSION
|
|
8
8
|
} from "./chunk-XJXDOF63.js";
|
|
@@ -16,20 +16,21 @@ async function main(argv) {
|
|
|
16
16
|
applySessionShellDefault();
|
|
17
17
|
const earlyFlags = parseArgs(argv).flags;
|
|
18
18
|
if (earlyFlags["help"] === true || earlyFlags["version"] === true) {
|
|
19
|
-
const { handleHelpVersionShortCircuit } = await import("./short-circuit-flags-
|
|
19
|
+
const { handleHelpVersionShortCircuit } = await import("./short-circuit-flags-RAT6UZVI.js");
|
|
20
20
|
const earlyExit = await handleHelpVersionShortCircuit(argv);
|
|
21
21
|
if (earlyExit !== null) return earlyExit;
|
|
22
22
|
}
|
|
23
|
-
const { initializeCli } = await import("./cli-context-
|
|
23
|
+
const { initializeCli } = await import("./cli-context-TIAP6YQK.js");
|
|
24
24
|
const cliCtx = await initializeCli(argv);
|
|
25
25
|
if (typeof cliCtx === "number") return cliCtx;
|
|
26
|
-
const { runInteractive } = await import("./cli-main-
|
|
26
|
+
const { runInteractive } = await import("./cli-main-AKJHDSHX.js");
|
|
27
27
|
return runInteractive(cliCtx);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// src/cli-entry-point.ts
|
|
31
31
|
import { resolve } from "node:path";
|
|
32
32
|
import { pathToFileURL } from "node:url";
|
|
33
|
+
import { scrubErrorText } from "@wrongstack/core/security";
|
|
33
34
|
import { installCrashShield, runFatalSalvageSync, writeErr } from "@wrongstack/core/utils";
|
|
34
35
|
var SQLITE_WARNING_RE = /sqlite is an experimental feature/i;
|
|
35
36
|
function installSqliteWarningFilter() {
|
|
@@ -128,7 +129,9 @@ function runAsMain(mainFn) {
|
|
|
128
129
|
},
|
|
129
130
|
(err) => {
|
|
130
131
|
runFatalSalvageSync();
|
|
131
|
-
writeErr(
|
|
132
|
+
writeErr(
|
|
133
|
+
scrubErrorText(err instanceof Error ? err.stack ?? err.message : String(err)) + "\n"
|
|
134
|
+
);
|
|
132
135
|
process.exitCode = 1;
|
|
133
136
|
scheduleForcedExit(1);
|
|
134
137
|
}
|
package/dist/input-reader.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { InputReader, PromptOption } from '@wrongstack/core/types';
|
|
1
|
+
import type { InputReader, PromptOption, ReadKeyOptions } from '@wrongstack/core/types';
|
|
2
2
|
interface ReadlineInputReaderOptions {
|
|
3
3
|
historyFile?: string | undefined;
|
|
4
4
|
prompt?: string | undefined;
|
|
@@ -30,7 +30,7 @@ export declare class ReadlineInputReader implements InputReader {
|
|
|
30
30
|
* protect and the ANSI clear/repaint would be noise in a file.
|
|
31
31
|
*/
|
|
32
32
|
private installPromptGuard;
|
|
33
|
-
readKey(prompt: string, options: PromptOption[]): Promise<string>;
|
|
33
|
+
readKey(prompt: string, options: PromptOption[], opts?: ReadKeyOptions): Promise<string>;
|
|
34
34
|
/**
|
|
35
35
|
* Read a line of input while masking each character with a bullet so the
|
|
36
36
|
* user gets visual confirmation that bytes are arriving (especially on
|