create-yss-spec 3.5.4 → 3.5.6

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 (105) hide show
  1. package/README.md +10 -0
  2. package/cli-core.lock.json +130 -0
  3. package/package.json +7 -3
  4. package/resources/upgrade-skill/SKILL.md +26 -0
  5. package/resources/upgrade-skill/protocol.md +40 -0
  6. package/resources/upgrade-skill/references/cli-families.md +14 -0
  7. package/src/cli/help.js +1 -0
  8. package/src/cli/index.js +12 -0
  9. package/src/filesystem/transaction-runner.js +27 -0
  10. package/src/template/asset-runtime.js +9 -1
  11. package/src/template/instance-runtime.js +4 -2
  12. package/src/template/verification-runtime.js +9 -1
  13. package/template/.agents/skills/.strategic-design-skills-manifest.json +2 -2
  14. package/template/.agents/skills/yss-harness-upgrade/SKILL.md +26 -0
  15. package/template/.agents/skills/yss-harness-upgrade/references/cli-families.md +14 -0
  16. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +1 -0
  17. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +15 -19
  18. package/template/.agents/skills/yss-stage-decision/SKILL.md +3 -0
  19. package/template/.agents/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +8 -4
  20. package/template/.agents/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +8 -4
  21. package/template/.agents/skills/yss-stage-decision/tests/run-scenarios.mjs +13 -1
  22. package/template/.codex/skills/yss-harness-upgrade/SKILL.md +26 -0
  23. package/template/.codex/skills/yss-harness-upgrade/references/cli-families.md +14 -0
  24. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +1 -0
  25. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +15 -19
  26. package/template/.codex/skills/yss-stage-decision/SKILL.md +3 -0
  27. package/template/.codex/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +8 -4
  28. package/template/.codex/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +8 -4
  29. package/template/.codex/skills/yss-stage-decision/tests/run-scenarios.mjs +13 -1
  30. package/template/.cursor/skills/yss-harness-upgrade/SKILL.md +26 -0
  31. package/template/.cursor/skills/yss-harness-upgrade/references/cli-families.md +14 -0
  32. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +1 -0
  33. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +15 -19
  34. package/template/.cursor/skills/yss-stage-decision/SKILL.md +3 -0
  35. package/template/.cursor/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +8 -4
  36. package/template/.cursor/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +8 -4
  37. package/template/.cursor/skills/yss-stage-decision/tests/run-scenarios.mjs +13 -1
  38. package/template/.pi/skills/yss-harness-upgrade/SKILL.md +26 -0
  39. package/template/.pi/skills/yss-harness-upgrade/references/cli-families.md +14 -0
  40. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +1 -0
  41. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +15 -19
  42. package/template/.pi/skills/yss-stage-decision/SKILL.md +3 -0
  43. package/template/.pi/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +8 -4
  44. package/template/.pi/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +8 -4
  45. package/template/.pi/skills/yss-stage-decision/tests/run-scenarios.mjs +13 -1
  46. package/template/.template-spec/agents/yss-skill-registry.yaml +9 -1
  47. package/template/.template-spec/process/contract-reading.md +1 -1
  48. package/template/.template-spec/process/document-writing.md +12 -0
  49. package/template/.template-spec/process/harness-upgrade.md +40 -0
  50. package/template/.template-spec/process/lifecycle-artifact-map.md +2 -2
  51. package/template/.template-spec/process/lifecycle-registry.yaml +3 -1
  52. package/template/.template-spec/process/schemas/approval-record.schema.json +23 -0
  53. package/template/.template-spec/process/stage-tracking.md +2 -2
  54. package/template/.template-spec/process/structured-assets.md +35 -0
  55. package/template/.template-spec/process/templates/lifecycle-checkpoint-template.json +48 -0
  56. package/template/.template-spec/templates/approval-record-template.json +23 -0
  57. package/template/scripts/check-plan-stage-coverage +12 -0
  58. package/template/scripts/contract +6 -0
  59. package/template/scripts/lib/approval-record.mjs +4 -3
  60. package/template/scripts/lib/asset-command.mjs +35 -0
  61. package/template/scripts/lib/asset-migration.mjs +101 -0
  62. package/template/scripts/lib/asset-transactions.mjs +235 -0
  63. package/template/scripts/lib/checkpoint-boundary.mjs +3 -0
  64. package/template/scripts/lib/contract-views.mjs +7 -1
  65. package/template/scripts/lib/json-schema.mjs +43 -4
  66. package/template/scripts/lib/lifecycle-context-query.mjs +7 -0
  67. package/template/scripts/lib/lifecycle-presentation.mjs +77 -0
  68. package/template/scripts/lib/lifecycle-status.mjs +16 -1
  69. package/template/scripts/lib/plan-stage-coverage.mjs +40 -0
  70. package/template/scripts/lib/reading-view-bundle.mjs +1 -0
  71. package/template/scripts/lib/reading-view-markdown.mjs +8 -6
  72. package/template/scripts/lib/stage-tracking-migration.mjs +11 -3
  73. package/template/scripts/lib/structured-assets.mjs +81 -0
  74. package/template/scripts/lib/task-package.mjs +4 -1
  75. package/template/scripts/lifecycle-status +6 -3
  76. package/template/scripts/verify-lifecycle-checkpoint +8 -5
  77. package/template/skills-lock.json +21 -9
  78. package/template.manifest.json +2 -1
  79. package/template.snapshot.json +5 -5
  80. package/vendor/cli-core/build.mjs +302 -0
  81. package/vendor/cli-core/bundle.mjs +198 -0
  82. package/vendor/cli-core/cli.mjs +182 -0
  83. package/vendor/cli-core/command-runner.mjs +107 -0
  84. package/vendor/cli-core/engine.mjs +239 -0
  85. package/vendor/cli-core/family.mjs +28 -0
  86. package/vendor/cli-core/gitignore.mjs +15 -0
  87. package/vendor/cli-core/identity.mjs +274 -0
  88. package/vendor/cli-core/io.mjs +153 -0
  89. package/vendor/cli-core/layout-migration.mjs +64 -0
  90. package/vendor/cli-core/legacy.mjs +19 -0
  91. package/vendor/cli-core/migrate.mjs +237 -0
  92. package/vendor/cli-core/migration-adapter.mjs +19 -0
  93. package/vendor/cli-core/package.json +13 -0
  94. package/vendor/cli-core/scaffold.mjs +117 -0
  95. package/vendor/cli-core/spec-migration-adapter.mjs +83 -0
  96. package/vendor/cli-core/tests/build.test.mjs +40 -0
  97. package/vendor/cli-core/tests/cli.test.mjs +1065 -0
  98. package/vendor/cli-core/tests/migration-version.test.mjs +8 -0
  99. package/vendor/cli-core/tests/package-contract.mjs +89 -0
  100. package/vendor/cli-core/transaction.mjs +529 -0
  101. package/vendor/cli-core/update.mjs +79 -0
  102. package/vendor/cli-core/vendor/NOTICES.md +6 -0
  103. package/vendor/cli-core/vendor/yaml.LICENSE +13 -0
  104. package/vendor/cli-core/vendor/yaml.mjs +6311 -0
  105. package/vendor/cli-core/verification.mjs +131 -0
