execweave 0.6.0__tar.gz

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 (165) hide show
  1. execweave-0.6.0/.github/workflows/ci.yml +250 -0
  2. execweave-0.6.0/.github/workflows/package-benchmark.yml +61 -0
  3. execweave-0.6.0/.github/workflows/publish.yml +61 -0
  4. execweave-0.6.0/.gitignore +10 -0
  5. execweave-0.6.0/LICENSE +21 -0
  6. execweave-0.6.0/PKG-INFO +356 -0
  7. execweave-0.6.0/README.ja.md +150 -0
  8. execweave-0.6.0/README.ko.md +150 -0
  9. execweave-0.6.0/README.md +300 -0
  10. execweave-0.6.0/README.zh-CN.md +150 -0
  11. execweave-0.6.0/README.zh-TW.md +210 -0
  12. execweave-0.6.0/benchmarks/phase1_overhead.py +5 -0
  13. execweave-0.6.0/docs/benchmarks/README.md +46 -0
  14. execweave-0.6.0/docs/benchmarks/v0.6.0-github-actions.json +67 -0
  15. execweave-0.6.0/docs/benchmarks/v0.6.0-github-actions.svg +46 -0
  16. execweave-0.6.0/docs/claude-code-hooks.ja.md +104 -0
  17. execweave-0.6.0/docs/claude-code-hooks.ko.md +104 -0
  18. execweave-0.6.0/docs/claude-code-hooks.md +272 -0
  19. execweave-0.6.0/docs/claude-code-hooks.zh-CN.md +218 -0
  20. execweave-0.6.0/docs/claude-code-hooks.zh-TW.md +218 -0
  21. execweave-0.6.0/docs/codex-hooks.ja.md +84 -0
  22. execweave-0.6.0/docs/codex-hooks.ko.md +77 -0
  23. execweave-0.6.0/docs/codex-hooks.md +179 -0
  24. execweave-0.6.0/docs/codex-hooks.zh-CN.md +175 -0
  25. execweave-0.6.0/docs/codex-hooks.zh-TW.md +175 -0
  26. execweave-0.6.0/docs/cursor-hooks.ja.md +80 -0
  27. execweave-0.6.0/docs/cursor-hooks.ko.md +80 -0
  28. execweave-0.6.0/docs/cursor-hooks.md +80 -0
  29. execweave-0.6.0/docs/cursor-hooks.zh-CN.md +80 -0
  30. execweave-0.6.0/docs/cursor-hooks.zh-TW.md +80 -0
  31. execweave-0.6.0/docs/gemini-hooks.ja.md +139 -0
  32. execweave-0.6.0/docs/gemini-hooks.ko.md +139 -0
  33. execweave-0.6.0/docs/gemini-hooks.md +186 -0
  34. execweave-0.6.0/docs/gemini-hooks.zh-CN.md +145 -0
  35. execweave-0.6.0/docs/gemini-hooks.zh-TW.md +184 -0
  36. execweave-0.6.0/docs/inference-gateway.ja.md +125 -0
  37. execweave-0.6.0/docs/inference-gateway.ko.md +125 -0
  38. execweave-0.6.0/docs/inference-gateway.md +125 -0
  39. execweave-0.6.0/docs/inference-gateway.zh-CN.md +125 -0
  40. execweave-0.6.0/docs/inference-gateway.zh-TW.md +125 -0
  41. execweave-0.6.0/docs/live-graph.ja.md +93 -0
  42. execweave-0.6.0/docs/live-graph.ko.md +93 -0
  43. execweave-0.6.0/docs/live-graph.md +135 -0
  44. execweave-0.6.0/docs/live-graph.zh-CN.md +131 -0
  45. execweave-0.6.0/docs/live-graph.zh-TW.md +131 -0
  46. execweave-0.6.0/docs/model-runtime.ja.md +97 -0
  47. execweave-0.6.0/docs/model-runtime.ko.md +97 -0
  48. execweave-0.6.0/docs/model-runtime.md +101 -0
  49. execweave-0.6.0/docs/model-runtime.zh-CN.md +97 -0
  50. execweave-0.6.0/docs/model-runtime.zh-TW.md +97 -0
  51. execweave-0.6.0/docs/opencode-plugin.ja.md +76 -0
  52. execweave-0.6.0/docs/opencode-plugin.ko.md +76 -0
  53. execweave-0.6.0/docs/opencode-plugin.md +76 -0
  54. execweave-0.6.0/docs/opencode-plugin.zh-CN.md +76 -0
  55. execweave-0.6.0/docs/opencode-plugin.zh-TW.md +76 -0
  56. execweave-0.6.0/docs/phase-1-runtime-collection.ja.md +153 -0
  57. execweave-0.6.0/docs/phase-1-runtime-collection.ko.md +151 -0
  58. execweave-0.6.0/docs/phase-1-runtime-collection.md +319 -0
  59. execweave-0.6.0/docs/phase-1-runtime-collection.zh-CN.md +309 -0
  60. execweave-0.6.0/docs/phase-1-runtime-collection.zh-TW.md +309 -0
  61. execweave-0.6.0/docs/phase-2-execution-graph.ja.md +110 -0
  62. execweave-0.6.0/docs/phase-2-execution-graph.ko.md +110 -0
  63. execweave-0.6.0/docs/phase-2-execution-graph.md +283 -0
  64. execweave-0.6.0/docs/phase-2-execution-graph.zh-CN.md +277 -0
  65. execweave-0.6.0/docs/phase-2-execution-graph.zh-TW.md +277 -0
  66. execweave-0.6.0/docs/security-analysis.ja.md +95 -0
  67. execweave-0.6.0/docs/security-analysis.ko.md +93 -0
  68. execweave-0.6.0/docs/security-analysis.md +175 -0
  69. execweave-0.6.0/docs/security-analysis.zh-CN.md +167 -0
  70. execweave-0.6.0/docs/security-analysis.zh-TW.md +167 -0
  71. execweave-0.6.0/docs/semantic-telemetry.ja.md +82 -0
  72. execweave-0.6.0/docs/semantic-telemetry.ko.md +77 -0
  73. execweave-0.6.0/docs/semantic-telemetry.md +157 -0
  74. execweave-0.6.0/docs/semantic-telemetry.zh-CN.md +174 -0
  75. execweave-0.6.0/docs/semantic-telemetry.zh-TW.md +174 -0
  76. execweave-0.6.0/pyproject.toml +88 -0
  77. execweave-0.6.0/scripts/check_claude_hook.py +73 -0
  78. execweave-0.6.0/scripts/check_claude_record_graph.py +31 -0
  79. execweave-0.6.0/scripts/check_correlation_graph.py +56 -0
  80. execweave-0.6.0/scripts/check_inference_gateway_cli.py +126 -0
  81. execweave-0.6.0/scripts/check_model_runtime_cli.py +242 -0
  82. execweave-0.6.0/scripts/check_semantic_graph.py +33 -0
  83. execweave-0.6.0/scripts/check_viewer_js.py +35 -0
  84. execweave-0.6.0/scripts/emit_claude_hook_smoke.py +47 -0
  85. execweave-0.6.0/scripts/emit_cursor_hook_smoke.py +64 -0
  86. execweave-0.6.0/scripts/emit_gemini_hook_smoke.py +46 -0
  87. execweave-0.6.0/scripts/emit_opencode_plugin_smoke.py +61 -0
  88. execweave-0.6.0/scripts/make_semantic_smoke.py +83 -0
  89. execweave-0.6.0/src/execweave/__init__.py +3 -0
  90. execweave-0.6.0/src/execweave/__main__.py +5 -0
  91. execweave-0.6.0/src/execweave/analysis.py +406 -0
  92. execweave-0.6.0/src/execweave/backends.py +63 -0
  93. execweave-0.6.0/src/execweave/benchmark.py +80 -0
  94. execweave-0.6.0/src/execweave/claude_adapter.py +448 -0
  95. execweave-0.6.0/src/execweave/claude_hook_cli.py +101 -0
  96. execweave-0.6.0/src/execweave/claude_record.py +106 -0
  97. execweave-0.6.0/src/execweave/cli.py +588 -0
  98. execweave-0.6.0/src/execweave/codex_adapter.py +314 -0
  99. execweave-0.6.0/src/execweave/codex_hook_cli.py +98 -0
  100. execweave-0.6.0/src/execweave/codex_record.py +111 -0
  101. execweave-0.6.0/src/execweave/collector.py +301 -0
  102. execweave-0.6.0/src/execweave/correlation.py +604 -0
  103. execweave-0.6.0/src/execweave/cursor_adapter.py +347 -0
  104. execweave-0.6.0/src/execweave/cursor_hook_cli.py +82 -0
  105. execweave-0.6.0/src/execweave/cursor_record.py +96 -0
  106. execweave-0.6.0/src/execweave/filesystem.py +103 -0
  107. execweave-0.6.0/src/execweave/focus.py +118 -0
  108. execweave-0.6.0/src/execweave/gemini_adapter.py +265 -0
  109. execweave-0.6.0/src/execweave/gemini_hook_cli.py +77 -0
  110. execweave-0.6.0/src/execweave/gemini_record.py +94 -0
  111. execweave-0.6.0/src/execweave/graph.py +300 -0
  112. execweave-0.6.0/src/execweave/graph_ops.py +446 -0
  113. execweave-0.6.0/src/execweave/inference_gateway.py +422 -0
  114. execweave-0.6.0/src/execweave/inference_gateway_cli.py +106 -0
  115. execweave-0.6.0/src/execweave/inference_identity.py +76 -0
  116. execweave-0.6.0/src/execweave/inference_identity_cli.py +60 -0
  117. execweave-0.6.0/src/execweave/live.py +275 -0
  118. execweave-0.6.0/src/execweave/model_runtime.py +535 -0
  119. execweave-0.6.0/src/execweave/model_runtime_cli.py +154 -0
  120. execweave-0.6.0/src/execweave/opencode_adapter.py +316 -0
  121. execweave-0.6.0/src/execweave/opencode_hook_cli.py +57 -0
  122. execweave-0.6.0/src/execweave/opencode_plugin_cli.py +110 -0
  123. execweave-0.6.0/src/execweave/opencode_record.py +96 -0
  124. execweave-0.6.0/src/execweave/overhead_benchmark.py +440 -0
  125. execweave-0.6.0/src/execweave/provider_record.py +215 -0
  126. execweave-0.6.0/src/execweave/schema.py +62 -0
  127. execweave-0.6.0/src/execweave/semantic.py +346 -0
  128. execweave-0.6.0/src/execweave/sink.py +33 -0
  129. execweave-0.6.0/src/execweave/strace_backend.py +682 -0
  130. execweave-0.6.0/src/execweave/validate.py +193 -0
  131. execweave-0.6.0/src/execweave/viewer.py +283 -0
  132. execweave-0.6.0/src/execweave/workflow.py +114 -0
  133. execweave-0.6.0/tests/test_analysis.py +154 -0
  134. execweave-0.6.0/tests/test_backends.py +21 -0
  135. execweave-0.6.0/tests/test_claude_adapter.py +226 -0
  136. execweave-0.6.0/tests/test_claude_record.py +197 -0
  137. execweave-0.6.0/tests/test_codex_adapter.py +135 -0
  138. execweave-0.6.0/tests/test_codex_record.py +185 -0
  139. execweave-0.6.0/tests/test_collector.py +44 -0
  140. execweave-0.6.0/tests/test_condense.py +154 -0
  141. execweave-0.6.0/tests/test_correlation.py +404 -0
  142. execweave-0.6.0/tests/test_correlation_canonical_path.py +76 -0
  143. execweave-0.6.0/tests/test_correlation_process_exe.py +83 -0
  144. execweave-0.6.0/tests/test_cursor_adapter.py +119 -0
  145. execweave-0.6.0/tests/test_cursor_record.py +82 -0
  146. execweave-0.6.0/tests/test_focus.py +139 -0
  147. execweave-0.6.0/tests/test_gemini_adapter.py +96 -0
  148. execweave-0.6.0/tests/test_gemini_record.py +71 -0
  149. execweave-0.6.0/tests/test_graph.py +208 -0
  150. execweave-0.6.0/tests/test_graph_ops.py +131 -0
  151. execweave-0.6.0/tests/test_inference_gateway.py +155 -0
  152. execweave-0.6.0/tests/test_inference_identity.py +78 -0
  153. execweave-0.6.0/tests/test_live.py +96 -0
  154. execweave-0.6.0/tests/test_model_runtime.py +222 -0
  155. execweave-0.6.0/tests/test_opencode_adapter.py +72 -0
  156. execweave-0.6.0/tests/test_opencode_plugin.py +27 -0
  157. execweave-0.6.0/tests/test_opencode_record.py +90 -0
  158. execweave-0.6.0/tests/test_overhead_benchmark.py +84 -0
  159. execweave-0.6.0/tests/test_schema.py +18 -0
  160. execweave-0.6.0/tests/test_semantic.py +238 -0
  161. execweave-0.6.0/tests/test_strace_backend.py +202 -0
  162. execweave-0.6.0/tests/test_validate.py +113 -0
  163. execweave-0.6.0/tests/test_version.py +7 -0
  164. execweave-0.6.0/tests/test_viewer.py +276 -0
  165. execweave-0.6.0/tests/test_workflow.py +79 -0
