cortico-world-image 0.1.3 → 0.1.4

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
@@ -192,9 +192,9 @@
192
192
  修法是抬版本 + 重启,主程序会在 Core 就绪时自动重载控制台外壳(
193
193
  `resources\app\app\main.cjs:285` `if (settings) settings.loadURL(consoleUrl());`):
194
194
 
195
- 1. 把 `package.json` 的 `version` 抬一格(例如 `0.1.2` → `0.1.3`);
195
+ 1. 把 `package.json` 的 `version` 抬一格(例如 `0.1.3` → `0.1.4`);
196
196
  2. 重启控制台(状态页「重启控制台」或 `node tools/patch.mjs --restart`);
197
- 3. 程序内窗口自动重载 → 新的 URL `/assets/extensions/cortico-world-image/0.1.3/console.js`
197
+ 3. 程序内窗口自动重载 → 新的 URL `/assets/extensions/cortico-world-image/0.1.4/console.js`
198
198
  取到新脚本,旧 URL 立刻变 404。
199
199
 
200
200
  不想抬版本也行,但要**先完全退出程序**再删缓存目录:`<安装>\data\Cache`、
@@ -230,7 +230,7 @@ registry 上有版本时直接从 npm 装;想自己改代码、或者 `npm vie
230
230
  或者用命令行,在 `data/extensions` 目录里(`extensions/package.json` 所在处)执行:
231
231
 
232
232
  ```powershell
