@xgent-ai/skills 0.7.8 → 0.7.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.
Files changed (44) hide show
  1. package/README.md +8 -19
  2. package/bin/xgent-skills.js +23 -55
  3. package/dist/phoenix-diagram/VERSION.json +18 -18
  4. package/dist/phoenix-diagram/bundle/ENGINE.json +18 -18
  5. package/dist/phoenix-diagram/bundle/manifest.json +4 -4
  6. package/dist/phoenix-diagram/bundle/references/migration.md +1 -1
  7. package/dist/phoenix-diagram/bundle/scripts/phoenix-bootstrap.cjs +4 -103
  8. package/dist/phoenix-ui/THIRD-PARTY.json +1 -1
  9. package/dist/phoenix-ui/VERSION.json +19 -19
  10. package/dist/phoenix-ui/bundle/blobs/{567c3f42394f9aee9b048a001016a7ba9d8773d78027f8c995c379886634e719 → 0c95d5c7163bc162cca460e2297ab146e331fd279a738a2055643b45b161c706} +1 -1
  11. package/dist/phoenix-ui/bundle/blobs/{f077545caeb3ecb9f51a3f703a09736ca924869f4b4345c1b1ffbd9bf927a287 → 14bd6a733ce89fcd02bf6dcf0f91378625cb7739a0baaca9cb7611c332ac4580} +1 -1
  12. package/dist/phoenix-ui/bundle/blobs/{125bc7030d7f2ba789d7b1d5f474af34f8902b764e7bc351b98f1f6f55779929 → 14f329a7925311958685a16ba370c4997e924d909091e0977e5d32b3e64ecc4f} +1 -1
  13. package/dist/phoenix-ui/bundle/blobs/{8078b804bea630ed9c4ea07ec2f8ac92aba4128725860a66599eda90390d98f6 → 2b168c9ff212b8daea0d4334c94810458a683cde62f26b985855f8bf3f959db7} +1 -1
  14. package/dist/phoenix-ui/bundle/blobs/{00f4a6a630f31eb05fbdd5725e4a294233d24574bd70f4f32f4597d8256a7c1c → 2fbbc46784d2ab789675941ce81d91822ac00bd5c3e144d06743d0b8ccaccc90} +2 -17
  15. package/dist/phoenix-ui/bundle/blobs/{90f8b07ec12b78e633e306322cda58415aea70d8e0f9ff85bd439361c01dabe1 → 35913e9a7ac47f91c8af70867c71d938aa7f200b562c867fa6a43c4a6209ef61} +1 -1
  16. package/dist/phoenix-ui/bundle/blobs/{0e684572eb98d24b39cd70fa23e66c163178f5a11756dcf8a98fe2335636b33f → 3b62a4d253765fe0bdb180581cf493434d15de94e1b31470c573c0a21ece9e31} +1 -1
  17. package/dist/phoenix-ui/bundle/blobs/{68b454a99ba72c3b9b93ed96c4267847297169f6a5bf321b20e60d637c271068 → 557baa7f9ea3d863f40602f37a85e9af09f9120cfa0669b0b95539774e87b9dc} +1 -1
  18. package/dist/phoenix-ui/bundle/blobs/{c0a70ab2889e5c16e1f09249aefad948ce352c42cfe2b5afb758a4524e1b21b6 → 67fc771aa87556ecc8236c44e76251a41fa4e1809c6ad8c6a1f8eb9de91bb2d7} +1 -1
  19. package/dist/phoenix-ui/bundle/blobs/{88b150cb804bc141b80a5687a091f61b99627155c465a27adb88546ef615af92 → 6b3068f23e684f8566e7f4b069a5554624f479d57ff9073610a0917fe5b5e5af} +1 -1
  20. package/dist/phoenix-ui/bundle/blobs/{61450dbef64859e3136cd17ae3e997134d5df5721d96985c4e07367f38522129 → 6f600dfa082ed593159d3906d108baff9f4cb6bf90817a47429d613a95771d6f} +1 -1
  21. package/dist/phoenix-ui/bundle/blobs/{36310febe3e7bd4c9b21407603f2a04afefdc87b7821758bb47098b1b2876765 → 7bff2e1985a347235ef84b783f801eb3f5872d6e2a8d0278fc8c52c3cd1ac4a4} +1 -1
  22. package/dist/phoenix-ui/bundle/blobs/{e46d63e5f8a6ead1d44c8b6302a0c7247af8585b975ab5715518381777622ede → 821bda87cb9fc9f4349cf5243e18d7b4afc899ee884e33b16007ca3f1f5c9de1} +1 -1
  23. package/dist/phoenix-ui/bundle/blobs/{cadc2daefcf238aab981fa56388381d3d5ab9c0686bb9dd8187035c9933dfcee → 8291ff7c0eef14199f7d209cb8eb5e6643034c1923805b5c7023c93010d7af6e} +1 -1
  24. package/dist/phoenix-ui/bundle/blobs/{6b8d4c71355429a0b16bf367163fea46103a0a99b4e34f87608a39d85b1b980a → 94e595bc8239f72e0f5389f83aa022b18541839fb651d87b5933e89c92836a15} +1 -1
  25. package/dist/phoenix-ui/bundle/blobs/{55277fa15eb4bd2f09bf7bb24c4e79df417b06654b1e10f502c7928b192fd7cc → ba015e8aac17711d7dfbcfce3e8c92190af383af595b9ca58b7df2c0c30ba579} +1 -1
  26. package/dist/phoenix-ui/bundle/blobs/{3625c5c2750f117021232ce81c1e39ac5ef7c21445729327b88cf54dfc937df0 → fddd4bd853ad367d7f755477ee7c5ac3d0d3965c81c8a8e20eb83edc9cb7d43b} +1 -1
  27. package/dist/phoenix-ui/bundle/manifest.json +34 -34
  28. package/docs/phoenix-diagram.md +8 -6
  29. package/{skills/review-ui/references/phoenix-review.md → docs/phoenix-ui-review.md} +7 -12
  30. package/docs/phoenix-ui.md +17 -19
  31. package/package.json +2 -1
  32. package/skills/apply-ui-review/SKILL.md +1 -1
  33. package/skills/optimize-agents-md/SKILL.md +39 -21
  34. package/skills/optimize-agents-md/assets/coding-principles.md +78 -38
  35. package/skills/phoenix-diagram/ENGINE.json +18 -18
  36. package/skills/phoenix-diagram/references/migration.md +1 -1
  37. package/skills/phoenix-diagram/scripts/phoenix-bootstrap.cjs +4 -103
  38. package/skills/phoenix-ui/GENERATED.json +78 -78
  39. package/skills/phoenix-ui/SKILL.md +1 -1
  40. package/skills/phoenix-ui/scripts/ENGINE.json +19 -19
  41. package/skills/phoenix-ui/scripts/phoenix-bootstrap.cjs +2 -17
  42. package/skills/review-ui/SKILL.md +2 -1
  43. package/skills/xgent-init/SKILL.md +1 -1
  44. package/skills/review-ui/references/rules.v1.json +0 -1853
