homegraph 1.5.10 → 1.6.1
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/CHANGELOG.md +27 -0
- package/README.md +64 -14
- package/dist/db/queries.d.ts +4 -0
- package/dist/db/queries.js +15 -0
- package/dist/extraction/grammars.d.ts +19 -0
- package/dist/extraction/grammars.js +44 -1
- package/dist/graph/evidence-paths.d.ts +2 -0
- package/dist/graph/evidence-paths.js +20 -3
- package/dist/mcp/arkts-evidence-packs.d.ts +17 -0
- package/dist/mcp/arkts-evidence-packs.js +219 -10
- package/dist/mcp/daemon.d.ts +21 -3
- package/dist/mcp/daemon.js +60 -6
- package/dist/mcp/engine.d.ts +26 -0
- package/dist/mcp/engine.js +143 -7
- package/dist/mcp/evidence-audit.d.ts +3 -0
- package/dist/mcp/evidence-audit.js +40 -0
- package/dist/mcp/implementation-context.d.ts +35 -0
- package/dist/mcp/implementation-context.js +232 -0
- package/dist/mcp/index-availability.d.ts +22 -0
- package/dist/mcp/index-availability.js +40 -1
- package/dist/mcp/index.js +9 -0
- package/dist/mcp/indexable-root.d.ts +22 -0
- package/dist/mcp/indexable-root.js +140 -0
- package/dist/mcp/liveness-watchdog.d.ts +6 -1
- package/dist/mcp/liveness-watchdog.js +17 -5
- package/dist/mcp/locate-contract.d.ts +50 -0
- package/dist/mcp/locate-contract.js +146 -0
- package/dist/mcp/query-cache.d.ts +1 -15
- package/dist/mcp/query-cache.js +20 -11
- package/dist/mcp/request-evidence.d.ts +69 -0
- package/dist/mcp/request-evidence.js +297 -0
- package/dist/mcp/server-instructions.d.ts +2 -2
- package/dist/mcp/server-instructions.js +12 -9
- package/dist/mcp/session.js +15 -0
- package/dist/mcp/tools.d.ts +67 -12
- package/dist/mcp/tools.js +841 -134
- package/dist/project-map/index.d.ts +45 -0
- package/dist/project-map/index.js +371 -3
- package/dist/resolution/callback-synthesizer.js +251 -0
- package/dist/resolution/frameworks/arkts-entry.d.ts +35 -6
- package/dist/resolution/frameworks/arkts-entry.js +513 -30
- package/dist/resolution/index.js +25 -21
- package/dist/runtime-log.d.ts +52 -0
- package/dist/runtime-log.js +199 -0
- package/dist/search/literal-evidence.js +11 -3
- package/dist/search/query-plan-provider.js +15 -6
- package/dist/search/query-plan.d.ts +3 -1
- package/dist/search/query-plan.js +25 -16
- package/dist/search/query-utils.d.ts +13 -0
- package/dist/search/query-utils.js +64 -0
- package/dist/search/request-contract.d.ts +29 -0
- package/dist/search/request-contract.js +76 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,30 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
## [1.6.1] - 2026-09-28
|
|
14
|
+
|
|
15
|
+
### Improvements
|
|
16
|
+
|
|
17
|
+
- MCP default tools/list is now the product slim pair — `homegraph_explore`, `homegraph_project` — so tool schemas stop dominating host context. Full catalog via `HOMEGRAPH_MCP_TOOLS=all` (or `*`) or an explicit comma list (e.g. add `arkui_migrate` when needed). MCP initialize instructions and the explore tool description match the slim surface (no pointers to tools hidden by default) (Spec 0051).
|
|
18
|
+
- ArkTS explore can bundle verified render/navigation scope, used imports and types, explicit module exports and local dependency configuration with the located source. Attached SDK modules provide bounded method/parameter signatures, while control summaries distinguish icon appearance, click guards and direct enabled bindings. Whole-group budgets and source fingerprints preserve evidence boundaries; optional local pack audit supports error analysis. No additional model call or mandatory tool (Spec 0050).
|
|
19
|
+
|
|
20
|
+
## [1.6.0] - 2026-09-23
|
|
21
|
+
|
|
22
|
+
### Improvements
|
|
23
|
+
|
|
24
|
+
- MCP auto-init (Spec 0049): empty workspace roots no longer create `.homegraph/` on `--auto-init` / `HOMEGRAPH_AUTO_INIT` (fixes DevEco in-place `devecocli create` hitting `PROJECT_EXISTS` because only an index dir existed). A 60s probe (`HOMEGRAPH_DEFER_PROBE_MS`; `0` = tool-kick only) and the first `homegraph_*` call re-check `isIndexableRoot` (root `build-profile.json5` or any indexable source); once non-empty, the existing fast-map + background full index path runs once. Status footers stay the product empty/fast/full/dirty/syncing lines. Lifecycle logging no longer mkdir's `.homegraph/` just to write `daemon.log`.
|
|
25
|
+
- Harmony locate seams (Spec 0048): index `form_config.json` / `shortcuts_config.json` (plus module.json5 form extensionAbilities and shortcuts/form metadata) as searchable capability nodes — explore may lead with **Capability profiles**, or an explicit no-in-repo form note instead of SDK `.d.ts`. Resource hits can append in-repo `$r('app.string.<key>')` **bound** `.ets` anchors. `homegraph_project` adds a **Module roster** (oh-package + local `file:` deps) and lists capability profile paths separately from rawfile. Explore may prepend **Seam notes** for nearby profiles and empty/log-only stubs.
|
|
26
|
+
- MCP product lifecycle (Spec 0047): main-thread liveness watchdog is **off by default** (enable with `HOMEGRAPH_WATCHDOG=1`; `HOMEGRAPH_NO_WATCHDOG=1` still forces off) so concurrent DevEco init no longer gets false "Main thread unresponsive" kills — file watch / incremental sync unchanged. Shared daemon idle linger defaults to **60s** after the last client disconnects; if auto-init/full index is still in `building_fast`/`indexing`, idle exit waits until that build settles, then starts the 60s linger. While any client is connected the daemon never idle-exits.
|
|
27
|
+
- MCP runtime log (Spec 0046): always-on coarse lifecycle lines (`mcp.start` / `mcp.initialize` / `auto-init.*` / `index.*` / `watcher.degraded`) go to stderr and `.homegraph/daemon.log` (same file daemon stdio already uses); soft-rotate at ~5 MiB to `daemon.log.1`. Set `HOMEGRAPH_DEBUG=1` for per-tool summaries (`tool.<name>` with duration / error / truncated query). No new `logs/` directory; default is not a full request ledger.
|
|
28
|
+
- ArkUI index-time edge synthesis (Spec 0045): `build` / `@Builder` bodies that call another in-repo `@Component` / `@Builder` gain `arkui-child` edges (ambiguous names dropped); literal `pushPathByName` / `replacePathByName` / `pushNamedRoute({ name })` link to indexed `route` nodes as `arkui-named-nav`. Complements existing `arkui-route` (`pushUrl`) and Spec 0039 route_map edges — no query-time synthesis.
|
|
29
|
+
- Explore locate contract (Spec 0044): Chinese/UI **literal witness** files stay in the first pack and rank ahead of Logger/hilog/Toast spines unless the query names those APIs; **Located** / **Partial** / **Miss** banners (Partial next-step → `node`/`usages`/`search`, no same-name Grep); Miss omits source bodies and lists fuzzy paths; filename≠primary-declaration risk note; `homegraph_node` for symbols already on the explore locate list bypasses the Partial depth-fuse cap. Dynamic-edge synthesis (10.3) remains deferred.
|
|
30
|
+
- When an MCP session already has a bound default project (`--path` / opened root), a tool `projectPath` that resolves to a **different** `.homegraph/` index root is soft-pinned: HomeGraph keeps answering from the bound root and prepends a short English notice (not `isError`). Same-root nested paths are unchanged; sessions with no default project still open cross-project indexes (Spec 0043).
|
|
31
|
+
- In-repo locate for explore: `taskContext` no longer enters the lexical/FTS query string (quoted literals from it still merge); PascalCase identifiers (≥8 chars) seed exact file/symbol roots like `Foo.ets`; business-oriented queries default `sourceScope=local` so SDK `.d.ts` stubs do not become roots; MCP trails / used-by / evidence packs hide `@dummyFile` and `%AM*` noise. `homegraph_project` adds a bounded HarmonyOS **resources path inventory** (string.json / rawfile / media dir counts / on-disk modules with zero indexed sources) — paths only, no JSON bodies or edges (Spec 0042).
|
|
32
|
+
- Harmony `resources/**/element/string.json` is indexed as searchable `constant` nodes (key + UI value in FTS). Explore may lead with a short **Resource hits** table and a `$r('app.string.<key>')` Grep hint — **no** graph edges to controls. Color/media/rawfile stay out of scope (Spec 0041).
|
|
33
|
+
- `homegraph_project` on Harmony repos now prints a **skeleton summary**: `bundle` from `app.json5`, a note that modules come from `build-profile.json5`, per-module `route profile:` paths (`route_map` / `router_map` / `main_pages`), and `oh-package` names when present. Still no call edges or profile JSON bodies — use explore for route→page (Spec 0039) and Read to edit. Tool descriptions and MCP initialize instructions spell out project vs explore (Spec 0040).
|
|
34
|
+
- Harmony `route_map.json` / `router_map.json` / `main_pages.json` are indexed (basename allowlist) and linked into the graph as `route` nodes → page / `buildFunction` symbols. Edges carry `synthesizedBy: arkts-route-map` and `registeredAt` pointing at the config file so explore/trails show the JSON wiring site. When an explore query mentions those filenames, replies lead with a short **Registration sources** table — evidence from those profiles, reducing blind re-Read of the JSON (Spec 0039).
|
|
35
|
+
- MCP tool replies that know the indexed project now begin with `HomeGraph project root: \`<absolute>\`` plus a one-line join rule: repo-relative paths below that root should be passed to Read/Grep as-is (or `<root>/<relative>` with `/`), without inventing experiment/result prefixes. MCP initialize instructions mention the same join base. Indexed path storage stays repo-relative (Spec 0038).
|
|
36
|
+
|
|
13
37
|
## [1.5.10] - 2026-09-20
|
|
14
38
|
|
|
15
39
|
### Fixes
|
|
@@ -21,6 +45,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
21
45
|
|
|
22
46
|
### Improvements
|
|
23
47
|
|
|
48
|
+
- ArkTS explore can retain grounded page/literal/object targets and report request evidence separately from source completeness. Verified joint targets improve candidate ordering; a scoped enabled-binding check distinguishes actual modifiers from appearance-only controls while keeping runtime behavior unverified. Results honor source fingerprints and pack budgets, with independent target/behavior switches. Existing precise relationship and resource routes remain available (Spec 0049).
|
|
24
49
|
- Bump `arkanalyzer` to **1.0.94**.
|
|
25
50
|
- Harmony projects with a root `build-profile.json5` now default to **serial indexing** after ArkAnalyzer: one parse worker and no resolve/synthesis worker pool. On SceneBoard-scale repos this cut peak process-tree PrivateMemory from ~8.5GB to ~3.8GB with only ~6% more wall clock. Opt out with `HOMEGRAPH_HARMONY_SERIAL=0`; force on with `=1`. Explicit `CODEGRAPH_PARSE_WORKERS` still overrides parse concurrency (Spec 0037).
|
|
26
51
|
- MCP product index readiness is now five short states (`empty` / `fast` / `full` / `dirty` / `syncing`): tool replies use a one-line `HomeGraph status=…` footer (or that line alone when the tool cannot answer yet). Pending edits surface as `dirty` with path list instead of the long stale banner; write locks stay `syncing`. MCP initialize includes a one-line status glossary (Spec 0035).
|
|
@@ -256,3 +281,5 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
256
281
|
[1.5.7]: https://github.com/fujiaxin-coder/homegraph/releases/tag/v1.5.7
|
|
257
282
|
[1.5.8]: https://github.com/fujiaxin-coder/homegraph/releases/tag/v1.5.8
|
|
258
283
|
[1.5.10]: https://github.com/fujiaxin-coder/homegraph/releases/tag/v1.5.10
|
|
284
|
+
[1.6.0]: https://github.com/fujiaxin-coder/homegraph/releases/tag/v1.6.0
|
|
285
|
+
[1.6.1]: https://github.com/fujiaxin-coder/homegraph/releases/tag/v1.6.1
|
package/README.md
CHANGED
|
@@ -171,29 +171,76 @@ homegraph serve mcp # 启动 MCP 服务(一般由 Agent 自动拉
|
|
|
171
171
|
|
|
172
172
|
Agent 侧工具名前缀为 `homegraph_`。
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
### 默认暴露(下载即用)
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
未设置 `HOMEGRAPH_MCP_TOOLS` 时,`tools/list` **只注册下面 2 个工具**(为压缩宿主上下文;Spec 0051)。刚升级后若发现以前能用的 `homegraph_node` / `search` / `arkui_migrate` 等「不见了」,不是卸载坏了,而是默认不再暴露——实现仍在,按下方「如何打开更多工具」恢复即可。
|
|
177
|
+
|
|
178
|
+
| 工具 | 用途 |
|
|
179
|
+
|------|------|
|
|
180
|
+
| `homegraph_project` | 工程/模块地图与 Harmony skeleton、资源**路径**导航(无符号正文、无调用图) |
|
|
181
|
+
| `homegraph_explore` | 通用结构探索:相关符号源码、调用路径、usage/依赖/NAPI 关系、route/resource/capability 等图证据 |
|
|
177
182
|
|
|
178
|
-
|
|
183
|
+
### 默认不暴露(需配置才进 tools/list)
|
|
184
|
+
|
|
185
|
+
下列工具 **handler 仍在**,默认不出现在 `tools/list`;未配置时直接调用会返回 `disabled via HOMEGRAPH_MCP_TOOLS`。
|
|
179
186
|
|
|
180
187
|
| 工具 | 用途 |
|
|
181
188
|
|------|------|
|
|
182
|
-
| `homegraph_usages` |
|
|
183
|
-
| `homegraph_modules` |
|
|
184
|
-
| `homegraph_native` |
|
|
185
|
-
| `
|
|
186
|
-
| `
|
|
187
|
-
| `homegraph_node` | 读取单个符号或整个文件的源码(带行号)及调用关系;可替代 Read 读文件 |
|
|
189
|
+
| `homegraph_usages` | 精确用法清单:已命名 API / 成员 / 常量 / 字段的引用位置 |
|
|
190
|
+
| `homegraph_modules` | 模块拓扑:已命名模块之间的依赖或循环依赖 |
|
|
191
|
+
| `homegraph_native` | Native 边界:NAPI / native 导出与注册位置 |
|
|
192
|
+
| `homegraph_search` | 按名称快速搜索符号(仅位置,不含源码) |
|
|
193
|
+
| `homegraph_node` | 读取单个符号或整个文件的源码(带行号)及调用关系 |
|
|
188
194
|
| `homegraph_callers` / `homegraph_callees` | 查看调用方 / 被调用方 |
|
|
189
195
|
| `homegraph_impact` | 变更影响分析(重构前使用) |
|
|
190
196
|
| `homegraph_diff_impact` | 传入 unified diff(或 hunks),返回与变更行相交的符号及调用/影响证据包(代码审查用) |
|
|
191
197
|
| `homegraph_arkui_migrate` | 一次返回 ArkUI 组件迁移/状态语义快照(装饰器、状态字段、Provide/Consume 等) |
|
|
192
198
|
| `homegraph_files` | 已索引的文件树(支持 glob 过滤、按语言分组) |
|
|
193
199
|
| `homegraph_status` | 索引健康状态(调试用;含 WAL 大小等) |
|
|
194
|
-
| `homegraph_spec_match` | 将新需求描述与 Commit4Spec
|
|
195
|
-
| `homegraph_spec_find` | 根据文件路径反向查找关联的Spec |
|
|
196
|
-
| `homegraph_spec_trace` | 根据代码符号追溯回关联的Spec |
|
|
200
|
+
| `homegraph_spec_match` | 将新需求描述与 Commit4Spec 知识图谱做全文匹配 |
|
|
201
|
+
| `homegraph_spec_find` | 根据文件路径反向查找关联的 Spec |
|
|
202
|
+
| `homegraph_spec_trace` | 根据代码符号追溯回关联的 Spec |
|
|
203
|
+
|
|
204
|
+
默认两件套下:用法/依赖/NAPI 类问题优先用 `homegraph_explore`;读已知路径用宿主 Read/Grep;ArkUI 迁移请显式打开 `arkui_migrate`(或 `all`)。
|
|
205
|
+
|
|
206
|
+
### 如何打开更多 / 全部 MCP 工具
|
|
207
|
+
|
|
208
|
+
在 **MCP 服务配置的 `environment` 字段**里设置(与 `HOMEGRAPH_NO_DAEMON` 同级)。这是注入给 HomeGraph MCP **进程**的环境变量;**不要**指望只在 Windows「系统属性 → 环境变量」里添加——MCP 子进程通常读不到系统/用户变量。
|
|
209
|
+
|
|
210
|
+
**打开全部工具:**
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"mcpServers": {
|
|
215
|
+
"homegraph": {
|
|
216
|
+
"command": "homegraph",
|
|
217
|
+
"args": ["serve", "mcp"],
|
|
218
|
+
"environment": {
|
|
219
|
+
"HOMEGRAPH_NO_DAEMON": "1",
|
|
220
|
+
"HOMEGRAPH_MCP_TOOLS": "all"
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
`HOMEGRAPH_MCP_TOOLS=*` 与 `all` 等价。
|
|
228
|
+
|
|
229
|
+
**只打开需要的子集(更省上下文):**
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
"environment": {
|
|
233
|
+
"HOMEGRAPH_MCP_TOOLS": "explore,project,node,search,arkui_migrate"
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
短名即可(`node` ≡ `homegraph_node`),逗号分隔。改完后**重启对应 Agent / MCP 服务**使配置生效。
|
|
238
|
+
|
|
239
|
+
**小仓注意:** 仅当设为 `all` / `*` 且索引文件数 **少于 500** 时,仍可能再裁到历史 TINY 核心集(`explore` / `search` / `node` / `diff_impact` / `project`)。小仓也要 `usages` / `arkui_migrate` 等时,请用**显式逗号列表**,不要只靠 `all`。
|
|
240
|
+
|
|
241
|
+
**跨项目查询:** 所有工具均支持可选参数 `projectPath`(绝对路径),用于在 monorepo 中查询子项目,或当 MCP 服务器根目录没有索引时指定目标项目。
|
|
242
|
+
|
|
243
|
+
**图谱数据源(`--sources` / `HOMEGRAPH_SOURCES`):** 控制 MCP 查询是否使用工程索引、OHOS SDK API 库,或两者。取值 `both`(默认)| `project` | `sdk` | `none`。CLI 优先于环境变量。评测示例:`homegraph serve mcp --path <app> --sources sdk`。`homegraph_status`(需先暴露该工具)会打印当前模式。
|
|
197
244
|
|
|
198
245
|
### 查询规划(实验性)
|
|
199
246
|
|
|
@@ -333,13 +380,16 @@ npm run cli
|
|
|
333
380
|
"homegraph": {
|
|
334
381
|
"type": "stdio",
|
|
335
382
|
"command": "homegraph",
|
|
336
|
-
"args": ["serve", "mcp"]
|
|
383
|
+
"args": ["serve", "mcp"],
|
|
384
|
+
"environment": {
|
|
385
|
+
"HOMEGRAPH_MCP_TOOLS": "all"
|
|
386
|
+
}
|
|
337
387
|
}
|
|
338
388
|
}
|
|
339
389
|
}
|
|
340
390
|
```
|
|
341
391
|
|
|
342
|
-
Cursor 等项目级配置写入 `./.cursor/mcp.json`,格式相同。推荐使用 `homegraph install` 自动完成。
|
|
392
|
+
不设 `HOMEGRAPH_MCP_TOOLS` 时默认只暴露 `explore` + `project`;需要全量或子集时按上一节「如何打开更多 / 全部 MCP 工具」配置。Cursor 等项目级配置写入 `./.cursor/mcp.json`,格式相同。推荐使用 `homegraph install` 自动完成。
|
|
343
393
|
|
|
344
394
|
---
|
|
345
395
|
|
package/dist/db/queries.d.ts
CHANGED
|
@@ -46,6 +46,10 @@ export declare class QueryBuilder {
|
|
|
46
46
|
/** Attach a versioned OHOS API db for federated symbol lookup. */
|
|
47
47
|
attachOhosApiDb(dbPath: string | null): void;
|
|
48
48
|
getOhosApiDbPath(): string | null;
|
|
49
|
+
/** Exact imported SDK module only. No cross-module bare-name fallback.
|
|
50
|
+
* A missing/oversized/ambiguous module returns no claim of signature coverage.
|
|
51
|
+
*/
|
|
52
|
+
getOhosApiModuleNodes(specifier: string): Node[];
|
|
49
53
|
private hasOhosApiAttached;
|
|
50
54
|
private mapOhosApiNodeRow;
|
|
51
55
|
/** Set the normalized project-name tokens used to down-weight non-discriminative
|
package/dist/db/queries.js
CHANGED
|
@@ -247,6 +247,21 @@ class QueryBuilder {
|
|
|
247
247
|
getOhosApiDbPath() {
|
|
248
248
|
return this.ohosApiDbPath;
|
|
249
249
|
}
|
|
250
|
+
/** Exact imported SDK module only. No cross-module bare-name fallback.
|
|
251
|
+
* A missing/oversized/ambiguous module returns no claim of signature coverage.
|
|
252
|
+
*/
|
|
253
|
+
getOhosApiModuleNodes(specifier) {
|
|
254
|
+
if (!this.ohosApiDbPath || !/^@(ohos|hms|kit)\.[A-Za-z0-9_.]+$/.test(specifier))
|
|
255
|
+
return [];
|
|
256
|
+
const stem = specifier.startsWith('@kit.') ? specifier.slice(5) : specifier;
|
|
257
|
+
const escaped = stem.replace(/[\\%_]/g, c => `\\${c}`);
|
|
258
|
+
const rows = this.db.prepare(`SELECT * FROM ohos_api.nodes WHERE
|
|
259
|
+
file_path = ? OR file_path = ? OR file_path LIKE ? ESCAPE '\\' OR file_path LIKE ? ESCAPE '\\'
|
|
260
|
+
ORDER BY file_path, start_line LIMIT 257`).all(`${stem}.d.ts`, `${stem}.d.ets`, `%/${escaped}.d.ts`, `%/${escaped}.d.ets`);
|
|
261
|
+
if (rows.length > 256 || new Set(rows.map(row => row.file_path)).size !== 1)
|
|
262
|
+
return [];
|
|
263
|
+
return rows.map(row => this.mapOhosApiNodeRow(row));
|
|
264
|
+
}
|
|
250
265
|
hasOhosApiAttached() {
|
|
251
266
|
return this.ohosApiDbPath != null;
|
|
252
267
|
}
|
|
@@ -45,6 +45,25 @@ export declare function isErlangAppFile(filePath: string): boolean;
|
|
|
45
45
|
export declare function isPlayRoutesFile(filePath: string): boolean;
|
|
46
46
|
/** HarmonyOS module manifest — parsed by the arkts-entry framework extractor. */
|
|
47
47
|
export declare function isArkModuleJson5(filePath: string): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Harmony Navigation / pages profile JSON (Spec 0039) — basename allowlist only.
|
|
50
|
+
* Parsed by arkts-entry; not general `.json` indexing.
|
|
51
|
+
*/
|
|
52
|
+
export declare function isHarmonyRouteProfileJson(filePath: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Harmony element string resources (Spec 0041) — path allowlist only.
|
|
55
|
+
* `…/resources/…/element/string.json` (not bare string.json, not color/media).
|
|
56
|
+
* Indexed as yaml file-level + arkts-entry constants for FTS; no graph edges.
|
|
57
|
+
*/
|
|
58
|
+
export declare function isHarmonyElementStringJson(filePath: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Harmony capability profiles (Spec 0048) — basename allowlist only.
|
|
61
|
+
* `form_config.json` (service widgets) and `shortcuts_config.json` (home-screen shortcuts).
|
|
62
|
+
* Indexed as yaml + arkts-entry constants; no UI call edges.
|
|
63
|
+
*/
|
|
64
|
+
export declare function isHarmonyCapabilityProfileJson(filePath: string): boolean;
|
|
65
|
+
/** Config files that host ArkTS `route` nodes (module manifest + Spec 0039 profiles). */
|
|
66
|
+
export declare function isHarmonyRouteConfigFile(filePath: string): boolean;
|
|
48
67
|
/**
|
|
49
68
|
* Initialize the tree-sitter WASM runtime. Must be called before loading grammars.
|
|
50
69
|
* Does NOT load any grammar WASM files — use loadGrammarsForLanguages() for that.
|
|
@@ -46,6 +46,10 @@ exports.isShopifyLiquidJson = isShopifyLiquidJson;
|
|
|
46
46
|
exports.isErlangAppFile = isErlangAppFile;
|
|
47
47
|
exports.isPlayRoutesFile = isPlayRoutesFile;
|
|
48
48
|
exports.isArkModuleJson5 = isArkModuleJson5;
|
|
49
|
+
exports.isHarmonyRouteProfileJson = isHarmonyRouteProfileJson;
|
|
50
|
+
exports.isHarmonyElementStringJson = isHarmonyElementStringJson;
|
|
51
|
+
exports.isHarmonyCapabilityProfileJson = isHarmonyCapabilityProfileJson;
|
|
52
|
+
exports.isHarmonyRouteConfigFile = isHarmonyRouteConfigFile;
|
|
49
53
|
exports.initGrammars = initGrammars;
|
|
50
54
|
exports.vendoredWasmFilenames = vendoredWasmFilenames;
|
|
51
55
|
exports.readGrammarWasmBytes = readGrammarWasmBytes;
|
|
@@ -235,6 +239,12 @@ function isSourceFile(filePath, overrides) {
|
|
|
235
239
|
return true; // Play `conf/routes` is extensionless
|
|
236
240
|
if (isArkModuleJson5(filePath))
|
|
237
241
|
return true;
|
|
242
|
+
if (isHarmonyRouteProfileJson(filePath))
|
|
243
|
+
return true; // Spec 0039
|
|
244
|
+
if (isHarmonyElementStringJson(filePath))
|
|
245
|
+
return true; // Spec 0041
|
|
246
|
+
if (isHarmonyCapabilityProfileJson(filePath))
|
|
247
|
+
return true; // Spec 0048
|
|
238
248
|
if (isShopifyLiquidJson(filePath))
|
|
239
249
|
return true; // Shopify OS 2.0 JSON templates / section groups
|
|
240
250
|
if (isErlangAppFile(filePath))
|
|
@@ -280,6 +290,35 @@ function isPlayRoutesFile(filePath) {
|
|
|
280
290
|
function isArkModuleJson5(filePath) {
|
|
281
291
|
return filePath.endsWith('module.json5');
|
|
282
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Harmony Navigation / pages profile JSON (Spec 0039) — basename allowlist only.
|
|
295
|
+
* Parsed by arkts-entry; not general `.json` indexing.
|
|
296
|
+
*/
|
|
297
|
+
function isHarmonyRouteProfileJson(filePath) {
|
|
298
|
+
const base = filePath.replace(/\\/g, '/').split('/').pop()?.toLowerCase() ?? '';
|
|
299
|
+
return base === 'route_map.json' || base === 'router_map.json' || base === 'main_pages.json';
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Harmony element string resources (Spec 0041) — path allowlist only.
|
|
303
|
+
* `…/resources/…/element/string.json` (not bare string.json, not color/media).
|
|
304
|
+
* Indexed as yaml file-level + arkts-entry constants for FTS; no graph edges.
|
|
305
|
+
*/
|
|
306
|
+
function isHarmonyElementStringJson(filePath) {
|
|
307
|
+
return /(?:^|\/)resources\/(?:[^/]+\/)*element\/string\.json$/i.test(filePath.replace(/\\/g, '/'));
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Harmony capability profiles (Spec 0048) — basename allowlist only.
|
|
311
|
+
* `form_config.json` (service widgets) and `shortcuts_config.json` (home-screen shortcuts).
|
|
312
|
+
* Indexed as yaml + arkts-entry constants; no UI call edges.
|
|
313
|
+
*/
|
|
314
|
+
function isHarmonyCapabilityProfileJson(filePath) {
|
|
315
|
+
const base = filePath.replace(/\\/g, '/').split('/').pop()?.toLowerCase() ?? '';
|
|
316
|
+
return base === 'form_config.json' || base === 'shortcuts_config.json';
|
|
317
|
+
}
|
|
318
|
+
/** Config files that host ArkTS `route` nodes (module manifest + Spec 0039 profiles). */
|
|
319
|
+
function isHarmonyRouteConfigFile(filePath) {
|
|
320
|
+
return isArkModuleJson5(filePath) || isHarmonyRouteProfileJson(filePath);
|
|
321
|
+
}
|
|
283
322
|
/**
|
|
284
323
|
* Caches for loaded grammars and parsers
|
|
285
324
|
*/
|
|
@@ -450,8 +489,12 @@ function detectLanguage(filePath, source, overrides) {
|
|
|
450
489
|
return 'yaml';
|
|
451
490
|
if (isArkModuleJson5(filePath))
|
|
452
491
|
return 'yaml';
|
|
453
|
-
if (
|
|
492
|
+
if (isHarmonyRouteProfileJson(filePath))
|
|
454
493
|
return 'yaml';
|
|
494
|
+
if (isHarmonyElementStringJson(filePath))
|
|
495
|
+
return 'yaml'; // Spec 0041
|
|
496
|
+
if (isHarmonyCapabilityProfileJson(filePath))
|
|
497
|
+
return 'yaml'; // Spec 0048
|
|
455
498
|
const ext = filePath.substring(filePath.lastIndexOf('.')).toLowerCase();
|
|
456
499
|
// Shopify OS 2.0 JSON templates / section groups → the Liquid extractor (it
|
|
457
500
|
// links each section `"type"` to its `sections/<type>.liquid`).
|
|
@@ -53,6 +53,8 @@ export declare function isEvidencePathNode(n: Node): boolean;
|
|
|
53
53
|
export declare function completeEvidencePathCandidates(query: string, nodes: Node[], lookup: (qualifiedName: string, limit: number) => Node[], plan?: QueryPlan): Node[];
|
|
54
54
|
/** Resolve only actual candidate identities; a bare homonym never selects the first hit. */
|
|
55
55
|
export declare function resolveEvidencePathGoal(query: string, nodes: Node[], focusIds: Set<string>, plan?: QueryPlan): EvidencePathGoal;
|
|
56
|
+
/** Framework-labelled static UI wiring; never treat an arbitrary reference as rendering. */
|
|
57
|
+
export declare function isArkuiScopeEdge(edge: Edge): boolean;
|
|
56
58
|
export declare function evidenceEdgeCost(edge: Edge, goal: EvidencePathGoal): number | null;
|
|
57
59
|
export declare function evidenceEdgeKey(edge: Edge): string;
|
|
58
60
|
/** One bounded search per request. Each orientation follows directed edges throughout. */
|
|
@@ -4,6 +4,7 @@ exports.EVIDENCE_PATH_LIMITS = void 0;
|
|
|
4
4
|
exports.isEvidencePathNode = isEvidencePathNode;
|
|
5
5
|
exports.completeEvidencePathCandidates = completeEvidencePathCandidates;
|
|
6
6
|
exports.resolveEvidencePathGoal = resolveEvidencePathGoal;
|
|
7
|
+
exports.isArkuiScopeEdge = isArkuiScopeEdge;
|
|
7
8
|
exports.evidenceEdgeCost = evidenceEdgeCost;
|
|
8
9
|
exports.evidenceEdgeKey = evidenceEdgeKey;
|
|
9
10
|
exports.searchEvidencePaths = searchEvidencePaths;
|
|
@@ -108,11 +109,18 @@ function edgeSemantics(edge) {
|
|
|
108
109
|
|| ['callback', 'event-emitter', 'closure-collection', 'fn-pointer-dispatch', 'arkui-emitter', 'arkui-common-event', 'arkui-taskpool'].includes(String(by));
|
|
109
110
|
return { state, event };
|
|
110
111
|
}
|
|
112
|
+
/** Framework-labelled static UI wiring; never treat an arbitrary reference as rendering. */
|
|
113
|
+
function isArkuiScopeEdge(edge) {
|
|
114
|
+
const by = edge.metadata?.synthesizedBy;
|
|
115
|
+
return (edge.kind === 'references' || edge.kind === 'calls' || edge.kind === 'contains') && ((by === 'viewtree' && ['child-component', 'builder', 'builder-param'].includes(String(edge.metadata?.via)))
|
|
116
|
+
|| (by === 'arkui-ownership' && edge.metadata?.via === 'build') || by === 'arkui-child' || by === 'arkui-named-nav' || by === 'arkts-route-map' || by === 'arkui-route');
|
|
117
|
+
}
|
|
111
118
|
function evidenceEdgeCost(edge, goal) {
|
|
112
119
|
const { state, event } = edgeSemantics(edge);
|
|
113
120
|
let relevanceCost;
|
|
114
121
|
if (goal.kind === 'structure') {
|
|
115
|
-
if (!['extends', 'implements', 'overrides', 'instantiates'].includes(edge.kind)
|
|
122
|
+
if (!['extends', 'implements', 'overrides', 'instantiates'].includes(edge.kind)
|
|
123
|
+
&& !(process.env.HOMEGRAPH_ARKTS_IMPLEMENTATION_CONTEXT !== '0' && isArkuiScopeEdge(edge)))
|
|
116
124
|
return null;
|
|
117
125
|
relevanceCost = 0;
|
|
118
126
|
}
|
|
@@ -143,7 +151,7 @@ function searchEvidencePaths(graph, goal, options = {}) {
|
|
|
143
151
|
const neighbors = new Map();
|
|
144
152
|
const paths = [];
|
|
145
153
|
const missing = [];
|
|
146
|
-
const kinds = goal.kind === 'structure' ? ['extends', 'implements', 'overrides', 'instantiates'] : ['calls', 'references'];
|
|
154
|
+
const kinds = goal.kind === 'structure' ? ['extends', 'implements', 'overrides', 'instantiates', ...(process.env.HOMEGRAPH_ARKTS_IMPLEMENTATION_CONTEXT !== '0' ? ['calls', 'references', 'contains'] : [])] : ['calls', 'references'];
|
|
147
155
|
const alive = () => {
|
|
148
156
|
if (now() - started >= limits.milliseconds) {
|
|
149
157
|
hits.add('time');
|
|
@@ -179,7 +187,16 @@ function searchEvidencePaths(graph, goal, options = {}) {
|
|
|
179
187
|
stats.rowsRead += rows.length;
|
|
180
188
|
if (rows.length > limits.perNode)
|
|
181
189
|
hits.add('neighbors');
|
|
182
|
-
const valid = rows.slice(0, limits.perNode).
|
|
190
|
+
const valid = rows.slice(0, limits.perNode).map(e => {
|
|
191
|
+
if (goal.kind === 'structure' && e.kind === 'contains' && process.env.HOMEGRAPH_ARKTS_IMPLEMENTATION_CONTEXT !== '0') {
|
|
192
|
+
const from = node(e.source);
|
|
193
|
+
const to = node(e.target);
|
|
194
|
+
if (from && ['component', 'struct'].includes(from.kind) && to?.kind === 'method' && to.name === 'build') {
|
|
195
|
+
return { ...e, metadata: { ...e.metadata, synthesizedBy: 'arkui-ownership', via: 'build' } };
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return e;
|
|
199
|
+
}).filter(e => evidenceEdgeCost(e, goal) !== null
|
|
183
200
|
&& node(e.source) && node(e.target)).sort((a, b) => evidenceEdgeCost(a, goal) - evidenceEdgeCost(b, goal)
|
|
184
201
|
|| evidenceEdgeKey(a).localeCompare(evidenceEdgeKey(b)));
|
|
185
202
|
adjacency.set(key, valid);
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { type SdkModule } from './implementation-context';
|
|
2
|
+
import { type RequestContract } from '../search/request-contract';
|
|
3
|
+
import { type RequestEvidence, type ControlEvidence } from './request-evidence';
|
|
1
4
|
import type HomeGraph from '../index';
|
|
2
5
|
import type { Edge, Node } from '../types';
|
|
3
6
|
import type { ExploreEmission } from './explore-session-state';
|
|
@@ -22,6 +25,15 @@ interface EvidencePack {
|
|
|
22
25
|
sources: string[];
|
|
23
26
|
priority: number;
|
|
24
27
|
gaps: EvidenceGap[];
|
|
28
|
+
context?: {
|
|
29
|
+
label: string;
|
|
30
|
+
notes: string[];
|
|
31
|
+
sdk?: {
|
|
32
|
+
module: string;
|
|
33
|
+
version: string;
|
|
34
|
+
nodes: Node[];
|
|
35
|
+
};
|
|
36
|
+
};
|
|
25
37
|
relation?: RelationEvidence;
|
|
26
38
|
path?: {
|
|
27
39
|
id: string;
|
|
@@ -36,6 +48,9 @@ export interface ArktsEvidenceResult {
|
|
|
36
48
|
version: 1 | 2;
|
|
37
49
|
scope: 'bounded_static_evidence';
|
|
38
50
|
status: 'complete' | 'partial' | 'empty';
|
|
51
|
+
requestEvidence?: RequestEvidence;
|
|
52
|
+
controls?: ControlEvidence[];
|
|
53
|
+
implementationContext?: Array<NonNullable<EvidencePack['context']>>;
|
|
39
54
|
selectedPacks: string[];
|
|
40
55
|
gaps: EvidenceGap[];
|
|
41
56
|
relations: NonNullable<EvidencePack['relation']>[];
|
|
@@ -62,6 +77,8 @@ export declare function buildArktsEvidencePacks(graph: Pick<HomeGraph, 'getNode'
|
|
|
62
77
|
maxChars: number;
|
|
63
78
|
maxFiles?: number;
|
|
64
79
|
pathSearch?: EvidencePathSearch;
|
|
80
|
+
requestContract?: RequestContract;
|
|
81
|
+
sdkModule?: (module: string) => SdkModule | undefined;
|
|
65
82
|
}): ArktsEvidenceResult | null;
|
|
66
83
|
export {};
|
|
67
84
|
//# sourceMappingURL=arkts-evidence-packs.d.ts.map
|