homegraph 1.5.0 → 1.5.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.
Files changed (214) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +305 -305
  3. package/dist/bin/command-supervision.d.ts.map +1 -1
  4. package/dist/bin/command-supervision.js +7 -4
  5. package/dist/bin/command-supervision.js.map +1 -1
  6. package/dist/bin/homegraph.js +9 -9
  7. package/dist/db/index.js +36 -36
  8. package/dist/db/migrations.js +37 -37
  9. package/dist/db/queries.js +156 -156
  10. package/dist/db/schema.sql +203 -203
  11. package/dist/directory.js +5 -5
  12. package/dist/extraction/languages/arkts-viewtree.d.ts +2 -4
  13. package/dist/extraction/languages/arkts-viewtree.d.ts.map +1 -1
  14. package/dist/extraction/languages/arkts-viewtree.js +6 -21
  15. package/dist/extraction/languages/arkts-viewtree.js.map +1 -1
  16. package/dist/extraction/languages/arkts.d.ts +16 -6
  17. package/dist/extraction/languages/arkts.d.ts.map +1 -1
  18. package/dist/extraction/languages/arkts.js +174 -21
  19. package/dist/extraction/languages/arkts.js.map +1 -1
  20. package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
  21. package/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
  22. package/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
  23. package/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
  24. package/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
  25. package/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
  26. package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
  27. package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  28. package/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
  29. package/dist/installer/instructions-template.js +9 -9
  30. package/dist/mcp/liveness-watchdog.d.ts +18 -0
  31. package/dist/mcp/liveness-watchdog.d.ts.map +1 -1
  32. package/dist/mcp/liveness-watchdog.js +185 -73
  33. package/dist/mcp/liveness-watchdog.js.map +1 -1
  34. package/dist/mcp/server-instructions.js +47 -47
  35. package/dist/reasoning/reasoner.js +32 -32
  36. package/dist/spec/db/commit-node.js +4 -4
  37. package/dist/spec/db/fragment-node.js +10 -10
  38. package/dist/spec/db/fts.js +8 -8
  39. package/dist/spec/db/relations.js +88 -88
  40. package/dist/spec/db/schema.js +6 -6
  41. package/dist/spec/db/schema.sql +121 -121
  42. package/dist/spec/db/spec-node.js +4 -4
  43. package/dist/spec/llm/prompts.js +53 -53
  44. package/dist/spec/utils.d.ts +16 -4
  45. package/dist/spec/utils.d.ts.map +1 -1
  46. package/dist/spec/utils.js +58 -6
  47. package/dist/spec/utils.js.map +1 -1
  48. package/package.json +62 -62
  49. package/scripts/_tmp-cfwk-resolve.log +0 -0
  50. package/scripts/_tmp-cfwk-sig.log +0 -0
  51. package/scripts/_tmp-cfwk-vt.log +0 -0
  52. package/scripts/add-lang/bench.sh +60 -60
  53. package/scripts/add-lang/check-grammar.mjs +75 -75
  54. package/scripts/add-lang/dump-ast.mjs +103 -103
  55. package/scripts/add-lang/verify-extraction.mjs +70 -70
  56. package/scripts/agent-eval/ab-adoption.sh +91 -91
  57. package/scripts/agent-eval/ab-hook.sh +86 -86
  58. package/scripts/agent-eval/ab-impl.sh +78 -78
  59. package/scripts/agent-eval/ab-new-vs-baseline.sh +102 -102
  60. package/scripts/agent-eval/ab-sufficiency.sh +78 -78
  61. package/scripts/agent-eval/arms-F.sh +21 -21
  62. package/scripts/agent-eval/arms-matrix.sh +37 -37
  63. package/scripts/agent-eval/audit.sh +68 -68
  64. package/scripts/agent-eval/bench-readme.sh +28 -28
  65. package/scripts/agent-eval/bench-why-repo.sh +22 -22
  66. package/scripts/agent-eval/block-read-hook.sh +19 -19
  67. package/scripts/agent-eval/hook-settings.json +15 -15
  68. package/scripts/agent-eval/itrun.sh +120 -120
  69. package/scripts/agent-eval/offload-eval-3arm.sh +72 -72
  70. package/scripts/agent-eval/offload-eval-cost.mjs +133 -133
  71. package/scripts/agent-eval/offload-eval-effort.mjs +108 -108
  72. package/scripts/agent-eval/offload-eval-frontload-matrix.sh +25 -25
  73. package/scripts/agent-eval/offload-eval-frontload.sh +47 -47
  74. package/scripts/agent-eval/offload-eval-ground-truth.json +18 -18
  75. package/scripts/agent-eval/offload-eval-hook.mjs +84 -84
  76. package/scripts/agent-eval/offload-eval-judge.mjs +103 -103
  77. package/scripts/agent-eval/offload-eval-matrix.sh +20 -20
  78. package/scripts/agent-eval/offload-eval-metrics.mjs +94 -94
  79. package/scripts/agent-eval/offload-eval-refs1.sh +50 -50
  80. package/scripts/agent-eval/offload-eval-setup.sh +24 -24
  81. package/scripts/agent-eval/offload-eval-styles.sh +71 -71
  82. package/scripts/agent-eval/offload-eval-summarize.mjs +68 -68
  83. package/scripts/agent-eval/offload-eval.md +76 -76
  84. package/scripts/agent-eval/parse-arms.mjs +116 -116
  85. package/scripts/agent-eval/parse-bench-readme.mjs +84 -84
  86. package/scripts/agent-eval/parse-run.mjs +45 -45
  87. package/scripts/agent-eval/parse-session.mjs +93 -93
  88. package/scripts/agent-eval/probe-context.mjs +21 -21
  89. package/scripts/agent-eval/probe-explore.mjs +40 -40
  90. package/scripts/agent-eval/probe-node.mjs +20 -20
  91. package/scripts/agent-eval/probe-sweep.mjs +119 -119
  92. package/scripts/agent-eval/probe-trace.mjs +20 -20
  93. package/scripts/agent-eval/redirect-read-hook.sh +38 -38
  94. package/scripts/agent-eval/repro-concurrent-explore.mjs +119 -119
  95. package/scripts/agent-eval/repro-daemon-clients.mjs +125 -125
  96. package/scripts/agent-eval/run-agent.sh +34 -34
  97. package/scripts/agent-eval/run-all.sh +75 -75
  98. package/scripts/agent-eval/run-arms.sh +56 -56
  99. package/scripts/agent-eval/seq-matrix.mjs +137 -137
  100. package/scripts/bench-arkts-init-rss.log +0 -0
  101. package/scripts/build-bundle.sh +123 -123
  102. package/scripts/exp_boundary_eval/README.md +247 -247
  103. package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-310.pyc +0 -0
  104. package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-38.pyc +0 -0
  105. package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-310.pyc +0 -0
  106. package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-38.pyc +0 -0
  107. package/scripts/exp_boundary_eval/__pycache__/deveco_arm.cpython-38.pyc +0 -0
  108. package/scripts/exp_boundary_eval/__pycache__/run_all.cpython-310.pyc +0 -0
  109. package/scripts/exp_boundary_eval/__pycache__/run_all.cpython-38.pyc +0 -0
  110. package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-310.pyc +0 -0
  111. package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-38.pyc +0 -0
  112. package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-310.pyc +0 -0
  113. package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-38.pyc +0 -0
  114. package/scripts/exp_boundary_eval/__pycache__/setup.cpython-310.pyc +0 -0
  115. package/scripts/exp_boundary_eval/__pycache__/setup.cpython-38.pyc +0 -0
  116. package/scripts/exp_boundary_eval/__pycache__/win_mcp_launcher.cpython-38.pyc +0 -0
  117. package/scripts/exp_boundary_eval/_test_mcp_chain.py +78 -78
  118. package/scripts/exp_boundary_eval/_test_stdin.py +8 -8
  119. package/scripts/exp_boundary_eval/_utils.py +1116 -1116
  120. package/scripts/exp_boundary_eval/analyze.py +1313 -1313
  121. package/scripts/exp_boundary_eval/deveco_arm.py +519 -519
  122. package/scripts/exp_boundary_eval/run_all.py +378 -378
  123. package/scripts/exp_boundary_eval/run_one.py +165 -165
  124. package/scripts/exp_boundary_eval/run_session.py +158 -158
  125. package/scripts/exp_boundary_eval/setup.py +120 -120
  126. package/scripts/exp_boundary_eval/win_mcp_launcher.py +73 -73
  127. package/scripts/exp_boundary_eval/win_mcp_stdio_wrap.js +36 -36
  128. package/scripts/exp_boundary_eval/win_node_launcher.py +24 -24
  129. package/scripts/extract-release-notes.mjs +130 -130
  130. package/scripts/local-install.sh +41 -41
  131. package/scripts/npm-sdk.js +75 -75
  132. package/scripts/npm-shim.js +275 -275
  133. package/scripts/ohos-sdk-publish.mjs +133 -133
  134. package/scripts/pack-npm.sh +119 -119
  135. package/scripts/prepare-release.mjs +270 -270
  136. package/scripts/probe-arkts-mem-why-run.log +0 -0
  137. package/scripts/probe-banner-livecard-ir.log +0 -0
  138. package/scripts/probe-cfwk-ast.stderr.log +0 -0
  139. package/scripts/probe-cfwk-ast.stdout.log +0 -0
  140. package/scripts/probe-cfwk-attr-shape.log +0 -0
  141. package/scripts/probe-cfwk-cfgdump.stderr.log +0 -0
  142. package/scripts/probe-cfwk-cfgdump.stdout.log +0 -0
  143. package/scripts/probe-cfwk-cvc.stderr.log +0 -0
  144. package/scripts/probe-cfwk-cvc.stdout.log +0 -0
  145. package/scripts/probe-cfwk-diag2.log +0 -0
  146. package/scripts/probe-cfwk-diag3.log +0 -0
  147. package/scripts/probe-cfwk-fedbg.stderr.log +0 -0
  148. package/scripts/probe-cfwk-fedbg.stdout.log +0 -0
  149. package/scripts/probe-cfwk-fileresult.log +0 -0
  150. package/scripts/probe-cfwk-fix.stderr.log +0 -0
  151. package/scripts/probe-cfwk-fix.stdout.log +0 -0
  152. package/scripts/probe-cfwk-fix2.stderr.log +0 -0
  153. package/scripts/probe-cfwk-fix2.stdout.log +0 -0
  154. package/scripts/probe-cfwk-fix3.stderr.log +0 -0
  155. package/scripts/probe-cfwk-fix3.stdout.log +0 -0
  156. package/scripts/probe-cfwk-foreach.log +0 -0
  157. package/scripts/probe-cfwk-getmethod-throw.log +0 -0
  158. package/scripts/probe-cfwk-hg-extract.log +0 -0
  159. package/scripts/probe-cfwk-pr1003-noprior.stderr.log +0 -0
  160. package/scripts/probe-cfwk-pr1003-noprior.stdout.log +0 -0
  161. package/scripts/probe-cfwk-pr1003.stderr.log +0 -0
  162. package/scripts/probe-cfwk-pr1003.stdout.log +0 -0
  163. package/scripts/probe-cfwk-preroot-noprior.stderr.log +0 -0
  164. package/scripts/probe-cfwk-preroot-noprior.stdout.log +0 -0
  165. package/scripts/probe-cfwk-preroot-prior.stderr.log +0 -0
  166. package/scripts/probe-cfwk-preroot-prior.stdout.log +0 -0
  167. package/scripts/probe-cfwk-preroot-skipstate.stderr.log +0 -0
  168. package/scripts/probe-cfwk-preroot-skipstate.stdout.log +0 -0
  169. package/scripts/probe-cfwk-resolve-sim.log +0 -0
  170. package/scripts/probe-cfwk-tree-shape.log +0 -0
  171. package/scripts/probe-cfwk-walk-abort.log +0 -0
  172. package/scripts/probe-cfwk.log +0 -0
  173. package/scripts/probe-force-index.log +0 -0
  174. package/scripts/probe-no-force-index.log +0 -0
  175. package/scripts/probe-samefile-ir.stderr.log +0 -0
  176. package/scripts/probe-samefile-ir.stdout.log +224 -0
  177. package/scripts/probe-sdk-vs-project.log +0 -0
  178. package/scripts/probe-viewtree-downgrade.log +0 -0
  179. package/dist/arkts/ohos-api-index.d.ts +0 -15
  180. package/dist/arkts/ohos-api-index.d.ts.map +0 -1
  181. package/dist/arkts/ohos-api-index.js +0 -190
  182. package/dist/arkts/ohos-api-index.js.map +0 -1
  183. package/dist/arkts/ohos-sdk-input.d.ts +0 -36
  184. package/dist/arkts/ohos-sdk-input.d.ts.map +0 -1
  185. package/dist/arkts/ohos-sdk-input.js +0 -214
  186. package/dist/arkts/ohos-sdk-input.js.map +0 -1
  187. package/dist/extraction/languages/arkts-state-decorators.d.ts +0 -13
  188. package/dist/extraction/languages/arkts-state-decorators.d.ts.map +0 -1
  189. package/dist/extraction/languages/arkts-state-decorators.js +0 -26
  190. package/dist/extraction/languages/arkts-state-decorators.js.map +0 -1
  191. package/dist/extraction/languages/ohos-api-consumer.d.ts +0 -34
  192. package/dist/extraction/languages/ohos-api-consumer.d.ts.map +0 -1
  193. package/dist/extraction/languages/ohos-api-consumer.js +0 -283
  194. package/dist/extraction/languages/ohos-api-consumer.js.map +0 -1
  195. package/dist/spec/build/git-scanner.d.ts +0 -93
  196. package/dist/spec/build/git-scanner.d.ts.map +0 -1
  197. package/dist/spec/build/git-scanner.js +0 -254
  198. package/dist/spec/build/git-scanner.js.map +0 -1
  199. package/dist/spec/git-utils.d.ts +0 -8
  200. package/dist/spec/git-utils.d.ts.map +0 -1
  201. package/dist/spec/git-utils.js +0 -14
  202. package/dist/spec/git-utils.js.map +0 -1
  203. package/dist/spec/mine/clusterer.d.ts +0 -63
  204. package/dist/spec/mine/clusterer.d.ts.map +0 -1
  205. package/dist/spec/mine/clusterer.js +0 -904
  206. package/dist/spec/mine/clusterer.js.map +0 -1
  207. package/dist/spec/mine/progress-handler.d.ts +0 -22
  208. package/dist/spec/mine/progress-handler.d.ts.map +0 -1
  209. package/dist/spec/mine/progress-handler.js +0 -108
  210. package/dist/spec/mine/progress-handler.js.map +0 -1
  211. package/dist/spec/mine/progress.d.ts +0 -23
  212. package/dist/spec/mine/progress.d.ts.map +0 -1
  213. package/dist/spec/mine/progress.js +0 -12
  214. package/dist/spec/mine/progress.js.map +0 -1
