@uoyo/mvtt 2.0.0-beta.0
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/LICENSE +21 -0
- package/README.md +209 -0
- package/dist/build/assembler.d.ts +6 -0
- package/dist/build/assembler.d.ts.map +1 -0
- package/dist/build/assembler.js +32 -0
- package/dist/build/assembler.js.map +1 -0
- package/dist/build/section-loader.d.ts +4 -0
- package/dist/build/section-loader.d.ts.map +1 -0
- package/dist/build/section-loader.js +55 -0
- package/dist/build/section-loader.js.map +1 -0
- package/dist/build/validator.d.ts +6 -0
- package/dist/build/validator.d.ts.map +1 -0
- package/dist/build/validator.js +77 -0
- package/dist/build/validator.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +49 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/build.d.ts +5 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +46 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +79 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/install.d.ts +5 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +63 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/shared.d.ts +2 -0
- package/dist/commands/shared.d.ts.map +1 -0
- package/dist/commands/shared.js +2 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/commands/uninstall.d.ts +2 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +56 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +5 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +59 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/fs/hash.d.ts +3 -0
- package/dist/fs/hash.d.ts.map +1 -0
- package/dist/fs/hash.js +10 -0
- package/dist/fs/hash.js.map +1 -0
- package/dist/fs/install-manifest.d.ts +16 -0
- package/dist/fs/install-manifest.d.ts.map +1 -0
- package/dist/fs/install-manifest.js +29 -0
- package/dist/fs/install-manifest.js.map +1 -0
- package/dist/fs/materialize.d.ts +14 -0
- package/dist/fs/materialize.d.ts.map +1 -0
- package/dist/fs/materialize.js +116 -0
- package/dist/fs/materialize.js.map +1 -0
- package/dist/fs/protection.d.ts +15 -0
- package/dist/fs/protection.d.ts.map +1 -0
- package/dist/fs/protection.js +16 -0
- package/dist/fs/protection.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/types/manifest.d.ts +21 -0
- package/dist/types/manifest.d.ts.map +1 -0
- package/dist/types/manifest.js +2 -0
- package/dist/types/manifest.js.map +1 -0
- package/dist/types/registry.d.ts +25 -0
- package/dist/types/registry.d.ts.map +1 -0
- package/dist/types/registry.js +2 -0
- package/dist/types/registry.js.map +1 -0
- package/dist/util/color.d.ts +9 -0
- package/dist/util/color.d.ts.map +1 -0
- package/dist/util/color.js +13 -0
- package/dist/util/color.js.map +1 -0
- package/dist/util/package.d.ts +3 -0
- package/dist/util/package.d.ts.map +1 -0
- package/dist/util/package.js +13 -0
- package/dist/util/package.js.map +1 -0
- package/install-manifest.yaml +27 -0
- package/package.json +57 -0
- package/registry.yaml +209 -0
- package/sources/defaults/config.yaml +30 -0
- package/sources/defaults/project-context.yaml +26 -0
- package/sources/defaults/session.yaml +23 -0
- package/sources/knowledge/core/manifest.yaml +47 -0
- package/sources/knowledge/core/review-principles.md +51 -0
- package/sources/knowledge/patterns/clean-architecture/manifest.yaml +66 -0
- package/sources/knowledge/patterns/clean-architecture/review-checklist.md +230 -0
- package/sources/knowledge/patterns/ddd/manifest.yaml +83 -0
- package/sources/knowledge/patterns/ddd/review-checklist.md +226 -0
- package/sources/knowledge/patterns/ddd/tactical-patterns.md +12 -0
- package/sources/knowledge/patterns/frontend-react/manifest.yaml +44 -0
- package/sources/knowledge/patterns/frontend-react/review-checklist.md +78 -0
- package/sources/knowledge/patterns/manifest.yaml +113 -0
- package/sources/sections/activation-load-config.md +5 -0
- package/sources/sections/activation-load-context.md +11 -0
- package/sources/sections/activation-preflight.md +4 -0
- package/sources/sections/footer-next-steps.md +9 -0
- package/sources/sections/role-header.md +13 -0
- package/sources/skills/mvt-add-context/business.md +47 -0
- package/sources/skills/mvt-add-context/manifest.yaml +83 -0
- package/sources/skills/mvt-analyze/business.md +33 -0
- package/sources/skills/mvt-analyze/manifest.yaml +89 -0
- package/sources/skills/mvt-analyze-code/business.md +35 -0
- package/sources/skills/mvt-analyze-code/manifest.yaml +88 -0
- package/sources/skills/mvt-check-context/business.md +42 -0
- package/sources/skills/mvt-check-context/manifest.yaml +74 -0
- package/sources/skills/mvt-cleanup/business.md +31 -0
- package/sources/skills/mvt-cleanup/manifest.yaml +93 -0
- package/sources/skills/mvt-config/business.md +26 -0
- package/sources/skills/mvt-config/manifest.yaml +108 -0
- package/sources/skills/mvt-create-skill/business.md +111 -0
- package/sources/skills/mvt-create-skill/manifest.yaml +79 -0
- package/sources/skills/mvt-design/business.md +34 -0
- package/sources/skills/mvt-design/manifest.yaml +105 -0
- package/sources/skills/mvt-fix/business.md +28 -0
- package/sources/skills/mvt-fix/manifest.yaml +86 -0
- package/sources/skills/mvt-help/business.md +70 -0
- package/sources/skills/mvt-help/manifest.yaml +61 -0
- package/sources/skills/mvt-implement/business.md +32 -0
- package/sources/skills/mvt-implement/manifest.yaml +96 -0
- package/sources/skills/mvt-init/business.md +49 -0
- package/sources/skills/mvt-init/manifest.yaml +93 -0
- package/sources/skills/mvt-refactor/business.md +33 -0
- package/sources/skills/mvt-refactor/manifest.yaml +101 -0
- package/sources/skills/mvt-review/business.md +49 -0
- package/sources/skills/mvt-review/manifest.yaml +106 -0
- package/sources/skills/mvt-status/business.md +24 -0
- package/sources/skills/mvt-status/manifest.yaml +74 -0
- package/sources/skills/mvt-sync-context/business.md +25 -0
- package/sources/skills/mvt-sync-context/manifest.yaml +84 -0
- package/sources/skills/mvt-template/business.md +49 -0
- package/sources/skills/mvt-template/manifest.yaml +71 -0
- package/sources/skills/mvt-test/business.md +36 -0
- package/sources/skills/mvt-test/manifest.yaml +111 -0
- package/sources/templates/analyze-code-output/body.md +44 -0
- package/sources/templates/analyze-code-output/manifest.yaml +11 -0
- package/sources/templates/analyze-output/body.md +38 -0
- package/sources/templates/analyze-output/manifest.yaml +11 -0
- package/sources/templates/cleanup-output/body.md +9 -0
- package/sources/templates/cleanup-output/manifest.yaml +11 -0
- package/sources/templates/config-output/body.md +11 -0
- package/sources/templates/config-output/manifest.yaml +11 -0
- package/sources/templates/context-check-output/body.md +32 -0
- package/sources/templates/context-check-output/manifest.yaml +11 -0
- package/sources/templates/design-output/body.md +50 -0
- package/sources/templates/design-output/manifest.yaml +11 -0
- package/sources/templates/fix-output/body.md +30 -0
- package/sources/templates/fix-output/manifest.yaml +11 -0
- package/sources/templates/implement-output/body.md +32 -0
- package/sources/templates/implement-output/manifest.yaml +11 -0
- package/sources/templates/init-output/body.md +34 -0
- package/sources/templates/init-output/manifest.yaml +11 -0
- package/sources/templates/refactor-output/body.md +32 -0
- package/sources/templates/refactor-output/manifest.yaml +11 -0
- package/sources/templates/review-output/body.md +45 -0
- package/sources/templates/review-output/manifest.yaml +11 -0
- package/sources/templates/status-output/body.md +36 -0
- package/sources/templates/status-output/manifest.yaml +11 -0
- package/sources/templates/sync-context-output/body.md +16 -0
- package/sources/templates/sync-context-output/manifest.yaml +11 -0
- package/sources/templates/test-output/body.md +31 -0
- package/sources/templates/test-output/manifest.yaml +11 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 xiangjie
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# My-Virtual-TechTeam (MVTT)
|
|
2
|
+
|
|
3
|
+
A virtual IT team made up of AI agents. Built for [Claude Code](https://claude.ai/claude-code), MVTT turns your IDE into a coordinated squad of Analyst, Architect, Developer, Reviewer, and Tester — each with a clear role, a shared workspace, and enforceable team conventions.
|
|
4
|
+
|
|
5
|
+
## Why MVTT
|
|
6
|
+
|
|
7
|
+
- **One-command install** — `npx @uoyo/mvtt install` drops a full skill suite into any project
|
|
8
|
+
- **Claude Code native** — 18 skills auto-discovered from `.claude/skills/`
|
|
9
|
+
- **Bilingual output** — choose `en-US` or `zh-CN` at install time; every skill honors the setting
|
|
10
|
+
- **Shared workspace** — `.ai-agents/` centralizes session state, domain knowledge, config, and output templates
|
|
11
|
+
- **Safe lifecycle** — `install` / `update` / `uninstall` / `doctor` with manifest-based file ownership, so user data is never overwritten
|
|
12
|
+
- **Extensible** — `/mvt-create-skill` lets your team grow its own skills for project-specific workflows
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx @uoyo/mvtt install
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The installer is interactive:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
? Select language / 选择语言
|
|
24
|
+
❯ English (en-US)
|
|
25
|
+
中文 (zh-CN)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Optional flags:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx @uoyo/mvtt install --pattern ddd # Preset architecture pattern (ddd | clean-architecture | frontend-react)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
1. Run `npx @uoyo/mvtt install` in your project root
|
|
37
|
+
2. Open the project in Claude Code
|
|
38
|
+
3. Run `/mvt-init` to initialize the workspace
|
|
39
|
+
4. Run `/mvt-help` to see all available skills
|
|
40
|
+
5. Follow the guided workflow through your development phases
|
|
41
|
+
|
|
42
|
+
## CLI Commands
|
|
43
|
+
|
|
44
|
+
| Command | Purpose |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `npx @uoyo/mvtt install` | First-time install; interactive language selection |
|
|
47
|
+
| `npx @uoyo/mvtt install --pattern <name>` | Install with a preset architecture pattern |
|
|
48
|
+
| `npx @uoyo/mvtt update` | Upgrade to the latest version (user data preserved) |
|
|
49
|
+
| `npx @uoyo/mvtt update --check` | Show version diff without modifying anything |
|
|
50
|
+
| `npx @uoyo/mvtt doctor` | Check installation health and detect manual edits |
|
|
51
|
+
| `npx @uoyo/mvtt uninstall` | Interactive confirmation, then remove generated files (user data preserved) |
|
|
52
|
+
| `npx @uoyo/mvtt --help` | Full CLI help |
|
|
53
|
+
| `npx @uoyo/mvtt --version` | Print version |
|
|
54
|
+
|
|
55
|
+
## Skills (18 total)
|
|
56
|
+
|
|
57
|
+
### Workflow Skills (Sequential Phases)
|
|
58
|
+
|
|
59
|
+
| Skill | Description |
|
|
60
|
+
|-------|-------------|
|
|
61
|
+
| `/mvt-analyze` | Analyze requirements and extract domain concepts |
|
|
62
|
+
| `/mvt-analyze-code` | Reverse-analyze existing code to generate context |
|
|
63
|
+
| `/mvt-design` | Create architecture design based on requirements |
|
|
64
|
+
| `/mvt-implement` | Implement features based on architecture design |
|
|
65
|
+
| `/mvt-review` | Code review for quality and standards compliance |
|
|
66
|
+
| `/mvt-test` | Generate tests to validate implementations |
|
|
67
|
+
|
|
68
|
+
### Shortcut Skills (Anytime)
|
|
69
|
+
|
|
70
|
+
| Skill | Description |
|
|
71
|
+
|-------|-------------|
|
|
72
|
+
| `/mvt-fix` | Diagnose and fix bugs or issues |
|
|
73
|
+
| `/mvt-refactor` | Refactor code while preserving behavior |
|
|
74
|
+
|
|
75
|
+
### Project Management Skills
|
|
76
|
+
|
|
77
|
+
| Skill | Description |
|
|
78
|
+
|-------|-------------|
|
|
79
|
+
| `/mvt-init` | Initialize or refresh project setup |
|
|
80
|
+
| `/mvt-status` | Show current project and workflow status |
|
|
81
|
+
| `/mvt-config` | Manage framework configuration |
|
|
82
|
+
| `/mvt-sync-context` | Synchronize context with code changes |
|
|
83
|
+
| `/mvt-cleanup` | Clean up workspace artifacts |
|
|
84
|
+
|
|
85
|
+
### Utility Skills
|
|
86
|
+
|
|
87
|
+
| Skill | Description |
|
|
88
|
+
|-------|-------------|
|
|
89
|
+
| `/mvt-help` | Show available skills and workflow guidance |
|
|
90
|
+
| `/mvt-create-skill` | Create custom MVTT skills |
|
|
91
|
+
| `/mvt-add-context` | Add or update project context interactively |
|
|
92
|
+
| `/mvt-check-context` | Analyze context token load and optimization |
|
|
93
|
+
| `/mvt-template` | View and customize output templates |
|
|
94
|
+
|
|
95
|
+
## Standard Workflow
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
/mvt-analyze → /mvt-design → /mvt-implement → /mvt-review → /mvt-test
|
|
99
|
+
Analyst Architect Developer Reviewer Tester
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The Conductor (the underlying orchestration logic) keeps session state in `.ai-agents/workspace/session.yaml` so any skill can pick up where the previous one left off.
|
|
103
|
+
|
|
104
|
+
## Configuration
|
|
105
|
+
|
|
106
|
+
All preferences live in `.ai-agents/config.yaml`:
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
version: "2.0"
|
|
110
|
+
|
|
111
|
+
preferences:
|
|
112
|
+
language: en-US # en-US | zh-CN — chosen during install, changeable anytime
|
|
113
|
+
output:
|
|
114
|
+
no_emojis: true # Disable emojis in skill output
|
|
115
|
+
data_format: yaml # yaml | json
|
|
116
|
+
|
|
117
|
+
pattern:
|
|
118
|
+
active: "" # Detected via /mvt-init or set via --pattern on install
|
|
119
|
+
selection:
|
|
120
|
+
auto_detect: true
|
|
121
|
+
confirm_with_user: true
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Every skill reads this file on activation and enforces the settings through the shared Activation Protocol.
|
|
125
|
+
|
|
126
|
+
## Architecture Patterns
|
|
127
|
+
|
|
128
|
+
MVTT ships with first-class knowledge for three patterns (`.ai-agents/knowledge/patterns/`):
|
|
129
|
+
|
|
130
|
+
- **`ddd`** — Domain-Driven Design (bounded contexts, aggregates, domain events)
|
|
131
|
+
- **`clean-architecture`** — Layered boundaries, dependency inversion
|
|
132
|
+
- **`frontend-react`** — React-specific structural conventions
|
|
133
|
+
|
|
134
|
+
Each pattern contributes its own review checklist and design guidance that `/mvt-design`, `/mvt-review`, and `/mvt-refactor` automatically consume.
|
|
135
|
+
|
|
136
|
+
## Runtime Layout
|
|
137
|
+
|
|
138
|
+
After `install`, your project has:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
.claude/skills/mvt-*/SKILL.md # GENERATED (18 skills, Claude Code entry points)
|
|
142
|
+
|
|
143
|
+
.ai-agents/
|
|
144
|
+
├── config.yaml # CREATE_ONCE (user-editable)
|
|
145
|
+
├── registry.yaml # GENERATED (skill metadata)
|
|
146
|
+
├── .mvtt-manifest.json # GENERATED (install metadata, hashes)
|
|
147
|
+
├── workspace/
|
|
148
|
+
│ ├── session.yaml # CREATE_ONCE
|
|
149
|
+
│ ├── project-context.yaml # CREATE_ONCE
|
|
150
|
+
│ └── artifacts/ # USER DATA (skill outputs)
|
|
151
|
+
├── skills/_templates/
|
|
152
|
+
│ ├── *-output.md # GENERATED (14 templates)
|
|
153
|
+
│ └── custom/ # USER DATA (your overrides)
|
|
154
|
+
└── knowledge/
|
|
155
|
+
├── core/ # GENERATED (framework-wide principles)
|
|
156
|
+
├── patterns/ # GENERATED (ddd, clean-architecture, frontend-react)
|
|
157
|
+
├── principle/ # USER DATA (team conventions)
|
|
158
|
+
└── project/ # USER DATA (domain-specific knowledge)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
File classification:
|
|
162
|
+
|
|
163
|
+
- **GENERATED** — owned by the CLI; overwritten on every `update`
|
|
164
|
+
- **CREATE_ONCE** — created only on first install; never overwritten
|
|
165
|
+
- **USER DATA** — CLI never touches these paths
|
|
166
|
+
|
|
167
|
+
`doctor` hashes every GENERATED file against the manifest, so manual edits are detected immediately.
|
|
168
|
+
|
|
169
|
+
## Activation Protocol (Runtime)
|
|
170
|
+
|
|
171
|
+
Every skill shares a 4-step activation sequence, inlined into each `SKILL.md` at build time:
|
|
172
|
+
|
|
173
|
+
1. **Load Context** — `session.yaml` + `project-context.yaml` + skill-specific extended context
|
|
174
|
+
2. **Load Config & Apply Preferences** — read `config.yaml`, enforce language and output style
|
|
175
|
+
3. **Pre-flight Checks** — validate prerequisites (workspace initialized, required artifacts exist, etc.)
|
|
176
|
+
4. **Execute** — run skill-specific logic
|
|
177
|
+
|
|
178
|
+
DRY at source (one shared section per step), flat at runtime (each `SKILL.md` is self-contained — no cross-file reads when Claude Code loads a skill).
|
|
179
|
+
|
|
180
|
+
## Extending MVTT
|
|
181
|
+
|
|
182
|
+
Beyond the 18 built-in skills, run `/mvt-create-skill` to scaffold a project-specific skill interactively. Custom skills live under `.ai-agents/skills/` and can override or complement any default behavior (e.g. a `/mvt-test-gherkin` variant that emits Gherkin feature files in your team's house style).
|
|
183
|
+
|
|
184
|
+
## Development (Contributing to MVTT Itself)
|
|
185
|
+
|
|
186
|
+
Requirements: Node.js ≥ 18.
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
npm install
|
|
190
|
+
npm run build # Compile TypeScript
|
|
191
|
+
npm test # Run test suite (66 tests)
|
|
192
|
+
npm test -- --coverage # With coverage report
|
|
193
|
+
|
|
194
|
+
# Rebuild skills / templates from sources into any output directory
|
|
195
|
+
node dist/index.js build --out .test-output
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Source layout:
|
|
199
|
+
|
|
200
|
+
- `src/` — CLI TypeScript source (commander-based; uses `prompts` for interactive selection)
|
|
201
|
+
- `sources/skills/<name>/manifest.yaml + business.md` — Skill source files
|
|
202
|
+
- `sources/templates/<name>/manifest.yaml + body.md` — Template source files
|
|
203
|
+
- `sources/sections/*.md` — Shared activation protocol sections (mustache-style blocks)
|
|
204
|
+
- `registry.yaml` — Single source of truth for skill metadata
|
|
205
|
+
- `install-manifest.yaml` — File classification (generated / create_once / user_data)
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assembler.d.ts","sourceRoot":"","sources":["../../src/build/assembler.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,eAAe,GACvB,MAAM,CAiBR"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parse as parseYaml } from "yaml";
|
|
4
|
+
import { loadSection } from "./section-loader.js";
|
|
5
|
+
function buildFrontmatter(fm) {
|
|
6
|
+
const lines = ["---"];
|
|
7
|
+
for (const [key, value] of Object.entries(fm)) {
|
|
8
|
+
if (value.includes("\n") || value.includes("'")) {
|
|
9
|
+
lines.push(`${key}: "${value.replace(/"/g, '\\"')}"`);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
lines.push(`${key}: '${value}'`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
lines.push("---");
|
|
16
|
+
return lines.join("\n");
|
|
17
|
+
}
|
|
18
|
+
export function assembleFromManifest(manifestPath, options) {
|
|
19
|
+
const raw = readFileSync(manifestPath, "utf-8");
|
|
20
|
+
const manifest = parseYaml(raw);
|
|
21
|
+
const skillDir = path.dirname(manifestPath);
|
|
22
|
+
const parts = [];
|
|
23
|
+
parts.push(buildFrontmatter(manifest.frontmatter));
|
|
24
|
+
parts.push("");
|
|
25
|
+
for (const section of manifest.sections) {
|
|
26
|
+
const content = loadSection(section, skillDir, options.sourcesDir);
|
|
27
|
+
parts.push(content.trimEnd());
|
|
28
|
+
parts.push("");
|
|
29
|
+
}
|
|
30
|
+
return parts.join("\n");
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=assembler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assembler.js","sourceRoot":"","sources":["../../src/build/assembler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,SAAS,gBAAgB,CAAC,EAA0B;IAClD,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC;IACtB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9C,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAChD,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,KAAK,GAAG,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAOD,MAAM,UAAU,oBAAoB,CAClC,YAAoB,EACpB,OAAwB;IAExB,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAa,SAAS,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAE5C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;IACnD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QACnE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Section } from "../types/manifest.js";
|
|
2
|
+
export declare function applyParams(template: string, params: Record<string, unknown>): string;
|
|
3
|
+
export declare function loadSection(section: Section, skillDir: string, sourcesDir: string): string;
|
|
4
|
+
//# sourceMappingURL=section-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"section-loader.d.ts","sourceRoot":"","sources":["../../src/build/section-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAuCpD,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAIR;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,MAAM,CAiBR"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const BLOCK_PATTERN = /\{\{#(\w+)\}\}([\s\S]*?)\{\{\/\1\}\}\n?/g;
|
|
4
|
+
const VAR_PATTERN = /\{\{(\w+|\.)?\}\}/g;
|
|
5
|
+
function replaceVars(template, vars) {
|
|
6
|
+
return template.replace(VAR_PATTERN, (_match, key) => {
|
|
7
|
+
if (key === ".")
|
|
8
|
+
return String(vars["."] ?? "");
|
|
9
|
+
const val = vars[key];
|
|
10
|
+
if (val === undefined || val === null)
|
|
11
|
+
return "";
|
|
12
|
+
return String(val);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function expandBlocks(template, params) {
|
|
16
|
+
return template.replace(BLOCK_PATTERN, (_match, key, rawBody) => {
|
|
17
|
+
const val = params[key];
|
|
18
|
+
if (val === undefined || val === null || val === false)
|
|
19
|
+
return "";
|
|
20
|
+
const body = rawBody.replace(/^\n/, "");
|
|
21
|
+
if (Array.isArray(val)) {
|
|
22
|
+
return val
|
|
23
|
+
.map((item) => {
|
|
24
|
+
if (typeof item === "object" && item !== null) {
|
|
25
|
+
return replaceVars(body, item).trimEnd();
|
|
26
|
+
}
|
|
27
|
+
return replaceVars(body, { ".": item }).trimEnd();
|
|
28
|
+
})
|
|
29
|
+
.join("\n");
|
|
30
|
+
}
|
|
31
|
+
return replaceVars(body, params);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export function applyParams(template, params) {
|
|
35
|
+
let result = expandBlocks(template, params);
|
|
36
|
+
result = replaceVars(result, params);
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
export function loadSection(section, skillDir, sourcesDir) {
|
|
40
|
+
switch (section.type) {
|
|
41
|
+
case "inline":
|
|
42
|
+
return section.content;
|
|
43
|
+
case "file": {
|
|
44
|
+
const filePath = path.resolve(skillDir, section.source);
|
|
45
|
+
return readFileSync(filePath, "utf-8");
|
|
46
|
+
}
|
|
47
|
+
case "shared":
|
|
48
|
+
case "template": {
|
|
49
|
+
const filePath = path.resolve(sourcesDir, section.source);
|
|
50
|
+
const content = readFileSync(filePath, "utf-8");
|
|
51
|
+
return applyParams(content, section.params ?? {});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=section-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"section-loader.js","sourceRoot":"","sources":["../../src/build/section-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/build/validator.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AA6CD,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,eAAe,EAAE,CAqDnB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parse as parseYaml } from "yaml";
|
|
4
|
+
function validateSectionRef(section, skillDir, sourcesDir) {
|
|
5
|
+
if (section.type === "file") {
|
|
6
|
+
const p = path.resolve(skillDir, section.source);
|
|
7
|
+
if (!existsSync(p))
|
|
8
|
+
return `File not found: ${section.source} (resolved: ${p})`;
|
|
9
|
+
}
|
|
10
|
+
if (section.type === "shared" || section.type === "template") {
|
|
11
|
+
const p = path.resolve(sourcesDir, section.source);
|
|
12
|
+
if (!existsSync(p))
|
|
13
|
+
return `Shared section not found: ${section.source} (resolved: ${p})`;
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
function checkParamCompleteness(sectionSource, sourcesDir, params) {
|
|
18
|
+
const errors = [];
|
|
19
|
+
const filePath = path.resolve(sourcesDir, sectionSource);
|
|
20
|
+
if (!existsSync(filePath))
|
|
21
|
+
return errors;
|
|
22
|
+
const content = readFileSync(filePath, "utf-8");
|
|
23
|
+
const stripped = content.replace(/\{\{#(\w+)\}\}[\s\S]*?\{\{\/\1\}\}/g, "");
|
|
24
|
+
const topLevelVars = stripped.match(/\{\{(\w+)\}\}/g) ?? [];
|
|
25
|
+
const requiredParams = new Set(topLevelVars.map((v) => v.slice(2, -2)));
|
|
26
|
+
for (const varName of requiredParams) {
|
|
27
|
+
if (varName === ".")
|
|
28
|
+
continue;
|
|
29
|
+
if (!params || !(varName in params)) {
|
|
30
|
+
errors.push(`Missing param "${varName}" for section "${sectionSource}"`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return errors;
|
|
34
|
+
}
|
|
35
|
+
export function validateManifest(manifestPath, sourcesDir) {
|
|
36
|
+
const errors = [];
|
|
37
|
+
if (!existsSync(manifestPath)) {
|
|
38
|
+
errors.push({ file: manifestPath, message: "Manifest file not found" });
|
|
39
|
+
return errors;
|
|
40
|
+
}
|
|
41
|
+
let manifest;
|
|
42
|
+
try {
|
|
43
|
+
const raw = readFileSync(manifestPath, "utf-8");
|
|
44
|
+
manifest = parseYaml(raw);
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
errors.push({ file: manifestPath, message: `Invalid YAML: ${e}` });
|
|
48
|
+
return errors;
|
|
49
|
+
}
|
|
50
|
+
if (!manifest.name) {
|
|
51
|
+
errors.push({ file: manifestPath, message: 'Missing required field "name"' });
|
|
52
|
+
}
|
|
53
|
+
if (!manifest.output) {
|
|
54
|
+
errors.push({ file: manifestPath, message: 'Missing required field "output"' });
|
|
55
|
+
}
|
|
56
|
+
if (!manifest.sections || !Array.isArray(manifest.sections)) {
|
|
57
|
+
errors.push({ file: manifestPath, message: 'Missing or invalid "sections" array' });
|
|
58
|
+
return errors;
|
|
59
|
+
}
|
|
60
|
+
const skillDir = path.dirname(manifestPath);
|
|
61
|
+
for (let i = 0; i < manifest.sections.length; i++) {
|
|
62
|
+
const section = manifest.sections[i];
|
|
63
|
+
const refErr = validateSectionRef(section, skillDir, sourcesDir);
|
|
64
|
+
if (refErr) {
|
|
65
|
+
errors.push({ file: manifestPath, message: `sections[${i}]: ${refErr}` });
|
|
66
|
+
}
|
|
67
|
+
if ((section.type === "shared" || section.type === "template") &&
|
|
68
|
+
section.params) {
|
|
69
|
+
const paramErrors = checkParamCompleteness(section.source, sourcesDir, section.params);
|
|
70
|
+
for (const pe of paramErrors) {
|
|
71
|
+
errors.push({ file: manifestPath, message: `sections[${i}]: ${pe}` });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return errors;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/build/validator.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAQA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+CvD"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { buildCommand } from "./commands/build.js";
|
|
3
|
+
import { installCommand } from "./commands/install.js";
|
|
4
|
+
import { updateCommand } from "./commands/update.js";
|
|
5
|
+
import { doctorCommand } from "./commands/doctor.js";
|
|
6
|
+
import { uninstallCommand } from "./commands/uninstall.js";
|
|
7
|
+
import { getVersion } from "./commands/shared.js";
|
|
8
|
+
export async function run(argv) {
|
|
9
|
+
const program = new Command();
|
|
10
|
+
program
|
|
11
|
+
.name("mvtt")
|
|
12
|
+
.description("My Virtual Tech Team CLI")
|
|
13
|
+
.version(getVersion(), "-v, --version");
|
|
14
|
+
program
|
|
15
|
+
.command("install")
|
|
16
|
+
.description("Install MVTT into current project")
|
|
17
|
+
.option("--pattern <name>", "Set architecture pattern (ddd, clean-architecture, etc.)")
|
|
18
|
+
.action(async (opts) => {
|
|
19
|
+
await installCommand(opts);
|
|
20
|
+
});
|
|
21
|
+
program
|
|
22
|
+
.command("update")
|
|
23
|
+
.description("Update MVTT to latest version")
|
|
24
|
+
.option("--check", "Only report version diff, do not modify")
|
|
25
|
+
.action((opts) => {
|
|
26
|
+
updateCommand(opts);
|
|
27
|
+
});
|
|
28
|
+
program
|
|
29
|
+
.command("doctor")
|
|
30
|
+
.description("Check installation health")
|
|
31
|
+
.action(() => {
|
|
32
|
+
doctorCommand();
|
|
33
|
+
});
|
|
34
|
+
program
|
|
35
|
+
.command("uninstall")
|
|
36
|
+
.description("Remove MVTT generated files")
|
|
37
|
+
.action(async () => {
|
|
38
|
+
await uninstallCommand();
|
|
39
|
+
});
|
|
40
|
+
program
|
|
41
|
+
.command("build")
|
|
42
|
+
.description("Build skills and templates from sources (dev)")
|
|
43
|
+
.option("--out <dir>", "Output directory (default: cwd)")
|
|
44
|
+
.action((opts) => {
|
|
45
|
+
buildCommand(opts);
|
|
46
|
+
});
|
|
47
|
+
await program.parseAsync(argv, { from: "user" });
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,0BAA0B,CAAC;SACvC,OAAO,CAAC,UAAU,EAAE,EAAE,eAAe,CAAC,CAAC;IAE1C,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,mCAAmC,CAAC;SAChD,MAAM,CAAC,kBAAkB,EAAE,0DAA0D,CAAC;SACtF,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,+BAA+B,CAAC;SAC5C,MAAM,CAAC,SAAS,EAAE,yCAAyC,CAAC;SAC5D,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACf,aAAa,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,2BAA2B,CAAC;SACxC,MAAM,CAAC,GAAG,EAAE;QACX,aAAa,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,6BAA6B,CAAC;SAC1C,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,gBAAgB,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,+CAA+C,CAAC;SAC5D,MAAM,CAAC,aAAa,EAAE,iCAAiC,CAAC;SACxD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACf,YAAY,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;IAEL,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAE,YAAiB,GAAG,IAAI,CA4C7D"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parse as parseYaml } from "yaml";
|
|
4
|
+
import { assembleFromManifest } from "../build/assembler.js";
|
|
5
|
+
import { validateManifest } from "../build/validator.js";
|
|
6
|
+
export function buildCommand(options = {}) {
|
|
7
|
+
const projectRoot = process.cwd();
|
|
8
|
+
const sourcesDir = path.resolve(projectRoot, "sources");
|
|
9
|
+
const outputRoot = options.out ? path.resolve(options.out) : projectRoot;
|
|
10
|
+
const timestamp = new Date().toISOString();
|
|
11
|
+
let totalFiles = 0;
|
|
12
|
+
let totalErrors = 0;
|
|
13
|
+
for (const kind of ["skills", "templates"]) {
|
|
14
|
+
const baseDir = path.resolve(sourcesDir, kind);
|
|
15
|
+
if (!existsSync(baseDir))
|
|
16
|
+
continue;
|
|
17
|
+
for (const entry of readdirSync(baseDir)) {
|
|
18
|
+
const manifestPath = path.join(baseDir, entry, "manifest.yaml");
|
|
19
|
+
if (!existsSync(manifestPath))
|
|
20
|
+
continue;
|
|
21
|
+
const errors = validateManifest(manifestPath, sourcesDir);
|
|
22
|
+
if (errors.length > 0) {
|
|
23
|
+
for (const err of errors) {
|
|
24
|
+
console.error(`[ERROR] ${err.file}: ${err.message}`);
|
|
25
|
+
}
|
|
26
|
+
totalErrors += errors.length;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const raw = readFileSync(manifestPath, "utf-8");
|
|
30
|
+
const manifest = parseYaml(raw);
|
|
31
|
+
const content = assembleFromManifest(manifestPath, {
|
|
32
|
+
sourcesDir,
|
|
33
|
+
timestamp,
|
|
34
|
+
});
|
|
35
|
+
const outPath = path.resolve(outputRoot, manifest.output);
|
|
36
|
+
mkdirSync(path.dirname(outPath), { recursive: true });
|
|
37
|
+
writeFileSync(outPath, content, "utf-8");
|
|
38
|
+
console.log(`[OK] ${manifest.output}`);
|
|
39
|
+
totalFiles++;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
console.log(`\nBuild complete: ${totalFiles} files generated, ${totalErrors} errors.`);
|
|
43
|
+
if (totalErrors > 0)
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC1F,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAMzD,MAAM,UAAU,YAAY,CAAC,UAAwB,EAAE;IACrD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAClC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;IAEzE,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAU,EAAE,CAAC;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,SAAS;QAEnC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YACzC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;YAChE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;gBAAE,SAAS;YAExC,MAAM,MAAM,GAAG,gBAAgB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;YAC1D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;oBACzB,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBACvD,CAAC;gBACD,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC;gBAC7B,SAAS;YACX,CAAC;YAED,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAChD,MAAM,QAAQ,GAAa,SAAS,CAAC,GAAG,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAG,oBAAoB,CAAC,YAAY,EAAE;gBACjD,UAAU;gBACV,SAAS;aACV,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC1D,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACtD,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAEzC,OAAO,CAAC,GAAG,CAAC,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACvC,UAAU,EAAE,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,qBAAqB,UAAU,qBAAqB,WAAW,UAAU,CAAC,CAAC;IACvF,IAAI,WAAW,GAAG,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAOA,wBAAgB,aAAa,IAAI,IAAI,CAgEpC"}
|