cox-protocol-package 1.0.1 → 1.2.0

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 (74) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/COX_FILE_FORMAT_SPECIFICATION_v1.0.md +40 -200
  3. package/FINALIZATION.md +50 -0
  4. package/LocalAppManager/Dashboard/analytics_sidebar_panels/analytics_sidebar_panels.cox +56 -0
  5. package/LocalAppManager/Dashboard/analytics_sidebar_panels/analytics_sidebar_panels_screenshot.placeholder.txt +1 -0
  6. package/LocalAppManager/Dashboard/dashboard.cox +62 -0
  7. package/LocalAppManager/Dashboard/dashboard_screenshot.placeholder.txt +1 -0
  8. package/LocalAppManager/Dashboard/left_navigation_sidebar/left_navigation_sidebar.cox +56 -0
  9. package/LocalAppManager/Dashboard/left_navigation_sidebar/left_navigation_sidebar_screenshot.placeholder.txt +1 -0
  10. package/LocalAppManager/Dashboard/projects_grid_cards/projects_grid_cards.cox +56 -0
  11. package/LocalAppManager/Dashboard/projects_grid_cards/projects_grid_cards_screenshot.placeholder.txt +1 -0
  12. package/LocalAppManager/Dashboard/top_header_stats_bar/top_header_stats_bar.cox +56 -0
  13. package/LocalAppManager/Dashboard/top_header_stats_bar/top_header_stats_bar_screenshot.placeholder.txt +1 -0
  14. package/MANIFEST.in +20 -0
  15. package/README.md +67 -154
  16. package/bin/cox-protocol.js +23 -97
  17. package/cox_protocol/__init__.py +2 -0
  18. package/cox_protocol/__main__.py +3 -0
  19. package/cox_protocol/compiler.py +273 -0
  20. package/cox_protocol/cox_cli.py +146 -0
  21. package/cox_protocol/cox_lib.py +599 -0
  22. package/cox_protocol/package_target.py +262 -0
  23. package/cox_protocol/react_target.py +306 -0
  24. package/cox_protocol/scaffold.py +56 -0
  25. package/cox_protocol/schemas/cox.component.v1.schema.json +180 -0
  26. package/cox_protocol/schemas/cox.crop_metadata.v1.schema.json +83 -0
  27. package/cox_protocol/schemas/cox.manifest.v1.schema.json +172 -0
  28. package/cox_protocol/schemas/cox.page.v1.schema.json +242 -0
  29. package/cox_protocol/schemas/cox.protocol.v1.schema.json +38 -0
  30. package/cox_protocol/starter/README.md +7 -0
  31. package/cox_protocol/starter/manifest.cox +26 -0
  32. package/cox_protocol/starter/page/action_button/action_button.cox +34 -0
  33. package/cox_protocol/starter/page/action_button/reference.svg +1 -0
  34. package/cox_protocol/starter/page/page.cox +39 -0
  35. package/cox_protocol/starter/page/reference.svg +1 -0
  36. package/editor-support/vscode/CHANGELOG.md +6 -0
  37. package/editor-support/vscode/README.md +2 -1
  38. package/editor-support/vscode/package.json +3 -3
  39. package/editor-support/vscode/snippets/cox-common.json +1 -1
  40. package/editor-support/vscode/snippets/cox-component.json +2 -1
  41. package/editor-support/vscode/snippets/cox-crop-metadata.json +1 -1
  42. package/editor-support/vscode/snippets/cox-manifest.json +1 -1
  43. package/editor-support/vscode/snippets/cox-page.json +2 -1
  44. package/editor-support/vscode/snippets/cox-protocol.json +1 -1
  45. package/examples/quickstart/README.md +7 -0
  46. package/examples/quickstart/manifest.cox +26 -0
  47. package/examples/quickstart/page/action_button/action_button.cox +34 -0
  48. package/examples/quickstart/page/action_button/reference.svg +1 -0
  49. package/examples/quickstart/page/page.cox +39 -0
  50. package/examples/quickstart/page/reference.svg +1 -0
  51. package/guides/contract-demo.md +24 -0
  52. package/guides/npm-installation.md +16 -287
  53. package/manifest.cox +7 -4
  54. package/package.json +30 -14
  55. package/protocols/recursive_decomposition_protocol.cox +8 -8
  56. package/pyproject.toml +17 -6
  57. package/schemas/cox.component.v1.schema.json +17 -4
  58. package/schemas/cox.crop_metadata.v1.schema.json +1 -1
  59. package/schemas/cox.manifest.v1.schema.json +1 -1
  60. package/schemas/cox.page.v1.schema.json +17 -4
  61. package/schemas/cox.protocol.v1.schema.json +1 -1
  62. package/scripts/check_distribution.py +87 -0
  63. package/scripts/demo.py +62 -0
  64. package/scripts/package-vscode.mjs +12 -0
  65. package/scripts/release_check.py +86 -0
  66. package/tests/conftest.py +21 -0
  67. package/tests/test_cli_and_typescript.py +123 -0
  68. package/tests/test_compiler.py +279 -0
  69. package/tests/test_validation.py +215 -0
  70. package/tools/__init__.py +2 -2
  71. package/tools/cox_cli.py +2 -123
  72. package/tools/cox_lib.py +2 -558
  73. package/tools/package_target.py +2 -214
  74. package/tools/react_target.py +2 -278
