@guanlin4924/devflow-pi 0.1.102 → 0.1.104

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,7 +11,7 @@ Devflow Pi 是一个面向项目研发交付的独立 OMP 产品入口,内置
11
11
  安装与启动:
12
12
 
13
13
  ```bash
14
- npm install -g @guanlin4924/devflow-pi@0.1.102
14
+ npm install -g @guanlin4924/devflow-pi@0.1.104
15
15
  cd /path/to/your-project
16
16
  devflow-pi init
17
17
  devflow-pi doctor
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guanlin4924/devflow-pi",
3
- "version": "0.1.102",
3
+ "version": "0.1.104",
4
4
  "type": "module",
5
5
  "description": "Devflow 专项研发 Pi,基于固定版本 OMP Runtime 组装研发状态机、代码智能、设计、实现与质量门禁。",
6
6
  "license": "UNLICENSED",
@@ -14,6 +14,14 @@ def sha256(path: Path) -> str:
14
14
  return hashlib.sha256(path.read_bytes()).hexdigest()
15
15
 
16
16
 
17
+ def input_present(path):
18
+ """A declared input without a trailing "/" may still be a rendered
19
+ directory (e.g. wireframes/screens); accept it when it holds a file."""
20
+ if path.is_file():
21
+ return True
22
+ return path.is_dir() and any(child.is_file() for child in path.rglob("*"))
23
+
24
+
17
25
  def within(root: Path, relative: str) -> Path:
18
26
  if not isinstance(relative, str) or not relative or Path(relative).is_absolute() or "\x00" in relative:
19
27
  raise ValueError("invalid relative path")
@@ -166,8 +174,11 @@ def preflight(root: Path, feature: str, step: str, contract_path: str,
166
174
  elif path.exists() or stage != "entry":
167
175
  issues.append({"code": "MISSING_INPUT_FACT", "index": index, "path": relative})
168
176
  elif producer == "existing":
169
- if not path.is_file():
177
+ if not input_present(path):
170
178
  issues.append({"code": "MISSING_INPUT_FACT", "index": index, "path": relative})
179
+ elif path.is_dir():
180
+ # A rendered directory has no single-file fingerprint.
181
+ evidence.append({"kind": "input_collection", "path": relative})
171
182
  elif obligation.get("sha256") is not None and obligation.get("sha256") != sha256(path):
172
183
  issues.append({"code": "STALE_INPUT_FACT", "index": index, "path": relative})
173
184
  else:
@@ -40,7 +40,13 @@ def read_handoff(root: Path, relative: str, evidence: list[dict], issues: list[d
40
40
  except ValueError:
41
41
  issues.append({"code": "PREVIOUS_OUTPUT_MISSING", "path": output_relative})
42
42
  continue
43
- if not output_path.is_file():
43
+ if output_path.is_dir() and item.get("sha256") is None:
44
+ # Directory outputs (e.g. wireframes/screens) are recorded without a hash.
45
+ if review_preflight.input_present(output_path):
46
+ evidence.append({"kind": "previous_output_collection", "path": output_relative})
47
+ else:
48
+ issues.append({"code": "PREVIOUS_OUTPUT_MISSING", "path": output_relative})
49
+ elif not output_path.is_file():
44
50
  issues.append({"code": "PREVIOUS_OUTPUT_MISSING", "path": output_relative})
45
51
  elif item.get("sha256") != review_preflight.sha256(output_path):
46
52
  issues.append({"code": "PREVIOUS_OUTPUT_CHANGED", "path": output_relative})
@@ -123,7 +129,7 @@ def startup_preflight(root: Path, feature: str, step: str,
123
129
  collection = relative.endswith("/")
124
130
  try:
125
131
  target = review_preflight.within(root, rendered)
126
- exists = target.is_dir() if collection else target.is_file()
132
+ exists = target.is_dir() if collection else review_preflight.input_present(target)
127
133
  except ValueError:
128
134
  exists = False
129
135
  # Same rule as gate_runtime.rb: a collection input may be absent at entry.
package/src/constants.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export const PRODUCT_NAME = "Devflow Pi";
2
- export const PRODUCT_VERSION = "0.1.102";
2
+ export const PRODUCT_VERSION = "0.1.104";
3
3
  export const PROJECT_SCHEMA_VERSION = 1;
4
4
  export const OMP_RUNTIME_VERSION = "17.2.7";
5
5