@wrongstack/cli 1.0.9 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{acp-CXLANMEZ.js → acp-IJ55NBMJ.js} +5 -3
- package/dist/acp-mcp-servers.d.ts +2 -0
- package/dist/arg-parser.d.ts +6 -0
- package/dist/{auth-3K6EN5JP.js → auth-YXK3EDUL.js} +9 -3
- package/dist/{chunk-EK2P53GL.js → chunk-C3Z4N6A6.js} +23 -3
- package/dist/{chunk-7K3IJGWC.js → chunk-OJR7K3OI.js} +8 -8
- package/dist/{chunk-SXJTVNWF.js → chunk-OWNC7LMD.js} +2 -2
- package/dist/{chunk-FSZ5QU3M.js → chunk-RDHFXOJM.js} +153 -69
- package/dist/{chunk-5VPDKQDH.js → chunk-TNZBQG45.js} +3 -3
- package/dist/{chunk-7FPN3QTH.js → chunk-YRC3I3LE.js} +172 -15
- package/dist/{cli-context-6GMXUOXD.js → cli-context-5IF7ZYEY.js} +7 -7
- package/dist/{cli-main-4E4YMCNS.js → cli-main-WC5JNIWY.js} +67 -48
- package/dist/{diag-doctor-PCER6KHH.js → diag-doctor-ANPRUYFM.js} +13 -3
- package/dist/{execution-4RXQLDAF.js → execution-EXDRBS4F.js} +2 -2
- package/dist/{hq-DQTUE7RC.js → hq-NO2NWGU4.js} +153 -5
- package/dist/hq-server/auth-state.d.ts +11 -0
- package/dist/hq-server/mailbox-gateway-health.d.ts +67 -0
- package/dist/hq-server/mailbox-gateway-manager.d.ts +38 -0
- package/dist/hq-server/routes/system-handlers.d.ts +27 -0
- package/dist/hq-server/routes.d.ts +11 -0
- package/dist/hq-server/snapshot.d.ts +14 -1
- package/dist/hq-server/upgrade-handler.d.ts +7 -0
- package/dist/{hq-server-JJFGFWI5.js → hq-server-KE5YDNGG.js} +2 -2
- package/dist/index.js +4 -4
- package/dist/{mcp-FX7TKPTV.js → mcp-DC5WSBOO.js} +28 -10
- package/dist/mcp-serve.d.ts +9 -0
- package/dist/services/mcp-management.d.ts +0 -6
- package/dist/{short-circuit-flags-LHUNLCZY.js → short-circuit-flags-72E77TJI.js} +3 -3
- package/dist/{subcommands-UXWY3OPC.js → subcommands-EJI7DBQS.js} +2 -2
- package/package.json +28 -28
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* W2 #14 (RFC hq-improvements-2026-09.md): Mailbox gateway health types.
|
|
3
|
+
*
|
|
4
|
+
* These types are the wire contract for `/api/health/mailbox`. They live in
|
|
5
|
+
* their own module so both the gateway manager (producer) and the HTTP
|
|
6
|
+
* handler (consumer) can import them without a circular dependency.
|
|
7
|
+
*
|
|
8
|
+
* Critical contract (from SAGE memory, surfaced multiple times in this work):
|
|
9
|
+
*
|
|
10
|
+
* - Mailbox credential `projectId` is the **basename** of the project
|
|
11
|
+
* directory, not the full path. `mailbox-serve.ts:192` derives it via
|
|
12
|
+
* `path.basename(projectDir)`. The dashboard MUST render `projectId`
|
|
13
|
+
* from this surface so it matches what other mailbox surfaces see.
|
|
14
|
+
*
|
|
15
|
+
* - HQ's `MailboxGatewayManager` binds gateways with the **full filesystem
|
|
16
|
+
* path** (from `resolveHqProjectRoot(...)` in `mailbox-handlers.ts:90`).
|
|
17
|
+
* We surface the full path as `projectRoot` so operators can debug
|
|
18
|
+
* path-mismatch issues without grepping the source.
|
|
19
|
+
*
|
|
20
|
+
* - HQ never attaches a `MailboxActorContext` to its mailbox authorization
|
|
21
|
+
* decisions (see `authorizeMailboxGateway` in `mailbox-gateway-manager.ts:57-96`).
|
|
22
|
+
* The aggregate `actorAttached: false` flag surfaces this truth so the
|
|
23
|
+
* dashboard can render "no actor context" honestly.
|
|
24
|
+
*
|
|
25
|
+
* @module hq-server/mailbox-gateway-health
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* One mailbox gateway entry — one per bound `projectDir` in the manager.
|
|
29
|
+
*/
|
|
30
|
+
export interface HqMailboxGatewayHealthEntry {
|
|
31
|
+
/**
|
|
32
|
+
* Credential contract key: `path.basename(projectRoot)`. Matches the
|
|
33
|
+
* `projectId` used by `mailbox-serve.ts` and other mailbox surfaces.
|
|
34
|
+
*/
|
|
35
|
+
projectId: string;
|
|
36
|
+
/** Full filesystem path the gateway is bound to. */
|
|
37
|
+
projectRoot: string;
|
|
38
|
+
/** Whether the gateway has any open HTTP streams right now. */
|
|
39
|
+
hasActiveStreams: boolean;
|
|
40
|
+
/** Epoch ms of the last `getMailboxGateway` / `authorizeMailboxGateway` hit, or null if never used. */
|
|
41
|
+
lastUsedAt: number | null;
|
|
42
|
+
/** Convenience: `Date.now() - lastUsedAt`, or null when `lastUsedAt` is null. */
|
|
43
|
+
idleForMs: number | null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Aggregate health snapshot for the HQ cockpit "Mailbox gateway" card.
|
|
47
|
+
*/
|
|
48
|
+
export interface HqMailboxGatewayHealth {
|
|
49
|
+
/** Total number of bound gateways. */
|
|
50
|
+
gatewayCount: number;
|
|
51
|
+
/** Whether the rate limiter is configured. Always `true` on the HQ mount. */
|
|
52
|
+
rateLimiterConfigured: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Whether the gateway manager attaches a `MailboxActorContext` to its
|
|
55
|
+
* authorization decisions. HQ is a read-mostly operator dashboard and
|
|
56
|
+
* never attaches one — this flag is `false` on the HQ mount and is
|
|
57
|
+
* surfaced so the dashboard can render the truthful state.
|
|
58
|
+
*/
|
|
59
|
+
actorAttached: boolean;
|
|
60
|
+
/** Per-gateway health entries, sorted by `projectId` for stable rendering. */
|
|
61
|
+
gateways: readonly HqMailboxGatewayHealthEntry[];
|
|
62
|
+
/** Idle-eviction sweep interval in ms (mirrors the manager's private constant). */
|
|
63
|
+
sweepIntervalMs: number;
|
|
64
|
+
/** Idle TTL after which a gateway is eligible for eviction. */
|
|
65
|
+
idleTtlMs: number;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=mailbox-gateway-health.d.ts.map
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import type { IncomingMessage } from 'node:http';
|
|
7
7
|
import { type MailboxHttpAccessDecision, MailboxHttpRateLimiter } from '@wrongstack/core/coordination';
|
|
8
8
|
import type { HqAuthState } from './auth-state.js';
|
|
9
|
+
import type { HqMailboxGatewayHealth } from './mailbox-gateway-health.js';
|
|
9
10
|
import { type HqRouterMailboxGateway } from './routes.js';
|
|
10
11
|
import type { HqSessionEntry } from './types.js';
|
|
11
12
|
interface MailboxGatewayManagerDeps {
|
|
@@ -27,6 +28,43 @@ export declare class MailboxGatewayManager {
|
|
|
27
28
|
authorizeMailboxGateway(req: IncomingMessage, projectDir: string): MailboxHttpAccessDecision;
|
|
28
29
|
getMailboxGateway(projectDir: string): HqRouterMailboxGateway;
|
|
29
30
|
private evictIdleGateways;
|
|
31
|
+
/**
|
|
32
|
+
* W2 #14 (RFC hq-improvements-2026-09.md): health snapshot for the cockpit
|
|
33
|
+
* "Mailbox gateway" card.
|
|
34
|
+
*
|
|
35
|
+
* Per-gateway entry surfaces the three diagnostic facts an operator
|
|
36
|
+
* needs:
|
|
37
|
+
*
|
|
38
|
+
* - `projectId`: the **basename** of the project directory, matching
|
|
39
|
+
* the credential contract used by `mailbox-serve.ts:192` (where
|
|
40
|
+
* `path.basename(projectDir)` is the `projectId` key for mailbox
|
|
41
|
+
* data). HQ binds the gateway with the full filesystem path
|
|
42
|
+
* (`resolveHqProjectRoot(...)` from `mailbox-handlers.ts:90`), so
|
|
43
|
+
* reporting the basename here means the dashboard's projectId
|
|
44
|
+
* matches what other mailbox surfaces see.
|
|
45
|
+
* - `projectRoot`: the full filesystem path the manager actually
|
|
46
|
+
* binds against. Surfaced separately so operators can debug
|
|
47
|
+
* path-mismatch issues without grepping the source.
|
|
48
|
+
* - `hasActiveStreams`: whether the gateway has any open HTTP streams
|
|
49
|
+
* right now. A gateway with `false` is a candidate for the next
|
|
50
|
+
* idle eviction; one with `true` is being watched.
|
|
51
|
+
* - `lastUsedAt`: epoch ms of the most recent `getMailboxGateway()`
|
|
52
|
+
* call (or the last `authorizeMailboxGateway` hit that resolved to
|
|
53
|
+
* this gateway). Surfaced so the dashboard can render the same
|
|
54
|
+
* "fresh / quiet / stale" staleness buckets the publisher health
|
|
55
|
+
* tile uses.
|
|
56
|
+
* - `idleForMs`: convenience — `Date.now() - lastUsedAt`. `Infinity`
|
|
57
|
+
* when the gateway was never used (shouldn't happen, since
|
|
58
|
+
* `getMailboxGateway` always stamps `mailboxGatewayLastUsed`).
|
|
59
|
+
*
|
|
60
|
+
* The aggregate `actor` field is **explicitly absent** on the HQ mount:
|
|
61
|
+
* `authorizeMailboxGateway` (L57-96) never attaches a `MailboxActorContext`
|
|
62
|
+
* to its decision, because HQ is a read-mostly operator dashboard, not
|
|
63
|
+
* a producer-side mailbox client. We surface this truth with a stable
|
|
64
|
+
* `actorAttached: false` so the dashboard can render "no actor
|
|
65
|
+
* context" honestly rather than papering over it.
|
|
66
|
+
*/
|
|
67
|
+
getHealth(): HqMailboxGatewayHealth;
|
|
30
68
|
close(): void;
|
|
31
69
|
}
|
|
32
70
|
export {};
|
|
@@ -7,9 +7,36 @@
|
|
|
7
7
|
import type * as http from 'node:http';
|
|
8
8
|
import type { HqAlertEngine, HqCommandAuditLog, HqEventEnvelope, HqPersistence } from '@wrongstack/core/hq';
|
|
9
9
|
import type { WebSocket } from 'ws';
|
|
10
|
+
import type { HqMailboxGatewayHealth } from '../mailbox-gateway-health.js';
|
|
10
11
|
import type { ConnectedClient } from '../types.js';
|
|
11
12
|
export declare function handleApiSystemUpdate(res: http.ServerResponse): Promise<void>;
|
|
12
13
|
export declare function handleApiSystemHealth(res: http.ServerResponse, clients: Map<WebSocket, ConnectedClient>, persistence: HqPersistence, eventLog: HqEventEnvelope[]): Promise<void>;
|
|
13
14
|
export declare function handleApiCommandsAudit(req: http.IncomingMessage, res: http.ServerResponse, auditLog: HqCommandAuditLog): Promise<void>;
|
|
14
15
|
export declare function handleApiAlerts(req: http.IncomingMessage, res: http.ServerResponse, alertEngine: HqAlertEngine): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Structural view of the gateway manager this handler needs. Typing the
|
|
18
|
+
* parameter structurally — rather than importing `MailboxGatewayManager` —
|
|
19
|
+
* keeps this module out of the type-inclusive cycle
|
|
20
|
+
* `mailbox-gateway-manager → routes → system-handlers`, which
|
|
21
|
+
* `check:architecture` reports as unexcepted. The real manager satisfies this
|
|
22
|
+
* shape, so callers and the wire contract are unaffected.
|
|
23
|
+
*/
|
|
24
|
+
interface MailboxHealthSource {
|
|
25
|
+
getHealth(): HqMailboxGatewayHealth;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* W2 #14 (RFC hq-improvements-2026-09.md): GET /api/health/mailbox —
|
|
29
|
+
* mailbox gateway health snapshot for the cockpit's "Mailbox gateway" card.
|
|
30
|
+
*
|
|
31
|
+
* Surfaces {@link MailboxHealthSource.getHealth} verbatim. The contract
|
|
32
|
+
* (basename as `projectId`, full path as `projectRoot`, `actorAttached: false`
|
|
33
|
+
* on the HQ mount, sorted gateways) is locked by the focused test in
|
|
34
|
+
* `packages/cli/tests/hq-mailbox-gateway-health.test.ts`.
|
|
35
|
+
*
|
|
36
|
+
* No query parameters. No mutation. Same auth contract as
|
|
37
|
+
* `/api/system/health` — gated by `requireBrowserAuth` upstream in the
|
|
38
|
+
* router, not duplicated here.
|
|
39
|
+
*/
|
|
40
|
+
export declare function handleApiMailboxHealth(res: http.ServerResponse, mailboxManager: MailboxHealthSource): void;
|
|
41
|
+
export {};
|
|
15
42
|
//# sourceMappingURL=system-handlers.d.ts.map
|
|
@@ -13,6 +13,7 @@ import type { createHqPersistence, HqAlertEngine, HqCommandAuditLog, HqEventEnve
|
|
|
13
13
|
import type { TrustBoundary } from '@wrongstack/core/security';
|
|
14
14
|
import type { WebSocket } from 'ws';
|
|
15
15
|
import * as HqServerAuth from './auth.js';
|
|
16
|
+
import type { HqMailboxGatewayHealth } from './mailbox-gateway-health.js';
|
|
16
17
|
import { type ApplyHqAuthFile } from './routes/auth-handlers.js';
|
|
17
18
|
import * as HqServerUtils from './utils.js';
|
|
18
19
|
export declare const setHqSecurityHeaders: typeof HqServerAuth.setHqSecurityHeaders;
|
|
@@ -73,6 +74,16 @@ export interface HqRouterDeps {
|
|
|
73
74
|
agentMessages: Map<string, HqTranscriptEntry[]>;
|
|
74
75
|
mailboxGateways: Map<string, HqRouterMailboxGateway>;
|
|
75
76
|
mailboxGatewayRateLimiter: MailboxHttpRateLimiter;
|
|
77
|
+
/**
|
|
78
|
+
* W2 #14 (RFC hq-improvements-2026-09.md): mailbox gateway manager used
|
|
79
|
+
* by `/api/health/mailbox` to surface the cockpit "Mailbox gateway"
|
|
80
|
+
* card. Same manager that owns `mailboxGateways` and
|
|
81
|
+
* `mailboxGatewayRateLimiter` — passed explicitly so the handler can
|
|
82
|
+
* call `getHealth()` without reaching into a closure.
|
|
83
|
+
*/
|
|
84
|
+
mailboxManager: {
|
|
85
|
+
getHealth(): HqMailboxGatewayHealth;
|
|
86
|
+
};
|
|
76
87
|
alertEngine: HqAlertEngine;
|
|
77
88
|
auditLog: HqCommandAuditLog;
|
|
78
89
|
persistence: ReturnType<typeof createHqPersistence>;
|
|
@@ -53,8 +53,21 @@ export declare const HQ_STALE_SNAPSHOT_MS: number;
|
|
|
53
53
|
export declare function reapStaleClientState(clients: Map<WebSocket, ConnectedClient>, nowMs?: number): void;
|
|
54
54
|
export declare function buildSnapshot(clients: Map<WebSocket, ConnectedClient>, options?: {
|
|
55
55
|
tokenStats?: HqSnapshot['totals']['tokenStats'];
|
|
56
|
+
/**
|
|
57
|
+
* Recent command-audit entries (W4 #7). The caller owns the audit ring, so
|
|
58
|
+
* it hands over the window rather than the builder reaching for a global.
|
|
59
|
+
*/
|
|
60
|
+
commandAudit?: readonly HqCommandAuditEntry[];
|
|
56
61
|
}): HqSnapshot;
|
|
57
|
-
export declare function createSnapshotBroadcaster(clients: Map<WebSocket, ConnectedClient>, browsers: Set<WebSocket>, persistence?: HqPersistence
|
|
62
|
+
export declare function createSnapshotBroadcaster(clients: Map<WebSocket, ConnectedClient>, browsers: Set<WebSocket>, persistence?: HqPersistence, options?: {
|
|
63
|
+
/**
|
|
64
|
+
* W4 #7: command-audit window for the latency roll-up. Passed as a
|
|
65
|
+
* provider rather than an array because the broadcaster caches its
|
|
66
|
+
* serialized frame and only rebuilds when marked dirty — reading the ring
|
|
67
|
+
* at serialize time is what keeps the cached frame current.
|
|
68
|
+
*/
|
|
69
|
+
commandAudit?: () => readonly HqCommandAuditEntry[];
|
|
70
|
+
}): HqSnapshotBroadcaster;
|
|
58
71
|
export declare function buildProjectDetail(clients: Map<WebSocket, ConnectedClient>, projectId: string): ProjectDetail | null;
|
|
59
72
|
export declare function broadcastEvent(event: HqEventEnvelope, browsers: Set<WebSocket>): void;
|
|
60
73
|
/** Push one control command's lifecycle to every authenticated HQ browser. */
|
|
@@ -21,6 +21,13 @@ interface HqUpgradeHandlerDeps {
|
|
|
21
21
|
sessions: Map<string, HqSessionEntry>;
|
|
22
22
|
clients: Map<WebSocket, ConnectedClient>;
|
|
23
23
|
clientSocketTokens: Map<WebSocket, HqToken | undefined>;
|
|
24
|
+
/**
|
|
25
|
+
* Session id that authorized each open browser socket, so token revocation
|
|
26
|
+
* can close only the affected browsers. Absent for a socket that
|
|
27
|
+
* authenticated with a bare loopback `?token=` rather than a cookie session;
|
|
28
|
+
* the revocation path treats that absence as "affected" (fail closed).
|
|
29
|
+
*/
|
|
30
|
+
browserSocketSessions: Map<WebSocket, string>;
|
|
24
31
|
browsers: Set<WebSocket>;
|
|
25
32
|
eventLog: import('@wrongstack/core/hq').HqEventEnvelope[];
|
|
26
33
|
transcripts: Map<string, TranscriptRing>;
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
readLocalSubagentTranscript,
|
|
11
11
|
sanitizeApiError,
|
|
12
12
|
startHqServer
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-YRC3I3LE.js";
|
|
14
14
|
import "./chunk-HXJYHAR4.js";
|
|
15
15
|
import "./chunk-5EA6OTLJ.js";
|
|
16
16
|
import "./chunk-Q7E3BPDU.js";
|
|
@@ -27,4 +27,4 @@ export {
|
|
|
27
27
|
sanitizeApiError,
|
|
28
28
|
startHqServer
|
|
29
29
|
};
|
|
30
|
-
//# sourceMappingURL=hq-server-
|
|
30
|
+
//# sourceMappingURL=hq-server-KE5YDNGG.js.map
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "./chunk-XJXDOF63.js";
|
|
9
9
|
import {
|
|
10
10
|
parseArgs
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-C3Z4N6A6.js";
|
|
12
12
|
|
|
13
13
|
// src/cli-entry-main.ts
|
|
14
14
|
async function main(argv) {
|
|
@@ -16,14 +16,14 @@ async function main(argv) {
|
|
|
16
16
|
applySessionShellDefault();
|
|
17
17
|
const earlyFlags = parseArgs(argv).flags;
|
|
18
18
|
if (earlyFlags["help"] === true || earlyFlags["version"] === true) {
|
|
19
|
-
const { handleHelpVersionShortCircuit } = await import("./short-circuit-flags-
|
|
19
|
+
const { handleHelpVersionShortCircuit } = await import("./short-circuit-flags-72E77TJI.js");
|
|
20
20
|
const earlyExit = await handleHelpVersionShortCircuit(argv);
|
|
21
21
|
if (earlyExit !== null) return earlyExit;
|
|
22
22
|
}
|
|
23
|
-
const { initializeCli } = await import("./cli-context-
|
|
23
|
+
const { initializeCli } = await import("./cli-context-5IF7ZYEY.js");
|
|
24
24
|
const cliCtx = await initializeCli(argv);
|
|
25
25
|
if (typeof cliCtx === "number") return cliCtx;
|
|
26
|
-
const { runInteractive } = await import("./cli-main-
|
|
26
|
+
const { runInteractive } = await import("./cli-main-WC5JNIWY.js");
|
|
27
27
|
return runInteractive(cliCtx);
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-YMXXOOFN.js";
|
|
7
7
|
|
|
8
8
|
// src/subcommands/handlers/mcp.ts
|
|
9
|
-
import { allServers } from "@wrongstack/core/infrastructure";
|
|
9
|
+
import { allServers, resolveMcpServerConfig } from "@wrongstack/core/infrastructure";
|
|
10
10
|
import {
|
|
11
11
|
expectDefined,
|
|
12
12
|
jsonObjectFileExists,
|
|
@@ -49,6 +49,15 @@ function parseToolsFlag(flags, positional) {
|
|
|
49
49
|
);
|
|
50
50
|
return set.size > 0 ? set : null;
|
|
51
51
|
}
|
|
52
|
+
function resolveServeHttpPort(flags) {
|
|
53
|
+
const raw = typeof flags["port"] === "string" ? flags["port"] : typeof flags["http"] === "string" ? flags["http"] : void 0;
|
|
54
|
+
if (raw === void 0 || raw.trim() === "") return 0;
|
|
55
|
+
const port = Number(raw);
|
|
56
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
57
|
+
throw new Error(`invalid --port "${raw}" \u2014 expected an integer between 0 and 65535`);
|
|
58
|
+
}
|
|
59
|
+
return port;
|
|
60
|
+
}
|
|
52
61
|
async function loadSelectedMcpServeContent(flags, cwd) {
|
|
53
62
|
const resources = [];
|
|
54
63
|
const prompts = [];
|
|
@@ -287,7 +296,13 @@ async function serveMcpStdio(deps, positional) {
|
|
|
287
296
|
});
|
|
288
297
|
const mode = yolo ? "yolo: all tools" : "safe: read-only tools";
|
|
289
298
|
if (flags["http"] === true || typeof flags["http"] === "string" || flags["port"] || flags["host"]) {
|
|
290
|
-
|
|
299
|
+
let port;
|
|
300
|
+
try {
|
|
301
|
+
port = resolveServeHttpPort(flags);
|
|
302
|
+
} catch (err) {
|
|
303
|
+
log(`wrongstack MCP server: ${err instanceof Error ? err.message : String(err)}`);
|
|
304
|
+
return 1;
|
|
305
|
+
}
|
|
291
306
|
const httpHost = typeof flags["host"] === "string" ? flags["host"] : "127.0.0.1";
|
|
292
307
|
const tokenFromArg = typeof flags["token"] === "string" ? flags["token"] : void 0;
|
|
293
308
|
const token = tokenFromArg ?? process.env.WRONGSTACK_MCP_TOKEN?.trim() ?? void 0;
|
|
@@ -344,10 +359,13 @@ var mcpCmd = async (args, deps) => {
|
|
|
344
359
|
deps.renderer.write("Use `wstack mcp add <name>` or set mcpServers in your config.\n");
|
|
345
360
|
return 0;
|
|
346
361
|
}
|
|
347
|
-
for (const [name,
|
|
348
|
-
const
|
|
349
|
-
const
|
|
350
|
-
|
|
362
|
+
for (const [name, entry] of Object.entries(servers)) {
|
|
363
|
+
const cfg = resolveMcpServerConfig(name, entry);
|
|
364
|
+
const status = entry?.enabled === false ? "disabled" : "enabled";
|
|
365
|
+
const description = cfg?.description ?? entry?.description;
|
|
366
|
+
const desc = description ? ` # ${description}` : "";
|
|
367
|
+
const transport = cfg?.transport ?? "invalid (no transport)";
|
|
368
|
+
deps.renderer.write(` ${name.padEnd(20)} ${transport.padEnd(16)} ${status}${desc}
|
|
351
369
|
`);
|
|
352
370
|
}
|
|
353
371
|
return 0;
|
|
@@ -391,7 +409,7 @@ async function addMcpServer(args, deps) {
|
|
|
391
409
|
deps.renderer.write("\nRun `wstack mcp add <name> --enable` to enable immediately.\n");
|
|
392
410
|
return 1;
|
|
393
411
|
}
|
|
394
|
-
const factory = BUILT_IN_MCP[name];
|
|
412
|
+
const factory = Object.hasOwn(BUILT_IN_MCP, name) ? BUILT_IN_MCP[name] : void 0;
|
|
395
413
|
if (!factory) {
|
|
396
414
|
deps.renderer.writeError(
|
|
397
415
|
`Unknown server "${name}". Run \`wstack mcp add\` without args to see available servers.
|
|
@@ -403,7 +421,7 @@ async function addMcpServer(args, deps) {
|
|
|
403
421
|
serverCfg.enabled = enable;
|
|
404
422
|
const existing = await readJsonObjectFile(configPath);
|
|
405
423
|
const mcpServers = isRecord(existing.mcpServers) ? existing.mcpServers : {};
|
|
406
|
-
if (mcpServers
|
|
424
|
+
if (Object.hasOwn(mcpServers, name))
|
|
407
425
|
deps.renderer.writeWarning(`Server "${name}" already in config. Updating.
|
|
408
426
|
`);
|
|
409
427
|
await updateJsonObjectFile(configPath, (config) => {
|
|
@@ -424,7 +442,7 @@ async function removeMcpServer(name, deps) {
|
|
|
424
442
|
}
|
|
425
443
|
const existing = await readJsonObjectFile(configPath);
|
|
426
444
|
const mcpServers = isRecord(existing.mcpServers) ? existing.mcpServers : {};
|
|
427
|
-
if (!mcpServers
|
|
445
|
+
if (!Object.hasOwn(mcpServers, name)) {
|
|
428
446
|
deps.renderer.writeError(`Server "${name}" not in config.
|
|
429
447
|
`);
|
|
430
448
|
return 1;
|
|
@@ -442,4 +460,4 @@ function isRecord(value) {
|
|
|
442
460
|
export {
|
|
443
461
|
mcpCmd
|
|
444
462
|
};
|
|
445
|
-
//# sourceMappingURL=mcp-
|
|
463
|
+
//# sourceMappingURL=mcp-DC5WSBOO.js.map
|
package/dist/mcp-serve.d.ts
CHANGED
|
@@ -45,6 +45,15 @@ export declare function yoloServePolicy(): AutoApprovePermissionPolicy;
|
|
|
45
45
|
* "flag present but no list" as an error, never as "no whitelist".
|
|
46
46
|
*/
|
|
47
47
|
export declare function parseToolsFlag(flags: Record<string, string | boolean>, positional?: readonly string[]): Set<string> | null;
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the TCP port for `mcp serve --http`.
|
|
50
|
+
*
|
|
51
|
+
* `--http` is also a boolean flag, and the old `Number(flags.port ?? flags.http)`
|
|
52
|
+
* turned a bare `--http` into `Number(true) === 1` — the server tried to bind
|
|
53
|
+
* privileged port 1 instead of an ephemeral one. A bare flag now means "pick a
|
|
54
|
+
* free port" (0); an explicit value must be an integer in 0–65535.
|
|
55
|
+
*/
|
|
56
|
+
export declare function resolveServeHttpPort(flags: Record<string, string | boolean>): number;
|
|
48
57
|
interface SelectedMcpServeContent {
|
|
49
58
|
resources: MCPServerResource[];
|
|
50
59
|
prompts: MCPServerPrompt[];
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared MCP management service.
|
|
3
|
-
* Contains the argument parser and the actual management logic shared between
|
|
4
|
-
* the CLI subcommand handler (packages/cli/src/subcommands/handlers/mcp.ts)
|
|
5
|
-
* and the slash-command wiring in index.ts.
|
|
6
|
-
*/
|
|
7
1
|
import type { Config, MCPServerConfig } from '@wrongstack/core/types';
|
|
8
2
|
import type { MCPRegistry } from '@wrongstack/mcp';
|
|
9
3
|
export interface McpParsedArgs {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handleHelpVersionShortCircuit
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TNZBQG45.js";
|
|
4
4
|
import "./chunk-6WRKAACA.js";
|
|
5
5
|
import "./chunk-XJXDOF63.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-C3Z4N6A6.js";
|
|
7
7
|
export {
|
|
8
8
|
handleHelpVersionShortCircuit
|
|
9
9
|
};
|
|
10
|
-
//# sourceMappingURL=short-circuit-flags-
|
|
10
|
+
//# sourceMappingURL=short-circuit-flags-72E77TJI.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack CLI — terminal AI coding agent with provider catalog from models.dev. Provides `wrongstack` and `wstack` binaries.",
|
|
6
6
|
"keywords": [
|
|
@@ -41,36 +41,36 @@
|
|
|
41
41
|
"data"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@wrongstack/acp": "1.0.
|
|
45
|
-
"@wrongstack/bench": "1.0.
|
|
46
|
-
"@wrongstack/core": "1.0.
|
|
47
|
-
"@wrongstack/kanban": "1.0.
|
|
48
|
-
"@wrongstack/mcp": "1.0.
|
|
49
|
-
"@wrongstack/persistence": "1.0.
|
|
50
|
-
"@wrongstack/plug-lsp": "1.0.
|
|
51
|
-
"@wrongstack/plugins": "1.0.
|
|
52
|
-
"@wrongstack/primitives": "1.0.
|
|
53
|
-
"@wrongstack/providers": "1.0.
|
|
54
|
-
"@wrongstack/requirement-intake": "1.0.
|
|
55
|
-
"@wrongstack/runtime": "1.0.
|
|
56
|
-
"@wrongstack/sage": "1.0.
|
|
57
|
-
"@wrongstack/sdd": "1.0.
|
|
58
|
-
"@wrongstack/security-scanner": "1.0.
|
|
59
|
-
"@wrongstack/simpleui": "1.0.
|
|
60
|
-
"@wrongstack/techstack": "1.0.
|
|
61
|
-
"@wrongstack/telegram": "1.0.
|
|
62
|
-
"@wrongstack/tools": "1.0.
|
|
63
|
-
"@wrongstack/tui": "1.0.
|
|
64
|
-
"@wrongstack/vector-memory": "1.0.
|
|
65
|
-
"@wrongstack/webui": "1.0.
|
|
66
|
-
"@wrongstack/webui-hq": "1.0.
|
|
67
|
-
"@wrongstack/webui-protocol": "1.0.
|
|
68
|
-
"@wrongstack/webui-server": "1.0.
|
|
69
|
-
"@wrongstack/wrongtrace": "1.0.
|
|
44
|
+
"@wrongstack/acp": "1.0.11",
|
|
45
|
+
"@wrongstack/bench": "1.0.11",
|
|
46
|
+
"@wrongstack/core": "1.0.11",
|
|
47
|
+
"@wrongstack/kanban": "1.0.11",
|
|
48
|
+
"@wrongstack/mcp": "1.0.11",
|
|
49
|
+
"@wrongstack/persistence": "1.0.11",
|
|
50
|
+
"@wrongstack/plug-lsp": "1.0.11",
|
|
51
|
+
"@wrongstack/plugins": "1.0.11",
|
|
52
|
+
"@wrongstack/primitives": "1.0.11",
|
|
53
|
+
"@wrongstack/providers": "1.0.11",
|
|
54
|
+
"@wrongstack/requirement-intake": "1.0.11",
|
|
55
|
+
"@wrongstack/runtime": "1.0.11",
|
|
56
|
+
"@wrongstack/sage": "1.0.11",
|
|
57
|
+
"@wrongstack/sdd": "1.0.11",
|
|
58
|
+
"@wrongstack/security-scanner": "1.0.11",
|
|
59
|
+
"@wrongstack/simpleui": "1.0.11",
|
|
60
|
+
"@wrongstack/techstack": "1.0.11",
|
|
61
|
+
"@wrongstack/telegram": "1.0.11",
|
|
62
|
+
"@wrongstack/tools": "1.0.11",
|
|
63
|
+
"@wrongstack/tui": "1.0.11",
|
|
64
|
+
"@wrongstack/vector-memory": "1.0.11",
|
|
65
|
+
"@wrongstack/webui": "1.0.11",
|
|
66
|
+
"@wrongstack/webui-hq": "1.0.11",
|
|
67
|
+
"@wrongstack/webui-protocol": "1.0.11",
|
|
68
|
+
"@wrongstack/webui-server": "1.0.11",
|
|
69
|
+
"@wrongstack/wrongtrace": "1.0.11",
|
|
70
70
|
"ws": "^8.21.3"
|
|
71
71
|
},
|
|
72
72
|
"optionalDependencies": {
|
|
73
|
-
"@wrongstack/desktop": "1.0.
|
|
73
|
+
"@wrongstack/desktop": "1.0.11"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@types/node": "^26.5.1",
|