@@ -0,0 +1,56 @@
1
+ CoxVersion: "1.0"
2
+ FileType: "component_spec"
3
+ ComponentName: "top_header_stats_bar"
4
+ Slug: "top_header_stats_bar"
5
+ Schema: "cox.component.v1"
6
+ Role: "Page header, search/action controls, and KPI summary cards"
7
+ EvidenceSummary:
8
+ Visible: []
9
+ UserSpecified:
10
+ - "Component name appears in the approved COX naming examples or derived example structure."
11
+ Inferred:
12
+ - "Detailed behavior should be adapted to actual screenshots when supplied."
13
+ Intended: []
14
+ Recommended: []
15
+
16
+ NamingDecision:
17
+ ChosenName: "top_header_stats_bar"
18
+ Reason: "Combines header and stats because user example binds them."
19
+ RejectedAlternatives:
20
+ - "generic_section"
21
+ - "nested_panel"
22
+ - "ambiguous_area"
23
+ AmbiguityRisk: "Low"
24
+ EvidenceLevel: "UserSpecified"
25
+
26
+ VisibleStructure:
27
+ Note: "Placeholder until real screenshot crop is supplied."
28
+ ExpectedRegions:
29
+ - "Container surface"
30
+ - "Primary content group"
31
+ - "Secondary controls or metadata where visible"
32
+
33
+ VisualStyle:
34
+ Tokens:
35
+ - "Color.SurfaceGlass"
36
+ - "Shape.CardRadius"
37
+ - "Typography.Body"
38
+ - "Motion.General"
39
+
40
+ Interactions:
41
+ Visible: []
42
+ Inferred:
43
+ - "Hover and selected states may be required if controls are interactive."
44
+ Intended: []
45
+ Recommended:
46
+ - "Add keyboard-focus states and accessible labels."
47
+
48
+ Responsive:
49
+ Desktop: "Use page-level placement."
50
+ Tablet: "Compress spacing and preserve hierarchy."
51
+ Mobile: "Stack or collapse only if layout requires it."
52
+
53
+ ImplementationHints:
54
+ - "Implement as reusable component mapped to this exact slug."
55
+ - "Do not rename without updating protocols/component_binding_graph.cox and manifest.cox."
56
+ ChildSubcomponents: []
@@ -0,0 +1 @@
1
+ Replace this placeholder with top_header_stats_bar_screenshot.png after real screenshot partitioning.
package/MANIFEST.in ADDED
@@ -0,0 +1,20 @@
1
+ include LICENSE README.md CHANGELOG.md COX_FILE_FORMAT_SPECIFICATION_v1.0.md
2
+ recursive-include cox_protocol/schemas *.json
3
+ recursive-include cox_protocol/starter *
4
+ recursive-include tests *.py
5
+ global-exclude *.py[cod]
6
+ global-exclude __pycache__
7
+ include FINALIZATION.md
8
+ recursive-include scripts *.py *.mjs
9
+ recursive-include schemas *.json
10
+ recursive-include examples *
11
+ recursive-include guides *.md
12
+ include manifest.cox package.json package-lock.json requirements.txt
13
+ recursive-include LocalAppManager *
14
+ recursive-include protocols *.cox
15
+ recursive-include templates *
16
+ recursive-include skills *
17
+ recursive-include editor-support *
18
+ recursive-include bin *.js
19
+ prune editor-support/vscode/node_modules
20
+ recursive-include tools *.py
package/README.md CHANGED
@@ -1,193 +1,106 @@
1
- # COX Protocol Package
1
+ # COX Protocol
2
2
 