@@ -36,7 +36,7 @@ dry-run只报告计划与冲突,零写入;遇pending只报告,不恢复。
36
36
 
37
37
  recover不接受dry-run;recover/rollback都不接受bundle-root、providers或confirm-remove-archify。它们核已存在的固定正确引擎与本地事务,不下载、不更新、不重装旧skill,不要求当前active安装已完整提交。
38
38
 
39
- 普通 install 的 pending 恢复仍按其回执重跑原显式 install;`migrate --recover ID` 用于已确认的迁移或正在回滚的指定事务,不能代替普通安装恢复。优先执行对应回执的 `recoveryCommand`,不要只因有 journal ID 就改用迁移恢复命令。
39
+ 普通 install 直接覆盖工具文件,不建立事务;中断后重跑即可。成功安装会清理旧安装与迁移状态,不保留历史回滚入口。`migrate --recover ID` 仅用于仍存在的已确认迁移或回滚事务,优先执行该迁移回执的 `recoveryCommand`。
40
40
 
41
41
  - Recover继续指定已确认事务的安全剩余步骤;同一确认范围不重复索取确认。后来新增/改写、删除后重建或父目录身份变化保留并报告recovery-required;不凭stdout推断哪些文件已删。
42
42
  - Rollback仅回滚**当前committed事务**的新入口受管写入;包括仍为v1的当前事务经原生引擎验证并扩展后的回滚,不是跳过后来安装去回滚任意历史ID。后来修改在预检时冲突,先保持零变更;中途身份变化仍保留拒绝。成功rolled-back,同一ID可幂等重试。
