patram 0.8.0 → 0.9.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.
Files changed (140) hide show
  1. package/bin/patram.js +2 -2
  2. package/lib/{parse-cli-color-options.js → cli/color-options.js} +2 -2
  3. package/lib/cli/command-helpers.js +35 -0
  4. package/lib/cli/commands/check.js +73 -0
  5. package/lib/cli/commands/fields.js +57 -0
  6. package/lib/cli/commands/queries.js +41 -0
  7. package/lib/cli/commands/query.js +239 -0
  8. package/lib/cli/commands/refs.js +72 -0
  9. package/lib/cli/commands/show.js +58 -0
  10. package/lib/{cli-help-metadata.js → cli/help-metadata.js} +6 -6
  11. package/lib/cli/main.js +76 -0
  12. package/lib/{parse-cli-arguments-helpers.js → cli/parse-arguments-helpers.js} +7 -7
  13. package/lib/{parse-cli-arguments.js → cli/parse-arguments.js} +12 -12
  14. package/lib/{parse-cli-query-pagination.js → cli/query-pagination.js} +2 -2
  15. package/lib/{render-cli-help.js → cli/render-help.js} +3 -3
  16. package/lib/{resolve-output-mode.js → cli/resolve-output-mode.js} +2 -2
  17. package/lib/cli/test-helpers.js +30 -0
  18. package/lib/config/defaults.d.ts +10 -0
  19. package/lib/config/defaults.js +80 -0
  20. package/lib/config/load-patram-config.d.ts +76 -0
  21. package/lib/config/load-patram-config.js +315 -0
  22. package/lib/config/load-patram-config.types.d.ts +45 -0
  23. package/lib/{patram-config.d.ts → config/patram-config.d.ts} +31 -31
  24. package/lib/{patram-config.js → config/patram-config.js} +3 -3
  25. package/lib/{patram-config.types.d.ts → config/patram-config.types.d.ts} +1 -1
  26. package/lib/{resolve-patram-graph-config.d.ts → config/resolve-patram-graph-config.d.ts} +2 -2
  27. package/lib/{resolve-patram-graph-config.js → config/resolve-patram-graph-config.js} +3 -3
  28. package/lib/{load-patram-config.d.ts → config/schema.d.ts} +147 -191
  29. package/lib/config/schema.js +324 -0
  30. package/lib/{source-file-defaults.d.ts → config/source-file-defaults.d.ts} +0 -1
  31. package/lib/{source-file-defaults.js → config/source-file-defaults.js} +1 -1
  32. package/lib/config/validation.d.ts +27 -0
  33. package/lib/config/validation.js +615 -0
  34. package/lib/directive-validation-test-helpers.js +1 -1
  35. package/lib/{build-graph-identity.d.ts → graph/build-graph-identity.d.ts} +2 -2
  36. package/lib/{build-graph-identity.js → graph/build-graph-identity.js} +1 -1
  37. package/lib/{build-graph.d.ts → graph/build-graph.d.ts} +3 -3
  38. package/lib/{build-graph.js → graph/build-graph.js} +17 -13
  39. package/lib/{build-graph.types.d.ts → graph/build-graph.types.d.ts} +1 -1
  40. package/lib/graph/check-directive-metadata.d.ts +23 -0
  41. package/lib/{check-directive-metadata.js → graph/check-directive-metadata.js} +7 -7
  42. package/lib/graph/check-directive-path-target.d.ts +32 -0
  43. package/lib/{check-directive-path-target.js → graph/check-directive-path-target.js} +4 -4
  44. package/lib/graph/check-directive-value.d.ts +19 -0
  45. package/lib/{check-directive-value.js → graph/check-directive-value.js} +3 -3
  46. package/lib/graph/check-graph.d.ts +29 -0
  47. package/lib/{check-graph.js → graph/check-graph.js} +6 -6
  48. package/lib/graph/directive-diagnostics.d.ts +20 -0
  49. package/lib/{directive-diagnostics.js → graph/directive-diagnostics.js} +2 -2
  50. package/lib/graph/directive-type-rules.d.ts +18 -0
  51. package/lib/{directive-type-rules.js → graph/directive-type-rules.js} +3 -3
  52. package/lib/{document-node-identity.d.ts → graph/document-node-identity.d.ts} +2 -2
  53. package/lib/{document-node-identity.js → graph/document-node-identity.js} +2 -2
  54. package/lib/graph/inspect-reverse-references.d.ts +22 -0
  55. package/lib/{inspect-reverse-references.js → graph/inspect-reverse-references.js} +2 -2
  56. package/lib/{load-project-graph.d.ts → graph/load-project-graph.d.ts} +10 -10
  57. package/lib/{load-project-graph.js → graph/load-project-graph.js} +12 -12
  58. package/lib/{parse-where-clause.types.d.ts → graph/parse-where-clause.types.d.ts} +1 -1
  59. package/lib/{query-graph.d.ts → graph/query/execute.d.ts} +11 -11
  60. package/lib/{query-graph.js → graph/query/execute.js} +12 -12
  61. package/lib/{query-inspection.d.ts → graph/query/inspect.d.ts} +10 -8
  62. package/lib/{query-inspection.js → graph/query/inspect.js} +16 -17
  63. package/lib/{parse-where-clause.d.ts → graph/query/parse.d.ts} +6 -6
  64. package/lib/{parse-where-clause.js → graph/query/parse.js} +2 -2
  65. package/lib/graph/query/resolve.d.ts +30 -0
  66. package/lib/{resolve-where-clause.js → graph/query/resolve.js} +1 -1
  67. package/lib/graph/reverse-reference-test-helpers.d.ts +55 -0
  68. package/lib/{command-output.js → output/command-output.js} +5 -5
  69. package/lib/{derived-summary.js → output/derived-summary.js} +7 -7
  70. package/lib/{layout-incoming-references.js → output/layout-incoming-references.js} +4 -4
  71. package/lib/{layout-incoming-summary-lines.js → output/layout-incoming-summary-lines.js} +0 -5
  72. package/lib/{layout-stored-queries.js → output/layout-stored-queries.js} +9 -9
  73. package/lib/{list-queries.js → output/list-queries.js} +1 -1
  74. package/lib/{render-check-output.js → output/render-check-output.js} +1 -1
  75. package/lib/{render-field-discovery.js → output/render-field-discovery.js} +3 -3
  76. package/lib/output/render-output-view.js +56 -0
  77. package/lib/{render-json-output.js → output/renderers/json.js} +1 -1
  78. package/lib/{render-plain-output.js → output/renderers/plain.js} +19 -7
  79. package/lib/{render-rich-output.js → output/renderers/rich.js} +29 -13
  80. package/lib/{resolve-check-target.js → output/resolve-check-target.js} +1 -1
  81. package/lib/{render-rich-source.js → output/rich-source/render.js} +6 -6
  82. package/lib/{show-document.js → output/show-document.js} +12 -12
  83. package/lib/{render-output-view.js → output/view-model/index.js} +6 -52
  84. package/lib/{write-paged-output.js → output/write-paged-output.js} +9 -5
  85. package/lib/{claim-helpers.d.ts → parse/claim-helpers.d.ts} +2 -2
  86. package/lib/{parse-jsdoc-claims.d.ts → parse/jsdoc/parse-jsdoc-claims.d.ts} +2 -2
  87. package/lib/{parse-jsdoc-claims.js → parse/jsdoc/parse-jsdoc-claims.js} +9 -9
  88. package/lib/{parse-jsdoc-prose.d.ts → parse/jsdoc/parse-jsdoc-prose.d.ts} +1 -1
  89. package/lib/{parse-jsdoc-prose.js → parse/jsdoc/parse-jsdoc-prose.js} +1 -1
  90. package/lib/{parse-markdown-claims.d.ts → parse/markdown/parse-markdown-claims.d.ts} +3 -3
  91. package/lib/{parse-markdown-claims.js → parse/markdown/parse-markdown-claims.js} +8 -8
  92. package/lib/{parse-markdown-directives.d.ts → parse/markdown/parse-markdown-directives.d.ts} +2 -2
  93. package/lib/{parse-markdown-directives.js → parse/markdown/parse-markdown-directives.js} +3 -3
  94. package/lib/{parse-claims.d.ts → parse/parse-claims.d.ts} +4 -13
  95. package/lib/{parse-claims.js → parse/parse-claims.js} +18 -26
  96. package/lib/{parse-claims.types.d.ts → parse/parse-claims.types.d.ts} +1 -1
  97. package/lib/{tagged-fenced-block-error.d.ts → parse/tagged-fenced/tagged-fenced-block-error.d.ts} +2 -2
  98. package/lib/{tagged-fenced-block-parser.d.ts → parse/tagged-fenced/tagged-fenced-block-parser.d.ts} +3 -3
  99. package/lib/{tagged-fenced-blocks.d.ts → parse/tagged-fenced/tagged-fenced-blocks.d.ts} +7 -7
  100. package/lib/{tagged-fenced-blocks.js → parse/tagged-fenced/tagged-fenced-blocks.js} +3 -3
  101. package/lib/{parse-yaml-claims.d.ts → parse/yaml/parse-yaml-claims.d.ts} +4 -4
  102. package/lib/{parse-yaml-claims.js → parse/yaml/parse-yaml-claims.js} +22 -13
  103. package/lib/patram.d.ts +29 -28
  104. package/lib/patram.js +5 -6
  105. package/lib/{discover-fields.js → scan/discover-fields.js} +9 -8
  106. package/lib/scan/list-repo-files.d.ts +16 -0
  107. package/lib/{list-source-files.js → scan/list-repo-files.js} +2 -35
  108. package/lib/{list-source-files.d.ts → scan/list-source-files.d.ts} +4 -11
  109. package/lib/scan/list-source-files.js +45 -0
  110. package/package.json +8 -7
  111. package/lib/build-graph.types.ts +0 -27
  112. package/lib/discover-fields.types.ts +0 -52
  113. package/lib/load-patram-config.js +0 -1215
  114. package/lib/load-patram-config.types.d.ts +0 -45
  115. package/lib/load-patram-config.types.ts +0 -56
  116. package/lib/output-view.types.d.ts +0 -88
  117. package/lib/output-view.types.ts +0 -113
  118. package/lib/overlay-graph.d.ts +0 -43
  119. package/lib/overlay-graph.js +0 -191
  120. package/lib/parse-claims.types.ts +0 -41
  121. package/lib/parse-cli-arguments.types.ts +0 -75
  122. package/lib/parse-where-clause.types.ts +0 -87
  123. package/lib/patram-cli.js +0 -593
  124. package/lib/patram-config.types.ts +0 -22
  125. package/lib/tagged-fenced-blocks.types.ts +0 -38
  126. /package/lib/{reverse-reference-test-helpers.js → graph/reverse-reference-test-helpers.js} +0 -0
  127. /package/lib/{format-derived-summary-row.js → output/format-derived-summary-row.js} +0 -0
  128. /package/lib/{format-node-header.js → output/format-node-header.js} +0 -0
  129. /package/lib/{format-output-item-block.js → output/format-output-item-block.js} +0 -0
  130. /package/lib/{format-output-metadata.js → output/format-output-metadata.js} +0 -0
  131. /package/lib/{claim-helpers.js → parse/claim-helpers.js} +0 -0
  132. /package/lib/{parse-jsdoc-blocks.d.ts → parse/jsdoc/parse-jsdoc-blocks.d.ts} +0 -0
  133. /package/lib/{parse-jsdoc-blocks.js → parse/jsdoc/parse-jsdoc-blocks.js} +0 -0
  134. /package/lib/{tagged-fenced-block-error.js → parse/tagged-fenced/tagged-fenced-block-error.js} +0 -0
  135. /package/lib/{tagged-fenced-block-markdown.d.ts → parse/tagged-fenced/tagged-fenced-block-markdown.d.ts} +0 -0
  136. /package/lib/{tagged-fenced-block-markdown.js → parse/tagged-fenced/tagged-fenced-block-markdown.js} +0 -0
  137. /package/lib/{tagged-fenced-block-metadata.d.ts → parse/tagged-fenced/tagged-fenced-block-metadata.d.ts} +0 -0
  138. /package/lib/{tagged-fenced-block-metadata.js → parse/tagged-fenced/tagged-fenced-block-metadata.js} +0 -0
  139. /package/lib/{tagged-fenced-block-parser.js → parse/tagged-fenced/tagged-fenced-block-parser.js} +0 -0
  140. /package/lib/{tagged-fenced-blocks.types.d.ts → parse/tagged-fenced/tagged-fenced-blocks.types.d.ts} +0 -0
