@aiready/cli 0.9.36 → 0.9.39

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.
@@ -1,6 +1,6 @@
1
1
 
2
2
  
3
- > @aiready/cli@0.9.36 build /Users/pengcao/projects/aiready/packages/cli
3
+ > @aiready/cli@0.9.39 build /Users/pengcao/projects/aiready/packages/cli
4
4
  > tsup src/index.ts src/cli.ts --format cjs,esm
5
5
 
6
6
  CLI Building entry: src/cli.ts, src/index.ts
@@ -10,27 +10,20 @@
10
10
  CJS Build start
11
11
  ESM Build start
12
12
 
13
- [9:41:44 PM]  WARN  ▲ [WARNING] "import.meta" is not available with the "cjs" output format and will be empty [empty-import-meta]
13
+ [1:04:00 PM]  WARN  ▲ [WARNING] "import.meta" is not available with the "cjs" output format and will be empty [empty-import-meta]
14
14
 
15
- src/cli.ts:22:31:
16
-  22 │ return dirname(fileURLToPath(import.meta.url));
15
+ src/cli.ts:23:31:
16
+  23 │ return dirname(fileURLToPath(import.meta.url));
17
17
  ╵ ~~~~~~~~~~~
18
18
 
19
19
  You need to set the output format to "esm" for "import.meta" to work correctly.
20
20
 
21
21
 
22
22
 
23
- CJS dist/cli.js 77.14 KB
24
- CJS dist/index.js 6.63 KB
25
- CJS ⚡️ Build success in 28ms
26
- ESM dist/hallucination-risk-XU6E7IGN.mjs 135.00 B
27
- ESM dist/cli.mjs 62.85 KB
28
- ESM dist/index.mjs 169.00 B
29
- ESM dist/agent-grounding-DAOSU4MF.mjs 129.00 B
30
- ESM dist/chunk-XAF2EW5H.mjs 1.75 KB
31
- ESM dist/chunk-RBWLQRKR.mjs 1.39 KB
32
- ESM dist/chunk-Y6FXYEAI.mjs 390.00 B
33
- ESM dist/chunk-YIS6WTY5.mjs 1.41 KB
34
- ESM dist/testability-VDZJZ4MF.mjs 123.00 B
35
- ESM dist/chunk-N4SLON5K.mjs 4.91 KB
36
- ESM ⚡️ Build success in 28ms
23
+ ESM dist/index.mjs 138.00 B
24
+ ESM dist/cli.mjs 63.68 KB
25
+ ESM dist/chunk-PDOONNSK.mjs 7.80 KB
26
+ ESM ⚡️ Build success in 34ms
27
+ CJS dist/cli.js 73.85 KB
28
+ CJS dist/index.js 9.15 KB
29
+ CJS ⚡️ Build success in 35ms
@@ -1,17 +1,17 @@
1
1
 
2
2
  
3
- > @aiready/cli@0.9.36 test /Users/pengcao/projects/aiready/packages/cli
3
+ > @aiready/cli@0.9.39 test /Users/pengcao/projects/aiready/packages/cli
4
4
  > vitest run
5
5
 