@@ -353,106 +353,12 @@ function projectRoot(start) {
353
353
  let directory = initial;
354
354
  if (!fs.statSync(initial).isDirectory()) throw failure(`Project is not a directory: ${start}`, 2);
355
355
  for (;;) {
356
- if (exists(path.join(directory, '.phoenix-diagram/install/active.json')) || exists(path.join(directory, '.git'))) return directory;
356
+ if (exists(path.join(directory, '.git'))) return directory;
357
357
  const parent = path.dirname(directory);
358
358
  if (parent === directory) return initial;
359
359
  directory = parent;
360
360
  }
361
361
  }
362
- function physical(stat) { return { device: stat.dev.toString(), inode: stat.ino.toString() }; }
363
- function identity(snapshot) {
364
- const { stat, bytes } = snapshot;
365
- return { ...physical(stat), links: Number(stat.nlink), mode: Number(stat.mode & 0o777n), uid: Number(stat.uid), sha256: sha256(bytes), bytes: bytes.length };
366
- }
367
- function same(left, right) { return JSON.stringify(left) === JSON.stringify(right); }
368
- function sealed(file) {
369
- const snapshot = readRegular(file, MAX_ENGINE, 0o600);
370
- const data = JSON.parse(snapshot.bytes);
371
- if (!object(data) || !SHA.test(data.checksum || '') || sha256(encoded({ ...data, checksum: '' })) !== data.checksum || !snapshot.bytes.equals(encoded(data))) throw failure(`Invalid canonical installation ownership/journal checksum: ${file}`);
372
- if (snapshot.stat.uid !== BigInt(process.getuid())) throw failure(`Installation state belongs to a different owner: ${file}`);
373
- return { ...snapshot, data };
374
- }
375
- function managed(name) {
376
- if (!relative(name)) return false;
377
- const [provider, skills, tool, ...rest] = name.split('/');
378
- return PROVIDERS.includes(provider) && provider !== '.codex' && skills === 'skills' && tool === TOOL && allowed(rest.join('/'), true);
379
- }
380
- function verifiedJournalPublicationEntry(journals, name) {
381
- const parent = fs.lstatSync(journals, { bigint: true });
382
- if (!parent.isDirectory() || parent.isSymbolicLink() || parent.uid !== BigInt(process.getuid()) || (parent.mode & 0o7777n) !== 0o700n) throw failure('Installation journal directory is not private.');
383
- if (name === '.phoenix-diagram-output-cleanup') {
384
- const directory = childFile(journals, name), stat = fs.lstatSync(directory, { bigint: true });
385
- if (!stat.isDirectory() || stat.isSymbolicLink() || stat.uid !== parent.uid || (stat.mode & 0o7777n) !== 0o700n) throw failure('Unknown journal publication cleanup directory.');
386
- const marker = readRegular(childFile(directory, 'owner-v1.json'), 16 * 1024, 0o600);
387
- const owner = JSON.parse(marker.bytes);
388
- const expected = { schemaVersion: 1, tool: TOOL, kind: 'output-cleanup-directory', parentPath: journals, parent: physical(parent), directory: physical(stat), recordIdentity: physical(marker.stat), checksum: '' };
389
- expected.checksum = sha256(Buffer.from(JSON.stringify(expected)));
390
- if (marker.stat.uid !== parent.uid || !marker.bytes.equals(encoded(expected)) || !same(owner, expected)) throw failure('Journal publication cleanup owner binding or checksum differs.');
391
- if (fs.readdirSync(directory).some(entry => entry !== 'owner-v1.json')) throw failure('Journal publication cleanup requires explicit native recovery; unknown records are preserved.');
392
- return true;
393
- }
394
- if (name.startsWith('.phoenix-diagram-lock-')) {
395
- const marker = readRegular(childFile(journals, name), 16 * 1024, 0o600), lock = JSON.parse(marker.bytes);
396
- if (!/^[a-f0-9]{32}\.json$/.test(lock.name || '') || name !== `.phoenix-diagram-lock-${sha256(lock.name)}.lock` || !exists(childFile(journals, lock.name))) throw failure('Unknown journal publication lock target or filename.');
397
- const expected = { schemaVersion: 1, tool: TOOL, kind: 'output-lock', name: lock.name, parentDevice: parent.dev.toString(), parentInode: parent.ino.toString() };
398
- if (marker.stat.uid !== parent.uid || !marker.bytes.equals(Buffer.from(JSON.stringify(expected)))) throw failure('Journal publication lock identity or bytes differ.');
399
- return true;
400
- }
401
- return false;
402
- }
403
- function verifyReceipt(project, manifest, options = {}) {
404
- const receiptPath = '.phoenix-diagram/install/active.json';
405
- const file = path.join(project, receiptPath);
406
- if (!exists(file)) {
407
- if (options.installedSkillRoot) throw failure('Installed skill has no diagram ownership receipt.');
408
- return null;
409
- }
410
- const snapshot = sealed(childFile(project, receiptPath));
411
- const active = snapshot.data; const version = manifest.data;
412
- const transaction = active.transactionId;
413
- if (![1, 2].includes(active.schemaVersion) || active.tool !== TOOL || active.toolVersion !== TOOL_VERSION || !/^[a-f0-9]{32}$/.test(transaction || '') || !same(active.project, physical(fs.statSync(project, { bigint: true })))
414
- || active.npmPackageVersion !== version.npmPackageVersion || active.bundleManifestSha256 !== version.bundleSha256 || active.engineManifestSha256 !== manifest.hash
415
- || active.engine?.sourceInputSha256 !== version.sourceInputSha256 || active.engine?.inputContractSchema !== 1 || active.engine?.receiptSchema !== 1 || active.engine?.viewerRevision !== 'phoenix-v2'
416
- || !Object.values(version.engines).some(meta => meta.sha256 === active.engine?.binary?.sha256 && meta.size === active.engine?.binary?.bytes)
417
- || !Array.isArray(active.providers) || !active.providers.length || new Set(active.providers).size !== active.providers.length || active.providers.some(provider => !PROVIDERS.includes(provider))
418
- || active.journal !== `.phoenix-diagram/install/journals/${transaction}.json` || active.backup !== `.phoenix-diagram/install/transactions/${transaction}/before`
419
- || !Array.isArray(active.ownership) || !active.ownership.length || active.ownership.length > 200000
420
- || active.planSha256 !== sha256(encoded([active.bundleManifestSha256, active.engineManifestSha256, active.providers, active.ownership]))) throw failure('Project ownership requires a different or invalid Phoenix Diagram package/contract identity.');
421
- const journal = sealed(childFile(project, active.journal)).data;
422
- if (![1, 2].includes(journal.schemaVersion) || journal.tool !== TOOL || journal.transactionId !== transaction || journal.phase !== 'committed' || journal.pending !== null || !Array.isArray(journal.operations) || !journal.operations.length || journal.completed !== journal.operations.length
423
- || !same(journal.project, active.project) || !same(journal.active, active)
424
- || !same(journal.transaction, physical(fs.statSync(path.dirname(path.join(project, active.backup)), { bigint: true })))
425
- || journal.operations[journal.operations.length - 1].path !== receiptPath || !same(journal.operations[journal.operations.length - 1].after, identity(snapshot))) throw failure('Installed ownership is not bound to a completed native journal.');
426
- if (journal.migration && (journal.schemaVersion !== 2 || journal.migration.confirmed !== true || !Array.isArray(journal.migration.roots) || journal.migration.roots.some(root => root.kind !== 'legacy-root-remove' || !active.providers.some(provider => root.path === `${provider}/skills/archify`) || !['legacy-2.17', 'legacy-2.17-when-to-use', 'reference-3.1.0'].includes(root.source) || root.pending !== null || !Array.isArray(root.entries) || !root.entries.length || root.entries.some(entry => entry.removed !== true)))) throw failure('Legacy removal journal has not committed its confirmed scope.');
427
- let previous; const owned = new Map();
428
- for (const entry of active.ownership) {
429
- if (!managed(entry.path) || !active.providers.includes(entry.path.split('/')[0]) || previous && Buffer.compare(Buffer.from(previous), Buffer.from(entry.path)) >= 0 || ![0o644, 0o755].includes(entry.identity?.mode)) throw failure(`Unsafe managed ownership path: ${entry.path}`);
430
- const actual = readRegular(childFile(project, entry.path), MAX_ENGINE, entry.identity.mode);
431
- if (!same(identity(actual), entry.identity)) throw failure(`Managed ownership identity or digest changed: ${entry.path}`);
432
- owned.set(entry.path, entry.identity); previous = entry.path;
433
- }
434
- for (const [index, operation] of journal.operations.entries()) {
435
- if ((journal.schemaVersion === 2 ? operation.kind !== 'file-write' : operation.kind !== undefined)) throw failure('Unknown native journal operation kind.');
436
- if (operation.stagePath !== `after/${index}` || operation.retiredPath !== `retired/${index}` || operation.undoPath !== `undo/${index}` || operation.backupPath !== (operation.before ? `before/${index}` : null)) throw failure('Journal staging/backup paths differ from native ownership.');
437
- if (index + 1 < journal.operations.length && (!managed(operation.path) || !same(owned.get(operation.path), operation.after))) throw failure(`Journal operation differs from managed ownership: ${operation.path}`);
438
- }
439
- const journals = path.join(project, '.phoenix-diagram/install/journals');
440
- for (const name of fs.readdirSync(journals)) {
441
- if (verifiedJournalPublicationEntry(journals, name)) continue;
442
- if (!/^[a-f0-9]{32}\.json$/.test(name)) throw failure(`Unknown installation journal entry: ${name}`);
443
- const other = sealed(childFile(journals, name)).data;
444
- if (![1, 2].includes(other.schemaVersion) || other.tool !== TOOL || !same(other.project, active.project) || !['committed', 'recovered'].includes(other.phase)) throw failure('Diagram installation requires explicit native recovery before ordinary use.');
445
- }
446
- if (options.installedSkillRoot) {
447
- const relativeRoot = path.relative(project, options.installedSkillRoot).split(path.sep).join('/');
448
- if (!owned.has(`${relativeRoot}/ENGINE.json`) || !owned.has(`${relativeRoot}/SKILL.md`)) throw failure('Launcher skill root is not managed by this project ownership record.');
449
- const engine = readRegular(childFile(options.installedSkillRoot, 'ENGINE.json'), 1024 * 1024).bytes;
450
- if (!engine.equals(manifest.bytes)) throw failure('Installed ENGINE bytes differ from their native ownership identity.');
451
- inventory(options.installedSkillRoot, new Set([...owned.keys()].filter(name => name.startsWith(`${relativeRoot}/`)).map(name => name.slice(relativeRoot.length + 1))));
452
- }
453
- return active;
454
- }
455
-
456
362
  function exists(file) {
457
363
  try { fs.lstatSync(file); return true; } catch (error) { if (error.code === 'ENOENT') return false; throw error; }
458
364
  }