@@ -1,120 +1,120 @@
1
- #!/usr/bin/env python3
2
- """Prepare a clean repo for an experiment run. Agent-aware."""
3
-
4
- import os
5
- import subprocess
6
- import sys
7
- from datetime import datetime, timezone
8
- from pathlib import Path
9
- from typing import Optional, Tuple
10
-
11
- from _utils import (append_run_log, error, generate_session_id,
12
- get_agent, get_agent_version, git_output, git_ok, log,
13
- shell_ok, verify_agent_binary, write_json)
14
- from deveco_arm import git_clean_repo, write_deveco_project_config
15
-
16
-
17
- def prepare_environment(exp_id: str, clean_mode: str = "full",
18
- agent_name: str = "",
19
- state_dir: Optional[Path] = None) -> Tuple[str, str]:
20
- """Prepare repo. Returns (session_id, agent_name)."""
21
- clone_path = os.environ.get("REPO_CLONE", "")
22
- is_clone = bool(clone_path and Path(clone_path).is_dir())
23
- local_repo = os.environ.get("REPO_PATH", "")
24
- if is_clone:
25
- repo_root = Path(clone_path)
26
- elif local_repo and Path(local_repo).is_dir():
27
- repo_root = Path(local_repo)
28
- else:
29
- error("No repo available. Clone via run_all.py or set REPO_PATH / REPO_CLONE.")
30
- sys.exit(1)
31
-
32
- if state_dir is not None:
33
- _state_dir = state_dir
34
- else:
35
- from _utils import LOG_DIR
36
- _state_dir = LOG_DIR
37
-
38
- if is_clone:
39
- log(f"Using cloned repo: {repo_root}")
40
- else:
41
- log(f"Using local repo: {repo_root}")
42
-
43
- os.chdir(repo_root)
44
-
45
- # Agent config
46
- agent = get_agent(agent_name)
47
- binary = agent["binary"]
48
-
49
- # Step 1: Clean repo
50
- arm = os.environ.get("EVAL_ARM", "baseline")
51
- if clean_mode == "full":
52
- log("Restoring repo to clean state...")
53
- branch = os.environ.get("BRANCH", "weekly_20260601")
54
- shell_ok(f"git checkout {branch}")
55
- git_ok(["checkout", "."], cwd=repo_root)
56
- git_clean_repo(repo_root, arm)
57
-
58
- current_branch = git_output(["branch", "--show-current"], cwd=repo_root)
59
- commit = git_output(["rev-parse", "--short", "HEAD"], cwd=repo_root)
60
- log(f"Branch: {current_branch} | Commit: {commit}")
61
-
62
- # Step 1b: DevEco A/B project config (.deveco/deveco.jsonc)
63
- if agent.get("binary") == "deveco":
64
- write_deveco_project_config(repo_root, arm)
65
-
66
- # Step 1c: Index rebuilt once at homegraph suite start (run_all / prebuild).
67
- # Per-experiment git reset restores the same commit — no second index here.
68
- # Step 2: Clear CLAUDE.md
69
- claude_md = repo_root / "CLAUDE.md"
70
- if claude_md.exists() and claude_md.stat().st_size > 0:
71
- backup_dir = _state_dir / "claude_md_backups"
72
- backup_dir.mkdir(parents=True, exist_ok=True)
73
- ts = datetime.now().strftime("%Y%m%d_%H%M%S")
74
- backup_path = backup_dir / f"CLAUDE.md.{ts}"
75
- backup_path.write_text(claude_md.read_text())
76
- log(f"Backed up CLAUDE.md → {backup_path}")
77
- with open(claude_md, "w") as f:
78
- f.write("")
79
- log("Cleared CLAUDE.md")
80
-
81
- for f in [".cursorrules", ".cursor/rules"]:
82
- p = repo_root / f
83
- if p.exists():
84
- p.unlink()
85
-
86
- # Step 3: Session ID
87
- session_id = generate_session_id()
88
- (_state_dir / f"session_{exp_id}.txt").write_text(session_id)
89
- log(f"Session ID: {session_id}")
90
-
91
- # Step 4: Verify agent binary
92
- ok, resolved, err_msg = verify_agent_binary(agent)
93
- if not ok:
94
- error(err_msg)
95
- sys.exit(1)
96
- binary = resolved
97
- agent_ver = get_agent_version(agent)
98
- log(f"Agent: {agent['name']} ({binary}) v{agent_ver}")
99
-
100
- # Step 5: Record state
101
- write_json(_state_dir / exp_id / "state.json", {
102
- "experiment_id": exp_id, "session_id": session_id,
103
- "started_at": datetime.now(timezone.utc).isoformat(),
104
- "clean_mode": clean_mode, "agent": agent["name"],
105
- "agent_version": agent_ver, "repo_root": str(repo_root),
106
- "git_branch": git_output(["branch", "--show-current"], cwd=repo_root),
107
- "git_commit": git_output(["rev-parse", "HEAD"], cwd=repo_root),
108
- })
109
-
110
- append_run_log(_state_dir, f"Setup complete for {exp_id}: session={session_id}, agent={agent['name']}")
111
- log("Setup complete.")
112
- return session_id, agent["name"]
113
-
114
-
115
- if __name__ == "__main__":
116
- exp_id = sys.argv[1] if len(sys.argv) > 1 else "all"
117
- clean_mode = sys.argv[2] if len(sys.argv) > 2 else "full"
118
- agent_name = sys.argv[3] if len(sys.argv) > 3 else ""
119
- sid, _ = prepare_environment(exp_id, clean_mode, agent_name)
120
- print(sid)
1
+ #!/usr/bin/env python3
2
+ """Prepare a clean repo for an experiment run. Agent-aware."""
3
+
4
+ import os
5
+ import subprocess
6
+ import sys
7
+ from datetime import datetime, timezone
8
+ from pathlib import Path
9
+ from typing import Optional, Tuple
10
+
11
+ from _utils import (append_run_log, error, generate_session_id,
12
+ get_agent, get_agent_version, git_output, git_ok, log,
13
+ shell_ok, verify_agent_binary, write_json)
14
+ from deveco_arm import git_clean_repo, write_deveco_project_config
15
+
16
+
17
+ def prepare_environment(exp_id: str, clean_mode: str = "full",
18
+ agent_name: str = "",
19
+ state_dir: Optional[Path] = None) -> Tuple[str, str]:
20
+ """Prepare repo. Returns (session_id, agent_name)."""
21
+ clone_path = os.environ.get("REPO_CLONE", "")
22
+ is_clone = bool(clone_path and Path(clone_path).is_dir())
23
+ local_repo = os.environ.get("REPO_PATH", "")
24
+ if is_clone:
25
+ repo_root = Path(clone_path)
26
+ elif local_repo and Path(local_repo).is_dir():
27
+ repo_root = Path(local_repo)
28
+ else:
29
+ error("No repo available. Clone via run_all.py or set REPO_PATH / REPO_CLONE.")
30
+ sys.exit(1)
31
+
32
+ if state_dir is not None:
33
+ _state_dir = state_dir
34
+ else:
35
+ from _utils import LOG_DIR
36
+ _state_dir = LOG_DIR
37
+
38
+ if is_clone:
39
+ log(f"Using cloned repo: {repo_root}")
40
+ else:
41
+ log(f"Using local repo: {repo_root}")
42
+
43
+ os.chdir(repo_root)
44
+
45
+ # Agent config
46
+ agent = get_agent(agent_name)
47
+ binary = agent["binary"]
48
+
49
+ # Step 1: Clean repo
50
+ arm = os.environ.get("EVAL_ARM", "baseline")
51
+ if clean_mode == "full":
52
+ log("Restoring repo to clean state...")
53
+ branch = os.environ.get("BRANCH", "weekly_20260601")
54
+ shell_ok(f"git checkout {branch}")
55
+ git_ok(["checkout", "."], cwd=repo_root)
56
+ git_clean_repo(repo_root, arm)
57
+
58
+ current_branch = git_output(["branch", "--show-current"], cwd=repo_root)
59
+ commit = git_output(["rev-parse", "--short", "HEAD"], cwd=repo_root)
60
+ log(f"Branch: {current_branch} | Commit: {commit}")
61
+
62
+ # Step 1b: DevEco A/B project config (.deveco/deveco.jsonc)
63
+ if agent.get("binary") == "deveco":
64
+ write_deveco_project_config(repo_root, arm)
65
+
66
+ # Step 1c: Index rebuilt once at homegraph suite start (run_all / prebuild).
67
+ # Per-experiment git reset restores the same commit — no second index here.
68
+ # Step 2: Clear CLAUDE.md
69
+ claude_md = repo_root / "CLAUDE.md"
70
+ if claude_md.exists() and claude_md.stat().st_size > 0:
71
+ backup_dir = _state_dir / "claude_md_backups"
72
+ backup_dir.mkdir(parents=True, exist_ok=True)
73
+ ts = datetime.now().strftime("%Y%m%d_%H%M%S")
74
+ backup_path = backup_dir / f"CLAUDE.md.{ts}"
75
+ backup_path.write_text(claude_md.read_text())
76
+ log(f"Backed up CLAUDE.md → {backup_path}")
77
+ with open(claude_md, "w") as f:
78
+ f.write("")
79
+ log("Cleared CLAUDE.md")
80
+
81
+ for f in [".cursorrules", ".cursor/rules"]:
82
+ p = repo_root / f
83
+ if p.exists():
84
+ p.unlink()
85
+
86
+ # Step 3: Session ID
87
+ session_id = generate_session_id()
88
+ (_state_dir / f"session_{exp_id}.txt").write_text(session_id)
89
+ log(f"Session ID: {session_id}")
90
+
91
+ # Step 4: Verify agent binary
92
+ ok, resolved, err_msg = verify_agent_binary(agent)
93
+ if not ok:
94
+ error(err_msg)
95
+ sys.exit(1)
96
+ binary = resolved
97
+ agent_ver = get_agent_version(agent)
98
+ log(f"Agent: {agent['name']} ({binary}) v{agent_ver}")
99
+
100
+ # Step 5: Record state
101
+ write_json(_state_dir / exp_id / "state.json", {
102
+ "experiment_id": exp_id, "session_id": session_id,
103
+ "started_at": datetime.now(timezone.utc).isoformat(),
104
+ "clean_mode": clean_mode, "agent": agent["name"],
105
+ "agent_version": agent_ver, "repo_root": str(repo_root),
106
+ "git_branch": git_output(["branch", "--show-current"], cwd=repo_root),
107
+ "git_commit": git_output(["rev-parse", "HEAD"], cwd=repo_root),
108
+ })
109
+
110
+ append_run_log(_state_dir, f"Setup complete for {exp_id}: session={session_id}, agent={agent['name']}")
111
+ log("Setup complete.")
112
+ return session_id, agent["name"]
113
+
114
+
115
+ if __name__ == "__main__":
116
+ exp_id = sys.argv[1] if len(sys.argv) > 1 else "all"
117
+ clean_mode = sys.argv[2] if len(sys.argv) > 2 else "full"
118
+ agent_name = sys.argv[3] if len(sys.argv) > 3 else ""
119
+ sid, _ = prepare_environment(exp_id, clean_mode, agent_name)
120
+ print(sid)
@@ -1,73 +1,73 @@
1
- #!/usr/bin/env python3
2
- """Windows MCP entry: pythonw (no window) → hidden node child; stdio inherited from DevEco."""
3
-
4
- from __future__ import annotations
5
-
6
- import os
7
- import shutil
8
- import subprocess
9
- import sys
10
-
11
- _CREATE_NO_WINDOW = getattr(subprocess, "CREATE_NO_WINDOW", 0x08000000)
12
-
13
- # Applied here so MCP works even if DevEco ignores deveco.jsonc "environment".
14
- _MCP_ENV_DEFAULTS = {
15
- "HOMEGRAPH_NO_DAEMON": "1",
16
- "HOMEGRAPH_NO_WATCHDOG": "1",
17
- "HOMEGRAPH_WASM_RELAUNCHED": "1",
18
- }
19
-
20
-
21
- def _resolve_node() -> str:
22
- env_node = os.environ.get("HOMEGRAPH_NODE", "").strip()
23
- if env_node:
24
- return env_node
25
- found = shutil.which("node")
26
- if not found:
27
- print("node not found on PATH", file=sys.stderr)
28
- sys.exit(127)
29
- return found
30
-
31
-
32
- def _node_argv(raw: list[str]) -> list[str]:
33
- """Ensure --liftoff-only is on the node command line (before homegraph.js)."""
34
- node = _resolve_node()
35
- args = list(raw)
36
- if "--liftoff-only" not in args:
37
- args.insert(0, "--liftoff-only")
38
- return [node, *args]
39
-
40
-
41
- def _hidden_call(argv: list[str], env: dict) -> int:
42
- si = subprocess.STARTUPINFO()
43
- si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
44
- si.wShowWindow = 0
45
- return subprocess.call(
46
- argv,
47
- env=env,
48
- stdin=sys.stdin,
49
- stdout=sys.stdout,
50
- stderr=sys.stderr,
51
- creationflags=_CREATE_NO_WINDOW,
52
- startupinfo=si,
53
- )
54
-
55
-
56
- def main() -> int:
57
- if len(sys.argv) < 2:
58
- print(
59
- "usage: win_mcp_launcher.py [--liftoff-only] [--stack-size=N] homegraph.js …",
60
- file=sys.stderr,
61
- )
62
- return 2
63
- env = os.environ.copy()
64
- for key, val in _MCP_ENV_DEFAULTS.items():
65
- env.setdefault(key, val)
66
- argv = _node_argv(sys.argv[1:])
67
- if os.name == "nt":
68
- return _hidden_call(argv, env)
69
- return subprocess.call(argv, env=env)
70
-
71
-
72
- if __name__ == "__main__":
73
- raise SystemExit(main())
1
+ #!/usr/bin/env python3
2
+ """Windows MCP entry: pythonw (no window) → hidden node child; stdio inherited from DevEco."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import os
7
+ import shutil
8
+ import subprocess
9
+ import sys
10
+
11
+ _CREATE_NO_WINDOW = getattr(subprocess, "CREATE_NO_WINDOW", 0x08000000)
12
+
13
+ # Applied here so MCP works even if DevEco ignores deveco.jsonc "environment".
14
+ _MCP_ENV_DEFAULTS = {
15
+ "HOMEGRAPH_NO_DAEMON": "1",
16
+ "HOMEGRAPH_NO_WATCHDOG": "1",
17
+ "HOMEGRAPH_WASM_RELAUNCHED": "1",
18
+ }
19
+
20
+
21
+ def _resolve_node() -> str:
22
+ env_node = os.environ.get("HOMEGRAPH_NODE", "").strip()
23
+ if env_node:
24
+ return env_node
25
+ found = shutil.which("node")
26
+ if not found:
27
+ print("node not found on PATH", file=sys.stderr)
28
+ sys.exit(127)
29
+ return found
30
+
31
+
32
+ def _node_argv(raw: list[str]) -> list[str]:
33
+ """Ensure --liftoff-only is on the node command line (before homegraph.js)."""
34
+ node = _resolve_node()
35
+ args = list(raw)
36
+ if "--liftoff-only" not in args:
37
+ args.insert(0, "--liftoff-only")
38
+ return [node, *args]
39
+
40
+
41
+ def _hidden_call(argv: list[str], env: dict) -> int:
42
+ si = subprocess.STARTUPINFO()
43
+ si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
44
+ si.wShowWindow = 0
45
+ return subprocess.call(
46
+ argv,
47
+ env=env,
48
+ stdin=sys.stdin,
49
+ stdout=sys.stdout,
50
+ stderr=sys.stderr,
51
+ creationflags=_CREATE_NO_WINDOW,
52
+ startupinfo=si,
53
+ )
54
+
55
+
56
+ def main() -> int:
57
+ if len(sys.argv) < 2:
58
+ print(
59
+ "usage: win_mcp_launcher.py [--liftoff-only] [--stack-size=N] homegraph.js …",
60
+ file=sys.stderr,
61
+ )
62
+ return 2
63
+ env = os.environ.copy()
64
+ for key, val in _MCP_ENV_DEFAULTS.items():
65
+ env.setdefault(key, val)
66
+ argv = _node_argv(sys.argv[1:])
67
+ if os.name == "nt":
68
+ return _hidden_call(argv, env)
69
+ return subprocess.call(argv, env=env)
70
+
71
+
72
+ if __name__ == "__main__":
73
+ raise SystemExit(main())
@@ -1,36 +1,36 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Windows MCP launcher: spawn homegraph with windowsHide while keeping stdio
4
- * connected to DevEco (pythonw + Python subprocess breaks JSON-RPC pipes).
5
- *
6
- * Usage: node win_mcp_stdio_wrap.js [--stack-size=N] homegraph.js serve --mcp --path <repo>
7
- */
8
- 'use strict';
9
-
10
- const cp = require('child_process');
11
-
12
- const node = process.env.HOMEGRAPH_NODE || process.execPath;
13
- const args = process.argv.slice(2);
14
- if (args.length === 0) {
15
- process.stderr.write('usage: node win_mcp_stdio_wrap.js [--stack-size=N] homegraph.js …\n');
16
- process.exit(2);
17
- }
18
-
19
- const child = cp.spawn(node, args, {
20
- stdio: 'inherit',
21
- windowsHide: true,
22
- env: process.env,
23
- });
24
-
25
- child.on('error', (err) => {
26
- process.stderr.write(String(err) + '\n');
27
- process.exit(1);
28
- });
29
-
30
- child.on('exit', (code, signal) => {
31
- if (signal) {
32
- process.kill(process.pid, signal);
33
- return;
34
- }
35
- process.exit(code ?? 1);
36
- });
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Windows MCP launcher: spawn homegraph with windowsHide while keeping stdio
4
+ * connected to DevEco (pythonw + Python subprocess breaks JSON-RPC pipes).
5
+ *
6
+ * Usage: node win_mcp_stdio_wrap.js [--stack-size=N] homegraph.js serve --mcp --path <repo>
7
+ */
8
+ 'use strict';
9
+
10
+ const cp = require('child_process');
11
+
12
+ const node = process.env.HOMEGRAPH_NODE || process.execPath;
13
+ const args = process.argv.slice(2);
14
+ if (args.length === 0) {
15
+ process.stderr.write('usage: node win_mcp_stdio_wrap.js [--stack-size=N] homegraph.js …\n');
16
+ process.exit(2);
17
+ }
18
+
19
+ const child = cp.spawn(node, args, {
20
+ stdio: 'inherit',
21
+ windowsHide: true,
22
+ env: process.env,
23
+ });
24
+
25
+ child.on('error', (err) => {
26
+ process.stderr.write(String(err) + '\n');
27
+ process.exit(1);
28
+ });
29
+
30
+ child.on('exit', (code, signal) => {
31
+ if (signal) {
32
+ process.kill(process.pid, signal);
33
+ return;
34
+ }
35
+ process.exit(code ?? 1);
36
+ });
@@ -1,24 +1,24 @@
1
- #!/usr/bin/env python3
2
- """Windows: run node without a console window; inherit stdio (MCP / homegraph CLI)."""
3
-
4
- from __future__ import annotations
5
-
6
- import os
7
- import subprocess
8
- import sys
9
-
10
- _CREATE_NO_WINDOW = getattr(subprocess, "CREATE_NO_WINDOW", 0x08000000)
11
-
12
-
13
- def main() -> int:
14
- if len(sys.argv) < 2:
15
- print("usage: win_node_launcher.py [--stack-size=N] script.js …", file=sys.stderr)
16
- return 2
17
- node = os.environ.get("HOMEGRAPH_NODE", "node")
18
- cmd = [node, *sys.argv[1:]]
19
- flags = _CREATE_NO_WINDOW if os.name == "nt" else 0
20
- return subprocess.call(cmd, creationflags=flags)
21
-
22
-
23
- if __name__ == "__main__":
24
- raise SystemExit(main())
1
+ #!/usr/bin/env python3
2
+ """Windows: run node without a console window; inherit stdio (MCP / homegraph CLI)."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import os
7
+ import subprocess
8
+ import sys
9
+
10
+ _CREATE_NO_WINDOW = getattr(subprocess, "CREATE_NO_WINDOW", 0x08000000)
11
+
12
+
13
+ def main() -> int:
14
+ if len(sys.argv) < 2:
15
+ print("usage: win_node_launcher.py [--stack-size=N] script.js …", file=sys.stderr)
16
+ return 2
17
+ node = os.environ.get("HOMEGRAPH_NODE", "node")
18
+ cmd = [node, *sys.argv[1:]]
19
+ flags = _CREATE_NO_WINDOW if os.name == "nt" else 0
20
+ return subprocess.call(cmd, creationflags=flags)
21
+
22
+
23
+ if __name__ == "__main__":
24
+ raise SystemExit(main())