sdd-tool 1.2.5 → 1.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +220 -32
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1627,12 +1627,16 @@ var startCommand = {
|
|
|
1627
1627
|
|
|
1628
1628
|
1. \uBA3C\uC800 \uD504\uB85C\uC81D\uD2B8 \uAD6C\uC870\uB97C \uBD84\uC11D\uD558\uC138\uC694:
|
|
1629
1629
|
- .sdd/ \uB514\uB809\uD1A0\uB9AC \uC874\uC7AC \uC5EC\uBD80 \uD655\uC778
|
|
1630
|
+
- .sdd/specs/ \uB514\uB809\uD1A0\uB9AC \uB0B4 \uC2A4\uD399 \uD30C\uC77C \uC874\uC7AC \uC5EC\uBD80 \uD655\uC778
|
|
1631
|
+
- src/ \uB610\uB294 lib/ \uB4F1 \uAE30\uC874 \uCF54\uB4DC \uC874\uC7AC \uC5EC\uBD80 \uD655\uC778 (\uBE0C\uB77C\uC6B4\uD544\uB4DC \uD310\uBCC4)
|
|
1630
1632
|
- .git/ \uB514\uB809\uD1A0\uB9AC \uC874\uC7AC \uC5EC\uBD80 \uD655\uC778
|
|
1631
1633
|
- .git/hooks/ \uB514\uB809\uD1A0\uB9AC\uC758 SDD \uD6C5 \uC124\uCE58 \uC5EC\uBD80 \uD655\uC778
|
|
1632
1634
|
- .github/workflows/ \uB514\uB809\uD1A0\uB9AC\uC758 SDD \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC874\uC7AC \uC5EC\uBD80 \uD655\uC778
|
|
1633
1635
|
|
|
1634
1636
|
2. \uBD84\uC11D \uACB0\uACFC\uC5D0 \uB530\uB77C \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC548\uB0B4\uD558\uC138\uC694:
|
|
1635
1637
|
- SDD \uBBF8\uCD08\uAE30\uD654: \`sdd init\` \uC2E4\uD589 \uAD8C\uC7A5
|
|
1638
|
+
- **\uAE30\uC874 \uCF54\uB4DC\uAC00 \uC788\uACE0 \uC2A4\uD399\uC774 \uC5C6\uC74C (\uBE0C\uB77C\uC6B4\uD544\uB4DC)**: \`/sdd.reverse\` \uC2E4\uD589 \uAD8C\uC7A5
|
|
1639
|
+
- \uC2A4\uD399 \uC5C6\uC74C (\uADF8\uB9B0\uD544\uB4DC): \`/sdd.new\` \uC2E4\uD589 \uAD8C\uC7A5
|
|
1636
1640
|
- Git Hooks \uBBF8\uC124\uCE58: Git \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC124\uC815 \uAD8C\uC7A5
|
|
1637
1641
|
- CI/CD \uBBF8\uC124\uC815: GitHub Actions \uC124\uC815 \uAD8C\uC7A5
|
|
1638
1642
|
|
|
@@ -1696,7 +1700,23 @@ sdd start --workflow validate
|
|
|
1696
1700
|
\uD504\uB85C\uC81D\uD2B8\uAC00 \uCD08\uAE30\uD654\uB418\uC9C0 \uC54A\uC740 \uACBD\uC6B0:
|
|
1697
1701
|
1. \`sdd init\`\uC73C\uB85C \uD504\uB85C\uC81D\uD2B8\uB97C \uCD08\uAE30\uD654\uD558\uC138\uC694 (Git/CI-CD \uC124\uC815 \uD3EC\uD568)
|
|
1698
1702
|
2. \`/sdd.constitution\`\uC73C\uB85C \uD504\uB85C\uC81D\uD2B8 \uC6D0\uCE59\uC744 \uC815\uC758\uD558\uC138\uC694
|
|
1699
|
-
3.
|
|
1703
|
+
3. \uB2E4\uC74C \uB2E8\uACC4 \uC120\uD0DD:
|
|
1704
|
+
- **\uADF8\uB9B0\uD544\uB4DC** (\uC0C8 \uD504\uB85C\uC81D\uD2B8): \`/sdd.new\`\uB85C \uCCAB \uAE30\uB2A5 \uBA85\uC138\uB97C \uC791\uC131\uD558\uC138\uC694
|
|
1705
|
+
- **\uBE0C\uB77C\uC6B4\uD544\uB4DC** (\uAE30\uC874 \uCF54\uB4DC): \`/sdd.reverse\`\uB85C \uAE30\uC874 \uCF54\uB4DC\uC5D0\uC11C \uC2A4\uD399\uC744 \uCD94\uCD9C\uD558\uC138\uC694
|
|
1706
|
+
|
|
1707
|
+
## \uBE0C\uB77C\uC6B4\uD544\uB4DC \uD504\uB85C\uC81D\uD2B8 (\uAE30\uC874 \uCF54\uB4DC\uBCA0\uC774\uC2A4)
|
|
1708
|
+
|
|
1709
|
+
\uAE30\uC874 \uCF54\uB4DC\uAC00 \uC788\uB294 \uD504\uB85C\uC81D\uD2B8\uC5D0\uC11C SDD\uB97C \uB3C4\uC785\uD560 \uB54C:
|
|
1710
|
+
|
|
1711
|
+
1. **\uC2A4\uD399 \uC5ED\uCD94\uCD9C**: \`/sdd.reverse scan\`\uC73C\uB85C \uD504\uB85C\uC81D\uD2B8 \uAD6C\uC870 \uBD84\uC11D
|
|
1712
|
+
2. **\uC2A4\uD399 \uCD94\uCD9C**: \`/sdd.reverse extract\`\uB85C \uCF54\uB4DC\uC5D0\uC11C \uC2A4\uD399 \uCD08\uC548 \uC0DD\uC131
|
|
1713
|
+
3. **\uB9AC\uBDF0 \uBC0F \uD655\uC815**: \`/sdd.reverse review\` \u2192 \`/sdd.reverse finalize\`
|
|
1714
|
+
4. \uC774\uD6C4 \uC0C8 \uAE30\uB2A5\uC740 \`/sdd.new\`\uB85C \uC791\uC131
|
|
1715
|
+
|
|
1716
|
+
**\uBE0C\uB77C\uC6B4\uD544\uB4DC \uD310\uBCC4 \uAE30\uC900**:
|
|
1717
|
+
- src/, lib/, app/ \uB4F1 \uC18C\uC2A4 \uB514\uB809\uD1A0\uB9AC\uAC00 \uC874\uC7AC
|
|
1718
|
+
- .sdd/specs/ \uC5D0 \uC2A4\uD399 \uD30C\uC77C\uC774 \uC5C6\uAC70\uB098 \uC801\uC74C
|
|
1719
|
+
- package.json, requirements.txt \uB4F1 \uD504\uB85C\uC81D\uD2B8 \uC124\uC815 \uD30C\uC77C \uC874\uC7AC
|
|
1700
1720
|
|
|
1701
1721
|
## Git \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC0C1\uC138
|
|
1702
1722
|
|
|
@@ -2549,75 +2569,121 @@ var reverseCommand = {
|
|
|
2549
2569
|
\uAE30\uC874 \uCF54\uB4DC\uB97C \uBD84\uC11D\uD558\uC5EC SDD \uC2A4\uD399 \uCD08\uC548\uC744 \uC790\uB3D9 \uC0DD\uC131\uD569\uB2C8\uB2E4.
|
|
2550
2570
|
\uB9AC\uBDF0\uC640 \uC2B9\uC778 \uACFC\uC815\uC744 \uD1B5\uD574 \uC815\uC2DD \uC2A4\uD399\uC73C\uB85C \uD655\uC815\uD569\uB2C8\uB2E4.
|
|
2551
2571
|
|
|
2572
|
+
## \uC911\uC694 \uC9C0\uC2DC\uC0AC\uD56D
|
|
2573
|
+
|
|
2574
|
+
**\uBC18\uB4DC\uC2DC CLI \uBA85\uB839\uC5B4\uB97C \uC0AC\uC6A9\uD558\uC138\uC694!**
|
|
2575
|
+
- \uC2A4\uD399 \uD30C\uC77C\uC744 \uC9C1\uC811 \uC791\uC131\uD558\uC9C0 \uB9C8\uC138\uC694
|
|
2576
|
+
- \`sdd reverse <subcommand>\` CLI\uB97C \uC2E4\uD589\uD558\uC138\uC694
|
|
2577
|
+
- \uCD08\uC548\uC740 \`.sdd/.reverse-drafts/\`\uC5D0 \uC800\uC7A5\uB429\uB2C8\uB2E4 (\uC9C1\uC811 \uAC74\uB4DC\uB9AC\uC9C0 \uB9C8\uC138\uC694)
|
|
2578
|
+
- \`.sdd/specs/\`\uC5D0\uB294 finalize \uD6C4\uC5D0\uB9CC \uD30C\uC77C\uC774 \uC0DD\uC131\uB429\uB2C8\uB2E4
|
|
2579
|
+
|
|
2552
2580
|
## \uD558\uC704 \uBA85\uB839\uC5B4
|
|
2553
2581
|
|
|
2554
2582
|
\`\`\`
|
|
2555
|
-
/sdd.reverse scan [path] # \uD504\uB85C\uC81D\uD2B8 \uAD6C\uC870 \uC2A4\uCE94
|
|
2556
|
-
/sdd.reverse extract [path] # \uCF54\uB4DC\uC5D0\uC11C \uC2A4\uD399 \uCD94\uCD9C
|
|
2557
|
-
/sdd.reverse review [spec-id] # \uCD94\uCD9C\uB41C \uC2A4\uD399 \uB9AC\uBDF0
|
|
2558
|
-
/sdd.reverse finalize [spec-id] # \uC2B9\uC778\uB41C \uC2A4\uD399 \uD655\uC815
|
|
2583
|
+
/sdd.reverse scan [path] # \uD504\uB85C\uC81D\uD2B8 \uAD6C\uC870 \uC2A4\uCE94 (CLI \uC2E4\uD589)
|
|
2584
|
+
/sdd.reverse extract [path] # \uCF54\uB4DC\uC5D0\uC11C \uC2A4\uD399 \uCD94\uCD9C (CLI \uC2E4\uD589)
|
|
2585
|
+
/sdd.reverse review [spec-id] # \uCD94\uCD9C\uB41C \uC2A4\uD399 \uB9AC\uBDF0 (CLI \uC2E4\uD589)
|
|
2586
|
+
/sdd.reverse finalize [spec-id] # \uC2B9\uC778\uB41C \uC2A4\uD399 \uD655\uC815 (CLI \uC2E4\uD589)
|
|
2559
2587
|
\`\`\`
|
|
2560
2588
|
|
|
2561
2589
|
## \uC6CC\uD06C\uD50C\uB85C\uC6B0
|
|
2562
2590
|
|
|
2563
2591
|
\`\`\`
|
|
2564
|
-
scan \u2192 extract \u2192 review \u2192 finalize
|
|
2592
|
+
scan (+ \uB3C4\uBA54\uC778 \uC790\uB3D9 \uC0DD\uC131) \u2192 extract \u2192 review \u2192 finalize
|
|
2565
2593
|
\`\`\`
|
|
2566
2594
|
|
|
2567
|
-
|
|
2595
|
+
**\uAC01 \uB2E8\uACC4\uB294 \uC21C\uCC28\uC801\uC73C\uB85C \uC9C4\uD589\uD569\uB2C8\uB2E4. \uC774\uC804 \uB2E8\uACC4\uB97C \uAC74\uB108\uB6F0\uC9C0 \uB9C8\uC138\uC694!**
|
|
2596
|
+
|
|
2597
|
+
### 1. Scan (\uC2A4\uCE94 + \uB3C4\uBA54\uC778 \uC0DD\uC131)
|
|
2568
2598
|
|
|
2569
|
-
|
|
2599
|
+
**Claude \uC9C0\uC2DC:** \`sdd reverse scan\` CLI \uBA85\uB839\uC5B4\uB97C \uC2E4\uD589\uD558\uC138\uC694.
|
|
2570
2600
|
|
|
2571
2601
|
\`\`\`bash
|
|
2572
|
-
sdd reverse scan
|
|
2573
|
-
sdd reverse scan src/
|
|
2602
|
+
sdd reverse scan # \uC2A4\uCE94 + \uB3C4\uBA54\uC778 \uC790\uB3D9 \uC0DD\uC131
|
|
2603
|
+
sdd reverse scan src/ # \uD2B9\uC815 \uACBD\uB85C \uC2A4\uCE94
|
|
2604
|
+
sdd reverse scan --no-create-domains # \uB3C4\uBA54\uC778 \uC0DD\uC131 \uC5C6\uC774 \uC2A4\uCE94\uB9CC
|
|
2574
2605
|
\`\`\`
|
|
2575
2606
|
|
|
2607
|
+
**\uC218\uD589 \uC791\uC5C5:**
|
|
2608
|
+
- \uD504\uB85C\uC81D\uD2B8 \uAD6C\uC870 \uBD84\uC11D (src/, lib/, packages/ \uB4F1)
|
|
2609
|
+
- \uC5B8\uC5B4 \uBD84\uD3EC \uD655\uC778
|
|
2610
|
+
- \uB3C4\uBA54\uC778 \uC790\uB3D9 \uC0DD\uC131 (.sdd/domains.yml\uC5D0 \uCD94\uAC00)
|
|
2611
|
+
- \uC2A4\uCE94 \uBA54\uD0C0\uB370\uC774\uD130 \uC800\uC7A5 (.sdd/.reverse-meta.json)
|
|
2612
|
+
|
|
2613
|
+
**\uC644\uB8CC \uD6C4 \uC548\uB0B4:** "\uC2A4\uCE94\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \`/sdd.reverse extract\`\uB85C \uCF54\uB4DC\uC5D0\uC11C \uC2A4\uD399\uC744 \uCD94\uCD9C\uD558\uC138\uC694."
|
|
2614
|
+
|
|
2576
2615
|
### 2. Extract (\uCD94\uCD9C)
|
|
2577
2616
|
|
|
2578
|
-
|
|
2617
|
+
**Claude \uC9C0\uC2DC:** \`sdd reverse extract\` CLI \uBA85\uB839\uC5B4\uB97C \uC2E4\uD589\uD558\uC138\uC694.
|
|
2618
|
+
**\uC8FC\uC758:** \uC2A4\uD399 \uD30C\uC77C\uC744 \uC9C1\uC811 \uC791\uC131\uD558\uC9C0 \uB9C8\uC138\uC694! CLI\uAC00 \`.sdd/.reverse-drafts/\`\uC5D0 \uCD08\uC548\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4.
|
|
2579
2619
|
|
|
2580
2620
|
\`\`\`bash
|
|
2581
|
-
sdd reverse extract
|
|
2582
|
-
sdd reverse extract --domain auth
|
|
2583
|
-
sdd reverse extract --depth deep
|
|
2621
|
+
sdd reverse extract # \uC804\uCCB4 \uCD94\uCD9C
|
|
2622
|
+
sdd reverse extract --domain auth # \uD2B9\uC815 \uB3C4\uBA54\uC778\uB9CC
|
|
2623
|
+
sdd reverse extract --depth deep # \uAE4A\uC740 \uBD84\uC11D
|
|
2584
2624
|
\`\`\`
|
|
2585
2625
|
|
|
2586
|
-
**\
|
|
2587
|
-
-
|
|
2588
|
-
-
|
|
2589
|
-
-
|
|
2626
|
+
**\uC218\uD589 \uC791\uC5C5:**
|
|
2627
|
+
- \uCF54\uB4DC \uC2EC\uBCFC \uBD84\uC11D
|
|
2628
|
+
- \uC2A4\uD399 \uCD08\uC548 \uC0DD\uC131 \u2192 \`.sdd/.reverse-drafts/<domain>/<name>.json\`
|
|
2629
|
+
- \uC0C1\uD0DC: \`pending\` (\uC544\uC9C1 \uC2B9\uC778\uB418\uC9C0 \uC54A\uC74C)
|
|
2630
|
+
|
|
2631
|
+
**\uC644\uB8CC \uD6C4 \uC548\uB0B4:** "\uCD94\uCD9C\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \`/sdd.reverse review\`\uB85C \uC2A4\uD399\uC744 \uB9AC\uBDF0\uD558\uC138\uC694."
|
|
2590
2632
|
|
|
2591
2633
|
### 3. Review (\uB9AC\uBDF0)
|
|
2592
2634
|
|
|
2593
|
-
|
|
2635
|
+
**Claude \uC9C0\uC2DC:** \`sdd reverse review\` CLI \uBA85\uB839\uC5B4\uB97C \uC2E4\uD589\uD558\uC138\uC694.
|
|
2594
2636
|
|
|
2595
2637
|
\`\`\`bash
|
|
2596
|
-
sdd reverse review
|
|
2597
|
-
sdd reverse review auth/login
|
|
2638
|
+
sdd reverse review # \uB9AC\uBDF0 \uB300\uAE30 \uBAA9\uB85D \uD655\uC778
|
|
2639
|
+
sdd reverse review auth/login # \uD2B9\uC815 \uC2A4\uD399 \uC0C1\uC138 \uBCF4\uAE30
|
|
2640
|
+
sdd reverse review auth/login --approve # \uC2A4\uD399 \uC2B9\uC778
|
|
2641
|
+
sdd reverse review auth/login --reject # \uC2A4\uD399 \uAC70\uBD80
|
|
2598
2642
|
\`\`\`
|
|
2599
2643
|
|
|
2644
|
+
**\uC218\uD589 \uC791\uC5C5:**
|
|
2645
|
+
- \uCD94\uCD9C\uB41C \uCD08\uC548 \uAC80\uD1A0
|
|
2646
|
+
- \`--approve\`\uB85C \uC2B9\uC778, \`--reject\`\uB85C \uAC70\uBD80
|
|
2647
|
+
|
|
2648
|
+
**\uC644\uB8CC \uD6C4 \uC548\uB0B4:** "\uB9AC\uBDF0\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \`/sdd.reverse finalize\`\uB85C \uC2B9\uC778\uB41C \uC2A4\uD399\uC744 \uD655\uC815\uD558\uC138\uC694."
|
|
2649
|
+
|
|
2600
2650
|
### 4. Finalize (\uD655\uC815)
|
|
2601
2651
|
|
|
2602
|
-
|
|
2652
|
+
**Claude \uC9C0\uC2DC:** \`sdd reverse finalize\` CLI \uBA85\uB839\uC5B4\uB97C \uC2E4\uD589\uD558\uC138\uC694.
|
|
2653
|
+
**\uC8FC\uC758:** finalize \uD6C4\uC5D0\uB9CC \`.sdd/specs/\`\uC5D0 \uC2A4\uD399\uC774 \uC0DD\uC131\uB429\uB2C8\uB2E4!
|
|
2603
2654
|
|
|
2604
2655
|
\`\`\`bash
|
|
2605
|
-
sdd reverse finalize --all
|
|
2606
|
-
sdd reverse finalize auth/login
|
|
2656
|
+
sdd reverse finalize --all # \uBAA8\uB4E0 \uC2B9\uC778 \uC2A4\uD399 \uD655\uC815
|
|
2657
|
+
sdd reverse finalize auth/login # \uD2B9\uC815 \uC2A4\uD399 \uD655\uC815
|
|
2658
|
+
sdd reverse finalize -d auth # \uD2B9\uC815 \uB3C4\uBA54\uC778 \uD655\uC815
|
|
2607
2659
|
\`\`\`
|
|
2608
2660
|
|
|
2661
|
+
**\uC218\uD589 \uC791\uC5C5:**
|
|
2662
|
+
- \`.sdd/.reverse-drafts/\`\uC5D0\uC11C \uC2B9\uC778\uB41C \uC2A4\uD399 \uC77D\uAE30
|
|
2663
|
+
- \`.sdd/specs/<feature-id>/spec.md\` \uC0DD\uC131
|
|
2664
|
+
- \uCD08\uC548 \uD30C\uC77C \uC0AD\uC81C
|
|
2665
|
+
|
|
2666
|
+
**\uC644\uB8CC \uD6C4 \uC548\uB0B4:** "\uC2A4\uD399 \uD655\uC815\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \`/sdd.validate\`\uB85C \uC2A4\uD399\uC744 \uAC80\uC99D\uD558\uAC70\uB098 \`/sdd.new\`\uB85C \uC0C8 \uAE30\uB2A5\uC744 \uCD94\uAC00\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."
|
|
2667
|
+
|
|
2609
2668
|
## \uCD9C\uB825 \uD30C\uC77C
|
|
2610
2669
|
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
|
2614
|
-
|
|
2615
|
-
| \`.sdd/
|
|
2670
|
+
**\uC8FC\uC758:** CLI\uAC00 \uC0DD\uC131\uD558\uB294 \uD30C\uC77C \uD615\uC2DD\uC744 \uC815\uD655\uD788 \uB530\uB974\uC138\uC694!
|
|
2671
|
+
|
|
2672
|
+
| \uD30C\uC77C | \uC124\uBA85 | \uC0DD\uC131 \uC2DC\uC810 |
|
|
2673
|
+
|------|------|----------|
|
|
2674
|
+
| \`.sdd/domains.yml\` | \uB3C4\uBA54\uC778 \uC124\uC815 (YAML \uD615\uC2DD, JSON \uC544\uB2D8!) | scan |
|
|
2675
|
+
| \`.sdd/domains/<domain>/domain.md\` | \uB3C4\uBA54\uC778\uBCC4 \uBB38\uC11C | scan |
|
|
2676
|
+
| \`.sdd/.reverse-meta.json\` | \uC2A4\uCE94/\uCD94\uCD9C \uBA54\uD0C0\uB370\uC774\uD130 | scan, extract |
|
|
2677
|
+
| \`.sdd/.reverse-drafts/\` | \uC2A4\uD399 \uCD08\uC548 \uB514\uB809\uD1A0\uB9AC | extract |
|
|
2678
|
+
| \`.sdd/specs/<feature-id>/spec.md\` | \uD655\uC815\uB41C \uC2A4\uD399 | finalize |
|
|
2679
|
+
|
|
2680
|
+
**\uD30C\uC77C\uC744 \uC9C1\uC811 \uC0DD\uC131\uD558\uC9C0 \uB9C8\uC138\uC694!** \uBAA8\uB4E0 \uD30C\uC77C\uC740 CLI \uBA85\uB839\uC5B4\uB85C \uC0DD\uC131\uB429\uB2C8\uB2E4.
|
|
2616
2681
|
|
|
2617
2682
|
## \uB2E4\uC74C \uB2E8\uACC4
|
|
2618
2683
|
|
|
2619
2684
|
- \uD655\uC815 \uD6C4: \`/sdd.validate\`\uB85C \uC2A4\uD399 \uAC80\uC99D
|
|
2620
|
-
- \uB3C4\uBA54\uC778 \uC815
|
|
2685
|
+
- \uB3C4\uBA54\uC778 \uC218\uC815: \`/sdd.domain\`\uC73C\uB85C \uB3C4\uBA54\uC778 \uC0C1\uC138 \uC870\uC815 (\uC774\uB984 \uBCC0\uACBD, \uC758\uC874\uC131 \uCD94\uAC00 \uB4F1)
|
|
2686
|
+
- \uC0C8 \uAE30\uB2A5: \`/sdd.new\`\uB85C \uC0C8 \uC2A4\uD399 \uC791\uC131
|
|
2621
2687
|
`
|
|
2622
2688
|
};
|
|
2623
2689
|
|
|
@@ -21392,6 +21458,68 @@ async function loadReviewList(sddPath) {
|
|
|
21392
21458
|
return failure(new Error(`\uB9AC\uBDF0 \uBAA9\uB85D \uB85C\uB4DC \uC2E4\uD328: ${error2}`));
|
|
21393
21459
|
}
|
|
21394
21460
|
}
|
|
21461
|
+
async function approveSpec(sddPath, specId, comment) {
|
|
21462
|
+
const loadResult = await loadReviewList(sddPath);
|
|
21463
|
+
if (!loadResult.success) {
|
|
21464
|
+
return failure(loadResult.error);
|
|
21465
|
+
}
|
|
21466
|
+
const item = loadResult.data.find((i) => i.specId === specId);
|
|
21467
|
+
if (!item) {
|
|
21468
|
+
return failure(new Error(`\uC2A4\uD399\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${specId}`));
|
|
21469
|
+
}
|
|
21470
|
+
item.status = "approved";
|
|
21471
|
+
item.spec.metadata.status = "approved";
|
|
21472
|
+
item.reviewedAt = /* @__PURE__ */ new Date();
|
|
21473
|
+
if (comment) {
|
|
21474
|
+
item.comments.push({
|
|
21475
|
+
type: "info",
|
|
21476
|
+
message: comment,
|
|
21477
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
21478
|
+
});
|
|
21479
|
+
}
|
|
21480
|
+
const saveResult = await saveReviewItem(sddPath, item);
|
|
21481
|
+
if (!saveResult.success) {
|
|
21482
|
+
return failure(saveResult.error);
|
|
21483
|
+
}
|
|
21484
|
+
return success(item);
|
|
21485
|
+
}
|
|
21486
|
+
async function rejectSpec(sddPath, specId, reason) {
|
|
21487
|
+
const loadResult = await loadReviewList(sddPath);
|
|
21488
|
+
if (!loadResult.success) {
|
|
21489
|
+
return failure(loadResult.error);
|
|
21490
|
+
}
|
|
21491
|
+
const item = loadResult.data.find((i) => i.specId === specId);
|
|
21492
|
+
if (!item) {
|
|
21493
|
+
return failure(new Error(`\uC2A4\uD399\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${specId}`));
|
|
21494
|
+
}
|
|
21495
|
+
item.status = "rejected";
|
|
21496
|
+
item.spec.metadata.status = "rejected";
|
|
21497
|
+
item.reviewedAt = /* @__PURE__ */ new Date();
|
|
21498
|
+
item.comments.push({
|
|
21499
|
+
type: "error",
|
|
21500
|
+
message: reason,
|
|
21501
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
21502
|
+
});
|
|
21503
|
+
const saveResult = await saveReviewItem(sddPath, item);
|
|
21504
|
+
if (!saveResult.success) {
|
|
21505
|
+
return failure(saveResult.error);
|
|
21506
|
+
}
|
|
21507
|
+
return success(item);
|
|
21508
|
+
}
|
|
21509
|
+
async function saveReviewItem(sddPath, item) {
|
|
21510
|
+
const [domain, name] = item.specId.split("/");
|
|
21511
|
+
const specDir = path51.join(sddPath, ".reverse-drafts", domain);
|
|
21512
|
+
try {
|
|
21513
|
+
await ensureDir(specDir);
|
|
21514
|
+
const jsonPath = path51.join(specDir, `${name}.json`);
|
|
21515
|
+
await fs33.writeFile(jsonPath, formatSpecAsJson(item.spec), "utf-8");
|
|
21516
|
+
const mdPath = path51.join(specDir, `${name}.md`);
|
|
21517
|
+
await fs33.writeFile(mdPath, formatSpecAsMarkdown(item.spec), "utf-8");
|
|
21518
|
+
return success(void 0);
|
|
21519
|
+
} catch (error2) {
|
|
21520
|
+
return failure(new Error(`\uB9AC\uBDF0 \uD56D\uBAA9 \uC800\uC7A5 \uC2E4\uD328: ${error2}`));
|
|
21521
|
+
}
|
|
21522
|
+
}
|
|
21395
21523
|
function calculateReviewSummary(items) {
|
|
21396
21524
|
return {
|
|
21397
21525
|
total: items.length,
|
|
@@ -22559,6 +22687,38 @@ async function handleScan(targetPath, options) {
|
|
|
22559
22687
|
error(`\uACB0\uACFC \uC800\uC7A5 \uC2E4\uD328: ${error2}`);
|
|
22560
22688
|
}
|
|
22561
22689
|
}
|
|
22690
|
+
const shouldCreateDomains = options.createDomains !== false;
|
|
22691
|
+
if (shouldCreateDomains && result.summary.suggestedDomains.length > 0) {
|
|
22692
|
+
const domainService = createDomainService(sddRoot);
|
|
22693
|
+
const existingDomainsResult = await domainService.list();
|
|
22694
|
+
const existingDomainIds = existingDomainsResult.success ? existingDomainsResult.data.map((d) => d.id) : [];
|
|
22695
|
+
let createdCount = 0;
|
|
22696
|
+
let skippedCount = 0;
|
|
22697
|
+
for (const suggested of result.summary.suggestedDomains) {
|
|
22698
|
+
if (existingDomainIds.includes(suggested.name)) {
|
|
22699
|
+
skippedCount++;
|
|
22700
|
+
continue;
|
|
22701
|
+
}
|
|
22702
|
+
const createResult = await domainService.create(suggested.name, {
|
|
22703
|
+
description: `${suggested.name} \uB3C4\uBA54\uC778 (reverse scan\uC73C\uB85C \uC790\uB3D9 \uC0DD\uC131)`,
|
|
22704
|
+
path: suggested.path
|
|
22705
|
+
});
|
|
22706
|
+
if (createResult.success) {
|
|
22707
|
+
createdCount++;
|
|
22708
|
+
}
|
|
22709
|
+
}
|
|
22710
|
+
if (!options.quiet && (createdCount > 0 || skippedCount > 0)) {
|
|
22711
|
+
console.log("");
|
|
22712
|
+
console.log(chalk10.bold("\u{1F4C1} \uB3C4\uBA54\uC778 \uC790\uB3D9 \uC0DD\uC131:"));
|
|
22713
|
+
if (createdCount > 0) {
|
|
22714
|
+
console.log(chalk10.green(` \u2705 ${createdCount}\uAC1C \uB3C4\uBA54\uC778 \uC0DD\uC131\uB428`));
|
|
22715
|
+
}
|
|
22716
|
+
if (skippedCount > 0) {
|
|
22717
|
+
console.log(chalk10.dim(` \u23ED\uFE0F ${skippedCount}\uAC1C \uB3C4\uBA54\uC778 \uC774\uBBF8 \uC874\uC7AC (\uAC74\uB108\uB700)`));
|
|
22718
|
+
}
|
|
22719
|
+
console.log("");
|
|
22720
|
+
}
|
|
22721
|
+
}
|
|
22562
22722
|
if (!options.skipSerenaCheck) {
|
|
22563
22723
|
const serenaCheck = await ensureSerenaAvailable("scan", { skipSerenaCheck: true, quiet: true });
|
|
22564
22724
|
if (!serenaCheck.success && !options.quiet) {
|
|
@@ -22566,6 +22726,11 @@ async function handleScan(targetPath, options) {
|
|
|
22566
22726
|
console.log(chalk10.dim(" docs/guide/serena-setup.md \uCC38\uC870\n"));
|
|
22567
22727
|
}
|
|
22568
22728
|
}
|
|
22729
|
+
if (!options.quiet && !options.json) {
|
|
22730
|
+
console.log(chalk10.bold("\u{1F4A1} \uB2E4\uC74C \uB2E8\uACC4:"));
|
|
22731
|
+
console.log(" sdd reverse extract # \uCF54\uB4DC\uC5D0\uC11C \uC2A4\uD399 \uCD94\uCD9C");
|
|
22732
|
+
console.log("");
|
|
22733
|
+
}
|
|
22569
22734
|
}
|
|
22570
22735
|
async function handleExtract(targetPath, options) {
|
|
22571
22736
|
const sddRoot = await findSddRoot();
|
|
@@ -22670,6 +22835,29 @@ async function handleReview(specId, options) {
|
|
|
22670
22835
|
error(`\uC2A4\uD399\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${specId}`);
|
|
22671
22836
|
process.exit(ExitCode.GENERAL_ERROR);
|
|
22672
22837
|
}
|
|
22838
|
+
if (options.approve) {
|
|
22839
|
+
const result = await approveSpec(sddPath, item.specId);
|
|
22840
|
+
if (result.success) {
|
|
22841
|
+
success2(`\uC2B9\uC778\uB428: ${item.specId}`);
|
|
22842
|
+
console.log("");
|
|
22843
|
+
console.log(chalk10.bold("\u{1F4A1} \uB2E4\uC74C \uB2E8\uACC4:"));
|
|
22844
|
+
console.log(" sdd reverse finalize --all # \uC2B9\uC778\uB41C \uC2A4\uD399 \uD655\uC815");
|
|
22845
|
+
} else {
|
|
22846
|
+
error(result.error.message);
|
|
22847
|
+
process.exit(ExitCode.GENERAL_ERROR);
|
|
22848
|
+
}
|
|
22849
|
+
return;
|
|
22850
|
+
}
|
|
22851
|
+
if (options.reject) {
|
|
22852
|
+
const result = await rejectSpec(sddPath, item.specId);
|
|
22853
|
+
if (result.success) {
|
|
22854
|
+
success2(`\uAC70\uBD80\uB428: ${item.specId}`);
|
|
22855
|
+
} else {
|
|
22856
|
+
error(result.error.message);
|
|
22857
|
+
process.exit(ExitCode.GENERAL_ERROR);
|
|
22858
|
+
}
|
|
22859
|
+
return;
|
|
22860
|
+
}
|
|
22673
22861
|
console.log(formatSpecDetail(item));
|
|
22674
22862
|
console.log(chalk10.bold("\u{1F4A1} \uC791\uC5C5:"));
|
|
22675
22863
|
console.log(` sdd reverse review ${specId} --approve # \uC2B9\uC778`);
|
|
@@ -22791,9 +22979,9 @@ function registerReverseCommand(program2) {
|
|
|
22791
22979
|
showReverseHelp();
|
|
22792
22980
|
}
|
|
22793
22981
|
});
|
|
22794
|
-
reverse.command("scan [path]").description("\uD504\uB85C\uC81D\uD2B8 \uAD6C\uC870 \uC2A4\uCE94").option("-d, --depth <n>", "\uBD84\uC11D \uAE4A\uC774", parseInt).option("-i, --include <pattern>", "\uD3EC\uD568 \uD328\uD134 (glob)").option("-e, --exclude <pattern>", "\uC81C\uC678 \uD328\uD134 (glob)").option("-l, --language <lang>", "\uD2B9\uC815 \uC5B8\uC5B4\uB9CC").option("-o, --output <file>", "\uACB0\uACFC \uC800\uC7A5 \uD30C\uC77C").option("-q, --quiet", "\uC870\uC6A9\uD55C \uBAA8\uB4DC").option("--skip-serena-check", "Serena \uCCB4\uD06C \uAC74\uB108\uB6F0\uAE30 (\uAC1C\uBC1C\uC6A9)").action(handleScan);
|
|
22982
|
+
reverse.command("scan [path]").description("\uD504\uB85C\uC81D\uD2B8 \uAD6C\uC870 \uC2A4\uCE94 \uBC0F \uB3C4\uBA54\uC778 \uC790\uB3D9 \uC0DD\uC131").option("-d, --depth <n>", "\uBD84\uC11D \uAE4A\uC774", parseInt).option("-i, --include <pattern>", "\uD3EC\uD568 \uD328\uD134 (glob)").option("-e, --exclude <pattern>", "\uC81C\uC678 \uD328\uD134 (glob)").option("-l, --language <lang>", "\uD2B9\uC815 \uC5B8\uC5B4\uB9CC").option("-o, --output <file>", "\uACB0\uACFC \uC800\uC7A5 \uD30C\uC77C").option("-q, --quiet", "\uC870\uC6A9\uD55C \uBAA8\uB4DC").option("--json", "JSON \uD615\uC2DD \uCD9C\uB825").option("--compare", "\uC774\uC804 \uC2A4\uCE94\uACFC \uBE44\uAD50").option("--no-create-domains", "\uB3C4\uBA54\uC778 \uC790\uB3D9 \uC0DD\uC131 \uBE44\uD65C\uC131\uD654").option("--skip-serena-check", "Serena \uCCB4\uD06C \uAC74\uB108\uB6F0\uAE30 (\uAC1C\uBC1C\uC6A9)").action(handleScan);
|
|
22795
22983
|
reverse.command("extract [path]").description("\uCF54\uB4DC\uC5D0\uC11C \uC2A4\uD399 \uCD94\uCD9C").option("--depth <level>", "\uCD94\uCD9C \uAE4A\uC774: shallow, medium, deep", "medium").option("--ai", "AI \uAE30\uBC18 \uC758\uB3C4 \uCD94\uB860 \uD65C\uC131\uD654").option("-d, --domain <name>", "\uB3C4\uBA54\uC778 \uC9C0\uC815").option("-o, --output <dir>", "\uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC").option("-q, --quiet", "\uC870\uC6A9\uD55C \uBAA8\uB4DC").option("--skip-serena-check", "Serena \uCCB4\uD06C \uAC74\uB108\uB6F0\uAE30 (\uAC1C\uBC1C\uC6A9)").action(handleExtract);
|
|
22796
|
-
reverse.command("review [spec]").description("\uCD94\uCD9C\uB41C \uC2A4\uD399 \uB9AC\uBDF0").option("-a, --all", "\uBAA8\uB4E0 \uC2A4\uD399 \uB9AC\uBDF0").option("-q, --quiet", "\uC870\uC6A9\uD55C \uBAA8\uB4DC").action(handleReview);
|
|
22984
|
+
reverse.command("review [spec]").description("\uCD94\uCD9C\uB41C \uC2A4\uD399 \uB9AC\uBDF0").option("-a, --all", "\uBAA8\uB4E0 \uC2A4\uD399 \uB9AC\uBDF0").option("--approve", "\uC2A4\uD399 \uC2B9\uC778").option("--reject", "\uC2A4\uD399 \uAC70\uBD80").option("-q, --quiet", "\uC870\uC6A9\uD55C \uBAA8\uB4DC").action(handleReview);
|
|
22797
22985
|
reverse.command("finalize [spec]").description("\uC2B9\uC778\uB41C \uC2A4\uD399 \uC815\uC2DD \uBCC0\uD658").option("-a, --all", "\uBAA8\uB4E0 \uC2B9\uC778 \uC2A4\uD399 \uD655\uC815").option("-d, --domain <name>", "\uD2B9\uC815 \uB3C4\uBA54\uC778 \uD655\uC815").option("-q, --quiet", "\uC870\uC6A9\uD55C \uBAA8\uB4DC").action(handleFinalize);
|
|
22798
22986
|
}
|
|
22799
22987
|
|