@@ -474,12 +380,7 @@ async function preflight(options = {}) {
474
380
  verifyBundle(bundleRoot, manifest);
475
381
  legalResources(path.dirname(versionManifestPath));
476
382
  if (options.releaseDir && options.allowInstall !== true) verifyOffline(path.resolve(options.releaseDir), manifest, verifyBundle(bundleRoot, manifest));
477
- // An explicit package upgrade lets native --dry-run validate the prior
478
- // ownership. Ordinary use never opts out of the current receipt binding.
479
- if (options.checkReceipt !== false) verifyReceipt(project, manifest);
480
383
  } else {
481
- if (!options.project && !exists(path.join(project, '.phoenix-diagram/install/active.json'))) project = projectRoot(skillDir);
482
- if (options.checkReceipt !== false) verifyReceipt(project, manifest, { installedSkillRoot: skillDir });
483
384
  bundleRoot = skillDir;
484
385
  if (options.releaseDir && options.allowInstall !== true) verifyOffline(path.resolve(options.releaseDir), manifest, null);
485
386
  }
@@ -551,14 +452,14 @@ async function main(args, options = {}) {
551
452
  }
552
453
  if (!requested) throw failure('Engine installation requires an explicit --project DIR.', 2);
553
454
  project = projectRoot(requested);