3
- COX is a versioned, YAML-compatible file format for UI reconstruction, evidence tracking, component binding, implementation guidance, and agent-readable design specifications.
3
+ **A design contract you can inspect, validate, and hand off.** COX records UI structure and the evidence behind a design decision in versioned `.cox` files. Its CLI checks the contract and generates normalized JSON, structural React scaffolds, and a reproducible ZIP with a SHA-256 inventory.
4
4
 
5
- This repository now treats `.cox` as a real format surface rather than renamed text files. COX v1.0 includes:
5
+ Tool release **1.2.0** implements format **1.0**. Python 3.9+ is required; the optional npm wrapper also requires Node 18+.
6
6
 
7
- - a formal file format specification
8
- - versioned headers on `.cox` documents
9
- - JSON Schemas for validation
10
- - a manifest-driven validator/compiler CLI
11
- - normalized JSON build output
12
- - deterministic package ZIP output
13
- - minimal VS Code language support
7
+ ## Try it
14
8
 
15
- ## COX v1.0
9
+ Install the release wheel in an isolated environment (replace the wheel path with your downloaded artifact):
16
10
 
17
- - Extension: `.cox`
18
- - MIME type: `application/vnd.cox+yaml`
19
- - Encoding: `UTF-8`
20
- - Syntax base: `YAML-compatible structured text`
21
- - Entry point: `manifest.cox`
22
-
23
- Every `.cox` document starts with a common header:
24
-
25
- ```yaml
26
- CoxVersion: "1.0"
27
- FileType: "component_spec"
28
- Slug: "projects_grid_cards"
29
- Schema: "cox.component.v1"
11
+ ```bash
12
+ python3 -m venv .venv
13
+ . .venv/bin/activate
14
+ python -m pip install /path/to/cox_protocol_package-1.2.0-py3-none-any.whl
15
+ cox --version
16
+ cox init my-contract --name MyProject
17
+ cox validate my-contract --strict
18
+ cox compile my-contract --target all --out build
19
+ cox verify-package my-contract/build/package/myproject.zip
30
20
  ```
31
21
 
32
- ## Repository Contents
22
+ Relative `--out` paths are resolved **inside the COX project**. Absolute output directories also work. `python -m cox_protocol` provides the same commands as `cox`.
33
23
 
34
- - `COX_FILE_FORMAT_SPECIFICATION_v1.0.md`: formal format rules for COX v1.0
35
- - `manifest.cox`: manifest entrypoint for validation and compilation
36
- - `protocols/`: shared protocol documents referenced by the manifest
37
- - `guides/`: package guides, including imported archive audit notes and NPM installation instructions
38
- - `skills/`: LLM-agent skill bundles imported from `llm_agent_zip_skills_bundle.zip`
39
- - `schemas/`: JSON Schemas for manifest, page, component, protocol, and crop metadata documents
40
- - `tools/`: Python validator/compiler package and CLI
41
- - `bin/`: NPM wrapper that delegates to the Python COX CLI
42
- - `editor-support/vscode/`: minimal VS Code language registration for `.cox`
43
- - `LocalAppManager/`: example manifest-driven project content
44
- - `templates/`: versioned starter templates for page, component, and crop metadata files
24
+ For a source checkout, replace the wheel installation with `python -m pip install -e '.[dev]'`. The npm installation guide is [here](guides/npm-installation.md). These commands refer to local release artifacts; consult [the release record](FINALIZATION.md) for publication status before assuming 1.2.0 is available on a registry.
45
25
 
46
- ## Commands
26
+ ## One rule, an observable failure, a correction
47
27
 
48
- Install the toolchain:
28
+ A manifest binds a component to `action_button`. Change the component document's `Slug` to `action_buton` and validation reports `BINDING_MISMATCH`, the file, the `Slug` field, and both values. Restore the slug and all targets compile.
49
29
 
50
- ```bash
51
- python -m pip install -e .
52
- ```
53
-
54
- Validate a COX project:
30
+ Run the complete walkthrough from a source checkout after installing the package:
55
31
 
56
32
  ```bash
