@lawaty/lacode 1.3.0-beta.8 → 1.3.0-beta.9

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/CHANGELOG.md CHANGED
@@ -9,6 +9,14 @@ commit as the changelog entry it describes.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [1.3.0-beta.9] — a timeline reply without bullets still lands
13
+
14
+ ### Fixed
15
+
16
+ - Timeline: a summarizer reply that arrives only as reasoning content is now read, so a rebuild no longer produces an empty timeline.
17
+ - Timeline: a non-bulleted summary is salvaged into entries instead of aborting the rebuild with `no bullet lines`.
18
+ - Timeline: summarizer failures now report the underlying message instead of `[object Object]`.
19
+
12
20
  ## [1.3.0-beta.8] — a blocked child is never silent
13
21
 
14
22
  ### Added
@@ -1097,7 +1105,8 @@ experimental; `latest` remains 0.4.2.
1097
1105
 
1098
1106
  - First published release: pooled subagents over a shared set of models.
1099
1107
 
1100
- [Unreleased]: https://github.com/lawaty/lacode/compare/v1.3.0-beta.8...HEAD
1108
+ [Unreleased]: https://github.com/lawaty/lacode/compare/v1.3.0-beta.9...HEAD
1109
+ [1.3.0-beta.9]: https://github.com/lawaty/lacode/releases/tag/v1.3.0-beta.9
1101
1110
  [1.3.0-beta.8]: https://github.com/lawaty/lacode/releases/tag/v1.3.0-beta.8
1102
1111
  [1.3.0-beta.0]: https://github.com/lawaty/lacode/releases/tag/v1.3.0-beta.0
1103
1112
  [1.2.0]: https://github.com/lawaty/lacode/compare/v1.1.0...v1.2.0
package/dist/index.js CHANGED
@@ -6987,6 +6987,29 @@ function parseBullets(text, max = 6) {
6987
6987
  }
6988
6988
  return result;
6989
6989
  }
6990
+ function salvageBullets(text, max = 6) {
6991
+ const result = [];
6992
+ const seen = /* @__PURE__ */ new Set();
6993
+ for (const raw of text.split("\n")) {
6994
+ let line = raw.trim();
6995
+ if (!line) continue;
6996
+ if (line.startsWith("```")) continue;
6997
+ if (line.startsWith("#")) continue;
6998
+ if (line.length > 320) continue;
6999
+ line = line.replace(/^([-*+•]|\d+[.)])\s*/, "").trim();
7000
+ if (!line) continue;
7001
+ line = line.replace(/`/g, "").replace(/\*\*/g, "").replace(/__/g, "").trim();
7002
+ const cleaned = stripAnsiAndControls(line).trim();
7003
+ if (!cleaned || cleaned.length > 320) continue;
7004
+ if (cleaned.endsWith(":")) continue;
7005
+ const key = cleaned.toLowerCase();
7006
+ if (seen.has(key)) continue;
7007
+ seen.add(key);
7008
+ result.push(cleaned);
7009
+ if (result.length >= max) break;
7010
+ }
7011
+ return result;
7012
+ }
6990
7013
  function isInternalTitle(title) {
6991
7014
  const t = (title ?? "").trim();
6992
7015
  return t.startsWith("context (auto") || t.startsWith("timeline (auto") || t.startsWith("pool probe");
@@ -7047,6 +7070,20 @@ This:
7047
7070
  - Providers: replaced the retired Gemini 2.5 Flash with Gemini 3.5 Flash.
7048
7071
 
7049
7072
  Your entire response must consist only of lines beginning with "- ".`;
7073
+ function errorText(value) {
7074
+ if (value instanceof Error) return value.message;
7075
+ if (typeof value === "string") return value;
7076
+ if (value && typeof value === "object") {
7077
+ const message = value.message;
7078
+ if (typeof message === "string" && message) return message;
7079
+ try {
7080
+ return JSON.stringify(value);
7081
+ } catch {
7082
+ return String(value);
7083
+ }
7084
+ }
7085
+ return String(value);
7086
+ }
7050
7087
  function timelineHooks(input, options) {
7051
7088
  const { client, directory } = input;
7052
7089
  const opts = options ?? {};
@@ -7210,21 +7247,31 @@ function timelineHooks(input, options) {
7210
7247
  }
7211
7248
  const failure = result?.error ?? result?.data?.info?.error;
7212
7249
  if (timedOut || failure !== void 0) {
7213
- return { ok: false, bullets: [], error: timedOut ? "timed out" : String(failure) };
7214
- } else {
7215
- const text = (result?.data?.parts ?? []).map((part) => part.type === "text" ? part.text ?? "" : "").join("\n");
7216
- const bullets = parseBullets(text, maxEntries);
7217
- if (bullets.length > 0) {
7218
- return { ok: true, bullets };
7219
- } else if (text.trim() === "") {
7220
- return { ok: true, bullets: [] };
7221
- } else {
7222
- if (process.env.LACODE_TIMELINE_DEBUG === "1") {
7223
- log("debug", "timeline: no bullet lines", { sessionID: id, text: text.slice(0, 300) });
7224
- }
7225
- return { ok: false, bullets: [], error: "no bullet lines" };
7226
- }
7250
+ return { ok: false, bullets: [], error: timedOut ? "timed out" : errorText(failure) };
7251
+ }
7252
+ if (!result?.data) {
7253
+ return { ok: false, bullets: [], error: "no response" };
7254
+ }
7255
+ const parts = result.data.parts ?? [];
7256
+ const textParts = parts.filter((part) => part.type === "text").map((part) => part.text ?? "").join("\n").trim();
7257
+ const reasoningParts = parts.filter((part) => part.type === "reasoning").map((part) => part.text ?? "").join("\n").trim();
7258
+ const text = textParts || reasoningParts;
7259
+ const bullets = parseBullets(text, maxEntries);
7260
+ if (bullets.length > 0) {
7261
+ return { ok: true, bullets };
7262
+ }
7263
+ if (text.trim() === "") {
7264
+ return { ok: true, bullets: [] };
7265
+ }
7266
+ const salvaged = salvageBullets(text, maxEntries);
7267
+ if (salvaged.length > 0) {
7268
+ log("warn", "timeline: salvaged non-bulleted output", { sessionID: id, text: text.slice(0, 300) });
7269
+ return { ok: true, bullets: salvaged };
7270
+ }
7271
+ if (process.env.LACODE_TIMELINE_DEBUG === "1") {
7272
+ log("debug", "timeline: no bullet lines", { sessionID: id, text: text.slice(0, 300) });
7227
7273
  }
7274
+ return { ok: false, bullets: [], error: "no bullet lines" };
7228
7275
  } finally {
7229
7276
  if (abort && abortListener) abort.removeEventListener("abort", abortListener);
7230
7277
  if (claimed && claimKey2) release(poolState, claimKey2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lawaty/lacode",
3
- "version": "1.3.0-beta.8",
3
+ "version": "1.3.0-beta.9",
4
4
  "description": "Ultimate opencode setup for Go users — cost-controlled pooled subagents, hang recovery, and notifications for opencode.",
5
5
  "license": "MIT",
6
6
  "type": "module",