@wrongstack/cli 0.308.6 → 0.309.0
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/{chunk-KV6DNQT6.js → chunk-BZJ4MP32.js} +24 -30
- package/dist/{chunk-RK7E3IXT.js → chunk-H6C7SO5H.js} +499 -13
- package/dist/{cli-main-HCCYX3D5.js → cli-main-RG2PTQ6S.js} +865 -597
- package/dist/{execution-6HIKTAUB.js → execution-TYUXABWI.js} +51 -2
- package/dist/fleet/host-explore-companion.d.ts +43 -0
- package/dist/fleet/host.d.ts +5 -0
- package/dist/index.js +6 -6
- package/dist/plugin-management.d.ts +9 -0
- package/dist/{plugin-usage-PTEETL3J.js → plugin-usage-26LIIW3P.js} +2 -2
- package/dist/{plugins-XRGWC3NJ.js → plugins-EEKHCMBE.js} +3 -3
- package/dist/{providers-models-4FAKM2WO.js → providers-models-D23WUD74.js} +2 -2
- package/dist/slash-commands/effort.d.ts +33 -0
- package/dist/wiring/external-plugins.d.ts +58 -0
- package/dist/wiring/plugins.d.ts +8 -0
- package/package.json +25 -25
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
} from "./chunk-T6YAVFXA.js";
|
|
28
28
|
import {
|
|
29
29
|
setupPlugins
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-BZJ4MP32.js";
|
|
31
31
|
import {
|
|
32
32
|
startCliHqConnection
|
|
33
33
|
} from "./chunk-FKWHSFX4.js";
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
import {
|
|
45
45
|
PLUGIN_AUDIT_ENTRIES,
|
|
46
46
|
runPluginManagementCommand
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-H6C7SO5H.js";
|
|
48
48
|
import {
|
|
49
49
|
configureSimpleUiRuntimeContext,
|
|
50
50
|
detectProjectFacts,
|
|
@@ -113,7 +113,7 @@ import {
|
|
|
113
113
|
|
|
114
114
|
// src/cli-main.ts
|
|
115
115
|
import * as path32 from "node:path";
|
|
116
|
-
import { FLEET_ROSTER as FLEET_ROSTER6, mailboxSessionTag as
|
|
116
|
+
import { FLEET_ROSTER as FLEET_ROSTER6, mailboxSessionTag as mailboxSessionTag6 } from "@wrongstack/core/coordination";
|
|
117
117
|
import { TOKENS as TOKENS12 } from "@wrongstack/core/kernel";
|
|
118
118
|
import { getSessionRegistry } from "@wrongstack/core/storage";
|
|
119
119
|
import { writeErr as writeErr3 } from "@wrongstack/core/utils";
|
|
@@ -1704,7 +1704,7 @@ function subscribeBrainDecisionLog(events) {
|
|
|
1704
1704
|
}
|
|
1705
1705
|
|
|
1706
1706
|
// src/fleet/host.ts
|
|
1707
|
-
import { randomUUID as
|
|
1707
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
1708
1708
|
import {
|
|
1709
1709
|
createProjectAgentRoster
|
|
1710
1710
|
} from "@wrongstack/core/agent-catalog";
|
|
@@ -2359,6 +2359,62 @@ function createHostStatusBroadcaster(input) {
|
|
|
2359
2359
|
});
|
|
2360
2360
|
}
|
|
2361
2361
|
|
|
2362
|
+
// src/fleet/host-explore-companion.ts
|
|
2363
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
2364
|
+
import {
|
|
2365
|
+
buildProbeTaskText,
|
|
2366
|
+
DEFAULT_EXPLORE_COMPANION_AGENT_ID,
|
|
2367
|
+
ExploreCompanion,
|
|
2368
|
+
getSharedProjectMailbox as getSharedProjectMailbox3,
|
|
2369
|
+
mailboxSessionTag as mailboxSessionTag2
|
|
2370
|
+
} from "@wrongstack/core/coordination";
|
|
2371
|
+
function createHostExploreCompanion(input) {
|
|
2372
|
+
const { director, events, sessionId, mailboxProjectDir, roster, config } = input;
|
|
2373
|
+
if (config?.enabled === false) return null;
|
|
2374
|
+
const sessionTag = mailboxSessionTag2(sessionId);
|
|
2375
|
+
const mailbox = () => getSharedProjectMailbox3(mailboxProjectDir, events);
|
|
2376
|
+
const template = roster[DEFAULT_EXPLORE_COMPANION_AGENT_ID];
|
|
2377
|
+
let residentId;
|
|
2378
|
+
const ensureResident = async () => {
|
|
2379
|
+
if (residentId) {
|
|
2380
|
+
const alive = director.status().subagents.some((s) => s.id === residentId);
|
|
2381
|
+
if (alive) return residentId;
|
|
2382
|
+
residentId = void 0;
|
|
2383
|
+
}
|
|
2384
|
+
if (!template) throw new Error("explore-companion role missing from roster");
|
|
2385
|
+
const subagentId = await director.spawn({
|
|
2386
|
+
...template,
|
|
2387
|
+
id: `explore-companion-${sessionTag}`,
|
|
2388
|
+
name: "Explore Companion"
|
|
2389
|
+
});
|
|
2390
|
+
residentId = subagentId;
|
|
2391
|
+
return subagentId;
|
|
2392
|
+
};
|
|
2393
|
+
const options = {
|
|
2394
|
+
events,
|
|
2395
|
+
mailbox: mailbox(),
|
|
2396
|
+
leaderSessionId: sessionId,
|
|
2397
|
+
leaderAgentId: "leader",
|
|
2398
|
+
onProbe: async (probe) => {
|
|
2399
|
+
const subagentId = await ensureResident();
|
|
2400
|
+
const taskId = randomUUID2();
|
|
2401
|
+
await director.assignInternal({
|
|
2402
|
+
id: taskId,
|
|
2403
|
+
description: buildProbeTaskText(probe),
|
|
2404
|
+
subagentId
|
|
2405
|
+
});
|
|
2406
|
+
return { subagentId, taskId };
|
|
2407
|
+
},
|
|
2408
|
+
cooldownMs: config?.cooldownMs,
|
|
2409
|
+
maxPending: config?.maxPending,
|
|
2410
|
+
pollIntervalMs: config?.pollIntervalMs,
|
|
2411
|
+
companionAgentId: `${DEFAULT_EXPLORE_COMPANION_AGENT_ID}@${sessionTag}`
|
|
2412
|
+
};
|
|
2413
|
+
const companion = new ExploreCompanion(options);
|
|
2414
|
+
companion.start();
|
|
2415
|
+
return companion;
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2362
2418
|
// src/fleet/host-learning-scheduler.ts
|
|
2363
2419
|
import {
|
|
2364
2420
|
LearningOptimizationScheduler,
|
|
@@ -3003,7 +3059,7 @@ function aggregateFleetUsage(completed) {
|
|
|
3003
3059
|
}
|
|
3004
3060
|
|
|
3005
3061
|
// src/fleet/host-subagent-factory.ts
|
|
3006
|
-
import { randomUUID as
|
|
3062
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
3007
3063
|
import { existsSync, statSync } from "node:fs";
|
|
3008
3064
|
import * as path6 from "node:path";
|
|
3009
3065
|
import {
|
|
@@ -3021,7 +3077,7 @@ import {
|
|
|
3021
3077
|
import {
|
|
3022
3078
|
DEFAULT_SUBAGENT_BASELINE,
|
|
3023
3079
|
FLEET_ROSTER,
|
|
3024
|
-
getSharedProjectMailbox as
|
|
3080
|
+
getSharedProjectMailbox as getSharedProjectMailbox4,
|
|
3025
3081
|
resolveSubagentModelTarget as resolveSubagentModelTarget2
|
|
3026
3082
|
} from "@wrongstack/core/coordination";
|
|
3027
3083
|
import { installDesignStudioMiddleware } from "@wrongstack/core/design";
|
|
@@ -3464,7 +3520,7 @@ ${message} Falling back to the assigned checkout.` : `${message} Falling back to
|
|
|
3464
3520
|
}
|
|
3465
3521
|
let onlineAgents = [];
|
|
3466
3522
|
try {
|
|
3467
|
-
const subagentMailbox =
|
|
3523
|
+
const subagentMailbox = getSharedProjectMailbox4(host.mailboxProjectDir());
|
|
3468
3524
|
onlineAgents = await subagentMailbox.getAgentStatuses();
|
|
3469
3525
|
} catch {
|
|
3470
3526
|
}
|
|
@@ -3531,7 +3587,7 @@ ${audienceMemory.map((text) => `- ${text}`).join("\n")}`
|
|
|
3531
3587
|
if (rolePrompt) {
|
|
3532
3588
|
baseSystem.push({ type: "text", text: rolePrompt });
|
|
3533
3589
|
}
|
|
3534
|
-
const subagentName = effectiveCfg.id ?? effectiveCfg.name ?? `sub_${
|
|
3590
|
+
const subagentName = effectiveCfg.id ?? effectiveCfg.name ?? `sub_${randomUUID3().slice(0, 8)}`;
|
|
3535
3591
|
if (effectiveCfg.role) {
|
|
3536
3592
|
host.recordLearningRole(subagentName, effectiveCfg.role, skillResolution.selected);
|
|
3537
3593
|
}
|
|
@@ -3680,12 +3736,12 @@ ${audienceMemory.map((text) => `- ${text}`).join("\n")}`
|
|
|
3680
3736
|
}
|
|
3681
3737
|
|
|
3682
3738
|
// src/fleet/host-supervisor.ts
|
|
3683
|
-
import { randomUUID as
|
|
3739
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
3684
3740
|
import {
|
|
3685
3741
|
dispatchAgent,
|
|
3686
3742
|
FleetSupervisor,
|
|
3687
|
-
getSharedProjectMailbox as
|
|
3688
|
-
mailboxSessionTag as
|
|
3743
|
+
getSharedProjectMailbox as getSharedProjectMailbox5,
|
|
3744
|
+
mailboxSessionTag as mailboxSessionTag3
|
|
3689
3745
|
} from "@wrongstack/core/coordination";
|
|
3690
3746
|
import { toErrorMessage as toErrorMessage2 } from "@wrongstack/core/utils/error";
|
|
3691
3747
|
|
|
@@ -3711,8 +3767,8 @@ function createHostFleetSupervisor(input) {
|
|
|
3711
3767
|
getLeaderMailboxId
|
|
3712
3768
|
} = input;
|
|
3713
3769
|
if (!director || !brain || supervisorConfig?.enabled === false) return null;
|
|
3714
|
-
const supTag = () =>
|
|
3715
|
-
const mailbox = () =>
|
|
3770
|
+
const supTag = () => mailboxSessionTag3(sessionId);
|
|
3771
|
+
const mailbox = () => getSharedProjectMailbox5(mailboxProjectDir, events);
|
|
3716
3772
|
const supervisor = new FleetSupervisor({
|
|
3717
3773
|
events,
|
|
3718
3774
|
fleet: director.fleet,
|
|
@@ -3738,7 +3794,7 @@ function createHostFleetSupervisor(input) {
|
|
|
3738
3794
|
].filter((part) => typeof part === "string" && part.trim().length > 0).join("\n\n");
|
|
3739
3795
|
const subagentId = await director.spawn({
|
|
3740
3796
|
...template ?? { name: "fleet helper", role: "executor" },
|
|
3741
|
-
id: `helper-${
|
|
3797
|
+
id: `helper-${randomUUID4().slice(0, 8)}`,
|
|
3742
3798
|
name: `fleet helper (${routed.role})`,
|
|
3743
3799
|
role: routed.role,
|
|
3744
3800
|
systemPromptOverride: helperPrompt
|
|
@@ -3780,8 +3836,8 @@ function createHostFleetSupervisor(input) {
|
|
|
3780
3836
|
// src/fleet/host-task-result-report.ts
|
|
3781
3837
|
import {
|
|
3782
3838
|
formatSubagentStructuredReport,
|
|
3783
|
-
getSharedProjectMailbox as
|
|
3784
|
-
mailboxSessionTag as
|
|
3839
|
+
getSharedProjectMailbox as getSharedProjectMailbox6,
|
|
3840
|
+
mailboxSessionTag as mailboxSessionTag4
|
|
3785
3841
|
} from "@wrongstack/core/coordination";
|
|
3786
3842
|
async function reportTaskResultToLeader({
|
|
3787
3843
|
notification: n,
|
|
@@ -3791,8 +3847,8 @@ async function reportTaskResultToLeader({
|
|
|
3791
3847
|
getLeaderMailboxId
|
|
3792
3848
|
}) {
|
|
3793
3849
|
try {
|
|
3794
|
-
const leaderId2 = getLeaderMailboxId?.() ?? `leader@${
|
|
3795
|
-
const mailbox =
|
|
3850
|
+
const leaderId2 = getLeaderMailboxId?.() ?? `leader@${mailboxSessionTag4(sessionId)}`;
|
|
3851
|
+
const mailbox = getSharedProjectMailbox6(mailboxProjectDir, events);
|
|
3796
3852
|
const ok = n.status === "success";
|
|
3797
3853
|
const MAX_BODY = 700;
|
|
3798
3854
|
const failureText = [
|
|
@@ -3895,6 +3951,11 @@ var MultiAgentHost = class {
|
|
|
3895
3951
|
* buildDirector() (when a BrainArbiter is available), stopped in
|
|
3896
3952
|
* dispose(). Also published to the supervisor registry for /supervisor. */
|
|
3897
3953
|
fleetSupervisor = null;
|
|
3954
|
+
/** ExploreCompanion — state-triggered background codebase explorer behind
|
|
3955
|
+
* the leader. Built in buildDirector() (unless disabled via
|
|
3956
|
+
* fleet.exploreCompanion.enabled=false), stopped in dispose(). Probes are
|
|
3957
|
+
* assigned to a lazily-spawned resident `explore-companion` subagent. */
|
|
3958
|
+
exploreCompanion = null;
|
|
3898
3959
|
/** Built-ins plus lazily-resolved project-created roles. */
|
|
3899
3960
|
roster;
|
|
3900
3961
|
/** Live roster surface shared by spawn_subagent and the blocking delegate tool. */
|
|
@@ -4009,6 +4070,14 @@ var MultiAgentHost = class {
|
|
|
4009
4070
|
});
|
|
4010
4071
|
this.statusBroadcaster.start();
|
|
4011
4072
|
this.buildFleetSupervisor(config);
|
|
4073
|
+
this.exploreCompanion = createHostExploreCompanion({
|
|
4074
|
+
director: this.director,
|
|
4075
|
+
events: this.deps.events,
|
|
4076
|
+
sessionId: this.deps.session.id,
|
|
4077
|
+
mailboxProjectDir: this.mailboxProjectDir(),
|
|
4078
|
+
roster: this.roster,
|
|
4079
|
+
config: config.fleet?.exploreCompanion
|
|
4080
|
+
});
|
|
4012
4081
|
this.directorOffHandles.push(
|
|
4013
4082
|
...registerDirectorBudgetAndContextBridges({
|
|
4014
4083
|
director: this.director,
|
|
@@ -4096,7 +4165,7 @@ var MultiAgentHost = class {
|
|
|
4096
4165
|
return this.acpRunnerCache.get(subagentId);
|
|
4097
4166
|
}
|
|
4098
4167
|
async spawnACP(subagentId, task, config) {
|
|
4099
|
-
const taskId =
|
|
4168
|
+
const taskId = randomUUID5();
|
|
4100
4169
|
await this.ensureCoordinator(config);
|
|
4101
4170
|
const coordinator = this.getCoordinator();
|
|
4102
4171
|
const acpRunner = await this.buildACPRunner(subagentId);
|
|
@@ -4208,7 +4277,7 @@ var MultiAgentHost = class {
|
|
|
4208
4277
|
return result;
|
|
4209
4278
|
}
|
|
4210
4279
|
async _spawnAndAssign(subagentConfig, description = "", opts) {
|
|
4211
|
-
const taskId =
|
|
4280
|
+
const taskId = randomUUID5();
|
|
4212
4281
|
if (!this.director)
|
|
4213
4282
|
throw new AgentError({
|
|
4214
4283
|
message: "Director is not initialized",
|
|
@@ -4354,6 +4423,8 @@ var MultiAgentHost = class {
|
|
|
4354
4423
|
this.fleetSupervisor?.stop();
|
|
4355
4424
|
if (this.fleetSupervisor) setActiveFleetSupervisor(null);
|
|
4356
4425
|
this.fleetSupervisor = null;
|
|
4426
|
+
this.exploreCompanion?.stop();
|
|
4427
|
+
this.exploreCompanion = null;
|
|
4357
4428
|
this.adaptiveConcurrencyController?.dispose();
|
|
4358
4429
|
this.adaptiveConcurrencyController = void 0;
|
|
4359
4430
|
if (this.director) {
|
|
@@ -4412,7 +4483,7 @@ function setupBrainAndOrchestration(deps) {
|
|
|
4412
4483
|
cwd,
|
|
4413
4484
|
wpaths,
|
|
4414
4485
|
teardownHandlers,
|
|
4415
|
-
mailboxSessionTag:
|
|
4486
|
+
mailboxSessionTag: mailboxSessionTag7,
|
|
4416
4487
|
brainMailbox,
|
|
4417
4488
|
agentMonitor,
|
|
4418
4489
|
manifestPath,
|
|
@@ -4565,9 +4636,9 @@ function setupBrainAndOrchestration(deps) {
|
|
|
4565
4636
|
// trigger corrective steers to the leader agent.
|
|
4566
4637
|
leaderSessionId: () => context.session?.id ?? session.id,
|
|
4567
4638
|
intervene: async ({ subject, body }) => {
|
|
4568
|
-
const leaderUniqueId = `leader@${
|
|
4639
|
+
const leaderUniqueId = `leader@${mailboxSessionTag7(session.id)}`;
|
|
4569
4640
|
await brainMailbox.send({
|
|
4570
|
-
from: `brain@${
|
|
4641
|
+
from: `brain@${mailboxSessionTag7(session.id)}`,
|
|
4571
4642
|
to: leaderUniqueId,
|
|
4572
4643
|
type: "steer",
|
|
4573
4644
|
subject,
|
|
@@ -5573,7 +5644,7 @@ async function runCliExecution(params) {
|
|
|
5573
5644
|
governanceHandle,
|
|
5574
5645
|
setConfig
|
|
5575
5646
|
} = params;
|
|
5576
|
-
const { execute } = await import("./execution-
|
|
5647
|
+
const { execute } = await import("./execution-TYUXABWI.js");
|
|
5577
5648
|
return execute(
|
|
5578
5649
|
toExecuteDeps({
|
|
5579
5650
|
core: {
|
|
@@ -6156,7 +6227,7 @@ ${res.out}` };
|
|
|
6156
6227
|
const orchestrator = new PhaseOrchestrator({
|
|
6157
6228
|
graph,
|
|
6158
6229
|
ctx: {
|
|
6159
|
-
executeTask: async (task, phaseId, env) => {
|
|
6230
|
+
executeTask: async (task, phaseId, env, signal) => {
|
|
6160
6231
|
const phase = graph.phases.get(phaseId);
|
|
6161
6232
|
const phaseName = phase?.name ?? phaseId;
|
|
6162
6233
|
let agentName = task.assignee;
|
|
@@ -6169,7 +6240,7 @@ ${res.out}` };
|
|
|
6169
6240
|
return runOnce(
|
|
6170
6241
|
buildTaskPrompt(task, phaseName, goal),
|
|
6171
6242
|
`goal-${agentName}`.slice(0, 48),
|
|
6172
|
-
abort.signal,
|
|
6243
|
+
signal ? AbortSignal.any([abort.signal, signal]) : abort.signal,
|
|
6173
6244
|
env?.cwd
|
|
6174
6245
|
);
|
|
6175
6246
|
},
|
|
@@ -6284,7 +6355,7 @@ ${res.out}` };
|
|
|
6284
6355
|
const orchestrator = new PhaseOrchestrator({
|
|
6285
6356
|
graph,
|
|
6286
6357
|
ctx: {
|
|
6287
|
-
executeTask: async (task, phaseId, env) => {
|
|
6358
|
+
executeTask: async (task, phaseId, env, signal) => {
|
|
6288
6359
|
const phase = graph.phases.get(phaseId);
|
|
6289
6360
|
const phaseName = phase?.name ?? phaseId;
|
|
6290
6361
|
let agentName = task.assignee;
|
|
@@ -6297,7 +6368,7 @@ ${res.out}` };
|
|
|
6297
6368
|
return runOnce(
|
|
6298
6369
|
buildTaskPrompt(task, phaseName, title),
|
|
6299
6370
|
"goal-" + agentName.slice(0, 48),
|
|
6300
|
-
abort.signal,
|
|
6371
|
+
signal ? AbortSignal.any([abort.signal, signal]) : abort.signal,
|
|
6301
6372
|
env?.cwd
|
|
6302
6373
|
);
|
|
6303
6374
|
},
|
|
@@ -8937,7 +9008,7 @@ ${color13.dim("YOLO enabled; tool calls run without approval unless an explicit
|
|
|
8937
9008
|
}
|
|
8938
9009
|
|
|
8939
9010
|
// src/slash-commands/brain.ts
|
|
8940
|
-
import { randomUUID as
|
|
9011
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
8941
9012
|
import { color as color16 } from "@wrongstack/core/utils";
|
|
8942
9013
|
|
|
8943
9014
|
// src/slash-commands/brain-council.ts
|
|
@@ -9547,7 +9618,7 @@ function buildBrainCommand(opts) {
|
|
|
9547
9618
|
}
|
|
9548
9619
|
try {
|
|
9549
9620
|
const decision = await opts.brain.decide({
|
|
9550
|
-
id: `brain-ask-${
|
|
9621
|
+
id: `brain-ask-${randomUUID6()}`,
|
|
9551
9622
|
sessionId: opts.context?.session.id,
|
|
9552
9623
|
source: "user",
|
|
9553
9624
|
question,
|
|
@@ -11925,7 +11996,7 @@ function buildDoctorCommand(opts) {
|
|
|
11925
11996
|
].join("\n");
|
|
11926
11997
|
async function loadPluginSchemas() {
|
|
11927
11998
|
try {
|
|
11928
|
-
const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-
|
|
11999
|
+
const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-EEKHCMBE.js");
|
|
11929
12000
|
const settled = await Promise.allSettled(BUILTIN_PLUGIN_FACTORIES.map((f) => f()));
|
|
11930
12001
|
const loaded = [];
|
|
11931
12002
|
for (const s of settled) {
|
|
@@ -15740,7 +15811,7 @@ function buildKanbanAgentPrompt(board, task, assignment) {
|
|
|
15740
15811
|
const dependencyLines = (task.dependsOn ?? []).map((depId) => board.tasks.find((candidate) => candidate.id === depId)).filter((dep) => Boolean(dep)).map((dep) => `- ${dep.title} [${dep.status}] (${dep.id})`);
|
|
15741
15812
|
const checks = task.successCriteria?.map((check) => `- ${check.description}`).join("\n");
|
|
15742
15813
|
const metrics = task.goalMetrics?.map(
|
|
15743
|
-
(metric) => `- ${metric.name}: ${metric.current ?? "n/a"}${metric.target !== void 0 ? ` / ${metric.target}` : ""}${metric.unit ? ` ${metric.unit}` : ""} [${metric.status}]`
|
|
15814
|
+
(metric) => `- ${metric.name}: ${metric.current ?? "n/a"}${metric.target !== void 0 ? ` / ${metric.direction === "at_most" ? "\u2264" : "\u2265"} ${metric.target}` : ""}${metric.unit ? ` ${metric.unit}` : ""} [${metric.status}]`
|
|
15744
15815
|
).join("\n");
|
|
15745
15816
|
const chain = task.chain ? [
|
|
15746
15817
|
`chainId: ${task.chain.chainId}`,
|
|
@@ -16648,8 +16719,8 @@ function buildKanbanCommand(opts) {
|
|
|
16648
16719
|
|
|
16649
16720
|
// src/slash-commands/mailbox.ts
|
|
16650
16721
|
import {
|
|
16651
|
-
getSharedProjectMailbox as
|
|
16652
|
-
mailboxSessionTag as
|
|
16722
|
+
getSharedProjectMailbox as getSharedProjectMailbox7,
|
|
16723
|
+
mailboxSessionTag as mailboxSessionTag5,
|
|
16653
16724
|
resolveMailboxIdentity,
|
|
16654
16725
|
resolveProjectDir as resolveProjectDir2
|
|
16655
16726
|
} from "@wrongstack/core/coordination";
|
|
@@ -16657,7 +16728,7 @@ import { color as color37, wstackGlobalRoot as wstackGlobalRoot2 } from "@wrongs
|
|
|
16657
16728
|
function buildMailbox(opts) {
|
|
16658
16729
|
const projectDir = opts.paths?.projectDir ?? resolveProjectDir2(opts.projectRoot, wstackGlobalRoot2());
|
|
16659
16730
|
try {
|
|
16660
|
-
return
|
|
16731
|
+
return getSharedProjectMailbox7(projectDir);
|
|
16661
16732
|
} catch {
|
|
16662
16733
|
return null;
|
|
16663
16734
|
}
|
|
@@ -16667,7 +16738,7 @@ function leaderId(opts) {
|
|
|
16667
16738
|
const identity = resolveMailboxIdentity(opts.context);
|
|
16668
16739
|
return { id: identity.callerId, base: identity.baseId };
|
|
16669
16740
|
}
|
|
16670
|
-
return { id: `leader@${
|
|
16741
|
+
return { id: `leader@${mailboxSessionTag5("default")}`, base: "leader" };
|
|
16671
16742
|
}
|
|
16672
16743
|
function fmtAge3(iso) {
|
|
16673
16744
|
const ms = Date.now() - new Date(iso).getTime();
|
|
@@ -16977,7 +17048,7 @@ function buildMailboxCommand(opts) {
|
|
|
16977
17048
|
|
|
16978
17049
|
// src/slash-commands/mailbox-demo.ts
|
|
16979
17050
|
import {
|
|
16980
|
-
getSharedProjectMailbox as
|
|
17051
|
+
getSharedProjectMailbox as getSharedProjectMailbox8,
|
|
16981
17052
|
resolveProjectDir as resolveProjectDir3
|
|
16982
17053
|
} from "@wrongstack/core/coordination";
|
|
16983
17054
|
import { wstackGlobalRoot as wstackGlobalRoot3 } from "@wrongstack/core/utils";
|
|
@@ -16985,7 +17056,7 @@ var DEMO_AGENT_ID = "mailbox-demo";
|
|
|
16985
17056
|
function buildMailbox2(opts) {
|
|
16986
17057
|
const projectDir = opts.paths?.projectDir ?? resolveProjectDir3(opts.projectRoot, wstackGlobalRoot3());
|
|
16987
17058
|
try {
|
|
16988
|
-
return
|
|
17059
|
+
return getSharedProjectMailbox8(projectDir);
|
|
16989
17060
|
} catch {
|
|
16990
17061
|
return null;
|
|
16991
17062
|
}
|
|
@@ -22895,7 +22966,9 @@ import {
|
|
|
22895
22966
|
} from "@wrongstack/core/coordination";
|
|
22896
22967
|
import { decryptConfigSecrets as decryptConfigSecrets4, encryptConfigSecrets as encryptConfigSecrets4, noOpVault as noOpVault6 } from "@wrongstack/core/security";
|
|
22897
22968
|
import {
|
|
22898
|
-
ConfigError as ConfigError5
|
|
22969
|
+
ConfigError as ConfigError5,
|
|
22970
|
+
REASONING_EFFORT_LEVELS,
|
|
22971
|
+
isReasoningEffort
|
|
22899
22972
|
} from "@wrongstack/core/types";
|
|
22900
22973
|
import { atomicWrite as atomicWrite8, color as color48, expectDefined as expectDefined6, toErrorMessage as toErrorMessage21 } from "@wrongstack/core/utils";
|
|
22901
22974
|
import { catalogProviderIdFor } from "@wrongstack/providers";
|
|
@@ -22950,18 +23023,6 @@ function parseTarget(tokens, profiles = {}) {
|
|
|
22950
23023
|
}
|
|
22951
23024
|
return { model: only };
|
|
22952
23025
|
}
|
|
22953
|
-
var REASONING_EFFORTS = [
|
|
22954
|
-
"none",
|
|
22955
|
-
"minimal",
|
|
22956
|
-
"low",
|
|
22957
|
-
"medium",
|
|
22958
|
-
"high",
|
|
22959
|
-
"xhigh",
|
|
22960
|
-
"max"
|
|
22961
|
-
];
|
|
22962
|
-
function isReasoningEffort(value) {
|
|
22963
|
-
return !!value && REASONING_EFFORTS.includes(value);
|
|
22964
|
-
}
|
|
22965
23026
|
function isReasoningMode(value) {
|
|
22966
23027
|
return value === "auto" || value === "on" || value === "off";
|
|
22967
23028
|
}
|
|
@@ -23339,7 +23400,7 @@ function buildSetModelCommand(opts) {
|
|
|
23339
23400
|
const key = parts[1];
|
|
23340
23401
|
if (!key) {
|
|
23341
23402
|
return {
|
|
23342
|
-
message: `${color48.amber("Usage:")} /setmodel ${sub} <role|phase|*> ${sub === "reasoning" ? "auto|on|off [effort]" : sub === "reasoning-effort" ?
|
|
23403
|
+
message: `${color48.amber("Usage:")} /setmodel ${sub} <role|phase|*> ${sub === "reasoning" ? "auto|on|off [effort]" : sub === "reasoning-effort" ? REASONING_EFFORT_LEVELS.join("|") : "on|off"}`
|
|
23343
23404
|
};
|
|
23344
23405
|
}
|
|
23345
23406
|
if (matrixKeyKind(key) === "unknown") {
|
|
@@ -23360,7 +23421,7 @@ function buildSetModelCommand(opts) {
|
|
|
23360
23421
|
if (parts[3] !== void 0) {
|
|
23361
23422
|
if (!isReasoningEffort(parts[3])) {
|
|
23362
23423
|
return {
|
|
23363
|
-
message: `${color48.red("Invalid effort")}: "${parts[3]}". Expected ${
|
|
23424
|
+
message: `${color48.red("Invalid effort")}: "${parts[3]}". Expected ${REASONING_EFFORT_LEVELS.join(", ")}.`
|
|
23364
23425
|
};
|
|
23365
23426
|
}
|
|
23366
23427
|
nextEffort = parts[3];
|
|
@@ -23368,7 +23429,7 @@ function buildSetModelCommand(opts) {
|
|
|
23368
23429
|
} else if (sub === "reasoning-effort") {
|
|
23369
23430
|
if (!isReasoningEffort(parts[2])) {
|
|
23370
23431
|
return {
|
|
23371
|
-
message: `${color48.amber("Usage:")} /setmodel reasoning-effort ${key} ${
|
|
23432
|
+
message: `${color48.amber("Usage:")} /setmodel reasoning-effort ${key} ${REASONING_EFFORT_LEVELS.join("|")}`
|
|
23372
23433
|
};
|
|
23373
23434
|
}
|
|
23374
23435
|
nextEffort = parts[2];
|
|
@@ -23478,11 +23539,213 @@ function buildSetModelCommand(opts) {
|
|
|
23478
23539
|
};
|
|
23479
23540
|
}
|
|
23480
23541
|
|
|
23542
|
+
// src/slash-commands/effort.ts
|
|
23543
|
+
import { decryptConfigSecrets as decryptConfigSecrets5, encryptConfigSecrets as encryptConfigSecrets5, noOpVault as noOpVault7 } from "@wrongstack/core/security";
|
|
23544
|
+
import {
|
|
23545
|
+
isReasoningEffort as isReasoningEffort2,
|
|
23546
|
+
REASONING_EFFORT_LEVELS as REASONING_EFFORT_LEVELS2
|
|
23547
|
+
} from "@wrongstack/core/types";
|
|
23548
|
+
import { atomicWrite as atomicWrite9, color as color49 } from "@wrongstack/core/utils";
|
|
23549
|
+
import { catalogProviderIdFor as catalogProviderIdFor2 } from "@wrongstack/providers";
|
|
23550
|
+
import * as fs14 from "node:fs/promises";
|
|
23551
|
+
function buildEffortCommand(opts) {
|
|
23552
|
+
const levelsHint = REASONING_EFFORT_LEVELS2.join("|");
|
|
23553
|
+
const help = [
|
|
23554
|
+
"Usage:",
|
|
23555
|
+
" /effort Show current session effort + supported levels",
|
|
23556
|
+
` /effort <level> Set session effort (${levelsHint})`,
|
|
23557
|
+
" /effort clear Remove the setting \u2014 provider default applies",
|
|
23558
|
+
" /effort matrix Show per-role/phase effort overrides (/setmodel)",
|
|
23559
|
+
"",
|
|
23560
|
+
"Applies to the active model on the next request. Unsupported values for the",
|
|
23561
|
+
"current model are rejected up front when its capabilities are known.",
|
|
23562
|
+
"Per-subagent overrides: /setmodel reasoning-effort <role|phase|*> <level>."
|
|
23563
|
+
].join("\n");
|
|
23564
|
+
async function loadModelLevels() {
|
|
23565
|
+
const registry = opts.modelsRegistry;
|
|
23566
|
+
if (!registry) return { levels: void 0, supported: void 0 };
|
|
23567
|
+
const config = opts.configStore.get();
|
|
23568
|
+
try {
|
|
23569
|
+
const catalogId = catalogProviderIdFor2(
|
|
23570
|
+
config.provider,
|
|
23571
|
+
config.providers?.[config.provider]?.type
|
|
23572
|
+
);
|
|
23573
|
+
const resolved = await registry.getModel(catalogId, config.model);
|
|
23574
|
+
const rc = resolved?.capabilities.reasoningConfig;
|
|
23575
|
+
if (!rc) {
|
|
23576
|
+
const provider = await registry.getProvider(catalogId).catch(() => void 0);
|
|
23577
|
+
const raw = provider?.models.find((m) => m.id === config.model);
|
|
23578
|
+
return { levels: void 0, supported: raw?.reasoning === false ? false : void 0 };
|
|
23579
|
+
}
|
|
23580
|
+
return {
|
|
23581
|
+
levels: rc.effortLevels?.length ? rc.effortLevels : void 0,
|
|
23582
|
+
// rc present ⇒ the model is known to reason. Only a DOCUMENTED
|
|
23583
|
+
// absence (`effortSupported === false`) marks it unsupported; an
|
|
23584
|
+
// undocumented vocabulary (`undefined`) is "supported, not
|
|
23585
|
+
// enumerated" — accept any canonical level and let the wire adapter
|
|
23586
|
+
// gate. `undefined` here is reserved for capabilities-unknown above.
|
|
23587
|
+
supported: rc.effortSupported !== false
|
|
23588
|
+
};
|
|
23589
|
+
} catch {
|
|
23590
|
+
return { levels: void 0, supported: void 0 };
|
|
23591
|
+
}
|
|
23592
|
+
}
|
|
23593
|
+
return {
|
|
23594
|
+
name: "effort",
|
|
23595
|
+
category: "Config",
|
|
23596
|
+
description: "View or set the session-wide reasoning effort for the active model.",
|
|
23597
|
+
argsHint: `[${levelsHint}|clear|matrix]`,
|
|
23598
|
+
help,
|
|
23599
|
+
async run(args) {
|
|
23600
|
+
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
23601
|
+
const sub = (parts[0] ?? "").toLowerCase();
|
|
23602
|
+
if (sub === "help" || sub === "--help") return { message: help };
|
|
23603
|
+
if (!opts.configStore || !opts.paths) {
|
|
23604
|
+
return { message: `${color49.red("Error")} config store not available.` };
|
|
23605
|
+
}
|
|
23606
|
+
const config = opts.configStore.get();
|
|
23607
|
+
if (sub === "matrix") {
|
|
23608
|
+
const matrix = config.modelMatrix ?? {};
|
|
23609
|
+
const entries = Object.entries(matrix).filter(([, e]) => e?.modelRuntime?.reasoning);
|
|
23610
|
+
if (entries.length === 0) {
|
|
23611
|
+
return {
|
|
23612
|
+
message: [
|
|
23613
|
+
`${color49.bold("Effort overrides")} ${color49.dim("(model matrix)")}`,
|
|
23614
|
+
` ${color49.dim("(none \u2014 set one with /setmodel reasoning-effort <role|phase|*> <level>)")}`
|
|
23615
|
+
].join("\n")
|
|
23616
|
+
};
|
|
23617
|
+
}
|
|
23618
|
+
const lines = [`${color49.bold("Effort overrides")} ${color49.dim("(model matrix)")}`];
|
|
23619
|
+
for (const [key, entry] of entries.sort(([a], [b]) => a.localeCompare(b))) {
|
|
23620
|
+
const reasoning = entry.modelRuntime.reasoning;
|
|
23621
|
+
const bits = [
|
|
23622
|
+
reasoning.effort ? `effort:${reasoning.effort}` : "",
|
|
23623
|
+
reasoning.mode ? `mode:${reasoning.mode}` : "",
|
|
23624
|
+
reasoning.preserve !== void 0 ? `preserve:${reasoning.preserve ? "on" : "off"}` : ""
|
|
23625
|
+
].filter(Boolean);
|
|
23626
|
+
lines.push(` ${color49.amber(key.padEnd(22))} \u2192 ${bits.join(" ")}`);
|
|
23627
|
+
}
|
|
23628
|
+
return { message: lines.join("\n") };
|
|
23629
|
+
}
|
|
23630
|
+
const { levels, supported } = await loadModelLevels();
|
|
23631
|
+
const current = config.modelRuntime?.reasoning?.effort;
|
|
23632
|
+
if (!sub) {
|
|
23633
|
+
const lines = [
|
|
23634
|
+
`${color49.bold("WrongStack")} ${color49.dim("\u2014 Session effort")}`,
|
|
23635
|
+
"",
|
|
23636
|
+
` ${color49.bold("model")} ${color49.cyan(`${config.provider}/${config.model}`)}`
|
|
23637
|
+
];
|
|
23638
|
+
if (current) {
|
|
23639
|
+
const ok = !levels || levels.includes(current);
|
|
23640
|
+
lines.push(
|
|
23641
|
+
` ${color49.bold("effort")} ${color49.bold(current)}${ok ? "" : ` ${color49.amber(`(not advertised by this model \u2014 supported: ${levels.join(", ")})`)}`}`
|
|
23642
|
+
);
|
|
23643
|
+
} else {
|
|
23644
|
+
lines.push(` ${color49.bold("effort")} ${color49.dim("(not set \u2014 provider default)")}`);
|
|
23645
|
+
}
|
|
23646
|
+
if (levels) {
|
|
23647
|
+
const rendered = REASONING_EFFORT_LEVELS2.filter((l) => levels.includes(l)).map(
|
|
23648
|
+
(l) => l === current ? color49.bold(l) : l
|
|
23649
|
+
);
|
|
23650
|
+
lines.push(` ${color49.bold("levels")} ${rendered.join(" \xB7 ")}`);
|
|
23651
|
+
} else if (supported === true) {
|
|
23652
|
+
lines.push(
|
|
23653
|
+
` ${color49.bold("levels")} ${color49.dim("(not enumerated \u2014 any level is accepted; the transport applies its own gating)")}`
|
|
23654
|
+
);
|
|
23655
|
+
} else if (supported === false) {
|
|
23656
|
+
lines.push(
|
|
23657
|
+
` ${color49.bold("levels")} ${color49.red("no effort control")}${color49.dim(" \u2014 documented as unsupported for this model")}`
|
|
23658
|
+
);
|
|
23659
|
+
} else {
|
|
23660
|
+
lines.push(
|
|
23661
|
+
` ${color49.bold("levels")} ${color49.dim("(unknown \u2014 the resolver drops unsupported values with a warning)")}`
|
|
23662
|
+
);
|
|
23663
|
+
}
|
|
23664
|
+
lines.push(
|
|
23665
|
+
"",
|
|
23666
|
+
` ${color49.dim("/effort <level> \xB7 clear \xB7 matrix \xB7 help")}`
|
|
23667
|
+
);
|
|
23668
|
+
return { message: lines.join("\n") };
|
|
23669
|
+
}
|
|
23670
|
+
if (sub === "clear" || sub === "off-default") {
|
|
23671
|
+
if (current === void 0) {
|
|
23672
|
+
return { message: `${color49.dim("No session effort set \u2014 provider default already applies.")}` };
|
|
23673
|
+
}
|
|
23674
|
+
await patchSessionEffort(void 0, opts.paths, config.activeProfile ?? "default");
|
|
23675
|
+
opts.configStore.update({
|
|
23676
|
+
modelRuntime: {
|
|
23677
|
+
...config.modelRuntime,
|
|
23678
|
+
reasoning: { ...config.modelRuntime?.reasoning, effort: void 0 }
|
|
23679
|
+
}
|
|
23680
|
+
});
|
|
23681
|
+
return {
|
|
23682
|
+
message: `${color49.green("\u2713")} session effort cleared ${color49.dim("\u2014 provider default applies")}`
|
|
23683
|
+
};
|
|
23684
|
+
}
|
|
23685
|
+
if (!isReasoningEffort2(sub)) {
|
|
23686
|
+
return {
|
|
23687
|
+
message: `${color49.amber("Usage:")} /effort ${REASONING_EFFORT_LEVELS2.join("|")} | clear | matrix`
|
|
23688
|
+
};
|
|
23689
|
+
}
|
|
23690
|
+
if (supported === false) {
|
|
23691
|
+
return {
|
|
23692
|
+
message: [
|
|
23693
|
+
`${color49.red("No effort control")} for ${config.provider}/${config.model}: the catalog documents this model's reasoning options without effort levels.`,
|
|
23694
|
+
` ${color49.dim("/effort clear removes the setting")}`
|
|
23695
|
+
].join("\n")
|
|
23696
|
+
};
|
|
23697
|
+
}
|
|
23698
|
+
if (levels && !levels.includes(sub)) {
|
|
23699
|
+
return {
|
|
23700
|
+
message: [
|
|
23701
|
+
`${color49.red("Unsupported effort")} for ${config.provider}/${config.model}: "${sub}".`,
|
|
23702
|
+
` ${color49.dim(`advertised: ${levels.join(", ")}`)}`,
|
|
23703
|
+
` ${color49.dim("the resolver would drop this value with a warning \u2014 pick an advertised level, or /effort clear")}`
|
|
23704
|
+
].join("\n")
|
|
23705
|
+
};
|
|
23706
|
+
}
|
|
23707
|
+
await patchSessionEffort(sub, opts.paths, config.activeProfile ?? "default");
|
|
23708
|
+
opts.configStore.update({
|
|
23709
|
+
modelRuntime: {
|
|
23710
|
+
...config.modelRuntime,
|
|
23711
|
+
reasoning: { ...config.modelRuntime?.reasoning, effort: sub }
|
|
23712
|
+
}
|
|
23713
|
+
});
|
|
23714
|
+
return {
|
|
23715
|
+
message: `${color49.green("\u2713")} session effort \u2192 ${color49.bold(sub)} ${color49.dim(`(${config.provider}/${config.model}, next request)`)}`
|
|
23716
|
+
};
|
|
23717
|
+
}
|
|
23718
|
+
};
|
|
23719
|
+
}
|
|
23720
|
+
async function patchSessionEffort(effort, paths, activeProfile) {
|
|
23721
|
+
const targetPath = paths.profileConfig(activeProfile);
|
|
23722
|
+
let raw = "{}";
|
|
23723
|
+
try {
|
|
23724
|
+
raw = await fs14.readFile(targetPath, "utf8");
|
|
23725
|
+
} catch {
|
|
23726
|
+
}
|
|
23727
|
+
let parsed;
|
|
23728
|
+
try {
|
|
23729
|
+
parsed = JSON.parse(raw);
|
|
23730
|
+
} catch {
|
|
23731
|
+
parsed = {};
|
|
23732
|
+
}
|
|
23733
|
+
const decrypted = decryptConfigSecrets5(parsed, noOpVault7);
|
|
23734
|
+
const mr = decrypted.modelRuntime ?? {};
|
|
23735
|
+
const reasoning = { ...mr.reasoning ?? {} };
|
|
23736
|
+
if (effort === void 0) delete reasoning.effort;
|
|
23737
|
+
else reasoning.effort = effort;
|
|
23738
|
+
mr.reasoning = reasoning;
|
|
23739
|
+
decrypted.modelRuntime = mr;
|
|
23740
|
+
const encrypted = encryptConfigSecrets5(decrypted, noOpVault7);
|
|
23741
|
+
await atomicWrite9(targetPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
23742
|
+
}
|
|
23743
|
+
|
|
23481
23744
|
// src/slash-commands/suggest.ts
|
|
23482
23745
|
import { execFile as execFile2 } from "node:child_process";
|
|
23483
23746
|
import { access as access3 } from "node:fs/promises";
|
|
23484
23747
|
import * as path16 from "node:path";
|
|
23485
|
-
import { color as
|
|
23748
|
+
import { color as color50, toErrorMessage as toErrorMessage22 } from "@wrongstack/core/utils";
|
|
23486
23749
|
import { parseNextSteps } from "@wrongstack/tools/next-steps";
|
|
23487
23750
|
function readGitStatus(projectRoot, includeBranch) {
|
|
23488
23751
|
const args = ["status", "--short"];
|
|
@@ -23574,7 +23837,7 @@ function buildSuggestCommand(opts) {
|
|
|
23574
23837
|
const suggestions = await generateHeuristicSuggestions(opts);
|
|
23575
23838
|
setSuggestions(suggestions);
|
|
23576
23839
|
opts.onSuggestions?.(suggestions);
|
|
23577
|
-
const display = formatSuggestions(suggestions) + "\n" +
|
|
23840
|
+
const display = formatSuggestions(suggestions) + "\n" + color50.dim("(Heuristic fallback \u2014 multi-agent not enabled)");
|
|
23578
23841
|
return { message: display };
|
|
23579
23842
|
}
|
|
23580
23843
|
if (!fresh && suggestCache && Date.now() - suggestCache.at < SUGGEST_CACHE_TTL_MS) {
|
|
@@ -23582,7 +23845,7 @@ function buildSuggestCommand(opts) {
|
|
|
23582
23845
|
opts.onSuggestions?.(suggestCache.suggestions);
|
|
23583
23846
|
const ageSec = Math.round((Date.now() - suggestCache.at) / 1e3);
|
|
23584
23847
|
return {
|
|
23585
|
-
message: formatSuggestions(suggestCache.suggestions) + "\n" +
|
|
23848
|
+
message: formatSuggestions(suggestCache.suggestions) + "\n" + color50.dim(`(cached ${ageSec}s ago \u2014 /suggest --fresh to regenerate)`)
|
|
23586
23849
|
};
|
|
23587
23850
|
}
|
|
23588
23851
|
const contextText = await collectContext({
|
|
@@ -23590,7 +23853,7 @@ function buildSuggestCommand(opts) {
|
|
|
23590
23853
|
projectRoot: opts.projectRoot
|
|
23591
23854
|
});
|
|
23592
23855
|
const task = buildSuggestPrompt(contextText);
|
|
23593
|
-
opts.renderer.write(
|
|
23856
|
+
opts.renderer.write(color50.dim("Generating suggestions..."));
|
|
23594
23857
|
try {
|
|
23595
23858
|
const raw = await opts.onSpawnAndWait(task, {
|
|
23596
23859
|
name: "suggest"
|
|
@@ -23685,14 +23948,14 @@ async function generateHeuristicSuggestions(opts) {
|
|
|
23685
23948
|
}
|
|
23686
23949
|
function formatSuggestions(suggestions) {
|
|
23687
23950
|
if (suggestions.length === 0) {
|
|
23688
|
-
return
|
|
23951
|
+
return color50.dim("No suggestions available.");
|
|
23689
23952
|
}
|
|
23690
23953
|
const lines = [
|
|
23691
|
-
` ${
|
|
23954
|
+
` ${color50.cyan("\u{1F4A1} Next steps")} ${color50.dim("(use /next 1, /next 2, or /next 1 2 3)")}`,
|
|
23692
23955
|
""
|
|
23693
23956
|
];
|
|
23694
23957
|
for (let i = 0; i < suggestions.length; i++) {
|
|
23695
|
-
const num =
|
|
23958
|
+
const num = color50.bold(`${i + 1}.`);
|
|
23696
23959
|
const text = suggestions[i] ?? "";
|
|
23697
23960
|
lines.push(` ${num} ${text}`);
|
|
23698
23961
|
}
|
|
@@ -23759,7 +24022,7 @@ function buildWebuiCommand() {
|
|
|
23759
24022
|
|
|
23760
24023
|
// src/slash-commands/theme.ts
|
|
23761
24024
|
import { THEME_PRESET_IDS } from "@wrongstack/core/types";
|
|
23762
|
-
import { color as
|
|
24025
|
+
import { color as color51, writeOut as writeOut3 } from "@wrongstack/core/utils";
|
|
23763
24026
|
var THEME_META = {
|
|
23764
24027
|
catppuccin: { name: "Catppuccin Mocha", desc: "Soft pastel dark theme (Default)" },
|
|
23765
24028
|
"tokyo-night": { name: "Tokyo Night", desc: "Deep violet, neon orange & cyan" },
|
|
@@ -23870,19 +24133,19 @@ async function runThemePicker(reader, activeId) {
|
|
|
23870
24133
|
);
|
|
23871
24134
|
const lines = [];
|
|
23872
24135
|
lines.push("");
|
|
23873
|
-
lines.push(`${
|
|
23874
|
-
lines.push(
|
|
24136
|
+
lines.push(`${color51.bold(color51.amber("WrongStack") + color51.dim(" \u2014 TUI Theme Selection"))}`);
|
|
24137
|
+
lines.push(color51.dim(" \u2191\u2193 navigate Enter select q quit"));
|
|
23875
24138
|
lines.push("");
|
|
23876
|
-
if (hasAbove) lines.push(
|
|
24139
|
+
if (hasAbove) lines.push(color51.dim(` \u2026 ${start} more above`));
|
|
23877
24140
|
for (let i = start; i < end; i++) {
|
|
23878
24141
|
const p = THEME_OPTIONS[i];
|
|
23879
|
-
const mark = p.id === activeId ?
|
|
23880
|
-
const prefix = i === currentCursor ?
|
|
23881
|
-
const name = i === currentCursor ?
|
|
24142
|
+
const mark = p.id === activeId ? color51.green(" [active]") : "";
|
|
24143
|
+
const prefix = i === currentCursor ? color51.bold("\u276F ") : " ";
|
|
24144
|
+
const name = i === currentCursor ? color51.bold(p.name) : p.name;
|
|
23882
24145
|
const desc = truncateDesc(p.desc, columns, p.id === activeId);
|
|
23883
|
-
lines.push(` ${prefix}${name.padEnd(21)} ${
|
|
24146
|
+
lines.push(` ${prefix}${name.padEnd(21)} ${color51.dim(desc)}${mark}`);
|
|
23884
24147
|
}
|
|
23885
|
-
if (hasBelow) lines.push(
|
|
24148
|
+
if (hasBelow) lines.push(color51.dim(` \u2026 ${THEME_OPTIONS.length - end} more below`));
|
|
23886
24149
|
lines.push("");
|
|
23887
24150
|
return lines.join("\n");
|
|
23888
24151
|
};
|
|
@@ -23937,21 +24200,21 @@ function buildThemeCommand(opts) {
|
|
|
23937
24200
|
}
|
|
23938
24201
|
}
|
|
23939
24202
|
return {
|
|
23940
|
-
message:
|
|
24203
|
+
message: color51.green(`Switched TUI theme preset to "${selected}" (saved to config).`),
|
|
23941
24204
|
metadata: { themePreset: selected }
|
|
23942
24205
|
};
|
|
23943
24206
|
}
|
|
23944
24207
|
const lines = [
|
|
23945
|
-
|
|
24208
|
+
color51.bold(`Current TUI theme: ${activePreset}`),
|
|
23946
24209
|
"",
|
|
23947
|
-
|
|
24210
|
+
color51.bold("Available Theme Presets:")
|
|
23948
24211
|
];
|
|
23949
24212
|
for (const t of THEME_OPTIONS) {
|
|
23950
|
-
const mark = t.id === activePreset ?
|
|
23951
|
-
lines.push(` \u2022 ${
|
|
24213
|
+
const mark = t.id === activePreset ? color51.green(" [active]") : "";
|
|
24214
|
+
lines.push(` \u2022 ${color51.bold(t.id.padEnd(21))} ${t.desc}${mark}`);
|
|
23952
24215
|
}
|
|
23953
24216
|
lines.push("");
|
|
23954
|
-
lines.push(
|
|
24217
|
+
lines.push(color51.dim("Usage: /theme <preset>"));
|
|
23955
24218
|
return { message: lines.join("\n") };
|
|
23956
24219
|
}
|
|
23957
24220
|
const preset = args.trim().toLowerCase();
|
|
@@ -23967,7 +24230,7 @@ function buildThemeCommand(opts) {
|
|
|
23967
24230
|
}
|
|
23968
24231
|
}
|
|
23969
24232
|
return {
|
|
23970
|
-
message:
|
|
24233
|
+
message: color51.green(`Switched TUI theme preset to "${preset}" (saved to config).`),
|
|
23971
24234
|
metadata: { themePreset: preset }
|
|
23972
24235
|
};
|
|
23973
24236
|
}
|
|
@@ -23975,7 +24238,7 @@ function buildThemeCommand(opts) {
|
|
|
23975
24238
|
}
|
|
23976
24239
|
|
|
23977
24240
|
// src/slash-commands/agents.ts
|
|
23978
|
-
import { noOpVault as
|
|
24241
|
+
import { noOpVault as noOpVault8 } from "@wrongstack/core/security";
|
|
23979
24242
|
function formatAgentLine(a) {
|
|
23980
24243
|
const statusIcon3 = {
|
|
23981
24244
|
spawned: "\u{1F7E2}",
|
|
@@ -24056,7 +24319,7 @@ function buildAgentsCommand(opts) {
|
|
|
24056
24319
|
configStore: opts.configStore,
|
|
24057
24320
|
profileConfigPath: opts.paths.profileConfig(activeProfile),
|
|
24058
24321
|
inProjectConfigPath: opts.paths.inProjectConfig,
|
|
24059
|
-
vault:
|
|
24322
|
+
vault: noOpVault8
|
|
24060
24323
|
},
|
|
24061
24324
|
(autonomy) => {
|
|
24062
24325
|
autonomy.fleetChatVerbosity = mode;
|
|
@@ -24214,8 +24477,8 @@ ${lines.join("\n")}` };
|
|
|
24214
24477
|
|
|
24215
24478
|
// src/slash-commands/hq.ts
|
|
24216
24479
|
import { readHqRuntimeFileSync, resolveHqConfig, resolveHqDataDir } from "@wrongstack/core/hq";
|
|
24217
|
-
import { noOpVault as
|
|
24218
|
-
import { color as
|
|
24480
|
+
import { noOpVault as noOpVault9 } from "@wrongstack/core/security";
|
|
24481
|
+
import { color as color52 } from "@wrongstack/core/utils";
|
|
24219
24482
|
function maskToken(t) {
|
|
24220
24483
|
if (t.length <= 10) return `${t.slice(0, 2)}\u2026(${t.length})`;
|
|
24221
24484
|
return `${t.slice(0, 6)}\u2026${t.slice(-4)} (${t.length} chars)`;
|
|
@@ -24226,12 +24489,12 @@ async function probeHq(url) {
|
|
|
24226
24489
|
const timer = setTimeout(() => ctrl.abort(), 2500);
|
|
24227
24490
|
const res = await fetch(url, { signal: ctrl.signal, redirect: "manual" }).catch(() => null);
|
|
24228
24491
|
clearTimeout(timer);
|
|
24229
|
-
if (!res) return
|
|
24230
|
-
if (res.ok) return
|
|
24231
|
-
if (res.status === 401) return
|
|
24232
|
-
return
|
|
24492
|
+
if (!res) return color52.red("unreachable");
|
|
24493
|
+
if (res.ok) return color52.green("reachable");
|
|
24494
|
+
if (res.status === 401) return color52.green("reachable") + color52.dim(" (token required)");
|
|
24495
|
+
return color52.amber(`reachable (HTTP ${res.status})`);
|
|
24233
24496
|
} catch {
|
|
24234
|
-
return
|
|
24497
|
+
return color52.red("unreachable");
|
|
24235
24498
|
}
|
|
24236
24499
|
}
|
|
24237
24500
|
function buildHqCommand(opts) {
|
|
@@ -24265,13 +24528,13 @@ function buildHqCommand(opts) {
|
|
|
24265
24528
|
const { cmd, rest } = parseSubcommand(args);
|
|
24266
24529
|
const sub = cmd;
|
|
24267
24530
|
if (!opts.configStore || !opts.paths) {
|
|
24268
|
-
return { message: `${
|
|
24531
|
+
return { message: `${color52.red("\u2717")} HQ config is unavailable in this surface.` };
|
|
24269
24532
|
}
|
|
24270
24533
|
const persistDeps = {
|
|
24271
24534
|
configStore: opts.configStore,
|
|
24272
24535
|
profileConfigPath: activeProfileConfigPath(opts.paths, opts.configStore.get()),
|
|
24273
24536
|
inProjectConfigPath: opts.paths.inProjectConfig,
|
|
24274
|
-
vault:
|
|
24537
|
+
vault: noOpVault9,
|
|
24275
24538
|
forceGlobal: true
|
|
24276
24539
|
};
|
|
24277
24540
|
const currentHq = opts.configStore.get().hq;
|
|
@@ -24279,14 +24542,14 @@ function buildHqCommand(opts) {
|
|
|
24279
24542
|
const url = (rest[0] ?? "").trim();
|
|
24280
24543
|
const token = rest.slice(1).join(" ").trim();
|
|
24281
24544
|
if (!url) {
|
|
24282
|
-
return { message: `${
|
|
24545
|
+
return { message: `${color52.amber("Usage:")} /hq set <http://host:3499> [client-token]` };
|
|
24283
24546
|
}
|
|
24284
24547
|
try {
|
|
24285
24548
|
const parsed = new URL(url);
|
|
24286
24549
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new Error("proto");
|
|
24287
24550
|
} catch {
|
|
24288
24551
|
return {
|
|
24289
|
-
message: `${
|
|
24552
|
+
message: `${color52.red("Invalid URL:")} ${url} ${color52.dim("(expected http://host:3499)")}`
|
|
24290
24553
|
};
|
|
24291
24554
|
}
|
|
24292
24555
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -24298,16 +24561,16 @@ function buildHqCommand(opts) {
|
|
|
24298
24561
|
});
|
|
24299
24562
|
const reach = await probeHq(url);
|
|
24300
24563
|
const tokLine = token ? `
|
|
24301
|
-
token: ${
|
|
24564
|
+
token: ${color52.dim(maskToken(token))}` : "";
|
|
24302
24565
|
return {
|
|
24303
|
-
message: `${
|
|
24566
|
+
message: `${color52.green("\u2713")} HQ set \u2192 ${color52.cyan(url)}${tokLine}
|
|
24304
24567
|
status: ${reach}
|
|
24305
|
-
${
|
|
24568
|
+
${color52.dim("Connects on the next session start.")}`
|
|
24306
24569
|
};
|
|
24307
24570
|
}
|
|
24308
24571
|
if (sub === "token") {
|
|
24309
24572
|
const token = rest.join(" ").trim();
|
|
24310
|
-
if (!token) return { message: `${
|
|
24573
|
+
if (!token) return { message: `${color52.amber("Usage:")} /hq token <client-token>` };
|
|
24311
24574
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
24312
24575
|
const hq = cfg.hq ?? {};
|
|
24313
24576
|
hq.token = token;
|
|
@@ -24315,14 +24578,14 @@ function buildHqCommand(opts) {
|
|
|
24315
24578
|
cfg.hq = hq;
|
|
24316
24579
|
});
|
|
24317
24580
|
return {
|
|
24318
|
-
message: `${
|
|
24581
|
+
message: `${color52.green("\u2713")} HQ client token saved ${color52.dim(maskToken(token))}`
|
|
24319
24582
|
};
|
|
24320
24583
|
}
|
|
24321
24584
|
if (sub === "raw") {
|
|
24322
24585
|
const mode = (rest[0] ?? "").trim().toLowerCase();
|
|
24323
24586
|
if (mode !== "on" && mode !== "off") {
|
|
24324
24587
|
return {
|
|
24325
|
-
message: `${
|
|
24588
|
+
message: `${color52.amber("Usage:")} /hq raw on|off ${color52.dim("(publish raw chat/tool content to HQ)")}`
|
|
24326
24589
|
};
|
|
24327
24590
|
}
|
|
24328
24591
|
const on = mode === "on";
|
|
@@ -24332,8 +24595,8 @@ function buildHqCommand(opts) {
|
|
|
24332
24595
|
cfg.hq = hq;
|
|
24333
24596
|
});
|
|
24334
24597
|
return {
|
|
24335
|
-
message: `${
|
|
24336
|
-
${
|
|
24598
|
+
message: `${color52.green("\u2713")} HQ raw content \u2192 ${on ? color52.amber("on (unredacted)") : color52.dim("off (redacted)")}
|
|
24599
|
+
${color52.dim("Applies to sessions started after this change. Only enable for HQ servers you trust.")}`
|
|
24337
24600
|
};
|
|
24338
24601
|
}
|
|
24339
24602
|
if (sub === "on" || sub === "off") {
|
|
@@ -24344,29 +24607,29 @@ function buildHqCommand(opts) {
|
|
|
24344
24607
|
cfg.hq = hq;
|
|
24345
24608
|
});
|
|
24346
24609
|
return {
|
|
24347
|
-
message: `${
|
|
24610
|
+
message: `${color52.green("\u2713")} HQ publishing \u2192 ${on ? color52.cyan("on") : color52.dim("off")}`
|
|
24348
24611
|
};
|
|
24349
24612
|
}
|
|
24350
24613
|
if (sub === "clear") {
|
|
24351
24614
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
24352
24615
|
delete cfg.hq;
|
|
24353
24616
|
});
|
|
24354
|
-
return { message: `${
|
|
24617
|
+
return { message: `${color52.green("\u2713")} HQ configuration cleared.` };
|
|
24355
24618
|
}
|
|
24356
24619
|
if (sub === "" || sub === "status") {
|
|
24357
24620
|
const dataDir = resolveHqDataDir(currentHq?.dataDir);
|
|
24358
24621
|
const runtime = readHqRuntimeFileSync(dataDir);
|
|
24359
24622
|
const resolved = resolveHqConfig({ config: currentHq });
|
|
24360
|
-
const lines = [`${
|
|
24623
|
+
const lines = [`${color52.bold("\u{1F4CB} WrongStack HQ \u2014 connection")}`, ""];
|
|
24361
24624
|
if (!resolved) {
|
|
24362
24625
|
lines.push(
|
|
24363
|
-
` ${
|
|
24626
|
+
` ${color52.dim("Not configured.")} Use ${color52.cyan("/hq set <url> [token]")} to connect,`
|
|
24364
24627
|
);
|
|
24365
|
-
lines.push(` or run ${
|
|
24628
|
+
lines.push(` or run ${color52.cyan("wstack --hq")} locally (auto-discovered).`);
|
|
24366
24629
|
if (runtime) {
|
|
24367
24630
|
lines.push("");
|
|
24368
24631
|
lines.push(
|
|
24369
|
-
` ${
|
|
24632
|
+
` ${color52.green("A local HQ is running")} at ${color52.cyan(runtime.url)} ${color52.dim("(start a new session to attach)")}`
|
|
24370
24633
|
);
|
|
24371
24634
|
}
|
|
24372
24635
|
const message = lines.join("\n");
|
|
@@ -24374,35 +24637,35 @@ function buildHqCommand(opts) {
|
|
|
24374
24637
|
}
|
|
24375
24638
|
if (resolved.discover && !runtime) {
|
|
24376
24639
|
lines.push(
|
|
24377
|
-
` mode: ${
|
|
24640
|
+
` mode: ${color52.cyan("auto-discovery")} ${color52.dim("(no local HQ running yet)")}`
|
|
24378
24641
|
);
|
|
24379
24642
|
lines.push(
|
|
24380
|
-
` ${
|
|
24643
|
+
` ${color52.dim("This session will attach automatically when `wstack --hq` starts")}`
|
|
24381
24644
|
);
|
|
24382
|
-
lines.push(` ${
|
|
24383
|
-
lines.push(` ${
|
|
24645
|
+
lines.push(` ${color52.dim(`on this machine (watching ${dataDir}).`)}`);
|
|
24646
|
+
lines.push(` ${color52.dim("Disable with WRONGSTACK_HQ_ENABLED=0 or /hq off.")}`);
|
|
24384
24647
|
return { message: lines.join("\n") };
|
|
24385
24648
|
}
|
|
24386
24649
|
const source = process.env["WRONGSTACK_HQ_URL"] ? "WRONGSTACK_HQ_URL env" : currentHq?.url ? "config.json" : runtime ? `local HQ marker (pid ${runtime.pid ?? "?"})` : "default";
|
|
24387
|
-
lines.push(` url: ${
|
|
24650
|
+
lines.push(` url: ${color52.cyan(resolved.url)}`);
|
|
24388
24651
|
lines.push(
|
|
24389
|
-
` enabled: ${resolved.enabled === false ?
|
|
24652
|
+
` enabled: ${resolved.enabled === false ? color52.dim("false") : color52.green("true")}`
|
|
24390
24653
|
);
|
|
24391
|
-
if (resolved.discover) lines.push(` mode: ${
|
|
24392
|
-
lines.push(` source: ${
|
|
24654
|
+
if (resolved.discover) lines.push(` mode: ${color52.cyan("auto-discovery")}`);
|
|
24655
|
+
lines.push(` source: ${color52.dim(source)}`);
|
|
24393
24656
|
lines.push(
|
|
24394
|
-
` token: ${resolved.token ?
|
|
24657
|
+
` token: ${resolved.token ? color52.dim(maskToken(resolved.token)) : color52.dim("none (open mode)")}`
|
|
24395
24658
|
);
|
|
24396
24659
|
lines.push(
|
|
24397
|
-
` content: ${resolved.rawContent === true ?
|
|
24660
|
+
` content: ${resolved.rawContent === true ? color52.amber("raw (unredacted)") : color52.dim("redacted \u2014 explicitly disabled; enable with /hq raw on")}`
|
|
24398
24661
|
);
|
|
24399
|
-
if (resolved.projectAlias) lines.push(` alias: ${
|
|
24662
|
+
if (resolved.projectAlias) lines.push(` alias: ${color52.cyan(resolved.projectAlias)}`);
|
|
24400
24663
|
lines.push(` status: ${await probeHq(resolved.url)}`);
|
|
24401
24664
|
return { message: lines.join("\n") };
|
|
24402
24665
|
}
|
|
24403
24666
|
return {
|
|
24404
|
-
message: `${
|
|
24405
|
-
${
|
|
24667
|
+
message: `${color52.red("Unknown subcommand:")} ${sub}
|
|
24668
|
+
${color52.dim("Try /hq, /hq set <url> [token], /hq raw on|off, /hq on|off, /hq clear, or /help hq")}`
|
|
24406
24669
|
};
|
|
24407
24670
|
}
|
|
24408
24671
|
};
|
|
@@ -24453,11 +24716,11 @@ function buildMouseCommand(_opts) {
|
|
|
24453
24716
|
|
|
24454
24717
|
// src/slash-commands/project.ts
|
|
24455
24718
|
import { spawn as spawn5 } from "node:child_process";
|
|
24456
|
-
import * as
|
|
24719
|
+
import * as fs15 from "node:fs/promises";
|
|
24457
24720
|
import { createRequire } from "node:module";
|
|
24458
24721
|
import * as path17 from "node:path";
|
|
24459
24722
|
import {
|
|
24460
|
-
color as
|
|
24723
|
+
color as color53,
|
|
24461
24724
|
ensureProjectGitignore,
|
|
24462
24725
|
ensureProjectIdentity as ensureProjectIdentity2,
|
|
24463
24726
|
projectIdentityPath,
|
|
@@ -24590,17 +24853,17 @@ async function projectIdentityCommand(opts, ctx, action, confirmed) {
|
|
|
24590
24853
|
if (action === "show") {
|
|
24591
24854
|
const identity = await readProjectIdentity(root);
|
|
24592
24855
|
return identity ? {
|
|
24593
|
-
message: `${
|
|
24594
|
-
${
|
|
24595
|
-
} : { message: `No committed project identity. Run ${
|
|
24856
|
+
message: `${color53.bold("Project ID:")} ${color53.cyan(identity.projectId)}
|
|
24857
|
+
${color53.dim(filePath)}`
|
|
24858
|
+
} : { message: `No committed project identity. Run ${color53.cyan("/project init")}.` };
|
|
24596
24859
|
}
|
|
24597
24860
|
if (action === "init") {
|
|
24598
24861
|
const result2 = await ensureProjectIdentity2(root);
|
|
24599
24862
|
await ensureProjectGitignore(root);
|
|
24600
24863
|
return {
|
|
24601
|
-
message: result2.created ? `${
|
|
24602
|
-
${
|
|
24603
|
-
${
|
|
24864
|
+
message: result2.created ? `${color53.green("Created")} ${filePath}
|
|
24865
|
+
${color53.cyan(result2.identity.projectId)}
|
|
24866
|
+
${color53.dim("Commit this file so every clone and machine shares the same HQ project.")}` : `${color53.dim("Project identity already exists:")} ${color53.cyan(result2.identity.projectId)}`
|
|
24604
24867
|
};
|
|
24605
24868
|
}
|
|
24606
24869
|
if (!confirmed && opts.confirm) {
|
|
@@ -24615,17 +24878,17 @@ ${color52.dim("Commit this file so every clone and machine shares the same HQ pr
|
|
|
24615
24878
|
}
|
|
24616
24879
|
if (!confirmed) {
|
|
24617
24880
|
return {
|
|
24618
|
-
message: `Rekey requires confirmation. Pass ${
|
|
24881
|
+
message: `Rekey requires confirmation. Pass ${color53.cyan("--yes")} or ${color53.cyan("-y")}.`
|
|
24619
24882
|
};
|
|
24620
24883
|
}
|
|
24621
24884
|
const result = await rekeyProjectIdentity(root);
|
|
24622
24885
|
await ensureProjectGitignore(root);
|
|
24623
24886
|
return {
|
|
24624
24887
|
message: [
|
|
24625
|
-
result.previous ?
|
|
24626
|
-
`${
|
|
24627
|
-
|
|
24628
|
-
|
|
24888
|
+
result.previous ? color53.dim(`Previous: ${result.previous.projectId}`) : color53.dim("Previous: none"),
|
|
24889
|
+
`${color53.green("New project ID:")} ${color53.cyan(result.identity.projectId)}`,
|
|
24890
|
+
color53.dim(`Commit ${filePath} to make this fork independent on every machine.`),
|
|
24891
|
+
color53.dim("Restart WrongStack before publishing HQ or Kanban updates under the new ID.")
|
|
24629
24892
|
].join("\n")
|
|
24630
24893
|
};
|
|
24631
24894
|
}
|
|
@@ -24634,7 +24897,7 @@ async function listProjectsCommand(opts, ctx) {
|
|
|
24634
24897
|
const currentRoot = ctx?.projectRoot;
|
|
24635
24898
|
if (manifest.projects.length === 0) {
|
|
24636
24899
|
return {
|
|
24637
|
-
message:
|
|
24900
|
+
message: color53.dim("No projects registered. Add one: /project add <path> [name]")
|
|
24638
24901
|
};
|
|
24639
24902
|
}
|
|
24640
24903
|
const sorted = [...manifest.projects].sort((a, b) => {
|
|
@@ -24646,19 +24909,19 @@ async function listProjectsCommand(opts, ctx) {
|
|
|
24646
24909
|
const lines = [`Projects (${sorted.length}) registered in projects.json:`, ""];
|
|
24647
24910
|
for (const p of sorted) {
|
|
24648
24911
|
const isCurrent = p.root === currentRoot;
|
|
24649
|
-
const marker = isCurrent ?
|
|
24650
|
-
const name = isCurrent ?
|
|
24651
|
-
const slug =
|
|
24652
|
-
const last =
|
|
24912
|
+
const marker = isCurrent ? color53.green("\u25CF") : color53.dim("\u25CB");
|
|
24913
|
+
const name = isCurrent ? color53.bold(p.name) : p.name;
|
|
24914
|
+
const slug = color53.dim(`[${p.slug}]`);
|
|
24915
|
+
const last = color53.dim(fmtLastSeen(p.lastSeen));
|
|
24653
24916
|
lines.push(` ${marker} ${name} ${slug} ${last}`);
|
|
24654
24917
|
lines.push(` ${p.root}`);
|
|
24655
24918
|
if (isCurrent) {
|
|
24656
|
-
lines.push(` ${
|
|
24919
|
+
lines.push(` ${color53.green("\u2190 active session")}`);
|
|
24657
24920
|
}
|
|
24658
24921
|
lines.push("");
|
|
24659
24922
|
}
|
|
24660
24923
|
lines.push(
|
|
24661
|
-
|
|
24924
|
+
color53.dim(
|
|
24662
24925
|
"Commands: add <path> [name] | rename <slug> <name> | remove <slug> | switch [dir] (no args = picker)"
|
|
24663
24926
|
)
|
|
24664
24927
|
);
|
|
@@ -24667,19 +24930,19 @@ async function listProjectsCommand(opts, ctx) {
|
|
|
24667
24930
|
async function addProjectCommand(opts, ctx, targetPath, displayName) {
|
|
24668
24931
|
const resolved = path17.resolve(ctx?.projectRoot ?? ctx?.cwd ?? process.cwd(), targetPath);
|
|
24669
24932
|
try {
|
|
24670
|
-
await
|
|
24933
|
+
await fs15.access(resolved);
|
|
24671
24934
|
} catch {
|
|
24672
|
-
return { message:
|
|
24935
|
+
return { message: color53.red(`Directory not found: ${resolved}`) };
|
|
24673
24936
|
}
|
|
24674
|
-
const stat5 = await
|
|
24937
|
+
const stat5 = await fs15.stat(resolved);
|
|
24675
24938
|
if (!stat5.isDirectory()) {
|
|
24676
|
-
return { message:
|
|
24939
|
+
return { message: color53.red(`Not a directory: ${resolved}`) };
|
|
24677
24940
|
}
|
|
24678
24941
|
const manifest = await loadManifest(opts.paths?.globalConfig);
|
|
24679
24942
|
const existing = manifest.projects.find((p) => p.root === resolved);
|
|
24680
24943
|
if (existing) {
|
|
24681
24944
|
return {
|
|
24682
|
-
message:
|
|
24945
|
+
message: color53.yellow(`Project already registered: "${existing.name}" (${existing.slug})`)
|
|
24683
24946
|
};
|
|
24684
24947
|
}
|
|
24685
24948
|
const name = displayName?.trim() || path17.basename(resolved);
|
|
@@ -24691,9 +24954,9 @@ async function addProjectCommand(opts, ctx, targetPath, displayName) {
|
|
|
24691
24954
|
return {
|
|
24692
24955
|
message: [
|
|
24693
24956
|
"",
|
|
24694
|
-
|
|
24695
|
-
|
|
24696
|
-
|
|
24957
|
+
color53.green(` Added project: ${name}`),
|
|
24958
|
+
color53.dim(` Root: ${resolved}`),
|
|
24959
|
+
color53.dim(` Slug: ${slug}`),
|
|
24697
24960
|
""
|
|
24698
24961
|
].join("\n")
|
|
24699
24962
|
};
|
|
@@ -24703,7 +24966,7 @@ async function renameProjectCommand(opts, _ctx, slugOrName, newName) {
|
|
|
24703
24966
|
const project = findProject(manifest, slugOrName);
|
|
24704
24967
|
if (!project) {
|
|
24705
24968
|
return {
|
|
24706
|
-
message:
|
|
24969
|
+
message: color53.red(
|
|
24707
24970
|
`Project not found: "${slugOrName}". Use /project list to see available projects.`
|
|
24708
24971
|
)
|
|
24709
24972
|
};
|
|
@@ -24711,7 +24974,7 @@ async function renameProjectCommand(opts, _ctx, slugOrName, newName) {
|
|
|
24711
24974
|
const oldName = project.name;
|
|
24712
24975
|
project.name = newName;
|
|
24713
24976
|
await saveManifest(manifest, opts.paths?.globalConfig);
|
|
24714
|
-
return { message:
|
|
24977
|
+
return { message: color53.green(`Renamed: "${oldName}" \u2192 "${newName}" (${project.slug})`) };
|
|
24715
24978
|
}
|
|
24716
24979
|
async function removeProjectCommand(opts, _ctx, slugOrName) {
|
|
24717
24980
|
const manifest = await loadManifest(opts.paths?.globalConfig);
|
|
@@ -24720,7 +24983,7 @@ async function removeProjectCommand(opts, _ctx, slugOrName) {
|
|
|
24720
24983
|
);
|
|
24721
24984
|
if (idx === -1) {
|
|
24722
24985
|
return {
|
|
24723
|
-
message:
|
|
24986
|
+
message: color53.red(
|
|
24724
24987
|
`Project not found: "${slugOrName}". Use /project list to see available projects.`
|
|
24725
24988
|
)
|
|
24726
24989
|
};
|
|
@@ -24729,7 +24992,7 @@ async function removeProjectCommand(opts, _ctx, slugOrName) {
|
|
|
24729
24992
|
manifest.projects.splice(idx, 1);
|
|
24730
24993
|
await saveManifest(manifest, opts.paths?.globalConfig);
|
|
24731
24994
|
return {
|
|
24732
|
-
message:
|
|
24995
|
+
message: color53.dim(
|
|
24733
24996
|
`Removed: "${removed.name}" (${removed.root}) \u2014 data directory kept at ~/.wrongstack/projects/${removed.slug}/`
|
|
24734
24997
|
)
|
|
24735
24998
|
};
|
|
@@ -24737,13 +25000,13 @@ async function removeProjectCommand(opts, _ctx, slugOrName) {
|
|
|
24737
25000
|
async function switchProjectCommand(opts, ctx, target, displayName) {
|
|
24738
25001
|
const resolved = path17.resolve(ctx?.projectRoot ?? ctx?.cwd ?? process.cwd(), target);
|
|
24739
25002
|
try {
|
|
24740
|
-
await
|
|
25003
|
+
await fs15.access(resolved);
|
|
24741
25004
|
} catch {
|
|
24742
|
-
return { message:
|
|
25005
|
+
return { message: color53.red(`Directory not found: ${resolved}`) };
|
|
24743
25006
|
}
|
|
24744
|
-
const stat5 = await
|
|
25007
|
+
const stat5 = await fs15.stat(resolved);
|
|
24745
25008
|
if (!stat5.isDirectory()) {
|
|
24746
|
-
return { message:
|
|
25009
|
+
return { message: color53.red(`Not a directory: ${resolved}`) };
|
|
24747
25010
|
}
|
|
24748
25011
|
let cliPath;
|
|
24749
25012
|
try {
|
|
@@ -24751,12 +25014,12 @@ async function switchProjectCommand(opts, ctx, target, displayName) {
|
|
|
24751
25014
|
const pkgPath = req.resolve("@wrongstack/cli/package.json");
|
|
24752
25015
|
const pkgDir = path17.dirname(pkgPath);
|
|
24753
25016
|
cliPath = path17.join(pkgDir, "dist", "index.js");
|
|
24754
|
-
await
|
|
25017
|
+
await fs15.access(cliPath);
|
|
24755
25018
|
} catch {
|
|
24756
25019
|
cliPath = process.argv[1] ?? "";
|
|
24757
25020
|
if (!cliPath) {
|
|
24758
25021
|
return {
|
|
24759
|
-
message:
|
|
25022
|
+
message: color53.red(
|
|
24760
25023
|
"Could not locate the CLI entry point. Run `wstack` manually in the target directory."
|
|
24761
25024
|
)
|
|
24762
25025
|
};
|
|
@@ -24789,14 +25052,14 @@ async function switchProjectCommand(opts, ctx, target, displayName) {
|
|
|
24789
25052
|
// and boot/tui-project-spawn.ts documents this exact bug being removed.
|
|
24790
25053
|
});
|
|
24791
25054
|
child.on("error", (err) => {
|
|
24792
|
-
console.error(
|
|
25055
|
+
console.error(color53.red(`Failed to spawn wstack: ${err.message}`));
|
|
24793
25056
|
});
|
|
24794
25057
|
child.unref();
|
|
24795
25058
|
return {
|
|
24796
25059
|
message: [
|
|
24797
25060
|
"",
|
|
24798
|
-
|
|
24799
|
-
|
|
25061
|
+
color53.green(` Spawning wstack in ${resolved} ...`),
|
|
25062
|
+
color53.dim(" (current session stays open \u2014 Ctrl+C to return)"),
|
|
24800
25063
|
""
|
|
24801
25064
|
].join("\n")
|
|
24802
25065
|
};
|
|
@@ -24810,45 +25073,45 @@ async function confirmProjectSwitch(opts, targetName) {
|
|
|
24810
25073
|
const parallelActive = parallelEngine?.currentState === "running";
|
|
24811
25074
|
const hasActiveAgents = fleetRunning > 0 || eternalActive || parallelActive;
|
|
24812
25075
|
if (!hasActiveAgents) return true;
|
|
24813
|
-
const parts = [
|
|
25076
|
+
const parts = [color53.yellow(`\u26A0 Switching projects will stop all running agents.`), ""];
|
|
24814
25077
|
if (fleetRunning > 0) {
|
|
24815
|
-
parts.push(
|
|
25078
|
+
parts.push(color53.dim(` \u2022 ${fleetRunning} subagent(s) currently running`));
|
|
24816
25079
|
}
|
|
24817
25080
|
if (eternalActive) {
|
|
24818
|
-
parts.push(
|
|
25081
|
+
parts.push(color53.dim(" \u2022 Eternal engine is active"));
|
|
24819
25082
|
}
|
|
24820
25083
|
if (parallelActive) {
|
|
24821
|
-
parts.push(
|
|
25084
|
+
parts.push(color53.dim(" \u2022 Parallel engine is active"));
|
|
24822
25085
|
}
|
|
24823
25086
|
parts.push("");
|
|
24824
|
-
parts.push(
|
|
25087
|
+
parts.push(color53.dim(` Target: ${targetName}`));
|
|
24825
25088
|
opts.renderer.write(`
|
|
24826
25089
|
${parts.join("\n")}
|
|
24827
25090
|
`);
|
|
24828
25091
|
if (!opts.confirm) return true;
|
|
24829
25092
|
const confirmed = await opts.confirm(
|
|
24830
|
-
|
|
25093
|
+
color53.yellow(`Stop all agents and switch to "${targetName}"?`),
|
|
24831
25094
|
false
|
|
24832
25095
|
// default to No for safety
|
|
24833
25096
|
);
|
|
24834
25097
|
if (!confirmed) {
|
|
24835
|
-
opts.renderer.write(
|
|
25098
|
+
opts.renderer.write(color53.dim(" Switch cancelled.\n"));
|
|
24836
25099
|
return false;
|
|
24837
25100
|
}
|
|
24838
25101
|
if (fleetRunning > 0) {
|
|
24839
25102
|
const killed = opts.onFleetKill ? await opts.onFleetKill() : 0;
|
|
24840
25103
|
if (killed > 0) {
|
|
24841
|
-
opts.renderer.write(
|
|
25104
|
+
opts.renderer.write(color53.dim(` Stopped ${killed} subagent(s).
|
|
24842
25105
|
`));
|
|
24843
25106
|
}
|
|
24844
25107
|
}
|
|
24845
25108
|
if (eternalActive) {
|
|
24846
25109
|
eternalEngine?.stop();
|
|
24847
|
-
opts.renderer.write(
|
|
25110
|
+
opts.renderer.write(color53.dim(" Stopped eternal engine.\n"));
|
|
24848
25111
|
}
|
|
24849
25112
|
if (parallelActive) {
|
|
24850
25113
|
parallelEngine?.stop();
|
|
24851
|
-
opts.renderer.write(
|
|
25114
|
+
opts.renderer.write(color53.dim(" Stopped parallel engine.\n"));
|
|
24852
25115
|
}
|
|
24853
25116
|
return true;
|
|
24854
25117
|
}
|
|
@@ -24860,16 +25123,16 @@ async function switchInteractiveCommand(opts, ctx) {
|
|
|
24860
25123
|
currentProjectRoot: currentRoot
|
|
24861
25124
|
});
|
|
24862
25125
|
if (!result) {
|
|
24863
|
-
return { message:
|
|
25126
|
+
return { message: color53.dim("Cancelled.") };
|
|
24864
25127
|
}
|
|
24865
25128
|
switch (result.kind) {
|
|
24866
25129
|
case "project": {
|
|
24867
25130
|
const project = manifest.projects.find((p) => p.slug === result.key);
|
|
24868
25131
|
if (!project) {
|
|
24869
|
-
return { message:
|
|
25132
|
+
return { message: color53.red(`Project not found: ${result.key}`) };
|
|
24870
25133
|
}
|
|
24871
25134
|
if (project.root === currentRoot) {
|
|
24872
|
-
return { message:
|
|
25135
|
+
return { message: color53.dim(`Already in ${project.name} (${project.root})`) };
|
|
24873
25136
|
}
|
|
24874
25137
|
const canSwitch = await confirmProjectSwitch(opts, project.name);
|
|
24875
25138
|
if (!canSwitch) return { message: "" };
|
|
@@ -24882,11 +25145,11 @@ async function switchInteractiveCommand(opts, ctx) {
|
|
|
24882
25145
|
case "prev-sessions":
|
|
24883
25146
|
return handlePrevSessions(opts, ctx);
|
|
24884
25147
|
default:
|
|
24885
|
-
return { message:
|
|
25148
|
+
return { message: color53.dim("Cancelled.") };
|
|
24886
25149
|
}
|
|
24887
25150
|
}
|
|
24888
25151
|
default:
|
|
24889
|
-
return { message:
|
|
25152
|
+
return { message: color53.dim("Cancelled.") };
|
|
24890
25153
|
}
|
|
24891
25154
|
}
|
|
24892
25155
|
async function spawnInProject(opts, _ctx, root, projectName) {
|
|
@@ -24896,12 +25159,12 @@ async function spawnInProject(opts, _ctx, root, projectName) {
|
|
|
24896
25159
|
const pkgPath = req.resolve("@wrongstack/cli/package.json");
|
|
24897
25160
|
const pkgDir = path17.dirname(pkgPath);
|
|
24898
25161
|
cliPath = path17.join(pkgDir, "dist", "index.js");
|
|
24899
|
-
await
|
|
25162
|
+
await fs15.access(cliPath);
|
|
24900
25163
|
} catch {
|
|
24901
25164
|
cliPath = process.argv[1] ?? "";
|
|
24902
25165
|
if (!cliPath) {
|
|
24903
25166
|
return {
|
|
24904
|
-
message:
|
|
25167
|
+
message: color53.red(
|
|
24905
25168
|
"Could not locate the CLI entry point. Run `wstack` manually in the target directory."
|
|
24906
25169
|
)
|
|
24907
25170
|
};
|
|
@@ -24931,15 +25194,15 @@ async function spawnInProject(opts, _ctx, root, projectName) {
|
|
|
24931
25194
|
// and boot/tui-project-spawn.ts documents this exact bug being removed.
|
|
24932
25195
|
});
|
|
24933
25196
|
child.on("error", (err) => {
|
|
24934
|
-
console.error(
|
|
25197
|
+
console.error(color53.red(`Failed to spawn wstack: ${err.message}`));
|
|
24935
25198
|
});
|
|
24936
25199
|
child.unref();
|
|
24937
25200
|
return {
|
|
24938
25201
|
message: [
|
|
24939
25202
|
"",
|
|
24940
|
-
|
|
24941
|
-
|
|
24942
|
-
|
|
25203
|
+
color53.green(` Switched to ${projectName}`),
|
|
25204
|
+
color53.dim(` Root: ${root}`),
|
|
25205
|
+
color53.dim(" (current session stays open \u2014 Ctrl+C to return)"),
|
|
24943
25206
|
""
|
|
24944
25207
|
].join("\n")
|
|
24945
25208
|
};
|
|
@@ -24951,12 +25214,12 @@ async function handleNewSession(_opts, _ctx) {
|
|
|
24951
25214
|
const pkgPath = req.resolve("@wrongstack/cli/package.json");
|
|
24952
25215
|
const pkgDir = path17.dirname(pkgPath);
|
|
24953
25216
|
cliPath = path17.join(pkgDir, "dist", "index.js");
|
|
24954
|
-
await
|
|
25217
|
+
await fs15.access(cliPath);
|
|
24955
25218
|
} catch {
|
|
24956
25219
|
cliPath = process.argv[1] ?? "";
|
|
24957
25220
|
if (!cliPath) {
|
|
24958
25221
|
return {
|
|
24959
|
-
message:
|
|
25222
|
+
message: color53.red("Could not locate the CLI entry point. Run `wstack` manually.")
|
|
24960
25223
|
};
|
|
24961
25224
|
}
|
|
24962
25225
|
}
|
|
@@ -24973,14 +25236,14 @@ async function handleNewSession(_opts, _ctx) {
|
|
|
24973
25236
|
// and boot/tui-project-spawn.ts documents this exact bug being removed.
|
|
24974
25237
|
});
|
|
24975
25238
|
child.on("error", (err) => {
|
|
24976
|
-
console.error(
|
|
25239
|
+
console.error(color53.red(`Failed to spawn wstack: ${err.message}`));
|
|
24977
25240
|
});
|
|
24978
25241
|
child.unref();
|
|
24979
25242
|
return {
|
|
24980
25243
|
message: [
|
|
24981
25244
|
"",
|
|
24982
|
-
|
|
24983
|
-
|
|
25245
|
+
color53.green(" Starting new session ..."),
|
|
25246
|
+
color53.dim(" (current session stays open \u2014 Ctrl+C to return)"),
|
|
24984
25247
|
""
|
|
24985
25248
|
].join("\n")
|
|
24986
25249
|
};
|
|
@@ -24991,25 +25254,25 @@ async function handlePrevSessions(opts, _ctx) {
|
|
|
24991
25254
|
}
|
|
24992
25255
|
const list = await opts.sessionStore.list(15);
|
|
24993
25256
|
if (list.length === 0) {
|
|
24994
|
-
return { message:
|
|
25257
|
+
return { message: color53.dim("No saved sessions.") };
|
|
24995
25258
|
}
|
|
24996
25259
|
const currentId = opts.context?.session?.id;
|
|
24997
|
-
const lines = [
|
|
25260
|
+
const lines = [color53.bold(`Recent sessions (${list.length}):`), ""];
|
|
24998
25261
|
for (const s of list) {
|
|
24999
25262
|
const isCurrent = s.id === currentId;
|
|
25000
|
-
const marker = isCurrent ?
|
|
25001
|
-
const date =
|
|
25263
|
+
const marker = isCurrent ? color53.cyan("\u25CF") : " ";
|
|
25264
|
+
const date = color53.dim(s.startedAt.slice(0, 16).replace("T", " "));
|
|
25002
25265
|
const stats = [
|
|
25003
|
-
|
|
25004
|
-
s.toolCallCount ?
|
|
25005
|
-
s.iterationCount ?
|
|
25266
|
+
color53.dim(`${s.tokenTotal.toLocaleString()} tok`),
|
|
25267
|
+
s.toolCallCount ? color53.cyan(`${s.toolCallCount} calls`) : "",
|
|
25268
|
+
s.iterationCount ? color53.dim(`${s.iterationCount} iter`) : ""
|
|
25006
25269
|
].filter(Boolean).join(" ");
|
|
25007
|
-
const outcome = s.outcome === "completed" ?
|
|
25008
|
-
lines.push(` ${marker} ${
|
|
25009
|
-
lines.push(` ${stats} ${outcome} ${
|
|
25270
|
+
const outcome = s.outcome === "completed" ? color53.green("\u2713") : s.outcome === "aborted" ? color53.yellow("\u26A0") : s.outcome === "error" ? color53.red("\u2717") : color53.dim("?");
|
|
25271
|
+
lines.push(` ${marker} ${color53.bold(s.id)} ${date}`);
|
|
25272
|
+
lines.push(` ${stats} ${outcome} ${color53.dim(s.title)}`);
|
|
25010
25273
|
lines.push("");
|
|
25011
25274
|
}
|
|
25012
|
-
lines.push(
|
|
25275
|
+
lines.push(color53.dim("Resume: /sessions or wstack resume <id>"));
|
|
25013
25276
|
return { message: lines.join("\n") };
|
|
25014
25277
|
}
|
|
25015
25278
|
|
|
@@ -25217,11 +25480,15 @@ function buildSecurityCommand(opts) {
|
|
|
25217
25480
|
}
|
|
25218
25481
|
|
|
25219
25482
|
// src/slash-commands/settings.ts
|
|
25220
|
-
import { color as
|
|
25483
|
+
import { color as color56 } from "@wrongstack/core/utils";
|
|
25221
25484
|
|
|
25222
25485
|
// src/slash-commands/settings-mutations.ts
|
|
25223
|
-
import { noOpVault as
|
|
25224
|
-
import {
|
|
25486
|
+
import { noOpVault as noOpVault10 } from "@wrongstack/core/security";
|
|
25487
|
+
import {
|
|
25488
|
+
isReasoningEffort as isReasoningEffort3,
|
|
25489
|
+
REASONING_EFFORT_LEVELS as REASONING_EFFORT_LEVELS3
|
|
25490
|
+
} from "@wrongstack/core/types";
|
|
25491
|
+
import { color as color54, toErrorMessage as toErrorMessage23 } from "@wrongstack/core/utils";
|
|
25225
25492
|
import { getProcessRegistry } from "@wrongstack/tools";
|
|
25226
25493
|
|
|
25227
25494
|
// src/utils/delay-format.ts
|
|
@@ -25284,13 +25551,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25284
25551
|
configStore: opts.configStore,
|
|
25285
25552
|
profileConfigPath: opts.paths.profileConfig(activeProfile),
|
|
25286
25553
|
inProjectConfigPath: opts.paths.inProjectConfig,
|
|
25287
|
-
vault:
|
|
25554
|
+
vault: noOpVault10
|
|
25288
25555
|
};
|
|
25289
25556
|
try {
|
|
25290
25557
|
if (sub === "hq") {
|
|
25291
25558
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25292
25559
|
if (!["on", "off"].includes(raw)) {
|
|
25293
|
-
return { message: `${
|
|
25560
|
+
return { message: `${color54.amber("Usage:")} /settings hq on|off` };
|
|
25294
25561
|
}
|
|
25295
25562
|
const on = raw === "on";
|
|
25296
25563
|
await persistConfigSetting({ ...persistDeps, forceGlobal: true }, (cfg) => {
|
|
@@ -25299,19 +25566,19 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25299
25566
|
cfg.hq = hq;
|
|
25300
25567
|
});
|
|
25301
25568
|
return {
|
|
25302
|
-
message: `${
|
|
25569
|
+
message: `${color54.green("\u2713")} HQ publishing \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
25303
25570
|
};
|
|
25304
25571
|
}
|
|
25305
25572
|
if (sub === "hq-url") {
|
|
25306
25573
|
const raw = rest.join(" ").trim();
|
|
25307
25574
|
if (!raw)
|
|
25308
|
-
return { message: `${
|
|
25575
|
+
return { message: `${color54.amber("Usage:")} /settings hq-url <http://host:3499>` };
|
|
25309
25576
|
try {
|
|
25310
25577
|
const url = new URL(raw);
|
|
25311
25578
|
if (url.protocol !== "http:" && url.protocol !== "https:")
|
|
25312
25579
|
throw new Error("bad protocol");
|
|
25313
25580
|
} catch {
|
|
25314
|
-
return { message: `${
|
|
25581
|
+
return { message: `${color54.red("Invalid URL")}: ${raw}` };
|
|
25315
25582
|
}
|
|
25316
25583
|
await persistConfigSetting({ ...persistDeps, forceGlobal: true }, (cfg) => {
|
|
25317
25584
|
const hq = cfg.hq ?? {};
|
|
@@ -25319,12 +25586,12 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25319
25586
|
hq.enabled = true;
|
|
25320
25587
|
cfg.hq = hq;
|
|
25321
25588
|
});
|
|
25322
|
-
return { message: `${
|
|
25589
|
+
return { message: `${color54.green("\u2713")} HQ URL \u2192 ${color54.cyan(raw)}` };
|
|
25323
25590
|
}
|
|
25324
25591
|
if (sub === "hq-token") {
|
|
25325
25592
|
const token = rest.join(" ").trim();
|
|
25326
25593
|
if (!token)
|
|
25327
|
-
return { message: `${
|
|
25594
|
+
return { message: `${color54.amber("Usage:")} /settings hq-token <client-token>` };
|
|
25328
25595
|
await persistConfigSetting({ ...persistDeps, forceGlobal: true }, (cfg) => {
|
|
25329
25596
|
const hq = cfg.hq ?? {};
|
|
25330
25597
|
hq.token = token;
|
|
@@ -25332,13 +25599,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25332
25599
|
cfg.hq = hq;
|
|
25333
25600
|
});
|
|
25334
25601
|
return {
|
|
25335
|
-
message: `${
|
|
25602
|
+
message: `${color54.green("\u2713")} HQ token saved ${color54.dim("(active profile config)")}`
|
|
25336
25603
|
};
|
|
25337
25604
|
}
|
|
25338
25605
|
if (sub === "hq-raw") {
|
|
25339
25606
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25340
25607
|
if (!["on", "off"].includes(raw)) {
|
|
25341
|
-
return { message: `${
|
|
25608
|
+
return { message: `${color54.amber("Usage:")} /settings hq-raw on|off` };
|
|
25342
25609
|
}
|
|
25343
25610
|
const on = raw === "on";
|
|
25344
25611
|
await persistConfigSetting({ ...persistDeps, forceGlobal: true }, (cfg) => {
|
|
@@ -25347,56 +25614,56 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25347
25614
|
cfg.hq = hq;
|
|
25348
25615
|
});
|
|
25349
25616
|
return {
|
|
25350
|
-
message: `${
|
|
25617
|
+
message: `${color54.green("\u2713")} HQ raw content \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
25351
25618
|
};
|
|
25352
25619
|
}
|
|
25353
25620
|
if (sub === "delay") {
|
|
25354
25621
|
const raw = rest[0];
|
|
25355
25622
|
if (raw === void 0) {
|
|
25356
25623
|
return {
|
|
25357
|
-
message: `${
|
|
25624
|
+
message: `${color54.amber("Usage:")} /settings delay <seconds> ${color54.dim("(0 disables)")}`
|
|
25358
25625
|
};
|
|
25359
25626
|
}
|
|
25360
25627
|
const seconds = Number.parseFloat(raw);
|
|
25361
25628
|
if (Number.isNaN(seconds) || seconds < 0) {
|
|
25362
25629
|
return {
|
|
25363
|
-
message: `${
|
|
25630
|
+
message: `${color54.red("Invalid number")}: "${raw}". Enter seconds, e.g. /settings delay 30`
|
|
25364
25631
|
};
|
|
25365
25632
|
}
|
|
25366
25633
|
const ms = Math.round(seconds * 1e3);
|
|
25367
25634
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25368
25635
|
autonomy.autoProceedDelayMs = ms;
|
|
25369
25636
|
});
|
|
25370
|
-
return { message: `${
|
|
25637
|
+
return { message: `${color54.green("\u2713")} auto-proceed delay \u2192 ${formatDelay(ms)}` };
|
|
25371
25638
|
}
|
|
25372
25639
|
if (sub === "mode") {
|
|
25373
25640
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25374
25641
|
const modes = ["off", "suggest", "auto"];
|
|
25375
25642
|
if (!modes.includes(raw)) {
|
|
25376
|
-
return { message: `${
|
|
25643
|
+
return { message: `${color54.amber("Usage:")} /settings mode off|suggest|auto` };
|
|
25377
25644
|
}
|
|
25378
25645
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25379
25646
|
autonomy.defaultMode = raw;
|
|
25380
25647
|
});
|
|
25381
|
-
return { message: `${
|
|
25648
|
+
return { message: `${color54.green("\u2713")} default autonomy \u2192 ${color54.bold(raw)}` };
|
|
25382
25649
|
}
|
|
25383
25650
|
if (sub === "hints") {
|
|
25384
25651
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25385
25652
|
if (!["on", "off"].includes(raw)) {
|
|
25386
|
-
return { message: `${
|
|
25653
|
+
return { message: `${color54.amber("Usage:")} /settings hints on|off` };
|
|
25387
25654
|
}
|
|
25388
25655
|
const on = raw === "on";
|
|
25389
25656
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25390
25657
|
cfg.hints = on;
|
|
25391
25658
|
});
|
|
25392
25659
|
return {
|
|
25393
|
-
message: `${
|
|
25660
|
+
message: `${color54.green("\u2713")} launch hints \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
25394
25661
|
};
|
|
25395
25662
|
}
|
|
25396
25663
|
if (sub === "debug-stream") {
|
|
25397
25664
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25398
25665
|
if (!["on", "off"].includes(raw)) {
|
|
25399
|
-
return { message: `${
|
|
25666
|
+
return { message: `${color54.amber("Usage:")} /settings debug-stream on|off` };
|
|
25400
25667
|
}
|
|
25401
25668
|
const on = raw === "on";
|
|
25402
25669
|
const { setDebugStreamEnabled } = await import("@wrongstack/providers");
|
|
@@ -25405,24 +25672,24 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25405
25672
|
cfg.debugStream = on;
|
|
25406
25673
|
});
|
|
25407
25674
|
return {
|
|
25408
|
-
message: `${
|
|
25675
|
+
message: `${color54.green("\u2713")} debug stream \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("raw SSE hex-dump to stderr")}`
|
|
25409
25676
|
};
|
|
25410
25677
|
}
|
|
25411
25678
|
if (sub === "config-scope") {
|
|
25412
25679
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25413
25680
|
if (!["global", "project"].includes(raw)) {
|
|
25414
|
-
return { message: `${
|
|
25681
|
+
return { message: `${color54.amber("Usage:")} /settings config-scope global|project` };
|
|
25415
25682
|
}
|
|
25416
25683
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25417
25684
|
cfg.configScope = raw;
|
|
25418
25685
|
});
|
|
25419
|
-
const label = raw === "project" ? `${
|
|
25420
|
-
return { message: `${
|
|
25686
|
+
const label = raw === "project" ? `${color54.cyan("project")} \u2014 settings saved to <project>/.wrongstack/config.json` : `${color54.cyan("global")} \u2014 settings saved to ~/.wrongstack/profiles/${activeProfile}/config.json`;
|
|
25687
|
+
return { message: `${color54.green("\u2713")} config scope \u2192 ${label}` };
|
|
25421
25688
|
}
|
|
25422
25689
|
if (sub === "fs-access") {
|
|
25423
25690
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25424
25691
|
if (!["unrestricted", "project"].includes(raw)) {
|
|
25425
|
-
return { message: `${
|
|
25692
|
+
return { message: `${color54.amber("Usage:")} /settings fs-access unrestricted|project` };
|
|
25426
25693
|
}
|
|
25427
25694
|
const restrict = raw === "project";
|
|
25428
25695
|
const fsAccess = deriveFsAccessPair({ restrictFsToRoot: restrict });
|
|
@@ -25434,15 +25701,15 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25434
25701
|
features.allowOutsideProjectRoot = fsAccess.allowOutsideProjectRoot;
|
|
25435
25702
|
cfg.features = features;
|
|
25436
25703
|
});
|
|
25437
|
-
const label = restrict ? `${
|
|
25704
|
+
const label = restrict ? `${color54.cyan("project")} \u2014 file tools confined to the project root` : `${color54.cyan("unrestricted")} \u2014 file tools may access paths outside the project root`;
|
|
25438
25705
|
return {
|
|
25439
|
-
message: `${
|
|
25706
|
+
message: `${color54.green("\u2713")} filesystem access \u2192 ${label} ${color54.dim("(restart or re-open the session to apply)")}`
|
|
25440
25707
|
};
|
|
25441
25708
|
}
|
|
25442
25709
|
if (sub === "refine") {
|
|
25443
25710
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25444
25711
|
if (!["on", "off"].includes(raw)) {
|
|
25445
|
-
return { message: `${
|
|
25712
|
+
return { message: `${color54.amber("Usage:")} /settings refine on|off` };
|
|
25446
25713
|
}
|
|
25447
25714
|
const on = raw === "on";
|
|
25448
25715
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
@@ -25452,52 +25719,52 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25452
25719
|
opts.enhanceController.setEnabled(on);
|
|
25453
25720
|
}
|
|
25454
25721
|
return {
|
|
25455
|
-
message: `${
|
|
25722
|
+
message: `${color54.green("\u2713")} refine \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim(on ? "prompts will be refined before sending" : "prompts sent verbatim")}`
|
|
25456
25723
|
};
|
|
25457
25724
|
}
|
|
25458
25725
|
if (sub === "refine-delay") {
|
|
25459
25726
|
const raw = rest[0];
|
|
25460
25727
|
if (raw === void 0) {
|
|
25461
|
-
return { message: `${
|
|
25728
|
+
return { message: `${color54.amber("Usage:")} /settings refine-delay <seconds>` };
|
|
25462
25729
|
}
|
|
25463
25730
|
const seconds = Number.parseFloat(raw);
|
|
25464
25731
|
if (Number.isNaN(seconds) || seconds < 0) {
|
|
25465
25732
|
return {
|
|
25466
|
-
message: `${
|
|
25733
|
+
message: `${color54.red("Invalid number")}: "${raw}". Enter seconds, e.g. /settings refine-delay 30`
|
|
25467
25734
|
};
|
|
25468
25735
|
}
|
|
25469
25736
|
const ms = Math.round(seconds * 1e3);
|
|
25470
25737
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25471
25738
|
autonomy.enhanceDelayMs = ms;
|
|
25472
25739
|
});
|
|
25473
|
-
return { message: `${
|
|
25740
|
+
return { message: `${color54.green("\u2713")} refine-delay \u2192 ${formatDelay(ms)}` };
|
|
25474
25741
|
}
|
|
25475
25742
|
if (sub === "refine-language") {
|
|
25476
25743
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25477
25744
|
if (!["original", "english"].includes(raw)) {
|
|
25478
25745
|
return {
|
|
25479
|
-
message: `${
|
|
25746
|
+
message: `${color54.amber("Usage:")} /settings refine-language original|english`
|
|
25480
25747
|
};
|
|
25481
25748
|
}
|
|
25482
25749
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25483
25750
|
autonomy.enhanceLanguage = raw;
|
|
25484
25751
|
});
|
|
25485
|
-
const label = raw === "original" ? `${
|
|
25486
|
-
return { message: `${
|
|
25752
|
+
const label = raw === "original" ? `${color54.cyan("original")} \u2014 use the language you wrote in` : `${color54.cyan("english")} \u2014 translate to English`;
|
|
25753
|
+
return { message: `${color54.green("\u2713")} refine-language \u2192 ${label}` };
|
|
25487
25754
|
}
|
|
25488
25755
|
if (sub === "refiner-provider") {
|
|
25489
25756
|
const raw = rest.join(" ").trim();
|
|
25490
25757
|
const currentProvider = opts.configStore.get().autonomy?.refinerProvider;
|
|
25491
25758
|
if (!raw) {
|
|
25492
25759
|
return {
|
|
25493
|
-
message: `${
|
|
25760
|
+
message: `${color54.amber("Usage:")} /settings refiner-provider <providerId> ${color54.dim('(e.g. "openai", "anthropic")' + (currentProvider ? ` Current: ${currentProvider}` : ""))}`
|
|
25494
25761
|
};
|
|
25495
25762
|
}
|
|
25496
25763
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25497
25764
|
autonomy.refinerProvider = raw;
|
|
25498
25765
|
});
|
|
25499
25766
|
return {
|
|
25500
|
-
message: `${
|
|
25767
|
+
message: `${color54.green("\u2713")} refiner-provider \u2192 ${color54.cyan(raw)} ${color54.dim("goal refinement will use this provider when refiner-model is also set")}`
|
|
25501
25768
|
};
|
|
25502
25769
|
}
|
|
25503
25770
|
if (sub === "refiner-model") {
|
|
@@ -25505,14 +25772,14 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25505
25772
|
const currentModel = opts.configStore.get().autonomy?.refinerModel;
|
|
25506
25773
|
if (!raw) {
|
|
25507
25774
|
return {
|
|
25508
|
-
message: `${
|
|
25775
|
+
message: `${color54.amber("Usage:")} /settings refiner-model <modelId> ${color54.dim('(must be a favorite or the active model; e.g. "gpt-4o-mini")' + (currentModel ? ` Current: ${currentModel}` : ""))}`
|
|
25509
25776
|
};
|
|
25510
25777
|
}
|
|
25511
25778
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25512
25779
|
autonomy.refinerModel = raw;
|
|
25513
25780
|
});
|
|
25514
25781
|
return {
|
|
25515
|
-
message: `${
|
|
25782
|
+
message: `${color54.green("\u2713")} refiner-model \u2192 ${color54.cyan(raw)} ${color54.dim("goal refinement will use this model when it passes favorites/active validation")}`
|
|
25516
25783
|
};
|
|
25517
25784
|
}
|
|
25518
25785
|
if (sub === "refiner-fallback-profile") {
|
|
@@ -25520,14 +25787,14 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25520
25787
|
const currentProfile = opts.configStore.get().autonomy?.refinerFallbackProfile;
|
|
25521
25788
|
if (!raw) {
|
|
25522
25789
|
return {
|
|
25523
|
-
message: `${
|
|
25790
|
+
message: `${color54.amber("Usage:")} /settings refiner-fallback-profile <name> ${color54.dim('(e.g. "default")' + (currentProfile ? ` Current: ${currentProfile}` : ""))}`
|
|
25524
25791
|
};
|
|
25525
25792
|
}
|
|
25526
25793
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25527
25794
|
autonomy.refinerFallbackProfile = raw;
|
|
25528
25795
|
});
|
|
25529
25796
|
return {
|
|
25530
|
-
message: `${
|
|
25797
|
+
message: `${color54.green("\u2713")} refiner-fallback-profile \u2192 ${color54.cyan(raw)} ${color54.dim("goal refinement will use the first valid entry from this profile chain")}`
|
|
25531
25798
|
};
|
|
25532
25799
|
}
|
|
25533
25800
|
if (sub === "refiner-clear") {
|
|
@@ -25537,7 +25804,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25537
25804
|
autonomy.refinerFallbackProfile = void 0;
|
|
25538
25805
|
});
|
|
25539
25806
|
return {
|
|
25540
|
-
message: `${
|
|
25807
|
+
message: `${color54.green("\u2713")} Refiner config cleared ${color54.dim("goal refinement will use the session provider+model")}`
|
|
25541
25808
|
};
|
|
25542
25809
|
}
|
|
25543
25810
|
if (sub === "semver-part") {
|
|
@@ -25545,7 +25812,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25545
25812
|
const parts = ["patch", "minor", "major", "auto"];
|
|
25546
25813
|
if (!parts.includes(raw)) {
|
|
25547
25814
|
return {
|
|
25548
|
-
message: `${
|
|
25815
|
+
message: `${color54.amber("Usage:")} /settings semver-part patch|minor|major|auto`
|
|
25549
25816
|
};
|
|
25550
25817
|
}
|
|
25551
25818
|
await persistConfigSetting({ ...persistDeps, inProjectConfigPath: void 0 }, (cfg) => {
|
|
@@ -25554,13 +25821,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25554
25821
|
cfg.extensions = ext;
|
|
25555
25822
|
});
|
|
25556
25823
|
return {
|
|
25557
|
-
message: `${
|
|
25824
|
+
message: `${color54.green("\u2713")} semver default part \u2192 ${color54.bold(raw)} ${color54.dim("saved to active profile config; used when /semver or semver_bump gets no explicit part")}`
|
|
25558
25825
|
};
|
|
25559
25826
|
}
|
|
25560
25827
|
if (sub === "breaker") {
|
|
25561
25828
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25562
25829
|
if (!["on", "off"].includes(raw)) {
|
|
25563
|
-
return { message: `${
|
|
25830
|
+
return { message: `${color54.amber("Usage:")} /settings breaker on|off` };
|
|
25564
25831
|
}
|
|
25565
25832
|
const on = raw === "on";
|
|
25566
25833
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25569,20 +25836,20 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25569
25836
|
});
|
|
25570
25837
|
getProcessRegistry().setBreakerConfig({ enabled: on });
|
|
25571
25838
|
return {
|
|
25572
|
-
message: `${
|
|
25839
|
+
message: `${color54.green("\u2713")} circuit breaker \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim(on ? "bash/exec gated on repeated failures; trips arm the kill/reset countdown" : "bash/exec always proceed")}`
|
|
25573
25840
|
};
|
|
25574
25841
|
}
|
|
25575
25842
|
if (sub === "breaker-timeout") {
|
|
25576
25843
|
const raw = rest[0];
|
|
25577
25844
|
if (raw === void 0) {
|
|
25578
25845
|
return {
|
|
25579
|
-
message: `${
|
|
25846
|
+
message: `${color54.amber("Usage:")} /settings breaker-timeout <seconds> ${color54.dim("(0 = manual recovery only)")}`
|
|
25580
25847
|
};
|
|
25581
25848
|
}
|
|
25582
25849
|
const seconds = Number.parseFloat(raw);
|
|
25583
25850
|
if (Number.isNaN(seconds) || seconds < 0) {
|
|
25584
25851
|
return {
|
|
25585
|
-
message: `${
|
|
25852
|
+
message: `${color54.red("Invalid number")}: "${raw}". Enter seconds, e.g. /settings breaker-timeout 60`
|
|
25586
25853
|
};
|
|
25587
25854
|
}
|
|
25588
25855
|
const ms = Math.round(seconds * 1e3);
|
|
@@ -25595,7 +25862,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25595
25862
|
});
|
|
25596
25863
|
getProcessRegistry().setBreakerConfig({ autoKillResetMs: ms });
|
|
25597
25864
|
return {
|
|
25598
|
-
message: `${
|
|
25865
|
+
message: `${color54.green("\u2713")} breaker kill/reset timeout \u2192 ${ms > 0 ? formatDelay(ms) : color54.dim("manual")} ${color54.dim(ms > 0 ? "statusline shows a countdown when the breaker trips" : "breaker trips require /kill reset")}`
|
|
25599
25866
|
};
|
|
25600
25867
|
}
|
|
25601
25868
|
if (sub === "context-mode") {
|
|
@@ -25603,7 +25870,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25603
25870
|
const modes = ["balanced", "frugal", "deep"];
|
|
25604
25871
|
if (!modes.includes(raw)) {
|
|
25605
25872
|
return {
|
|
25606
|
-
message: `${
|
|
25873
|
+
message: `${color54.amber("Usage:")} /settings context-mode balanced|frugal|deep`
|
|
25607
25874
|
};
|
|
25608
25875
|
}
|
|
25609
25876
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25612,7 +25879,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25612
25879
|
cfg.context = ctx;
|
|
25613
25880
|
});
|
|
25614
25881
|
return {
|
|
25615
|
-
message: `${
|
|
25882
|
+
message: `${color54.green("\u2713")} context mode \u2192 ${color54.cyan(raw)} ${color54.dim("context window policy")}`
|
|
25616
25883
|
};
|
|
25617
25884
|
}
|
|
25618
25885
|
if (sub === "context-strategy") {
|
|
@@ -25620,7 +25887,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25620
25887
|
const strategies = ["hybrid", "intelligent", "selective"];
|
|
25621
25888
|
if (!strategies.includes(raw)) {
|
|
25622
25889
|
return {
|
|
25623
|
-
message: `${
|
|
25890
|
+
message: `${color54.amber("Usage:")} /settings context-strategy hybrid|intelligent|selective`
|
|
25624
25891
|
};
|
|
25625
25892
|
}
|
|
25626
25893
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25629,13 +25896,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25629
25896
|
cfg.context = ctx;
|
|
25630
25897
|
});
|
|
25631
25898
|
return {
|
|
25632
|
-
message: `${
|
|
25899
|
+
message: `${color54.green("\u2713")} context strategy \u2192 ${color54.cyan(raw)} ${color54.dim("compactor strategy")}`
|
|
25633
25900
|
};
|
|
25634
25901
|
}
|
|
25635
25902
|
if (sub === "context-auto-compact") {
|
|
25636
25903
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25637
25904
|
if (!["on", "off"].includes(raw)) {
|
|
25638
|
-
return { message: `${
|
|
25905
|
+
return { message: `${color54.amber("Usage:")} /settings context-auto-compact on|off` };
|
|
25639
25906
|
}
|
|
25640
25907
|
const on = raw === "on";
|
|
25641
25908
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25644,13 +25911,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25644
25911
|
cfg.context = ctx;
|
|
25645
25912
|
});
|
|
25646
25913
|
return {
|
|
25647
|
-
message: `${
|
|
25914
|
+
message: `${color54.green("\u2713")} context auto-compact \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("auto-compact context when thresholds crossed")}`
|
|
25648
25915
|
};
|
|
25649
25916
|
}
|
|
25650
25917
|
if (sub === "nextsteps-tool") {
|
|
25651
25918
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25652
25919
|
if (!["on", "off"].includes(raw)) {
|
|
25653
|
-
return { message: `${
|
|
25920
|
+
return { message: `${color54.amber("Usage:")} /settings nextsteps-tool on|off` };
|
|
25654
25921
|
}
|
|
25655
25922
|
const on = raw === "on";
|
|
25656
25923
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25659,7 +25926,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25659
25926
|
cfg.tools = tools;
|
|
25660
25927
|
});
|
|
25661
25928
|
return {
|
|
25662
|
-
message: `${
|
|
25929
|
+
message: `${color54.green("\u2713")} nextsteps tool \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("takes effect in the next session")}`
|
|
25663
25930
|
};
|
|
25664
25931
|
}
|
|
25665
25932
|
if (sub === "token-saving") {
|
|
@@ -25667,7 +25934,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25667
25934
|
const tiers = ["off", "minimal", "light", "medium", "aggressive"];
|
|
25668
25935
|
if (!tiers.includes(raw)) {
|
|
25669
25936
|
return {
|
|
25670
|
-
message: `${
|
|
25937
|
+
message: `${color54.amber("Usage:")} /settings token-saving off|minimal|light|medium|aggressive`
|
|
25671
25938
|
};
|
|
25672
25939
|
}
|
|
25673
25940
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25676,47 +25943,47 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25676
25943
|
cfg.features = feat;
|
|
25677
25944
|
});
|
|
25678
25945
|
return {
|
|
25679
|
-
message: `${
|
|
25946
|
+
message: `${color54.green("\u2713")} token-saving \u2192 ${color54.cyan(raw)} ${color54.dim("token-saving mode")}`
|
|
25680
25947
|
};
|
|
25681
25948
|
}
|
|
25682
25949
|
if (sub === "max-concurrent") {
|
|
25683
25950
|
const raw = rest[0];
|
|
25684
25951
|
if (raw === void 0) {
|
|
25685
25952
|
return {
|
|
25686
|
-
message: `${
|
|
25953
|
+
message: `${color54.amber("Usage:")} /settings max-concurrent <n> ${color54.dim("(0 = default)")}`
|
|
25687
25954
|
};
|
|
25688
25955
|
}
|
|
25689
25956
|
const n = Number.parseInt(raw, 10);
|
|
25690
25957
|
if (Number.isNaN(n) || n < 0) {
|
|
25691
25958
|
return {
|
|
25692
|
-
message: `${
|
|
25959
|
+
message: `${color54.red("Invalid number")}: "${raw}". Enter a non-negative integer (0 = default)`
|
|
25693
25960
|
};
|
|
25694
25961
|
}
|
|
25695
25962
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25696
25963
|
cfg.maxConcurrent = n;
|
|
25697
25964
|
});
|
|
25698
25965
|
return {
|
|
25699
|
-
message: `${
|
|
25966
|
+
message: `${color54.green("\u2713")} max-concurrent \u2192 ${color54.cyan(n === 0 ? "default" : String(n))} ${color54.dim("max concurrent subagents")}`
|
|
25700
25967
|
};
|
|
25701
25968
|
}
|
|
25702
25969
|
if (sub === "title-animation") {
|
|
25703
25970
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25704
25971
|
if (!["on", "off"].includes(raw)) {
|
|
25705
|
-
return { message: `${
|
|
25972
|
+
return { message: `${color54.amber("Usage:")} /settings title-animation on|off` };
|
|
25706
25973
|
}
|
|
25707
25974
|
const on = raw === "on";
|
|
25708
25975
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25709
25976
|
autonomy.terminalTitleAnimation = on;
|
|
25710
25977
|
});
|
|
25711
25978
|
return {
|
|
25712
|
-
message: `${
|
|
25979
|
+
message: `${color54.green("\u2713")} title animation \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("terminal title animation")}`
|
|
25713
25980
|
};
|
|
25714
25981
|
}
|
|
25715
25982
|
if (sub === "reasoning") {
|
|
25716
25983
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25717
25984
|
const modes = ["auto", "on", "off"];
|
|
25718
25985
|
if (!modes.includes(raw)) {
|
|
25719
|
-
return { message: `${
|
|
25986
|
+
return { message: `${color54.amber("Usage:")} /settings reasoning auto|on|off` };
|
|
25720
25987
|
}
|
|
25721
25988
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25722
25989
|
const mr = cfg.modelRuntime;
|
|
@@ -25724,14 +25991,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25724
25991
|
reasoning.mode = raw;
|
|
25725
25992
|
cfg.modelRuntime = { ...mr, reasoning };
|
|
25726
25993
|
});
|
|
25727
|
-
return { message: `${
|
|
25994
|
+
return { message: `${color54.green("\u2713")} reasoning mode \u2192 ${color54.bold(raw)}` };
|
|
25728
25995
|
}
|
|
25729
25996
|
if (sub === "reasoning-effort") {
|
|
25730
25997
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25731
|
-
|
|
25732
|
-
if (!efforts.includes(raw)) {
|
|
25998
|
+
if (!isReasoningEffort3(raw)) {
|
|
25733
25999
|
return {
|
|
25734
|
-
message: `${
|
|
26000
|
+
message: `${color54.amber("Usage:")} /settings reasoning-effort ${REASONING_EFFORT_LEVELS3.join("|")}`
|
|
25735
26001
|
};
|
|
25736
26002
|
}
|
|
25737
26003
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25740,12 +26006,12 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25740
26006
|
reasoning.effort = raw;
|
|
25741
26007
|
cfg.modelRuntime = { ...mr, reasoning };
|
|
25742
26008
|
});
|
|
25743
|
-
return { message: `${
|
|
26009
|
+
return { message: `${color54.green("\u2713")} reasoning effort \u2192 ${color54.bold(raw)}` };
|
|
25744
26010
|
}
|
|
25745
26011
|
if (sub === "reasoning-preserve") {
|
|
25746
26012
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25747
26013
|
if (!["on", "off"].includes(raw)) {
|
|
25748
|
-
return { message: `${
|
|
26014
|
+
return { message: `${color54.amber("Usage:")} /settings reasoning-preserve on|off` };
|
|
25749
26015
|
}
|
|
25750
26016
|
const on = raw === "on";
|
|
25751
26017
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25755,24 +26021,24 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25755
26021
|
cfg.modelRuntime = { ...mr, reasoning };
|
|
25756
26022
|
});
|
|
25757
26023
|
return {
|
|
25758
|
-
message: `${
|
|
26024
|
+
message: `${color54.green("\u2713")} reasoning preserve \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
25759
26025
|
};
|
|
25760
26026
|
}
|
|
25761
26027
|
if (sub === "cache-ttl") {
|
|
25762
26028
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25763
26029
|
if (!["5m", "1h"].includes(raw)) {
|
|
25764
|
-
return { message: `${
|
|
26030
|
+
return { message: `${color54.amber("Usage:")} /settings cache-ttl 5m|1h` };
|
|
25765
26031
|
}
|
|
25766
26032
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25767
26033
|
const mr = cfg.modelRuntime;
|
|
25768
26034
|
cfg.modelRuntime = { ...mr, cache: { ttl: raw } };
|
|
25769
26035
|
});
|
|
25770
|
-
return { message: `${
|
|
26036
|
+
return { message: `${color54.green("\u2713")} cache TTL \u2192 ${color54.bold(raw)}` };
|
|
25771
26037
|
}
|
|
25772
26038
|
if (sub === "mcp") {
|
|
25773
26039
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25774
26040
|
if (!["on", "off"].includes(raw))
|
|
25775
|
-
return { message: `${
|
|
26041
|
+
return { message: `${color54.amber("Usage:")} /settings mcp on|off` };
|
|
25776
26042
|
const on = raw === "on";
|
|
25777
26043
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25778
26044
|
const feats = cfg.features ?? {};
|
|
@@ -25780,13 +26046,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25780
26046
|
cfg.features = feats;
|
|
25781
26047
|
});
|
|
25782
26048
|
return {
|
|
25783
|
-
message: `${
|
|
26049
|
+
message: `${color54.green("\u2713")} MCP features \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
|
|
25784
26050
|
};
|
|
25785
26051
|
}
|
|
25786
26052
|
if (sub === "plugins") {
|
|
25787
26053
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25788
26054
|
if (!["on", "off"].includes(raw))
|
|
25789
|
-
return { message: `${
|
|
26055
|
+
return { message: `${color54.amber("Usage:")} /settings plugins on|off` };
|
|
25790
26056
|
const on = raw === "on";
|
|
25791
26057
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25792
26058
|
const feats = cfg.features ?? {};
|
|
@@ -25794,13 +26060,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25794
26060
|
cfg.features = feats;
|
|
25795
26061
|
});
|
|
25796
26062
|
return {
|
|
25797
|
-
message: `${
|
|
26063
|
+
message: `${color54.green("\u2713")} Plugin features \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
|
|
25798
26064
|
};
|
|
25799
26065
|
}
|
|
25800
26066
|
if (sub === "memory") {
|
|
25801
26067
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25802
26068
|
if (!["on", "off"].includes(raw))
|
|
25803
|
-
return { message: `${
|
|
26069
|
+
return { message: `${color54.amber("Usage:")} /settings memory on|off` };
|
|
25804
26070
|
const on = raw === "on";
|
|
25805
26071
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25806
26072
|
const feats = cfg.features ?? {};
|
|
@@ -25808,13 +26074,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25808
26074
|
cfg.features = feats;
|
|
25809
26075
|
});
|
|
25810
26076
|
return {
|
|
25811
|
-
message: `${
|
|
26077
|
+
message: `${color54.green("\u2713")} Memory features \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
|
|
25812
26078
|
};
|
|
25813
26079
|
}
|
|
25814
26080
|
if (sub === "skills") {
|
|
25815
26081
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25816
26082
|
if (!["on", "off"].includes(raw))
|
|
25817
|
-
return { message: `${
|
|
26083
|
+
return { message: `${color54.amber("Usage:")} /settings skills on|off` };
|
|
25818
26084
|
const on = raw === "on";
|
|
25819
26085
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25820
26086
|
const feats = cfg.features ?? {};
|
|
@@ -25822,13 +26088,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25822
26088
|
cfg.features = feats;
|
|
25823
26089
|
});
|
|
25824
26090
|
return {
|
|
25825
|
-
message: `${
|
|
26091
|
+
message: `${color54.green("\u2713")} Skills features \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
|
|
25826
26092
|
};
|
|
25827
26093
|
}
|
|
25828
26094
|
if (sub === "models-registry") {
|
|
25829
26095
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25830
26096
|
if (!["on", "off"].includes(raw))
|
|
25831
|
-
return { message: `${
|
|
26097
|
+
return { message: `${color54.amber("Usage:")} /settings models-registry on|off` };
|
|
25832
26098
|
const on = raw === "on";
|
|
25833
26099
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25834
26100
|
const feats = cfg.features ?? {};
|
|
@@ -25836,7 +26102,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25836
26102
|
cfg.features = feats;
|
|
25837
26103
|
});
|
|
25838
26104
|
return {
|
|
25839
|
-
message: `${
|
|
26105
|
+
message: `${color54.green("\u2713")} Models registry \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
|
|
25840
26106
|
};
|
|
25841
26107
|
}
|
|
25842
26108
|
if (sub === "stream-fleet") {
|
|
@@ -25844,7 +26110,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25844
26110
|
const mode = raw === "on" ? "full" : raw === "off" || raw === "full" ? raw : void 0;
|
|
25845
26111
|
if (!mode)
|
|
25846
26112
|
return {
|
|
25847
|
-
message: `${
|
|
26113
|
+
message: `${color54.amber("Usage:")} /settings stream-fleet off|full (on = full)`
|
|
25848
26114
|
};
|
|
25849
26115
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25850
26116
|
autonomy.fleetChatVerbosity = mode;
|
|
@@ -25852,43 +26118,43 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25852
26118
|
opts.fleetStreamController?.setMode(mode);
|
|
25853
26119
|
const desc = mode === "full" ? "every subagent tool call and message in chat" : "subagent chat lines hidden (F2/F3 stay live)";
|
|
25854
26120
|
return {
|
|
25855
|
-
message: `${
|
|
26121
|
+
message: `${color54.green("\u2713")} fleet chat \u2192 ${color54.cyan(mode)} ${color54.dim(desc)}`
|
|
25856
26122
|
};
|
|
25857
26123
|
}
|
|
25858
26124
|
if (sub === "chime") {
|
|
25859
26125
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25860
26126
|
if (!["on", "off"].includes(raw))
|
|
25861
|
-
return { message: `${
|
|
26127
|
+
return { message: `${color54.amber("Usage:")} /settings chime on|off` };
|
|
25862
26128
|
const on = raw === "on";
|
|
25863
26129
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25864
26130
|
autonomy.chime = on;
|
|
25865
26131
|
});
|
|
25866
26132
|
return {
|
|
25867
|
-
message: `${
|
|
26133
|
+
message: `${color54.green("\u2713")} completion chime \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
25868
26134
|
};
|
|
25869
26135
|
}
|
|
25870
26136
|
if (sub === "confirm-exit") {
|
|
25871
26137
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25872
26138
|
if (!["on", "off"].includes(raw))
|
|
25873
|
-
return { message: `${
|
|
26139
|
+
return { message: `${color54.amber("Usage:")} /settings confirm-exit on|off` };
|
|
25874
26140
|
const on = raw === "on";
|
|
25875
26141
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25876
26142
|
autonomy.confirmExit = on;
|
|
25877
26143
|
});
|
|
25878
26144
|
return {
|
|
25879
|
-
message: `${
|
|
26145
|
+
message: `${color54.green("\u2713")} confirm before exit \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
25880
26146
|
};
|
|
25881
26147
|
}
|
|
25882
26148
|
if (sub === "max-iterations") {
|
|
25883
26149
|
const raw = rest[0];
|
|
25884
26150
|
if (raw === void 0)
|
|
25885
26151
|
return {
|
|
25886
|
-
message: `${
|
|
26152
|
+
message: `${color54.amber("Usage:")} /settings max-iterations <n> ${color54.dim("(0 = default)")}`
|
|
25887
26153
|
};
|
|
25888
26154
|
const n = Number.parseInt(raw, 10);
|
|
25889
26155
|
if (Number.isNaN(n) || n < 0)
|
|
25890
26156
|
return {
|
|
25891
|
-
message: `${
|
|
26157
|
+
message: `${color54.red("Invalid number")}: "${raw}". Enter a non-negative integer.`
|
|
25892
26158
|
};
|
|
25893
26159
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25894
26160
|
const tools = cfg.tools ?? {};
|
|
@@ -25896,31 +26162,31 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25896
26162
|
cfg.tools = tools;
|
|
25897
26163
|
});
|
|
25898
26164
|
return {
|
|
25899
|
-
message: `${
|
|
26165
|
+
message: `${color54.green("\u2713")} max iterations \u2192 ${color54.cyan(n === 0 ? "default" : String(n))} ${color54.dim("agent pauses after this many iterations")}`
|
|
25900
26166
|
};
|
|
25901
26167
|
}
|
|
25902
26168
|
if (sub === "auto-proceed-max-iterations") {
|
|
25903
26169
|
const raw = rest[0];
|
|
25904
26170
|
if (raw === void 0)
|
|
25905
26171
|
return {
|
|
25906
|
-
message: `${
|
|
26172
|
+
message: `${color54.amber("Usage:")} /settings auto-proceed-max-iterations <n> ${color54.dim("(0 = unlimited)")}`
|
|
25907
26173
|
};
|
|
25908
26174
|
const n = Number.parseInt(raw, 10);
|
|
25909
26175
|
if (Number.isNaN(n) || n < 0)
|
|
25910
26176
|
return {
|
|
25911
|
-
message: `${
|
|
26177
|
+
message: `${color54.red("Invalid number")}: "${raw}". Enter a non-negative integer.`
|
|
25912
26178
|
};
|
|
25913
26179
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25914
26180
|
autonomy.autoProceedMaxIterations = n;
|
|
25915
26181
|
});
|
|
25916
26182
|
return {
|
|
25917
|
-
message: `${
|
|
26183
|
+
message: `${color54.green("\u2713")} auto-proceed max iterations \u2192 ${color54.cyan(n === 0 ? "unlimited" : String(n))}`
|
|
25918
26184
|
};
|
|
25919
26185
|
}
|
|
25920
26186
|
if (sub === "index-on-start") {
|
|
25921
26187
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25922
26188
|
if (!["on", "off"].includes(raw))
|
|
25923
|
-
return { message: `${
|
|
26189
|
+
return { message: `${color54.amber("Usage:")} /settings index-on-start on|off` };
|
|
25924
26190
|
const on = raw === "on";
|
|
25925
26191
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25926
26192
|
const idx = cfg.indexing ?? {};
|
|
@@ -25928,7 +26194,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25928
26194
|
cfg.indexing = idx;
|
|
25929
26195
|
});
|
|
25930
26196
|
return {
|
|
25931
|
-
message: `${
|
|
26197
|
+
message: `${color54.green("\u2713")} index on session start \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("effective next session")}`
|
|
25932
26198
|
};
|
|
25933
26199
|
}
|
|
25934
26200
|
if (sub === "log-level") {
|
|
@@ -25936,21 +26202,21 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25936
26202
|
const levels = ["error", "warn", "info", "debug", "trace"];
|
|
25937
26203
|
if (!levels.includes(raw))
|
|
25938
26204
|
return {
|
|
25939
|
-
message: `${
|
|
26205
|
+
message: `${color54.amber("Usage:")} /settings log-level error|warn|info|debug|trace`
|
|
25940
26206
|
};
|
|
25941
26207
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25942
26208
|
const log = cfg.log ?? {};
|
|
25943
26209
|
log.level = raw;
|
|
25944
26210
|
cfg.log = log;
|
|
25945
26211
|
});
|
|
25946
|
-
return { message: `${
|
|
26212
|
+
return { message: `${color54.green("\u2713")} log level \u2192 ${color54.cyan(raw)}` };
|
|
25947
26213
|
}
|
|
25948
26214
|
if (sub === "audit-level") {
|
|
25949
26215
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25950
26216
|
const levels = ["minimal", "standard", "full"];
|
|
25951
26217
|
if (!levels.includes(raw))
|
|
25952
26218
|
return {
|
|
25953
|
-
message: `${
|
|
26219
|
+
message: `${color54.amber("Usage:")} /settings audit-level minimal|standard|full`
|
|
25954
26220
|
};
|
|
25955
26221
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25956
26222
|
const sess = cfg.session ?? {};
|
|
@@ -25958,38 +26224,38 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25958
26224
|
cfg.session = sess;
|
|
25959
26225
|
});
|
|
25960
26226
|
return {
|
|
25961
|
-
message: `${
|
|
26227
|
+
message: `${color54.green("\u2713")} audit level \u2192 ${color54.cyan(raw)} ${color54.dim("restart to apply")}`
|
|
25962
26228
|
};
|
|
25963
26229
|
}
|
|
25964
26230
|
if (sub === "thinking-word") {
|
|
25965
26231
|
const raw = rest.join(" ").trim();
|
|
25966
26232
|
if (!raw)
|
|
25967
26233
|
return {
|
|
25968
|
-
message: `${
|
|
26234
|
+
message: `${color54.amber("Usage:")} /settings thinking-word <word> ${color54.dim('single short word, e.g. "thinking", "vibing", "cooking"')}`
|
|
25969
26235
|
};
|
|
25970
26236
|
if (raw.length > 16)
|
|
25971
|
-
return { message: `${
|
|
26237
|
+
return { message: `${color54.red("Word too long")}: max 16 characters.` };
|
|
25972
26238
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25973
26239
|
autonomy.thinkingWord = raw;
|
|
25974
26240
|
});
|
|
25975
|
-
return { message: `${
|
|
26241
|
+
return { message: `${color54.green("\u2713")} thinking word \u2192 ${color54.cyan(raw)}` };
|
|
25976
26242
|
}
|
|
25977
26243
|
if (sub === "statusline") {
|
|
25978
26244
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25979
26245
|
const modes = ["minimum", "detailed", "no-color"];
|
|
25980
26246
|
if (!modes.includes(raw))
|
|
25981
26247
|
return {
|
|
25982
|
-
message: `${
|
|
26248
|
+
message: `${color54.amber("Usage:")} /settings statusline minimum|detailed|no-color`
|
|
25983
26249
|
};
|
|
25984
26250
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25985
26251
|
autonomy.statuslineMode = raw;
|
|
25986
26252
|
});
|
|
25987
|
-
return { message: `${
|
|
26253
|
+
return { message: `${color54.green("\u2713")} statusline mode \u2192 ${color54.cyan(raw)}` };
|
|
25988
26254
|
}
|
|
25989
26255
|
if (sub === "read-symbols") {
|
|
25990
26256
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25991
26257
|
if (!["on", "off"].includes(raw)) {
|
|
25992
|
-
return { message: `${
|
|
26258
|
+
return { message: `${color54.amber("Usage:")} /settings read-symbols on|off` };
|
|
25993
26259
|
}
|
|
25994
26260
|
const on = raw === "on";
|
|
25995
26261
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
@@ -25999,7 +26265,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25999
26265
|
opts.context.meta["tools.read.advancedMode"] = on;
|
|
26000
26266
|
}
|
|
26001
26267
|
return {
|
|
26002
|
-
message: `${
|
|
26268
|
+
message: `${color54.green("\u2713")} read symbols \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim(on ? "codebase-index symbols will be included in read tool results" : "read tool returns file content only")}`
|
|
26003
26269
|
};
|
|
26004
26270
|
}
|
|
26005
26271
|
if (sub === "animation") {
|
|
@@ -26007,26 +26273,26 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
26007
26273
|
const styles = ["rainbow", "wave", "pulse", "dots", "breathe", "cycle"];
|
|
26008
26274
|
if (!styles.includes(raw))
|
|
26009
26275
|
return {
|
|
26010
|
-
message: `${
|
|
26276
|
+
message: `${color54.amber("Usage:")} /settings animation rainbow|wave|pulse|dots|breathe|cycle`
|
|
26011
26277
|
};
|
|
26012
26278
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
26013
26279
|
autonomy.animationStyle = raw;
|
|
26014
26280
|
});
|
|
26015
|
-
return { message: `${
|
|
26281
|
+
return { message: `${color54.green("\u2713")} animation style \u2192 ${color54.cyan(raw)}` };
|
|
26016
26282
|
}
|
|
26017
26283
|
return {
|
|
26018
|
-
message: `${
|
|
26284
|
+
message: `${color54.red("Unknown setting")} "${sub}". ${unknownSubcommand(sub, ALL_SETTINGS_KEYS, "settings")}`
|
|
26019
26285
|
};
|
|
26020
26286
|
} catch (err) {
|
|
26021
26287
|
return {
|
|
26022
|
-
message: `${
|
|
26288
|
+
message: `${color54.red("Settings error")}: ${toErrorMessage23(err)}`
|
|
26023
26289
|
};
|
|
26024
26290
|
}
|
|
26025
26291
|
}
|
|
26026
26292
|
|
|
26027
26293
|
// src/slash-commands/settings-view.ts
|
|
26028
26294
|
import { resolveFleetChatVerbosity } from "@wrongstack/core/types";
|
|
26029
|
-
import { color as
|
|
26295
|
+
import { color as color55 } from "@wrongstack/core/utils";
|
|
26030
26296
|
var SETTINGS_HELP = [
|
|
26031
26297
|
"Usage:",
|
|
26032
26298
|
" /settings Show current settings",
|
|
@@ -26084,16 +26350,16 @@ var SETTINGS_HELP = [
|
|
|
26084
26350
|
].join("\n");
|
|
26085
26351
|
function formatSettingsDefaults() {
|
|
26086
26352
|
return [
|
|
26087
|
-
`${
|
|
26353
|
+
`${color55.bold("Default Values")}`,
|
|
26088
26354
|
"",
|
|
26089
|
-
` auto-proceed delay: ${
|
|
26090
|
-
` default autonomy mode: ${
|
|
26091
|
-
` launch hints: ${
|
|
26092
|
-
` iteration timeout: ${
|
|
26093
|
-
` session timeout: ${
|
|
26094
|
-
` max iterations: ${
|
|
26095
|
-
` max concurrent: ${
|
|
26096
|
-
` semver default part: ${
|
|
26355
|
+
` auto-proceed delay: ${color55.cyan("45s")} ${color55.dim("(WRONGSTACK_AUTO_PROCEED_DELAY_MS env)")}`,
|
|
26356
|
+
` default autonomy mode: ${color55.cyan("off")}`,
|
|
26357
|
+
` launch hints: ${color55.cyan("on")}`,
|
|
26358
|
+
` iteration timeout: ${color55.cyan("5 min")}`,
|
|
26359
|
+
` session timeout: ${color55.cyan("30 min")}`,
|
|
26360
|
+
` max iterations: ${color55.cyan("100")}`,
|
|
26361
|
+
` max concurrent: ${color55.cyan("4")}`,
|
|
26362
|
+
` semver default part: ${color55.cyan("patch")}`
|
|
26097
26363
|
].join("\n");
|
|
26098
26364
|
}
|
|
26099
26365
|
function formatCurrentSettingsView(opts) {
|
|
@@ -26137,56 +26403,56 @@ function formatCurrentSettingsView(opts) {
|
|
|
26137
26403
|
const idx = opts.configStore.get().indexing;
|
|
26138
26404
|
const sess = opts.configStore.get().session;
|
|
26139
26405
|
return [
|
|
26140
|
-
`${
|
|
26406
|
+
`${color55.bold("WrongStack")} ${color55.dim("\u2014 Settings")}`,
|
|
26141
26407
|
"",
|
|
26142
|
-
` auto-proceed delay: ${
|
|
26143
|
-
` default autonomy mode: ${
|
|
26144
|
-
` fleet chat: ${
|
|
26145
|
-
` completion chime: ${au?.chime === true ?
|
|
26146
|
-
` confirm before exit: ${au?.confirmExit !== false ?
|
|
26147
|
-
` launch hints: ${hints ?
|
|
26148
|
-
` debug stream: ${debugStream ?
|
|
26149
|
-
` config scope: ${
|
|
26150
|
-
` filesystem access: ${
|
|
26151
|
-
` refine: ${enhanceEnabled ?
|
|
26152
|
-
` refine-delay: ${
|
|
26153
|
-
` refine-language: ${
|
|
26154
|
-
` refiner-provider: ${
|
|
26155
|
-
` refiner-model: ${
|
|
26156
|
-
` refiner-fallback-profile: ${
|
|
26157
|
-
` semver default part: ${
|
|
26158
|
-
` circuit breaker: ${breakerEnabled ?
|
|
26159
|
-
` context mode: ${
|
|
26160
|
-
` context strategy: ${
|
|
26161
|
-
` context auto-compact: ${contextAutoCompact ?
|
|
26162
|
-
` token-saving: ${
|
|
26163
|
-
` nextsteps tool: ${nextStepsToolEnabled ?
|
|
26164
|
-
` MCP features: ${feats?.mcp !== false ?
|
|
26165
|
-
` plugin features: ${feats?.plugins !== false ?
|
|
26166
|
-
` memory features: ${feats?.memory !== false ?
|
|
26167
|
-
` skills features: ${feats?.skills !== false ?
|
|
26168
|
-
` models registry: ${feats?.modelsRegistry !== false ?
|
|
26169
|
-
` max concurrent: ${
|
|
26170
|
-
` max iterations: ${
|
|
26171
|
-
` auto-proceed max iters: ${
|
|
26172
|
-
` title animation: ${titleAnimation ?
|
|
26173
|
-
` thinking word: ${
|
|
26174
|
-
` statusline mode: ${
|
|
26175
|
-
` animation style: ${
|
|
26176
|
-
` read symbols: ${au?.readAdvancedMode === true ?
|
|
26177
|
-
` reasoning mode: ${
|
|
26178
|
-
` reasoning effort: ${
|
|
26179
|
-
` reasoning preserve: ${reasoningPreserve ?
|
|
26180
|
-
` cache TTL: ${
|
|
26181
|
-
` index on start: ${idx?.onSessionStart !== false ?
|
|
26182
|
-
` log level: ${
|
|
26183
|
-
` audit level: ${
|
|
26184
|
-
` HQ publishing: ${hqEnabled ?
|
|
26185
|
-
` HQ URL: ${
|
|
26186
|
-
` HQ token: ${
|
|
26187
|
-
` HQ raw content: ${hq?.rawContent === true ?
|
|
26408
|
+
` auto-proceed delay: ${color55.cyan(formatDelay(delay))} ${color55.dim("change: /settings delay <seconds>")}`,
|
|
26409
|
+
` default autonomy mode: ${color55.cyan(mode)} ${color55.dim("change: /settings mode off|suggest|auto")}`,
|
|
26410
|
+
` fleet chat: ${color55.cyan(resolveFleetChatVerbosity(au))} ${color55.dim("change: /settings stream-fleet off|full")}`,
|
|
26411
|
+
` completion chime: ${au?.chime === true ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings chime on|off")}`,
|
|
26412
|
+
` confirm before exit: ${au?.confirmExit !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings confirm-exit on|off")}`,
|
|
26413
|
+
` launch hints: ${hints ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings hints on|off")}`,
|
|
26414
|
+
` debug stream: ${debugStream ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings debug-stream on|off")}`,
|
|
26415
|
+
` config scope: ${color55.cyan(configScope)} ${color55.dim("change: /settings config-scope global|project")}`,
|
|
26416
|
+
` filesystem access: ${color55.cyan(fsAccess)} ${color55.dim("change: /settings fs-access unrestricted|project")}`,
|
|
26417
|
+
` refine: ${enhanceEnabled ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings refine on|off")}`,
|
|
26418
|
+
` refine-delay: ${color55.cyan(formatDelay(enhanceDelay))} ${color55.dim("change: /settings refine-delay <seconds>")}`,
|
|
26419
|
+
` refine-language: ${color55.cyan(enhanceLanguage)} ${color55.dim("change: /settings refine-language original|english")}`,
|
|
26420
|
+
` refiner-provider: ${color55.cyan(au?.refinerProvider ?? color55.dim("(unset)"))} ${color55.dim("change: /settings refiner-provider <id>")}`,
|
|
26421
|
+
` refiner-model: ${color55.cyan(au?.refinerModel ?? color55.dim("(unset)"))} ${color55.dim("change: /settings refiner-model <model>")}`,
|
|
26422
|
+
` refiner-fallback-profile: ${color55.cyan(au?.refinerFallbackProfile ?? color55.dim("(unset)"))} ${color55.dim("change: /settings refiner-fallback-profile <name>")}`,
|
|
26423
|
+
` semver default part: ${color55.cyan(semverPart)} ${color55.dim("change: /settings semver-part patch|minor|major|auto")}`,
|
|
26424
|
+
` circuit breaker: ${breakerEnabled ? color55.cyan("on") : color55.dim("off")} (${breakerTimeout > 0 ? formatDelay(breakerTimeout) : color55.dim("manual")}) ${color55.dim("change: /settings breaker on|off")}`,
|
|
26425
|
+
` context mode: ${color55.cyan(contextMode)} ${color55.dim("change: /settings context-mode balanced|frugal|deep")}`,
|
|
26426
|
+
` context strategy: ${color55.cyan(contextStrategy)} ${color55.dim("change: /settings context-strategy hybrid|intelligent|selective")}`,
|
|
26427
|
+
` context auto-compact: ${contextAutoCompact ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings context-auto-compact on|off")}`,
|
|
26428
|
+
` token-saving: ${color55.cyan(tokenSavingTier)} ${color55.dim("change: /settings token-saving off|minimal|light|medium|aggressive")}`,
|
|
26429
|
+
` nextsteps tool: ${nextStepsToolEnabled ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings nextsteps-tool on|off")}`,
|
|
26430
|
+
` MCP features: ${feats?.mcp !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings mcp on|off")}`,
|
|
26431
|
+
` plugin features: ${feats?.plugins !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings plugins on|off")}`,
|
|
26432
|
+
` memory features: ${feats?.memory !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings memory on|off")}`,
|
|
26433
|
+
` skills features: ${feats?.skills !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings skills on|off")}`,
|
|
26434
|
+
` models registry: ${feats?.modelsRegistry !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings models-registry on|off")}`,
|
|
26435
|
+
` max concurrent: ${color55.cyan(maxConcurrent === 0 ? "default" : String(maxConcurrent))} ${color55.dim("change: /settings max-concurrent <n>")}`,
|
|
26436
|
+
` max iterations: ${color55.cyan(String(tools?.maxIterations ?? "default"))} ${color55.dim("change: /settings max-iterations <n>")}`,
|
|
26437
|
+
` auto-proceed max iters: ${color55.cyan(String(au?.autoProceedMaxIterations ?? "unlimited"))} ${color55.dim("change: /settings auto-proceed-max-iterations <n>")}`,
|
|
26438
|
+
` title animation: ${titleAnimation ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings title-animation on|off")}`,
|
|
26439
|
+
` thinking word: ${color55.cyan(au?.thinkingWord ?? "thinking")} ${color55.dim("change: /settings thinking-word <word>")}`,
|
|
26440
|
+
` statusline mode: ${color55.cyan(au?.statuslineMode ?? "minimum")} ${color55.dim("change: /settings statusline minimum|detailed|no-color")}`,
|
|
26441
|
+
` animation style: ${color55.cyan(au?.animationStyle ?? "rainbow")} ${color55.dim("change: /settings animation rainbow|wave|pulse|dots|breathe|cycle")}`,
|
|
26442
|
+
` read symbols: ${au?.readAdvancedMode === true ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings read-symbols on|off")}`,
|
|
26443
|
+
` reasoning mode: ${color55.cyan(reasoningMode)} ${color55.dim("change: /settings reasoning auto|on|off")}`,
|
|
26444
|
+
` reasoning effort: ${color55.cyan(reasoningEffort)} ${color55.dim("change: /settings reasoning-effort <level>")}`,
|
|
26445
|
+
` reasoning preserve: ${reasoningPreserve ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings reasoning-preserve on|off")}`,
|
|
26446
|
+
` cache TTL: ${color55.cyan(cacheTtl)} ${color55.dim("change: /settings cache-ttl 5m|1h")}`,
|
|
26447
|
+
` index on start: ${idx?.onSessionStart !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings index-on-start on|off")}`,
|
|
26448
|
+
` log level: ${color55.cyan(log?.level ?? "info")} ${color55.dim("change: /settings log-level error|warn|info|debug|trace")}`,
|
|
26449
|
+
` audit level: ${color55.cyan(sess?.auditLevel ?? "standard")} ${color55.dim("change: /settings audit-level minimal|standard|full")}`,
|
|
26450
|
+
` HQ publishing: ${hqEnabled ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings hq on|off")}`,
|
|
26451
|
+
` HQ URL: ${color55.cyan(hqUrl)} ${color55.dim("change: /settings hq-url <url>")}`,
|
|
26452
|
+
` HQ token: ${color55.cyan(hqToken)} ${color55.dim("change: /settings hq-token <token>")}`,
|
|
26453
|
+
` HQ raw content: ${hq?.rawContent === true ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings hq-raw on|off")}`,
|
|
26188
26454
|
"",
|
|
26189
|
-
|
|
26455
|
+
color55.dim(` Persisted to ${persistedTo} \xB7 /settings help for more`)
|
|
26190
26456
|
].join("\n");
|
|
26191
26457
|
}
|
|
26192
26458
|
|
|
@@ -26204,7 +26470,7 @@ function buildSettingsCommand(opts) {
|
|
|
26204
26470
|
return { message: this.help ?? "" };
|
|
26205
26471
|
}
|
|
26206
26472
|
if (!opts.configStore || !opts.paths) {
|
|
26207
|
-
return { message: `${
|
|
26473
|
+
return { message: `${color56.red("Error")} config store not available.` };
|
|
26208
26474
|
}
|
|
26209
26475
|
if (!sub) {
|
|
26210
26476
|
return { message: formatCurrentSettingsView(opts) };
|
|
@@ -26221,7 +26487,7 @@ function buildSettingsCommand(opts) {
|
|
|
26221
26487
|
|
|
26222
26488
|
// src/slash-commands/shadow.ts
|
|
26223
26489
|
import { ToolValidationError as ToolValidationError5 } from "@wrongstack/core/types";
|
|
26224
|
-
import { color as
|
|
26490
|
+
import { color as color57 } from "@wrongstack/core/utils";
|
|
26225
26491
|
var DEFAULT_SHADOW_INTERVAL_MS = 3e4;
|
|
26226
26492
|
var MIN_SHADOW_INTERVAL_MS = 5e3;
|
|
26227
26493
|
function buildShadowCommand(opts) {
|
|
@@ -26291,7 +26557,7 @@ function buildShadowCommand(opts) {
|
|
|
26291
26557
|
if (opts.shadowController?.activeId != null) {
|
|
26292
26558
|
return {
|
|
26293
26559
|
message: [
|
|
26294
|
-
`${
|
|
26560
|
+
`${color57.yellow("\u26A0")} A Shadow Agent is already running (${opts.shadowController.activeId.slice(0, 8)}).`,
|
|
26295
26561
|
"",
|
|
26296
26562
|
"Only one Shadow Agent instance is allowed per session.",
|
|
26297
26563
|
"Use /shadow status to view the current instance."
|
|
@@ -26330,16 +26596,16 @@ function buildShadowCommand(opts) {
|
|
|
26330
26596
|
shadowIntervalMs: intervalMs
|
|
26331
26597
|
});
|
|
26332
26598
|
return {
|
|
26333
|
-
message: `${
|
|
26334
|
-
${
|
|
26335
|
-
${
|
|
26599
|
+
message: `${color57.green("\u2713")} Shadow Agent queued: ${spawnId}
|
|
26600
|
+
${color57.dim("Mode:")} one-shot quiet check
|
|
26601
|
+
${color57.dim("Model:")} ${modelRef.label}`
|
|
26336
26602
|
};
|
|
26337
26603
|
}
|
|
26338
26604
|
case "stop": {
|
|
26339
26605
|
const activeId = opts.shadowController?.activeId;
|
|
26340
26606
|
if (!activeId) {
|
|
26341
26607
|
return {
|
|
26342
|
-
message: `${
|
|
26608
|
+
message: `${color57.yellow("\u26A0")} No active Shadow Agent is registered for this session.`
|
|
26343
26609
|
};
|
|
26344
26610
|
}
|
|
26345
26611
|
if (!opts.onFleetTerminate) {
|
|
@@ -26348,12 +26614,12 @@ ${color56.dim("Model:")} ${modelRef.label}`
|
|
|
26348
26614
|
const ok = await opts.onFleetTerminate(activeId);
|
|
26349
26615
|
if (ok) {
|
|
26350
26616
|
opts.shadowController?.clear();
|
|
26351
|
-
return { message: `${
|
|
26617
|
+
return { message: `${color57.green("\u2713")} Shadow Agent stopped: ${activeId}` };
|
|
26352
26618
|
}
|
|
26353
26619
|
return {
|
|
26354
26620
|
message: [
|
|
26355
|
-
`${
|
|
26356
|
-
`It may already be stopped. Use ${
|
|
26621
|
+
`${color57.red("\u2717")} Failed to stop Shadow Agent ${color57.bold(activeId)}.`,
|
|
26622
|
+
`It may already be stopped. Use ${color57.bold("/shadow status")} to inspect active agents.`
|
|
26357
26623
|
].join("\n")
|
|
26358
26624
|
};
|
|
26359
26625
|
}
|
|
@@ -26381,10 +26647,10 @@ ${color56.dim("Model:")} ${modelRef.label}`
|
|
|
26381
26647
|
opts.shadowController?.clear();
|
|
26382
26648
|
return {
|
|
26383
26649
|
message: [
|
|
26384
|
-
`${
|
|
26650
|
+
`${color57.red("\u26A0")} HOOP: Stopped ${killed} running agent(s)`,
|
|
26385
26651
|
"",
|
|
26386
|
-
`Target: ${
|
|
26387
|
-
`Reason: ${
|
|
26652
|
+
`Target: ${color57.bold("all")}`,
|
|
26653
|
+
`Reason: ${color57.yellow(reason)}`
|
|
26388
26654
|
].join("\n")
|
|
26389
26655
|
};
|
|
26390
26656
|
}
|
|
@@ -26398,10 +26664,10 @@ ${color56.dim("Model:")} ${modelRef.label}`
|
|
|
26398
26664
|
}
|
|
26399
26665
|
return {
|
|
26400
26666
|
message: [
|
|
26401
|
-
ok ? `${
|
|
26667
|
+
ok ? `${color57.red("\u26A0")} HOOP: Stopped agent` : `${color57.red("\u2717")} HOOP: Failed to stop agent`,
|
|
26402
26668
|
"",
|
|
26403
|
-
`Target: ${
|
|
26404
|
-
`Reason: ${
|
|
26669
|
+
`Target: ${color57.bold(targetId)}`,
|
|
26670
|
+
`Reason: ${color57.yellow(reason)}`,
|
|
26405
26671
|
agentInfo ? `
|
|
26406
26672
|
Agent info:
|
|
26407
26673
|
${agentInfo}` : ""
|
|
@@ -26426,7 +26692,7 @@ Current default: ${defaultModelRef.label}`
|
|
|
26426
26692
|
opts.shadowController?.setDefaults?.({ provider: parsed.provider, model: parsed.model });
|
|
26427
26693
|
return {
|
|
26428
26694
|
message: `/shadow model ${parsed.label}
|
|
26429
|
-
${
|
|
26695
|
+
${color57.dim("Model will be applied on next /shadow start")}`
|
|
26430
26696
|
};
|
|
26431
26697
|
}
|
|
26432
26698
|
case "interval": {
|
|
@@ -26446,7 +26712,7 @@ Current default: ${DEFAULT_SHADOW_INTERVAL_MS}ms (30 seconds)`
|
|
|
26446
26712
|
opts.shadowController?.setDefaults?.({ intervalMs: ms });
|
|
26447
26713
|
return {
|
|
26448
26714
|
message: `/shadow interval ${ms}ms
|
|
26449
|
-
${
|
|
26715
|
+
${color57.dim("Interval will be applied on next /shadow start")}`
|
|
26450
26716
|
};
|
|
26451
26717
|
}
|
|
26452
26718
|
default: {
|
|
@@ -26719,7 +26985,7 @@ function buildStatuslineCommand(deps) {
|
|
|
26719
26985
|
}
|
|
26720
26986
|
|
|
26721
26987
|
// src/slash-commands/supervisor.ts
|
|
26722
|
-
import { color as
|
|
26988
|
+
import { color as color58 } from "@wrongstack/core/utils";
|
|
26723
26989
|
function fmtAge4(at) {
|
|
26724
26990
|
const s = Math.max(0, Math.round((Date.now() - at) / 1e3));
|
|
26725
26991
|
if (s < 60) return `${s}s ago`;
|
|
@@ -26755,13 +27021,13 @@ function buildSupervisorCommand(opts) {
|
|
|
26755
27021
|
}
|
|
26756
27022
|
if (sub === "on") {
|
|
26757
27023
|
supervisor.start();
|
|
26758
|
-
const msg2 = `Fleet supervisor ${
|
|
27024
|
+
const msg2 = `Fleet supervisor ${color58.green("armed")} \u2014 evaluating every ${Math.round(supervisor.configSnapshot().intervalMs / 1e3)}s.`;
|
|
26759
27025
|
opts.renderer.write(msg2);
|
|
26760
27026
|
return { message: msg2 };
|
|
26761
27027
|
}
|
|
26762
27028
|
if (sub === "off") {
|
|
26763
27029
|
supervisor.stop();
|
|
26764
|
-
const msg2 = `Fleet supervisor ${
|
|
27030
|
+
const msg2 = `Fleet supervisor ${color58.yellow("disarmed")} \u2014 no further automatic interventions this session.`;
|
|
26765
27031
|
opts.renderer.write(msg2);
|
|
26766
27032
|
return { message: msg2 };
|
|
26767
27033
|
}
|
|
@@ -26774,10 +27040,10 @@ function buildSupervisorCommand(opts) {
|
|
|
26774
27040
|
return { message: msg3 };
|
|
26775
27041
|
}
|
|
26776
27042
|
const lines2 = entries.map((e) => {
|
|
26777
|
-
const who = e.subagentId ? ` ${
|
|
27043
|
+
const who = e.subagentId ? ` ${color58.cyan(e.subagentId)}` : "";
|
|
26778
27044
|
const task = e.taskId ? ` task=${e.taskId.slice(0, 8)}` : "";
|
|
26779
|
-
const outcome = e.outcome === "approved" ?
|
|
26780
|
-
return `${
|
|
27045
|
+
const outcome = e.outcome === "approved" ? color58.green(e.outcome) : e.outcome === "denied" || e.outcome === "error" ? color58.red(e.outcome) : color58.yellow(e.outcome);
|
|
27046
|
+
return `${color58.dim(fmtAge4(e.at))} ${e.kind}${who}${task} \u2192 ${e.proposedAction} [${outcome}] ${color58.dim(e.detail)}`;
|
|
26781
27047
|
});
|
|
26782
27048
|
const msg2 = lines2.join("\n");
|
|
26783
27049
|
opts.renderer.write(msg2);
|
|
@@ -26787,12 +27053,12 @@ function buildSupervisorCommand(opts) {
|
|
|
26787
27053
|
const history = supervisor.history();
|
|
26788
27054
|
const last = history[history.length - 1];
|
|
26789
27055
|
const lines = [
|
|
26790
|
-
`Fleet supervisor: ${supervisor.isRunning() ?
|
|
27056
|
+
`Fleet supervisor: ${supervisor.isRunning() ? color58.green("armed") : color58.yellow("disarmed")}`,
|
|
26791
27057
|
` interval ${Math.round(cfg.intervalMs / 1e3)}s \xB7 cooldown ${Math.round(cfg.cooldownMs / 1e3)}s \xB7 max ${cfg.maxInterventionsPerSubagent} interventions/agent`,
|
|
26792
27058
|
` signals: starvation>${Math.round(cfg.pinnedWaitMs / 1e3)}s \xB7 overload\u2265${cfg.overloadPinnedThreshold} pinned \xB7 backlog>${cfg.backlogFactor}\xD7workers \xB7 stuck>${Math.round(cfg.stuckMs / 1e3)}s \xB7 failstreak\u2265${cfg.failureStreak}`,
|
|
26793
27059
|
` actions: retarget \u2713 \xB7 spawn ${cfg.allowSpawn ? "\u2713" : "\u2717"} \xB7 steer \u2713 \xB7 terminate ${cfg.allowTerminate ? "\u2713" : "\u2717 (config fleet.supervisor.allowTerminate)"}`,
|
|
26794
27060
|
` activity: ${history.length} engagement(s)${last ? ` \u2014 last: ${last.kind} \u2192 ${last.proposedAction} [${last.outcome}] ${fmtAge4(last.at)}` : ""}`,
|
|
26795
|
-
|
|
27061
|
+
color58.dim(" decisions are gated by the Brain \u2014 see /brain (risk ceiling applies)")
|
|
26796
27062
|
];
|
|
26797
27063
|
const msg = lines.join("\n");
|
|
26798
27064
|
opts.renderer.write(msg);
|
|
@@ -26802,7 +27068,7 @@ function buildSupervisorCommand(opts) {
|
|
|
26802
27068
|
}
|
|
26803
27069
|
|
|
26804
27070
|
// src/slash-commands/tasks.ts
|
|
26805
|
-
import { randomUUID as
|
|
27071
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
26806
27072
|
import {
|
|
26807
27073
|
addPlanItem as addPlanItem2,
|
|
26808
27074
|
emptyPlan as emptyPlan2,
|
|
@@ -26965,7 +27231,7 @@ ${formatPlan2(updated)}`;
|
|
|
26965
27231
|
const title = parts.join(" ");
|
|
26966
27232
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
26967
27233
|
file.tasks.push({
|
|
26968
|
-
id: `task_${
|
|
27234
|
+
id: `task_${randomUUID7()}`,
|
|
26969
27235
|
title,
|
|
26970
27236
|
type,
|
|
26971
27237
|
priority,
|
|
@@ -27135,7 +27401,7 @@ ${formatTaskProgress(file.tasks)}`;
|
|
|
27135
27401
|
];
|
|
27136
27402
|
if (found.item.description) {
|
|
27137
27403
|
todos.push({
|
|
27138
|
-
id: `todo_${
|
|
27404
|
+
id: `todo_${randomUUID7()}`,
|
|
27139
27405
|
content: found.item.description.slice(0, 200),
|
|
27140
27406
|
status: "pending",
|
|
27141
27407
|
promotedFromTask: found.item.id
|
|
@@ -27219,21 +27485,21 @@ ${formatTaskProgress(file.tasks)}`;
|
|
|
27219
27485
|
}
|
|
27220
27486
|
|
|
27221
27487
|
// src/slash-commands/techstack.ts
|
|
27222
|
-
import * as
|
|
27488
|
+
import * as fs16 from "node:fs/promises";
|
|
27223
27489
|
import * as path19 from "node:path";
|
|
27224
|
-
import { color as
|
|
27490
|
+
import { color as color59, toErrorMessage as toErrorMessage25 } from "@wrongstack/core/utils";
|
|
27225
27491
|
async function discoverPackageFiles(projectRoot) {
|
|
27226
27492
|
const files = [];
|
|
27227
27493
|
const rootPkg = path19.join(projectRoot, "package.json");
|
|
27228
27494
|
try {
|
|
27229
|
-
await
|
|
27495
|
+
await fs16.access(rootPkg);
|
|
27230
27496
|
files.push(rootPkg);
|
|
27231
27497
|
} catch {
|
|
27232
27498
|
}
|
|
27233
27499
|
const workspaceFile = path19.join(projectRoot, "pnpm-workspace.yaml");
|
|
27234
27500
|
try {
|
|
27235
|
-
await
|
|
27236
|
-
const content = await
|
|
27501
|
+
await fs16.access(workspaceFile);
|
|
27502
|
+
const content = await fs16.readFile(workspaceFile, "utf8");
|
|
27237
27503
|
const globMatch = /packages?:\s*\[([^\]]+)\]/s.exec(content);
|
|
27238
27504
|
const rawGlobs = globMatch?.[1];
|
|
27239
27505
|
if (!rawGlobs) return files;
|
|
@@ -27242,12 +27508,12 @@ async function discoverPackageFiles(projectRoot) {
|
|
|
27242
27508
|
const dirPrefix = g.replace(/\/?\*$/, "").replace(/\/\*$/, "");
|
|
27243
27509
|
const dir = path19.join(projectRoot, dirPrefix);
|
|
27244
27510
|
try {
|
|
27245
|
-
const entries = await
|
|
27511
|
+
const entries = await fs16.readdir(dir, { withFileTypes: true });
|
|
27246
27512
|
for (const e of entries) {
|
|
27247
27513
|
if (!e.isDirectory()) continue;
|
|
27248
27514
|
const subPkg = path19.join(dir, e.name, "package.json");
|
|
27249
27515
|
try {
|
|
27250
|
-
await
|
|
27516
|
+
await fs16.access(subPkg);
|
|
27251
27517
|
files.push(subPkg);
|
|
27252
27518
|
} catch {
|
|
27253
27519
|
}
|
|
@@ -27371,10 +27637,10 @@ function buildTechStackCommand(opts) {
|
|
|
27371
27637
|
" 1. Reads every package.json in the project",
|
|
27372
27638
|
" 2. Looks up latest versions on the npm registry",
|
|
27373
27639
|
" 3. Flags outdated, dead, or obsolete packages",
|
|
27374
|
-
` 4. Writes a ${
|
|
27640
|
+
` 4. Writes a ${color59.cyan("techstack.md")} (or .json) report to the project root`,
|
|
27375
27641
|
"",
|
|
27376
27642
|
"Uses the `tech-stack` skill for version verification rules.",
|
|
27377
|
-
`Hooked into ${
|
|
27643
|
+
`Hooked into ${color59.cyan("/init")} \u2014 runs automatically on first project setup.`
|
|
27378
27644
|
].join("\n"),
|
|
27379
27645
|
async run(args, _ctx) {
|
|
27380
27646
|
const trimmed = args.trim().toLowerCase();
|
|
@@ -27458,12 +27724,12 @@ function buildTechStackCommand(opts) {
|
|
|
27458
27724
|
try {
|
|
27459
27725
|
packageFiles = await discoverPackageFiles(opts.projectRoot);
|
|
27460
27726
|
if (packageFiles.length === 0) {
|
|
27461
|
-
discoveryNote =
|
|
27727
|
+
discoveryNote = color59.amber(
|
|
27462
27728
|
"\u26A0 No package.json files found. This does not look like a Node.js project."
|
|
27463
27729
|
);
|
|
27464
27730
|
}
|
|
27465
27731
|
} catch (err) {
|
|
27466
|
-
discoveryNote =
|
|
27732
|
+
discoveryNote = color59.red(`Could not scan for package files: ${toErrorMessage25(err)}`);
|
|
27467
27733
|
}
|
|
27468
27734
|
const task = buildTechStackTask({
|
|
27469
27735
|
projectRoot: opts.projectRoot,
|
|
@@ -27486,11 +27752,11 @@ function buildTechStackCommand(opts) {
|
|
|
27486
27752
|
};
|
|
27487
27753
|
}
|
|
27488
27754
|
const header = isInit ? "Tech Stack Init Audit" : "Tech Stack Audit";
|
|
27489
|
-
const label = `${
|
|
27755
|
+
const label = `${color59.cyan("\u{1F50D}")} ${color59.bold(header)} ${color59.dim(`(${packageFiles.length} package files)`)}`;
|
|
27490
27756
|
opts.renderer.write(label);
|
|
27491
27757
|
if (discoveryNote) opts.renderer.write(discoveryNote);
|
|
27492
27758
|
opts.renderer.write(
|
|
27493
|
-
|
|
27759
|
+
color59.dim(
|
|
27494
27760
|
`Spawning tech-stack subagent \u2192 writes ${outputFormat === "json" ? "techstack.json" : "techstack.md"} when done.`
|
|
27495
27761
|
)
|
|
27496
27762
|
);
|
|
@@ -27512,10 +27778,10 @@ function buildTechStackCommand(opts) {
|
|
|
27512
27778
|
}
|
|
27513
27779
|
|
|
27514
27780
|
// src/slash-commands/telegram-settings.ts
|
|
27515
|
-
import { color as
|
|
27781
|
+
import { color as color61, toErrorMessage as toErrorMessage26 } from "@wrongstack/core/utils";
|
|
27516
27782
|
|
|
27517
27783
|
// src/slash-commands/telegram-setup.ts
|
|
27518
|
-
import { color as
|
|
27784
|
+
import { color as color60 } from "@wrongstack/core/utils";
|
|
27519
27785
|
|
|
27520
27786
|
// src/slash-commands/telegram-pairing.ts
|
|
27521
27787
|
var DISCOVERY_LIMIT = 25;
|
|
@@ -27631,31 +27897,31 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27631
27897
|
if (BOT_TOKEN_RE.test(first)) {
|
|
27632
27898
|
return {
|
|
27633
27899
|
message: [
|
|
27634
|
-
`${
|
|
27635
|
-
`Run ${
|
|
27900
|
+
`${color60.red("\u2717")} Bot tokens are no longer accepted as slash-command arguments.`,
|
|
27901
|
+
`Run ${color60.cyan("/telegram-setup [chatId]")} and enter it at the masked prompt.`
|
|
27636
27902
|
].join("\n")
|
|
27637
27903
|
};
|
|
27638
27904
|
}
|
|
27639
27905
|
if (parts.length > 1) {
|
|
27640
|
-
return { message: `${
|
|
27906
|
+
return { message: `${color60.amber("Usage:")} /telegram-setup [chatId]` };
|
|
27641
27907
|
}
|
|
27642
27908
|
if (!opts.readSecret || !opts.vault || !opts.paths?.globalConfig) {
|
|
27643
27909
|
return {
|
|
27644
|
-
message: `${
|
|
27910
|
+
message: `${color60.red("\u2717")} Secure Telegram setup is unavailable in this session.`
|
|
27645
27911
|
};
|
|
27646
27912
|
}
|
|
27647
27913
|
let botToken;
|
|
27648
27914
|
try {
|
|
27649
|
-
botToken = (await opts.readSecret(`Telegram bot token ${
|
|
27915
|
+
botToken = (await opts.readSecret(`Telegram bot token ${color60.dim("(hidden, paste OK)")}: `)).trim();
|
|
27650
27916
|
} catch {
|
|
27651
|
-
return { message:
|
|
27917
|
+
return { message: color60.dim("Telegram setup cancelled.") };
|
|
27652
27918
|
}
|
|
27653
|
-
if (!botToken) return { message:
|
|
27919
|
+
if (!botToken) return { message: color60.dim("Telegram setup cancelled.") };
|
|
27654
27920
|
if (!BOT_TOKEN_RE.test(botToken)) {
|
|
27655
27921
|
return {
|
|
27656
27922
|
message: [
|
|
27657
|
-
`${
|
|
27658
|
-
`Expected: ${
|
|
27923
|
+
`${color60.red("\u2717")} Invalid token format.`,
|
|
27924
|
+
`Expected: ${color60.dim("123456789:ABCdefGHIjkl...")}`,
|
|
27659
27925
|
"",
|
|
27660
27926
|
"Get a valid token from @BotFather on Telegram."
|
|
27661
27927
|
].join("\n")
|
|
@@ -27670,7 +27936,7 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27670
27936
|
} catch {
|
|
27671
27937
|
return {
|
|
27672
27938
|
message: [
|
|
27673
|
-
`${
|
|
27939
|
+
`${color60.red("\u2717")} Could not reach Telegram API.`,
|
|
27674
27940
|
"",
|
|
27675
27941
|
"Check your network connection and try again."
|
|
27676
27942
|
].join("\n")
|
|
@@ -27679,7 +27945,7 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27679
27945
|
if (!botInfo.ok || !botInfo.result) {
|
|
27680
27946
|
return {
|
|
27681
27947
|
message: [
|
|
27682
|
-
`${
|
|
27948
|
+
`${color60.red("\u2717")} Invalid bot token.`,
|
|
27683
27949
|
"",
|
|
27684
27950
|
"Get a valid token from @BotFather on Telegram."
|
|
27685
27951
|
].join("\n")
|
|
@@ -27689,13 +27955,13 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27689
27955
|
const classifiedChatId = chatId ? classifyTelegramChatId(chatId) : void 0;
|
|
27690
27956
|
if (classifiedChatId?.kind === "invalid") {
|
|
27691
27957
|
return {
|
|
27692
|
-
message: `${
|
|
27958
|
+
message: `${color60.red("\u2717")} Invalid Telegram chat ID. Expected a positive private chat ID.`
|
|
27693
27959
|
};
|
|
27694
27960
|
}
|
|
27695
27961
|
if (classifiedChatId?.kind === "group") {
|
|
27696
27962
|
return {
|
|
27697
27963
|
message: [
|
|
27698
|
-
`${
|
|
27964
|
+
`${color60.amber("\u26A0")} Shared group, supergroup, and channel IDs cannot be paired by manual ID.`,
|
|
27699
27965
|
"Run /telegram-setup without a chat ID and select a discovered private identity.",
|
|
27700
27966
|
"No configuration was changed."
|
|
27701
27967
|
].join("\n")
|
|
@@ -27709,7 +27975,7 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27709
27975
|
} catch {
|
|
27710
27976
|
return {
|
|
27711
27977
|
message: [
|
|
27712
|
-
`${
|
|
27978
|
+
`${color60.red("\u2717")} Could not discover recent Telegram chats.`,
|
|
27713
27979
|
"Message the bot once, then run /telegram-setup again.",
|
|
27714
27980
|
"No configuration was changed."
|
|
27715
27981
|
].join("\n")
|
|
@@ -27718,7 +27984,7 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27718
27984
|
if (candidates.length === 0) {
|
|
27719
27985
|
return {
|
|
27720
27986
|
message: [
|
|
27721
|
-
`${
|
|
27987
|
+
`${color60.amber("No recent chats found.")}`,
|
|
27722
27988
|
"Message the bot from the private account you want to pair, then run setup again.",
|
|
27723
27989
|
"No configuration was changed."
|
|
27724
27990
|
].join("\n")
|
|
@@ -27726,31 +27992,31 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27726
27992
|
}
|
|
27727
27993
|
opts.renderer.write(
|
|
27728
27994
|
[
|
|
27729
|
-
|
|
27995
|
+
color60.bold("Recent Telegram identities"),
|
|
27730
27996
|
formatTelegramPairingCandidates(candidates),
|
|
27731
27997
|
"",
|
|
27732
|
-
|
|
27998
|
+
color60.dim("Choose a private candidate number, or press Enter to cancel.")
|
|
27733
27999
|
].join("\n")
|
|
27734
28000
|
);
|
|
27735
28001
|
let choiceInput;
|
|
27736
28002
|
try {
|
|
27737
28003
|
choiceInput = opts.readText ? await opts.readText("Pair candidate \u203A ") : await opts.reader.readLine("Pair candidate \u203A ");
|
|
27738
28004
|
} catch {
|
|
27739
|
-
return { message:
|
|
28005
|
+
return { message: color60.dim("Telegram setup cancelled. No configuration was changed.") };
|
|
27740
28006
|
}
|
|
27741
28007
|
const choice = parseTelegramPairingChoice(choiceInput, candidates);
|
|
27742
28008
|
if (choice.kind === "cancel") {
|
|
27743
|
-
return { message:
|
|
28009
|
+
return { message: color60.dim("Telegram setup cancelled. No configuration was changed.") };
|
|
27744
28010
|
}
|
|
27745
28011
|
if (choice.kind === "invalid") {
|
|
27746
28012
|
return {
|
|
27747
|
-
message: `${
|
|
28013
|
+
message: `${color60.red("\u2717")} Invalid pairing choice. No configuration was changed.`
|
|
27748
28014
|
};
|
|
27749
28015
|
}
|
|
27750
28016
|
if (!choice.candidate.eligible) {
|
|
27751
28017
|
return {
|
|
27752
28018
|
message: [
|
|
27753
|
-
`${
|
|
28019
|
+
`${color60.amber("\u26A0")} Shared, group, or ambiguous identities are not paired automatically.`,
|
|
27754
28020
|
"Use a private chat where chat_id and user_id identify the same account.",
|
|
27755
28021
|
"No configuration was changed."
|
|
27756
28022
|
].join("\n")
|
|
@@ -27792,7 +28058,7 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27792
28058
|
} catch {
|
|
27793
28059
|
return {
|
|
27794
28060
|
message: [
|
|
27795
|
-
`${
|
|
28061
|
+
`${color60.red("\u2717")} Failed to save Telegram configuration.`,
|
|
27796
28062
|
"The token was not printed. Check the config path and vault, then try again."
|
|
27797
28063
|
].join("\n")
|
|
27798
28064
|
};
|
|
@@ -27800,15 +28066,15 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27800
28066
|
const bot = botInfo.result;
|
|
27801
28067
|
return {
|
|
27802
28068
|
message: [
|
|
27803
|
-
`${
|
|
28069
|
+
`${color60.green("\u2713")} Telegram configured successfully.`,
|
|
27804
28070
|
"",
|
|
27805
|
-
`Bot: ${
|
|
28071
|
+
`Bot: ${color60.bold(`@${bot.username ?? bot.first_name}`)}`,
|
|
27806
28072
|
...pairedCandidate ? [
|
|
27807
|
-
`Paired private chat: ${
|
|
27808
|
-
`Paired user: ${
|
|
27809
|
-
] : chatId ? [`Default chat: ${
|
|
28073
|
+
`Paired private chat: ${color60.green(String(pairedCandidate.chatId))}`,
|
|
28074
|
+
`Paired user: ${color60.green(String(pairedCandidate.userId))}`
|
|
28075
|
+
] : chatId ? [`Default chat: ${color60.green(chatId)}`] : [],
|
|
27810
28076
|
"",
|
|
27811
|
-
`${
|
|
28077
|
+
`${color60.amber("\u26A0")} Restart WrongStack for the plugin to load the new token.`
|
|
27812
28078
|
].join("\n")
|
|
27813
28079
|
};
|
|
27814
28080
|
}
|
|
@@ -27842,15 +28108,15 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
27842
28108
|
const chat = tg.notifyChatId !== void 0 && tg.notifyChatId !== null ? String(tg.notifyChatId) : "not set";
|
|
27843
28109
|
const hasToken = typeof tg.botToken === "string" && tg.botToken.length > 0;
|
|
27844
28110
|
return [
|
|
27845
|
-
`${
|
|
28111
|
+
`${color61.bold("Telegram")} ${color61.dim("\u2014 Notification Settings")}`,
|
|
27846
28112
|
"",
|
|
27847
|
-
` session end: ${sessionEnd ?
|
|
27848
|
-
` delegate done: ${delegate ?
|
|
27849
|
-
` long tool: ${
|
|
27850
|
-
` poll interval: ${
|
|
27851
|
-
` notify chat: ${
|
|
28113
|
+
` session end: ${sessionEnd ? color61.cyan("on") : color61.dim("off")} ${color61.dim("change: /telegram-settings session-end on|off")}`,
|
|
28114
|
+
` delegate done: ${delegate ? color61.cyan("on") : color61.dim("off")} ${color61.dim("change: /telegram-settings delegate on|off")}`,
|
|
28115
|
+
` long tool: ${color61.cyan(longTool)} ${color61.dim("change: /telegram-settings long-tool <ms|off>")}`,
|
|
28116
|
+
` poll interval: ${color61.cyan(poll)} ${color61.dim("change: /telegram-settings poll <seconds>")}`,
|
|
28117
|
+
` notify chat: ${color61.cyan(chat)} ${color61.dim("change: /telegram-settings chat <chatId>")}`,
|
|
27852
28118
|
"",
|
|
27853
|
-
hasToken ?
|
|
28119
|
+
hasToken ? color61.dim(" Bot token configured. Changes apply immediately.") : `${color61.amber("\u26A0")} No bot token configured. Run: /telegram-setup <botToken> [chatId]`
|
|
27854
28120
|
].join("\n");
|
|
27855
28121
|
}
|
|
27856
28122
|
return {
|
|
@@ -27866,7 +28132,7 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
27866
28132
|
return { message: HELP2 };
|
|
27867
28133
|
}
|
|
27868
28134
|
if (!opts.configStore || !opts.paths?.globalConfig || !opts.vault) {
|
|
27869
|
-
return { message: `${
|
|
28135
|
+
return { message: `${color61.red("Error")} secure config persistence not available.` };
|
|
27870
28136
|
}
|
|
27871
28137
|
if (!sub) {
|
|
27872
28138
|
return { message: currentView() };
|
|
@@ -27880,7 +28146,7 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
27880
28146
|
if (sub === "all") {
|
|
27881
28147
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
27882
28148
|
if (!["on", "off"].includes(raw)) {
|
|
27883
|
-
return { message: `${
|
|
28149
|
+
return { message: `${color61.amber("Usage:")} /telegram-settings all on|off` };
|
|
27884
28150
|
}
|
|
27885
28151
|
const on = raw === "on";
|
|
27886
28152
|
await persistTelegramConfig(persistDeps, (tg) => {
|
|
@@ -27888,40 +28154,40 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
27888
28154
|
tg.notifyOnDelegate = on;
|
|
27889
28155
|
});
|
|
27890
28156
|
return {
|
|
27891
|
-
message: `${
|
|
28157
|
+
message: `${color61.green("\u2713")} all event notifications \u2192 ${on ? color61.cyan("on") : color61.dim("off")} ${color61.dim("(session-end, delegate)")}`
|
|
27892
28158
|
};
|
|
27893
28159
|
}
|
|
27894
28160
|
if (sub === "session-end") {
|
|
27895
28161
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
27896
28162
|
if (!["on", "off"].includes(raw)) {
|
|
27897
|
-
return { message: `${
|
|
28163
|
+
return { message: `${color61.amber("Usage:")} /telegram-settings session-end on|off` };
|
|
27898
28164
|
}
|
|
27899
28165
|
const on = raw === "on";
|
|
27900
28166
|
await persistTelegramConfig(persistDeps, (tg) => {
|
|
27901
28167
|
tg.notifyOnSessionEnd = on;
|
|
27902
28168
|
});
|
|
27903
28169
|
return {
|
|
27904
|
-
message: `${
|
|
28170
|
+
message: `${color61.green("\u2713")} session-end \u2192 ${on ? color61.cyan("on") : color61.dim("off")}`
|
|
27905
28171
|
};
|
|
27906
28172
|
}
|
|
27907
28173
|
if (sub === "delegate") {
|
|
27908
28174
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
27909
28175
|
if (!["on", "off"].includes(raw)) {
|
|
27910
|
-
return { message: `${
|
|
28176
|
+
return { message: `${color61.amber("Usage:")} /telegram-settings delegate on|off` };
|
|
27911
28177
|
}
|
|
27912
28178
|
const on = raw === "on";
|
|
27913
28179
|
await persistTelegramConfig(persistDeps, (tg) => {
|
|
27914
28180
|
tg.notifyOnDelegate = on;
|
|
27915
28181
|
});
|
|
27916
28182
|
return {
|
|
27917
|
-
message: `${
|
|
28183
|
+
message: `${color61.green("\u2713")} delegate \u2192 ${on ? color61.cyan("on") : color61.dim("off")}`
|
|
27918
28184
|
};
|
|
27919
28185
|
}
|
|
27920
28186
|
if (sub === "long-tool") {
|
|
27921
28187
|
const raw = rest[0];
|
|
27922
28188
|
if (raw === void 0) {
|
|
27923
28189
|
return {
|
|
27924
|
-
message: `${
|
|
28190
|
+
message: `${color61.amber("Usage:")} /telegram-settings long-tool <ms|off> ${color61.dim("(0 or off disables)")}`
|
|
27925
28191
|
};
|
|
27926
28192
|
}
|
|
27927
28193
|
if (raw === "off") {
|
|
@@ -27929,57 +28195,57 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
27929
28195
|
tg.longToolThresholdMs = 0;
|
|
27930
28196
|
});
|
|
27931
28197
|
return {
|
|
27932
|
-
message: `${
|
|
28198
|
+
message: `${color61.green("\u2713")} long-tool \u2192 ${color61.dim("off")}`
|
|
27933
28199
|
};
|
|
27934
28200
|
}
|
|
27935
28201
|
const ms = Number.parseInt(raw, 10);
|
|
27936
28202
|
if (Number.isNaN(ms) || ms < 0) {
|
|
27937
28203
|
return {
|
|
27938
|
-
message: `${
|
|
28204
|
+
message: `${color61.red("Invalid number")}: "${raw}". Enter milliseconds, e.g. /telegram-settings long-tool 15000`
|
|
27939
28205
|
};
|
|
27940
28206
|
}
|
|
27941
28207
|
await persistTelegramConfig(persistDeps, (tg) => {
|
|
27942
28208
|
tg.longToolThresholdMs = ms;
|
|
27943
28209
|
});
|
|
27944
28210
|
return {
|
|
27945
|
-
message: `${
|
|
28211
|
+
message: `${color61.green("\u2713")} long-tool \u2192 ${color61.cyan(`${ms}ms`)}`
|
|
27946
28212
|
};
|
|
27947
28213
|
}
|
|
27948
28214
|
if (sub === "poll") {
|
|
27949
28215
|
const raw = rest[0];
|
|
27950
28216
|
if (raw === void 0) {
|
|
27951
28217
|
return {
|
|
27952
|
-
message: `${
|
|
28218
|
+
message: `${color61.amber("Usage:")} /telegram-settings poll <seconds> ${color61.dim("(1\u201360)")}`
|
|
27953
28219
|
};
|
|
27954
28220
|
}
|
|
27955
28221
|
const sec = Number.parseInt(raw, 10);
|
|
27956
28222
|
if (Number.isNaN(sec) || sec < 1 || sec > 60) {
|
|
27957
28223
|
return {
|
|
27958
|
-
message: `${
|
|
28224
|
+
message: `${color61.red("Invalid value")}: "${raw}". Enter seconds between 1 and 60.`
|
|
27959
28225
|
};
|
|
27960
28226
|
}
|
|
27961
28227
|
await persistTelegramConfig(persistDeps, (tg) => {
|
|
27962
28228
|
tg.pollIntervalSec = sec;
|
|
27963
28229
|
});
|
|
27964
28230
|
return {
|
|
27965
|
-
message: `${
|
|
28231
|
+
message: `${color61.green("\u2713")} poll \u2192 ${color61.cyan(`${sec}s`)}`
|
|
27966
28232
|
};
|
|
27967
28233
|
}
|
|
27968
28234
|
if (sub === "chat") {
|
|
27969
28235
|
const raw = rest[0];
|
|
27970
28236
|
if (!raw) {
|
|
27971
|
-
return { message: `${
|
|
28237
|
+
return { message: `${color61.amber("Usage:")} /telegram-settings chat <chatId>` };
|
|
27972
28238
|
}
|
|
27973
28239
|
const classification = classifyTelegramChatId(raw);
|
|
27974
28240
|
if (classification.kind === "invalid") {
|
|
27975
|
-
return { message: `${
|
|
28241
|
+
return { message: `${color61.red("Invalid chat ID")}: expected a non-zero integer.` };
|
|
27976
28242
|
}
|
|
27977
28243
|
const current = opts.configStore.get();
|
|
27978
28244
|
const allowGroupChats = current.extensions?.telegram?.allowGroupChats === true;
|
|
27979
28245
|
if (classification.kind === "group" && !allowGroupChats) {
|
|
27980
28246
|
return {
|
|
27981
28247
|
message: [
|
|
27982
|
-
`${
|
|
28248
|
+
`${color61.amber("\u26A0")} Group, supergroup, and channel targets require explicit allowGroupChats=true.`,
|
|
27983
28249
|
"No configuration was changed."
|
|
27984
28250
|
].join("\n")
|
|
27985
28251
|
};
|
|
@@ -28002,15 +28268,15 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
28002
28268
|
}
|
|
28003
28269
|
});
|
|
28004
28270
|
return {
|
|
28005
|
-
message: `${
|
|
28271
|
+
message: `${color61.green("\u2713")} notify chat \u2192 ${color61.cyan(raw)}`
|
|
28006
28272
|
};
|
|
28007
28273
|
}
|
|
28008
28274
|
return {
|
|
28009
|
-
message: `${
|
|
28275
|
+
message: `${color61.red("Unknown setting")} "${sub}". ${unknownSubcommand(sub, ["session-end", "delegate", "long-tool", "poll", "chat", "all"], "telegram-settings")}`
|
|
28010
28276
|
};
|
|
28011
28277
|
} catch (err) {
|
|
28012
28278
|
return {
|
|
28013
|
-
message: `${
|
|
28279
|
+
message: `${color61.red("Settings error")}: ${toErrorMessage26(err)}`
|
|
28014
28280
|
};
|
|
28015
28281
|
}
|
|
28016
28282
|
}
|
|
@@ -28018,7 +28284,7 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
28018
28284
|
}
|
|
28019
28285
|
|
|
28020
28286
|
// src/slash-commands/todos.ts
|
|
28021
|
-
import { randomUUID as
|
|
28287
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
28022
28288
|
import { formatTodosList as formatTodosList2 } from "@wrongstack/core/utils";
|
|
28023
28289
|
import { todoTool as todoTool3 } from "@wrongstack/tools";
|
|
28024
28290
|
function findTodo(todos, query) {
|
|
@@ -28077,7 +28343,7 @@ function buildTodosCommand(opts) {
|
|
|
28077
28343
|
return { message: "This Todo list is a Kanban projection. Add the task in Kanban." };
|
|
28078
28344
|
}
|
|
28079
28345
|
const item = {
|
|
28080
|
-
id: `todo_${Date.now()}_${
|
|
28346
|
+
id: `todo_${Date.now()}_${randomUUID8().slice(0, 7)}`,
|
|
28081
28347
|
content: restJoined,
|
|
28082
28348
|
status: "pending"
|
|
28083
28349
|
};
|
|
@@ -28156,9 +28422,9 @@ function buildTodosCommand(opts) {
|
|
|
28156
28422
|
}
|
|
28157
28423
|
|
|
28158
28424
|
// src/slash-commands/tool.ts
|
|
28159
|
-
import { noOpVault as
|
|
28425
|
+
import { noOpVault as noOpVault11 } from "@wrongstack/core/security";
|
|
28160
28426
|
import {
|
|
28161
|
-
color as
|
|
28427
|
+
color as color62,
|
|
28162
28428
|
getToolDescriptionMode,
|
|
28163
28429
|
getToolResultRenderMode,
|
|
28164
28430
|
normalizeToolDescriptionMode,
|
|
@@ -28172,11 +28438,11 @@ function fit(text, width) {
|
|
|
28172
28438
|
}
|
|
28173
28439
|
function formatDescriptionMode(mode) {
|
|
28174
28440
|
const raw = `desc:${mode}`;
|
|
28175
|
-
return mode === "simple" ?
|
|
28441
|
+
return mode === "simple" ? color62.amber(raw) : color62.cyan(raw);
|
|
28176
28442
|
}
|
|
28177
28443
|
function formatResultRenderMode(mode) {
|
|
28178
28444
|
const raw = `result:${mode}`;
|
|
28179
|
-
return mode === "simple" ?
|
|
28445
|
+
return mode === "simple" ? color62.amber(raw) : color62.cyan(raw);
|
|
28180
28446
|
}
|
|
28181
28447
|
function buildToolCommand(opts) {
|
|
28182
28448
|
const help = [
|
|
@@ -28240,7 +28506,7 @@ function buildToolCommand(opts) {
|
|
|
28240
28506
|
configStore: opts.configStore,
|
|
28241
28507
|
profileConfigPath: activeProfileConfigPath(opts.paths, opts.configStore.get()),
|
|
28242
28508
|
inProjectConfigPath: opts.paths.inProjectConfig,
|
|
28243
|
-
vault:
|
|
28509
|
+
vault: noOpVault11
|
|
28244
28510
|
},
|
|
28245
28511
|
(cfg) => {
|
|
28246
28512
|
cfg.tools = next;
|
|
@@ -28269,7 +28535,7 @@ function buildToolCommand(opts) {
|
|
|
28269
28535
|
configStore: opts.configStore,
|
|
28270
28536
|
profileConfigPath: activeProfileConfigPath(opts.paths, opts.configStore.get()),
|
|
28271
28537
|
inProjectConfigPath: opts.paths.inProjectConfig,
|
|
28272
|
-
vault:
|
|
28538
|
+
vault: noOpVault11
|
|
28273
28539
|
},
|
|
28274
28540
|
(cfg) => {
|
|
28275
28541
|
cfg.tools = nextTools;
|
|
@@ -28282,38 +28548,38 @@ function buildToolCommand(opts) {
|
|
|
28282
28548
|
const resultSimple = Object.entries(configured.resultRenderMode ?? {}).filter(([, mode]) => normalizeToolResultRenderMode(mode) === "simple").map(([name]) => name).sort();
|
|
28283
28549
|
const disabled = opts.toolRegistry.listDisabled();
|
|
28284
28550
|
const lines = [
|
|
28285
|
-
`${
|
|
28551
|
+
`${color62.bold("Tool modes")} ${color62.dim("(default: extend on both axes)")}`,
|
|
28286
28552
|
"",
|
|
28287
|
-
`${formatDescriptionMode("simple")}: ${descSimple.length > 0 ? descSimple.map((n) =>
|
|
28288
|
-
`${formatResultRenderMode("simple")}: ${resultSimple.length > 0 ? resultSimple.map((n) =>
|
|
28553
|
+
`${formatDescriptionMode("simple")}: ${descSimple.length > 0 ? descSimple.map((n) => color62.cyan(n)).join(", ") : color62.dim("none")}`,
|
|
28554
|
+
`${formatResultRenderMode("simple")}: ${resultSimple.length > 0 ? resultSimple.map((n) => color62.cyan(n)).join(", ") : color62.dim("none")}`,
|
|
28289
28555
|
""
|
|
28290
28556
|
];
|
|
28291
28557
|
if (disabled.length > 0) {
|
|
28292
28558
|
lines.push(
|
|
28293
|
-
`${
|
|
28559
|
+
`${color62.bold("Disabled tools")}`,
|
|
28294
28560
|
"",
|
|
28295
|
-
` ${
|
|
28561
|
+
` ${color62.red("disabled")}: ${disabled.map(({ tool }) => color62.dim(tool.name)).join(", ")}`,
|
|
28296
28562
|
""
|
|
28297
28563
|
);
|
|
28298
28564
|
}
|
|
28299
28565
|
lines.push(
|
|
28300
|
-
|
|
28566
|
+
color62.dim(
|
|
28301
28567
|
" /tool <name> desc simple \xB7 /tool <name> result simple \xB7 /tool list \xB7 /tool disable|enable <name>"
|
|
28302
28568
|
)
|
|
28303
28569
|
);
|
|
28304
28570
|
return lines.join("\n");
|
|
28305
28571
|
}
|
|
28306
28572
|
function formatList() {
|
|
28307
|
-
const header = ` ${
|
|
28573
|
+
const header = ` ${color62.dim(fit("tool", 28))} ${color62.dim(fit("owner", 28))} ${color62.dim(fit("status", 10))} ${color62.dim(fit("desc", 14))} ` + color62.dim("result");
|
|
28308
28574
|
const rows = opts.toolRegistry.listWithOwner().map(({ tool }) => {
|
|
28309
28575
|
const descMode = getToolDescriptionMode(opts.toolRegistry, tool.name);
|
|
28310
28576
|
const resultMode = getToolResultRenderMode(opts.toolRegistry, tool.name);
|
|
28311
28577
|
const owner = opts.toolRegistry.ownerOf(tool.name) ?? "core";
|
|
28312
|
-
const status = opts.toolRegistry.isDisabled(tool.name) ?
|
|
28313
|
-
return ` ${fit(tool.name, 28)} ${
|
|
28578
|
+
const status = opts.toolRegistry.isDisabled(tool.name) ? color62.red("disabled") : color62.green("active");
|
|
28579
|
+
return ` ${fit(tool.name, 28)} ${color62.dim(fit(`[${owner}]`, 28))} ${fit(status, 10)} ${fit(formatDescriptionMode(descMode), 14)} ` + formatResultRenderMode(resultMode);
|
|
28314
28580
|
});
|
|
28315
28581
|
return [
|
|
28316
|
-
`${
|
|
28582
|
+
`${color62.bold("Tool modes")} ${color62.dim("(default: extend on both axes)")}`,
|
|
28317
28583
|
"",
|
|
28318
28584
|
header,
|
|
28319
28585
|
...rows
|
|
@@ -28324,55 +28590,55 @@ function buildToolCommand(opts) {
|
|
|
28324
28590
|
const tool = reg.get(name);
|
|
28325
28591
|
if (!tool) {
|
|
28326
28592
|
if (reg.isDisabled(name)) {
|
|
28327
|
-
return `${
|
|
28593
|
+
return `${color62.amber(name)} is disabled. Use ${color62.dim(`/tool enable ${name}`)} to restore.`;
|
|
28328
28594
|
}
|
|
28329
|
-
return `${
|
|
28595
|
+
return `${color62.red("Unknown tool")}: ${name}. Use ${color62.dim("/tools")} to list registered tools.`;
|
|
28330
28596
|
}
|
|
28331
28597
|
const descMode = getToolDescriptionMode(reg, name);
|
|
28332
28598
|
const resultMode = getToolResultRenderMode(reg, name);
|
|
28333
|
-
const status = reg.isDisabled(name) ?
|
|
28599
|
+
const status = reg.isDisabled(name) ? color62.red("disabled") : color62.green("active");
|
|
28334
28600
|
return [
|
|
28335
|
-
`${
|
|
28601
|
+
`${color62.bold(name)} ${status}`,
|
|
28336
28602
|
`description mode: ${formatDescriptionMode(descMode)}`,
|
|
28337
28603
|
`result mode: ${formatResultRenderMode(resultMode)}`,
|
|
28338
28604
|
"",
|
|
28339
|
-
|
|
28605
|
+
color62.dim(tool.description)
|
|
28340
28606
|
].join("\n");
|
|
28341
28607
|
}
|
|
28342
28608
|
async function cmdEnable(name) {
|
|
28343
28609
|
const reg = opts.toolRegistry;
|
|
28344
28610
|
if (!reg.isDisabled(name)) {
|
|
28345
|
-
return `${
|
|
28611
|
+
return `${color62.amber(name)} is not disabled.`;
|
|
28346
28612
|
}
|
|
28347
28613
|
const ok = reg.enable(name);
|
|
28348
|
-
if (!ok) return `${
|
|
28614
|
+
if (!ok) return `${color62.red("Could not enable")}: ${name}.`;
|
|
28349
28615
|
const disabled = currentDisabledSet();
|
|
28350
28616
|
disabled.delete(name);
|
|
28351
28617
|
await persistDisabled(Array.from(disabled));
|
|
28352
|
-
return `${
|
|
28618
|
+
return `${color62.green("\u2713")} ${color62.cyan(name)} re-enabled \u2014 will appear in next provider request.`;
|
|
28353
28619
|
}
|
|
28354
28620
|
async function cmdEnableAll() {
|
|
28355
28621
|
const reg = opts.toolRegistry;
|
|
28356
28622
|
const count = reg.enableAll();
|
|
28357
|
-
if (count === 0) return `${
|
|
28623
|
+
if (count === 0) return `${color62.amber("No disabled tools to re-enable.")}`;
|
|
28358
28624
|
await persistDisabled([]);
|
|
28359
|
-
return `${
|
|
28625
|
+
return `${color62.green("\u2713")} All ${count} disabled tool(s) re-enabled.`;
|
|
28360
28626
|
}
|
|
28361
28627
|
async function cmdDisable(name) {
|
|
28362
28628
|
const reg = opts.toolRegistry;
|
|
28363
28629
|
const tool = reg.get(name);
|
|
28364
28630
|
if (!tool) {
|
|
28365
28631
|
if (reg.isDisabled(name)) {
|
|
28366
|
-
return `${
|
|
28632
|
+
return `${color62.amber(name)} is already disabled.`;
|
|
28367
28633
|
}
|
|
28368
|
-
return `${
|
|
28634
|
+
return `${color62.red("Unknown tool")}: ${name}. Use ${color62.dim("/tools")} to list registered tools.`;
|
|
28369
28635
|
}
|
|
28370
28636
|
const ok = reg.disable(name);
|
|
28371
|
-
if (!ok) return `${
|
|
28637
|
+
if (!ok) return `${color62.red("Could not disable")}: ${name}.`;
|
|
28372
28638
|
const disabled = currentDisabledSet();
|
|
28373
28639
|
disabled.add(name);
|
|
28374
28640
|
await persistDisabled(Array.from(disabled));
|
|
28375
|
-
return `${
|
|
28641
|
+
return `${color62.green("\u2713")} ${color62.cyan(name)} disabled \u2014 removed from system prompt and tool registry.`;
|
|
28376
28642
|
}
|
|
28377
28643
|
function applyDescMode(name, mode) {
|
|
28378
28644
|
opts.toolRegistry.setDescriptionMode?.(name, mode);
|
|
@@ -28388,7 +28654,7 @@ function buildToolCommand(opts) {
|
|
|
28388
28654
|
help,
|
|
28389
28655
|
async run(args) {
|
|
28390
28656
|
if (!opts.configStore) {
|
|
28391
|
-
return { message: `${
|
|
28657
|
+
return { message: `${color62.red("Error")} config store not available.` };
|
|
28392
28658
|
}
|
|
28393
28659
|
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
28394
28660
|
const sub = (parts[0] ?? "").toLowerCase();
|
|
@@ -28399,7 +28665,7 @@ function buildToolCommand(opts) {
|
|
|
28399
28665
|
try {
|
|
28400
28666
|
return { message: await cmdEnableAll() };
|
|
28401
28667
|
} catch (err) {
|
|
28402
|
-
return { message: `${
|
|
28668
|
+
return { message: `${color62.red("Error")}: ${toErrorMessage27(err)}` };
|
|
28403
28669
|
}
|
|
28404
28670
|
}
|
|
28405
28671
|
const name = parts[0] ?? "";
|
|
@@ -28407,43 +28673,43 @@ function buildToolCommand(opts) {
|
|
|
28407
28673
|
if (sub === "disable") {
|
|
28408
28674
|
const targets = parts.slice(1);
|
|
28409
28675
|
if (targets.length === 0)
|
|
28410
|
-
return { message: `${
|
|
28676
|
+
return { message: `${color62.amber("Usage:")} /tool disable <name> [name...]` };
|
|
28411
28677
|
try {
|
|
28412
28678
|
const results = [];
|
|
28413
28679
|
for (const t of targets) results.push(await cmdDisable(t));
|
|
28414
28680
|
return { message: results.join("\n") };
|
|
28415
28681
|
} catch (err) {
|
|
28416
|
-
return { message: `${
|
|
28682
|
+
return { message: `${color62.red("Error")}: ${toErrorMessage27(err)}` };
|
|
28417
28683
|
}
|
|
28418
28684
|
}
|
|
28419
28685
|
if (sub === "enable") {
|
|
28420
28686
|
const targets = parts.slice(1);
|
|
28421
28687
|
if (targets.length === 0)
|
|
28422
|
-
return { message: `${
|
|
28688
|
+
return { message: `${color62.amber("Usage:")} /tool enable <name> [name...]` };
|
|
28423
28689
|
try {
|
|
28424
28690
|
const results = [];
|
|
28425
28691
|
for (const t of targets) results.push(await cmdEnable(t));
|
|
28426
28692
|
return { message: results.join("\n") };
|
|
28427
28693
|
} catch (err) {
|
|
28428
|
-
return { message: `${
|
|
28694
|
+
return { message: `${color62.red("Error")}: ${toErrorMessage27(err)}` };
|
|
28429
28695
|
}
|
|
28430
28696
|
}
|
|
28431
28697
|
const action = parts[1]?.toLowerCase();
|
|
28432
28698
|
if (action === "disable" || action === "enable") {
|
|
28433
28699
|
if (parts.length > 2) {
|
|
28434
28700
|
return {
|
|
28435
|
-
message: `${
|
|
28701
|
+
message: `${color62.amber("Usage:")} /tool ${name} ${action}`
|
|
28436
28702
|
};
|
|
28437
28703
|
}
|
|
28438
28704
|
try {
|
|
28439
28705
|
return { message: action === "disable" ? await cmdDisable(name) : await cmdEnable(name) };
|
|
28440
28706
|
} catch (err) {
|
|
28441
|
-
return { message: `${
|
|
28707
|
+
return { message: `${color62.red("Error")}: ${toErrorMessage27(err)}` };
|
|
28442
28708
|
}
|
|
28443
28709
|
}
|
|
28444
28710
|
if (!opts.toolRegistry.get(name) && !opts.toolRegistry.isDisabled(name)) {
|
|
28445
28711
|
return {
|
|
28446
|
-
message: `${
|
|
28712
|
+
message: `${color62.red("Unknown tool")}: ${name}. Use ${color62.dim("/tools")} to list registered tools.`
|
|
28447
28713
|
};
|
|
28448
28714
|
}
|
|
28449
28715
|
if (parts.length === 1) return { message: formatOne(name) };
|
|
@@ -28452,53 +28718,53 @@ function buildToolCommand(opts) {
|
|
|
28452
28718
|
const rawMode = parts[2];
|
|
28453
28719
|
if (!rawMode) {
|
|
28454
28720
|
return {
|
|
28455
|
-
message: `${
|
|
28721
|
+
message: `${color62.amber("Usage:")} /tool ${name} ${axis} simple|extend`
|
|
28456
28722
|
};
|
|
28457
28723
|
}
|
|
28458
28724
|
const mode2 = normalizeToolDescriptionMode(rawMode);
|
|
28459
28725
|
if (!mode2) {
|
|
28460
28726
|
return {
|
|
28461
|
-
message: `${
|
|
28727
|
+
message: `${color62.amber("Usage:")} /tool ${name} ${axis} simple|extend`
|
|
28462
28728
|
};
|
|
28463
28729
|
}
|
|
28464
28730
|
try {
|
|
28465
28731
|
if (axis === "desc") {
|
|
28466
28732
|
const persisted2 = await persistModeForAxis(name, "desc", mode2);
|
|
28467
28733
|
applyDescMode(name, mode2);
|
|
28468
|
-
const persistence2 = persisted2 ?
|
|
28734
|
+
const persistence2 = persisted2 ? color62.dim("saved") : color62.dim("runtime only; config paths unavailable");
|
|
28469
28735
|
return {
|
|
28470
|
-
message: `${
|
|
28736
|
+
message: `${color62.green("\u2713")} ${color62.cyan(name)} ${formatDescriptionMode(mode2)} ${persistence2}`
|
|
28471
28737
|
};
|
|
28472
28738
|
}
|
|
28473
28739
|
const persisted = await persistModeForAxis(name, "result", mode2);
|
|
28474
28740
|
applyResultMode(name, mode2);
|
|
28475
|
-
const persistence = persisted ?
|
|
28741
|
+
const persistence = persisted ? color62.dim("saved") : color62.dim("runtime only; config paths unavailable");
|
|
28476
28742
|
return {
|
|
28477
|
-
message: `${
|
|
28743
|
+
message: `${color62.green("\u2713")} ${color62.cyan(name)} ${formatResultRenderMode(mode2)} ${persistence}`
|
|
28478
28744
|
};
|
|
28479
28745
|
} catch (err) {
|
|
28480
28746
|
return {
|
|
28481
|
-
message: `${
|
|
28747
|
+
message: `${color62.red("Could not save tool setting")}: ${toErrorMessage27(err)}`
|
|
28482
28748
|
};
|
|
28483
28749
|
}
|
|
28484
28750
|
}
|
|
28485
28751
|
const mode = normalizeToolDescriptionMode(axis);
|
|
28486
28752
|
if (!mode) {
|
|
28487
28753
|
return {
|
|
28488
|
-
message: `${
|
|
28754
|
+
message: `${color62.amber("Usage:")} /tool ${name} [desc|result] simple|extend`
|
|
28489
28755
|
};
|
|
28490
28756
|
}
|
|
28491
28757
|
try {
|
|
28492
28758
|
const persisted = await persistModeBoth(name, mode);
|
|
28493
28759
|
applyDescMode(name, mode);
|
|
28494
28760
|
applyResultMode(name, mode);
|
|
28495
|
-
const persistence = persisted ?
|
|
28761
|
+
const persistence = persisted ? color62.dim("saved (both axes)") : color62.dim("runtime only; config paths unavailable");
|
|
28496
28762
|
return {
|
|
28497
|
-
message: `${
|
|
28763
|
+
message: `${color62.green("\u2713")} ${color62.cyan(name)} ${formatDescriptionMode(mode)} + ${formatResultRenderMode(mode)} ${persistence}`
|
|
28498
28764
|
};
|
|
28499
28765
|
} catch (err) {
|
|
28500
28766
|
return {
|
|
28501
|
-
message: `${
|
|
28767
|
+
message: `${color62.red("Could not save tool setting")}: ${toErrorMessage27(err)}`
|
|
28502
28768
|
};
|
|
28503
28769
|
}
|
|
28504
28770
|
}
|
|
@@ -28506,14 +28772,14 @@ function buildToolCommand(opts) {
|
|
|
28506
28772
|
}
|
|
28507
28773
|
|
|
28508
28774
|
// src/slash-commands/tools.ts
|
|
28509
|
-
import { color as
|
|
28775
|
+
import { color as color63, getToolDescriptionMode as getToolDescriptionMode2 } from "@wrongstack/core/utils";
|
|
28510
28776
|
function fit2(text, width) {
|
|
28511
28777
|
if (text.length <= width) return text.padEnd(width);
|
|
28512
28778
|
return `${text.slice(0, Math.max(0, width - 3))}...`;
|
|
28513
28779
|
}
|
|
28514
28780
|
function formatDescriptionMode2(mode) {
|
|
28515
28781
|
const raw = `desc:${mode}`;
|
|
28516
|
-
return mode === "simple" ?
|
|
28782
|
+
return mode === "simple" ? color63.amber(raw) : color63.dim(raw);
|
|
28517
28783
|
}
|
|
28518
28784
|
function buildToolsCommand(opts) {
|
|
28519
28785
|
return {
|
|
@@ -28534,21 +28800,21 @@ function buildToolsCommand(opts) {
|
|
|
28534
28800
|
if (opened) return { message: "" };
|
|
28535
28801
|
}
|
|
28536
28802
|
if (filter && all.length === 0) {
|
|
28537
|
-
const msg2 = `${
|
|
28803
|
+
const msg2 = `${color63.bold("Tools")} \u2014 no tool name or owner matched "${filter}".`;
|
|
28538
28804
|
opts.renderer.write(msg2);
|
|
28539
28805
|
return { message: msg2 };
|
|
28540
28806
|
}
|
|
28541
|
-
const header = ` ${
|
|
28807
|
+
const header = ` ${color63.dim(fit2("tool", 28))} ${color63.dim(fit2("owner", 28))} ${color63.dim(fit2("rw", 4))} ${color63.dim(fit2("perm", 8))} ${color63.dim(fit2("status", 10))} ` + color63.dim("description");
|
|
28542
28808
|
const lines = all.map(({ tool, owner }) => {
|
|
28543
28809
|
const mode = getToolDescriptionMode2(reg, tool.name);
|
|
28544
|
-
const rw = tool.mutating ?
|
|
28545
|
-
const status = reg.isDisabled(tool.name) ?
|
|
28546
|
-
return ` ${fit2(tool.name, 28)} ${
|
|
28810
|
+
const rw = tool.mutating ? color63.yellow(fit2("mut", 4)) : color63.cyan(fit2("ro", 4));
|
|
28811
|
+
const status = reg.isDisabled(tool.name) ? color63.red("disabled") : color63.green("active");
|
|
28812
|
+
return ` ${fit2(tool.name, 28)} ${color63.dim(fit2(`[${owner}]`, 28))} ${rw} ${color63.dim(fit2(tool.permission, 8))} ${fit2(status, 10)} ` + formatDescriptionMode2(mode);
|
|
28547
28813
|
});
|
|
28548
28814
|
const extra = disabled.length > 0 ? `
|
|
28549
|
-
${
|
|
28550
|
-
const filterNote = filter ?
|
|
28551
|
-
const msg = `${
|
|
28815
|
+
${color63.dim(`${disabled.length} tool(s) disabled. Use /tool enable <name> or /tool enable-all to restore.`)}` : "";
|
|
28816
|
+
const filterNote = filter ? color63.dim(` matching "${filter}" (${all.length} of ${allTools.length})`) : "";
|
|
28817
|
+
const msg = `${color63.bold("Tools")}${filterNote} (${all.length} shown, ${disabled.length} disabled) ${color63.dim("description detail via /tool <name> simple|extend")}:
|
|
28552
28818
|
${header}
|
|
28553
28819
|
${lines.join("\n")}${extra}
|
|
28554
28820
|
`;
|
|
@@ -28559,10 +28825,10 @@ ${lines.join("\n")}${extra}
|
|
|
28559
28825
|
}
|
|
28560
28826
|
|
|
28561
28827
|
// src/slash-commands/tuneup.ts
|
|
28562
|
-
import * as
|
|
28828
|
+
import * as fs17 from "node:fs/promises";
|
|
28563
28829
|
import * as os3 from "node:os";
|
|
28564
28830
|
import * as path20 from "node:path";
|
|
28565
|
-
import { atomicWrite as
|
|
28831
|
+
import { atomicWrite as atomicWrite10, color as color64 } from "@wrongstack/core/utils";
|
|
28566
28832
|
|
|
28567
28833
|
// src/tuneup.ts
|
|
28568
28834
|
var DEFAULT_EAGER_MAX_CHARS = 24e3;
|
|
@@ -29040,17 +29306,17 @@ function buildTuneupCommand(opts) {
|
|
|
29040
29306
|
const parsed = parseArgs(args);
|
|
29041
29307
|
if (parsed.mode === "help") return { message: help };
|
|
29042
29308
|
if (parsed.mode === "usage") {
|
|
29043
|
-
return { message: `${
|
|
29309
|
+
return { message: `${color64.amber("Usage:")} /tuneup [fix [--power] [--pick] | deep]` };
|
|
29044
29310
|
}
|
|
29045
29311
|
if (!opts.paths) {
|
|
29046
|
-
return { message: `${
|
|
29312
|
+
return { message: `${color64.red("Error")} config paths not available.` };
|
|
29047
29313
|
}
|
|
29048
29314
|
const input = await gatherInput(opts, parsed.power);
|
|
29049
29315
|
const report = runTuneup(input);
|
|
29050
|
-
const lines = [`${
|
|
29316
|
+
const lines = [`${color64.bold("WrongStack")} ${color64.dim("\u2014 Tune-up")}`];
|
|
29051
29317
|
renderFindings(lines, report.findings);
|
|
29052
29318
|
if (parsed.mode === "deep") {
|
|
29053
|
-
lines.push("",
|
|
29319
|
+
lines.push("", color64.dim(" \u2192 asking the agent for a project-specific optimization plan\u2026"));
|
|
29054
29320
|
return { message: lines.join("\n"), runText: buildDeepPrompt(report) };
|
|
29055
29321
|
}
|
|
29056
29322
|
if (parsed.mode === "report") {
|
|
@@ -29072,18 +29338,18 @@ function buildTuneupCommand(opts) {
|
|
|
29072
29338
|
const applied = await applyActions(actions, opts);
|
|
29073
29339
|
lines.push("");
|
|
29074
29340
|
if (applied.messages.length === 0) {
|
|
29075
|
-
lines.push(
|
|
29341
|
+
lines.push(color64.dim(" no deterministic fixes to apply"));
|
|
29076
29342
|
} else {
|
|
29077
|
-
for (const m of applied.messages) lines.push(` ${
|
|
29343
|
+
for (const m of applied.messages) lines.push(` ${color64.green("\u2713")} ${m}`);
|
|
29078
29344
|
if (applied.changed) {
|
|
29079
29345
|
lines.push(
|
|
29080
|
-
` ${
|
|
29346
|
+
` ${color64.green("\u2713")} written ${color64.dim("(backup: config.json.last + timestamped .bak)")}`
|
|
29081
29347
|
);
|
|
29082
29348
|
}
|
|
29083
29349
|
}
|
|
29084
29350
|
const runText = report.agentHandoff || void 0;
|
|
29085
29351
|
if (runText) {
|
|
29086
|
-
lines.push("",
|
|
29352
|
+
lines.push("", color64.dim(" \u2192 handing instruction-file cleanups to the agent\u2026"));
|
|
29087
29353
|
}
|
|
29088
29354
|
return { message: lines.join("\n"), ...runText ? { runText } : {} };
|
|
29089
29355
|
}
|
|
@@ -29169,7 +29435,7 @@ async function gatherMemoryFiles(opts) {
|
|
|
29169
29435
|
const out = [];
|
|
29170
29436
|
for (const c of candidates) {
|
|
29171
29437
|
try {
|
|
29172
|
-
const content = await
|
|
29438
|
+
const content = await fs17.readFile(c.file, "utf8");
|
|
29173
29439
|
out.push({ label: c.label, path: c.file, content, committed: c.committed });
|
|
29174
29440
|
} catch {
|
|
29175
29441
|
}
|
|
@@ -29187,7 +29453,7 @@ async function gatherTrust(opts) {
|
|
|
29187
29453
|
const file = opts.paths?.projectTrust;
|
|
29188
29454
|
if (!file) return void 0;
|
|
29189
29455
|
try {
|
|
29190
|
-
const raw = await
|
|
29456
|
+
const raw = await fs17.readFile(file, "utf8");
|
|
29191
29457
|
const parsed = JSON.parse(raw);
|
|
29192
29458
|
if (parsed && typeof parsed === "object") return parsed;
|
|
29193
29459
|
} catch {
|
|
@@ -29198,7 +29464,7 @@ async function gatherConfigIssues(opts) {
|
|
|
29198
29464
|
if (!opts.paths) return 0;
|
|
29199
29465
|
const file = activeProfileConfigPath(opts.paths, opts.configStore.get());
|
|
29200
29466
|
try {
|
|
29201
|
-
const raw = await
|
|
29467
|
+
const raw = await fs17.readFile(file, "utf8");
|
|
29202
29468
|
const parsed = JSON.parse(raw);
|
|
29203
29469
|
return diagnoseConfig(parsed).findings.length;
|
|
29204
29470
|
} catch {
|
|
@@ -29216,14 +29482,14 @@ async function gatherSessionBytes(opts) {
|
|
|
29216
29482
|
}
|
|
29217
29483
|
async function dirSize(dir) {
|
|
29218
29484
|
let total = 0;
|
|
29219
|
-
const entries = await
|
|
29485
|
+
const entries = await fs17.readdir(dir, { withFileTypes: true });
|
|
29220
29486
|
for (const e of entries) {
|
|
29221
29487
|
const full = path20.join(dir, e.name);
|
|
29222
29488
|
if (e.isDirectory()) {
|
|
29223
29489
|
total += await dirSize(full);
|
|
29224
29490
|
} else if (e.isFile()) {
|
|
29225
29491
|
try {
|
|
29226
|
-
total += (await
|
|
29492
|
+
total += (await fs17.stat(full)).size;
|
|
29227
29493
|
} catch {
|
|
29228
29494
|
}
|
|
29229
29495
|
}
|
|
@@ -29236,7 +29502,7 @@ async function applyActions(actions, opts) {
|
|
|
29236
29502
|
const file = activeProfileConfigPath(opts.paths, opts.configStore.get());
|
|
29237
29503
|
let raw = "{}";
|
|
29238
29504
|
try {
|
|
29239
|
-
raw = await
|
|
29505
|
+
raw = await fs17.readFile(file, "utf8");
|
|
29240
29506
|
} catch {
|
|
29241
29507
|
}
|
|
29242
29508
|
let parsed;
|
|
@@ -29244,7 +29510,7 @@ async function applyActions(actions, opts) {
|
|
|
29244
29510
|
parsed = JSON.parse(raw);
|
|
29245
29511
|
} catch {
|
|
29246
29512
|
return {
|
|
29247
|
-
messages: [`${
|
|
29513
|
+
messages: [`${color64.red("\u2717")} global config is not valid JSON \u2014 run /doctor fix first`],
|
|
29248
29514
|
changed: false
|
|
29249
29515
|
};
|
|
29250
29516
|
}
|
|
@@ -29282,11 +29548,11 @@ async function applyActions(actions, opts) {
|
|
|
29282
29548
|
const changed = JSON.stringify(parsed) !== before;
|
|
29283
29549
|
if (!changed) return { messages, changed: false };
|
|
29284
29550
|
try {
|
|
29285
|
-
await
|
|
29286
|
-
await
|
|
29551
|
+
await atomicWrite10(`${file}.last`, raw);
|
|
29552
|
+
await atomicWrite10(`${file}.${Date.now()}.bak`, raw);
|
|
29287
29553
|
} catch {
|
|
29288
29554
|
}
|
|
29289
|
-
await
|
|
29555
|
+
await atomicWrite10(file, JSON.stringify(parsed, null, 2));
|
|
29290
29556
|
try {
|
|
29291
29557
|
const homeFn = () => path20.dirname(path20.dirname(file));
|
|
29292
29558
|
await appendHistory(JSON.parse(raw), parsed, "tuneup auto-fix", homeFn, file);
|
|
@@ -29353,26 +29619,26 @@ var CATEGORY_ORDER = [
|
|
|
29353
29619
|
function severityIcon(severity) {
|
|
29354
29620
|
switch (severity) {
|
|
29355
29621
|
case "error":
|
|
29356
|
-
return
|
|
29622
|
+
return color64.red("\u2717");
|
|
29357
29623
|
case "warning":
|
|
29358
|
-
return
|
|
29624
|
+
return color64.amber("!");
|
|
29359
29625
|
case "ok":
|
|
29360
|
-
return
|
|
29626
|
+
return color64.green("\u2713");
|
|
29361
29627
|
default:
|
|
29362
|
-
return
|
|
29628
|
+
return color64.cyan("\xB7");
|
|
29363
29629
|
}
|
|
29364
29630
|
}
|
|
29365
29631
|
function renderFindings(lines, findings) {
|
|
29366
29632
|
for (const category of CATEGORY_ORDER) {
|
|
29367
29633
|
const group = findings.filter((f) => f.category === category);
|
|
29368
29634
|
if (group.length === 0) continue;
|
|
29369
|
-
lines.push("",
|
|
29635
|
+
lines.push("", color64.bold(CATEGORY_LABELS[category]));
|
|
29370
29636
|
for (const f of group) {
|
|
29371
29637
|
lines.push(` ${severityIcon(f.severity)} ${f.problem}`);
|
|
29372
29638
|
if (f.suggestion) {
|
|
29373
|
-
for (const s of f.suggestion.split("\n")) lines.push(
|
|
29639
|
+
for (const s of f.suggestion.split("\n")) lines.push(color64.dim(` ${s}`));
|
|
29374
29640
|
}
|
|
29375
|
-
if (f.fix) lines.push(
|
|
29641
|
+
if (f.fix) lines.push(color64.dim(` \u2192 fixable: ${f.fix}`));
|
|
29376
29642
|
}
|
|
29377
29643
|
}
|
|
29378
29644
|
}
|
|
@@ -29381,20 +29647,20 @@ function summaryLine(findings, fixable, handoffs, power) {
|
|
|
29381
29647
|
(f) => f.severity === "warning" || f.severity === "error"
|
|
29382
29648
|
).length;
|
|
29383
29649
|
if (warnings === 0 && fixable === 0 && handoffs === 0) {
|
|
29384
|
-
return `${
|
|
29650
|
+
return `${color64.green("\u2713")} everything looks healthy`;
|
|
29385
29651
|
}
|
|
29386
29652
|
const parts = [];
|
|
29387
29653
|
if (warnings > 0) parts.push(`${warnings} warning(s)`);
|
|
29388
29654
|
if (fixable > 0) parts.push(`${fixable} auto-fixable`);
|
|
29389
29655
|
if (handoffs > 0) parts.push(`${handoffs} for the agent`);
|
|
29390
29656
|
const cmd = power ? "/tuneup fix --power" : "/tuneup fix";
|
|
29391
|
-
return `${parts.join(", ")} ${
|
|
29657
|
+
return `${parts.join(", ")} ${color64.dim(`\u2014 run ${cmd}`)}`;
|
|
29392
29658
|
}
|
|
29393
29659
|
|
|
29394
29660
|
// src/slash-commands/working-dir.ts
|
|
29395
|
-
import * as
|
|
29661
|
+
import * as fs18 from "node:fs/promises";
|
|
29396
29662
|
import * as path21 from "node:path";
|
|
29397
|
-
import { color as
|
|
29663
|
+
import { color as color65, toErrorMessage as toErrorMessage28 } from "@wrongstack/core/utils";
|
|
29398
29664
|
function buildWorkingDirCommand(_opts) {
|
|
29399
29665
|
return {
|
|
29400
29666
|
name: "working_dir",
|
|
@@ -29413,16 +29679,16 @@ function buildWorkingDirCommand(_opts) {
|
|
|
29413
29679
|
].join("\n"),
|
|
29414
29680
|
async run(args, ctx) {
|
|
29415
29681
|
if (!ctx) {
|
|
29416
|
-
return { message:
|
|
29682
|
+
return { message: color65.yellow("No active context. Start a session first.") };
|
|
29417
29683
|
}
|
|
29418
29684
|
const trimmed = args.trim();
|
|
29419
29685
|
if (!trimmed) {
|
|
29420
29686
|
const rel2 = path21.relative(ctx.projectRoot, ctx.workingDir) || ".";
|
|
29421
29687
|
return {
|
|
29422
29688
|
message: [
|
|
29423
|
-
`Working directory: ${
|
|
29424
|
-
|
|
29425
|
-
|
|
29689
|
+
`Working directory: ${color65.bold(ctx.workingDir)}`,
|
|
29690
|
+
color65.dim(` (relative to root: ${rel2})`),
|
|
29691
|
+
color65.dim(` Project root: ${ctx.projectRoot}`)
|
|
29426
29692
|
].join("\n")
|
|
29427
29693
|
};
|
|
29428
29694
|
}
|
|
@@ -29431,7 +29697,7 @@ function buildWorkingDirCommand(_opts) {
|
|
|
29431
29697
|
const rel = path21.relative(root, resolved);
|
|
29432
29698
|
if (rel.startsWith("..") || path21.isAbsolute(rel)) {
|
|
29433
29699
|
return {
|
|
29434
|
-
message:
|
|
29700
|
+
message: color65.red(
|
|
29435
29701
|
`Directory "${trimmed}" is outside the project root.
|
|
29436
29702
|
Resolved: ${resolved}
|
|
29437
29703
|
Root: ${root}`
|
|
@@ -29439,27 +29705,27 @@ function buildWorkingDirCommand(_opts) {
|
|
|
29439
29705
|
};
|
|
29440
29706
|
}
|
|
29441
29707
|
try {
|
|
29442
|
-
const stat5 = await
|
|
29708
|
+
const stat5 = await fs18.stat(resolved);
|
|
29443
29709
|
if (!stat5.isDirectory()) {
|
|
29444
|
-
return { message:
|
|
29710
|
+
return { message: color65.red(`Not a directory: ${resolved}`) };
|
|
29445
29711
|
}
|
|
29446
29712
|
} catch {
|
|
29447
|
-
return { message:
|
|
29713
|
+
return { message: color65.red(`Directory does not exist: ${resolved}`) };
|
|
29448
29714
|
}
|
|
29449
29715
|
const previous = ctx.workingDir;
|
|
29450
29716
|
try {
|
|
29451
29717
|
ctx.setWorkingDir(resolved);
|
|
29452
29718
|
} catch (err) {
|
|
29453
29719
|
return {
|
|
29454
|
-
message:
|
|
29720
|
+
message: color65.red(toErrorMessage28(err))
|
|
29455
29721
|
};
|
|
29456
29722
|
}
|
|
29457
29723
|
const prevRel = path21.relative(ctx.projectRoot, previous) || ".";
|
|
29458
29724
|
const newRel = path21.relative(ctx.projectRoot, resolved) || ".";
|
|
29459
29725
|
return {
|
|
29460
29726
|
message: [
|
|
29461
|
-
|
|
29462
|
-
|
|
29727
|
+
color65.green(` \u2713 ${prevRel} \u2192 ${color65.bold(newRel)}`),
|
|
29728
|
+
color65.dim(` ${resolved}`)
|
|
29463
29729
|
].join("\n")
|
|
29464
29730
|
};
|
|
29465
29731
|
}
|
|
@@ -29528,7 +29794,7 @@ function buildWorktreeCommand(opts) {
|
|
|
29528
29794
|
}
|
|
29529
29795
|
|
|
29530
29796
|
// src/slash-commands/yolo.ts
|
|
29531
|
-
import { color as
|
|
29797
|
+
import { color as color66 } from "@wrongstack/core/utils";
|
|
29532
29798
|
function buildYoloCommand(opts) {
|
|
29533
29799
|
return {
|
|
29534
29800
|
name: "yolo",
|
|
@@ -29552,7 +29818,7 @@ function buildYoloCommand(opts) {
|
|
|
29552
29818
|
}
|
|
29553
29819
|
if (!arg) {
|
|
29554
29820
|
const current = opts.onYolo();
|
|
29555
|
-
const status = current ? `${
|
|
29821
|
+
const status = current ? `${color66.yellow("ON")} ${color66.dim("(auto-approving tool calls)")}` : `${color66.green("OFF")} ${color66.dim("(permission prompts active)")}`;
|
|
29556
29822
|
const msg2 = `YOLO mode: ${status}`;
|
|
29557
29823
|
opts.renderer.write(msg2);
|
|
29558
29824
|
return { message: msg2 };
|
|
@@ -29567,11 +29833,11 @@ function buildYoloCommand(opts) {
|
|
|
29567
29833
|
} else if (arg === "destructive") {
|
|
29568
29834
|
const currentMode = opts.onYolo();
|
|
29569
29835
|
if (!currentMode) {
|
|
29570
|
-
const msg3 = `${
|
|
29836
|
+
const msg3 = `${color66.amber("YOLO is OFF.")} Destructive-gate flags are deprecated; prompts are active because YOLO is off.`;
|
|
29571
29837
|
opts.renderer.writeWarning(msg3);
|
|
29572
29838
|
return { message: msg3 };
|
|
29573
29839
|
}
|
|
29574
|
-
const msg2 = `${
|
|
29840
|
+
const msg2 = `${color66.amber("Destructive gate:")} ${color66.dim("deprecated \u2014 YOLO auto-approves all non-denied tool calls.")}`;
|
|
29575
29841
|
opts.renderer.writeWarning(msg2);
|
|
29576
29842
|
return { message: msg2 };
|
|
29577
29843
|
} else {
|
|
@@ -29580,7 +29846,7 @@ function buildYoloCommand(opts) {
|
|
|
29580
29846
|
return { message: msg2 };
|
|
29581
29847
|
}
|
|
29582
29848
|
opts.onYolo(newState);
|
|
29583
|
-
const label = newState ? `${
|
|
29849
|
+
const label = newState ? `${color66.yellow("ENABLED")} \u2014 tool calls will be auto-approved unless explicitly denied` : `${color66.green("DISABLED")} \u2014 permission prompts are active`;
|
|
29584
29850
|
const msg = `YOLO mode: ${label}`;
|
|
29585
29851
|
opts.renderer.write(msg);
|
|
29586
29852
|
return { message: msg };
|
|
@@ -29658,6 +29924,7 @@ function buildBuiltinSlashCommands(opts) {
|
|
|
29658
29924
|
buildTelegramSetupCommand(opts),
|
|
29659
29925
|
buildTelegramSettingsCommand(opts),
|
|
29660
29926
|
buildSetModelCommand(opts),
|
|
29927
|
+
buildEffortCommand(opts),
|
|
29661
29928
|
buildRefinerCommand(opts),
|
|
29662
29929
|
buildFallbackCommand(opts),
|
|
29663
29930
|
...opts.statusTracker ? [buildProviderStatusCommand(opts.statusTracker)] : [],
|
|
@@ -30099,7 +30366,7 @@ async function spawnAgent2(director, role, task, maxIterations) {
|
|
|
30099
30366
|
// src/wiring/dep-watcher.ts
|
|
30100
30367
|
import * as path22 from "node:path";
|
|
30101
30368
|
import {
|
|
30102
|
-
getSharedProjectMailbox as
|
|
30369
|
+
getSharedProjectMailbox as getSharedProjectMailbox9,
|
|
30103
30370
|
startPackageOutdatedWatcher,
|
|
30104
30371
|
startTechStackConsumer
|
|
30105
30372
|
} from "@wrongstack/core/coordination";
|
|
@@ -30119,7 +30386,7 @@ function setupDepWatcherConsumers(deps) {
|
|
|
30119
30386
|
if (dwCfg?.["enabled"] === true) {
|
|
30120
30387
|
try {
|
|
30121
30388
|
const projectDir = path22.join(globalRoot, "projects", projectSlug);
|
|
30122
|
-
const tsMailbox =
|
|
30389
|
+
const tsMailbox = getSharedProjectMailbox9(projectDir, events);
|
|
30123
30390
|
const fileAuthorOpts = {
|
|
30124
30391
|
storageDir: projectDir,
|
|
30125
30392
|
projectRoot
|
|
@@ -30152,7 +30419,7 @@ function setupDepWatcherConsumers(deps) {
|
|
|
30152
30419
|
if (dwCfg?.["enabled"] === true) {
|
|
30153
30420
|
try {
|
|
30154
30421
|
const projectDir = path22.join(globalRoot, "projects", projectSlug);
|
|
30155
|
-
const pkgMailbox =
|
|
30422
|
+
const pkgMailbox = getSharedProjectMailbox9(projectDir, events);
|
|
30156
30423
|
const pkgTrackerOpts = {
|
|
30157
30424
|
storageDir: projectDir,
|
|
30158
30425
|
projectRoot
|
|
@@ -30195,7 +30462,7 @@ function setupDepWatcherConsumers(deps) {
|
|
|
30195
30462
|
|
|
30196
30463
|
// src/wiring/dep-watcher-bridge.ts
|
|
30197
30464
|
import * as path23 from "node:path";
|
|
30198
|
-
import { attachDepWatcherBridge, getSharedProjectMailbox as
|
|
30465
|
+
import { attachDepWatcherBridge, getSharedProjectMailbox as getSharedProjectMailbox10 } from "@wrongstack/core/coordination";
|
|
30199
30466
|
function setupDepWatcherBridge(deps) {
|
|
30200
30467
|
const { config, wpaths, projectRoot, events, logger, teardownHandlers } = deps;
|
|
30201
30468
|
const fwCfg = config.extensions?.["file-watcher"];
|
|
@@ -30204,7 +30471,7 @@ function setupDepWatcherBridge(deps) {
|
|
|
30204
30471
|
if (dwCfg?.["enabled"] === true) {
|
|
30205
30472
|
try {
|
|
30206
30473
|
const projectDir = path23.join(wpaths.globalRoot, "projects", wpaths.projectSlug);
|
|
30207
|
-
const dwMailbox =
|
|
30474
|
+
const dwMailbox = getSharedProjectMailbox10(projectDir, events);
|
|
30208
30475
|
depWatcherDispose = attachDepWatcherBridge({
|
|
30209
30476
|
events,
|
|
30210
30477
|
mailbox: dwMailbox,
|
|
@@ -30540,7 +30807,7 @@ function setupHqTelemetry(deps) {
|
|
|
30540
30807
|
agentMonitor,
|
|
30541
30808
|
brainMailbox,
|
|
30542
30809
|
teardownHandlers,
|
|
30543
|
-
mailboxSessionTag:
|
|
30810
|
+
mailboxSessionTag: mailboxSessionTag7,
|
|
30544
30811
|
hqPublisherRef,
|
|
30545
30812
|
mcpRegistry
|
|
30546
30813
|
} = deps;
|
|
@@ -30549,7 +30816,7 @@ function setupHqTelemetry(deps) {
|
|
|
30549
30816
|
const hqCommandController = {
|
|
30550
30817
|
steerMailbox: brainMailbox,
|
|
30551
30818
|
interruptLeader: () => false,
|
|
30552
|
-
sessionTag: () =>
|
|
30819
|
+
sessionTag: () => mailboxSessionTag7(session.id),
|
|
30553
30820
|
allowRunCommand: () => flags["hq-allow-exec"] === true
|
|
30554
30821
|
};
|
|
30555
30822
|
const hqOnCommand = createHqCommandDispatcher(hqCommandController);
|
|
@@ -30704,7 +30971,7 @@ function setupHqTelemetry(deps) {
|
|
|
30704
30971
|
|
|
30705
30972
|
// src/wiring/lifecycle-plugins.ts
|
|
30706
30973
|
import * as path28 from "node:path";
|
|
30707
|
-
import { getSharedProjectMailbox as
|
|
30974
|
+
import { getSharedProjectMailbox as getSharedProjectMailbox11 } from "@wrongstack/core/coordination";
|
|
30708
30975
|
import { CouncilOrchestrator, OneShotOrchestrator as OneShotOrchestrator2 } from "@wrongstack/core/execution";
|
|
30709
30976
|
import { countShellHooks, HookRegistry, HookRunner, shellHooksEqual } from "@wrongstack/core/hooks";
|
|
30710
30977
|
import { allServers as allServers3 } from "@wrongstack/core/infrastructure";
|
|
@@ -30786,7 +31053,7 @@ function installDesignStudio(deps) {
|
|
|
30786
31053
|
|
|
30787
31054
|
// src/wiring/metrics.ts
|
|
30788
31055
|
import { constants as fsConstants, writeFileSync } from "node:fs";
|
|
30789
|
-
import * as
|
|
31056
|
+
import * as fs19 from "node:fs/promises";
|
|
30790
31057
|
import * as path26 from "node:path";
|
|
30791
31058
|
import {
|
|
30792
31059
|
DefaultHealthRegistry,
|
|
@@ -30933,7 +31200,7 @@ function setupMetrics(params) {
|
|
|
30933
31200
|
name: "session-store",
|
|
30934
31201
|
check: async () => {
|
|
30935
31202
|
try {
|
|
30936
|
-
await
|
|
31203
|
+
await fs19.access(wpaths.projectSessions, fsConstants.R_OK | fsConstants.W_OK);
|
|
30937
31204
|
return { status: "healthy" };
|
|
30938
31205
|
} catch {
|
|
30939
31206
|
return { status: "unhealthy", detail: "session storage is not readable and writable" };
|
|
@@ -30944,7 +31211,7 @@ function setupMetrics(params) {
|
|
|
30944
31211
|
name: "project-storage",
|
|
30945
31212
|
check: async () => {
|
|
30946
31213
|
try {
|
|
30947
|
-
await
|
|
31214
|
+
await fs19.access(wpaths.projectDir, fsConstants.R_OK | fsConstants.W_OK);
|
|
30948
31215
|
return { status: "healthy" };
|
|
30949
31216
|
} catch {
|
|
30950
31217
|
return { status: "unhealthy", detail: "project storage is not readable and writable" };
|
|
@@ -31764,7 +32031,7 @@ async function setupLifecycleAndPlugins(deps) {
|
|
|
31764
32031
|
registerMcpObservability(healthRegistry, metricsSink, mcpRegistry);
|
|
31765
32032
|
const slashRegistry = new SlashCommandRegistry();
|
|
31766
32033
|
const hqPublisherRef = { current: void 0 };
|
|
31767
|
-
const brainMailbox =
|
|
32034
|
+
const brainMailbox = getSharedProjectMailbox11(
|
|
31768
32035
|
wpaths.projectDir,
|
|
31769
32036
|
events,
|
|
31770
32037
|
() => hqPublisherRef.current
|
|
@@ -31825,7 +32092,8 @@ async function setupLifecycleAndPlugins(deps) {
|
|
|
31825
32092
|
historyFile: wpaths.historyFile,
|
|
31826
32093
|
syncConfig: wpaths.syncConfig,
|
|
31827
32094
|
projectDir: wpaths.projectDir,
|
|
31828
|
-
projectGoal: wpaths.projectGoal
|
|
32095
|
+
projectGoal: wpaths.projectGoal,
|
|
32096
|
+
projectRoot: wpaths.projectRoot
|
|
31829
32097
|
},
|
|
31830
32098
|
hookRegistry,
|
|
31831
32099
|
mailbox: brainMailbox,
|
|
@@ -32277,14 +32545,14 @@ function setupProviderRuntime(deps) {
|
|
|
32277
32545
|
}
|
|
32278
32546
|
|
|
32279
32547
|
// src/wiring/provider-status.ts
|
|
32280
|
-
import * as
|
|
32548
|
+
import * as fs20 from "node:fs/promises";
|
|
32281
32549
|
import { ProviderModelStatusTracker } from "@wrongstack/core/coordination";
|
|
32282
|
-
import { atomicWrite as
|
|
32550
|
+
import { atomicWrite as atomicWrite11, withFileLock } from "@wrongstack/core/utils";
|
|
32283
32551
|
async function setupProviderStatus(input) {
|
|
32284
32552
|
const tracker = new ProviderModelStatusTracker({ events: input.events });
|
|
32285
32553
|
const statusFile = input.paths.profileProviderStatus(input.paths.profileName);
|
|
32286
32554
|
try {
|
|
32287
|
-
const saved = JSON.parse(await
|
|
32555
|
+
const saved = JSON.parse(await fs20.readFile(statusFile, "utf8"));
|
|
32288
32556
|
const restored = tracker.restoreSnapshot(saved);
|
|
32289
32557
|
if (restored > 0) input.logger.info(`Restored ${restored} provider waiting-room entries`);
|
|
32290
32558
|
} catch (error) {
|
|
@@ -32296,7 +32564,7 @@ async function setupProviderStatus(input) {
|
|
|
32296
32564
|
tracker.sweepExpired();
|
|
32297
32565
|
if (syncRunning) return;
|
|
32298
32566
|
syncRunning = true;
|
|
32299
|
-
void
|
|
32567
|
+
void fs20.readFile(statusFile, "utf8").then((raw) => tracker.restoreSnapshot(JSON.parse(raw))).catch((error) => warnUnlessMissing(input.logger, "sync", error)).finally(() => {
|
|
32300
32568
|
syncRunning = false;
|
|
32301
32569
|
});
|
|
32302
32570
|
}, 3e4);
|
|
@@ -32311,7 +32579,7 @@ async function setupProviderStatus(input) {
|
|
|
32311
32579
|
await withFileLock(statusFile, async () => {
|
|
32312
32580
|
let statuses = [];
|
|
32313
32581
|
try {
|
|
32314
|
-
const current = JSON.parse(await
|
|
32582
|
+
const current = JSON.parse(await fs20.readFile(statusFile, "utf8"));
|
|
32315
32583
|
if (Array.isArray(current.statuses)) statuses = current.statuses;
|
|
32316
32584
|
} catch (error) {
|
|
32317
32585
|
if (error.code !== "ENOENT") throw error;
|
|
@@ -32327,7 +32595,7 @@ async function setupProviderStatus(input) {
|
|
|
32327
32595
|
if (current && current.state !== "healthy") statuses.push(current);
|
|
32328
32596
|
}
|
|
32329
32597
|
}
|
|
32330
|
-
await
|
|
32598
|
+
await atomicWrite11(
|
|
32331
32599
|
statusFile,
|
|
32332
32600
|
JSON.stringify({ version: 1, updatedAt: Date.now(), statuses }, null, 2),
|
|
32333
32601
|
{ mode: 384 }
|
|
@@ -33384,7 +33652,7 @@ async function runInteractive(cliCtx) {
|
|
|
33384
33652
|
cwd,
|
|
33385
33653
|
wpaths,
|
|
33386
33654
|
teardownHandlers,
|
|
33387
|
-
mailboxSessionTag:
|
|
33655
|
+
mailboxSessionTag: mailboxSessionTag6,
|
|
33388
33656
|
brainMailbox,
|
|
33389
33657
|
agentMonitor,
|
|
33390
33658
|
manifestPath,
|
|
@@ -33415,7 +33683,7 @@ async function runInteractive(cliCtx) {
|
|
|
33415
33683
|
agentMonitor,
|
|
33416
33684
|
brainMailbox,
|
|
33417
33685
|
teardownHandlers,
|
|
33418
|
-
mailboxSessionTag:
|
|
33686
|
+
mailboxSessionTag: mailboxSessionTag6,
|
|
33419
33687
|
hqPublisherRef,
|
|
33420
33688
|
mcpRegistry
|
|
33421
33689
|
});
|
|
@@ -33748,4 +34016,4 @@ export {
|
|
|
33748
34016
|
CLI_VERSION,
|
|
33749
34017
|
runInteractive
|
|
33750
34018
|
};
|
|
33751
|
-
//# sourceMappingURL=cli-main-
|
|
34019
|
+
//# sourceMappingURL=cli-main-RG2PTQ6S.js.map
|