@opensip-cli/yagni 0.1.11

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.
Files changed (152) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +33 -0
  4. package/dist/__tests__/apply-advisory-exit.test.d.ts +2 -0
  5. package/dist/__tests__/apply-advisory-exit.test.d.ts.map +1 -0
  6. package/dist/__tests__/apply-advisory-exit.test.js +31 -0
  7. package/dist/__tests__/apply-advisory-exit.test.js.map +1 -0
  8. package/dist/__tests__/fixtures/unused-config-surface/pkg/src/app-config.d.ts +6 -0
  9. package/dist/__tests__/fixtures/unused-config-surface/pkg/src/app-config.d.ts.map +1 -0
  10. package/dist/__tests__/fixtures/unused-config-surface/pkg/src/app-config.js +5 -0
  11. package/dist/__tests__/fixtures/unused-config-surface/pkg/src/app-config.js.map +1 -0
  12. package/dist/__tests__/fixtures/unused-config-surface/pkg/src/consumer.d.ts +3 -0
  13. package/dist/__tests__/fixtures/unused-config-surface/pkg/src/consumer.d.ts.map +1 -0
  14. package/dist/__tests__/fixtures/unused-config-surface/pkg/src/consumer.js +4 -0
  15. package/dist/__tests__/fixtures/unused-config-surface/pkg/src/consumer.js.map +1 -0
  16. package/dist/__tests__/fixtures/unused-config-surface/pkg/src/index.d.ts +3 -0
  17. package/dist/__tests__/fixtures/unused-config-surface/pkg/src/index.d.ts.map +1 -0
  18. package/dist/__tests__/fixtures/unused-config-surface/pkg/src/index.js +2 -0
  19. package/dist/__tests__/fixtures/unused-config-surface/pkg/src/index.js.map +1 -0
  20. package/dist/__tests__/graph-evidence.test.d.ts +2 -0
  21. package/dist/__tests__/graph-evidence.test.d.ts.map +1 -0
  22. package/dist/__tests__/graph-evidence.test.js +159 -0
  23. package/dist/__tests__/graph-evidence.test.js.map +1 -0
  24. package/dist/__tests__/walk-typescript-files.test.d.ts +2 -0
  25. package/dist/__tests__/walk-typescript-files.test.d.ts.map +1 -0
  26. package/dist/__tests__/walk-typescript-files.test.js +47 -0
  27. package/dist/__tests__/walk-typescript-files.test.js.map +1 -0
  28. package/dist/__tests__/yagni-coverage.test.d.ts +2 -0
  29. package/dist/__tests__/yagni-coverage.test.d.ts.map +1 -0
  30. package/dist/__tests__/yagni-coverage.test.js +542 -0
  31. package/dist/__tests__/yagni-coverage.test.js.map +1 -0
  32. package/dist/__tests__/yagni-golden.test.d.ts +5 -0
  33. package/dist/__tests__/yagni-golden.test.d.ts.map +1 -0
  34. package/dist/__tests__/yagni-golden.test.js +135 -0
  35. package/dist/__tests__/yagni-golden.test.js.map +1 -0
  36. package/dist/__tests__/yagni-presentation.test.d.ts +2 -0
  37. package/dist/__tests__/yagni-presentation.test.d.ts.map +1 -0
  38. package/dist/__tests__/yagni-presentation.test.js +30 -0
  39. package/dist/__tests__/yagni-presentation.test.js.map +1 -0
  40. package/dist/baseline-strategy.d.ts +9 -0
  41. package/dist/baseline-strategy.d.ts.map +1 -0
  42. package/dist/baseline-strategy.js +30 -0
  43. package/dist/baseline-strategy.js.map +1 -0
  44. package/dist/cli/__tests__/yagni-runner.test.d.ts +5 -0
  45. package/dist/cli/__tests__/yagni-runner.test.d.ts.map +1 -0
  46. package/dist/cli/__tests__/yagni-runner.test.js +126 -0
  47. package/dist/cli/__tests__/yagni-runner.test.js.map +1 -0
  48. package/dist/cli/execute-yagni.d.ts +32 -0
  49. package/dist/cli/execute-yagni.d.ts.map +1 -0
  50. package/dist/cli/execute-yagni.js +127 -0
  51. package/dist/cli/execute-yagni.js.map +1 -0
  52. package/dist/cli/report-data.d.ts +23 -0
  53. package/dist/cli/report-data.d.ts.map +1 -0
  54. package/dist/cli/report-data.js +23 -0
  55. package/dist/cli/report-data.js.map +1 -0
  56. package/dist/cli/yagni-command-spec.d.ts +6 -0
  57. package/dist/cli/yagni-command-spec.d.ts.map +1 -0
  58. package/dist/cli/yagni-command-spec.js +152 -0
  59. package/dist/cli/yagni-command-spec.js.map +1 -0
  60. package/dist/cli/yagni-config-schema.d.ts +28 -0
  61. package/dist/cli/yagni-config-schema.d.ts.map +1 -0
  62. package/dist/cli/yagni-config-schema.js +39 -0
  63. package/dist/cli/yagni-config-schema.js.map +1 -0
  64. package/dist/cli/yagni-config.d.ts +27 -0
  65. package/dist/cli/yagni-config.d.ts.map +1 -0
  66. package/dist/cli/yagni-config.js +72 -0
  67. package/dist/cli/yagni-config.js.map +1 -0
  68. package/dist/cli/yagni-presentation.d.ts +15 -0
  69. package/dist/cli/yagni-presentation.d.ts.map +1 -0
  70. package/dist/cli/yagni-presentation.js +92 -0
  71. package/dist/cli/yagni-presentation.js.map +1 -0
  72. package/dist/cli/yagni-runner.d.ts +20 -0
  73. package/dist/cli/yagni-runner.d.ts.map +1 -0
  74. package/dist/cli/yagni-runner.js +95 -0
  75. package/dist/cli/yagni-runner.js.map +1 -0
  76. package/dist/detectors/create-yagni-signal.d.ts +8 -0
  77. package/dist/detectors/create-yagni-signal.d.ts.map +1 -0
  78. package/dist/detectors/create-yagni-signal.js +10 -0
  79. package/dist/detectors/create-yagni-signal.js.map +1 -0
  80. package/dist/detectors/duplicate-body-candidate.d.ts +7 -0
  81. package/dist/detectors/duplicate-body-candidate.d.ts.map +1 -0
  82. package/dist/detectors/duplicate-body-candidate.js +137 -0
  83. package/dist/detectors/duplicate-body-candidate.js.map +1 -0
  84. package/dist/detectors/registry.d.ts +4 -0
  85. package/dist/detectors/registry.d.ts.map +1 -0
  86. package/dist/detectors/registry.js +8 -0
  87. package/dist/detectors/registry.js.map +1 -0
  88. package/dist/detectors/types.d.ts +28 -0
  89. package/dist/detectors/types.d.ts.map +1 -0
  90. package/dist/detectors/types.js +2 -0
  91. package/dist/detectors/types.js.map +1 -0
  92. package/dist/detectors/unused-config-surface.d.ts +10 -0
  93. package/dist/detectors/unused-config-surface.d.ts.map +1 -0
  94. package/dist/detectors/unused-config-surface.js +199 -0
  95. package/dist/detectors/unused-config-surface.js.map +1 -0
  96. package/dist/evidence/graph-evidence.d.ts +15 -0
  97. package/dist/evidence/graph-evidence.d.ts.map +1 -0
  98. package/dist/evidence/graph-evidence.js +89 -0
  99. package/dist/evidence/graph-evidence.js.map +1 -0
  100. package/dist/evidence/load-graph-adapters.d.ts +13 -0
  101. package/dist/evidence/load-graph-adapters.d.ts.map +1 -0
  102. package/dist/evidence/load-graph-adapters.js +67 -0
  103. package/dist/evidence/load-graph-adapters.js.map +1 -0
  104. package/dist/identity.d.ts +7 -0
  105. package/dist/identity.d.ts.map +1 -0
  106. package/dist/identity.js +7 -0
  107. package/dist/identity.js.map +1 -0
  108. package/dist/index.d.ts +8 -0
  109. package/dist/index.d.ts.map +1 -0
  110. package/dist/index.js +6 -0
  111. package/dist/index.js.map +1 -0
  112. package/dist/lib/apply-advisory-exit.d.ts +8 -0
  113. package/dist/lib/apply-advisory-exit.d.ts.map +1 -0
  114. package/dist/lib/apply-advisory-exit.js +16 -0
  115. package/dist/lib/apply-advisory-exit.js.map +1 -0
  116. package/dist/lib/isolate-exit-code.d.ts +8 -0
  117. package/dist/lib/isolate-exit-code.d.ts.map +1 -0
  118. package/dist/lib/isolate-exit-code.js +27 -0
  119. package/dist/lib/isolate-exit-code.js.map +1 -0
  120. package/dist/lib/resolve-positional-paths.d.ts +6 -0
  121. package/dist/lib/resolve-positional-paths.d.ts.map +1 -0
  122. package/dist/lib/resolve-positional-paths.js +33 -0
  123. package/dist/lib/resolve-positional-paths.js.map +1 -0
  124. package/dist/lib/walk-typescript-files.d.ts +2 -0
  125. package/dist/lib/walk-typescript-files.d.ts.map +1 -0
  126. package/dist/lib/walk-typescript-files.js +50 -0
  127. package/dist/lib/walk-typescript-files.js.map +1 -0
  128. package/dist/persistence/session-payload.d.ts +54 -0
  129. package/dist/persistence/session-payload.d.ts.map +1 -0
  130. package/dist/persistence/session-payload.js +48 -0
  131. package/dist/persistence/session-payload.js.map +1 -0
  132. package/dist/scoring/__tests__/confidence.test.d.ts +2 -0
  133. package/dist/scoring/__tests__/confidence.test.d.ts.map +1 -0
  134. package/dist/scoring/__tests__/confidence.test.js +123 -0
  135. package/dist/scoring/__tests__/confidence.test.js.map +1 -0
  136. package/dist/scoring/confidence.d.ts +12 -0
  137. package/dist/scoring/confidence.d.ts.map +1 -0
  138. package/dist/scoring/confidence.js +106 -0
  139. package/dist/scoring/confidence.js.map +1 -0
  140. package/dist/tool.d.ts +11 -0
  141. package/dist/tool.d.ts.map +1 -0
  142. package/dist/tool.js +38 -0
  143. package/dist/tool.js.map +1 -0
  144. package/dist/types/yagni-config.d.ts +18 -0
  145. package/dist/types/yagni-config.d.ts.map +1 -0
  146. package/dist/types/yagni-config.js +11 -0
  147. package/dist/types/yagni-config.js.map +1 -0
  148. package/dist/types/yagni-metadata.d.ts +51 -0
  149. package/dist/types/yagni-metadata.d.ts.map +1 -0
  150. package/dist/types/yagni-metadata.js +5 -0
  151. package/dist/types/yagni-metadata.js.map +1 -0
  152. package/package.json +77 -0
