workspai 0.46.0 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +225 -81
- package/contracts/agent-customization-pack.v1.json +11 -1
- package/contracts/bootstrap-compliance.v1.json +14 -0
- package/contracts/cli-runtime-command-inventory.v1.snapshot.json +4 -0
- package/contracts/extension-cli-compatibility.v1.json +13 -2
- package/contracts/mirror-ops.v1.json +16 -0
- package/contracts/published-contract-catalog.v1.json +59 -1
- package/contracts/runtime-command-surface.v1.json +294 -2
- package/contracts/transparency-evidence.v1.json +13 -0
- package/contracts/workspace-contract.v1.json +78 -0
- package/contracts/workspace-intelligence/model-usage-event.v1.json +82 -0
- package/contracts/workspace-intelligence/workspace-context.v1.json +20 -0
- package/contracts/workspace-intelligence/workspace-graph-token-efficiency.v1.json +72 -0
- package/contracts/workspace-intelligence/workspace-intelligence-evaluation-comparison.v1.json +53 -0
- package/contracts/workspace-intelligence/workspace-intelligence-evaluation.v1.json +120 -0
- package/contracts/workspace-intelligence/workspace-intelligence-run.v1.json +6 -1
- package/contracts/workspace-intelligence/workspace-knowledge-graph-change-overlay.v1.json +200 -0
- package/contracts/workspace-intelligence/workspace-knowledge-graph.v1.json +260 -0
- package/contracts/workspace-intelligence/workspace-knowledge-search.v1.json +60 -0
- package/contracts/workspace-intelligence-architecture.v1.json +37 -5
- package/contracts/workspace-intelligence-chain.v1.json +58 -6
- package/contracts/workspace-share-bundle.v1.json +16 -0
- package/dist/analyze-EEEU3MIF.js +1 -0
- package/dist/artifact-remediation-plan-SPOUHMK5.js +3 -0
- package/dist/autopilot-release-XGVXPOZI.js +1 -0
- package/dist/chunk-32OJDBIG.js +2 -0
- package/dist/chunk-37CVKXBD.js +1 -0
- package/dist/chunk-3NU32T4A.js +2 -0
- package/dist/chunk-3VFA7D5T.js +1 -0
- package/dist/chunk-4HDYADHT.js +13 -0
- package/dist/chunk-54EP5CEV.js +8 -0
- package/dist/chunk-5S3DJQEP.js +8 -0
- package/dist/chunk-AFL3ACCR.js +2 -0
- package/dist/{chunk-VFDM65IE.js → chunk-BFLJ2R4D.js} +22 -22
- package/dist/chunk-BGPXQQNY.js +4 -0
- package/dist/chunk-BMWFQXGW.js +1 -0
- package/dist/{chunk-UQWOVV6V.js → chunk-CRHYBQI3.js} +1 -1
- package/dist/chunk-CV5HKU4P.js +1 -0
- package/dist/chunk-ESLPI3XZ.js +1 -0
- package/dist/chunk-FB7SCXAZ.js +1 -0
- package/dist/{chunk-WPEEC5BX.js → chunk-HDXNIN4N.js} +1 -1
- package/dist/chunk-HZDXO65G.js +36 -0
- package/dist/{chunk-J5PIZCAU.js → chunk-I46XEIPL.js} +1 -1
- package/dist/chunk-J5ENLXDF.js +1 -0
- package/dist/chunk-KB44JP4M.js +2 -0
- package/dist/chunk-LHOZXC2M.js +2 -0
- package/dist/chunk-NAJCUQ4X.js +2 -0
- package/dist/chunk-OA537ZQ5.js +1 -0
- package/dist/chunk-OW42TZFB.js +1 -0
- package/dist/chunk-P3D5YQB2.js +1 -0
- package/dist/chunk-PHXQR6PX.js +2 -0
- package/dist/{chunk-ZKAI3PJE.js → chunk-PRTR2DQ2.js} +1 -1
- package/dist/{chunk-QA5BGEQW.js → chunk-QNONOO4F.js} +1 -1
- package/dist/chunk-RHQW3DTP.js +1 -0
- package/dist/chunk-T4YR4RAI.js +2 -0
- package/dist/chunk-THIOE2PB.js +2 -0
- package/dist/{chunk-4LGXSBCN.js → chunk-VU7NZHPM.js} +1 -1
- package/dist/chunk-WDKNMTJQ.js +1 -0
- package/dist/{chunk-YUATNVOT.js → chunk-Y5UJLPS4.js} +16 -16
- package/dist/{chunk-6IIZJQLV.js → chunk-YJZOMRAS.js} +1 -1
- package/dist/{create-WCV3L6XH.js → create-DBQNAMKP.js} +1 -1
- package/dist/{doctor-5BWM2EMJ.js → doctor-4NNUDNGZ.js} +1 -1
- package/dist/{dotnet-webapi-clean-6TVFBTVI.js → dotnet-webapi-clean-A6MVDYXX.js} +4 -4
- package/dist/{gofiber-standard-2BL7GWZB.js → gofiber-standard-I5YPQG5V.js} +1 -1
- package/dist/{gogin-standard-XGP3KBXA.js → gogin-standard-VY2L4QT5.js} +1 -1
- package/dist/index.d.ts +56 -14
- package/dist/index.js +322 -320
- package/dist/pipeline-TQM43A3K.js +5 -0
- package/dist/{springboot-standard-JJNUID6M.js → springboot-standard-55XKCBIZ.js} +4 -4
- package/dist/{workspace-7OXW5YTJ.js → workspace-NCWRINEF.js} +1 -1
- package/dist/{workspace-agent-sync-O4IA6VOA.js → workspace-agent-sync-662QHXGF.js} +1 -1
- package/dist/{workspace-archive-H74NBBNW.js → workspace-archive-P76EDIUG.js} +1 -1
- package/dist/{workspace-context-R7IPUBPG.js → workspace-context-23YYCUCP.js} +1 -1
- package/dist/workspace-contract-TU2I7GC2.js +1 -0
- package/dist/workspace-dependency-graph-BP4EXYQ5.js +1 -0
- package/dist/workspace-explain-MWUEN643.js +1 -0
- package/dist/workspace-explain-contract-ZPI3JXJU.js +1 -0
- package/dist/{workspace-feedback-REOS36ZZ.js → workspace-feedback-SUVH2LUJ.js} +1 -1
- package/dist/{workspace-foundation-KXT4QI5O.js → workspace-foundation-WXJ6I7ES.js} +1 -1
- package/dist/workspace-graph-token-efficiency-CFGFCJ5V.js +1 -0
- package/dist/{workspace-history-OGOVSKZG.js → workspace-history-BANOJRQ2.js} +1 -1
- package/dist/workspace-intelligence-MFJE7W67.js +1 -0
- package/dist/workspace-intelligence-evaluation-IPH7M3WV.js +1 -0
- package/dist/workspace-intelligence-runner-THYLHHMF.js +1 -0
- package/dist/workspace-knowledge-graph-ARDC6HHG.js +1 -0
- package/dist/workspace-knowledge-graph-change-overlay-XG6FC4IX.js +1 -0
- package/dist/workspace-knowledge-graph-export-UYAYFTWX.js +10 -0
- package/dist/workspace-knowledge-graph-query-VOSPPH4W.js +1 -0
- package/dist/workspace-mcp-serve-EZR6O76D.js +3 -0
- package/dist/workspace-model-7OU2M3LE.js +1 -0
- package/dist/workspace-model-hash-MHXK5MEI.js +1 -0
- package/dist/{workspace-registry-summary-SZ46R5PD.js → workspace-registry-summary-ORDK7A36.js} +1 -1
- package/dist/workspace-run-RLIYSOTN.js +1 -0
- package/dist/{workspace-verify-MFQ7IXGD.js → workspace-verify-EBVL7FWT.js} +1 -1
- package/dist/workspace-watch-3BPGLFLB.js +1 -0
- package/docs/AI_DYNAMIC_INTEGRATION.md +73 -428
- package/docs/AI_EXAMPLES.md +37 -395
- package/docs/AI_FEATURES.md +76 -456
- package/docs/AI_QUICKSTART.md +49 -212
- package/docs/GLOSSARY.md +64 -0
- package/docs/OPEN_SOURCE_USER_SCENARIOS.md +68 -7
- package/docs/README.md +70 -41
- package/docs/README_CONTENT_CONTRACT.md +154 -0
- package/docs/commands-reference.md +64 -4
- package/docs/config-file-guide.md +6 -2
- package/docs/contracts/ARTIFACT_CATALOG.md +76 -37
- package/docs/contracts/README.md +47 -8
- package/docs/graph-benchmark-methodology.md +121 -0
- package/docs/workspace-intelligence-evaluation.md +147 -0
- package/docs/workspace-knowledge-graph.md +316 -0
- package/docs/workspace-operations.md +49 -0
- package/package.json +2 -1
- package/dist/analyze-BEBEZSZK.js +0 -1
- package/dist/artifact-remediation-plan-FFQSESAM.js +0 -3
- package/dist/autopilot-release-WUR4CQIT.js +0 -1
- package/dist/chunk-2G7FASAO.js +0 -2
- package/dist/chunk-4EPHWD27.js +0 -8
- package/dist/chunk-CVHMUSRX.js +0 -1
- package/dist/chunk-DIPD72H4.js +0 -2
- package/dist/chunk-EFYHGCGX.js +0 -2
- package/dist/chunk-FWRXA435.js +0 -2
- package/dist/chunk-HDURFXW5.js +0 -2
- package/dist/chunk-HMUKBW2S.js +0 -4
- package/dist/chunk-K4WNYXKK.js +0 -33
- package/dist/chunk-LG6RFLPZ.js +0 -1
- package/dist/chunk-N7DV5L7C.js +0 -1
- package/dist/chunk-PRBVYW3T.js +0 -1
- package/dist/chunk-QZLIURER.js +0 -13
- package/dist/chunk-RIEF2DDX.js +0 -8
- package/dist/chunk-SXMTSV5M.js +0 -1
- package/dist/chunk-SXPY523X.js +0 -1
- package/dist/chunk-V3LRQZ36.js +0 -1
- package/dist/chunk-WYFPXTTS.js +0 -2
- package/dist/pipeline-ORIWVVYM.js +0 -5
- package/dist/workspace-contract-HKCMOMFE.js +0 -1
- package/dist/workspace-explain-GOPQYTPQ.js +0 -1
- package/dist/workspace-explain-contract-SVFJAAEI.js +0 -1
- package/dist/workspace-intelligence-7IESQSXY.js +0 -1
- package/dist/workspace-intelligence-runner-6GJ5M4HB.js +0 -1
- package/dist/workspace-mcp-serve-FRVWBO36.js +0 -3
- package/dist/workspace-model-PPYX7B4S.js +0 -1
- package/dist/workspace-run-V3KKHTVF.js +0 -1
- package/dist/workspace-watch-SOPZHRWA.js +0 -1
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# Workspace Knowledge Graph
|
|
2
|
+
|
|
3
|
+
Most code graphs answer questions about one repository. Workspai connects code,
|
|
4
|
+
APIs, infrastructure, delivery, documentation, ownership, tests, and runtime
|
|
5
|
+
configuration across a whole workspace—and records why every relationship is
|
|
6
|
+
believed.
|
|
7
|
+
|
|
8
|
+
The graph is local-first and deterministic. Building it does not require an
|
|
9
|
+
LLM, a hosted service, embeddings, or a graph database.
|
|
10
|
+
|
|
11
|
+
## Why this is useful
|
|
12
|
+
|
|
13
|
+
A repository graph can tell you that function A calls function B. A workspace
|
|
14
|
+
question is usually wider:
|
|
15
|
+
|
|
16
|
+
> If we change this endpoint, which project consumes it, which deployment ships
|
|
17
|
+
> it, which tests cover it, which document describes it, and which release gate
|
|
18
|
+
> can stop it?
|
|
19
|
+
|
|
20
|
+
Workspai keeps those domains in one proof-carrying representation. The graph is
|
|
21
|
+
not the final product screen; it is the shared knowledge layer behind impact,
|
|
22
|
+
verification, context, MCP, IDE, CI, and agent workflows.
|
|
23
|
+
|
|
24
|
+
| If you are… | The graph helps you… |
|
|
25
|
+
| -------------------- | ------------------------------------------------------------------------------------------ |
|
|
26
|
+
| A developer | find the implementation, nearby dependencies, tests, and evidence without repo-wide search |
|
|
27
|
+
| A tech lead | inspect cross-project boundaries, owners, contracts, and change paths |
|
|
28
|
+
| An AI coding agent | retrieve question-sized context and verify every returned claim |
|
|
29
|
+
| A CI/release system | consume versioned JSON, source hashes, quality diagnostics, and deterministic exits |
|
|
30
|
+
| An IDE or MCP client | offer the same system understanding without rebuilding a private index |
|
|
31
|
+
|
|
32
|
+
## What makes it a workspace graph
|
|
33
|
+
|
|
34
|
+
Workspai does not stop at files, imports, functions, and classes. Repository
|
|
35
|
+
structure is one provider domain alongside APIs, containers, infrastructure,
|
|
36
|
+
pipelines, documents, decisions, ownership, tests, environments, and authored
|
|
37
|
+
workspace contracts.
|
|
38
|
+
|
|
39
|
+
That distinction matters when the answer crosses repositories. The canonical
|
|
40
|
+
Workspace Model remains the source of truth; the Knowledge Graph is its rich,
|
|
41
|
+
queryable, evidence-backed representation. AI is a consumer, never a requirement
|
|
42
|
+
for building the graph.
|
|
43
|
+
|
|
44
|
+
## Try it in two minutes
|
|
45
|
+
|
|
46
|
+
Run from a Workspai workspace:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx workspai workspace model --write --json
|
|
50
|
+
npx workspai workspace graph search "authentication endpoint" --limit 12 --json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Useful follow-up questions:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# What APIs and endpoints exist?
|
|
57
|
+
npx workspai workspace graph entities endpoint --json
|
|
58
|
+
|
|
59
|
+
# Why does Workspai believe this entity exists?
|
|
60
|
+
npx workspai workspace graph evidence "GET /users" --json
|
|
61
|
+
|
|
62
|
+
# How are two services, files, or APIs connected?
|
|
63
|
+
npx workspai workspace graph path frontend-api "GET /users" --json
|
|
64
|
+
|
|
65
|
+
# What changed since a saved graph revision?
|
|
66
|
+
npx workspai workspace graph overlay --from previous-graph.json --json
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
For agents and MCP clients, prefer bounded search over loading the complete
|
|
70
|
+
graph:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npx workspai workspace graph search "billing database" --limit 12 --json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
A simplified response looks like this:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"schemaVersion": "workspace-knowledge-search.v1",
|
|
81
|
+
"query": "billing database",
|
|
82
|
+
"totalMatches": 23,
|
|
83
|
+
"truncated": true,
|
|
84
|
+
"entities": [{ "kind": "database", "label": "billing-db", "proofIds": ["proof:..."] }],
|
|
85
|
+
"relations": [{ "kind": "reads-from", "from": "service:billing", "to": "database:billing-db" }],
|
|
86
|
+
"proofs": [{ "provider": "compose", "artifact": "infra/compose.yml", "trust": "authoritative" }]
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The response is intentionally bounded. `totalMatches` tells the consumer more
|
|
91
|
+
results exist, `truncated` prevents silent omission, and every returned claim can
|
|
92
|
+
be traced through `proofIds`.
|
|
93
|
+
|
|
94
|
+
## Pick the command by question
|
|
95
|
+
|
|
96
|
+
| You want to know… | Use |
|
|
97
|
+
| ---------------------------------------------------- | ------------------------------------------------------- |
|
|
98
|
+
| What is relevant to a natural-language question? | `workspace graph search <query> --limit <n> --json` |
|
|
99
|
+
| Which entities of one type exist? | `workspace graph entities <kind> --json` |
|
|
100
|
+
| Why does Workspai believe an item exists? | `workspace graph evidence <entity-or-relation> --json` |
|
|
101
|
+
| How are two things connected? | `workspace graph path <from> <to> --json` |
|
|
102
|
+
| What changed between graph revisions? | `workspace graph overlay --from <graph.json> --json` |
|
|
103
|
+
| What is the full portable graph? | `workspace graph emit --json` |
|
|
104
|
+
| How do I export to semantic or graph-analysis tools? | `workspace graph jsonld\|graphml\|gexf --output <file>` |
|
|
105
|
+
| How much retrieval payload did one query avoid? | `workspace graph benchmark <query> --limit <n> --json` |
|
|
106
|
+
| How should an MCP-compatible agent retrieve context? | `workspace mcp serve` → `searchWorkspaceGraph` |
|
|
107
|
+
|
|
108
|
+
## What it models
|
|
109
|
+
|
|
110
|
+
The current graph can represent:
|
|
111
|
+
|
|
112
|
+
- workspaces, projects, services, packages, modules, files, and symbols;
|
|
113
|
+
- APIs, endpoints, schemas, events, queues, and databases;
|
|
114
|
+
- containers, deployments, environments, pipelines, and infrastructure;
|
|
115
|
+
- documentation, architecture decisions, tests, and owners.
|
|
116
|
+
|
|
117
|
+
Relations include `contains`, `imports`, `depends-on`, `calls`, `exposes`,
|
|
118
|
+
`implements`, `reads-from`, `writes-to`, `publishes`, `consumes`, `deploys`,
|
|
119
|
+
`documents`, `decided-by`, `tests`, and `owns`.
|
|
120
|
+
|
|
121
|
+
Every entity and relation carries portable proof references. A proof records its
|
|
122
|
+
provider, source artifact, optional pointer/line, content hash, freshness,
|
|
123
|
+
derivation, trust, and confidence. Secret values and machine-local absolute
|
|
124
|
+
paths are excluded from the portable graph contract.
|
|
125
|
+
|
|
126
|
+
## Model first, graph second
|
|
127
|
+
|
|
128
|
+
The canonical direction is one-way:
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
Workspace sources
|
|
132
|
+
↓
|
|
133
|
+
Canonical Workspace Model + project topology
|
|
134
|
+
↓
|
|
135
|
+
Evidence-backed Workspace Knowledge Graph
|
|
136
|
+
↓
|
|
137
|
+
CLI queries · Context · MCP · Agents · IDEs · CI
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The graph does not rewrite or replace the canonical Workspace Model. It is a
|
|
141
|
+
derived representation bound to an exact model revision by SHA-256. Context and
|
|
142
|
+
MCP consumers reject a graph whose source hash no longer matches the model.
|
|
143
|
+
|
|
144
|
+
The model also contains a smaller project dependency graph. That projection is
|
|
145
|
+
used for impact, blast radius, verify, explain, watch, and affected fleet runs.
|
|
146
|
+
The richer Knowledge Graph is used for proof-backed retrieval and cross-domain
|
|
147
|
+
understanding.
|
|
148
|
+
|
|
149
|
+
## Sources and providers
|
|
150
|
+
|
|
151
|
+
The current CLI uses bounded providers for:
|
|
152
|
+
|
|
153
|
+
- workspace/project foundations and service contracts;
|
|
154
|
+
- language-neutral source structure and package manifests;
|
|
155
|
+
- OpenAPI, GraphQL, Protobuf, and AsyncAPI interfaces;
|
|
156
|
+
- Docker/Compose, Kubernetes, Terraform, and CI workflows;
|
|
157
|
+
- README/docs, ADRs, tests, and CODEOWNERS.
|
|
158
|
+
|
|
159
|
+
Providers emit facts and proofs. The graph engine owns stable identity,
|
|
160
|
+
deduplication, typed relations, reconciliation, quality metrics, diagnostics,
|
|
161
|
+
and deterministic ordering. Regex-backed source observations are explicitly
|
|
162
|
+
marked as observed/medium-confidence; authored contracts remain authoritative.
|
|
163
|
+
|
|
164
|
+
## Outputs and consumers
|
|
165
|
+
|
|
166
|
+
`workspace model --write` publishes these two artifacts atomically:
|
|
167
|
+
|
|
168
|
+
```text
|
|
169
|
+
.workspai/reports/workspace-model.json
|
|
170
|
+
.workspai/reports/workspace-knowledge-graph.json
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The Knowledge Graph is consumed by:
|
|
174
|
+
|
|
175
|
+
- `workspace graph search|entities|evidence|path|overlay`;
|
|
176
|
+
- `workspace context`, which validates the model hash and publishes graph
|
|
177
|
+
availability and query commands;
|
|
178
|
+
- `workspace agent-sync`, which places it in the evidence index and generated
|
|
179
|
+
agent/MCP instructions;
|
|
180
|
+
- `workspace mcp serve`, through `getWorkspaceKnowledgeGraph`,
|
|
181
|
+
`searchWorkspaceGraph`, `queryWorkspaceEntities`,
|
|
182
|
+
`getWorkspaceGraphEvidence`, and `findWorkspaceGraphPath`;
|
|
183
|
+
- `workspace contract graph`, which exposes the contract projection, project
|
|
184
|
+
topology, rich graph, and quality summary in one response.
|
|
185
|
+
|
|
186
|
+
The complete graph is an interchange artifact, not a prompt. Agents should
|
|
187
|
+
start with `INDEX.json`, use bounded search, then retrieve evidence or a path
|
|
188
|
+
for the selected result.
|
|
189
|
+
|
|
190
|
+
### Interchange and visualization
|
|
191
|
+
|
|
192
|
+
The JSON artifact is the canonical interchange form of the derived graph; the
|
|
193
|
+
Workspace Model remains the system source of truth. Other formats are
|
|
194
|
+
deterministic projections of that same graph revision:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
npx workspai workspace graph mermaid
|
|
198
|
+
npx workspai workspace graph dot
|
|
199
|
+
npx workspai workspace graph jsonld --output workspace-graph.jsonld
|
|
200
|
+
npx workspai workspace graph graphml --output workspace-graph.graphml
|
|
201
|
+
npx workspai workspace graph gexf --output workspace-graph.gexf
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
- Mermaid and DOT are suited to documentation and architecture diagrams.
|
|
205
|
+
- JSON-LD carries semantic identities, relations, and proof references.
|
|
206
|
+
- GraphML and GEXF work with graph-analysis and interactive visualization tools.
|
|
207
|
+
- The canonical JSON, JSON-LD, GraphML, and GEXF outputs can drive 2D or 3D
|
|
208
|
+
viewers; a 3D view is a presentation layer, not a separate source of truth.
|
|
209
|
+
|
|
210
|
+
## AI tool output locations
|
|
211
|
+
|
|
212
|
+
`workspace agent-sync --write --preset enterprise` generates native surfaces
|
|
213
|
+
without changing project source:
|
|
214
|
+
|
|
215
|
+
| Consumer | Canonical output |
|
|
216
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
217
|
+
| Cross-tool/Codex | `AGENTS.md`, `.workspai/reports/INDEX.json` |
|
|
218
|
+
| Claude Code | `CLAUDE.md`, `.claude/rules/workspai-evidence.md` |
|
|
219
|
+
| GitHub Copilot/VS Code | `.github/copilot-instructions.md`, `.github/instructions/workspai-*.instructions.md`, `.github/agents/workspai-*.agent.md`, `.github/prompts/workspai-*.prompt.md` |
|
|
220
|
+
| Cursor | `.cursor/rules/workspai-grounding.mdc` |
|
|
221
|
+
| MCP clients | `.workspai/reports/workspai-mcp-design.json`, `workspace mcp serve` |
|
|
222
|
+
|
|
223
|
+
Files named `rapidkit-*` are compatibility aliases for older consumers. They
|
|
224
|
+
must stay narrowly scoped and must not duplicate an always-applied canonical
|
|
225
|
+
rule.
|
|
226
|
+
|
|
227
|
+
### Avoiding duplicate AI instructions
|
|
228
|
+
|
|
229
|
+
Canonical Workspai rules are the only always-applied surfaces. Legacy RapidKit
|
|
230
|
+
aliases point to the canonical files and apply only to `.rapidkit/**`. This
|
|
231
|
+
prevents two equivalent instruction files from being injected into one prompt.
|
|
232
|
+
|
|
233
|
+
The recommended read order is:
|
|
234
|
+
|
|
235
|
+
1. `AGENTS.md` for stable workspace policy and navigation;
|
|
236
|
+
2. `.workspai/reports/INDEX.json` for artifact discovery and freshness;
|
|
237
|
+
3. `workspace graph search` or `searchWorkspaceGraph` for question-sized facts;
|
|
238
|
+
4. `workspace graph evidence|path` when a claim needs proof;
|
|
239
|
+
5. the complete model or graph only for export, audit, or whole-system analysis.
|
|
240
|
+
|
|
241
|
+
## Performance and scale
|
|
242
|
+
|
|
243
|
+
Graph construction inventories each project once per build and caps the number
|
|
244
|
+
of scanned files. Providers reuse the same in-memory inventory and content
|
|
245
|
+
hashes. Query indexes are cached per immutable graph object; replacing the graph
|
|
246
|
+
is the invalidation boundary. `workspace model --cache` and `--incremental`
|
|
247
|
+
avoid unnecessary model/project work when inputs are unchanged.
|
|
248
|
+
|
|
249
|
+
Use full graph export for interchange or offline analysis. Use bounded search
|
|
250
|
+
for interactive agents. The latter keeps response size proportional to the
|
|
251
|
+
question instead of workspace size.
|
|
252
|
+
|
|
253
|
+
## Measuring retrieval payload reduction
|
|
254
|
+
|
|
255
|
+
Workspai does not publish an unqualified “N× fewer tokens” claim. Such a claim
|
|
256
|
+
depends on the workspace, query, tokenizer, model, answer-quality target, and
|
|
257
|
+
baseline.
|
|
258
|
+
|
|
259
|
+
Measure the current workspace instead:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
npx workspai workspace graph benchmark "authentication endpoint" --limit 12 --json
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
The report compares the readable, proof-indexed source corpus with the bounded
|
|
266
|
+
search payload using a clearly labelled `characters / 4` token estimate. It
|
|
267
|
+
reports corpus size, retrieval size, estimated ratio, percentage reduction,
|
|
268
|
+
unreadable artifacts, query, limit, graph counts, and the exact source-model
|
|
269
|
+
SHA-256 needed to reproduce the run.
|
|
270
|
+
|
|
271
|
+
This proves **retrieval payload reduction**, not equivalent answer quality,
|
|
272
|
+
model-specific billing savings, or universal token savings. A publishable
|
|
273
|
+
cross-project claim additionally requires pinned source revisions, fixed
|
|
274
|
+
queries, a real tokenizer, repeated runs, and answer-quality evaluation.
|
|
275
|
+
|
|
276
|
+
In the current 16-project development fixture, the query `api endpoint` with
|
|
277
|
+
`--limit 8` returned 8 entities and 9 proofs. The compact retrieval was 2,812
|
|
278
|
+
estimated tokens versus 134,105 estimated tokens in 392 readable proof-source
|
|
279
|
+
artifacts: an observed 47.69× / 97.9% payload reduction. This is a transparent
|
|
280
|
+
fixture result, not a headline claim for every workspace.
|
|
281
|
+
|
|
282
|
+
See [Graph Benchmark Methodology](./graph-benchmark-methodology.md) for formulas,
|
|
283
|
+
reproduction rules, realistic baselines, and the gate required before publishing
|
|
284
|
+
a general performance claim.
|
|
285
|
+
|
|
286
|
+
## Current boundaries
|
|
287
|
+
|
|
288
|
+
- The CLI graph is intentionally file-backed; a graph database is not required.
|
|
289
|
+
- Text search is deterministic lexical retrieval, not embedding similarity.
|
|
290
|
+
- Compiler/LSP-grade symbol resolution belongs in deeper language providers.
|
|
291
|
+
- Missing project edges mean “relationship not proven,” not “projects are
|
|
292
|
+
independent.” Author service contracts or provide API/package/runtime
|
|
293
|
+
evidence to close that gap.
|
|
294
|
+
- The standalone `@workspai/graph` package remains unpublished while its public
|
|
295
|
+
contracts and conformance gates are developed.
|
|
296
|
+
|
|
297
|
+
## When the graph looks incomplete
|
|
298
|
+
|
|
299
|
+
Workspai does not invent relationships. If projects appear as disconnected
|
|
300
|
+
nodes, check the following in order:
|
|
301
|
+
|
|
302
|
+
1. run `workspace sync --json` and regenerate the model;
|
|
303
|
+
2. declare `dependsOn`, APIs, published events, and consumed events in the
|
|
304
|
+
workspace/project contracts;
|
|
305
|
+
3. confirm package manifests, OpenAPI/AsyncAPI/GraphQL/Protobuf documents,
|
|
306
|
+
Compose/Kubernetes/Terraform files, and CI definitions are inside registered
|
|
307
|
+
project paths;
|
|
308
|
+
4. inspect `graph.quality`, `providers`, and `diagnostics` before treating a
|
|
309
|
+
missing edge as proof of independence.
|
|
310
|
+
|
|
311
|
+
An absent edge means “not proven by current evidence,” not “no dependency
|
|
312
|
+
exists.”
|
|
313
|
+
|
|
314
|
+
For schemas and machine contracts, see the
|
|
315
|
+
[Artifact Catalog](./contracts/ARTIFACT_CATALOG.md). For the full command
|
|
316
|
+
surface, see [Commands Reference](./commands-reference.md).
|
|
@@ -94,6 +94,55 @@ npx workspai workspace contract graph
|
|
|
94
94
|
|
|
95
95
|
Contract file: `.workspai/workspace.contract.json`. Verification checks schema, duplicate slugs, port collisions, and unknown dependencies.
|
|
96
96
|
|
|
97
|
+
`workspace contract graph --json` preserves its original `nodes`, `edges`, and
|
|
98
|
+
summary fields for existing consumers, and now adds an evidence-backed
|
|
99
|
+
`dependencyGraph` using the public `workspace-dependency-graph.v1` contract. It
|
|
100
|
+
discovers package/workspace dependencies and supported cross-project imports,
|
|
101
|
+
records relationship provenance and confidence, and reports graph coverage,
|
|
102
|
+
orphans, hotspots, and cycles. Project nodes also expose safe package metadata,
|
|
103
|
+
public environment-template keys, command capabilities, key manifests,
|
|
104
|
+
entrypoints, API specifications, infrastructure, documentation, and an
|
|
105
|
+
operational verification profile. Environment values are never emitted.
|
|
106
|
+
|
|
107
|
+
The same response also exposes `knowledgeGraph` under the public
|
|
108
|
+
`workspace-knowledge-graph.v1` contract. It is a provider-neutral,
|
|
109
|
+
proof-carrying view spanning source structure, packages, service and API
|
|
110
|
+
contracts, infrastructure, delivery pipelines, docs/ADRs, ownership, tests,
|
|
111
|
+
runtime resources, and safe configuration keys. Use the dedicated query and
|
|
112
|
+
change-overlay surfaces when the full document is larger than a human needs:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npx workspai workspace graph entities endpoint --json
|
|
116
|
+
npx workspai workspace graph search "authentication endpoint" --limit 12 --json
|
|
117
|
+
npx workspai workspace graph benchmark "authentication endpoint" --limit 12 --json
|
|
118
|
+
npx workspai workspace graph evidence "GET /users" --json
|
|
119
|
+
npx workspai workspace graph path frontend-api "GET /users" --json
|
|
120
|
+
npx workspai workspace graph emit --json > .workspai/reports/knowledge-baseline.json
|
|
121
|
+
npx workspai workspace graph overlay --from .workspai/reports/knowledge-baseline.json --json
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The Model step persists the same projection to
|
|
125
|
+
`.workspai/reports/workspace-knowledge-graph.json`. It is registered in the
|
|
126
|
+
artifact contract registry and agent report index, required by the unified
|
|
127
|
+
runner's Model stage, referenced from `workspace-context-agent.json`, and
|
|
128
|
+
queryable through the read-mostly MCP server. This keeps CLI, CI, IDE and agent
|
|
129
|
+
consumers on one contract revision without injecting the full graph into every
|
|
130
|
+
agent prompt.
|
|
131
|
+
|
|
132
|
+
The overlay follows
|
|
133
|
+
`workspace-knowledge-graph-change-overlay.v1`: graph revisions are identified
|
|
134
|
+
by content-derived fingerprints (timestamps do not create false changes), and
|
|
135
|
+
changed artifacts are portable proof paths rather than machine-local absolute
|
|
136
|
+
paths. Proof additions, removals, and content-hash changes are first-class
|
|
137
|
+
overlay changes, so a source edit is visible even when the entity and relation
|
|
138
|
+
shape remains stable. The builder performs one bounded inventory pass per project and reuses
|
|
139
|
+
in-memory content hashes; query indexes live only for the immutable graph
|
|
140
|
+
instance, so replacing the graph is the invalidation boundary.
|
|
141
|
+
|
|
142
|
+
Direction is explicit: legacy `edges` remain producer-to-consumer for backward
|
|
143
|
+
compatibility; `dependencyGraph.edges` use consumer-to-dependency semantics so
|
|
144
|
+
impact and blast-radius consumers share one canonical interpretation.
|
|
145
|
+
|
|
97
146
|
Workspai keeps the contract alive during `create project` and `workspace sync` without overwriting manual API/event/owner declarations.
|
|
98
147
|
|
|
99
148
|
On a freshly cloned or moved workspace, `workspace sync` also repairs the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "workspai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Open-source workspace intelligence CLI for software systems: create, adopt, govern, verify, and align polyglot workspaces for humans, CI, IDEs, and AI agents.",
|
|
6
6
|
"keywords": [
|
|
@@ -158,6 +158,7 @@
|
|
|
158
158
|
"openai": "^6.22.0",
|
|
159
159
|
"ora": "^8.0.1",
|
|
160
160
|
"validate-npm-package-name": "^5.0.1",
|
|
161
|
+
"yaml": "^2.9.0",
|
|
161
162
|
"yauzl": "^3.4.0",
|
|
162
163
|
"yazl": "^3.3.1"
|
|
163
164
|
},
|
package/dist/analyze-BEBEZSZK.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export{b as printAnalyzeReport,a as runAnalyze}from'./chunk-RIEF2DDX.js';
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import {a}from'./chunk-2E6WGUN6.js';import {c,g,d}from'./chunk-HDURFXW5.js';import y from'path';import {existsSync}from'fs';import x from'fs-extra';var I=[{artifactKind:"bootstrap-compliance",cardId:"bootstrap",fileNames:["bootstrap-compliance.latest.json"]},{artifactKind:"doctor-workspace",cardId:"doctor",fileNames:["doctor-remediation-plan-last-run.json"]},{artifactKind:"analyze",cardId:"analyze",fileNames:["analyze-last-run.json"]},{artifactKind:"readiness",cardId:"readiness",fileNames:["release-readiness-last-run.json"]},{artifactKind:"pipeline",cardId:"pipeline",fileNames:["pipeline-last-run.json"]},{artifactKind:"workspace-run",cardId:"workspaceRun",fileNames:["workspace-run-last.json"]},{artifactKind:"workspace-verify",cardId:"workspaceVerify",fileNames:["workspace-verify-last-run.json"]}];function m(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function f(e){return Array.isArray(e)?e.filter(r=>typeof r=="string"&&r.trim().length>0):[]}function u(e){return [...new Set(e.map(r=>r.trim()).filter(Boolean))]}function K(e,r,t){return t?r:y.relative(e,r)}function C(e){let r=e?.trim()||"npx workspai bootstrap";if(!/(?:^|\s)--ci(?:\s|$)/.test(r)&&/(?:^|\s)--json(?:\s|$)/.test(r))return r.replace(/(?:^|\s)--json(?:\s|$)/,i=>{let n=i.startsWith(" ")?" ":"",c=i.endsWith(" ")?" ":"";return `${n}--ci --json${c}`}).trim();let t=/(?:^|\s)--ci(?:\s|$)/.test(r)?r:`${r} --ci`;return /(?:^|\s)--json(?:\s|$)/.test(t)?t:`${t} --json`}function M(e){return `${JSON.stringify({schemaVersion:"rapidkit.compatibility-matrix.v1",generatedAt:e,source:"workspai workspace remediation-plan",runtimes:{},notes:["Minimal enterprise baseline. Add runtime and toolchain entries as governance matures."]},null,2)}
|
|
2
|
-
`}function N(e){return `${JSON.stringify({schema_version:"1.0",enabled:false,strategy:"on-demand",artifacts:[],created_at:e,note:"Minimal enterprise baseline. Set enabled: true and add artifact entries to activate mirroring."},null,2)}
|
|
3
|
-
`}function P(e){let r=e.payload,t=f(r.blockers),i=f(r.blockingReasons),n=f(r.failures),c=f(r.reasons),d=f(r.policyViolations),a=m(r.summary),l=f(a?.blockers);if(e.artifactKind==="analyze"){let o=(Array.isArray(r.findings)?r.findings:[]).map(s=>m(s)).filter(s=>!!s).map(s=>String(s.message??s.title??s.id??"").trim()).filter(Boolean);return u([...t,...o,...i])}if(e.artifactKind==="workspace-run"){let g=m(r.stages),o=Object.entries(g??{}).flatMap(([s,b])=>{let A=m(b);return (Array.isArray(A?.projects)?A.projects:[]).map(p=>m(p)).filter(p=>!!p).filter(p=>p.status==="failed"||p.ok===false).map(p=>`${s}: ${String(p.project??p.name??"project")} failed`)});return u([...t,...o,...i])}return u([...t,...i,...n,...c,...d,...l])}function k(e){return {id:e.id,artifactKind:e.artifactKind,cardId:e.cardId,title:e.title,order:e.order,phase:e.phase,scope:"workspace",status:e.status??"ready",mode:e.mode,risk:e.risk,requiresApproval:true,blocker:e.blocker,summary:e.summary,...e.command?{command:e.command}:{},verifyCommand:e.verifyCommand,cwd:"workspace",files:e.files??[],...e.operation?{operation:e.operation}:{},rollback:{available:!!e.operation,strategy:e.operation?"idempotent":"none"},notes:e.notes??[]}}function S(e){let r=[],t=C("npx workspai bootstrap --json");for(let i of e.blockers)i.includes("profile.enterprise.ci")&&r.push(k({id:"bootstrap.enterprise-ci",artifactKind:"bootstrap-compliance",cardId:"bootstrap",title:"Run bootstrap in deterministic CI mode",order:10,phase:"bootstrap-preflight",blocker:i,summary:"Enterprise bootstrap compliance requires --ci for deterministic execution.",mode:"run-command",risk:"safe",command:t,verifyCommand:t})),i.includes("profile.enterprise.compatibility-matrix")&&r.push(k({id:"bootstrap.compatibility-matrix",artifactKind:"bootstrap-compliance",cardId:"bootstrap",title:"Create enterprise compatibility matrix baseline",order:20,phase:"bootstrap-config",blocker:i,summary:"Create the missing compatibility matrix baseline without overwriting user data.",mode:"edit-file",risk:"safe",verifyCommand:t,files:[".workspai/compatibility-matrix.json"],operation:{type:"file-create",path:".workspai/compatibility-matrix.json",content:M(e.generatedAt),overwrite:false}})),i.includes("profile.enterprise.mirror-config")&&r.push(k({id:"bootstrap.mirror-config",artifactKind:"bootstrap-compliance",cardId:"bootstrap",title:"Create enterprise mirror config baseline",order:30,phase:"bootstrap-config",blocker:i,summary:"Create the missing mirror configuration baseline without enabling mirroring.",mode:"edit-file",risk:"safe",verifyCommand:t,files:[".workspai/mirror-config.json"],operation:{type:"file-create",path:".workspai/mirror-config.json",content:N(e.generatedAt),overwrite:false}}));return r}function $(e){let t={analyze:{title:"Refresh analyze evidence",phase:"analysis",command:"npx workspai analyze --strict --json",verify:"npx workspai analyze --strict --json"},readiness:{title:"Refresh release readiness",phase:"release-readiness",command:e.ciMode?"npx workspai readiness --strict --json":"npx workspai readiness --json",verify:e.ciMode?"npx workspai readiness --strict --json":"npx workspai readiness --json"},pipeline:{title:"Rerun governance pipeline",phase:"governance-pipeline",command:"npx workspai pipeline --json --strict",verify:"npx workspai pipeline --json --strict"},"workspace-run":{title:"Rerun failed workspace stage",phase:"fleet-run",command:e.ciMode?"npx workspai workspace run test --strict --json":"npx workspai workspace run test --json",verify:e.ciMode?"npx workspai workspace run test --strict --json":"npx workspai workspace run test --json"},"workspace-verify":{title:"Refresh workspace verify gate",phase:"verification",command:e.ciMode?"npx workspai workspace verify --strict --json":"npx workspai workspace verify --json",verify:e.ciMode?"npx workspai workspace verify --strict --json":"npx workspai workspace verify --json"},"doctor-workspace":{title:"Use Doctor remediation plan",phase:"doctor-remediation",command:"npx workspai doctor workspace --plan --json",verify:"npx workspai doctor workspace --json"}}[e.report.artifactKind]??{title:"Refresh artifact evidence",phase:"evidence-refresh",command:"npx workspai pipeline --json --strict",verify:"npx workspai pipeline --json --strict"};return k({id:`${e.report.cardId}.refresh.${e.order}`,artifactKind:e.report.artifactKind,cardId:e.report.cardId,title:t.title,order:e.order,phase:t.phase,blocker:e.blocker,summary:"No deterministic file operation is available for this artifact yet; refresh the evidence and continue with the card-specific plan.",mode:e.report.artifactKind==="doctor-workspace"?"verify-before-fix":"run-command",risk:"guarded",status:e.report.artifactKind==="doctor-workspace"?"review-required":"ready",command:t.command,verifyCommand:t.verify,notes:e.report.artifactKind==="doctor-workspace"?["Read doctor-remediation-plan-last-run.json for ordered file-level steps."]:[]})}async function O(e){let r=[c(e,".workspai/reports"),d(e,".workspai/reports")],t=[],i=new Set;for(let n of I)for(let c of n.fileNames){let d=(await Promise.all(r.map(a=>y.join(a,c)))).find(a=>existsSync(a));if(!(!d||i.has(`${n.artifactKind}:${c}`))){i.add(`${n.artifactKind}:${c}`);try{let a=await x.readJSON(d),l=m(a);if(!l)continue;t.push({artifactKind:n.artifactKind,cardId:n.cardId,fileName:c,absolutePath:d,payload:l});}catch{t.push({artifactKind:n.artifactKind,cardId:n.cardId,fileName:c,absolutePath:d,payload:{blockers:[`${n.artifactKind}: report exists but could not be parsed.`]}});}}}return t}async function F(e){let r=y.resolve(e.workspacePath),t=e.includeAbsolutePaths===true,i=e.ciMode===true,n=new Date().toISOString(),c$1=c(r,".workspai/reports"),d=await O(r),a$1=[],l=1;for(let o of d){let s=P(o);if(s.length!==0){if(o.artifactKind==="bootstrap-compliance"){a$1.push(...S({blockers:s,generatedAt:n})),l=a$1.length+1;continue}for(let b of s.slice(0,8))a$1.push($({report:o,blocker:b,order:l,ciMode:i})),l+=1;}}let g={safe:a$1.filter(o=>o.risk==="safe").length,guarded:a$1.filter(o=>o.risk==="guarded").length,invasive:a$1.filter(o=>o.risk==="invasive").length};return {schemaVersion:a,generatedAt:n,workspace:{name:y.basename(r),...t?{path:r}:{}},source:{command:"workspace remediation-plan",reportsDir:K(r,c$1,t),includeAbsolutePaths:t,ciMode:i},summary:{artifactsScanned:d.length,cardsCovered:u(a$1.map(o=>o.cardId)).length,totalActions:a$1.length,executableActions:a$1.filter(o=>o.status==="ready").length,risk:g},actions:a$1}}async function W(e,r){return g(r,".workspai/reports/artifact-remediation-plan-last-run.json",e)}export{F as buildArtifactRemediationPlan,W as writeArtifactRemediationPlan};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export{b as AUTOPILOT_RELEASE_ALIAS_FILENAME,a as AUTOPILOT_RELEASE_LAST_RUN_FILENAME,c as runAutopilotRelease}from'./chunk-4EPHWD27.js';
|
package/dist/chunk-2G7FASAO.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import {b as b$1}from'./chunk-NHN4QXPP.js';import {i}from'./chunk-MER6ZBN2.js';import {c}from'./chunk-PRBVYW3T.js';import {a}from'./chunk-Y45WZR5N.js';import {f}from'./chunk-7YHK5NM3.js';import {b}from'./chunk-RO73VVHW.js';import {h,g as g$1}from'./chunk-5XATWNME.js';import {promises,constants}from'fs';import c$1 from'path';import T,{homedir}from'os';import {pathToFileURL}from'url';import g from'process';import E from'crypto';import s from'fs/promises';function q(t){let e=t.label.indexOf(" \u2014 ");return e>=0?t.label.slice(e+3).trim():t.label.trim()}function B(){let t=c().map(e=>({value:e.id,label:q(e),hint:e.description,name:e.label})),r=i().map(e=>({value:e.kitId,label:e.displayName,hint:e.commandDisplay("my-app"),name:`${e.displayName} \u2014 ${e.framework}`}));return [...t,...r]}var Q=".workspairc.json",z=".rapidkitrc.json",Z=["workspai.config.js","workspai.config.mjs","workspai.config.cjs","rapidkit.config.js","rapidkit.config.mjs","rapidkit.config.cjs"],ee=["workspai.config.json","rapidkit.config.json"];function I(t){return typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT"}function L(t,r){let e=r instanceof Error?r.message:String(r),i=t.endsWith(".js")&&/module is not defined in ES module scope/i.test(e)?' CommonJS syntax in a .js config is not valid when the project package uses "type": "module"; rename the file to .cjs or use export default.':"";return `Failed to load Workspai config at ${t}.${i} Cause: ${e}`}async function _e(){for(let t of [c$1.join(T.homedir(),Q),c$1.join(T.homedir(),z)])try{let r=await promises.readFile(t,"utf-8"),e=JSON.parse(r);return f.debug(`Loaded config from ${t}`),e}catch{}return f.debug("No user config found, using defaults"),{}}async function Ke(t=process.cwd(),r={}){let e=t,i=c$1.parse(e).root;for(;e!==i;){for(let o of ee){let n=c$1.join(e,o);try{let a=await promises.readFile(n,"utf-8"),l=JSON.parse(a);if(!l||typeof l!="object"||Array.isArray(l))throw new Error("configuration root must be a JSON object");return f.debug(`Loaded data-only Workspai config from ${o}`),l}catch(a){if(I(a))continue;throw new Error(L(n,a))}}for(let o of Z){let n=c$1.join(e,o);try{await promises.access(n);}catch(a){if(I(a))continue;throw new Error(L(n,a))}if(f.debug(`Found config file: ${n}`),!r.trustExecutableConfig)throw new Error(`Refusing to execute Workspai config at ${n} without explicit trust. Use a data-only workspai.config.json file, pass --trust-config, or set WORKSPAI_TRUST_CONFIG=1.`);try{let l=await import(pathToFileURL(n).href),f$1=l.default||l;return f.debug(`Loaded Workspai config from ${o}`),f$1}catch(a){throw new Error(L(n,a))}}e=c$1.dirname(e);}return f.debug("No Workspai config file found, using defaults"),{}}function Me(t,r,e){return {author:e.author||r.workspace?.defaultAuthor||t.author,pythonVersion:e.pythonVersion||r.workspace?.pythonVersion||t.pythonVersion,defaultInstallMethod:e.defaultInstallMethod||r.workspace?.installMethod||t.defaultInstallMethod,defaultKit:e.defaultKit||r.projects?.defaultKit||t.defaultKit,skipGit:e.skipGit??r.projects?.skipGit??t.skipGit,license:e.license||t.license,testRapidKitPath:e.testRapidKitPath||t.testRapidKitPath}}function Ge(t){return a("DEV_PATH")||t.testRapidKitPath||void 0}function re(t,r){let e=t.indexOf(r);if(e>=0&&e+1<t.length)return t[e+1];let i=t.find(o=>o.startsWith(`${r}=`));if(i)return i.slice(r.length+1)}function ie(t){return t.includes("--here")}function U(t,r=g.cwd()){if(ie(t))return c$1.resolve(r);let e=re(t,"--output");if(e)return c$1.resolve(e)}function Ze(t,r=g.cwd()){let e=c$1.resolve(t),i=c$1.resolve(r),o=c$1.relative(i,e);return o.length>0&&!o.startsWith("..")&&!c$1.isAbsolute(o)?`cd ${o}`:`cd ${e}`}function et(t,r={}){let e=r.argv??[],i=r.outputParent??U(e,g.cwd());return h(t.trim(),{homeDir:r.homeDir,outputDir:i})}function tt(t,r,e={}){return t?c$1.resolve(t)===c$1.resolve(r)?true:e.outputParent===void 0:false}async function rt(t,r={}){let e=r.cwd??g.cwd(),i=r.homeDir??homedir(),o=U(t,e);if(o!==void 0)return o;let n=r.hasYes??(t.includes("--yes")||t.includes("-y"));if(!(r.interactive??(!n&&!!g.stdin.isTTY&&!b())))return;let l=g$1(i),{location:f}=await b$1([{type:"rawlist",name:"location",message:"Where should the workspace be created?",choices:[{value:"managed",label:"Managed home",hint:l},{value:"here",label:"Current directory",hint:e}],default:0}]);if(f==="here")return c$1.resolve(e)}var W="workspai.lifecycle-transaction",J=1,N="manifest.json",_="lifecycle-transaction-";async function w(t){try{return await s.lstat(t)}catch(r){if(r.code==="ENOENT")return null;throw r}}function K(t){let r=t?.code;return process.platform==="win32"&&(r==="EPERM"||r==="EINVAL"||r==="ENOSYS")}async function D(t){try{await t.sync();}catch(r){if(!K(r))throw r}}function oe(t){if(typeof t!="string"||!c$1.isAbsolute(t))throw new Error("Lifecycle transaction journal contains a non-absolute target path.")}function ne(t){if(typeof t!="string"||t.length===0||c$1.basename(t)!==t||t==="."||t==="..")throw new Error("Lifecycle transaction journal contains an unsafe backup reference.")}function ae(t){if(!t||typeof t!="object")throw new Error("Lifecycle transaction journal is not an object.");let r=t;if(r.kind!==W||r.version!==J)throw new Error("Lifecycle transaction journal has an unsupported format.");if(!Number.isInteger(r.ownerPid)||r.ownerPid<=0)throw new Error("Lifecycle transaction journal has an invalid owner process.");if(!["active","committed","rolling-back"].includes(r.phase))throw new Error("Lifecycle transaction journal has an invalid phase.");if(!Array.isArray(r.operations))throw new Error("Lifecycle transaction journal has invalid operations.");for(let e of r.operations){if(!e||typeof e!="object")throw new Error("Lifecycle transaction journal contains an invalid operation.");let i=e;if(oe(i.path),i.type!=="tree"){if(i.type!=="file"||!["absent","regular"].includes(i.state))throw new Error("Lifecycle transaction journal contains an invalid operation.");if(i.state==="regular"){if(!Number.isInteger(i.mode)||i.mode<0||i.mode>4095)throw new Error("Lifecycle transaction journal contains an invalid file mode.");ne(i.backup);}}}return r}async function x(t){let r;try{r=await s.open(t,constants.O_RDONLY);}catch(e){if(K(e))return;throw e}try{await D(r);}finally{await r.close();}}async function M(t,r){let e=c$1.join(c$1.dirname(t),`.${c$1.basename(t)}.${process.pid}.${E.randomUUID()}.tmp`);try{let i=await s.open(e,constants.O_WRONLY|constants.O_CREAT|constants.O_EXCL,384);try{await i.writeFile(r),await D(i);}finally{await i.close();}await s.rename(e,t),await x(c$1.dirname(t));}catch(i){throw await s.rm(e,{force:true}).catch(()=>{}),i}}async function G(t,r){await M(c$1.join(t,N),Buffer.from(`${JSON.stringify(r,null,2)}
|
|
2
|
-
`));}async function V(t,r){let e=await w(t.path);if(e?.isSymbolicLink()||e&&!e.isFile())throw new Error(`Refusing to restore over a non-regular file: ${t.path}`);if(t.state==="absent"){e&&await s.unlink(t.path);return}if(!r)throw new Error(`Missing durable backup for: ${t.path}`);if(!await w(c$1.dirname(t.path)))return;let i=c$1.join(r,t.backup),o=await s.lstat(i).catch(f=>{if(f.code==="ENOENT"&&e?.isFile())return e;throw f});if(o===e)return;if(!o.isFile()||o.isSymbolicLink())throw new Error(`Lifecycle transaction backup is not a regular file: ${i}`);let n=await s.readFile(i),a=c$1.join(c$1.dirname(t.path),`.${c$1.basename(t.path)}.${process.pid}.${E.randomUUID()}.rollback`),l=await s.open(a,constants.O_WRONLY|constants.O_CREAT|constants.O_EXCL,t.mode);try{await l.writeFile(n),await l.chmod(t.mode),await D(l);}finally{await l.close();}try{await s.rename(a,t.path),await x(c$1.dirname(t.path));}catch(f){throw await s.rm(a,{force:true}).catch(()=>{}),f}}async function Y(t){let r=await w(t.path);if(r){if(r.isSymbolicLink()||!r.isDirectory())throw new Error(`Refusing to remove a non-directory owned tree: ${t.path}`);await s.rm(t.path,{recursive:true});}}async function se(t,r){let e=[];for(let i of [...t].reverse())try{i.type==="file"?await V(i,r):await Y(i);}catch(o){e.push(o);}if(e.length>0)throw new AggregateError(e,"Lifecycle transaction rollback failed.")}var j=class t{constructor(r){this.transactionDirectory=r;this.journalPath=r?c$1.join(r,N):void 0;}transactionDirectory;journalPath;actions=[];durableOperations=[];phase="active";finished=false;static async create(r={}){if(!r.journalDirectory)return new t;let e=c$1.resolve(r.journalDirectory);await s.mkdir(e,{recursive:true});let i=await s.mkdtemp(c$1.join(e,_));await x(e);let o=new t(i);return await o.persist(),o}assertActive(){if(this.finished||this.phase!=="active")throw new Error("Lifecycle transaction is no longer active.")}async persist(r=this.durableOperations){this.transactionDirectory&&await G(this.transactionDirectory,{kind:W,version:J,ownerPid:process.pid,phase:this.phase,operations:r});}async addDurableOperation(r){let e=[...this.durableOperations,r];await this.persist(e),this.durableOperations.push(r),this.actions.push(r);}async captureFile(r){this.assertActive();let e=c$1.resolve(r),i=await w(e);if(!i){await this.addDurableOperation({type:"file",path:e,state:"absent"});return}if(i.isSymbolicLink()||!i.isFile())throw new Error(`Lifecycle transaction can only capture regular files: ${e}`);let o;try{o=await s.open(e,constants.O_RDONLY|(constants.O_NOFOLLOW??0));}catch(n){throw n.code==="ENOENT"?new Error(`File changed while being captured: ${e}`,{cause:n}):n}try{let n=await o.stat();if(!n.isFile())throw new Error(`Lifecycle transaction can only capture regular files: ${e}`);let a=await o.readFile(),l=n.mode&4095;if(this.transactionDirectory){let f=`file-${this.durableOperations.length}-${E.randomUUID()}.bin`;await M(c$1.join(this.transactionDirectory,f),a),await this.addDurableOperation({type:"file",path:e,state:"regular",mode:l,backup:f});}else {let f=`memory-${this.durableOperations.length}`,y={type:"file",path:e,state:"regular",mode:l,backup:f};this.durableOperations.push(y),this.actions.push({type:"compensation",run:async()=>{let d=await w(e);if(d?.isSymbolicLink()||d&&!d.isFile())throw new Error(`Refusing to restore over a non-regular file: ${e}`);let b=c$1.join(c$1.dirname(e),`.${c$1.basename(e)}.${process.pid}.${E.randomUUID()}.rollback`);await s.writeFile(b,a,{flag:"wx",mode:l}),await s.chmod(b,l);try{await s.rename(b,e);}catch(H){throw await s.rm(b,{force:true}).catch(()=>{}),H}}});}}finally{await o.close();}}async captureOwnedTree(r){this.assertActive();let e=c$1.resolve(r),i=await w(e);if(!i)return await this.addDurableOperation({type:"tree",path:e}),true;if(i.isSymbolicLink()||!i.isDirectory())throw new Error(`Lifecycle transaction tree must be absent or a directory: ${e}`);return false}registerCompensation(r){this.assertActive(),this.actions.push({type:"compensation",run:async()=>r()});}async commit(){if(!this.finished){this.assertActive(),this.phase="committed";try{await this.persist(),this.finished=true,this.actions.length=0,this.transactionDirectory&&await s.rm(this.transactionDirectory,{recursive:true}).catch(()=>{});}catch(r){throw this.phase="active",r}}}async rollback(){if(this.finished||this.phase==="committed")return;this.assertActive(),this.phase="rolling-back";try{await this.persist();}catch(e){throw this.phase="active",e}let r=[];for(let e of [...this.actions].reverse())try{e.type==="compensation"?await e.run():e.type==="file"?await V(e,this.transactionDirectory):await Y(e);}catch(i){r.push(i);}if(r.length>0)throw new AggregateError(r,"Lifecycle transaction rollback failed.");this.finished=true,this.transactionDirectory&&await s.rm(this.transactionDirectory,{recursive:true});}};async function lt(t={}){return j.create(t)}async function ft(t){let r=c$1.resolve(t),e=await s.readdir(r,{withFileTypes:true}).catch(n=>{if(n.code==="ENOENT")return [];throw n}),i=[],o=[];for(let n of e){if(!n.isDirectory()||!n.name.startsWith(_))continue;let a=c$1.join(r,n.name);try{let l;try{l=await s.readFile(c$1.join(a,N),"utf8");}catch(d){if(d.code==="ENOENT")continue;throw d}let f=ae(JSON.parse(l));if(f.phase==="committed"){await s.rm(a,{recursive:true});continue}let y=false;try{process.kill(f.ownerPid,0),y=true;}catch(d){y=d.code==="EPERM";}if(y)continue;f.phase==="active"&&(f.phase="rolling-back",await G(a,f)),await se(f.operations,a),await s.rm(a,{recursive:true}),i.push(a);}catch(l){o.push(l);}}if(o.length>0)throw new AggregateError(o,"Lifecycle transaction recovery failed.");return i}export{B as a,_e as b,Ke as c,Me as d,Ge as e,Ze as f,et as g,tt as h,rt as i,lt as j,ft as k};
|
package/dist/chunk-4EPHWD27.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import {a as a$1}from'./chunk-QA5BGEQW.js';import {a as a$4}from'./chunk-22DT744Z.js';import {a as a$2,e}from'./chunk-WPEEC5BX.js';import {f,c,g}from'./chunk-HDURFXW5.js';import {a}from'./chunk-N7DV5L7C.js';import a$3 from'chalk';import se from'fs';import b from'path';import {execa}from'execa';var G="autopilot-release-last-run.json",V="autopilot-release.json";function j(r){try{return JSON.parse(r)}catch{return null}}function Re(r){let e=b.resolve(r),n=a$4(e);if(!n)throw new Error("No Workspai workspace found in current directory or parents");return n}async function S(r,e){let n=process.argv[1];if(!n)return {exitCode:1,stdout:"",stderr:"RapidKit entrypoint is unavailable for autopilot execution.",crashed:true};try{let o=await execa(process.execPath,[n,...r],{cwd:e,reject:false,env:{...process.env,RAPIDKIT_AUTOPILOT_CHILD:"1"}});return {exitCode:Number(o.exitCode??1),stdout:o.stdout,stderr:o.stderr,crashed:false}}catch(o){return {exitCode:1,stdout:"",stderr:o instanceof Error?o.message:String(o),crashed:true}}}function re(r){let e=r.toLowerCase();return e==="pass"?"pass":e==="warn"?"warn":e==="fail"?"fail":"warn"}function oe(r){return r.summary.failed>0||r.gates.results.some(e=>e.status==="fail")?"fail":r.gates.results.some(e=>e.status==="warn")?"warn":"pass"}function Se(r){let e=r.filter(o=>o.status!=="skipped");if(e.length===0)return 100;let n=e.reduce((o,t)=>t.status==="pass"?o+1:t.status==="warn"?o+.6:o,0);return Math.round(n/e.length*100)}function be(r){return r.executionError?["Re-run: npx workspai autopilot release --mode audit --json","Inspect .workspai/reports/autopilot-release-last-run.json for execution failure details"]:r.blockers.length>0?["Run: npx workspai doctor workspace --plan","Run: npx workspai readiness --json --strict","Run: npx workspai workspace run test --affected --strict"]:r.hasWarnings&&r.mode!=="enforce"?["Review warning-level findings in autopilot report","Optionally run: npx workspai autopilot release --mode safe-fix"]:["Workspace is release-ready based on current autopilot policy"]}async function xe(r,e){await se.promises.mkdir(b.dirname(r),{recursive:true}),await se.promises.writeFile(r,`${JSON.stringify(e,null,2)}
|
|
2
|
-
`,"utf-8");}async function Me(r){let e$1=Re(r.workspacePath),n=r.mode,o=[],t=[],F,H,D,q,Q,X=0,f$1=false,T=0,L=0,N=-1,W=-1,c$1="skipped",d="skipped",ae=n==="enforce"?["doctor","workspace","--json","--strict"]:["doctor","workspace","--json","--ci"];if(r.skipPipelineStages)o.push({name:"doctor-workspace",status:"skipped",durationMs:0,summary:"doctor stage skipped (pipeline already executed)"},{name:"analyze",status:"skipped",durationMs:0,summary:"analyze stage skipped (pipeline already executed)"},{name:"readiness",status:"skipped",durationMs:0,summary:"readiness stage skipped (pipeline already executed)"});else {let s=Date.now(),l=await S([...ae],e$1),m=Date.now()-s;if(c$1="pass",l.crashed)c$1="fail",f$1=true,t.push(`doctor workspace execution error: ${l.stderr||"unknown error"}`);else if(l.exitCode===1)c$1="fail",t.push("doctor workspace command failed or reported errors");else if(l.exitCode===2)c$1="warn",t.push("doctor workspace reported warnings");else if(l.exitCode!==0)c$1="fail",t.push("doctor workspace command failed");else {let p=j(l.stdout),E=p&&p.healthScore&&typeof p.healthScore=="object"?p.healthScore:{},k=Number(E.errors??0),$=Number(E.warnings??0);Number.isFinite(k)&&k>0?(c$1="fail",t.push(`doctor workspace reports ${k} error(s)`)):Number.isFinite($)&&$>0&&(c$1="warn");}N=o.push({name:"doctor-workspace",status:c$1,durationMs:m,summary:c$1==="pass"?"doctor workspace passed":c$1==="warn"?"doctor workspace reported warnings":"doctor workspace reported errors"})-1,n==="enforce"&&c$1==="warn"&&t.push("doctor workspace reported warnings under enforce mode");let g=Date.now(),w=await S(["analyze","--json"],e$1),v=Date.now()-g;H=await f(e$1,a.analyze)??c(e$1,a.analyze);let i="pass";if(w.crashed)i="fail",f$1=true,t.push(`analyze execution error: ${w.stderr||"unknown error"}`);else if(w.exitCode!==0)i=w.exitCode===2?"warn":"fail",t.push(w.exitCode===2?"analyze reported needs-attention verdict":"analyze command failed or reported blocked verdict");else {let p=j(w.stdout),E=p&&p.summary&&typeof p.summary=="object"?p.summary:{},k=String(E.verdict??"ready");k==="blocked"?(i="fail",t.push("analyze reported blocked verdict")):k==="needs-attention"&&(i="warn");}o.push({name:"analyze",status:i,durationMs:v,summary:i==="pass"?"analyze passed":i==="warn"?"analyze reported needs-attention":"analyze reported blocked verdict"}),n==="enforce"&&i==="warn"&&t.push("analyze reported warnings under enforce mode");let P=Date.now(),h=await S(["readiness","--json"],e$1),y=Date.now()-P;if(d="fail",h.crashed)d="fail",f$1=true,t.push(`readiness execution error: ${h.stderr||"unknown error"}`);else if(h.exitCode!==0)d="fail",t.push("readiness command failed");else {let p=j(h.stdout),E=String(p?.overallStatus??"fail");if(d=re(E),typeof p?.evidencePath=="string"&&p.evidencePath.trim().length>0&&(F=p.evidencePath),d==="fail"){let k=Array.isArray(p?.blockingReasons)?p?.blockingReasons.filter($=>typeof $=="string"):[];k.length>0?t.push(...k.map($=>`readiness: ${$}`)):t.push("readiness overall status is fail");}}W=o.push({name:"readiness",status:d,durationMs:y,summary:`readiness overall status is ${d}`})-1,n==="enforce"&&d==="warn"&&t.push("readiness reported warnings under enforce mode");}let ne=Date.now(),z=await S(["doctor","workspace","--plan","--json"],e$1),ie=Date.now()-ne,R="warn";if(z.crashed)R="fail",f$1=true,t.push(`doctor remediation plan execution error: ${z.stderr||"unknown error"}`);else if(z.exitCode!==0)R="fail",t.push("doctor remediation plan command failed");else {let s=j(z.stdout),l=s&&s.remediationPlan&&typeof s.remediationPlan=="object"?s.remediationPlan:null,m=Number(l?.totalSteps??0),g=Number(l?.executableSteps??0);Number.isFinite(m)&&m>0&&(T=m),Number.isFinite(g)&&g>0&&(L=g),Number.isFinite(m)&&m===0?R="pass":R="warn";}if(o.push({name:"remediation-plan",status:R,durationMs:ie,summary:R==="pass"?"no remediation steps required":"remediation steps available"}),n==="enforce"&&R==="warn"&&t.push("remediation plan has pending steps under enforce mode"),n==="safe-fix"){let s=Date.now(),l=await S(["doctor","workspace","--apply"],e$1),m=Date.now()-s,g=l.crashed||l.exitCode!==0?"fail":"pass";if(l.crashed)f$1=true,t.push(`doctor remediation apply execution error: ${l.stderr||"unknown error"}`);else if(g==="fail")t.push("doctor remediation apply failed");else {X=L>0?L:T>0?T:1;let w=await S(["doctor","workspace","--json"],e$1);if(w.crashed)c$1="fail",f$1=true,t.push(`post-apply doctor execution error: ${w.stderr||"unknown error"}`);else if(w.exitCode!==0)c$1="fail",t.push("post-apply doctor workspace command failed");else {let i=j(w.stdout),P=i&&i.healthScore&&typeof i.healthScore=="object"?i.healthScore:{},h=Number(P.errors??0),y=Number(P.warnings??0);Number.isFinite(h)&&h>0?(c$1="fail",t.push(`post-apply doctor reports ${h} error(s)`)):Number.isFinite(y)&&y>0?c$1="warn":c$1="pass";}N>=0&&(o[N].status=c$1,o[N].summary=`doctor workspace post-apply status is ${c$1}`);let v=await S(["readiness","--json"],e$1);if(v.crashed)d="fail",f$1=true,t.push(`post-apply readiness execution error: ${v.stderr||"unknown error"}`);else if(v.exitCode!==0)d="fail",t.push("post-apply readiness command failed");else {let i=j(v.stdout),P=String(i?.overallStatus??"fail");if(d=re(P),typeof i?.evidencePath=="string"&&i.evidencePath.trim().length>0&&(F=i.evidencePath),d==="fail"){let h=Array.isArray(i?.blockingReasons)?i?.blockingReasons.filter(y=>typeof y=="string"):[];h.length>0?t.push(...h.map(y=>`post-apply readiness: ${y}`)):t.push("post-apply readiness overall status is fail");}}W>=0&&(o[W].status=d,o[W].summary=`readiness post-apply overall status is ${d}`);}o.push({name:"remediation-apply",status:g,durationMs:m,summary:g==="pass"?"safe remediation apply completed":"safe remediation apply failed"});}else o.push({name:"remediation-apply",status:"skipped",durationMs:0,summary:"remediation apply is skipped for this mode"});let le=Date.now(),x="pass",A="workspace test/build completed for selected projects";try{let s=await a$1({workspacePath:e$1,stage:"test",affected:true,since:r.since,parallel:r.parallel,maxWorkers:r.maxWorkers,strict:true,json:true,enforceGates:false});D=c(e$1,b.join(".workspai","reports",a$2)),await e(e$1,s),q=D;let l=oe(s);if(l==="fail")x="fail",A="workspace test stage failed for selected projects",t.push("workspace run test failed for selected projects");else {l==="warn"&&(x="warn",A="workspace test stage completed with warnings",n==="enforce"&&t.push("workspace run test reported warnings under enforce mode"));let m=await a$1({workspacePath:e$1,stage:"build",affected:true,since:r.since,parallel:r.parallel,maxWorkers:r.maxWorkers,strict:true,json:true,enforceGates:false});await e(e$1,m),Q=D;let g=oe(m);g==="fail"?(x="fail",A="workspace build stage failed for selected projects",t.push("workspace run build failed for selected projects")):g==="warn"&&(x="warn",A="workspace test/build completed with warnings",n==="enforce"&&t.push("workspace run test/build reported warnings under enforce mode"));}}catch(s){x="fail",A="workspace test/build orchestration failed",f$1=true,t.push(`workspace run orchestration error: ${s instanceof Error?s.message:String(s)}`);}let ce=Date.now()-le;o.push({name:"workspace-run-test-build",status:x,durationMs:ce,summary:A});let M=o.filter(s=>s.status==="warn").length,pe=o.filter(s=>s.status==="fail").length,_=n==="enforce"?o.some(s=>s.status==="warn"||s.status==="fail"):pe>0,C=[...new Set(t)],O=f$1||_?Math.max(1,C.length):0,ue=O>0?C:[],de=O===0?C:[],fe=Se(o),me=f$1||_?"blocked":M>0?"partial":"approved",ge=f$1?3:_?1:M>0?2:0,we=be({mode:n,executionError:f$1,blockers:C,hasWarnings:M>0}),Y=c(e$1,".workspai/reports"),he=b.join(Y,G),ke=b.join(Y,V),u={schemaVersion:"autopilot-release-v1",generatedAt:new Date().toISOString(),workspacePath:e$1,mode:n,summary:{releaseScore:fe,verdict:me,blockers:O,warnings:M,safeFixesApplied:X,manualActions:C.length,exitCode:ge},stages:o,blockingReasons:ue,warningReasons:de,nextActions:we,artifacts:{reportPath:he,aliasEvidencePath:ke,analyzeEvidencePath:H,readinessEvidencePath:F,workspaceRunEvidencePath:D,workspaceRunTestPath:q,workspaceRunBuildPath:Q},enterpriseControls:{jsonReady:true,evidencePath:`.workspai/reports/${G}`,aliasEvidencePath:`.workspai/reports/${V}`}};if(await g(e$1,`.workspai/reports/${G}`,u),await g(e$1,`.workspai/reports/${V}`,u),r.output&&await xe(b.resolve(r.output),u),!r.json){console.log(a$3.bold.cyan(`
|
|
3
|
-
\u{1F680} Workspai Autopilot Release
|
|
4
|
-
`)),console.log(a$3.bold(`Workspace: ${a$3.cyan(b.basename(e$1))}`)),console.log(a$3.gray(`Path: ${e$1}`)),console.log(a$3.white(`Mode: ${n}`)),console.log(a$3.white(`Verdict: ${u.summary.verdict==="approved"?a$3.green("approved"):u.summary.verdict==="partial"?a$3.yellow("partial"):a$3.red("blocked")}`)),console.log(a$3.white(`Release score: ${u.summary.releaseScore}`));for(let s of u.stages){let l=s.status==="pass"?a$3.green("PASS"):s.status==="warn"?a$3.yellow("WARN"):s.status==="skipped"?a$3.gray("SKIP"):a$3.red("FAIL");console.log(` - ${s.name}: ${l} ${s.summary} (${s.durationMs}ms)`);}if(u.blockingReasons.length>0){console.log(a$3.bold.red(`
|
|
5
|
-
Blocking reasons:`));for(let s of u.blockingReasons)console.log(a$3.red(` - ${s}`));}if(u.warningReasons.length>0){console.log(a$3.bold.yellow(`
|
|
6
|
-
Warning reasons:`));for(let s of u.warningReasons)console.log(a$3.yellow(` - ${s}`));}if(u.nextActions.length>0){console.log(a$3.bold(`
|
|
7
|
-
Next actions:`));for(let s of u.nextActions)console.log(a$3.gray(` - ${s}`));}console.log(a$3.gray(`
|
|
8
|
-
Report: ${u.artifacts.reportPath}`));}return u}export{G as a,V as b,Me as c};
|
package/dist/chunk-CVHMUSRX.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import {a as a$6}from'./chunk-HTYMXMQM.js';import {d,q,a as a$5}from'./chunk-DIPD72H4.js';import {i as i$1,h}from'./chunk-4KUIFXHM.js';import {i}from'./chunk-MER6ZBN2.js';import {c,b as b$2}from'./chunk-PRBVYW3T.js';import {a as a$4,k,b as b$3}from'./chunk-WYFPXTTS.js';import {a as a$2}from'./chunk-FXQJX34Z.js';import {g,f as f$1,c as c$1}from'./chunk-HDURFXW5.js';import {a as a$1}from'./chunk-GSWPGELT.js';import {a as a$3}from'./chunk-GZTYAEWX.js';import {b as b$1,a}from'./chunk-N7DV5L7C.js';import {p,o}from'./chunk-5XATWNME.js';import f from'path';import P from'fs-extra';import yt from'crypto';import {createRequire}from'module';var ft=new Set(["service","frontend","worker","library","infra","docs","test-suite","unknown"]);async function He(e){try{if(!await P.pathExists(e))return null;let t=await P.readJSON(e);return t&&typeof t=="object"?t:null}catch{return null}}async function mt(e){for(let t of e){let r=await He(t);if(r)return r}return null}function Te(e){if(typeof e!="string")return null;let t=e.trim().toLowerCase();return ft.has(t)?t:null}async function $e(e,t){let r=t??await mt(p(e,"project.json")),o=Te(r?.kind)??Te(r?.type);if(o)return o;let s=typeof r?.kit_name=="string"?r.kit_name:r?.kit,n=typeof r?.framework=="string"?r.framework:null,a=typeof r?.runtime=="string"?r.runtime:null,i=`${typeof s=="string"?s:""} ${n??""} ${a??""}`.trim().toLowerCase();if(/\b(frontend|nextjs|next\.js|react|vue|svelte|vite|angular|astro|remix|nuxt)\b/.test(i))return "frontend";if(/\b(fastapi|nestjs|springboot|spring boot|gofiber|gogin|dotnet|webapi|django|flask|express|fastify|python|node|java|go|rust|php|ruby|elixir)\b/.test(i))return "service";let c=await He(f.join(e,"package.json"));if(c){let d={...c.dependencies??{},...c.devDependencies??{}},l=c.scripts??{},p=Object.values(l).filter(u=>typeof u=="string").join(" ").toLowerCase();if(d.next||d.react||d.vue||d.svelte||d.vite||d["@angular/core"]||p.includes("next ")||p.includes("vite "))return "frontend";if(c.private===true&&!d.express&&!d["@nestjs/core"])return "library"}return await P.pathExists(f.join(e,"Dockerfile"))||await P.pathExists(f.join(e,"docker-compose.yml"))||await P.pathExists(f.join(e,"terraform.tf"))?"infra":"service"}var gt=new Set(c().map(e=>e.id)),ht=[...i().map(e=>({id:e.kitId,aliases:[...e.aliases],ecosystem:e.framework,status:"available",canExecuteCreate:true,officialCommands:[e.commandDisplay("<name>",{skipGit:false,skipInstall:false})],adoptAfterCreate:true})),{id:"wordpress-site",aliases:["wordpress","wordpress-site","wp","wp-site"],ecosystem:"wordpress",status:"planned",canExecuteCreate:false,officialCommands:["wp core download","wp config create","wp db create","wp core install"],adoptAfterCreate:true},{id:"wordpress-block",aliases:["wordpress-block","wp-block","gutenberg-block"],ecosystem:"wordpress",status:"planned",canExecuteCreate:false,officialCommands:["npx @wordpress/create-block@latest <slug>"],adoptAfterCreate:true},{id:"laravel",aliases:["laravel","php-laravel"],ecosystem:"php",status:"planned",canExecuteCreate:false,officialCommands:["composer create-project laravel/laravel <name>"],adoptAfterCreate:true},{id:"symfony",aliases:["symfony","php-symfony"],ecosystem:"php",status:"planned",canExecuteCreate:false,officialCommands:["composer create-project symfony/skeleton <name>"],adoptAfterCreate:true},{id:"rails",aliases:["rails","ruby-on-rails","ruby-rails"],ecosystem:"ruby",status:"planned",canExecuteCreate:false,officialCommands:["rails new <name>"],adoptAfterCreate:true}],V=new Map;for(let e of ht){V.set(e.id,e);for(let t of e.aliases)V.set(t,e);}var kt=new Set(["php","ruby","rust","elixir","clojure","scala","kotlin","unknown"]);function F(e){return e?.trim().toLowerCase()||void 0}function Ve(e){let t=F(e.kitId)??F(e.framework)??F(e.runtime)??"unknown";if(e.projectExists)return {lane:"existing",status:"available",canExecuteCreate:false,requested:t,reason:"Existing projects enter Workspace Intelligence through adopt/import."};let r=e.kitId?b$2(e.kitId):void 0;if(r&>.has(r))return {lane:"native",status:"available",canExecuteCreate:true,requested:t,resolved:r,reason:"Workspai owns the create contract, project marker, registry, doctor, and workspace model path."};let o=V.get(t)??V.get(F(e.framework)??"")??V.get(F(e.runtime)??"");if(o)return {lane:"official",status:o.status,canExecuteCreate:o.canExecuteCreate,requested:t,resolved:o.id,officialCommands:o.officialCommands,fallbackLane:o.canExecuteCreate?void 0:"existing",reason:o.status==="available"?"Workspai runs the official ecosystem generator, then registers the project in Workspace Intelligence.":"Official generator support is planned but not enabled; use adopt/import until Workspai owns the post-create contract."};let s=F(e.runtime);return s&&kt.has(s)?{lane:"existing",status:"available",canExecuteCreate:false,requested:t,resolved:s,reason:"Runtime can be governed through Workspace Intelligence, but native create is not supported."}:{lane:"existing",status:"available",canExecuteCreate:false,requested:t,reason:"No native create contract is available; use adopt/import to enter Workspace Intelligence."}}function br(e){return !e.canExecuteCreate&&(e.lane==="official"||e.lane==="existing"&&e.resolved!==void 0)}var Ke="workspace-dependency-graph.v1",Be=["code-import","package-dep","event-pub-sub","service-dependsOn","shared-resource"];var Wr="rapidkit-freshness-metadata-v1";function le(e){if(Array.isArray(e))return e.map(t=>le(t));if(e&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=le(e[r]);return t}return e}function wt(e){return JSON.stringify(le(e))}function M(e){return yt.createHash("sha256").update(wt(e)).digest("hex")}var Le=".workspai/workspace-graph.overrides.json",vt=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs"]),bt=new Set([".git",".hg",".svn",".workspai",".rapidkit",".venv","node_modules","dist","build","out","target","coverage","htmlcov",".next",".turbo",".cache"]),Ue=600,Je=5,jt=256*1024,ze={inferred:1,contract:2,manual:3};function Ct(e){return e.split(f.sep).join("/")}function Z(e,t){return Ct(f.relative(e,t)||".")}function qe(e){let t=new Map;for(let r of e.projects)t.has(r.name)||t.set(r.name,{id:r.name,path:r.path,...r.runtime?{runtime:r.runtime}:{},...r.framework?{framework:r.framework}:{},...r.kind?{kind:r.kind}:{}});return [...t.values()].sort((r,o)=>r.id.localeCompare(o.id))}function Xe(e,t){let r=new Map,o=new Map;for(let n of t.projects){if(r.has(n.name))continue;let a=n.absolutePath?f.resolve(n.absolutePath):f.resolve(e,n.path);r.set(n.name,a),o.has(a)||o.set(a,n.name);}let s=[...o.entries()].map(([n,a])=>({dir:n,id:a})).sort((n,a)=>a.dir.length-n.dir.length||n.dir.localeCompare(a.dir));return {idToDir:r,dirToId:o,sortedDirs:s}}function ee(e,t){let r=f.resolve(t);for(let{dir:o,id:s}of e.sortedDirs)if(r===o||r.startsWith(`${o}${f.sep}`))return s;return null}async function me(e){try{if(!await P.pathExists(e))return null;let t=await P.readJSON(e);return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}async function he(e){try{return await P.pathExists(e)?await P.readFile(e,"utf8"):null}catch{return null}}async function Ye(e,t){let r=[],o=new Map;for(let[s,n]of t.idToDir.entries()){let a=await me(f.join(n,"package.json")),i=typeof a?.name=="string"?a.name.trim():"";i&&!o.has(i)&&o.set(i,s);}for(let[s,n]of t.idToDir.entries()){let a=await me(f.join(n,"package.json"));if(a){let i=["dependencies","devDependencies","peerDependencies","optionalDependencies"],c=new Set;for(let d of i){let l=a[d];if(!(!l||typeof l!="object"||Array.isArray(l)))for(let p of Object.keys(l)){let u=o.get(p);!u||u===s||c.has(u)||(c.add(u),r.push({from:s,to:u,kind:"package-dep",source:"inferred",confidence:"high",evidence:[{file:Z(e,f.join(n,"package.json")),detail:`declares dependency ${p}`}]}));}}}r.push(...await Et(e,t,s,n)),r.push(...await St(e,t,s,n));}return r}async function Et(e,t,r,o){let s=await he(f.join(o,"pyproject.toml"));if(!s)return [];let n=[],a=new Set,i=/path\s*=\s*["']([^"']+)["']/g,c;for(;(c=i.exec(s))!==null;){let d=ee(t,f.resolve(o,c[1]));!d||d===r||a.has(d)||(a.add(d),n.push({from:r,to:d,kind:"package-dep",source:"inferred",confidence:"high",evidence:[{file:Z(e,f.join(o,"pyproject.toml")),detail:`path dependency ${c[1]}`}]}));}return n}async function St(e,t,r,o){let s=await he(f.join(o,"go.mod"));if(!s)return [];let n=[],a=new Set,i=/replace\s+\S+\s+=>\s+(\.[^\s]+)/g,c;for(;(c=i.exec(s))!==null;){let d=ee(t,f.resolve(o,c[1]));!d||d===r||a.has(d)||(a.add(d),n.push({from:r,to:d,kind:"package-dep",source:"inferred",confidence:"high",evidence:[{file:Z(e,f.join(o,"go.mod")),detail:`go.mod replace ${c[1]}`}]}));}return n}async function Pt(e,t){let r=[],o=[e];for(;o.length>0&&r.length<t;){let s=o.shift();if(!s)continue;let n=[];try{n=await P.readdir(s,{withFileTypes:true});}catch{continue}let a=[],i=[];for(let c of n)if(c.isDirectory()){if(bt.has(c.name)||c.name.startsWith("."))continue;a.push(f.join(s,c.name));}else c.isFile()&&vt.has(f.extname(c.name))&&i.push(f.join(s,c.name));i.sort((c,d)=>c.localeCompare(d)),a.sort((c,d)=>c.localeCompare(d));for(let c of i){if(r.length>=t)break;r.push(c);}o.push(...a);}return r}var Wt=[/\bfrom\s+["']([^"']+)["']/g,/\bimport\s+["']([^"']+)["']/g,/\bimport\s*\(\s*["']([^"']+)["']\s*\)/g,/\brequire\s*\(\s*["']([^"']+)["']\s*\)/g];function xt(e){let t=new Set;for(let r of Wt){r.lastIndex=0;let o;for(;(o=r.exec(e))!==null;){let s=o[1];s.startsWith(".")&&t.add(s);}}return [...t]}async function ge(e,t,r,o){let s=new Map;for(let[n,a]of t.idToDir.entries()){if(o&&!o.has(n))continue;let i=await Pt(a,r);for(let c of i){let d=await P.stat(c).catch(()=>null);if(!d||d.size>jt)continue;let l=await he(c);if(l)for(let p of xt(l)){let u=f.resolve(f.dirname(c),p),m=ee(t,u);if(!m||m===n)continue;let E=`${n}\0${m}`,w=s.get(E);w||(w={from:n,to:m,evidence:[]},s.set(E,w)),w.evidence.length<Je&&w.evidence.push({file:Z(e,c),detail:`imports ${p}`});}}}return [...s.values()].map(n=>({from:n.from,to:n.to,kind:"code-import",source:"inferred",confidence:"medium",evidence:n.evidence}))}function Rt(e,t,r){let o=new Map;for(let s of r.projects){let n=At(e,t,s);n&&o.set(s.slug,n);}return o}function At(e,t,r){let o=[r.relativePath,r.externalPath].filter(s=>typeof s=="string"&&s.length>0);for(let s of o){let n=f.resolve(e,s),a=t.dirToId.get(n)??ee(t,n);if(a)return a}return t.idToDir.has(r.slug)?r.slug:null}function Qe(e,t,r){let o=[],s=Rt(e,t,r),n=b$3,a=new Map,i=new Map;for(let c of r.projects){let d=s.get(c.slug);if(!d)continue;let l=c.contracts??{publishes:[],consumes:[],dependsOn:[]};for(let p of l.dependsOn??[]){let u=s.get(p);!u||u===d||o.push({from:d,to:u,kind:"service-dependsOn",source:"contract",confidence:"high",evidence:[{file:n,detail:`dependsOn ${p}`}]});}for(let p of l.publishes??[])a.has(p)||a.set(p,new Set),a.get(p)?.add(d);for(let p of l.consumes??[])i.has(p)||i.set(p,new Set),i.get(p)?.add(d);}for(let[c,d]of a.entries()){let l=i.get(c);if(l)for(let p of l)for(let u of d)p!==u&&o.push({from:p,to:u,kind:"event-pub-sub",source:"contract",confidence:"high",evidence:[{file:n,detail:`consumes event ${c}`}]});}return o.push(...It(r,s)),o}function ue(e){return e.toLowerCase().replace(/[^a-z0-9]/g,"")}function It(e,t){let r=[],o=e.projects.map(s=>({project:s,id:t.get(s.slug)})).filter(s=>!!s.id).filter(s=>ue(s.project.slug).length>=3);for(let s of e.projects){let n=t.get(s.slug);if(!n)continue;let a=s.contracts?.env??[];if(a.length===0)continue;let i=new Set;for(let c of a){let d=ue(c);for(let l of o)l.id===n||i.has(l.id)||!(d.includes(ue(l.project.slug))&&(l.project.ports?.length??0)>0)||(i.add(l.id),r.push({from:n,to:l.id,kind:"shared-resource",source:"inferred",confidence:"low",evidence:[{file:b$3,detail:`env ${c} references ${l.project.slug}`}]}));}}return r}async function Ze(e,t){let r=await me(f.join(e,Le)),o=Array.isArray(r?.edges)?r?.edges:[],s=[],n=new Set(Be);for(let a of o){if(!a||typeof a!="object"||Array.isArray(a))continue;let i=a,c=typeof i.from=="string"?i.from:"",d=typeof i.to=="string"?i.to:"",l=typeof i.kind=="string"?i.kind:"";if(!t.has(c)||!t.has(d)||c===d||!n.has(l))continue;let p=Array.isArray(i.evidence)?i.evidence.map(u=>u&&typeof u=="object"&&typeof u.file=="string"?{file:u.file,...typeof u.detail=="string"?{detail:u.detail}:{}}:null).filter(u=>!!u):[];s.push({from:c,to:d,kind:l,source:"manual",confidence:"high",evidence:p.length>0?p:[{file:Le,detail:"manual edge"}]});}return s}function Ft(e){return `${e.from}\0${e.to}\0${e.kind}`}function Mt(e){let t=new Set,r=[];for(let o of e){let s=`${o.file}\0${o.detail??""}`;t.has(s)||(t.add(s),r.push(o));}return r.sort((o,s)=>o.file.localeCompare(s.file)||(o.detail??"").localeCompare(s.detail??"")).slice(0,Je)}function Dt(e){let t=new Map;for(let r of e){let o=Ft(r),s=t.get(o);if(!s){t.set(o,{...r,evidence:[...r.evidence]});continue}let n=ze[s.source],a=ze[r.source];a>n?t.set(o,{...r,evidence:[...r.evidence,...s.evidence]}):a===n&&s.evidence.push(...r.evidence);}return [...t.values()].map(r=>({from:r.from,to:r.to,kind:r.kind,source:r.source,confidence:r.confidence,evidence:Mt(r.evidence)})).sort((r,o)=>r.from.localeCompare(o.from)||r.to.localeCompare(o.to)||r.kind.localeCompare(o.kind)||r.source.localeCompare(o.source))}function fe(e){return Math.round(e*1e3)/1e3}function Gt(e){return Math.max(0,Math.min(100,Math.round(e)))}function Ot(e){return e>=75?"critical":e>=50?"high":e>=20?"medium":"low"}function _t(e){return e==="critical"||e==="high"?"strict":e==="medium"?"elevated":"normal"}function Nt(e,t){let r=a$6({nodes:e,edges:t}),o=new Map;for(let s of e){let n=r.byId.get(s.id)??{fanIn:0,fanOut:0,reach:0,betweenness:0,isHotspot:false},a=t.filter(m=>m.from===s.id||m.to===s.id),i=a.filter(m=>m.source==="contract"||m.source==="manual").length,c=a.filter(m=>m.confidence==="low").length,d=[],l=n.reach*20+n.fanIn*14+n.fanOut*8+Math.min(20,n.betweenness*4)+i*8;n.isHotspot&&(l+=24,d.push("Critical-path hotspot in dependency graph")),n.reach>0&&d.push(`Change reaches ${n.reach} dependent project(s)`),n.fanIn>0&&d.push(`${n.fanIn} direct dependent project(s)`),n.fanOut>0&&d.push(`${n.fanOut} direct dependency project(s)`),i>0&&d.push(`${i} contract/manual edge(s)`),c>0&&d.push(`${c} low-confidence inferred edge(s) need review`),a.length===0&&d.push("No dependency evidence connected to this project yet");let p=Gt(l),u=Ot(p);o.set(s.id,{weight:u,score:p,verificationPriority:_t(u),reasons:d.slice(0,5),centrality:{fanIn:n.fanIn,fanOut:n.fanOut,reach:n.reach,betweenness:n.betweenness,isHotspot:n.isHotspot}});}return o}function Tt(e,t){let r=Nt(e,t);return e.map(o=>({...o,operationalProfile:r.get(o.id)}))}function Ht(e,t){let r=new Set;for(let c of t)r.add(c.from),r.add(c.to);let o=e.length,s=t.length,n=e.filter(c=>r.has(c.id)).length,a=Math.max(0,o-n),i=a$6({nodes:e,edges:t});return {nodeCount:o,edgeCount:s,inferredEdges:t.filter(c=>c.source==="inferred").length,contractEdges:t.filter(c=>c.source==="contract").length,manualEdges:t.filter(c=>c.source==="manual").length,authoritativeEdges:t.filter(c=>c.source==="contract"||c.source==="manual").length,lowConfidenceEdges:t.filter(c=>c.confidence==="low").length,orphanCount:a,connectedNodeCount:n,density:fe(o>1?s/(o*(o-1)):0),edgeCoverageRatio:fe(o>0?n/o:1),evidenceCoverageRatio:fe(s>0?t.filter(c=>c.evidence.length>0).length/s:1),hotspotCount:i.hotspots.length,hasCycle:Vt(e,t)}}function $t(e,t,r){let o=[],s=e.filter(n=>!t.some(a=>a.from===n.id||a.to===n.id)).map(n=>n.id).sort((n,a)=>n.localeCompare(a));return r.nodeCount===0&&o.push({code:"graph.empty",severity:"info",message:"Workspace model has no projects, so dependency reasoning is unavailable.",recommendation:"Import, scaffold, or register projects before relying on graph-aware impact."}),r.nodeCount>1&&r.edgeCount===0?o.push({code:"graph.edges.missing",severity:"warning",message:"Projects were detected, but no inter-project dependency edges were found.",recommendation:"Run graph explain, add workspace contract relationships, or define manual graph overrides for operational dependencies that code imports cannot reveal.",nodeIds:s}):r.orphanCount>0&&o.push({code:"graph.orphans.detected",severity:"warning",message:`${r.orphanCount} project(s) have no dependency evidence connected to the graph.`,recommendation:"Review isolated projects and add package, contract, or manual edges when they participate in release-critical flows.",nodeIds:s.slice(0,12)}),r.lowConfidenceEdges>0&&o.push({code:"graph.low_confidence_edges",severity:"info",message:`${r.lowConfidenceEdges} inferred edge(s) are low confidence.`,recommendation:"Promote important low-confidence relationships to workspace contract or manual overrides."}),r.edgeCount>0&&r.evidenceCoverageRatio<1&&o.push({code:"graph.evidence.partial",severity:"warning",message:"Some dependency edges do not include file-level evidence.",recommendation:"Attach evidence to manual overrides so agents can audit why a relationship exists."}),r.hasCycle&&o.push({code:"graph.cycle.detected",severity:"error",message:"The dependency graph contains at least one directed cycle.",recommendation:"Break the cycle or document the relationship explicitly before using graph-aware release gates."}),o.sort((n,a)=>{let i={error:0,warning:1,info:2};return i[n.severity]-i[a.severity]||n.code.localeCompare(a.code)})}function Vt(e,t){let r=new Map;for(let c of e)r.set(c.id,[]);for(let c of t)r.has(c.from)||r.set(c.from,[]),r.get(c.from)?.push(c.to);let o=0,s=1,n=2,a=new Map;for(let c of r.keys())a.set(c,o);let i=c=>{let d=[{id:c,index:0}];for(a.set(c,s);d.length>0;){let l=d[d.length-1],p=r.get(l.id)??[];if(l.index>=p.length){a.set(l.id,n),d.pop();continue}let u=p[l.index];l.index+=1;let m=a.get(u)??o;if(m===s)return true;m===o&&(a.set(u,s),d.push({id:u,index:0}));}return false};for(let c of [...r.keys()].sort())if(a.get(c)===o&&i(c))return true;return false}function et(e,t,r,o){let s=Dt(r.filter(c=>t.has(c.from)&&t.has(c.to))),n=Tt(e,s),a=Ht(e,s),i=$t(e,s,a);return {schemaVersion:Ke,generatedAt:(o??new Date).toISOString(),nodes:n,edges:s,stats:a,...i.length>0?{diagnostics:i}:{}}}async function tt(e){let t=f.resolve(e.workspacePath),r=e.maxImportFilesPerProject??Ue,o=qe(e.model),s=new Set(o.map(i=>i.id)),n=Xe(t,e.model),a=[];return a.push(...await Ye(t,n)),a.push(...await ge(t,n,r)),e.contract&&a.push(...Qe(t,n,e.contract)),a.push(...await Ze(t,s)),et(o,s,a,e.now)}async function rt(e){let t=f.resolve(e.workspacePath),r=e.maxImportFilesPerProject??Ue,o=qe(e.model),s=new Set(o.map(i=>i.id)),n=Xe(t,e.model),a=[];if(a.push(...await Ye(t,n)),e.structuralChange)a.push(...await ge(t,n,r));else {a.push(...await ge(t,n,r,e.changedProjectIds));for(let i of e.previousGraph.edges)i.kind==="code-import"&&i.source==="inferred"&&!e.changedProjectIds.has(i.from)&&s.has(i.from)&&s.has(i.to)&&a.push({from:i.from,to:i.to,kind:"code-import",source:"inferred",confidence:i.confidence,evidence:i.evidence});}return e.contract&&a.push(...Qe(t,n,e.contract)),a.push(...await Ze(t,s)),et(o,s,a,e.now)}var ye="workspace-model-cache.v1",ke=".workspai/cache/workspace-model.v1.json",nt=["package.json","pyproject.toml","requirements.txt","go.mod","go.sum","pom.xml","build.gradle","build.gradle.kts","Cargo.toml","composer.json","Gemfile","workspai.project.json",".workspai/project.json",".workspai/context.json","rapidkit.project.json",".rapidkit/project.json",".rapidkit/context.json"],ot=[".workspai/workspace.contract.json",".workspai/workspace.json","workspai.workspace.json",".workspai/policies.yml",".workspai/policies.yaml",".rapidkit/workspace.contract.json",".rapidkit/workspace.json","rapidkit.workspace.json",".rapidkit/policies.yml",".rapidkit/policies.yaml"],Lt=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs"]),zt=new Set([".git",".workspai",".rapidkit","node_modules","dist","build","out","target","coverage",".next",".turbo",".cache",".venv"]),Ut=1500,K=null;function we(){if(K)return K;try{K=createRequire(import.meta.url)("../package.json")?.version??"0.0.0";}catch{K="0.0.0";}return K}async function te(e){try{let t=await P.readFile(e);return yt.createHash("sha256").update(t).digest("hex")}catch{return null}}async function Jt(e){let t={};for(let s of nt){let n=await te(f.join(e,s));n&&(t[s]=n);}let r=[],o=[e];for(;o.length>0&&r.length<Ut;){let s=o.shift();if(!s)continue;let n=[];try{n=await P.readdir(s,{withFileTypes:true});}catch{continue}let a=[];for(let i of n)if(i.isDirectory()){if(zt.has(i.name)||i.name.startsWith("."))continue;a.push(f.join(s,i.name));}else if(i.isFile()&&Lt.has(f.extname(i.name))){let c=f.join(s,i.name),d=await P.stat(c).catch(()=>null);if(d){let l=f.relative(e,c).split(f.sep).join("/");r.push(`${l}:${d.size}:${Math.round(d.mtimeMs)}`);}}a.sort((i,c)=>i.localeCompare(c)),o.push(...a);}return r.sort((s,n)=>s.localeCompare(n)),M({manifests:t,source:r})}async function re(e,t){let r=f.resolve(e),o={},s=[...new Set(t.map(n=>f.relative(r,f.resolve(n)).split(f.sep).join("/")))].sort((n,a)=>n.localeCompare(a));for(let n of s)o[n]=await Jt(f.join(r,n));return o}async function ne(e){let t=f.resolve(e),r={};for(let o of ot){let s=await te(f.join(t,o));s&&(r[o]=s);}return r}async function oe(e){let t=f.resolve(e.workspacePath),r=[...new Set(e.projectPaths.map(n=>f.relative(t,f.resolve(n)).split(f.sep).join("/")))].sort((n,a)=>n.localeCompare(a)),o=[];for(let n of r){let a={};for(let i of nt){let c=await te(f.join(t,n,i));c&&(a[i]=c);}o.push({project:n,manifests:a});}let s={};for(let n of ot){let a=await te(f.join(t,n));a&&(s[n]=a);}return M({cacheSchema:ye,cliVersion:e.cliVersion,flags:e.flags,workspaceJson:e.workspaceJson??null,marker:e.marker??null,projects:o,workspaceFiles:s})}async function ve(e){let t=await f$1(e,ke)??c$1(e,ke);try{if(!await P.pathExists(t))return null;let r=await P.readJson(t);return !r||r.schemaVersion!==ye||typeof r.inputsHash!="string"||typeof r.cliVersion!="string"||!r.model?null:r}catch{return null}}async function se(e,t){let r={schemaVersion:ye,...t};return g(e,ke,r)}var st="rapidkit-fact-freshness-v1",L={durable:720*60*60,derived:10080*60,evidenceBacked:1440*60,live:300,verifyBeforeUse:1440*60};function qt(e){switch(e){case "durable":return L.durable;case "derived":return L.derived;case "evidence-backed":return L.evidenceBacked;case "live":return L.live;case "verify-before-use":return L.verifyBeforeUse}}function Xt(e){if(e.status)return e.status;if(e.ttlSeconds===null)return "unknown";let t=Date.parse(e.generatedAt);if(!Number.isFinite(t))return "unknown";let r=t+e.ttlSeconds*1e3;return e.now.getTime()>r?"stale":"fresh"}function Yt(e){let t=e.now??new Date,r=e.generatedAt??t.toISOString(),o=Date.parse(r),s=Number.isFinite(o),n=s?r:t.toISOString(),a=e.ttlSeconds===void 0?qt(e.kind):e.ttlSeconds,i=Xt({generatedAt:n,ttlSeconds:a,status:e.status??(s?void 0:"unknown"),now:t}),c=Date.parse(n),d=a===null||!Number.isFinite(c)?void 0:new Date(c+a*1e3),l=e.verifyBeforeUse??(e.kind==="live"||e.kind==="verify-before-use"||e.category!=="structure"||i!=="fresh");return {schemaVersion:st,kind:e.kind,category:e.category,generatedAt:n,ttlSeconds:a,...d?{expiresAt:d.toISOString()}:{},status:i,verifyBeforeUse:l,...e.sourceArtifact?{sourceArtifact:e.sourceArtifact}:{},...e.sourcePath?{sourcePath:e.sourcePath}:{},inputsHash:e.inputsHash??M(e.value??null),reason:e.reason}}function v(e){return {id:e.id,label:e.label,scope:e.scope,value:e.value,...e.project?{project:e.project}:{},freshness:Yt({...e.freshness,value:e.value})}}function at(e){let t=e.generatedAt??(e.now??new Date).toISOString(),r={durable:0,derived:0,"evidence-backed":0,live:0,"verify-before-use":0},o={structure:0,verification:0,state:0},s=0,n=0,a=0,i=0;for(let c of e.facts)r[c.freshness.kind]+=1,o[c.freshness.category]+=1,c.freshness.status==="stale"&&(s+=1),c.freshness.status==="unknown"&&(n+=1),c.freshness.kind==="live"&&(a+=1),c.freshness.verifyBeforeUse&&(i+=1);return {schemaVersion:st,generatedAt:t,status:s>0?"stale":n>0?"unknown":"fresh",totalFacts:e.facts.length,staleFacts:s,unknownFacts:n,liveFacts:a,verifyBeforeUseFacts:i,byKind:r,byCategory:o}}var Qt=b$1.model,ct=a.model,Zt=["package.json","pyproject.toml","requirements.txt","go.mod","pom.xml","build.gradle","build.gradle.kts","Cargo.toml","composer.json","Gemfile","mix.exs","deno.json","deno.jsonc","bun.lock","bun.lockb","deps.edn","project.clj","build.sbt","docker-compose.yml","docker-compose.yaml","terraform.tf"],er=new Set([".git",".hg",".svn",".workspai",".rapidkit",".venv","node_modules","dist","build","target","coverage","htmlcov",".next",".turbo"]);function dt(e,t){return (f.relative(e,t)||".").split(f.sep).join("/")}async function pt(e){try{if(!await P.pathExists(e))return null;let t=await P.readJSON(e);return t&&typeof t=="object"?t:null}catch{return null}}async function tr(e,t){for(let r of t)if(await P.pathExists(f.join(e,r)))return true;return false}function be(e){let t=Number.parseInt(process.env.RAPIDKIT_WORKSPACE_MODEL_SCAN_DEPTH??"",10),r=typeof e=="number"&&Number.isFinite(e)?e:Number.isFinite(t)?t:4;return Math.min(12,Math.max(1,Math.trunc(r)))}async function je(e,t){let r=f.resolve(e),o=[{dirPath:r,depth:0}],s=new Set,n=new Set;for(;o.length>0;){let a=o.shift();if(!a)continue;let i=f.resolve(a.dirPath);if(n.has(i))continue;if(n.add(i),i!==r&&await tr(i,Zt)){s.add(i);continue}if(a.depth>=t)continue;let c=[];try{c=await P.readdir(i,{withFileTypes:true});}catch{continue}for(let d of c)!d.isDirectory()||er.has(d.name)||d.name.startsWith(".")&&d.name!==".config"||o.push({dirPath:f.join(i,d.name),depth:a.depth+1});}return Array.from(s).sort((a,i)=>a.localeCompare(i))}function Ce(e){let t=new Set,r=[];for(let o of e){let s=f.resolve(o);t.has(s)||(t.add(s),r.push(s));}return r.sort((o,s)=>o.localeCompare(s))}function it(e,t){let r=e?.[t];return typeof r=="string"&&r.trim()?r.trim():void 0}function rr(e,t){return e?.[t]===true}function nr(e,t,r){let o=e?.frontend&&typeof e.frontend=="object"&&!Array.isArray(e.frontend)?e.frontend:void 0,s=it(o,"generator"),n=it(o,"command_display"),a=typeof t=="string"&&t.startsWith("frontend.");if(!(!s&&!a))return {...s?{id:s}:{},...t?{kit:t}:{},displayName:r,source:rr(o,"official_generator")?"official-generator":"metadata",...n?{commandDisplay:n}:{}}}async function or(e){let t=[".workspai/project.json",".workspai/context.json",".rapidkit/project.json",".rapidkit/context.json","package.json","pyproject.toml","requirements.txt","go.mod","pom.xml","build.gradle","build.gradle.kts","Cargo.toml","composer.json","Gemfile","mix.exs","deno.json","Dockerfile","docker-compose.yml","README.md"],r=[];for(let o of t)await P.pathExists(f.join(e,o))&&r.push(o);return r}async function S(e,t,r,o=t){let s=await f$1(e,t),n=s!==null,a={path:o.split(f.sep).join("/"),exists:n};if(s&&r){let i=await pt(s);typeof i?.generatedAt=="string"&&(a.generatedAt=i.generatedAt);let c=i?.status??i?.result??i?.verdict;typeof c=="string"&&(a.status=c);}return a}async function sr(e,t,r){let o=dt(e,t),s=".workspai/reports",n=c=>S(t,`${s}/${c}`,r,`${o}/${s}/${c}`),a=await n("doctor-project-last-run.json");return {doctor:a?.exists===true?a:await n("doctor-last-run.json"),remediationPlan:await n("doctor-remediation-plan-last-run.json"),fixResult:await n("doctor-fix-result-last-run.json"),analyze:await n("analyze-last-run.json"),readiness:await n("release-readiness-last-run.json")}}async function ar(e,t,r){let o=d(t),s=i$1(t,o),n=q(t),a=a$5(s.runtime),i=await $e(t,o),c=typeof o?.name=="string"&&o.name.trim()?o.name.trim():f.basename(t),d$1=typeof o?.kit_name=="string"?o.kit_name:typeof o?.kit=="string"?o.kit:void 0,l=typeof o?.engine=="string"?o.engine:n.engine!=="unknown"?n.engine:void 0,p=nr(o,d$1,s.displayName),u=Ve({kitId:d$1,framework:s.key,runtime:s.runtime});return {name:c,path:dt(e,t),...r.includeAbsolutePaths?{absolutePath:t}:{},kind:i,runtime:s.runtime,runtimeCandidates:h(t),framework:s.key,frameworkDisplayName:s.displayName,confidence:s.confidence,detectionSource:s.source,supportTier:s.supportTier,runtimeSupportTier:a.tier,runtimeDoctorSupport:a.doctorSupport,moduleSupport:n.moduleSupport,...d$1?{kit:d$1}:{},...l?{engine:l}:{},...p?{generator:p}:{},createCapability:u,commands:{supported:n.supportedCommands,unsupported:n.unsupportedCommands,global:n.globalCommands,fleetStages:n.fleetStages,localOnly:n.localOnlyCommands,map:n.commandMap},importantFiles:await or(t),evidence:await sr(e,t,r.includeEvidence),provenance:{path:"filesystem discovery",runtime:s.source,framework:s.source,commands:"project command capability matrix",createCapability:"create planner capability contract",evidence:"project .workspai/reports"}}}async function Ee(e){for(let t of o(e,"workspace.json")){let r=await pt(t);if(r)return r}return null}function ir(e){return e.length===0?"empty-workspace":e.some(t=>t.kind==="frontend")&&e.length>1?"full-stack-workspace":e.some(t=>t.kind==="frontend")?"frontend-workspace":e.length>1?"backend-platform":"backend-workspace"}function cr(e){let t=new Set;for(let r of e){let o=`${r.name} ${r.path}`.toLowerCase();for(let s of ["auth","billing","payment","notification","order","admin","report","search","analytics"])o.includes(s)&&t.add(s);}return Array.from(t).sort()}function C(e,t,r,o){return {severity:e,code:t,message:r,target:o}}function lt(e){let t=[];e.workspace.name.trim()||t.push(C("error","workspace.name.missing","Workspace name could not be resolved.","workspace")),e.workspace.type==="observed-workspace"&&t.push(C("warning","workspace.marker.missing","Workspace marker is missing; model is based on filesystem observation.","workspace.marker")),e.summary.projectCount===0&&t.push(C("warning","workspace.projects.empty","No project roots were detected in this workspace.","projects")),e.contracts.exists||t.push(C("warning","workspace.contract.missing","Workspace contract is missing; dependency and API edges may be incomplete.",e.contracts.workspaceContractPath));let r=new Map;for(let n of e.projects){let a=n.name.toLowerCase(),i=r.get(a)??[];i.push(n),r.set(a,i),n.importantFiles.length||t.push(C("warning","project.markers.missing",`Project ${n.name} has no important manifest files recorded.`,n.path)),n.runtime==="unknown"&&t.push(C("warning","project.runtime.unknown",`Project ${n.name} runtime could not be confidently detected.`,n.path));let c=["test","build"];for(let p of c)n.commands.supported.includes(p)&&n.commands.unsupported.includes(p)&&t.push(C("error","project.commands.conflict",`Project ${n.name} marks ${p} as both supported and unsupported.`,n.path));let d=new Set(n.commands.fleetStages),l=new Set(n.commands.localOnly);for(let p of n.commands.fleetStages){l.has(p)&&t.push(C("error","project.commands.scope-conflict",`Project ${n.name} marks ${p} as both fleet and local-only.`,n.path));let u=n.commands.map[p];(!u||u.status!=="supported"||u.fleetEligible!==true||u.executionScope!=="fleet")&&t.push(C("error","project.commands.fleet-stage-invalid",`Project ${n.name} advertises ${p} as a fleet stage without a supported fleet capability.`,n.path));}for(let p of n.commands.localOnly){let u=n.commands.map[p];(!u||u.status!=="supported"||u.executionScope!=="local-only"||u.fleetEligible===true)&&t.push(C("error","project.commands.local-only-invalid",`Project ${n.name} advertises ${p} as local-only without a matching local-only capability.`,n.path));}for(let p of Object.values(n.commands.map))p.status==="supported"&&(p.fleetEligible===true&&!d.has(p.command)&&t.push(C("error","project.commands.fleet-stage-missing",`Project ${n.name} capability ${p.command} is fleet-eligible but missing from fleetStages.`,n.path)),p.executionScope==="local-only"&&p.fleetEligible!==true&&!l.has(p.command)&&t.push(C("error","project.commands.local-only-missing",`Project ${n.name} capability ${p.command} is local-only but missing from localOnly commands.`,n.path)));}for(let[n,a]of r.entries())a.length>1&&t.push(C("error","project.name.duplicate",`Project name "${n}" is ambiguous across ${a.length} project roots.`,a.map(i=>i.path).join(", ")));let o=t.filter(n=>n.severity==="error").length,s=t.filter(n=>n.severity==="warning").length;return {status:o>0?"failed":s>0?"warning":"passed",errors:o,warnings:s,issues:t}}function gn(e){return lt(e)}function b(e){return e.join(".")}function dr(e,t){let r=ct,o=e.generatedAt,s=[v({id:"workspace.name",label:"Workspace name",scope:"workspace",value:e.workspace.name,freshness:{kind:"durable",category:"structure",generatedAt:o,now:t,sourceArtifact:r,sourcePath:b(["workspace","name"]),reason:"Workspace identity is structural metadata and changes through workspace setup."}}),v({id:"workspace.type",label:"Workspace type",scope:"workspace",value:e.identity.workspaceType,freshness:{kind:"derived",category:"structure",generatedAt:o,now:t,sourceArtifact:r,sourcePath:b(["identity","workspaceType"]),reason:"Workspace type is derived from the current project inventory."}}),v({id:"workspace.projectCount",label:"Project count",scope:"workspace",value:e.summary.projectCount,freshness:{kind:"derived",category:"structure",generatedAt:o,now:t,sourceArtifact:r,sourcePath:b(["summary","projectCount"]),reason:"Project count is derived from workspace discovery and should be refreshed after structural changes."}}),v({id:"workspace.runtimeFamilies",label:"Runtime families",scope:"workspace",value:e.identity.runtimeFamilies,freshness:{kind:"derived",category:"structure",generatedAt:o,now:t,sourceArtifact:r,sourcePath:b(["identity","runtimeFamilies"]),reason:"Runtime coverage is inferred from project surfaces."}}),v({id:"workspace.policyMode",label:"Workspace policy mode",scope:"policy",value:e.policies.mode,freshness:{kind:"durable",category:"structure",generatedAt:o,now:t,sourceArtifact:r,sourcePath:b(["policies","mode"]),reason:"Policy mode is configuration, not runtime state."}}),v({id:"workspace.contract.exists",label:"Workspace contract presence",scope:"contract",value:e.contracts.exists,freshness:{kind:"derived",category:"structure",generatedAt:o,now:t,sourceArtifact:r,sourcePath:b(["contracts","exists"]),reason:"Contract presence is derived from workspace files and should be refreshed before release gating."}})];e.graph&&s.push(v({id:"graph.edgeCount",label:"Dependency graph edge count",scope:"graph",value:e.graph.stats.edgeCount,freshness:{kind:"derived",category:"structure",generatedAt:e.graph.generatedAt??o,now:t,sourceArtifact:r,sourcePath:b(["graph","stats","edgeCount"]),reason:"Graph topology is derived from manifests, imports, and workspace contracts."}}),v({id:"graph.evidenceCoverageRatio",label:"Dependency graph evidence coverage",scope:"graph",value:e.graph.stats.evidenceCoverageRatio,freshness:{kind:"derived",category:"structure",generatedAt:e.graph.generatedAt??o,now:t,sourceArtifact:r,sourcePath:b(["graph","stats","evidenceCoverageRatio"]),reason:"Graph evidence coverage changes when dependency evidence or contract edges change."}}));for(let[n,a]of e.projects.entries()){let i=`projects[${n}]`,c={kind:"derived",category:"structure",generatedAt:o,now:t,sourceArtifact:r,reason:"Project facts are derived from workspace discovery, project metadata, and framework probes."};s.push(v({id:`project.${a.name}.kind`,label:`${a.name} kind`,scope:"project",project:a.name,value:a.kind,freshness:{...c,sourcePath:b([i,"kind"])}}),v({id:`project.${a.name}.runtime`,label:`${a.name} runtime`,scope:"project",project:a.name,value:a.runtime,freshness:{...c,sourcePath:b([i,"runtime"])}}),v({id:`project.${a.name}.framework`,label:`${a.name} framework`,scope:"project",project:a.name,value:a.frameworkDisplayName,freshness:{...c,sourcePath:b([i,"frameworkDisplayName"])}}),v({id:`project.${a.name}.supportTier`,label:`${a.name} support tier`,scope:"project",project:a.name,value:a.supportTier,freshness:{...c,sourcePath:b([i,"supportTier"])}}),v({id:`project.${a.name}.safeFleetStages`,label:`${a.name} safe fleet stages`,scope:"command",project:a.name,value:a.commands.fleetStages,freshness:{...c,sourcePath:b([i,"commands","fleetStages"]),reason:"Safe command availability is derived from package and project command surfaces."}}));for(let[d,l]of Object.entries(a.evidence))s.push(v({id:`project.${a.name}.evidence.${d}`,label:`${a.name} ${d} evidence`,scope:"evidence",project:a.name,value:l?{path:l.path,exists:l.exists,status:l.status??null}:{exists:false},freshness:{kind:l?.exists?"evidence-backed":"verify-before-use",category:"verification",generatedAt:l?.generatedAt??o,now:t,status:l?.exists?void 0:"unknown",sourceArtifact:l?.path??r,sourcePath:b([i,"evidence",d]),verifyBeforeUse:true,reason:l?.exists?"Evidence reports can expire or become stale after source changes.":"Missing evidence must be generated before this fact is used for verification."}}));}for(let[n,a]of Object.entries(e.evidence))s.push(v({id:`workspace.evidence.${n}`,label:`Workspace ${n} evidence`,scope:"evidence",value:a?{path:a.path,exists:a.exists,status:a.status??null}:null,freshness:{kind:a?.exists?"evidence-backed":"verify-before-use",category:"verification",generatedAt:a?.generatedAt??o,now:t,status:a?.exists?void 0:"unknown",sourceArtifact:a?.path??r,sourcePath:b(["evidence",n]),verifyBeforeUse:true,reason:a?.exists?"Workspace evidence can expire or become stale after project, dependency, or policy changes.":"Missing workspace evidence must be generated before release or repair decisions."}}));return s}async function ae(e){let t=f.resolve(e.workspacePath),r=e.includeAbsolutePaths===true,o$1=e.includeEvidence===true,s=be(e.observableScanDepth),n=e.now??new Date,[a$4,i,c,d,l]=await Promise.all([a$1(t),Ee(t),a$2(t),a$3(t,{descendIntoMatchedProjects:false}),je(t,s)]),p=Ce([...d,...l,...c.map(g=>f.isAbsolute(g.path)?g.path:f.join(t,g.path))]),u=e.reuseProjectModels,m=await Promise.all(p.map(g=>{if(u){let ut=f.relative(t,f.resolve(g)).split(f.sep).join("/"),Se=u.get(ut);if(Se)return Promise.resolve(Se)}return ar(t,g,{includeAbsolutePaths:r,includeEvidence:o$1})})),E=typeof i?.workspace_name=="string"?i.workspace_name:typeof i?.name=="string"?i.name:a$4?.name||f.basename(t),w=typeof i?.profile=="string"?i.profile:typeof i?.mode=="string"?i.mode:void 0,G=Array.from(new Set(m.map(g=>g.kind))).sort(),A=Array.from(new Set(m.map(g=>g.runtime))).sort(),ie=Array.from(new Set(m.map(g=>g.framework))).sort(),O=[".workspai/policies.yml",".workspai/policies.yaml",".rapidkit/policies.yml",".rapidkit/policies.yaml"].find(g=>P.existsSync(f.join(t,g))),_=o(t,"workspace.contract.json").map(g=>f.relative(t,g).split(f.sep).join("/")).find(g=>P.existsSync(f.join(t,g)))??".workspai/workspace.contract.json",W=await P.pathExists(f.join(t,_)),z={schemaVersion:Qt,generatedAt:n.toISOString(),workspace:{name:E,root:t,...w?{profile:w}:{},type:a$4?"rapidkit-workspace":"observed-workspace",...a$4?{marker:{createdBy:a$4.createdBy,version:a$4.version,createdAt:a$4.createdAt}}:{}},identity:{workspaceType:ir(m),surfaces:G,runtimeFamilies:A,businessCapabilities:cr(m)},discovery:{observableScanDepth:s},projects:m,policies:{mode:typeof i?.policy_mode=="string"?i.policy_mode:typeof i?.policyMode=="string"?i.policyMode:"warn",source:O??null,exists:!!O},contracts:{workspaceContractPath:_,exists:W,status:W?"known":"missing"},evidence:{doctor:await S(t,a.doctor,o$1),projectDoctor:await S(t,".workspai/reports/doctor-project-last-run.json",o$1),doctorRemediationPlan:await S(t,".workspai/reports/doctor-remediation-plan-last-run.json",o$1),artifactRemediationPlan:await S(t,".workspai/reports/artifact-remediation-plan-last-run.json",o$1),doctorFixResult:await S(t,".workspai/reports/doctor-fix-result-last-run.json",o$1),analyze:await S(t,a.analyze,o$1),readiness:await S(t,a.readiness,o$1),pipeline:await S(t,".workspai/reports/pipeline-last-run.json",o$1)},summary:{projectCount:m.length,runtimes:A,frameworks:ie,firstClassProjects:m.filter(g=>g.supportTier==="first-class").length,observedProjects:m.filter(g=>g.supportTier==="observed").length}},N=await fr(t,z,{contractExists:W,now:n,incrementalGraph:e.incrementalGraph}),T={...z,graph:N},y=lt(T),j=dr({...T},n),I=at({facts:j,generatedAt:n.toISOString(),now:n});return {...T,facts:j,factFreshness:I,validation:y}}async function hn(e){if(e.cache!==true)return {model:await ae(e),cache:"disabled"};let t=f.resolve(e.workspacePath),r=be(e.observableScanDepth),o=we(),[s,n,a,i,c]=await Promise.all([a$1(t),Ee(t),a$2(t),a$3(t,{descendIntoMatchedProjects:false}),je(t,r)]),d=Ce([...i,...c,...a.map(w=>f.isAbsolute(w.path)?w.path:f.join(t,w.path))]),l=await oe({workspacePath:t,cliVersion:o,flags:{includeAbsolutePaths:e.includeAbsolutePaths===true,includeEvidence:e.includeEvidence===true,observableScanDepth:r},projectPaths:d,workspaceJson:n,marker:s}),p=await ve(t);if(p&&p.cliVersion===o&&p.inputsHash===l)return {model:p.model,cache:"hit"};let u=await ae({...e}),[m,E]=await Promise.all([re(t,d),ne(t)]);return await se(t,{cliVersion:o,inputsHash:l,generatedAt:(e.now??new Date).toISOString(),model:u,projectSignatures:m,workspaceFileSignatures:E}),{model:u,cache:"miss"}}function pr(e,t){let r=new Set,o=new Set,s=new Set;for(let[n,a]of Object.entries(t))n in e?e[n]!==a&&r.add(n):o.add(n);for(let n of Object.keys(e))n in t||s.add(n);return {changed:r,added:o,removed:s}}function lr(e={},t={}){let r=new Set([...Object.keys(e),...Object.keys(t)]);for(let o of r)if(e[o]!==t[o])return false;return true}async function kn(e){let t=f.resolve(e.workspacePath),r=be(e.observableScanDepth),o=we(),s=e.now??new Date,[n,a,i,c,d]=await Promise.all([a$1(t),Ee(t),a$2(t),a$3(t,{descendIntoMatchedProjects:false}),je(t,r)]),l=Ce([...c,...d,...i.map(y=>f.isAbsolute(y.path)?y.path:f.join(t,y.path))]),p=await ve(t),u=async()=>{let y=await ae({...e}),j=await oe({workspacePath:t,cliVersion:o,flags:{includeAbsolutePaths:e.includeAbsolutePaths===true,includeEvidence:e.includeEvidence===true,observableScanDepth:r},projectPaths:l,workspaceJson:a,marker:n}),[I,g]=await Promise.all([re(t,l),ne(t)]);return await se(t,{cliVersion:o,inputsHash:j,generatedAt:s.toISOString(),model:y,projectSignatures:I,workspaceFileSignatures:g}),{model:y,mode:"full"}};if(!p||p.cliVersion!==o||!p.projectSignatures||!p.model?.graph)return u();let m=await ne(t);if(!lr(p.workspaceFileSignatures,m))return u();let E=await re(t,l),{changed:w,added:G,removed:A}=pr(p.projectSignatures,E);if(w.size===0&&G.size===0&&A.size===0)return {model:p.model,mode:"unchanged"};let ie=new Set([...w,...G]),O=new Map;for(let y of p.model.projects){let j=y.path.split(f.sep).join("/");!ie.has(j)&&!A.has(j)&&O.set(j,y);}let _=new Set,W=false;for(let y of p.model.projects){let j=y.path.split(f.sep).join("/");w.has(j)&&_.add(y.name);}let z=G.size>0||A.size>0,N=await ae({...e,reuseProjectModels:O,incrementalGraph:{previousGraph:p.model.graph,changedProjectIds:_,structuralChange:z||W}});for(let y of p.model.projects){let j=y.path.split(f.sep).join("/");if(!w.has(j))continue;let I=N.projects.find(g=>g.path.split(f.sep).join("/")===j);if(I&&I.name!==y.name){W=true;break}}if(W)return u();let T=await oe({workspacePath:t,cliVersion:o,flags:{includeAbsolutePaths:e.includeAbsolutePaths===true,includeEvidence:e.includeEvidence===true,observableScanDepth:r},projectPaths:l,workspaceJson:a,marker:n});return await se(t,{cliVersion:o,inputsHash:T,generatedAt:s.toISOString(),model:N,projectSignatures:E,workspaceFileSignatures:m}),{model:N,mode:"incremental"}}async function ur(e){try{let{contract:t}=await k({workspacePath:e});return t&&typeof t=="object"?t:null}catch{return null}}async function fr(e,t,r){let o=r.contractExists?await ur(e):null;try{return r.incrementalGraph?await rt({workspacePath:e,model:t,contract:o,now:r.now,previousGraph:r.incrementalGraph.previousGraph,changedProjectIds:r.incrementalGraph.changedProjectIds,structuralChange:r.incrementalGraph.structuralChange}):await tt({workspacePath:e,model:t,contract:o,now:r.now})}catch{let s=t.projects.map(n=>({id:n.name,path:n.path}));return {schemaVersion:"workspace-dependency-graph.v1",generatedAt:r.now.toISOString(),nodes:s,edges:[],stats:{nodeCount:s.length,edgeCount:0,inferredEdges:0,contractEdges:0,manualEdges:0,authoritativeEdges:0,lowConfidenceEdges:0,orphanCount:s.length,connectedNodeCount:0,density:0,edgeCoverageRatio:s.length>0?0:1,evidenceCoverageRatio:1,hotspotCount:0,hasCycle:false},diagnostics:s.length>1?[{code:"graph.inference.failed",severity:"warning",message:"Dependency graph inference failed; model contains projects but no dependency edges.",recommendation:"Run workspace model again after fixing graph inputs, or add workspace contract/manual graph overrides.",nodeIds:s.map(n=>n.id).sort((n,a)=>n.localeCompare(a))}]:void 0}}}async function yn(e,t){return g(t,ct,a$4(e))}export{Wr as a,M as b,st as c,v as d,at as e,Ve as f,br as g,$e as h,Ke as i,Qt as j,ct as k,gn as l,dr as m,ae as n,hn as o,kn as p,yn as q};
|