@zhuan-ai/zhuanspec 2.1.3 → 2.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/dist/cli/index.js CHANGED
@@ -189,6 +189,7 @@ program
189
189
  .option('-y, --yes', 'Skip confirmation prompts')
190
190
  .option('--skip-specs', 'Skip spec update operations (useful for infrastructure, tooling, or doc-only changes)')
191
191
  .option('--no-validate', 'Skip validation (not recommended, requires confirmation)')
192
+ .option('--business-direction <direction>', 'Business direction used for template refresh and remote sync (e.g., oms)')
192
193
  .action(async (changeName, options) => {
193
194
  try {
194
195
  const archiveCommand = new ArchiveCommand();
@@ -206,6 +207,7 @@ program
206
207
  .option('-y, --yes', 'Skip confirmation prompts and archive all active changes')
207
208
  .option('--skip-specs', 'Skip spec update operations')
208
209
  .option('--no-validate', 'Skip validation (not recommended)')
210
+ .option('--business-direction <direction>', 'Business direction used for template refresh and remote sync (e.g., oms)')
209
211
  .action(async (options) => {
210
212
  try {
211
213
  const archiveCommand = new ArchiveCommand();
@@ -1,10 +1,12 @@
1
+ type ArchiveOptions = {
2
+ yes?: boolean;
3
+ skipSpecs?: boolean;
4
+ noValidate?: boolean;
5
+ validate?: boolean;
6
+ businessDirection?: string;
7
+ };
1
8
  export declare class ArchiveCommand {
2
- execute(changeName?: string, options?: {
3
- yes?: boolean;
4
- skipSpecs?: boolean;
5
- noValidate?: boolean;
6
- validate?: boolean;
7
- }): Promise<void>;
9
+ execute(changeName?: string, options?: ArchiveOptions): Promise<void>;
8
10
  /**
9
11
  * Move a directory, falling back to copy+remove when rename fails
10
12
  * (e.g., across devices, network drives, or permission issues).
@@ -20,11 +22,19 @@ export declare class ArchiveCommand {
20
22
  * Bulk archive multiple completed changes at once.
21
23
  * Lists all active changes, lets user select multiple, then archives them sequentially.
22
24
  */
23
- bulkArchive(options?: {
24
- yes?: boolean;
25
- skipSpecs?: boolean;
26
- noValidate?: boolean;
27
- validate?: boolean;
28
- }): Promise<void>;
25
+ bulkArchive(options?: ArchiveOptions): Promise<void>;
26
+ private resolveBusinessDirection;
27
+ private refreshBusinessTemplateFromRemote;
28
+ private pushArchiveResultToRemote;
29
+ private cloneRemoteRepoToTemp;
30
+ private git;
31
+ private hasGitChanges;
32
+ private copyDirectoryContentsIfExists;
33
+ private mirrorDirectory;
34
+ private findFirstDirectoryByName;
35
+ private resolveBusinessTemplateRoot;
36
+ private resolveRemoteBusinessRoot;
37
+ private toErrorMessage;
29
38
  }
39
+ export {};
30
40
  //# sourceMappingURL=archive.d.ts.map
@@ -1,15 +1,21 @@
1
- import { promises as fs } from 'fs';
1
+ import { promises as fs, existsSync, readdirSync } from 'fs';
2
2
  import path from 'path';
3
+ import os from 'os';
4
+ import { mkdtempSync, rmSync } from 'fs';
5
+ import { execSync } from 'child_process';
3
6
  import { getTaskProgressForChange, formatTaskStatus } from '../utils/task-progress.js';
4
7
  import { Validator } from './validation/validator.js';
5
8
  import chalk from 'chalk';
6
9
  import { findSpecUpdates, buildUpdatedSpec, writeUpdatedSpec, } from './specs-apply.js';
10
+ const ARCH_REPO_URL = 'http://gitlab.zhuanspirit.com/zz-kf/spec_repo.git';
11
+ const ARCH_REPO_BRANCH = 'spec_repo-feature-6612-2';
7
12
  export class ArchiveCommand {
8
13
  async execute(changeName, options = {}) {
9
14
  const targetPath = '.';
10
15
  const changesDir = path.join(targetPath, 'zhuanspec', 'changes');
11
16
  const archiveDir = path.join(changesDir, 'archive');
12
17
  const mainSpecsDir = path.join(targetPath, 'zhuanspec', 'specs');
18
+ const zhuanspecDir = path.join(targetPath, 'zhuanspec');
13
19
  // Check if changes directory exists
14
20
  try {
15
21
  await fs.access(changesDir);
@@ -17,6 +23,11 @@ export class ArchiveCommand {
17
23
  catch {
18
24
  throw new Error("未找到 ZhuanSpec 变更目录。请先运行 'zhuanspec init'。");
19
25
  }
26
+ const businessDirection = await this.resolveBusinessDirection(zhuanspecDir, options.businessDirection);
27
+ if (!businessDirection) {
28
+ throw new Error('未解析到业务方向,无法执行归档前拉取与归档后回推。请使用 --business-direction 或在 zhuanspec/.business-direction、zhuanspec/project.md 中配置。');
29
+ }
30
+ await this.refreshBusinessTemplateFromRemote(zhuanspecDir, businessDirection);
20
31
  // Get change name interactively if not provided
21
32
  if (!changeName) {
22
33
  const selectedChange = await this.selectChange(changesDir);
@@ -214,20 +225,27 @@ export class ArchiveCommand {
214
225
  const archiveName = `${this.getArchiveDate()}-${changeName}`;
215
226
  const archivePath = path.join(archiveDir, archiveName);
216
227
  // Check if archive already exists
228
+ let archiveExists = false;
217
229
  try {
218
230
  await fs.access(archivePath);
219
- throw new Error(`归档 '${archiveName}' 已存在。`);
231
+ archiveExists = true;
220
232
  }
221
233
  catch (error) {
222
234
  if (error.code !== 'ENOENT') {
223
235
  throw error;
224
236
  }
225
237
  }
226
- // Create archive directory if needed
227
- await fs.mkdir(archiveDir, { recursive: true });
228
- // Move change to archive (with cross-device fallback)
229
- await this.moveDirectory(changeDir, archivePath);
230
- console.log(`变更 '${changeName}' 已归档为 '${archiveName}'。`);
238
+ if (archiveExists) {
239
+ console.log(chalk.yellow(`归档 '${archiveName}' 已存在,跳过归档移动。`));
240
+ }
241
+ else {
242
+ // Create archive directory if needed
243
+ await fs.mkdir(archiveDir, { recursive: true });
244
+ // Move change to archive (with cross-device fallback)
245
+ await this.moveDirectory(changeDir, archivePath);
246
+ console.log(`变更 '${changeName}' 已归档为 '${archiveName}'。`);
247
+ }
248
+ await this.pushArchiveResultToRemote(zhuanspecDir, businessDirection);
231
249
  }
232
250
  /**
233
251
  * Move a directory, falling back to copy+remove when rename fails
@@ -434,5 +452,221 @@ export class ArchiveCommand {
434
452
  console.log(chalk.cyan(`\n━━━ 批量归档完成 ━━━`));
435
453
  console.log(`成功: ${successCount}, 失败: ${failCount}, 总计: ${selectedChanges.length}`);
436
454
  }
455
+ async resolveBusinessDirection(zhuanspecDir, explicitDirection) {
456
+ if (explicitDirection && explicitDirection.trim()) {
457
+ return explicitDirection.trim().toLowerCase();
458
+ }
459
+ const directionFilePath = path.join(zhuanspecDir, '.business-direction');
460
+ try {
461
+ const fromFile = (await fs.readFile(directionFilePath, 'utf-8')).trim();
462
+ if (fromFile) {
463
+ return fromFile.toLowerCase();
464
+ }
465
+ }
466
+ catch {
467
+ // Continue to project.md fallback.
468
+ }
469
+ const projectPath = path.join(zhuanspecDir, 'project.md');
470
+ try {
471
+ const content = await fs.readFile(projectPath, 'utf-8');
472
+ const patterns = [
473
+ /业务方向\s*[::]\s*([A-Za-z0-9_-]+)/i,
474
+ /business\s*direction\s*[::]\s*([A-Za-z0-9_-]+)/i,
475
+ ];
476
+ for (const pattern of patterns) {
477
+ const match = content.match(pattern);
478
+ if (match?.[1]) {
479
+ return match[1].trim().toLowerCase();
480
+ }
481
+ }
482
+ }
483
+ catch {
484
+ // Ignore parsing errors and fall back to null.
485
+ }
486
+ return null;
487
+ }
488
+ async refreshBusinessTemplateFromRemote(zhuanspecDir, businessDirection) {
489
+ const tempRepo = this.cloneRemoteRepoToTemp();
490
+ try {
491
+ const remoteBusiness = this.resolveRemoteBusinessRoot(tempRepo, businessDirection);
492
+ if (!remoteBusiness) {
493
+ throw new Error(`未在远端 specs 目录中找到业务方向 '${businessDirection}',归档已中止。`);
494
+ }
495
+ const { businessRoot } = remoteBusiness;
496
+ const templateRoot = this.resolveBusinessTemplateRoot(businessRoot);
497
+ if (!templateRoot) {
498
+ throw new Error(`未在业务方向 '${businessDirection}' 目录下递归找到可用的 zhuanspec 目录,归档已中止。`);
499
+ }
500
+ await this.copyDirectoryContentsIfExists(path.join(templateRoot, 'specs'), path.join(zhuanspecDir, 'specs'));
501
+ await this.copyDirectoryContentsIfExists(path.join(templateRoot, 'changes'), path.join(zhuanspecDir, 'changes'));
502
+ console.log(chalk.gray(`已拉取 ${businessDirection} 业务模板(specs/changes)。`));
503
+ }
504
+ finally {
505
+ rmSync(tempRepo, { recursive: true, force: true });
506
+ }
507
+ }
508
+ async pushArchiveResultToRemote(zhuanspecDir, businessDirection) {
509
+ const tempRepo = this.cloneRemoteRepoToTemp();
510
+ try {
511
+ const remoteBusiness = this.resolveRemoteBusinessRoot(tempRepo, businessDirection);
512
+ if (!remoteBusiness) {
513
+ throw new Error(`未在远端 specs 目录中找到业务方向 '${businessDirection}',归档结果回推已中止。`);
514
+ }
515
+ const { businessRoot } = remoteBusiness;
516
+ const templateRoot = this.resolveBusinessTemplateRoot(businessRoot);
517
+ if (!templateRoot) {
518
+ throw new Error(`未在业务方向 '${businessDirection}' 目录下递归找到可用的 zhuanspec 目录,归档结果回推已中止。`);
519
+ }
520
+ const remoteBase = templateRoot;
521
+ const remoteSpecsPath = path.join(remoteBase, 'specs');
522
+ const remoteArchivePath = path.join(remoteBase, 'changes', 'archive');
523
+ const localSpecsPath = path.join(zhuanspecDir, 'specs');
524
+ const localArchivePath = path.join(zhuanspecDir, 'changes', 'archive');
525
+ await this.mirrorDirectory(localSpecsPath, remoteSpecsPath);
526
+ await this.mirrorDirectory(localArchivePath, remoteArchivePath);
527
+ const changed = this.hasGitChanges(tempRepo);
528
+ if (!changed) {
529
+ console.log(chalk.gray('远端模板仓库无变更,跳过 push。'));
530
+ return;
531
+ }
532
+ this.git(tempRepo, 'git add .');
533
+ const commitMsg = `chore: sync archive outputs for ${businessDirection}`;
534
+ this.git(tempRepo, `git commit -m "${commitMsg}"`);
535
+ this.git(tempRepo, `git push origin ${ARCH_REPO_BRANCH}`);
536
+ console.log(chalk.green(`已推送归档结果到远端 ${ARCH_REPO_BRANCH}(${businessDirection})。`));
537
+ }
538
+ finally {
539
+ rmSync(tempRepo, { recursive: true, force: true });
540
+ }
541
+ }
542
+ cloneRemoteRepoToTemp() {
543
+ const tempDir = mkdtempSync(path.join(os.tmpdir(), 'zhuanspec-archive-'));
544
+ try {
545
+ this.git(process.cwd(), `git clone --depth 1 --single-branch --branch ${ARCH_REPO_BRANCH} ${ARCH_REPO_URL} "${tempDir}"`);
546
+ return tempDir;
547
+ }
548
+ catch (error) {
549
+ rmSync(tempDir, { recursive: true, force: true });
550
+ throw new Error(`拉取远端模板仓库失败:${this.toErrorMessage(error)}`);
551
+ }
552
+ }
553
+ git(cwd, command) {
554
+ return execSync(command, {
555
+ cwd,
556
+ encoding: 'utf-8',
557
+ stdio: ['pipe', 'pipe', 'pipe'],
558
+ });
559
+ }
560
+ hasGitChanges(repoDir) {
561
+ try {
562
+ const output = this.git(repoDir, 'git status --porcelain');
563
+ return output.trim().length > 0;
564
+ }
565
+ catch {
566
+ return false;
567
+ }
568
+ }
569
+ async copyDirectoryContentsIfExists(sourceDir, targetDir) {
570
+ try {
571
+ const stat = await fs.stat(sourceDir);
572
+ if (!stat.isDirectory()) {
573
+ return false;
574
+ }
575
+ }
576
+ catch {
577
+ return false;
578
+ }
579
+ await fs.mkdir(targetDir, { recursive: true });
580
+ const entries = await fs.readdir(sourceDir, { withFileTypes: true });
581
+ for (const entry of entries) {
582
+ const src = path.join(sourceDir, entry.name);
583
+ const dest = path.join(targetDir, entry.name);
584
+ if (entry.isDirectory()) {
585
+ await this.copyDirectoryRecursive(src, dest);
586
+ }
587
+ else {
588
+ await fs.copyFile(src, dest);
589
+ }
590
+ }
591
+ return true;
592
+ }
593
+ async mirrorDirectory(sourceDir, targetDir) {
594
+ const sourceStat = await fs.stat(sourceDir);
595
+ if (!sourceStat.isDirectory()) {
596
+ throw new Error(`源目录不是目录:${sourceDir}`);
597
+ }
598
+ await fs.rm(targetDir, { recursive: true, force: true });
599
+ await fs.mkdir(path.dirname(targetDir), { recursive: true });
600
+ await fs.cp(sourceDir, targetDir, { recursive: true, force: true });
601
+ }
602
+ findFirstDirectoryByName(searchRoot, targetName) {
603
+ if (!existsSync(searchRoot)) {
604
+ return null;
605
+ }
606
+ const queue = [searchRoot];
607
+ const targetLower = targetName.toLowerCase();
608
+ while (queue.length > 0) {
609
+ const current = queue.shift();
610
+ if (!current) {
611
+ continue;
612
+ }
613
+ try {
614
+ const children = readdirSync(current, { withFileTypes: true })
615
+ .filter((entry) => entry.isDirectory())
616
+ .map((entry) => entry.name)
617
+ .sort((a, b) => a.localeCompare(b));
618
+ for (const child of children) {
619
+ const childPath = path.join(current, child);
620
+ if (child.toLowerCase() === targetLower) {
621
+ return childPath;
622
+ }
623
+ queue.push(childPath);
624
+ }
625
+ }
626
+ catch {
627
+ // Continue searching.
628
+ }
629
+ }
630
+ return null;
631
+ }
632
+ resolveBusinessTemplateRoot(businessRoot) {
633
+ if (!existsSync(businessRoot)) {
634
+ return null;
635
+ }
636
+ // Business directory selection is recursive (first match).
637
+ // Once selected, template root must be its direct child: <business>/zhuanspec.
638
+ const zhuanspecRoot = path.join(businessRoot, 'zhuanspec');
639
+ if (!existsSync(zhuanspecRoot)) {
640
+ return null;
641
+ }
642
+ const specsDir = path.join(zhuanspecRoot, 'specs');
643
+ const changesDir = path.join(zhuanspecRoot, 'changes');
644
+ if (!existsSync(specsDir) || !existsSync(changesDir)) {
645
+ return null;
646
+ }
647
+ return zhuanspecRoot;
648
+ }
649
+ resolveRemoteBusinessRoot(tempRepo, businessDirection) {
650
+ const candidates = Array.from(new Set([
651
+ path.join(tempRepo, 'spec_repo', 'specs'),
652
+ path.join(tempRepo, 'specs'),
653
+ ]));
654
+ for (const specsRoot of candidates) {
655
+ if (!existsSync(specsRoot)) {
656
+ continue;
657
+ }
658
+ const businessRoot = this.findFirstDirectoryByName(specsRoot, businessDirection);
659
+ if (businessRoot) {
660
+ return { specsRoot, businessRoot };
661
+ }
662
+ }
663
+ return null;
664
+ }
665
+ toErrorMessage(error) {
666
+ if (error instanceof Error) {
667
+ return error.message;
668
+ }
669
+ return String(error);
670
+ }
437
671
  }
438
672
  //# sourceMappingURL=archive.js.map
@@ -48,6 +48,11 @@ export declare class InitCommand {
48
48
  private fetchArchitectureFile;
49
49
  private fetchRemoteArchitectureFiles;
50
50
  private fetchRemoteArchitectureContent;
51
+ private cloneRemoteArchitectureRepoToTemp;
52
+ private syncBusinessSpecTemplate;
53
+ private findFirstDirectoryByName;
54
+ private findFirstTemplateSourceRoot;
55
+ private copyDirectoryContentsIfExists;
51
56
  private writeTemplateFiles;
52
57
  private configureAITools;
53
58
  private configureRootAgentsStub;
package/dist/core/init.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import path from 'path';
2
2
  import os from 'os';
3
- import { existsSync, mkdtempSync, readdirSync, readFileSync, rmSync } from 'fs';
3
+ import { cpSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, } from 'fs';
4
4
  import { createPrompt, isBackspaceKey, isDownKey, isEnterKey, isSpaceKey, isUpKey, useKeypress, usePagination, useState, } from '@inquirer/core';
5
5
  import chalk from 'chalk';
6
6
  import ora from 'ora';
@@ -297,6 +297,8 @@ export class InitCommand {
297
297
  // Step 3: Select business direction and apply architecture file
298
298
  await this.promptForBusinessDirection();
299
299
  if (this.businessDirection) {
300
+ const directionMetaPath = path.join(zhuanspecPath, '.business-direction');
301
+ await FileSystemUtils.writeFile(directionMetaPath, `${this.businessDirection.toLowerCase()}\n`);
300
302
  const archSpinner = this.startSpinner(`正在获取 ${this.businessDirection} 业务架构文档...`);
301
303
  const architectureContent = await this.fetchArchitectureFile();
302
304
  if (architectureContent) {
@@ -316,6 +318,27 @@ export class InitCommand {
316
318
  text: PALETTE.midGray(`未找到 ${this.businessDirection} 业务架构文档,使用默认模板`),
317
319
  });
318
320
  }
321
+ const specTemplateSpinner = this.startSpinner(`正在同步 ${this.businessDirection} 业务规范模板...`);
322
+ const syncResult = this.syncBusinessSpecTemplate(zhuanspecPath);
323
+ if (syncResult.syncedSpecs || syncResult.syncedChanges) {
324
+ const syncedParts = [];
325
+ if (syncResult.syncedSpecs) {
326
+ syncedParts.push('specs');
327
+ }
328
+ if (syncResult.syncedChanges) {
329
+ syncedParts.push('changes');
330
+ }
331
+ specTemplateSpinner.stopAndPersist({
332
+ symbol: PALETTE.white('▌'),
333
+ text: PALETTE.white(`已从远端模板同步 ${syncedParts.join('、')} 目录`),
334
+ });
335
+ }
336
+ else {
337
+ specTemplateSpinner.stopAndPersist({
338
+ symbol: PALETTE.midGray('▌'),
339
+ text: PALETTE.midGray(`未找到 ${this.businessDirection} 业务规范模板目录,保留默认模板`),
340
+ });
341
+ }
319
342
  }
320
343
  // Success message
321
344
  this.displaySuccessMessage(selectedTools, created, refreshed, skippedExisting, skipped, extendMode, rootStubStatus);
@@ -679,9 +702,11 @@ export class InitCommand {
679
702
  return null;
680
703
  }
681
704
  fetchRemoteArchitectureFiles() {
682
- const tempDir = mkdtempSync(path.join(os.tmpdir(), 'zhuanspec-arch-'));
705
+ const tempDir = this.cloneRemoteArchitectureRepoToTemp();
706
+ if (!tempDir) {
707
+ return [];
708
+ }
683
709
  try {
684
- execSync(`git clone --depth 1 --single-branch --branch ${ARCH_REPO_BRANCH} ${ARCH_REPO_URL} "${tempDir}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] });
685
710
  const commonDir = path.join(tempDir, 'specs', 'common');
686
711
  if (!existsSync(commonDir)) {
687
712
  return [];
@@ -696,9 +721,11 @@ export class InitCommand {
696
721
  }
697
722
  }
698
723
  fetchRemoteArchitectureContent(fileName) {
699
- const tempDir = mkdtempSync(path.join(os.tmpdir(), 'zhuanspec-arch-'));
724
+ const tempDir = this.cloneRemoteArchitectureRepoToTemp();
725
+ if (!tempDir) {
726
+ return null;
727
+ }
700
728
  try {
701
- execSync(`git clone --depth 1 --single-branch --branch ${ARCH_REPO_BRANCH} ${ARCH_REPO_URL} "${tempDir}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] });
702
729
  const fullPath = path.join(tempDir, 'specs', 'common', fileName);
703
730
  if (!existsSync(fullPath)) {
704
731
  return null;
@@ -712,6 +739,117 @@ export class InitCommand {
712
739
  rmSync(tempDir, { recursive: true, force: true });
713
740
  }
714
741
  }
742
+ cloneRemoteArchitectureRepoToTemp() {
743
+ const tempDir = mkdtempSync(path.join(os.tmpdir(), 'zhuanspec-arch-'));
744
+ try {
745
+ execSync(`git clone --depth 1 --single-branch --branch ${ARCH_REPO_BRANCH} ${ARCH_REPO_URL} "${tempDir}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] });
746
+ return tempDir;
747
+ }
748
+ catch {
749
+ rmSync(tempDir, { recursive: true, force: true });
750
+ return null;
751
+ }
752
+ }
753
+ syncBusinessSpecTemplate(zhuanspecPath) {
754
+ if (!this.businessDirection) {
755
+ return { syncedSpecs: false, syncedChanges: false };
756
+ }
757
+ const tempDir = this.cloneRemoteArchitectureRepoToTemp();
758
+ if (!tempDir) {
759
+ return { syncedSpecs: false, syncedChanges: false };
760
+ }
761
+ try {
762
+ const specsRoot = path.join(tempDir, 'specs');
763
+ const businessRoot = this.findFirstDirectoryByName(specsRoot, this.businessDirection);
764
+ if (!businessRoot) {
765
+ return { syncedSpecs: false, syncedChanges: false };
766
+ }
767
+ const templateRoot = this.findFirstTemplateSourceRoot(businessRoot);
768
+ if (!templateRoot) {
769
+ return { syncedSpecs: false, syncedChanges: false };
770
+ }
771
+ const syncedSpecs = this.copyDirectoryContentsIfExists(path.join(templateRoot, 'specs'), path.join(zhuanspecPath, 'specs'));
772
+ const syncedChanges = this.copyDirectoryContentsIfExists(path.join(templateRoot, 'changes'), path.join(zhuanspecPath, 'changes'));
773
+ return { syncedSpecs, syncedChanges };
774
+ }
775
+ catch {
776
+ return { syncedSpecs: false, syncedChanges: false };
777
+ }
778
+ finally {
779
+ rmSync(tempDir, { recursive: true, force: true });
780
+ }
781
+ }
782
+ findFirstDirectoryByName(searchRoot, targetName) {
783
+ if (!existsSync(searchRoot)) {
784
+ return null;
785
+ }
786
+ const queue = [searchRoot];
787
+ while (queue.length > 0) {
788
+ const current = queue.shift();
789
+ if (!current) {
790
+ continue;
791
+ }
792
+ try {
793
+ const children = readdirSync(current, { withFileTypes: true })
794
+ .filter((entry) => entry.isDirectory())
795
+ .map((entry) => entry.name)
796
+ .sort((a, b) => a.localeCompare(b));
797
+ for (const child of children) {
798
+ const childPath = path.join(current, child);
799
+ if (child === targetName) {
800
+ return childPath;
801
+ }
802
+ queue.push(childPath);
803
+ }
804
+ }
805
+ catch {
806
+ // Continue searching other branches when a directory cannot be read.
807
+ }
808
+ }
809
+ return null;
810
+ }
811
+ findFirstTemplateSourceRoot(searchRoot) {
812
+ if (!existsSync(searchRoot)) {
813
+ return null;
814
+ }
815
+ const queue = [searchRoot];
816
+ while (queue.length > 0) {
817
+ const current = queue.shift();
818
+ if (!current) {
819
+ continue;
820
+ }
821
+ const specsDir = path.join(current, 'specs');
822
+ const changesDir = path.join(current, 'changes');
823
+ if (existsSync(specsDir) && existsSync(changesDir)) {
824
+ return current;
825
+ }
826
+ try {
827
+ const children = readdirSync(current, { withFileTypes: true })
828
+ .filter((entry) => entry.isDirectory())
829
+ .map((entry) => entry.name)
830
+ .sort((a, b) => a.localeCompare(b));
831
+ children.forEach((child) => queue.push(path.join(current, child)));
832
+ }
833
+ catch {
834
+ // Continue searching other branches when a directory cannot be read.
835
+ }
836
+ }
837
+ return null;
838
+ }
839
+ copyDirectoryContentsIfExists(sourceDir, targetDir) {
840
+ if (!existsSync(sourceDir)) {
841
+ return false;
842
+ }
843
+ mkdirSync(targetDir, { recursive: true });
844
+ const entries = readdirSync(sourceDir);
845
+ for (const entry of entries) {
846
+ cpSync(path.join(sourceDir, entry), path.join(targetDir, entry), {
847
+ recursive: true,
848
+ force: true,
849
+ });
850
+ }
851
+ return true;
852
+ }
715
853
  async writeTemplateFiles(zhuanspecPath, config, skipExisting) {
716
854
  const context = {};
717
855
  const templates = TemplateManager.getTemplates(context);
@@ -141,14 +141,19 @@ export async function buildUpdatedSpec(update, changeName) {
141
141
  targetContent = await fs.readFile(update.target, 'utf-8');
142
142
  }
143
143
  catch {
144
- // Target spec does not exist; MODIFIED and RENAMED are not allowed for new specs
145
- // REMOVED will be ignored with a warning since there's nothing to remove
146
- if (plan.modified.length > 0 || plan.renamed.length > 0) {
147
- throw new Error(`${specName}: target spec does not exist; only ADDED requirements are allowed for new specs. MODIFIED and RENAMED operations require an existing spec.`);
144
+ // Target spec does not exist: process as new spec creation.
145
+ // Only ADDED operations are applied; other operations are ignored.
146
+ if (plan.modified.length > 0) {
147
+ console.log(chalk.yellow(`⚠️ Warning: ${specName} - ${plan.modified.length} MODIFIED requirement(s) ignored for new spec (only ADDED is applied).`));
148
+ plan.modified.length = 0;
149
+ }
150
+ if (plan.renamed.length > 0) {
151
+ console.log(chalk.yellow(`⚠️ Warning: ${specName} - ${plan.renamed.length} RENAMED operation(s) ignored for new spec (only ADDED is applied).`));
152
+ plan.renamed.length = 0;
148
153
  }
149
- // Warn about REMOVED requirements being ignored for new specs
150
154
  if (plan.removed.length > 0) {
151
155
  console.log(chalk.yellow(`⚠️ Warning: ${specName} - ${plan.removed.length} REMOVED requirement(s) ignored for new spec (nothing to remove).`));
156
+ plan.removed.length = 0;
152
157
  }
153
158
  isNewSpec = true;
154
159
  targetContent = buildSpecSkeleton(specName, changeName);
@@ -160,6 +165,7 @@ export async function buildUpdatedSpec(update, changeName) {
160
165
  nameToBlock.set(normalizeRequirementName(block.name), block);
161
166
  }
162
167
  // Apply operations in order: RENAMED → REMOVED → MODIFIED → ADDED
168
+ let skippedAdded = 0;
163
169
  // RENAMED
164
170
  for (const r of plan.renamed) {
165
171
  const from = normalizeRequirementName(r.from);
@@ -200,7 +206,10 @@ export async function buildUpdatedSpec(update, changeName) {
200
206
  for (const mod of plan.modified) {
201
207
  const key = normalizeRequirementName(mod.name);
202
208
  if (!nameToBlock.has(key)) {
203
- throw new Error(`${specName} MODIFIED failed for header "### Requirement: ${mod.name}" - not found`);
209
+ // Lenient mode: if MODIFIED target is missing, treat it as ADDED.
210
+ console.log(chalk.yellow(`⚠️ Warning: ${specName} MODIFIED target not found for "### Requirement: ${mod.name}", auto-applying as ADDED.`));
211
+ nameToBlock.set(key, mod);
212
+ continue;
204
213
  }
205
214
  // Replace block with provided raw (ensure header line matches key)
206
215
  const modHeaderMatch = mod.raw.split('\n')[0].match(/^###\s*Requirement:\s*(.+)\s*$/);
@@ -213,7 +222,9 @@ export async function buildUpdatedSpec(update, changeName) {
213
222
  for (const add of plan.added) {
214
223
  const key = normalizeRequirementName(add.name);
215
224
  if (nameToBlock.has(key)) {
216
- throw new Error(`${specName} ADDED failed for header "### Requirement: ${add.name}" - already exists`);
225
+ console.log(chalk.yellow(`⚠️ Warning: ${specName} ADDED target already exists for "### Requirement: ${add.name}", skipping.`));
226
+ skippedAdded++;
227
+ continue;
217
228
  }
218
229
  nameToBlock.set(key, add);
219
230
  }
@@ -247,7 +258,7 @@ export async function buildUpdatedSpec(update, changeName) {
247
258
  return {
248
259
  rebuilt,
249
260
  counts: {
250
- added: plan.added.length,
261
+ added: plan.added.length - skippedAdded,
251
262
  modified: plan.modified.length,
252
263
  removed: plan.removed.length,
253
264
  renamed: plan.renamed.length,
@@ -51,20 +51,33 @@ export function renderExecutionPlanXml(plan) {
51
51
  }
52
52
  // Render full plan
53
53
  lines.push(`<execution_plan total_tasks="${plan.totalTasks}" parallel_tasks="${plan.parallelTasks}" serial_tasks="${plan.serialTasks}">`);
54
- // Render each wave
54
+ // Render each wave with subagent execution directive
55
55
  for (const wave of plan.waves) {
56
- lines.push(` <wave number="${wave.wave}" parallel="${wave.parallel}">`);
56
+ const subagentCount = wave.tasks.length;
57
+ const executionMode = wave.parallel ? 'parallel' : 'serial';
58
+ lines.push(` <wave number="${wave.wave}" parallel="${wave.parallel}" subagent_count="${subagentCount}" execution_mode="${executionMode}">`);
57
59
  for (const task of wave.tasks) {
58
60
  lines.push(renderTaskXml(task, ' '));
59
61
  }
60
62
  lines.push(' </wave>');
61
63
  }
62
- // Add orchestration strategy
64
+ // Add orchestration strategy with concrete scheduling summary
63
65
  lines.push('');
64
66
  lines.push(' <orchestration_strategy>');
65
- lines.push(' 每个 wave 内的任务通过独立 subagent 并行执行。');
66
67
  lines.push(' Wave 之间严格串行,前一 wave 全部完成后才启动下一 wave。');
67
68
  lines.push(' 每个 subagent 仅加载其 task 关联的 @skill,实现上下文隔离。');
69
+ lines.push('');
70
+ lines.push(' <scheduling_summary>');
71
+ for (const wave of plan.waves) {
72
+ const taskCount = wave.tasks.length;
73
+ if (taskCount === 1) {
74
+ lines.push(` Wave ${wave.wave} → 启动 1 个 subagent 执行该波次的单个任务`);
75
+ }
76
+ else {
77
+ lines.push(` Wave ${wave.wave} → 启动 ${taskCount} 个 subagent 并行执行该波次的 ${taskCount} 个任务`);
78
+ }
79
+ }
80
+ lines.push(' </scheduling_summary>');
68
81
  lines.push(' </orchestration_strategy>');
69
82
  lines.push('</execution_plan>');
70
83
  return lines.join('\n');
@@ -1,2 +1,2 @@
1
- export declare const agentsTemplate = "# ZhuanSpec \u4F7F\u7528\u8BF4\u660E\n\n\u9762\u5411\u4F7F\u7528 ZhuanSpec \u8FDB\u884C\u89C4\u8303\u9A71\u52A8\u5F00\u53D1\u7684 AI \u7F16\u7A0B\u52A9\u624B\u7684\u8BF4\u660E\u6587\u6863\u3002\n\n## \u5FEB\u901F\u68C0\u67E5\u6E05\u5355\n\n- \u641C\u7D22\u73B0\u6709\u5DE5\u4F5C\uFF1A`zhuanspec spec list --long`\u3001`zhuanspec list`\uFF08\u4EC5\u4F7F\u7528 `rg` \u8FDB\u884C\u5168\u6587\u641C\u7D22\uFF09\n- \u786E\u5B9A\u8303\u56F4\uFF1A\u65B0\u529F\u80FD vs \u4FEE\u6539\u73B0\u6709\u529F\u80FD\n- \u9009\u62E9\u552F\u4E00\u7684 `change-id`\uFF1Akebab-case \u683C\u5F0F\uFF0C\u52A8\u8BCD\u5F00\u5934\uFF08`add-`\u3001`update-`\u3001`remove-`\u3001`refactor-`\uFF09\n- \u642D\u5EFA\u7ED3\u6784\uFF1A`proposal.md`\u3001`tasks.md`\u3001`design.md`\uFF08\u4EC5\u5728\u9700\u8981\u65F6\uFF09\uFF0C\u4EE5\u53CA\u6BCF\u4E2A\u53D7\u5F71\u54CD\u529F\u80FD\u7684\u89C4\u8303\u589E\u91CF\n- \u7F16\u5199\u589E\u91CF\uFF1A\u4F7F\u7528 `## ADDED|MODIFIED|REMOVED|RENAMED Requirements`\uFF1B\u6BCF\u4E2A\u8981\u6C42\u81F3\u5C11\u5305\u542B\u4E00\u4E2A `#### Scenario:`\n- \u9A8C\u8BC1\uFF1A\u8FD0\u884C `zhuanspec validate [change-id] --strict` \u5E76\u4FEE\u590D\u95EE\u9898\n- \u8BF7\u6C42\u6279\u51C6\uFF1A\u5728\u63D0\u6848\u83B7\u5F97\u6279\u51C6\u4E4B\u524D\u4E0D\u8981\u5F00\u59CB\u5B9E\u65BD\n\n## \u4E09\u9636\u6BB5\u5DE5\u4F5C\u6D41\n\n### \u9636\u6BB5 1\uFF1A\u521B\u5EFA\u53D8\u66F4\n\u5728\u4EE5\u4E0B\u60C5\u51B5\u4E0B\u521B\u5EFA\u63D0\u6848\uFF1A\n- \u6DFB\u52A0\u529F\u80FD\u6216\u7279\u6027\n- \u8FDB\u884C\u7834\u574F\u6027\u66F4\u6539\uFF08API\u3001schema\uFF09\n- \u66F4\u6539\u67B6\u6784\u6216\u6A21\u5F0F\n- \u4F18\u5316\u6027\u80FD\uFF08\u6539\u53D8\u884C\u4E3A\uFF09\n- \u66F4\u65B0\u5B89\u5168\u6A21\u5F0F\n\n\u89E6\u53D1\u8BCD\u793A\u4F8B\uFF1A\n- \"\u5E2E\u6211\u521B\u5EFA\u4E00\u4E2A\u53D8\u66F4\u63D0\u6848\"\n- \"\u5E2E\u6211\u89C4\u5212\u4E00\u4E2A\u53D8\u66F4\"\n- \"\u5E2E\u6211\u521B\u5EFA\u4E00\u4E2A\u63D0\u6848\"\n- \"\u6211\u60F3\u521B\u5EFA\u4E00\u4E2A\u89C4\u8303\u63D0\u6848\"\n- \"\u6211\u60F3\u521B\u5EFA\u4E00\u4E2A\u89C4\u8303\"\n\n\u5BBD\u677E\u5339\u914D\u6307\u5BFC\uFF1A\n- \u5305\u542B\u4EE5\u4E0B\u4E4B\u4E00\uFF1A`proposal`\u3001`change`\u3001`spec`\n- \u4E0E\u4EE5\u4E0B\u4E4B\u4E00\u7EC4\u5408\uFF1A`create`\u3001`plan`\u3001`make`\u3001`start`\u3001`help`\n\n\u8DF3\u8FC7\u63D0\u6848\u7684\u60C5\u51B5\uFF1A\n- Bug \u4FEE\u590D\uFF08\u6062\u590D\u9884\u671F\u884C\u4E3A\uFF09\n- \u62FC\u5199\u9519\u8BEF\u3001\u683C\u5F0F\u3001\u6CE8\u91CA\n- \u4F9D\u8D56\u66F4\u65B0\uFF08\u975E\u7834\u574F\u6027\uFF09\n- \u914D\u7F6E\u66F4\u6539\n- \u73B0\u6709\u884C\u4E3A\u7684\u6D4B\u8BD5\n\n**\u5DE5\u4F5C\u6D41**\n0. \u5BA1\u67E5 `zhuanspec/project.md`\u3001`zhuanspec list` \u548C `zhuanspec list --specs` \u4EE5\u4E86\u89E3\u5F53\u524D\u4E0A\u4E0B\u6587\u3002\n1. **\u5F3A\u5236\u6F84\u6E05\u68C0\u67E5\uFF08\u5FC5\u987B\u9996\u5148\u6267\u884C\uFF09**\uFF1A\u5206\u6790\u7528\u6237\u8BF7\u6C42\uFF0C\u8BC6\u522B\u6240\u6709\u4E0D\u786E\u5B9A\u6216\u6A21\u7CCA\u7684\u65B9\u9762\uFF08\u8303\u56F4\u3001\u6280\u672F\u9009\u62E9\u3001\u5B9E\u73B0\u7EC6\u8282\u3001\u6570\u636E\u83B7\u53D6\u6765\u6E90\u3001\u670D\u52A1\u5206\u5C42\u3001\u4F9D\u8D56\u5173\u7CFB\u3001\u4F18\u5148\u7EA7\u3001\u9A8C\u6536\u6807\u51C6\u7B49......\uFF09\u3002\u5982\u679C\u53D1\u73B0\u4EFB\u4F55\u6A21\u7CCA\u4E4B\u5904\uFF0C\u5FC5\u987B\u505C\u6B62\u5E76\u4F7F\u7528**\u9009\u9879\u5F0F\u4EA4\u4E92**\uFF08\u5982 `AskQuestion` \u5DE5\u5177\uFF09\u63D0\u95EE\uFF0C\u83B7\u5F97\u660E\u786E\u7B54\u590D\u540E\u624D\u80FD\u7EE7\u7EED\u3002\u4E25\u7981\u5728\u4E0D\u786E\u5B9A\u7684\u60C5\u51B5\u4E0B\u81EA\u884C\u63A8\u6D4B\u6216\u521B\u5EFA\u63D0\u6848\uFF0C\u4E25\u7981\u8981\u6C42\u7528\u6237\u624B\u52A8\u8F93\u5165\u5927\u6BB5\u6587\u5B57\u3002\n\n \u26A0\uFE0F **\u68C0\u67E5\u70B9 [\u5F3A\u5236\u6F84\u6E05]**\uFF1A\n \u5FC5\u987B\u5728 tasks.md \u4E2D\u8BB0\u5F55\u6F84\u6E05\u7ED3\u679C\uFF0C\u6DFB\u52A0 \"## \u6F84\u6E05\u65E5\u5FD7\" \u7AE0\u8282\uFF1A\n - \u5982\u679C\u8FDB\u884C\u4E86\u63D0\u95EE\uFF1A\u8BB0\u5F55\u6BCF\u4E2A\u95EE\u9898\u53CA\u7528\u6237\u7684\u56DE\u7B54\n - \u5982\u679C\u65E0\u9700\u6F84\u6E05\uFF1A\u5199\u660E\"\u72B6\u6001\uFF1A\u5DF2\u5B8C\u6210 - \u65E0\u9700\u6F84\u6E05\"\u5E76\u7B80\u8981\u8BF4\u660E\u7406\u7531\n - \u6B64\u7AE0\u8282\u4E0D\u80FD\u4E3A\u7A7A\u6216\u4EC5\u5305\u542B HTML \u6CE8\u91CA\n - \u672A\u5B8C\u6210\u6B64\u68C0\u67E5\u70B9\u524D\u7981\u6B62\u7EE7\u7EED\u7F16\u5199\u63D0\u6848\n\n2. \u9009\u62E9\u4E00\u4E2A\u552F\u4E00\u7684\u52A8\u8BCD\u5F00\u5934\u7684 `change-id`\uFF0C\u5E76\u5728 `zhuanspec/changes/<id>/` \u4E0B\u642D\u5EFA `proposal.md`\u3001`tasks.md`\u3001\u53EF\u9009\u7684 `design.md` \u548C\u89C4\u8303\u589E\u91CF\u3002\n3. \u4F7F\u7528 `## ADDED|MODIFIED|REMOVED Requirements` \u8D77\u8349\u89C4\u8303\u589E\u91CF\uFF0C\u6BCF\u4E2A\u8981\u6C42\u81F3\u5C11\u5305\u542B\u4E00\u4E2A `#### Scenario:`\u3002\n4. \u8FD0\u884C `zhuanspec validate <id> --strict` \u5E76\u5728\u5206\u4EAB\u63D0\u6848\u4E4B\u524D\u89E3\u51B3\u6240\u6709\u95EE\u9898\u3002\n\n### \u9636\u6BB5 2\uFF1A\u5B9E\u65BD\u53D8\u66F4\n\n\u5C06\u8FD9\u4E9B\u6B65\u9AA4\u4F5C\u4E3A\u5F85\u529E\u4E8B\u9879\u8DDF\u8E2A\uFF0C\u9010\u4E00\u5B8C\u6210\u3002\n\n1. **\u9605\u8BFB proposal.md** - \u4E86\u89E3\u8981\u6784\u5EFA\u7684\u5185\u5BB9\n2. **\u9605\u8BFB design.md**\uFF08\u5982\u679C\u5B58\u5728\uFF09 - \u5BA1\u67E5\u6280\u672F\u51B3\u7B56\n3. **\u9605\u8BFB tasks.md** - \u83B7\u53D6\u5B9E\u65BD\u6E05\u5355\n4. **\u5224\u65AD\u6267\u884C\u6A21\u5F0F** - \u6839\u636E tasks.md \u5185\u5BB9\u9009\u62E9\u6267\u884C\u7B56\u7565\uFF1A\n - **\u5982\u679C tasks.md \u5305\u542B `@depends` \u4F9D\u8D56\u58F0\u660E**\uFF08\u5B58\u5728 `<execution_plan>`\uFF09\uFF1A\n \u2192 \u6309\u3010\u4EFB\u52A1\u6267\u884C\u7F16\u6392\u3011\u89C4\u5219\u6267\u884C\uFF08\u89C1\u4E0B\u65B9\"\u4EFB\u52A1\u6267\u884C\u7F16\u6392\"\u7AE0\u8282\uFF09\n - **\u5982\u679C tasks.md \u65E0\u4F9D\u8D56\u58F0\u660E**\uFF1A\n \u2192 \u6309\u987A\u5E8F\u6267\u884C\uFF08\u89C1\u4E0B\u65B9\u6B65\u9AA4 5-7\uFF09\n5. **\u6309\u987A\u5E8F\u5B9E\u65BD\u4EFB\u52A1**\uFF08\u65E0\u4F9D\u8D56\u58F0\u660E\u65F6\uFF09- \u6309\u987A\u5E8F\u5B8C\u6210\u3002\u5982\u679C\u4EFB\u52A1\u6807\u6CE8\u4E86 `@skill:<skill-name>`\uFF0C\u76F4\u63A5\u8C03\u7528\u5BF9\u5E94 skill\n6. **\u786E\u8BA4\u5B8C\u6210** - \u5728\u66F4\u65B0\u72B6\u6001\u4E4B\u524D\u786E\u4FDD `tasks.md` \u4E2D\u7684\u6BCF\u4E2A\u9879\u76EE\u90FD\u5DF2\u5B8C\u6210\n7. **\u66F4\u65B0\u6E05\u5355** - \u6240\u6709\u5DE5\u4F5C\u5B8C\u6210\u540E\uFF0C\u5C06\u6BCF\u4E2A\u4EFB\u52A1\u8BBE\u7F6E\u4E3A `- [x]`\uFF0C\u4EE5\u4FBF\u5217\u8868\u53CD\u6620\u5B9E\u9645\u60C5\u51B5\n8. **\u4EE3\u7801\u5BA1\u67E5**\uFF08\u53EF\u9009\uFF09 - \u57FA\u4E8E\u751F\u6210\u7684\u4E0A\u4E0B\u6587\u6587\u4EF6\u5BA1\u67E5\u5DF2\u5B9E\u65BD\u7684\u4EE3\u7801\uFF0C\u68C0\u67E5\uFF1A\n - \u4EE3\u7801\u89C4\u8303\u548C\u7EA6\u5B9A\u5408\u89C4\u6027\n - \u903B\u8F91\u6B63\u786E\u6027\n - \u6027\u80FD\u95EE\u9898\u548C\u6F5C\u5728\u74F6\u9888\n - \u5B89\u5168\u6027\u95EE\u9898\n - \u6700\u4F73\u5B9E\u8DF5\u9075\u5FAA\u60C5\u51B5\n - \u5BF9\u4E8E Java \u4EE3\u7801\uFF1A\u7279\u522B\u5173\u6CE8 Java \u7279\u5B9A\u7684\u6A21\u5F0F\u3001\u7EA6\u5B9A\u548C\u6F5C\u5728\u95EE\u9898\n - \u6B64\u6B65\u9AA4\u662F\u53EF\u9009\u7684\uFF0C\u5982\u679C\u8DF3\u8FC7\u4E0D\u4F1A\u963B\u585E\u5DE5\u4F5C\u6D41\n - \u5982\u679C\u53D1\u73B0\u95EE\u9898\uFF0C\u5E94\u5728\u5F52\u6863\u4E4B\u524D\u89E3\u51B3\n9. **\u6279\u51C6\u95E8\u69DB** - \u5728\u63D0\u6848\u7ECF\u8FC7\u5BA1\u67E5\u548C\u6279\u51C6\u4E4B\u524D\u4E0D\u8981\u5F00\u59CB\u5B9E\u65BD\n\n### \u9636\u6BB5 3\uFF1A\u5F52\u6863\u53D8\u66F4\n\u90E8\u7F72\u540E\uFF0C\u521B\u5EFA\u5355\u72EC\u7684 PR\uFF1A\n- \u5C06 `changes/[name]/` \u2192 `changes/archive/YYYY-MM-DD-[name]/`\n- \u5982\u679C\u529F\u80FD\u5DF2\u66F4\u6539\uFF0C\u66F4\u65B0 `specs/`\n- \u5BF9\u4E8E\u4EC5\u5DE5\u5177\u7C7B\u7684\u53D8\u66F4\uFF0C\u4F7F\u7528 `zhuanspec archive <change-id> --skip-specs --yes`\uFF08\u59CB\u7EC8\u663E\u5F0F\u4F20\u9012\u53D8\u66F4 ID\uFF09\n- \u8FD0\u884C `zhuanspec validate --strict` \u4EE5\u786E\u8BA4\u5F52\u6863\u7684\u53D8\u66F4\u901A\u8FC7\u68C0\u67E5\n\n## \u6267\u884C\u4EFB\u4F55\u4EFB\u52A1\u4E4B\u524D\n\n**\u4E0A\u4E0B\u6587\u68C0\u67E5\u6E05\u5355\uFF1A**\n- [ ] \u5728 `specs/[capability]/spec.md` \u4E2D\u9605\u8BFB\u76F8\u5173\u89C4\u8303\n- [ ] \u68C0\u67E5 `changes/` \u4E2D\u7684\u5F85\u5904\u7406\u53D8\u66F4\u662F\u5426\u5B58\u5728\u51B2\u7A81\n- [ ] \u9605\u8BFB `zhuanspec/project.md` \u4E86\u89E3\u7EA6\u5B9A\u3001\u9879\u76EE\u7ED3\u6784\u548C\u76F8\u5173\u529F\u80FD\u6A21\u5757\uFF08\u6309\u9700\u52A0\u8F7D\uFF09\n- [ ] \u8FD0\u884C `zhuanspec list` \u67E5\u770B\u6D3B\u52A8\u53D8\u66F4\n- [ ] \u8FD0\u884C `zhuanspec list --specs` \u67E5\u770B\u73B0\u6709\u529F\u80FD\n\n**\u521B\u5EFA\u89C4\u8303\u4E4B\u524D\uFF1A**\n- \u59CB\u7EC8\u68C0\u67E5\u529F\u80FD\u662F\u5426\u5DF2\u5B58\u5728\n- \u4F18\u5148\u4FEE\u6539\u73B0\u6709\u89C4\u8303\u800C\u4E0D\u662F\u521B\u5EFA\u91CD\u590D\u9879\n- \u4F7F\u7528 `zhuanspec show [spec]` \u5BA1\u67E5\u5F53\u524D\u72B6\u6001\n- **\u5F3A\u5236\u6F84\u6E05\u8981\u6C42**\uFF1A\u5982\u679C\u8BF7\u6C42\u6709\u4EFB\u4F55\u4E0D\u660E\u786E\u3001\u6A21\u7CCA\u6216\u4E0D\u786E\u5B9A\u7684\u65B9\u9762\uFF0C\u5FC5\u987B\u505C\u6B62\u5E76\u4F7F\u7528**\u9009\u9879\u5F0F\u4EA4\u4E92**\u63D0\u95EE\u3002\u4E25\u7981\u5728\u4E0D\u786E\u5B9A\u7684\u60C5\u51B5\u4E0B\u81EA\u884C\u63A8\u6D4B\u3001\u5047\u8BBE\u6216\u7EE7\u7EED\u521B\u5EFA\u6587\u4EF6\u3002\u4E25\u7981\u8981\u6C42\u7528\u6237\u624B\u52A8\u8F93\u5165\u5927\u6BB5\u6587\u5B57\u56DE\u7B54\u3002\n\n## \u5F3A\u5236\u6F84\u6E05\u5DE5\u4F5C\u6D41\n\n\u5728\u521B\u5EFA\u4EFB\u4F55\u63D0\u6848\u6587\u4EF6\u4E4B\u524D\uFF0C\u5FC5\u987B\u6267\u884C\u5F3A\u5236\u6F84\u6E05\u68C0\u67E5\u3002\u8FD9\u662F\u4E0D\u53EF\u8DF3\u8FC7\u7684\u6B65\u9AA4\u3002\n\n**\u91CD\u8981\u539F\u5219\uFF1A\u5148\u67E5\u9605\u540E\u8BE2\u95EE\uFF0C\u907F\u514D\u8FC7\u5EA6\u8BE2\u95EE**\n\n\u5728\u8BE2\u95EE\u4E4B\u524D\uFF0C\u5FC5\u987B\u5148\u67E5\u9605\u4EE5\u4E0B\u6765\u6E90\uFF0C\u53EA\u6709\u5728\u786E\u5B9E\u65E0\u6CD5\u4ECE\u8FD9\u4E9B\u6765\u6E90\u786E\u5B9A\u65F6\u624D\u8BE2\u95EE\uFF1A\n- \u73B0\u6709\u89C4\u8303\uFF08`zhuanspec/specs/`\uFF09\n- \u9879\u76EE\u7EA6\u5B9A\uFF08`zhuanspec/project.md`\uFF09\n- \u4EE3\u7801\u5E93\u7ED3\u6784\u548C\u73B0\u6709\u6A21\u5F0F\n- \u4E0A\u4E0B\u6587\u6587\u4EF6\u548C\u76F8\u5173\u53D8\u66F4\n\n### \u4F55\u65F6\u9700\u8981\u6F84\u6E05\n\n\u5728\u4EE5\u4E0B\u60C5\u51B5\u4E0B\uFF0C**\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u89C4\u8303\u3001\u9879\u76EE\u7EA6\u5B9A\u3001\u4EE3\u7801\u5E93\u7ED3\u6784\u4E2D\u786E\u5B9A\u65F6**\uFF0C\u5FC5\u987B\u505C\u6B62\u5E76\u63D0\u95EE\uFF08\u5305\u62EC\u4F46\u4E0D\u9650\u4E8E\uFF09\uFF1A\n- **\u8303\u56F4\u4E0D\u660E\u786E**\uFF1A\u7528\u6237\u8BF7\u6C42\u7684\u8303\u56F4\u8FB9\u754C\u4E0D\u6E05\u695A\uFF08\u4F8B\u5982\uFF1A\"\u6539\u8FDB\u6027\u80FD\"\u3001\"\u4F18\u5316\u4EE3\u7801\"\uFF09\n- **\u6280\u672F\u9009\u62E9\u4E0D\u660E\u786E**\uFF1A\u6709\u591A\u79CD\u5B9E\u73B0\u65B9\u5F0F\uFF0C\u4F46\u7528\u6237\u672A\u6307\u5B9A\u504F\u597D\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u4EE3\u7801\u6A21\u5F0F\u4E2D\u786E\u5B9A\uFF08\u4F8B\u5982\uFF1A\u4F7F\u7528\u54EA\u79CD\u6570\u636E\u5E93\u3001\u54EA\u79CD\u6846\u67B6\uFF09\n- **\u4F18\u5148\u7EA7\u4E0D\u660E\u786E**\uFF1A\u591A\u4E2A\u9700\u6C42\u4F46\u672A\u8BF4\u660E\u4F18\u5148\u7EA7\u6216\u987A\u5E8F\n- **\u9A8C\u6536\u6807\u51C6\u4E0D\u660E\u786E**\uFF1A\u4E0D\u6E05\u695A\u5982\u4F55\u5224\u65AD\u5B8C\u6210\u6216\u6210\u529F\n- **\u5B9E\u73B0\u7EC6\u8282\u4E0D\u660E\u786E**\uFF1A\u4E0D\u6E05\u695A\u5982\u4F55\u5B9E\u73B0\u6216\u5B9E\u73B0\u7EC6\u8282\u4E0D\u660E\u786E\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u4EE3\u7801\u5E93\u5206\u6790\u4E2D\u786E\u5B9A\uFF08\u4F8B\u5982\uFF1A\u5982\u4F55\u83B7\u53D6\u6570\u636E\u3001\u5982\u4F55\u5904\u7406\u9519\u8BEF\u3001\u5982\u4F55\u4F18\u5316\u6027\u80FD\uFF09\n- **\u4EE3\u7801\u6539\u52A8\u4F4D\u7F6E\u4E0D\u660E\u786E**\uFF1A\u4E0D\u6E05\u695A\u9700\u8981\u4FEE\u6539\u54EA\u4E9B\u6587\u4EF6\u3001\u5728\u54EA\u4E9B\u4F4D\u7F6E\u8FDB\u884C\u4FEE\u6539\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u4EE3\u7801\u5E93\u7ED3\u6784\u5206\u6790\u4E2D\u786E\u5B9A\n- **\u4EE3\u7801\u5206\u5C42\u67B6\u6784\u4E0D\u660E\u786E**\uFF1A\u5982\u679C\u6D89\u53CA\u670D\u52A1\u5206\u5C42\uFF08\u5982 4 \u5C42\u67B6\u6784\u30013 \u5C42\u67B6\u6784\u7B49\uFF09\uFF0C\u4E0D\u6E05\u695A\u5404\u5C42\u7684\u804C\u8D23\u548C\u6539\u52A8\u4F4D\u7F6E\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u4EE3\u7801\u7ED3\u6784\u6216\u89C4\u8303\u4E2D\u786E\u5B9A\n- **\u6570\u636E\u83B7\u53D6\u6765\u6E90\u4E0D\u660E\u786E**\uFF1A\u4E0D\u6E05\u695A\u4ECE\u54EA\u91CC\u83B7\u53D6\u6570\u636E\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u4EE3\u7801\u6216\u89C4\u8303\u4E2D\u786E\u5B9A\uFF08\u4F8B\u5982\uFF1A\u4ECE\u6570\u636E\u5E93\u3001API\u3001\u6587\u4EF6\u3001\u5916\u90E8\u670D\u52A1\u3001\u5386\u53F2\u903B\u8F91\u590D\u7528\uFF09\n- **\u670D\u52A1\u5206\u5C42\u4E0D\u660E\u786E**\uFF1A\u4E0D\u6E05\u695A\u670D\u52A1\u5206\u5C42\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u4EE3\u7801\u7ED3\u6784\u6216\u89C4\u8303\u4E2D\u786E\u5B9A\uFF08\u4F8B\u5982\uFF1A\u524D\u7AEF\u3001\u540E\u7AEF\u3001\u6570\u636E\u5E93\u3001API\u3001\u670D\u52A1\u30014\u5C42\u67B6\u6784\u30013\u5C42\u67B6\u6784\u30012\u5C42\u67B6\u6784\u3001\u9886\u57DF\u6A21\u578B\uFF09\n- **\u4F9D\u8D56\u5173\u7CFB\u4E0D\u660E\u786E**\uFF1A\u4E0D\u6E05\u695A\u4F9D\u8D56\u5173\u7CFB\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u4EE3\u7801\u5E93\u5206\u6790\u4E2D\u786E\u5B9A\uFF08\u4F8B\u5982\uFF1A\u4F9D\u8D56\u54EA\u4E9B\u670D\u52A1\u3001\u4F9D\u8D56\u54EA\u4E9B\u5E93\u3001\u4F9D\u8D56\u54EA\u4E9B\u7EC4\u4EF6\uFF09\n- **\u4E0A\u4E0B\u6587\u4FE1\u606F\u7F3A\u5931**\uFF1A\u7F3A\u5C11\u5FC5\u8981\u7684\u80CC\u666F\u4FE1\u606F\u6765\u7406\u89E3\u9700\u6C42\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u89C4\u8303\u6216\u4EE3\u7801\u4E2D\u83B7\u53D6\n- **\u6B67\u4E49\u6027\u8868\u8FF0**\uFF1A\u7528\u6237\u8BF7\u6C42\u53EF\u4EE5\u7528\u591A\u79CD\u65B9\u5F0F\u7406\u89E3\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u4E0A\u4E0B\u6587\u786E\u5B9A\n- **\u5176\u4ED6\u4E0D\u660E\u786E**\uFF1A\u5176\u4ED6\u4E0D\u660E\u786E\u7684\u60C5\u51B5\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u6765\u6E90\u786E\u5B9A\n\n### \u4F55\u65F6\u4E0D\u9700\u8981\u6F84\u6E05\n\n\u5728\u4EE5\u4E0B\u60C5\u51B5\u4E0B\uFF0C**\u4E0D\u5E94\u8BE2\u95EE**\uFF0C\u5E94\u76F4\u63A5\u4F7F\u7528\u4ECE\u73B0\u6709\u6765\u6E90\u83B7\u53D6\u7684\u4FE1\u606F\uFF1A\n- **\u4FE1\u606F\u5DF2\u660E\u786E**\uFF1A\u7528\u6237\u8BF7\u6C42\u4E2D\u5DF2\u7ECF\u660E\u786E\u8BF4\u660E\u4E86\u76F8\u5173\u4FE1\u606F\n- **\u53EF\u4ECE\u89C4\u8303\u83B7\u53D6**\uFF1A\u4FE1\u606F\u53EF\u4EE5\u4ECE\u73B0\u6709\u89C4\u8303\uFF08`zhuanspec/specs/`\uFF09\u4E2D\u83B7\u53D6\n- **\u53EF\u4ECE\u9879\u76EE\u7EA6\u5B9A\u83B7\u53D6**\uFF1A\u4FE1\u606F\u53EF\u4EE5\u4ECE\u9879\u76EE\u7EA6\u5B9A\uFF08`zhuanspec/project.md`\uFF09\u4E2D\u83B7\u53D6\n- **\u53EF\u4ECE\u4EE3\u7801\u5E93\u5206\u6790\u83B7\u53D6**\uFF1A\u4FE1\u606F\u53EF\u4EE5\u901A\u8FC7\u5206\u6790\u4EE3\u7801\u5E93\u7ED3\u6784\u3001\u73B0\u6709\u6A21\u5F0F\u3001\u76F8\u5173\u6587\u4EF6\u83B7\u53D6\n- **\u53EF\u4ECE\u4E0A\u4E0B\u6587\u83B7\u53D6**\uFF1A\u4FE1\u606F\u53EF\u4EE5\u4ECE\u4E0A\u4E0B\u6587\u6587\u4EF6\u3001\u76F8\u5173\u53D8\u66F4\u3001\u5386\u53F2\u8BB0\u5F55\u4E2D\u83B7\u53D6\n- **\u7B26\u5408\u5E38\u89C1\u6A21\u5F0F**\uFF1A\u5B9E\u73B0\u65B9\u5F0F\u7B26\u5408\u9879\u76EE\u4E2D\u7684\u5E38\u89C1\u6A21\u5F0F\u6216\u6700\u4F73\u5B9E\u8DF5\uFF0C\u65E0\u9700\u7279\u522B\u8BE2\u95EE\n\n**\u539F\u5219**\uFF1A\u5982\u679C\u53EF\u4EE5\u901A\u8FC7\u67E5\u9605\u73B0\u6709\u6765\u6E90\u786E\u5B9A\u4FE1\u606F\uFF0C\u5C31\u4E0D\u8981\u8BE2\u95EE\u7528\u6237\uFF0C\u4EE5\u63D0\u9AD8\u6548\u7387\u3002\n\n### \u6F84\u6E05\u95EE\u9898\u683C\u5F0F\n\n**\u5FC5\u987B\u4F7F\u7528\u9009\u9879\u5F0F\u4EA4\u4E92\uFF0C\u4E25\u7981\u8981\u6C42\u7528\u6237\u624B\u52A8\u8F93\u5165\u6587\u5B57\u56DE\u7B54\u3002**\n\n\u4F7F\u7528\u7F16\u8F91\u5668\u63D0\u4F9B\u7684\u7ED3\u6784\u5316\u95EE\u7B54\u5DE5\u5177\uFF08\u5982 Cursor \u7684 `AskQuestion` \u5DE5\u5177\u3001Claude Code \u7684\u4EA4\u4E92\u5F0F\u9009\u62E9\u7B49\uFF09\u5411\u7528\u6237\u63D0\u95EE\uFF0C\u5C06\u6BCF\u4E2A\u6F84\u6E05\u95EE\u9898\u8F6C\u5316\u4E3A\u5E26\u9884\u8BBE\u9009\u9879\u7684\u9009\u62E9\u9898\uFF1A\n\n**\u683C\u5F0F\u8981\u6C42\uFF1A**\n- \u6BCF\u4E2A\u95EE\u9898\u63D0\u4F9B 2-5 \u4E2A\u9884\u8BBE\u9009\u9879\n- \u6BCF\u4E2A\u95EE\u9898\u672B\u5C3E\u5305\u542B\u4E00\u4E2A\"\u5176\u4ED6\"\u9009\u9879\uFF0C\u4EE5\u8986\u76D6\u672A\u5217\u51FA\u7684\u60C5\u51B5\n- \u5141\u8BB8\u7528\u6237\u591A\u9009\uFF08\u5F53\u95EE\u9898\u53EF\u80FD\u6709\u591A\u4E2A\u7B54\u6848\u65F6\u8BBE\u7F6E `allow_multiple: true`\uFF09\n- \u9009\u9879\u6587\u672C\u8981\u7B80\u6D01\u660E\u4E86\uFF0C\u5FC5\u8981\u65F6\u9644\u5E26\u7B80\u77ED\u8BF4\u660E\n- \u5982\u679C\u6709\u591A\u4E2A\u72EC\u7ACB\u7684\u6F84\u6E05\u95EE\u9898\uFF0C\u5408\u5E76\u5230\u540C\u4E00\u6B21\u95EE\u7B54\u4EA4\u4E92\u4E2D\uFF08\u4E00\u6B21\u6027\u5C55\u793A\u591A\u4E2A\u95EE\u9898\uFF09\n\n**\u6807\u51C6\u683C\u5F0F\u6A21\u677F\uFF1A**\n\n```\n\u4F7F\u7528 AskQuestion \u5DE5\u5177\u63D0\u95EE\uFF0C\u7ED3\u6784\u5982\u4E0B\uFF1A\n\n\u95EE\u9898 1: \"\u5173\u4E8E [\u4E0D\u786E\u5B9A\u7684\u65B9\u9762]\uFF1A[\u5177\u4F53\u95EE\u9898]\"\n\u9009\u9879\uFF1A\n A) [\u9009\u98791 - \u7B80\u77ED\u8BF4\u660E]\n B) [\u9009\u98792 - \u7B80\u77ED\u8BF4\u660E]\n C) [\u9009\u98793 - \u7B80\u77ED\u8BF4\u660E]\n D) \u5176\u4ED6\uFF08\u8BF7\u5728\u540E\u7EED\u8865\u5145\u8BF4\u660E\uFF09\n\n\u95EE\u9898 2: \"\u5173\u4E8E [\u53E6\u4E00\u4E2A\u65B9\u9762]\uFF1A[\u5177\u4F53\u95EE\u9898]\"\n\u9009\u9879\uFF1A\n A) [\u9009\u98791]\n B) [\u9009\u98792]\n C) \u5176\u4ED6\n```\n\n**\u5DE5\u5177\u8C03\u7528\u793A\u4F8B\uFF08Cursor AskQuestion\uFF09\uFF1A**\n```json\n{\n \"questions\": [\n {\n \"id\": \"scope\",\n \"prompt\": \"\u5173\u4E8E\u6539\u8FDB\u8303\u56F4\uFF1A\u60A8\u5E0C\u671B\u6539\u8FDB\u54EA\u4E9B\u65B9\u9762\uFF1F\",\n \"options\": [\n {\"id\": \"security\", \"label\": \"\u5B89\u5168\u6027\uFF08\u5982\u53CC\u56E0\u7D20\u8BA4\u8BC1\uFF09\"},\n {\"id\": \"ux\", \"label\": \"\u7528\u6237\u4F53\u9A8C\uFF08\u5982\u7B80\u5316\u6D41\u7A0B\uFF09\"},\n {\"id\": \"performance\", \"label\": \"\u6027\u80FD\uFF08\u5982\u54CD\u5E94\u65F6\u95F4\u4F18\u5316\uFF09\"},\n {\"id\": \"other\", \"label\": \"\u5176\u4ED6\"}\n ],\n \"allow_multiple\": true\n },\n {\n \"id\": \"priority\",\n \"prompt\": \"\u5982\u679C\u6709\u591A\u4E2A\u6539\u8FDB\u70B9\uFF0C\u4F18\u5148\u7EA7\u5982\u4F55\uFF1F\",\n \"options\": [\n {\"id\": \"security_first\", \"label\": \"\u5B89\u5168\u6027\u4F18\u5148\"},\n {\"id\": \"ux_first\", \"label\": \"\u7528\u6237\u4F53\u9A8C\u4F18\u5148\"},\n {\"id\": \"all_equal\", \"label\": \"\u540C\u7B49\u91CD\u8981\uFF0C\u4E00\u8D77\u505A\"}\n ]\n }\n ]\n}\n```\n\n**\u539F\u5219\uFF1A**\n- \u6C38\u8FDC\u4E0D\u8981\u8BA9\u7528\u6237\u4ECE\u96F6\u5F00\u59CB\u8F93\u5165\u7B54\u6848\uFF0C\u603B\u662F\u63D0\u4F9B\u53EF\u9009\u7684\u9009\u9879\n- \u9009\u9879\u5E94\u8986\u76D6\u6700\u5E38\u89C1\u7684\u7B54\u6848\u573A\u666F\n- \"\u5176\u4ED6\"\u9009\u9879\u4F5C\u4E3A\u515C\u5E95\uFF0C\u786E\u4FDD\u4E0D\u9057\u6F0F\u7279\u6B8A\u60C5\u51B5\n- \u7528\u6237\u9009\u62E9\"\u5176\u4ED6\"\u540E\uFF0C\u518D\u9488\u5BF9\u6027\u5730\u8FFD\u95EE\u7EC6\u8282\n\n### \u7981\u6B62\u884C\u4E3A\n\n\u5728\u9047\u5230\u6A21\u7CCA\u9700\u6C42\u65F6\uFF0C**\u4E25\u7981**\u4EE5\u4E0B\u884C\u4E3A\uFF1A\n- \u274C \u81EA\u884C\u63A8\u6D4B\u7528\u6237\u610F\u56FE\n- \u274C \u57FA\u4E8E\"\u6700\u4F73\u731C\u6D4B\"\u521B\u5EFA\u63D0\u6848\n- \u274C \u5047\u8BBE\u7528\u6237\u60F3\u8981\u4EC0\u4E48\n- \u274C \u8DF3\u8FC7\u6F84\u6E05\u76F4\u63A5\u521B\u5EFA\u6587\u4EF6\n- \u274C \u4F7F\u7528\u6A21\u7CCA\u7684\u8868\u8FF0\u6765\u63A9\u76D6\u4E0D\u786E\u5B9A\u6027\n- \u274C \u8981\u6C42\u7528\u6237\u624B\u52A8\u8F93\u5165\u5927\u6BB5\u6587\u5B57\u6765\u56DE\u7B54\u6F84\u6E05\u95EE\u9898\uFF08\u5FC5\u987B\u4F7F\u7528\u9009\u9879\u5F0F\u4EA4\u4E92\uFF09\n\n### \u6F84\u6E05\u6D41\u7A0B\n\n1. **\u67E5\u9605\u73B0\u6709\u6765\u6E90**\uFF1A\u9996\u5148\u67E5\u9605\u73B0\u6709\u89C4\u8303\u3001\u9879\u76EE\u7EA6\u5B9A\u3001\u4EE3\u7801\u5E93\u7ED3\u6784\u3001\u4E0A\u4E0B\u6587\u6587\u4EF6\u7B49\uFF0C\u5C1D\u8BD5\u4ECE\u8FD9\u4E9B\u6765\u6E90\u83B7\u53D6\u6240\u9700\u4FE1\u606F\n2. **\u8BC6\u522B\u6A21\u7CCA\u70B9**\uFF1A\u4ED4\u7EC6\u5206\u6790\u7528\u6237\u8BF7\u6C42\uFF0C\u5217\u51FA\u6240\u6709\u4E0D\u786E\u5B9A\u7684\u65B9\u9762\uFF0C**\u4F46\u6392\u9664\u90A3\u4E9B\u53EF\u4EE5\u4ECE\u73B0\u6709\u6765\u6E90\u786E\u5B9A\u7684\u65B9\u9762**\n3. **\u5224\u65AD\u662F\u5426\u9700\u8981\u8BE2\u95EE**\uFF1A\u5BF9\u4E8E\u6BCF\u4E2A\u4E0D\u786E\u5B9A\u7684\u65B9\u9762\uFF0C\u5224\u65AD\u662F\u5426\u53EF\u4EE5\u4ECE\u73B0\u6709\u6765\u6E90\u786E\u5B9A\uFF1A\n - \u5982\u679C\u53EF\u4EE5\u786E\u5B9A\uFF0C\u5219\u4F7F\u7528\u4ECE\u73B0\u6709\u6765\u6E90\u83B7\u53D6\u7684\u4FE1\u606F\uFF0C\u4E0D\u8BE2\u95EE\n - \u5982\u679C\u65E0\u6CD5\u786E\u5B9A\uFF0C\u5219\u6807\u8BB0\u4E3A\u9700\u8981\u8BE2\u95EE\n4. **\u6784\u9020\u9009\u9879\u5F0F\u95EE\u9898**\uFF1A\u5C06\u6240\u6709\u9700\u8981\u8BE2\u95EE\u7684\u6A21\u7CCA\u70B9\u8F6C\u5316\u4E3A\u5E26\u9884\u8BBE\u9009\u9879\u7684\u9009\u62E9\u9898\uFF0C\u5C3D\u91CF\u5408\u5E76\u5230\u4E00\u6B21\u4EA4\u4E92\u4E2D\n5. **\u4F7F\u7528\u5DE5\u5177\u63D0\u95EE**\uFF1A\u8C03\u7528\u7F16\u8F91\u5668\u7684\u7ED3\u6784\u5316\u95EE\u7B54\u5DE5\u5177\uFF08\u5982 `AskQuestion`\uFF09\u4E00\u6B21\u6027\u5C55\u793A\u6240\u6709\u95EE\u9898\u548C\u9009\u9879\uFF0C\u7B49\u5F85\u7528\u6237\u9009\u62E9\n6. **\u7B49\u5F85\u7528\u6237\u9009\u62E9**\uFF1A\u5FC5\u987B\u7B49\u5F85\u7528\u6237\u9009\u62E9\u7B54\u6848\uFF0C\u4E0D\u80FD\u7EE7\u7EED\n7. **\u5904\u7406\"\u5176\u4ED6\"\u9009\u9879**\uFF1A\u5982\u679C\u7528\u6237\u9009\u62E9\u4E86\"\u5176\u4ED6\"\uFF0C\u518D\u9488\u5BF9\u8BE5\u95EE\u9898\u8FFD\u95EE\u5177\u4F53\u7EC6\u8282\uFF08\u4ECD\u4F18\u5148\u4F7F\u7528\u9009\u9879\u5F0F\uFF0C\u5982\u786E\u5B9E\u65E0\u6CD5\u9884\u8BBE\u5219\u5141\u8BB8\u7B80\u77ED\u6587\u5B57\u8F93\u5165\uFF09\n8. **\u786E\u8BA4\u7406\u89E3**\uFF1A\u5728\u5F00\u59CB\u521B\u5EFA\u6587\u4EF6\u524D\uFF0C\u7B80\u8981\u603B\u7ED3\u7406\u89E3\u4EE5\u786E\u4FDD\u51C6\u786E\n9. **\u5F00\u59CB\u521B\u5EFA**\uFF1A\u53EA\u6709\u5728\u6240\u6709\u5FC5\u8981\u7684\u6A21\u7CCA\u70B9\u90FD\u660E\u786E\u540E\uFF0C\u624D\u80FD\u5F00\u59CB\u521B\u5EFA\u63D0\u6848\u6587\u4EF6\n\n### \u793A\u4F8B\n\n**\u7528\u6237\u8BF7\u6C42**\uFF1A\"\u6539\u8FDB\u767B\u5F55\u529F\u80FD\"\n\n**\u5206\u6790\u8FC7\u7A0B**\uFF1A\n1. \u9996\u5148\u67E5\u9605\u73B0\u6709\u89C4\u8303\uFF08`zhuanspec/specs/`\uFF09\u4E2D\u662F\u5426\u6709\u767B\u5F55\u76F8\u5173\u7684\u89C4\u8303\n2. \u67E5\u9605\u9879\u76EE\u7EA6\u5B9A\uFF08`zhuanspec/project.md`\uFF09\u4E86\u89E3\u9879\u76EE\u67B6\u6784\u548C\u7EA6\u5B9A\n3. \u5206\u6790\u4EE3\u7801\u5E93\u7ED3\u6784\uFF0C\u4E86\u89E3\u73B0\u6709\u7684\u767B\u5F55\u5B9E\u73B0\u65B9\u5F0F\n4. \u5982\u679C\u4ECE\u8FD9\u4E9B\u6765\u6E90\u65E0\u6CD5\u786E\u5B9A\u6539\u8FDB\u8303\u56F4\uFF0C\u5219\u4F7F\u7528\u9009\u9879\u5F0F\u4EA4\u4E92\u8BE2\u95EE\n\n**\u5FC5\u987B\u4F7F\u7528\u9009\u9879\u5F0F\u4EA4\u4E92\u63D0\u95EE**\uFF08\u4EC5\u5728\u65E0\u6CD5\u4ECE\u73B0\u6709\u6765\u6E90\u786E\u5B9A\u65F6\uFF09\uFF1A\n\n```json\n{\n \"questions\": [\n {\n \"id\": \"improvement_scope\",\n \"prompt\": \"\u60A8\u5E0C\u671B\u6539\u8FDB\u767B\u5F55\u529F\u80FD\u7684\u54EA\u4E9B\u65B9\u9762\uFF1F\",\n \"options\": [\n {\"id\": \"security\", \"label\": \"\u5B89\u5168\u6027\uFF08\u5982\u6DFB\u52A0\u53CC\u56E0\u7D20\u8BA4\u8BC1\uFF09\"},\n {\"id\": \"ux\", \"label\": \"\u7528\u6237\u4F53\u9A8C\uFF08\u5982\u7B80\u5316\u767B\u5F55\u6D41\u7A0B\uFF09\"},\n {\"id\": \"performance\", \"label\": \"\u6027\u80FD\uFF08\u5982\u4F18\u5316\u767B\u5F55\u54CD\u5E94\u65F6\u95F4\uFF09\"},\n {\"id\": \"other\", \"label\": \"\u5176\u4ED6\"}\n ],\n \"allow_multiple\": true\n },\n {\n \"id\": \"tech_preference\",\n \"prompt\": \"\u60A8\u6709\u7279\u5B9A\u7684\u6280\u672F\u504F\u597D\u5417\uFF1F\",\n \"options\": [\n {\"id\": \"jwt\", \"label\": \"JWT Token \u8BA4\u8BC1\"},\n {\"id\": \"session\", \"label\": \"Session \u8BA4\u8BC1\"},\n {\"id\": \"oauth\", \"label\": \"OAuth \u7B2C\u4E09\u65B9\u96C6\u6210\"},\n {\"id\": \"no_preference\", \"label\": \"\u65E0\u504F\u597D\uFF0C\u7531\u4F60\u63A8\u8350\"},\n {\"id\": \"other\", \"label\": \"\u5176\u4ED6\"}\n ]\n },\n {\n \"id\": \"priority\",\n \"prompt\": \"\u5982\u679C\u6709\u591A\u4E2A\u6539\u8FDB\u70B9\uFF0C\u4F18\u5148\u7EA7\u5982\u4F55\uFF1F\",\n \"options\": [\n {\"id\": \"security_first\", \"label\": \"\u5B89\u5168\u6027\u4F18\u5148\"},\n {\"id\": \"ux_first\", \"label\": \"\u7528\u6237\u4F53\u9A8C\u4F18\u5148\"},\n {\"id\": \"perf_first\", \"label\": \"\u6027\u80FD\u4F18\u5148\"},\n {\"id\": \"all_equal\", \"label\": \"\u540C\u7B49\u91CD\u8981\uFF0C\u4E00\u8D77\u505A\"}\n ]\n }\n ]\n}\n```\n\n**\u5B9E\u73B0\u7EC6\u8282\u76F8\u5173\u793A\u4F8B**\uFF08\u4EC5\u5728\u65E0\u6CD5\u4ECE\u4EE3\u7801\u5E93\u5206\u6790\u786E\u5B9A\u65F6\u8BE2\u95EE\uFF09\uFF1A\n\n**\u7528\u6237\u8BF7\u6C42**\uFF1A\"\u91CD\u6784\u7528\u6237\u8BA4\u8BC1\u670D\u52A1\"\n\n**\u5982\u679C\u65E0\u6CD5\u4ECE\u4EE3\u7801\u5E93\u5206\u6790\u786E\u5B9A\uFF0C\u4F7F\u7528\u9009\u9879\u5F0F\u4EA4\u4E92\u63D0\u95EE**\uFF1A\n\n```json\n{\n \"questions\": [\n {\n \"id\": \"change_scope\",\n \"prompt\": \"\u91CD\u6784\u6D89\u53CA\u54EA\u4E9B\u6539\u52A8\uFF1F\",\n \"options\": [\n {\"id\": \"modify_existing\", \"label\": \"\u4FEE\u6539\u73B0\u6709\u8BA4\u8BC1\u670D\u52A1\u7C7B\"},\n {\"id\": \"new_service\", \"label\": \"\u521B\u5EFA\u65B0\u7684\u670D\u52A1\u5C42\"},\n {\"id\": \"both\", \"label\": \"\u4E24\u8005\u90FD\u6D89\u53CA\"},\n {\"id\": \"other\", \"label\": \"\u5176\u4ED6\"}\n ]\n },\n {\n \"id\": \"layer_scope\",\n \"prompt\": \"\u6539\u52A8\u5E94\u8BE5\u5728\u54EA\u4E9B\u5C42\u8FDB\u884C\uFF1F\",\n \"options\": [\n {\"id\": \"controller\", \"label\": \"Controller \u5C42\"},\n {\"id\": \"service\", \"label\": \"Service \u5C42\"},\n {\"id\": \"repository\", \"label\": \"Repository \u5C42\"},\n {\"id\": \"all\", \"label\": \"\u5168\u90E8\u5C42\"}\n ],\n \"allow_multiple\": true\n },\n {\n \"id\": \"refactor_strategy\",\n \"prompt\": \"\u91CD\u6784\u7B56\u7565\u504F\u597D\uFF1F\",\n \"options\": [\n {\"id\": \"incremental\", \"label\": \"\u6E10\u8FDB\u5F0F\u91CD\u6784\uFF08\u9010\u6B65\u66FF\u6362\uFF09\"},\n {\"id\": \"rewrite\", \"label\": \"\u5B8C\u5168\u91CD\u5199\"},\n {\"id\": \"strangler\", \"label\": \"\u7EDE\u6740\u8005\u6A21\u5F0F\uFF08\u65B0\u65E7\u5E76\u884C\u540E\u5207\u6362\uFF09\"},\n {\"id\": \"no_preference\", \"label\": \"\u65E0\u504F\u597D\uFF0C\u7531\u4F60\u63A8\u8350\"}\n ]\n }\n ]\n}\n```\n\n**\u6CE8\u610F**\uFF1A\u5982\u679C\u53EF\u4EE5\u4ECE\u73B0\u6709\u4EE3\u7801\u7ED3\u6784\u3001\u89C4\u8303\u6216\u9879\u76EE\u7EA6\u5B9A\u4E2D\u786E\u5B9A\u8FD9\u4E9B\u4FE1\u606F\uFF0C\u5219\u4E0D\u5E94\u8BE2\u95EE\uFF0C\u76F4\u63A5\u4F7F\u7528\u4ECE\u73B0\u6709\u6765\u6E90\u83B7\u53D6\u7684\u4FE1\u606F\u3002\n\n### \u641C\u7D22\u6307\u5BFC\n- \u679A\u4E3E\u89C4\u8303\uFF1A`zhuanspec spec list --long`\uFF08\u6216\u4F7F\u7528 `--json` \u7528\u4E8E\u811A\u672C\uFF09\n- \u679A\u4E3E\u53D8\u66F4\uFF1A`zhuanspec list`\uFF08\u6216 `zhuanspec change list --json` - \u5DF2\u5F03\u7528\u4F46\u53EF\u7528\uFF09\n- \u663E\u793A\u8BE6\u7EC6\u4FE1\u606F\uFF1A\n - \u89C4\u8303\uFF1A`zhuanspec show <spec-id> --type spec`\uFF08\u4F7F\u7528 `--json` \u8FDB\u884C\u8FC7\u6EE4\uFF09\n - \u53D8\u66F4\uFF1A`zhuanspec show <change-id> --json --deltas-only`\n- \u5168\u6587\u641C\u7D22\uFF08\u4F7F\u7528 ripgrep\uFF09\uFF1A`rg -n \"Requirement:|Scenario:\" zhuanspec/specs`\n\n## \u5FEB\u901F\u5F00\u59CB\n\n### CLI \u547D\u4EE4\n\n```bash\n# \u57FA\u672C\u547D\u4EE4\nzhuanspec list # \u5217\u51FA\u6D3B\u52A8\u53D8\u66F4\nzhuanspec list --specs # \u5217\u51FA\u89C4\u8303\nzhuanspec show [item] # \u663E\u793A\u53D8\u66F4\u6216\u89C4\u8303\nzhuanspec validate [item] # \u9A8C\u8BC1\u53D8\u66F4\u6216\u89C4\u8303\nzhuanspec archive <change-id> [--yes|-y] # \u90E8\u7F72\u540E\u5F52\u6863\uFF08\u6DFB\u52A0 --yes \u7528\u4E8E\u975E\u4EA4\u4E92\u5F0F\u8FD0\u884C\uFF09\n\n# \u9879\u76EE\u7BA1\u7406\nzhuanspec init [path] # \u521D\u59CB\u5316 ZhuanSpec\nzhuanspec update [path] # \u66F4\u65B0\u8BF4\u660E\u6587\u4EF6\n\n# \u4EA4\u4E92\u6A21\u5F0F\nzhuanspec show # \u63D0\u793A\u9009\u62E9\nzhuanspec validate # \u6279\u91CF\u9A8C\u8BC1\u6A21\u5F0F\n\n# \u8C03\u8BD5\nzhuanspec show [change] --json --deltas-only\nzhuanspec validate [change] --strict\n```\n\n### \u547D\u4EE4\u6807\u5FD7\n\n- `--json` - \u673A\u5668\u53EF\u8BFB\u8F93\u51FA\n- `--type change|spec` - \u6D88\u9664\u9879\u76EE\u6B67\u4E49\n- `--strict` - \u5168\u9762\u9A8C\u8BC1\n- `--no-interactive` - \u7981\u7528\u63D0\u793A\n- `--skip-specs` - \u5F52\u6863\u65F6\u4E0D\u66F4\u65B0\u89C4\u8303\n- `--yes`/`-y` - \u8DF3\u8FC7\u786E\u8BA4\u63D0\u793A\uFF08\u975E\u4EA4\u4E92\u5F0F\u5F52\u6863\uFF09\n\n## \u76EE\u5F55\u7ED3\u6784\n\n```\nzhuanspec/\n\u251C\u2500\u2500 project.md # \u9879\u76EE\u7EA6\u5B9A\n\u251C\u2500\u2500 specs/ # \u5F53\u524D\u771F\u5B9E\u72B6\u6001 - \u5DF2\u6784\u5EFA\u7684\u5185\u5BB9\n\u2502 \u2514\u2500\u2500 [capability]/ # \u5355\u4E00\u805A\u7126\u7684\u529F\u80FD\n\u2502 \u251C\u2500\u2500 spec.md # \u8981\u6C42\u548C\u573A\u666F\n\u2502 \u2514\u2500\u2500 design.md # \u6280\u672F\u6A21\u5F0F\n\u251C\u2500\u2500 changes/ # \u63D0\u6848 - \u5E94\u8BE5\u66F4\u6539\u7684\u5185\u5BB9\n\u2502 \u251C\u2500\u2500 [change-name]/\n\u2502 \u2502 \u251C\u2500\u2500 proposal.md # \u539F\u56E0\u3001\u5185\u5BB9\u3001\u5F71\u54CD\n\u2502 \u2502 \u251C\u2500\u2500 tasks.md # \u5B9E\u65BD\u6E05\u5355\n\u2502 \u2502 \u251C\u2500\u2500 design.md # \u6280\u672F\u51B3\u7B56\uFF08\u53EF\u9009\uFF1B\u89C1\u6807\u51C6\uFF09\n\u2502 \u2502 \u2514\u2500\u2500 specs/ # \u589E\u91CF\u53D8\u66F4\n\u2502 \u2502 \u2514\u2500\u2500 [capability]/\n\u2502 \u2502 \u2514\u2500\u2500 spec.md # ADDED/MODIFIED/REMOVED\n\u2502 \u2514\u2500\u2500 archive/ # \u5DF2\u5B8C\u6210\u7684\u53D8\u66F4\n```\n\n## \u521B\u5EFA\u53D8\u66F4\u63D0\u6848\n\n### \u51B3\u7B56\u6811\n\n```\n\u65B0\u8BF7\u6C42\uFF1F\n\u251C\u2500 \u4FEE\u590D\u6062\u590D\u89C4\u8303\u884C\u4E3A\u7684 Bug\uFF1F \u2192 \u76F4\u63A5\u4FEE\u590D\n\u251C\u2500 \u62FC\u5199\u9519\u8BEF/\u683C\u5F0F/\u6CE8\u91CA\uFF1F \u2192 \u76F4\u63A5\u4FEE\u590D\n\u251C\u2500 \u65B0\u529F\u80FD/\u80FD\u529B\uFF1F \u2192 \u521B\u5EFA\u63D0\u6848\n\u251C\u2500 \u7834\u574F\u6027\u66F4\u6539\uFF1F \u2192 \u521B\u5EFA\u63D0\u6848\n\u251C\u2500 \u67B6\u6784\u66F4\u6539\uFF1F \u2192 \u521B\u5EFA\u63D0\u6848\n\u2514\u2500 \u4E0D\u660E\u786E\uFF1F \u2192 \u521B\u5EFA\u63D0\u6848\uFF08\u66F4\u5B89\u5168\uFF09\n```\n\n### \u63D0\u6848\u7ED3\u6784\n\n1. **\u521B\u5EFA\u76EE\u5F55\uFF1A** `changes/[change-id]/`\uFF08kebab-case\uFF0C\u52A8\u8BCD\u5F00\u5934\uFF0C\u552F\u4E00\uFF09\n\n2. **\u7F16\u5199 proposal.md\uFF1A**\n```markdown\n# Change: [\u53D8\u66F4\u7684\u7B80\u8981\u63CF\u8FF0]\n\n## \u53D8\u66F4\u539F\u56E0\n[\u5173\u4E8E\u95EE\u9898/\u673A\u4F1A\u7684 1-2 \u53E5\u8BDD]\n\n## \u53D8\u66F4\u5185\u5BB9\n- [\u53D8\u66F4\u7684\u8981\u70B9\u5217\u8868]\n- [\u7528 **BREAKING** \u6807\u8BB0\u7834\u574F\u6027\u66F4\u6539]\n\n## \u5F71\u54CD\u8303\u56F4\n- Affected specs: [\u5217\u51FA\u529F\u80FD]\n- Affected code: [\u5173\u952E\u6587\u4EF6/\u7CFB\u7EDF]\n```\n\n3. **\u521B\u5EFA\u89C4\u8303\u589E\u91CF\uFF1A** `specs/[capability]/spec.md`\n```markdown\n## ADDED Requirements\n### \u9700\u6C42\uFF1ANew Feature\nThe system SHALL provide...\n\n#### \u573A\u666F\uFF1ASuccess case\n- **\u5F53** user performs action\n- **\u5219** expected result\n\n## MODIFIED Requirements\n### \u9700\u6C42\uFF1AExisting Feature\n[\u5B8C\u6574\u7684\u4FEE\u6539\u540E\u8981\u6C42]\n\n## REMOVED Requirements\n### \u9700\u6C42\uFF1AOld Feature\n**Reason**: [\u79FB\u9664\u539F\u56E0]\n**Migration**: [\u5982\u4F55\u5904\u7406]\n```\n\u5982\u679C\u591A\u4E2A\u529F\u80FD\u53D7\u5230\u5F71\u54CD\uFF0C\u5728 `changes/[change-id]/specs/<capability>/spec.md` \u4E0B\u521B\u5EFA\u591A\u4E2A\u589E\u91CF\u6587\u4EF6\u2014\u2014\u6BCF\u4E2A\u529F\u80FD\u4E00\u4E2A\u3002\n\n4. **\u521B\u5EFA tasks.md\uFF1A**\n\n\u5148\u8FD0\u884C `zhuanspec skills list --json` \u53D1\u73B0\u5F53\u524D\u73AF\u5883\u4E2D\u53EF\u7528\u7684 skill \u53CA\u5176 description\uFF0C\u7136\u540E\u57FA\u4E8E\u8BED\u4E49\u5339\u914D\u5728\u4EFB\u52A1\u4E2D\u6807\u6CE8\u771F\u5B9E skill \u540D\u79F0\uFF1A\n\n```markdown\n## 1. \u5B9E\u73B0\n- [ ] 1.1 \u521B\u5EFA\u6570\u636E\u5E93\u8868\u7ED3\u6784 @skill:java-db-schema-standards\n- [ ] 1.2 \u5B9E\u73B0 RPC \u63A5\u53E3 @skill:java-scf-rpc-usage-skill\n- [ ] 1.3 \u6DFB\u52A0\u524D\u7AEF\u7EC4\u4EF6 @skill:kf-fe-frontend-dev\n- [ ] 1.4 \u7F16\u5199\u6D4B\u8BD5 @skill:generate-mockito-unit-test-skill\n```\n> **@skill \u6807\u7B7E**\uFF1A\u521B\u5EFA tasks.md \u524D\uFF0C\u8FD0\u884C `zhuanspec skills list --json` \u53D1\u73B0\u53EF\u7528 skill \u53CA\u5176 description\u3002\u57FA\u4E8E skill description \u8FDB\u884C\u8BED\u4E49\u5339\u914D\uFF1A\n> - \u4ED4\u7EC6\u9605\u8BFB\u6BCF\u4E2A skill \u7684 description\uFF0C\u7406\u89E3\u5176\u5177\u4F53\u529F\u80FD\u548C\u9002\u7528\u573A\u666F\n> - \u53EA\u6709\u5F53\u4EFB\u52A1\u529F\u80FD\u4E0E skill description \u660E\u786E\u5339\u914D\u65F6\u624D\u6807\u6CE8\n> - \u7B80\u5355\u7684\u4EE3\u7801\u4FEE\u6539\uFF08\u5982\u589E\u5220\u679A\u4E3E\u503C\uFF09\u5E94\u5339\u914D\u901A\u7528\u7F16\u7801\u89C4\u8303 skill\uFF0C\u800C\u975E\u67B6\u6784\u7EA7 skill\n> - \u907F\u514D\u4EC5\u56E0\u6587\u4EF6\u540D\u6216\u8DEF\u5F84\u5173\u952E\u8BCD\u800C\u9519\u8BEF\u5339\u914D\n> - \u4F7F\u7528\u771F\u5B9E skill \u540D\u79F0\u6807\u6CE8\uFF0C\u652F\u6301\u591A\u4E2A skill\uFF08`@skill:name1,name2`\uFF09\n> - Apply \u9636\u6BB5 AI \u6839\u636E\u6807\u7B7E\u76F4\u63A5\u8C03\u7528\u5BF9\u5E94 skill\u3002\u65E0\u53EF\u7528 skill \u65F6\u53EF\u7701\u7565\u3002\n\n\u26A0\uFE0F **\u68C0\u67E5\u70B9 [Skill \u6807\u6CE8]**\uFF1A\n1. \u5FC5\u987B\u5148\u8FD0\u884C `zhuanspec skills list` \u5E76\u5728 Skill \u6620\u5C04\u8868\u4E2D\u8BB0\u5F55\u53D1\u73B0\u7684 skill\n2. \u6BCF\u4E2A\u4EFB\u52A1\u5FC5\u987B\u6807\u6CE8 @skill:\u771F\u5B9Eskill\u540D\u79F0 \u6216 @skill:none\n3. \u5982\u679C\u4F7F\u7528 @skill:none\uFF0C\u5FC5\u987B\u63D0\u4F9B\u7406\u7531\uFF08\u4F8B\u5982\uFF1A\"\u7EAF\u914D\u7F6E\u53D8\u66F4\uFF0C\u65E0\u9700 skill\"\uFF09\n4. @skill \u540D\u79F0\u5FC5\u987B\u4E0E `zhuanspec skills list` \u8FD4\u56DE\u7684\u540D\u79F0\u5B8C\u5168\u4E00\u81F4 \u2014\u2014 \u7981\u6B62\u865A\u6784 skill \u540D\u79F0\n5. tasks.md \u4E2D\u7684 Skill \u6620\u5C04\u8868\u4E0D\u80FD\u4E3A\u7A7A\n6. validate --strict \u4F1A\u9A8C\u8BC1\u6240\u6709 @skill \u540D\u79F0\u662F\u5426\u5B58\u5728\u4E8E\u5DF2\u77E5 skill \u5217\u8868\u4E2D\n\n\u26A0\uFE0F **\u68C0\u67E5\u70B9 [\u4EFB\u52A1\u6392\u5E8F]**\uFF1A\n1. tasks.md \u4E2D\u7684\u4EFB\u52A1\u5FC5\u987B\u6309\u6CE2\u6B21\u7EC4\u7EC7\uFF08### \u6CE2\u6B21 1, ### \u6CE2\u6B21 2 \u7B49\uFF09\n2. \u6CE2\u6B21\u5206\u914D\u5FC5\u987B\u6839\u636E @depends \u4F9D\u8D56\u5173\u7CFB\u8BA1\u7B97\uFF08\u6CE2\u6B21 1 = \u65E0\u4F9D\u8D56\uFF0C\u6CE2\u6B21 N = \u4F9D\u8D56\u6CE2\u6B21 N-1\uFF09\n3. \u4EFB\u52A1\u4E0D\u80FD\u51FA\u73B0\u5728\u5176\u4F9D\u8D56\u7684\u4EFB\u52A1\u4E4B\u524D\n4. \u5FC5\u987B\u5728\u6587\u4EF6\u672B\u5C3E\u6DFB\u52A0 \"## \u4F9D\u8D56\u5206\u6790\" \u7AE0\u8282\u5E76\u6807\u660E\"\u72B6\u6001\uFF1A\u5DF2\u5B8C\u6210\"\n5. validate --strict \u4F1A\u9A8C\u8BC1\u4EFB\u52A1\u6392\u5E8F\u662F\u5426\u4E0E\u8BA1\u7B97\u7684\u6CE2\u6B21\u5339\u914D\n\n5. **\u5728\u9700\u8981\u65F6\u521B\u5EFA design.md\uFF1A**\n\u5982\u679C\u4EE5\u4E0B\u4EFB\u4F55\u60C5\u51B5\u9002\u7528\uFF0C\u5219\u521B\u5EFA `design.md`\uFF1B\u5426\u5219\u7701\u7565\uFF1A\n- \u6A2A\u5207\u53D8\u66F4\uFF08\u591A\u4E2A\u670D\u52A1/\u6A21\u5757\uFF09\u6216\u65B0\u7684\u67B6\u6784\u6A21\u5F0F\n- \u65B0\u7684\u5916\u90E8\u4F9D\u8D56\u6216\u91CD\u8981\u7684\u6570\u636E\u6A21\u578B\u66F4\u6539\n- \u5B89\u5168\u6027\u3001\u6027\u80FD\u6216\u8FC1\u79FB\u590D\u6742\u6027\n- \u5728\u7F16\u7801\u4E4B\u524D\u4ECE\u6280\u672F\u51B3\u7B56\u4E2D\u53D7\u76CA\u7684\u6A21\u7CCA\u6027\n\n\u6700\u5C0F `design.md` \u9AA8\u67B6\uFF1A\n```markdown\n## \u80CC\u666F\n[\u80CC\u666F\u3001\u7EA6\u675F\u3001\u5229\u76CA\u76F8\u5173\u8005]\n\n## \u76EE\u6807 / \u975E\u76EE\u6807\n- Goals: [...]\n- Non-Goals: [...]\n\n## \u51B3\u7B56\n- Decision: [\u5185\u5BB9\u548C\u539F\u56E0]\n- Alternatives considered: [\u9009\u9879 + \u7406\u7531]\n\n## \u98CE\u9669 / \u6743\u8861\n- [\u98CE\u9669] \u2192 \u7F13\u89E3\u63AA\u65BD\n\n## \u8FC1\u79FB\u8BA1\u5212\n[\u6B65\u9AA4\u3001\u56DE\u6EDA]\n\n## \u5F85\u89E3\u51B3\u95EE\u9898\n- [...]\n```\n\n## \u89C4\u8303\u6587\u4EF6\u683C\u5F0F\n\n### \u5173\u952E\uFF1A\u573A\u666F\u683C\u5F0F\n\n**\u6B63\u786E**\uFF08\u4F7F\u7528 #### \u6807\u9898\uFF09\uFF1A\n```markdown\n#### \u573A\u666F\uFF1A\u7528\u6237\u767B\u5F55\u6210\u529F\n- **\u5F53** \u63D0\u4F9B\u4E86\u6709\u6548\u51ED\u636E\n- **\u5219** \u8FD4\u56DE JWT token\n```\n\n**\u9519\u8BEF**\uFF08\u4E0D\u8981\u4F7F\u7528\u9879\u76EE\u7B26\u53F7\u6216\u7C97\u4F53\uFF09\uFF1A\n```markdown\n- **\u573A\u666F\uFF1A\u7528\u6237\u767B\u5F55** \u274C\n**\u573A\u666F**\uFF1A\u7528\u6237\u767B\u5F55 \u274C\n### \u573A\u666F\uFF1A\u7528\u6237\u767B\u5F55 \u274C\n```\n\n\u6BCF\u4E2A\u8981\u6C42\u5FC5\u987B\u81F3\u5C11\u6709\u4E00\u4E2A\u573A\u666F\u3002\n\n### \u8981\u6C42\u63AA\u8F9E\n- \u5BF9\u89C4\u8303\u6027\u8981\u6C42\u4F7F\u7528 SHALL/MUST\uFF08\u9664\u975E\u6709\u610F\u975E\u89C4\u8303\u6027\uFF0C\u5426\u5219\u907F\u514D\u4F7F\u7528 should/may\uFF09\n\n### \u589E\u91CF\u64CD\u4F5C\n\n- `## ADDED Requirements` - \u65B0\u529F\u80FD\n- `## MODIFIED Requirements` - \u66F4\u6539\u7684\u884C\u4E3A\n- `## REMOVED Requirements` - \u5DF2\u5F03\u7528\u7684\u529F\u80FD\n- `## RENAMED Requirements` - \u540D\u79F0\u66F4\u6539\n\n\u6807\u9898\u4F7F\u7528 `trim(header)` \u5339\u914D - \u5FFD\u7565\u7A7A\u767D\u3002\n\n#### \u4F55\u65F6\u4F7F\u7528 ADDED vs MODIFIED\n- ADDED\uFF1A\u5F15\u5165\u4E00\u4E2A\u65B0\u7684\u529F\u80FD\u6216\u5B50\u529F\u80FD\uFF0C\u53EF\u4EE5\u72EC\u7ACB\u4F5C\u4E3A\u8981\u6C42\u3002\u5F53\u66F4\u6539\u662F\u6B63\u4EA4\u7684\uFF08\u4F8B\u5982\uFF0C\u6DFB\u52A0\"\u659C\u6760\u547D\u4EE4\u914D\u7F6E\"\uFF09\u800C\u4E0D\u662F\u6539\u53D8\u73B0\u6709\u8981\u6C42\u7684\u8BED\u4E49\u65F6\uFF0C\u4F18\u5148\u4F7F\u7528 ADDED\u3002\n- MODIFIED\uFF1A\u66F4\u6539\u73B0\u6709\u8981\u6C42\u7684\u884C\u4E3A\u3001\u8303\u56F4\u6216\u9A8C\u6536\u6807\u51C6\u3002\u59CB\u7EC8\u7C98\u8D34\u5B8C\u6574\u7684\u3001\u66F4\u65B0\u7684\u8981\u6C42\u5185\u5BB9\uFF08\u6807\u9898 + \u6240\u6709\u573A\u666F\uFF09\u3002\u5F52\u6863\u5668\u5C06\u7528\u60A8\u5728\u6B64\u5904\u63D0\u4F9B\u7684\u5185\u5BB9\u66FF\u6362\u6574\u4E2A\u8981\u6C42\uFF1B\u90E8\u5206\u589E\u91CF\u5C06\u4E22\u5931\u5148\u524D\u7684\u8BE6\u7EC6\u4FE1\u606F\u3002\n- RENAMED\uFF1A\u4EC5\u5728\u540D\u79F0\u66F4\u6539\u65F6\u4F7F\u7528\u3002\u5982\u679C\u60A8\u8FD8\u66F4\u6539\u884C\u4E3A\uFF0C\u8BF7\u4F7F\u7528 RENAMED\uFF08\u540D\u79F0\uFF09\u52A0\u4E0A MODIFIED\uFF08\u5185\u5BB9\uFF09\uFF0C\u5F15\u7528\u65B0\u540D\u79F0\u3002\n\n\u5E38\u89C1\u9677\u9631\uFF1A\u4F7F\u7528 MODIFIED \u6DFB\u52A0\u65B0\u5173\u6CE8\u70B9\u800C\u4E0D\u5305\u542B\u5148\u524D\u7684\u6587\u672C\u3002\u8FD9\u4F1A\u5728\u5F52\u6863\u65F6\u5BFC\u81F4\u8BE6\u7EC6\u4FE1\u606F\u4E22\u5931\u3002\u5982\u679C\u60A8\u6CA1\u6709\u660E\u786E\u66F4\u6539\u73B0\u6709\u8981\u6C42\uFF0C\u8BF7\u5728 ADDED \u4E0B\u6DFB\u52A0\u65B0\u8981\u6C42\u3002\n\n\u6B63\u786E\u7F16\u5199 MODIFIED \u8981\u6C42\uFF1A\n1) \u5728 `zhuanspec/specs/<capability>/spec.md` \u4E2D\u627E\u5230\u73B0\u6709\u8981\u6C42\u3002\n2) \u590D\u5236\u6574\u4E2A\u8981\u6C42\u5757\uFF08\u4ECE `### Requirement: ...` \u5230\u5176\u573A\u666F\uFF09\u3002\n3) \u5C06\u5176\u7C98\u8D34\u5230 `## MODIFIED Requirements` \u4E0B\u5E76\u7F16\u8F91\u4EE5\u53CD\u6620\u65B0\u884C\u4E3A\u3002\n4) \u786E\u4FDD\u6807\u9898\u6587\u672C\u5B8C\u5168\u5339\u914D\uFF08\u5FFD\u7565\u7A7A\u767D\uFF09\u5E76\u81F3\u5C11\u4FDD\u7559\u4E00\u4E2A `#### Scenario:`\u3002\n\nRENAMED \u793A\u4F8B\uFF1A\n```markdown\n## RENAMED Requirements\n- FROM: `### \u9700\u6C42\uFF1ALogin`\n- TO: `### \u9700\u6C42\uFF1AUser Authentication`\n```\n\n## \u6545\u969C\u6392\u9664\n\n### \u5E38\u89C1\u9519\u8BEF\n\n**\"\u53D8\u66F4\u5FC5\u987B\u81F3\u5C11\u6709\u4E00\u4E2A\u589E\u91CF\"**\n- \u68C0\u67E5 `changes/[name]/specs/` \u662F\u5426\u5B58\u5728 .md \u6587\u4EF6\n- \u9A8C\u8BC1\u6587\u4EF6\u5177\u6709\u64CD\u4F5C\u524D\u7F00\uFF08## ADDED Requirements\uFF09\n\n**\"\u8981\u6C42\u5FC5\u987B\u81F3\u5C11\u6709\u4E00\u4E2A\u573A\u666F\"**\n- \u68C0\u67E5\u573A\u666F\u662F\u5426\u4F7F\u7528 `#### Scenario:` \u683C\u5F0F\uFF084 \u4E2A\u4E95\u53F7\uFF09\n- \u4E0D\u8981\u5BF9\u573A\u666F\u6807\u9898\u4F7F\u7528\u9879\u76EE\u7B26\u53F7\u6216\u7C97\u4F53\n\n**\u9759\u9ED8\u573A\u666F\u89E3\u6790\u5931\u8D25**\n- \u9700\u8981\u7CBE\u786E\u683C\u5F0F\uFF1A`#### Scenario: Name`\n- \u4F7F\u7528\u4EE5\u4E0B\u547D\u4EE4\u8C03\u8BD5\uFF1A`zhuanspec show [change] --json --deltas-only`\n\n### \u9A8C\u8BC1\u63D0\u793A\n\n```bash\n# \u59CB\u7EC8\u4F7F\u7528\u4E25\u683C\u6A21\u5F0F\u8FDB\u884C\u5168\u9762\u68C0\u67E5\nzhuanspec validate [change] --strict\n\n# \u8C03\u8BD5\u589E\u91CF\u89E3\u6790\nzhuanspec show [change] --json | jq '.deltas'\n\n# \u68C0\u67E5\u7279\u5B9A\u8981\u6C42\nzhuanspec show [spec] --json -r 1\n```\n\n## \u7406\u60F3\u8DEF\u5F84\u811A\u672C\n\n```bash\n# 1) \u63A2\u7D22\u5F53\u524D\u72B6\u6001\nzhuanspec spec list --long\nzhuanspec list\n# \u53EF\u9009\u5168\u6587\u641C\u7D22\uFF1A\n# rg -n \"Requirement:|Scenario:\" zhuanspec/specs\n# rg -n \"^#|Requirement:\" zhuanspec/changes\n\n# 2) \u9009\u62E9\u53D8\u66F4 ID \u5E76\u642D\u5EFA\nCHANGE=add-two-factor-auth\nmkdir -p zhuanspec/changes/$CHANGE/{specs/auth}\nprintf \"## \u53D8\u66F4\u539F\u56E0\\n...\\n\\n## \u53D8\u66F4\u5185\u5BB9\\n- ...\\n\\n## \u5F71\u54CD\u8303\u56F4\\n- ...\\n\" > zhuanspec/changes/\\$CHANGE/proposal.md\nprintf \"## 1. \u5B9E\u73B0\n- [ ] 1.1 ...\n\" > zhuanspec/changes/$CHANGE/tasks.md\n\n# 3) \u6DFB\u52A0\u589E\u91CF\uFF08\u793A\u4F8B\uFF09\ncat > zhuanspec/changes/$CHANGE/specs/auth/spec.md << 'EOF'\n## ADDED Requirements\n### \u9700\u6C42\uFF1A\u53CC\u56E0\u7D20\u8BA4\u8BC1\n\u7528\u6237 MUST \u5728\u767B\u5F55\u65F6\u63D0\u4F9B\u7B2C\u4E8C\u4E2A\u8BA4\u8BC1\u56E0\u7D20\u3002\n\n#### \u573A\u666F\uFF1A\u9700\u8981 OTP\n- **\u5F53** \u63D0\u4F9B\u4E86\u6709\u6548\u51ED\u636E\n- **\u5219** \u9700\u8981 OTP \u6311\u6218\nEOF\n\n# 4) \u9A8C\u8BC1\nzhuanspec validate $CHANGE --strict\n```\n\n## \u591A\u529F\u80FD\u793A\u4F8B\n\n```\nzhuanspec/changes/add-2fa-notify/\n\u251C\u2500\u2500 proposal.md\n\u251C\u2500\u2500 tasks.md\n\u2514\u2500\u2500 specs/\n \u251C\u2500\u2500 auth/\n \u2502 \u2514\u2500\u2500 spec.md # ADDED: \u53CC\u56E0\u7D20\u8BA4\u8BC1\n \u2514\u2500\u2500 notifications/\n \u2514\u2500\u2500 spec.md # ADDED: OTP \u90AE\u4EF6\u901A\u77E5\n```\n\nauth/spec.md\n```markdown\n## ADDED Requirements\n### \u9700\u6C42\uFF1A\u53CC\u56E0\u7D20\u8BA4\u8BC1\n...\n```\n\nnotifications/spec.md\n```markdown\n## ADDED Requirements\n### \u9700\u6C42\uFF1AOTP \u90AE\u4EF6\u901A\u77E5\n...\n```\n\n## \u6700\u4F73\u5B9E\u8DF5\n\n### \u7B80\u5355\u4F18\u5148\n- \u9ED8\u8BA4\u65B0\u589E\u4EE3\u7801 <100 \u884C\n- \u5355\u6587\u4EF6\u5B9E\u73B0\uFF0C\u76F4\u5230\u8BC1\u660E\u4E0D\u8DB3\n- \u907F\u514D\u6CA1\u6709\u660E\u786E\u7406\u7531\u7684\u6846\u67B6\n- \u9009\u62E9\u65E0\u804A\u4F46\u7ECF\u8FC7\u9A8C\u8BC1\u7684\u6A21\u5F0F\n\n### \u590D\u6742\u6027\u89E6\u53D1\u6761\u4EF6\n\u4EC5\u5728\u4EE5\u4E0B\u60C5\u51B5\u4E0B\u6DFB\u52A0\u590D\u6742\u6027\uFF1A\n- \u6027\u80FD\u6570\u636E\u8868\u660E\u5F53\u524D\u89E3\u51B3\u65B9\u6848\u592A\u6162\n- \u5177\u4F53\u7684\u89C4\u6A21\u8981\u6C42\uFF08>1000 \u7528\u6237\uFF0C>100MB \u6570\u636E\uFF09\n- \u591A\u4E2A\u7ECF\u8FC7\u9A8C\u8BC1\u7684\u7528\u4F8B\u9700\u8981\u62BD\u8C61\n\n### \u6E05\u6670\u7684\u5F15\u7528\n- \u4F7F\u7528 `file.ts:42` \u683C\u5F0F\u8868\u793A\u4EE3\u7801\u4F4D\u7F6E\n- \u5C06\u89C4\u8303\u5F15\u7528\u4E3A `specs/auth/spec.md`\n- \u94FE\u63A5\u76F8\u5173\u53D8\u66F4\u548C PR\n\n### \u529F\u80FD\u547D\u540D\n- \u4F7F\u7528\u52A8\u8BCD-\u540D\u8BCD\uFF1A`user-auth`\u3001`payment-capture`\n- \u6BCF\u4E2A\u529F\u80FD\u5355\u4E00\u76EE\u7684\n- 10 \u5206\u949F\u53EF\u7406\u89E3\u6027\u89C4\u5219\n- \u5982\u679C\u63CF\u8FF0\u9700\u8981\"AND\"\uFF0C\u5219\u62C6\u5206\n\n### \u53D8\u66F4 ID \u547D\u540D\n- \u4F7F\u7528 kebab-case\uFF0C\u7B80\u77ED\u4E14\u63CF\u8FF0\u6027\uFF1A`add-two-factor-auth`\n- \u4F18\u5148\u4F7F\u7528\u52A8\u8BCD\u5F00\u5934\u7684\u524D\u7F00\uFF1A`add-`\u3001`update-`\u3001`remove-`\u3001`refactor-`\n- \u786E\u4FDD\u552F\u4E00\u6027\uFF1B\u5982\u679C\u5DF2\u4F7F\u7528\uFF0C\u8FFD\u52A0 `-2`\u3001`-3` \u7B49\n\n## \u5DE5\u5177\u9009\u62E9\u6307\u5357\n\n| \u4EFB\u52A1 | \u5DE5\u5177 | \u539F\u56E0 |\n|------|------|-----|\n| \u6309\u6A21\u5F0F\u67E5\u627E\u6587\u4EF6 | Glob | \u5FEB\u901F\u6A21\u5F0F\u5339\u914D |\n| \u641C\u7D22\u4EE3\u7801\u5185\u5BB9 | Grep | \u4F18\u5316\u7684\u6B63\u5219\u8868\u8FBE\u5F0F\u641C\u7D22 |\n| \u8BFB\u53D6\u7279\u5B9A\u6587\u4EF6 | Read | \u76F4\u63A5\u6587\u4EF6\u8BBF\u95EE |\n| \u63A2\u7D22\u672A\u77E5\u8303\u56F4 | Task | \u591A\u6B65\u9AA4\u8C03\u67E5 |\n\n## \u9519\u8BEF\u6062\u590D\n\n### \u53D8\u66F4\u51B2\u7A81\n1. \u8FD0\u884C `zhuanspec list` \u67E5\u770B\u6D3B\u52A8\u53D8\u66F4\n2. \u68C0\u67E5\u91CD\u53E0\u7684\u89C4\u8303\n3. \u4E0E\u53D8\u66F4\u6240\u6709\u8005\u534F\u8C03\n4. \u8003\u8651\u5408\u5E76\u63D0\u6848\n\n### \u9A8C\u8BC1\u5931\u8D25\n1. \u4F7F\u7528 `--strict` \u6807\u5FD7\u8FD0\u884C\n2. \u68C0\u67E5 JSON \u8F93\u51FA\u4EE5\u83B7\u53D6\u8BE6\u7EC6\u4FE1\u606F\n3. \u9A8C\u8BC1\u89C4\u8303\u6587\u4EF6\u683C\u5F0F\n4. \u786E\u4FDD\u573A\u666F\u683C\u5F0F\u6B63\u786E\n\n### \u7F3A\u5C11\u4E0A\u4E0B\u6587\n1. \u9996\u5148\u9605\u8BFB project.md\n2. \u68C0\u67E5\u76F8\u5173\u89C4\u8303\n3. \u5BA1\u67E5\u6700\u8FD1\u7684\u5F52\u6863\n4. \u8BF7\u6C42\u6F84\u6E05\n\n## \u5FEB\u901F\u53C2\u8003\n\n### \u9636\u6BB5\u6307\u793A\u5668\n- `changes/` - \u5DF2\u63D0\u8BAE\uFF0C\u5C1A\u672A\u6784\u5EFA\n- `specs/` - \u5DF2\u6784\u5EFA\u5E76\u90E8\u7F72\n- `archive/` - \u5DF2\u5B8C\u6210\u7684\u53D8\u66F4\n\n### \u6587\u4EF6\u7528\u9014\n- `proposal.md` - \u539F\u56E0\u548C\u5185\u5BB9\n- `tasks.md` - \u5B9E\u65BD\u6B65\u9AA4\n- `design.md` - \u6280\u672F\u51B3\u7B56\n- `spec.md` - \u8981\u6C42\u548C\u884C\u4E3A\n\n### CLI \u8981\u70B9\n```bash\nzhuanspec list # \u6B63\u5728\u8FDB\u884C\u4EC0\u4E48\uFF1F\nzhuanspec show [item] # \u67E5\u770B\u8BE6\u7EC6\u4FE1\u606F\nzhuanspec validate --strict # \u662F\u5426\u6B63\u786E\uFF1F\nzhuanspec archive <change-id> [--yes|-y] # \u6807\u8BB0\u5B8C\u6210\uFF08\u6DFB\u52A0 --yes \u7528\u4E8E\u81EA\u52A8\u5316\uFF09\n```\n\n\u8BB0\u4F4F\uFF1A\u89C4\u8303\u662F\u771F\u76F8\u3002\u53D8\u66F4\u662F\u63D0\u6848\u3002\u4FDD\u6301\u5B83\u4EEC\u540C\u6B65\u3002\n\n## \u4EFB\u52A1\u6267\u884C\u7F16\u6392\n\n\u5F53 apply \u6307\u4EE4\u4E2D\u5305\u542B `<execution_plan>`/task.md\u4E2D\u5305\u542B `@depends` \u65F6\uFF0C\u5FC5\u987B\u6309\u4EE5\u4E0B\u7B56\u7565\u6267\u884C\u4EFB\u52A1\uFF0C\u800C\u975E\u987A\u5E8F\u9010\u4E00\u6267\u884C\u3002\n\n### \u8C03\u5EA6\u89C4\u5219\n\n1. **\u6309 wave \u7F16\u53F7\u4ECE\u5C0F\u5230\u5927**\u4F9D\u6B21\u6267\u884C\uFF0Cwave \u4E4B\u95F4\u4E25\u683C\u4E32\u884C\n2. **\u540C\u4E00 wave \u5185\u7684\u591A\u4E2A task**\uFF1A\u4E3A\u6BCF\u4E2A task \u542F\u52A8\u72EC\u7ACB\u7684 subagent\uFF08Coding \u7C7B\u578B\uFF09\uFF0C\u6240\u6709 subagent \u5E76\u884C\u6267\u884C\n3. **\u7B49\u5F85\u672C wave \u6240\u6709 subagent \u5B8C\u6210\u540E**\uFF0C\u624D\u542F\u52A8\u4E0B\u4E00 wave\n4. \u540C\u4E00 wave \u5185\u4EC5\u6709\u4E00\u4E2A task \u65F6\uFF0C\u542F\u52A8\u5355\u4E2A subagent \u6267\u884C\n\n### Subagent \u4E0A\u4E0B\u6587\u9694\u79BB\n\n\u6BCF\u4E2A subagent \u7684 prompt \u4E2D**\u4EC5\u5305\u542B**\uFF1A\n- \u5F53\u524D task \u7684\u63CF\u8FF0\u548C\u9A8C\u6536\u6807\u51C6\n- \u5F53\u524D task \u5173\u8054\u7684 `@skill` \u5185\u5BB9\uFF08\u901A\u8FC7 skill \u540D\u79F0\u89E6\u53D1\u52A0\u8F7D\uFF09\n- \u76F8\u5173\u7684 spec \u6587\u4EF6\u8DEF\u5F84\u548C\u5185\u5BB9\uFF08\u4EC5\u9650\u8BE5 task \u6D89\u53CA\u7684\u90E8\u5206\uFF09\n- \u524D\u5E8F wave \u7684\u5B8C\u6210\u6458\u8981\uFF08\u800C\u975E\u5B8C\u6574\u8F93\u51FA\uFF09\n\n**\u7981\u6B62**\u5411 subagent \u6CE8\u5165\uFF1A\n- \u5176\u4ED6 wave \u7684 task \u8BE6\u60C5\n- \u4E0D\u76F8\u5173\u7684 skill \u5185\u5BB9\n- \u5176\u4ED6 subagent \u7684\u5B8C\u6574\u8F93\u51FA\n\n### \u5B8C\u6210\u540C\u6B65\n\n- \u6BCF\u4E2A subagent \u5B8C\u6210\u540E\uFF0C\u63D0\u53D6\u7B80\u77ED\u7684**\u5B8C\u6210\u6458\u8981**\uFF08\u4FEE\u6539\u4E86\u54EA\u4E9B\u6587\u4EF6\u3001\u5173\u952E\u53D8\u66F4\u70B9\uFF09\n- \u5C06\u6458\u8981\u4F20\u9012\u7ED9\u540E\u7EED wave \u7684 subagent \u4F5C\u4E3A\u4E0A\u4E0B\u6587\n- \u5728 `tasks.md` \u4E2D\u5C06\u5BF9\u5E94\u4EFB\u52A1\u6807\u8BB0\u4E3A `[x]`\n\n### \u964D\u7EA7\u7B56\u7565\n\n\u5F53 AI \u5E73\u53F0\u4E0D\u652F\u6301 subagent \u65F6\uFF0C\u6309\u4EE5\u4E0B\u964D\u7EA7\u7B56\u7565\u6267\u884C\uFF1A\n1. \u4ECD\u6309 wave \u987A\u5E8F\u6267\u884C\u4EFB\u52A1\n2. \u6BCF\u4E2A task \u6267\u884C\u524D\uFF0C\u6E05\u7406\u4E0D\u76F8\u5173\u7684 skill \u4E0A\u4E0B\u6587\n3. \u6BCF\u4E2A task \u6267\u884C\u540E\uFF0C\u4EC5\u4FDD\u7559\u5B8C\u6210\u6458\u8981\uFF0C\u907F\u514D\u4E0A\u4E0B\u6587\u7D2F\u79EF\u81A8\u80C0\n";
1
+ export declare const agentsTemplate = "# ZhuanSpec \u4F7F\u7528\u8BF4\u660E\n\n\u9762\u5411\u4F7F\u7528 ZhuanSpec \u8FDB\u884C\u89C4\u8303\u9A71\u52A8\u5F00\u53D1\u7684 AI \u7F16\u7A0B\u52A9\u624B\u7684\u8BF4\u660E\u6587\u6863\u3002\n\n## \u5FEB\u901F\u68C0\u67E5\u6E05\u5355\n\n- \u641C\u7D22\u73B0\u6709\u5DE5\u4F5C\uFF1A`zhuanspec spec list --long`\u3001`zhuanspec list`\uFF08\u4EC5\u4F7F\u7528 `rg` \u8FDB\u884C\u5168\u6587\u641C\u7D22\uFF09\n- \u786E\u5B9A\u8303\u56F4\uFF1A\u65B0\u529F\u80FD vs \u4FEE\u6539\u73B0\u6709\u529F\u80FD\n- \u9009\u62E9\u552F\u4E00\u7684 `change-id`\uFF1Akebab-case \u683C\u5F0F\uFF0C\u52A8\u8BCD\u5F00\u5934\uFF08`add-`\u3001`update-`\u3001`remove-`\u3001`refactor-`\uFF09\n- \u642D\u5EFA\u7ED3\u6784\uFF1A`proposal.md`\u3001`tasks.md`\u3001`design.md`\uFF08\u4EC5\u5728\u9700\u8981\u65F6\uFF09\uFF0C\u4EE5\u53CA\u6BCF\u4E2A\u53D7\u5F71\u54CD\u529F\u80FD\u7684\u89C4\u8303\u589E\u91CF\n- \u7F16\u5199\u589E\u91CF\uFF1A\u4F7F\u7528 `## ADDED|MODIFIED|REMOVED|RENAMED Requirements`\uFF1B\u6BCF\u4E2A\u8981\u6C42\u81F3\u5C11\u5305\u542B\u4E00\u4E2A `#### Scenario:`\n- \u9A8C\u8BC1\uFF1A\u8FD0\u884C `zhuanspec validate [change-id] --strict` \u5E76\u4FEE\u590D\u95EE\u9898\n- \u8BF7\u6C42\u6279\u51C6\uFF1A\u5728\u63D0\u6848\u83B7\u5F97\u6279\u51C6\u4E4B\u524D\u4E0D\u8981\u5F00\u59CB\u5B9E\u65BD\n\n## \u4E09\u9636\u6BB5\u5DE5\u4F5C\u6D41\n\n### \u9636\u6BB5 1\uFF1A\u521B\u5EFA\u53D8\u66F4\n\u5728\u4EE5\u4E0B\u60C5\u51B5\u4E0B\u521B\u5EFA\u63D0\u6848\uFF1A\n- \u6DFB\u52A0\u529F\u80FD\u6216\u7279\u6027\n- \u8FDB\u884C\u7834\u574F\u6027\u66F4\u6539\uFF08API\u3001schema\uFF09\n- \u66F4\u6539\u67B6\u6784\u6216\u6A21\u5F0F\n- \u4F18\u5316\u6027\u80FD\uFF08\u6539\u53D8\u884C\u4E3A\uFF09\n- \u66F4\u65B0\u5B89\u5168\u6A21\u5F0F\n\n\u89E6\u53D1\u8BCD\u793A\u4F8B\uFF1A\n- \"\u5E2E\u6211\u521B\u5EFA\u4E00\u4E2A\u53D8\u66F4\u63D0\u6848\"\n- \"\u5E2E\u6211\u89C4\u5212\u4E00\u4E2A\u53D8\u66F4\"\n- \"\u5E2E\u6211\u521B\u5EFA\u4E00\u4E2A\u63D0\u6848\"\n- \"\u6211\u60F3\u521B\u5EFA\u4E00\u4E2A\u89C4\u8303\u63D0\u6848\"\n- \"\u6211\u60F3\u521B\u5EFA\u4E00\u4E2A\u89C4\u8303\"\n\n\u5BBD\u677E\u5339\u914D\u6307\u5BFC\uFF1A\n- \u5305\u542B\u4EE5\u4E0B\u4E4B\u4E00\uFF1A`proposal`\u3001`change`\u3001`spec`\n- \u4E0E\u4EE5\u4E0B\u4E4B\u4E00\u7EC4\u5408\uFF1A`create`\u3001`plan`\u3001`make`\u3001`start`\u3001`help`\n\n\u8DF3\u8FC7\u63D0\u6848\u7684\u60C5\u51B5\uFF1A\n- Bug \u4FEE\u590D\uFF08\u6062\u590D\u9884\u671F\u884C\u4E3A\uFF09\n- \u62FC\u5199\u9519\u8BEF\u3001\u683C\u5F0F\u3001\u6CE8\u91CA\n- \u4F9D\u8D56\u66F4\u65B0\uFF08\u975E\u7834\u574F\u6027\uFF09\n- \u914D\u7F6E\u66F4\u6539\n- \u73B0\u6709\u884C\u4E3A\u7684\u6D4B\u8BD5\n\n**\u5DE5\u4F5C\u6D41**\n0. \u5BA1\u67E5 `zhuanspec/project.md`\u3001`zhuanspec list` \u548C `zhuanspec list --specs` \u4EE5\u4E86\u89E3\u5F53\u524D\u4E0A\u4E0B\u6587\u3002\n1. **\u5F3A\u5236\u6F84\u6E05\u68C0\u67E5\uFF08\u5FC5\u987B\u9996\u5148\u6267\u884C\uFF09**\uFF1A\u5206\u6790\u7528\u6237\u8BF7\u6C42\uFF0C\u8BC6\u522B\u6240\u6709\u4E0D\u786E\u5B9A\u6216\u6A21\u7CCA\u7684\u65B9\u9762\uFF08\u8303\u56F4\u3001\u6280\u672F\u9009\u62E9\u3001\u5B9E\u73B0\u7EC6\u8282\u3001\u6570\u636E\u83B7\u53D6\u6765\u6E90\u3001\u670D\u52A1\u5206\u5C42\u3001\u4F9D\u8D56\u5173\u7CFB\u3001\u4F18\u5148\u7EA7\u3001\u9A8C\u6536\u6807\u51C6\u7B49......\uFF09\u3002\u5982\u679C\u53D1\u73B0\u4EFB\u4F55\u6A21\u7CCA\u4E4B\u5904\uFF0C\u5FC5\u987B\u505C\u6B62\u5E76\u4F7F\u7528**\u9009\u9879\u5F0F\u4EA4\u4E92**\uFF08\u5982 `AskQuestion` \u5DE5\u5177\uFF09\u63D0\u95EE\uFF0C\u83B7\u5F97\u660E\u786E\u7B54\u590D\u540E\u624D\u80FD\u7EE7\u7EED\u3002\u4E25\u7981\u5728\u4E0D\u786E\u5B9A\u7684\u60C5\u51B5\u4E0B\u81EA\u884C\u63A8\u6D4B\u6216\u521B\u5EFA\u63D0\u6848\uFF0C\u4E25\u7981\u8981\u6C42\u7528\u6237\u624B\u52A8\u8F93\u5165\u5927\u6BB5\u6587\u5B57\u3002\n\n \u26A0\uFE0F **\u68C0\u67E5\u70B9 [\u5F3A\u5236\u6F84\u6E05]**\uFF1A\n \u5FC5\u987B\u5728 tasks.md \u4E2D\u8BB0\u5F55\u6F84\u6E05\u7ED3\u679C\uFF0C\u6DFB\u52A0 \"## \u6F84\u6E05\u65E5\u5FD7\" \u7AE0\u8282\uFF1A\n - \u5982\u679C\u8FDB\u884C\u4E86\u63D0\u95EE\uFF1A\u8BB0\u5F55\u6BCF\u4E2A\u95EE\u9898\u53CA\u7528\u6237\u7684\u56DE\u7B54\n - \u5982\u679C\u65E0\u9700\u6F84\u6E05\uFF1A\u5199\u660E\"\u72B6\u6001\uFF1A\u5DF2\u5B8C\u6210 - \u65E0\u9700\u6F84\u6E05\"\u5E76\u7B80\u8981\u8BF4\u660E\u7406\u7531\n - \u6B64\u7AE0\u8282\u4E0D\u80FD\u4E3A\u7A7A\u6216\u4EC5\u5305\u542B HTML \u6CE8\u91CA\n - \u672A\u5B8C\u6210\u6B64\u68C0\u67E5\u70B9\u524D\u7981\u6B62\u7EE7\u7EED\u7F16\u5199\u63D0\u6848\n\n2. \u9009\u62E9\u4E00\u4E2A\u552F\u4E00\u7684\u52A8\u8BCD\u5F00\u5934\u7684 `change-id`\uFF0C\u5E76\u5728 `zhuanspec/changes/<id>/` \u4E0B\u642D\u5EFA `proposal.md`\u3001`tasks.md`\u3001\u53EF\u9009\u7684 `design.md` \u548C\u89C4\u8303\u589E\u91CF\u3002\n3. \u4F7F\u7528 `## ADDED|MODIFIED|REMOVED Requirements` \u8D77\u8349\u89C4\u8303\u589E\u91CF\uFF0C\u6BCF\u4E2A\u8981\u6C42\u81F3\u5C11\u5305\u542B\u4E00\u4E2A `#### Scenario:`\u3002\n4. \u8FD0\u884C `zhuanspec validate <id> --strict` \u5E76\u5728\u5206\u4EAB\u63D0\u6848\u4E4B\u524D\u89E3\u51B3\u6240\u6709\u95EE\u9898\u3002\n\n### \u9636\u6BB5 2\uFF1A\u5B9E\u65BD\u53D8\u66F4\n\n\u5C06\u8FD9\u4E9B\u6B65\u9AA4\u4F5C\u4E3A\u5F85\u529E\u4E8B\u9879\u8DDF\u8E2A\uFF0C\u9010\u4E00\u5B8C\u6210\u3002\n\n1. **\u9605\u8BFB proposal.md** - \u4E86\u89E3\u8981\u6784\u5EFA\u7684\u5185\u5BB9\n2. **\u9605\u8BFB design.md**\uFF08\u5982\u679C\u5B58\u5728\uFF09 - \u5BA1\u67E5\u6280\u672F\u51B3\u7B56\n3. **\u9605\u8BFB tasks.md** - \u83B7\u53D6\u5B9E\u65BD\u6E05\u5355\n4. **\u5224\u65AD\u6267\u884C\u6A21\u5F0F** - \u6839\u636E tasks.md \u5185\u5BB9\u9009\u62E9\u6267\u884C\u7B56\u7565\uFF1A\n - **\u5982\u679C tasks.md \u5305\u542B `@depends` \u4F9D\u8D56\u58F0\u660E**\uFF08\u5B58\u5728 `<execution_plan>`\uFF09\uFF1A\n \u2192 \u6309\u3010\u4EFB\u52A1\u6267\u884C\u7F16\u6392\u3011\u89C4\u5219\u6267\u884C\uFF08\u89C1\u4E0B\u65B9\"\u4EFB\u52A1\u6267\u884C\u7F16\u6392\"\u7AE0\u8282\uFF09\n - **\u5982\u679C tasks.md \u65E0\u4F9D\u8D56\u58F0\u660E**\uFF1A\n \u2192 \u6309\u987A\u5E8F\u6267\u884C\uFF08\u89C1\u4E0B\u65B9\u6B65\u9AA4 5-7\uFF09\n5. **\u6309\u987A\u5E8F\u5B9E\u65BD\u4EFB\u52A1**\uFF08\u65E0\u4F9D\u8D56\u58F0\u660E\u65F6\uFF09- \u6309\u987A\u5E8F\u5B8C\u6210\u3002\u5982\u679C\u4EFB\u52A1\u6807\u6CE8\u4E86 `@skill:<skill-name>`\uFF0C\u76F4\u63A5\u8C03\u7528\u5BF9\u5E94 skill\n6. **\u786E\u8BA4\u5B8C\u6210** - \u5728\u66F4\u65B0\u72B6\u6001\u4E4B\u524D\u786E\u4FDD `tasks.md` \u4E2D\u7684\u6BCF\u4E2A\u9879\u76EE\u90FD\u5DF2\u5B8C\u6210\n7. **\u66F4\u65B0\u6E05\u5355** - \u6240\u6709\u5DE5\u4F5C\u5B8C\u6210\u540E\uFF0C\u5C06\u6BCF\u4E2A\u4EFB\u52A1\u8BBE\u7F6E\u4E3A `- [x]`\uFF0C\u4EE5\u4FBF\u5217\u8868\u53CD\u6620\u5B9E\u9645\u60C5\u51B5\n8. **\u4EE3\u7801\u5BA1\u67E5**\uFF08\u53EF\u9009\uFF09 - \u57FA\u4E8E\u751F\u6210\u7684\u4E0A\u4E0B\u6587\u6587\u4EF6\u5BA1\u67E5\u5DF2\u5B9E\u65BD\u7684\u4EE3\u7801\uFF0C\u68C0\u67E5\uFF1A\n - \u4EE3\u7801\u89C4\u8303\u548C\u7EA6\u5B9A\u5408\u89C4\u6027\n - \u903B\u8F91\u6B63\u786E\u6027\n - \u6027\u80FD\u95EE\u9898\u548C\u6F5C\u5728\u74F6\u9888\n - \u5B89\u5168\u6027\u95EE\u9898\n - \u6700\u4F73\u5B9E\u8DF5\u9075\u5FAA\u60C5\u51B5\n - \u5BF9\u4E8E Java \u4EE3\u7801\uFF1A\u7279\u522B\u5173\u6CE8 Java \u7279\u5B9A\u7684\u6A21\u5F0F\u3001\u7EA6\u5B9A\u548C\u6F5C\u5728\u95EE\u9898\n - \u6B64\u6B65\u9AA4\u662F\u53EF\u9009\u7684\uFF0C\u5982\u679C\u8DF3\u8FC7\u4E0D\u4F1A\u963B\u585E\u5DE5\u4F5C\u6D41\n - \u5982\u679C\u53D1\u73B0\u95EE\u9898\uFF0C\u5E94\u5728\u5F52\u6863\u4E4B\u524D\u89E3\u51B3\n9. **\u6279\u51C6\u95E8\u69DB** - \u5728\u63D0\u6848\u7ECF\u8FC7\u5BA1\u67E5\u548C\u6279\u51C6\u4E4B\u524D\u4E0D\u8981\u5F00\u59CB\u5B9E\u65BD\n\n### \u9636\u6BB5 3\uFF1A\u5F52\u6863\u53D8\u66F4\n\u90E8\u7F72\u540E\uFF0C\u521B\u5EFA\u5355\u72EC\u7684 PR\uFF1A\n- \u5C06 `changes/[name]/` \u2192 `changes/archive/YYYY-MM-DD-[name]/`\n- \u5982\u679C\u529F\u80FD\u5DF2\u66F4\u6539\uFF0C\u66F4\u65B0 `specs/`\n- \u5BF9\u4E8E\u4EC5\u5DE5\u5177\u7C7B\u7684\u53D8\u66F4\uFF0C\u4F7F\u7528 `zhuanspec archive <change-id> --skip-specs --yes`\uFF08\u59CB\u7EC8\u663E\u5F0F\u4F20\u9012\u53D8\u66F4 ID\uFF09\n- \u8FD0\u884C `zhuanspec validate --strict` \u4EE5\u786E\u8BA4\u5F52\u6863\u7684\u53D8\u66F4\u901A\u8FC7\u68C0\u67E5\n\n## \u6267\u884C\u4EFB\u4F55\u4EFB\u52A1\u4E4B\u524D\n\n**\u4E0A\u4E0B\u6587\u68C0\u67E5\u6E05\u5355\uFF1A**\n- [ ] \u5728 `specs/[capability]/spec.md` \u4E2D\u9605\u8BFB\u76F8\u5173\u89C4\u8303\n- [ ] \u68C0\u67E5 `changes/` \u4E2D\u7684\u5F85\u5904\u7406\u53D8\u66F4\u662F\u5426\u5B58\u5728\u51B2\u7A81\n- [ ] \u9605\u8BFB `zhuanspec/project.md` \u4E86\u89E3\u7EA6\u5B9A\u3001\u9879\u76EE\u7ED3\u6784\u548C\u76F8\u5173\u529F\u80FD\u6A21\u5757\uFF08\u6309\u9700\u52A0\u8F7D\uFF09\n- [ ] \u8FD0\u884C `zhuanspec list` \u67E5\u770B\u6D3B\u52A8\u53D8\u66F4\n- [ ] \u8FD0\u884C `zhuanspec list --specs` \u67E5\u770B\u73B0\u6709\u529F\u80FD\n\n**\u521B\u5EFA\u89C4\u8303\u4E4B\u524D\uFF1A**\n- \u59CB\u7EC8\u68C0\u67E5\u529F\u80FD\u662F\u5426\u5DF2\u5B58\u5728\n- \u4F18\u5148\u4FEE\u6539\u73B0\u6709\u89C4\u8303\u800C\u4E0D\u662F\u521B\u5EFA\u91CD\u590D\u9879\n- \u4F7F\u7528 `zhuanspec show [spec]` \u5BA1\u67E5\u5F53\u524D\u72B6\u6001\n- **\u5F3A\u5236\u6F84\u6E05\u8981\u6C42**\uFF1A\u5982\u679C\u8BF7\u6C42\u6709\u4EFB\u4F55\u4E0D\u660E\u786E\u3001\u6A21\u7CCA\u6216\u4E0D\u786E\u5B9A\u7684\u65B9\u9762\uFF0C\u5FC5\u987B\u505C\u6B62\u5E76\u4F7F\u7528**\u9009\u9879\u5F0F\u4EA4\u4E92**\u63D0\u95EE\u3002\u4E25\u7981\u5728\u4E0D\u786E\u5B9A\u7684\u60C5\u51B5\u4E0B\u81EA\u884C\u63A8\u6D4B\u3001\u5047\u8BBE\u6216\u7EE7\u7EED\u521B\u5EFA\u6587\u4EF6\u3002\u4E25\u7981\u8981\u6C42\u7528\u6237\u624B\u52A8\u8F93\u5165\u5927\u6BB5\u6587\u5B57\u56DE\u7B54\u3002\n\n## \u5F3A\u5236\u6F84\u6E05\u5DE5\u4F5C\u6D41\n\n\u5728\u521B\u5EFA\u4EFB\u4F55\u63D0\u6848\u6587\u4EF6\u4E4B\u524D\uFF0C\u5FC5\u987B\u6267\u884C\u5F3A\u5236\u6F84\u6E05\u68C0\u67E5\u3002\u8FD9\u662F\u4E0D\u53EF\u8DF3\u8FC7\u7684\u6B65\u9AA4\u3002\n\n**\u91CD\u8981\u539F\u5219\uFF1A\u5148\u67E5\u9605\u540E\u8BE2\u95EE\uFF0C\u907F\u514D\u8FC7\u5EA6\u8BE2\u95EE**\n\n\u5728\u8BE2\u95EE\u4E4B\u524D\uFF0C\u5FC5\u987B\u5148\u67E5\u9605\u4EE5\u4E0B\u6765\u6E90\uFF0C\u53EA\u6709\u5728\u786E\u5B9E\u65E0\u6CD5\u4ECE\u8FD9\u4E9B\u6765\u6E90\u786E\u5B9A\u65F6\u624D\u8BE2\u95EE\uFF1A\n- \u73B0\u6709\u89C4\u8303\uFF08`zhuanspec/specs/`\uFF09\n- \u9879\u76EE\u7EA6\u5B9A\uFF08`zhuanspec/project.md`\uFF09\n- \u4EE3\u7801\u5E93\u7ED3\u6784\u548C\u73B0\u6709\u6A21\u5F0F\n- \u4E0A\u4E0B\u6587\u6587\u4EF6\u548C\u76F8\u5173\u53D8\u66F4\n\n### \u4F55\u65F6\u9700\u8981\u6F84\u6E05\n\n\u5728\u4EE5\u4E0B\u60C5\u51B5\u4E0B\uFF0C**\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u89C4\u8303\u3001\u9879\u76EE\u7EA6\u5B9A\u3001\u4EE3\u7801\u5E93\u7ED3\u6784\u4E2D\u786E\u5B9A\u65F6**\uFF0C\u5FC5\u987B\u505C\u6B62\u5E76\u63D0\u95EE\uFF08\u5305\u62EC\u4F46\u4E0D\u9650\u4E8E\uFF09\uFF1A\n- **\u8303\u56F4\u4E0D\u660E\u786E**\uFF1A\u7528\u6237\u8BF7\u6C42\u7684\u8303\u56F4\u8FB9\u754C\u4E0D\u6E05\u695A\uFF08\u4F8B\u5982\uFF1A\"\u6539\u8FDB\u6027\u80FD\"\u3001\"\u4F18\u5316\u4EE3\u7801\"\uFF09\n- **\u6280\u672F\u9009\u62E9\u4E0D\u660E\u786E**\uFF1A\u6709\u591A\u79CD\u5B9E\u73B0\u65B9\u5F0F\uFF0C\u4F46\u7528\u6237\u672A\u6307\u5B9A\u504F\u597D\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u4EE3\u7801\u6A21\u5F0F\u4E2D\u786E\u5B9A\uFF08\u4F8B\u5982\uFF1A\u4F7F\u7528\u54EA\u79CD\u6570\u636E\u5E93\u3001\u54EA\u79CD\u6846\u67B6\uFF09\n- **\u4F18\u5148\u7EA7\u4E0D\u660E\u786E**\uFF1A\u591A\u4E2A\u9700\u6C42\u4F46\u672A\u8BF4\u660E\u4F18\u5148\u7EA7\u6216\u987A\u5E8F\n- **\u9A8C\u6536\u6807\u51C6\u4E0D\u660E\u786E**\uFF1A\u4E0D\u6E05\u695A\u5982\u4F55\u5224\u65AD\u5B8C\u6210\u6216\u6210\u529F\n- **\u5B9E\u73B0\u7EC6\u8282\u4E0D\u660E\u786E**\uFF1A\u4E0D\u6E05\u695A\u5982\u4F55\u5B9E\u73B0\u6216\u5B9E\u73B0\u7EC6\u8282\u4E0D\u660E\u786E\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u4EE3\u7801\u5E93\u5206\u6790\u4E2D\u786E\u5B9A\uFF08\u4F8B\u5982\uFF1A\u5982\u4F55\u83B7\u53D6\u6570\u636E\u3001\u5982\u4F55\u5904\u7406\u9519\u8BEF\u3001\u5982\u4F55\u4F18\u5316\u6027\u80FD\uFF09\n- **\u4EE3\u7801\u6539\u52A8\u4F4D\u7F6E\u4E0D\u660E\u786E**\uFF1A\u4E0D\u6E05\u695A\u9700\u8981\u4FEE\u6539\u54EA\u4E9B\u6587\u4EF6\u3001\u5728\u54EA\u4E9B\u4F4D\u7F6E\u8FDB\u884C\u4FEE\u6539\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u4EE3\u7801\u5E93\u7ED3\u6784\u5206\u6790\u4E2D\u786E\u5B9A\n- **\u4EE3\u7801\u5206\u5C42\u67B6\u6784\u4E0D\u660E\u786E**\uFF1A\u5982\u679C\u6D89\u53CA\u670D\u52A1\u5206\u5C42\uFF08\u5982 4 \u5C42\u67B6\u6784\u30013 \u5C42\u67B6\u6784\u7B49\uFF09\uFF0C\u4E0D\u6E05\u695A\u5404\u5C42\u7684\u804C\u8D23\u548C\u6539\u52A8\u4F4D\u7F6E\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u4EE3\u7801\u7ED3\u6784\u6216\u89C4\u8303\u4E2D\u786E\u5B9A\n- **\u6570\u636E\u83B7\u53D6\u6765\u6E90\u4E0D\u660E\u786E**\uFF1A\u4E0D\u6E05\u695A\u4ECE\u54EA\u91CC\u83B7\u53D6\u6570\u636E\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u4EE3\u7801\u6216\u89C4\u8303\u4E2D\u786E\u5B9A\uFF08\u4F8B\u5982\uFF1A\u4ECE\u6570\u636E\u5E93\u3001API\u3001\u6587\u4EF6\u3001\u5916\u90E8\u670D\u52A1\u3001\u5386\u53F2\u903B\u8F91\u590D\u7528\uFF09\n- **\u670D\u52A1\u5206\u5C42\u4E0D\u660E\u786E**\uFF1A\u4E0D\u6E05\u695A\u670D\u52A1\u5206\u5C42\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u4EE3\u7801\u7ED3\u6784\u6216\u89C4\u8303\u4E2D\u786E\u5B9A\uFF08\u4F8B\u5982\uFF1A\u524D\u7AEF\u3001\u540E\u7AEF\u3001\u6570\u636E\u5E93\u3001API\u3001\u670D\u52A1\u30014\u5C42\u67B6\u6784\u30013\u5C42\u67B6\u6784\u30012\u5C42\u67B6\u6784\u3001\u9886\u57DF\u6A21\u578B\uFF09\n- **\u4F9D\u8D56\u5173\u7CFB\u4E0D\u660E\u786E**\uFF1A\u4E0D\u6E05\u695A\u4F9D\u8D56\u5173\u7CFB\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u4EE3\u7801\u5E93\u5206\u6790\u4E2D\u786E\u5B9A\uFF08\u4F8B\u5982\uFF1A\u4F9D\u8D56\u54EA\u4E9B\u670D\u52A1\u3001\u4F9D\u8D56\u54EA\u4E9B\u5E93\u3001\u4F9D\u8D56\u54EA\u4E9B\u7EC4\u4EF6\uFF09\n- **\u4E0A\u4E0B\u6587\u4FE1\u606F\u7F3A\u5931**\uFF1A\u7F3A\u5C11\u5FC5\u8981\u7684\u80CC\u666F\u4FE1\u606F\u6765\u7406\u89E3\u9700\u6C42\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u89C4\u8303\u6216\u4EE3\u7801\u4E2D\u83B7\u53D6\n- **\u6B67\u4E49\u6027\u8868\u8FF0**\uFF1A\u7528\u6237\u8BF7\u6C42\u53EF\u4EE5\u7528\u591A\u79CD\u65B9\u5F0F\u7406\u89E3\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u4E0A\u4E0B\u6587\u786E\u5B9A\n- **\u5176\u4ED6\u4E0D\u660E\u786E**\uFF1A\u5176\u4ED6\u4E0D\u660E\u786E\u7684\u60C5\u51B5\uFF0C\u4E14\u65E0\u6CD5\u4ECE\u73B0\u6709\u6765\u6E90\u786E\u5B9A\n\n### \u4F55\u65F6\u4E0D\u9700\u8981\u6F84\u6E05\n\n\u5728\u4EE5\u4E0B\u60C5\u51B5\u4E0B\uFF0C**\u4E0D\u5E94\u8BE2\u95EE**\uFF0C\u5E94\u76F4\u63A5\u4F7F\u7528\u4ECE\u73B0\u6709\u6765\u6E90\u83B7\u53D6\u7684\u4FE1\u606F\uFF1A\n- **\u4FE1\u606F\u5DF2\u660E\u786E**\uFF1A\u7528\u6237\u8BF7\u6C42\u4E2D\u5DF2\u7ECF\u660E\u786E\u8BF4\u660E\u4E86\u76F8\u5173\u4FE1\u606F\n- **\u53EF\u4ECE\u89C4\u8303\u83B7\u53D6**\uFF1A\u4FE1\u606F\u53EF\u4EE5\u4ECE\u73B0\u6709\u89C4\u8303\uFF08`zhuanspec/specs/`\uFF09\u4E2D\u83B7\u53D6\n- **\u53EF\u4ECE\u9879\u76EE\u7EA6\u5B9A\u83B7\u53D6**\uFF1A\u4FE1\u606F\u53EF\u4EE5\u4ECE\u9879\u76EE\u7EA6\u5B9A\uFF08`zhuanspec/project.md`\uFF09\u4E2D\u83B7\u53D6\n- **\u53EF\u4ECE\u4EE3\u7801\u5E93\u5206\u6790\u83B7\u53D6**\uFF1A\u4FE1\u606F\u53EF\u4EE5\u901A\u8FC7\u5206\u6790\u4EE3\u7801\u5E93\u7ED3\u6784\u3001\u73B0\u6709\u6A21\u5F0F\u3001\u76F8\u5173\u6587\u4EF6\u83B7\u53D6\n- **\u53EF\u4ECE\u4E0A\u4E0B\u6587\u83B7\u53D6**\uFF1A\u4FE1\u606F\u53EF\u4EE5\u4ECE\u4E0A\u4E0B\u6587\u6587\u4EF6\u3001\u76F8\u5173\u53D8\u66F4\u3001\u5386\u53F2\u8BB0\u5F55\u4E2D\u83B7\u53D6\n- **\u7B26\u5408\u5E38\u89C1\u6A21\u5F0F**\uFF1A\u5B9E\u73B0\u65B9\u5F0F\u7B26\u5408\u9879\u76EE\u4E2D\u7684\u5E38\u89C1\u6A21\u5F0F\u6216\u6700\u4F73\u5B9E\u8DF5\uFF0C\u65E0\u9700\u7279\u522B\u8BE2\u95EE\n\n**\u539F\u5219**\uFF1A\u5982\u679C\u53EF\u4EE5\u901A\u8FC7\u67E5\u9605\u73B0\u6709\u6765\u6E90\u786E\u5B9A\u4FE1\u606F\uFF0C\u5C31\u4E0D\u8981\u8BE2\u95EE\u7528\u6237\uFF0C\u4EE5\u63D0\u9AD8\u6548\u7387\u3002\n\n### \u6F84\u6E05\u95EE\u9898\u683C\u5F0F\n\n**\u5FC5\u987B\u4F7F\u7528\u9009\u9879\u5F0F\u4EA4\u4E92\uFF0C\u4E25\u7981\u8981\u6C42\u7528\u6237\u624B\u52A8\u8F93\u5165\u6587\u5B57\u56DE\u7B54\u3002**\n\n\u4F7F\u7528\u7F16\u8F91\u5668\u63D0\u4F9B\u7684\u7ED3\u6784\u5316\u95EE\u7B54\u5DE5\u5177\uFF08\u5982 Cursor \u7684 `AskQuestion` \u5DE5\u5177\u3001Claude Code \u7684\u4EA4\u4E92\u5F0F\u9009\u62E9\u7B49\uFF09\u5411\u7528\u6237\u63D0\u95EE\uFF0C\u5C06\u6BCF\u4E2A\u6F84\u6E05\u95EE\u9898\u8F6C\u5316\u4E3A\u5E26\u9884\u8BBE\u9009\u9879\u7684\u9009\u62E9\u9898\uFF1A\n\n**\u683C\u5F0F\u8981\u6C42\uFF1A**\n- \u6BCF\u4E2A\u95EE\u9898\u63D0\u4F9B 2-5 \u4E2A\u9884\u8BBE\u9009\u9879\n- \u6BCF\u4E2A\u95EE\u9898\u672B\u5C3E\u5305\u542B\u4E00\u4E2A\"\u5176\u4ED6\"\u9009\u9879\uFF0C\u4EE5\u8986\u76D6\u672A\u5217\u51FA\u7684\u60C5\u51B5\n- \u5141\u8BB8\u7528\u6237\u591A\u9009\uFF08\u5F53\u95EE\u9898\u53EF\u80FD\u6709\u591A\u4E2A\u7B54\u6848\u65F6\u8BBE\u7F6E `allow_multiple: true`\uFF09\n- \u9009\u9879\u6587\u672C\u8981\u7B80\u6D01\u660E\u4E86\uFF0C\u5FC5\u8981\u65F6\u9644\u5E26\u7B80\u77ED\u8BF4\u660E\n- \u5982\u679C\u6709\u591A\u4E2A\u72EC\u7ACB\u7684\u6F84\u6E05\u95EE\u9898\uFF0C\u5408\u5E76\u5230\u540C\u4E00\u6B21\u95EE\u7B54\u4EA4\u4E92\u4E2D\uFF08\u4E00\u6B21\u6027\u5C55\u793A\u591A\u4E2A\u95EE\u9898\uFF09\n\n**\u6807\u51C6\u683C\u5F0F\u6A21\u677F\uFF1A**\n\n```\n\u4F7F\u7528 AskQuestion \u5DE5\u5177\u63D0\u95EE\uFF0C\u7ED3\u6784\u5982\u4E0B\uFF1A\n\n\u95EE\u9898 1: \"\u5173\u4E8E [\u4E0D\u786E\u5B9A\u7684\u65B9\u9762]\uFF1A[\u5177\u4F53\u95EE\u9898]\"\n\u9009\u9879\uFF1A\n A) [\u9009\u98791 - \u7B80\u77ED\u8BF4\u660E]\n B) [\u9009\u98792 - \u7B80\u77ED\u8BF4\u660E]\n C) [\u9009\u98793 - \u7B80\u77ED\u8BF4\u660E]\n D) \u5176\u4ED6\uFF08\u8BF7\u5728\u540E\u7EED\u8865\u5145\u8BF4\u660E\uFF09\n\n\u95EE\u9898 2: \"\u5173\u4E8E [\u53E6\u4E00\u4E2A\u65B9\u9762]\uFF1A[\u5177\u4F53\u95EE\u9898]\"\n\u9009\u9879\uFF1A\n A) [\u9009\u98791]\n B) [\u9009\u98792]\n C) \u5176\u4ED6\n```\n\n**\u5DE5\u5177\u8C03\u7528\u793A\u4F8B\uFF08Cursor AskQuestion\uFF09\uFF1A**\n```json\n{\n \"questions\": [\n {\n \"id\": \"scope\",\n \"prompt\": \"\u5173\u4E8E\u6539\u8FDB\u8303\u56F4\uFF1A\u60A8\u5E0C\u671B\u6539\u8FDB\u54EA\u4E9B\u65B9\u9762\uFF1F\",\n \"options\": [\n {\"id\": \"security\", \"label\": \"\u5B89\u5168\u6027\uFF08\u5982\u53CC\u56E0\u7D20\u8BA4\u8BC1\uFF09\"},\n {\"id\": \"ux\", \"label\": \"\u7528\u6237\u4F53\u9A8C\uFF08\u5982\u7B80\u5316\u6D41\u7A0B\uFF09\"},\n {\"id\": \"performance\", \"label\": \"\u6027\u80FD\uFF08\u5982\u54CD\u5E94\u65F6\u95F4\u4F18\u5316\uFF09\"},\n {\"id\": \"other\", \"label\": \"\u5176\u4ED6\"}\n ],\n \"allow_multiple\": true\n },\n {\n \"id\": \"priority\",\n \"prompt\": \"\u5982\u679C\u6709\u591A\u4E2A\u6539\u8FDB\u70B9\uFF0C\u4F18\u5148\u7EA7\u5982\u4F55\uFF1F\",\n \"options\": [\n {\"id\": \"security_first\", \"label\": \"\u5B89\u5168\u6027\u4F18\u5148\"},\n {\"id\": \"ux_first\", \"label\": \"\u7528\u6237\u4F53\u9A8C\u4F18\u5148\"},\n {\"id\": \"all_equal\", \"label\": \"\u540C\u7B49\u91CD\u8981\uFF0C\u4E00\u8D77\u505A\"}\n ]\n }\n ]\n}\n```\n\n**\u539F\u5219\uFF1A**\n- \u6C38\u8FDC\u4E0D\u8981\u8BA9\u7528\u6237\u4ECE\u96F6\u5F00\u59CB\u8F93\u5165\u7B54\u6848\uFF0C\u603B\u662F\u63D0\u4F9B\u53EF\u9009\u7684\u9009\u9879\n- \u9009\u9879\u5E94\u8986\u76D6\u6700\u5E38\u89C1\u7684\u7B54\u6848\u573A\u666F\n- \"\u5176\u4ED6\"\u9009\u9879\u4F5C\u4E3A\u515C\u5E95\uFF0C\u786E\u4FDD\u4E0D\u9057\u6F0F\u7279\u6B8A\u60C5\u51B5\n- \u7528\u6237\u9009\u62E9\"\u5176\u4ED6\"\u540E\uFF0C\u518D\u9488\u5BF9\u6027\u5730\u8FFD\u95EE\u7EC6\u8282\n\n### \u7981\u6B62\u884C\u4E3A\n\n\u5728\u9047\u5230\u6A21\u7CCA\u9700\u6C42\u65F6\uFF0C**\u4E25\u7981**\u4EE5\u4E0B\u884C\u4E3A\uFF1A\n- \u274C \u81EA\u884C\u63A8\u6D4B\u7528\u6237\u610F\u56FE\n- \u274C \u57FA\u4E8E\"\u6700\u4F73\u731C\u6D4B\"\u521B\u5EFA\u63D0\u6848\n- \u274C \u5047\u8BBE\u7528\u6237\u60F3\u8981\u4EC0\u4E48\n- \u274C \u8DF3\u8FC7\u6F84\u6E05\u76F4\u63A5\u521B\u5EFA\u6587\u4EF6\n- \u274C \u4F7F\u7528\u6A21\u7CCA\u7684\u8868\u8FF0\u6765\u63A9\u76D6\u4E0D\u786E\u5B9A\u6027\n- \u274C \u8981\u6C42\u7528\u6237\u624B\u52A8\u8F93\u5165\u5927\u6BB5\u6587\u5B57\u6765\u56DE\u7B54\u6F84\u6E05\u95EE\u9898\uFF08\u5FC5\u987B\u4F7F\u7528\u9009\u9879\u5F0F\u4EA4\u4E92\uFF09\n\n### \u6F84\u6E05\u6D41\u7A0B\n\n1. **\u67E5\u9605\u73B0\u6709\u6765\u6E90**\uFF1A\u9996\u5148\u67E5\u9605\u73B0\u6709\u89C4\u8303\u3001\u9879\u76EE\u7EA6\u5B9A\u3001\u4EE3\u7801\u5E93\u7ED3\u6784\u3001\u4E0A\u4E0B\u6587\u6587\u4EF6\u7B49\uFF0C\u5C1D\u8BD5\u4ECE\u8FD9\u4E9B\u6765\u6E90\u83B7\u53D6\u6240\u9700\u4FE1\u606F\n2. **\u8BC6\u522B\u6A21\u7CCA\u70B9**\uFF1A\u4ED4\u7EC6\u5206\u6790\u7528\u6237\u8BF7\u6C42\uFF0C\u5217\u51FA\u6240\u6709\u4E0D\u786E\u5B9A\u7684\u65B9\u9762\uFF0C**\u4F46\u6392\u9664\u90A3\u4E9B\u53EF\u4EE5\u4ECE\u73B0\u6709\u6765\u6E90\u786E\u5B9A\u7684\u65B9\u9762**\n3. **\u5224\u65AD\u662F\u5426\u9700\u8981\u8BE2\u95EE**\uFF1A\u5BF9\u4E8E\u6BCF\u4E2A\u4E0D\u786E\u5B9A\u7684\u65B9\u9762\uFF0C\u5224\u65AD\u662F\u5426\u53EF\u4EE5\u4ECE\u73B0\u6709\u6765\u6E90\u786E\u5B9A\uFF1A\n - \u5982\u679C\u53EF\u4EE5\u786E\u5B9A\uFF0C\u5219\u4F7F\u7528\u4ECE\u73B0\u6709\u6765\u6E90\u83B7\u53D6\u7684\u4FE1\u606F\uFF0C\u4E0D\u8BE2\u95EE\n - \u5982\u679C\u65E0\u6CD5\u786E\u5B9A\uFF0C\u5219\u6807\u8BB0\u4E3A\u9700\u8981\u8BE2\u95EE\n4. **\u6784\u9020\u9009\u9879\u5F0F\u95EE\u9898**\uFF1A\u5C06\u6240\u6709\u9700\u8981\u8BE2\u95EE\u7684\u6A21\u7CCA\u70B9\u8F6C\u5316\u4E3A\u5E26\u9884\u8BBE\u9009\u9879\u7684\u9009\u62E9\u9898\uFF0C\u5C3D\u91CF\u5408\u5E76\u5230\u4E00\u6B21\u4EA4\u4E92\u4E2D\n5. **\u4F7F\u7528\u5DE5\u5177\u63D0\u95EE**\uFF1A\u8C03\u7528\u7F16\u8F91\u5668\u7684\u7ED3\u6784\u5316\u95EE\u7B54\u5DE5\u5177\uFF08\u5982 `AskQuestion`\uFF09\u4E00\u6B21\u6027\u5C55\u793A\u6240\u6709\u95EE\u9898\u548C\u9009\u9879\uFF0C\u7B49\u5F85\u7528\u6237\u9009\u62E9\n6. **\u7B49\u5F85\u7528\u6237\u9009\u62E9**\uFF1A\u5FC5\u987B\u7B49\u5F85\u7528\u6237\u9009\u62E9\u7B54\u6848\uFF0C\u4E0D\u80FD\u7EE7\u7EED\n7. **\u5904\u7406\"\u5176\u4ED6\"\u9009\u9879**\uFF1A\u5982\u679C\u7528\u6237\u9009\u62E9\u4E86\"\u5176\u4ED6\"\uFF0C\u518D\u9488\u5BF9\u8BE5\u95EE\u9898\u8FFD\u95EE\u5177\u4F53\u7EC6\u8282\uFF08\u4ECD\u4F18\u5148\u4F7F\u7528\u9009\u9879\u5F0F\uFF0C\u5982\u786E\u5B9E\u65E0\u6CD5\u9884\u8BBE\u5219\u5141\u8BB8\u7B80\u77ED\u6587\u5B57\u8F93\u5165\uFF09\n8. **\u786E\u8BA4\u7406\u89E3**\uFF1A\u5728\u5F00\u59CB\u521B\u5EFA\u6587\u4EF6\u524D\uFF0C\u7B80\u8981\u603B\u7ED3\u7406\u89E3\u4EE5\u786E\u4FDD\u51C6\u786E\n9. **\u5F00\u59CB\u521B\u5EFA**\uFF1A\u53EA\u6709\u5728\u6240\u6709\u5FC5\u8981\u7684\u6A21\u7CCA\u70B9\u90FD\u660E\u786E\u540E\uFF0C\u624D\u80FD\u5F00\u59CB\u521B\u5EFA\u63D0\u6848\u6587\u4EF6\n\n### \u793A\u4F8B\n\n**\u7528\u6237\u8BF7\u6C42**\uFF1A\"\u6539\u8FDB\u767B\u5F55\u529F\u80FD\"\n\n**\u5206\u6790\u8FC7\u7A0B**\uFF1A\n1. \u9996\u5148\u67E5\u9605\u73B0\u6709\u89C4\u8303\uFF08`zhuanspec/specs/`\uFF09\u4E2D\u662F\u5426\u6709\u767B\u5F55\u76F8\u5173\u7684\u89C4\u8303\n2. \u67E5\u9605\u9879\u76EE\u7EA6\u5B9A\uFF08`zhuanspec/project.md`\uFF09\u4E86\u89E3\u9879\u76EE\u67B6\u6784\u548C\u7EA6\u5B9A\n3. \u5206\u6790\u4EE3\u7801\u5E93\u7ED3\u6784\uFF0C\u4E86\u89E3\u73B0\u6709\u7684\u767B\u5F55\u5B9E\u73B0\u65B9\u5F0F\n4. \u5982\u679C\u4ECE\u8FD9\u4E9B\u6765\u6E90\u65E0\u6CD5\u786E\u5B9A\u6539\u8FDB\u8303\u56F4\uFF0C\u5219\u4F7F\u7528\u9009\u9879\u5F0F\u4EA4\u4E92\u8BE2\u95EE\n\n**\u5FC5\u987B\u4F7F\u7528\u9009\u9879\u5F0F\u4EA4\u4E92\u63D0\u95EE**\uFF08\u4EC5\u5728\u65E0\u6CD5\u4ECE\u73B0\u6709\u6765\u6E90\u786E\u5B9A\u65F6\uFF09\uFF1A\n\n```json\n{\n \"questions\": [\n {\n \"id\": \"improvement_scope\",\n \"prompt\": \"\u60A8\u5E0C\u671B\u6539\u8FDB\u767B\u5F55\u529F\u80FD\u7684\u54EA\u4E9B\u65B9\u9762\uFF1F\",\n \"options\": [\n {\"id\": \"security\", \"label\": \"\u5B89\u5168\u6027\uFF08\u5982\u6DFB\u52A0\u53CC\u56E0\u7D20\u8BA4\u8BC1\uFF09\"},\n {\"id\": \"ux\", \"label\": \"\u7528\u6237\u4F53\u9A8C\uFF08\u5982\u7B80\u5316\u767B\u5F55\u6D41\u7A0B\uFF09\"},\n {\"id\": \"performance\", \"label\": \"\u6027\u80FD\uFF08\u5982\u4F18\u5316\u767B\u5F55\u54CD\u5E94\u65F6\u95F4\uFF09\"},\n {\"id\": \"other\", \"label\": \"\u5176\u4ED6\"}\n ],\n \"allow_multiple\": true\n },\n {\n \"id\": \"tech_preference\",\n \"prompt\": \"\u60A8\u6709\u7279\u5B9A\u7684\u6280\u672F\u504F\u597D\u5417\uFF1F\",\n \"options\": [\n {\"id\": \"jwt\", \"label\": \"JWT Token \u8BA4\u8BC1\"},\n {\"id\": \"session\", \"label\": \"Session \u8BA4\u8BC1\"},\n {\"id\": \"oauth\", \"label\": \"OAuth \u7B2C\u4E09\u65B9\u96C6\u6210\"},\n {\"id\": \"no_preference\", \"label\": \"\u65E0\u504F\u597D\uFF0C\u7531\u4F60\u63A8\u8350\"},\n {\"id\": \"other\", \"label\": \"\u5176\u4ED6\"}\n ]\n },\n {\n \"id\": \"priority\",\n \"prompt\": \"\u5982\u679C\u6709\u591A\u4E2A\u6539\u8FDB\u70B9\uFF0C\u4F18\u5148\u7EA7\u5982\u4F55\uFF1F\",\n \"options\": [\n {\"id\": \"security_first\", \"label\": \"\u5B89\u5168\u6027\u4F18\u5148\"},\n {\"id\": \"ux_first\", \"label\": \"\u7528\u6237\u4F53\u9A8C\u4F18\u5148\"},\n {\"id\": \"perf_first\", \"label\": \"\u6027\u80FD\u4F18\u5148\"},\n {\"id\": \"all_equal\", \"label\": \"\u540C\u7B49\u91CD\u8981\uFF0C\u4E00\u8D77\u505A\"}\n ]\n }\n ]\n}\n```\n\n**\u5B9E\u73B0\u7EC6\u8282\u76F8\u5173\u793A\u4F8B**\uFF08\u4EC5\u5728\u65E0\u6CD5\u4ECE\u4EE3\u7801\u5E93\u5206\u6790\u786E\u5B9A\u65F6\u8BE2\u95EE\uFF09\uFF1A\n\n**\u7528\u6237\u8BF7\u6C42**\uFF1A\"\u91CD\u6784\u7528\u6237\u8BA4\u8BC1\u670D\u52A1\"\n\n**\u5982\u679C\u65E0\u6CD5\u4ECE\u4EE3\u7801\u5E93\u5206\u6790\u786E\u5B9A\uFF0C\u4F7F\u7528\u9009\u9879\u5F0F\u4EA4\u4E92\u63D0\u95EE**\uFF1A\n\n```json\n{\n \"questions\": [\n {\n \"id\": \"change_scope\",\n \"prompt\": \"\u91CD\u6784\u6D89\u53CA\u54EA\u4E9B\u6539\u52A8\uFF1F\",\n \"options\": [\n {\"id\": \"modify_existing\", \"label\": \"\u4FEE\u6539\u73B0\u6709\u8BA4\u8BC1\u670D\u52A1\u7C7B\"},\n {\"id\": \"new_service\", \"label\": \"\u521B\u5EFA\u65B0\u7684\u670D\u52A1\u5C42\"},\n {\"id\": \"both\", \"label\": \"\u4E24\u8005\u90FD\u6D89\u53CA\"},\n {\"id\": \"other\", \"label\": \"\u5176\u4ED6\"}\n ]\n },\n {\n \"id\": \"layer_scope\",\n \"prompt\": \"\u6539\u52A8\u5E94\u8BE5\u5728\u54EA\u4E9B\u5C42\u8FDB\u884C\uFF1F\",\n \"options\": [\n {\"id\": \"controller\", \"label\": \"Controller \u5C42\"},\n {\"id\": \"service\", \"label\": \"Service \u5C42\"},\n {\"id\": \"repository\", \"label\": \"Repository \u5C42\"},\n {\"id\": \"all\", \"label\": \"\u5168\u90E8\u5C42\"}\n ],\n \"allow_multiple\": true\n },\n {\n \"id\": \"refactor_strategy\",\n \"prompt\": \"\u91CD\u6784\u7B56\u7565\u504F\u597D\uFF1F\",\n \"options\": [\n {\"id\": \"incremental\", \"label\": \"\u6E10\u8FDB\u5F0F\u91CD\u6784\uFF08\u9010\u6B65\u66FF\u6362\uFF09\"},\n {\"id\": \"rewrite\", \"label\": \"\u5B8C\u5168\u91CD\u5199\"},\n {\"id\": \"strangler\", \"label\": \"\u7EDE\u6740\u8005\u6A21\u5F0F\uFF08\u65B0\u65E7\u5E76\u884C\u540E\u5207\u6362\uFF09\"},\n {\"id\": \"no_preference\", \"label\": \"\u65E0\u504F\u597D\uFF0C\u7531\u4F60\u63A8\u8350\"}\n ]\n }\n ]\n}\n```\n\n**\u6CE8\u610F**\uFF1A\u5982\u679C\u53EF\u4EE5\u4ECE\u73B0\u6709\u4EE3\u7801\u7ED3\u6784\u3001\u89C4\u8303\u6216\u9879\u76EE\u7EA6\u5B9A\u4E2D\u786E\u5B9A\u8FD9\u4E9B\u4FE1\u606F\uFF0C\u5219\u4E0D\u5E94\u8BE2\u95EE\uFF0C\u76F4\u63A5\u4F7F\u7528\u4ECE\u73B0\u6709\u6765\u6E90\u83B7\u53D6\u7684\u4FE1\u606F\u3002\n\n### \u641C\u7D22\u6307\u5BFC\n- \u679A\u4E3E\u89C4\u8303\uFF1A`zhuanspec spec list --long`\uFF08\u6216\u4F7F\u7528 `--json` \u7528\u4E8E\u811A\u672C\uFF09\n- \u679A\u4E3E\u53D8\u66F4\uFF1A`zhuanspec list`\uFF08\u6216 `zhuanspec change list --json` - \u5DF2\u5F03\u7528\u4F46\u53EF\u7528\uFF09\n- \u663E\u793A\u8BE6\u7EC6\u4FE1\u606F\uFF1A\n - \u89C4\u8303\uFF1A`zhuanspec show <spec-id> --type spec`\uFF08\u4F7F\u7528 `--json` \u8FDB\u884C\u8FC7\u6EE4\uFF09\n - \u53D8\u66F4\uFF1A`zhuanspec show <change-id> --json --deltas-only`\n- \u5168\u6587\u641C\u7D22\uFF08\u4F7F\u7528 ripgrep\uFF09\uFF1A`rg -n \"Requirement:|Scenario:\" zhuanspec/specs`\n\n## \u5FEB\u901F\u5F00\u59CB\n\n### CLI \u547D\u4EE4\n\n```bash\n# \u57FA\u672C\u547D\u4EE4\nzhuanspec list # \u5217\u51FA\u6D3B\u52A8\u53D8\u66F4\nzhuanspec list --specs # \u5217\u51FA\u89C4\u8303\nzhuanspec show [item] # \u663E\u793A\u53D8\u66F4\u6216\u89C4\u8303\nzhuanspec validate [item] # \u9A8C\u8BC1\u53D8\u66F4\u6216\u89C4\u8303\nzhuanspec archive <change-id> [--yes|-y] # \u90E8\u7F72\u540E\u5F52\u6863\uFF08\u6DFB\u52A0 --yes \u7528\u4E8E\u975E\u4EA4\u4E92\u5F0F\u8FD0\u884C\uFF09\n\n# \u9879\u76EE\u7BA1\u7406\nzhuanspec init [path] # \u521D\u59CB\u5316 ZhuanSpec\nzhuanspec update [path] # \u66F4\u65B0\u8BF4\u660E\u6587\u4EF6\n\n# \u4EA4\u4E92\u6A21\u5F0F\nzhuanspec show # \u63D0\u793A\u9009\u62E9\nzhuanspec validate # \u6279\u91CF\u9A8C\u8BC1\u6A21\u5F0F\n\n# \u8C03\u8BD5\nzhuanspec show [change] --json --deltas-only\nzhuanspec validate [change] --strict\n```\n\n### \u547D\u4EE4\u6807\u5FD7\n\n- `--json` - \u673A\u5668\u53EF\u8BFB\u8F93\u51FA\n- `--type change|spec` - \u6D88\u9664\u9879\u76EE\u6B67\u4E49\n- `--strict` - \u5168\u9762\u9A8C\u8BC1\n- `--no-interactive` - \u7981\u7528\u63D0\u793A\n- `--skip-specs` - \u5F52\u6863\u65F6\u4E0D\u66F4\u65B0\u89C4\u8303\n- `--yes`/`-y` - \u8DF3\u8FC7\u786E\u8BA4\u63D0\u793A\uFF08\u975E\u4EA4\u4E92\u5F0F\u5F52\u6863\uFF09\n\n## \u76EE\u5F55\u7ED3\u6784\n\n```\nzhuanspec/\n\u251C\u2500\u2500 project.md # \u9879\u76EE\u7EA6\u5B9A\n\u251C\u2500\u2500 specs/ # \u5F53\u524D\u771F\u5B9E\u72B6\u6001 - \u5DF2\u6784\u5EFA\u7684\u5185\u5BB9\n\u2502 \u2514\u2500\u2500 [capability]/ # \u5355\u4E00\u805A\u7126\u7684\u529F\u80FD\n\u2502 \u251C\u2500\u2500 spec.md # \u8981\u6C42\u548C\u573A\u666F\n\u2502 \u2514\u2500\u2500 design.md # \u6280\u672F\u6A21\u5F0F\n\u251C\u2500\u2500 changes/ # \u63D0\u6848 - \u5E94\u8BE5\u66F4\u6539\u7684\u5185\u5BB9\n\u2502 \u251C\u2500\u2500 [change-name]/\n\u2502 \u2502 \u251C\u2500\u2500 proposal.md # \u539F\u56E0\u3001\u5185\u5BB9\u3001\u5F71\u54CD\n\u2502 \u2502 \u251C\u2500\u2500 tasks.md # \u5B9E\u65BD\u6E05\u5355\n\u2502 \u2502 \u251C\u2500\u2500 design.md # \u6280\u672F\u51B3\u7B56\uFF08\u53EF\u9009\uFF1B\u89C1\u6807\u51C6\uFF09\n\u2502 \u2502 \u2514\u2500\u2500 specs/ # \u589E\u91CF\u53D8\u66F4\n\u2502 \u2502 \u2514\u2500\u2500 [capability]/\n\u2502 \u2502 \u2514\u2500\u2500 spec.md # ADDED/MODIFIED/REMOVED\n\u2502 \u2514\u2500\u2500 archive/ # \u5DF2\u5B8C\u6210\u7684\u53D8\u66F4\n```\n\n## \u521B\u5EFA\u53D8\u66F4\u63D0\u6848\n\n### \u51B3\u7B56\u6811\n\n```\n\u65B0\u8BF7\u6C42\uFF1F\n\u251C\u2500 \u4FEE\u590D\u6062\u590D\u89C4\u8303\u884C\u4E3A\u7684 Bug\uFF1F \u2192 \u76F4\u63A5\u4FEE\u590D\n\u251C\u2500 \u62FC\u5199\u9519\u8BEF/\u683C\u5F0F/\u6CE8\u91CA\uFF1F \u2192 \u76F4\u63A5\u4FEE\u590D\n\u251C\u2500 \u65B0\u529F\u80FD/\u80FD\u529B\uFF1F \u2192 \u521B\u5EFA\u63D0\u6848\n\u251C\u2500 \u7834\u574F\u6027\u66F4\u6539\uFF1F \u2192 \u521B\u5EFA\u63D0\u6848\n\u251C\u2500 \u67B6\u6784\u66F4\u6539\uFF1F \u2192 \u521B\u5EFA\u63D0\u6848\n\u2514\u2500 \u4E0D\u660E\u786E\uFF1F \u2192 \u521B\u5EFA\u63D0\u6848\uFF08\u66F4\u5B89\u5168\uFF09\n```\n\n### \u63D0\u6848\u7ED3\u6784\n\n1. **\u521B\u5EFA\u76EE\u5F55\uFF1A** `changes/[change-id]/`\uFF08kebab-case\uFF0C\u52A8\u8BCD\u5F00\u5934\uFF0C\u552F\u4E00\uFF09\n\n2. **\u7F16\u5199 proposal.md\uFF1A**\n```markdown\n# Change: [\u53D8\u66F4\u7684\u7B80\u8981\u63CF\u8FF0]\n\n## \u53D8\u66F4\u539F\u56E0\n[\u5173\u4E8E\u95EE\u9898/\u673A\u4F1A\u7684 1-2 \u53E5\u8BDD]\n\n## \u53D8\u66F4\u5185\u5BB9\n- [\u53D8\u66F4\u7684\u8981\u70B9\u5217\u8868]\n- [\u7528 **BREAKING** \u6807\u8BB0\u7834\u574F\u6027\u66F4\u6539]\n\n## \u5F71\u54CD\u8303\u56F4\n- Affected specs: [\u5217\u51FA\u529F\u80FD]\n- Affected code: [\u5173\u952E\u6587\u4EF6/\u7CFB\u7EDF]\n```\n\n3. **\u521B\u5EFA\u89C4\u8303\u589E\u91CF\uFF1A** `specs/[capability]/spec.md`\n```markdown\n## ADDED Requirements\n### \u9700\u6C42\uFF1ANew Feature\nThe system SHALL provide...\n\n#### \u573A\u666F\uFF1ASuccess case\n- **\u5F53** user performs action\n- **\u5219** expected result\n\n## MODIFIED Requirements\n### \u9700\u6C42\uFF1AExisting Feature\n[\u5B8C\u6574\u7684\u4FEE\u6539\u540E\u8981\u6C42]\n\n## REMOVED Requirements\n### \u9700\u6C42\uFF1AOld Feature\n**Reason**: [\u79FB\u9664\u539F\u56E0]\n**Migration**: [\u5982\u4F55\u5904\u7406]\n```\n\u5982\u679C\u591A\u4E2A\u529F\u80FD\u53D7\u5230\u5F71\u54CD\uFF0C\u5728 `changes/[change-id]/specs/<capability>/spec.md` \u4E0B\u521B\u5EFA\u591A\u4E2A\u589E\u91CF\u6587\u4EF6\u2014\u2014\u6BCF\u4E2A\u529F\u80FD\u4E00\u4E2A\u3002\n\n4. **\u521B\u5EFA tasks.md\uFF1A**\n\n\u5148\u8FD0\u884C `zhuanspec skills list --json` \u53D1\u73B0\u5F53\u524D\u73AF\u5883\u4E2D\u53EF\u7528\u7684 skill \u53CA\u5176 description\uFF0C\u7136\u540E\u57FA\u4E8E\u8BED\u4E49\u5339\u914D\u5728\u4EFB\u52A1\u4E2D\u6807\u6CE8\u771F\u5B9E skill \u540D\u79F0\uFF1A\n\n```markdown\n## 1. \u5B9E\u73B0\n- [ ] 1.1 \u521B\u5EFA\u6570\u636E\u5E93\u8868\u7ED3\u6784 @skill:java-db-schema-standards\n- [ ] 1.2 \u5B9E\u73B0 RPC \u63A5\u53E3 @skill:java-scf-rpc-usage-skill\n- [ ] 1.3 \u6DFB\u52A0\u524D\u7AEF\u7EC4\u4EF6 @skill:kf-fe-frontend-dev\n- [ ] 1.4 \u7F16\u5199\u6D4B\u8BD5 @skill:generate-mockito-unit-test-skill\n```\n> **@skill \u6807\u7B7E**\uFF1A\u521B\u5EFA tasks.md \u524D\uFF0C\u8FD0\u884C `zhuanspec skills list --json` \u53D1\u73B0\u53EF\u7528 skill \u53CA\u5176 description\u3002\u57FA\u4E8E skill description \u8FDB\u884C\u8BED\u4E49\u5339\u914D\uFF1A\n> - \u4ED4\u7EC6\u9605\u8BFB\u6BCF\u4E2A skill \u7684 description\uFF0C\u7406\u89E3\u5176\u5177\u4F53\u529F\u80FD\u548C\u9002\u7528\u573A\u666F\n> - \u53EA\u6709\u5F53\u4EFB\u52A1\u529F\u80FD\u4E0E skill description \u660E\u786E\u5339\u914D\u65F6\u624D\u6807\u6CE8\n> - \u7B80\u5355\u7684\u4EE3\u7801\u4FEE\u6539\uFF08\u5982\u589E\u5220\u679A\u4E3E\u503C\uFF09\u5E94\u5339\u914D\u901A\u7528\u7F16\u7801\u89C4\u8303 skill\uFF0C\u800C\u975E\u67B6\u6784\u7EA7 skill\n> - \u907F\u514D\u4EC5\u56E0\u6587\u4EF6\u540D\u6216\u8DEF\u5F84\u5173\u952E\u8BCD\u800C\u9519\u8BEF\u5339\u914D\n> - \u4F7F\u7528\u771F\u5B9E skill \u540D\u79F0\u6807\u6CE8\uFF0C\u652F\u6301\u591A\u4E2A skill\uFF08`@skill:name1,name2`\uFF09\n> - Apply \u9636\u6BB5 AI \u6839\u636E\u6807\u7B7E\u76F4\u63A5\u8C03\u7528\u5BF9\u5E94 skill\u3002\u65E0\u53EF\u7528 skill \u65F6\u53EF\u7701\u7565\u3002\n\n\u26A0\uFE0F **\u68C0\u67E5\u70B9 [Skill \u6807\u6CE8]**\uFF1A\n1. \u5FC5\u987B\u5148\u8FD0\u884C `zhuanspec skills list` \u5E76\u5728 Skill \u6620\u5C04\u8868\u4E2D\u8BB0\u5F55\u53D1\u73B0\u7684 skill\n2. \u6BCF\u4E2A\u4EFB\u52A1\u5FC5\u987B\u6807\u6CE8 @skill:\u771F\u5B9Eskill\u540D\u79F0 \u6216 @skill:none\n3. \u5982\u679C\u4F7F\u7528 @skill:none\uFF0C\u5FC5\u987B\u63D0\u4F9B\u7406\u7531\uFF08\u4F8B\u5982\uFF1A\"\u7EAF\u914D\u7F6E\u53D8\u66F4\uFF0C\u65E0\u9700 skill\"\uFF09\n4. @skill \u540D\u79F0\u5FC5\u987B\u4E0E `zhuanspec skills list` \u8FD4\u56DE\u7684\u540D\u79F0\u5B8C\u5168\u4E00\u81F4 \u2014\u2014 \u7981\u6B62\u865A\u6784 skill \u540D\u79F0\n5. tasks.md \u4E2D\u7684 Skill \u6620\u5C04\u8868\u4E0D\u80FD\u4E3A\u7A7A\n6. validate --strict \u4F1A\u9A8C\u8BC1\u6240\u6709 @skill \u540D\u79F0\u662F\u5426\u5B58\u5728\u4E8E\u5DF2\u77E5 skill \u5217\u8868\u4E2D\n\n\u26A0\uFE0F **\u68C0\u67E5\u70B9 [\u4EFB\u52A1\u6392\u5E8F]**\uFF1A\n1. tasks.md \u4E2D\u7684\u4EFB\u52A1\u5FC5\u987B\u6309\u6CE2\u6B21\u7EC4\u7EC7\uFF08### \u6CE2\u6B21 1, ### \u6CE2\u6B21 2 \u7B49\uFF09\n2. \u6CE2\u6B21\u5206\u914D\u5FC5\u987B\u6839\u636E @depends \u4F9D\u8D56\u5173\u7CFB\u8BA1\u7B97\uFF08\u6CE2\u6B21 1 = \u65E0\u4F9D\u8D56\uFF0C\u6CE2\u6B21 N = \u4F9D\u8D56\u6CE2\u6B21 N-1\uFF09\n3. \u4EFB\u52A1\u4E0D\u80FD\u51FA\u73B0\u5728\u5176\u4F9D\u8D56\u7684\u4EFB\u52A1\u4E4B\u524D\n4. \u5FC5\u987B\u5728\u6587\u4EF6\u672B\u5C3E\u6DFB\u52A0 \"## \u4F9D\u8D56\u5206\u6790\" \u7AE0\u8282\u5E76\u6807\u660E\"\u72B6\u6001\uFF1A\u5DF2\u5B8C\u6210\"\n5. validate --strict \u4F1A\u9A8C\u8BC1\u4EFB\u52A1\u6392\u5E8F\u662F\u5426\u4E0E\u8BA1\u7B97\u7684\u6CE2\u6B21\u5339\u914D\n\n5. **\u5728\u9700\u8981\u65F6\u521B\u5EFA design.md\uFF1A**\n\u5982\u679C\u4EE5\u4E0B\u4EFB\u4F55\u60C5\u51B5\u9002\u7528\uFF0C\u5219\u521B\u5EFA `design.md`\uFF1B\u5426\u5219\u7701\u7565\uFF1A\n- \u6A2A\u5207\u53D8\u66F4\uFF08\u591A\u4E2A\u670D\u52A1/\u6A21\u5757\uFF09\u6216\u65B0\u7684\u67B6\u6784\u6A21\u5F0F\n- \u65B0\u7684\u5916\u90E8\u4F9D\u8D56\u6216\u91CD\u8981\u7684\u6570\u636E\u6A21\u578B\u66F4\u6539\n- \u5B89\u5168\u6027\u3001\u6027\u80FD\u6216\u8FC1\u79FB\u590D\u6742\u6027\n- \u5728\u7F16\u7801\u4E4B\u524D\u4ECE\u6280\u672F\u51B3\u7B56\u4E2D\u53D7\u76CA\u7684\u6A21\u7CCA\u6027\n\n\u6700\u5C0F `design.md` \u9AA8\u67B6\uFF1A\n```markdown\n## \u80CC\u666F\n[\u80CC\u666F\u3001\u7EA6\u675F\u3001\u5229\u76CA\u76F8\u5173\u8005]\n\n## \u76EE\u6807 / \u975E\u76EE\u6807\n- Goals: [...]\n- Non-Goals: [...]\n\n## \u51B3\u7B56\n- Decision: [\u5185\u5BB9\u548C\u539F\u56E0]\n- Alternatives considered: [\u9009\u9879 + \u7406\u7531]\n\n## \u98CE\u9669 / \u6743\u8861\n- [\u98CE\u9669] \u2192 \u7F13\u89E3\u63AA\u65BD\n\n## \u8FC1\u79FB\u8BA1\u5212\n[\u6B65\u9AA4\u3001\u56DE\u6EDA]\n\n## \u5F85\u89E3\u51B3\u95EE\u9898\n- [...]\n```\n\n## \u89C4\u8303\u6587\u4EF6\u683C\u5F0F\n\n### \u5173\u952E\uFF1A\u573A\u666F\u683C\u5F0F\n\n**\u6B63\u786E**\uFF08\u4F7F\u7528 #### \u6807\u9898\uFF09\uFF1A\n```markdown\n#### \u573A\u666F\uFF1A\u7528\u6237\u767B\u5F55\u6210\u529F\n- **\u5F53** \u63D0\u4F9B\u4E86\u6709\u6548\u51ED\u636E\n- **\u5219** \u8FD4\u56DE JWT token\n```\n\n**\u9519\u8BEF**\uFF08\u4E0D\u8981\u4F7F\u7528\u9879\u76EE\u7B26\u53F7\u6216\u7C97\u4F53\uFF09\uFF1A\n```markdown\n- **\u573A\u666F\uFF1A\u7528\u6237\u767B\u5F55** \u274C\n**\u573A\u666F**\uFF1A\u7528\u6237\u767B\u5F55 \u274C\n### \u573A\u666F\uFF1A\u7528\u6237\u767B\u5F55 \u274C\n```\n\n\u6BCF\u4E2A\u8981\u6C42\u5FC5\u987B\u81F3\u5C11\u6709\u4E00\u4E2A\u573A\u666F\u3002\n\n### \u8981\u6C42\u63AA\u8F9E\n- \u5BF9\u89C4\u8303\u6027\u8981\u6C42\u4F7F\u7528 SHALL/MUST\uFF08\u9664\u975E\u6709\u610F\u975E\u89C4\u8303\u6027\uFF0C\u5426\u5219\u907F\u514D\u4F7F\u7528 should/may\uFF09\n\n### \u589E\u91CF\u64CD\u4F5C\n\n- `## ADDED Requirements` - \u65B0\u529F\u80FD\n- `## MODIFIED Requirements` - \u66F4\u6539\u7684\u884C\u4E3A\n- `## REMOVED Requirements` - \u5DF2\u5F03\u7528\u7684\u529F\u80FD\n- `## RENAMED Requirements` - \u540D\u79F0\u66F4\u6539\n\n\u6807\u9898\u4F7F\u7528 `trim(header)` \u5339\u914D - \u5FFD\u7565\u7A7A\u767D\u3002\n\n#### \u4F55\u65F6\u4F7F\u7528 ADDED vs MODIFIED\n- ADDED\uFF1A\u5F15\u5165\u4E00\u4E2A\u65B0\u7684\u529F\u80FD\u6216\u5B50\u529F\u80FD\uFF0C\u53EF\u4EE5\u72EC\u7ACB\u4F5C\u4E3A\u8981\u6C42\u3002\u5F53\u66F4\u6539\u662F\u6B63\u4EA4\u7684\uFF08\u4F8B\u5982\uFF0C\u6DFB\u52A0\"\u659C\u6760\u547D\u4EE4\u914D\u7F6E\"\uFF09\u800C\u4E0D\u662F\u6539\u53D8\u73B0\u6709\u8981\u6C42\u7684\u8BED\u4E49\u65F6\uFF0C\u4F18\u5148\u4F7F\u7528 ADDED\u3002\n- MODIFIED\uFF1A\u66F4\u6539\u73B0\u6709\u8981\u6C42\u7684\u884C\u4E3A\u3001\u8303\u56F4\u6216\u9A8C\u6536\u6807\u51C6\u3002\u59CB\u7EC8\u7C98\u8D34\u5B8C\u6574\u7684\u3001\u66F4\u65B0\u7684\u8981\u6C42\u5185\u5BB9\uFF08\u6807\u9898 + \u6240\u6709\u573A\u666F\uFF09\u3002\u5F52\u6863\u5668\u5C06\u7528\u60A8\u5728\u6B64\u5904\u63D0\u4F9B\u7684\u5185\u5BB9\u66FF\u6362\u6574\u4E2A\u8981\u6C42\uFF1B\u90E8\u5206\u589E\u91CF\u5C06\u4E22\u5931\u5148\u524D\u7684\u8BE6\u7EC6\u4FE1\u606F\u3002\n- RENAMED\uFF1A\u4EC5\u5728\u540D\u79F0\u66F4\u6539\u65F6\u4F7F\u7528\u3002\u5982\u679C\u60A8\u8FD8\u66F4\u6539\u884C\u4E3A\uFF0C\u8BF7\u4F7F\u7528 RENAMED\uFF08\u540D\u79F0\uFF09\u52A0\u4E0A MODIFIED\uFF08\u5185\u5BB9\uFF09\uFF0C\u5F15\u7528\u65B0\u540D\u79F0\u3002\n\n\u5E38\u89C1\u9677\u9631\uFF1A\u4F7F\u7528 MODIFIED \u6DFB\u52A0\u65B0\u5173\u6CE8\u70B9\u800C\u4E0D\u5305\u542B\u5148\u524D\u7684\u6587\u672C\u3002\u8FD9\u4F1A\u5728\u5F52\u6863\u65F6\u5BFC\u81F4\u8BE6\u7EC6\u4FE1\u606F\u4E22\u5931\u3002\u5982\u679C\u60A8\u6CA1\u6709\u660E\u786E\u66F4\u6539\u73B0\u6709\u8981\u6C42\uFF0C\u8BF7\u5728 ADDED \u4E0B\u6DFB\u52A0\u65B0\u8981\u6C42\u3002\n\n\u6B63\u786E\u7F16\u5199 MODIFIED \u8981\u6C42\uFF1A\n1) \u5728 `zhuanspec/specs/<capability>/spec.md` \u4E2D\u627E\u5230\u73B0\u6709\u8981\u6C42\u3002\n2) \u590D\u5236\u6574\u4E2A\u8981\u6C42\u5757\uFF08\u4ECE `### Requirement: ...` \u5230\u5176\u573A\u666F\uFF09\u3002\n3) \u5C06\u5176\u7C98\u8D34\u5230 `## MODIFIED Requirements` \u4E0B\u5E76\u7F16\u8F91\u4EE5\u53CD\u6620\u65B0\u884C\u4E3A\u3002\n4) \u786E\u4FDD\u6807\u9898\u6587\u672C\u5B8C\u5168\u5339\u914D\uFF08\u5FFD\u7565\u7A7A\u767D\uFF09\u5E76\u81F3\u5C11\u4FDD\u7559\u4E00\u4E2A `#### Scenario:`\u3002\n\nRENAMED \u793A\u4F8B\uFF1A\n```markdown\n## RENAMED Requirements\n- FROM: `### \u9700\u6C42\uFF1ALogin`\n- TO: `### \u9700\u6C42\uFF1AUser Authentication`\n```\n\n## \u6545\u969C\u6392\u9664\n\n### \u5E38\u89C1\u9519\u8BEF\n\n**\"\u53D8\u66F4\u5FC5\u987B\u81F3\u5C11\u6709\u4E00\u4E2A\u589E\u91CF\"**\n- \u68C0\u67E5 `changes/[name]/specs/` \u662F\u5426\u5B58\u5728 .md \u6587\u4EF6\n- \u9A8C\u8BC1\u6587\u4EF6\u5177\u6709\u64CD\u4F5C\u524D\u7F00\uFF08## ADDED Requirements\uFF09\n\n**\"\u8981\u6C42\u5FC5\u987B\u81F3\u5C11\u6709\u4E00\u4E2A\u573A\u666F\"**\n- \u68C0\u67E5\u573A\u666F\u662F\u5426\u4F7F\u7528 `#### Scenario:` \u683C\u5F0F\uFF084 \u4E2A\u4E95\u53F7\uFF09\n- \u4E0D\u8981\u5BF9\u573A\u666F\u6807\u9898\u4F7F\u7528\u9879\u76EE\u7B26\u53F7\u6216\u7C97\u4F53\n\n**\u9759\u9ED8\u573A\u666F\u89E3\u6790\u5931\u8D25**\n- \u9700\u8981\u7CBE\u786E\u683C\u5F0F\uFF1A`#### Scenario: Name`\n- \u4F7F\u7528\u4EE5\u4E0B\u547D\u4EE4\u8C03\u8BD5\uFF1A`zhuanspec show [change] --json --deltas-only`\n\n### \u9A8C\u8BC1\u63D0\u793A\n\n```bash\n# \u59CB\u7EC8\u4F7F\u7528\u4E25\u683C\u6A21\u5F0F\u8FDB\u884C\u5168\u9762\u68C0\u67E5\nzhuanspec validate [change] --strict\n\n# \u8C03\u8BD5\u589E\u91CF\u89E3\u6790\nzhuanspec show [change] --json | jq '.deltas'\n\n# \u68C0\u67E5\u7279\u5B9A\u8981\u6C42\nzhuanspec show [spec] --json -r 1\n```\n\n## \u7406\u60F3\u8DEF\u5F84\u811A\u672C\n\n```bash\n# 1) \u63A2\u7D22\u5F53\u524D\u72B6\u6001\nzhuanspec spec list --long\nzhuanspec list\n# \u53EF\u9009\u5168\u6587\u641C\u7D22\uFF1A\n# rg -n \"Requirement:|Scenario:\" zhuanspec/specs\n# rg -n \"^#|Requirement:\" zhuanspec/changes\n\n# 2) \u9009\u62E9\u53D8\u66F4 ID \u5E76\u642D\u5EFA\nCHANGE=add-two-factor-auth\nmkdir -p zhuanspec/changes/$CHANGE/{specs/auth}\nprintf \"## \u53D8\u66F4\u539F\u56E0\\n...\\n\\n## \u53D8\u66F4\u5185\u5BB9\\n- ...\\n\\n## \u5F71\u54CD\u8303\u56F4\\n- ...\\n\" > zhuanspec/changes/\\$CHANGE/proposal.md\nprintf \"## 1. \u5B9E\u73B0\n- [ ] 1.1 ...\n\" > zhuanspec/changes/$CHANGE/tasks.md\n\n# 3) \u6DFB\u52A0\u589E\u91CF\uFF08\u793A\u4F8B\uFF09\ncat > zhuanspec/changes/$CHANGE/specs/auth/spec.md << 'EOF'\n## ADDED Requirements\n### \u9700\u6C42\uFF1A\u53CC\u56E0\u7D20\u8BA4\u8BC1\n\u7528\u6237 MUST \u5728\u767B\u5F55\u65F6\u63D0\u4F9B\u7B2C\u4E8C\u4E2A\u8BA4\u8BC1\u56E0\u7D20\u3002\n\n#### \u573A\u666F\uFF1A\u9700\u8981 OTP\n- **\u5F53** \u63D0\u4F9B\u4E86\u6709\u6548\u51ED\u636E\n- **\u5219** \u9700\u8981 OTP \u6311\u6218\nEOF\n\n# 4) \u9A8C\u8BC1\nzhuanspec validate $CHANGE --strict\n```\n\n## \u591A\u529F\u80FD\u793A\u4F8B\n\n```\nzhuanspec/changes/add-2fa-notify/\n\u251C\u2500\u2500 proposal.md\n\u251C\u2500\u2500 tasks.md\n\u2514\u2500\u2500 specs/\n \u251C\u2500\u2500 auth/\n \u2502 \u2514\u2500\u2500 spec.md # ADDED: \u53CC\u56E0\u7D20\u8BA4\u8BC1\n \u2514\u2500\u2500 notifications/\n \u2514\u2500\u2500 spec.md # ADDED: OTP \u90AE\u4EF6\u901A\u77E5\n```\n\nauth/spec.md\n```markdown\n## ADDED Requirements\n### \u9700\u6C42\uFF1A\u53CC\u56E0\u7D20\u8BA4\u8BC1\n...\n```\n\nnotifications/spec.md\n```markdown\n## ADDED Requirements\n### \u9700\u6C42\uFF1AOTP \u90AE\u4EF6\u901A\u77E5\n...\n```\n\n## \u6700\u4F73\u5B9E\u8DF5\n\n### \u7B80\u5355\u4F18\u5148\n- \u9ED8\u8BA4\u65B0\u589E\u4EE3\u7801 <100 \u884C\n- \u5355\u6587\u4EF6\u5B9E\u73B0\uFF0C\u76F4\u5230\u8BC1\u660E\u4E0D\u8DB3\n- \u907F\u514D\u6CA1\u6709\u660E\u786E\u7406\u7531\u7684\u6846\u67B6\n- \u9009\u62E9\u65E0\u804A\u4F46\u7ECF\u8FC7\u9A8C\u8BC1\u7684\u6A21\u5F0F\n\n### \u590D\u6742\u6027\u89E6\u53D1\u6761\u4EF6\n\u4EC5\u5728\u4EE5\u4E0B\u60C5\u51B5\u4E0B\u6DFB\u52A0\u590D\u6742\u6027\uFF1A\n- \u6027\u80FD\u6570\u636E\u8868\u660E\u5F53\u524D\u89E3\u51B3\u65B9\u6848\u592A\u6162\n- \u5177\u4F53\u7684\u89C4\u6A21\u8981\u6C42\uFF08>1000 \u7528\u6237\uFF0C>100MB \u6570\u636E\uFF09\n- \u591A\u4E2A\u7ECF\u8FC7\u9A8C\u8BC1\u7684\u7528\u4F8B\u9700\u8981\u62BD\u8C61\n\n### \u6E05\u6670\u7684\u5F15\u7528\n- \u4F7F\u7528 `file.ts:42` \u683C\u5F0F\u8868\u793A\u4EE3\u7801\u4F4D\u7F6E\n- \u5C06\u89C4\u8303\u5F15\u7528\u4E3A `specs/auth/spec.md`\n- \u94FE\u63A5\u76F8\u5173\u53D8\u66F4\u548C PR\n\n### \u529F\u80FD\u547D\u540D\n- \u4F7F\u7528\u52A8\u8BCD-\u540D\u8BCD\uFF1A`user-auth`\u3001`payment-capture`\n- \u6BCF\u4E2A\u529F\u80FD\u5355\u4E00\u76EE\u7684\n- 10 \u5206\u949F\u53EF\u7406\u89E3\u6027\u89C4\u5219\n- \u5982\u679C\u63CF\u8FF0\u9700\u8981\"AND\"\uFF0C\u5219\u62C6\u5206\n\n### \u53D8\u66F4 ID \u547D\u540D\n- \u4F7F\u7528 kebab-case\uFF0C\u7B80\u77ED\u4E14\u63CF\u8FF0\u6027\uFF1A`add-two-factor-auth`\n- \u4F18\u5148\u4F7F\u7528\u52A8\u8BCD\u5F00\u5934\u7684\u524D\u7F00\uFF1A`add-`\u3001`update-`\u3001`remove-`\u3001`refactor-`\n- \u786E\u4FDD\u552F\u4E00\u6027\uFF1B\u5982\u679C\u5DF2\u4F7F\u7528\uFF0C\u8FFD\u52A0 `-2`\u3001`-3` \u7B49\n\n## \u5DE5\u5177\u9009\u62E9\u6307\u5357\n\n| \u4EFB\u52A1 | \u5DE5\u5177 | \u539F\u56E0 |\n|------|------|-----|\n| \u6309\u6A21\u5F0F\u67E5\u627E\u6587\u4EF6 | Glob | \u5FEB\u901F\u6A21\u5F0F\u5339\u914D |\n| \u641C\u7D22\u4EE3\u7801\u5185\u5BB9 | Grep | \u4F18\u5316\u7684\u6B63\u5219\u8868\u8FBE\u5F0F\u641C\u7D22 |\n| \u8BFB\u53D6\u7279\u5B9A\u6587\u4EF6 | Read | \u76F4\u63A5\u6587\u4EF6\u8BBF\u95EE |\n| \u63A2\u7D22\u672A\u77E5\u8303\u56F4 | Task | \u591A\u6B65\u9AA4\u8C03\u67E5 |\n\n## \u9519\u8BEF\u6062\u590D\n\n### \u53D8\u66F4\u51B2\u7A81\n1. \u8FD0\u884C `zhuanspec list` \u67E5\u770B\u6D3B\u52A8\u53D8\u66F4\n2. \u68C0\u67E5\u91CD\u53E0\u7684\u89C4\u8303\n3. \u4E0E\u53D8\u66F4\u6240\u6709\u8005\u534F\u8C03\n4. \u8003\u8651\u5408\u5E76\u63D0\u6848\n\n### \u9A8C\u8BC1\u5931\u8D25\n1. \u4F7F\u7528 `--strict` \u6807\u5FD7\u8FD0\u884C\n2. \u68C0\u67E5 JSON \u8F93\u51FA\u4EE5\u83B7\u53D6\u8BE6\u7EC6\u4FE1\u606F\n3. \u9A8C\u8BC1\u89C4\u8303\u6587\u4EF6\u683C\u5F0F\n4. \u786E\u4FDD\u573A\u666F\u683C\u5F0F\u6B63\u786E\n\n### \u7F3A\u5C11\u4E0A\u4E0B\u6587\n1. \u9996\u5148\u9605\u8BFB project.md\n2. \u68C0\u67E5\u76F8\u5173\u89C4\u8303\n3. \u5BA1\u67E5\u6700\u8FD1\u7684\u5F52\u6863\n4. \u8BF7\u6C42\u6F84\u6E05\n\n## \u5FEB\u901F\u53C2\u8003\n\n### \u9636\u6BB5\u6307\u793A\u5668\n- `changes/` - \u5DF2\u63D0\u8BAE\uFF0C\u5C1A\u672A\u6784\u5EFA\n- `specs/` - \u5DF2\u6784\u5EFA\u5E76\u90E8\u7F72\n- `archive/` - \u5DF2\u5B8C\u6210\u7684\u53D8\u66F4\n\n### \u6587\u4EF6\u7528\u9014\n- `proposal.md` - \u539F\u56E0\u548C\u5185\u5BB9\n- `tasks.md` - \u5B9E\u65BD\u6B65\u9AA4\n- `design.md` - \u6280\u672F\u51B3\u7B56\n- `spec.md` - \u8981\u6C42\u548C\u884C\u4E3A\n\n### CLI \u8981\u70B9\n```bash\nzhuanspec list # \u6B63\u5728\u8FDB\u884C\u4EC0\u4E48\uFF1F\nzhuanspec show [item] # \u67E5\u770B\u8BE6\u7EC6\u4FE1\u606F\nzhuanspec validate --strict # \u662F\u5426\u6B63\u786E\uFF1F\nzhuanspec archive <change-id> [--yes|-y] # \u6807\u8BB0\u5B8C\u6210\uFF08\u6DFB\u52A0 --yes \u7528\u4E8E\u81EA\u52A8\u5316\uFF09\n```\n\n\u8BB0\u4F4F\uFF1A\u89C4\u8303\u662F\u771F\u76F8\u3002\u53D8\u66F4\u662F\u63D0\u6848\u3002\u4FDD\u6301\u5B83\u4EEC\u540C\u6B65\u3002\n\n## \u4EFB\u52A1\u6267\u884C\u7F16\u6392\n\n\u5F53 apply \u6307\u4EE4\u4E2D\u5305\u542B `<execution_plan>`/task.md\u4E2D\u5305\u542B `@depends` \u65F6\uFF0C\u5FC5\u987B\u6309\u4EE5\u4E0B\u7B56\u7565\u6267\u884C\u4EFB\u52A1\uFF0C\u800C\u975E\u987A\u5E8F\u9010\u4E00\u6267\u884C\u3002\n\n### \u8C03\u5EA6\u89C4\u5219\n\n1. **\u6309 wave \u7F16\u53F7\u4ECE\u5C0F\u5230\u5927**\u4F9D\u6B21\u6267\u884C\uFF0Cwave \u4E4B\u95F4\u4E25\u683C\u4E32\u884C\n2. **\u540C\u4E00 wave \u5185\u7684\u591A\u4E2A task**\uFF1A\u4E3A\u6BCF\u4E2A task \u542F\u52A8\u72EC\u7ACB\u7684 subagent\uFF08Coding \u7C7B\u578B\uFF09\uFF0C\u6240\u6709 subagent \u5E76\u884C\u6267\u884C\n3. **\u7B49\u5F85\u672C wave \u6240\u6709 subagent \u5B8C\u6210\u540E**\uFF0C\u624D\u542F\u52A8\u4E0B\u4E00 wave\n4. \u540C\u4E00 wave \u5185\u4EC5\u6709\u4E00\u4E2A task \u65F6\uFF0C\u542F\u52A8\u5355\u4E2A subagent \u6267\u884C\n5. **\u53C2\u8003 `<scheduling_summary>` \u4E2D\u7684\u5177\u4F53\u8C03\u5EA6\u6307\u4EE4**\uFF0C\u660E\u786E\u6BCF\u4E2A wave \u9700\u8981\u542F\u52A8\u7684 subagent \u6570\u91CF\u548C\u6267\u884C\u65B9\u5F0F\n\n### \u8C03\u5EA6\u6307\u4EE4\u683C\u5F0F\n\n\u6267\u884C\u8BA1\u5212\u7684 `<wave>` \u5143\u7D20\u5305\u542B\u4EE5\u4E0B\u5C5E\u6027\u7528\u4E8E\u6307\u5BFC subagent \u8C03\u5EA6\uFF1A\n- `subagent_count`\uFF1A\u8BE5\u6CE2\u6B21\u9700\u8981\u542F\u52A8\u7684 subagent \u6570\u91CF\uFF08\u7B49\u4E8E wave \u5185\u7684\u4EFB\u52A1\u6570\uFF09\n- `execution_mode`\uFF1A\u6267\u884C\u6A21\u5F0F\uFF0C`parallel`\uFF08\u5E76\u884C\uFF09\u6216 `serial`\uFF08\u4E32\u884C\uFF09\n\n`<scheduling_summary>` \u63D0\u4F9B\u4EBA\u7C7B\u53EF\u8BFB\u7684\u8C03\u5EA6\u6458\u8981\uFF0C\u683C\u5F0F\u5982\u4E0B\uFF1A\n```\nWave 1 \u2192 \u542F\u52A8 1 \u4E2A subagent \u6267\u884C\u8BE5\u6CE2\u6B21\u7684\u5355\u4E2A\u4EFB\u52A1\nWave 2 \u2192 \u542F\u52A8 1 \u4E2A subagent \u6267\u884C\u8BE5\u6CE2\u6B21\u7684\u5355\u4E2A\u4EFB\u52A1\nWave 3 \u2192 \u542F\u52A8 2 \u4E2A subagent \u5E76\u884C\u6267\u884C\u8BE5\u6CE2\u6B21\u7684 2 \u4E2A\u4EFB\u52A1\n```\n\nAI \u52A9\u624B\u5728\u6267\u884C\u65F6**\u5FC5\u987B**\u6309\u7167 `<scheduling_summary>` \u4E2D\u7684\u6307\u4EE4\u542F\u52A8\u5BF9\u5E94\u6570\u91CF\u7684 subagent\u3002\n\n### Subagent \u4E0A\u4E0B\u6587\u9694\u79BB\n\n\u6BCF\u4E2A subagent \u7684 prompt \u4E2D**\u4EC5\u5305\u542B**\uFF1A\n- \u5F53\u524D task \u7684\u63CF\u8FF0\u548C\u9A8C\u6536\u6807\u51C6\n- \u5F53\u524D task \u5173\u8054\u7684 `@skill` \u5185\u5BB9\uFF08\u901A\u8FC7 skill \u540D\u79F0\u89E6\u53D1\u52A0\u8F7D\uFF09\n- \u76F8\u5173\u7684 spec \u6587\u4EF6\u8DEF\u5F84\u548C\u5185\u5BB9\uFF08\u4EC5\u9650\u8BE5 task \u6D89\u53CA\u7684\u90E8\u5206\uFF09\n- \u524D\u5E8F wave \u7684\u5B8C\u6210\u6458\u8981\uFF08\u800C\u975E\u5B8C\u6574\u8F93\u51FA\uFF09\n\n**\u7981\u6B62**\u5411 subagent \u6CE8\u5165\uFF1A\n- \u5176\u4ED6 wave \u7684 task \u8BE6\u60C5\n- \u4E0D\u76F8\u5173\u7684 skill \u5185\u5BB9\n- \u5176\u4ED6 subagent \u7684\u5B8C\u6574\u8F93\u51FA\n\n### \u5B8C\u6210\u540C\u6B65\n\n- \u6BCF\u4E2A subagent \u5B8C\u6210\u540E\uFF0C\u63D0\u53D6\u7B80\u77ED\u7684**\u5B8C\u6210\u6458\u8981**\uFF08\u4FEE\u6539\u4E86\u54EA\u4E9B\u6587\u4EF6\u3001\u5173\u952E\u53D8\u66F4\u70B9\uFF09\n- \u5C06\u6458\u8981\u4F20\u9012\u7ED9\u540E\u7EED wave \u7684 subagent \u4F5C\u4E3A\u4E0A\u4E0B\u6587\n- \u5728 `tasks.md` \u4E2D\u5C06\u5BF9\u5E94\u4EFB\u52A1\u6807\u8BB0\u4E3A `[x]`\n\n### \u964D\u7EA7\u7B56\u7565\n\n\u5F53 AI \u5E73\u53F0\u4E0D\u652F\u6301 subagent \u65F6\uFF0C\u6309\u4EE5\u4E0B\u964D\u7EA7\u7B56\u7565\u6267\u884C\uFF1A\n1. \u4ECD\u6309 wave \u987A\u5E8F\u6267\u884C\u4EFB\u52A1\n2. \u6BCF\u4E2A task \u6267\u884C\u524D\uFF0C\u6E05\u7406\u4E0D\u76F8\u5173\u7684 skill \u4E0A\u4E0B\u6587\n3. \u6BCF\u4E2A task \u6267\u884C\u540E\uFF0C\u4EC5\u4FDD\u7559\u5B8C\u6210\u6458\u8981\uFF0C\u907F\u514D\u4E0A\u4E0B\u6587\u7D2F\u79EF\u81A8\u80C0\n";
2
2
  //# sourceMappingURL=agents-template.d.ts.map
@@ -743,6 +743,22 @@ zhuanspec archive <change-id> [--yes|-y] # 标记完成(添加 --yes 用于
743
743
  2. **同一 wave 内的多个 task**:为每个 task 启动独立的 subagent(Coding 类型),所有 subagent 并行执行
744
744
  3. **等待本 wave 所有 subagent 完成后**,才启动下一 wave
745
745
  4. 同一 wave 内仅有一个 task 时,启动单个 subagent 执行
746
+ 5. **参考 \`<scheduling_summary>\` 中的具体调度指令**,明确每个 wave 需要启动的 subagent 数量和执行方式
747
+
748
+ ### 调度指令格式
749
+
750
+ 执行计划的 \`<wave>\` 元素包含以下属性用于指导 subagent 调度:
751
+ - \`subagent_count\`:该波次需要启动的 subagent 数量(等于 wave 内的任务数)
752
+ - \`execution_mode\`:执行模式,\`parallel\`(并行)或 \`serial\`(串行)
753
+
754
+ \`<scheduling_summary>\` 提供人类可读的调度摘要,格式如下:
755
+ \`\`\`
756
+ Wave 1 → 启动 1 个 subagent 执行该波次的单个任务
757
+ Wave 2 → 启动 1 个 subagent 执行该波次的单个任务
758
+ Wave 3 → 启动 2 个 subagent 并行执行该波次的 2 个任务
759
+ \`\`\`
760
+
761
+ AI 助手在执行时**必须**按照 \`<scheduling_summary>\` 中的指令启动对应数量的 subagent。
746
762
 
747
763
  ### Subagent 上下文隔离
748
764
 
@@ -53,6 +53,17 @@ export declare function checkSkillTagsValid(tasksContent: string, parsedTasks: P
53
53
  * - Tasks.md must have Wave headers
54
54
  */
55
55
  export declare function checkTaskOrderingByWave(tasksContent: string, parsedTasks: ParsedTask[]): StrictCheckResult;
56
+ /**
57
+ * Rule 4: subagent-directives-valid
58
+ *
59
+ * Validates that the generated execution plan XML contains proper subagent directives:
60
+ * - Each <wave> element has subagent_count and execution_mode attributes
61
+ * - subagent_count matches the number of tasks in the wave
62
+ * - execution_mode is 'parallel' when subagent_count > 1, 'serial' when subagent_count == 1
63
+ * - <scheduling_summary> section exists with entries for each wave
64
+ * - Each scheduling_summary entry correctly describes subagent count and execution mode
65
+ */
66
+ export declare function checkSubagentDirectives(parsedTasks: ParsedTask[]): StrictCheckResult;
56
67
  /**
57
68
  * Main entry: Run all strict validation rules
58
69
  */
@@ -7,6 +7,7 @@
7
7
  * 3. task-ordering-by-wave: Verify task ordering follows wave structure
8
8
  */
9
9
  import { generateExecutionPlan } from '../task-graph/execution-planner.js';
10
+ import { renderExecutionPlanXml } from '../task-graph/xml-renderer.js';
10
11
  // Patterns for detecting unresolved markers
11
12
  const UNRESOLVED_MARKERS = /\b(TODO|TBD|PENDING|\?)\b/i;
12
13
  const HTML_COMMENT_PATTERN = /<!--[\s\S]*?-->/g;
@@ -269,6 +270,72 @@ export function checkTaskOrderingByWave(tasksContent, parsedTasks) {
269
270
  result.passed = result.errors.length === 0;
270
271
  return result;
271
272
  }
273
+ /**
274
+ * Rule 4: subagent-directives-valid
275
+ *
276
+ * Validates that the generated execution plan XML contains proper subagent directives:
277
+ * - Each <wave> element has subagent_count and execution_mode attributes
278
+ * - subagent_count matches the number of tasks in the wave
279
+ * - execution_mode is 'parallel' when subagent_count > 1, 'serial' when subagent_count == 1
280
+ * - <scheduling_summary> section exists with entries for each wave
281
+ * - Each scheduling_summary entry correctly describes subagent count and execution mode
282
+ */
283
+ export function checkSubagentDirectives(parsedTasks) {
284
+ const result = {
285
+ ruleId: 'subagent-directives-valid',
286
+ ruleName: 'Subagent directives valid',
287
+ passed: false,
288
+ errors: [],
289
+ warnings: [],
290
+ };
291
+ // If no tasks, consider it valid
292
+ if (parsedTasks.length === 0) {
293
+ result.passed = true;
294
+ return result;
295
+ }
296
+ // Generate execution plan
297
+ const executionPlan = generateExecutionPlan(parsedTasks);
298
+ if (executionPlan.hasCycle) {
299
+ result.errors.push('Task dependency graph has cycles, cannot validate subagent directives');
300
+ return result;
301
+ }
302
+ if (executionPlan.waves.length === 0) {
303
+ result.passed = true;
304
+ return result;
305
+ }
306
+ // Render XML to validate its structure
307
+ const xml = renderExecutionPlanXml(executionPlan);
308
+ // Validate each wave has subagent_count and execution_mode attributes
309
+ for (const wave of executionPlan.waves) {
310
+ const taskCount = wave.tasks.length;
311
+ const expectedMode = taskCount > 1 ? 'parallel' : 'serial';
312
+ // Check subagent_count attribute exists with correct value
313
+ const subagentCountPattern = new RegExp(`<wave[^>]*number="${wave.wave}"[^>]*subagent_count="${taskCount}"`);
314
+ if (!subagentCountPattern.test(xml)) {
315
+ result.errors.push(`Wave ${wave.wave}: missing or incorrect subagent_count attribute (expected ${taskCount})`);
316
+ }
317
+ // Check execution_mode attribute exists with correct value
318
+ const executionModePattern = new RegExp(`<wave[^>]*number="${wave.wave}"[^>]*execution_mode="${expectedMode}"`);
319
+ if (!executionModePattern.test(xml)) {
320
+ result.errors.push(`Wave ${wave.wave}: missing or incorrect execution_mode attribute (expected "${expectedMode}")`);
321
+ }
322
+ }
323
+ // Validate scheduling_summary section exists
324
+ if (!xml.includes('<scheduling_summary>')) {
325
+ result.errors.push('Missing <scheduling_summary> section in orchestration_strategy');
326
+ }
327
+ else {
328
+ // Validate each wave has a scheduling summary entry
329
+ for (const wave of executionPlan.waves) {
330
+ const waveSummaryPattern = new RegExp(`Wave ${wave.wave} \u2192`);
331
+ if (!waveSummaryPattern.test(xml)) {
332
+ result.errors.push(`Wave ${wave.wave}: missing scheduling summary entry in <scheduling_summary>`);
333
+ }
334
+ }
335
+ }
336
+ result.passed = result.errors.length === 0;
337
+ return result;
338
+ }
272
339
  /**
273
340
  * Main entry: Run all strict validation rules
274
341
  */
@@ -277,6 +344,7 @@ export async function runStrictValidation(tasksContent, parsedTasks, knownSkillN
277
344
  checkPreClarification(tasksContent),
278
345
  checkSkillTagsValid(tasksContent, parsedTasks, knownSkillNames),
279
346
  checkTaskOrderingByWave(tasksContent, parsedTasks),
347
+ checkSubagentDirectives(parsedTasks),
280
348
  ];
281
349
  const allPassed = checks.every(check => check.passed);
282
350
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhuan-ai/zhuanspec",
3
- "version": "2.1.3",
3
+ "version": "2.2.1",
4
4
  "description": "AI-native system for spec-driven development",
5
5
  "keywords": [
6
6
  "zhuanspec",