@ncoderz/awa 1.2.0 → 1.4.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/README.md +31 -191
- package/dist/{chunk-3SSUJFKN.js → chunk-ALEGCDAZ.js} +1 -1
- package/dist/chunk-ALEGCDAZ.js.map +1 -0
- package/dist/{config-2TOQATI3.js → config-LWUO5EXL.js} +2 -2
- package/dist/index.js +1185 -53
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/templates/awa/.awa/.agent/schemas/EXAMPLES.schema.yaml +2 -2
- package/templates/awa/.awa/.agent/schemas/FEAT.schema.yaml +3 -3
- package/templates/awa/.awa/.agent/schemas/README.schema.yaml +4 -4
- package/templates/awa/.awa/.agent/schemas/REQ.schema.yaml +2 -2
- package/templates/awa/_README.md +7 -7
- package/templates/awa/_partials/awa.core.md +1 -1
- package/templates/awa/_partials/awa.usage.md +12 -12
- package/dist/chunk-3SSUJFKN.js.map +0 -1
- /package/dist/{config-2TOQATI3.js.map → config-LWUO5EXL.js.map} +0 -0
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ awa is an Agent Workflow for AIs. It is also a CLI tool to powerfully manage age
|
|
|
10
10
|
|
|
11
11
|
> awa was written by awa (AI-assisted development using its own workflows). The workflows themselves are designed and crafted by a human who uses Copilot. If something is wrong, let's fix it together.
|
|
12
12
|
|
|
13
|
+
**[Documentation](https://awa.ncoderz.com)** · **[Quick Start](https://awa.ncoderz.com/guides/quick-start/)** · **[CLI Reference](https://awa.ncoderz.com/reference/cli/)**
|
|
13
14
|
|
|
14
15
|
## The Problem
|
|
15
16
|
|
|
@@ -21,45 +22,36 @@ Without structure, work drifts and nobody, including the AI, can trace what happ
|
|
|
21
22
|
|
|
22
23
|
## How awa Solves It
|
|
23
24
|
|
|
24
|
-
awa generates agent configuration files from **templates**.
|
|
25
|
+
awa does two thing. Firstly, it generates agent configuration files from **templates**. Secondly, the generated output includes a powerful spec-driven development workflow with full traceability:
|
|
25
26
|
|
|
26
27
|
```
|
|
27
28
|
ARCHITECTURE → FEAT → REQUIREMENTS → DESIGN → TASKS → CODE & TESTS → DOCUMENTATION
|
|
28
29
|
```
|
|
29
30
|
|
|
30
|
-
Every code and test
|
|
31
|
+
Every code and test artifact traces back to its requirement and acceptance criteria origin through explicit markers (`@awa-impl`, `@awa-test`, `@awa-component`). Any line of code traces back to the requirement that motivated it. Any requirement traces forward to the tests that verify it.
|
|
31
32
|
|
|
32
33
|
Not only this, but awa actively checks that specs match a high quality schema, and that all requirements and acceptance criteria map to code and tests. This helps guide the AI to produce higher quality output.
|
|
33
34
|
|
|
34
|
-
## Features
|
|
35
|
+
## Workflow Features
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
- **Structured workflow with full traceability** - every requirement, acceptance critera and property test has an ID, every line of code links back via `@awa-component`, `@awa-impl` and `@awa-test` code markers
|
|
38
|
+
- **`awa check`** - allows AI or humans to enforces spec structure via YAML schemas, and to validate traceability markers against spec IDs
|
|
39
|
+
- **`awa trace`** - allows AI or humans to explore traceability chains and quickly assemble context from specs, code, and tests
|
|
40
|
+
- **Agent-agnostic** - Copilot, Claude, Cursor, Windsurf, and more from a single template set
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
- Requirements written in [EARS format](https://en.wikipedia.org/wiki/Easy_Approach_to_Requirements_Syntax) (INCOSE) — structured, testable, unambiguous
|
|
40
|
-
- Every requirement has an ID, every line of code links back to it via `@awa-impl` and `@awa-test` markers
|
|
41
|
-
- `awa check` checks that specs match their schemas, and that all traceability markers resolve to real spec IDs. Any acceptance criteria missing tests are flagged to the AI automatically
|
|
42
|
-
- All AI orchestration documents all live in `.awa/`
|
|
42
|
+
## Template Features
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
- **[Eta](https://eta.js.org/) templates** with conditionals, loops, and partials for AI configuration files
|
|
45
|
+
- **Feature flags and presets** - to turn content on/off per project
|
|
46
|
+
- **Template overlays** - to layer customizations without forking
|
|
47
|
+
- **`awa template diff`** - shows exactly what changed before you commit; `--watch` re-diffs on template changes
|
|
48
|
+
- **`awa template test`** - verifies templates against fixtures and snapshots
|
|
49
|
+
- **`awa template features`** - discovers available feature flags and presets
|
|
50
|
+
- **Multi-target configuration** - for generating different agent setups in one command
|
|
51
|
+
- **Git or local** - template sources — GitHub, GitLab, Bitbucket, or local path
|
|
52
|
+
- **`--json` and `--summary`** - flags for CI integration
|
|
45
53
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
The awa CLI can be used to update your AI guiding files such as AGENTS.md automatically from templates, making it easy to keep them up-to-date and in-sync for every project.
|
|
49
|
-
|
|
50
|
-
- [Eta](https://eta.js.org/) templates with conditionals, loops, and partials allow templating AI files (and other project files if you wish)
|
|
51
|
-
- Pull templates from GitHub, GitLab, Bitbucket, or use a local path
|
|
52
|
-
- Optional `.awa.toml` config, or just use CLI flags
|
|
53
|
-
- Feature flags and presets to turn content on/off per project
|
|
54
|
-
- `awa check` validates traceability markers against spec IDs and enforces spec file structure via YAML schemas
|
|
55
|
-
- Template overlays (`--overlay`) allow layering custom files over a base template without forking it
|
|
56
|
-
- `awa diff` shows exactly what has changed in a template before applying it to your project; `--watch` re-diffs on template changes, making template development easy
|
|
57
|
-
- `awa test` verifies templates produce expected output across feature combinations by automatically diffing against fixture files
|
|
58
|
-
- `awa features` discovers available feature flags and presets in a template
|
|
59
|
-
- `--json` flag for machine-readable output in CI pipelines
|
|
60
|
-
- `--summary` flag for compact one-line counts output
|
|
61
|
-
|
|
62
|
-
See [CLI Reference](docs/CLI.md), [Template Engine](docs/TEMPLATE_ENGINE.md), [Template Testing](docs/TEMPLATE_TESTING.md), and [Schema Rules](docs/SCHEMA_RULES.md) for details.
|
|
54
|
+
See the **[full documentation](https://awa.ncoderz.com)** for details.
|
|
63
55
|
|
|
64
56
|
## Quick Start
|
|
65
57
|
|
|
@@ -75,177 +67,18 @@ Or use with npx:
|
|
|
75
67
|
npx @ncoderz/awa init .
|
|
76
68
|
```
|
|
77
69
|
|
|
78
|
-
###
|
|
79
|
-
|
|
80
|
-
Generate files into the current directory using the bundled default template:
|
|
70
|
+
### Initialise Project
|
|
81
71
|
|
|
82
72
|
```bash
|
|
73
|
+
# Current directory, default template
|
|
83
74
|
awa init .
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Generate with specific features enabled:
|
|
87
75
|
|
|
88
|
-
|
|
76
|
+
# With specific features
|
|
89
77
|
awa init . --features copilot claude cursor
|
|
90
78
|
```
|
|
91
79
|
|
|
92
|
-
Generate to a specific output directory:
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
awa init ./my-project
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### Preview Changes
|
|
99
80
|
|
|
100
|
-
See
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
awa diff .
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
Watch for template changes and re-diff automatically:
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
awa diff . --watch
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Apply any template configured file deletions (disabled by default):
|
|
113
|
-
|
|
114
|
-
```bash
|
|
115
|
-
awa init . --delete
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Layer custom files over the base template with overlays:
|
|
119
|
-
|
|
120
|
-
```bash
|
|
121
|
-
awa init . --overlay ./my-overrides
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Validate
|
|
125
|
-
|
|
126
|
-
Check traceability markers and spec file structure:
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
awa check
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### Test Templates
|
|
133
|
-
|
|
134
|
-
Verify templates produce expected output across feature combinations:
|
|
135
|
-
|
|
136
|
-
```bash
|
|
137
|
-
awa test
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Discover Features
|
|
141
|
-
|
|
142
|
-
List all feature flags available in a template:
|
|
143
|
-
|
|
144
|
-
```bash
|
|
145
|
-
awa features
|
|
146
|
-
awa features --json # machine-readable output
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
## The `.awa/` Directory
|
|
150
|
-
|
|
151
|
-
Each workflow stage produces artifacts in `.awa/`:
|
|
152
|
-
|
|
153
|
-
```
|
|
154
|
-
.awa/
|
|
155
|
-
├── specs/
|
|
156
|
-
│ ├── ARCHITECTURE.md # System overview
|
|
157
|
-
│ ├── FEAT-{CODE}-*.md # Feature context & motivation
|
|
158
|
-
│ ├── EXAMPLES-{CODE}-*-{nnn}.md # Usage examples per feature
|
|
159
|
-
│ ├── REQ-{CODE}-*.md # Requirements (EARS format)
|
|
160
|
-
│ ├── DESIGN-{CODE}-*.md # Design & components
|
|
161
|
-
│ └── API-{CODE}-*.tsp # TypeSpec API definitions
|
|
162
|
-
├── tasks/
|
|
163
|
-
│ └── TASK-{CODE}-*-{nnn}.md # Implementation steps
|
|
164
|
-
├── plans/
|
|
165
|
-
│ └── PLAN-{nnn}-*.md # Ad-hoc plans
|
|
166
|
-
├── align/
|
|
167
|
-
│ └── ALIGN-{x}-WITH-{y}-{nnn}.md # Alignment reports
|
|
168
|
-
└── rules/
|
|
169
|
-
└── *.md # Project-specific rules
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
## The Traceability Chain
|
|
173
|
-
|
|
174
|
-
Every artifact links to its origin through IDs and markers:
|
|
175
|
-
|
|
176
|
-
```
|
|
177
|
-
REQ-{CODE}-*.md
|
|
178
|
-
└── {CODE}-1: Requirement title
|
|
179
|
-
└── {CODE}-1_AC-1: Acceptance criterion
|
|
180
|
-
│
|
|
181
|
-
▼
|
|
182
|
-
DESIGN-{CODE}-*.md
|
|
183
|
-
└── {CODE}-ComponentName
|
|
184
|
-
├── IMPLEMENTS: {CODE}-1_AC-1
|
|
185
|
-
└── {CODE}_P-1: Correctness property
|
|
186
|
-
│
|
|
187
|
-
▼
|
|
188
|
-
Source code
|
|
189
|
-
└── // @awa-component: {CODE}-ComponentName
|
|
190
|
-
└── // @awa-impl: {CODE}-1_AC-1
|
|
191
|
-
│
|
|
192
|
-
▼
|
|
193
|
-
Tests
|
|
194
|
-
├── // @awa-test: {CODE}_P-1 ← verifies property
|
|
195
|
-
└── // @awa-test: {CODE}-1_AC-1 ← verifies acceptance criterion
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
Every link is explicit. Nothing is implied.
|
|
199
|
-
|
|
200
|
-
See [Workflow](docs/WORKFLOW.md) for IDs, markers, and how to read a trace.
|
|
201
|
-
|
|
202
|
-
## CI Integration
|
|
203
|
-
|
|
204
|
-
Use `--json` for structured output in CI pipelines, or `--summary` for compact build-log output:
|
|
205
|
-
|
|
206
|
-
```bash
|
|
207
|
-
# Detect template drift (exit code 1 = differences found)
|
|
208
|
-
awa diff . --json > diff-result.json
|
|
209
|
-
|
|
210
|
-
# Compact summary for build logs
|
|
211
|
-
awa diff . --summary
|
|
212
|
-
# Output: changed: 2, new: 1, matching: 10, deleted: 0
|
|
213
|
-
|
|
214
|
-
# Validate traceability
|
|
215
|
-
awa check --format json > check-result.json
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
See [CI Integration](docs/CLI.md#ci-integration) in the CLI reference for JSON output formats.
|
|
219
|
-
|
|
220
|
-
## Exit Codes
|
|
221
|
-
|
|
222
|
-
| Command | 0 | 1 | 2 |
|
|
223
|
-
|---------|---|---|---|
|
|
224
|
-
| `awa init` / `awa generate` | Success | — | Internal error |
|
|
225
|
-
| `awa diff` | All files match | Differences found | Internal error |
|
|
226
|
-
| `awa check` | All checks pass | Errors found | Internal error |
|
|
227
|
-
| `awa test` | All fixtures pass | Failures found | Internal error |
|
|
228
|
-
| `awa features` | Success | Error | — |
|
|
229
|
-
|
|
230
|
-
## Documentation
|
|
231
|
-
|
|
232
|
-
| Document | Description |
|
|
233
|
-
|----------|-------------|
|
|
234
|
-
| [Workflow](docs/WORKFLOW.md) | The awa workflow, `.awa/` structure, traceability chain, IDs and markers |
|
|
235
|
-
| [CLI Reference](docs/CLI.md) | Commands, options, configuration, presets, and how it works |
|
|
236
|
-
| [Template Engine](docs/TEMPLATE_ENGINE.md) | Template sources, Eta syntax, partials, file handling, delete lists |
|
|
237
|
-
| [Template Testing](docs/TEMPLATE_TESTING.md) | The `awa test` command, fixture format, snapshots, CI setup |
|
|
238
|
-
| [Traceability Check](docs/TRACEABILITY_CHECK.md) | The `awa check` command, checks, configuration, JSON output |
|
|
239
|
-
| [Schema Rules](docs/SCHEMA_RULES.md) | Declarative YAML rules for validating spec file structure |
|
|
240
|
-
|
|
241
|
-
## Community
|
|
242
|
-
|
|
243
|
-
- [Contributing Guide](CONTRIBUTING.md)
|
|
244
|
-
- [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
245
|
-
- [Security Policy](SECURITY.md)
|
|
246
|
-
- [Support](SUPPORT.md)
|
|
247
|
-
- [Maintainers](MAINTAINERS.md)
|
|
248
|
-
- [Funding](.github/FUNDING.yml)
|
|
81
|
+
See the **[Quick Start guide](https://awa.ncoderz.com/guides/quick-start/)** for more.
|
|
249
82
|
|
|
250
83
|
## Alternatives
|
|
251
84
|
|
|
@@ -260,7 +93,7 @@ Several tools address parts of the AI-assisted development workflow. Here's how
|
|
|
260
93
|
| **Template engine** | ✅ Eta with conditionals, loops, partials | ❌ | ❌ Static templates copied on init | ❌ Static skill files | ❌ Static markdown | ❌ |
|
|
261
94
|
| **Feature flags** | ✅ Enable/disable content per project | ❌ | ❌ | ❌ | ⚠️ Lite/Full modes | ❌ |
|
|
262
95
|
| **Presets** | ✅ Named flag bundles | ❌ | ❌ | ⚠️ Complexity levels | ⚠️ Operation levels | ❌ |
|
|
263
|
-
| **AI Instructions Drift detection** | ✅ `awa diff` shows what changed vs. templates | ❌ | ❌ | ❌ | ⚠️ Manual compliance checklist | ❌ |
|
|
96
|
+
| **AI Instructions Drift detection** | ✅ `awa template diff` shows what changed vs. templates | ❌ | ❌ | ❌ | ⚠️ Manual compliance checklist | ❌ |
|
|
264
97
|
| **Re-generation** | ✅ Generates from templates on every run | ❌ Specs created per feature | ❌ One-time `specify init` | ❌ One-time install | ❌ One-time copy | ❌ One-time manual creation |
|
|
265
98
|
| **Agent hooks** | ❌ | ✅ Event-driven agent triggers on file save | ❌ | ❌ | ❌ | ❌ |
|
|
266
99
|
| **Built-in IDE** | ❌ | ✅ VS Code-compatible IDE | ❌ | ❌ | ❌ | ❌ |
|
|
@@ -301,7 +134,14 @@ npm run build
|
|
|
301
134
|
| `npm run gen:awa:this` | Generate awa templates to current directory |
|
|
302
135
|
| `npm run diff:awa:this` | Diff awa templates against current directory |
|
|
303
136
|
|
|
137
|
+
## Community
|
|
304
138
|
|
|
139
|
+
- [Contributing Guide](CONTRIBUTING.md)
|
|
140
|
+
- [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
141
|
+
- [Security Policy](SECURITY.md)
|
|
142
|
+
- [Support](SUPPORT.md)
|
|
143
|
+
- [Maintainers](MAINTAINERS.md)
|
|
144
|
+
- [Funding](.github/FUNDING.yml)
|
|
305
145
|
|
|
306
146
|
## License
|
|
307
147
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/config.ts","../src/types/index.ts","../src/utils/fs.ts","../src/utils/logger.ts"],"sourcesContent":["// @awa-component: CFG-ConfigLoader\n// @awa-component: MULTI-TargetResolver\n// @awa-impl: CFG-1_AC-1\n// @awa-impl: CFG-1_AC-2\n// @awa-impl: CFG-1_AC-3\n// @awa-impl: CFG-1_AC-4\n// @awa-impl: CFG-2_AC-1\n// @awa-impl: CFG-2_AC-2\n// @awa-impl: CFG-2_AC-3\n// @awa-impl: CFG-3_AC-1\n// @awa-impl: CFG-3_AC-2\n// @awa-impl: CFG-3_AC-3\n// @awa-impl: CFG-3_AC-4\n// @awa-impl: CFG-3_AC-5\n// @awa-impl: CFG-3_AC-6\n// @awa-impl: CFG-3_AC-7\n// @awa-impl: CFG-3_AC-8\n// @awa-impl: CFG-3_AC-9\n// @awa-impl: CFG-3_AC-10\n// @awa-impl: CFG-4_AC-1\n// @awa-impl: CFG-4_AC-2\n// @awa-impl: CFG-4_AC-3\n// @awa-impl: CFG-4_AC-4\n// @awa-impl: CFG-5_AC-1\n// @awa-impl: CFG-6_AC-1\n// @awa-impl: CFG-6_AC-2\n// @awa-impl: CLI-1_AC-4\n// @awa-impl: CLI-2_AC-2\n// @awa-impl: CLI-2_AC-3\n// @awa-impl: CLI-2_AC-4\n// @awa-impl: CLI-4_AC-3\n// @awa-impl: CLI-7_AC-2\n// @awa-impl: FP-1_AC-1\n// @awa-impl: FP-1_AC-2\n// @awa-impl: FP-1_AC-3\n// @awa-impl: FP-1_AC-4\n// @awa-impl: FP-3_AC-1\n// @awa-impl: FP-3_AC-2\n// @awa-impl: FP-3_AC-3\n// @awa-impl: FP-5_AC-1\n// @awa-impl: FP-5_AC-2\n// @awa-impl: FP-5_AC-3\n// @awa-impl: MULTI-1_AC-1\n// @awa-impl: MULTI-2_AC-1\n// @awa-impl: MULTI-3_AC-1\n// @awa-impl: MULTI-5_AC-2\n\nimport { parse } from 'smol-toml';\nimport {\n ConfigError,\n type FileConfig,\n type PresetDefinitions,\n type RawCliOptions,\n type ResolvedOptions,\n type TargetConfig,\n type UpdateCheckConfig,\n} from '../types/index.js';\nimport { pathExists, readTextFile } from '../utils/fs.js';\nimport { logger } from '../utils/logger.js';\n\nconst DEFAULT_CONFIG_PATH = '.awa.toml';\n\nexport class ConfigLoader {\n // @awa-impl: CFG-1_AC-1, CFG-1_AC-2, CFG-1_AC-3, CFG-1_AC-4\n async load(configPath: string | null): Promise<FileConfig | null> {\n const pathToLoad = configPath ?? DEFAULT_CONFIG_PATH;\n\n // Check if file exists\n const exists = await pathExists(pathToLoad);\n\n // If explicit path provided but doesn't exist, error\n if (configPath && !exists) {\n throw new ConfigError(\n `Configuration file not found: ${configPath}`,\n 'FILE_NOT_FOUND',\n configPath\n );\n }\n\n // If default path doesn't exist, return null (no error)\n if (!configPath && !exists) {\n return null;\n }\n\n // Read and parse TOML\n try {\n const content = await readTextFile(pathToLoad);\n const parsed = parse(content) as Record<string, unknown>;\n\n // Validate and extract known options\n const config: FileConfig = {};\n\n if (parsed.output !== undefined) {\n if (typeof parsed.output !== 'string') {\n throw new ConfigError(\n `Invalid type for 'output': expected string, got ${typeof parsed.output}`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n config.output = parsed.output;\n }\n\n if (parsed.template !== undefined) {\n if (typeof parsed.template !== 'string') {\n throw new ConfigError(\n `Invalid type for 'template': expected string, got ${typeof parsed.template}`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n config.template = parsed.template;\n }\n\n if (parsed.features !== undefined) {\n if (\n !Array.isArray(parsed.features) ||\n !parsed.features.every((f) => typeof f === 'string')\n ) {\n throw new ConfigError(\n `Invalid type for 'features': expected array of strings`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n config.features = parsed.features;\n }\n\n if (parsed.preset !== undefined) {\n if (!Array.isArray(parsed.preset) || !parsed.preset.every((p) => typeof p === 'string')) {\n throw new ConfigError(\n `Invalid type for 'preset': expected array of strings`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n config.preset = parsed.preset;\n }\n\n if (parsed['remove-features'] !== undefined) {\n if (\n !Array.isArray(parsed['remove-features']) ||\n !parsed['remove-features'].every((f) => typeof f === 'string')\n ) {\n throw new ConfigError(\n `Invalid type for 'remove-features': expected array of strings`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n config['remove-features'] = parsed['remove-features'];\n }\n\n if (parsed.force !== undefined) {\n if (typeof parsed.force !== 'boolean') {\n throw new ConfigError(\n `Invalid type for 'force': expected boolean, got ${typeof parsed.force}`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n config.force = parsed.force;\n }\n\n if (parsed['dry-run'] !== undefined) {\n if (typeof parsed['dry-run'] !== 'boolean') {\n throw new ConfigError(\n `Invalid type for 'dry-run': expected boolean, got ${typeof parsed['dry-run']}`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n config['dry-run'] = parsed['dry-run'];\n }\n\n if (parsed.delete !== undefined) {\n if (typeof parsed.delete !== 'boolean') {\n throw new ConfigError(\n `Invalid type for 'delete': expected boolean, got ${typeof parsed.delete}`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n config.delete = parsed.delete;\n }\n\n if (parsed.refresh !== undefined) {\n if (typeof parsed.refresh !== 'boolean') {\n throw new ConfigError(\n `Invalid type for 'refresh': expected boolean, got ${typeof parsed.refresh}`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n config.refresh = parsed.refresh;\n }\n\n if (parsed.presets !== undefined) {\n if (\n parsed.presets === null ||\n typeof parsed.presets !== 'object' ||\n Array.isArray(parsed.presets)\n ) {\n throw new ConfigError(\n `Invalid type for 'presets': expected table of string arrays`,\n 'INVALID_PRESET',\n pathToLoad\n );\n }\n\n const defs: PresetDefinitions = {};\n for (const [presetName, value] of Object.entries(\n parsed.presets as Record<string, unknown>\n )) {\n if (!Array.isArray(value) || !value.every((v) => typeof v === 'string')) {\n throw new ConfigError(\n `Invalid preset '${presetName}': expected array of strings`,\n 'INVALID_PRESET',\n pathToLoad\n );\n }\n defs[presetName] = value as string[];\n }\n\n config.presets = defs;\n }\n\n if (parsed['list-unknown'] !== undefined) {\n if (typeof parsed['list-unknown'] !== 'boolean') {\n throw new ConfigError(\n `Invalid type for 'list-unknown': expected boolean, got ${typeof parsed['list-unknown']}`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n config['list-unknown'] = parsed['list-unknown'];\n }\n\n // @awa-impl: CHK-16_AC-1\n // Pass through [check] table as-is for check command to process\n if (parsed.check !== undefined) {\n if (\n parsed.check === null ||\n typeof parsed.check !== 'object' ||\n Array.isArray(parsed.check)\n ) {\n throw new ConfigError(\n `Invalid type for 'check': expected table`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n config.check = parsed.check as Record<string, unknown>;\n }\n\n // @awa-impl: OVL-8_AC-1\n if (parsed.overlay !== undefined) {\n if (!Array.isArray(parsed.overlay) || !parsed.overlay.every((o) => typeof o === 'string')) {\n throw new ConfigError(\n `Invalid type for 'overlay': expected array of strings`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n config.overlay = parsed.overlay;\n }\n\n if (parsed['update-check'] !== undefined) {\n if (\n parsed['update-check'] === null ||\n typeof parsed['update-check'] !== 'object' ||\n Array.isArray(parsed['update-check'])\n ) {\n throw new ConfigError(\n `Invalid type for 'update-check': expected table`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n\n const raw = parsed['update-check'] as Record<string, unknown>;\n const updateCheckConfig: UpdateCheckConfig = {};\n\n if (raw.enabled !== undefined) {\n if (typeof raw.enabled !== 'boolean') {\n throw new ConfigError(\n `Invalid type for 'update-check.enabled': expected boolean, got ${typeof raw.enabled}`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n updateCheckConfig.enabled = raw.enabled;\n }\n\n if (raw.interval !== undefined) {\n if (typeof raw.interval !== 'number') {\n throw new ConfigError(\n `Invalid type for 'update-check.interval': expected number, got ${typeof raw.interval}`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n updateCheckConfig.interval = raw.interval;\n }\n\n config['update-check'] = updateCheckConfig;\n }\n\n // Parse [targets.*] sections\n if (parsed.targets !== undefined) {\n if (\n parsed.targets === null ||\n typeof parsed.targets !== 'object' ||\n Array.isArray(parsed.targets)\n ) {\n throw new ConfigError(\n `Invalid type for 'targets': expected table of target sections`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n\n const targets: Record<string, TargetConfig> = {};\n for (const [targetName, targetValue] of Object.entries(\n parsed.targets as Record<string, unknown>\n )) {\n if (\n targetValue === null ||\n typeof targetValue !== 'object' ||\n Array.isArray(targetValue)\n ) {\n throw new ConfigError(\n `Invalid target '${targetName}': expected table`,\n 'INVALID_TYPE',\n pathToLoad\n );\n }\n targets[targetName] = this.parseTargetSection(\n targetValue as Record<string, unknown>,\n targetName,\n pathToLoad\n );\n }\n config.targets = targets;\n }\n\n // Warn about unknown options\n const knownKeys = new Set([\n 'output',\n 'template',\n 'features',\n 'preset',\n 'remove-features',\n 'presets',\n 'force',\n 'dry-run',\n 'delete',\n 'refresh',\n 'list-unknown',\n 'check',\n 'targets',\n 'overlay',\n 'update-check',\n ]);\n for (const key of Object.keys(parsed)) {\n if (!knownKeys.has(key)) {\n logger.warn(`Unknown configuration option: '${key}'`);\n }\n }\n\n return config;\n } catch (error) {\n if (error instanceof ConfigError) {\n throw error;\n }\n\n // TOML parsing error\n throw new ConfigError(\n `Failed to parse TOML configuration: ${error instanceof Error ? error.message : String(error)}`,\n 'PARSE_ERROR',\n pathToLoad\n );\n }\n }\n\n // @awa-impl: CFG-4_AC-1, CFG-4_AC-2, CFG-4_AC-3, CFG-4_AC-4\n // @awa-impl: CLI-2_AC-2, CLI-2_AC-3, CLI-2_AC-4\n merge(cli: RawCliOptions, file: FileConfig | null): ResolvedOptions {\n // CLI arguments override file config values\n // Output can come from CLI (positional argument) or config file\n\n // @awa-impl: CLI-2_AC-2, CLI-2_AC-3\n const output = cli.output ?? file?.output;\n\n // @awa-impl: CLI-1_AC-4, CLI-2_AC-4\n if (!output) {\n throw new ConfigError(\n 'Output directory is required. Provide it as a positional argument or in the config file.',\n 'MISSING_OUTPUT',\n null\n );\n }\n\n const template = cli.template ?? file?.template ?? null;\n\n // Features: CLI completely replaces config (no merge)\n const features = cli.features ?? file?.features ?? [];\n\n const preset = cli.preset ?? file?.preset ?? [];\n const removeFeatures = cli.removeFeatures ?? file?.['remove-features'] ?? [];\n const presets = file?.presets ?? {};\n\n const force = cli.force ?? file?.force ?? false;\n const dryRun = cli.dryRun ?? file?.['dry-run'] ?? false;\n const enableDelete = cli.delete ?? file?.delete ?? false;\n const refresh = cli.refresh ?? file?.refresh ?? false;\n const listUnknown = cli.listUnknown ?? file?.['list-unknown'] ?? false;\n const overlay = cli.overlay ?? file?.overlay ?? [];\n const json = cli.json ?? false;\n const summary = cli.summary ?? false;\n\n return {\n output,\n template,\n features,\n preset,\n removeFeatures,\n force,\n dryRun,\n delete: enableDelete,\n refresh,\n presets,\n listUnknown,\n overlay,\n json,\n summary,\n };\n }\n\n // Parse a [targets.<name>] section, validating allowed keys and types\n private parseTargetSection(\n section: Record<string, unknown>,\n targetName: string,\n configPath: string\n ): TargetConfig {\n const target: TargetConfig = {};\n const allowedKeys = new Set(['output', 'template', 'features', 'preset', 'remove-features']);\n\n for (const key of Object.keys(section)) {\n if (!allowedKeys.has(key)) {\n logger.warn(`Unknown option in target '${targetName}': '${key}'`);\n }\n }\n\n if (section.output !== undefined) {\n if (typeof section.output !== 'string') {\n throw new ConfigError(\n `Invalid type for 'targets.${targetName}.output': expected string, got ${typeof section.output}`,\n 'INVALID_TYPE',\n configPath\n );\n }\n target.output = section.output;\n }\n\n if (section.template !== undefined) {\n if (typeof section.template !== 'string') {\n throw new ConfigError(\n `Invalid type for 'targets.${targetName}.template': expected string, got ${typeof section.template}`,\n 'INVALID_TYPE',\n configPath\n );\n }\n target.template = section.template;\n }\n\n if (section.features !== undefined) {\n if (\n !Array.isArray(section.features) ||\n !section.features.every((f) => typeof f === 'string')\n ) {\n throw new ConfigError(\n `Invalid type for 'targets.${targetName}.features': expected array of strings`,\n 'INVALID_TYPE',\n configPath\n );\n }\n target.features = section.features;\n }\n\n if (section.preset !== undefined) {\n if (!Array.isArray(section.preset) || !section.preset.every((p) => typeof p === 'string')) {\n throw new ConfigError(\n `Invalid type for 'targets.${targetName}.preset': expected array of strings`,\n 'INVALID_TYPE',\n configPath\n );\n }\n target.preset = section.preset;\n }\n\n if (section['remove-features'] !== undefined) {\n if (\n !Array.isArray(section['remove-features']) ||\n !section['remove-features'].every((f) => typeof f === 'string')\n ) {\n throw new ConfigError(\n `Invalid type for 'targets.${targetName}.remove-features': expected array of strings`,\n 'INVALID_TYPE',\n configPath\n );\n }\n target['remove-features'] = section['remove-features'];\n }\n\n return target;\n }\n\n // Resolve a target by merging target config with root config (target overrides root via nullish coalescing)\n resolveTarget(targetName: string, fileConfig: FileConfig): FileConfig {\n const targets = fileConfig.targets;\n if (!targets || Object.keys(targets).length === 0) {\n throw new ConfigError(\n 'No targets defined in configuration. Add [targets.<name>] sections to .awa.toml.',\n 'NO_TARGETS',\n null\n );\n }\n\n const target = targets[targetName];\n if (!target) {\n throw new ConfigError(\n `Unknown target: '${targetName}'. Available targets: ${Object.keys(targets).join(', ')}`,\n 'UNKNOWN_TARGET',\n null\n );\n }\n\n // Merge: target fields override root (nullish coalescing — target value ?? root value)\n return {\n ...fileConfig,\n output: target.output ?? fileConfig.output,\n template: target.template ?? fileConfig.template,\n features: target.features ?? fileConfig.features,\n preset: target.preset ?? fileConfig.preset,\n 'remove-features': target['remove-features'] ?? fileConfig['remove-features'],\n targets: undefined, // Don't propagate targets into resolved config\n };\n }\n\n // Get all target names from config\n getTargetNames(fileConfig: FileConfig | null): string[] {\n if (!fileConfig?.targets) {\n return [];\n }\n return Object.keys(fileConfig.targets);\n }\n}\n\nexport const configLoader = new ConfigLoader();\n","// @awa-component: GEN-CoreTypes\n\n// Custom error classes for diff operations\nexport class DiffError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DiffError';\n }\n}\n\n// RawCliOptions - CLI argument parser output\nexport interface RawCliOptions {\n output?: string; // Optional positional argument (required if not in config)\n template?: string;\n features?: string[];\n preset?: string[];\n removeFeatures?: string[];\n force?: boolean;\n dryRun?: boolean;\n delete?: boolean;\n config?: string;\n refresh?: boolean;\n listUnknown?: boolean;\n all?: boolean;\n target?: string;\n watch?: boolean;\n overlay?: string[];\n json?: boolean;\n summary?: boolean;\n}\n\n// PresetDefinitions - Named feature bundles\nexport interface PresetDefinitions {\n [presetName: string]: string[];\n}\n\n// TargetConfig - Per-target configuration (generation-related fields only, no boolean flags)\nexport interface TargetConfig {\n output?: string;\n template?: string;\n features?: string[];\n preset?: string[];\n 'remove-features'?: string[];\n}\n\n// UpdateCheckConfig - Update check configuration\nexport interface UpdateCheckConfig {\n enabled?: boolean;\n interval?: number;\n}\n\n// FileConfig - TOML configuration file structure\nexport interface FileConfig {\n output?: string;\n template?: string;\n features?: string[];\n preset?: string[];\n 'remove-features'?: string[];\n force?: boolean;\n 'dry-run'?: boolean;\n delete?: boolean;\n refresh?: boolean;\n presets?: PresetDefinitions;\n 'list-unknown'?: boolean;\n check?: Record<string, unknown>;\n targets?: Record<string, TargetConfig>;\n overlay?: string[];\n 'update-check'?: UpdateCheckConfig;\n}\n\n// ResolvedOptions - Fully resolved configuration with defaults applied\nexport interface ResolvedOptions {\n readonly output: string;\n readonly template: string | null;\n readonly features: readonly string[];\n readonly preset: readonly string[];\n readonly removeFeatures: readonly string[];\n readonly force: boolean;\n readonly dryRun: boolean;\n readonly delete: boolean;\n readonly refresh: boolean;\n readonly presets: PresetDefinitions;\n readonly listUnknown: boolean;\n readonly overlay: readonly string[];\n readonly json: boolean;\n readonly summary: boolean;\n}\n\n// TemplateSourceType - Template source type detection\nexport type TemplateSourceType = 'local' | 'git' | 'bundled';\n\n// ResolvedTemplate - Template source resolution result\nexport interface ResolvedTemplate {\n type: TemplateSourceType;\n localPath: string;\n source: string;\n}\n\n// TemplateContext - Context passed to template engine\nexport interface TemplateContext {\n features: string[];\n version?: string;\n}\n\n// RenderResult - Template rendering output\nexport interface RenderResult {\n content: string;\n isEmpty: boolean;\n isEmptyFileMarker: boolean;\n}\n\n// FileAction - Tagged union for file operations\nexport type FileAction =\n | { type: 'create'; sourcePath: string; outputPath: string }\n | { type: 'overwrite'; sourcePath: string; outputPath: string }\n | { type: 'skip-user'; sourcePath: string; outputPath: string }\n | { type: 'skip-empty'; sourcePath: string; outputPath: string }\n | { type: 'skip-equal'; sourcePath: string; outputPath: string }\n | { type: 'delete'; outputPath: string };\n\n// GenerationResult - Aggregated generation outcome\nexport interface GenerationResult {\n readonly actions: readonly FileAction[];\n readonly created: number;\n readonly overwritten: number;\n readonly deleted: number;\n readonly skipped: number;\n readonly skippedEmpty: number;\n readonly skippedUser: number;\n readonly skippedEqual: number;\n}\n\n// GenerateOptions - File generation parameters\nexport interface GenerateOptions {\n templatePath: string;\n outputPath: string;\n features: string[];\n force: boolean;\n dryRun: boolean;\n delete: boolean;\n}\n\n// ConflictChoice - User choice for conflict resolution\nexport type ConflictChoice = 'overwrite' | 'skip';\n\n// ConflictItem - Individual file conflict for batch resolution\nexport interface ConflictItem {\n outputPath: string;\n sourcePath: string;\n newContent: string;\n existingContent: string;\n}\n\n// BatchConflictResolution - Result of batch conflict resolution\nexport interface BatchConflictResolution {\n overwrite: string[]; // List of output paths to overwrite\n skip: string[]; // List of output paths to skip\n equal: string[]; // List of output paths skipped because content is identical\n}\n\n// TemplateFile - Template file metadata\nexport interface TemplateFile {\n path: string;\n absolutePath: string;\n isPartial: boolean;\n}\n\n// DiffOptions - Diff operation parameters\nexport interface DiffOptions {\n templatePath: string;\n targetPath: string;\n features: string[];\n listUnknown: boolean;\n}\n\n// FileDiffStatus - File comparison status\nexport type FileDiffStatus =\n | 'identical'\n | 'modified'\n | 'new'\n | 'extra'\n | 'binary-differs'\n | 'delete-listed';\n\n// FileDiff - Comparison result for a single file\nexport interface FileDiff {\n relativePath: string;\n status: FileDiffStatus;\n unifiedDiff?: string; // Present only for 'modified' text files\n}\n\n// DiffResult - Aggregated diff outcome\nexport interface DiffResult {\n files: FileDiff[];\n identical: number;\n modified: number;\n newFiles: number;\n extraFiles: number;\n binaryDiffers: number;\n deleteListed: number;\n hasDifferences: boolean;\n}\n\n// CachedTemplate - Cached Git template metadata\nexport interface CachedTemplate {\n source: string;\n localPath: string;\n fetchedAt: Date;\n ref?: string;\n}\n\n// JSON output types for --json flag\n// @awa-impl: JSON-3_AC-1\nexport interface GenerationActionJSON {\n type: string;\n path: string;\n}\n\nexport interface GenerationJSON {\n actions: GenerationActionJSON[];\n counts: {\n created: number;\n overwritten: number;\n skipped: number;\n deleted: number;\n };\n}\n\n// @awa-impl: JSON-4_AC-1\nexport interface DiffFileJSON {\n path: string;\n status: string;\n diff?: string;\n}\n\nexport interface DiffJSON {\n diffs: DiffFileJSON[];\n counts: {\n changed: number;\n new: number;\n matching: number;\n deleted: number;\n };\n}\n\n// Custom error types\nexport class ConfigError extends Error {\n constructor(\n message: string,\n public code:\n | 'FILE_NOT_FOUND'\n | 'PARSE_ERROR'\n | 'INVALID_TYPE'\n | 'MISSING_OUTPUT'\n | 'INVALID_PRESET'\n | 'UNKNOWN_PRESET'\n | 'UNKNOWN_TARGET'\n | 'NO_TARGETS',\n public filePath?: string | null\n ) {\n super(message);\n this.name = 'ConfigError';\n }\n}\n\nexport class TemplateError extends Error {\n constructor(\n message: string,\n public code: 'SOURCE_NOT_FOUND' | 'FETCH_FAILED' | 'RENDER_ERROR',\n public source?: string\n ) {\n super(message);\n this.name = 'TemplateError';\n }\n}\n\nexport class GenerationError extends Error {\n constructor(\n message: string,\n public code: 'PERMISSION_DENIED' | 'DISK_FULL'\n ) {\n super(message);\n this.name = 'GenerationError';\n }\n}\n","// @awa-component: GEN-FileSystem\n\nimport { mkdir, readdir, readFile, rm, stat, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport async function ensureDir(dirPath: string): Promise<void> {\n await mkdir(dirPath, { recursive: true });\n}\n\nexport async function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function isDirectory(path: string): Promise<boolean> {\n try {\n const stats = await stat(path);\n return stats.isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function readTextFile(path: string): Promise<string> {\n return readFile(path, 'utf-8');\n}\n\nexport async function readBinaryFile(path: string): Promise<Buffer> {\n return readFile(path);\n}\n\nexport async function writeTextFile(path: string, content: string): Promise<void> {\n await ensureDir(dirname(path));\n await writeFile(path, content, 'utf-8');\n}\n\nexport async function* walkDirectory(dir: string): AsyncGenerator<string> {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // Skip directories starting with underscore\n if (entry.name.startsWith('_')) {\n continue;\n }\n yield* walkDirectory(fullPath);\n } else if (entry.isFile()) {\n // Skip files starting with underscore\n if (entry.name.startsWith('_')) {\n continue;\n }\n yield fullPath;\n }\n }\n}\n\nexport function getCacheDir(): string {\n return join(homedir(), '.cache', 'awa', 'templates');\n}\n\nexport function getTemplateDir(): string {\n // In built dist, we need to go up from dist/index.js to project root\n // In development, we're in src/utils/fs.ts\n const currentFile = fileURLToPath(import.meta.url);\n const currentDir = dirname(currentFile);\n\n // Check if we're in dist/ or src/\n if (currentDir.includes('/dist')) {\n // In dist: go up one level to project root\n return join(dirname(currentDir), 'templates');\n }\n\n // In src: go up two levels to project root\n return join(currentDir, '..', '..', 'templates');\n}\n\nexport async function rmDir(dirPath: string): Promise<void> {\n await rm(dirPath, { recursive: true, force: true });\n}\n\nexport async function deleteFile(filePath: string): Promise<void> {\n await rm(filePath, { force: true });\n}\n","// @awa-component: GEN-Logger\n// @awa-impl: CLI-6_AC-3\n// @awa-impl: GEN-6_AC-4\n// @awa-impl: GEN-7_AC-1\n// @awa-impl: GEN-7_AC-2\n// @awa-impl: GEN-7_AC-3\n// @awa-impl: GEN-7_AC-4\n// @awa-impl: GEN-9_AC-1\n// @awa-impl: GEN-9_AC-2\n// @awa-impl: GEN-9_AC-3\n// @awa-impl: GEN-9_AC-4\n// @awa-impl: GEN-9_AC-5\n// @awa-impl: GEN-9_AC-6\n// @awa-impl: GEN-9_AC-7\n// @awa-impl: GEN-9_AC-8\n// @awa-impl: GEN-11_AC-1\n// @awa-impl: GEN-11_AC-2\n// @awa-impl: GEN-11_AC-4\n// @awa-impl: TPL-7_AC-3\n\nimport chalk from 'chalk';\nimport type { DiffResult, FileAction, GenerationResult } from '../types/index.js';\n\nexport class Logger {\n info(message: string): void {\n console.log(chalk.blue('ℹ'), message);\n }\n\n success(message: string): void {\n console.log(chalk.green('✔'), message);\n }\n\n warn(message: string): void {\n console.warn(chalk.yellow('⚠'), message);\n }\n\n error(message: string): void {\n console.error(chalk.red('✖'), message);\n }\n\n fileAction(action: FileAction): void {\n const { type, outputPath } = action;\n\n switch (type) {\n case 'create':\n console.log(chalk.green(' + '), chalk.dim(outputPath));\n break;\n case 'overwrite':\n console.log(chalk.yellow(' ~ '), chalk.dim(outputPath));\n break;\n case 'skip-user':\n console.log(chalk.blue(' - '), chalk.dim(outputPath), chalk.dim('(skipped)'));\n break;\n case 'skip-empty':\n console.log(chalk.dim(' · '), chalk.dim(outputPath), chalk.dim('(empty)'));\n break;\n case 'skip-equal':\n console.log(chalk.dim(' = '), chalk.dim(outputPath), chalk.dim('(unchanged)'));\n break;\n case 'delete':\n console.log(chalk.red(' ✖ '), chalk.dim(outputPath), chalk.red('(deleted)'));\n break;\n }\n }\n\n // @awa-impl: GEN-9_AC-1, GEN-9_AC-2, GEN-9_AC-3, GEN-9_AC-4, GEN-9_AC-5, GEN-9_AC-6\n summary(result: GenerationResult): void {\n console.log('');\n console.log(chalk.bold('Summary:'));\n\n // @awa-impl: GEN-9_AC-6\n // Check if no files were created, overwritten, or deleted\n if (result.created === 0 && result.overwritten === 0 && result.deleted === 0) {\n console.log(chalk.yellow(' ⚠ No files were created, overwritten, or deleted'));\n }\n\n if (result.created > 0) {\n console.log(chalk.green(` Created: ${result.created}`));\n }\n\n if (result.overwritten > 0) {\n console.log(chalk.yellow(` Overwritten: ${result.overwritten}`));\n }\n\n if (result.deleted > 0) {\n console.log(chalk.red(` Deleted: ${result.deleted}`));\n }\n\n if (result.skippedEqual > 0) {\n console.log(chalk.dim(` Skipped (equal): ${result.skippedEqual}`));\n }\n\n if (result.skippedUser > 0) {\n console.log(chalk.blue(` Skipped (user): ${result.skippedUser}`));\n }\n\n if (result.skippedEmpty > 0) {\n console.log(chalk.dim(` Skipped (empty): ${result.skippedEmpty}`));\n }\n\n console.log('');\n }\n\n // @awa-impl: DIFF-4_AC-3\n diffLine(line: string, type: 'add' | 'remove' | 'context'): void {\n switch (type) {\n case 'add':\n console.log(chalk.green(line));\n break;\n case 'remove':\n console.log(chalk.red(line));\n break;\n case 'context':\n console.log(chalk.dim(line));\n break;\n }\n }\n\n // @awa-impl: DIFF-4_AC-4, DIFF-4_AC-5\n diffSummary(result: DiffResult): void {\n console.log('');\n\n const filesCompared =\n result.identical +\n result.modified +\n result.newFiles +\n result.extraFiles +\n result.binaryDiffers +\n result.deleteListed;\n const differences =\n result.modified +\n result.newFiles +\n result.extraFiles +\n result.binaryDiffers +\n result.deleteListed;\n\n // @awa-impl: DIFF-4_AC-5\n console.log(chalk.bold(`${filesCompared} files compared, ${differences} differences`));\n\n if (!result.hasDifferences) {\n // @awa-impl: DIFF-4_AC-4\n console.log(chalk.green('✔ No differences found'));\n }\n\n // @awa-impl: DIFF-4_AC-5\n console.log(chalk.bold('Summary:'));\n console.log(chalk.dim(` Identical: ${result.identical}`));\n\n if (result.modified > 0) {\n console.log(chalk.yellow(` Modified: ${result.modified}`));\n }\n\n if (result.newFiles > 0) {\n console.log(chalk.green(` New: ${result.newFiles}`));\n }\n\n if (result.extraFiles > 0) {\n console.log(chalk.red(` Extra: ${result.extraFiles}`));\n }\n\n if (result.binaryDiffers > 0) {\n console.log(chalk.red(` Binary differs: ${result.binaryDiffers}`));\n }\n\n if (result.deleteListed > 0) {\n console.log(chalk.red(` Delete listed: ${result.deleteListed}`));\n }\n\n console.log('');\n }\n}\n\nexport const logger = new Logger();\n"],"mappings":"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","names":[]}
|