554
- const ready = await preflight({ ...options, project, releaseDir, env, allowInstall: true, checkReceipt: true });
455
+ const ready = await preflight({ ...options, project, releaseDir, env, allowInstall: true });
555
456
  manifest = ready.manifest; target = ready.target;
556
457
  const result = { schemaVersion: 1, tool: TOOL, toolVersion: TOOL_VERSION, command: 'engine install', status: 'installed', scope: 'engine-cache', diagnostics: [], npmPackageVersion: ready.version.npmPackageVersion, target, enginePath: ready.enginePath, project: ready.project };
557
458
  process.stdout.write(json ? encoded(result) : `Phoenix Diagram engine ${TOOL_VERSION} ready: ${ready.enginePath}\n`);
558
459
  return 0;
559
460
  }
560
461
  const migration = migrationOptions(args);
561
- const ready = await preflight({ ...options, ...(migration ? { project: migration.project, exactProject: true, ...(migration.from && migration.bundleRoot ? { bundleRoot: path.resolve(migration.bundleRoot) } : {}) } : {}), env, allowInstall: false, checkReceipt: !['install', 'migrate'].includes(args[0]) });
462
+ const ready = await preflight({ ...options, ...(migration ? { project: migration.project, exactProject: true, ...(migration.from && migration.bundleRoot ? { bundleRoot: path.resolve(migration.bundleRoot) } : {}) } : {}), env, allowInstall: false });
562
463
  manifest = ready.manifest; target = ready.target; project = ready.project;
563
464
  const childArgs = [...args];
564
465
  if ((args[0] === 'install' || migration?.from) && !args.some(arg => arg === '--bundle-root' || arg.startsWith('--bundle-root='))) childArgs.push('--bundle-root', ready.bundleRoot);
@@ -585,5 +486,5 @@ async function main(args, options = {}) {
585
486
  }
586
487
  }
587
488
 
588
- module.exports = { TARGETS, platformTarget, manifestAt, verifyBundle, verifyReceipt, verifyEngine, enginePath, installEngine, preflight, setupCommand, shellQuote, proxyFor, checkedUrl, sha256, migrationOptions, main };
489
+ module.exports = { TARGETS, platformTarget, manifestAt, verifyBundle, verifyEngine, enginePath, installEngine, preflight, setupCommand, shellQuote, proxyFor, checkedUrl, sha256, migrationOptions, main };
589
490
  if (require.main === module) main(process.argv.slice(2)).then(code => { process.exitCode = code; }).catch(error => { process.stderr.write(`Phoenix Diagram: ${error.message}\n`); process.exitCode = 4; });