@wrongstack/cli 1.0.19 → 1.0.26
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 +44 -0
- package/dist/{acp-INCNOH42.js → acp-LI665LO2.js} +18 -7
- package/dist/arg-parser.d.ts +1 -0
- package/dist/ascii-mode-SG4PRNLP.js +7 -0
- package/dist/{auth-YXK3EDUL.js → auth-TE55JF4Z.js} +68 -22
- package/dist/auth-menu/direct.d.ts +1 -0
- package/dist/auth-menu/local.d.ts +2 -0
- package/dist/auth-menu/oauth-menu.d.ts +3 -1
- package/dist/auth-menu/panel-service.d.ts +20 -0
- package/dist/{bench-YBU6BVQP.js → bench-GTLPM22B.js} +2 -2
- package/dist/boot/append-system-prompt.d.ts +10 -0
- package/dist/boot/ascii-mode.d.ts +12 -0
- package/dist/boot/config-backup-recovery.d.ts +2 -1
- package/dist/boot/container-wiring.d.ts +4 -2
- package/dist/boot/dispatch-singleshot.d.ts +4 -1
- package/dist/boot/dispatch-webui.d.ts +11 -0
- package/dist/boot/mcp-config-flag.d.ts +22 -0
- package/dist/boot/piped-stdin.d.ts +40 -0
- package/dist/boot/restricted-mode.d.ts +15 -0
- package/dist/boot/safe-mode.d.ts +30 -0
- package/dist/boot/short-circuit-desktop.d.ts +1 -0
- package/dist/boot/single-shot-budget.d.ts +30 -0
- package/dist/boot/stream-json.d.ts +36 -0
- package/dist/boot/structured-output.d.ts +16 -0
- package/dist/boot/system-prompt-builder.d.ts +2 -0
- package/dist/boot/tool-restriction-flags.d.ts +36 -0
- package/dist/boot/tui-project-picker-callback.d.ts +1 -1
- package/dist/boot/tui-settings-adapter.d.ts +15 -2
- package/dist/boot/worktree-sessions.d.ts +21 -0
- package/dist/{boot-auto-thin-MANHOYHE.js → boot-auto-thin-6Q56FY3F.js} +3 -2
- package/dist/boot-provider-selection.d.ts +67 -0
- package/dist/boot.d.ts +1 -38
- package/dist/{chunk-JY52HWL6.js → chunk-2EBVTYJR.js} +2 -2
- package/dist/{chunk-RDHFXOJM.js → chunk-2ERX3RPN.js} +112 -65
- package/dist/chunk-4TVYGG6G.js +62 -0
- package/dist/chunk-5JYDKG5B.js +154 -0
- package/dist/{chunk-KEPABQYT.js → chunk-5SEYGOCH.js} +8 -82
- package/dist/{chunk-3VXYY5JC.js → chunk-5UZBUV2H.js} +3 -19
- package/dist/chunk-BBHWW6LR.js +549 -0
- package/dist/chunk-BEHGRNOQ.js +58 -0
- package/dist/chunk-CZTXF6HY.js +140 -0
- package/dist/{chunk-JX6KL7OF.js → chunk-EPR42SWM.js} +39 -8
- package/dist/chunk-F5DCFAKI.js +36 -0
- package/dist/chunk-HLSHFXTO.js +97 -0
- package/dist/{chunk-CJTBLTS4.js → chunk-KJS5543T.js} +4 -3
- package/dist/{chunk-DE7BZDNK.js → chunk-KOEO4CJG.js} +27 -4
- package/dist/{chunk-SIS37L3W.js → chunk-L2RVEQWO.js} +211 -193
- package/dist/chunk-LBPLTTZ6.js +105 -0
- package/dist/chunk-LDCGZJTC.js +46 -0
- package/dist/chunk-LKPEBZBE.js +143 -0
- package/dist/chunk-LUMETJFO.js +171 -0
- package/dist/{chunk-KK2LB3ZS.js → chunk-OAVBM55Q.js} +9 -5
- package/dist/chunk-PZQBGUVZ.js +18 -0
- package/dist/{chunk-C3Z4N6A6.js → chunk-Q4INH2DG.js} +51 -3
- package/dist/chunk-R4QGL6GB.js +10 -0
- package/dist/{chunk-YLQEGYV4.js → chunk-RZ4ZDRYA.js} +14 -4
- package/dist/chunk-S4FFHDJG.js +93 -0
- package/dist/chunk-SFBFYIOW.js +271 -0
- package/dist/{chunk-RMQNCHGO.js → chunk-TI7KLHYX.js} +136 -11
- package/dist/{chunk-2ENZU66X.js → chunk-WQV2NP57.js} +5 -5
- package/dist/{chunk-B4JLSXZB.js → chunk-WSTVGC2C.js} +73 -45
- package/dist/chunk-X756ZS72.js +329 -0
- package/dist/{chunk-XJ7K67PP.js → chunk-YHYINL47.js} +63 -24
- package/dist/{chunk-2VMJ3E5Z.js → chunk-YTEOAWOJ.js} +6 -2
- package/dist/{chunk-GPPRNAKW.js → chunk-ZMX5HRLI.js} +2 -2
- package/dist/{cli-context-33F74CSZ.js → cli-context-UVGAN3NO.js} +496 -384
- package/dist/cli-entry-point.d.ts +2 -0
- package/dist/{cli-main-FNGMKPBA.js → cli-main-TN3KZ2P6.js} +3561 -2724
- package/dist/cli-update-notice.d.ts +2 -1
- package/dist/config-doctor.d.ts +10 -2
- package/dist/{config-transfer-2YF3CRTN.js → config-transfer-RUWLDCNK.js} +34 -13
- package/dist/{diag-doctor-ANPRUYFM.js → diag-doctor-BIZAFIAT.js} +2 -2
- package/dist/execute-deps.d.ts +2 -1
- package/dist/{execution-A6WJLSOC.js → execution-7QIP6GRY.js} +2384 -2055
- package/dist/fleet/host-types.d.ts +3 -1
- package/dist/goal-commands.d.ts +47 -0
- package/dist/goal-host.d.ts +1 -14
- package/dist/{hq-XQWQTRDA.js → hq-GLZ7QESM.js} +277 -261
- package/dist/hq-command-controller.d.ts +1 -1
- package/dist/{hq-server-IIBZQZU4.js → hq-server-YTKDVQPY.js} +2 -2
- package/dist/{hq-service-L5INQFM4.js → hq-service-BMMJAHRT.js} +11 -4
- package/dist/import-claude-code-32PCSIQI.js +236 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +19 -10
- package/dist/kanban-supervisor-67ECABTD.js +7 -0
- package/dist/live-settings-input.d.ts +7 -0
- package/dist/{mailbox-serve-3GFOK2I7.js → mailbox-serve-NW5VZG7R.js} +3 -3
- package/dist/{mcp-DC5WSBOO.js → mcp-LBS45HWZ.js} +4 -4
- package/dist/modeldiag-36VODVIH.js +828 -0
- package/dist/{per-subcommand-help-DHTYU524.js → per-subcommand-help-QDAQASPZ.js} +3 -3
- package/dist/permission-prompt-mirror.d.ts +1 -1
- package/dist/permission-prompt.d.ts +16 -2
- package/dist/permission-rules-view.d.ts +18 -0
- package/dist/{permissions-CFDLXETM.js → permissions-PL27UHYD.js} +67 -45
- package/dist/plugin-config.d.ts +12 -0
- package/dist/plugin-management-types.d.ts +31 -0
- package/dist/plugin-management.d.ts +2 -30
- package/dist/plugin-package-install.d.ts +3 -0
- package/dist/{plugin-usage-M6KET4OZ.js → plugin-usage-CIGOOTX3.js} +6 -5
- package/dist/{plugins-WJLW6ULV.js → plugins-HQTXUD6A.js} +6 -3
- package/dist/preflight.d.ts +1 -1
- package/dist/{projects-LMNAGGEU.js → projects-T4CZCA25.js} +3 -6
- package/dist/provider-config-utils.d.ts +1 -6
- package/dist/provider-helpers.d.ts +7 -11
- package/dist/{providers-models-LFNZ5WI7.js → providers-models-5Z2PJTEW.js} +44 -34
- package/dist/release-asset-download.d.ts +13 -0
- package/dist/release-attestation.d.ts +28 -0
- package/dist/remote/remote-session.d.ts +64 -0
- package/dist/remote/remote-target.d.ts +69 -0
- package/dist/remote-O5WXHLWV.js +561 -0
- package/dist/{replay-Z3FTJEMM.js → replay-DEI566CW.js} +2 -2
- package/dist/services/commit-message.d.ts +2 -1
- package/dist/services/dispatch-classifier.d.ts +39 -5
- package/dist/session-move-P2EC2COA.js +44 -0
- package/dist/session-move.d.ts +20 -0
- package/dist/session-stats.d.ts +10 -0
- package/dist/{sessions-config-UL45XKX7.js → sessions-config-SXTTLNXA.js} +47 -9
- package/dist/settings-menu.d.ts +2 -0
- package/dist/short-circuit-flags-74Y5N6CF.js +10 -0
- package/dist/{simpleui-dist-CXSIDAXZ.js → simpleui-dist-7BQISSEP.js} +7 -3
- package/dist/skill-suggest-L2EVWB6R.js +290 -0
- package/dist/slash-commands/command-context.d.ts +15 -5
- package/dist/slash-commands/effort.d.ts +1 -1
- package/dist/slash-commands/fallback.d.ts +1 -1
- package/dist/slash-commands/gitid.d.ts +1 -1
- package/dist/slash-commands/goal-refiner.d.ts +4 -49
- package/dist/slash-commands/jev.d.ts +4 -0
- package/dist/slash-commands/mcp.d.ts +2 -1
- package/dist/slash-commands/openai-quota.d.ts +15 -0
- package/dist/slash-commands/permissions.d.ts +4 -0
- package/dist/slash-commands/sdd-task-mutations.d.ts +4 -0
- package/dist/slash-commands/settings-context-mutations.d.ts +5 -0
- package/dist/slash-commands/settings-keys.d.ts +2 -0
- package/dist/slash-commands/settings-limits-mutations.d.ts +12 -0
- package/dist/slash-commands/settings-reset.d.ts +6 -0
- package/dist/standalone-auto-update-TOTRGCSA.js +249 -0
- package/dist/standalone-auto-update.d.ts +65 -0
- package/dist/standalone-update-LZO3MNLH.js +24 -0
- package/dist/standalone-update.d.ts +55 -0
- package/dist/subcommands/handlers/hq-alerts.d.ts +3 -0
- package/dist/subcommands/handlers/hq-audit.d.ts +46 -0
- package/dist/subcommands/handlers/hq-data-dir.d.ts +13 -0
- package/dist/subcommands/handlers/import-claude-code.d.ts +42 -0
- package/dist/subcommands/handlers/permissions.d.ts +9 -3
- package/dist/subcommands/handlers/remote.d.ts +6 -0
- package/dist/subcommands/handlers/skill-suggest.d.ts +21 -0
- package/dist/subcommands/handlers/typesafe-brain-replay.d.ts +26 -0
- package/dist/subcommands/handlers/typesafe-judgment-check.d.ts +3 -0
- package/dist/subcommands/handlers/typesafe-topic-replay.d.ts +19 -0
- package/dist/subcommands/handlers/typesafe-triage-replay.d.ts +18 -0
- package/dist/subcommands/handlers/typesafe.d.ts +23 -0
- package/dist/subcommands/handlers/version-help.d.ts +5 -0
- package/dist/{subcommands-XSLXMIDP.js → subcommands-Q6ORSB2E.js} +2 -2
- package/dist/tui-resume-callback.d.ts +18 -0
- package/dist/typesafe-U7YB2RRV.js +316 -0
- package/dist/typesafe-brain-replay-C5276FVR.js +222 -0
- package/dist/typesafe-judgment-check-GGYYV5UF.js +29 -0
- package/dist/typesafe-topic-replay-ZILIU3WS.js +234 -0
- package/dist/typesafe-triage-replay-FGAW7QM7.js +215 -0
- package/dist/{update-5DPB4YD4.js → update-TDZX4IL2.js} +4 -3
- package/dist/{update-check-BS3DHTSI.js → update-check-J5ZVKS73.js} +3 -2
- package/dist/update-check.d.ts +1 -1
- package/dist/version-JB2UAV2A.js +11 -0
- package/dist/version-help-XJJQ7YSH.js +10 -0
- package/dist/version.d.ts +3 -2
- package/dist/webui-client-observability.d.ts +7 -0
- package/dist/webui-server/route-contexts.d.ts +1 -1
- package/dist/webui-server/session-start-payload.d.ts +5 -1
- package/dist/{webui-server-MRPGTTKL.js → webui-server-YTHLRFD2.js} +577 -370
- package/dist/webui-server-lifecycle.d.ts +57 -0
- package/dist/webui-server-options.d.ts +11 -0
- package/dist/webui-server.d.ts +1 -1
- package/dist/wiring/brain-and-orchestration.d.ts +3 -1
- package/dist/wiring/cli-prompt-and-tools-setup.d.ts +9 -0
- package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
- package/dist/wiring/domain-glossary.d.ts +5 -4
- package/dist/wiring/lifecycle-plugins.d.ts +4 -2
- package/dist/wiring/metrics.d.ts +9 -1
- package/dist/wiring/pipeline.d.ts +2 -7
- package/dist/wiring/plugins.d.ts +4 -1
- package/dist/wiring/provider-persisters.d.ts +24 -0
- package/dist/wiring/provider-runtime.d.ts +9 -1
- package/dist/wiring/provider-status.d.ts +1 -0
- package/dist/wiring/provider-utility-tools.d.ts +3 -1
- package/dist/wiring/runtime-dispatch-state.d.ts +3 -1
- package/package.json +28 -28
- package/dist/chunk-2CZEORLV.js +0 -54
- package/dist/chunk-672UXYL3.js +0 -65
- package/dist/chunk-6WRKAACA.js +0 -96
- package/dist/chunk-DR2OXU46.js +0 -174
- package/dist/chunk-JACOMTIH.js +0 -275
- package/dist/chunk-XJXDOF63.js +0 -28
- package/dist/modeldiag-CJSFHZ3J.js +0 -1356
- package/dist/short-circuit-flags-7GQIGMVD.js +0 -10
- package/dist/version-help-WXI42PZ3.js +0 -10
|
@@ -3,7 +3,7 @@ import type { BrainArbiter, ProviderModelStatusTracker } from '@wrongstack/core/
|
|
|
3
3
|
import type { HookRunner } from '@wrongstack/core/hooks';
|
|
4
4
|
import type { Container, EventBus } from '@wrongstack/core/kernel';
|
|
5
5
|
import type { ProviderRegistry, ToolRegistry } from '@wrongstack/core/registry';
|
|
6
|
-
import type { ConfigStore, ModelsRegistry, Renderer, SecretScrubber, SessionWriter, SkillLoader, SystemPromptBuilder, TokenCounter } from '@wrongstack/core/types';
|
|
6
|
+
import type { ConfigStore, ModelsRegistry, Renderer, SecretScrubber, SessionWriter, SkillLoader, SystemPromptBuilder, TokenCounter, Tracer } from '@wrongstack/core/types';
|
|
7
7
|
export interface MultiAgentDeps {
|
|
8
8
|
container: Container;
|
|
9
9
|
toolRegistry: ToolRegistry;
|
|
@@ -23,6 +23,8 @@ export interface MultiAgentDeps {
|
|
|
23
23
|
projectRoot: string;
|
|
24
24
|
cwd: string;
|
|
25
25
|
secretScrubber: SecretScrubber;
|
|
26
|
+
/** OTLP tracer shared with the leader, so worker runs join its traces. */
|
|
27
|
+
tracer?: Tracer | undefined;
|
|
26
28
|
/** Loader used to resolve the roster's per-role skill names. */
|
|
27
29
|
skillLoader?: SkillLoader | undefined;
|
|
28
30
|
renderer?: Renderer | undefined;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** Async `fs.access`-style existence check — never throws. */
|
|
2
|
+
export declare function pathExists(p: string): Promise<boolean>;
|
|
3
|
+
/**
|
|
4
|
+
* Cap on captured command output. Verification commands (`pnpm test` across
|
|
5
|
+
* a large monorepo) can emit tens of MB on a verbose run — accumulating the
|
|
6
|
+
* full transcript spikes the host heap for output nothing ever reads in
|
|
7
|
+
* full. runCmd keeps the TAIL (the failure summary lives at the end of a
|
|
8
|
+
* test run); gitText keeps the head (its commands are tiny).
|
|
9
|
+
*/
|
|
10
|
+
export declare const MAX_CMD_OUTPUT = 200000;
|
|
11
|
+
/** Run a git command, returning trimmed stdout (empty string on failure). */
|
|
12
|
+
export declare function gitText(args: string[], cwd: string): Promise<{
|
|
13
|
+
code: number;
|
|
14
|
+
out: string;
|
|
15
|
+
}>;
|
|
16
|
+
export declare function isGitRepo(cwd: string): Promise<boolean>;
|
|
17
|
+
export declare const GOAL_BASE_SAFE_CMDS: ReadonlySet<string>;
|
|
18
|
+
export declare let goalAllowed: Set<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Extend/trim the autonomous goal command allowlist from the user's exec
|
|
21
|
+
* policy. Mirrors `configureExecPolicy` but keeps goal's narrower base.
|
|
22
|
+
* Idempotent (always rebuilt from the base).
|
|
23
|
+
*/
|
|
24
|
+
export declare function configureGoalPolicy(opts?: {
|
|
25
|
+
allow?: readonly string[] | undefined;
|
|
26
|
+
deny?: readonly string[] | undefined;
|
|
27
|
+
}): void;
|
|
28
|
+
/** Reset the goal allowlist to its built-in base (tests / re-init). */
|
|
29
|
+
export declare function resetGoalPolicy(): void;
|
|
30
|
+
/** Whether `cmd` may run in autonomous goal verification. */
|
|
31
|
+
export declare function isGoalCommandAllowed(cmd: string): boolean;
|
|
32
|
+
export declare const DESTRUCTIVE_PATTERNS: readonly RegExp[];
|
|
33
|
+
/** Run an arbitrary command, capturing combined stdout+stderr. */
|
|
34
|
+
export declare function runCmd(cmd: string, args: string[], cwd: string, shell?: boolean): Promise<{
|
|
35
|
+
code: number;
|
|
36
|
+
out: string;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Detect the project's package manager from lockfiles at the repo root.
|
|
40
|
+
* Async so the verify-step boot path doesn't block the event loop on `stat`
|
|
41
|
+
* for missing files in CWD or in monorepo setups where the lockfile lives
|
|
42
|
+
* several levels up.
|
|
43
|
+
*/
|
|
44
|
+
export declare function detectPackageManager(root: string): Promise<string>;
|
|
45
|
+
/** Read package.json scripts for a directory (empty on any failure). */
|
|
46
|
+
export declare function readScripts(cwd: string): Promise<Record<string, string>>;
|
|
47
|
+
//# sourceMappingURL=goal-commands.d.ts.map
|
package/dist/goal-host.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { configureGoalPolicy, isGoalCommandAllowed, resetGoalPolicy } from './goal-commands.js';
|
|
1
2
|
/**
|
|
2
3
|
* Goal host wiring for the CLI.
|
|
3
4
|
*
|
|
@@ -20,19 +21,6 @@ import { type PhaseGraph, type PhaseProgress } from '@wrongstack/core/goal';
|
|
|
20
21
|
import type { EventBus } from '@wrongstack/core/kernel';
|
|
21
22
|
import type { Config, TaskNode } from '@wrongstack/core/types';
|
|
22
23
|
import type { MultiAgentHost } from './multi-agent.js';
|
|
23
|
-
/**
|
|
24
|
-
* Extend/trim the autonomous goal command allowlist from the user's exec
|
|
25
|
-
* policy. Mirrors `configureExecPolicy` but keeps goal's narrower base.
|
|
26
|
-
* Idempotent (always rebuilt from the base).
|
|
27
|
-
*/
|
|
28
|
-
export declare function configureGoalPolicy(opts?: {
|
|
29
|
-
allow?: readonly string[] | undefined;
|
|
30
|
-
deny?: readonly string[] | undefined;
|
|
31
|
-
}): void;
|
|
32
|
-
/** Reset the goal allowlist to its built-in base (tests / re-init). */
|
|
33
|
-
export declare function resetGoalPolicy(): void;
|
|
34
|
-
/** Whether `cmd` may run in autonomous goal verification. */
|
|
35
|
-
export declare function isGoalCommandAllowed(cmd: string): boolean;
|
|
36
24
|
export interface GoalHostDeps {
|
|
37
25
|
multiAgentHost: MultiAgentHost;
|
|
38
26
|
/** Read the *current* Config lazily (it may be patched, e.g. YOLO toggles). */
|
|
@@ -103,5 +91,4 @@ export interface GoalHostHooks {
|
|
|
103
91
|
onWorktree: (action: 'list' | 'merge' | 'prune' | 'clean', target?: string) => Promise<string>;
|
|
104
92
|
}
|
|
105
93
|
export declare function createGoalHost(deps: GoalHostDeps): GoalHostHooks;
|
|
106
|
-
export {};
|
|
107
94
|
//# sourceMappingURL=goal-host.d.ts.map
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
parseTokenTtlValue
|
|
3
|
-
} from "./chunk-UZ2TMHNH.js";
|
|
4
1
|
import {
|
|
5
2
|
resolveHqPasswordInput
|
|
6
3
|
} from "./chunk-AUQDGU5D.js";
|
|
@@ -11,31 +8,295 @@ import {
|
|
|
11
8
|
import {
|
|
12
9
|
parseHqIpAllowlist
|
|
13
10
|
} from "./chunk-Q7E3BPDU.js";
|
|
11
|
+
import {
|
|
12
|
+
parseTokenTtlValue
|
|
13
|
+
} from "./chunk-UZ2TMHNH.js";
|
|
14
14
|
|
|
15
15
|
// src/subcommands/handlers/hq.ts
|
|
16
|
-
import * as fs from "node:fs/promises";
|
|
17
|
-
import * as path from "node:path";
|
|
18
16
|
import {
|
|
19
17
|
HQ_AUTH_FILE_VERSION,
|
|
20
18
|
HQ_CLI_DEFAULT_HOST,
|
|
21
|
-
HqAlertEngine,
|
|
22
19
|
HqInsecureExposureError,
|
|
23
|
-
hqAuthAuditPath,
|
|
24
|
-
hqAuthContentHash,
|
|
25
|
-
hqAuthFilePath,
|
|
26
20
|
isLoopbackHost,
|
|
27
21
|
logHqAuthAudit,
|
|
28
22
|
mintHqToken,
|
|
29
23
|
mutateHqAuthFile,
|
|
30
|
-
|
|
31
|
-
readHqAuthFile,
|
|
32
|
-
resolveHqDataDir
|
|
24
|
+
readHqAuthFile as readHqAuthFile2
|
|
33
25
|
} from "@wrongstack/core/hq";
|
|
34
26
|
import { expectDefined } from "@wrongstack/core/utils";
|
|
27
|
+
|
|
28
|
+
// src/subcommands/handlers/hq-alerts.ts
|
|
29
|
+
import * as fs from "node:fs/promises";
|
|
30
|
+
import * as path from "node:path";
|
|
31
|
+
import {
|
|
32
|
+
HqAlertEngine,
|
|
33
|
+
readHqAlertsConfig
|
|
34
|
+
} from "@wrongstack/core/hq";
|
|
35
|
+
|
|
36
|
+
// src/subcommands/handlers/hq-data-dir.ts
|
|
37
|
+
import { resolveHqDataDir } from "@wrongstack/core/hq";
|
|
35
38
|
function resolveDataDir(deps) {
|
|
36
39
|
const override = typeof deps.flags?.["data-dir"] === "string" ? deps.flags["data-dir"] : void 0;
|
|
37
40
|
return resolveHqDataDir(override);
|
|
38
41
|
}
|
|
42
|
+
|
|
43
|
+
// src/subcommands/handlers/hq-alerts.ts
|
|
44
|
+
async function hqAlertsCmd(args, deps) {
|
|
45
|
+
const action = args[0];
|
|
46
|
+
if (deps.flags?.["help"] === true || action === "help" || action === "--help") {
|
|
47
|
+
printAlertsHelp(deps);
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
if (action === "eval" || action === void 0) {
|
|
51
|
+
return hqAlertsEval(args.slice(1), deps);
|
|
52
|
+
}
|
|
53
|
+
deps.renderer.writeError(`Unknown hq alerts subcommand: ${action ?? "(none)"}
|
|
54
|
+
`);
|
|
55
|
+
printAlertsHelp(deps);
|
|
56
|
+
return 1;
|
|
57
|
+
}
|
|
58
|
+
async function hqAlertsEval(_args, deps) {
|
|
59
|
+
const flags = deps.flags ?? {};
|
|
60
|
+
const snapshotArg = typeof flags["snapshot"] === "string" ? flags["snapshot"] : void 0;
|
|
61
|
+
let snapshotPath;
|
|
62
|
+
try {
|
|
63
|
+
if (snapshotArg !== void 0) {
|
|
64
|
+
snapshotPath = path.resolve(snapshotArg);
|
|
65
|
+
} else {
|
|
66
|
+
const dataDir2 = resolveDataDir(deps);
|
|
67
|
+
snapshotPath = path.join(dataDir2, "snapshot.json");
|
|
68
|
+
}
|
|
69
|
+
} catch (err) {
|
|
70
|
+
deps.renderer.writeError(`Failed to resolve snapshot path: ${err.message}
|
|
71
|
+
`);
|
|
72
|
+
return 2;
|
|
73
|
+
}
|
|
74
|
+
let raw;
|
|
75
|
+
try {
|
|
76
|
+
raw = await fs.readFile(snapshotPath, "utf8");
|
|
77
|
+
} catch (err) {
|
|
78
|
+
deps.renderer.writeError(
|
|
79
|
+
`Cannot read snapshot at ${snapshotPath}: ${err.message}
|
|
80
|
+
Pass --snapshot <path> to evaluate against a specific file.
|
|
81
|
+
`
|
|
82
|
+
);
|
|
83
|
+
return 2;
|
|
84
|
+
}
|
|
85
|
+
let snapshot;
|
|
86
|
+
try {
|
|
87
|
+
snapshot = JSON.parse(raw);
|
|
88
|
+
} catch (err) {
|
|
89
|
+
deps.renderer.writeError(
|
|
90
|
+
`Snapshot at ${snapshotPath} is not valid JSON: ${err.message}
|
|
91
|
+
`
|
|
92
|
+
);
|
|
93
|
+
return 2;
|
|
94
|
+
}
|
|
95
|
+
const dataDir = resolveDataDir(deps);
|
|
96
|
+
let thresholds;
|
|
97
|
+
try {
|
|
98
|
+
const config = await readHqAlertsConfig(dataDir);
|
|
99
|
+
thresholds = config.thresholds;
|
|
100
|
+
} catch {
|
|
101
|
+
}
|
|
102
|
+
const engine = new HqAlertEngine({
|
|
103
|
+
onAlert: () => {
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
let fired;
|
|
107
|
+
try {
|
|
108
|
+
fired = engine.evaluate(snapshot, thresholds);
|
|
109
|
+
} catch (err) {
|
|
110
|
+
deps.renderer.writeError(`Alert evaluation failed: ${err.message}
|
|
111
|
+
`);
|
|
112
|
+
return 2;
|
|
113
|
+
}
|
|
114
|
+
if (fired.length === 0) {
|
|
115
|
+
deps.renderer.write(`No alert rules fired against ${snapshotPath}.
|
|
116
|
+
`);
|
|
117
|
+
if (thresholds === void 0) {
|
|
118
|
+
deps.renderer.write(
|
|
119
|
+
"(No persisted thresholds; using built-in defaults. Run `wstack hq alerts` with a populated alerts-config.json to override.)\n"
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
124
|
+
deps.renderer.write(`${fired.length} alert rule(s) fired against ${snapshotPath}:
|
|
125
|
+
`);
|
|
126
|
+
for (const alert of fired) {
|
|
127
|
+
deps.renderer.write(` [${alert.severity}] ${alert.ruleId}: ${alert.message}
|
|
128
|
+
`);
|
|
129
|
+
}
|
|
130
|
+
return 1;
|
|
131
|
+
}
|
|
132
|
+
function printAlertsHelp(deps) {
|
|
133
|
+
deps.renderer.write(`Usage: wstack hq alerts <eval>
|
|
134
|
+
`);
|
|
135
|
+
deps.renderer.write("\n");
|
|
136
|
+
deps.renderer.write(
|
|
137
|
+
` wstack hq alerts eval [--snapshot <path>] Run HqAlertEngine.evaluate() against a
|
|
138
|
+
`
|
|
139
|
+
);
|
|
140
|
+
deps.renderer.write(
|
|
141
|
+
` snapshot file (or the live <dataDir>/
|
|
142
|
+
`
|
|
143
|
+
);
|
|
144
|
+
deps.renderer.write(
|
|
145
|
+
` snapshot.json). Pure-function dry run;
|
|
146
|
+
`
|
|
147
|
+
);
|
|
148
|
+
deps.renderer.write(
|
|
149
|
+
` no server required. Exits 0 when no
|
|
150
|
+
`
|
|
151
|
+
);
|
|
152
|
+
deps.renderer.write(
|
|
153
|
+
` rules fire, 1 when rules fire, 2 on errors.
|
|
154
|
+
`
|
|
155
|
+
);
|
|
156
|
+
deps.renderer.write("\n");
|
|
157
|
+
deps.renderer.write(
|
|
158
|
+
`Persisted thresholds (<dataDir>/alerts-config.json) are loaded automatically when
|
|
159
|
+
`
|
|
160
|
+
);
|
|
161
|
+
deps.renderer.write(
|
|
162
|
+
`present; otherwise the engine's built-in defaults apply. Snoozes are NOT honored
|
|
163
|
+
`
|
|
164
|
+
);
|
|
165
|
+
deps.renderer.write(
|
|
166
|
+
`by this command \u2014 eval is a "what would fire RIGHT NOW if there were no snoozes"
|
|
167
|
+
`
|
|
168
|
+
);
|
|
169
|
+
deps.renderer.write(`probe.
|
|
170
|
+
`);
|
|
171
|
+
deps.renderer.write("\n");
|
|
172
|
+
deps.renderer.write(`Flags:
|
|
173
|
+
`);
|
|
174
|
+
deps.renderer.write(
|
|
175
|
+
` --snapshot <path> Evaluate against this snapshot file instead of the live one.
|
|
176
|
+
`
|
|
177
|
+
);
|
|
178
|
+
deps.renderer.write(
|
|
179
|
+
` --data-dir <path> Override HQ data directory (default ~/.wrongstack/hq).
|
|
180
|
+
`
|
|
181
|
+
);
|
|
182
|
+
deps.renderer.write("\n");
|
|
183
|
+
deps.renderer.write(`Run \`wstack hq --help\` for the full HQ command list.
|
|
184
|
+
`);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/subcommands/handlers/hq-audit.ts
|
|
188
|
+
import * as fs2 from "node:fs/promises";
|
|
189
|
+
import {
|
|
190
|
+
hqAuthAuditPath,
|
|
191
|
+
hqAuthContentHash,
|
|
192
|
+
hqAuthFilePath,
|
|
193
|
+
readHqAuthFile
|
|
194
|
+
} from "@wrongstack/core/hq";
|
|
195
|
+
async function hqAuditCmd(args, deps) {
|
|
196
|
+
const action = args[0];
|
|
197
|
+
if (deps.flags?.["help"] === true || action === "help" || action === "--help") {
|
|
198
|
+
printAuditHelp(deps);
|
|
199
|
+
return 0;
|
|
200
|
+
}
|
|
201
|
+
if (action === "verify" || action === void 0) {
|
|
202
|
+
return hqAuditVerify(deps);
|
|
203
|
+
}
|
|
204
|
+
deps.renderer.writeError(`Unknown hq audit subcommand: ${action ?? "(none)"}
|
|
205
|
+
`);
|
|
206
|
+
printAuditHelp(deps);
|
|
207
|
+
return 1;
|
|
208
|
+
}
|
|
209
|
+
async function hqAuditVerify(deps) {
|
|
210
|
+
const dataDir = resolveDataDir(deps);
|
|
211
|
+
const authPath = hqAuthFilePath(dataDir);
|
|
212
|
+
const auditPath = hqAuthAuditPath(dataDir);
|
|
213
|
+
deps.renderer.write(`auth file: ${authPath}
|
|
214
|
+
`);
|
|
215
|
+
deps.renderer.write(`audit log: ${auditPath}
|
|
216
|
+
`);
|
|
217
|
+
const fileExists = await fileExistsQuiet(authPath);
|
|
218
|
+
if (!fileExists) {
|
|
219
|
+
deps.renderer.write(`contentHash: (unavailable \u2014 auth.json does not exist)
|
|
220
|
+
`);
|
|
221
|
+
deps.renderer.write(
|
|
222
|
+
`Compare historical entries in the audit log above against a known-good hash.
|
|
223
|
+
`
|
|
224
|
+
);
|
|
225
|
+
return 1;
|
|
226
|
+
}
|
|
227
|
+
const authFile = await readHqAuthFile(dataDir, {
|
|
228
|
+
warn: (msg) => deps.renderer.writeWarning(`${msg}
|
|
229
|
+
`)
|
|
230
|
+
});
|
|
231
|
+
const hash = hqAuthContentHash(authFile);
|
|
232
|
+
if (hash === void 0) {
|
|
233
|
+
deps.renderer.write(`contentHash: (unavailable \u2014 auth.json is unreadable or malformed)
|
|
234
|
+
`);
|
|
235
|
+
deps.renderer.write(
|
|
236
|
+
`Compare historical entries in the audit log above against a known-good hash.
|
|
237
|
+
`
|
|
238
|
+
);
|
|
239
|
+
return 1;
|
|
240
|
+
}
|
|
241
|
+
deps.renderer.write(`contentHash: ${hash}
|
|
242
|
+
`);
|
|
243
|
+
deps.renderer.write("\n");
|
|
244
|
+
deps.renderer.write(
|
|
245
|
+
`Compare this value against the 'contentHash' field of entries in the audit log.
|
|
246
|
+
`
|
|
247
|
+
);
|
|
248
|
+
deps.renderer.write(
|
|
249
|
+
`A match means the redacted projection of auth.json is identical to when that
|
|
250
|
+
`
|
|
251
|
+
);
|
|
252
|
+
deps.renderer.write(
|
|
253
|
+
`entry was emitted (secrets may differ \u2014 only the non-secret shape is hashed).
|
|
254
|
+
`
|
|
255
|
+
);
|
|
256
|
+
return 0;
|
|
257
|
+
}
|
|
258
|
+
async function fileExistsQuiet(filePath) {
|
|
259
|
+
try {
|
|
260
|
+
await fs2.access(filePath);
|
|
261
|
+
return true;
|
|
262
|
+
} catch {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async function computeAuditHashField(dataDir, warn) {
|
|
267
|
+
const persisted = await readHqAuthFile(dataDir, { warn });
|
|
268
|
+
const hash = hqAuthContentHash(persisted);
|
|
269
|
+
return hash !== void 0 ? { contentHash: hash } : {};
|
|
270
|
+
}
|
|
271
|
+
function printAuditHelp(deps) {
|
|
272
|
+
deps.renderer.write(`Usage: wstack hq audit <verify>
|
|
273
|
+
`);
|
|
274
|
+
deps.renderer.write("\n");
|
|
275
|
+
deps.renderer.write(
|
|
276
|
+
` wstack hq audit verify Re-derive the SHA-256 contentHash from the current
|
|
277
|
+
`
|
|
278
|
+
);
|
|
279
|
+
deps.renderer.write(
|
|
280
|
+
` on-disk auth.json and print it so an operator can compare
|
|
281
|
+
`
|
|
282
|
+
);
|
|
283
|
+
deps.renderer.write(
|
|
284
|
+
` it against a contentHash field in an audit-log entry.
|
|
285
|
+
`
|
|
286
|
+
);
|
|
287
|
+
deps.renderer.write("\n");
|
|
288
|
+
deps.renderer.write(`Flags:
|
|
289
|
+
`);
|
|
290
|
+
deps.renderer.write(
|
|
291
|
+
` --data-dir <path> Override HQ data directory (default ~/.wrongstack/hq).
|
|
292
|
+
`
|
|
293
|
+
);
|
|
294
|
+
deps.renderer.write("\n");
|
|
295
|
+
deps.renderer.write(`Run \`wstack hq --help\` for the full HQ command list.
|
|
296
|
+
`);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// src/subcommands/handlers/hq.ts
|
|
39
300
|
var hqCmd = async (args, deps) => {
|
|
40
301
|
const sub = args[0];
|
|
41
302
|
if (deps.flags?.["help"] === true && (!sub || sub === "serve")) {
|
|
@@ -55,7 +316,7 @@ var hqCmd = async (args, deps) => {
|
|
|
55
316
|
return hqAlertsCmd(args.slice(1), deps);
|
|
56
317
|
}
|
|
57
318
|
if (sub === "service") {
|
|
58
|
-
const { hqServiceCmd } = await import("./hq-service-
|
|
319
|
+
const { hqServiceCmd } = await import("./hq-service-BMMJAHRT.js");
|
|
59
320
|
return hqServiceCmd(args.slice(1), deps);
|
|
60
321
|
}
|
|
61
322
|
if (sub === "help" || sub === "--help") {
|
|
@@ -68,7 +329,7 @@ var hqCmd = async (args, deps) => {
|
|
|
68
329
|
return 1;
|
|
69
330
|
};
|
|
70
331
|
async function startServer(deps) {
|
|
71
|
-
const { startHqServer } = await import("./hq-server-
|
|
332
|
+
const { startHqServer } = await import("./hq-server-YTKDVQPY.js");
|
|
72
333
|
const dataDir = resolveDataDir(deps);
|
|
73
334
|
const flags = deps.flags ?? {};
|
|
74
335
|
const rawPublicUrl = typeof flags["hq-public-url"] === "string" ? flags["hq-public-url"] : process.env.WRONGSTACK_HQ_PUBLIC_URL;
|
|
@@ -286,82 +547,6 @@ async function hqTokenCmd(args, deps) {
|
|
|
286
547
|
printTokenHelp(deps);
|
|
287
548
|
return 1;
|
|
288
549
|
}
|
|
289
|
-
async function hqAuditCmd(args, deps) {
|
|
290
|
-
const action = args[0];
|
|
291
|
-
if (deps.flags?.["help"] === true || action === "help" || action === "--help") {
|
|
292
|
-
printAuditHelp(deps);
|
|
293
|
-
return 0;
|
|
294
|
-
}
|
|
295
|
-
if (action === "verify" || action === void 0) {
|
|
296
|
-
return hqAuditVerify(deps);
|
|
297
|
-
}
|
|
298
|
-
deps.renderer.writeError(`Unknown hq audit subcommand: ${action ?? "(none)"}
|
|
299
|
-
`);
|
|
300
|
-
printAuditHelp(deps);
|
|
301
|
-
return 1;
|
|
302
|
-
}
|
|
303
|
-
async function hqAuditVerify(deps) {
|
|
304
|
-
const dataDir = resolveDataDir(deps);
|
|
305
|
-
const authPath = hqAuthFilePath(dataDir);
|
|
306
|
-
const auditPath = hqAuthAuditPath(dataDir);
|
|
307
|
-
deps.renderer.write(`auth file: ${authPath}
|
|
308
|
-
`);
|
|
309
|
-
deps.renderer.write(`audit log: ${auditPath}
|
|
310
|
-
`);
|
|
311
|
-
const fileExists = await fileExistsQuiet(authPath);
|
|
312
|
-
if (!fileExists) {
|
|
313
|
-
deps.renderer.write(`contentHash: (unavailable \u2014 auth.json does not exist)
|
|
314
|
-
`);
|
|
315
|
-
deps.renderer.write(
|
|
316
|
-
`Compare historical entries in the audit log above against a known-good hash.
|
|
317
|
-
`
|
|
318
|
-
);
|
|
319
|
-
return 1;
|
|
320
|
-
}
|
|
321
|
-
const authFile = await readHqAuthFile(dataDir, {
|
|
322
|
-
warn: (msg) => deps.renderer.writeWarning(`${msg}
|
|
323
|
-
`)
|
|
324
|
-
});
|
|
325
|
-
const hash = hqAuthContentHash(authFile);
|
|
326
|
-
if (hash === void 0) {
|
|
327
|
-
deps.renderer.write(`contentHash: (unavailable \u2014 auth.json is unreadable or malformed)
|
|
328
|
-
`);
|
|
329
|
-
deps.renderer.write(
|
|
330
|
-
`Compare historical entries in the audit log above against a known-good hash.
|
|
331
|
-
`
|
|
332
|
-
);
|
|
333
|
-
return 1;
|
|
334
|
-
}
|
|
335
|
-
deps.renderer.write(`contentHash: ${hash}
|
|
336
|
-
`);
|
|
337
|
-
deps.renderer.write("\n");
|
|
338
|
-
deps.renderer.write(
|
|
339
|
-
`Compare this value against the 'contentHash' field of entries in the audit log.
|
|
340
|
-
`
|
|
341
|
-
);
|
|
342
|
-
deps.renderer.write(
|
|
343
|
-
`A match means the redacted projection of auth.json is identical to when that
|
|
344
|
-
`
|
|
345
|
-
);
|
|
346
|
-
deps.renderer.write(
|
|
347
|
-
`entry was emitted (secrets may differ \u2014 only the non-secret shape is hashed).
|
|
348
|
-
`
|
|
349
|
-
);
|
|
350
|
-
return 0;
|
|
351
|
-
}
|
|
352
|
-
async function fileExistsQuiet(filePath) {
|
|
353
|
-
try {
|
|
354
|
-
await fs.access(filePath);
|
|
355
|
-
return true;
|
|
356
|
-
} catch {
|
|
357
|
-
return false;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
async function computeAuditHashField(dataDir, warn) {
|
|
361
|
-
const persisted = await readHqAuthFile(dataDir, { warn });
|
|
362
|
-
const hash = hqAuthContentHash(persisted);
|
|
363
|
-
return hash !== void 0 ? { contentHash: hash } : {};
|
|
364
|
-
}
|
|
365
550
|
var TOKEN_CAPABILITIES = {
|
|
366
551
|
// `control.approve` is grantable but never default — see
|
|
367
552
|
// DEFAULT_TOKEN_CAPABILITIES below.
|
|
@@ -532,7 +717,7 @@ async function tokenList(args, deps) {
|
|
|
532
717
|
const scope = resolveTokenScope(args, deps);
|
|
533
718
|
const dataDir = resolveDataDir(deps);
|
|
534
719
|
const tokenField = scope === "client" ? "clientTokens" : "browserTokens";
|
|
535
|
-
const authFile = await
|
|
720
|
+
const authFile = await readHqAuthFile2(dataDir, {
|
|
536
721
|
warn: (msg) => deps.renderer.writeWarning(`${msg}
|
|
537
722
|
`)
|
|
538
723
|
});
|
|
@@ -814,177 +999,8 @@ function printTokenHelp(deps) {
|
|
|
814
999
|
deps.renderer.write(`Run \`wstack hq --help\` for the full HQ command list.
|
|
815
1000
|
`);
|
|
816
1001
|
}
|
|
817
|
-
function printAuditHelp(deps) {
|
|
818
|
-
deps.renderer.write(`Usage: wstack hq audit <verify>
|
|
819
|
-
`);
|
|
820
|
-
deps.renderer.write("\n");
|
|
821
|
-
deps.renderer.write(
|
|
822
|
-
` wstack hq audit verify Re-derive the SHA-256 contentHash from the current
|
|
823
|
-
`
|
|
824
|
-
);
|
|
825
|
-
deps.renderer.write(
|
|
826
|
-
` on-disk auth.json and print it so an operator can compare
|
|
827
|
-
`
|
|
828
|
-
);
|
|
829
|
-
deps.renderer.write(
|
|
830
|
-
` it against a contentHash field in an audit-log entry.
|
|
831
|
-
`
|
|
832
|
-
);
|
|
833
|
-
deps.renderer.write("\n");
|
|
834
|
-
deps.renderer.write(`Flags:
|
|
835
|
-
`);
|
|
836
|
-
deps.renderer.write(
|
|
837
|
-
` --data-dir <path> Override HQ data directory (default ~/.wrongstack/hq).
|
|
838
|
-
`
|
|
839
|
-
);
|
|
840
|
-
deps.renderer.write("\n");
|
|
841
|
-
deps.renderer.write(`Run \`wstack hq --help\` for the full HQ command list.
|
|
842
|
-
`);
|
|
843
|
-
}
|
|
844
|
-
async function hqAlertsCmd(args, deps) {
|
|
845
|
-
const action = args[0];
|
|
846
|
-
if (deps.flags?.["help"] === true || action === "help" || action === "--help") {
|
|
847
|
-
printAlertsHelp(deps);
|
|
848
|
-
return 0;
|
|
849
|
-
}
|
|
850
|
-
if (action === "eval" || action === void 0) {
|
|
851
|
-
return hqAlertsEval(args.slice(1), deps);
|
|
852
|
-
}
|
|
853
|
-
deps.renderer.writeError(`Unknown hq alerts subcommand: ${action ?? "(none)"}
|
|
854
|
-
`);
|
|
855
|
-
printAlertsHelp(deps);
|
|
856
|
-
return 1;
|
|
857
|
-
}
|
|
858
|
-
async function hqAlertsEval(_args, deps) {
|
|
859
|
-
const flags = deps.flags ?? {};
|
|
860
|
-
const snapshotArg = typeof flags["snapshot"] === "string" ? flags["snapshot"] : void 0;
|
|
861
|
-
let snapshotPath;
|
|
862
|
-
try {
|
|
863
|
-
if (snapshotArg !== void 0) {
|
|
864
|
-
snapshotPath = path.resolve(snapshotArg);
|
|
865
|
-
} else {
|
|
866
|
-
const dataDir2 = resolveDataDir(deps);
|
|
867
|
-
snapshotPath = path.join(dataDir2, "snapshot.json");
|
|
868
|
-
}
|
|
869
|
-
} catch (err) {
|
|
870
|
-
deps.renderer.writeError(`Failed to resolve snapshot path: ${err.message}
|
|
871
|
-
`);
|
|
872
|
-
return 2;
|
|
873
|
-
}
|
|
874
|
-
let raw;
|
|
875
|
-
try {
|
|
876
|
-
raw = await fs.readFile(snapshotPath, "utf8");
|
|
877
|
-
} catch (err) {
|
|
878
|
-
deps.renderer.writeError(
|
|
879
|
-
`Cannot read snapshot at ${snapshotPath}: ${err.message}
|
|
880
|
-
Pass --snapshot <path> to evaluate against a specific file.
|
|
881
|
-
`
|
|
882
|
-
);
|
|
883
|
-
return 2;
|
|
884
|
-
}
|
|
885
|
-
let snapshot;
|
|
886
|
-
try {
|
|
887
|
-
snapshot = JSON.parse(raw);
|
|
888
|
-
} catch (err) {
|
|
889
|
-
deps.renderer.writeError(
|
|
890
|
-
`Snapshot at ${snapshotPath} is not valid JSON: ${err.message}
|
|
891
|
-
`
|
|
892
|
-
);
|
|
893
|
-
return 2;
|
|
894
|
-
}
|
|
895
|
-
const dataDir = resolveDataDir(deps);
|
|
896
|
-
let thresholds;
|
|
897
|
-
try {
|
|
898
|
-
const config = await readHqAlertsConfig(dataDir);
|
|
899
|
-
thresholds = config.thresholds;
|
|
900
|
-
} catch {
|
|
901
|
-
}
|
|
902
|
-
const engine = new HqAlertEngine({
|
|
903
|
-
onAlert: () => {
|
|
904
|
-
}
|
|
905
|
-
});
|
|
906
|
-
let fired;
|
|
907
|
-
try {
|
|
908
|
-
fired = engine.evaluate(snapshot, thresholds);
|
|
909
|
-
} catch (err) {
|
|
910
|
-
deps.renderer.writeError(`Alert evaluation failed: ${err.message}
|
|
911
|
-
`);
|
|
912
|
-
return 2;
|
|
913
|
-
}
|
|
914
|
-
if (fired.length === 0) {
|
|
915
|
-
deps.renderer.write(`No alert rules fired against ${snapshotPath}.
|
|
916
|
-
`);
|
|
917
|
-
if (thresholds === void 0) {
|
|
918
|
-
deps.renderer.write(
|
|
919
|
-
"(No persisted thresholds; using built-in defaults. Run `wstack hq alerts` with a populated alerts-config.json to override.)\n"
|
|
920
|
-
);
|
|
921
|
-
}
|
|
922
|
-
return 0;
|
|
923
|
-
}
|
|
924
|
-
deps.renderer.write(`${fired.length} alert rule(s) fired against ${snapshotPath}:
|
|
925
|
-
`);
|
|
926
|
-
for (const alert of fired) {
|
|
927
|
-
deps.renderer.write(` [${alert.severity}] ${alert.ruleId}: ${alert.message}
|
|
928
|
-
`);
|
|
929
|
-
}
|
|
930
|
-
return 1;
|
|
931
|
-
}
|
|
932
|
-
function printAlertsHelp(deps) {
|
|
933
|
-
deps.renderer.write(`Usage: wstack hq alerts <eval>
|
|
934
|
-
`);
|
|
935
|
-
deps.renderer.write("\n");
|
|
936
|
-
deps.renderer.write(
|
|
937
|
-
` wstack hq alerts eval [--snapshot <path>] Run HqAlertEngine.evaluate() against a
|
|
938
|
-
`
|
|
939
|
-
);
|
|
940
|
-
deps.renderer.write(
|
|
941
|
-
` snapshot file (or the live <dataDir>/
|
|
942
|
-
`
|
|
943
|
-
);
|
|
944
|
-
deps.renderer.write(
|
|
945
|
-
` snapshot.json). Pure-function dry run;
|
|
946
|
-
`
|
|
947
|
-
);
|
|
948
|
-
deps.renderer.write(
|
|
949
|
-
` no server required. Exits 0 when no
|
|
950
|
-
`
|
|
951
|
-
);
|
|
952
|
-
deps.renderer.write(
|
|
953
|
-
` rules fire, 1 when rules fire, 2 on errors.
|
|
954
|
-
`
|
|
955
|
-
);
|
|
956
|
-
deps.renderer.write("\n");
|
|
957
|
-
deps.renderer.write(
|
|
958
|
-
`Persisted thresholds (<dataDir>/alerts-config.json) are loaded automatically when
|
|
959
|
-
`
|
|
960
|
-
);
|
|
961
|
-
deps.renderer.write(
|
|
962
|
-
`present; otherwise the engine's built-in defaults apply. Snoozes are NOT honored
|
|
963
|
-
`
|
|
964
|
-
);
|
|
965
|
-
deps.renderer.write(
|
|
966
|
-
`by this command \u2014 eval is a "what would fire RIGHT NOW if there were no snoozes"
|
|
967
|
-
`
|
|
968
|
-
);
|
|
969
|
-
deps.renderer.write(`probe.
|
|
970
|
-
`);
|
|
971
|
-
deps.renderer.write("\n");
|
|
972
|
-
deps.renderer.write(`Flags:
|
|
973
|
-
`);
|
|
974
|
-
deps.renderer.write(
|
|
975
|
-
` --snapshot <path> Evaluate against this snapshot file instead of the live one.
|
|
976
|
-
`
|
|
977
|
-
);
|
|
978
|
-
deps.renderer.write(
|
|
979
|
-
` --data-dir <path> Override HQ data directory (default ~/.wrongstack/hq).
|
|
980
|
-
`
|
|
981
|
-
);
|
|
982
|
-
deps.renderer.write("\n");
|
|
983
|
-
deps.renderer.write(`Run \`wstack hq --help\` for the full HQ command list.
|
|
984
|
-
`);
|
|
985
|
-
}
|
|
986
1002
|
export {
|
|
987
1003
|
hqCmd,
|
|
988
1004
|
resolveAuditActor
|
|
989
1005
|
};
|
|
990
|
-
//# sourceMappingURL=hq-
|
|
1006
|
+
//# sourceMappingURL=hq-GLZ7QESM.js.map
|
|
@@ -81,7 +81,7 @@ export interface HqCommandController {
|
|
|
81
81
|
* (`createApprovalRegistry` in `@wrongstack/core/hq`), which is the only
|
|
82
82
|
* holder of the resolver closures.
|
|
83
83
|
*/
|
|
84
|
-
resolveApproval?: ((toolUseId: string, decision: 'yes' | 'no' | 'always' | 'deny', sessionId?: string | undefined) => boolean) | undefined;
|
|
84
|
+
resolveApproval?: ((toolUseId: string, decision: 'yes' | 'no' | 'always' | 'always-exact' | 'always-command' | 'always-tool' | 'deny', sessionId?: string | undefined) => boolean) | undefined;
|
|
85
85
|
resolveUserInput?: ((requestId: string, response: UserInputResponse, sessionId?: string | undefined) => boolean) | undefined;
|
|
86
86
|
/** Apply a lifecycle transition through the project's Kanban IPC client. */
|
|
87
87
|
kanbanTransition?: ((input: {
|