233
- pnpm add cortico-world-image --ignore-workspace # 想钉住版本就写 cortico-world-image@0.1.3
233
+ pnpm add cortico-world-image --ignore-workspace # 想钉住版本就写 cortico-world-image@0.1.4
234
234
  ```
235
235
 
236
236
  装完重启。升级同理:重跑一遍(控制台的「扩展」页会显示已装版本与最新版本),装完同样要重启。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cortico-world-image",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "description": "Image Studio(图片工坊)—— 给 Coopanion 桌宠的 cortico World 扩展:用任意 OpenAI 兼容的图片接口画图/改图、落盘成作品库、把图贴进控制台「对话」页,并自带一套自动重打的自愈补丁。 / A cortico World extension that draws through any OpenAI-compatible image API, keeps pictures on disk and shows them in the console.",
6
6
  "license": "MIT",
@@ -320,22 +320,32 @@ const QQ_SEND_NEW = 'const p = resolveLocalImagePath(image, this.config.memoryDi
320
320
  const QQ_VIEW_OLD = "const p = isAbsolute(url) ? url : join(this.packageDir || '.', url);";
321
321
  const QQ_VIEW_NEW = 'const p = resolveLocalImagePath(url, this.config.memoryDir, this.packageDir);';
322
322
 
323
- /** 工具说明里那三处「相对扩展目录」要跟着改成「相对桌宠工作区」——模型只看得到说明。 */
323
+ /**
324
+ * 工具说明里那三处要跟着改成「相对桌宠工作区」——模型只看得到说明。
325
+ * 上游爱改措辞(0.1.16 就把 image 那句换成了「如 /home/user/pics/a.png」),所以每条列出
326
+ * 见过的旧写法:一条都对不上只跳过、不判失败;整条补丁一句都认不出来才算版本变了。
327
+ */
324
328
  const QQ_HINTS = [
325
329
  {
326
- from: "description: '本地文件路径(绝对路径,或相对扩展目录)或 http(s) 链接。'",
330
+ from: [
331
+ "description: '本地文件路径(绝对路径,或相对扩展目录)或 http(s) 链接。'",
332
+ "description: '本地文件路径(如 /home/user/pics/a.png)或 http(s) 链接。'",
333
+ ],
327
334
  to: "description: '本地文件路径(绝对路径,或相对桌宠工作区的路径,如 blobs/xx.jpg)或 http(s) 链接。'",
328
335
  },
329
336
  {
330
- from: '或本地文件路径;给了就不再翻缓冲。',
337
+ from: ['或本地文件路径;给了就不再翻缓冲。'],
331
338
  to: '或本地文件路径(绝对路径,或相对桌宠工作区的路径,如 blobs/xx.jpg);给了就不再翻缓冲。',
332
339
  },
333
340
  {
334
- from: '给某个会话发一张图。`image` 给本地文件路径或 http(s) 链接(本机下载后再发),二者挑一个。',
341
+ from: ['给某个会话发一张图。`image` 给本地文件路径或 http(s) 链接(本机下载后再发),二者挑一个。'],
335
342
  to: '给某个会话发一张图。`image` 给本地文件路径(绝对路径,或相对桌宠工作区的路径,如 blobs/xx.jpg)或 http(s) 链接(本机下载后再发),二者挑一个。',
336
343
  },
337
344
  ];
338
345
 
346
+ /** 这条说明还没改成我们的说法、而且上游还有它认得的旧写法 → 需要动手。 */
347
+ const hintNeedsWork = (text, h) => !text.includes(h.to) && [].concat(h.from).some((from) => text.includes(from));
348
+
339
349
  /**
340
350
  * 每个补丁:`file` 是绝对路径,`done` 说这段原文是不是已经改过了,
341
351
  * `apply` 返回新文本或 `{ error }`。全部按顺序跑,互不依赖。
@@ -467,14 +477,26 @@ export function rulesFor(id) {
467
477
  };
468
478
  case 'qq-image-hints':
469
479
  return {
470
- done: (text) => QQ_HINTS.every((h) => text.includes(h.to)),
480
+ // 已经有一处是我们的说法,且没有哪处还留着认得的旧写法 → 不用再管(上游换掉的措辞不再拖住这条)。
481
+ done: (text) => QQ_HINTS.some((h) => text.includes(h.to)) && QQ_HINTS.every((h) => !hintNeedsWork(text, h)),
471
482
  apply: (text) => {
472
483
  let work = text;
484
+ let recognized = 0;
473
485
  for (const h of QQ_HINTS) {
474
- const out = swap(work, h.from, h.to);
475
- if (out === null) return { error: `工具说明对不上:${h.from.slice(0, 40)}` };
476
- work = out;
486
+ if (work.includes(h.to)) {
487
+ recognized += 1;
488
+ continue;
489
+ }
490
+ for (const from of [].concat(h.from)) {
491
+ const out = swap(work, from, h.to);
492
+ if (out !== null) {
493
+ work = out;
494
+ recognized += 1;
495
+ break;
496
+ }
497
+ }
477
498
  }
499
+ if (recognized === 0) return { error: `工具说明已大改,一句都认不出来:${[].concat(QQ_HINTS[0].from)[0].slice(0, 40)}` };
478
500
  return { text: work };
479
501
  },
480
502
  };
package/tools/check.mjs CHANGED
@@ -746,6 +746,28 @@ try {
746
746
  check(qqRules.done(qqPatched?.text ?? ''), '改完认成「已打过」(幂等)');
747
747
  check(qqPatched.text.includes("import { existsSync } from 'node:fs';"), '导入本来就够时不多改一行');
748
748
 
749
+ // 上游爱改工具说明的措辞(0.1.16 就把 image 那句换成了「如 /home/user/pics/a.png」):
750
+ // 一条对不上不该让整条补丁失败;但一句都认不出来仍然要报。
751
+ const hintRules = patchMod.rulesFor('qq-image-hints');
752
+ check(typeof hintRules?.done === 'function' && typeof hintRules?.apply === 'function', 'QQ 说明补丁有 done/apply');
753
+ const hintFixture = [
754
+ " parameters: [{ name: 'url', description: '可选:直接给图片链接(事件里带的图)或本地文件路径;给了就不再翻缓冲。' }],",
755
+ " description: '给某个会话发一张图。`image` 给本地文件路径或 http(s) 链接(本机下载后再发),二者挑一个。',",
756
+ " parameters: [{ name: 'image', description: '本地文件路径(如 /home/user/pics/a.png)或 http(s) 链接。' }],",
757
+ '',
758
+ ].join('\n');
759
+ check(!hintRules.done(hintFixture), '夹具还是「只认绝对路径」的说明(有东西可改)');
760
+ const hinted = hintRules.apply(hintFixture);
761
+ check(!hinted?.error, '上游换了说明措辞也照改,不报失败', String(hinted?.error ?? 'ok'));
762
+ check((hinted?.text ?? '').includes('或本地文件路径(绝对路径,或相对桌宠工作区的路径,如 blobs/xx.jpg);给了就不再翻缓冲。'), '认得出的那两处照改');
763
+ check(!(hinted?.text ?? '').includes('相对扩展目录'), '旧说法不再残留在说明里');
764
+ check(hintRules.done(hinted?.text ?? ''), '改完认成「已打过」(幂等)');
765
+ const reworded = hintFixture.replace("'本地文件路径(如 /home/user/pics/a.png)或 http(s) 链接。'", "'图片本地路径或链接。'");
766
+ const rewordedOut = hintRules.apply(reworded);
767
+ check(!rewordedOut?.error && hintRules.done(rewordedOut?.text ?? ''), '上游整句换掉时跳过那一处,不算失败也不算没打', String(rewordedOut?.error ?? 'ok'));
768
+ check(Boolean(hintRules.apply('export const nope = 1;\n')?.error), '一句都认不出来时仍然报失败');
769
+ check(!hintRules.done('export const nope = 1;\n'), '文件整个换了写法时不谎报「已打过」');
770
+
749
771
  // pet_show_image 也要能认相对路径(按桌宠工作区解析)。
750
772
  const petSpecs = specs.filter((s) => s.id.startsWith('pet-workspace-'));
751
773
  check(petSpecs.length === 3 && petSpecs.every((s) => s.optional !== true), '桌宠工作区相对路径那 3 处是必备补丁', JSON.stringify(petSpecs.map((s) => s.id)));
package/tools/patch.mjs CHANGED
@@ -142,7 +142,7 @@ const QQ_FIXTURE_TS = [
142
142
  'export const qqSendImage = {',
143
143
  " name: 'qq_send_image',",
144
144
  " description: '给某个会话发一张图。`image` 给本地文件路径或 http(s) 链接(本机下载后再发),二者挑一个。',",
145
- " parameters: [{ name: 'image', description: '本地文件路径(绝对路径,或相对扩展目录)或 http(s) 链接。' }],",
145
+ " parameters: [{ name: 'image', description: '本地文件路径(如 /home/user/pics/a.png)或 http(s) 链接。' }],",
146
146
  '};',
147
147
  'export class QQWorld implements World {',
148
148
  " private packageDir = '.';",