opencode-acp 1.14.9-dev.1 → 1.14.9-dev.2

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/README.md CHANGED
@@ -492,6 +492,26 @@ For the complete list with root cause analysis, see the [bug tracker](https://gi
492
492
 
493
493
  ## Changelog
494
494
 
495
+ ### v1.14.9 — Stable Release (3 PRs since v1.14.8)
496
+
497
+ Stable release with nudge loop fix, holistic T2/T3 compression prompts, and multi-entry compress format documentation.
498
+
499
+ **PRs included**:
500
+ - **#252** — Two fixes: (1) **Issue #251**: `filterRecommendedRanges` suppressed ALL recommendations when compressible content was below 5% of modelContextLimit. Rewrote to always show all ranges. (2) **Nudge loop fix**: `lastNudgeShownTokens` reset to `undefined` on `nothingToCompress` caused nudges firing every turn.
501
+ - **#257** — Bump `context-compress-algorithms` 1.2.1 → 1.3.0. Holistic TIER2/TIER3 prompts — summarize by theme instead of per-block, fixing length overflow with 70+ T1 blocks (issue #256).
502
+ - **#259** — Document multi-entry compress format in system prompt and T2/T3 nudge. The compress tool already supported `content` arrays (PR #156), but only single-entry was shown for block-based compression.
503
+
504
+ **Install**: `opencode plugin opencode-acp@stable --global`
505
+
506
+ ### v1.14.9-dev.2 — Dev Prerelease (1 PR since v1.14.9-dev.1)
507
+
508
+ Dev prerelease covering PR #263. Published to `dev` npm tag for early testing.
509
+
510
+ **PRs included**:
511
+ - **#263** — Fix: `omo-mode-injection` filter was dropping entire user messages when OMO mode injections (`<ultrawork-mode>`, `[search-mode]`, etc.) were prepended to user content. Mode injections are prepended via `UserPromptSubmit.additionalContext`, not standalone — the old filter (v1.0.0) matched the injection and returned `drop`, clearing the entire message including the user's actual request. Rewrote to v1.1.0: strips injection blocks and preserves user content via `modify`. Also fixes config validation (messageFilters.filters dynamic key skip) and adds messageFilters to dcp.schema.json.
512
+
513
+ **Install**: `opencode plugin opencode-acp@dev --global`
514
+
495
515
  ### v1.14.9-dev.1 — Dev Prerelease (1 PR since v1.14.8-dev.5)
496
516
 
497
517
  Dev prerelease covering PR #259. Published to `dev` npm tag for early testing.
package/README.zh-CN.md CHANGED
@@ -446,6 +446,26 @@ ACP 是 DCP 的直接替代品。迁移步骤:
446
446
 
447
447
  ## 更新日志
448
448
 
449
+ ### v1.14.9 — 正式版(v1.14.8 以来 3 个 PR)
450
+
451
+ 正式版发布,包含 nudge 循环修复、整体式 T2/T3 压缩提示词、多条目 compress 格式文档。
452
+
453
+ **包含的 PR**:
454
+ - **#252** — 两个修复:(1) **Issue #251**:`filterRecommendedRanges` 在可压缩内容低于 modelContextLimit 的 5% 时抑制所有推荐。重写为始终显示所有范围。(2) **Nudge 循环修复**:`lastNudgeShownTokens` 在 `nothingToCompress` 时被重置为 `undefined`,导致每轮都触发 nudge。
455
+ - **#257** — 升级 `context-compress-algorithms` 1.2.1 → 1.3.0。整体式 TIER2/TIER3 提示词 — 按主题综述而非逐块处理,修复 70+ T1 块时的长度溢出问题(issue #256)。
456
+ - **#259** — 在系统提示词和 T2/T3 nudge 中文档化多条目 compress 格式。compress 工具已支持 `content` 数组(PR #156),但块压缩只展示了单条目格式。
457
+
458
+ **安装**:`opencode plugin opencode-acp@stable --global`
459
+
460
+ ### v1.14.9-dev.2 — Dev 预发布(v1.14.9-dev.1 以来 1 个 PR)
461
+
462
+ Dev 预发布,覆盖 PR #263。已发布到 `dev` npm 标签供早期测试。
463
+
464
+ **包含的 PR**:
465
+ - **#263** — 修复:`omo-mode-injection` 过滤器在 OMO 模式注入(`<ultrawork-mode>`、`[search-mode]` 等)被前置到用户消息时,会丢弃整个用户消息。模式注入通过 `UserPromptSubmit.additionalContext` 前置,不是独立消息——旧过滤器(v1.0.0)匹配到注入就返回 `drop`,清空了整个消息包括用户的实际请求。重写为 v1.1.0:剥离注入块、通过 `modify` 保留用户内容。同时修复配置校验(messageFilters.filters 动态键跳过)并补充 dcp.schema.json。
466
+
467
+ **安装**:`opencode plugin opencode-acp@dev --global`
468
+
449
469
  ### v1.14.9-dev.1 — Dev 预发布(v1.14.8-dev.5 以来 1 个 PR)
450
470
 
451
471
  Dev 预发布,涵盖 PR #259。发布到 `dev` npm tag 供早期测试。
package/dist/index.js CHANGED
@@ -929,7 +929,7 @@ function getConfigKeyPaths(obj, prefix = "") {
929
929
  for (const key of Object.keys(obj)) {
930
930
  const fullKey = prefix ? `${prefix}.${key}` : key;
931
931
  keys.push(fullKey);
932
- if (fullKey === "compress.modelMaxLimits" || fullKey === "compress.modelMinLimits") {
932
+ if (fullKey === "compress.modelMaxLimits" || fullKey === "compress.modelMinLimits" || fullKey === "messageFilters.filters") {
933
933
  continue;
934
934
  }
935
935
  if (obj[key] && typeof obj[key] === "object" && !Array.isArray(obj[key])) {
@@ -8831,7 +8831,7 @@ import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
8831
8831
  import { join as join3 } from "path";
8832
8832
  import { existsSync as existsSync3 } from "fs";
8833
8833
  import { homedir as homedir3 } from "os";
8834
- var LOG_VERSION = true ? "1.14.9-dev.1" : "dev";
8834
+ var LOG_VERSION = true ? "1.14.9-dev.2" : "dev";
8835
8835
  var Logger = class {
8836
8836
  logDir;
8837
8837
  enabled;
@@ -10134,17 +10134,62 @@ var OMO_TASK_FILTER = {
10134
10134
  };
10135
10135
 
10136
10136
  // lib/messages/filter/builtin/omo-mode-injection.ts
10137
- var MODE_PATTERNS = ["[search-mode]", "[analyze-mode]", "<ultrawork-mode>", "[ultrawork-mode]"];
10137
+ var XML_MODE_TAGS = [
10138
+ { open: "<hyperplan-ultrawork-mode>", close: "</hyperplan-ultrawork-mode>" },
10139
+ { open: "<ultrawork-mode>", close: "</ultrawork-mode>" }
10140
+ ];
10141
+ var BRACKET_MODE_PATTERNS = ["[search-mode]", "[analyze-mode]", "[ultrawork-mode]"];
10142
+ function stripLeadingModeInjections(text) {
10143
+ let current = text;
10144
+ let strippedAny = false;
10145
+ for (let iter = 0; iter < 5; iter++) {
10146
+ current = current.trimStart();
10147
+ let matched = false;
10148
+ for (const { open, close } of XML_MODE_TAGS) {
10149
+ if (current.startsWith(open)) {
10150
+ const closeIdx = current.indexOf(close);
10151
+ if (closeIdx !== -1) {
10152
+ current = current.slice(closeIdx + close.length);
10153
+ } else {
10154
+ current = current.slice(open.length);
10155
+ }
10156
+ matched = true;
10157
+ break;
10158
+ }
10159
+ }
10160
+ if (!matched) {
10161
+ for (const pattern of BRACKET_MODE_PATTERNS) {
10162
+ if (current.startsWith(pattern)) {
10163
+ current = current.slice(pattern.length);
10164
+ matched = true;
10165
+ break;
10166
+ }
10167
+ }
10168
+ }
10169
+ if (matched) {
10170
+ strippedAny = true;
10171
+ } else {
10172
+ break;
10173
+ }
10174
+ }
10175
+ return strippedAny ? current.trim() : null;
10176
+ }
10138
10177
  var OMO_MODE_FILTER = {
10139
10178
  name: "omo-mode-injection",
10140
- version: "1.0.0",
10141
- description: "Strip OMO mode injection blocks ([search-mode], [analyze-mode], <ultrawork-mode>)",
10179
+ version: "1.1.0",
10180
+ description: "Strip OMO mode injection blocks (<ultrawork-mode>...</ultrawork-mode>, [search-mode], etc.) from user messages, preserving user content",
10142
10181
  filter(ctx) {
10143
10182
  if (ctx.role !== "user") return { action: "keep" };
10144
- const stripped = ctx.text.trimStart();
10145
- const isModeInjection = MODE_PATTERNS.some((p) => stripped.startsWith(p));
10146
- if (!isModeInjection) return { action: "keep" };
10147
- return { action: "drop", reason: "OMO mode injection" };
10183
+ const remaining = stripLeadingModeInjections(ctx.text);
10184
+ if (remaining === null) return { action: "keep" };
10185
+ if (remaining.length === 0) {
10186
+ return { action: "drop", reason: "OMO mode injection (no user content after stripping)" };
10187
+ }
10188
+ return {
10189
+ action: "modify",
10190
+ text: remaining,
10191
+ reason: "Stripped OMO mode injection block(s), preserved user content"
10192
+ };
10148
10193
  }
10149
10194
  };
10150
10195