@@ -1,26 +1,25 @@
1
1
  /* eslint-disable max-lines */
2
2
  /**
3
- * @import { PatramDiagnostic, PatramRepoConfig } from './load-patram-config.types.ts';
4
- * @import { ResolvedOutputMode } from './output-view.types.ts';
3
+ * @import { PatramDiagnostic, PatramRepoConfig } from '../../config/load-patram-config.types.ts';
5
4
  * @import {
6
5
  * ParsedExpression,
7
6
  * ParsedRelationTargetTerm,
8
7
  * ParsedRelationTerm,
9
8
  * ParsedTerm,
10
9
  * ParsedTraversalTerm,
11
- * } from './parse-where-clause.types.ts';
10
+ * } from '../parse-where-clause.types.ts';
12
11
  */
13
12
 
14
13
  import { Ansis } from 'ansis';
15
14
 
16
- import { parseWhereClause } from './parse-where-clause.js';
15
+ import { parseWhereClause } from './parse.js';
17
16
 
18
17
  /**
19
18
  * @typedef {{ kind: 'ad_hoc' } | { kind: 'stored_query', name: string }} QuerySource
20
19
  */
21
20
 
22
21
  /**
23
- * @typedef {import('./parse-where-clause.types.ts').ParsedFieldTerm | import('./parse-where-clause.types.ts').ParsedFieldSetTerm} FieldDiagnosticTerm
22
+ * @typedef {import('../parse-where-clause.types.ts').ParsedFieldTerm | import('../parse-where-clause.types.ts').ParsedFieldSetTerm} FieldDiagnosticTerm
24
23
  */
