1
This commit is contained in:
parent
2380b3680d
commit
f594968946
86
.claude/skills/gitnexus/gitnexus-cli/SKILL.md
Normal file
86
.claude/skills/gitnexus/gitnexus-cli/SKILL.md
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
---
|
||||||
|
name: gitnexus-cli
|
||||||
|
description: "Use when the user needs to run GitNexus CLI commands like analyze/index a repo, check status, clean the index, generate a wiki, or list indexed repos. Examples: \"Index this repo\", \"Reanalyze the codebase\", \"Generate a wiki\""
|
||||||
|
---
|
||||||
|
|
||||||
|
# GitNexus CLI Commands
|
||||||
|
|
||||||
|
Commands below use `node .gitnexus/run.cjs <command>` — the project-local runner `gitnexus analyze` drops next to the index. It auto-selects an available runner at call time (global `gitnexus`, else `pnpm dlx`, else `npx`), so no package-manager assumption and no global install is required.
|
||||||
|
|
||||||
|
> **Not analyzed yet, or `node .gitnexus/run.cjs` reports `Cannot find module`** (the gitignored runner is absent — e.g. a fresh clone or `git clean`)? (Re)generate it with `npx gitnexus analyze` from the project root. On **npm 11.x**, if `npx` crashes during install (`node.target is null`), install once with `npm i -g gitnexus` (then `gitnexus analyze`) or use `pnpm --allow-build=@ladybugdb/core --allow-build=gitnexus --allow-build=tree-sitter dlx gitnexus@latest analyze`. See [#1939](https://github.com/abhigyanpatwari/GitNexus/issues/1939).
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
### analyze — Build or refresh the index
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node .gitnexus/run.cjs analyze
|
||||||
|
```
|
||||||
|
|
||||||
|
Run from the project root. This parses all source files, builds the knowledge graph, writes it to `.gitnexus/`, and generates CLAUDE.md / AGENTS.md context files.
|
||||||
|
|
||||||
|
| Flag | Effect |
|
||||||
|
| -------------- | ---------------------------------------------------------------- |
|
||||||
|
| `--force` | Force full re-index even if up to date |
|
||||||
|
| `--embeddings` | Enable embedding generation for semantic search (off by default) |
|
||||||
|
| `--drop-embeddings` | Drop existing embeddings on rebuild. By default, an `analyze` without `--embeddings` preserves them. |
|
||||||
|
| `--pdg` | Build the program-dependence layers used by `explain` and `pdg_query` (taint, CDG, and REACHING_DEF). |
|
||||||
|
|
||||||
|
**When to run:** First time in a project, after major code changes, or when `gitnexus://repo/{name}/context` reports the index is stale. In Claude Code, a PostToolUse hook detects staleness after `git commit` and `git merge` and notifies the agent to run `analyze` — the hook does not run analyze itself, to avoid blocking the agent for up to 120s and risking KuzuDB corruption on timeout.
|
||||||
|
|
||||||
|
### status — Check index freshness
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node .gitnexus/run.cjs status
|
||||||
|
```
|
||||||
|
|
||||||
|
Shows whether the current repo has a GitNexus index, when it was last updated, and symbol/relationship counts. Use this to check if re-indexing is needed.
|
||||||
|
|
||||||
|
### clean — Delete the index
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node .gitnexus/run.cjs clean
|
||||||
|
```
|
||||||
|
|
||||||
|
Deletes the `.gitnexus/` directory and unregisters the repo from the global registry. Use before re-indexing if the index is corrupt or after removing GitNexus from a project.
|
||||||
|
|
||||||
|
| Flag | Effect |
|
||||||
|
| --------- | ------------------------------------------------- |
|
||||||
|
| `--force` | Skip confirmation prompt |
|
||||||
|
| `--all` | Clean all indexed repos, not just the current one |
|
||||||
|
|
||||||
|
### wiki — Generate documentation from the graph
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node .gitnexus/run.cjs wiki
|
||||||
|
```
|
||||||
|
|
||||||
|
Generates repository documentation from the knowledge graph using an LLM. Requires an API key (saved to `~/.gitnexus/config.json` on first use).
|
||||||
|
|
||||||
|
| Flag | Effect |
|
||||||
|
| ------------------- | ----------------------------------------- |
|
||||||
|
| `--force` | Force full regeneration |
|
||||||
|
| `--model <model>` | LLM model (default: minimax/minimax-m2.5) |
|
||||||
|
| `--base-url <url>` | LLM API base URL |
|
||||||
|
| `--api-key <key>` | LLM API key |
|
||||||
|
| `--concurrency <n>` | Parallel LLM calls (default: 3) |
|
||||||
|
| `--gist` | Publish wiki as a public GitHub Gist |
|
||||||
|
|
||||||
|
### list — Show all indexed repos
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node .gitnexus/run.cjs list
|
||||||
|
```
|
||||||
|
|
||||||
|
Lists all repositories registered in `~/.gitnexus/registry.json`. The MCP `list_repos` tool provides the same information.
|
||||||
|
|
||||||
|
## After Indexing
|
||||||
|
|
||||||
|
1. **Read `gitnexus://repo/{name}/context`** to verify the index loaded
|
||||||
|
2. Use the other GitNexus skills (`exploring`, `debugging`, `impact-analysis`, `refactoring`) for your task
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- **"Not inside a git repository"**: Run from a directory inside a git repo
|
||||||
|
- **Index is stale after re-analyzing**: Restart Claude Code to reload the MCP server
|
||||||
|
- **Embeddings slow**: Omit `--embeddings` (it's off by default) or set `OPENAI_API_KEY` for faster API-based embedding
|
||||||
101
.claude/skills/gitnexus/gitnexus-debugging/SKILL.md
Normal file
101
.claude/skills/gitnexus/gitnexus-debugging/SKILL.md
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
---
|
||||||
|
name: gitnexus-debugging
|
||||||
|
description: "Use when the user is debugging a bug, tracing an error, or asking why something fails. Examples: \"Why is X failing?\", \"Where does this error come from?\", \"Trace this bug\""
|
||||||
|
---
|
||||||
|
|
||||||
|
# Debugging with GitNexus
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- "Why is this function failing?"
|
||||||
|
- "Trace where this error comes from"
|
||||||
|
- "Who calls this method?"
|
||||||
|
- "This endpoint returns 500"
|
||||||
|
- Investigating bugs, errors, or unexpected behavior
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
```
|
||||||
|
1. query({search_query: "<error or symptom>"}) → Find related execution flows
|
||||||
|
2. context({name: "<suspect>"}) → See callers/callees/processes
|
||||||
|
3. READ gitnexus://repo/{name}/process/{name} → Trace execution flow
|
||||||
|
4. cypher({statement: "MATCH path..."}) → Custom traces if needed
|
||||||
|
```
|
||||||
|
|
||||||
|
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
```
|
||||||
|
- [ ] Understand the symptom (error message, unexpected behavior)
|
||||||
|
- [ ] query for error text or related code
|
||||||
|
- [ ] Identify the suspect function from returned processes
|
||||||
|
- [ ] context to see callers and callees
|
||||||
|
- [ ] Trace execution flow via process resource if applicable
|
||||||
|
- [ ] cypher for custom call chain traces if needed
|
||||||
|
- [ ] Read source files to confirm root cause
|
||||||
|
```
|
||||||
|
|
||||||
|
## Debugging Patterns
|
||||||
|
|
||||||
|
| Symptom | GitNexus Approach |
|
||||||
|
| -------------------- | ---------------------------------------------------------- |
|
||||||
|
| Error message | `query` for error text → `context` on throw sites |
|
||||||
|
| Wrong return value | `context` on the function → trace callees for data flow |
|
||||||
|
| Intermittent failure | `context` → look for external calls, async deps |
|
||||||
|
| Performance issue | `context` → find symbols with many callers (hot paths) |
|
||||||
|
| Recent regression | `detect_changes` to see what your changes affect |
|
||||||
|
| "How does A reach B?" | `trace` between the two symbols — shortest call chain in one call |
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
**query** — find code related to error:
|
||||||
|
|
||||||
|
```
|
||||||
|
query({search_query: "payment validation error"})
|
||||||
|
→ Processes: CheckoutFlow, ErrorHandling
|
||||||
|
→ Symbols: validatePayment, handlePaymentError, PaymentException
|
||||||
|
```
|
||||||
|
|
||||||
|
**context** — full context for a suspect:
|
||||||
|
|
||||||
|
```
|
||||||
|
context({name: "validatePayment"})
|
||||||
|
→ Incoming calls: processCheckout, webhookHandler
|
||||||
|
→ Outgoing calls: verifyCard, fetchRates (external API!)
|
||||||
|
→ Processes: CheckoutFlow (step 3/7)
|
||||||
|
```
|
||||||
|
|
||||||
|
**cypher** — custom call chain traces:
|
||||||
|
|
||||||
|
```cypher
|
||||||
|
MATCH path = (a)-[:CodeRelation {type: 'CALLS'}*1..2]->(b:Function {name: "validatePayment"})
|
||||||
|
RETURN [n IN nodes(path) | n.name] AS chain
|
||||||
|
```
|
||||||
|
|
||||||
|
**trace** — shortest call chain between two symbols ("how does A reach B?"), one call instead of chaining `context` hops:
|
||||||
|
|
||||||
|
```
|
||||||
|
trace({ from: "processCheckout", to: "fetchRates" })
|
||||||
|
→ status: ok, hopCount: 3
|
||||||
|
→ hops: processCheckout → validatePayment → verifyCard → fetchRates
|
||||||
|
→ edges: CALLS (1.0), CALLS (0.95), CALLS (1.0)
|
||||||
|
```
|
||||||
|
|
||||||
|
When no path exists, `trace` reports the furthest reachable node — exactly where the chain breaks (dynamic dispatch, reflection, or an external boundary).
|
||||||
|
|
||||||
|
## Example: "Payment endpoint returns 500 intermittently"
|
||||||
|
|
||||||
|
```
|
||||||
|
1. query({search_query: "payment error handling"})
|
||||||
|
→ Processes: CheckoutFlow, ErrorHandling
|
||||||
|
→ Symbols: validatePayment, handlePaymentError
|
||||||
|
|
||||||
|
2. context({name: "validatePayment"})
|
||||||
|
→ Outgoing calls: verifyCard, fetchRates (external API!)
|
||||||
|
|
||||||
|
3. READ gitnexus://repo/my-app/process/CheckoutFlow
|
||||||
|
→ Step 3: validatePayment → calls fetchRates (external)
|
||||||
|
|
||||||
|
4. Root cause: fetchRates calls external API without proper timeout
|
||||||
|
```
|
||||||
78
.claude/skills/gitnexus/gitnexus-exploring/SKILL.md
Normal file
78
.claude/skills/gitnexus/gitnexus-exploring/SKILL.md
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
---
|
||||||
|
name: gitnexus-exploring
|
||||||
|
description: "Use when the user asks how code works, wants to understand architecture, trace execution flows, or explore unfamiliar parts of the codebase. Examples: \"How does X work?\", \"What calls this function?\", \"Show me the auth flow\""
|
||||||
|
---
|
||||||
|
|
||||||
|
# Exploring Codebases with GitNexus
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- "How does authentication work?"
|
||||||
|
- "What's the project structure?"
|
||||||
|
- "Show me the main components"
|
||||||
|
- "Where is the database logic?"
|
||||||
|
- Understanding code you haven't seen before
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
```
|
||||||
|
1. READ gitnexus://repos → Discover indexed repos
|
||||||
|
2. READ gitnexus://repo/{name}/context → Codebase overview, check staleness
|
||||||
|
3. query({search_query: "<what you want to understand>"}) → Find related execution flows
|
||||||
|
4. context({name: "<symbol>"}) → Deep dive on specific symbol
|
||||||
|
5. READ gitnexus://repo/{name}/process/{name} → Trace full execution flow
|
||||||
|
```
|
||||||
|
|
||||||
|
> If step 2 says "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
```
|
||||||
|
- [ ] READ gitnexus://repo/{name}/context
|
||||||
|
- [ ] query for the concept you want to understand
|
||||||
|
- [ ] Review returned processes (execution flows)
|
||||||
|
- [ ] context on key symbols for callers/callees
|
||||||
|
- [ ] READ process resource for full execution traces
|
||||||
|
- [ ] Read source files for implementation details
|
||||||
|
```
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
| Resource | What you get |
|
||||||
|
| --------------------------------------- | ------------------------------------------------------- |
|
||||||
|
| `gitnexus://repo/{name}/context` | Stats, staleness warning (~150 tokens) |
|
||||||
|
| `gitnexus://repo/{name}/clusters` | All functional areas with cohesion scores (~300 tokens) |
|
||||||
|
| `gitnexus://repo/{name}/cluster/{name}` | Area members with file paths (~500 tokens) |
|
||||||
|
| `gitnexus://repo/{name}/process/{name}` | Step-by-step execution trace (~200 tokens) |
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
**query** — find execution flows related to a concept:
|
||||||
|
|
||||||
|
```
|
||||||
|
query({search_query: "payment processing"})
|
||||||
|
→ Processes: CheckoutFlow, RefundFlow, WebhookHandler
|
||||||
|
→ Symbols grouped by flow with file locations
|
||||||
|
```
|
||||||
|
|
||||||
|
**context** — 360-degree view of a symbol:
|
||||||
|
|
||||||
|
```
|
||||||
|
context({name: "validateUser"})
|
||||||
|
→ Incoming calls: loginHandler, apiMiddleware
|
||||||
|
→ Outgoing calls: checkToken, getUserById
|
||||||
|
→ Processes: LoginFlow (step 2/5), TokenRefresh (step 1/3)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example: "How does payment processing work?"
|
||||||
|
|
||||||
|
```
|
||||||
|
1. READ gitnexus://repo/my-app/context → 918 symbols, 45 processes
|
||||||
|
2. query({search_query: "payment processing"})
|
||||||
|
→ CheckoutFlow: processPayment → validateCard → chargeStripe
|
||||||
|
→ RefundFlow: initiateRefund → calculateRefund → processRefund
|
||||||
|
3. context({name: "processPayment"})
|
||||||
|
→ Incoming: checkoutHandler, webhookHandler
|
||||||
|
→ Outgoing: validateCard, chargeStripe, saveTransaction
|
||||||
|
4. Read src/payments/processor.ts for implementation details
|
||||||
|
```
|
||||||
138
.claude/skills/gitnexus/gitnexus-guide/SKILL.md
Normal file
138
.claude/skills/gitnexus/gitnexus-guide/SKILL.md
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
---
|
||||||
|
name: gitnexus-guide
|
||||||
|
description: "Use when the user asks about GitNexus itself — available tools, how to query the knowledge graph, MCP resources, graph schema, or workflow reference. Examples: \"What GitNexus tools are available?\", \"How do I use GitNexus?\""
|
||||||
|
---
|
||||||
|
|
||||||
|
# GitNexus Guide
|
||||||
|
|
||||||
|
Quick reference for all GitNexus MCP tools, resources, and the knowledge graph schema.
|
||||||
|
|
||||||
|
## Always Start Here
|
||||||
|
|
||||||
|
For any task involving code understanding, debugging, impact analysis, or refactoring:
|
||||||
|
|
||||||
|
1. **Read `gitnexus://repo/{name}/context`** — codebase overview + check index freshness
|
||||||
|
2. **Match your task to a skill below** and **read that skill file**
|
||||||
|
3. **Follow the skill's workflow and checklist**
|
||||||
|
|
||||||
|
> If step 1 warns the index is stale, run `node .gitnexus/run.cjs analyze` in the terminal first.
|
||||||
|
|
||||||
|
## Skills
|
||||||
|
|
||||||
|
| Task | Skill to read |
|
||||||
|
| -------------------------------------------- | ------------------- |
|
||||||
|
| Understand architecture / "How does X work?" | `gitnexus-exploring` |
|
||||||
|
| Blast radius / "What breaks if I change X?" | `gitnexus-impact-analysis` |
|
||||||
|
| Trace bugs / "Why is X failing?" | `gitnexus-debugging` |
|
||||||
|
| Rename / extract / split / refactor | `gitnexus-refactoring` |
|
||||||
|
| Tools, resources, schema reference | `gitnexus-guide` (this file) |
|
||||||
|
| Index, status, clean, wiki CLI commands | `gitnexus-cli` |
|
||||||
|
|
||||||
|
## Tools Reference
|
||||||
|
|
||||||
|
| Tool | What it gives you |
|
||||||
|
| ---------------- | ------------------------------------------------------------------------ |
|
||||||
|
| `query` | Process-grouped code intelligence — execution flows related to a concept |
|
||||||
|
| `context` | 360-degree symbol view — categorized refs, processes it participates in |
|
||||||
|
| `impact` | Symbol blast radius — what breaks at depth 1/2/3 with confidence |
|
||||||
|
| `trace` | Shortest path between two symbols — "how does A reach B?" in one call |
|
||||||
|
| `detect_changes` | Git-diff impact — what do your current changes affect |
|
||||||
|
| `rename` | Multi-file coordinated rename with confidence-tagged edits |
|
||||||
|
| `cypher` | Raw graph queries (read `gitnexus://repo/{name}/schema` first) |
|
||||||
|
| `explain` | Persisted taint findings — source→sink data flows (needs `analyze --pdg`) |
|
||||||
|
| `pdg_query` | Control/data dependence — what gates X (CDG) / where Y flows (REACHING_DEF); needs `analyze --pdg` |
|
||||||
|
| `check` | Check graph invariants such as circular imports |
|
||||||
|
| `route_map` | API route map — which components/hooks fetch which endpoints, and the handler files that serve them |
|
||||||
|
| `shape_check` | Response-shape drift — keys each route returns vs keys its consumers access (flags MISMATCH) |
|
||||||
|
| `api_impact` | Pre-change report for an API route — consumers, middleware, shape mismatches, risk level |
|
||||||
|
| `tool_map` | MCP/RPC tool definitions and the files that handle them |
|
||||||
|
| `group_list` | List configured multi-repo groups, or one group's config |
|
||||||
|
| `group_sync` | Rebuild a group's Contract Registry (cross-repo HTTP contract links); run after `group.yaml` changes or member re-index |
|
||||||
|
| `list_repos` | Discover indexed repos (paginated — `limit`/`offset`) |
|
||||||
|
|
||||||
|
### Paginating `list_repos`
|
||||||
|
|
||||||
|
`list_repos` is paginated so a large registry is not truncated by MCP/LLM token limits. It takes optional `limit` (default **50**, max **200**) and `offset`, and returns:
|
||||||
|
|
||||||
|
```jsonc
|
||||||
|
{
|
||||||
|
"repositories": [
|
||||||
|
{ "name": "...", "path": "...", "indexedAt": "...", "lastCommit": "...", "stats": { } }
|
||||||
|
],
|
||||||
|
"pagination": {
|
||||||
|
"total": 437,
|
||||||
|
"limit": 50,
|
||||||
|
"offset": 0,
|
||||||
|
"returned": 50,
|
||||||
|
"hasMore": true,
|
||||||
|
"nextOffset": 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To enumerate **every** repository, keep calling with `offset` set to `pagination.nextOffset` until `hasMore` is `false`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
list_repos {} → repos 1–50, nextOffset 50, hasMore true
|
||||||
|
list_repos { offset: 50 } → repos 51–100, nextOffset 100, hasMore true
|
||||||
|
…
|
||||||
|
list_repos { offset: 400 } → repos 401–437, hasMore false (done)
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes: `offset` ≥ `total` returns an empty page (with `total` still reported). Out-of-range or malformed `limit`/`offset` (non-integer, `limit` outside `[1, 200]`, `offset < 0`) are rejected with a clear error — `limit` above the max is rejected, not silently capped. The order is deterministic (lower-cased name, then path), so paging never skips or duplicates an entry while the registry is unchanged.
|
||||||
|
|
||||||
|
### Taint findings (`explain`)
|
||||||
|
|
||||||
|
`explain` returns taint findings recorded by `gitnexus analyze --pdg` — intra-procedural `TAINTED` edges plus cross-function `TAINT_PATH` hops where the interprocedural taint phase found a function-level source→sink chain. Each finding includes a sink category (command-injection, code-injection, path-traversal, sql-injection, xss), source/sink lines, and the ordered hop path with the variable carried on each hop.
|
||||||
|
|
||||||
|
- `explain {}` — enumerate all findings for the repo (bounded by `limit`, deterministic order)
|
||||||
|
- `explain { target: "src/vuln.ts" }` — findings in a file (suffix path match accepted)
|
||||||
|
- `explain { target: "runUserCommand" }` — findings in a function (resolved like `context`; ambiguous names return ranked candidates)
|
||||||
|
|
||||||
|
A repo indexed without `--pdg` returns a clear "no taint layer" note. Caveats: closure/callback, property/field, and implicit flows are not modeled, and interprocedural findings are function-level `TAINT_PATH` hops rather than statement-level path proof, so the absence of a finding is **not** proof of safety. `SANITIZES` (sanitizer-kill) edges are queryable via `cypher`.
|
||||||
|
|
||||||
|
### Control & data dependence (`pdg_query`)
|
||||||
|
|
||||||
|
`pdg_query` reads the control/data-dependence layers `gitnexus analyze --pdg` records (CDG + REACHING_DEF, basic-block granular) — the control/data analog of `explain`. It is **always anchored** (a `target` file path or symbol, resolved like `context`) and has two modes:
|
||||||
|
|
||||||
|
- `pdg_query { mode: "controls", target: "..." }` — CDG: "under what condition does X run?". Each edge is a controlling predicate block → dependent block with the branch sense (`'T'`/`'F'`) in `reason`; an edge into an early `return`/`throw` is flagged `guard: true` (guard-clause discovery — the sense depends on the predicate, so don't filter guards by a fixed label).
|
||||||
|
- `pdg_query { mode: "flows", target: "...", variable?: "..." }` — REACHING_DEF def→use edges within the function; pass `variable` to trace one binding.
|
||||||
|
|
||||||
|
A repo indexed without `--pdg` returns a "no PDG layer" note (or "status unknown" when the layer can't be confirmed). Intra-procedural only — cross-function flow is taint's domain (`explain`). The raw CDG/REACHING_DEF edges are also queryable via `cypher`. See the `gitnexus-pdg-query` skill for the full query surface.
|
||||||
|
|
||||||
|
### Shortest path between two symbols (`trace`)
|
||||||
|
|
||||||
|
`trace` answers "how does A reach B?" in one call — the shortest directed path over `CALLS` (plus `HAS_METHOD`, so a class-rooted trace descends into its methods) instead of chaining 3–8 `context`/`impact` hops by hand.
|
||||||
|
|
||||||
|
- `trace { from: "validateUser", to: "executeQuery" }` — shortest path between two symbols.
|
||||||
|
- Disambiguate common names with `from_uid`/`to_uid` (zero-ambiguity) or `from_file`/`to_file`; an ambiguous name returns ranked candidates.
|
||||||
|
- `maxDepth` (default 10, max 30) bounds the search; `includeTests` (default false) lets the traversal pass through test-file symbols.
|
||||||
|
|
||||||
|
Returns ordered `hops` (each `{ name, filePath, startLine }`) and an aligned `edges[]` of `{ relType, confidence }`, so call hops and containment (`HAS_METHOD`) hops stay distinguishable. When no path exists it reports the **furthest** reachable node (where the chain breaks) and sets `truncated: true` if a traversal cap was hit first. Every result carries a `status`: `ok` / `no_path` / `ambiguous` / `not_found` / `error`.
|
||||||
|
|
||||||
|
Cross-repo (experimental): pass `repo: "@groupName"` to trace across a group's member repos — the path may cross **one** `ContractLink` boundary (reported as a `CONTRACT_LINK` hop with the bridged contract in `crossings[]`). Omit `to` entirely to follow `from`'s outgoing HTTP call to whatever provider endpoint it lands on. Groups are configured via `group_list` / `group_sync`.
|
||||||
|
|
||||||
|
## Resources Reference
|
||||||
|
|
||||||
|
Lightweight reads (~100-500 tokens) for navigation:
|
||||||
|
|
||||||
|
| Resource | Content |
|
||||||
|
| ---------------------------------------------- | ----------------------------------------- |
|
||||||
|
| `gitnexus://repo/{name}/context` | Stats, staleness check |
|
||||||
|
| `gitnexus://repo/{name}/clusters` | All functional areas with cohesion scores |
|
||||||
|
| `gitnexus://repo/{name}/cluster/{clusterName}` | Area members |
|
||||||
|
| `gitnexus://repo/{name}/processes` | All execution flows |
|
||||||
|
| `gitnexus://repo/{name}/process/{processName}` | Step-by-step trace |
|
||||||
|
| `gitnexus://repo/{name}/schema` | Graph schema for Cypher |
|
||||||
|
|
||||||
|
## Graph Schema
|
||||||
|
|
||||||
|
**Nodes:** File, Folder, Function, Class, Interface, Method, CodeElement, Community, Process, Route, Tool, plus language-specific types (Struct, Enum, Trait, Impl, Namespace, Module, …) and BasicBlock (`--pdg` indexes only). The full node list lives in `gitnexus://repo/{name}/schema`.
|
||||||
|
**Edges (via CodeRelation.type):** CALLS, IMPORTS, EXTENDS, IMPLEMENTS, DEFINES, CONTAINS, MEMBER_OF, HAS_METHOD, HAS_PROPERTY, ACCESSES, METHOD_OVERRIDES, METHOD_IMPLEMENTS, STEP_IN_PROCESS, HANDLES_ROUTE, FETCHES, HANDLES_TOOL, ENTRY_POINT_OF, WRAPS, QUERIES, INJECTS, plus `--pdg`-only types (CFG, REACHING_DEF, TAINTED, SANITIZES, TAINT_PATH, CDG — zero rows on a default index).
|
||||||
|
|
||||||
|
Read `gitnexus://repo/{name}/schema` before writing Cypher — it is the authoritative schema for the indexed repo.
|
||||||
|
|
||||||
|
```cypher
|
||||||
|
MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "myFunc"})
|
||||||
|
RETURN caller.name, caller.filePath
|
||||||
|
```
|
||||||
97
.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md
Normal file
97
.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
---
|
||||||
|
name: gitnexus-impact-analysis
|
||||||
|
description: "Use when the user wants to know what will break if they change something, or needs safety analysis before editing code. Examples: \"Is it safe to change X?\", \"What depends on this?\", \"What will break?\""
|
||||||
|
---
|
||||||
|
|
||||||
|
# Impact Analysis with GitNexus
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- "Is it safe to change this function?"
|
||||||
|
- "What will break if I modify X?"
|
||||||
|
- "Show me the blast radius"
|
||||||
|
- "Who uses this code?"
|
||||||
|
- Before making non-trivial code changes
|
||||||
|
- Before committing — to understand what your changes affect
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
```
|
||||||
|
1. impact({target: "X", direction: "upstream"}) → What depends on this
|
||||||
|
2. READ gitnexus://repo/{name}/processes → Check affected execution flows
|
||||||
|
3. detect_changes() → Map current git changes to affected flows
|
||||||
|
4. Assess risk and report to user
|
||||||
|
```
|
||||||
|
|
||||||
|
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
```
|
||||||
|
- [ ] impact({target, direction: "upstream"}) to find dependents
|
||||||
|
- [ ] Review d=1 items first (these WILL BREAK)
|
||||||
|
- [ ] Check high-confidence (>0.8) dependencies
|
||||||
|
- [ ] READ processes to check affected execution flows
|
||||||
|
- [ ] detect_changes() for pre-commit check
|
||||||
|
- [ ] Assess risk level and report to user
|
||||||
|
```
|
||||||
|
|
||||||
|
## Understanding Output
|
||||||
|
|
||||||
|
| Depth | Risk Level | Meaning |
|
||||||
|
| ----- | ---------------- | ------------------------ |
|
||||||
|
| d=1 | **WILL BREAK** | Direct callers/importers |
|
||||||
|
| d=2 | LIKELY AFFECTED | Indirect dependencies |
|
||||||
|
| d=3 | MAY NEED TESTING | Transitive effects |
|
||||||
|
|
||||||
|
## Risk Assessment
|
||||||
|
|
||||||
|
| Affected | Risk |
|
||||||
|
| ------------------------------ | -------- |
|
||||||
|
| <5 symbols, few processes | LOW |
|
||||||
|
| 5-15 symbols, 2-5 processes | MEDIUM |
|
||||||
|
| >15 symbols or many processes | HIGH |
|
||||||
|
| Critical path (auth, payments) | CRITICAL |
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
**impact** — the primary tool for symbol blast radius:
|
||||||
|
|
||||||
|
```
|
||||||
|
impact({
|
||||||
|
target: "validateUser",
|
||||||
|
direction: "upstream",
|
||||||
|
minConfidence: 0.8,
|
||||||
|
maxDepth: 3
|
||||||
|
})
|
||||||
|
|
||||||
|
→ d=1 (WILL BREAK):
|
||||||
|
- loginHandler (src/auth/login.ts:42) [CALLS, 100%]
|
||||||
|
- apiMiddleware (src/api/middleware.ts:15) [CALLS, 100%]
|
||||||
|
|
||||||
|
→ d=2 (LIKELY AFFECTED):
|
||||||
|
- authRouter (src/routes/auth.ts:22) [CALLS, 95%]
|
||||||
|
```
|
||||||
|
|
||||||
|
**detect_changes** — git-diff based impact analysis:
|
||||||
|
|
||||||
|
```
|
||||||
|
detect_changes({scope: "staged"})
|
||||||
|
|
||||||
|
→ Changed: 5 symbols in 3 files
|
||||||
|
→ Affected: LoginFlow, TokenRefresh, APIMiddlewarePipeline
|
||||||
|
→ Risk: MEDIUM
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example: "What breaks if I change validateUser?"
|
||||||
|
|
||||||
|
```
|
||||||
|
1. impact({target: "validateUser", direction: "upstream"})
|
||||||
|
→ d=1: loginHandler, apiMiddleware (WILL BREAK)
|
||||||
|
→ d=2: authRouter, sessionManager (LIKELY AFFECTED)
|
||||||
|
|
||||||
|
2. READ gitnexus://repo/my-app/processes
|
||||||
|
→ LoginFlow and TokenRefresh touch validateUser
|
||||||
|
|
||||||
|
3. Risk: 2 direct callers, 2 processes = MEDIUM
|
||||||
|
```
|
||||||
121
.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md
Normal file
121
.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
---
|
||||||
|
name: gitnexus-refactoring
|
||||||
|
description: "Use when the user wants to rename, extract, split, move, or restructure code safely. Examples: \"Rename this function\", \"Extract this into a module\", \"Refactor this class\", \"Move this to a separate file\""
|
||||||
|
---
|
||||||
|
|
||||||
|
# Refactoring with GitNexus
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- "Rename this function safely"
|
||||||
|
- "Extract this into a module"
|
||||||
|
- "Split this service"
|
||||||
|
- "Move this to a new file"
|
||||||
|
- Any task involving renaming, extracting, splitting, or restructuring code
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
```
|
||||||
|
1. impact({target: "X", direction: "upstream"}) → Map all dependents
|
||||||
|
2. query({search_query: "X"}) → Find execution flows involving X
|
||||||
|
3. context({name: "X"}) → See all incoming/outgoing refs
|
||||||
|
4. Plan update order: interfaces → implementations → callers → tests
|
||||||
|
```
|
||||||
|
|
||||||
|
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
||||||
|
|
||||||
|
## Checklists
|
||||||
|
|
||||||
|
### Rename Symbol
|
||||||
|
|
||||||
|
```
|
||||||
|
- [ ] rename({symbol_name: "oldName", new_name: "newName", dry_run: true}) — preview all edits
|
||||||
|
- [ ] Review graph edits (high confidence) and text_search edits (review carefully)
|
||||||
|
- [ ] If satisfied: rename({..., dry_run: false}) — apply edits
|
||||||
|
- [ ] detect_changes() — verify only expected files changed
|
||||||
|
- [ ] Run tests for affected processes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Extract Module
|
||||||
|
|
||||||
|
```
|
||||||
|
- [ ] context({name: target}) — see all incoming/outgoing refs
|
||||||
|
- [ ] impact({target, direction: "upstream"}) — find all external callers
|
||||||
|
- [ ] Define new module interface
|
||||||
|
- [ ] Extract code, update imports
|
||||||
|
- [ ] detect_changes() — verify affected scope
|
||||||
|
- [ ] Run tests for affected processes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Split Function/Service
|
||||||
|
|
||||||
|
```
|
||||||
|
- [ ] context({name: target}) — understand all callees
|
||||||
|
- [ ] Group callees by responsibility
|
||||||
|
- [ ] impact({target, direction: "upstream"}) — map callers to update
|
||||||
|
- [ ] Create new functions/services
|
||||||
|
- [ ] Update callers
|
||||||
|
- [ ] detect_changes() — verify affected scope
|
||||||
|
- [ ] Run tests for affected processes
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
**rename** — automated multi-file rename:
|
||||||
|
|
||||||
|
```
|
||||||
|
rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true})
|
||||||
|
→ 12 edits across 8 files
|
||||||
|
→ 10 graph edits (high confidence), 2 text_search edits (review)
|
||||||
|
→ Changes: [{file_path, edits: [{line, old_text, new_text, confidence}]}]
|
||||||
|
```
|
||||||
|
|
||||||
|
**impact** — map all dependents first:
|
||||||
|
|
||||||
|
```
|
||||||
|
impact({target: "validateUser", direction: "upstream"})
|
||||||
|
→ d=1: loginHandler, apiMiddleware, testUtils
|
||||||
|
→ Affected Processes: LoginFlow, TokenRefresh
|
||||||
|
```
|
||||||
|
|
||||||
|
**detect_changes** — verify your changes after refactoring:
|
||||||
|
|
||||||
|
```
|
||||||
|
detect_changes({scope: "all"})
|
||||||
|
→ Changed: 8 files, 12 symbols
|
||||||
|
→ Affected processes: LoginFlow, TokenRefresh
|
||||||
|
→ Risk: MEDIUM
|
||||||
|
```
|
||||||
|
|
||||||
|
**cypher** — custom reference queries:
|
||||||
|
|
||||||
|
```cypher
|
||||||
|
MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "validateUser"})
|
||||||
|
RETURN caller.name, caller.filePath ORDER BY caller.filePath
|
||||||
|
```
|
||||||
|
|
||||||
|
## Risk Rules
|
||||||
|
|
||||||
|
| Risk Factor | Mitigation |
|
||||||
|
| ------------------- | ----------------------------------------- |
|
||||||
|
| Many callers (>5) | Use rename for automated updates |
|
||||||
|
| Cross-area refs | Use detect_changes after to verify scope |
|
||||||
|
| String/dynamic refs | query to find them |
|
||||||
|
| External/public API | Version and deprecate properly |
|
||||||
|
|
||||||
|
## Example: Rename `validateUser` to `authenticateUser`
|
||||||
|
|
||||||
|
```
|
||||||
|
1. rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true})
|
||||||
|
→ 12 edits: 10 graph (safe), 2 text_search (review)
|
||||||
|
→ Files: validator.ts, login.ts, middleware.ts, config.json...
|
||||||
|
|
||||||
|
2. Review text_search edits (config.json: dynamic reference!)
|
||||||
|
|
||||||
|
3. rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: false})
|
||||||
|
→ Applied 12 edits across 8 files
|
||||||
|
|
||||||
|
4. detect_changes({scope: "all"})
|
||||||
|
→ Affected: LoginFlow, TokenRefresh
|
||||||
|
→ Risk: MEDIUM — run tests for these flows
|
||||||
|
```
|
||||||
BIN
.gitnexus/lbug
BIN
.gitnexus/lbug
Binary file not shown.
Binary file not shown.
1
.playwright-cli/console-2026-08-16T07-11-48-915Z.log
Normal file
1
.playwright-cli/console-2026-08-16T07-11-48-915Z.log
Normal file
@ -0,0 +1 @@
|
|||||||
|
[ 159ms] [INFO] %cDownload the React DevTools for a better development experience: https://react.dev/link/react-devtools font-weight:bold @ http://127.0.0.1:5173/node_modules/.vite/deps/react-dom_client.js?v=9a31a45b:20102
|
||||||
1
.playwright-cli/console-2026-08-16T07-19-15-689Z.log
Normal file
1
.playwright-cli/console-2026-08-16T07-19-15-689Z.log
Normal file
@ -0,0 +1 @@
|
|||||||
|
[ 158ms] [INFO] %cDownload the React DevTools for a better development experience: https://react.dev/link/react-devtools font-weight:bold @ http://127.0.0.1:5173/node_modules/.vite/deps/react-dom_client.js?v=9a31a45b:20102
|
||||||
0
.playwright-cli/page-2026-08-16T07-11-14-950Z.yml
Normal file
0
.playwright-cli/page-2026-08-16T07-11-14-950Z.yml
Normal file
70
.playwright-cli/page-2026-08-16T07-11-49-316Z.yml
Normal file
70
.playwright-cli/page-2026-08-16T07-11-49-316Z.yml
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
- main [ref=e3]:
|
||||||
|
- generic:
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- region "年度费用模板" [ref=e4]:
|
||||||
|
- generic "筛选条件" [ref=e5]:
|
||||||
|
- button "省市区" [ref=e6] [cursor=pointer]
|
||||||
|
- button "自然地理区位" [ref=e12] [cursor=pointer]
|
||||||
|
- button "设施类别" [ref=e17] [cursor=pointer]
|
||||||
|
- button "建筑性质" [ref=e23] [cursor=pointer]
|
||||||
|
- button "建设阶段" [ref=e28] [cursor=pointer]
|
||||||
|
- button "规划形式" [ref=e35] [cursor=pointer]
|
||||||
|
- button "时间" [ref=e42] [cursor=pointer]
|
||||||
|
- button "面积" [ref=e46] [cursor=pointer]
|
||||||
|
- region "年度总费用图表" [ref=e54]:
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- button "纵坐标:造价(元)" [ref=e57] [cursor=pointer]: 造价(元)
|
||||||
|
- generic [ref=e58]: 正在加载数据
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- figure "图表,共有0个系列":
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img "interactive chart"
|
||||||
|
- region [ref=e61]
|
||||||
|
- toolbar "标注" [ref=e62]:
|
||||||
|
- button "库" [ref=e63] [cursor=pointer]
|
||||||
|
- button "指" [ref=e64] [cursor=pointer]
|
||||||
|
- button "均" [ref=e65] [cursor=pointer]
|
||||||
|
- button "Line Tool" [disabled] [ref=e66]
|
||||||
|
- button "Text Tool" [disabled] [ref=e67]
|
||||||
|
- button "Shape Tool" [disabled] [ref=e68]
|
||||||
|
- button "Fibonacci Tool" [disabled] [ref=e69]
|
||||||
|
- button "全屏(F11)" [ref=e70] [cursor=pointer]
|
||||||
|
- button "Clear annotations" [disabled] [ref=e71]
|
||||||
|
- button "切换到表格" [ref=e72] [cursor=pointer]:
|
||||||
|
- generic: 趋
|
||||||
|
- status:
|
||||||
|
- generic: 请选择右侧分类项
|
||||||
|
- toolbar "缩放" [ref=e73]:
|
||||||
|
- button "缩小" [disabled] [ref=e74]
|
||||||
|
- button "放大" [ref=e75] [cursor=pointer]
|
||||||
|
- button "左移" [disabled] [ref=e76]
|
||||||
|
- button "右移" [disabled] [ref=e77]
|
||||||
|
- button "重置" [disabled] [ref=e78]
|
||||||
|
- generic [ref=e79]: 正在加载数据
|
||||||
|
- button "收起选择区" [expanded] [ref=e81] [cursor=pointer]
|
||||||
|
- complementary "选择内容" [ref=e85]:
|
||||||
|
- tablist "选择内容切换项" [ref=e86]:
|
||||||
|
- tab "自然地理区位" [selected] [ref=e87] [cursor=pointer]
|
||||||
|
- tab "设施类别" [ref=e88] [cursor=pointer]
|
||||||
|
- tab "建设阶段" [ref=e89] [cursor=pointer]
|
||||||
|
- tab "规划形式" [ref=e90] [cursor=pointer]
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- generic [ref=e92]: 自然地理区位
|
||||||
|
- generic [ref=e93]: 加载中
|
||||||
80
.playwright-cli/page-2026-08-16T07-12-14-673Z.yml
Normal file
80
.playwright-cli/page-2026-08-16T07-12-14-673Z.yml
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
- main [ref=e3]:
|
||||||
|
- generic:
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- region "年度费用模板" [ref=e4]:
|
||||||
|
- generic "筛选条件" [ref=e5]:
|
||||||
|
- button "省市区" [ref=e6] [cursor=pointer]
|
||||||
|
- button "自然地理区位" [ref=e12] [cursor=pointer]
|
||||||
|
- button "设施类别" [ref=e17] [cursor=pointer]
|
||||||
|
- button "建筑性质" [active] [ref=e23] [cursor=pointer]
|
||||||
|
- button "建设阶段" [ref=e28] [cursor=pointer]
|
||||||
|
- button "规划形式" [ref=e35] [cursor=pointer]
|
||||||
|
- button "时间" [ref=e42] [cursor=pointer]
|
||||||
|
- button "面积" [ref=e46] [cursor=pointer]
|
||||||
|
- region "年度总费用图表" [ref=e54]:
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- button "纵坐标:造价(元)" [ref=e57] [cursor=pointer]: 造价(元)
|
||||||
|
- generic [ref=e58]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- figure "图表,共有0个系列":
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img "interactive chart"
|
||||||
|
- region [ref=e61]
|
||||||
|
- toolbar "标注" [ref=e62]:
|
||||||
|
- button "库" [ref=e63] [cursor=pointer]
|
||||||
|
- button "指" [ref=e64] [cursor=pointer]
|
||||||
|
- button "均" [ref=e65] [cursor=pointer]
|
||||||
|
- button "Line Tool" [disabled] [ref=e66]
|
||||||
|
- button "Text Tool" [disabled] [ref=e67]
|
||||||
|
- button "Shape Tool" [disabled] [ref=e68]
|
||||||
|
- button "Fibonacci Tool" [disabled] [ref=e69]
|
||||||
|
- button "全屏(F11)" [ref=e70] [cursor=pointer]
|
||||||
|
- button "Clear annotations" [disabled] [ref=e71]
|
||||||
|
- button "切换到表格" [ref=e72] [cursor=pointer]:
|
||||||
|
- generic: 趋
|
||||||
|
- status:
|
||||||
|
- generic: 请选择右侧分类项
|
||||||
|
- toolbar "缩放" [ref=e73]:
|
||||||
|
- button "缩小" [disabled] [ref=e74]
|
||||||
|
- button "放大" [ref=e75] [cursor=pointer]
|
||||||
|
- button "左移" [disabled] [ref=e76]
|
||||||
|
- button "右移" [disabled] [ref=e77]
|
||||||
|
- button "重置" [disabled] [ref=e78]
|
||||||
|
- button "收起选择区" [expanded] [ref=e81] [cursor=pointer]
|
||||||
|
- complementary "选择内容" [ref=e85]:
|
||||||
|
- tablist "选择内容切换项" [ref=e86]:
|
||||||
|
- tab "自然地理区位" [selected] [ref=e87] [cursor=pointer]
|
||||||
|
- tab "设施类别" [ref=e88] [cursor=pointer]
|
||||||
|
- tab "建设阶段" [ref=e89] [cursor=pointer]
|
||||||
|
- tab "规划形式" [ref=e90] [cursor=pointer]
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- generic [ref=e92]: 自然地理区位
|
||||||
|
- generic [ref=e93]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
|
- dialog "建筑性质筛选" [ref=e94]:
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- heading "建筑性质" [level=2] [ref=e96]
|
||||||
|
- button "关闭" [ref=e97] [cursor=pointer]: ×
|
||||||
|
- searchbox "搜索" [ref=e99]
|
||||||
|
- generic [ref=e100]: 未选择
|
||||||
|
- generic [ref=e101]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
|
- generic [ref=e103]:
|
||||||
|
- button "清空当前" [ref=e104] [cursor=pointer]
|
||||||
|
- button "取消" [ref=e105] [cursor=pointer]
|
||||||
|
- button "确认" [ref=e106] [cursor=pointer]
|
||||||
69
.playwright-cli/page-2026-08-16T07-13-28-337Z.yml
Normal file
69
.playwright-cli/page-2026-08-16T07-13-28-337Z.yml
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
- main [ref=e3]:
|
||||||
|
- generic:
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- region "年度费用模板" [ref=e4]:
|
||||||
|
- generic "筛选条件" [ref=e5]:
|
||||||
|
- button "省市区" [ref=e6] [cursor=pointer]
|
||||||
|
- button "自然地理区位" [ref=e12] [cursor=pointer]
|
||||||
|
- button "设施类别" [ref=e17] [cursor=pointer]
|
||||||
|
- button "建筑性质" [ref=e23] [cursor=pointer]
|
||||||
|
- button "建设阶段" [ref=e28] [cursor=pointer]
|
||||||
|
- button "规划形式" [ref=e35] [cursor=pointer]
|
||||||
|
- button "时间" [ref=e42] [cursor=pointer]
|
||||||
|
- button "面积" [ref=e46] [cursor=pointer]
|
||||||
|
- region "年度总费用图表" [ref=e54]:
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- button "纵坐标:造价(元)" [ref=e57] [cursor=pointer]: 造价(元)
|
||||||
|
- generic [ref=e58]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- figure "图表,共有0个系列":
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img "interactive chart"
|
||||||
|
- region [ref=e61]
|
||||||
|
- toolbar "标注" [ref=e62]:
|
||||||
|
- button "库" [ref=e63] [cursor=pointer]
|
||||||
|
- button "指" [ref=e64] [cursor=pointer]
|
||||||
|
- button "均" [ref=e65] [cursor=pointer]
|
||||||
|
- button "Line Tool" [disabled] [ref=e66]
|
||||||
|
- button "Text Tool" [disabled] [ref=e67]
|
||||||
|
- button "Shape Tool" [disabled] [ref=e68]
|
||||||
|
- button "Fibonacci Tool" [disabled] [ref=e69]
|
||||||
|
- button "全屏(F11)" [ref=e70] [cursor=pointer]
|
||||||
|
- button "Clear annotations" [disabled] [ref=e71]
|
||||||
|
- button "切换到表格" [ref=e72] [cursor=pointer]:
|
||||||
|
- generic: 趋
|
||||||
|
- status:
|
||||||
|
- generic: 请选择右侧分类项
|
||||||
|
- toolbar "缩放" [ref=e73]:
|
||||||
|
- button "缩小" [disabled] [ref=e74]
|
||||||
|
- button "放大" [ref=e75] [cursor=pointer]
|
||||||
|
- button "左移" [disabled] [ref=e76]
|
||||||
|
- button "右移" [disabled] [ref=e77]
|
||||||
|
- button "重置" [disabled] [ref=e78]
|
||||||
|
- button "收起选择区" [expanded] [ref=e81] [cursor=pointer]
|
||||||
|
- complementary "选择内容" [ref=e85]:
|
||||||
|
- tablist "选择内容切换项" [ref=e86]:
|
||||||
|
- tab "自然地理区位" [selected] [ref=e87] [cursor=pointer]
|
||||||
|
- tab "设施类别" [ref=e88] [cursor=pointer]
|
||||||
|
- tab "建设阶段" [ref=e89] [cursor=pointer]
|
||||||
|
- tab "规划形式" [ref=e90] [cursor=pointer]
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- generic [ref=e92]: 自然地理区位
|
||||||
|
- generic [ref=e93]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
86
.playwright-cli/page-2026-08-16T07-13-47-595Z.yml
Normal file
86
.playwright-cli/page-2026-08-16T07-13-47-595Z.yml
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
- main [ref=e3]:
|
||||||
|
- generic:
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- region "年度费用模板" [ref=e4]:
|
||||||
|
- generic "筛选条件" [ref=e5]:
|
||||||
|
- button "省市区" [ref=e6] [cursor=pointer]
|
||||||
|
- button "自然地理区位" [ref=e12] [cursor=pointer]
|
||||||
|
- button "设施类别" [ref=e17] [cursor=pointer]
|
||||||
|
- button "建筑性质" [active] [ref=e23] [cursor=pointer]
|
||||||
|
- button "建设阶段" [ref=e28] [cursor=pointer]
|
||||||
|
- button "规划形式" [ref=e35] [cursor=pointer]
|
||||||
|
- button "时间" [ref=e42] [cursor=pointer]
|
||||||
|
- button "面积" [ref=e46] [cursor=pointer]
|
||||||
|
- region "年度总费用图表" [ref=e54]:
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- button "纵坐标:造价(元)" [ref=e57] [cursor=pointer]: 造价(元)
|
||||||
|
- generic [ref=e58]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- figure "图表,共有0个系列":
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img "interactive chart"
|
||||||
|
- region [ref=e61]
|
||||||
|
- toolbar "标注" [ref=e62]:
|
||||||
|
- button "库" [ref=e63] [cursor=pointer]
|
||||||
|
- button "指" [ref=e64] [cursor=pointer]
|
||||||
|
- button "均" [ref=e65] [cursor=pointer]
|
||||||
|
- button "Line Tool" [disabled] [ref=e66]
|
||||||
|
- button "Text Tool" [disabled] [ref=e67]
|
||||||
|
- button "Shape Tool" [disabled] [ref=e68]
|
||||||
|
- button "Fibonacci Tool" [disabled] [ref=e69]
|
||||||
|
- button "全屏(F11)" [ref=e70] [cursor=pointer]
|
||||||
|
- button "Clear annotations" [disabled] [ref=e71]
|
||||||
|
- button "切换到表格" [ref=e72] [cursor=pointer]:
|
||||||
|
- generic: 趋
|
||||||
|
- status:
|
||||||
|
- generic: 请选择右侧分类项
|
||||||
|
- toolbar "缩放" [ref=e73]:
|
||||||
|
- button "缩小" [disabled] [ref=e74]
|
||||||
|
- button "放大" [ref=e75] [cursor=pointer]
|
||||||
|
- button "左移" [disabled] [ref=e76]
|
||||||
|
- button "右移" [disabled] [ref=e77]
|
||||||
|
- button "重置" [disabled] [ref=e78]
|
||||||
|
- button "收起选择区" [expanded] [ref=e81] [cursor=pointer]
|
||||||
|
- complementary "选择内容" [ref=e85]:
|
||||||
|
- tablist "选择内容切换项" [ref=e86]:
|
||||||
|
- tab "自然地理区位" [selected] [ref=e87] [cursor=pointer]
|
||||||
|
- tab "设施类别" [ref=e88] [cursor=pointer]
|
||||||
|
- tab "建设阶段" [ref=e89] [cursor=pointer]
|
||||||
|
- tab "规划形式" [ref=e90] [cursor=pointer]
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- generic [ref=e92]: 自然地理区位
|
||||||
|
- generic [ref=e93]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
|
- dialog "建筑性质筛选" [ref=e108]:
|
||||||
|
- generic [ref=e109]:
|
||||||
|
- heading "建筑性质" [level=2] [ref=e110]
|
||||||
|
- button "关闭" [ref=e111] [cursor=pointer]: ×
|
||||||
|
- searchbox "搜索" [ref=e113]
|
||||||
|
- generic [ref=e114]: 未选择
|
||||||
|
- tree [ref=e116]:
|
||||||
|
- treeitem [ref=e117]:
|
||||||
|
- button "公共建筑" [ref=e120] [cursor=pointer]
|
||||||
|
- treeitem [ref=e123]:
|
||||||
|
- button "民用建筑" [ref=e126] [cursor=pointer]
|
||||||
|
- treeitem [ref=e129]:
|
||||||
|
- button "工业建筑" [ref=e132] [cursor=pointer]
|
||||||
|
- generic [ref=e135]:
|
||||||
|
- button "清空当前" [ref=e136] [cursor=pointer]
|
||||||
|
- button "取消" [ref=e137] [cursor=pointer]
|
||||||
|
- button "确认" [ref=e138] [cursor=pointer]
|
||||||
82
.playwright-cli/page-2026-08-16T07-14-31-423Z.yml
Normal file
82
.playwright-cli/page-2026-08-16T07-14-31-423Z.yml
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
- main [ref=e3]:
|
||||||
|
- generic:
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- region "年度费用模板" [ref=e4]:
|
||||||
|
- generic "筛选条件" [ref=e5]:
|
||||||
|
- button "省市区" [ref=e6] [cursor=pointer]
|
||||||
|
- button "自然地理区位" [ref=e12] [cursor=pointer]
|
||||||
|
- button "设施类别" [ref=e17] [cursor=pointer]
|
||||||
|
- button "建筑性质" [ref=e23] [cursor=pointer]
|
||||||
|
- button "建设阶段" [ref=e28] [cursor=pointer]
|
||||||
|
- button "规划形式" [ref=e35] [cursor=pointer]
|
||||||
|
- button "时间" [ref=e42] [cursor=pointer]
|
||||||
|
- button "面积" [ref=e46] [cursor=pointer]
|
||||||
|
- region "年度总费用图表" [ref=e54]:
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- button "纵坐标:造价(元)" [ref=e57] [cursor=pointer]: 造价(元)
|
||||||
|
- generic [ref=e58]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- figure "图表,共有0个系列":
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img "interactive chart"
|
||||||
|
- region [ref=e61]
|
||||||
|
- toolbar "标注" [ref=e62]:
|
||||||
|
- button "库" [ref=e63] [cursor=pointer]
|
||||||
|
- button "指" [ref=e64] [cursor=pointer]
|
||||||
|
- button "均" [ref=e65] [cursor=pointer]
|
||||||
|
- button "Line Tool" [disabled] [ref=e66]
|
||||||
|
- button "Text Tool" [disabled] [ref=e67]
|
||||||
|
- button "Shape Tool" [disabled] [ref=e68]
|
||||||
|
- button "Fibonacci Tool" [disabled] [ref=e69]
|
||||||
|
- button "全屏(F11)" [ref=e70] [cursor=pointer]
|
||||||
|
- button "Clear annotations" [disabled] [ref=e71]
|
||||||
|
- button "切换到表格" [ref=e72] [cursor=pointer]:
|
||||||
|
- generic: 趋
|
||||||
|
- status:
|
||||||
|
- generic: 请选择右侧分类项
|
||||||
|
- toolbar "缩放" [ref=e73]:
|
||||||
|
- button "缩小" [disabled] [ref=e74]
|
||||||
|
- button "放大" [ref=e75] [cursor=pointer]
|
||||||
|
- button "左移" [disabled] [ref=e76]
|
||||||
|
- button "右移" [disabled] [ref=e77]
|
||||||
|
- button "重置" [disabled] [ref=e78]
|
||||||
|
- button "收起选择区" [expanded] [ref=e81] [cursor=pointer]
|
||||||
|
- complementary "选择内容" [ref=e85]:
|
||||||
|
- tablist "选择内容切换项" [ref=e86]:
|
||||||
|
- tab "自然地理区位" [selected] [ref=e87] [cursor=pointer]
|
||||||
|
- tab "设施类别" [ref=e88] [cursor=pointer]
|
||||||
|
- tab "建设阶段" [ref=e89] [cursor=pointer]
|
||||||
|
- tab "规划形式" [ref=e90] [cursor=pointer]
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- generic [ref=e92]: 自然地理区位
|
||||||
|
- generic [ref=e93]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
|
- dialog "建筑性质筛选" [ref=e108]:
|
||||||
|
- generic [ref=e109]:
|
||||||
|
- heading "建筑性质" [level=2] [ref=e110]
|
||||||
|
- button "关闭" [ref=e111] [cursor=pointer]: ×
|
||||||
|
- searchbox "搜索" [ref=e113]: 公共
|
||||||
|
- generic [ref=e114]: 已选 1 项
|
||||||
|
- tree [ref=e139]:
|
||||||
|
- treeitem [ref=e140]:
|
||||||
|
- button "公共建筑" [active] [pressed] [ref=e143] [cursor=pointer]
|
||||||
|
- generic [ref=e135]:
|
||||||
|
- button "清空当前" [ref=e136] [cursor=pointer]
|
||||||
|
- button "取消" [ref=e137] [cursor=pointer]
|
||||||
|
- button "确认" [ref=e138] [cursor=pointer]
|
||||||
72
.playwright-cli/page-2026-08-16T07-14-45-319Z.yml
Normal file
72
.playwright-cli/page-2026-08-16T07-14-45-319Z.yml
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
- main [ref=e3]:
|
||||||
|
- generic:
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- region "年度费用模板" [ref=e4]:
|
||||||
|
- generic "筛选条件" [ref=e5]:
|
||||||
|
- button "省市区" [ref=e6] [cursor=pointer]
|
||||||
|
- button "自然地理区位" [ref=e12] [cursor=pointer]
|
||||||
|
- button "设施类别" [ref=e17] [cursor=pointer]
|
||||||
|
- button "建筑性质 1" [pressed] [ref=e146] [cursor=pointer]:
|
||||||
|
- generic [ref=e27]: 建筑性质
|
||||||
|
- strong [ref=e147]: "1"
|
||||||
|
- button "建设阶段" [ref=e28] [cursor=pointer]
|
||||||
|
- button "规划形式" [ref=e35] [cursor=pointer]
|
||||||
|
- button "时间" [ref=e42] [cursor=pointer]
|
||||||
|
- button "面积" [ref=e46] [cursor=pointer]
|
||||||
|
- button "清空" [ref=e148] [cursor=pointer]
|
||||||
|
- region "年度总费用图表" [ref=e54]:
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- button "纵坐标:造价(元)" [ref=e57] [cursor=pointer]: 造价(元)
|
||||||
|
- generic [ref=e149]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- figure "图表,共有0个系列":
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img "interactive chart"
|
||||||
|
- region [ref=e61]
|
||||||
|
- toolbar "标注" [ref=e62]:
|
||||||
|
- button "库" [ref=e63] [cursor=pointer]
|
||||||
|
- button "指" [ref=e64] [cursor=pointer]
|
||||||
|
- button "均" [ref=e65] [cursor=pointer]
|
||||||
|
- button "Line Tool" [disabled] [ref=e66]
|
||||||
|
- button "Text Tool" [disabled] [ref=e67]
|
||||||
|
- button "Shape Tool" [disabled] [ref=e68]
|
||||||
|
- button "Fibonacci Tool" [disabled] [ref=e69]
|
||||||
|
- button "全屏(F11)" [ref=e70] [cursor=pointer]
|
||||||
|
- button "Clear annotations" [disabled] [ref=e71]
|
||||||
|
- button "切换到表格" [ref=e72] [cursor=pointer]:
|
||||||
|
- generic: 趋
|
||||||
|
- status:
|
||||||
|
- generic: 请选择右侧分类项
|
||||||
|
- toolbar "缩放" [ref=e73]:
|
||||||
|
- button "缩小" [disabled] [ref=e74]
|
||||||
|
- button "放大" [ref=e75] [cursor=pointer]
|
||||||
|
- button "左移" [disabled] [ref=e76]
|
||||||
|
- button "右移" [disabled] [ref=e77]
|
||||||
|
- button "重置" [disabled] [ref=e78]
|
||||||
|
- button "收起选择区" [expanded] [ref=e81] [cursor=pointer]
|
||||||
|
- complementary "选择内容" [ref=e85]:
|
||||||
|
- tablist "选择内容切换项" [ref=e86]:
|
||||||
|
- tab "自然地理区位" [selected] [ref=e87] [cursor=pointer]
|
||||||
|
- tab "设施类别" [ref=e88] [cursor=pointer]
|
||||||
|
- tab "建设阶段" [ref=e89] [cursor=pointer]
|
||||||
|
- tab "规划形式" [ref=e90] [cursor=pointer]
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- generic [ref=e92]: 自然地理区位
|
||||||
|
- generic [ref=e93]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
89
.playwright-cli/page-2026-08-16T07-15-28-927Z.yml
Normal file
89
.playwright-cli/page-2026-08-16T07-15-28-927Z.yml
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
- main [ref=e3]:
|
||||||
|
- generic:
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- region "年度费用模板" [ref=e4]:
|
||||||
|
- generic "筛选条件" [ref=e5]:
|
||||||
|
- button "省市区" [ref=e6] [cursor=pointer]
|
||||||
|
- button "自然地理区位" [ref=e12] [cursor=pointer]
|
||||||
|
- button "设施类别" [ref=e17] [cursor=pointer]
|
||||||
|
- button "建筑性质 1" [active] [pressed] [ref=e146] [cursor=pointer]:
|
||||||
|
- generic [ref=e27]: 建筑性质
|
||||||
|
- strong [ref=e147]: "1"
|
||||||
|
- button "建设阶段" [ref=e28] [cursor=pointer]
|
||||||
|
- button "规划形式" [ref=e35] [cursor=pointer]
|
||||||
|
- button "时间" [ref=e42] [cursor=pointer]
|
||||||
|
- button "面积" [ref=e46] [cursor=pointer]
|
||||||
|
- button "清空" [ref=e148] [cursor=pointer]
|
||||||
|
- region "年度总费用图表" [ref=e54]:
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- button "纵坐标:造价(元)" [ref=e57] [cursor=pointer]: 造价(元)
|
||||||
|
- generic [ref=e149]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- figure "图表,共有0个系列":
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img "interactive chart"
|
||||||
|
- region [ref=e61]
|
||||||
|
- toolbar "标注" [ref=e62]:
|
||||||
|
- button "库" [ref=e63] [cursor=pointer]
|
||||||
|
- button "指" [ref=e64] [cursor=pointer]
|
||||||
|
- button "均" [ref=e65] [cursor=pointer]
|
||||||
|
- button "Line Tool" [disabled] [ref=e66]
|
||||||
|
- button "Text Tool" [disabled] [ref=e67]
|
||||||
|
- button "Shape Tool" [disabled] [ref=e68]
|
||||||
|
- button "Fibonacci Tool" [disabled] [ref=e69]
|
||||||
|
- button "全屏(F11)" [ref=e70] [cursor=pointer]
|
||||||
|
- button "Clear annotations" [disabled] [ref=e71]
|
||||||
|
- button "切换到表格" [ref=e72] [cursor=pointer]:
|
||||||
|
- generic: 趋
|
||||||
|
- status:
|
||||||
|
- generic: 请选择右侧分类项
|
||||||
|
- toolbar "缩放" [ref=e73]:
|
||||||
|
- button "缩小" [disabled] [ref=e74]
|
||||||
|
- button "放大" [ref=e75] [cursor=pointer]
|
||||||
|
- button "左移" [disabled] [ref=e76]
|
||||||
|
- button "右移" [disabled] [ref=e77]
|
||||||
|
- button "重置" [disabled] [ref=e78]
|
||||||
|
- button "收起选择区" [expanded] [ref=e81] [cursor=pointer]
|
||||||
|
- complementary "选择内容" [ref=e85]:
|
||||||
|
- tablist "选择内容切换项" [ref=e86]:
|
||||||
|
- tab "自然地理区位" [selected] [ref=e87] [cursor=pointer]
|
||||||
|
- tab "设施类别" [ref=e88] [cursor=pointer]
|
||||||
|
- tab "建设阶段" [ref=e89] [cursor=pointer]
|
||||||
|
- tab "规划形式" [ref=e90] [cursor=pointer]
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- generic [ref=e92]: 自然地理区位
|
||||||
|
- generic [ref=e93]: "Expected property name or '}' in JSON at position 1 (line 1 column 2)"
|
||||||
|
- dialog "建筑性质筛选" [ref=e150]:
|
||||||
|
- generic [ref=e151]:
|
||||||
|
- heading "建筑性质" [level=2] [ref=e152]
|
||||||
|
- button "关闭" [ref=e153] [cursor=pointer]: ×
|
||||||
|
- searchbox "搜索" [ref=e155]
|
||||||
|
- generic [ref=e156]: 已选 1 项
|
||||||
|
- tree [ref=e158]:
|
||||||
|
- treeitem [ref=e159]:
|
||||||
|
- button "公共建筑" [pressed] [ref=e162] [cursor=pointer]
|
||||||
|
- treeitem [ref=e165]:
|
||||||
|
- button "民用建筑" [ref=e168] [cursor=pointer]
|
||||||
|
- treeitem [ref=e171]:
|
||||||
|
- button "工业建筑" [ref=e174] [cursor=pointer]
|
||||||
|
- generic [ref=e177]:
|
||||||
|
- button "清空当前" [ref=e178] [cursor=pointer]
|
||||||
|
- button "取消" [ref=e179] [cursor=pointer]
|
||||||
|
- button "确认" [ref=e180] [cursor=pointer]
|
||||||
0
.playwright-cli/page-2026-08-16T07-18-55-077Z.yml
Normal file
0
.playwright-cli/page-2026-08-16T07-18-55-077Z.yml
Normal file
70
.playwright-cli/page-2026-08-16T07-19-16-089Z.yml
Normal file
70
.playwright-cli/page-2026-08-16T07-19-16-089Z.yml
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
- main [ref=e3]:
|
||||||
|
- generic:
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- region "年度费用模板" [ref=e4]:
|
||||||
|
- generic "筛选条件" [ref=e5]:
|
||||||
|
- button "省市区" [ref=e6] [cursor=pointer]
|
||||||
|
- button "自然地理区位" [ref=e12] [cursor=pointer]
|
||||||
|
- button "设施类别" [ref=e17] [cursor=pointer]
|
||||||
|
- button "建筑性质" [ref=e23] [cursor=pointer]
|
||||||
|
- button "建设阶段" [ref=e28] [cursor=pointer]
|
||||||
|
- button "规划形式" [ref=e35] [cursor=pointer]
|
||||||
|
- button "时间" [ref=e42] [cursor=pointer]
|
||||||
|
- button "面积" [ref=e46] [cursor=pointer]
|
||||||
|
- region "年度总费用图表" [ref=e54]:
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- button "纵坐标:造价(元)" [ref=e57] [cursor=pointer]: 造价(元)
|
||||||
|
- generic [ref=e58]: 正在加载数据
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- figure "图表,共有0个系列":
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img "interactive chart"
|
||||||
|
- region [ref=e61]
|
||||||
|
- toolbar "标注" [ref=e62]:
|
||||||
|
- button "库" [ref=e63] [cursor=pointer]
|
||||||
|
- button "指" [ref=e64] [cursor=pointer]
|
||||||
|
- button "均" [ref=e65] [cursor=pointer]
|
||||||
|
- button "Line Tool" [disabled] [ref=e66]
|
||||||
|
- button "Text Tool" [disabled] [ref=e67]
|
||||||
|
- button "Shape Tool" [disabled] [ref=e68]
|
||||||
|
- button "Fibonacci Tool" [disabled] [ref=e69]
|
||||||
|
- button "全屏(F11)" [ref=e70] [cursor=pointer]
|
||||||
|
- button "Clear annotations" [disabled] [ref=e71]
|
||||||
|
- button "切换到表格" [ref=e72] [cursor=pointer]:
|
||||||
|
- generic: 趋
|
||||||
|
- status:
|
||||||
|
- generic: 请选择右侧分类项
|
||||||
|
- toolbar "缩放" [ref=e73]:
|
||||||
|
- button "缩小" [disabled] [ref=e74]
|
||||||
|
- button "放大" [ref=e75] [cursor=pointer]
|
||||||
|
- button "左移" [disabled] [ref=e76]
|
||||||
|
- button "右移" [disabled] [ref=e77]
|
||||||
|
- button "重置" [disabled] [ref=e78]
|
||||||
|
- generic [ref=e79]: 正在加载数据
|
||||||
|
- button "收起选择区" [expanded] [ref=e81] [cursor=pointer]
|
||||||
|
- complementary "选择内容" [ref=e85]:
|
||||||
|
- tablist "选择内容切换项" [ref=e86]:
|
||||||
|
- tab "自然地理区位" [selected] [ref=e87] [cursor=pointer]
|
||||||
|
- tab "设施类别" [ref=e88] [cursor=pointer]
|
||||||
|
- tab "建设阶段" [ref=e89] [cursor=pointer]
|
||||||
|
- tab "规划形式" [ref=e90] [cursor=pointer]
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- generic [ref=e92]: 自然地理区位
|
||||||
|
- generic [ref=e93]: 加载中
|
||||||
85
.playwright-cli/page-2026-08-16T07-19-36-679Z.yml
Normal file
85
.playwright-cli/page-2026-08-16T07-19-36-679Z.yml
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
- main [ref=e3]:
|
||||||
|
- generic:
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- generic: 众为数字化管理平台
|
||||||
|
- region "年度费用模板" [ref=e4]:
|
||||||
|
- generic "筛选条件" [ref=e5]:
|
||||||
|
- button "省市区" [ref=e6] [cursor=pointer]
|
||||||
|
- button "自然地理区位" [ref=e12] [cursor=pointer]
|
||||||
|
- button "设施类别" [ref=e17] [cursor=pointer]
|
||||||
|
- button "建筑性质" [active] [ref=e23] [cursor=pointer]
|
||||||
|
- button "建设阶段" [ref=e28] [cursor=pointer]
|
||||||
|
- button "规划形式" [ref=e35] [cursor=pointer]
|
||||||
|
- button "时间" [ref=e42] [cursor=pointer]
|
||||||
|
- button "面积" [ref=e46] [cursor=pointer]
|
||||||
|
- region "年度总费用图表" [ref=e54]:
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- button "纵坐标:造价(元)" [ref=e57] [cursor=pointer]: 造价(元)
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- figure "图表,共有0个系列":
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img "interactive chart"
|
||||||
|
- region [ref=e61]
|
||||||
|
- toolbar "标注" [ref=e62]:
|
||||||
|
- button "库" [ref=e63] [cursor=pointer]
|
||||||
|
- button "指" [ref=e64] [cursor=pointer]
|
||||||
|
- button "均" [ref=e65] [cursor=pointer]
|
||||||
|
- button "Line Tool" [disabled] [ref=e66]
|
||||||
|
- button "Text Tool" [disabled] [ref=e67]
|
||||||
|
- button "Shape Tool" [disabled] [ref=e68]
|
||||||
|
- button "Fibonacci Tool" [disabled] [ref=e69]
|
||||||
|
- button "全屏(F11)" [ref=e70] [cursor=pointer]
|
||||||
|
- button "Clear annotations" [disabled] [ref=e71]
|
||||||
|
- button "切换到表格" [ref=e72] [cursor=pointer]:
|
||||||
|
- generic: 趋
|
||||||
|
- status:
|
||||||
|
- generic: 请选择右侧分类项
|
||||||
|
- toolbar "缩放" [ref=e73]:
|
||||||
|
- button "缩小" [disabled] [ref=e74]
|
||||||
|
- button "放大" [ref=e75] [cursor=pointer]
|
||||||
|
- button "左移" [disabled] [ref=e76]
|
||||||
|
- button "右移" [disabled] [ref=e77]
|
||||||
|
- button "重置" [disabled] [ref=e78]
|
||||||
|
- button "收起选择区" [expanded] [ref=e81] [cursor=pointer]
|
||||||
|
- complementary "选择内容" [ref=e85]:
|
||||||
|
- tablist "选择内容切换项" [ref=e86]:
|
||||||
|
- tab "自然地理区位" [selected] [ref=e87] [cursor=pointer]
|
||||||
|
- tab "设施类别" [ref=e88] [cursor=pointer]
|
||||||
|
- tab "建设阶段" [ref=e89] [cursor=pointer]
|
||||||
|
- tab "规划形式" [ref=e90] [cursor=pointer]
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- generic [ref=e92]: 自然地理区位
|
||||||
|
- generic [ref=e93]: 接口待接入
|
||||||
|
- dialog "建筑性质筛选" [ref=e94]:
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- heading "建筑性质" [level=2] [ref=e96]
|
||||||
|
- button "关闭" [ref=e97] [cursor=pointer]: ×
|
||||||
|
- searchbox "搜索" [ref=e99]
|
||||||
|
- generic [ref=e100]: 未选择
|
||||||
|
- tree [ref=e102]:
|
||||||
|
- treeitem [ref=e103]:
|
||||||
|
- button "公共建筑" [ref=e106] [cursor=pointer]
|
||||||
|
- treeitem [ref=e109]:
|
||||||
|
- button "民用建筑" [ref=e112] [cursor=pointer]
|
||||||
|
- treeitem [ref=e115]:
|
||||||
|
- button "工业建筑" [ref=e118] [cursor=pointer]
|
||||||
|
- generic [ref=e121]:
|
||||||
|
- button "清空当前" [ref=e122] [cursor=pointer]
|
||||||
|
- button "取消" [ref=e123] [cursor=pointer]
|
||||||
|
- button "确认" [ref=e124] [cursor=pointer]
|
||||||
44
AGENTS.md
Normal file
44
AGENTS.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<!-- gitnexus:start -->
|
||||||
|
# GitNexus — Code Intelligence
|
||||||
|
|
||||||
|
This project is indexed by GitNexus as **agchart** (187 symbols, 490 relationships, 20 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
|
||||||
|
|
||||||
|
> Index stale? Run `node .gitnexus/run.cjs analyze` from the project root — it auto-selects an available runner. No `.gitnexus/run.cjs` yet? `npx gitnexus analyze` (npm 11 crash → `npm i -g gitnexus`; #1939).
|
||||||
|
|
||||||
|
## Always Do
|
||||||
|
|
||||||
|
- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user.
|
||||||
|
- **MUST run `detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows. For regression review, compare against the default branch: `detect_changes({scope: "compare", base_ref: "main"})`.
|
||||||
|
- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits.
|
||||||
|
- When exploring unfamiliar code, use `query({search_query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance.
|
||||||
|
- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use `context({name: "symbolName"})`.
|
||||||
|
- For security review, `explain({target: "fileOrSymbol"})` lists taint findings (source→sink flows; needs `analyze --pdg`).
|
||||||
|
|
||||||
|
## Never Do
|
||||||
|
|
||||||
|
- NEVER edit a function, class, or method without first running `impact` on it.
|
||||||
|
- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis.
|
||||||
|
- NEVER rename symbols with find-and-replace — use `rename` which understands the call graph.
|
||||||
|
- NEVER commit changes without running `detect_changes()` to check affected scope.
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
| Resource | Use for |
|
||||||
|
|----------|---------|
|
||||||
|
| `gitnexus://repo/agchart/context` | Codebase overview, check index freshness |
|
||||||
|
| `gitnexus://repo/agchart/clusters` | All functional areas |
|
||||||
|
| `gitnexus://repo/agchart/processes` | All execution flows |
|
||||||
|
| `gitnexus://repo/agchart/process/{name}` | Step-by-step execution trace |
|
||||||
|
|
||||||
|
## CLI
|
||||||
|
|
||||||
|
| Task | Read this skill file |
|
||||||
|
|------|---------------------|
|
||||||
|
| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` |
|
||||||
|
| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` |
|
||||||
|
| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` |
|
||||||
|
| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` |
|
||||||
|
| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` |
|
||||||
|
| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` |
|
||||||
|
|
||||||
|
<!-- gitnexus:end -->
|
||||||
44
CLAUDE.md
Normal file
44
CLAUDE.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<!-- gitnexus:start -->
|
||||||
|
# GitNexus — Code Intelligence
|
||||||
|
|
||||||
|
This project is indexed by GitNexus as **agchart** (187 symbols, 490 relationships, 20 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
|
||||||
|
|
||||||
|
> Index stale? Run `node .gitnexus/run.cjs analyze` from the project root — it auto-selects an available runner. No `.gitnexus/run.cjs` yet? `npx gitnexus analyze` (npm 11 crash → `npm i -g gitnexus`; #1939).
|
||||||
|
|
||||||
|
## Always Do
|
||||||
|
|
||||||
|
- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user.
|
||||||
|
- **MUST run `detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows. For regression review, compare against the default branch: `detect_changes({scope: "compare", base_ref: "main"})`.
|
||||||
|
- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits.
|
||||||
|
- When exploring unfamiliar code, use `query({search_query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance.
|
||||||
|
- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use `context({name: "symbolName"})`.
|
||||||
|
- For security review, `explain({target: "fileOrSymbol"})` lists taint findings (source→sink flows; needs `analyze --pdg`).
|
||||||
|
|
||||||
|
## Never Do
|
||||||
|
|
||||||
|
- NEVER edit a function, class, or method without first running `impact` on it.
|
||||||
|
- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis.
|
||||||
|
- NEVER rename symbols with find-and-replace — use `rename` which understands the call graph.
|
||||||
|
- NEVER commit changes without running `detect_changes()` to check affected scope.
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
| Resource | Use for |
|
||||||
|
|----------|---------|
|
||||||
|
| `gitnexus://repo/agchart/context` | Codebase overview, check index freshness |
|
||||||
|
| `gitnexus://repo/agchart/clusters` | All functional areas |
|
||||||
|
| `gitnexus://repo/agchart/processes` | All execution flows |
|
||||||
|
| `gitnexus://repo/agchart/process/{name}` | Step-by-step execution trace |
|
||||||
|
|
||||||
|
## CLI
|
||||||
|
|
||||||
|
| Task | Read this skill file |
|
||||||
|
|------|---------------------|
|
||||||
|
| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` |
|
||||||
|
| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` |
|
||||||
|
| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` |
|
||||||
|
| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` |
|
||||||
|
| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` |
|
||||||
|
| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` |
|
||||||
|
|
||||||
|
<!-- gitnexus:end -->
|
||||||
BIN
output/playwright/building-nature/desktop-dialog.png
Normal file
BIN
output/playwright/building-nature/desktop-dialog.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
BIN
output/playwright/building-nature/mobile-dialog.png
Normal file
BIN
output/playwright/building-nature/mobile-dialog.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
BIN
output/playwright/building-nature/mobile-toolbar.png
Normal file
BIN
output/playwright/building-nature/mobile-toolbar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
14
output/playwright/building-nature/playwright-cli.json
Normal file
14
output/playwright/building-nature/playwright-cli.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"browser": {
|
||||||
|
"launchOptions": {
|
||||||
|
"headless": true,
|
||||||
|
"executablePath": "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe"
|
||||||
|
},
|
||||||
|
"contextOptions": {
|
||||||
|
"viewport": {
|
||||||
|
"width": 1440,
|
||||||
|
"height": 900
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
128
src/App.tsx
128
src/App.tsx
@ -12,7 +12,7 @@ import {
|
|||||||
} from 'ag-grid-community';
|
} from 'ag-grid-community';
|
||||||
import type { AgCartesianChartOptions } from 'ag-charts-community';
|
import type { AgCartesianChartOptions } from 'ag-charts-community';
|
||||||
import { ModuleRegistry } from 'ag-charts-community';
|
import { ModuleRegistry } from 'ag-charts-community';
|
||||||
import { Building2, CalendarRange, Construction, LayoutGrid, Library, LocateFixed, MapPinned, PanelRightClose, PanelRightOpen, Ruler, Waypoints } from 'lucide-react';
|
import { Building2, CalendarRange, Construction, House, LayoutGrid, Library, LocateFixed, MapPinned, PanelRightClose, PanelRightOpen, Ruler, Waypoints } from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
AnnotationsModule,
|
AnnotationsModule,
|
||||||
ContextMenuModule,
|
ContextMenuModule,
|
||||||
@ -29,6 +29,12 @@ AgGridModuleRegistry.registerModules([AgGridAllCommunityModule]);
|
|||||||
const API_BASE_URL = 'https://nest.zwgczx.com/api/v1';
|
const API_BASE_URL = 'https://nest.zwgczx.com/api/v1';
|
||||||
// const API_BASE_URL = 'http://127.0.0.1:9089/api/v1';
|
// const API_BASE_URL = 'http://127.0.0.1:9089/api/v1';
|
||||||
|
|
||||||
|
const API_ROUTES = {
|
||||||
|
filterTree: '/zw/getBuildingFacilityObjectFilterTree',
|
||||||
|
filterTreeSearch: '/zw/getBuildingFacilityObjectFilterTreeSearch',
|
||||||
|
statsBatch: '/zw/getBuildingFacilityObjectStatsBatch',
|
||||||
|
} as const;
|
||||||
|
|
||||||
const statisticOptions = [
|
const statisticOptions = [
|
||||||
{ key: 'minValue', label: '最低值', shortLabel: '低' },
|
{ key: 'minValue', label: '最低值', shortLabel: '低' },
|
||||||
{ key: 'maxValue', label: '最高值', shortLabel: '高' },
|
{ key: 'maxValue', label: '最高值', shortLabel: '高' },
|
||||||
@ -67,6 +73,7 @@ const filterOptions = [
|
|||||||
{ key: 'region', label: '省市区', icon: MapPinned },
|
{ key: 'region', label: '省市区', icon: MapPinned },
|
||||||
{ key: 'geoLocation', label: '自然地理区位', icon: LocateFixed },
|
{ key: 'geoLocation', label: '自然地理区位', icon: LocateFixed },
|
||||||
{ key: 'facilityType', label: '设施类别', icon: Building2 },
|
{ key: 'facilityType', label: '设施类别', icon: Building2 },
|
||||||
|
{ key: 'buildingNature', label: '建筑性质', icon: House },
|
||||||
{ key: 'constructionStage', label: '建设阶段', icon: Construction },
|
{ key: 'constructionStage', label: '建设阶段', icon: Construction },
|
||||||
{ key: 'planningForm', label: '规划形式', icon: LayoutGrid },
|
{ key: 'planningForm', label: '规划形式', icon: LayoutGrid },
|
||||||
{ key: 'time', label: '时间', icon: CalendarRange },
|
{ key: 'time', label: '时间', icon: CalendarRange },
|
||||||
@ -121,6 +128,26 @@ const contentTreeConfigs = {
|
|||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
const buildingNatureBrowserConfig = {
|
||||||
|
conditionEndpoint: '/api/public/browser/condition/256',
|
||||||
|
dataEndpoint: '/api/public/browser/data/256',
|
||||||
|
treeid: '95504',
|
||||||
|
fieldid: '316390',
|
||||||
|
searchbrowserid: '36523',
|
||||||
|
browserParams: {
|
||||||
|
requestid: '',
|
||||||
|
isshowsearchtab: '1',
|
||||||
|
workflowid: '182028',
|
||||||
|
wfid: '182028',
|
||||||
|
billid: '-1815',
|
||||||
|
f_weaver_belongto_userid: '',
|
||||||
|
f_weaver_belongto_usertype: '',
|
||||||
|
wf_isagent: '',
|
||||||
|
wf_beagenter: '',
|
||||||
|
wfCreater: '',
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
const chartLineColors = ['#0078a8', '#d14d72', '#1f8f4d', '#d96f23', '#6b5cc8', '#0d7680', '#9a6b12', '#b24b38'];
|
const chartLineColors = ['#0078a8', '#d14d72', '#1f8f4d', '#d96f23', '#6b5cc8', '#0d7680', '#9a6b12', '#b24b38'];
|
||||||
const defaultTemplateFilterNode = {
|
const defaultTemplateFilterNode = {
|
||||||
id: '3',
|
id: '3',
|
||||||
@ -583,6 +610,10 @@ function isIndicatorTreeFilterKey(filterKey: FilterKey): filterKey is 'indicator
|
|||||||
return filterKey === 'indicatorTree';
|
return filterKey === 'indicatorTree';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isBuildingNatureFilterKey(filterKey: FilterKey): filterKey is 'buildingNature' {
|
||||||
|
return filterKey === 'buildingNature';
|
||||||
|
}
|
||||||
|
|
||||||
function isRangeFilterKey(filterKey: FilterKey): filterKey is RangeFilterKey {
|
function isRangeFilterKey(filterKey: FilterKey): filterKey is RangeFilterKey {
|
||||||
return filterKey === 'time' || filterKey === 'area';
|
return filterKey === 'time' || filterKey === 'area';
|
||||||
}
|
}
|
||||||
@ -750,6 +781,7 @@ function App() {
|
|||||||
region: false,
|
region: false,
|
||||||
geoLocation: false,
|
geoLocation: false,
|
||||||
facilityType: false,
|
facilityType: false,
|
||||||
|
buildingNature: false,
|
||||||
constructionStage: false,
|
constructionStage: false,
|
||||||
planningForm: false,
|
planningForm: false,
|
||||||
time: false,
|
time: false,
|
||||||
@ -795,6 +827,7 @@ function App() {
|
|||||||
region: [],
|
region: [],
|
||||||
geoLocation: [],
|
geoLocation: [],
|
||||||
facilityType: [],
|
facilityType: [],
|
||||||
|
buildingNature: [],
|
||||||
constructionStage: [],
|
constructionStage: [],
|
||||||
planningForm: [],
|
planningForm: [],
|
||||||
time: [],
|
time: [],
|
||||||
@ -806,6 +839,7 @@ function App() {
|
|||||||
region: false,
|
region: false,
|
||||||
geoLocation: false,
|
geoLocation: false,
|
||||||
facilityType: false,
|
facilityType: false,
|
||||||
|
buildingNature: false,
|
||||||
constructionStage: false,
|
constructionStage: false,
|
||||||
planningForm: false,
|
planningForm: false,
|
||||||
time: false,
|
time: false,
|
||||||
@ -817,6 +851,7 @@ function App() {
|
|||||||
region: null,
|
region: null,
|
||||||
geoLocation: null,
|
geoLocation: null,
|
||||||
facilityType: null,
|
facilityType: null,
|
||||||
|
buildingNature: null,
|
||||||
constructionStage: null,
|
constructionStage: null,
|
||||||
planningForm: null,
|
planningForm: null,
|
||||||
time: null,
|
time: null,
|
||||||
@ -828,6 +863,7 @@ function App() {
|
|||||||
region: [],
|
region: [],
|
||||||
geoLocation: [],
|
geoLocation: [],
|
||||||
facilityType: [],
|
facilityType: [],
|
||||||
|
buildingNature: [],
|
||||||
constructionStage: [],
|
constructionStage: [],
|
||||||
planningForm: [],
|
planningForm: [],
|
||||||
time: [],
|
time: [],
|
||||||
@ -839,6 +875,7 @@ function App() {
|
|||||||
region: false,
|
region: false,
|
||||||
geoLocation: false,
|
geoLocation: false,
|
||||||
facilityType: false,
|
facilityType: false,
|
||||||
|
buildingNature: false,
|
||||||
constructionStage: false,
|
constructionStage: false,
|
||||||
planningForm: false,
|
planningForm: false,
|
||||||
time: false,
|
time: false,
|
||||||
@ -850,6 +887,7 @@ function App() {
|
|||||||
region: null,
|
region: null,
|
||||||
geoLocation: null,
|
geoLocation: null,
|
||||||
facilityType: null,
|
facilityType: null,
|
||||||
|
buildingNature: null,
|
||||||
constructionStage: null,
|
constructionStage: null,
|
||||||
planningForm: null,
|
planningForm: null,
|
||||||
time: null,
|
time: null,
|
||||||
@ -861,6 +899,7 @@ function App() {
|
|||||||
region: [],
|
region: [],
|
||||||
geoLocation: [],
|
geoLocation: [],
|
||||||
facilityType: [],
|
facilityType: [],
|
||||||
|
buildingNature: [],
|
||||||
constructionStage: [],
|
constructionStage: [],
|
||||||
planningForm: [],
|
planningForm: [],
|
||||||
time: [],
|
time: [],
|
||||||
@ -878,6 +917,7 @@ function App() {
|
|||||||
region: 0,
|
region: 0,
|
||||||
geoLocation: 0,
|
geoLocation: 0,
|
||||||
facilityType: 0,
|
facilityType: 0,
|
||||||
|
buildingNature: 0,
|
||||||
constructionStage: 0,
|
constructionStage: 0,
|
||||||
planningForm: 0,
|
planningForm: 0,
|
||||||
time: 0,
|
time: 0,
|
||||||
@ -1201,6 +1241,7 @@ function App() {
|
|||||||
.filter((filter) => filter.nodes.length > 0),
|
.filter((filter) => filter.nodes.length > 0),
|
||||||
[
|
[
|
||||||
appliedFilters.area,
|
appliedFilters.area,
|
||||||
|
appliedFilters.buildingNature,
|
||||||
appliedFilters.constructionStage,
|
appliedFilters.constructionStage,
|
||||||
appliedFilters.facilityType,
|
appliedFilters.facilityType,
|
||||||
appliedFilters.geoLocation,
|
appliedFilters.geoLocation,
|
||||||
@ -1259,6 +1300,65 @@ function App() {
|
|||||||
return normalizeTreeRows(rows);
|
return normalizeTreeRows(rows);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchBuildingNatureFilterTree = async (nodeId?: string, signal?: AbortSignal) => {
|
||||||
|
const treeParams = {
|
||||||
|
...browserTreeDefaults,
|
||||||
|
...buildingNatureBrowserConfig.browserParams,
|
||||||
|
treeid: buildingNatureBrowserConfig.treeid,
|
||||||
|
cube_treeid: buildingNatureBrowserConfig.treeid,
|
||||||
|
searchbrowserid: buildingNatureBrowserConfig.searchbrowserid,
|
||||||
|
fieldid: buildingNatureBrowserConfig.fieldid,
|
||||||
|
};
|
||||||
|
const requestOptions: RequestInit = {
|
||||||
|
credentials: 'include',
|
||||||
|
signal,
|
||||||
|
headers: {
|
||||||
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!nodeId) {
|
||||||
|
const conditionResponse = await fetch(
|
||||||
|
`${buildingNatureBrowserConfig.conditionEndpoint}?${buildQuery(treeParams)}`,
|
||||||
|
requestOptions,
|
||||||
|
);
|
||||||
|
if (!conditionResponse.ok) {
|
||||||
|
throw new Error(`建筑性质浏览条件加载失败:HTTP ${conditionResponse.status}`);
|
||||||
|
}
|
||||||
|
const conditionPayload = await conditionResponse.json() as { status?: boolean; msg?: string };
|
||||||
|
if (conditionPayload.status === false) {
|
||||||
|
throw new Error(conditionPayload.msg || '建筑性质浏览条件加载失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const dataParams = nodeId
|
||||||
|
? {
|
||||||
|
...treeParams,
|
||||||
|
type: '2',
|
||||||
|
id: nodeId,
|
||||||
|
isVirtual: '',
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
...treeParams,
|
||||||
|
pageSize: '10',
|
||||||
|
current: '1',
|
||||||
|
min: '1',
|
||||||
|
max: '10',
|
||||||
|
};
|
||||||
|
const dataResponse = await fetch(
|
||||||
|
`${buildingNatureBrowserConfig.dataEndpoint}?${buildQuery(dataParams)}`,
|
||||||
|
requestOptions,
|
||||||
|
);
|
||||||
|
if (!dataResponse.ok) {
|
||||||
|
throw new Error(`建筑性质浏览数据加载失败:HTTP ${dataResponse.status}`);
|
||||||
|
}
|
||||||
|
const dataPayload = await dataResponse.json() as { status?: boolean; msg?: string };
|
||||||
|
if (dataPayload.status === false) {
|
||||||
|
throw new Error(dataPayload.msg || '建筑性质浏览数据加载失败');
|
||||||
|
}
|
||||||
|
return normalizeTreeRows(pickArray(dataPayload));
|
||||||
|
};
|
||||||
|
|
||||||
const normalizeBackendTree = (nodes: TreeNode[]): TreeNode[] => nodes.map((node) => ({
|
const normalizeBackendTree = (nodes: TreeNode[]): TreeNode[] => nodes.map((node) => ({
|
||||||
...node,
|
...node,
|
||||||
hasChildren: node.children.length > 0 || node.hasChildren,
|
hasChildren: node.children.length > 0 || node.hasChildren,
|
||||||
@ -1284,7 +1384,7 @@ function App() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const fetchRegionFilterTree = async (signal?: AbortSignal) => {
|
const fetchRegionFilterTree = async (signal?: AbortSignal) => {
|
||||||
const response = await fetch(`${API_BASE_URL}/zw/getBuildingFunctionCostFilterTree?${buildQuery({ key: 'region' })}`, {
|
const response = await fetch(`${API_BASE_URL}${API_ROUTES.filterTree}?${buildQuery({ key: 'region' })}`, {
|
||||||
signal,
|
signal,
|
||||||
headers: {
|
headers: {
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
@ -1299,7 +1399,7 @@ function App() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const fetchTemplateLibraryTree = async (signal?: AbortSignal) => {
|
const fetchTemplateLibraryTree = async (signal?: AbortSignal) => {
|
||||||
const response = await fetch(`${API_BASE_URL}/zw/getBuildingFunctionCostFilterTree?${buildQuery({ key: 'templateLibrary' })}`, {
|
const response = await fetch(`${API_BASE_URL}${API_ROUTES.filterTree}?${buildQuery({ key: 'templateLibrary' })}`, {
|
||||||
signal,
|
signal,
|
||||||
headers: {
|
headers: {
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
@ -1314,7 +1414,7 @@ function App() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const fetchIndicatorTree = async (signal?: AbortSignal) => {
|
const fetchIndicatorTree = async (signal?: AbortSignal) => {
|
||||||
const response = await fetch(`${API_BASE_URL}/zw/getBuildingFunctionCostFilterTree?${buildQuery({ key: 'indicatorTree', templateId: selectedTemplateId })}`, {
|
const response = await fetch(`${API_BASE_URL}${API_ROUTES.filterTree}?${buildQuery({ key: 'indicatorTree', templateId: selectedTemplateId })}`, {
|
||||||
signal,
|
signal,
|
||||||
headers: {
|
headers: {
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
@ -1329,7 +1429,7 @@ function App() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const fetchBackendFilterTreeSearch = async (filterKey: FilterKey, keyword: string, signal?: AbortSignal) => {
|
const fetchBackendFilterTreeSearch = async (filterKey: FilterKey, keyword: string, signal?: AbortSignal) => {
|
||||||
const response = await fetch(`${API_BASE_URL}/zw/getBuildingFunctionCostFilterTreeSearch?${buildQuery({
|
const response = await fetch(`${API_BASE_URL}${API_ROUTES.filterTreeSearch}?${buildQuery({
|
||||||
key: filterKey,
|
key: filterKey,
|
||||||
keyword,
|
keyword,
|
||||||
nodePrefix: isContentFilterKey(filterKey) ? getTreeNodePrefix(filterTreeByKey[filterKey]) : '',
|
nodePrefix: isContentFilterKey(filterKey) ? getTreeNodePrefix(filterTreeByKey[filterKey]) : '',
|
||||||
@ -1372,6 +1472,12 @@ function App() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const loadFilterTree = async (filterKey: FilterKey, keyword?: string, signal?: AbortSignal) => {
|
const loadFilterTree = async (filterKey: FilterKey, keyword?: string, signal?: AbortSignal) => {
|
||||||
|
if (isBuildingNatureFilterKey(filterKey)) {
|
||||||
|
const nodes = filterTreeByKey.buildingNature.length > 0
|
||||||
|
? filterTreeByKey.buildingNature
|
||||||
|
: await fetchBuildingNatureFilterTree(undefined, signal);
|
||||||
|
return keyword?.trim() ? filterTreeNodesByKeyword(nodes, keyword) : nodes;
|
||||||
|
}
|
||||||
if (filterKey === 'region') {
|
if (filterKey === 'region') {
|
||||||
const nodes = await fetchRegionFilterTree(signal);
|
const nodes = await fetchRegionFilterTree(signal);
|
||||||
return keyword?.trim() ? filterTreeNodesByKeyword(nodes, keyword) : nodes;
|
return keyword?.trim() ? filterTreeNodesByKeyword(nodes, keyword) : nodes;
|
||||||
@ -1578,7 +1684,7 @@ function App() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTemplateFilterKey(filterKey) || filterKey === 'indicatorTree') {
|
if (isTemplateFilterKey(filterKey) || filterKey === 'indicatorTree' || isBuildingNatureFilterKey(filterKey)) {
|
||||||
filterSearchTimerRef.current = window.setTimeout(() => {
|
filterSearchTimerRef.current = window.setTimeout(() => {
|
||||||
setFilterSearchLoadingByKey((current) => ({ ...current, [filterKey]: true }));
|
setFilterSearchLoadingByKey((current) => ({ ...current, [filterKey]: true }));
|
||||||
setFilterSearchErrorByKey((current) => ({ ...current, [filterKey]: null }));
|
setFilterSearchErrorByKey((current) => ({ ...current, [filterKey]: null }));
|
||||||
@ -1635,10 +1741,13 @@ function App() {
|
|||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (node.loaded || !isContentFilterKey(filterModalKey)) return;
|
if (node.loaded || (!isContentFilterKey(filterModalKey) && !isBuildingNatureFilterKey(filterModalKey))) return;
|
||||||
|
|
||||||
const currentFilterKey = filterModalKey;
|
const currentFilterKey = filterModalKey;
|
||||||
fetchContentTree(currentFilterKey, nodeId)
|
const childRequest = isBuildingNatureFilterKey(currentFilterKey)
|
||||||
|
? fetchBuildingNatureFilterTree(nodeId)
|
||||||
|
: fetchContentTree(currentFilterKey, nodeId);
|
||||||
|
childRequest
|
||||||
.then((children) => {
|
.then((children) => {
|
||||||
setFilterTreeByKey((current) => ({
|
setFilterTreeByKey((current) => ({
|
||||||
...current,
|
...current,
|
||||||
@ -1895,7 +2004,7 @@ function App() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(`${API_BASE_URL}/zw/getBuildingFunctionCostStatsBatch`, {
|
const response = await fetch(`${API_BASE_URL}${API_ROUTES.statsBatch}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
headers: {
|
headers: {
|
||||||
@ -2437,6 +2546,7 @@ function App() {
|
|||||||
region: [],
|
region: [],
|
||||||
geoLocation: [],
|
geoLocation: [],
|
||||||
facilityType: [],
|
facilityType: [],
|
||||||
|
buildingNature: [],
|
||||||
constructionStage: [],
|
constructionStage: [],
|
||||||
planningForm: [],
|
planningForm: [],
|
||||||
time: [],
|
time: [],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user