@wrongstack/cli 1.0.1 → 1.0.4
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/data/providers.json +21 -21
- package/dist/{acp-3LARESEO.js → acp-AB54FWM2.js} +122 -39
- package/dist/acp-agent-list.d.ts +14 -0
- package/dist/acp-hq-telemetry.d.ts +9 -2
- package/dist/acp-mcp-servers.d.ts +49 -0
- package/dist/acp-server-agent.d.ts +18 -6
- package/dist/{auth-ZUMCDNE5.js → auth-WDMSNZ3S.js} +79 -55
- package/dist/auth-menu/index.d.ts +1 -0
- package/dist/auth-menu/oauth-menu.d.ts +3 -1
- package/dist/auth-menu/panel-service.d.ts +2 -0
- package/dist/auth-menu/provider-auth-login.d.ts +12 -0
- package/dist/auth-menu/types.d.ts +3 -0
- package/dist/auto-discover-providers-DXR25GTG.js +7 -0
- package/dist/boot/dispatch-webui.d.ts +1 -0
- package/dist/boot/short-circuit-hq.d.ts +2 -0
- package/dist/boot/system-prompt-builder.d.ts +7 -0
- package/dist/boot/system-prompt.d.ts +2 -1
- package/dist/boot/tool-registry.d.ts +18 -1
- package/dist/chimera-reviewer-policy.d.ts +1 -1
- package/dist/{chunk-C2E24IXZ.js → chunk-3I5ZJXM5.js} +147 -241
- package/dist/{chunk-JHPXJRRI.js → chunk-4XCBEUBX.js} +13 -3
- package/dist/{chunk-FPIWTJ2G.js → chunk-6WRKAACA.js} +4 -4
- package/dist/chunk-AUQDGU5D.js +32 -0
- package/dist/{chunk-D2VCUN7M.js → chunk-BIWE22O5.js} +17 -17
- package/dist/{chunk-VOTTENR5.js → chunk-CDY4D5QK.js} +2 -2
- package/dist/chunk-D5GB5MHA.js +87 -0
- package/dist/chunk-DAKVBMD4.js +36 -0
- package/dist/{chunk-E6RFXHWD.js → chunk-EK2P53GL.js} +3 -2
- package/dist/chunk-I7V2OYVH.js +242 -0
- package/dist/{chunk-MXEJEYT7.js → chunk-JX6KL7OF.js} +15 -5
- package/dist/{chunk-ZSZ3EYWH.js → chunk-KEPABQYT.js} +109 -6
- package/dist/{chunk-IMWXXF4J.js → chunk-KNMIBKLV.js} +79 -1
- package/dist/{chunk-MNQQ4ZNF.js → chunk-ONOT5OJ2.js} +290 -687
- package/dist/chunk-Q7E3BPDU.js +62 -0
- package/dist/chunk-SIGUWXAA.js +43 -0
- package/dist/{chunk-TEBMCYZN.js → chunk-SIS37L3W.js} +58 -2
- package/dist/{chunk-KHWDTNBZ.js → chunk-U6PGWDMZ.js} +5 -5
- package/dist/{chunk-5IA5337I.js → chunk-XJ7K67PP.js} +8 -2
- package/dist/{cli-context-7X3M6U73.js → cli-context-WFC3BNGM.js} +131 -25
- package/dist/{cli-main-53KG6HAV.js → cli-main-GU3YZLMO.js} +3986 -2827
- package/dist/{diag-doctor-7LYUYU35.js → diag-doctor-PCER6KHH.js} +2 -2
- package/dist/execute-deps.d.ts +1 -0
- package/dist/{execution-MIBWBYB6.js → execution-RAZDDQFC.js} +115 -16
- package/dist/execution-specialist-trigger.d.ts +28 -0
- package/dist/fleet/acp-live-progress.d.ts +19 -0
- package/dist/fleet/host-acp-runner-cache.d.ts +3 -1
- package/dist/fleet/host-acp.d.ts +14 -2
- package/dist/fleet/host.d.ts +1 -0
- package/dist/{hq-IG3YRGCO.js → hq-5XHEIIH6.js} +127 -8
- package/dist/hq-command-controller.d.ts +31 -2
- package/dist/hq-server/client-address.d.ts +2 -0
- package/dist/hq-server/ip-allowlist.d.ts +16 -0
- package/dist/hq-server/preflight.d.ts +1 -0
- package/dist/hq-server/routes/auth/password-routes.d.ts +1 -1
- package/dist/hq-server/routes.d.ts +5 -4
- package/dist/hq-server/secret-input.d.ts +7 -0
- package/dist/hq-server/types.d.ts +3 -2
- package/dist/hq-server/upgrade-handler.d.ts +2 -0
- package/dist/hq-server/utils.d.ts +6 -0
- package/dist/{hq-server-OILU3NPI.js → hq-server-CNUTBWTK.js} +4 -3
- package/dist/hq-server.d.ts +4 -0
- package/dist/hq-service-L5INQFM4.js +507 -0
- package/dist/hq-service.d.ts +22 -0
- package/dist/index.js +4 -4
- package/dist/ip-allowlist-NHXO6AKJ.js +9 -0
- package/dist/live-settings-input.d.ts +4 -0
- package/dist/{mailbox-serve-VUCWZ2SJ.js → mailbox-serve-X3CR6VFW.js} +4 -3
- package/dist/{modeldiag-FMJT37SN.js → modeldiag-46CMWUNM.js} +31 -24
- package/dist/{per-subcommand-help-BWBHYVJO.js → per-subcommand-help-DHTYU524.js} +2 -2
- package/dist/{plugin-usage-HFBI3TFT.js → plugin-usage-M6KET4OZ.js} +2 -2
- package/dist/{plugins-PZ2VZL7V.js → plugins-WJLW6ULV.js} +3 -3
- package/dist/projects-LMNAGGEU.js +36 -0
- package/dist/{providers-models-YVMVYWRS.js → providers-models-6MOGAOVK.js} +2 -2
- package/dist/{proxy-wiring-MGRSKZZB.js → proxy-wiring-K2DORFFL.js} +3 -3
- package/dist/short-circuit-flags-YDMLAQ5R.js +10 -0
- package/dist/slash-commands/acp.d.ts +3 -0
- package/dist/slash-commands/codebase-map.d.ts +11 -0
- package/dist/slash-commands/command-context.d.ts +29 -0
- package/dist/slash-commands/context.d.ts +10 -0
- package/dist/slash-commands/ensemble.d.ts +1 -1
- package/dist/slash-commands/openai-quota.d.ts +31 -0
- package/dist/slash-commands/profile.d.ts +7 -0
- package/dist/subcommands/handlers/hq.d.ts +1 -0
- package/dist/subcommands/handlers/projects.d.ts +14 -0
- package/dist/{subcommands-WJLBHVKC.js → subcommands-7N4RIK6H.js} +2 -2
- package/dist/{version-help-MYKF724O.js → version-help-WXI42PZ3.js} +2 -2
- package/dist/{webui-server-5R35BHWZ.js → webui-server-OBV5JYJV.js} +27 -4
- package/dist/webui-server-options.d.ts +1 -0
- package/dist/wiring/atlas-prompt-contributor.d.ts +54 -0
- package/dist/wiring/cli-execute-builder.d.ts +1 -0
- package/dist/wiring/cli-slash-commands-setup.d.ts +7 -0
- package/dist/wiring/codebase-embeddings.d.ts +31 -0
- package/dist/wiring/command-host-state.d.ts +9 -0
- package/dist/wiring/concept-summarizer.d.ts +32 -0
- package/dist/wiring/external-plugins.d.ts +1 -0
- package/dist/wiring/lifecycle-plugins.d.ts +2 -1
- package/dist/wiring/pipeline.d.ts +2 -0
- package/dist/wiring/plugins.d.ts +2 -1
- package/dist/wiring/provider-runtime-setup.d.ts +1 -1
- package/dist/wiring/provider.d.ts +2 -1
- package/dist/wiring/session-command-handlers.d.ts +2 -1
- package/dist/wiring/slash-commands.d.ts +1 -0
- package/package.json +29 -29
- package/dist/auto-discover-providers-VQU3IZMR.js +0 -7
- package/dist/chunk-52C7PD2H.js +0 -61
- package/dist/chunk-Q5GTM25S.js +0 -17
- package/dist/chunk-TNK6237M.js +0 -262
- package/dist/projects-L6C6XLDY.js +0 -37
- package/dist/short-circuit-flags-UREFSYBL.js +0 -10
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
startProxyProbe
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4XCBEUBX.js";
|
|
4
4
|
import {
|
|
5
5
|
formatGateCounterReport,
|
|
6
6
|
loadWrongTraceGateCounters
|
|
@@ -382,4 +382,4 @@ export {
|
|
|
382
382
|
doctorCmd,
|
|
383
383
|
proxyCmd
|
|
384
384
|
};
|
|
385
|
-
//# sourceMappingURL=diag-doctor-
|
|
385
|
+
//# sourceMappingURL=diag-doctor-PCER6KHH.js.map
|
package/dist/execute-deps.d.ts
CHANGED
|
@@ -149,6 +149,7 @@ interface SessionDeps {
|
|
|
149
149
|
/** Provider/model registry, selection and switching. */
|
|
150
150
|
interface ProviderDeps {
|
|
151
151
|
statusTracker?: import('@wrongstack/core/coordination').ProviderModelStatusTracker | undefined;
|
|
152
|
+
providerAuthRegistry: import('@wrongstack/core/registry').ProviderAuthRegistry;
|
|
152
153
|
modelsRegistry: ModelsRegistry;
|
|
153
154
|
savedProviderCfg: ProviderConfig | undefined;
|
|
154
155
|
resolvedProvider: ResolvedProvider | undefined;
|
|
@@ -11,17 +11,6 @@ import {
|
|
|
11
11
|
resolveActualTarget,
|
|
12
12
|
resolvePersistPath
|
|
13
13
|
} from "./chunk-JACOMTIH.js";
|
|
14
|
-
import {
|
|
15
|
-
theme
|
|
16
|
-
} from "./chunk-QD544J2B.js";
|
|
17
|
-
import {
|
|
18
|
-
WEBUI_SESSION_CHILD_CAPABILITIES,
|
|
19
|
-
writeWebuiSessionChildError,
|
|
20
|
-
writeWebuiSessionChildReady
|
|
21
|
-
} from "./chunk-GPPRNAKW.js";
|
|
22
|
-
import {
|
|
23
|
-
fmtTok
|
|
24
|
-
} from "./chunk-EWKESL4L.js";
|
|
25
14
|
import "./chunk-WHOIR577.js";
|
|
26
15
|
import {
|
|
27
16
|
advanceToNextTask,
|
|
@@ -36,6 +25,17 @@ import {
|
|
|
36
25
|
trySaveSpecFromAIOutput,
|
|
37
26
|
trySaveTasksFromAIOutput
|
|
38
27
|
} from "./chunk-JHUJUIOH.js";
|
|
28
|
+
import {
|
|
29
|
+
theme
|
|
30
|
+
} from "./chunk-QD544J2B.js";
|
|
31
|
+
import {
|
|
32
|
+
fmtTok
|
|
33
|
+
} from "./chunk-EWKESL4L.js";
|
|
34
|
+
import {
|
|
35
|
+
WEBUI_SESSION_CHILD_CAPABILITIES,
|
|
36
|
+
writeWebuiSessionChildError,
|
|
37
|
+
writeWebuiSessionChildReady
|
|
38
|
+
} from "./chunk-GPPRNAKW.js";
|
|
39
39
|
import {
|
|
40
40
|
terminalLink,
|
|
41
41
|
terminalText
|
|
@@ -178,6 +178,7 @@ async function runWebUIDispatch(ctx) {
|
|
|
178
178
|
globalConfigPath,
|
|
179
179
|
projectSessionsDir,
|
|
180
180
|
modelsRegistry,
|
|
181
|
+
providerAuthRegistry,
|
|
181
182
|
mcpRegistry,
|
|
182
183
|
brain,
|
|
183
184
|
brainSettings,
|
|
@@ -211,7 +212,7 @@ async function runWebUIDispatch(ctx) {
|
|
|
211
212
|
const isSimpleUi = !isSessionChild && flags["simpleui"] === true;
|
|
212
213
|
agent.disableInteractiveConfirmation();
|
|
213
214
|
renderer.setSilent(true);
|
|
214
|
-
const { runWebUI } = await import("./webui-server-
|
|
215
|
+
const { runWebUI } = await import("./webui-server-OBV5JYJV.js");
|
|
215
216
|
const flagValue = (names) => {
|
|
216
217
|
for (const name of names) {
|
|
217
218
|
if (!Object.hasOwn(flags, name)) continue;
|
|
@@ -305,6 +306,7 @@ async function runWebUIDispatch(ctx) {
|
|
|
305
306
|
agentTranscripts,
|
|
306
307
|
hqAllowExec: flagBoolean(["hq-allow-exec"]) ?? false,
|
|
307
308
|
modelsRegistry,
|
|
309
|
+
providerAuthRegistry,
|
|
308
310
|
globalConfigPath,
|
|
309
311
|
profileConfigPath: ctx.profileConfigPath,
|
|
310
312
|
mcpRegistry,
|
|
@@ -414,7 +416,7 @@ async function runWebUIDispatch(ctx) {
|
|
|
414
416
|
applyLiveSettings?.({ yolo: enabled });
|
|
415
417
|
},
|
|
416
418
|
onWrongProxyPrefsChange: (payload) => {
|
|
417
|
-
void import("./proxy-wiring-
|
|
419
|
+
void import("./proxy-wiring-K2DORFFL.js").then(
|
|
418
420
|
({ applyWrongProxyPrefs }) => applyWrongProxyPrefs(payload)
|
|
419
421
|
);
|
|
420
422
|
}
|
|
@@ -1923,6 +1925,7 @@ function createSettingsAdapter(ctx) {
|
|
|
1923
1925
|
systemPromptVariant: cfg.systemPrompt?.variant === "lite" || cfg.systemPrompt?.variant === "pro" ? cfg.systemPrompt.variant : cfg.systemPrompt?.variant === "default" ? "default" : "pro",
|
|
1924
1926
|
enhanceDelayMs: cfg.autonomy?.enhanceDelayMs ?? 15e3,
|
|
1925
1927
|
enhanceEnabled: cfg.autonomy?.enhance ?? true,
|
|
1928
|
+
preRefineSeconds: cfg.autonomy?.preRefineSeconds ?? 3,
|
|
1926
1929
|
enhanceLanguage: cfg.autonomy?.enhanceLanguage === "english" ? "english" : cfg.autonomy?.enhanceLanguage === "original" ? "original" : "english",
|
|
1927
1930
|
midRunSendPicker: cfg.autonomy?.midRunSendPicker ?? true,
|
|
1928
1931
|
mouseMode: autonomy?.mouseMode ?? false,
|
|
@@ -1934,6 +1937,7 @@ function createSettingsAdapter(ctx) {
|
|
|
1934
1937
|
breakerEnabled: cfg.circuitBreaker?.enabled === true,
|
|
1935
1938
|
breakerAutoKillResetMs: cfg.circuitBreaker?.autoKillResetMs ?? 6e4,
|
|
1936
1939
|
showModelReasoning: autonomy?.showModelReasoning ?? false,
|
|
1940
|
+
toolResultViewMode: autonomy?.toolResultViewMode === "minimal" || autonomy?.toolResultViewMode === "full" ? autonomy.toolResultViewMode : "normal",
|
|
1937
1941
|
showAgentSwarmPanel: coerceAgentSwarmMode(autonomy?.showAgentSwarmPanel),
|
|
1938
1942
|
showSidebar: autonomy?.showSidebar ?? true,
|
|
1939
1943
|
// Migrate the legacy `autonomy.showAgentSwarmPanel: 'sidebar'` into
|
|
@@ -1960,7 +1964,7 @@ function createSettingsAdapter(ctx) {
|
|
|
1960
1964
|
}
|
|
1961
1965
|
async function saveSettings(s) {
|
|
1962
1966
|
try {
|
|
1963
|
-
if (s.mode !== void 0 || s.delayMs !== void 0 || s.titleAnimation !== void 0 || s.yolo !== void 0 || s.fleetChatVerbosity !== void 0 || s.chime !== void 0 || s.confirmExit !== void 0 || s.mouseMode !== void 0 || s.featureMcp !== void 0 || s.featurePlugins !== void 0 || s.featureMemory !== void 0 || s.featureSkills !== void 0 || s.featureModelsRegistry !== void 0 || s.featureTokenSaving !== void 0 || s.allowOutsideProjectRoot !== void 0 || s.contextAutoCompact !== void 0 || s.contextStrategy !== void 0 || s.contextMode !== void 0 || s.maxConcurrent !== void 0 || s.logLevel !== void 0 || s.auditLevel !== void 0 || s.indexOnStart !== void 0 || s.maxIterations !== void 0 || s.multiDiffSummaryThreshold !== void 0 || s.nextStepsTool !== void 0 || s.restrictFsToRoot !== void 0 || s.nextPrediction !== void 0 || s.debugStream !== void 0 || s.shellBangWarningDontShowAgain !== void 0 || s.configScope !== void 0 || s.enhanceDelayMs !== void 0 || s.enhanceEnabled !== void 0 || s.enhanceLanguage !== void 0 || s.midRunSendPicker !== void 0 || s.statuslineMode !== void 0 || s.thinkingWord !== void 0 || s.animationStyle !== void 0 || s.autonomyNextPrompt !== void 0 || s.autoProceedMaxIterations !== void 0 || s.reasoningMode !== void 0 || s.reasoningEffort !== void 0 || s.reasoningPreserve !== void 0 || s.cacheTtl !== void 0 || s.breakerEnabled !== void 0 || s.breakerAutoKillResetMs !== void 0 || s.showModelReasoning !== void 0 || s.showAgentSwarmPanel !== void 0 || s.showSidebar !== void 0 || s.panelPositions !== void 0 || s.showSageMemoryInject !== void 0 || s.sageMemoryInjectThreshold !== void 0 || s.readSymbols !== void 0 || // WrongProxy / WrongTrace: gate the persisted-section write on
|
|
1967
|
+
if (s.mode !== void 0 || s.delayMs !== void 0 || s.titleAnimation !== void 0 || s.yolo !== void 0 || s.fleetChatVerbosity !== void 0 || s.chime !== void 0 || s.confirmExit !== void 0 || s.mouseMode !== void 0 || s.featureMcp !== void 0 || s.featurePlugins !== void 0 || s.featureMemory !== void 0 || s.featureSkills !== void 0 || s.featureModelsRegistry !== void 0 || s.featureTokenSaving !== void 0 || s.allowOutsideProjectRoot !== void 0 || s.contextAutoCompact !== void 0 || s.contextStrategy !== void 0 || s.contextMode !== void 0 || s.maxConcurrent !== void 0 || s.logLevel !== void 0 || s.auditLevel !== void 0 || s.indexOnStart !== void 0 || s.maxIterations !== void 0 || s.multiDiffSummaryThreshold !== void 0 || s.nextStepsTool !== void 0 || s.restrictFsToRoot !== void 0 || s.nextPrediction !== void 0 || s.debugStream !== void 0 || s.shellBangWarningDontShowAgain !== void 0 || s.configScope !== void 0 || s.enhanceDelayMs !== void 0 || s.enhanceEnabled !== void 0 || s.preRefineSeconds !== void 0 || s.enhanceLanguage !== void 0 || s.midRunSendPicker !== void 0 || s.statuslineMode !== void 0 || s.thinkingWord !== void 0 || s.animationStyle !== void 0 || s.autonomyNextPrompt !== void 0 || s.autoProceedMaxIterations !== void 0 || s.reasoningMode !== void 0 || s.reasoningEffort !== void 0 || s.reasoningPreserve !== void 0 || s.cacheTtl !== void 0 || s.breakerEnabled !== void 0 || s.breakerAutoKillResetMs !== void 0 || s.showModelReasoning !== void 0 || s.toolResultViewMode !== void 0 || s.showAgentSwarmPanel !== void 0 || s.showSidebar !== void 0 || s.panelPositions !== void 0 || s.showSageMemoryInject !== void 0 || s.sageMemoryInjectThreshold !== void 0 || s.readSymbols !== void 0 || // WrongProxy / WrongTrace: gate the persisted-section write on
|
|
1964
1968
|
// either key being present in the live patch. Without this, a
|
|
1965
1969
|
// picker toggle round-trip would silently no-op the persistence
|
|
1966
1970
|
// layer (the runtime probe would never read the change).
|
|
@@ -2005,6 +2009,7 @@ function createSettingsAdapter(ctx) {
|
|
|
2005
2009
|
if (s.mouseMode !== void 0) autonomy.mouseMode = s.mouseMode;
|
|
2006
2010
|
if (s.enhanceDelayMs !== void 0) autonomy.enhanceDelayMs = s.enhanceDelayMs;
|
|
2007
2011
|
if (s.enhanceEnabled !== void 0) autonomy.enhance = s.enhanceEnabled;
|
|
2012
|
+
if (s.preRefineSeconds !== void 0) autonomy.preRefineSeconds = s.preRefineSeconds;
|
|
2008
2013
|
if (s.enhanceLanguage !== void 0) autonomy.enhanceLanguage = s.enhanceLanguage;
|
|
2009
2014
|
if (s.midRunSendPicker !== void 0) autonomy.midRunSendPicker = s.midRunSendPicker;
|
|
2010
2015
|
if (s.shellBangWarningDontShowAgain !== void 0)
|
|
@@ -2014,6 +2019,7 @@ function createSettingsAdapter(ctx) {
|
|
|
2014
2019
|
autonomy.thinkingWord = normalizeTuiThinkingWord(s.thinkingWord);
|
|
2015
2020
|
if (s.animationStyle !== void 0) autonomy.animationStyle = s.animationStyle;
|
|
2016
2021
|
if (s.showModelReasoning !== void 0) autonomy.showModelReasoning = s.showModelReasoning;
|
|
2022
|
+
if (s.toolResultViewMode !== void 0) autonomy.toolResultViewMode = s.toolResultViewMode;
|
|
2017
2023
|
if (s.showAgentSwarmPanel !== void 0)
|
|
2018
2024
|
autonomy.showAgentSwarmPanel = s.showAgentSwarmPanel;
|
|
2019
2025
|
if (s.showSidebar !== void 0) autonomy.showSidebar = s.showSidebar;
|
|
@@ -2570,6 +2576,7 @@ var CHIMERA_REVIEW_READ_ONLY_TOOLS = Object.freeze([
|
|
|
2570
2576
|
"codebase-stats",
|
|
2571
2577
|
"codebase-search",
|
|
2572
2578
|
"codebase-skeleton",
|
|
2579
|
+
"codebase-context",
|
|
2573
2580
|
"codebase-repo-map",
|
|
2574
2581
|
"codebase-incoming-calls",
|
|
2575
2582
|
"codebase-outgoing-calls"
|
|
@@ -4364,6 +4371,87 @@ async function persistChimeraReview(payload, projectDir) {
|
|
|
4364
4371
|
}
|
|
4365
4372
|
}
|
|
4366
4373
|
|
|
4374
|
+
// src/execution-specialist-trigger.ts
|
|
4375
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
4376
|
+
var SPECIALIST_MAX_ITERATIONS = 30;
|
|
4377
|
+
var SPECIALIST_MAX_TOOL_CALLS = 120;
|
|
4378
|
+
var SPECIALIST_TIMEOUT_MS = 6 * 60 * 1e3;
|
|
4379
|
+
function installSpecialistTriggerHandler({
|
|
4380
|
+
events,
|
|
4381
|
+
director,
|
|
4382
|
+
session,
|
|
4383
|
+
teardownHandlers,
|
|
4384
|
+
trackWork
|
|
4385
|
+
}) {
|
|
4386
|
+
const off = events.onPattern(
|
|
4387
|
+
"fleet.specialist_needed",
|
|
4388
|
+
(_event, payload) => {
|
|
4389
|
+
const request = payload;
|
|
4390
|
+
const dir = director;
|
|
4391
|
+
if (!dir) return;
|
|
4392
|
+
if (!request?.role || !request.task) return;
|
|
4393
|
+
const work = (async () => {
|
|
4394
|
+
try {
|
|
4395
|
+
const subagentId = await dir.spawn({
|
|
4396
|
+
name: `trigger-${request.role}`,
|
|
4397
|
+
role: request.role,
|
|
4398
|
+
tier: request.tier,
|
|
4399
|
+
maxIterations: SPECIALIST_MAX_ITERATIONS,
|
|
4400
|
+
maxToolCalls: SPECIALIST_MAX_TOOL_CALLS,
|
|
4401
|
+
timeoutMs: SPECIALIST_TIMEOUT_MS,
|
|
4402
|
+
// Triggered specialists are background infrastructure, like
|
|
4403
|
+
// reviewers: they must not eat the leader's lifetime spawn budget,
|
|
4404
|
+
// which the user reserved for work they asked for.
|
|
4405
|
+
spawnBudgetExempt: true
|
|
4406
|
+
});
|
|
4407
|
+
const taskId = await dir.assign({
|
|
4408
|
+
id: randomUUID4(),
|
|
4409
|
+
description: request.task,
|
|
4410
|
+
subagentId,
|
|
4411
|
+
timeoutMs: SPECIALIST_TIMEOUT_MS
|
|
4412
|
+
});
|
|
4413
|
+
const [result] = await dir.awaitTasks([taskId]);
|
|
4414
|
+
if (result?.status === "success") {
|
|
4415
|
+
const text = typeof result.result === "string" ? result.result : JSON.stringify(result.result);
|
|
4416
|
+
await session.append({
|
|
4417
|
+
type: "llm_response",
|
|
4418
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4419
|
+
content: [
|
|
4420
|
+
{
|
|
4421
|
+
type: "text",
|
|
4422
|
+
text: `\u{1F514} ${request.role} (triggered by ${request.paths.length} changed file(s)) \u2014 ${text}`
|
|
4423
|
+
}
|
|
4424
|
+
],
|
|
4425
|
+
stopReason: "end_turn",
|
|
4426
|
+
usage: { input: 0, output: 0 }
|
|
4427
|
+
});
|
|
4428
|
+
return;
|
|
4429
|
+
}
|
|
4430
|
+
await session.append({
|
|
4431
|
+
type: "error",
|
|
4432
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4433
|
+
message: `\u{1F514} ${request.role} trigger ${result?.status ?? "unknown"}: ${result?.error?.message ?? "no result"}`,
|
|
4434
|
+
phase: "agent"
|
|
4435
|
+
});
|
|
4436
|
+
} catch (err) {
|
|
4437
|
+
try {
|
|
4438
|
+
await session.append({
|
|
4439
|
+
type: "error",
|
|
4440
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4441
|
+
message: `\u{1F514} ${request.role} trigger failed to run: ${err instanceof Error ? err.message : String(err)}`,
|
|
4442
|
+
phase: "agent"
|
|
4443
|
+
});
|
|
4444
|
+
} catch {
|
|
4445
|
+
}
|
|
4446
|
+
}
|
|
4447
|
+
})();
|
|
4448
|
+
trackWork?.(work);
|
|
4449
|
+
},
|
|
4450
|
+
"specialist-trigger"
|
|
4451
|
+
);
|
|
4452
|
+
if (off) teardownHandlers.push(off);
|
|
4453
|
+
}
|
|
4454
|
+
|
|
4367
4455
|
// src/execution-storage-observability.ts
|
|
4368
4456
|
function installStorageObservability(events, rootTraceId) {
|
|
4369
4457
|
const isStorageNamespace = (event) => event === "storage.read" || event === "storage.write" || event === "storage.error" || event.startsWith("storage.");
|
|
@@ -4445,7 +4533,7 @@ ${list}`);
|
|
|
4445
4533
|
function parsePredictions(raw, max = 3) {
|
|
4446
4534
|
const text = raw.trim();
|
|
4447
4535
|
if (!text) return [];
|
|
4448
|
-
if (/^none\.?\s*$/i.test(text) || /^no further steps
|
|
4536
|
+
if (/^none\.?\s*$/i.test(text) || /^no further steps(?: needed)?\.?\s*$/i.test(text)) return [];
|
|
4449
4537
|
const out = [];
|
|
4450
4538
|
for (const lineRaw of text.split("\n")) {
|
|
4451
4539
|
const line = lineRaw.trim();
|
|
@@ -6091,6 +6179,7 @@ async function execute(deps) {
|
|
|
6091
6179
|
},
|
|
6092
6180
|
provider: {
|
|
6093
6181
|
modelsRegistry,
|
|
6182
|
+
providerAuthRegistry,
|
|
6094
6183
|
savedProviderCfg,
|
|
6095
6184
|
resolvedProvider,
|
|
6096
6185
|
statusTracker,
|
|
@@ -6211,6 +6300,15 @@ async function execute(deps) {
|
|
|
6211
6300
|
chimeraWork.track(work);
|
|
6212
6301
|
}
|
|
6213
6302
|
});
|
|
6303
|
+
installSpecialistTriggerHandler({
|
|
6304
|
+
events,
|
|
6305
|
+
director,
|
|
6306
|
+
session,
|
|
6307
|
+
teardownHandlers: chimeraTeardowns,
|
|
6308
|
+
trackWork: (work) => {
|
|
6309
|
+
chimeraWork.track(work);
|
|
6310
|
+
}
|
|
6311
|
+
});
|
|
6214
6312
|
installChimeraCascadeHandler({
|
|
6215
6313
|
events,
|
|
6216
6314
|
director,
|
|
@@ -6595,6 +6693,7 @@ async function execute(deps) {
|
|
|
6595
6693
|
profileConfigPath: wpaths.profileConfig(profileName),
|
|
6596
6694
|
projectSessionsDir: wpaths.projectSessions,
|
|
6597
6695
|
modelsRegistry,
|
|
6696
|
+
providerAuthRegistry,
|
|
6598
6697
|
mcpRegistry,
|
|
6599
6698
|
brain,
|
|
6600
6699
|
brainSettings,
|
|
@@ -6741,4 +6840,4 @@ export {
|
|
|
6741
6840
|
execute,
|
|
6742
6841
|
resolveReviewerFallbackModels
|
|
6743
6842
|
};
|
|
6744
|
-
//# sourceMappingURL=execution-
|
|
6843
|
+
//# sourceMappingURL=execution-RAZDDQFC.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawns the roster specialist a file-pattern trigger asked for.
|
|
3
|
+
*
|
|
4
|
+
* The detection half lives in core (`specialist-trigger-plugin.ts`) and knows
|
|
5
|
+
* nothing about the fleet; this is the other side of that boundary, mirroring
|
|
6
|
+
* how `chimera.review_needed` is handled. A host with no Director simply never
|
|
7
|
+
* spawns, and the plugin keeps working as a pure detector.
|
|
8
|
+
*
|
|
9
|
+
* What it deliberately does not do: retry ladders, model pinning, cascades, or
|
|
10
|
+
* report persistence. A specialist woken by a glob is a background opinion,
|
|
11
|
+
* not a gate — if the model is down, the right outcome is one line in the
|
|
12
|
+
* transcript saying so, not a chain of failovers spending more money on an
|
|
13
|
+
* opinion nobody asked for.
|
|
14
|
+
*/
|
|
15
|
+
import type { Director } from '@wrongstack/core/coordination';
|
|
16
|
+
import type { EventBus } from '@wrongstack/core/kernel';
|
|
17
|
+
import type { SessionWriter } from '@wrongstack/core/types';
|
|
18
|
+
export interface InstallSpecialistTriggerHandlerOptions {
|
|
19
|
+
events: EventBus;
|
|
20
|
+
director: Director | null | undefined;
|
|
21
|
+
session: SessionWriter;
|
|
22
|
+
/** Session-scoped disposers, drained at session end. */
|
|
23
|
+
teardownHandlers: Array<() => void>;
|
|
24
|
+
/** Registers background work so the session waits for it before closing. */
|
|
25
|
+
trackWork?: ((work: Promise<void>) => void) | undefined;
|
|
26
|
+
}
|
|
27
|
+
export declare function installSpecialistTriggerHandler({ events, director, session, teardownHandlers, trackWork, }: InstallSpecialistTriggerHandlerOptions): void;
|
|
28
|
+
//# sourceMappingURL=execution-specialist-trigger.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge ACP session/update progress onto the same buses in-process
|
|
3
|
+
* subagents use, so TUI fleet chat, WebUI Agents panel, and HQ timeline
|
|
4
|
+
* can watch Claude Code / Gemini / Kimi the same way they watch a native worker.
|
|
5
|
+
*/
|
|
6
|
+
import type { ACPProgressEvent } from '@wrongstack/acp';
|
|
7
|
+
import type { FleetBus } from '@wrongstack/core/coordination';
|
|
8
|
+
import type { EventBus } from '@wrongstack/core/kernel';
|
|
9
|
+
export interface PublishAcpLiveProgressOpts {
|
|
10
|
+
event: ACPProgressEvent;
|
|
11
|
+
subagentId: string;
|
|
12
|
+
agentName: string;
|
|
13
|
+
sessionId?: string | undefined;
|
|
14
|
+
taskId?: string | undefined;
|
|
15
|
+
fleet?: Pick<FleetBus, 'emit'> | undefined;
|
|
16
|
+
hostEvents?: Pick<EventBus, 'emit'> | undefined;
|
|
17
|
+
}
|
|
18
|
+
export declare function publishAcpLiveProgress(opts: PublishAcpLiveProgressOpts): void;
|
|
19
|
+
//# sourceMappingURL=acp-live-progress.d.ts.map
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { SubagentRunner } from '@wrongstack/core/types';
|
|
2
|
+
import { type BuildAcpSubagentRunnerOptions } from './host-acp.js';
|
|
2
3
|
export declare class HostAcpRunnerCache {
|
|
3
4
|
private readonly maxEntries;
|
|
5
|
+
private readonly resolveOpts?;
|
|
4
6
|
private readonly runners;
|
|
5
7
|
private readonly accessOrder;
|
|
6
|
-
constructor(maxEntries?: number);
|
|
8
|
+
constructor(maxEntries?: number, resolveOpts?: (() => BuildAcpSubagentRunnerOptions | undefined) | undefined);
|
|
7
9
|
get(subagentId: string): Promise<SubagentRunner>;
|
|
8
10
|
}
|
|
9
11
|
//# sourceMappingURL=host-acp-runner-cache.d.ts.map
|
package/dist/fleet/host-acp.d.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
-
import type
|
|
2
|
-
|
|
1
|
+
import { type ACPProgressEvent, type AcpAgentCommandOverrides, type AcpLiveCatalog } from '@wrongstack/acp';
|
|
2
|
+
import type { SubagentRunContext, SubagentRunner, TaskSpec } from '@wrongstack/core/types';
|
|
3
|
+
export type AcpLivePublisher = (ctx: SubagentRunContext, task: TaskSpec, event: ACPProgressEvent) => void;
|
|
4
|
+
export interface BuildAcpSubagentRunnerOptions {
|
|
5
|
+
overrides?: AcpAgentCommandOverrides | undefined;
|
|
6
|
+
live?: AcpLiveCatalog | undefined;
|
|
7
|
+
publishLive?: AcpLivePublisher | undefined;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Same command resolution as `wstack acp spawn` / `/acp` — user override,
|
|
11
|
+
* bundled catalog, synced registry, then the legacy map. Director / `--bg`
|
|
12
|
+
* must not use a different argv than the CLI spawn path.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildAcpSubagentRunner(subagentId: string, options?: BuildAcpSubagentRunnerOptions): Promise<SubagentRunner>;
|
|
3
15
|
//# sourceMappingURL=host-acp.d.ts.map
|
package/dist/fleet/host.d.ts
CHANGED
|
@@ -120,6 +120,7 @@ export declare class MultiAgentHost {
|
|
|
120
120
|
*/
|
|
121
121
|
buildSubagentRunner(config: Config): Promise<SubagentRunner>;
|
|
122
122
|
buildACPRunner(subagentId: string): Promise<SubagentRunner>;
|
|
123
|
+
private acpCommandOpts;
|
|
123
124
|
spawnACP(subagentId: string, task: string, config: Config): Promise<string>;
|
|
124
125
|
private filterTools;
|
|
125
126
|
private mailboxProjectDir;
|
|
@@ -2,8 +2,15 @@ import {
|
|
|
2
2
|
parseTokenTtlValue
|
|
3
3
|
} from "./chunk-UZ2TMHNH.js";
|
|
4
4
|
import {
|
|
5
|
+
resolveHqPasswordInput
|
|
6
|
+
} from "./chunk-AUQDGU5D.js";
|
|
7
|
+
import {
|
|
8
|
+
normalizeHqPublicOrigin,
|
|
5
9
|
resolveAuditActor
|
|
6
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-I7V2OYVH.js";
|
|
11
|
+
import {
|
|
12
|
+
parseHqIpAllowlist
|
|
13
|
+
} from "./chunk-Q7E3BPDU.js";
|
|
7
14
|
|
|
8
15
|
// src/subcommands/handlers/hq.ts
|
|
9
16
|
import * as fs from "node:fs/promises";
|
|
@@ -14,6 +21,7 @@ import {
|
|
|
14
21
|
hqAuthAuditPath,
|
|
15
22
|
hqAuthContentHash,
|
|
16
23
|
hqAuthFilePath,
|
|
24
|
+
isLoopbackHost,
|
|
17
25
|
logHqAuthAudit,
|
|
18
26
|
mintHqToken,
|
|
19
27
|
mutateHqAuthFile,
|
|
@@ -40,6 +48,10 @@ var hqCmd = async (args, deps) => {
|
|
|
40
48
|
if (sub === "audit") {
|
|
41
49
|
return hqAuditCmd(args.slice(1), deps);
|
|
42
50
|
}
|
|
51
|
+
if (sub === "service") {
|
|
52
|
+
const { hqServiceCmd } = await import("./hq-service-L5INQFM4.js");
|
|
53
|
+
return hqServiceCmd(args.slice(1), deps);
|
|
54
|
+
}
|
|
43
55
|
if (sub === "help" || sub === "--help") {
|
|
44
56
|
printHelp(deps);
|
|
45
57
|
return 0;
|
|
@@ -50,15 +62,53 @@ var hqCmd = async (args, deps) => {
|
|
|
50
62
|
return 1;
|
|
51
63
|
};
|
|
52
64
|
async function startServer(deps) {
|
|
53
|
-
const { startHqServer } = await import("./hq-server-
|
|
65
|
+
const { startHqServer } = await import("./hq-server-CNUTBWTK.js");
|
|
54
66
|
const dataDir = resolveDataDir(deps);
|
|
55
67
|
const flags = deps.flags ?? {};
|
|
56
|
-
const
|
|
68
|
+
const rawPublicUrl = typeof flags["hq-public-url"] === "string" ? flags["hq-public-url"] : process.env.WRONGSTACK_HQ_PUBLIC_URL;
|
|
69
|
+
let publicOrigin;
|
|
70
|
+
if (rawPublicUrl !== void 0 && rawPublicUrl.trim() !== "") {
|
|
71
|
+
try {
|
|
72
|
+
publicOrigin = normalizeHqPublicOrigin(rawPublicUrl);
|
|
73
|
+
} catch (cause) {
|
|
74
|
+
deps.renderer.writeError(`${cause instanceof Error ? cause.message : String(cause)}
|
|
75
|
+
`);
|
|
76
|
+
return 1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const host = typeof flags["host"] === "string" ? flags["host"] : publicOrigin !== void 0 ? "127.0.0.1" : HQ_CLI_DEFAULT_HOST;
|
|
57
80
|
const port = typeof flags["port"] === "string" ? Number.parseInt(flags["port"], 10) : 3499;
|
|
81
|
+
if (publicOrigin !== void 0 && !isLoopbackHost(host)) {
|
|
82
|
+
deps.renderer.writeError(
|
|
83
|
+
"Persistent public HQ requires a loopback bind. Remove --host or use --host 127.0.0.1.\n"
|
|
84
|
+
);
|
|
85
|
+
return 1;
|
|
86
|
+
}
|
|
58
87
|
const strictPort = flags["strict-port"] === true;
|
|
59
88
|
const open = flags["open"] === true;
|
|
60
|
-
|
|
89
|
+
let password;
|
|
90
|
+
try {
|
|
91
|
+
password = await resolveHqPasswordInput({
|
|
92
|
+
...typeof flags["password"] === "string" ? { explicitPassword: flags["password"] } : {}
|
|
93
|
+
});
|
|
94
|
+
} catch (cause) {
|
|
95
|
+
deps.renderer.writeError(`${cause instanceof Error ? cause.message : String(cause)}
|
|
96
|
+
`);
|
|
97
|
+
return 1;
|
|
98
|
+
}
|
|
99
|
+
const bootstrapPasswordOnly = /^(?:1|true)$/i.test(
|
|
100
|
+
process.env.WRONGSTACK_HQ_BOOTSTRAP_PASSWORD_ONLY?.trim() ?? ""
|
|
101
|
+
);
|
|
61
102
|
const allowInsecureOpen = flags["insecure-open"] === true;
|
|
103
|
+
const rawAllowlist = typeof flags["hq-allowlist"] === "string" ? flags["hq-allowlist"] : process.env.WRONGSTACK_HQ_ALLOWLIST;
|
|
104
|
+
let ipAllowlist;
|
|
105
|
+
try {
|
|
106
|
+
ipAllowlist = parseHqIpAllowlist(rawAllowlist);
|
|
107
|
+
} catch (cause) {
|
|
108
|
+
deps.renderer.writeError(`${cause instanceof Error ? cause.message : String(cause)}
|
|
109
|
+
`);
|
|
110
|
+
return 1;
|
|
111
|
+
}
|
|
62
112
|
const rawTtl = typeof flags["hq-token-ttl"] === "string" ? flags["hq-token-ttl"] : void 0;
|
|
63
113
|
let tokenTtlMs;
|
|
64
114
|
if (rawTtl !== void 0 && rawTtl.length > 0) {
|
|
@@ -94,9 +144,13 @@ async function startServer(deps) {
|
|
|
94
144
|
strictPort,
|
|
95
145
|
dataDir,
|
|
96
146
|
allowInsecureOpen,
|
|
147
|
+
secureCookies: publicOrigin !== void 0,
|
|
148
|
+
requireBrowserAuth: publicOrigin !== void 0,
|
|
97
149
|
...password !== void 0 ? { password } : {},
|
|
150
|
+
...bootstrapPasswordOnly ? { bootstrapPasswordOnly: true } : {},
|
|
98
151
|
...tokenTtlMs !== void 0 ? { tokenTtlMs } : {},
|
|
99
|
-
...trustedProxyHops !== void 0 ? { trustedProxyHops } : {}
|
|
152
|
+
...trustedProxyHops !== void 0 ? { trustedProxyHops } : {},
|
|
153
|
+
...ipAllowlist !== void 0 ? { ipAllowlist } : {}
|
|
100
154
|
});
|
|
101
155
|
} catch (err) {
|
|
102
156
|
if (err instanceof HqInsecureExposureError) {
|
|
@@ -106,14 +160,34 @@ async function startServer(deps) {
|
|
|
106
160
|
}
|
|
107
161
|
throw err;
|
|
108
162
|
}
|
|
163
|
+
if (publicOrigin !== void 0) {
|
|
164
|
+
if (handle.firstRunSetup?.passwordMode !== true) {
|
|
165
|
+
await handle.close();
|
|
166
|
+
deps.renderer.writeError(
|
|
167
|
+
"Persistent public HQ requires password mode. Set WRONGSTACK_HQ_PASSWORD and retry.\n"
|
|
168
|
+
);
|
|
169
|
+
return 1;
|
|
170
|
+
}
|
|
171
|
+
handle.trustPublicOrigin(publicOrigin);
|
|
172
|
+
deps.renderer.write(`Public endpoint: ${publicOrigin}/
|
|
173
|
+
`);
|
|
174
|
+
deps.renderer.write(`Public mobile: ${publicOrigin}/mobile
|
|
175
|
+
`);
|
|
176
|
+
}
|
|
109
177
|
if (open) {
|
|
110
178
|
try {
|
|
111
179
|
const { openBrowser } = await import("@wrongstack/webui-server");
|
|
112
|
-
openBrowser(
|
|
180
|
+
openBrowser(
|
|
181
|
+
publicOrigin ?? handle.firstRunSetup?.browserUrl ?? `http://${handle.host}:${handle.port}`
|
|
182
|
+
);
|
|
113
183
|
} catch {
|
|
114
184
|
}
|
|
115
185
|
}
|
|
116
186
|
writeStartupInfo(deps, handle);
|
|
187
|
+
deps.renderer.write(
|
|
188
|
+
ipAllowlist === void 0 ? "Network allowlist: disabled (authentication remains required when configured).\n" : `Network allowlist: active (${ipAllowlist.length} configured rule${ipAllowlist.length === 1 ? "" : "s"} + loopback).
|
|
189
|
+
`
|
|
190
|
+
);
|
|
117
191
|
await new Promise((resolve) => {
|
|
118
192
|
const shutdown = async () => {
|
|
119
193
|
try {
|
|
@@ -137,9 +211,34 @@ function writeStartupInfo(deps, handle) {
|
|
|
137
211
|
`);
|
|
138
212
|
deps.renderer.write(`Browser endpoint: http://${handle.host}:${handle.port}
|
|
139
213
|
`);
|
|
214
|
+
deps.renderer.write(
|
|
215
|
+
`Mobile endpoint: http://${handle.host}:${handle.port}/mobile (password required)
|
|
216
|
+
`
|
|
217
|
+
);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (process.env.WRONGSTACK_HQ_SUPPRESS_STARTUP_SECRETS === "1") {
|
|
221
|
+
deps.renderer.write(`Browser endpoint: http://${handle.host}:${handle.port}
|
|
222
|
+
`);
|
|
223
|
+
deps.renderer.write(
|
|
224
|
+
`Mobile endpoint: http://${handle.host}:${handle.port}/mobile (password required)
|
|
225
|
+
`
|
|
226
|
+
);
|
|
227
|
+
deps.renderer.write(`Client endpoint: ws://${handle.host}:${handle.port}/ws/client
|
|
228
|
+
`);
|
|
229
|
+
deps.renderer.write(
|
|
230
|
+
`Startup credentials suppressed; auth state is stored in ${handle.firstRunSetup.dataDir}.
|
|
231
|
+
`
|
|
232
|
+
);
|
|
140
233
|
return;
|
|
141
234
|
}
|
|
235
|
+
const mobileUrl = new URL(handle.firstRunSetup.browserUrl);
|
|
236
|
+
mobileUrl.pathname = "/mobile";
|
|
237
|
+
mobileUrl.search = "";
|
|
238
|
+
mobileUrl.hash = "";
|
|
142
239
|
deps.renderer.write(`Browser endpoint: ${handle.firstRunSetup.browserUrl}
|
|
240
|
+
`);
|
|
241
|
+
deps.renderer.write(`Mobile endpoint: ${mobileUrl.toString()} (password required)
|
|
143
242
|
`);
|
|
144
243
|
deps.renderer.write(`Client endpoint: ${handle.firstRunSetup.clientUrl}
|
|
145
244
|
`);
|
|
@@ -537,7 +636,7 @@ async function tokenRevoke(args, deps) {
|
|
|
537
636
|
return 0;
|
|
538
637
|
}
|
|
539
638
|
function printHelp(deps) {
|
|
540
|
-
deps.renderer.write(`Usage: wstack hq <serve | token | audit>
|
|
639
|
+
deps.renderer.write(`Usage: wstack hq <serve | token | audit | service>
|
|
541
640
|
`);
|
|
542
641
|
deps.renderer.write("\n");
|
|
543
642
|
deps.renderer.write(` wstack hq Start the HQ command center server.
|
|
@@ -564,6 +663,18 @@ function printHelp(deps) {
|
|
|
564
663
|
`);
|
|
565
664
|
deps.renderer.write(
|
|
566
665
|
` wstack hq audit verify Re-derive auth.json contentHash for forensic comparison.
|
|
666
|
+
`
|
|
667
|
+
);
|
|
668
|
+
deps.renderer.write(
|
|
669
|
+
` wstack hq service install Install persistent Ubuntu/systemd service + updater timer.
|
|
670
|
+
`
|
|
671
|
+
);
|
|
672
|
+
deps.renderer.write(` wstack hq service status Show service and updater status.
|
|
673
|
+
`);
|
|
674
|
+
deps.renderer.write(` wstack hq service update Run the guarded update job now.
|
|
675
|
+
`);
|
|
676
|
+
deps.renderer.write(
|
|
677
|
+
` wstack hq service uninstall Remove units but preserve HQ data and secret file.
|
|
567
678
|
`
|
|
568
679
|
);
|
|
569
680
|
deps.renderer.write("\n");
|
|
@@ -579,6 +690,10 @@ function printHelp(deps) {
|
|
|
579
690
|
);
|
|
580
691
|
deps.renderer.write(
|
|
581
692
|
` --tunnel Publish a temporary *.trycloudflare.com URL (requires cloudflared).
|
|
693
|
+
`
|
|
694
|
+
);
|
|
695
|
+
deps.renderer.write(
|
|
696
|
+
` --hq-public-url <https-origin> Trust a persistent TLS reverse-proxy origin; binds loopback and requires password mode.
|
|
582
697
|
`
|
|
583
698
|
);
|
|
584
699
|
deps.renderer.write(` --password <value> Set or rotate the browser login password.
|
|
@@ -599,6 +714,10 @@ function printHelp(deps) {
|
|
|
599
714
|
` --hq-trusted-proxy-hops <n> Trust the rightmost n X-Forwarded-For entries when rate-limiting logins.
|
|
600
715
|
Default 0 (ignore the header). Set to the real hop count behind a tunnel,
|
|
601
716
|
otherwise every user shares one backoff bucket. Never guess high.
|
|
717
|
+
`
|
|
718
|
+
);
|
|
719
|
+
deps.renderer.write(
|
|
720
|
+
` --hq-allowlist <csv> Optional source IP/CIDR allowlist (for example 203.0.113.4,10.0.0.0/8).
|
|
602
721
|
`
|
|
603
722
|
);
|
|
604
723
|
deps.renderer.write(` --open Open the dashboard in the default browser.
|
|
@@ -708,4 +827,4 @@ export {
|
|
|
708
827
|
hqCmd,
|
|
709
828
|
resolveAuditActor
|
|
710
829
|
};
|
|
711
|
-
//# sourceMappingURL=hq-
|
|
830
|
+
//# sourceMappingURL=hq-5XHEIIH6.js.map
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* (`director`, the rebound `interruptLeader`) are not yet defined at HQ-connect
|
|
7
7
|
* time.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* project mailbox
|
|
9
|
+
* Conversational commands route through the agent's own decision loop or the
|
|
10
|
+
* project mailbox; Kanban commands route through its project IPC owner, so
|
|
11
|
+
* both inherit existing guardrails. `run-command` (raw
|
|
11
12
|
* shell) is deliberately NOT wired here — it requires a separately-audited
|
|
12
13
|
* escalation policy (operator flag + per-token `control.execute` + allowlist)
|
|
13
14
|
* and is left as a stub that rejects until that policy exists.
|
|
@@ -67,7 +68,35 @@ export interface HqCommandController {
|
|
|
67
68
|
ownsSession?: ((sessionId: string) => boolean) | undefined;
|
|
68
69
|
/** Whether raw shell execution is explicitly opted-in by the operator. */
|
|
69
70
|
allowRunCommand: () => boolean;
|
|
71
|
+
/** Apply a lifecycle transition through the project's Kanban IPC client. */
|
|
72
|
+
kanbanTransition?: ((input: {
|
|
73
|
+
boardId: string;
|
|
74
|
+
taskId: string;
|
|
75
|
+
to: 'backlog' | 'todo' | 'running' | 'review' | 'done';
|
|
76
|
+
comment: string;
|
|
77
|
+
sessionId?: string | undefined;
|
|
78
|
+
}) => Promise<string>) | undefined;
|
|
79
|
+
/** Assign a card through the project owner while preserving active leases. */
|
|
80
|
+
kanbanAssign?: ((input: {
|
|
81
|
+
boardId: string;
|
|
82
|
+
taskId: string;
|
|
83
|
+
agentId: string;
|
|
84
|
+
assignee: string;
|
|
85
|
+
comment: string;
|
|
86
|
+
sessionId?: string | undefined;
|
|
87
|
+
}) => Promise<string>) | undefined;
|
|
88
|
+
/** Claim and dispatch one ready card through this host's canonical Director path. */
|
|
89
|
+
kanbanDispatch?: ((input: {
|
|
90
|
+
boardId: string;
|
|
91
|
+
taskId: string;
|
|
92
|
+
comment: string;
|
|
93
|
+
sessionId?: string | undefined;
|
|
94
|
+
}) => Promise<string>) | undefined;
|
|
70
95
|
}
|
|
96
|
+
/** Bind HQ transitions to the same project-scoped IPC path every other client uses. */
|
|
97
|
+
export declare function createProjectKanbanTransitionHandler(projectRoot: string): NonNullable<HqCommandController['kanbanTransition']>;
|
|
98
|
+
/** Bind guarded HQ assignment to the canonical project-scoped Kanban owner. */
|
|
99
|
+
export declare function createProjectKanbanAssignHandler(projectRoot: string): NonNullable<HqCommandController['kanbanAssign']>;
|
|
71
100
|
/**
|
|
72
101
|
* Build the `onCommand` handler for an HQ publisher. The handler validates
|
|
73
102
|
* the command, dispatches through the controller, and returns an ack result
|
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
* @module hq-server/client-address
|
|
36
36
|
*/
|
|
37
37
|
import type * as http from 'node:http';
|
|
38
|
+
/** The actual TCP peer, with IPv4-mapped IPv6 normalized. Never reads headers. */
|
|
39
|
+
export declare function resolveSocketAddress(req: http.IncomingMessage): string | undefined;
|
|
38
40
|
/**
|
|
39
41
|
* Parse one `X-Forwarded-For` element into a bare address, or `undefined` when
|
|
40
42
|
* it is not one. Handles `1.2.3.4`, `1.2.3.4:5678`, `[::1]`, and `[::1]:5678`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface HqIpAllowlist {
|
|
2
|
+
readonly entries: readonly string[];
|
|
3
|
+
allows(address: string | undefined): boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Build the optional HQ admission allowlist.
|
|
7
|
+
*
|
|
8
|
+
* Matching is intentionally performed against the TCP peer, never a forwarded
|
|
9
|
+
* header. When HQ is directly reachable on 0.0.0.0, trusting a client-supplied
|
|
10
|
+
* X-Forwarded-For value here would turn the allowlist into a bypass. Loopback
|
|
11
|
+
* remains implicit so local administration and health checks cannot be locked
|
|
12
|
+
* out by a remote-only list.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createHqIpAllowlist(rules: readonly string[] | undefined): HqIpAllowlist | undefined;
|
|
15
|
+
export declare function parseHqIpAllowlist(value: string | undefined): string[] | undefined;
|
|
16
|
+
//# sourceMappingURL=ip-allowlist.d.ts.map
|