@zigrivers/scaffold 3.21.0 → 3.23.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 (124) hide show
  1. package/README.md +21 -7
  2. package/content/knowledge/data-science/README.md +23 -0
  3. package/content/knowledge/data-science/data-science-architecture.md +163 -0
  4. package/content/knowledge/data-science/data-science-conventions.md +233 -0
  5. package/content/knowledge/data-science/data-science-data-versioning.md +198 -0
  6. package/content/knowledge/data-science/data-science-dev-environment.md +159 -0
  7. package/content/knowledge/data-science/data-science-experiment-tracking.md +194 -0
  8. package/content/knowledge/data-science/data-science-model-evaluation.md +160 -0
  9. package/content/knowledge/data-science/data-science-notebook-discipline.md +170 -0
  10. package/content/knowledge/data-science/data-science-observability.md +161 -0
  11. package/content/knowledge/data-science/data-science-project-structure.md +178 -0
  12. package/content/knowledge/data-science/data-science-reproducibility.md +164 -0
  13. package/content/knowledge/data-science/data-science-requirements.md +151 -0
  14. package/content/knowledge/data-science/data-science-security.md +151 -0
  15. package/content/knowledge/data-science/data-science-testing.md +183 -0
  16. package/content/knowledge/ml/README.md +10 -0
  17. package/content/methodology/data-science-overlay.yml +39 -0
  18. package/dist/cli/commands/dashboard.d.ts.map +1 -1
  19. package/dist/cli/commands/dashboard.js +40 -0
  20. package/dist/cli/commands/dashboard.js.map +1 -1
  21. package/dist/config/schema.d.ts +672 -126
  22. package/dist/config/schema.d.ts.map +1 -1
  23. package/dist/config/schema.js +8 -0
  24. package/dist/config/schema.js.map +1 -1
  25. package/dist/config/schema.test.js +2 -2
  26. package/dist/config/schema.test.js.map +1 -1
  27. package/dist/config/validators/data-science.d.ts +4 -0
  28. package/dist/config/validators/data-science.d.ts.map +1 -0
  29. package/dist/config/validators/data-science.js +15 -0
  30. package/dist/config/validators/data-science.js.map +1 -0
  31. package/dist/config/validators/index.d.ts.map +1 -1
  32. package/dist/config/validators/index.js +2 -0
  33. package/dist/config/validators/index.js.map +1 -1
  34. package/dist/core/assembly/knowledge-loader.d.ts.map +1 -1
  35. package/dist/core/assembly/knowledge-loader.js +6 -0
  36. package/dist/core/assembly/knowledge-loader.js.map +1 -1
  37. package/dist/core/assembly/knowledge-loader.test.js +34 -0
  38. package/dist/core/assembly/knowledge-loader.test.js.map +1 -1
  39. package/dist/dashboard/dependency-graph.d.ts +19 -0
  40. package/dist/dashboard/dependency-graph.d.ts.map +1 -0
  41. package/dist/dashboard/dependency-graph.js +180 -0
  42. package/dist/dashboard/dependency-graph.js.map +1 -0
  43. package/dist/dashboard/dependency-graph.test.d.ts +2 -0
  44. package/dist/dashboard/dependency-graph.test.d.ts.map +1 -0
  45. package/dist/dashboard/dependency-graph.test.js +409 -0
  46. package/dist/dashboard/dependency-graph.test.js.map +1 -0
  47. package/dist/dashboard/generator.d.ts +46 -0
  48. package/dist/dashboard/generator.d.ts.map +1 -1
  49. package/dist/dashboard/generator.js +1 -0
  50. package/dist/dashboard/generator.js.map +1 -1
  51. package/dist/dashboard/multi-service.test.js +257 -1
  52. package/dist/dashboard/multi-service.test.js.map +1 -1
  53. package/dist/dashboard/template.d.ts +13 -0
  54. package/dist/dashboard/template.d.ts.map +1 -1
  55. package/dist/dashboard/template.js +176 -0
  56. package/dist/dashboard/template.js.map +1 -1
  57. package/dist/e2e/dashboard-cross-service-graph-wiring.test.d.ts +2 -0
  58. package/dist/e2e/dashboard-cross-service-graph-wiring.test.d.ts.map +1 -0
  59. package/dist/e2e/dashboard-cross-service-graph-wiring.test.js +130 -0
  60. package/dist/e2e/dashboard-cross-service-graph-wiring.test.js.map +1 -0
  61. package/dist/e2e/dashboard-cross-service-graph.test.d.ts +2 -0
  62. package/dist/e2e/dashboard-cross-service-graph.test.d.ts.map +1 -0
  63. package/dist/e2e/dashboard-cross-service-graph.test.js +216 -0
  64. package/dist/e2e/dashboard-cross-service-graph.test.js.map +1 -0
  65. package/dist/e2e/project-type-overlays.test.js +73 -0
  66. package/dist/e2e/project-type-overlays.test.js.map +1 -1
  67. package/dist/project/adopt.d.ts.map +1 -1
  68. package/dist/project/adopt.js +3 -1
  69. package/dist/project/adopt.js.map +1 -1
  70. package/dist/project/detectors/coverage.test.d.ts +2 -0
  71. package/dist/project/detectors/coverage.test.d.ts.map +1 -0
  72. package/dist/project/detectors/coverage.test.js +78 -0
  73. package/dist/project/detectors/coverage.test.js.map +1 -0
  74. package/dist/project/detectors/data-science.d.ts +4 -0
  75. package/dist/project/detectors/data-science.d.ts.map +1 -0
  76. package/dist/project/detectors/data-science.js +32 -0
  77. package/dist/project/detectors/data-science.js.map +1 -0
  78. package/dist/project/detectors/data-science.test.d.ts +2 -0
  79. package/dist/project/detectors/data-science.test.d.ts.map +1 -0
  80. package/dist/project/detectors/data-science.test.js +62 -0
  81. package/dist/project/detectors/data-science.test.js.map +1 -0
  82. package/dist/project/detectors/disambiguate.d.ts +2 -0
  83. package/dist/project/detectors/disambiguate.d.ts.map +1 -1
  84. package/dist/project/detectors/disambiguate.js +3 -2
  85. package/dist/project/detectors/disambiguate.js.map +1 -1
  86. package/dist/project/detectors/disambiguate.test.js +10 -1
  87. package/dist/project/detectors/disambiguate.test.js.map +1 -1
  88. package/dist/project/detectors/index.d.ts.map +1 -1
  89. package/dist/project/detectors/index.js +2 -0
  90. package/dist/project/detectors/index.js.map +1 -1
  91. package/dist/project/detectors/library.d.ts.map +1 -1
  92. package/dist/project/detectors/library.js +1 -0
  93. package/dist/project/detectors/library.js.map +1 -1
  94. package/dist/project/detectors/resolve-detection.test.js +31 -0
  95. package/dist/project/detectors/resolve-detection.test.js.map +1 -1
  96. package/dist/project/detectors/types.d.ts +6 -2
  97. package/dist/project/detectors/types.d.ts.map +1 -1
  98. package/dist/project/detectors/types.js.map +1 -1
  99. package/dist/types/config.d.ts +8 -1
  100. package/dist/types/config.d.ts.map +1 -1
  101. package/dist/wizard/copy/core.d.ts.map +1 -1
  102. package/dist/wizard/copy/core.js +4 -0
  103. package/dist/wizard/copy/core.js.map +1 -1
  104. package/dist/wizard/copy/data-science.d.ts +3 -0
  105. package/dist/wizard/copy/data-science.d.ts.map +1 -0
  106. package/dist/wizard/copy/data-science.js +15 -0
  107. package/dist/wizard/copy/data-science.js.map +1 -0
  108. package/dist/wizard/copy/index.d.ts.map +1 -1
  109. package/dist/wizard/copy/index.js +2 -0
  110. package/dist/wizard/copy/index.js.map +1 -1
  111. package/dist/wizard/copy/types.d.ts +5 -1
  112. package/dist/wizard/copy/types.d.ts.map +1 -1
  113. package/dist/wizard/copy/types.test-d.js +7 -0
  114. package/dist/wizard/copy/types.test-d.js.map +1 -1
  115. package/dist/wizard/questions.d.ts +2 -1
  116. package/dist/wizard/questions.d.ts.map +1 -1
  117. package/dist/wizard/questions.js +9 -1
  118. package/dist/wizard/questions.js.map +1 -1
  119. package/dist/wizard/questions.test.js +14 -0
  120. package/dist/wizard/questions.test.js.map +1 -1
  121. package/dist/wizard/wizard.d.ts.map +1 -1
  122. package/dist/wizard/wizard.js +1 -0
  123. package/dist/wizard/wizard.js.map +1 -1
  124. package/package.json +1 -1
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: data-science-testing
3
+ description: Testing strategy for solo DS code — pytest for pure functions, pandera for DataFrame schemas at test time and at ingest boundaries, and committed CSV fixtures for deterministic tests
4
+ topics: [data-science, testing, pytest, pandera]
5
+ ---
6
+
7
+ Data-science code rots quietly. A notebook cell that worked on Tuesday's snapshot silently breaks on Friday's because an upstream column was renamed, a dtype shifted from `int64` to `float64`, or a categorical grew a new level nobody tested for. Refactors that move feature logic out of a notebook into `src/` routinely regress because there was no test pinning the old behavior. Tests catch these failures at the line that introduced them instead of at the end of a three-hour pipeline run.
8
+
9
+ ## Summary
10
+
11
+ Treat DS testing as three separate layers with distinct tools. Use `pytest` for pure-function unit tests — feature engineering, metric calculations, preprocessing helpers in `src/`. Use `pandera` for DataFrame-level contracts: schemas assert column names, dtypes, value ranges, and non-null expectations, and those same schemas run both in tests and at runtime at ingest boundaries. Use committed CSV fixtures in `tests/fixtures/` loaded through pytest fixtures for deterministic, reviewable test data. Keep this doc's scope to CODE correctness; model quality (AUC, calibration, drift) belongs in `data-science-model-evaluation.md`.
12
+
13
+ ## Deep Guidance
14
+
15
+ ### Unit tests with pytest
16
+
17
+ Every helper in `src/` that transforms data is a pure function candidate for `pytest`. Arrange small inputs, act by calling the function, assert on the output. If a helper reaches for a database or filesystem, push that I/O out to the caller so the core logic stays testable without mocks.
18
+
19
+ ```python
20
+ # tests/test_features.py
21
+ import numpy as np
22
+ import pandas as pd
23
+ import pytest
24
+ from src.features import impute_missing_ages
25
+
26
+ class TestImputeMissingAges:
27
+ def test_fills_nan_with_median(self):
28
+ df = pd.DataFrame({"age": [10.0, 20.0, 30.0, np.nan]})
29
+ result = impute_missing_ages(df)
30
+ assert result["age"].isna().sum() == 0
31
+ assert result.loc[3, "age"] == 20.0 # median of [10, 20, 30]
32
+
33
+ def test_preserves_non_null_values(self):
34
+ df = pd.DataFrame({"age": [10.0, 20.0, 30.0, np.nan]})
35
+ result = impute_missing_ages(df)
36
+ pd.testing.assert_series_equal(
37
+ result.loc[:2, "age"], df.loc[:2, "age"], check_names=False
38
+ )
39
+
40
+ def test_all_nan_raises(self):
41
+ df = pd.DataFrame({"age": [np.nan, np.nan]})
42
+ with pytest.raises(ValueError, match="all-null"):
43
+ impute_missing_ages(df)
44
+ ```
45
+
46
+ Run with `pytest -q`. Add `--cov=src` via `pytest-cov` once the project has more than a handful of helpers; aim for coverage on feature-engineering and metrics modules, not notebooks.
47
+
48
+ Four rules keep this layer productive:
49
+
50
+ - **Name tests after the behavior, not the function**: `test_fills_nan_with_median` beats `test_impute_missing_ages_1`. The name is the failure message when CI turns red.
51
+ - **One assertion family per test**: a test checks either output values, or output shape, or error behavior — not all three. Split into three tests. Failures point at the broken property immediately.
52
+ - **Use `pd.testing.assert_frame_equal` and `np.testing.assert_allclose`**: never compare DataFrames with `==` or floats with exact equality. Pass `rtol`/`atol` explicitly so the tolerance is visible in the test.
53
+ - **Mark slow tests**: decorate any test that loads a non-trivial dataset with `@pytest.mark.slow` and run the default suite with `-m "not slow"` so `pytest` stays under ~5 seconds on save.
54
+
55
+ ### Data-frame validation with pandera
56
+
57
+ Column drift is the single most common source of silent DS bugs. `pandera` encodes a DataFrame contract once and reuses it as a test assertion and a runtime guard at ingest boundaries — the moment a CSV, parquet file, or API response becomes a DataFrame.
58
+
59
+ ```python
60
+ # src/schemas.py
61
+ import pandera.pandas as pa
62
+ from pandera.typing import Series
63
+
64
+ class CustomersSchema(pa.DataFrameModel):
65
+ customer_id: Series[int] = pa.Field(unique=True, ge=0)
66
+ age: Series[float] = pa.Field(ge=0, le=120, nullable=True)
67
+ signup_date: Series[pa.DateTime]
68
+ segment: Series[str] = pa.Field(isin=["free", "pro", "enterprise"])
69
+
70
+ class Config:
71
+ strict = True # reject unexpected columns
72
+
73
+ # src/ingest.py — runtime validation at the boundary
74
+ from src.schemas import CustomersSchema
75
+
76
+ def load_customers(path: str) -> pd.DataFrame:
77
+ df = pd.read_csv(path, parse_dates=["signup_date"])
78
+ return CustomersSchema.validate(df) # raises SchemaError on violation
79
+ ```
80
+
81
+ The same schema doubles as a test fixture contract:
82
+
83
+ ```python
84
+ # tests/test_ingest.py
85
+ import pandas as pd
86
+ import pytest
87
+ from pandera.errors import SchemaError
88
+ from src.ingest import load_customers
89
+
90
+ def test_rejects_invalid_segment(tmp_path):
91
+ bad = tmp_path / "bad.csv"
92
+ bad.write_text("customer_id,age,signup_date,segment\n1,30,2024-01-01,vip\n")
93
+ with pytest.raises(SchemaError, match="segment"):
94
+ load_customers(str(bad))
95
+ ```
96
+
97
+ Prefer `schema.validate(df)` calls over the `@pa.check_input` decorator — explicit validation is easier to trace in stack traces and does not hide behind import-time decoration.
98
+
99
+ Three patterns make pandera pay off:
100
+
101
+ - **Validate once at the boundary, trust downstream**: call `Schema.validate(df)` inside `load_customers`, `load_orders`, or whatever function first produces a DataFrame. Downstream code can then assume columns, dtypes, and ranges without re-checking.
102
+ - **Use `lazy=True` during development**: `Schema.validate(df, lazy=True)` collects every violation instead of failing on the first, which is dramatically faster when fixing a bad CSV.
103
+ - **Version schemas alongside migrations**: when a column renames or a new category lands, update the schema in the same PR as the code change. Schema drift caught in code review is cheaper than schema drift caught in production.
104
+
105
+ ### Fixtures: deterministic test data
106
+
107
+ Random DataFrames in tests produce flaky failures that are painful to debug. Commit small, hand-curated CSVs to `tests/fixtures/` and load them through pytest `fixture` functions. The CSVs are reviewable in PRs, the fixtures are reusable across test modules.
108
+
109
+ ```python
110
+ # tests/conftest.py
111
+ from pathlib import Path
112
+ import pandas as pd
113
+ import pytest
114
+
115
+ FIXTURES = Path(__file__).parent / "fixtures"
116
+
117
+ @pytest.fixture
118
+ def customers_df() -> pd.DataFrame:
119
+ return pd.read_csv(FIXTURES / "customers_small.csv", parse_dates=["signup_date"])
120
+
121
+ @pytest.fixture(params=["customers_empty.csv", "customers_one_row.csv", "customers_small.csv"])
122
+ def customers_edge_cases(request) -> pd.DataFrame:
123
+ return pd.read_csv(FIXTURES / request.param, parse_dates=["signup_date"])
124
+ ```
125
+
126
+ Use `@pytest.mark.parametrize` to cover multiple scenarios without duplicating test bodies:
127
+
128
+ ```python
129
+ @pytest.mark.parametrize(
130
+ "segment,expected_discount",
131
+ [("free", 0.0), ("pro", 0.1), ("enterprise", 0.2)],
132
+ )
133
+ def test_discount_by_segment(segment, expected_discount):
134
+ assert compute_discount(segment) == expected_discount
135
+ ```
136
+
137
+ Keep fixture CSVs under ~50 rows. Anything larger belongs in a `data/` directory and should be generated or downloaded, not committed.
138
+
139
+ When a test genuinely needs a larger or procedurally generated DataFrame, build it deterministically with a seeded RNG inside a fixture — never inline, and never with the global `np.random` state:
140
+
141
+ ```python
142
+ @pytest.fixture
143
+ def synthetic_transactions() -> pd.DataFrame:
144
+ rng = np.random.default_rng(seed=42)
145
+ n = 1000
146
+ return pd.DataFrame({
147
+ "user_id": rng.integers(0, 100, size=n),
148
+ "amount": rng.lognormal(mean=3.0, sigma=1.0, size=n),
149
+ "ts": pd.date_range("2024-01-01", periods=n, freq="1h"),
150
+ })
151
+ ```
152
+
153
+ A fixed seed means the same test always sees the same data, so flaky-failure postmortems are possible instead of "must have been a weird random sample."
154
+
155
+ ### Running the suite
156
+
157
+ Layout and commands stay boring on purpose:
158
+
159
+ ```
160
+ tests/
161
+ conftest.py # shared fixtures
162
+ fixtures/ # small committed CSVs
163
+ customers_small.csv
164
+ customers_empty.csv
165
+ test_features.py # pytest for src/features.py
166
+ test_ingest.py # pandera + ingest tests
167
+ test_metrics.py # pytest for src/metrics.py
168
+ ```
169
+
170
+ Wire `pytest` into `pyproject.toml` so `pytest` alone runs the right suite:
171
+
172
+ ```toml
173
+ [tool.pytest.ini_options]
174
+ testpaths = ["tests"]
175
+ addopts = "-q --strict-markers -m 'not slow'"
176
+ markers = ["slow: tests that load non-trivial data"]
177
+ ```
178
+
179
+ Run the fast suite on every save (a file-watcher like `pytest-watch` helps), and run `pytest -m slow` or `pytest` with no marker filter before each commit. In CI, run the full suite unconditionally.
180
+
181
+ ### What NOT to test
182
+
183
+ Don't unit-test `pandas`, `numpy`, or `pandera` themselves — assume upstream libraries work and pin versions in `pyproject.toml` to catch surprises via dependency bumps, not your own test suite. Don't assert on model quality metrics here (AUC, precision, calibration); those live in `data-science-model-evaluation.md` and run on held-out data, not fixtures. Don't write tests that require a live database, S3 bucket, or trained model file — those belong in integration tests run out-of-band, not the fast `pytest` suite a developer runs on save. And don't test notebooks directly; if a notebook cell has logic worth testing, extract it to `src/` first, then test the function.
@@ -0,0 +1,10 @@
1
+ # `ml/` knowledge
2
+
3
+ Production machine-learning domain knowledge injected into universal pipeline
4
+ steps by `content/methodology/ml-overlay.yml`.
5
+
6
+ ## Lockstep pairs with `data-science/`
7
+
8
+ Five documents here mirror documents in `content/knowledge/data-science/`. See
9
+ `content/knowledge/data-science/README.md` for the full pair table. Edits to
10
+ one side should trigger review of the other to prevent recommendation drift.
@@ -0,0 +1,39 @@
1
+ # methodology/data-science-overlay.yml
2
+ name: data-science
3
+ description: >
4
+ Data science overlay — injects solo / small-team data science domain
5
+ knowledge into existing pipeline steps for local-first, reproducibility-first
6
+ analytical work and model prototyping.
7
+ project-type: data-science
8
+
9
+ knowledge-overrides:
10
+ # Foundational
11
+ create-prd: { append: [data-science-requirements] }
12
+ user-stories: { append: [data-science-requirements] }
13
+ coding-standards: { append: [data-science-conventions, data-science-notebook-discipline] }
14
+ project-structure: { append: [data-science-project-structure] }
15
+ dev-env-setup: { append: [data-science-dev-environment] }
16
+ git-workflow: { append: [data-science-reproducibility] }
17
+
18
+ # Architecture & Design
19
+ system-architecture: { append: [data-science-architecture] }
20
+ tech-stack: { append: [data-science-architecture, data-science-dev-environment] }
21
+ adrs: { append: [data-science-architecture] }
22
+ domain-modeling: { append: [data-science-data-versioning] }
23
+ database-schema: { append: [data-science-data-versioning] }
24
+ security: { append: [data-science-security] }
25
+ operations: { append: [data-science-experiment-tracking, data-science-observability, data-science-reproducibility] }
26
+
27
+ # Testing
28
+ tdd: { append: [data-science-testing] }
29
+ create-evals: { append: [data-science-testing, data-science-model-evaluation] }
30
+
31
+ # Reviews
32
+ review-architecture: { append: [data-science-architecture] }
33
+ review-database: { append: [data-science-data-versioning] }
34
+ review-security: { append: [data-science-security] }
35
+ review-operations: { append: [data-science-experiment-tracking, data-science-observability] }
36
+ review-testing: { append: [data-science-testing, data-science-model-evaluation] }
37
+
38
+ # Planning
39
+ implementation-plan: { append: [data-science-architecture] }
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AA4B1C,UAAU,aAAa;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAkCD,QAAA,MAAM,gBAAgB,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,CAyL3E,CAAA;AAED,eAAe,gBAAgB,CAAA"}
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAgC1C,UAAU,aAAa;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAkCD,QAAA,MAAM,gBAAgB,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,CAkO3E,CAAA;AAED,eAAe,gBAAgB,CAAA"}
@@ -17,6 +17,9 @@ import { ensureV3Migration } from '../../state/ensure-v3-migration.js';
17
17
  import { generateDashboardData, generateHtml, generateMultiServiceDashboardData, generateMultiServiceHtml, } from '../../dashboard/generator.js';
