@wrongstack/cli 1.0.17 → 1.0.19

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.
@@ -31,7 +31,7 @@ var loaders = {
31
31
  quick: async () => (await import("./quick-CNB4Z3HS.js")).quickCmd,
32
32
  bench: async () => (await import("./bench-YBU6BVQP.js")).benchCmd,
33
33
  chronicle: async () => (await import("./chronicle-UTFETHP6.js")).chronicleCmd,
34
- hq: async () => (await import("./hq-NU75W3SE.js")).hqCmd,
34
+ hq: async () => (await import("./hq-XQWQTRDA.js")).hqCmd,
35
35
  mailbox: async () => (await import("./mailbox-serve-3GFOK2I7.js")).mailboxServeCmd,
36
36
  permissions: async () => (await import("./permissions-CFDLXETM.js")).permissionsCmd,
37
37
  project: async () => (await import("./project-AOQI5XTK.js")).projectCmd,
@@ -51,4 +51,4 @@ export {
51
51
  subcommands,
52
52
  subcommandNames
53
53
  };
54
- //# sourceMappingURL=chunk-M4W3QLQW.js.map
54
+ //# sourceMappingURL=chunk-2CZEORLV.js.map
@@ -22,7 +22,7 @@ async function handleHelpVersionShortCircuit(argv) {
22
22
  }
23
23
  if (earlyFlags["help"] === true) {
24
24
  if (positional.length > 0) {
25
- const { subcommandNames } = await import("./subcommands-ERDDIJ3L.js");
25
+ const { subcommandNames } = await import("./subcommands-XSLXMIDP.js");
26
26
  if (subcommandNames.includes(positional[0])) {
27
27
  const first = positional[0];
28
28
  const deep = positional[1];
@@ -43,4 +43,4 @@ async function handleHelpVersionShortCircuit(argv) {
43
43
  export {
44
44
  handleHelpVersionShortCircuit
45
45
  };
46
- //# sourceMappingURL=chunk-VGER3HYZ.js.map
46
+ //# sourceMappingURL=chunk-2ENZU66X.js.map
@@ -33,7 +33,7 @@ import {
33
33
  import { randomUUID as randomUUID6 } from "node:crypto";
34
34
  import * as fs4 from "node:fs/promises";
35
35
  import * as http from "node:http";
36
- import * as path7 from "node:path";
36
+ import * as path8 from "node:path";
37
37
  import { getSharedProjectMailbox } from "@wrongstack/core/coordination";
38
38
  import {
39
39
  assessHqExposure as assessHqExposure2,
@@ -635,7 +635,7 @@ import {
635
635
  MailboxEventEmitter,
636
636
  MailboxHttpRateLimiter
637
637
  } from "@wrongstack/core/coordination";
638
- import * as path5 from "node:path";
638
+ import * as path6 from "node:path";
639
639
 
640
640
  // src/hq-static-serve.ts
641
641
  import * as fs2 from "node:fs";
@@ -2165,11 +2165,24 @@ async function authorizeHqCommand(input) {
2165
2165
  }
2166
2166
 
2167
2167
  // src/hq-server/routes/mailbox-handlers.ts
2168
- import * as path3 from "node:path";
2168
+ import * as path4 from "node:path";
2169
2169
  import { resolveProjectDir } from "@wrongstack/core/coordination";
2170
2170
 
2171
2171
  // src/hq-server/project-root.ts
2172
+ import * as fsp from "node:fs/promises";
2173
+ import * as path3 from "node:path";
2172
2174
  import { deriveHqProjectId } from "@wrongstack/core/hq";
2175
+ function isPlainSegment(value) {
2176
+ return value.length > 0 && value !== "." && value !== ".." && !value.includes("/") && !value.includes("\\") && !path3.isAbsolute(value);
2177
+ }
2178
+ async function projectDirectoryExists(globalRoot, projectId) {
2179
+ if (!isPlainSegment(projectId)) return false;
2180
+ try {
2181
+ return (await fsp.stat(path3.join(globalRoot, "projects", projectId))).isDirectory();
2182
+ } catch {
2183
+ return false;
2184
+ }
2185
+ }
2173
2186
  function resolveHqProjectRoot(globalRoot, ids) {
2174
2187
  const fn = async () => {
2175
2188
  const { getSessionRegistry } = await import("@wrongstack/core/storage");
@@ -2177,7 +2190,7 @@ function resolveHqProjectRoot(globalRoot, ids) {
2177
2190
  const registry = getSessionRegistry(globalRoot);
2178
2191
  if (typeof ids.sessionId === "string") {
2179
2192
  const entry = await registry.get(ids.sessionId).catch(() => null);
2180
- if (entry?.projectRoot) return entry.projectRoot;
2193
+ if (entry?.projectRoot) return { status: "found", projectRoot: entry.projectRoot };
2181
2194
  }
2182
2195
  if (typeof ids.projectId === "string") {
2183
2196
  const { createHash: createHash2 } = await import("node:crypto");
@@ -2193,11 +2206,15 @@ function resolveHqProjectRoot(globalRoot, ids) {
2193
2206
  const match = all.find(
2194
2207
  (e) => e.projectSlug === ids.projectId || projectIdForRoot(e.projectRoot) === ids.projectId || createHash2("sha256").update(e.projectRoot).digest("hex").slice(0, 12) === ids.projectId
2195
2208
  );
2196
- if (match) return match.projectRoot;
2209
+ if (match) return { status: "found", projectRoot: match.projectRoot };
2210
+ if (await projectDirectoryExists(globalRoot, ids.projectId)) {
2211
+ return { status: "unavailable" };
2212
+ }
2197
2213
  }
2198
2214
  } catch {
2215
+ return { status: "unavailable" };
2199
2216
  }
2200
- return void 0;
2217
+ return { status: "unknown" };
2201
2218
  };
2202
2219
  return fn();
2203
2220
  }
@@ -2221,7 +2238,7 @@ async function handleMailboxGateway(_req, res, match, authorizeMailboxGateway, g
2221
2238
  );
2222
2239
  return;
2223
2240
  }
2224
- const gatewayGlobalRoot = path3.dirname(dataDir);
2241
+ const gatewayGlobalRoot = path4.dirname(dataDir);
2225
2242
  const preliminaryAccess = authorizeMailboxGateway(_req, `project:${projectId}`);
2226
2243
  if (!preliminaryAccess.allowed) {
2227
2244
  res.writeHead(preliminaryAccess.status ?? 401, {
@@ -2231,14 +2248,27 @@ async function handleMailboxGateway(_req, res, match, authorizeMailboxGateway, g
2231
2248
  res.end(JSON.stringify(preliminaryAccess.body));
2232
2249
  return;
2233
2250
  }
2234
- const projectRoot = await resolveHqProjectRoot(gatewayGlobalRoot, { projectId });
2235
- if (!projectRoot) {
2251
+ const resolution = await resolveHqProjectRoot(gatewayGlobalRoot, { projectId });
2252
+ if (resolution.status === "unavailable") {
2253
+ res.writeHead(503, { "Content-Type": "application/json", "Retry-After": "1" });
2254
+ res.end(
2255
+ JSON.stringify({
2256
+ error: {
2257
+ code: "UNAVAILABLE",
2258
+ message: `Project ${projectId} is not reachable right now; retry shortly.`
2259
+ }
2260
+ })
2261
+ );
2262
+ return;
2263
+ }
2264
+ if (resolution.status !== "found") {
2236
2265
  res.writeHead(404, { "Content-Type": "application/json" });
2237
2266
  res.end(
2238
2267
  JSON.stringify({ error: { code: "NOT_FOUND", message: `Unknown project: ${projectId}` } })
2239
2268
  );
2240
2269
  return;
2241
2270
  }
2271
+ const projectRoot = resolution.projectRoot;
2242
2272
  const suffix = match[2];
2243
2273
  const rawUrl = _req.url ?? "";
2244
2274
  const queryIndex = rawUrl.indexOf("?");
@@ -2287,16 +2317,22 @@ async function handleApiMailboxSend(_req, res, mutableAuth, sessions, dataDir, g
2287
2317
  res.end(JSON.stringify({ error: "audience must be all or leaders" }));
2288
2318
  return;
2289
2319
  }
2290
- const mbGlobalRoot = path3.dirname(dataDir);
2291
- const projectRoot = await resolveHqProjectRoot(mbGlobalRoot, {
2320
+ const mbGlobalRoot = path4.dirname(dataDir);
2321
+ const mbResolution = await resolveHqProjectRoot(mbGlobalRoot, {
2292
2322
  sessionId: mbody.sessionId,
2293
2323
  projectId: mbody.projectId
2294
2324
  });
2295
- if (typeof projectRoot !== "string" || projectRoot.length === 0) {
2325
+ if (mbResolution.status === "unavailable") {
2326
+ res.writeHead(503, { "Content-Type": "application/json", "Retry-After": "1" });
2327
+ res.end(JSON.stringify({ error: "target project mailbox is not reachable right now" }));
2328
+ return;
2329
+ }
2330
+ if (mbResolution.status !== "found" || mbResolution.projectRoot.length === 0) {
2296
2331
  res.writeHead(404, { "Content-Type": "application/json" });
2297
2332
  res.end(JSON.stringify({ error: "could not resolve target project mailbox" }));
2298
2333
  return;
2299
2334
  }
2335
+ const projectRoot = mbResolution.projectRoot;
2300
2336
  const to = typeof mbody.to === "string" ? mbody.to : "leader";
2301
2337
  const subject = typeof mbody.subject === "string" ? mbody.subject : "HQ prompt";
2302
2338
  const priority = mbody.priority === "high" ? "high" : mbody.priority === "low" ? "low" : "normal";
@@ -2407,16 +2443,22 @@ async function handleMailboxAction(_req, res, match, mutableAuth, sessions, data
2407
2443
  res.end(JSON.stringify({ error: "missing sessionId or projectId" }));
2408
2444
  return;
2409
2445
  }
2410
- const actGlobalRoot = path3.dirname(dataDir);
2411
- const projectRoot = await resolveHqProjectRoot(actGlobalRoot, {
2446
+ const actGlobalRoot = path4.dirname(dataDir);
2447
+ const actResolution = await resolveHqProjectRoot(actGlobalRoot, {
2412
2448
  sessionId: abody.sessionId,
2413
2449
  projectId: abody.projectId
2414
2450
  });
2415
- if (typeof projectRoot !== "string" || projectRoot.length === 0) {
2451
+ if (actResolution.status === "unavailable") {
2452
+ res.writeHead(503, { "Content-Type": "application/json", "Retry-After": "1" });
2453
+ res.end(JSON.stringify({ error: "target project mailbox is not reachable right now" }));
2454
+ return;
2455
+ }
2456
+ if (actResolution.status !== "found" || actResolution.projectRoot.length === 0) {
2416
2457
  res.writeHead(404, { "Content-Type": "application/json" });
2417
2458
  res.end(JSON.stringify({ error: "could not resolve target project mailbox" }));
2418
2459
  return;
2419
2460
  }
2461
+ const projectRoot = actResolution.projectRoot;
2420
2462
  try {
2421
2463
  const { actionToAckInput } = await import("@wrongstack/core/coordination");
2422
2464
  const projectDir = resolveProjectDir(projectRoot, actGlobalRoot);
@@ -2647,14 +2689,14 @@ async function handleApiTrendsCost(req, res, persistence) {
2647
2689
  }
2648
2690
 
2649
2691
  // src/hq-server/routes/session-handlers.ts
2650
- import * as path4 from "node:path";
2692
+ import * as path5 from "node:path";
2651
2693
  import {
2652
2694
  buildTranscriptFromEvents,
2653
2695
  resolveHqDataDir
2654
2696
  } from "@wrongstack/core/hq";
2655
2697
  async function handleApiSessions(res) {
2656
2698
  const { getSessionRegistry } = await import("@wrongstack/core/storage");
2657
- const globalRoot = path4.dirname(resolveHqDataDir());
2699
+ const globalRoot = path5.dirname(resolveHqDataDir());
2658
2700
  try {
2659
2701
  const registry = getSessionRegistry(globalRoot);
2660
2702
  const sessions = await registry.list();
@@ -2699,7 +2741,7 @@ async function handleApiSessionEvents(req, res, match, transcripts) {
2699
2741
  res.end(JSON.stringify({ error: "invalid sessionId encoding" }));
2700
2742
  return;
2701
2743
  }
2702
- const globalRoot = path4.dirname(resolveHqDataDir());
2744
+ const globalRoot = path5.dirname(resolveHqDataDir());
2703
2745
  try {
2704
2746
  const registry = getSessionRegistry(globalRoot);
2705
2747
  const entry = await registry.get(sessionId).catch(() => null);
@@ -3430,7 +3472,7 @@ var MailboxGatewayManager = class {
3430
3472
  const lastUsed = this.mailboxGatewayLastUsed.get(projectDir);
3431
3473
  gateways.push({
3432
3474
  // projectId = basename(projectDir) — matches the credential contract.
3433
- projectId: path5.basename(projectDir),
3475
+ projectId: path6.basename(projectDir),
3434
3476
  projectRoot: projectDir,
3435
3477
  hasActiveStreams: gateway.router.hasActiveStreams(),
3436
3478
  lastUsedAt: typeof lastUsed === "number" ? lastUsed : null,
@@ -3520,7 +3562,7 @@ async function prepareHqServerStart(options, defaults) {
3520
3562
 
3521
3563
  // src/hq-server/startup.ts
3522
3564
  import * as fs3 from "node:fs/promises";
3523
- import * as path6 from "node:path";
3565
+ import * as path7 from "node:path";
3524
3566
  import { writeHqRuntimeFile } from "@wrongstack/core/hq";
3525
3567
  var hqRuntimeMarkerPath2 = hqRuntimeMarkerPath;
3526
3568
  async function writeHqRuntimeMarker(dataDir, url) {
@@ -3601,7 +3643,7 @@ HQ auth loaded from ${startup.dataDir}
3601
3643
  if (startup.clientEnv.WRONGSTACK_HQ_TOKEN) {
3602
3644
  write(` WRONGSTACK_HQ_TOKEN=${startup.clientEnv.WRONGSTACK_HQ_TOKEN}
3603
3645
  `);
3604
- write(`Credentials are stored in ${path6.join(startup.dataDir, "auth.json")}
3646
+ write(`Credentials are stored in ${path7.join(startup.dataDir, "auth.json")}
3605
3647
  `);
3606
3648
  }
3607
3649
  writeHqLanEndpoints(write, handle, void 0);
@@ -4731,12 +4773,12 @@ async function startHqServerWithAuth(options, host, port, dataDir, firstRunAuth)
4731
4773
  const persistence = createHqPersistence(dataDir);
4732
4774
  const auditLog = new HqCommandAuditLog(1e3, (entry) => persistence.commandLog.append(entry));
4733
4775
  void (async () => {
4734
- const projectsDir = path7.join(path7.dirname(dataDir), "projects");
4776
+ const projectsDir = path8.join(path8.dirname(dataDir), "projects");
4735
4777
  const entries = await fs4.readdir(projectsDir, { withFileTypes: true }).catch(() => []);
4736
4778
  await Promise.all(
4737
4779
  entries.filter((entry) => entry.isDirectory()).map(async (entry) => {
4738
- const projectDir = path7.join(projectsDir, entry.name);
4739
- const metadataPath = path7.join(projectDir, ".mailbox-server.json");
4780
+ const projectDir = path8.join(projectsDir, entry.name);
4781
+ const metadataPath = path8.join(projectDir, ".mailbox-server.json");
4740
4782
  const ownerPid = await fs4.readFile(metadataPath, "utf8").then((raw) => JSON.parse(raw).pid).catch(() => void 0);
4741
4783
  if (ownerPid === void 0) return;
4742
4784
  let ownerAlive = false;
@@ -5104,4 +5146,4 @@ export {
5104
5146
  startHqServer,
5105
5147
  HqInsecureExposureError2 as HqInsecureExposureError
5106
5148
  };
5107
- //# sourceMappingURL=chunk-K5PAL6KR.js.map
5149
+ //# sourceMappingURL=chunk-KK2LB3ZS.js.map
@@ -19,17 +19,17 @@ import {
19
19
  } from "./chunk-GPPRNAKW.js";
20
20
  import {
21
21
  subcommands
22
- } from "./chunk-M4W3QLQW.js";
22
+ } from "./chunk-2CZEORLV.js";
23
23
  import {
24
24
  renderDeepHelp,
25
25
  renderFocusedHelp
26
26
  } from "./chunk-JX6KL7OF.js";
27
27
  import {
28
28
  handleHelpVersionShortCircuit
29
- } from "./chunk-VGER3HYZ.js";
29
+ } from "./chunk-2ENZU66X.js";
30
30
  import {
31
31
  DEFAULT_PORT
32
- } from "./chunk-K5PAL6KR.js";
32
+ } from "./chunk-KK2LB3ZS.js";
33
33
  import "./chunk-HXJYHAR4.js";
34
34
  import {
35
35
  resolveHqPasswordInput
@@ -866,7 +866,7 @@ async function isPortInUse(host, port) {
866
866
  }
867
867
  async function handleHqShortCircuit(flags) {
868
868
  if (flags["hq"] !== true) return null;
869
- const { startHqServer } = await import("./hq-server-M2JWVW4D.js");
869
+ const { startHqServer } = await import("./hq-server-IIBZQZU4.js");
870
870
  const tunnelRequested = flags["tunnel"] === true;
871
871
  const rawPublicUrl = typeof flags["hq-public-url"] === "string" ? flags["hq-public-url"] : process.env.WRONGSTACK_HQ_PUBLIC_URL;
872
872
  let publicOrigin;
@@ -3303,4 +3303,4 @@ async function initializeCli(argv) {
3303
3303
  export {
3304
3304
  initializeCli
3305
3305
  };
3306
- //# sourceMappingURL=cli-context-4PTWEK52.js.map
3306
+ //# sourceMappingURL=cli-context-33F74CSZ.js.map
@@ -5,6 +5,7 @@ import {
5
5
  normalizeTuiThinkingWord,
6
6
  removeSuggestions,
7
7
  runGit,
8
+ setAutoSuggestions,
8
9
  setSuggestions
9
10
  } from "./chunk-OWNC7LMD.js";
10
11
  import {
@@ -26389,9 +26390,14 @@ function buildSuggestPrompt(contextText) {
26389
26390
  "Based on the current project state below, generate 3-5 exact natural-language",
26390
26391
  "prompt messages that the user could submit back to the coding agent through the",
26391
26392
  "TUI or WebUI. Each prompt must ask the agent to perform useful work immediately.",
26393
+ "Generate prompt messages only; do not execute the proposed work in this request.",
26392
26394
  "Agent-directed imperatives are valid and do not need to be shell commands.",
26393
26395
  "Never output a human-only chore or an instruction that expects the user to do",
26394
26396
  "the work after selecting it. Be specific \u2014 mention relevant files or tools.",
26397
+ "The recipient is the LLM, not the user. Each item is submitted verbatim as",
26398
+ "the next user prompt: name the target, action, and useful verification or output.",
26399
+ "Omit approval requests, questions for the user, and mixed agent/human checklists.",
26400
+ "Use the user's language when it is known from the supplied context.",
26395
26401
  "Do NOT include preamble, explanation, or wrap the output in code blocks.",
26396
26402
  "",
26397
26403
  "Rules:",
@@ -26409,8 +26415,9 @@ function buildSuggestPrompt(contextText) {
26409
26415
  ].join("\n");
26410
26416
  }
26411
26417
  var SUGGEST_CACHE_TTL_MS = 6e4;
26412
- var suggestCache = null;
26413
26418
  function buildSuggestCommand(opts) {
26419
+ let suggestCache;
26420
+ let requestVersion = 0;
26414
26421
  return {
26415
26422
  name: "suggest",
26416
26423
  aliases: ["next-steps", "what-next"],
@@ -26429,25 +26436,37 @@ function buildSuggestCommand(opts) {
26429
26436
  "",
26430
26437
  "Use `/next list` to see the current suggestions at any time."
26431
26438
  ].join("\n"),
26432
- async run(args, _ctx) {
26433
- const trimmed = args.trim().toLowerCase();
26434
- const fast = /\b(--fast|-f)\b/.test(trimmed);
26435
- const fresh = /--fresh\b/.test(trimmed);
26439
+ async run(args, ctx) {
26440
+ const flags = new Set(args.trim().toLowerCase().split(/\s+/));
26441
+ const fast = flags.has("--fast") || flags.has("-f");
26442
+ const fresh = flags.has("--fresh");
26443
+ const context = ctx ?? opts.context;
26444
+ const currentScope = () => JSON.stringify([opts.projectRoot, opts.cwd, context?.session?.id]);
26445
+ const scope = currentScope();
26446
+ const lastMessage = context?.messages?.at(-1);
26447
+ const version = ++requestVersion;
26448
+ const isCurrent = () => version === requestVersion && scope === currentScope() && lastMessage === context?.messages?.at(-1);
26449
+ const superseded = () => ({ message: color52.dim("Discarded stale suggestion result.") });
26450
+ setAutoSuggestions([]);
26436
26451
  if (fast) {
26452
+ suggestCache = void 0;
26437
26453
  const suggestions = await generateHeuristicSuggestions(opts);
26454
+ if (!isCurrent()) return superseded();
26438
26455
  setSuggestions(suggestions);
26439
26456
  opts.onSuggestions?.(suggestions);
26440
26457
  const display = formatSuggestions(suggestions);
26441
26458
  return { message: display };
26442
26459
  }
26443
26460
  if (!opts.onSpawnAndWait) {
26461
+ suggestCache = void 0;
26444
26462
  const suggestions = await generateHeuristicSuggestions(opts);
26463
+ if (!isCurrent()) return superseded();
26445
26464
  setSuggestions(suggestions);
26446
26465
  opts.onSuggestions?.(suggestions);
26447
26466
  const display = formatSuggestions(suggestions) + "\n" + color52.dim("(Heuristic fallback \u2014 multi-agent not enabled)");
26448
26467
  return { message: display };
26449
26468
  }
26450
- if (!fresh && suggestCache && Date.now() - suggestCache.at < SUGGEST_CACHE_TTL_MS) {
26469
+ if (!fresh && suggestCache?.context === context && suggestCache?.scope === scope && suggestCache?.lastMessage === lastMessage && Date.now() - suggestCache.at < SUGGEST_CACHE_TTL_MS) {
26451
26470
  setSuggestions(suggestCache.suggestions);
26452
26471
  opts.onSuggestions?.(suggestCache.suggestions);
26453
26472
  const ageSec = Math.round((Date.now() - suggestCache.at) / 1e3);
@@ -26455,28 +26474,26 @@ function buildSuggestCommand(opts) {
26455
26474
  message: formatSuggestions(suggestCache.suggestions) + "\n" + color52.dim(`(cached ${ageSec}s ago \u2014 /suggest --fresh to regenerate)`)
26456
26475
  };
26457
26476
  }
26477
+ suggestCache = void 0;
26458
26478
  const contextText = await collectContext({
26459
26479
  cwd: opts.cwd,
26460
26480
  projectRoot: opts.projectRoot
26461
26481
  });
26482
+ if (!isCurrent()) return superseded();
26462
26483
  const task = buildSuggestPrompt(contextText);
26463
26484
  opts.renderer.write(color52.dim("Generating suggestions..."));
26464
26485
  try {
26465
26486
  const raw = await opts.onSpawnAndWait(task, {
26466
26487
  name: "suggest"
26467
26488
  });
26489
+ if (!isCurrent()) return superseded();
26468
26490
  const suggestions = parseSuggestions(raw);
26469
- if (suggestions.length === 0) {
26470
- const fallback = [];
26471
- setSuggestions(fallback);
26472
- opts.onSuggestions?.(fallback);
26473
- return { message: formatSuggestions(fallback) };
26474
- }
26475
26491
  setSuggestions(suggestions);
26476
26492
  opts.onSuggestions?.(suggestions);
26477
- suggestCache = { suggestions, at: Date.now() };
26493
+ suggestCache = { suggestions, at: Date.now(), context, scope, lastMessage };
26478
26494
  return { message: formatSuggestions(suggestions) };
26479
26495
  } catch (err) {
26496
+ if (!isCurrent()) return superseded();
26480
26497
  const msg = `Suggestion generation failed: ${toErrorMessage24(err)}`;
26481
26498
  opts.renderer.writeWarning(msg);
26482
26499
  return { message: msg };
@@ -26486,12 +26503,10 @@ function buildSuggestCommand(opts) {
26486
26503
  }
26487
26504
  function parseSuggestions(raw) {
26488
26505
  const trimmed = raw.trim();
26489
- if (/^none\b/i.test(trimmed) || /no (?:pending actions|further steps)/i.test(trimmed)) {
26506
+ if (/^none[.!]?$/i.test(trimmed)) {
26490
26507
  return [];
26491
26508
  }
26492
- const { texts } = parseNextSteps(raw, false);
26493
- if (texts.length > 0) return texts;
26494
- return raw.split("\n").map((l) => l.trim()).filter((l) => l.length > 10 && !l.startsWith("#") && !l.startsWith("```")).slice(0, 5);
26509
+ return parseNextSteps(raw, false).texts.slice(0, 5);
26495
26510
  }
26496
26511
  async function pathExists2(filePath) {
26497
26512
  try {
@@ -39114,4 +39129,4 @@ export {
39114
39129
  CLI_VERSION,
39115
39130
  runInteractive
39116
39131
  };
39117
- //# sourceMappingURL=cli-main-DQ2GBY7M.js.map
39132
+ //# sourceMappingURL=cli-main-FNGMKPBA.js.map
@@ -68,7 +68,7 @@ var hqCmd = async (args, deps) => {
68
68
  return 1;
69
69
  };
70
70
  async function startServer(deps) {
71
- const { startHqServer } = await import("./hq-server-M2JWVW4D.js");
71
+ const { startHqServer } = await import("./hq-server-IIBZQZU4.js");
72
72
  const dataDir = resolveDataDir(deps);
73
73
  const flags = deps.flags ?? {};
74
74
  const rawPublicUrl = typeof flags["hq-public-url"] === "string" ? flags["hq-public-url"] : process.env.WRONGSTACK_HQ_PUBLIC_URL;
@@ -987,4 +987,4 @@ export {
987
987
  hqCmd,
988
988
  resolveAuditActor
989
989
  };
990
- //# sourceMappingURL=hq-NU75W3SE.js.map
990
+ //# sourceMappingURL=hq-XQWQTRDA.js.map
@@ -1,5 +1,39 @@
1
+ /**
2
+ * Why this is not just `string | undefined`.
3
+ *
4
+ * Resolution walks `ProjectSessionRegistry.list()`, which probes each known
5
+ * project's session-catalog daemon with `callExisting` — a path that must never
6
+ * spawn — and turns EVERY per-project failure into an empty result: metadata not
7
+ * yet written, the daemon gone, the IPC connect refused, a timeout. The gateway
8
+ * then reported that as `404 Unknown project`, which is indistinguishable from
9
+ * "this project does not exist".
10
+ *
11
+ * That conflation is observable: a session lease lives 30s and is renewed every
12
+ * 5s, so under heavy load a live project's daemon can lapse and exit, and a
13
+ * perfectly real project answers 404 for a moment. The caller cannot tell a
14
+ * permanent negative from a blip, so it cannot know whether retrying is
15
+ * sensible.
16
+ *
17
+ * The on-disk project directory is the discriminator: it is created when the
18
+ * project first gets a daemon and it outlives that daemon (only the metadata
19
+ * file is removed on exit). A directory therefore means "this machine knows
20
+ * this project, it just is not answering right now" — transient. No directory
21
+ * means genuinely unknown.
22
+ */
23
+ export type HqProjectResolution = {
24
+ status: 'found';
25
+ projectRoot: string;
26
+ }
27
+ /** No such project on this machine. A retry will not help. */
28
+ | {
29
+ status: 'unknown';
30
+ }
31
+ /** The project is known but could not be resolved right now; retry may help. */
32
+ | {
33
+ status: 'unavailable';
34
+ };
1
35
  export declare function resolveHqProjectRoot(globalRoot: string, ids: {
2
36
  sessionId?: string | undefined;
3
37
  projectId?: string | undefined;
4
- }): Promise<string | undefined>;
38
+ }): Promise<HqProjectResolution>;
5
39
  //# sourceMappingURL=project-root.d.ts.map
@@ -10,7 +10,7 @@ import {
10
10
  readLocalSubagentTranscript,
11
11
  sanitizeApiError,
12
12
  startHqServer
13
- } from "./chunk-K5PAL6KR.js";
13
+ } from "./chunk-KK2LB3ZS.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-M2JWVW4D.js.map
30
+ //# sourceMappingURL=hq-server-IIBZQZU4.js.map
package/dist/index.js CHANGED
@@ -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-SJQBJ33I.js");
19
+ const { handleHelpVersionShortCircuit } = await import("./short-circuit-flags-7GQIGMVD.js");
20
20
  const earlyExit = await handleHelpVersionShortCircuit(argv);
21
21
  if (earlyExit !== null) return earlyExit;
22
22
  }
23
- const { initializeCli } = await import("./cli-context-4PTWEK52.js");
23
+ const { initializeCli } = await import("./cli-context-33F74CSZ.js");
24
24
  const cliCtx = await initializeCli(argv);
25
25
  if (typeof cliCtx === "number") return cliCtx;
26
- const { runInteractive } = await import("./cli-main-DQ2GBY7M.js");
26
+ const { runInteractive } = await import("./cli-main-FNGMKPBA.js");
27
27
  return runInteractive(cliCtx);
28
28
  }
29
29
 
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  handleHelpVersionShortCircuit
3
- } from "./chunk-VGER3HYZ.js";
3
+ } from "./chunk-2ENZU66X.js";
4
4
  import "./chunk-6WRKAACA.js";
5
5
  import "./chunk-XJXDOF63.js";
6
6
  import "./chunk-C3Z4N6A6.js";
7
7
  export {
8
8
  handleHelpVersionShortCircuit
9
9
  };
10
- //# sourceMappingURL=short-circuit-flags-SJQBJ33I.js.map
10
+ //# sourceMappingURL=short-circuit-flags-7GQIGMVD.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  subcommandNames,
3
3
  subcommands
4
- } from "./chunk-M4W3QLQW.js";
4
+ } from "./chunk-2CZEORLV.js";
5
5
  export {
6
6
  subcommandNames,
7
7
  subcommands
8
8
  };
9
- //# sourceMappingURL=subcommands-ERDDIJ3L.js.map
9
+ //# sourceMappingURL=subcommands-XSLXMIDP.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/cli",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
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.17",
45
- "@wrongstack/bench": "1.0.17",
46
- "@wrongstack/core": "1.0.17",
47
- "@wrongstack/kanban": "1.0.17",
48
- "@wrongstack/mcp": "1.0.17",
49
- "@wrongstack/persistence": "1.0.17",
50
- "@wrongstack/plug-lsp": "1.0.17",
51
- "@wrongstack/plugins": "1.0.17",
52
- "@wrongstack/primitives": "1.0.17",
53
- "@wrongstack/providers": "1.0.17",
54
- "@wrongstack/requirement-intake": "1.0.17",
55
- "@wrongstack/runtime": "1.0.17",
56
- "@wrongstack/sage": "1.0.17",
57
- "@wrongstack/sdd": "1.0.17",
58
- "@wrongstack/security-scanner": "1.0.17",
59
- "@wrongstack/simpleui": "1.0.17",
60
- "@wrongstack/techstack": "1.0.17",
61
- "@wrongstack/telegram": "1.0.17",
62
- "@wrongstack/tools": "1.0.17",
63
- "@wrongstack/tui": "1.0.17",
64
- "@wrongstack/vector-memory": "1.0.17",
65
- "@wrongstack/webui": "1.0.17",
66
- "@wrongstack/webui-hq": "1.0.17",
67
- "@wrongstack/webui-protocol": "1.0.17",
68
- "@wrongstack/webui-server": "1.0.17",
69
- "@wrongstack/wrongtrace": "1.0.17",
44
+ "@wrongstack/acp": "1.0.19",
45
+ "@wrongstack/bench": "1.0.19",
46
+ "@wrongstack/core": "1.0.19",
47
+ "@wrongstack/kanban": "1.0.19",
48
+ "@wrongstack/mcp": "1.0.19",
49
+ "@wrongstack/persistence": "1.0.19",
50
+ "@wrongstack/plug-lsp": "1.0.19",
51
+ "@wrongstack/plugins": "1.0.19",
52
+ "@wrongstack/primitives": "1.0.19",
53
+ "@wrongstack/providers": "1.0.19",
54
+ "@wrongstack/requirement-intake": "1.0.19",
55
+ "@wrongstack/runtime": "1.0.19",
56
+ "@wrongstack/sage": "1.0.19",
57
+ "@wrongstack/sdd": "1.0.19",
58
+ "@wrongstack/security-scanner": "1.0.19",
59
+ "@wrongstack/simpleui": "1.0.19",
60
+ "@wrongstack/techstack": "1.0.19",
61
+ "@wrongstack/telegram": "1.0.19",
62
+ "@wrongstack/tools": "1.0.19",
63
+ "@wrongstack/tui": "1.0.19",
64
+ "@wrongstack/vector-memory": "1.0.19",
65
+ "@wrongstack/webui": "1.0.19",
66
+ "@wrongstack/webui-hq": "1.0.19",
67
+ "@wrongstack/webui-protocol": "1.0.19",
68
+ "@wrongstack/webui-server": "1.0.19",
69
+ "@wrongstack/wrongtrace": "1.0.19",
70
70
  "ws": "^8.21.3"
71
71
  },
72
72
  "optionalDependencies": {
73
- "@wrongstack/desktop": "1.0.17"
73
+ "@wrongstack/desktop": "1.0.19"
74
74
  },
75
75
  "devDependencies": {
76
76
  "@types/node": "^26.5.1",