57
- cox validate .
33
+ python scripts/demo.py --out /tmp/cox-contract-demo
58
34
  ```
59
35
 
60
- Compile a COX project to normalized JSON:
36
+ It saves the invalid input, actual diagnostic, corrected input, verification result, generated React, and package. Use a new output folder on each run. [Example guide](guides/contract-demo.md).
61
37
 
62
- ```bash
63
- cox compile . --out build
64
- ```
38
+ ## What is checked
65
39
 
66
- Compile React stubs from the same normalized COX document model:
67
-
68
- ```bash
69
- cox compile . --target react --out build
70
- ```
40
+ - UTF-8 and a JSON-compatible YAML subset, with duplicate keys, aliases, non-string keys, dates and non-finite numbers rejected.
41
+ - Five canonical Draft 2020-12 schemas, shipped with the compiler: manifest, page, component, protocol, crop metadata.
42
+ - Manifest references, file/directory expectations, project boundaries, and page/component identity and folder bindings.
43
+ - Evidence labels: `Visible`, `UserSpecified`, `Inferred`, `Intended`, `Recommended`. Their factual accuracy still requires human evidence review.
44
+ - Generated identifiers, collisions, output ownership and archive inventory integrity.
71
45
 
72
- Compile multiple targets in one pass:
46
+ The contract describes an interface. It does **not** inspect an application's AST, execute design rules against a rendered page, implement interactions, prove accessibility, or provide an MCP server. The React target emits typed structural scaffolds with evidence comments; it does not infer finished styling or behavior. Protocol prose and `VerificationRules` are authoring guidance, not arbitrary executable rules.
73
47
 
74
- ```bash
75
- cox compile . --target json --target react --target package --out build
76
- ```
48
+ ## Commands
77
49
 
78
- The `package` target emits a deterministic ZIP archive and package manifest under `build/package/`. The archive uses sorted paths, fixed ZIP timestamps, project-relative names, SHA-256 file records, and excludes transient local artifacts such as `.venv`, `.mypy_cache`, `node_modules`, `*.egg-info`, raw intake ZIPs, and `build/package` itself.
50
+ | Command | Result |
51
+ |---|---|
52
+ | `cox init PATH --name NAME` | Complete small project; destination must be new or empty |
53
+ | `cox validate PATH --json` | Machine-readable diagnostics with exit 1 on invalid input |
54
+ | `cox validate PATH --strict` | Also fail on unreferenced-document warnings |
55
+ | `cox compile PATH --target json` | Normalized JSON (the default target) |
56
+ | `cox compile PATH -t react -t package` | Requested targets in stable order |
57
+ | `cox compile PATH -t all --json` | All three targets and artifact paths as JSON |
58
+ | `cox verify-package FILE.zip --json` | Check every payload against its embedded size/hash/mode record |
59
+ | `cox --version` | Tool version |
79
60
 
80
- ## Build Output
61
+ `--target` accepts repeated flags and comma-separated values. `BuildTargets` records supported project intent; the command selects which targets to emit and defaults to JSON. Usage errors exit 2; validation, compilation and verification failures exit 1. JSON mode applies to command results; argument parsing errors retain the CLI's normal usage format.
81
62
 
82
- Compilation emits:
63
+ ## Build artifacts and ownership
83
64
 
84
65
  ```text
85
66
  build/
67
+ .cox-build.json # exact files owned by this compiler run
86
68
  manifest.compiled.json
