@guanlin4924/devflow-pi 0.1.79 → 0.1.81

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guanlin4924/devflow-pi",
3
- "version": "0.1.79",
3
+ "version": "0.1.81",
4
4
  "type": "module",
5
5
  "description": "Devflow 专项研发 Pi,基于固定版本 OMP Runtime 组装研发状态机、代码智能、设计、实现与质量门禁。",
6
6
  "license": "UNLICENSED",
@@ -1,4 +1,5 @@
1
- import { existsSync } from "node:fs";
1
+ import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
2
3
  import path from "node:path";
3
4
  import { fileURLToPath } from "node:url";
4
5
 
@@ -53,21 +54,32 @@ export default function devflowIntel(pi: ExtensionAPI) {
53
54
  label: "Devflow Code Index",
54
55
  description: "Scan, validate, audit, or query the deterministic project code index.",
55
56
  parameters: z.object({
56
- action: z.enum(["scan", "validate", "audit", "query", "relations", "impact"]),
57
+ action: z.enum(["scan", "validate", "audit", "query", "relations", "impact", "search-content", "resolve-domain", "query-plan", "domain-import"]),
57
58
  term: z.string().optional(),
58
59
  object: z.string().optional(),
59
60
  entity: z.string().optional(),
61
+ projectId: z.string().default("default"),
62
+ plan: z.record(z.string(), z.unknown()).optional(),
63
+ bundle: z.record(z.string(), z.unknown()).optional(),
64
+ repository: z.string().optional(),
65
+ pathPrefix: z.string().optional(),
66
+ language: z.string().optional(),
67
+ matchKind: z.enum(["literal", "identifier", "phrase", "substring"]).default("literal"),
68
+ direction: z.enum(["incoming", "outgoing", "both"]).default("outgoing"),
69
+ expectedRevision: z.string().optional(),
60
70
  changeType: z.enum(["remove_field", "rename_field", "change_type", "optional_to_required", "required_to_optional", "change_nullability", "change_enum"]).optional(),
61
71
  snapshot: z.string().optional(),
72
+ mappingRevision: z.string().optional(),
62
73
  depth: z.number().int().min(0).max(20).default(3),
63
74
  includeHeuristic: z.boolean().default(false),
64
75
  limit: z.number().int().min(1).max(100).default(20),
65
76
  changedFiles: z.array(z.string()).default([]),
77
+ validationLevel: z.enum(["fast", "publish", "full"]).default("publish"),
66
78
  }),
67
79
  approval: (args) => {
68
80
  const action = (args as { action?: string }).action;
69
81
  // scan 写 .planning/code-index,按 exec 询问;validate/audit/query 只读,免确认。
70
- return action === "scan" ? "exec" : "read";
82
+ return ["scan", "domain-import"].includes(action ?? "") ? "exec" : "read";
71
83
  },
72
84
  async execute(_id, params, _signal, _onUpdate, ctx) {
73
85
  const skillRoot = resolveSkillRoot(ctx.cwd);
@@ -78,9 +90,11 @@ export default function devflowIntel(pi: ExtensionAPI) {
78
90
  if (params.changedFiles.length > 0) args.push("--changed-files", ...params.changedFiles);
79
91
  } else if (params.action === "validate") {
80
92
  args.push("--index", ".planning/code-index");
93
+ args.push("--level", params.validationLevel);
81
94
  if (params.snapshot) args.push("--snapshot", params.snapshot);
82
95
  } else if (params.action === "audit") {
83
96
  args.push("--root", ctx.cwd, "--index", ".planning/code-index", "--skill-root", skillRoot);
97
+ args.push("--level", params.validationLevel === "fast" ? "publish" : params.validationLevel);
84
98
  if (params.snapshot) args.push("--snapshot", params.snapshot);
85
99
  } else if (params.action === "query") {
86
100
  if (!params.term) {
@@ -89,6 +103,40 @@ export default function devflowIntel(pi: ExtensionAPI) {
89
103
  args.push("--index", ".planning/code-index", "--term", params.term, "--limit", String(params.limit));
90
104
  if (params.snapshot) args.push("--snapshot", params.snapshot);
91
105
  } else {
106
+ if (params.action === "search-content") {
107
+ if (!params.term) return render({ ok: false, exitCode: 2, stdout: "", stderr: "term is required" }, {});
108
+ args.push("--index", ".planning/code-index", "--term", params.term, "--limit", String(params.limit));
109
+ args.push("--project-id", params.projectId);
110
+ args.push("--match-kind", params.matchKind === "phrase" ? "exact_phrase" : params.matchKind);
111
+ if (params.repository) args.push("--repository", params.repository);
112
+ if (params.pathPrefix) args.push("--path-prefix", params.pathPrefix);
113
+ if (params.language) args.push("--language", params.language);
114
+ return render(await run(args, ctx.cwd), { action: params.action });
115
+ } else if (params.action === "resolve-domain") {
116
+ if (!params.term) return render({ ok: false, exitCode: 2, stdout: "", stderr: "term is required" }, {});
117
+ args.push("--index", ".planning/code-index", "--term", params.term, "--project-id", params.projectId, "--limit", String(params.limit));
118
+ if (params.mappingRevision) args.push("--mapping-revision", params.mappingRevision);
119
+ return render(await run(args, ctx.cwd), { action: params.action });
120
+ } else if (params.action === "query-plan") {
121
+ if (!params.plan) return render({ ok: false, exitCode: 2, stdout: "", stderr: "plan is required" }, {});
122
+ const plan = { ...params.plan };
123
+ if (plan.limit === undefined) plan.limit = params.limit;
124
+ args.push("--index", ".planning/code-index", "--project-id", params.projectId, "--plan", JSON.stringify(plan));
125
+ if (params.snapshot) args.push("--snapshot", params.snapshot);
126
+ return render(await run(args, ctx.cwd), { action: params.action });
127
+ } else if (params.action === "domain-import") {
128
+ if (!params.bundle) return render({ ok: false, exitCode: 2, stdout: "", stderr: "bundle is required" }, {});
129
+ const bundleDir = mkdtempSync(path.join(tmpdir(), "devflow-domain-"));
130
+ const bundlePath = path.join(bundleDir, "bundle.json");
131
+ try {
132
+ writeFileSync(bundlePath, JSON.stringify(params.bundle), { encoding: "utf8", mode: 0o600 });
133
+ args.push("--index", ".planning/code-index", "--project-id", params.projectId, "--bundle", bundlePath);
134
+ if (params.expectedRevision) args.push("--expected-revision", params.expectedRevision);
135
+ return render(await run(args, ctx.cwd), { action: params.action });
136
+ } finally {
137
+ rmSync(bundleDir, { recursive: true, force: true });
138
+ }
139
+ }
92
140
  if (params.action === "impact") {
93
141
  if (!params.entity) return render({ ok: false, exitCode: 2, stdout: "", stderr: "entity is required" }, {});
94
142
  args.push("--index", ".planning/code-index", "--entity", params.entity, "--depth", String(params.depth), "--limit", String(params.limit));
@@ -98,6 +146,7 @@ export default function devflowIntel(pi: ExtensionAPI) {
98
146
  }
99
147
  if (!params.object) return render({ ok: false, exitCode: 2, stdout: "", stderr: "object is required" }, {});
100
148
  args.push("--index", ".planning/code-index", "--object", params.object, "--depth", String(params.depth), "--limit", String(params.limit));
149
+ args.push("--direction", params.direction);
101
150
  if (params.snapshot) args.push("--snapshot", params.snapshot);
102
151
  if (params.includeHeuristic) args.push("--include-heuristic");
103
152
  }
@@ -47,6 +47,20 @@ devflow_code_index(action="audit")
47
47
  devflow_code_index(action="impact", entity="api:orders", changeType="remove_field")
48
48
  ```
49
49
 
50
+ Validation is staged so large indexes do not block publication on a full
51
+ sidecar audit:
52
+
53
+ - `validationLevel="fast"` checks the snapshot bundle and generation metadata.
54
+ - `validationLevel="publish"` (the default) adds SQLite quick-checks and
55
+ SQL-backed symbol/relation referential checks. It is the initialization
56
+ publish gate and does not load every JSONL sidecar into memory.
57
+ - `validationLevel="full"` additionally validates every JSONL record and the
58
+ semantic graph. Run it as an explicit audit when complete verification is
59
+ required.
60
+
61
+ The same split is available to `audit`: the default publish audit is bounded;
62
+ `validationLevel="full"` performs stale-file and full relation auditing.
63
+
50
64
  For changed-file indexing:
51
65
 
52
66
  ```text