18
18
  import { discoverMetaPrompts } from '../../core/assembly/meta-prompt-loader.js';
19
19
  import { getPackagePipelineDir, atomicWriteFile } from '../../utils/fs.js';
20
+ import { loadPipelineContext } from '../../core/pipeline/context.js';
21
+ import { resolvePipeline } from '../../core/pipeline/resolver.js';
22
+ import { buildDependencyGraph } from '../../dashboard/dependency-graph.js';
20
23
  /**
21
24
  * Write HTML to the requested path (or a tmpfile), then optionally open it in
22
25
  * the system browser. Shared between single-service and multi-service modes.
@@ -92,12 +95,40 @@ const dashboardCommand = {
92
95
  if (isMultiServiceMode) {
93
96
  // Load meta-prompts ONCE and share across all services.
94
97
  const metaPrompts = discoverMetaPrompts(getPackagePipelineDir(projectRoot));
98
+ // NEW: load pipeline context once (shared across all services). Default
99
+ // includeTools: false — tool meta-prompts aren't pipeline participants;
100
+ // their crossReads would leak into overlay.crossReads and into the graph.
101
+ const pipelineContext = loadPipelineContext(projectRoot);
102
+ // NEW: per-service overlay map populated alongside loadedServices below.
103
+ const perServiceOverlay = new Map();
104
+ let capturedGlobalSteps;
95
105
  // Methodology resolution: prefer config.methodology.preset; else fall back to
96
106
  // the first loaded service state's config_methodology; else 'unknown'.
97
107
  const configMethodology = config?.methodology?.preset;
98
108
  const loadedServices = [];
99
109
  let fallbackStateMethodology;
100
110
  for (const svc of configuredServices) {
111
+ // NEW: resolve pipeline per service to capture overlay + globalSteps.
112
+ // Wrap in try/catch mirroring loadState's STATE_MISSING fallback — a
113
+ // malformed overlay for one service must not crash the multi-service
114
+ // dashboard. On failure, warn + skip this service's outgoing graph
115
+ // contribution; the service's card still renders because the
116
+ // loadState block below has its own fallback. Incoming edges FROM
117
+ // other services INTO this service are still rendered — only this
118
+ // service's OWN outgoing declarations are lost.
119
+ try {
120
+ const svcPipeline = resolvePipeline(pipelineContext, { output, serviceId: svc.name });
121
+ perServiceOverlay.set(svc.name, svcPipeline.overlay);
122
+ if (!capturedGlobalSteps)
123
+ capturedGlobalSteps = svcPipeline.globalSteps;
124
+ }
125
+ catch (err) {
126
+ output.warn(`Could not resolve pipeline for service '${svc.name}' — `
127
+ + 'outgoing graph edges from this service omitted '
128
+ + '(incoming edges from other services are still rendered) '
129
+ + `(${err.message})`);
130
+ }
131
+ // Existing state-loading block (unchanged from HEAD):
101
132
  const svcResolver = new StatePathResolver(projectRoot, svc.name);
102
133
  const svcStateManager = new StateManager(projectRoot, () => [], () => config ?? undefined, svcResolver, new Set(), undefined);
103
134
  let svcState;
@@ -138,9 +169,18 @@ const dashboardCommand = {
138
169
  });
139
170
  }
140
171
  const methodology = configMethodology ?? fallbackStateMethodology ?? 'unknown';
172
+ // NEW: build the dependency graph (returns null if no edges after filtering).
173
+ const dependencyGraph = buildDependencyGraph({
174
+ config: config,
175
+ projectRoot,
176
+ services: configuredServices.map(s => ({ name: s.name, projectType: s.projectType })),
177
+ perServiceOverlay,
178
+ globalSteps: capturedGlobalSteps,
179
+ });
141
180
  const dashboardData = generateMultiServiceDashboardData({
142
181
  services: loadedServices,
143
182
  methodology,
183
+ dependencyGraph, // NEW — threaded into generator
144
184
  });
145
185
  if (argv['json-only']) {
146
186
  output.result(dashboardData);
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../../src/cli/commands/dashboard.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,uBAAuB,CAAwB,CAAA;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,EACL,qBAAqB,EACrB,YAAY,EACZ,iCAAiC,EACjC,wBAAwB,GACzB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAA;AAC/E,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAiB1E;;;;GAIG;AACH,SAAS,qBAAqB,CAC5B,IAAY,EACZ,IAAmB,EACnB,MAA0C;IAE1C,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,sBAAsB,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAEjG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC3D,eAAe,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;IAEjC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACrB,IAAI,MAAM,GAAG,UAAU,CAAA;QACvB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAAE,MAAM,GAAG,MAAM,CAAA;QAClD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;YAAE,MAAM,GAAG,OAAO,CAAA;QAClD,IAAI,CAAC;YACH,YAAY,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,qCAAqC;QACvC,CAAC;IACH,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAA;IACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,MAAM,gBAAgB,GAA0D;IAC9E,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,oCAAoC;IAC9C,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QACjB,OAAO,KAAK;aACT,MAAM,CAAC,QAAQ,EAAE;YAChB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,2BAA2B;SACzC,CAAC;aACD,MAAM,CAAC,SAAS,EAAE;YACjB,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,yBAAyB;YACtC,OAAO,EAAE,KAAK;SACf,CAAC;aACD,MAAM,CAAC,WAAW,EAAE;YACnB,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,+BAA+B;YAC5C,OAAO,EAAE,KAAK;SACf,CAAC;aACD,MAAM,CAAC,SAAS,EAAE;YACjB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,8CAA8C;SACzD,CAAC,CAAA;IACN,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtB,0BAA0B;QAC1B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,IAAI,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;QAC/D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oEAAoE;gBACpE,sDAAsD,CACvD,CAAA;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACf,OAAM;QACR,CAAC;QAED,4CAA4C;QAC5C,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAA;QAC1C,MAAM,MAAM,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAA;QAE9C,sEAAsE;QACtE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,OAA6B,CAAA;QAClD,iBAAiB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QACtC,oBAAoB,CAAC,MAAM,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAA;QACjF,IAAI,OAAO,CAAC,QAAQ,KAAK,CAAC;YAAE,OAAM;QAElC,mEAAmE;QACnE,8DAA8D;QAC9D,MAAM,kBAAkB,GAAG,MAAM,EAAE,OAAO,EAAE,QAAuC,CAAA;QACnF,MAAM,kBAAkB,GACtB,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAA;QAEhF,IAAI,kBAAkB,EAAE,CAAC;YACvB,wDAAwD;YACxD,MAAM,WAAW,GAAG,mBAAmB,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAA;YAE3E,8EAA8E;YAC9E,uEAAuE;YACvE,MAAM,iBAAiB,GAAI,MAAgC,EAAE,WAAW,EAAE,MAAM,CAAA;YAEhF,MAAM,cAAc,GAKf,EAAE,CAAA;YAEP,IAAI,wBAA4C,CAAA;YAChD,KAAK,MAAM,GAAG,IAAI,kBAAmB,EAAE,CAAC;gBACtC,MAAM,WAAW,GAAG,IAAI,iBAAiB,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;gBAChE,MAAM,eAAe,GAAG,IAAI,YAAY,CACtC,WAAW,EACX,GAAG,EAAE,CAAC,EAAE,EACR,GAAG,EAAE,CAAC,MAAM,IAAI,SAAS,EACzB,WAAW,EACX,IAAI,GAAG,EAAU,EACjB,SAAS,CACV,CAAA;gBACD,IAAI,QAAuB,CAAA;gBAC3B,IAAI,CAAC;oBACH,QAAQ,GAAG,eAAe,CAAC,SAAS,EAAE,CAAA;oBACtC,IAAI,CAAC,wBAAwB,EAAE,CAAC;wBAC9B,wBAAwB,GAAG,QAAQ,CAAC,kBAAkB,CAAA;oBACxD,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,qEAAqE;oBACrE,qEAAqE;oBACrE,8DAA8D;oBAC9D,gEAAgE;oBAChE,MAAM,IAAI,GAAI,GAAqC,EAAE,IAAI,CAAA;oBACzD,IAAI,IAAI,KAAK,eAAe;wBAAE,MAAM,GAAG,CAAA;oBACvC,oEAAoE;oBACpE,wDAAwD;oBACxD,QAAQ,GAAG;wBACT,gBAAgB,EAAE,CAAC;wBACnB,kBAAkB,EAAE,GAAG,CAAC,OAAO;wBAC/B,gBAAgB,EAAE,iBAAiB,IAAI,SAAS;wBAChD,kBAAkB,EAAE,iBAAiB,IAAI,SAAS;wBAClD,WAAW,EAAE,YAAY;wBACzB,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wBACjC,WAAW,EAAE,IAAI;wBACjB,KAAK,EAAE,EAAE;wBACT,aAAa,EAAE,EAAE;wBACjB,aAAa,EAAE,EAAE;qBACD,CAAA;gBACpB,CAAC;gBACD,cAAc,CAAC,IAAI,CAAC;oBAClB,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,WAAW,EAAE,GAAG,CAAC,WAAW;oBAC5B,KAAK,EAAE,QAAQ;oBACf,WAAW;iBACZ,CAAC,CAAA;YACJ,CAAC;YAED,MAAM,WAAW,GAAG,iBAAiB,IAAI,wBAAwB,IAAI,SAAS,CAAA;YAE9E,MAAM,aAAa,GAAG,iCAAiC,CAAC;gBACtD,QAAQ,EAAE,cAAc;gBACxB,WAAW;aACZ,CAAC,CAAA;YAEF,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBACtB,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;gBAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACf,OAAM;YACR,CAAC;YAED,MAAM,IAAI,GAAG,wBAAwB,CAAC,aAAa,CAAC,CAAA;YACpD,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;YACzC,OAAM;QACR,CAAC;QAED,gDAAgD;QAChD,MAAM,YAAY,GAAG,IAAI,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QAChE,MAAM,YAAY,GAAG,IAAI,YAAY,CACnC,WAAW,EACX,GAAG,EAAE,CAAC,EAAE,EACR,GAAG,EAAE,CAAC,MAAM,IAAI,SAAS,EACzB,YAAY;QACZ,kFAAkF;QAClF,gFAAgF;QAChF,gFAAgF;QAChF,6EAA6E;QAC7E,IAAI,GAAG,EAAU,EACjB,SAAS,CACV,CAAA;QACD,IAAI,KAAoB,CAAA;QACxB,IAAI,CAAC;YACH,KAAK,GAAG,YAAY,CAAC,SAAS,EAAE,CAAA;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,KAAK,CAAC;gBACX,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,qBAAqB;gBAC9B,QAAQ,EAAE,CAAC;gBACX,QAAQ,EAAE,mBAAmB;aAC9B,CAAC,CAAA;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACf,OAAM;QACR,CAAC;QAED,oBAAoB;QACpB,MAAM,SAAS,GAAG,aAAa,CAAC,WAAW,EAAE,EAAE,EAAE,YAAY,CAAC,CAAA;QAC9D,MAAM,WAAW,GACd,MAAgC,EAAE,WAAW,EAAE,MAAM;YACtD,KAAK,CAAC,kBAAkB;YACxB,SAAS,CAAA;QAEX,8CAA8C;QAC9C,MAAM,WAAW,GAAG,mBAAmB,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAA;QAE3E,6BAA6B;QAC7B,MAAM,aAAa,GAAG,qBAAqB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAA;QAE3F,2CAA2C;QAC3C,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;YAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACf,OAAM;QACR,CAAC;QAED,kCAAkC;QAClC,MAAM,IAAI,GAAG,YAAY,CAAC,aAAa,CAAC,CAAA;QACxC,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;IAC3C,CAAC;CACF,CAAA;AAED,eAAe,gBAAgB,CAAA"}
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../../src/cli/commands/dashboard.ts"],"names":[],"mappings":"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"}