@@ -0,0 +1,152 @@
1
+ /**
2
+ * yagni-command-spec — declarative primary `yagni` command.
3
+ */
4
+ import { definePrimaryCommand } from '@opensip-cli/core';
5
+ import { YAGNI_LIVE_VIEW_KEY } from '../identity.js';
6
+ import { applyAdvisoryExitCode } from '../lib/apply-advisory-exit.js';
7
+ import { resolveYagniPositionalPaths } from '../lib/resolve-positional-paths.js';
8
+ import { executeYagni } from './execute-yagni.js';
9
+ import { loadYagniConfig } from './yagni-config.js';
10
+ import { buildYagniRunPresentation } from './yagni-presentation.js';
11
+ function parseGraphMode(raw) {
12
+ if (raw === 'auto' || raw === 'reuse' || raw === 'build' || raw === 'off')
13
+ return raw;
14
+ return undefined;
15
+ }
16
+ function parseMinConfidence(raw) {
17
+ if (raw === 'low' || raw === 'medium' || raw === 'high')
18
+ return raw;
19
+ return undefined;
20
+ }
21
+ function normalizeRepeatable(raw) {
22
+ if (raw === undefined)
23
+ return [];
24
+ return Array.isArray(raw) ? raw : [raw];
25
+ }
26
+ function buildYagniLiveArgs(opts, graphMode, pathRoots) {
27
+ return {
28
+ cwd: opts.cwd,
29
+ verbose: opts.verbose === true,
30
+ quiet: opts.quiet === true,
31
+ graphMode,
32
+ minConfidence: parseMinConfidence(opts.minConfidence),
33
+ detectors: normalizeRepeatable(opts.detector),
34
+ categories: normalizeRepeatable(opts.category),
35
+ includeTests: opts.includeTests,
36
+ pathRoots,
37
+ };
38
+ }
39
+ async function deliverYagniRun(opts, cli, config, outcome) {
40
+ await cli.deliverSignals(outcome.envelope, {
41
+ cwd: opts.cwd,
42
+ reportTo: opts.reportTo,
43
+ apiKey: opts.apiKey,
44
+ });
45
+ await cli.maybeOpenReport({
46
+ openRequested: opts.open === true,
47
+ jsonOutput: opts.json === true,
48
+ });
49
+ // Re-affirm after delivery (--report-to may set exit 4; advisory policy wins otherwise).
50
+ applyAdvisoryExitCode(cli, config);
51
+ }
52
+ async function runYagniCommand(rawOpts, cli, setUpLiveView) {
53
+ const opts = rawOpts;
54
+ const config = loadYagniConfig(opts.cwd);
55
+ const graphMode = parseGraphMode(opts.graph) ?? config.graphMode ?? 'auto';
56
+ const positionals = opts._args ?? [];
57
+ const paths = (positionals[0] ?? []);
58
+ const pathRoots = paths.length > 0 ? resolveYagniPositionalPaths(paths, opts.cwd) : undefined;
59
+ const useLiveView = opts.json !== true && process.stdout.isTTY === true && pathRoots === undefined;
60
+ if (useLiveView) {
61
+ setUpLiveView(cli);
62
+ const completion = await cli.renderLive(YAGNI_LIVE_VIEW_KEY, buildYagniLiveArgs(opts, graphMode, pathRoots));
63
+ const envelope = completion?.envelope;
64
+ if (envelope !== undefined) {
65
+ await deliverYagniRun(opts, cli, config, { envelope });
66
+ }
67
+ return completion ?? {};
68
+ }
69
+ const startedAt = Date.now();
70
+ const outcome = await executeYagni({
71
+ cwd: opts.cwd,
72
+ config,
73
+ graphMode,
74
+ minConfidence: parseMinConfidence(opts.minConfidence),
75
+ detectors: normalizeRepeatable(opts.detector),
76
+ categories: normalizeRepeatable(opts.category),
77
+ includeTests: opts.includeTests ?? config.includeTests,
78
+ pathRoots,
79
+ }, cli);
80
+ // Clear exit codes leaked by in-process `executeGraph` before the host wraps
81
+ // the envelope (emitEnvelope snapshots getExitCode at write time).
82
+ applyAdvisoryExitCode(cli, config);
83
+ if (opts.json === true) {
84
+ cli.emitEnvelope(outcome.envelope);
85
+ }
86
+ else {
87
+ const durationMs = Math.max(0, Date.now() - startedAt);
88
+ const presentation = buildYagniRunPresentation({
89
+ envelope: outcome.envelope,
90
+ cwd: opts.cwd,
91
+ graphMode: outcome.session.payload.summary.graphMode ?? graphMode,
92
+ skippedDetectors: outcome.session.payload.summary.skippedDetectors,
93
+ verbose: opts.verbose === true,
94
+ durationMs,
95
+ });
96
+ await cli.render(presentation);
97
+ }
98
+ await deliverYagniRun(opts, cli, config, outcome);
99
+ return { session: outcome.session };
100
+ }
101
+ export function buildYagniCommandSpec(setUpLiveView) {
102
+ return definePrimaryCommand({
103
+ description: 'Run YAGNI reduction audit detectors (advisory; exit 0 by default)',
104
+ commonFlags: ['cwd', 'json', 'quiet', 'verbose', 'debug', 'reportTo', 'apiKey', 'open'],
105
+ options: [
106
+ {
107
+ flag: '--graph',
108
+ value: '<mode>',
109
+ description: 'Graph evidence mode: auto (reuse or build), reuse, build, or off (default from config)',
110
+ choices: ['auto', 'reuse', 'build', 'off'],
111
+ },
112
+ {
113
+ flag: '--min-confidence',
114
+ value: '<level>',
115
+ description: 'Minimum confidence level: low, medium, or high',
116
+ choices: ['low', 'medium', 'high'],
117
+ },
118
+ {
119
+ flag: '--detector',
120
+ value: '<slug>',
121
+ description: 'Run only the named detector (repeatable)',
122
+ arrayDefault: [],
123
+ parse: (val, prev) => [...prev, val],
124
+ },
125
+ {
126
+ flag: '--category',
127
+ value: '<name>',
128
+ description: 'Filter findings by reduction category (repeatable)',
129
+ arrayDefault: [],
130
+ parse: (val, prev) => [...prev, val],
131
+ },
132
+ {
133
+ flag: '--include-tests',
134
+ description: 'Include test and fixture code in analysis',
135
+ default: false,
136
+ },
137
+ ],
138
+ args: [
139
+ {
140
+ name: 'paths',
141
+ description: 'Limit analysis to one or more directory subtrees',
142
+ variadic: true,
143
+ optional: true,
144
+ },
145
+ ],
146
+ scope: 'project',
147
+ output: 'raw-stream',
148
+ rawStreamReason: 'runtime-render-dispatch',
149
+ handler: (rawOpts, cli) => runYagniCommand(rawOpts, cli, setUpLiveView),
150
+ });
151
+ }
152
+ //# sourceMappingURL=yagni-command-spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yagni-command-spec.js","sourceRoot":"","sources":["../../src/cli/yagni-command-spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * yagni-config-schema — the YAGNI tool's namespaced Zod config schema.
3
+ *
4
+ * Mirrors {@link YagniConfig} one-for-one. Gate keys (`failOnErrors` /
5
+ * `failOnWarnings`) default to `0` so advisory findings never fail the run.
6
+ */
7
+ import { z } from 'zod';
8
+ import type { ToolConfigDeclaration } from '@opensip-cli/config';
9
+ export declare const YagniConfigSchema: z.ZodObject<{
10
+ failOnErrors: z.ZodOptional<z.ZodNumber>;
11
+ failOnWarnings: z.ZodOptional<z.ZodNumber>;
12
+ defaultMinConfidence: z.ZodOptional<z.ZodEnum<{
13
+ low: "low";
14
+ medium: "medium";
15
+ high: "high";
16
+ }>>;
17
+ graphMode: z.ZodOptional<z.ZodEnum<{
18
+ auto: "auto";
19
+ reuse: "reuse";
20
+ build: "build";
21
+ off: "off";
22
+ }>>;
23
+ includeTests: z.ZodOptional<z.ZodBoolean>;
24
+ disabledDetectors: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
25
+ detectorSettings: z.ZodOptional<z.ZodReadonly<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>>;
26
+ }, z.core.$strip>;
27
+ export declare const yagniConfigDeclaration: ToolConfigDeclaration;
28
+ //# sourceMappingURL=yagni-config-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yagni-config-schema.d.ts","sourceRoot":"","sources":["../../src/cli/yagni-config-schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAKjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;iBAQ5B,CAAC;AAMH,eAAO,MAAM,sBAAsB,EAAE,qBAmBpC,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * yagni-config-schema — the YAGNI tool's namespaced Zod config schema.
3
+ *
4
+ * Mirrors {@link YagniConfig} one-for-one. Gate keys (`failOnErrors` /
5
+ * `failOnWarnings`) default to `0` so advisory findings never fail the run.
6
+ */
7
+ import { z } from 'zod';
8
+ const graphMode = z.enum(['auto', 'reuse', 'build', 'off']);
9
+ const confidenceLevel = z.enum(['low', 'medium', 'high']);
10
+ export const YagniConfigSchema = z.object({
11
+ failOnErrors: z.number().int().min(0).optional(),
12
+ failOnWarnings: z.number().int().min(0).optional(),
13
+ defaultMinConfidence: confidenceLevel.optional(),
14
+ graphMode: graphMode.optional(),
15
+ includeTests: z.boolean().optional(),
16
+ disabledDetectors: z.array(z.string().min(1)).readonly().optional(),
17
+ detectorSettings: z.record(z.string(), z.record(z.string(), z.unknown())).readonly().optional(),
18
+ });
19
+ export const yagniConfigDeclaration = {
20
+ namespace: 'yagni',
21
+ schema: YagniConfigSchema,
22
+ defaults: {
23
+ failOnErrors: 0,
24
+ failOnWarnings: 0,
25
+ defaultMinConfidence: 'medium',
26
+ graphMode: 'auto',
27
+ includeTests: false,
28
+ },
29
+ env: [
30
+ { envVar: 'OPENSIP_YAGNI_GRAPH_MODE', key: 'graphMode' },
31
+ { envVar: 'OPENSIP_YAGNI_MIN_CONFIDENCE', key: 'defaultMinConfidence' },
32
+ {
33
+ envVar: 'OPENSIP_YAGNI_INCLUDE_TESTS',
34
+ key: 'includeTests',
35
+ type: 'boolean',
36
+ },
37
+ ],
38
+ };
39
+ //# sourceMappingURL=yagni-config-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yagni-config-schema.js","sourceRoot":"","sources":["../../src/cli/yagni-config-schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AAC5D,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAE1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAChD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAClD,oBAAoB,EAAE,eAAe,CAAC,QAAQ,EAAE;IAChD,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE;IAC/B,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACpC,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACnE,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAChG,CAAC,CAAC;AAMH,MAAM,CAAC,MAAM,sBAAsB,GAA0B;IAC3D,SAAS,EAAE,OAAO;IAClB,MAAM,EAAE,iBAAiB;IACzB,QAAQ,EAAE;QACR,YAAY,EAAE,CAAC;QACf,cAAc,EAAE,CAAC;QACjB,oBAAoB,EAAE,QAAQ;QAC9B,SAAS,EAAE,MAAM;QACjB,YAAY,EAAE,KAAK;KACpB;IACD,GAAG,EAAE;QACH,EAAE,MAAM,EAAE,0BAA0B,EAAE,GAAG,EAAE,WAAW,EAAE;QACxD,EAAE,MAAM,EAAE,8BAA8B,EAAE,GAAG,EAAE,sBAAsB,EAAE;QACvE;YACE,MAAM,EAAE,6BAA6B;YACrC,GAAG,EAAE,cAAc;YACnB,IAAI,EAAE,SAAS;SAChB;KACF;CACF,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * yagni-config — load the resolved `yagni:` block of `opensip-cli.config.yml`
3
+ * into a {@link YagniConfig}.
4
+ *
5
+ * ADR-0023, Phase 4: the resolved `yagni:` block rides on the per-run scope
6
+ * (`scope.toolConfig.yagni`) — the host already strict-validated +
7
+ * precedence-resolved (flag > env > file > defaults) the whole document before
8
+ * dispatch, using yagni's own namespaced {@link YagniConfigSchema} (the same
9
+ * schema yagni contributes via `yagniConfigDeclaration`). So when a scope is
10
+ * present (every CLI dispatch path goes through the pre-action hook) this returns
11
+ * the SCOPE value and does NOT re-read YAML — mirroring `loadGraphConfig` /
12
+ * `readSimulationRecipe`. The YAML read below is the fallback for a scope-less
13
+ * direct caller (a unit test driving `loadYagniConfig`); there it stays
14
+ * best-effort: a missing config, malformed YAML, an absent `yagni:` key, or a
15
+ * block that fails the schema all collapse to the merged defaults.
16
+ *
17
+ * This loader is the yagni peer of graph's `graph-config.ts` and sim's
18
+ * `sim-config.ts` config-loader bridges — it is allowlisted in the
19
+ * `dogfood-one-config-document-ratchet` check's sanctioned config readers for
20
+ * exactly this reason.
21
+ */
22
+ import type { YagniConfig } from '../types/yagni-config.js';
23
+ /**
24
+ * Load the `yagni:` namespace for a run. Prefers the host-resolved scope value.
25
+ */
26
+ export declare function loadYagniConfig(cwd: string, explicitPath?: string): YagniConfig;
27
+ //# sourceMappingURL=yagni-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yagni-config.d.ts","sourceRoot":"","sources":["../../src/cli/yagni-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAQH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAoB5D;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,WAAW,CA0B/E"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * yagni-config — load the resolved `yagni:` block of `opensip-cli.config.yml`
3
+ * into a {@link YagniConfig}.
4
+ *
5
+ * ADR-0023, Phase 4: the resolved `yagni:` block rides on the per-run scope
6
+ * (`scope.toolConfig.yagni`) — the host already strict-validated +
7
+ * precedence-resolved (flag > env > file > defaults) the whole document before
8
+ * dispatch, using yagni's own namespaced {@link YagniConfigSchema} (the same
9
+ * schema yagni contributes via `yagniConfigDeclaration`). So when a scope is
10
+ * present (every CLI dispatch path goes through the pre-action hook) this returns
11
+ * the SCOPE value and does NOT re-read YAML — mirroring `loadGraphConfig` /
12
+ * `readSimulationRecipe`. The YAML read below is the fallback for a scope-less
13
+ * direct caller (a unit test driving `loadYagniConfig`); there it stays
14
+ * best-effort: a missing config, malformed YAML, an absent `yagni:` key, or a
15
+ * block that fails the schema all collapse to the merged defaults.
16
+ *
17
+ * This loader is the yagni peer of graph's `graph-config.ts` and sim's
18
+ * `sim-config.ts` config-loader bridges — it is allowlisted in the
19
+ * `dogfood-one-config-document-ratchet` check's sanctioned config readers for
20
+ * exactly this reason.
21
+ */
22
+ import { currentScope, readYamlFile, resolveProjectConfigPath } from '@opensip-cli/core';
23
+ import { DEFAULT_YAGNI_CONFIG } from '../types/yagni-config.js';
24
+ import { YagniConfigSchema } from './yagni-config-schema.js';
25
+ function isPlainObject(v) {
26
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
27
+ }
28
+ function mergeDefaults(parsed) {
29
+ return {
30
+ failOnErrors: parsed.failOnErrors ?? DEFAULT_YAGNI_CONFIG.failOnErrors,
31
+ failOnWarnings: parsed.failOnWarnings ?? DEFAULT_YAGNI_CONFIG.failOnWarnings,
32
+ defaultMinConfidence: parsed.defaultMinConfidence ?? DEFAULT_YAGNI_CONFIG.defaultMinConfidence,
33
+ graphMode: parsed.graphMode ?? DEFAULT_YAGNI_CONFIG.graphMode,
34
+ includeTests: parsed.includeTests ?? DEFAULT_YAGNI_CONFIG.includeTests,
35
+ ...(parsed.disabledDetectors === undefined
36
+ ? {}
37
+ : { disabledDetectors: parsed.disabledDetectors }),
38
+ ...(parsed.detectorSettings === undefined ? {} : { detectorSettings: parsed.detectorSettings }),
39
+ };
40
+ }
41
+ /**
42
+ * Load the `yagni:` namespace for a run. Prefers the host-resolved scope value.
43
+ */
44
+ export function loadYagniConfig(cwd, explicitPath) {
45
+ // Scope-first: the resolved, strict-validated `yagni:` block (env/flag
46
+ // precedence already folded in by the composer). Present on every CLI dispatch
47
+ // path; absent only off-CLI (direct unit-test calls), where we fall back to the
48
+ // YAML read below.
49
+ const scope = currentScope();
50
+ const scoped = scope?.toolConfig?.yagni;
51
+ if (isPlainObject(scoped)) {
52
+ const parsed = YagniConfigSchema.safeParse(scoped);
53
+ if (parsed.success)
54
+ return mergeDefaults(parsed.data);
55
+ }
56
+ if (scope !== undefined) {
57
+ // A scope-bound dispatch has already had its config composed. If there is no
58
+ // resolved `yagni:` block, do not perform a second YAML read; use the merged
59
+ // tool defaults instead (mirrors loadGraphConfig / readSimulationRecipe).
60
+ return mergeDefaults({});
61
+ }
62
+ const configPath = resolveProjectConfigPath(cwd, explicitPath);
63
+ const doc = readYamlFile(configPath);
64
+ if (!isPlainObject(doc) || !isPlainObject(doc.yagni)) {
65
+ return mergeDefaults({});
66
+ }
67
+ const parsed = YagniConfigSchema.safeParse(doc.yagni);
68
+ if (!parsed.success)
69
+ return mergeDefaults({});
70
+ return mergeDefaults(parsed.data);
71
+ }
72
+ //# sourceMappingURL=yagni-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yagni-config.js","sourceRoot":"","sources":["../../src/cli/yagni-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAEzF,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAI7D,SAAS,aAAa,CAAC,CAAU;IAC/B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,aAAa,CAAC,MAAmB;IACxC,OAAO;QACL,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,oBAAoB,CAAC,YAAY;QACtE,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,oBAAoB,CAAC,cAAc;QAC5E,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,IAAI,oBAAoB,CAAC,oBAAoB;QAC9F,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,oBAAoB,CAAC,SAAS;QAC7D,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,oBAAoB,CAAC,YAAY;QACtE,GAAG,CAAC,MAAM,CAAC,iBAAiB,KAAK,SAAS;YACxC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,EAAE,CAAC;QACpD,GAAG,CAAC,MAAM,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC;KAChG,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,YAAqB;IAChE,uEAAuE;IACvE,+EAA+E;IAC/E,gFAAgF;IAChF,mBAAmB;IACnB,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC;IACxC,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACnD,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,6EAA6E;QAC7E,6EAA6E;QAC7E,0EAA0E;QAC1E,OAAO,aAAa,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,UAAU,GAAG,wBAAwB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO,aAAa,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,aAAa,CAAC,EAAE,CAAC,CAAC;IAC9C,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Human presentation for YAGNI audit runs (spec §11).
3
+ */
4
+ import type { SkippedDetector } from '../detectors/types.js';
5
+ import type { RunPresentation, SignalEnvelope } from '@opensip-cli/contracts';
6
+ export declare function buildYagniPresentationLines(envelope: SignalEnvelope, cwd: string, graphMode: string, skippedDetectors: readonly SkippedDetector[], verbose: boolean): string[];
7
+ export declare function buildYagniRunPresentation(input: {
8
+ readonly envelope: SignalEnvelope;
9
+ readonly cwd: string;
10
+ readonly graphMode: string;
11
+ readonly skippedDetectors: readonly SkippedDetector[];
12
+ readonly verbose: boolean;
13
+ readonly durationMs?: number;
14
+ }): RunPresentation;
15
+ //# sourceMappingURL=yagni-presentation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yagni-presentation.d.ts","sourceRoot":"","sources":["../../src/cli/yagni-presentation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAiB,MAAM,wBAAwB,CAAC;AAqD7F,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,SAAS,eAAe,EAAE,EAC5C,OAAO,EAAE,OAAO,GACf,MAAM,EAAE,CA8BV;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,SAAS,eAAe,EAAE,CAAC;IACtD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,GAAG,eAAe,CAelB"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Human presentation for YAGNI audit runs (spec §11).
3
+ */
4
+ import { relative } from 'node:path';
5
+ import { buildYagniRunSummary, readYagniMetadata } from '../scoring/confidence.js';
6
+ const CONFIDENCE_SECTION_ORDER = ['high', 'medium', 'low'];
7
+ function formatYagniSignalLocation(signal, cwd) {
8
+ if (signal.filePath === '')
9
+ return '<unknown>';
10
+ const rel = relative(cwd, signal.filePath).split('\\').join('/');
11
+ return signal.line === undefined ? rel : `${rel}:${String(signal.line)}`;
12
+ }
13
+ function formatLocSuffix(signal) {
14
+ const meta = readYagniMetadata(signal);
15
+ if (meta?.locDelta === undefined)
16
+ return '';
17
+ const { netEstimate, estimateKind } = meta.locDelta;
18
+ return `(~${String(netEstimate)} LOC, ${estimateKind})`;
19
+ }
20
+ function formatCandidateBlock(signal, cwd, verbose) {
21
+ const meta = readYagniMetadata(signal);
22
+ if (meta === undefined)
23
+ return [];
24
+ const loc = formatYagniSignalLocation(signal, cwd);
25
+ const block = [
26
+ ` ${meta.reductionCategory.padEnd(6)} ${meta.detector.padEnd(28)} ${loc}`,
27
+ ` → ${meta.suggestedAction.padEnd(44)} ${formatLocSuffix(signal)}`,
28
+ ];
29
+ if (!verbose)
30
+ return block;
31
+ block.push(` preservation: ${meta.preservationArgument}`);
32
+ if (meta.validationRequired.length > 0) {
33
+ block.push(` validation: ${meta.validationRequired.join('; ')}`);
34
+ }
35
+ if (meta.riskTags.length > 0) {
36
+ block.push(` risks: ${meta.riskTags.join(', ')}`);
37
+ }
38
+ for (const ev of meta.evidence) {
39
+ block.push(` evidence [${ev.kind}]: ${ev.summary}`);
40
+ }
41
+ return block;
42
+ }
43
+ function candidateLines(signals, cwd, verbose) {
44
+ const lines = [];
45
+ for (const confidence of CONFIDENCE_SECTION_ORDER) {
46
+ const bucket = signals.filter((s) => readYagniMetadata(s)?.confidence === confidence);
47
+ if (bucket.length === 0)
48
+ continue;
49
+ lines.push('', `${confidence.charAt(0).toUpperCase()}${confidence.slice(1)} confidence`);
50
+ for (const signal of bucket) {
51
+ lines.push(...formatCandidateBlock(signal, cwd, verbose));
52
+ }
53
+ }
54
+ return lines;
55
+ }
56
+ export function buildYagniPresentationLines(envelope, cwd, graphMode, skippedDetectors, verbose) {
57
+ const summary = buildYagniRunSummary(envelope.signals, graphMode, skippedDetectors);
58
+ const visibleSignals = verbose
59
+ ? envelope.signals
60
+ : envelope.signals.filter((s) => {
61
+ const conf = readYagniMetadata(s)?.confidence;
62
+ return conf === 'high' || conf === 'medium';
63
+ });
64
+ const { high, medium } = summary.byConfidence;
65
+ const headline = `YAGNI audit: ${String(summary.totalCandidates)} reduction candidates (${String(high)} high, ${String(medium)} medium)`;
66
+ const ran = envelope.units.length;
67
+ const skipped = skippedDetectors.length;
68
+ const metaLine = `Graph: ${graphMode} · ${String(ran)} detectors ran · ${String(skipped)} skipped`;
69
+ const lines = [headline, metaLine, ...candidateLines(visibleSignals, cwd, verbose)];
70
+ if (summary.estimatedTotalLocReduction > 0) {
71
+ lines.push('', `net: ~${String(summary.estimatedTotalLocReduction)} LOC possible`);
72
+ }
73
+ if (verbose && skippedDetectors.length > 0) {
74
+ lines.push('', 'Skipped detectors:');
75
+ for (const skip of skippedDetectors) {
76
+ const detail = skip.detail === undefined ? '' : ` (${skip.detail})`;
77
+ lines.push(` ${skip.slug}: ${skip.reason}${detail}`);
78
+ }
79
+ }
80
+ return lines;
81
+ }
82
+ export function buildYagniRunPresentation(input) {
83
+ const lines = buildYagniPresentationLines(input.envelope, input.cwd, input.graphMode, input.skippedDetectors, input.verbose);
84
+ return {
85
+ type: 'run-presentation',
86
+ tool: 'yagni',
87
+ envelope: input.envelope,
88
+ ...(input.verbose ? { verboseDetail: { kind: 'lines', lines } } : {}),
89
+ ...(input.durationMs === undefined ? {} : { durationMs: input.durationMs }),
90
+ };
91
+ }
92
+ //# sourceMappingURL=yagni-presentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yagni-presentation.js","sourceRoot":"","sources":["../../src/cli/yagni-presentation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * yagni-runner — live-view entry for `opensip yagni` via @opensip-cli/cli-live.
3
+ */
4
+ import { type LiveViewContext, type ToolCliContext } from '@opensip-cli/core';
5
+ import type { YagniGraphMode } from '../types/yagni-config.js';
6
+ import type { YagniConfidence } from '../types/yagni-metadata.js';
7
+ export { YAGNI_LIVE_VIEW_KEY } from '../identity.js';
8
+ export interface YagniLiveArgs {
9
+ readonly cwd: string;
10
+ readonly verbose?: boolean;
11
+ readonly quiet?: boolean;
12
+ readonly graphMode: YagniGraphMode;
13
+ readonly minConfidence?: YagniConfidence;
14
+ readonly detectors?: readonly string[];
15
+ readonly categories?: readonly string[];
16
+ readonly includeTests?: boolean;
17
+ readonly pathRoots?: readonly string[];
18
+ }
19
+ export declare function renderYagniLive(args: YagniLiveArgs, cli: ToolCliContext, liveContext?: LiveViewContext): Promise<import("@opensip-cli/core").ToolRunCompletion>;
20
+ //# sourceMappingURL=yagni-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yagni-runner.d.ts","sourceRoot":"","sources":["../../src/cli/yagni-runner.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAM3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AASlE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,aAAa,CAAC,EAAE,eAAe,CAAC;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AA2BD,wBAAsB,eAAe,CACnC,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,cAAc,EACnB,WAAW,CAAC,EAAE,eAAe,0DAmE9B"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * yagni-runner — live-view entry for `opensip yagni` via @opensip-cli/cli-live.
3
+ */
4
+ import { runToolLiveView } from '@opensip-cli/cli-live';
5
+ import { groupSignalsBySource } from '@opensip-cli/contracts';
6
+ import { isErrorSignal, currentScope, } from '@opensip-cli/core';
7
+ import { executeYagni } from './execute-yagni.js';
8
+ import { loadYagniConfig } from './yagni-config.js';
9
+ import { buildYagniPresentationLines } from './yagni-presentation.js';
10
+ const YAGNI_TOOL_TITLE = 'YAGNI Audit';
11
+ const YAGNI_TOOL_DESCRIPTION = 'Scanning for speculative surface to remove.';
12
+ const YAGNI_RUNNING_SURFACE = { shape: 'pool', label: 'Running detectors...' };
13
+ const YAGNI_LOADING_SURFACE = { shape: 'pool', label: 'Loading detectors...' };
14
+ export { YAGNI_LIVE_VIEW_KEY } from '../identity.js';
15
+ function rowStatus(unit) {
16
+ if (unit.error !== undefined)
17
+ return 'ERROR';
18
+ return unit.passed ? 'PASS' : 'FAIL';
19
+ }
20
+ function envelopeToLiveRunTableRows(envelope) {
21
+ const bySource = groupSignalsBySource(envelope.signals);
22
+ return envelope.units.map((unit) => {
23
+ const unitSignals = bySource.get(unit.slug) ?? [];
24
+ let errors = 0;
25
+ let warnings = 0;
26
+ for (const s of unitSignals) {
27
+ if (isErrorSignal(s))
28
+ errors += 1;
29
+ else
30
+ warnings += 1;
31
+ }
32
+ return {
33
+ unit: unit.slug,
34
+ status: rowStatus(unit),
35
+ errors,
36
+ warnings,
37
+ durationMs: unit.durationMs,
38
+ };
39
+ });
40
+ }
41
+ export async function renderYagniLive(args, cli, liveContext) {
42
+ const config = loadYagniConfig(args.cwd);
43
+ return runToolLiveView({
44
+ tool: 'yagni',
45
+ meta: { title: YAGNI_TOOL_TITLE, description: YAGNI_TOOL_DESCRIPTION },
46
+ surface: YAGNI_RUNNING_SURFACE,
47
+ loadingSurface: YAGNI_LOADING_SURFACE,
48
+ verbose: args.verbose === true,
49
+ quiet: args.quiet === true,
50
+ projectPath: args.cwd,
51
+ walkedUp: currentScope()?.projectContext?.walkedUp,
52
+ produce: async (emit, helpers) => {
53
+ emit({ type: 'stage-start', stage: 'detectors', label: 'Running detectors...' });
54
+ helpers.setRunning(() => {
55
+ // In-process run — progress events flow through emit() directly.
56
+ });
57
+ const executeOpts = {
58
+ cwd: args.cwd,
59
+ config,
60
+ graphMode: args.graphMode,
61
+ minConfidence: args.minConfidence,
62
+ detectors: args.detectors,
63
+ categories: args.categories,
64
+ includeTests: args.includeTests,
65
+ pathRoots: args.pathRoots,
66
+ onProgress: (completed, total) => {
67
+ emit({ type: 'stage-progress', stage: 'detectors', completed, total });
68
+ },
69
+ };
70
+ const outcome = await executeYagni(executeOpts, cli);
71
+ const graphMode = outcome.session.payload.summary.graphMode ?? args.graphMode;
72
+ const skippedDetectors = outcome.session.payload.summary.skippedDetectors;
73
+ const verboseLines = buildYagniPresentationLines(outcome.envelope, args.cwd, graphMode, skippedDetectors, args.verbose === true);
74
+ return {
75
+ kind: 'done',
76
+ done: {
77
+ summary: {
78
+ passed: outcome.envelope.verdict.passed,
79
+ errors: outcome.envelope.verdict.summary.errors,
80
+ warnings: outcome.envelope.verdict.summary.warnings,
81
+ },
82
+ ...(args.verbose === true
83
+ ? {
84
+ verboseLines,
85
+ table: envelopeToLiveRunTableRows(outcome.envelope),
86
+ }
87
+ : {}),
88
+ },
89
+ envelope: outcome.envelope,
90
+ session: outcome.session,
91
+ };
92
+ },
93
+ }, { liveContext, setExitCode: cli.setExitCode });
94
+ }
95
+ //# sourceMappingURL=yagni-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yagni-runner.js","sourceRoot":"","sources":["../../src/cli/yagni-runner.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { YagniFindingMetadata } from '../types/yagni-metadata.js';
2
+ import type { CreateSignalInput, Signal } from '@opensip-cli/core';
3
+ export interface YagniSignalInput extends Omit<CreateSignalInput, 'metadata'> {
4
+ readonly yagni: YagniFindingMetadata;
5
+ }
6
+ /** Stamp a finding with full `metadata.yagni` and the canonical rule id shape. */
7
+ export declare function createYagniSignal(input: YagniSignalInput): Signal;
8
+ //# sourceMappingURL=create-yagni-signal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-yagni-signal.d.ts","sourceRoot":"","sources":["../../src/detectors/create-yagni-signal.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEnE,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC;IAC3E,QAAQ,CAAC,KAAK,EAAE,oBAAoB,CAAC;CACtC;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAMjE"}
@@ -0,0 +1,10 @@
1
+ import { createSignal } from '@opensip-cli/core';
2
+ /** Stamp a finding with full `metadata.yagni` and the canonical rule id shape. */
3
+ export function createYagniSignal(input) {
4
+ return createSignal({
5
+ ...input,
6
+ provider: input.provider ?? 'yagni',
7
+ metadata: { yagni: input.yagni },
8
+ });
9
+ }
10
+ //# sourceMappingURL=create-yagni-signal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-yagni-signal.js","sourceRoot":"","sources":["../../src/detectors/create-yagni-signal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AASjD,kFAAkF;AAClF,MAAM,UAAU,iBAAiB,CAAC,KAAuB;IACvD,OAAO,YAAY,CAAC;QAClB,GAAG,KAAK;QACR,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,OAAO;QACnC,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;KACjC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * duplicate-body-candidate — surfaces cross-occurrence duplicate function bodies
3
+ * from a graph catalog bodyHash grouping as consolidation candidates.
4
+ */
5
+ import type { YagniDetector } from './types.js';
6
+ export declare const duplicateBodyCandidateDetector: YagniDetector;
7
+ //# sourceMappingURL=duplicate-body-candidate.d.ts.map