@moxxy/cli 0.13.1 → 0.14.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/bin.js +240 -147
- package/dist/bin.js.map +1 -1
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { z as z$1, createMutex, defineTunnelProvider,
|
|
3
|
+
import { z as z$1, createMutex, defineTunnelProvider, definePlugin, defineProvider, defineTool, MoxxyError, asTurnId, defineMode, asPluginId, defineCommand, defineChannel, defineWorkflowExecutor, toFriendlyError, estimateTextTokens, classifyHttpStatus, createStuckLoopDetector, runCompactionIfNeeded, runElisionIfNeeded, collectProviderStream, usageEventFields, isContextOverflowError, emitRequestsAndDetectStuck, executeToolUses, buildSystemPromptWithSkills, projectMessages, defineCompactor, defineCacheStrategy, denyByDefaultResolver, createAllowListResolver, zodToJsonSchema, fileDiffSummary, runSingleShotTurn, defineSurface, runManualCompaction, isFileDiffDisplay, renderFrontmatter, defineEmbedder, migrateModeName, skillFrontmatterSchema, asSkillId, getInstallHint, parseFrontmatterFile, createDeferredPermissionResolver, encodeLoginPrompt, defineTranscriber, summarizeTokensByModel, countNodes, moxxyPackageSchema, classifyNetworkError, addModelTotals, createJsonFileStore, ISOLATION_RANK, MOXXY_PCM16_24KHZ_MIME, fileDiffVerb, parseFrontmatter, createCallbackResolver, autoAllowResolver, asSessionId, asToolCallId, defineViewRenderer, DEFAULT_VIEW_TAGS, isSafeViewUrl, evaluateToolRule, summarizeSessionTokensFromEvents, toDiffRows, diffGutterNo, computeElisionState, toolResultStubbed, toolResultStub, toolResultBytes, conversationalStubbed, conversationalStub, asEventId } from '@moxxy/sdk';
|
|
4
4
|
import * as fs32 from 'fs';
|
|
5
|
-
import fs32__default, { existsSync, promises, ReadStream, mkdirSync, statSync, readdirSync, writeFileSync, readFileSync,
|
|
5
|
+
import fs32__default, { existsSync, promises, ReadStream, mkdirSync, statSync, readdirSync, writeFileSync, readFileSync, unlinkSync, chmodSync, watch, createReadStream } from 'fs';
|
|
6
6
|
import * as path3 from 'path';
|
|
7
7
|
import path3__default, { join, dirname, basename } from 'path';
|
|
8
|
+
import { isCliTunnelAvailable, writeFileAtomic, spawnCliTunnel, moxxyPath, moxxyHome, bearerTokenMatches, resolveChannelToken, rotateChannelToken, readRequestBody, MOXXY_WS_SUBPROTOCOL, bearerGuard, tokenFromWsProtocolHeader, writeFileAtomicSync } from '@moxxy/sdk/server';
|
|
8
9
|
import { z } from 'zod';
|
|
9
10
|
import * as os5 from 'os';
|
|
10
11
|
import os5__default, { homedir, tmpdir, userInfo } from 'os';
|
|
@@ -2966,6 +2967,8 @@ var init_workflow_executors = __esm({
|
|
|
2966
2967
|
};
|
|
2967
2968
|
}
|
|
2968
2969
|
});
|
|
2970
|
+
|
|
2971
|
+
// ../core/dist/requirements.js
|
|
2969
2972
|
function issue(requirement, code, message) {
|
|
2970
2973
|
return {
|
|
2971
2974
|
requirement,
|
|
@@ -2984,9 +2987,10 @@ function activeModeName(modes) {
|
|
|
2984
2987
|
return null;
|
|
2985
2988
|
}
|
|
2986
2989
|
}
|
|
2987
|
-
var RequirementRegistry;
|
|
2990
|
+
var ALWAYS_ACTIVE, RequirementRegistry, TARGET_DESCRIPTORS;
|
|
2988
2991
|
var init_requirements = __esm({
|
|
2989
2992
|
"../core/dist/requirements.js"() {
|
|
2993
|
+
ALWAYS_ACTIVE = () => true;
|
|
2990
2994
|
RequirementRegistry = class {
|
|
2991
2995
|
opts;
|
|
2992
2996
|
runtime = /* @__PURE__ */ new Map();
|
|
@@ -3049,52 +3053,54 @@ var init_requirements = __esm({
|
|
|
3049
3053
|
return null;
|
|
3050
3054
|
}
|
|
3051
3055
|
targetInfo(kind3, name) {
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
return plugin5 ? { kind: kind3, name, version: plugin5.version, active: true } : null;
|
|
3056
|
-
}
|
|
3057
|
-
case "provider": {
|
|
3058
|
-
const def = this.opts.providers.list().find((p3) => p3.name === name);
|
|
3059
|
-
return def ? { kind: kind3, name, active: this.opts.providers.getActiveName() === name } : null;
|
|
3060
|
-
}
|
|
3061
|
-
case "tool": {
|
|
3062
|
-
const def = this.opts.tools.get(name);
|
|
3063
|
-
return def ? { kind: kind3, name, active: true } : null;
|
|
3064
|
-
}
|
|
3065
|
-
case "transcriber": {
|
|
3066
|
-
const def = this.opts.transcribers.list().find((t2) => t2.name === name);
|
|
3067
|
-
return def ? { kind: kind3, name, active: this.opts.transcribers.getActiveName() === name } : null;
|
|
3068
|
-
}
|
|
3069
|
-
case "synthesizer": {
|
|
3070
|
-
const def = this.opts.synthesizers.list().find((s2) => s2.name === name);
|
|
3071
|
-
return def ? { kind: kind3, name, active: this.opts.synthesizers.getActiveName() === name } : null;
|
|
3072
|
-
}
|
|
3073
|
-
case "mode": {
|
|
3074
|
-
const def = this.opts.modes.list().find((m3) => m3.name === name);
|
|
3075
|
-
return def ? { kind: kind3, name, active: activeModeName(this.opts.modes) === name } : null;
|
|
3076
|
-
}
|
|
3077
|
-
case "compactor": {
|
|
3078
|
-
const def = this.opts.compactors.list().find((c2) => c2.name === name);
|
|
3079
|
-
return def ? { kind: kind3, name, active: this.opts.compactors.getActive()?.name === name } : null;
|
|
3080
|
-
}
|
|
3081
|
-
case "channel": {
|
|
3082
|
-
const def = this.opts.channels.get(name);
|
|
3083
|
-
return def ? { kind: kind3, name, active: true } : null;
|
|
3084
|
-
}
|
|
3085
|
-
case "agent": {
|
|
3086
|
-
const def = this.opts.agents.get(name);
|
|
3087
|
-
return def ? { kind: kind3, name, active: true } : null;
|
|
3088
|
-
}
|
|
3089
|
-
case "command": {
|
|
3090
|
-
const def = this.opts.commands.get(name);
|
|
3091
|
-
return def ? { kind: kind3, name, active: true } : null;
|
|
3092
|
-
}
|
|
3093
|
-
case "runtime":
|
|
3094
|
-
return null;
|
|
3095
|
-
default:
|
|
3096
|
-
return assertNever(kind3);
|
|
3056
|
+
if (kind3 === "plugin") {
|
|
3057
|
+
const plugin5 = this.plugins.get(name);
|
|
3058
|
+
return plugin5 ? { kind: kind3, name, version: plugin5.version, active: true } : null;
|
|
3097
3059
|
}
|
|
3060
|
+
if (kind3 === "runtime")
|
|
3061
|
+
return null;
|
|
3062
|
+
const descriptor = TARGET_DESCRIPTORS[kind3];
|
|
3063
|
+
if (!descriptor.present(this.opts, name))
|
|
3064
|
+
return null;
|
|
3065
|
+
return { kind: kind3, name, active: descriptor.active(this.opts, name) };
|
|
3066
|
+
}
|
|
3067
|
+
};
|
|
3068
|
+
TARGET_DESCRIPTORS = {
|
|
3069
|
+
provider: {
|
|
3070
|
+
present: (opts, name) => opts.providers.list().some((p3) => p3.name === name),
|
|
3071
|
+
active: (opts, name) => opts.providers.getActiveName() === name
|
|
3072
|
+
},
|
|
3073
|
+
tool: {
|
|
3074
|
+
present: (opts, name) => opts.tools.get(name) !== void 0,
|
|
3075
|
+
active: ALWAYS_ACTIVE
|
|
3076
|
+
},
|
|
3077
|
+
transcriber: {
|
|
3078
|
+
present: (opts, name) => opts.transcribers.list().some((t2) => t2.name === name),
|
|
3079
|
+
active: (opts, name) => opts.transcribers.getActiveName() === name
|
|
3080
|
+
},
|
|
3081
|
+
synthesizer: {
|
|
3082
|
+
present: (opts, name) => opts.synthesizers.list().some((s2) => s2.name === name),
|
|
3083
|
+
active: (opts, name) => opts.synthesizers.getActiveName() === name
|
|
3084
|
+
},
|
|
3085
|
+
mode: {
|
|
3086
|
+
present: (opts, name) => opts.modes.list().some((m3) => m3.name === name),
|
|
3087
|
+
active: (opts, name) => activeModeName(opts.modes) === name
|
|
3088
|
+
},
|
|
3089
|
+
compactor: {
|
|
3090
|
+
present: (opts, name) => opts.compactors.list().some((c2) => c2.name === name),
|
|
3091
|
+
active: (opts, name) => opts.compactors.getActive()?.name === name
|
|
3092
|
+
},
|
|
3093
|
+
channel: {
|
|
3094
|
+
present: (opts, name) => opts.channels.get(name) !== void 0,
|
|
3095
|
+
active: ALWAYS_ACTIVE
|
|
3096
|
+
},
|
|
3097
|
+
agent: {
|
|
3098
|
+
present: (opts, name) => opts.agents.get(name) !== void 0,
|
|
3099
|
+
active: ALWAYS_ACTIVE
|
|
3100
|
+
},
|
|
3101
|
+
command: {
|
|
3102
|
+
present: (opts, name) => opts.commands.get(name) !== void 0,
|
|
3103
|
+
active: ALWAYS_ACTIVE
|
|
3098
3104
|
}
|
|
3099
3105
|
};
|
|
3100
3106
|
}
|
|
@@ -85505,12 +85511,9 @@ function handleCollabEvent(e3, ref, root) {
|
|
|
85505
85511
|
root.push(block2);
|
|
85506
85512
|
return;
|
|
85507
85513
|
}
|
|
85508
|
-
|
|
85509
|
-
if (!block)
|
|
85510
|
-
|
|
85511
|
-
ref.current = block;
|
|
85512
|
-
root.push(block);
|
|
85513
|
-
}
|
|
85514
|
+
const block = ref.current;
|
|
85515
|
+
if (!block)
|
|
85516
|
+
return;
|
|
85514
85517
|
switch (e3.subtype) {
|
|
85515
85518
|
case "collab_fallback_sequential":
|
|
85516
85519
|
block.fallbackReason = String(p3.reason ?? "");
|
|
@@ -87762,7 +87765,7 @@ function useVoiceInput(opts) {
|
|
|
87762
87765
|
const pcm = await recording.stop();
|
|
87763
87766
|
const transcriber = resolveCodexTranscriber(session);
|
|
87764
87767
|
const result = await transcriber.transcribe(pcm, {
|
|
87765
|
-
mimeType:
|
|
87768
|
+
mimeType: MOXXY_PCM16_24KHZ_MIME
|
|
87766
87769
|
});
|
|
87767
87770
|
const text = result.text.trim();
|
|
87768
87771
|
if (!text) {
|
|
@@ -87869,13 +87872,12 @@ function formatVoiceError(err) {
|
|
|
87869
87872
|
return `voice: ${message}`;
|
|
87870
87873
|
return `voice: ${message || "failed"}`;
|
|
87871
87874
|
}
|
|
87872
|
-
var import_react51, CODEX_TRANSCRIBER_NAME
|
|
87875
|
+
var import_react51, CODEX_TRANSCRIBER_NAME;
|
|
87873
87876
|
var init_use_voice_input = __esm({
|
|
87874
87877
|
"../plugin-cli/dist/session/use-voice-input.js"() {
|
|
87875
87878
|
import_react51 = __toESM(require_react());
|
|
87876
87879
|
init_voice_input();
|
|
87877
87880
|
CODEX_TRANSCRIBER_NAME = "openai-codex-transcribe";
|
|
87878
|
-
MOXXY_PCM16_24KHZ_MIME2 = "audio/x-moxxy-pcm16-24khz";
|
|
87879
87881
|
}
|
|
87880
87882
|
});
|
|
87881
87883
|
|
|
@@ -88165,13 +88167,17 @@ function startCollab(deps, arg) {
|
|
|
88165
88167
|
deps.submitPrompt(objective);
|
|
88166
88168
|
}
|
|
88167
88169
|
function openModePicker(deps, arg = "") {
|
|
88168
|
-
const modes = deps.session.modes.list();
|
|
88170
|
+
const modes = deps.session.modes.list().filter((m3) => !COLLAB_HIDDEN_MODES.has(m3.name));
|
|
88169
88171
|
if (modes.length === 0) {
|
|
88170
88172
|
deps.setSystemNotice("no modes registered");
|
|
88171
88173
|
return;
|
|
88172
88174
|
}
|
|
88173
88175
|
const target = arg.trim().toLowerCase();
|
|
88174
88176
|
if (target) {
|
|
88177
|
+
if (COLLAB_HIDDEN_MODES.has(target)) {
|
|
88178
|
+
deps.setSystemNotice("Use /collab <goal> to run a collaborative team (only one runs at a time).");
|
|
88179
|
+
return;
|
|
88180
|
+
}
|
|
88175
88181
|
const match = modes.find((m3) => m3.name.toLowerCase() === target);
|
|
88176
88182
|
if (match) {
|
|
88177
88183
|
try {
|
|
@@ -88197,7 +88203,7 @@ function openModePicker(deps, arg = "") {
|
|
|
88197
88203
|
function truncate5(s2, n2) {
|
|
88198
88204
|
return s2.length <= n2 ? s2 : s2.slice(0, n2 - 1) + "\u2026";
|
|
88199
88205
|
}
|
|
88200
|
-
var PLUGIN_KIND_TAB, OTHER_TAB, PLUGIN_TAB_ORDER;
|
|
88206
|
+
var PLUGIN_KIND_TAB, OTHER_TAB, PLUGIN_TAB_ORDER, COLLAB_HIDDEN_MODES;
|
|
88201
88207
|
var init_run_slash = __esm({
|
|
88202
88208
|
async "../plugin-cli/dist/session/run-slash.js"() {
|
|
88203
88209
|
init_dist();
|
|
@@ -88212,6 +88218,11 @@ var init_run_slash = __esm({
|
|
|
88212
88218
|
};
|
|
88213
88219
|
OTHER_TAB = { id: "others", label: "Others" };
|
|
88214
88220
|
PLUGIN_TAB_ORDER = ["providers", "modes", "channels", "tools", "others"];
|
|
88221
|
+
COLLAB_HIDDEN_MODES = /* @__PURE__ */ new Set([
|
|
88222
|
+
"collaborative",
|
|
88223
|
+
"collab-architect",
|
|
88224
|
+
"collab-peer"
|
|
88225
|
+
]);
|
|
88215
88226
|
}
|
|
88216
88227
|
});
|
|
88217
88228
|
|
|
@@ -128479,7 +128490,7 @@ var ChatCompletionStream = class _ChatCompletionStream extends AbstractChatCompl
|
|
|
128479
128490
|
arguments_delta: toolCallDelta.function?.arguments ?? ""
|
|
128480
128491
|
});
|
|
128481
128492
|
} else {
|
|
128482
|
-
|
|
128493
|
+
assertNever2(toolCallSnapshot?.type);
|
|
128483
128494
|
}
|
|
128484
128495
|
}
|
|
128485
128496
|
}
|
|
@@ -128504,7 +128515,7 @@ var ChatCompletionStream = class _ChatCompletionStream extends AbstractChatCompl
|
|
|
128504
128515
|
parsed_arguments: isAutoParsableTool(inputTool) ? inputTool.$parseRaw(toolCallSnapshot.function.arguments) : inputTool?.function.strict ? JSON.parse(toolCallSnapshot.function.arguments) : null
|
|
128505
128516
|
});
|
|
128506
128517
|
} else {
|
|
128507
|
-
|
|
128518
|
+
assertNever2(toolCallSnapshot.type);
|
|
128508
128519
|
}
|
|
128509
128520
|
}, _ChatCompletionStream_emitContentDoneEvents = function _ChatCompletionStream_emitContentDoneEvents2(choiceSnapshot) {
|
|
128510
128521
|
const state = __classPrivateFieldGet15(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
|
|
@@ -128784,7 +128795,7 @@ ${str(snapshot)}`);
|
|
|
128784
128795
|
function str(x4) {
|
|
128785
128796
|
return JSON.stringify(x4);
|
|
128786
128797
|
}
|
|
128787
|
-
function
|
|
128798
|
+
function assertNever2(_x) {
|
|
128788
128799
|
}
|
|
128789
128800
|
|
|
128790
128801
|
// ../../node_modules/.pnpm/openai@4.104.0_encoding@0.1.13_ws@8.20.0_zod@3.25.76/node_modules/openai/lib/ChatCompletionStreamingRunner.mjs
|
|
@@ -133481,9 +133492,6 @@ var localPlugin = definePlugin({
|
|
|
133481
133492
|
version: "0.0.0",
|
|
133482
133493
|
providers: [localProviderDef]
|
|
133483
133494
|
});
|
|
133484
|
-
|
|
133485
|
-
// ../plugin-stt-whisper/dist/audio.js
|
|
133486
|
-
var MOXXY_PCM16_24KHZ_MIME = "audio/x-moxxy-pcm16-24khz";
|
|
133487
133495
|
var WHISPER_FILENAME_BY_MIME = {
|
|
133488
133496
|
"audio/ogg": "audio.ogg",
|
|
133489
133497
|
"audio/opus": "audio.opus",
|
|
@@ -136258,7 +136266,7 @@ async function reclaimStaleSocket(socketPath) {
|
|
|
136258
136266
|
|
|
136259
136267
|
// ../runner/dist/server.js
|
|
136260
136268
|
init_dist();
|
|
136261
|
-
var RUNNER_PROTOCOL_VERSION =
|
|
136269
|
+
var RUNNER_PROTOCOL_VERSION = 9;
|
|
136262
136270
|
var MIN_COMPATIBLE_PROTOCOL_VERSION = 1;
|
|
136263
136271
|
var RunnerMethod = {
|
|
136264
136272
|
/** client->server: handshake; returns the initial info snapshot. */
|
|
@@ -136281,6 +136289,8 @@ var RunnerMethod = {
|
|
|
136281
136289
|
SetResolver: "setResolver",
|
|
136282
136290
|
/** client->server: switch the active mode. */
|
|
136283
136291
|
ModeSetActive: "mode.setActive",
|
|
136292
|
+
/** client->server: set the session's reasoning/thinking effort (v9). */
|
|
136293
|
+
SessionSetReasoning: "session.setReasoning",
|
|
136284
136294
|
/** client->server: switch the active provider (server resolves credentials). */
|
|
136285
136295
|
ProviderSetActive: "provider.setActive",
|
|
136286
136296
|
/** client->server: enable/disable a provider (v7; persists to preferences). */
|
|
@@ -136397,6 +136407,9 @@ var setResolverParamsSchema = z.object({
|
|
|
136397
136407
|
approval: z.boolean().optional()
|
|
136398
136408
|
});
|
|
136399
136409
|
var modeSetActiveParamsSchema = z.object({ name: z.string() });
|
|
136410
|
+
var sessionSetReasoningParamsSchema = z.object({
|
|
136411
|
+
effort: z.enum(["off", "low", "medium", "high"])
|
|
136412
|
+
});
|
|
136400
136413
|
var providerSetActiveParamsSchema = z.object({
|
|
136401
136414
|
name: z.string(),
|
|
136402
136415
|
config: z.record(z.unknown()).optional()
|
|
@@ -136726,6 +136739,12 @@ function handleModeSetActive(ctx, raw) {
|
|
|
136726
136739
|
ctx.session.modes.setActive(name);
|
|
136727
136740
|
return {};
|
|
136728
136741
|
}
|
|
136742
|
+
function handleSessionSetReasoning(ctx, raw) {
|
|
136743
|
+
const { effort } = sessionSetReasoningParamsSchema.parse(raw);
|
|
136744
|
+
ctx.session.reasoning = effort === "off" ? void 0 : { effort };
|
|
136745
|
+
ctx.broadcastInfo();
|
|
136746
|
+
return {};
|
|
136747
|
+
}
|
|
136729
136748
|
async function handlePermissionAddAllow(ctx, raw) {
|
|
136730
136749
|
const { name, reason } = permissionAddAllowParamsSchema.parse(raw);
|
|
136731
136750
|
await ctx.session.permissions.addAllow({ name, ...reason ? { reason } : {} });
|
|
@@ -136846,6 +136865,7 @@ var RunnerServer = class {
|
|
|
136846
136865
|
peer.handle(RunnerMethod.SessionReset, () => this.handleSessionReset());
|
|
136847
136866
|
peer.handle(RunnerMethod.SetResolver, (raw) => this.handleSetResolver(client, raw));
|
|
136848
136867
|
peer.handle(RunnerMethod.ModeSetActive, (raw) => handleModeSetActive(ctx, raw));
|
|
136868
|
+
peer.handle(RunnerMethod.SessionSetReasoning, (raw) => handleSessionSetReasoning(ctx, raw));
|
|
136849
136869
|
peer.handle(RunnerMethod.ProviderSetActive, (raw) => handleProviderSetActive(ctx, raw));
|
|
136850
136870
|
peer.handle(RunnerMethod.ProviderSetEnabled, (raw) => handleProviderSetEnabled(ctx, raw));
|
|
136851
136871
|
peer.handle(RunnerMethod.ProviderRefreshReady, () => handleProviderRefreshReady(ctx));
|
|
@@ -137282,6 +137302,10 @@ function makeProviderAdminView(ctx) {
|
|
|
137282
137302
|
configure: async (name, patch) => {
|
|
137283
137303
|
requireServerProtocol(7, "Configuring a provider");
|
|
137284
137304
|
await peer.request(RunnerMethod.ProviderConfigure, { name, patch });
|
|
137305
|
+
},
|
|
137306
|
+
setReasoning: async (effort) => {
|
|
137307
|
+
requireServerProtocol(9, "Setting reasoning effort");
|
|
137308
|
+
await peer.request(RunnerMethod.SessionSetReasoning, { effort });
|
|
137285
137309
|
}
|
|
137286
137310
|
};
|
|
137287
137311
|
}
|
|
@@ -139079,6 +139103,57 @@ async function integrate(input) {
|
|
|
139079
139103
|
}
|
|
139080
139104
|
return { merged, conflicts, resolvedByOwnership, stagingBranch: branchName, promoted };
|
|
139081
139105
|
}
|
|
139106
|
+
var COLLAB_LOCK_PATH = join(homedir(), ".moxxy", "collab", "active.lock");
|
|
139107
|
+
function collabLockPath() {
|
|
139108
|
+
return process.env.MOXXY_COLLAB_LOCK || COLLAB_LOCK_PATH;
|
|
139109
|
+
}
|
|
139110
|
+
function readRaw() {
|
|
139111
|
+
try {
|
|
139112
|
+
return JSON.parse(readFileSync(collabLockPath(), "utf8"));
|
|
139113
|
+
} catch {
|
|
139114
|
+
return null;
|
|
139115
|
+
}
|
|
139116
|
+
}
|
|
139117
|
+
function isAlive(pid) {
|
|
139118
|
+
try {
|
|
139119
|
+
process.kill(pid, 0);
|
|
139120
|
+
return true;
|
|
139121
|
+
} catch (err) {
|
|
139122
|
+
return err.code === "EPERM";
|
|
139123
|
+
}
|
|
139124
|
+
}
|
|
139125
|
+
function readActiveCollab() {
|
|
139126
|
+
const info = readRaw();
|
|
139127
|
+
if (!info)
|
|
139128
|
+
return null;
|
|
139129
|
+
if (!isAlive(info.pid)) {
|
|
139130
|
+
try {
|
|
139131
|
+
unlinkSync(collabLockPath());
|
|
139132
|
+
} catch {
|
|
139133
|
+
}
|
|
139134
|
+
return null;
|
|
139135
|
+
}
|
|
139136
|
+
return info;
|
|
139137
|
+
}
|
|
139138
|
+
function tryAcquireCollabLock(args) {
|
|
139139
|
+
mkdirSync(dirname(collabLockPath()), { recursive: true });
|
|
139140
|
+
const existing = readActiveCollab();
|
|
139141
|
+
if (existing && existing.sessionId !== args.sessionId) {
|
|
139142
|
+
return { ok: false, holder: existing };
|
|
139143
|
+
}
|
|
139144
|
+
const info = { pid: process.pid, ...args };
|
|
139145
|
+
writeFileSync(collabLockPath(), JSON.stringify(info));
|
|
139146
|
+
return { ok: true };
|
|
139147
|
+
}
|
|
139148
|
+
function releaseCollabLock(sessionId) {
|
|
139149
|
+
const info = readRaw();
|
|
139150
|
+
if (info && info.sessionId === sessionId) {
|
|
139151
|
+
try {
|
|
139152
|
+
unlinkSync(collabLockPath());
|
|
139153
|
+
} catch {
|
|
139154
|
+
}
|
|
139155
|
+
}
|
|
139156
|
+
}
|
|
139082
139157
|
|
|
139083
139158
|
// ../mode-collaborative/dist/collab-loop.js
|
|
139084
139159
|
var POLL_MS = 500;
|
|
@@ -139097,47 +139172,56 @@ async function* runCollaborative(ctx, deps) {
|
|
|
139097
139172
|
yield await ctx.emit(assistant(ctx, "Collaborative mode needs a task to work on."));
|
|
139098
139173
|
return;
|
|
139099
139174
|
}
|
|
139100
|
-
const
|
|
139101
|
-
|
|
139102
|
-
|
|
139103
|
-
|
|
139104
|
-
|
|
139105
|
-
yield await ctx.emit(plugin4(ctx, "collab_fallback_sequential", {
|
|
139106
|
-
reason: !gitInstalled2 ? "git is not installed \u2014 running agents sequentially in your workspace" : !gitRepo ? "this folder is not a git repository \u2014 running agents sequentially in your workspace" : "sequential mode selected"
|
|
139107
|
-
}));
|
|
139108
|
-
}
|
|
139109
|
-
let baseSha = "";
|
|
139110
|
-
if (parallel) {
|
|
139111
|
-
const base2 = await resolveBase(cwd2);
|
|
139112
|
-
baseSha = base2.baseSha;
|
|
139175
|
+
const lock = tryAcquireCollabLock({ sessionId: String(ctx.sessionId), task, startedAtMs: Date.now() });
|
|
139176
|
+
if (!lock.ok) {
|
|
139177
|
+
yield await ctx.emit(plugin4(ctx, "collab_blocked", { reason: "already-running", holderTask: lock.holder.task }));
|
|
139178
|
+
yield await ctx.emit(assistant(ctx, `A collaboration is already running ("${lock.holder.task}"). Only one runs at a time to save resources \u2014 stop it first, then start again.`));
|
|
139179
|
+
return;
|
|
139113
139180
|
}
|
|
139181
|
+
const runId = collabRunId(String(ctx.sessionId), String(ctx.turnId));
|
|
139114
139182
|
const worktrees = /* @__PURE__ */ new Map();
|
|
139115
|
-
|
|
139116
|
-
|
|
139117
|
-
|
|
139118
|
-
role: "architect",
|
|
139119
|
-
subtask: task
|
|
139120
|
-
};
|
|
139121
|
-
const hub = await createCollaborationHub({
|
|
139122
|
-
socketPath: hubSocketPath(runId),
|
|
139123
|
-
task,
|
|
139124
|
-
roster: [architectEntry],
|
|
139125
|
-
peerReader: peerReaderFor(worktrees, baseSha)
|
|
139126
|
-
});
|
|
139127
|
-
registerActiveHub(String(ctx.sessionId), hub);
|
|
139128
|
-
const unsubscribe = hub.subscribe((e3) => {
|
|
139129
|
-
void ctx.emit(toCollabEvent(ctx, e3));
|
|
139130
|
-
});
|
|
139131
|
-
const supervisorOpts = {
|
|
139132
|
-
runId,
|
|
139133
|
-
hubSocket: hub.socketPath,
|
|
139134
|
-
coordinatorSessionId: String(ctx.sessionId),
|
|
139135
|
-
parentTask: task,
|
|
139136
|
-
...cfg.defaultModel ? { defaultModel: cfg.defaultModel } : {},
|
|
139137
|
-
signal: ctx.signal
|
|
139138
|
-
};
|
|
139139
|
-
const supervisor = (deps.createSupervisor ?? ((o2) => new PeerSupervisor(o2)))(supervisorOpts, hub);
|
|
139183
|
+
let hub = null;
|
|
139184
|
+
let supervisor = null;
|
|
139185
|
+
let unsubscribe = null;
|
|
139140
139186
|
try {
|
|
139187
|
+
mkdirSync(collabRunDir(runId), { recursive: true });
|
|
139188
|
+
const { installed: gitInstalled2, repo: gitRepo } = await detectGit(cwd2);
|
|
139189
|
+
const parallel = cfg.concurrency === "parallel" && gitRepo;
|
|
139190
|
+
if (!parallel) {
|
|
139191
|
+
yield await ctx.emit(plugin4(ctx, "collab_fallback_sequential", {
|
|
139192
|
+
reason: !gitInstalled2 ? "git is not installed \u2014 running agents sequentially in your workspace" : !gitRepo ? "this folder is not a git repository \u2014 running agents sequentially in your workspace" : "sequential mode selected"
|
|
139193
|
+
}));
|
|
139194
|
+
}
|
|
139195
|
+
let baseSha = "";
|
|
139196
|
+
if (parallel) {
|
|
139197
|
+
const base2 = await resolveBase(cwd2, { snapshotDirty: true });
|
|
139198
|
+
baseSha = base2.baseSha;
|
|
139199
|
+
}
|
|
139200
|
+
const architectEntry = {
|
|
139201
|
+
id: ARCHITECT_AGENT_ID,
|
|
139202
|
+
name: "Architect",
|
|
139203
|
+
role: "architect",
|
|
139204
|
+
subtask: task
|
|
139205
|
+
};
|
|
139206
|
+
hub = await createCollaborationHub({
|
|
139207
|
+
socketPath: hubSocketPath(runId),
|
|
139208
|
+
task,
|
|
139209
|
+
roster: [architectEntry],
|
|
139210
|
+
peerReader: peerReaderFor(worktrees, baseSha)
|
|
139211
|
+
});
|
|
139212
|
+
registerActiveHub(String(ctx.sessionId), hub);
|
|
139213
|
+
unsubscribe = hub.subscribe((e3) => {
|
|
139214
|
+
void ctx.emit(toCollabEvent(ctx, e3));
|
|
139215
|
+
});
|
|
139216
|
+
const supervisorOpts = {
|
|
139217
|
+
runId,
|
|
139218
|
+
hubSocket: hub.socketPath,
|
|
139219
|
+
coordinatorSessionId: String(ctx.sessionId),
|
|
139220
|
+
parentTask: task,
|
|
139221
|
+
...cfg.defaultModel ? { defaultModel: cfg.defaultModel } : {},
|
|
139222
|
+
signal: ctx.signal
|
|
139223
|
+
};
|
|
139224
|
+
supervisor = (deps.createSupervisor ?? ((o2) => new PeerSupervisor(o2)))(supervisorOpts, hub);
|
|
139141
139225
|
yield await ctx.emit(plugin4(ctx, "collab_started", { task, parallel, gitInstalled: gitInstalled2, gitRepo }));
|
|
139142
139226
|
supervisor.spawn({ entry: architectEntry, cwd: cwd2, mode: COLLAB_ARCHITECT_MODE_NAME });
|
|
139143
139227
|
yield await ctx.emit(plugin4(ctx, "collab_agent_spawned", { id: ARCHITECT_AGENT_ID, role: "architect" }));
|
|
@@ -139235,10 +139319,14 @@ ${summaryBlock}${mergeNote ? `
|
|
|
139235
139319
|
${mergeNote}` : ""}`));
|
|
139236
139320
|
yield await ctx.emit(plugin4(ctx, "collab_completed", { done: doneIds, total: roster.length }));
|
|
139237
139321
|
} finally {
|
|
139238
|
-
|
|
139239
|
-
|
|
139322
|
+
if (supervisor)
|
|
139323
|
+
await supervisor.shutdownAll("collaboration complete");
|
|
139324
|
+
if (unsubscribe)
|
|
139325
|
+
unsubscribe();
|
|
139240
139326
|
unregisterActiveHub(String(ctx.sessionId));
|
|
139241
|
-
|
|
139327
|
+
if (hub)
|
|
139328
|
+
await hub.close();
|
|
139329
|
+
releaseCollabLock(String(ctx.sessionId));
|
|
139242
139330
|
}
|
|
139243
139331
|
}
|
|
139244
139332
|
function lastUserPromptText(ctx) {
|
|
@@ -144062,6 +144150,7 @@ var optionalWorkspace = z.string().min(1).max(256).optional();
|
|
|
144062
144150
|
var MAX_AUDIO_BASE64 = 4e7;
|
|
144063
144151
|
var MAX_INLINE_ATTACHMENT_CONTENT = 12e6;
|
|
144064
144152
|
var commandName = z.string().min(1).max(64).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/, "invalid command name");
|
|
144153
|
+
var appId = z.string().min(1).max(64).regex(/^[a-z][a-z0-9-]*$/, "invalid app id");
|
|
144065
144154
|
var workflowName = z.string().min(1).max(200).refine((s2) => !s2.includes("..") && !s2.includes("/") && !s2.includes("\\"), "invalid workflow name");
|
|
144066
144155
|
var ipcInputSchemas = {
|
|
144067
144156
|
// No-arg, but spawns a child process (npm install) — pin the payload to
|
|
@@ -144168,9 +144257,36 @@ var ipcInputSchemas = {
|
|
|
144168
144257
|
path: z.string().max(4096).optional()
|
|
144169
144258
|
}),
|
|
144170
144259
|
"settings.fetchProviderModels": z.object({ provider: providerName }),
|
|
144260
|
+
// Session config mutation — pin the effort to the known enum so a renderer
|
|
144261
|
+
// can't push an arbitrary string through to the runner / provider request.
|
|
144262
|
+
"settings.setReasoning": z.object({
|
|
144263
|
+
workspaceId: optionalWorkspace,
|
|
144264
|
+
effort: z.enum(["off", "low", "medium", "high"])
|
|
144265
|
+
}),
|
|
144171
144266
|
"settings.writeSkill": z.object({ name: skillName, body: z.string().max(1e6) }),
|
|
144172
144267
|
"settings.readSkill": z.object({ name: skillName }),
|
|
144173
144268
|
"settings.deleteSkill": z.object({ name: skillName }),
|
|
144269
|
+
// Desktop apps: appId keys the per-app install dir + a network download, so
|
|
144270
|
+
// pin it to a non-traversing slug. (pickDocument is no-arg → see below.)
|
|
144271
|
+
"apps.status": z.object({ appId }),
|
|
144272
|
+
"apps.install": z.object({ appId }),
|
|
144273
|
+
"apps.uninstall": z.object({ appId }),
|
|
144274
|
+
// Anonymizer: parseDocument reads a file (bound the path), saveRedacted writes
|
|
144275
|
+
// one (bound name + cap content so a renderer can't OOM main). pickDocument
|
|
144276
|
+
// takes nothing — pin it to "nothing" so no args can be smuggled across.
|
|
144277
|
+
"anonymizer.pickDocument": z.undefined(),
|
|
144278
|
+
"anonymizer.parseDocument": z.object({ path: z.string().min(1).max(4096) }),
|
|
144279
|
+
// A drag-dropped doc: the renderer sends the dropped file's BYTES (base64),
|
|
144280
|
+
// not a path — so there's no arbitrary-file-read to gate, only a size to cap.
|
|
144281
|
+
// ~67 MB of base64 ≈ 50 MB of file, matching the picker's practical ceiling.
|
|
144282
|
+
"anonymizer.parseDocumentBytes": z.object({
|
|
144283
|
+
name: z.string().min(1).max(255),
|
|
144284
|
+
dataBase64: z.string().min(1).max(67e6)
|
|
144285
|
+
}),
|
|
144286
|
+
"anonymizer.saveRedacted": z.object({
|
|
144287
|
+
suggestedName: z.string().min(1).max(255),
|
|
144288
|
+
content: z.string().max(2e7)
|
|
144289
|
+
}),
|
|
144174
144290
|
"desks.create": z.object({ name: z.string().min(1).max(200), cwd: z.string().min(1).max(4096) }),
|
|
144175
144291
|
// Mirror desks.create's name bounds — rename writes the name into the desks
|
|
144176
144292
|
// JSON, so an unbounded string would let a renderer bloat the state file.
|
|
@@ -146562,37 +146678,25 @@ async function compactSession(session) {
|
|
|
146562
146678
|
if (events.length === 0) {
|
|
146563
146679
|
return { kind: "text", text: "nothing to compact: event log is empty" };
|
|
146564
146680
|
}
|
|
146565
|
-
const providerCtxWindow = resolveActiveContextWindow(s2);
|
|
146566
146681
|
const provider = safe(() => s2.providers?.getActive()) ?? void 0;
|
|
146567
146682
|
const model = provider?.models[0]?.id;
|
|
146683
|
+
const contextWindow = provider?.models[0]?.contextWindow;
|
|
146568
146684
|
try {
|
|
146569
|
-
const result = await
|
|
146570
|
-
|
|
146571
|
-
|
|
146572
|
-
|
|
146573
|
-
estimatedTokens: estimateContextTokens$1(s2.log.asReader ? s2.log.asReader() : s2.log),
|
|
146574
|
-
reserveForOutput: 0
|
|
146575
|
-
},
|
|
146576
|
-
signal: s2.signal ?? new AbortController().signal,
|
|
146685
|
+
const result = await runManualCompaction({
|
|
146686
|
+
compactor,
|
|
146687
|
+
log: s2.log,
|
|
146688
|
+
signal: s2.signal,
|
|
146577
146689
|
...provider ? { provider } : {},
|
|
146578
|
-
...model ? { model } : {}
|
|
146690
|
+
...model !== void 0 ? { model } : {},
|
|
146691
|
+
...contextWindow !== void 0 ? { contextWindow } : {},
|
|
146692
|
+
...s2.id !== void 0 ? { sessionId: s2.id } : {}
|
|
146579
146693
|
});
|
|
146580
|
-
if (result.
|
|
146694
|
+
if (!result.compacted) {
|
|
146581
146695
|
return { kind: "text", text: "nothing to compact yet" };
|
|
146582
146696
|
}
|
|
146583
|
-
const lastEvent = events[events.length - 1];
|
|
146584
|
-
const emittable = {
|
|
146585
|
-
sessionId: s2.id ?? lastEvent?.sessionId,
|
|
146586
|
-
turnId: lastEvent?.turnId,
|
|
146587
|
-
source: "compactor",
|
|
146588
|
-
...result
|
|
146589
|
-
};
|
|
146590
|
-
await s2.log.append(emittable);
|
|
146591
|
-
const [fromSeq, toSeq] = result.replacedRange;
|
|
146592
|
-
const compactedEvents = events.filter((e3) => e3.seq >= fromSeq && e3.seq <= toSeq).length;
|
|
146593
146697
|
return {
|
|
146594
146698
|
kind: "text",
|
|
146595
|
-
text: `context compacted: ${formatCount2(
|
|
146699
|
+
text: `context compacted: ${formatCount2(result.eventsCompacted)} ${plural2(result.eventsCompacted, "event")}, ~${formatTokenCount2(result.tokensSaved)} tokens saved`
|
|
146596
146700
|
};
|
|
146597
146701
|
} catch (err) {
|
|
146598
146702
|
return {
|
|
@@ -146601,17 +146705,6 @@ async function compactSession(session) {
|
|
|
146601
146705
|
};
|
|
146602
146706
|
}
|
|
146603
146707
|
}
|
|
146604
|
-
function resolveActiveContextWindow(s2) {
|
|
146605
|
-
try {
|
|
146606
|
-
const provider = s2.providers?.getActive();
|
|
146607
|
-
if (!provider)
|
|
146608
|
-
return Number.MAX_SAFE_INTEGER;
|
|
146609
|
-
const window2 = provider.models[0]?.contextWindow;
|
|
146610
|
-
return window2 && window2 > 0 ? window2 : Number.MAX_SAFE_INTEGER;
|
|
146611
|
-
} catch {
|
|
146612
|
-
return Number.MAX_SAFE_INTEGER;
|
|
146613
|
-
}
|
|
146614
|
-
}
|
|
146615
146708
|
function formatCount2(value) {
|
|
146616
146709
|
return new Intl.NumberFormat("en-US").format(value);
|
|
146617
146710
|
}
|
|
@@ -147136,7 +147229,7 @@ var computerControlPlugin = definePlugin({
|
|
|
147136
147229
|
tools: [...computerControlTools]
|
|
147137
147230
|
});
|
|
147138
147231
|
|
|
147139
|
-
//
|
|
147232
|
+
// ../plugin-voice-admin/dist/index.js
|
|
147140
147233
|
init_dist();
|
|
147141
147234
|
function buildVoiceAdminPlugin(session) {
|
|
147142
147235
|
const voiceNames = () => [
|
|
@@ -147170,9 +147263,7 @@ function buildVoiceAdminPlugin(session) {
|
|
|
147170
147263
|
return { active: "system" };
|
|
147171
147264
|
}
|
|
147172
147265
|
if (!session.synthesizers.has(synthesizer)) {
|
|
147173
|
-
throw new Error(
|
|
147174
|
-
`No synthesizer named "${synthesizer}". Available: ${voiceNames().join(", ")}.`
|
|
147175
|
-
);
|
|
147266
|
+
throw new Error(`No synthesizer named "${synthesizer}". Available: ${voiceNames().join(", ")}.`);
|
|
147176
147267
|
}
|
|
147177
147268
|
session.synthesizers.setActive(synthesizer);
|
|
147178
147269
|
return { active: synthesizer };
|
|
@@ -147610,6 +147701,8 @@ var stepSchema = z.object({
|
|
|
147610
147701
|
needs: z.array(z.string().min(1)).default([]),
|
|
147611
147702
|
when: z.string().min(1).optional(),
|
|
147612
147703
|
onError: z.enum(["fail", "continue", "retry"]).default("fail"),
|
|
147704
|
+
// `retries` only takes effect when `onError: 'retry'`; with 'fail'/'continue'
|
|
147705
|
+
// the step runs exactly one attempt (see runStep in executor/steps.ts).
|
|
147613
147706
|
retries: z.number().int().min(0).max(3).default(0),
|
|
147614
147707
|
label: z.string().max(60).optional(),
|
|
147615
147708
|
format: z.enum(["json", "plain"]).optional(),
|
|
@@ -148519,7 +148612,7 @@ function buildRunResult(ctx, status, ok, extra) {
|
|
|
148519
148612
|
};
|
|
148520
148613
|
}
|
|
148521
148614
|
async function runStep(step, scope, ctx) {
|
|
148522
|
-
const attempts = 1 + Math.max(0, step.retries);
|
|
148615
|
+
const attempts = step.onError === "retry" ? 1 + Math.max(0, step.retries) : 1;
|
|
148523
148616
|
let lastError = "";
|
|
148524
148617
|
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
148525
148618
|
if (ctx.deps.signal.aborted)
|
|
@@ -149040,7 +149133,7 @@ ${userMessage.trim()}${FINALIZE_REPLY_SUFFIX}`;
|
|
|
149040
149133
|
var DAG_EXECUTOR_NAME = "dag";
|
|
149041
149134
|
var dagExecutor = defineWorkflowExecutor({
|
|
149042
149135
|
name: DAG_EXECUTOR_NAME,
|
|
149043
|
-
description: "DAG runner: steps with settled dependencies are scheduled in waves of up to `concurrency` ready steps, then executed sequentially within each wave (no overlap
|
|
149136
|
+
description: "DAG runner: steps with settled dependencies are scheduled in waves of up to `concurrency` ready steps, then executed sequentially within each wave (no overlap \u2014 `concurrency` caps the batch size drained per pass, not wall-clock latency).",
|
|
149044
149137
|
run: runExecutor
|
|
149045
149138
|
});
|
|
149046
149139
|
|
|
@@ -149107,7 +149200,7 @@ A workflow is a DAG of steps. Schema:
|
|
|
149107
149200
|
- args: templated args object for tool/workflow steps
|
|
149108
149201
|
- needs: [ <upstream step ids> ] (defines the DAG; omit only for true sources)
|
|
149109
149202
|
- when (optional, legacy): simple guards only \u2014 '{{ steps.x.output }} is not empty'. Do NOT use when for semantic decisions (use condition/switch).
|
|
149110
|
-
- onError (optional): fail | continue | retry ; retries (optional, 0-3)
|
|
149203
|
+
- onError (optional): fail | continue | retry ; retries (optional, 0-3 \u2014 only applies when onError is retry; fail/continue always run exactly one attempt)
|
|
149111
149204
|
|
|
149112
149205
|
Operator data \u2014 two ways: declare a value the operator can supply UP FRONT as an \`inputs\` field (filled in before Run). To PAUSE mid-run and ask a question whose answer depends on earlier steps, set \`awaitInput: true\` on a prompt or skill step: the workflow pauses, surfaces the step's prompt to the operator, and resumes with their reply once they answer. Prefer \`inputs\` for known-up-front values; use \`awaitInput\` only for genuinely mid-run questions.
|
|
149113
149206
|
|