25
24
 
26
25
  /**
@@ -114,7 +113,7 @@ export function inspectQuery(
114
113
  * Render a successful query inspection in one output mode.
115
114
  *
116
115
  * @param {QueryInspectionSuccess} query_inspection
117
- * @param {ResolvedOutputMode} output_mode
116
+ * @param {{ color_enabled: boolean, renderer_name: 'json' | 'plain' | 'rich' }} output_mode
118
117
  * @returns {string}
119
118
  */
120
119
  export function renderQueryInspection(query_inspection, output_mode) {
@@ -175,7 +174,7 @@ export function getQuerySemanticDiagnostics(
175
174
  * @param {ParsedExpression} expression
176
175
  * @param {PatramDiagnostic[]} diagnostics
177
176
  * @param {Set<string>} known_relation_names
178
- * @param {Record<string, import('./load-patram-config.types.ts').MetadataFieldConfig>} known_field_definitions
177
+ * @param {Record<string, import('../../config/load-patram-config.types.ts').MetadataFieldConfig>} known_field_definitions
179
178
  * @param {string} diagnostic_path
180
179
  */
181
180
  function collectExpressionDiagnostics(
@@ -230,7 +229,7 @@ function collectExpressionDiagnostics(
230
229
  * @param {ParsedTerm} term
231
230
  * @param {PatramDiagnostic[]} diagnostics
232
231
  * @param {Set<string>} known_relation_names
233
- * @param {Record<string, import('./load-patram-config.types.ts').MetadataFieldConfig>} known_field_definitions
232
+ * @param {Record<string, import('../../config/load-patram-config.types.ts').MetadataFieldConfig>} known_field_definitions
234
233
  * @param {string} diagnostic_path
235
234
  */
236
235
  function collectTermDiagnostics(
@@ -293,7 +292,7 @@ function collectTermDiagnostics(
293
292
  /**
294
293
  * @param {FieldDiagnosticTerm} term
295
294
  * @param {PatramDiagnostic[]} diagnostics
296
- * @param {Record<string, import('./load-patram-config.types.ts').MetadataFieldConfig>} known_field_definitions
295
+ * @param {Record<string, import('../../config/load-patram-config.types.ts').MetadataFieldConfig>} known_field_definitions
297
296
  * @param {string} diagnostic_path
298
297
  */
299
298
  function collectFieldDiagnostics(
@@ -302,12 +301,12 @@ function collectFieldDiagnostics(
302
301
  known_field_definitions,
303
302
  diagnostic_path,
304
303
  ) {
305
- const field_diagnostics_collector = getFieldDiagnosticsCollector(
304
+ const fieldDiagnosticsCollector = getFieldDiagnosticsCollector(
306
305
  term.field_name,
307
306
  );
308
307
 
309
- if (field_diagnostics_collector) {
310
- field_diagnostics_collector(term, diagnostics, diagnostic_path);
308
+ if (fieldDiagnosticsCollector) {
309
+ fieldDiagnosticsCollector(term, diagnostics, diagnostic_path);
311
310
  return;
312
311
  }
313
312
 
@@ -430,8 +429,8 @@ function collectStructuralFieldDiagnostics(term, diagnostics, diagnostic_path) {
430
429
  }
431
430
 
432
431
  /**
433
- * @param {import('./parse-where-clause.types.ts').ParsedFieldTerm} term
434
- * @param {import('./load-patram-config.types.ts').MetadataFieldConfig} field_definition
432
+ * @param {import('../parse-where-clause.types.ts').ParsedFieldTerm} term
433
+ * @param {import('../../config/load-patram-config.types.ts').MetadataFieldConfig} field_definition
435
434
  * @param {string} diagnostic_path
436
435
  * @returns {PatramDiagnostic | null}
437
436
  */
@@ -454,7 +453,7 @@ function getMetadataFieldOperatorDiagnostic(
454
453
 
455
454
  /**
456
455
  * @param {string} operator
457
- * @param {import('./load-patram-config.types.ts').MetadataFieldConfig} field_definition
456
+ * @param {import('../../config/load-patram-config.types.ts').MetadataFieldConfig} field_definition
458
457
  * @returns {boolean}
459
458
  */
460
459
  function supportsMetadataFieldOperator(operator, field_definition) {
@@ -474,7 +473,7 @@ function supportsMetadataFieldOperator(operator, field_definition) {
474
473
  }
475
474
 
476
475
  /**
477
- * @param {import('./load-patram-config.types.ts').MetadataFieldConfig} field_definition
476
+ * @param {import('../../config/load-patram-config.types.ts').MetadataFieldConfig} field_definition
478
477
  * @returns {boolean}
479
478
  */
480
479
  function supportsPrefixOperator(field_definition) {
@@ -489,7 +488,7 @@ function supportsPrefixOperator(field_definition) {
489
488
  }
490
489
 
491
490
  /**
492
- * @param {import('./load-patram-config.types.ts').MetadataFieldConfig} field_definition
491
+ * @param {import('../../config/load-patram-config.types.ts').MetadataFieldConfig} field_definition
493
492
  * @returns {boolean}
494
493
  */
495
494
  function supportsContainsOperator(field_definition) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @import { PatramDiagnostic } from './load-patram-config.types.ts';
2
+ * @import { PatramDiagnostic } from '../../config/load-patram-config.types.d.ts';
3
3
  * @import {
4
4
  * ParseWhereClauseResult,
5
5
  * ParsedAggregateComparison,
@@ -9,7 +9,7 @@
9
9
  * ParsedFieldName,
10
10
  * ParsedTerm,
11
11
  * ParsedTraversalTerm,
12
- * } from './parse-where-clause.types.ts';
12
+ * } from '../parse-where-clause.types.d.ts';
13
13
  */
14
14
  /**
15
15
  * @typedef {{ bindings: Record<string, string>, index: number, where_clause: string }} ParserState
@@ -69,7 +69,7 @@ export type ParseValueResult = {
69
69
  success: true;
70
70
  value: string;
71
71
  } | ParseFailureResult;
72
- import type { ParseWhereClauseResult } from './parse-where-clause.types.ts';
73
- import type { PatramDiagnostic } from './load-patram-config.types.ts';
74
- import type { ParsedExpression } from './parse-where-clause.types.ts';
75
- import type { ParsedTerm } from './parse-where-clause.types.ts';
72
+ import type { ParseWhereClauseResult } from '../parse-where-clause.types.d.ts';
73
+ import type { PatramDiagnostic } from '../../config/load-patram-config.types.d.ts';
74
+ import type { ParsedExpression } from '../parse-where-clause.types.d.ts';
75
+ import type { ParsedTerm } from '../parse-where-clause.types.d.ts';
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable max-lines */
2
2
  /**
3
- * @import { PatramDiagnostic } from './load-patram-config.types.ts';
3
+ * @import { PatramDiagnostic } from '../../config/load-patram-config.types.ts';
4
4
  * @import {
5
5
  * ParseWhereClauseResult,
6
6
  * ParsedAggregateComparison,
@@ -10,7 +10,7 @@
10
10
  * ParsedFieldName,
11
11
  * ParsedTerm,
12
12
  * ParsedTraversalTerm,
13
- * } from './parse-where-clause.types.ts';
13
+ * } from '../parse-where-clause.types.ts';
14
14
  */
15
15
 
16
16
  /**
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @import { PatramRepoConfig } from '../../config/load-patram-config.types.d.ts';
3
+ */
4
+ /**
5
+ * @typedef {{ kind: 'ad_hoc' } | { kind: 'stored_query', name: string }} QuerySource
6
+ */
7
+ /**
8
+ * Resolve an ad hoc or stored query into a where clause.
9
+ *
10
+ * @param {PatramRepoConfig} repo_config
11
+ * @param {string[]} command_arguments
12
+ * @returns {{ success: true, value: { query_source: QuerySource, where_clause: string } } | { success: false, message: string }}
13
+ */
14
+ export function resolveWhereClause(repo_config: PatramRepoConfig, command_arguments: string[]): {
15
+ success: true;
16
+ value: {
17
+ query_source: QuerySource;
18
+ where_clause: string;
19
+ };
20
+ } | {
21
+ success: false;
22
+ message: string;
23
+ };
24
+ export type QuerySource = {
25
+ kind: "ad_hoc";
26
+ } | {
27
+ kind: "stored_query";
28
+ name: string;
29
+ };
30
+ import type { PatramRepoConfig } from '../../config/load-patram-config.types.d.ts';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @import { PatramRepoConfig } from './load-patram-config.types.ts';
2
+ * @import { PatramRepoConfig } from '../../config/load-patram-config.types.ts';
3
3
  */
4
4
 
5
5
  /**
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Shared reverse-reference graph fixtures for tests.
3
+ */
4
+ export function createDecisionNode(): {
5
+ $class: string;
6
+ $id: string;
7
+ $path: string;
8
+ id: string;
9
+ path: string;
10
+ status: string;
11
+ title: string;
12
+ };
13
+ export function createReconcileNode(): {
14
+ $class: string;
15
+ $id: string;
16
+ $path: string;
17
+ id: string;
18
+ path: string;
19
+ title: string;
20
+ };
21
+ export function createResumeNode(): {
22
+ $class: string;
23
+ $id: string;
24
+ $path: string;
25
+ id: string;
26
+ path: string;
27
+ title: string;
28
+ };
29
+ export function createTaskNode(): {
30
+ $class: string;
31
+ $id: string;
32
+ $path: string;
33
+ id: string;
34
+ path: string;
35
+ status: string;
36
+ title: string;
37
+ };
38
+ /**
39
+ * @param {string} edge_id
40
+ * @param {string} from_id
41
+ * @param {string} origin_path
42
+ * @param {string} relation_name
43
+ * @param {string} to_id
44
+ */
45
+ export function createGraphEdge(edge_id: string, from_id: string, origin_path: string, relation_name: string, to_id: string): {
46
+ from: string;
47
+ id: string;
48
+ origin: {
49
+ column: number;
50
+ line: number;
51
+ path: string;
52
+ };
53
+ relation: string;
54
+ to: string;
55
+ };
@@ -1,12 +1,12 @@
1
1
  /**
2
- * @import { ParsedCliArguments } from './parse-cli-arguments.types.ts';
2
+ * @import { ParsedCliArguments } from '../cli/arguments.types.ts';
3
3
  * @import { OutputView } from './output-view.types.ts';
4
4
  */
5
5
 
6
6
  import process from 'node:process';
7
7
 
8
+ import { resolveOutputMode } from '../cli/resolve-output-mode.js';
8
9
  import { renderOutputView } from './render-output-view.js';
9
- import { resolveOutputMode } from './resolve-output-mode.js';
10
10
  import { writePagedOutput } from './write-paged-output.js';
11
11
 
12
12
  /**
@@ -17,11 +17,11 @@ import { writePagedOutput } from './write-paged-output.js';
17
17
  *
18
18
  * Kind: output
19
19
  * Status: active
20
- * Tracked in: ../docs/plans/v0/source-anchor-dogfooding.md
21
- * Decided by: ../docs/decisions/tty-pager-output.md
20
+ * Tracked in: ../../docs/plans/v0/source-anchor-dogfooding.md
21
+ * Decided by: ../../docs/decisions/tty-pager-output.md
22
22
  * @patram
23
23
  * @see {@link ./render-output-view.js}
24
- * @see {@link ../docs/decisions/tty-pager-output.md}
24
+ * @see {@link ../../docs/decisions/tty-pager-output.md}
25
25
  */
26
26
 
27
27
  /**
@@ -1,10 +1,10 @@
1
1
  /**
2
- * @import { BuildGraphResult, GraphNode } from './build-graph.types.ts';
2
+ * @import { BuildGraphResult, GraphNode } from '../graph/build-graph.types.ts';
3
3
  * @import { OutputDerivedSummary } from './output-view.types.ts';
4
- * @import { DerivedSummaryConfig, DerivedSummaryFieldConfig, DerivedSummaryScalar, PatramRepoConfig } from './load-patram-config.types.ts';
4
+ * @import { DerivedSummaryConfig, DerivedSummaryFieldConfig, DerivedSummaryScalar, PatramRepoConfig } from '../config/load-patram-config.types.ts';
5
5
  */
6
6
 
7
- import { queryGraph } from './query-graph.js';
7
+ import { queryGraph } from '../graph/query/execute.js';
8
8
 
9
9
  /**
10
10
  * Derived summary evaluation.
@@ -14,11 +14,11 @@ import { queryGraph } from './query-graph.js';
14
14
  *
15
15
  * Kind: output
16
16
  * Status: active
17
- * Tracked in: ../docs/plans/v0/declarative-derived-summaries.md
18
- * Decided by: ../docs/decisions/declarative-derived-summary-config.md
19
- * Decided by: ../docs/decisions/declarative-derived-summary-side-effects.md
17
+ * Tracked in: ../../docs/plans/v0/declarative-derived-summaries.md
18
+ * Decided by: ../../docs/decisions/declarative-derived-summary-config.md
19
+ * Decided by: ../../docs/decisions/declarative-derived-summary-side-effects.md
20
20
  * @patram
21
- * @see {@link ./load-patram-config.js}
21
+ * @see {@link ../config/load-patram-config.js}
22
22
  * @see {@link ./render-output-view.js}
23
23
  */
24
24
 
@@ -17,9 +17,9 @@ import { formatOutputItemBlock } from './format-output-item-block.js';
17
17
  * @returns {string[]}
18
18
  */
19
19
  export function layoutIncomingReferenceLines(incoming, layout_options = {}) {
20
- const format_node_header =
20
+ const formatNodeHeader =
21
21
  layout_options.format_node_header ?? defaultNodeHeaderFormatter;
22
- const format_relation_header =
22
+ const formatRelationHeader =
23
23
  layout_options.format_relation_header ?? defaultRelationHeaderFormatter;
24
24
  /** @type {string[]} */
25
25
  const output_lines = [];
@@ -32,10 +32,10 @@ export function layoutIncomingReferenceLines(incoming, layout_options = {}) {
32
32
  const relation_sources = incoming[relation_name];
33
33
 
34
34
  output_lines.push(
35
- format_relation_header(relation_name, relation_sources.length),
35
+ formatRelationHeader(relation_name, relation_sources.length),
36
36
  );
37
37
  output_lines.push(
38
- ...layoutIncomingRelationSources(relation_sources, format_node_header),
38
+ ...layoutIncomingRelationSources(relation_sources, formatNodeHeader),
39
39
  );
40
40
  }
41
41
 
@@ -8,11 +8,6 @@ export function layoutIncomingSummaryLines(incoming_summary) {
8
8
  const relation_names = Object.keys(incoming_summary);
9
9
  const output_lines = ['incoming refs:'];
10
10
 
11
- if (relation_names.length === 0) {
12
- output_lines.push(' none');
13
- return output_lines;
14
- }
15
-
16
11
  for (const relation_name of relation_names) {
17
12
  output_lines.push(` ${relation_name}: ${incoming_summary[relation_name]}`);
18
13
  }
@@ -3,7 +3,7 @@
3
3
  * @import { OutputStoredQueryItem } from './output-view.types.ts';
4
4
  */
5
5
 
6
- import { parseWhereClause } from './parse-where-clause.js';
6
+ import { parseWhereClause } from '../graph/query/parse.js';
7
7
 
8
8
  const MAX_STORED_QUERY_WIDTH = 100;
9
9
  const MIN_TERM_COLUMN_WIDTH = 20;
@@ -96,7 +96,7 @@ function createStoredQueryPhrases(where_clause) {
96
96
  }
97
97
 
98
98
  /**
99
- * @param {import('./parse-where-clause.types.ts').ParsedExpression} expression
99
+ * @param {import('../graph/parse-where-clause.types.ts').ParsedExpression} expression
100
100
  * @returns {StoredQuerySegment[][]}
101
101
  */
102
102
  function createExpressionPhrases(expression) {
@@ -114,7 +114,7 @@ function createExpressionPhrases(expression) {
114
114
  }
115
115
 
116
116
  /**
117
- * @param {import('./parse-where-clause.types.ts').ParsedExpression} expression
117
+ * @param {import('../graph/parse-where-clause.types.ts').ParsedExpression} expression
118
118
  * @param {'and' | 'or'} operator
119
119
  * @param {boolean} should_prefix_operator
120
120
  * @returns {StoredQuerySegment[]}
@@ -139,7 +139,7 @@ function createExpressionPhrase(expression, operator, should_prefix_operator) {
139
139
  }
140
140
 
141
141
  /**
142
- * @param {import('./parse-where-clause.types.ts').ParsedExpression} expression
142
+ * @param {import('../graph/parse-where-clause.types.ts').ParsedExpression} expression
143
143
  * @param {number} parent_precedence
144
144
  * @returns {StoredQuerySegment[]}
145
145
  */
@@ -159,7 +159,7 @@ function createExpressionSegments(expression, parent_precedence) {
159
159
  }
160
160
 
161
161
  /**
162
- * @param {import('./parse-where-clause.types.ts').ParsedExpression} expression
162
+ * @param {import('../graph/parse-where-clause.types.ts').ParsedExpression} expression
163
163
  * @returns {StoredQuerySegment[]}
164
164
  */
165
165
  function createRawExpressionSegments(expression) {
@@ -202,7 +202,7 @@ function createRawExpressionSegments(expression) {
202
202
  }
203
203
 
204
204
  /**
205
- * @param {import('./parse-where-clause.types.ts').ParsedExpression} expression
205
+ * @param {import('../graph/parse-where-clause.types.ts').ParsedExpression} expression
206
206
  * @returns {number}
207
207
  */
208
208
  function getExpressionPrecedence(expression) {
@@ -230,7 +230,7 @@ function getBooleanExpressionPrecedence(operator) {
230
230
  }
231
231
 
232
232
  /**
233
- * @param {import('./parse-where-clause.types.ts').ParsedTerm} term
233
+ * @param {import('../graph/parse-where-clause.types.ts').ParsedTerm} term
234
234
  * @returns {StoredQuerySegment[]}
235
235
  */
236
236
  function createTermSegments(term) {
@@ -265,7 +265,7 @@ function createTermSegments(term) {
265
265
  }
266
266
 
267
267
  /**
268
- * @param {import('./parse-where-clause.types.ts').ParsedFieldSetTerm} term
268
+ * @param {import('../graph/parse-where-clause.types.ts').ParsedFieldSetTerm} term
269
269
  * @returns {StoredQuerySegment[]}
270
270
  */
271
271
  function createFieldSetSegments(term) {
@@ -281,7 +281,7 @@ function createFieldSetSegments(term) {
281
281
  }
282
282
 
283
283
  /**
284
- * @param {import('./parse-where-clause.types.ts').ParsedAggregateTerm} term
284
+ * @param {import('../graph/parse-where-clause.types.ts').ParsedAggregateTerm} term
285
285
  * @returns {StoredQuerySegment[]}
286
286
  */
287
287
  function createAggregateSegments(term) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @import { StoredQueryConfig } from './load-patram-config.types.ts';
2
+ * @import { StoredQueryConfig } from '../config/load-patram-config.types.ts';
3
3
  */
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @import { PatramDiagnostic } from './load-patram-config.types.ts';
2
+ * @import { PatramDiagnostic } from '../config/load-patram-config.types.ts';
3
3
  * @import { ResolvedOutputMode } from './output-view.types.ts';
4
4
  */
5
5
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @import { ResolvedOutputMode } from './output-view.types.ts';
3
- * @import { FieldDiscoveryResult, FieldDiscoverySuggestion } from './discover-fields.types.ts';
3
+ * @import { FieldDiscoveryResult, FieldDiscoverySuggestion } from '../scan/discover-fields.types.ts';
4
4
  */
5
5
 
6
6
  import { Ansis } from 'ansis';
@@ -135,7 +135,7 @@ function formatTextFieldSuggestion(field_suggestion, render_options) {
135
135
 
136
136
  /**
137
137
  * @param {string} section_title
138
- * @param {import('./discover-fields.types.ts').FieldDiscoveryEvidenceReference[]} evidence_references
138
+ * @param {import('../scan/discover-fields.types.ts').FieldDiscoveryEvidenceReference[]} evidence_references
139
139
  * @param {{ header: (value: string) => string, label: (value: string) => string }} render_options
140
140
  * @returns {string[]}
141
141
  */
@@ -168,7 +168,7 @@ function formatTextEvidenceSection(
168
168
  }
169
169
 
170
170
  /**
171
- * @param {import('./discover-fields.types.ts').FieldDiscoveryEvidenceReference} evidence_reference
171
+ * @param {import('../scan/discover-fields.types.ts').FieldDiscoveryEvidenceReference} evidence_reference
172
172
  * @returns {string}
173
173
  */
174
174
  function formatEvidenceReference(evidence_reference) {
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @import { ParsedCliArguments } from '../cli/arguments.types.ts';
3
+ * @import { ResolvedOutputMode, OutputView } from './output-view.types.ts';
4
+ */
5
+
6
+ import { renderJsonOutput } from './renderers/json.js';
7
+ import { renderPlainOutput } from './renderers/plain.js';
8
+ import { renderRichOutput } from './renderers/rich.js';
9
+
10
+ /**
11
+ * Shared command output views.
12
+ *
13
+ * Normalizes `query`, `queries`, and `show` results into renderer-specific
14
+ * output models.
15
+ *
16
+ * Kind: output
17
+ * Status: active
18
+ * Tracked in: ../../docs/plans/v0/source-anchor-dogfooding.md
19
+ * Decided by: ../../docs/decisions/cli-output-architecture.md
20
+ * @patram
21
+ * @see {@link ./show-document.js}
22
+ * @see {@link ../../docs/decisions/cli-output-architecture.md}
23
+ */
24
+
25
+ export {
26
+ createOutputView,
27
+ createRefsOutputView,
28
+ createShowOutputView,
29
+ } from './view-model/index.js';
30
+
31
+ /**
32
+ * Render one shared output view through the resolved renderer.
33
+ *
34
+ * @param {OutputView} output_view
35
+ * @param {ResolvedOutputMode} output_mode
36
+ * @param {ParsedCliArguments} parsed_arguments
37
+ * @returns {Promise<string>}
38
+ */
39
+ export async function renderOutputView(
40
+ output_view,
41
+ output_mode,
42
+ parsed_arguments,
43
+ ) {
44
+ if (output_mode.renderer_name === 'json') {
45
+ return renderJsonOutput(output_view);
46
+ }
47
+
48
+ if (output_mode.renderer_name === 'plain') {
49
+ return renderPlainOutput(output_view);
50
+ }
51
+
52
+ return renderRichOutput(output_view, {
53
+ color_enabled: output_mode.color_enabled,
54
+ color_mode: parsed_arguments.color_mode,
55
+ });
56
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @import { OutputNodeItem, OutputResolvedLinkItem, OutputStoredQueryItem, OutputView } from './output-view.types.ts';
2
+ * @import { OutputNodeItem, OutputResolvedLinkItem, OutputStoredQueryItem, OutputView } from '../output-view.types.ts';
3
3
  */
4
4
 
5
5
  /**
@@ -1,16 +1,16 @@
1
1
  /**
2
- * @import { OutputNodeItem, OutputResolvedLinkItem, OutputStoredQueryItem, OutputView, QueryOutputView, RefsOutputView, ShowOutputView } from './output-view.types.ts';
2
+ * @import { OutputNodeItem, OutputResolvedLinkItem, OutputStoredQueryItem, OutputView, QueryOutputView, RefsOutputView, ShowOutputView } from '../output-view.types.ts';
3
3
  */
4
4
 
5
5
  import {
6
6
  formatOutputNodeMetadataRows,
7
7
  formatResolvedLinkMetadataRows,
8
- } from './format-output-metadata.js';
9
- import { formatNodeHeader } from './format-node-header.js';
10
- import { formatOutputItemBlock } from './format-output-item-block.js';
11
- import { layoutIncomingReferenceLines } from './layout-incoming-references.js';
12
- import { layoutIncomingSummaryLines } from './layout-incoming-summary-lines.js';
13
- import { layoutStoredQueries } from './layout-stored-queries.js';
8
+ } from '../format-output-metadata.js';
9
+ import { formatNodeHeader } from '../format-node-header.js';
10
+ import { formatOutputItemBlock } from '../format-output-item-block.js';
11
+ import { layoutIncomingReferenceLines } from '../layout-incoming-references.js';
12
+ import { layoutIncomingSummaryLines } from '../layout-incoming-summary-lines.js';
13
+ import { layoutStoredQueries } from '../layout-stored-queries.js';
14
14
 
15
15
  /**
16
16
  * Render the canonical plain output for one output view.
@@ -172,12 +172,24 @@ function formatPlainResolvedLinkItem(output_item) {
172
172
  * @returns {string}
173
173
  */
174
174
  function renderPlainIncomingSummary(output_view) {
175
+ if (!hasIncomingSummary(output_view.incoming_summary)) {
176
+ return '';
177
+ }
178
+
175
179
  const output_lines = layoutIncomingSummaryLines(output_view.incoming_summary);
176
180
  output_lines.push('', `Hint: patram refs ${output_view.path}`);
177
181
 
178
182
  return output_lines.join('\n');
179
183
  }
180
184
 
185
+ /**
186
+ * @param {Record<string, number>} incoming_summary
187
+ * @returns {boolean}
188
+ */
189
+ function hasIncomingSummary(incoming_summary) {
190
+ return Object.keys(incoming_summary).length > 0;
191
+ }
192
+
181
193
  /**
182
194
  * @param {string} value
183
195
  * @returns {string}