@@ -0,0 +1,250 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ["v*"]
7
+ pull_request:
8
+ workflow_dispatch:
9
+ inputs:
10
+ full_matrix:
11
+ description: Run the full 3-OS x Python 3.10/3.12 compatibility matrix
12
+ required: false
13
+ default: true
14
+ type: boolean
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ concurrency:
20
+ group: ci-${{ github.ref }}
21
+ cancel-in-progress: ${{ github.event_name != 'workflow_dispatch' }}
22
+
23
+ jobs:
24
+ plan:
25
+ runs-on: ubuntu-latest
26
+ outputs:
27
+ matrix: ${{ steps.matrix.outputs.matrix }}
28
+ mode: ${{ steps.matrix.outputs.mode }}
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+ with:
32
+ fetch-depth: 0
33
+ - id: matrix
34
+ name: Choose CI matrix
35
+ shell: bash
36
+ env:
37
+ EVENT_NAME: ${{ github.event_name }}
38
+ REF_NAME: ${{ github.ref }}
39
+ BEFORE_SHA: ${{ github.event.before }}
40
+ BASE_SHA: ${{ github.event.pull_request.base.sha }}
41
+ CURRENT_SHA: ${{ github.sha }}
42
+ FULL_MATRIX: ${{ inputs.full_matrix }}
43
+ run: |
44
+ python - <<'PY'
45
+ import json
46
+ import os
47
+ import subprocess
48
+
49
+ event = os.environ.get("EVENT_NAME", "")
50
+ ref = os.environ.get("REF_NAME", "")
51
+ full_requested = os.environ.get("FULL_MATRIX", "").lower() == "true"
52
+
53
+ if ref.startswith("refs/tags/v") or (event == "workflow_dispatch" and full_requested):
54
+ mode = "full"
55
+ systems = ["ubuntu-latest", "macos-latest", "windows-latest"]
56
+ versions = ["3.10", "3.12"]
57
+ else:
58
+ before = os.environ.get("BEFORE_SHA", "")
59
+ base = os.environ.get("BASE_SHA", "")
60
+ current = os.environ.get("CURRENT_SHA", "HEAD")
61
+ if event == "pull_request" and base:
62
+ diff_base = base
63
+ elif before and set(before) != {"0"}:
64
+ diff_base = before
65
+ else:
66
+ diff_base = f"{current}^"
67
+
68
+ try:
69
+ output = subprocess.check_output(
70
+ ["git", "diff", "--name-only", diff_base, current],
71
+ text=True,
72
+ stderr=subprocess.DEVNULL,
73
+ )
74
+ changed = [line.strip() for line in output.splitlines() if line.strip()]
75
+ except (subprocess.CalledProcessError, OSError):
76
+ changed = ["src/"]
77
+
78
+ cross_platform_prefixes = (
79
+ "src/",
80
+ "tests/",
81
+ "scripts/",
82
+ ".github/workflows/",
83
+ ".github/actions/",
84
+ )
85
+ cross_platform_files = {"pyproject.toml"}
86
+ cross_platform = any(
87
+ path in cross_platform_files
88
+ or any(path.startswith(prefix) for prefix in cross_platform_prefixes)
89
+ for path in changed
90
+ )
91
+ mode = "cross-platform" if cross_platform else "quick"
92
+ systems = (
93
+ ["ubuntu-latest", "macos-latest", "windows-latest"]
94
+ if cross_platform
95
+ else ["ubuntu-latest"]
96
+ )
97
+ versions = ["3.12"]
98
+
99
+ matrix = {
100
+ "include": [
101
+ {"os": system, "python-version": version}
102
+ for system in systems
103
+ for version in versions
104
+ ]
105
+ }
106
+ print(f"CI mode: {mode}")
107
+ print(json.dumps(matrix, indent=2))
108
+ with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as handle:
109
+ handle.write(f"mode={mode}\n")
110
+ handle.write("matrix=" + json.dumps(matrix, separators=(",", ":")) + "\n")
111
+ PY
112
+
113
+ test:
114
+ needs: plan
115
+ name: test (${{ matrix.os }}, ${{ matrix.python-version }})
116
+ strategy:
117
+ fail-fast: false
118
+ matrix: ${{ fromJSON(needs.plan.outputs.matrix) }}
119
+ runs-on: ${{ matrix.os }}
120
+ timeout-minutes: 30
121
+
122
+ steps:
123
+ - uses: actions/checkout@v4
124
+ - uses: actions/setup-python@v5
125
+ with:
126
+ python-version: ${{ matrix.python-version }}
127
+ cache: pip
128
+ - name: Install strace on Linux
129
+ if: runner.os == 'Linux'
130
+ run: command -v strace >/dev/null || (sudo apt-get update && sudo apt-get install -y strace)
131
+ - name: Install
132
+ run: python -m pip install -e ".[dev]"
133
+ - name: Ruff
134
+ run: ruff check .
135
+ - name: Tests
136
+ run: pytest -q
137
+ - name: Claude hook command smoke
138
+ run: python scripts/check_claude_hook.py
139
+ - name: Claude run-bound semantic and correlation smoke
140
+ run: execweave-claude-record --backend auto --no-files --no-network --output-dir claude-record-smoke -- python scripts/emit_claude_hook_smoke.py
141
+ - name: Validate Claude runtime stream
142
+ run: execweave validate claude-record-smoke/events.jsonl
143
+ - name: Validate Claude merged stream
144
+ run: execweave validate claude-record-smoke/events.semantic.jsonl
145
+ - name: Verify Claude semantic graph
146
+ run: python scripts/check_claude_record_graph.py claude-record-smoke/graph.semantic.json
147
+ - name: Validate automatic correlated stream
148
+ run: execweave validate claude-record-smoke/events.correlated.jsonl
149
+ - name: Verify automatic conservative correlation edge
150
+ run: python scripts/check_correlation_graph.py claude-record-smoke/graph.correlated.json
151
+ - name: Check correlated standalone viewer JavaScript syntax
152
+ run: python scripts/check_viewer_js.py claude-record-smoke/viewer.correlated.html --output claude-record-smoke/viewer.correlated.js
153
+ - name: Gemini run-bound semantic and correlation smoke
154
+ run: execweave-gemini-record --backend auto --no-files --no-network --output-dir gemini-record-smoke -- python scripts/emit_gemini_hook_smoke.py
155
+ - name: Validate Gemini runtime stream
156
+ run: execweave validate gemini-record-smoke/events.jsonl
157
+ - name: Validate Gemini merged stream
158
+ run: execweave validate gemini-record-smoke/events.semantic.jsonl
159
+ - name: Validate Gemini correlated stream
160
+ run: execweave validate gemini-record-smoke/events.correlated.jsonl
161
+ - name: Verify Gemini conservative correlation edge
162
+ run: python scripts/check_correlation_graph.py gemini-record-smoke/graph.correlated.json
163
+ - name: Check Gemini correlated viewer JavaScript syntax
164
+ run: python scripts/check_viewer_js.py gemini-record-smoke/viewer.correlated.html --output gemini-record-smoke/viewer.correlated.js
165
+ - name: Cursor run-bound semantic and correlation smoke
166
+ run: execweave-cursor-record --backend auto --no-files --no-network --output-dir cursor-record-smoke -- python scripts/emit_cursor_hook_smoke.py
167
+ - name: Validate Cursor runtime stream
168
+ run: execweave validate cursor-record-smoke/events.jsonl
169
+ - name: Validate Cursor merged stream
170
+ run: execweave validate cursor-record-smoke/events.semantic.jsonl
171
+ - name: Validate Cursor correlated stream
172
+ run: execweave validate cursor-record-smoke/events.correlated.jsonl
173
+ - name: Verify Cursor conservative correlation edge
174
+ run: python scripts/check_correlation_graph.py cursor-record-smoke/graph.correlated.json
175
+ - name: Check Cursor correlated viewer JavaScript syntax
176
+ run: python scripts/check_viewer_js.py cursor-record-smoke/viewer.correlated.html --output cursor-record-smoke/viewer.correlated.js
177
+ - name: OpenCode plugin installer smoke
178
+ run: execweave-opencode-plugin --install --root opencode-plugin-smoke
179
+ - name: OpenCode run-bound semantic and correlation smoke
180
+ run: execweave-opencode-record --backend auto --no-files --no-network --output-dir opencode-record-smoke -- python scripts/emit_opencode_plugin_smoke.py
181
+ - name: Validate OpenCode runtime stream
182
+ run: execweave validate opencode-record-smoke/events.jsonl
183
+ - name: Validate OpenCode merged stream
184
+ run: execweave validate opencode-record-smoke/events.semantic.jsonl
185
+ - name: Validate OpenCode correlated stream
186
+ run: execweave validate opencode-record-smoke/events.correlated.jsonl
187
+ - name: Verify OpenCode conservative correlation edge
188
+ run: python scripts/check_correlation_graph.py opencode-record-smoke/graph.correlated.json
189
+ - name: Check OpenCode correlated viewer JavaScript syntax
190
+ run: python scripts/check_viewer_js.py opencode-record-smoke/viewer.correlated.html --output opencode-record-smoke/viewer.correlated.js
191
+ - name: Model runtime CLI smoke
192
+ run: python scripts/check_model_runtime_cli.py
193
+ - name: Inference gateway CLI smoke
194
+ run: python scripts/check_inference_gateway_cli.py
195
+ - name: Collector diagnostics
196
+ run: execweave doctor
197
+ - name: Portable end-to-end smoke
198
+ run: execweave run --backend portable --no-files --no-network --output phase1-portable.jsonl -- python -c "print('execweave portable smoke')"
199
+ - name: Validate portable stream
200
+ run: execweave validate phase1-portable.jsonl
201
+ - name: Build semantic telemetry sidecar
202
+ run: python scripts/make_semantic_smoke.py phase1-portable.jsonl phase1-semantic.jsonl
203
+ - name: Merge semantic telemetry
204
+ run: execweave semantic-merge phase1-portable.jsonl phase1-semantic.jsonl --output phase1-semantic-merged.jsonl
205
+ - name: Validate semantic merged stream
206
+ run: execweave validate phase1-semantic-merged.jsonl
207
+ - name: Materialize semantic graph
208
+ run: execweave graph phase1-semantic-merged.jsonl --output phase1-semantic.graph.json
209
+ - name: Verify semantic graph relations
210
+ run: python scripts/check_semantic_graph.py phase1-semantic.graph.json
211
+ - name: Build semantic standalone viewer
212
+ run: execweave view phase1-semantic.graph.json --output phase1-semantic.html
213
+ - name: Materialize portable graph
214
+ run: execweave graph phase1-portable.jsonl --output phase1-portable.graph.json
215
+ - name: Build portable standalone viewer
216
+ run: execweave view phase1-portable.graph.json --output phase1-portable.html
217
+ - name: Check standalone viewer JavaScript syntax
218
+ run: python scripts/check_viewer_js.py phase1-portable.html --output phase1-portable.viewer.js
219
+ - name: Focus portable graph smoke
220
+ run: python -c "import json, subprocess; g=json.load(open('phase1-portable.graph.json', encoding='utf-8')); a=g['nodes'][0]['id']; subprocess.run(['execweave','graph-focus','phase1-portable.graph.json',a,'--hops','1','--output','phase1-portable.focus.graph.json'], check=True)"
221
+ - name: Build focused standalone viewer
222
+ run: execweave view phase1-portable.focus.graph.json --output phase1-portable.focus.html
223
+ - name: Condense portable graph smoke
224
+ run: execweave graph-condense phase1-portable.graph.json --output phase1-portable.compact.graph.json --threshold 2 --keep-expansion
225
+ - name: Build expandable condensed viewer
226
+ run: execweave view phase1-portable.compact.graph.json --output phase1-portable.compact.html
227
+ - name: Analyze portable graph smoke
228
+ run: execweave analyze phase1-portable.graph.json --output phase1-portable.analysis.json
229
+ - name: One-command record workflow smoke
230
+ run: execweave record --backend portable --no-files --no-network --output-dir record-smoke -- python -c "print('execweave record smoke')"
231
+ - name: Validate record workflow stream
232
+ run: execweave validate record-smoke/events.jsonl
233
+ - name: Live graph workflow smoke
234
+ run: execweave live --no-files --no-network --linger 0 --output-dir live-smoke -- python -c "import time; time.sleep(0.2)"
235
+ - name: Validate live workflow stream
236
+ run: execweave validate live-smoke/events.jsonl
237
+ - name: Summarize live workflow graph
238
+ run: execweave graph-summary live-smoke/graph.json
239
+ - name: Linux strace end-to-end smoke
240
+ if: runner.os == 'Linux'
241
+ run: execweave run --backend strace --no-network --output phase1-strace.jsonl -- python -c "from pathlib import Path; p=Path('ci-phase1.txt'); p.write_text('ok'); p.read_text(); p.unlink()"
242
+ - name: Validate Linux strace stream
243
+ if: runner.os == 'Linux'
244
+ run: execweave validate phase1-strace.jsonl
245
+ - name: Materialize Linux strace graph
246
+ if: runner.os == 'Linux'
247
+ run: execweave graph phase1-strace.jsonl --output phase1-strace.graph.json
248
+ - name: Phase 1 portable benchmark smoke test
249
+ if: runner.os == 'Linux' && matrix.python-version == '3.12'
250
+ run: execweave benchmark --backend portable --iterations 1
@@ -0,0 +1,61 @@
1
+ name: Package and reference benchmark
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - "pyproject.toml"
8
+ - "src/execweave/__init__.py"
9
+ - "src/execweave/overhead_benchmark.py"
10
+ - "tests/test_overhead_benchmark.py"
11
+ - ".github/workflows/package-benchmark.yml"
12
+ workflow_dispatch:
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ jobs:
18
+ package-benchmark:
19
+ runs-on: ubuntu-latest
20
+ timeout-minutes: 20
21
+
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: actions/setup-python@v5
25
+ with:
26
+ python-version: "3.12"
27
+ cache: pip
28
+ - name: Install build tooling and strace
29
+ run: |
30
+ python -m pip install --upgrade pip
31
+ python -m pip install build twine
32
+ command -v strace >/dev/null || (sudo apt-get update && sudo apt-get install -y strace)
33
+ - name: Build wheel and sdist
34
+ run: |
35
+ python -m build
36
+ python -m twine check dist/*
37
+ ls -lh dist/
38
+ - name: Install wheel in a clean environment
39
+ run: |
40
+ python -m venv .package-smoke
41
+ .package-smoke/bin/python -m pip install --upgrade pip
42
+ .package-smoke/bin/python -m pip install dist/*.whl
43
+ .package-smoke/bin/execweave --help >/dev/null
44
+ .package-smoke/bin/execweave-overhead --help >/dev/null
45
+ - name: Run reference overhead benchmark from installed wheel
46
+ run: |
47
+ .package-smoke/bin/execweave-overhead \
48
+ --iterations 7 \
49
+ --strace auto \
50
+ --output-json benchmark-results.json \
51
+ --output-svg benchmark-overhead.svg
52
+ - name: Upload package and benchmark artifacts
53
+ uses: actions/upload-artifact@v4
54
+ with:
55
+ name: execweave-package-benchmark
56
+ path: |
57
+ dist/*
58
+ benchmark-results.json
59
+ benchmark-overhead.svg
60
+ if-no-files-found: error
61
+ retention-days: 30
@@ -0,0 +1,61 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+ - name: Verify release tag matches package version
19
+ env:
20
+ RELEASE_TAG: ${{ github.event.release.tag_name }}
21
+ run: |
22
+ python - <<'PY'
23
+ import os
24
+ import tomllib
25
+ from pathlib import Path
26
+
27
+ package_version = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))["project"]["version"]
28
+ tag_version = os.environ["RELEASE_TAG"].removeprefix("v")
29
+ if tag_version != package_version:
30
+ raise SystemExit(
31
+ f"release tag {tag_version!r} does not match package version {package_version!r}"
32
+ )
33
+ print(f"Publishing ExecWeave {package_version}")
34
+ PY
35
+ - name: Build and validate distributions
36
+ run: |
37
+ python -m pip install --upgrade pip
38
+ python -m pip install build twine
39
+ python -m build
40
+ python -m twine check dist/*
41
+ - uses: actions/upload-artifact@v4
42
+ with:
43
+ name: python-package-distributions
44
+ path: dist/
45
+ if-no-files-found: error
46
+
47
+ publish:
48
+ needs: build
49
+ runs-on: ubuntu-latest
50
+ environment:
51
+ name: pypi
52
+ url: https://pypi.org/p/execweave
53
+ permissions:
54
+ id-token: write
55
+ steps:
56
+ - uses: actions/download-artifact@v4
57
+ with:
58
+ name: python-package-distributions
59
+ path: dist/
60
+ - name: Publish package distributions to PyPI
61
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,10 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .pytest_cache/
4
+ .ruff_cache/
5
+ .venv/
6
+ venv/
7
+ dist/
8
+ build/
9
+ *.egg-info/
10
+ .execweave/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GWW
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.