87
- normalized/
88
- reports/
89
- verification_report.txt
90
- package/
91
- cox_protocol_package_corrected.zip
92
- cox_protocol_package_corrected.manifest.json
69
+ normalized/ # selected json target
70
+ react/ # selected react target
71
+ package/ # selected package target
72
+ reports/verification_report.json
73
+ reports/verification_report.txt
93
74
  ```
94
75
 
95
- When the `react` target is requested, compilation also emits:
96
-
97
- ```text
98
- build/
99
- react/
100
- components/
101
- pages/
102
- index.ts
103
- manifest.react.json
104
- ```
105
-
106
- The React target is intentionally stub-oriented. It uses COX structure, roles, token references, layout notes, and implementation hints to generate TSX placeholders, but it does not invent concrete CSS values, event handlers, or runtime data contracts from prose-only fields.
107
-
108
- ## Guide and Skill Bundle Intake
109
-
110
- The manifest has first-class `GuideDocs` and `SkillBundles` sections.
76
+ The package includes manifest-referenced inputs and artifacts generated in the current run, under the manifest slug. Entries have sorted names, fixed timestamps, normalized permissions, and SHA-256 records. The external inventory also records the ZIP's checksum. Neither inventory is a digital signature. Determinism is verified for identical input bytes/modes and toolchain; ZIP compression bytes may differ between compression-library versions.
111
77
 
112
- Current imported content:
78
+ Recompilation replaces only the exact generated files recorded in `.cox-build.json`. Files from deselected targets are removed; unrelated files are preserved. A collision, edited generated file, or symlink produces an error before publication. Use a fresh `--out` directory for legacy builds without an ownership marker or when preserving edits. There is no force-overwrite mode. Publication attempts rollback on I/O failure; it is not a concurrent-writer or power-loss transaction.
113
79
 
114
- - `cox_protocol_package_compiled.zip` was audited as a legacy snapshot of this same package. It was not extracted over the live source because the current repository has the newer COX v1.0 manifest, schema, compiler, package target, and `protocols/` layout. See `guides/imported-packages/cox_protocol_package_compiled.md`.
115
- - `llm_agent_zip_skills_bundle.zip` was expanded into six skill directories under `skills/`.
116
- - NPM installation instructions for another device live in `guides/npm-installation.md`.
80
+ ## Development and release checks
117
81
 
118
- Use this intake flow for future ZIP files:
82
+ Use Node 22+ for development packaging; Node 18+ remains sufficient for the runtime wrapper.
119
83
 
120
84
  ```bash
