@harness-mix/cli 0.1.12 → 0.2.1
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 +15 -2
- package/NOTICE +14 -0
- package/README.md +4 -24
- package/docs/multi-agent-collaboration.md +1 -1
- package/licenses/anthropic-codex-theme-MIT.txt +21 -0
- package/licenses/codex-dream-skin-MIT.txt +21 -0
- package/output/native-build/renderer-extension.js +703 -58
- package/package.json +192 -189
- package/scripts/collaboration-test.cjs +262 -200
- package/scripts/collaboration-ui-smoke.cjs +85 -77
- package/scripts/core-concurrency-test.cjs +23 -1
- package/scripts/e2e-pi-cancel.cjs +99 -0
- package/scripts/native-file-change-test.cjs +42 -2
- package/scripts/native-sidebar-test.cjs +8 -0
- package/scripts/native-vendor-adapters-test.cjs +67 -1
- package/scripts/pets-test.cjs +63 -0
- package/scripts/pi-cancel-race-test.cjs +102 -0
- package/scripts/stuck-turn-test.cjs +73 -0
- package/scripts/workspace-test.cjs +9 -0
- package/src/assets/skins/dream-skin/NOTICE.md +13 -0
- package/src/assets/skins/dream-skin/themes/gothic-void-crusade/hero.webp +0 -0
- package/src/assets/skins/dream-skin/themes/gothic-void-crusade/theme.json +34 -0
- package/src/main/adapters/claude.js +9 -6
- package/src/main/adapters/pi-family.js +41 -8
- package/src/main/harness-adapter/event-normalizer.js +270 -258
- package/src/main/host/collaboration-mcp.cjs +8 -1
- package/src/main/host/collaboration-tools.js +1 -1
- package/src/main/host/collaboration.js +81 -11
- package/src/main/host/runtime.js +1420 -1341
- package/src/main/native/pets.js +79 -2
- package/src/main/native/protocol.js +1160 -1145
- package/src/main/native/thread-list.js +6 -1
- package/src/main/workspace/core-review.js +75 -0
- package/src/main/workspace/diff.js +5 -1
- package/src/main/workspace/file-changes.js +9 -4
- package/src/main/workspace/review-controller.js +115 -102
- package/src/main/workspace/review.js +90 -88
- package/src/native-ui/renderer-extension/dist/contract-audit.js +16637 -0
- package/src/native-ui/renderer-extension/dist/index.js +34853 -0
- package/src/native-ui/renderer-extension/dist/production.js +34263 -0
- package/src/native-ui/renderer-extension/dist/renderer-binding-probe.js +34254 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts +11 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-pet-switcher.d.ts +73 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-pet-switcher.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-settings-lifecycle.d.ts +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-settings-lifecycle.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-team-cards.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/collaboration-page.d.ts +12 -0
- package/src/native-ui/renderer-extension/dist/types/settings/collaboration-page.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/icons.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/icons.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/localization.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts +5 -3
- package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/pet-market.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/pet-market.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/pets-client.d.ts +9 -0
- package/src/native-ui/renderer-extension/dist/types/settings/pets-client.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/skin-runtime.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/skin-runtime.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/tsconfig.tsbuildinfo +1 -1
- package/src/native-ui/renderer-extension/src/renderer-binding-probe.ts +3181 -3171
- package/src/native-ui/renderer-extension/src/renderer-model-client.ts +14 -0
- package/src/native-ui/renderer-extension/src/renderer-pet-switcher.ts +308 -0
- package/src/native-ui/renderer-extension/src/renderer-settings-lifecycle.ts +2 -0
- package/src/native-ui/renderer-extension/src/renderer-team-cards.ts +76 -21
- package/src/native-ui/renderer-extension/src/settings/collaboration-page.ts +139 -0
- package/src/native-ui/renderer-extension/src/settings/icons.ts +155 -153
- package/src/native-ui/renderer-extension/src/settings/localization.ts +785 -783
- package/src/native-ui/renderer-extension/src/settings/pages.ts +694 -681
- package/src/native-ui/renderer-extension/src/settings/pet-market.css +110 -1
- package/src/native-ui/renderer-extension/src/settings/pet-market.ts +276 -22
- package/src/native-ui/renderer-extension/src/settings/pets-client.ts +32 -0
- package/src/native-ui/renderer-extension/src/settings/shell.css +2294 -2255
- package/src/native-ui/renderer-extension/src/settings/skin-runtime.ts +51 -1
- package/src/native-ui/renderer-extension/test/renderer-model-client.test.ts +2 -0
- package/src/native-ui/renderer-extension/test/renderer-pet-switcher.test.ts +400 -0
- package/src/native-ui/renderer-extension/test/settings/localization.test.ts +80 -79
- package/src/native-ui/renderer-extension/test/settings/pet-market.test.ts +378 -0
- package/src/native-ui/renderer-extension/test/settings/pets-client.test.ts +83 -0
- package/src/native-ui/renderer-extension/test/settings/shell.test.ts +3 -0
- package/src/native-ui/renderer-extension/test/settings/skin-runtime.test.ts +15 -1
package/src/main/native/pets.js
CHANGED
|
@@ -7,7 +7,8 @@ const path = require('path');
|
|
|
7
7
|
// 桌宠市场数据源(只读官方资产,不随 Harness Mix 分发):
|
|
8
8
|
// - 官方预载:Codex Desktop 安装包 app.asar 内嵌的 *-spritesheet-vN-<hash>.webp,运行时按需提取;
|
|
9
9
|
// - 已安装:~/.codex/pets/<id>/{pet.json, spritesheet.webp}(官方 Pets 设置页读取同一目录)。
|
|
10
|
-
//
|
|
10
|
+
// 账号级 accessory_id 始终留给官方 Pets 设置页 / /pet 指令,Harness Mix 不代理账号 API;
|
|
11
|
+
// Harness Mix 自己的选择状态(selection/select)是数据目录下的本地 JSON,只驱动 Harness Mix 自有展示面。
|
|
11
12
|
|
|
12
13
|
const PET_ID_PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
13
14
|
const SPRITESHEET_PATTERN = /^([a-z0-9]+(?:-[a-z0-9]+)*)-spritesheet-v\d+-[0-9a-f]+\.webp$/;
|
|
@@ -25,6 +26,15 @@ function petsDirectory(env = process.env) {
|
|
|
25
26
|
return env.HARNESS_MIX_PETS_DIR || path.join(os.homedir(), '.codex', 'pets');
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
// 桌宠选择是 Harness Mix 本地状态(不是账号级 accessory_id),持久化在数据目录下的小 JSON 里
|
|
30
|
+
function harnessMixDataDirectory(env = process.env) {
|
|
31
|
+
return env.HARNESSMIX_DATA_DIR || path.join(os.homedir(), '.harness-mix');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function petSelectionFile(env = process.env) {
|
|
35
|
+
return path.join(harnessMixDataDirectory(env), 'pet-selection.json');
|
|
36
|
+
}
|
|
37
|
+
|
|
28
38
|
// HARNESSMIX_STOCK_CODEX_PATH 指向安装包内的 codex CLI(win: <root>/app/resources/codex.exe,
|
|
29
39
|
// mac: <root>/Contents/Resources/codex),app.asar 与其同目录。Host 进程由 Shim 启动时该变量已注入;
|
|
30
40
|
// 缺失时按平台探测(Windows 走 AppX 查询,macOS 检查标准 .app 路径),结果进程内缓存。
|
|
@@ -314,6 +324,47 @@ function createPetMarket({ env = process.env } = {}) {
|
|
|
314
324
|
return pets;
|
|
315
325
|
}
|
|
316
326
|
|
|
327
|
+
// 可选中的宠物:已安装或官方预载(选择状态只是 Harness Mix 本地展示状态,不要求已安装)
|
|
328
|
+
function findSelectablePet(id) {
|
|
329
|
+
const installed = installedPets().find(pet => pet.id === id);
|
|
330
|
+
if (installed) return installed;
|
|
331
|
+
return officialPets().pets.find(pet => pet.id === id) ?? null;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// 读取持久化的选择;文件缺失/损坏/id 非法一律视为无选择
|
|
335
|
+
function readPersistedSelection() {
|
|
336
|
+
let raw;
|
|
337
|
+
try { raw = JSON.parse(fs.readFileSync(petSelectionFile(env), 'utf8')); } catch { return null; }
|
|
338
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;
|
|
339
|
+
if (typeof raw.id !== 'string' || !PET_ID_PATTERN.test(raw.id)) return null;
|
|
340
|
+
const displayName = typeof raw.displayName === 'string' && raw.displayName.trim() ? raw.displayName : titleCase(raw.id);
|
|
341
|
+
const spriteVersionNumber = Number.isInteger(raw.spriteVersionNumber) && raw.spriteVersionNumber >= 1 ? raw.spriteVersionNumber : undefined;
|
|
342
|
+
return { id: raw.id, displayName, spriteVersionNumber };
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// 原子写入(tmp + rename,与 config.js 的 saveNativeSettings 一致);selection 为 null 表示清除
|
|
346
|
+
function writePersistedSelection(selection) {
|
|
347
|
+
const dir = harnessMixDataDirectory(env);
|
|
348
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
349
|
+
const file = petSelectionFile(env);
|
|
350
|
+
const payload = selection
|
|
351
|
+
? { id: selection.id, displayName: selection.displayName, spriteVersionNumber: selection.spriteVersionNumber, selectedAt: new Date().toISOString() }
|
|
352
|
+
: { id: null, selectedAt: new Date().toISOString() };
|
|
353
|
+
fs.writeFileSync(`${file}.tmp`, `${JSON.stringify(payload, null, 2)}\n`);
|
|
354
|
+
try {
|
|
355
|
+
fs.renameSync(`${file}.tmp`, file);
|
|
356
|
+
} catch (err) {
|
|
357
|
+
// rename 失败(如文件占用)时清理暂存文件,避免数据目录残留 .tmp
|
|
358
|
+
try { fs.rmSync(`${file}.tmp`, { force: true }); } catch { /* best effort */ }
|
|
359
|
+
throw err;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// 选择结果的渲染描述:id + displayName + spriteVersionNumber,调用方无需二次查询即可渲染
|
|
364
|
+
function describeSelection(pet) {
|
|
365
|
+
return { id: pet.id, displayName: pet.displayName, spriteVersionNumber: pet.spriteVersionNumber ?? 2 };
|
|
366
|
+
}
|
|
367
|
+
|
|
317
368
|
return {
|
|
318
369
|
catalog() {
|
|
319
370
|
const official = officialPets();
|
|
@@ -523,12 +574,38 @@ function createPetMarket({ env = process.env } = {}) {
|
|
|
523
574
|
fs.rmSync(targetDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
|
|
524
575
|
if (fs.existsSync(targetDir)) throw new Error(`Failed to remove pet directory: ${targetDir}`);
|
|
525
576
|
previewCache.delete(id);
|
|
577
|
+
// 卸载当前选中的桌宠时自动清除选择,避免悬空的过期选择
|
|
578
|
+
const persisted = readPersistedSelection();
|
|
579
|
+
if (persisted && persisted.id === id) writePersistedSelection(null);
|
|
526
580
|
return { id, removed: true };
|
|
527
581
|
} finally {
|
|
528
582
|
releaseOperation(id);
|
|
529
583
|
}
|
|
530
584
|
},
|
|
585
|
+
|
|
586
|
+
// 当前 Harness Mix 桌宠选择;持久化的选择指向已不可用的宠物时按无选择处理(过期容忍)
|
|
587
|
+
selection() {
|
|
588
|
+
const persisted = readPersistedSelection();
|
|
589
|
+
if (!persisted) return { id: null };
|
|
590
|
+
const pet = findSelectablePet(persisted.id);
|
|
591
|
+
if (!pet) return { id: null };
|
|
592
|
+
return describeSelection(pet);
|
|
593
|
+
},
|
|
594
|
+
|
|
595
|
+
// 设置/清除选择:{ id } 选中(必须已安装或为官方预载),{ id: null } 清除
|
|
596
|
+
select({ id } = {}) {
|
|
597
|
+
if (id === null || id === undefined) {
|
|
598
|
+
writePersistedSelection(null);
|
|
599
|
+
return { id: null };
|
|
600
|
+
}
|
|
601
|
+
if (!PET_ID_PATTERN.test(String(id))) throw new Error('Invalid pet id');
|
|
602
|
+
const pet = findSelectablePet(id);
|
|
603
|
+
if (!pet) throw new Error(`Unknown pet: ${id}`);
|
|
604
|
+
const selection = describeSelection(pet);
|
|
605
|
+
writePersistedSelection(selection);
|
|
606
|
+
return selection;
|
|
607
|
+
},
|
|
531
608
|
};
|
|
532
609
|
}
|
|
533
610
|
|
|
534
|
-
module.exports = { createPetMarket, petsDirectory, resolveAsarPath, readAsarHeader, CURATED_COMMUNITY_PETS, isWebpBuffer, validatePetMetadata };
|
|
611
|
+
module.exports = { createPetMarket, petsDirectory, petSelectionFile, resolveAsarPath, readAsarHeader, CURATED_COMMUNITY_PETS, isWebpBuffer, validatePetMetadata };
|