@xgent-ai/skills 0.7.3 → 0.7.5
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 +4 -2
- package/bin/xgent-skills.js +136 -12
- package/dist/phoenix-ui/THIRD-PARTY.json +2 -2
- package/dist/phoenix-ui/VERSION.json +15 -15
- package/dist/phoenix-ui/bundle/blobs/{99f49df49ade2ca21deffcc752fc8a76c9a6645f5416b9314ea3ab1bd010f34c → 2291169748fe0c4c80634dff3083e7464f82d4358b9b2186759b316e612d466f} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{335ccd78685b679dc0c880fc46139d0fa94aebcfa6e5ff848fd0599b187d25c4 → 2ceacad745665f79fd7ad5565646426a36a1b508c0469b931d0f202fad45a80b} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{ec8968ee6a8e42b952e5ece2369ba69f40185c62a135ed54e930df3170421d9c → 45bbd4a8e02ca0012216c5c68e1dcd655ae0046bd50ba4295ef1f58ec4a0957c} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{1ba392d45294b3e90cc7f3964f134ae685118bbbcc84ca944953a4270ec67a54 → 546a8428a2d8628bb3496fadb8c36a6dd65a33464291f214ceb581828f37081b} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{8b1723fb51e6aad9bfc0bc5ba8e09b5a373b0e33c251331f6ca14ff6b1c261ef → 547e3c89d5b8feeddd67e43131fd84b95253eb42bf7d730b4e471dba011f6e51} +2 -1
- package/dist/phoenix-ui/bundle/blobs/{d21ccafc83495872c80ec9873ad4fbfb4223837a747b524aa03b6d819f7c08e3 → 6d8315e307eab11d3236935daf7267746cce6da3b51296e6999651ac97bda3a3} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{3077452231f1ce3c48ae5d8dd912b14ab30de55a270a031d07065357bc1cca94 → 78662176c1d31cec2d640f70df203f93cc1aec604cfc31619f4d2c62ab78861b} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{3133bec6998506bf92baeeabba39438c5ee27aa3330c2e6245f9df216fbe7b2d → 852d2943678a76c33b2f7a090d2ca6c152cd120e9ae62775fcc91519b9289011} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{3759780bd25526f7eaa3793c010356bccb850d40db931e0c6d47d35e81e96f96 → 878064e46af4e4109bab405f965e4149bee40bbe8912ffede10b74cec6cff027} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{48b7e6acf597d4f0320834db1393003451d1bd7c0d024dd62f7577a398b2e320 → 8de7c97949b0bc4194b3be7645e4b13e9419767927482d01cf19476f6cbeda14} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{5f5fc6bb04605feb7ac6f6b19e35ff2f8d39e11a89fdd260159c6829f27b4a4d → bc29e115fd337dda2cc7fc70b868dc18e426b08ec186fd270fcfe96bb2efaa5d} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{a64a45a4e082a0d05daf711080cb7c3195f15fb6b3f3dce0521f4816b64452f3 → bde88bf5ac59d744440d9b65f95ceaae01c803b101d48e6afd644a06eeb5de63} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{882bfe4d8ffd9bc217b0c1bdd5e3cf659cd4b46598d631c4649aaaf0e13333ce → d50780cb0a345051ae3fb12c5f8249a5dac9324d6a1963f04d03aaf769ffc27c} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{d9f1d8e01b40a8d7310e367f7e3da7d1fac5850313082feb853093b7eb36d2bd → d5102701d41f7c6195d410a873f742ac72c428b04196e47df5555c5ccaf80504} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{b544da38492c15f5295053b64189a9ec5ebe446c77138ac52ca7bd9da9c0e842 → e49257c0fd32b195cccb16fbfda769c007be6b38f25aceefecd23cfff9366cec} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{6530364f99c98b9ae9a8f9f3d34866a6393a75e75db48d8c0cbb49dd93a69f81 → f82bfc4c6bc9169d4978d5e16fb925f6e152fdd21dc6a2fae719dfdc1645581f} +1 -1
- package/dist/phoenix-ui/bundle/blobs/{b49cdd7f125d9cb5ce10de7d39c5e3daff7d6649b9ac1c5ffd36a0aebdc4e7ca → ffcaa5c58e779ec74d18bfc3013ad8003f6e7a23f629c1a3b878618961a8b6a3} +1 -1
- package/dist/phoenix-ui/bundle/manifest.json +34 -34
- package/docs/phoenix-ui.md +22 -7
- package/package.json +1 -1
- package/skills/phoenix-ui/GENERATED.json +79 -79
- package/skills/phoenix-ui/SKILL.md +1 -1
- package/skills/phoenix-ui/scripts/ENGINE.json +15 -15
- package/skills/phoenix-ui/scripts/phoenix-bootstrap.cjs +2 -1
package/README.md
CHANGED
|
@@ -37,6 +37,8 @@ npx --package=@xgent-ai/skills@0.7.2 xgent-skills install
|
|
|
37
37
|
| --- | --- |
|
|
38
38
|
| `--no-phoenix-ui` | 跳过 Phoenix UI,仍安装 XGENT 的 hooks 与 settings;不删除已装版本 |
|
|
39
39
|
| `--no-impeccable` | 已弃用,等同 `--no-phoenix-ui`,保留一个迁移主版本 |
|
|
40
|
+
| `--replace-impeccable` | 删除所选工具目录中的项目级及个人级 impeccable 入口和 hooks,不备份 |
|
|
41
|
+
| `--keep-impeccable` | 保留 impeccable,与 Phoenix UI 共存;无交互环境默认采用 |
|
|
40
42
|
| `--release-dir=DIR` | 离线安装 Phoenix UI engine:使用已核验的 release 目录,不联网 |
|
|
41
43
|
| `--xgent-init` | 直接创建仓根 `AGENTS.md` (已有则跳过),不再询问 |
|
|
42
44
|
| `--no-xgent-init` | 跳过创建 `AGENTS.md`,不再询问 |
|
|
@@ -79,8 +81,8 @@ npx skills add XGENT-ai/skills --skill xgent-init
|
|
|
79
81
|
|
|
80
82
|
Phoenix UI 是 XGENT 自主维护的设计工具:从 [impeccable](https://github.com/pbakaus/impeccable) 4.5.0 / engine 0.1.11 的固定源码承接(Apache-2.0,来源与修改见 `dist/phoenix-ui/NOTICE.md`),版本、规则与发布由本仓控制,不再查询或下载上游 latest。它只随 npm 安装器分发:`install` 装入 `phoenix-ui` skill、对应 hooks,以及 design-md、design-reference、ui-pattern-research、review-ui、apply-ui-review 五个辅助 skill。对话里用 `/phoenix-ui`(Codex 用 `$phoenix-ui`);终端命令为 `npm exec --package=@xgent-ai/skills -- phoenix-ui --help`。
|
|
81
83
|
|
|
82
|
-
- **engine**:按包内 `dist/phoenix-ui/VERSION.json` 的摘要校验后放进 `~/.phoenix-ui/bin
|
|
83
|
-
-
|
|
84
|
+
- **engine**:按包内 `dist/phoenix-ui/VERSION.json` 的摘要校验后放进 `~/.phoenix-ui/bin/<版本>/<平台>/<engineSha256>/`(`PHOENIX_UI_HOME` 可改),新旧项目的引擎可共存,本期支持 darwin-arm64、darwin-x64、linux-x64、linux-arm64,Windows 延期。不可用时整个安装在写项目前停止,可改用 `--release-dir=DIR` 离线安装或 `--no-phoenix-ui`。hook 与 context 运行时不联网补下载。
|
|
85
|
+
- **已有工具**:安装时发现 impeccable 会询问是否替换。选择替换则直接删除所选 provider 的项目级及个人级旧入口和旧 hooks,不备份、不留转跳入口;选择保留则共存,不阻止 Phoenix 安装,无交互环境默认保留。没有安装事务状态的 Phoenix 源码副本直接删除后重装。业务源码、旧工具的数据和文档不改动;共享配置中的其他 hooks 保留。
|
|
84
86
|
- **回滚**:安装输出给出事务 ID、备份位置与完整命令,例如 `npm exec --package=@xgent-ai/skills@<版本> -- phoenix-ui migrate --rollback <事务ID> --project <项目>`;回滚只撤销本次安装的条目,后来新增的配置保留。
|
|
85
87
|
|
|
86
88
|
安装、迁移、回滚、支持矩阵与渠道说明见 [docs/phoenix-ui.md](docs/phoenix-ui.md)。原 `vendor/impeccable/` 副本及其 vendor/R2 脚本已删除,需要时从 git 历史查看。
|
package/bin/xgent-skills.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
const { spawnSync } = require('node:child_process');
|
|
9
9
|
const fs = require('node:fs');
|
|
10
10
|
const path = require('node:path');
|
|
11
|
+
const os = require('node:os');
|
|
11
12
|
const readline = require('node:readline');
|
|
12
13
|
|
|
13
14
|
const PKG_ROOT = path.join(__dirname, '..');
|
|
@@ -31,9 +32,8 @@ const MANAGED_SETTINGS = {
|
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
// ─── Phoenix UI ─────────────────────────────────────────────────────────────
|
|
34
|
-
// Phoenix
|
|
35
|
-
//
|
|
36
|
-
// 它,不在 JS 里再写一套配置合并。旧 vendor/impeccable 安装路径已移除。
|
|
35
|
+
// Phoenix 的受管安装、hooks 与回执由 Rust 执行器事务化完成。
|
|
36
|
+
// 旧工具是否删除由 npm 安装入口询问,工具清理不备份、不迁移旧数据。
|
|
37
37
|
|
|
38
38
|
const bootstrap = require('../skills/phoenix-ui/scripts/phoenix-bootstrap.cjs');
|
|
39
39
|
const PHOENIX_DIR = path.join(PKG_ROOT, 'dist', 'phoenix-ui');
|
|
@@ -69,6 +69,112 @@ function runPhoenix(binary, args) {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
// Tool directories are reinstallable. Shared settings retain unrelated entries.
|
|
73
|
+
function preparePhoenixTools(project, providers) {
|
|
74
|
+
const refresh = [];
|
|
75
|
+
const legacy = new Set();
|
|
76
|
+
const configs = new Set();
|
|
77
|
+
const parents = new Map();
|
|
78
|
+
let managed = [];
|
|
79
|
+
try {
|
|
80
|
+
managed = readJson(path.join(project, '.phoenix-ui/install/active.json')).ownership
|
|
81
|
+
.filter(item => item.sha256).map(item => item.path);
|
|
82
|
+
} catch { /* The engine reports an absent or invalid receipt during preflight. */ }
|
|
83
|
+
const present = (file) => !!fs.lstatSync(file, { throwIfNoEntry: false });
|
|
84
|
+
const checked = (root, relative) => {
|
|
85
|
+
const file = path.join(root, relative);
|
|
86
|
+
parents.set(file, root);
|
|
87
|
+
return file;
|
|
88
|
+
};
|
|
89
|
+
const home = fs.realpathSync(os.homedir());
|
|
90
|
+
for (const provider of providers) {
|
|
91
|
+
const roots = provider === '.agents' || provider === '.codex'
|
|
92
|
+
? ['.agents', '.codex'] : [provider];
|
|
93
|
+
for (const root of [project, home]) {
|
|
94
|
+
for (const dir of roots) {
|
|
95
|
+
for (const relative of [
|
|
96
|
+
`${dir}/skills/impeccable`, `${dir}/commands/impeccable.md`,
|
|
97
|
+
...['asset-producer', 'documenter', 'finish-reviewer', 'manual-edit-applier']
|
|
98
|
+
.map(name => `${dir}/agents/impeccable-${name}.md`),
|
|
99
|
+
]) {
|
|
100
|
+
// An earlier explicit migration may own a Phoenix compatibility entry.
|
|
101
|
+
if (root === project && managed.some(file => file === relative || file.startsWith(`${relative}/`))) continue;
|
|
102
|
+
const file = checked(root, relative);
|
|
103
|
+
if (present(file)) legacy.add(file);
|
|
104
|
+
}
|
|
105
|
+
const shared = dir === '.claude' ? ['settings.json', 'settings.local.json']
|
|
106
|
+
: dir === '.gemini' ? ['settings.json']
|
|
107
|
+
: ['.github', '.grok'].includes(dir) ? ['hooks/impeccable.json', 'hooks/phoenix-ui.json'] : ['hooks.json'];
|
|
108
|
+
for (const relative of shared) {
|
|
109
|
+
const file = checked(root, `${dir}/${relative}`);
|
|
110
|
+
if (present(file)) configs.add(file);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (!fs.existsSync(path.join(project, '.phoenix-ui/install'))) {
|
|
115
|
+
const file = checked(project, `${provider}/skills/phoenix-ui`);
|
|
116
|
+
if (present(file)) refresh.push(file);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const oldCommand = value => typeof value === 'string'
|
|
120
|
+
&& /(?:skills[\\/]impeccable[\\/]scripts[\\/](?:impeccable(?:\.cmd)?|hook(?:-(?:probe|before-edit|after-edit|stop))?\.mjs)|(?:^|[\s"'])impeccable\s+hook\b)/.test(value);
|
|
121
|
+
const oldHandler = value => value?.type === 'command'
|
|
122
|
+
&& [value.command, value.commandWindows].some(oldCommand);
|
|
123
|
+
const originals = [...configs].map(file => ({ file, before: fs.readFileSync(file) }));
|
|
124
|
+
const hasLegacy = legacy.size > 0 || originals.some(({ before }) =>
|
|
125
|
+
/impeccable/.test(before.toString()) && (oldCommand(before.toString().replaceAll('\\"', '"')) || /"impeccable[^"\n]*"\s*:\s*true/.test(before.toString())));
|
|
126
|
+
const covers = relative => refresh.some(file => {
|
|
127
|
+
const target = path.relative(project, file).split(path.sep).join('/');
|
|
128
|
+
return relative === target || relative.startsWith(`${target}/`);
|
|
129
|
+
});
|
|
130
|
+
return {
|
|
131
|
+
hasLegacy, covers,
|
|
132
|
+
apply(replace) {
|
|
133
|
+
const updates = [];
|
|
134
|
+
if (replace) {
|
|
135
|
+
const clean = value => {
|
|
136
|
+
if (Array.isArray(value)) return value.filter(item => !oldHandler(item))
|
|
137
|
+
.flatMap(item => {
|
|
138
|
+
const next = clean(item);
|
|
139
|
+
return item?.hooks?.length > 0 && Array.isArray(next.hooks) && next.hooks.length === 0 ? [] : [next];
|
|
140
|
+
});
|
|
141
|
+
if (!value || typeof value !== 'object') return value;
|
|
142
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, clean(item)]));
|
|
143
|
+
};
|
|
144
|
+
for (const item of originals) {
|
|
145
|
+
let data;
|
|
146
|
+
try { data = JSON.parse(item.before.toString('utf8')); }
|
|
147
|
+
catch { throw phoenixFailure(1, `无法移除旧 hooks,配置不是合法 JSON: ${item.file}`); }
|
|
148
|
+
const next = { ...data };
|
|
149
|
+
if (data.hooks) next.hooks = clean(data.hooks);
|
|
150
|
+
if (data.enabledPlugins) next.enabledPlugins = Object.fromEntries(Object.entries(data.enabledPlugins)
|
|
151
|
+
.map(([key, value]) => [key, key.startsWith('impeccable') ? false : value]));
|
|
152
|
+
if (JSON.stringify(data) !== JSON.stringify(next)) updates.push({ ...item, after: JSON.stringify(next, null, 2) + '\n' });
|
|
153
|
+
}
|
|
154
|
+
for (const item of updates) {
|
|
155
|
+
if (!fs.readFileSync(item.file).equals(item.before)) throw phoenixFailure(3, `配置在预检后发生变化,请重跑: ${item.file}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const removals = [...refresh, ...(replace ? legacy : [])];
|
|
159
|
+
for (const file of [...removals, ...updates.map(item => item.file)]) {
|
|
160
|
+
for (let dir = path.dirname(file); dir !== parents.get(file); dir = path.dirname(dir)) {
|
|
161
|
+
if (fs.lstatSync(dir, { throwIfNoEntry: false })?.isSymbolicLink()) throw phoenixFailure(3, `工具目录的父路径是符号链接,未修改: ${dir}`);
|
|
162
|
+
}
|
|
163
|
+
if (updates.some(item => item.file === file) && fs.lstatSync(file).isSymbolicLink()) throw phoenixFailure(3, `共享配置是符号链接,未修改: ${file}`);
|
|
164
|
+
}
|
|
165
|
+
for (const file of removals) {
|
|
166
|
+
fs.rmSync(file, { recursive: true, force: true });
|
|
167
|
+
console.log(` ${refresh.includes(file) ? '重新安装' : '删除'} ${file}`);
|
|
168
|
+
}
|
|
169
|
+
for (const item of updates) {
|
|
170
|
+
fs.writeFileSync(item.file, item.after);
|
|
171
|
+
console.log(` 更新 ${item.file} (移除 impeccable hooks/插件启用项)`);
|
|
172
|
+
}
|
|
173
|
+
if (hasLegacy && !replace) console.log(' 保留 impeccable,与 Phoenix UI 共存');
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
72
178
|
// 预检只写用户 cache 里的 engine;dry-run 不写项目。冲突时整个安装在写项目前停下。
|
|
73
179
|
async function preparePhoenix(targetDir, options) {
|
|
74
180
|
const manifest = bootstrap.manifestAt(path.join(PHOENIX_DIR, 'VERSION.json'));
|
|
@@ -81,14 +187,15 @@ async function preparePhoenix(targetDir, options) {
|
|
|
81
187
|
+ ' 可用 --release-dir=DIR 指向已核验的离线 release 目录,或加 --no-phoenix-ui 先安装其余部分。');
|
|
82
188
|
}
|
|
83
189
|
const args = ['install', '--project', targetDir, '--bundle-root', path.join(PHOENIX_DIR, 'bundle'),
|
|
84
|
-
'--auxiliary-root', path.join(PKG_ROOT, 'skills'), '--json'];
|
|
190
|
+
'--auxiliary-root', path.join(PKG_ROOT, 'skills'), '--keep-impeccable', '--json'];
|
|
85
191
|
if (options.providers) args.push('--providers', options.providers);
|
|
86
192
|
const plan = runPhoenix(binary, [...args, '--dry-run']).report;
|
|
87
|
-
|
|
193
|
+
const tools = preparePhoenixTools(plan.project, plan.providers);
|
|
194
|
+
if (plan.status === 'conflict' && plan.conflicts.some(conflict => !tools.covers(conflict.path))) {
|
|
88
195
|
printPhoenix(plan, manifest);
|
|
89
196
|
throw phoenixFailure(3, 'Phoenix UI 预检发现冲突,未修改项目。解决上列冲突后重跑;或加 --no-phoenix-ui 先安装其余部分。');
|
|
90
197
|
}
|
|
91
|
-
return { manifest, binary, args };
|
|
198
|
+
return { manifest, binary, args, tools };
|
|
92
199
|
}
|
|
93
200
|
|
|
94
201
|
function groupedPaths(paths) {
|
|
@@ -334,7 +441,7 @@ function usage() {
|
|
|
334
441
|
install [dir] 为目标项目(默认当前目录)安装 .claude/hooks 下的全部
|
|
335
442
|
hook,在 .claude/settings.json 中启用对应配置,并安装
|
|
336
443
|
Phoenix UI(设计 skill、hooks 与五个辅助 skill;engine 校验后
|
|
337
|
-
放入用户 cache;旧 impeccable
|
|
444
|
+
放入用户 cache;旧 impeccable 可选择替换或共存),
|
|
338
445
|
并询问是否创建通用的 AGENTS.md;
|
|
339
446
|
Codex / Claude Code goal 上下文收尾提醒默认不安装
|
|
340
447
|
help 显示本帮助
|
|
@@ -342,6 +449,8 @@ function usage() {
|
|
|
342
449
|
install 选项:
|
|
343
450
|
--no-phoenix-ui 跳过 Phoenix UI,仍安装 XGENT 的 hooks 与 settings(不删除已装版本)
|
|
344
451
|
--no-impeccable 已弃用,等同 --no-phoenix-ui
|
|
452
|
+
--replace-impeccable 删除项目及个人级旧 impeccable 工具和 hooks,不备份
|
|
453
|
+
--keep-impeccable 保留 impeccable,与 Phoenix UI 共存(无交互时默认)
|
|
345
454
|
--release-dir=DIR 离线安装 Phoenix UI engine:使用已核验的 release 目录,不联网
|
|
346
455
|
--xgent-init 创建 AGENTS.md (已有则跳过),不再询问
|
|
347
456
|
--no-xgent-init 跳过 AGENTS.md,不再询问
|
|
@@ -356,14 +465,14 @@ install 选项:
|
|
|
356
465
|
--providers=a,b 指定 Phoenix UI 装进哪些 harness 目录(默认按项目里已有的
|
|
357
466
|
目录判断,都没有时装 .claude;codex 同时选 .agents 与 .codex)
|
|
358
467
|
--force 允许覆盖非法 JSON 的 guard 配置(先存 .bak),不覆盖已有 AGENTS.md;
|
|
359
|
-
|
|
468
|
+
不绕过 Phoenix 受管安装及共享配置的冲突保护
|
|
360
469
|
`);
|
|
361
470
|
}
|
|
362
471
|
|
|
363
472
|
async function install(args) {
|
|
364
473
|
const flags = args.filter((a) => a.startsWith('--'));
|
|
365
474
|
const dirArg = args.find((a) => !a.startsWith('--'));
|
|
366
|
-
const unknown = flags.filter((f) => !['--no-phoenix-ui', '--no-impeccable', '--xgent-init', '--no-xgent-init', '--context-goal-guard', '--no-context-goal-guard', '--claude-context-goal-guard', '--no-claude-context-goal-guard', '--force'].includes(f)
|
|
475
|
+
const unknown = flags.filter((f) => !['--no-phoenix-ui', '--no-impeccable', '--replace-impeccable', '--keep-impeccable', '--xgent-init', '--no-xgent-init', '--context-goal-guard', '--no-context-goal-guard', '--claude-context-goal-guard', '--no-claude-context-goal-guard', '--force'].includes(f)
|
|
367
476
|
&& !['--providers=', '--release-dir=', '--context-goal-guard-threshold=', '--claude-context-goal-guard-threshold='].some((p) => f.startsWith(p)));
|
|
368
477
|
if (unknown.length > 0) {
|
|
369
478
|
console.error(`错误: 未知选项: ${unknown.join(', ')}\n`);
|
|
@@ -374,6 +483,9 @@ async function install(args) {
|
|
|
374
483
|
console.error('错误: --xgent-init 与 --no-xgent-init 不能同时使用');
|
|
375
484
|
process.exit(1);
|
|
376
485
|
}
|
|
486
|
+
if (flags.includes('--replace-impeccable') && flags.includes('--keep-impeccable')) {
|
|
487
|
+
throw phoenixFailure(1, '--replace-impeccable 与 --keep-impeccable 不能同时使用');
|
|
488
|
+
}
|
|
377
489
|
if (flags.includes('--context-goal-guard') && flags.includes('--no-context-goal-guard')) {
|
|
378
490
|
console.error('错误: --context-goal-guard 与 --no-context-goal-guard 不能同时使用');
|
|
379
491
|
process.exit(1);
|
|
@@ -444,21 +556,33 @@ async function install(args) {
|
|
|
444
556
|
const askAgents = !flags.includes('--xgent-init') && !flags.includes('--no-xgent-init') && !agentsExists;
|
|
445
557
|
const guard = flags.includes('--context-goal-guard') || codexThreshold !== undefined;
|
|
446
558
|
const claudeGuard = flags.includes('--claude-context-goal-guard') || claudeThreshold !== undefined;
|
|
447
|
-
|
|
448
|
-
|
|
559
|
+
let codexGuardPlan = guard ? prepareContextGoalGuard(targetDir, options.force, codexThreshold) : null;
|
|
560
|
+
let claudeGuardPlan = claudeGuard ? prepareClaudeContextGoalGuard(targetDir, options.force, claudeThreshold) : null;
|
|
449
561
|
const phoenix = options.phoenix ? await preparePhoenix(targetDir, options) : null;
|
|
450
|
-
const
|
|
562
|
+
const askReplace = phoenix?.tools.hasLegacy && !flags.includes('--replace-impeccable') && !flags.includes('--keep-impeccable');
|
|
563
|
+
const rl = process.stdin.isTTY && (askAgents || askReplace)
|
|
451
564
|
? readline.createInterface({ input: process.stdin, output: process.stdout }) : null;
|
|
452
565
|
const answers = rl?.[Symbol.asyncIterator]();
|
|
453
566
|
rl?.once('SIGINT', () => { rl.close(); process.exit(130); });
|
|
454
567
|
let agents;
|
|
568
|
+
let replace = flags.includes('--replace-impeccable');
|
|
455
569
|
try {
|
|
570
|
+
if (askReplace) replace = await confirm(
|
|
571
|
+
'发现旧 impeccable,是否删除并替换为 Phoenix UI(含个人级入口,不备份)? [y/N] ',
|
|
572
|
+
' 保留 impeccable:无交互环境默认共存;可用 --replace-impeccable 替换', answers);
|
|
456
573
|
agents = flags.includes('--xgent-init') || (askAgents && await confirm(
|
|
457
574
|
'是否同时创建通用的 AGENTS.md (含 Portal 联调与前端验收约定)? [y/N] ',
|
|
458
575
|
' 跳过 AGENTS.md:非交互环境,可加 --xgent-init 创建', answers));
|
|
459
576
|
} finally {
|
|
460
577
|
rl?.close();
|
|
461
578
|
}
|
|
579
|
+
if (phoenix) {
|
|
580
|
+
phoenix.tools.apply(replace);
|
|
581
|
+
// Cleanup may change shared settings that the optional guards also merge.
|
|
582
|
+
if (fs.existsSync(settingsPath)) settings = readJson(settingsPath);
|
|
583
|
+
codexGuardPlan = guard ? prepareContextGoalGuard(targetDir, options.force, codexThreshold) : null;
|
|
584
|
+
claudeGuardPlan = claudeGuard ? prepareClaudeContextGoalGuard(targetDir, options.force, claudeThreshold) : null;
|
|
585
|
+
}
|
|
462
586
|
codexGuardPlan?.write();
|
|
463
587
|
claudeGuardPlan?.write();
|
|
464
588
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"bunLockSha256": "a270544054db793212391f3b409111fd56ffd71eaca913038168585e7ace95f9",
|
|
6
6
|
"policySha256": "ca369705c8ce28efdbdc96fcc666e579f17f394fb4c6696e993c3b2b8e46b095",
|
|
7
7
|
"checkerSha256": "806b2e325b8b8b4832e7827581061ee50bf56879f4ab275de1139e3760c933f3",
|
|
8
|
-
"buildToolsSha256": "
|
|
8
|
+
"buildToolsSha256": "a58ae8b0b7b973fd68d611b5f613807b6658a8917fc70729ea8f6ac0a74f7bf1"
|
|
9
9
|
},
|
|
10
10
|
"rust": [
|
|
11
11
|
{
|
|
@@ -6615,7 +6615,7 @@
|
|
|
6615
6615
|
{
|
|
6616
6616
|
"path": "tools/phoenix-ui/crates/live/assets/detect-antipatterns-browser.js",
|
|
6617
6617
|
"importedPath": "crates/live/assets/detect-antipatterns-browser.js",
|
|
6618
|
-
"sha256": "
|
|
6618
|
+
"sha256": "eecc6bd09d7327312ab03e533b9f5d4dfca4cf8236fa8bffbdf38fbc50c676a8",
|
|
6619
6619
|
"license": "Apache-2.0",
|
|
6620
6620
|
"licenses": [
|
|
6621
6621
|
{
|
|
@@ -2,38 +2,38 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"distribution": "release",
|
|
4
4
|
"toolVersion": "0.1.0",
|
|
5
|
-
"npmPackageVersion": "0.7.
|
|
6
|
-
"sourceCommit": "
|
|
7
|
-
"sourceTree": "
|
|
5
|
+
"npmPackageVersion": "0.7.5",
|
|
6
|
+
"sourceCommit": "042e28223bf25ba50906ed4b1d035bb59d4e704f",
|
|
7
|
+
"sourceTree": "c9ebe58210496864b2c4c7cf12009db0f16f38ab",
|
|
8
8
|
"sourceState": "dirty",
|
|
9
|
-
"sourceInputSha256": "
|
|
9
|
+
"sourceInputSha256": "ebcdd29be3ccde395a68ee05baf3b6d3e24b4c53248602b087c629d9fef46bec",
|
|
10
10
|
"bundleSchema": 1,
|
|
11
|
-
"bundleSha256": "
|
|
11
|
+
"bundleSha256": "6edaf6302bd6db2029279f9fea9d610ae36b0a0629692a4afd3badfabe1b58c8",
|
|
12
12
|
"reviewSchema": 1,
|
|
13
13
|
"engines": {
|
|
14
14
|
"darwin-arm64": {
|
|
15
15
|
"asset": "phoenix-ui-darwin-arm64",
|
|
16
|
-
"sha256": "
|
|
16
|
+
"sha256": "df68d6d5dedf38af728b8e97fd92488a07ddb3b7fb380ca61bd3a8e2a6e913dc",
|
|
17
17
|
"size": 18284080,
|
|
18
|
-
"url": "https://download.xgent.ai/vendor/phoenix-ui/v0.7.
|
|
18
|
+
"url": "https://download.xgent.ai/vendor/phoenix-ui/v0.7.5/darwin-arm64/phoenix-ui-darwin-arm64"
|
|
19
19
|
},
|
|
20
20
|
"darwin-x64": {
|
|
21
21
|
"asset": "phoenix-ui-darwin-x64",
|
|
22
|
-
"sha256": "
|
|
23
|
-
"size":
|
|
24
|
-
"url": "https://download.xgent.ai/vendor/phoenix-ui/v0.7.
|
|
22
|
+
"sha256": "b9db99603466c35439f790558b965acd36f49a346b25411c9385abc1cd43ed88",
|
|
23
|
+
"size": 20776616,
|
|
24
|
+
"url": "https://download.xgent.ai/vendor/phoenix-ui/v0.7.5/darwin-x64/phoenix-ui-darwin-x64"
|
|
25
25
|
},
|
|
26
26
|
"linux-x64": {
|
|
27
27
|
"asset": "phoenix-ui-linux-x64",
|
|
28
|
-
"sha256": "
|
|
29
|
-
"size":
|
|
30
|
-
"url": "https://download.xgent.ai/vendor/phoenix-ui/v0.7.
|
|
28
|
+
"sha256": "4a6784eec02e3d6b6889a45fae8a1382d7a1294c499e2ac2fb84e3705bc14221",
|
|
29
|
+
"size": 22856560,
|
|
30
|
+
"url": "https://download.xgent.ai/vendor/phoenix-ui/v0.7.5/linux-x64/phoenix-ui-linux-x64"
|
|
31
31
|
},
|
|
32
32
|
"linux-arm64": {
|
|
33
33
|
"asset": "phoenix-ui-linux-arm64",
|
|
34
|
-
"sha256": "
|
|
34
|
+
"sha256": "529d442d539da819a7a9e44092e66d3aefc19135eda9526bf50f4f979591b493",
|
|
35
35
|
"size": 19702656,
|
|
36
|
-
"url": "https://download.xgent.ai/vendor/phoenix-ui/v0.7.
|
|
36
|
+
"url": "https://download.xgent.ai/vendor/phoenix-ui/v0.7.5/linux-arm64/phoenix-ui-linux-arm64"
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -8,7 +8,7 @@ license: Apache 2.0
|
|
|
8
8
|
metadata:
|
|
9
9
|
version: 0.1.0
|
|
10
10
|
source: skills/phoenix-ui/src
|
|
11
|
-
source_sha256:
|
|
11
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
Phoenix UI provides local design tools for frontend work. Follow the project's product truth, accepted direction, and design rules; use the command references to create complete, accessible interfaces with a clear visual direction.
|
|
@@ -8,7 +8,7 @@ license: Apache 2.0
|
|
|
8
8
|
metadata:
|
|
9
9
|
version: 0.1.0
|
|
10
10
|
source: skills/phoenix-ui/src
|
|
11
|
-
source_sha256:
|
|
11
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
12
12
|
allowed-tools:
|
|
13
13
|
- Bash(.opencode/skills/phoenix-ui/scripts/phoenix-ui *)
|
|
14
14
|
---
|
|
@@ -8,7 +8,7 @@ license: Apache 2.0
|
|
|
8
8
|
metadata:
|
|
9
9
|
version: 0.1.0
|
|
10
10
|
source: skills/phoenix-ui/src
|
|
11
|
-
source_sha256:
|
|
11
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
12
12
|
allowed-tools:
|
|
13
13
|
- Bash(.rovodev/skills/phoenix-ui/scripts/phoenix-ui *)
|
|
14
14
|
---
|
|
@@ -8,7 +8,7 @@ license: Apache 2.0
|
|
|
8
8
|
metadata:
|
|
9
9
|
version: 0.1.0
|
|
10
10
|
source: skills/phoenix-ui/src
|
|
11
|
-
source_sha256:
|
|
11
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
12
12
|
allowed-tools:
|
|
13
13
|
- Bash(.grok/skills/phoenix-ui/scripts/phoenix-ui *)
|
|
14
14
|
---
|
|
@@ -59,7 +59,8 @@ function cacheRoot(env = process.env) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function enginePath(manifest, target, env = process.env) {
|
|
62
|
-
return path.join(cacheRoot(env), 'bin', manifest.data.toolVersion, target, target.
|
|
62
|
+
return path.join(cacheRoot(env), 'bin', manifest.data.toolVersion, target, manifest.data.engines[target].sha256,
|
|
63
|
+
target.startsWith('windows-') ? 'phoenix-ui.exe' : 'phoenix-ui');
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
function projectRoot(start) {
|
|
@@ -6,7 +6,7 @@ license: Apache 2.0
|
|
|
6
6
|
metadata:
|
|
7
7
|
version: 0.1.0
|
|
8
8
|
source: skills/phoenix-ui/src
|
|
9
|
-
source_sha256:
|
|
9
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
10
10
|
allowed-tools:
|
|
11
11
|
- Bash(.agent/skills/phoenix-ui/scripts/phoenix-ui *)
|
|
12
12
|
---
|
|
@@ -8,7 +8,7 @@ license: Apache 2.0
|
|
|
8
8
|
metadata:
|
|
9
9
|
version: 0.1.0
|
|
10
10
|
source: skills/phoenix-ui/src
|
|
11
|
-
source_sha256:
|
|
11
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
Phoenix UI provides local design tools for frontend work. Follow the project's product truth, accepted direction, and design rules; use the command references to create complete, accessible interfaces with a clear visual direction.
|
|
@@ -6,7 +6,7 @@ license: Apache 2.0
|
|
|
6
6
|
metadata:
|
|
7
7
|
version: 0.1.0
|
|
8
8
|
source: skills/phoenix-ui/src
|
|
9
|
-
source_sha256:
|
|
9
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
10
10
|
allowed-tools:
|
|
11
11
|
- Bash(.pi/skills/phoenix-ui/scripts/phoenix-ui *)
|
|
12
12
|
---
|
|
@@ -6,7 +6,7 @@ license: Apache 2.0
|
|
|
6
6
|
metadata:
|
|
7
7
|
version: 0.1.0
|
|
8
8
|
source: skills/phoenix-ui/src
|
|
9
|
-
source_sha256:
|
|
9
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
Phoenix UI provides local design tools for frontend work. Follow the project's product truth, accepted direction, and design rules; use the command references to create complete, accessible interfaces with a clear visual direction.
|
|
@@ -8,7 +8,7 @@ license: Apache 2.0
|
|
|
8
8
|
metadata:
|
|
9
9
|
version: 0.1.0
|
|
10
10
|
source: skills/phoenix-ui/src
|
|
11
|
-
source_sha256:
|
|
11
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
Phoenix UI provides local design tools for frontend work. Follow the project's product truth, accepted direction, and design rules; use the command references to create complete, accessible interfaces with a clear visual direction.
|
|
@@ -8,7 +8,7 @@ license: Apache 2.0
|
|
|
8
8
|
metadata:
|
|
9
9
|
version: 0.1.0
|
|
10
10
|
source: skills/phoenix-ui/src
|
|
11
|
-
source_sha256:
|
|
11
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
12
12
|
allowed-tools:
|
|
13
13
|
- Bash(.qoder/skills/phoenix-ui/scripts/phoenix-ui *)
|
|
14
14
|
---
|
|
@@ -8,7 +8,7 @@ license: Apache 2.0
|
|
|
8
8
|
metadata:
|
|
9
9
|
version: 0.1.0
|
|
10
10
|
source: skills/phoenix-ui/src
|
|
11
|
-
source_sha256:
|
|
11
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
Phoenix UI provides local design tools for frontend work. Follow the project's product truth, accepted direction, and design rules; use the command references to create complete, accessible interfaces with a clear visual direction.
|
|
@@ -6,7 +6,7 @@ license: Apache 2.0
|
|
|
6
6
|
metadata:
|
|
7
7
|
version: 0.1.0
|
|
8
8
|
source: skills/phoenix-ui/src
|
|
9
|
-
source_sha256:
|
|
9
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
Phoenix UI provides local design tools for frontend work. Follow the project's product truth, accepted direction, and design rules; use the command references to create complete, accessible interfaces with a clear visual direction.
|
|
@@ -7,7 +7,7 @@ license: Apache 2.0
|
|
|
7
7
|
metadata:
|
|
8
8
|
version: 0.1.0
|
|
9
9
|
source: skills/phoenix-ui/src
|
|
10
|
-
source_sha256:
|
|
10
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
Phoenix UI provides local design tools for frontend work. Follow the project's product truth, accepted direction, and design rules; use the command references to create complete, accessible interfaces with a clear visual direction.
|
|
@@ -6,7 +6,7 @@ license: Apache 2.0
|
|
|
6
6
|
metadata:
|
|
7
7
|
version: 0.1.0
|
|
8
8
|
source: skills/phoenix-ui/src
|
|
9
|
-
source_sha256:
|
|
9
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
Phoenix UI provides local design tools for frontend work. Follow the project's product truth, accepted direction, and design rules; use the command references to create complete, accessible interfaces with a clear visual direction.
|
|
@@ -7,7 +7,7 @@ license: Apache 2.0
|
|
|
7
7
|
metadata:
|
|
8
8
|
version: 0.1.0
|
|
9
9
|
source: skills/phoenix-ui/src
|
|
10
|
-
source_sha256:
|
|
10
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
11
11
|
allowed-tools:
|
|
12
12
|
- Bash(.vibe/skills/phoenix-ui/scripts/phoenix-ui *)
|
|
13
13
|
---
|
|
@@ -6,7 +6,7 @@ license: Apache 2.0
|
|
|
6
6
|
metadata:
|
|
7
7
|
version: 0.1.0
|
|
8
8
|
source: skills/phoenix-ui/src
|
|
9
|
-
source_sha256:
|
|
9
|
+
source_sha256: 5c927aea719c3d5648b13943c104508009f50ceb59aef7e0317d9b33215311aa
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
Phoenix UI provides local design tools for frontend work. Follow the project's product truth, accepted direction, and design rules; use the command references to create complete, accessible interfaces with a clear visual direction.
|