@@ -0,0 +1,83 @@
1
+ import * as fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import {createRequire} from 'node:module';
5
+ import {hash,ensure,same,descriptor,write} from './io.mjs';
6
+ import {inventory,copyCandidate,migration,parseMigration,assertUpgradeVersion} from './migrate.mjs';
7
+ import {verifyCore} from './build.mjs';
8
+ export function specAdapter(packageRoot) {
9
+ verifyCore(packageRoot);
10
+ const require=createRequire(path.join(packageRoot,'package.json'));
11
+ const {buildSyncContext,applySyncContext}=require('./src/api/_sync-service');
12
+ const {verifyGeneratedProjectInstance,refreshGeneratedProjectInstance,readProjectSkillLock}=require('./src/template/verification-runtime');
13
+ const {readTemplateSnapshot}=require('./src/template/instance-runtime');
14
+ const pkg=require('./package.json'),snapshot=readTemplateSnapshot();
15
+ const family={side:'spec',packageName:'create-yss-spec',profileId:'harness.spec-template',metadataFile:'.yss-template.json'};
16
+ const fingerprint=hash(JSON.stringify({pkg,snapshot,src:inventory(path.join(packageRoot,'src')),driver:inventory(path.join(packageRoot,'vendor/cli-core'))}));
17
+ return {family,fingerprint,template:{version:pkg.version,...snapshot},
18
+ check(root,opts){const c=buildSyncContext({targetDir:root,migrateLayout:opts.migrateLayout});assertUpgradeVersion(c.metadata.cliVersion || c.metadata.templateVersion,pkg.version);},
19
+ prepare(root,opts,id,time){
20
+ const context=buildSyncContext({targetDir:root,migrateLayout:opts.migrateLayout});
21
+ const resolutions={...(opts.resolutions || {})}, conflictMap=new Map(context.syncPlan.forceableConflicts.map(o=>[o.relativePath,o]));
22
+ for(const op of context.syncPlan.forceableConflicts){
23
+ const saved=context.metadata.managedFiles[op.relativePath]?.migrationCustomization;
24
+ if(!resolutions[op.relativePath] && saved?.templateDigest===op.desiredHash && saved.contentDigest===context.syncPlan.currentHashes[op.relativePath])
25
+ resolutions[op.relativePath]={action:'preserve',beforeDigest:saved.contentDigest,templateDigest:saved.templateDigest};
26
+ }
27
+ const unresolved=context.syncPlan.conflicts.filter(o=>!resolutions[o.relativePath]);
28
+ if(unresolved.length)throw Object.assign(new Error(`治理文件冲突,需逐项决议: ${unresolved.map(o=>o.relativePath).join(', ')}`),{code:'CONFLICT',result:{conflicts:unresolved.map(o=>({path:o.relativePath,beforeDigest:context.syncPlan.currentHashes[o.relativePath],templateDigest:o.desiredHash,resolutionSupported:conflictMap.has(o.relativePath)}))}});
29
+ for(const [ref,r]of Object.entries(resolutions)) {
30
+ const op=conflictMap.get(ref);
31
+ ensure(op && context.metadata.managedFiles[ref] && r.beforeDigest===context.syncPlan.currentHashes[ref] && r.templateDigest===op.desiredHash,`非可信或过期的冲突决议: ${ref}`,'CONFLICT');
32
+ ensure(['preserve','merge'].includes(r.action) && (r.action!=='merge' || typeof r.contentBase64==='string'),'冲突决议非法','CONFLICT');
33
+ }
34
+ const scratch=fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(),'yss-spec-migration-')));
35
+ try {
36
+ const before=inventory(root);delete before['.yss-harness-migrate.lock'];copyCandidate(root,scratch,before);
37
+ const stage=buildSyncContext({targetDir:scratch,migrateLayout:opts.migrateLayout});
38
+ stage.syncPlan.forceableConflicts=stage.syncPlan.forceableConflicts.filter(o=>resolutions[o.relativePath]?.action==='merge');
39
+ const applied=applySyncContext(stage,{force:stage.syncPlan.forceableConflicts.length>0,prune:opts.prune});
40
+ try {
41
+ const merged=Object.entries(resolutions).filter(([,r])=>r.action==='merge');
42
+ if(merged.length){
43
+ const lock=readProjectSkillLock(scratch);
44
+ for(const [ref,r] of merged)write(scratch,ref,Buffer.from(r.contentBase64,'base64'),descriptor(root,ref).mode);
45
+ // Regenerate from merged skill bytes; historical upstream baselines remain unchanged.
46
+ const transaction={writeFile:(p,bytes)=>fs.writeFileSync(p,bytes),prepare(){},mark(){},ensureParent:p=>fs.mkdirSync(path.dirname(p),{recursive:true})};
47
+ refreshGeneratedProjectInstance(scratch,{previousSkillLock:lock,previousManagedFiles:stage.metadata.managedFiles,transaction});
48
+ verifyGeneratedProjectInstance(scratch);
49
+ }
50
+ const metaFile=path.join(scratch,family.metadataFile),meta=JSON.parse(fs.readFileSync(metaFile));
51
+ for(const [ref,r] of Object.entries(resolutions)) {
52
+ // Keep the upstream baseline separate from explicitly accepted local content.
53
+ meta.managedFiles[ref]={...context.metadata.managedFiles[ref],contentHash:r.templateDigest,migrationCustomization:{templateDigest:r.templateDigest,contentDigest:hash(fs.readFileSync(path.join(scratch,ref)))}};
54
+ }
55
+ const prior=JSON.parse(fs.readFileSync(path.join(root,family.metadataFile)));
56
+ meta.lastSyncedAt=prior.lastSyncedAt;
57
+ if(JSON.stringify(meta)!==JSON.stringify(prior))meta.lastSyncedAt=time;
58
+ fs.writeFileSync(metaFile,JSON.stringify(meta,null,2)+'\n');
59
+ const after=inventory(scratch),operations=[];
60
+ for(const ref of [...new Set([...Object.keys(before),...Object.keys(after)])].sort()) {
61
+ const a=before[ref] || null,b=after[ref] || null;
62
+ if(a?.type==='directory' || b?.type==='directory')continue;
63
+ if(a?.type==='symlink' || b?.type==='symlink'){ensure(JSON.stringify(a)===JSON.stringify(b),'候选改变符号链接','PATH');continue;}
64
+ if(!same(a,b))operations.push({path:ref,before:a,after:b,bytes:b?fs.readFileSync(path.join(scratch,ref)):undefined});
65
+ }
66
+ operations.sort((a,b)=>(a.path===family.metadataFile?1:0)-(b.path===family.metadataFile?1:0));
67
+ return {operations,changes:context.plan.changes};
68
+ }finally{if(applied.backupPath)fs.rmSync(applied.backupPath,{recursive:true,force:true});}
69
+ }finally{fs.rmSync(scratch,{recursive:true,force:true});}
70
+ },
71
+ verify(root){
72
+ const scratch=fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(),'yss-spec-verify-')));
73
+ try{const tree=inventory(root);delete tree['.yss-harness-migrate.lock'];copyCandidate(root,scratch,tree);verifyGeneratedProjectInstance(scratch);return [{name:'project-instance',status:'passed',location:'isolated-copy'}];}
74
+ finally{fs.rmSync(scratch,{recursive:true,force:true});}
75
+ },
76
+ };
77
+ }
78
+ export function runSpecMigration(packageRoot,args){
79
+ const {command,opts}=parseMigration(args),require=createRequire(path.join(packageRoot,'package.json'));
80
+ const {withVerificationOutput}=require('./src/template/verification-runtime'),logs=[];
81
+ const result=withVerificationOutput(text=>logs.push(text),()=>migration(specAdapter(packageRoot),command,opts));
82
+ return {...result,...(logs.length?{verificationLog:logs.join('')}:{})};
83
+ }
@@ -0,0 +1,40 @@
1
+ import {test} from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import * as fs from 'node:fs';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import {spawnSync} from 'node:child_process';
7
+ import {syncCore,syncTemplate,verifyCore} from '../build.mjs';
8
+ import {loadBundle} from '../bundle.mjs';
9
+ const put=(root,ref,bytes)=>{fs.mkdirSync(path.dirname(path.join(root,ref)),{recursive:true});fs.writeFileSync(path.join(root,ref),bytes);};
10
+ test('战略 YAML 清单投影、固定来源与 WORKTREE 仅在临时副本构建',t=>{
11
+ const tmp=fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(),'harness-build-')));t.after(()=>fs.rmSync(tmp,{recursive:true,force:true}));
12
+ const source=path.join(tmp,'source'),pkg=path.join(tmp,'package');
13
+ fs.mkdirSync(source);put(pkg,'package.json',JSON.stringify({name:'create-yss-harness-design',version:'0.6.0'}));
14
+ fs.cpSync(path.resolve(import.meta.dirname,'..'),path.join(source,'.template-source/cli-core'),{recursive:true});
15
+ for(const name of ['README.md','AGENTS.md','CONTEXT.md','DESIGN.md'])put(source,name,name+'\n');
16
+ put(source,'yss-project.yaml','schema_version: 1\nrepository_mode: template-source\n');
17
+ put(source,'.template-spec/process/harness-profile.yaml','schema_version: 2\nprofile_id: harness.business-ddd-strategy-handoff\n');
18
+ put(source,'.template-spec/user-guide/retired.md','retired handbook\n');
19
+ put(source,'.template-spec/user-guide/current.md','current handbook v1\n');
20
+ put(source,'.template-spec/process/instance-distribution-manifest.yaml',`schema_version: 1
21
+ profile_id: harness.business-ddd-strategy-handoff
22
+ cli_package: create-yss-harness-design
23
+ template_source: github:iloveZzz/yss-harness-design-agent
24
+ allow_root_entries: [.template-spec]
25
+ allow_root_files: [README.md, AGENTS.md, CONTEXT.md, DESIGN.md, yss-project.yaml]
26
+ exclude_root_entries: [.git, .template-source]
27
+ render_paths: [README.md, AGENTS.md, yss-project.yaml]
28
+ `);
29
+ const git=(...args)=>{const r=spawnSync('git',['-C',source,...args],{encoding:'utf8'});assert.equal(r.status,0,r.stderr);return r.stdout.trim();};
30
+ git('init','--initial-branch=main');git('add','.');git('-c','user.name=Fixture','-c','user.email=fixture@example.invalid','commit','-m','fixture');
31
+ const ref=git('rev-parse','HEAD');syncCore(source,ref,pkg);syncTemplate(source,ref,pkg);verifyCore(pkg);loadBundle(pkg);
32
+ const before=fs.readFileSync(path.join(pkg,'template.snapshot.json'));
33
+ put(source,'DESIGN.md','worktree changes\n');syncTemplate(source,ref,pkg,true);assert.deepEqual(fs.readFileSync(path.join(pkg,'template.snapshot.json')),before);
34
+ fs.rmSync(path.join(source,'.template-spec/user-guide/retired.md'));
35
+ put(source,'.template-spec/user-guide/current.md','current handbook v2\n');
36
+ syncTemplate(source,'WORKTREE',pkg);const worktreeBundle=loadBundle(pkg);assert.equal(worktreeBundle.snapshot.sourceState,'working-tree');
37
+ assert.equal(worktreeBundle.retiredFiles['.template-spec/user-guide/retired.md'].digest.length,64);
38
+ assert.equal(worktreeBundle.transitionBaselines['.template-spec/user-guide/current.md'].digest.length,64);
39
+ assert.throws(()=>syncTemplate(source,ref,pkg,true),/漂移/);
40
+ });