6
6
  [?25l
7
7
   RUN  v4.0.18 /Users/pengcao/projects/aiready/packages/cli
8
8
 
9
- ✓ src/__tests__/cli.test.ts (3 tests) 3ms
10
- ✓ dist/__tests__/cli.test.js (3 tests) 3ms
9
+ ✓ dist/__tests__/cli.test.js (3 tests) 4ms
10
+ ✓ src/__tests__/cli.test.ts (3 tests) 6ms
11
11
 
12
12
   Test Files  2 passed (2)
13
13
   Tests  6 passed (6)
14
-  Start at  21:42:04
15
-  Duration  1.60s (transform 926ms, setup 0ms, import 2.72s, tests 5ms, environment 0ms)
14
+  Start at  13:04:30
15
+  Duration  2.67s (transform 1.17s, setup 0ms, import 4.60s, tests 10ms, environment 0ms)
16
16
 
17
17
  [?25h
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # @aiready/cli
2
2
 
3
- > **Unified CLI for AIReady analysis tools - Run all AI-readiness checks from a single command**
4
-
5
- The CLI provides both unified analysis (scan multiple tools at once) and individual tool access for pattern detection, context analysis, and consistency checking.
3
+ > Unified command-line interface for the AIReady framework.
6
4
 
7
5
  ## 🏛️ Architecture
8
6
 
@@ -10,296 +8,38 @@ The CLI provides both unified analysis (scan multiple tools at once) and individ
10
8
  🎯 USER
11
9
 
12
10
 
13
- ┌──────────────────────────────────────────┐
14
- 🎛️ CLI (@aiready/cli)
15
- │ Unified Interface & Orchestration │
16
- │ YOU ARE HERE │
17
- └─────────────────┬────────────────────────┘
18
-
19
- ┌─────────────┴─────────────┐
20
- │ │
21
- ▼ ▼
22
- ┌────────┐ ┌────────┐
23
- │🎨 VIS- │ │ ANALY- │
24
- │UALIZER │ │ SIS │
25
- │ │ │ SPOKES
26
- │✅ Ready│ │ │
27
- └────────┘ └───┬────┘
28
- │ │
29
- │ ┌───────────────┼───────────────┐
30
- │ ▼ ▼ ▼
31
- │ ┌────────┐ ┌────────┐ ┌────────┐
32
- │ │📊 PAT- │ │📦 CON- │ │🔧 CON- │
33
- │ │TERN │ │TEXT │ │SISTENCY│
34
- │ │DETECT │ │ANALYZER│ │ │
35
- │ │✅ Ready│ │✅ Ready│ │✅ Ready│
36
- │ └────────┘ └────────┘ └────────┘
37
- │ │ │ │
38
- └─────────┴───────────────┴───────────────┘
39
-
40
-
41
- 🏢 HUB (@aiready/core)
42
- ```
43
-
44
- ## 🌍 Language Support
45
-
46
- **Currently Supported (64% market coverage):**
47
-
48
- - ✅ **TypeScript** (`.ts`, `.tsx`)
49
- - ✅ **JavaScript** (`.js`, `.jsx`)
50
- - ✅ **Python** (`.py`) - PEP 8 conventions, import analysis, pattern detection
51
-
52
- **Roadmap:**
53
-
54
- - 🔜 **Java** (Q3 2026) - Maven/Gradle, Spring Framework
55
- - 🔜 **Go** (Q4 2026) - Go modules, concurrency patterns
56
- - 🔜 **Rust** (Q4 2026) - Cargo, ownership patterns
57
- - 🔜 **C#** (Q1 2027) - .NET, LINQ patterns
58
-
59
- Mixed-language projects are fully supported - the tool automatically detects and analyzes each file type appropriately.
60
-
61
- ## 🚀 Quick Start
62
-
63
- **Zero config, works out of the box:**
64
-
65
- ```bash
66
- # Run without installation (recommended)
67
- npx @aiready/cli scan ./src
68
-
69
- # Or install globally for simpler command and faster runs
70
- npm install -g @aiready/cli
71
- aiready scan ./src
72
- ```
73
-
74
- ### 🎯 Input & Output
75
-
76
- **Input:** Path to your source code directory
77
-
78
- ```bash
79
- aiready scan ./src
80
- ```
81
-
82
- **Output:** Terminal report + optional JSON file (saved to `.aiready/` directory)
83
-
84
- ```
85
- 📊 AIReady Scan Results
86
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━
87
- 🔍 Pattern Detection
88
- 📁 Files analyzed: 47
89
- ⚠️ Duplicate patterns: 12 files with 23 issues
90
- 💰 Wasted tokens: 8,450
91
-
92
- 📦 Context Analysis
93
- 📁 Files analyzed: 47
94
- ⚠️ High context cost: 8 files
95
- 🔗 Deep import chains: 5 files
96
- ```
97
-
98
- ### ✨ Smart Defaults (Zero Config)
99
-
100
- - ✅ **Auto-excludes** test files (`**/*.test.*`, `**/*.spec.*`, `**/__tests__/**`)
101
- - ✅ **Auto-excludes** build outputs (`dist/`, `build/`, `.next/`, `cdk.out/`)
102
- - ✅ **Auto-excludes** dependencies (`node_modules/`)
103
- - ✅ **Adaptive thresholds**: Adjusts issue detection based on codebase size
104
- - ✅ **Unified reporting**: Combines results from all tools into one view
105
-
106
- > Override defaults with `--include` or `--exclude` options as needed
107
-
108
- ## 📦 Commands
109
-
110
- ### Unified Scan
111
-
112
- Run multiple analysis tools in one command:
113
-
114
- ```bash
115
- aiready scan <directory>
116
- ```
117
-
118
- **Options:**
119
-
120
- - `-t, --tools <tools>`: Tools to run (comma-separated: patterns,context,consistency) (default: patterns,context)
121
- - `--include <patterns>`: File patterns to include (comma-separated)
122
- - `--exclude <patterns>`: File patterns to exclude (comma-separated)
123
- - `-o, --output <format>`: Output format: console, json (default: console)
124
- - `--output-file <path>`: Output file path (defaults to `.aiready/aiready-scan-YYYY-MM-DD.json`)
125
-
126
- ### Individual Tools
127
-
128
- Access each tool directly for focused analysis:
129
-
130
- #### Pattern Detection
131
-
132
- ```bash
133
- aiready patterns <directory> [options]
134
- ```
135
-
136
- **Options:**
137
-
138
- - `-s, --similarity <number>`: Minimum similarity score (0-1) (default: 0.40)
139
- - `-l, --min-lines <number>`: Minimum lines to consider (default: 5)
140
- - `--include <patterns>`: File patterns to include (comma-separated)
141
- - `--exclude <patterns>`: File patterns to exclude (comma-separated)
142
- - `-o, --output <format>`: Output format: console, json (default: console)
143
- - `--output-file <path>`: Output file path (defaults to `.aiready/pattern-report-YYYY-MM-DD.json`)
144
-
145
- #### Context Analysis
146
-
147
- ```bash
148
- aiready context <directory> [options]
149
- ```
11
+ 🎛️ @aiready/cli (orchestrator) ← YOU ARE HERE
12
+ │ │ │ │ │ │ │
13
+ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
14
+ [PAT] [CTX] [CON] [AMP] [DEP] [DOC] [SIG] [AGT] [TST]
15
+ │ │ │ │ │ │ │ │ │
16
+ └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
17
+
18
+
19
+ 🏢 @aiready/core
20
+
21
+ Legend:
22
+ PAT = pattern-detect CTX = context-analyzer
23
+ CON = consistency AMP = change-amplification
24
+ DEP = deps-health DOC = doc-drift
25
+ SIG = ai-signal-clarity AGT = agent-grounding
26
+ TST = testability
27
+ ```
28
+
29
+ ## Overview
150
30
 
151
- **Options:**
152
-
153
- - `--max-depth <number>`: Maximum acceptable import depth (default: 5)
154
- - `--max-context <number>`: Maximum acceptable context budget (tokens) (default: 10000)
155
- - `--include <patterns>`: File patterns to include (comma-separated)
156
- - `--exclude <patterns>`: File patterns to exclude (comma-separated)
157
- - `-o, --output <format>`: Output format: console, json (default: console)
158
- - `--output-file <path>`: Output file path (defaults to `.aiready/context-report-YYYY-MM-DD.json`)
159
-
160
- #### Consistency Analysis
161
-
162
- ```bash
163
- aiready consistency <directory> [options]
164
- ```
165
-
166
- **Options:**
167
-
168
- - `--include <patterns>`: File patterns to include (comma-separated)
169
- - `--exclude <patterns>`: File patterns to exclude (comma-separated)
170
- - `-o, --output <format>`: Output format: console, json (default: console)
171
- - `--output-file <path>`: Output file path (defaults to `.aiready/consistency-report-YYYY-MM-DD.json`)
172
-
173
- > **📁 Output Files:** By default, all output files are saved to the `.aiready/` directory in your project root with timestamped filenames. You can override this with `--output-file`.
174
-
175
- ## 💡 Examples
31
+ The CLI provides both unified analysis (scan multiple tools at once) and individual tool access for pattern detection, context analysis, and consistency checking.
176
32
 
177
- ### Basic Usage
33
+ ## Usage
178
34
 
179
35
  ```bash
180
- # Analyze current directory with all tools
36
+ # Scan a codebase
181
37
  aiready scan .
182
38
 
183
- # Run specific tools only
184
- aiready scan . --tools patterns,context
185
-
186
- # Analyze only patterns
187
- aiready patterns .
188
-
189
- # Analyze only context costs
190
- aiready context .
191
-
192
- # Analyze only consistency
193
- aiready consistency .
194
- ```
195
-
196
- ### Advanced Usage
197
-
198
- ```bash
199
- # Analyze specific file types
200
- aiready scan ./src --include "**/*.ts,**/*.js"
201
-
202
- # Exclude test files
203
- aiready scan . --exclude "**/*.test.*,**/*.spec.*"
204
-
205
- # Save results to JSON file (.aiready/ directory by default)
206
- aiready scan . --output json
207
-
208
- # Save to custom location
209
- aiready scan . --output json --output-file custom-results.json
210
-
211
- # Run only pattern analysis with custom similarity threshold
212
- aiready patterns . --similarity 0.6 --min-lines 10
213
-
214
- # Run context analysis with custom thresholds
215
- aiready context . --max-depth 3 --max-context 5000
39
+ # Run a specific tool
40
+ aiready pattern-detect .
216
41
  ```
217
42
 
218
- ## ⚙️ Configuration
219
-
220
- AIReady supports configuration files to persist your settings. Create one of these files in your project root:
221
-
222
- - `aiready.json`
223
- - `aiready.config.json`
224
- - `.aiready.json`
225
- - `.aireadyrc.json`
226
- - `aiready.config.js`
227
- - `.aireadyrc.js`
228
-
229
- ### Example Configuration
230
-
231
- ```json
232
- {
233
- "scan": {
234
- "include": ["**/*.{ts,tsx,js,jsx}"],
235
- "exclude": ["**/test/**", "**/*.test.*", "**/*.spec.*"]
236
- },
237
- "tools": {
238
- "pattern-detect": {
239
- "minSimilarity": 0.5,
240
- "minLines": 8,
241
- "approx": false
242
- },
243
- "context-analyzer": {
244
- "maxDepth": 4,
245
- "maxContextBudget": 8000,
246
- "includeNodeModules": false
247
- }
248
- },
249
- "output": {
250
- "format": "console",
251
- "file": "aiready-report.json"
252
- }
253
- }
254
- ```
255
-
256
- Configuration values are merged with defaults, and CLI options take precedence over config file settings.
257
-
258
- ## 🔄 CI/CD Integration
259
-
260
- ```bash
261
- # JSON output for automated processing
262
- aiready scan . --output json --output-file aiready-results.json
263
-
264
- # Exit with error code if issues found
265
- aiready scan . && echo "No issues found" || echo "Issues detected"
266
- ```
267
-
268
- ## 📊 Output Formats
269
-
270
- ### Console Output
271
-
272
- Human-readable summary with key metrics and issue counts.
273
-
274
- ### JSON Output
275
-
276
- Structured data including:
277
-
278
- - Full analysis results
279
- - Detailed metrics
280
- - Issue breakdowns
281
- - Execution timing
282
-
283
- ## 🚦 Exit Codes
284
-
285
- - `0`: Success, no critical issues
286
- - `1`: Analysis failed or critical issues found
287
-
288
- ## 🔗 Integration
289
-
290
- The CLI is designed to integrate with:
291
-
292
- - CI/CD pipelines
293
- - Pre-commit hooks
294
- - IDE extensions
295
- - Automated workflows
296
-
297
- For programmatic usage, see the individual packages:
298
-
299
- - [@aiready/pattern-detect](https://www.npmjs.com/package/@aiready/pattern-detect)
300
- - [@aiready/context-analyzer](https://www.npmjs.com/package/@aiready/context-analyzer)
301
- - [@aiready/consistency](https://www.npmjs.com/package/@aiready/consistency)
302
-
303
- ## 🌐 Visit Our Website
43
+ ## License
304
44
 
305
- **Try AIReady tools online and learn more:** [getaiready.dev](https://getaiready.dev)
45
+ MIT
@@ -0,0 +1,211 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/index.ts
9
+ import { analyzePatterns } from "@aiready/pattern-detect";
10
+ import { analyzeContext } from "@aiready/context-analyzer";
11
+ import { analyzeConsistency } from "@aiready/consistency";
12
+ var severityOrder = {
13
+ critical: 4,
14
+ major: 3,
15
+ minor: 2,
16
+ info: 1
17
+ };
18
+ function sortBySeverity(results) {
19
+ return results.map((file) => {
20
+ const sortedIssues = [...file.issues].sort((a, b) => {
21
+ const severityDiff = (severityOrder[b.severity] || 0) - (severityOrder[a.severity] || 0);
22
+ if (severityDiff !== 0) return severityDiff;
23
+ return (a.location?.line || 0) - (b.location?.line || 0);
24
+ });
25
+ return { ...file, issues: sortedIssues };
26
+ }).sort((a, b) => {
27
+ const aMaxSeverity = Math.max(...a.issues.map((i) => severityOrder[i.severity] || 0), 0);
28
+ const bMaxSeverity = Math.max(...b.issues.map((i) => severityOrder[i.severity] || 0), 0);
29
+ if (aMaxSeverity !== bMaxSeverity) {
30
+ return bMaxSeverity - aMaxSeverity;
31
+ }
32
+ if (a.issues.length !== b.issues.length) {
33
+ return b.issues.length - a.issues.length;
34
+ }
35
+ return a.fileName.localeCompare(b.fileName);
36
+ });
37
+ }
38
+ async function analyzeUnified(options) {
39
+ const startTime = Date.now();
40
+ const tools = options.tools || ["patterns", "context", "consistency"];
41
+ const result = {
42
+ summary: {
43
+ totalIssues: 0,
44
+ toolsRun: tools,
45
+ executionTime: 0
46
+ }
47
+ };
48
+ if (tools.includes("patterns")) {
49
+ const patternResult = await analyzePatterns(options);
50
+ if (options.progressCallback) {
51
+ options.progressCallback({ tool: "patterns", data: patternResult });
52
+ }
53
+ result.patterns = sortBySeverity(patternResult.results);
54
+ result.duplicates = patternResult.duplicates;
55
+ result.summary.totalIssues += patternResult.results.reduce(
56
+ (sum, file) => sum + file.issues.length,
57
+ 0
58
+ );
59
+ }
60
+ if (tools.includes("context")) {
61
+ const contextResults = await analyzeContext(options);
62
+ if (options.progressCallback) {
63
+ options.progressCallback({ tool: "context", data: contextResults });
64
+ }
65
+ result.context = contextResults.sort((a, b) => {
66
+ const severityDiff = (severityOrder[b.severity] || 0) - (severityOrder[a.severity] || 0);
67
+ if (severityDiff !== 0) return severityDiff;
68
+ if (a.tokenCost !== b.tokenCost) return b.tokenCost - a.tokenCost;
69
+ return b.fragmentationScore - a.fragmentationScore;
70
+ });
71
+ result.summary.totalIssues += result.context?.length || 0;
72
+ }
73
+ if (tools.includes("consistency")) {
74
+ const consistencyOptions = {
75
+ rootDir: options.rootDir,
76
+ include: options.include,
77
+ exclude: options.exclude,
78
+ ...options.consistency || {}
79
+ };
80
+ const report = await analyzeConsistency(consistencyOptions);
81
+ if (options.progressCallback) {
82
+ options.progressCallback({ tool: "consistency", data: report });
83
+ }
84
+ if (report.results) {
85
+ report.results = sortBySeverity(report.results);
86
+ }
87
+ result.consistency = report;
88
+ result.summary.totalIssues += report.summary.totalIssues;
89
+ }
90
+ if (tools.includes("doc-drift")) {
91
+ const { analyzeDocDrift } = await import("@aiready/doc-drift");
92
+ const report = await analyzeDocDrift({
93
+ rootDir: options.rootDir,
94
+ include: options.include,
95
+ exclude: options.exclude
96
+ });
97
+ if (options.progressCallback) {
98
+ options.progressCallback({ tool: "doc-drift", data: report });
99
+ }
100
+ result.docDrift = report;
101
+ result.summary.totalIssues += report.issues?.length || 0;
102
+ }
103
+ if (tools.includes("deps-health")) {
104
+ const { analyzeDeps } = await import("@aiready/deps");
105
+ const report = await analyzeDeps({
106
+ rootDir: options.rootDir,
107
+ include: options.include,
108
+ exclude: options.exclude
109
+ });
110
+ if (options.progressCallback) {
111
+ options.progressCallback({ tool: "deps-health", data: report });
112
+ }
113
+ result.deps = report;
114
+ result.summary.totalIssues += report.issues?.length || 0;
115
+ }
116
+ if (tools.includes("hallucination")) {
117
+ const { analyzeHallucinationRisk } = await import("@aiready/hallucination-risk");
118
+ const report = await analyzeHallucinationRisk({
119
+ rootDir: options.rootDir,
120
+ include: options.include,
121
+ exclude: options.exclude
122
+ });
123
+ if (options.progressCallback) {
124
+ options.progressCallback({ tool: "hallucination", data: report });
125
+ }
126
+ result.hallucination = report;
127
+ result.summary.totalIssues += report.results?.reduce((sum, r) => sum + (r.issues?.length || 0), 0) || 0;
128
+ }
129
+ if (tools.includes("grounding")) {
130
+ const { analyzeAgentGrounding } = await import("@aiready/agent-grounding");
131
+ const report = await analyzeAgentGrounding({
132
+ rootDir: options.rootDir,
133
+ include: options.include,
134
+ exclude: options.exclude
135
+ });
136
+ if (options.progressCallback) {
137
+ options.progressCallback({ tool: "grounding", data: report });
138
+ }
139
+ result.grounding = report;
140
+ result.summary.totalIssues += report.issues?.length || 0;
141
+ }
142
+ if (tools.includes("testability")) {
143
+ const { analyzeTestability } = await import("@aiready/testability");
144
+ const report = await analyzeTestability({
145
+ rootDir: options.rootDir,
146
+ include: options.include,
147
+ exclude: options.exclude
148
+ });
149
+ if (options.progressCallback) {
150
+ options.progressCallback({ tool: "testability", data: report });
151
+ }
152
+ result.testability = report;
153
+ result.summary.totalIssues += report.issues?.length || 0;
154
+ }
155
+ result.summary.executionTime = Date.now() - startTime;
156
+ return result;
157
+ }
158
+ function generateUnifiedSummary(result) {
159
+ const { summary } = result;
160
+ let output = `\u{1F680} AIReady Analysis Complete
161
+
162
+ `;
163
+ output += `\u{1F4CA} Summary:
164
+ `;
165
+ output += ` Tools run: ${summary.toolsRun.join(", ")}
166
+ `;
167
+ output += ` Total issues found: ${summary.totalIssues}
168
+ `;
169
+ output += ` Execution time: ${(summary.executionTime / 1e3).toFixed(2)}s
170
+
171
+ `;
172
+ if (result.patterns) {
173
+ output += `\u{1F50D} Pattern Analysis: ${result.patterns.length} issues
174
+ `;
175
+ }
176
+ if (result.context) {
177
+ output += `\u{1F9E0} Context Analysis: ${result.context.length} issues
178
+ `;
179
+ }
180
+ if (result.consistency) {
181
+ output += `\u{1F3F7}\uFE0F Consistency Analysis: ${result.consistency.summary.totalIssues} issues
182
+ `;
183
+ }
184
+ if (result.docDrift) {
185
+ output += `\u{1F4DD} Doc Drift Analysis: ${result.docDrift.issues?.length || 0} issues
186
+ `;
187
+ }
188
+ if (result.deps) {
189
+ output += `\u{1F4E6} Dependency Health: ${result.deps.issues?.length || 0} issues
190
+ `;
191
+ }
192
+ if (result.hallucination) {
193
+ output += `\u{1F9E0} Hallucination Risk: ${result.hallucination.summary?.totalSignals || 0} signals
194
+ `;
195
+ }
196
+ if (result.grounding) {
197
+ output += `\u{1F9ED} Agent Grounding: ${result.grounding.issues?.length || 0} issues
198
+ `;
199
+ }
200
+ if (result.testability) {
201
+ output += `\u{1F9EA} Testability Index: ${result.testability.issues?.length || 0} issues
202
+ `;
203
+ }
204
+ return output;
205
+ }
206
+
207
+ export {
208
+ __require,
209
+ analyzeUnified,
210
+ generateUnifiedSummary
211
+ };