121
- unzip -l cox_protocol_package_compiled.zip
122
- unzip -l llm_agent_zip_skills_bundle.zip
123
- ```
124
-
125
- Inspect the listings before extraction. Reject or rename entries with absolute paths, `..` path segments, root-level collisions such as `README.md` or `manifest.cox`, generated caches, or unrelated build artifacts. Curated guide content should land in `guides/`; curated skill bundle content should land in `skills/`. After that, add concrete paths to `GuideDocs` and `SkillBundles`, then rerun validation and compilation.
126
-
127
- ## Protocol Readiness Score
128
-
129
- | Attribute | Meter | Score | Notes |
130
- | --- | --- | ---: | --- |
131
- | Determinism | `[########--]` | 8/10 | Versioned headers, schema-backed manifests, stable package ordering, fixed ZIP timestamps, and SHA-256 records are now in place. Remaining work is an optional generated artifact policy for release bundles. |
132
- | Validation rigor | `[########--]` | 8/10 | YAML parsing, JSON Schema, manifest path checks, target enums, referenced guides, referenced skill bundle directories, and unreferenced `.cox` warnings are active. |
133
- | Evidence traceability | `[########--]` | 8/10 | Evidence and uncertainty protocols are explicit, and the package manifest records exact file hashes. Runtime visual evidence still depends on real screenshots replacing placeholders. |
134
- | Distribution readiness | `[#######---]` | 7/10 | Local Python CLI, NPM wrapper metadata, deterministic package output, VSIX packaging, guide docs, and skill bundle content are present. Public publishing still needs final repository URLs and account tokens. |
135
- | Interoperability | `[#######---]` | 7/10 | COX works as YAML-compatible structured text with JSON, React stub, VS Code, NPM, and ZIP surfaces. A TypeScript-native compiler and concrete design-token CSS layer remain future improvements. |
136
-
137
- COX complements Vercel v0 and Stitch-style AI design tools rather than replacing them. Those tools optimize prompt-to-app generation, visual iteration, repo sync, and deployment. COX optimizes deterministic file contracts, evidence tracking, schema validation, reproducible package output, and agent-to-agent handoff.
138
-
139
- ## Publication and Local Testing
140
-
141
- Install and test the Python CLI locally:
142
-
143
- ```bash
144
- python -m pip install -e .
145
- cox validate .
146
- cox compile . --target json --target react --target package --out build
147
- ```
148
-
149
- Check the NPM package contents before publishing:
150
-
151
- ```bash
152
- npm pack --dry-run
85
+ python -m pip install -e '.[dev]'
86
+ npm ci
87
+ COX_REQUIRE_TYPESCRIPT=1 python -m pytest
88
+ python scripts/release_check.py
89
+ python -m build
153
90
  npm pack
154
- npm install -g ./cox-protocol-package-<version>.tgz
155
- python3 -m pip install PyYAML jsonschema typer rich
156
- cox-protocol validate .
157
- ```
158
-
159
- The NPM wrapper delegates to the Python CLI, so the Python dependencies in `requirements.txt` must be installed in the environment used by `cox-protocol`. Set `COX_PYTHON=/path/to/python` if the desired interpreter is not `python3`.
160
-
161
- For a device-by-device installation walkthrough, see `guides/npm-installation.md`.
162
-
163
- Package the VS Code extension locally:
164
-
165
- ```bash
166
- cd editor-support/vscode
167
- npm run package
91
+ npm run package:vscode
168
92
  ```
169
93
 
170
- Public publishing still requires verified NPM, PyPI, and VS Code Marketplace credentials. Before publishing, confirm the repository URLs in `package.json`, `pyproject.toml`, and `editor-support/vscode/package.json` point to the final public repository.
94
+ The tests exercise format errors, bindings, generated TypeScript, deterministic archives, tamper detection, safe rebuilds, CLI behavior and snippet validity. CI additionally installs a wheel and an sdist into separate environments, installs the npm tarball locally, and verifies their CLIs away from the checkout. Python schemas and starter files must work from the installed package alone.
171
95
 
172
- ## Example Layout
96
+ ## Contents
173
97
 
174
- ```text
175
- LocalAppManager/
176
- Dashboard/
177
- dashboard.cox
178
- dashboard_screenshot.placeholder.txt
179
- left_navigation_sidebar/
180
- left_navigation_sidebar.cox
181
- left_navigation_sidebar_screenshot.placeholder.txt
182
- top_header_stats_bar/
183
- top_header_stats_bar.cox
184
- top_header_stats_bar_screenshot.placeholder.txt
185
- projects_grid_cards/
186
- projects_grid_cards.cox
187
- projects_grid_cards_screenshot.placeholder.txt
188
- analytics_sidebar_panels/
189
- analytics_sidebar_panels.cox
190
- analytics_sidebar_panels_screenshot.placeholder.txt
191
- ```
98
+ - `cox_protocol/`: installed compiler, canonical schema resources, starter assets.
99
+ - `schemas/`: matching public schemas for external tooling.
100
+ - `examples/quickstart/`: independent, small project with reference illustrations.
101
+ - `LocalAppManager/` and root `manifest.cox`: larger sample with explicitly labelled screenshot placeholders.
102
+ - `protocols/`, `templates/`, `skills/`, `guides/`: human/agent authoring material.
103
+ - `editor-support/vscode/`: syntax highlighting and snippets; CLI validation is separate.
104
+ - `tools/`: compatibility entry points for older source-checkout commands.
192
105
 
193
- The formal COX rules live in `COX_FILE_FORMAT_SPECIFICATION_v1.0.md`, and the executable contract lives in the schema files under `schemas/`.
106
+ The [format specification](COX_FILE_FORMAT_SPECIFICATION_v1.0.md), [changelog](CHANGELOG.md), and [finalisation record](FINALIZATION.md) describe the implemented contract and release evidence. The [historical intake guide](guides/imported-packages/cox_protocol_package_compiled.md) records earlier archive provenance.
@@ -1,101 +1,27 @@
1
1
  #!/usr/bin/env node
2
- import { spawnSync } from "node:child_process";
3
- import path from "node:path";
4
- import { fileURLToPath } from "node:url";
5
-
6
- const scriptPath = fileURLToPath(import.meta.url);
7
- const packageRoot = path.resolve(path.dirname(scriptPath), "..");
8
- const python = process.env.COX_PYTHON || "python3";
9
- const pythonPath = [packageRoot, process.env.PYTHONPATH]
10
- .filter(Boolean)
11
- .join(path.delimiter);
12
- const pythonEnv = {
13
- ...process.env,
14
- PYTHONPATH: pythonPath,
15
- };
16
-
17
- const versionCheck = spawnSync(
18
- python,
19
- [
20
- "-c",
21
- "import sys; print('.'.join(map(str, sys.version_info[:3]))); raise SystemExit(0 if sys.version_info >= (3, 9) else 1)",
22
- ],
23
- {
24
- cwd: process.cwd(),
25
- env: pythonEnv,
26
- stdio: "pipe",
27
- },
28
- );
29
-
30
- if (versionCheck.error) {
31
- console.error(
32
- `Unable to run the configured Python interpreter ${python}: ${versionCheck.error.message}`,
33
- );
34
- console.error(
35
- "Install Python 3.9 or newer, or set COX_PYTHON to a working interpreter.",
36
- );
37
- process.exit(1);
2
+ import { spawnSync } from 'node:child_process';
3
+ import { readFileSync } from 'node:fs';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
8
+ if (process.argv.length === 3 && process.argv[2] === '--version') {
9
+ console.log(JSON.parse(readFileSync(path.join(packageRoot, 'package.json'), 'utf8')).version);
10
+ process.exit(0);
38
11
  }
39
-
40
- if (versionCheck.status !== 0) {
41
- const detectedVersion = versionCheck.stdout.toString().trim() || "unknown";
42
- console.error(
43
- `COX requires Python 3.9 or newer, but ${python} resolved to ${detectedVersion}.`,
44
- );
45
- console.error(
46
- "Install Python 3.9+ or point COX_PYTHON at a supported interpreter.",
47
- );
48
- process.exit(versionCheck.status ?? 1);
49
- }
50
-
51
- const dependencyCheck = spawnSync(
52
- python,
53
- ["-c", "import typer, yaml, jsonschema, rich"],
54
- {
55
- cwd: process.cwd(),
56
- env: pythonEnv,
57
- stdio: "pipe",
58
- },
59
- );
60
-
61
- if (dependencyCheck.error) {
62
- console.error(
63
- `Unable to run the configured Python interpreter ${python}: ${dependencyCheck.error.message}`,
64
- );
65
- console.error(
66
- "Install Python 3.9+ or point COX_PYTHON at a working interpreter.",
67
- );
12
+ const python = process.env.COX_PYTHON || (process.platform === 'win32' ? 'python' : 'python3');
13
+ const env = { ...process.env };
14
+ delete env.PYTHONPATH;
15
+ // Remove the caller's directory before importing dependencies or the bundled CLI.
16
+ const bootstrap = "import sys; root=sys.argv.pop(1); cwd=sys.argv.pop(1); sys.path=[root]+[p for p in sys.path if p and p!=cwd]; ";
17
+ const probe = spawnSync(python, ['-c', bootstrap + "print('.'.join(map(str,sys.version_info[:3]))); sys.exit(3) if sys.version_info < (3,9) else None; import yaml,jsonschema,typer,rich", packageRoot, process.cwd()], { env, encoding: 'utf8' });
18
+ if (probe.error || probe.status !== 0) {
19
+ console.error(`COX needs Python 3.9+ with its dependencies in the selected interpreter: ${python}`);
20
+ if (probe.error) console.error(probe.error.message);
21
+ else if (probe.status === 3) console.error(`Detected Python ${probe.stdout.trim()}.`);
22
+ else console.error('Install the Python package in a virtual environment, or install its requirements there; set COX_PYTHON to that environment’s Python executable.');
68
23
  process.exit(1);
69
24
  }
70
-
71
- if (dependencyCheck.status !== 0) {
72
- console.error(
73
- `Python dependencies for COX are missing in ${python}.`,
74
- );
75
- console.error(
76
- "Install them with `python3 -m pip install PyYAML jsonschema typer rich` or point COX_PYTHON at an environment that already has them.",
77
- );
78
- process.exit(dependencyCheck.status ?? 1);
79
- }
80
-
81
- const result = spawnSync(
82
- python,
83
- ["-m", "tools.cox_cli", ...process.argv.slice(2)],
84
- {
85
- cwd: process.cwd(),
86
- env: pythonEnv,
87
- stdio: "inherit",
88
- },
89
- );
90
-
91
- if (result.error) {
92
- console.error(
93
- `Unable to run COX Python CLI with ${python}: ${result.error.message}`,
94
- );
95
- console.error(
96
- "Install Python dependencies with `python -m pip install PyYAML jsonschema typer rich` or set COX_PYTHON.",
97
- );
98
- process.exit(1);
99
- }
100
-
101
- process.exit(result.status ?? 1);
25
+ const result = spawnSync(python, ['-c', bootstrap + "sys.argv[0]='cox-protocol'; import runpy; runpy.run_module('cox_protocol.cox_cli',run_name='__main__')", packageRoot, process.cwd(), ...process.argv.slice(2)], { env, stdio: 'inherit' });
26
+ if (result.error) console.error(`Could not start COX: ${result.error.message}`);
27
+ process.exit(result.status ?? 1);
@@ -0,0 +1,2 @@
1
+ __version__ = "1.2.0"
2
+ __all__ = ["__version__"]
@@ -0,0 +1,3 @@
1
+ from .cox_cli import app
2
+
3
+ app()