workstate-stack 0.1.1__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.
@@ -0,0 +1,47 @@
1
+ Metadata-Version: 2.4
2
+ Name: workstate-stack
3
+ Version: 0.1.1
4
+ Summary: Workstate meta-package: one version anchor that pins the full published Workstate runtime stack (payload, protocol, bootstrap, MCP servers).
5
+ License: MIT
6
+ Project-URL: Homepage, https://github.com/darce/workstate
7
+ Project-URL: Source, https://github.com/darce/workstate/tree/main/packages/workstate-stack
8
+ Project-URL: Changelog, https://github.com/darce/workstate/blob/main/packages/workstate-stack/CHANGELOG.md
9
+ Project-URL: Issues, https://github.com/darce/workstate/issues
10
+ Requires-Python: >=3.12
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: workstate-protocol==0.2.2
13
+ Requires-Dist: mcp-workstate-handoff==0.12.4
14
+ Requires-Dist: mcp-workstate-orchestrator==0.6.1
15
+ Requires-Dist: workstate-bootstrap==0.8.3
16
+ Requires-Dist: workstate-system==0.2.2
17
+ Provides-Extra: dev
18
+ Requires-Dist: pytest>=8; extra == "dev"
19
+
20
+ # workstate-stack
21
+
22
+ One-number version anchor for the Workstate runtime stack.
23
+
24
+ Installing or upgrading this meta-package pulls every published Workstate
25
+ runtime member at the exact versions released together:
26
+
27
+ ```sh
28
+ pip install --upgrade workstate-stack
29
+ ```
30
+
31
+ Pinned members (exact `==` pins, regenerated by `make stack-pins-sync`,
32
+ gated by `make stack-pins-check`):
33
+
34
+ - `workstate-protocol`
35
+ - `mcp-workstate-handoff`
36
+ - `mcp-workstate-orchestrator`
37
+ - `workstate-bootstrap`
38
+ - `workstate-system`
39
+
40
+ Deliberately excluded: `mcp-workstate-canvas` (private, `publish=false`) and
41
+ `workstate-codex-bridge` (optional host-specific bridge; future
42
+ `workstate-stack[codex]` extra).
43
+
44
+ The package ships no code — `workstate_stack` is an empty module for wheel
45
+ validity. Consumers normally reach it through `make workstate-update`
46
+ (implementation note), which upgrades this anchor and then re-materializes the repo
47
+ overlay via `workstate-bootstrap update`.
@@ -0,0 +1,28 @@
1
+ # workstate-stack
2
+
3
+ One-number version anchor for the Workstate runtime stack.
4
+
5
+ Installing or upgrading this meta-package pulls every published Workstate
6
+ runtime member at the exact versions released together:
7
+
8
+ ```sh
9
+ pip install --upgrade workstate-stack
10
+ ```
11
+
12
+ Pinned members (exact `==` pins, regenerated by `make stack-pins-sync`,
13
+ gated by `make stack-pins-check`):
14
+
15
+ - `workstate-protocol`
16
+ - `mcp-workstate-handoff`
17
+ - `mcp-workstate-orchestrator`
18
+ - `workstate-bootstrap`
19
+ - `workstate-system`
20
+
21
+ Deliberately excluded: `mcp-workstate-canvas` (private, `publish=false`) and
22
+ `workstate-codex-bridge` (optional host-specific bridge; future
23
+ `workstate-stack[codex]` extra).
24
+
25
+ The package ships no code — `workstate_stack` is an empty module for wheel
26
+ validity. Consumers normally reach it through `make workstate-update`
27
+ (implementation note), which upgrades this anchor and then re-materializes the repo
28
+ overlay via `workstate-bootstrap update`.
@@ -0,0 +1,39 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "workstate-stack"
7
+ version = "0.1.1"
8
+ description = "Workstate meta-package: one version anchor that pins the full published Workstate runtime stack (payload, protocol, bootstrap, MCP servers)."
9
+ readme = "README.md"
10
+ # Floor must match the strictest member pin (mcp-workstate-handoff >=3.12);
11
+ # a looser floor makes `uv sync` unresolvable and aborts `make task-start`.
12
+ requires-python = ">=3.12"
13
+ license = { text = "MIT" }
14
+ # Exact pins are GENERATED — never hand-edit. `make stack-pins-sync` rewrites
15
+ # the block from sibling pyproject versions; `make stack-pins-check` gates
16
+ # check-all and release on the pins matching.
17
+ dependencies = [
18
+ # >>> STACK PINS (generated by scripts/stack_pins.py; make stack-pins-sync) >>>
19
+ "workstate-protocol==0.2.2",
20
+ "mcp-workstate-handoff==0.12.4",
21
+ "mcp-workstate-orchestrator==0.6.1",
22
+ "workstate-bootstrap==0.8.3",
23
+ "workstate-system==0.2.2",
24
+ # <<< STACK PINS <<<
25
+ ]
26
+
27
+ [project.urls]
28
+ Homepage = "https://github.com/darce/workstate"
29
+ Source = "https://github.com/darce/workstate/tree/main/packages/workstate-stack"
30
+ Changelog = "https://github.com/darce/workstate/blob/main/packages/workstate-stack/CHANGELOG.md"
31
+ Issues = "https://github.com/darce/workstate/issues"
32
+
33
+ [project.optional-dependencies]
34
+ dev = [
35
+ "pytest>=8",
36
+ ]
37
+
38
+ [tool.setuptools.packages.find]
39
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,7 @@
1
+ """Empty anchor module: ``workstate-stack`` ships no code of its own.
2
+
3
+ The distribution exists solely to carry exact ``==`` pins on the published
4
+ Workstate runtime members (see ``pyproject.toml``), so consumers upgrade the
5
+ whole stack with one version number:
6
+ ``pip install --upgrade workstate-stack``.
7
+ """
@@ -0,0 +1,47 @@
1
+ Metadata-Version: 2.4
2
+ Name: workstate-stack
3
+ Version: 0.1.1
4
+ Summary: Workstate meta-package: one version anchor that pins the full published Workstate runtime stack (payload, protocol, bootstrap, MCP servers).
5
+ License: MIT
6
+ Project-URL: Homepage, https://github.com/darce/workstate
7
+ Project-URL: Source, https://github.com/darce/workstate/tree/main/packages/workstate-stack
8
+ Project-URL: Changelog, https://github.com/darce/workstate/blob/main/packages/workstate-stack/CHANGELOG.md
9
+ Project-URL: Issues, https://github.com/darce/workstate/issues
10
+ Requires-Python: >=3.12
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: workstate-protocol==0.2.2
13
+ Requires-Dist: mcp-workstate-handoff==0.12.4
14
+ Requires-Dist: mcp-workstate-orchestrator==0.6.1
15
+ Requires-Dist: workstate-bootstrap==0.8.3
16
+ Requires-Dist: workstate-system==0.2.2
17
+ Provides-Extra: dev
18
+ Requires-Dist: pytest>=8; extra == "dev"
19
+
20
+ # workstate-stack
21
+
22
+ One-number version anchor for the Workstate runtime stack.
23
+
24
+ Installing or upgrading this meta-package pulls every published Workstate
25
+ runtime member at the exact versions released together:
26
+
27
+ ```sh
28
+ pip install --upgrade workstate-stack
29
+ ```
30
+
31
+ Pinned members (exact `==` pins, regenerated by `make stack-pins-sync`,
32
+ gated by `make stack-pins-check`):
33
+
34
+ - `workstate-protocol`
35
+ - `mcp-workstate-handoff`
36
+ - `mcp-workstate-orchestrator`
37
+ - `workstate-bootstrap`
38
+ - `workstate-system`
39
+
40
+ Deliberately excluded: `mcp-workstate-canvas` (private, `publish=false`) and
41
+ `workstate-codex-bridge` (optional host-specific bridge; future
42
+ `workstate-stack[codex]` extra).
43
+
44
+ The package ships no code — `workstate_stack` is an empty module for wheel
45
+ validity. Consumers normally reach it through `make workstate-update`
46
+ (implementation note), which upgrades this anchor and then re-materializes the repo
47
+ overlay via `workstate-bootstrap update`.
@@ -0,0 +1,9 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/workstate_stack/__init__.py
4
+ src/workstate_stack.egg-info/PKG-INFO
5
+ src/workstate_stack.egg-info/SOURCES.txt
6
+ src/workstate_stack.egg-info/dependency_links.txt
7
+ src/workstate_stack.egg-info/requires.txt
8
+ src/workstate_stack.egg-info/top_level.txt
9
+ tests/test_stack_pins.py
@@ -0,0 +1,8 @@
1
+ workstate-protocol==0.2.2
2
+ mcp-workstate-handoff==0.12.4
3
+ mcp-workstate-orchestrator==0.6.1
4
+ workstate-bootstrap==0.8.3
5
+ workstate-system==0.2.2
6
+
7
+ [dev]
8
+ pytest>=8
@@ -0,0 +1 @@
1
+ workstate_stack
@@ -0,0 +1,224 @@
1
+ """Pin-sync gate for the ``workstate-stack`` meta-package (implementation note implementation note).
2
+
3
+ The meta-package is the single version anchor consumers install: its
4
+ ``dependencies`` block carries exact ``==`` pins on every published stack
5
+ member. Pins are never hand-edited — ``scripts/stack_pins.py sync``
6
+ regenerates them from sibling ``pyproject.toml`` versions and
7
+ ``scripts/stack_pins.py check`` (``make stack-pins-check``) fails when they
8
+ drift, so a member bump can never ship without moving the meta pins.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import importlib.util
14
+ import json
15
+ import sys
16
+ from pathlib import Path
17
+
18
+
19
+ REPO_ROOT = Path(__file__).resolve().parents[3]
20
+ SOURCE_STACK_PINS = REPO_ROOT / "scripts" / "stack_pins.py"
21
+
22
+ EXPECTED_MEMBERS = (
23
+ "workstate-protocol",
24
+ "mcp-workstate-handoff",
25
+ "mcp-workstate-orchestrator",
26
+ "workstate-bootstrap",
27
+ "workstate-system",
28
+ )
29
+
30
+
31
+ def _load_module():
32
+ spec = importlib.util.spec_from_file_location(
33
+ "stack_pins_under_test", SOURCE_STACK_PINS
34
+ )
35
+ assert spec and spec.loader
36
+ module = importlib.util.module_from_spec(spec)
37
+ # Register before exec so @dataclass (under `from __future__ import
38
+ # annotations`) can resolve the module via sys.modules[cls.__module__].
39
+ sys.modules[spec.name] = module
40
+ spec.loader.exec_module(module)
41
+ return module
42
+
43
+
44
+ def _write(path: Path, text: str) -> None:
45
+ path.parent.mkdir(parents=True, exist_ok=True)
46
+ path.write_text(text, encoding="utf-8")
47
+
48
+
49
+ def _member_pyproject(name: str, version: str) -> str:
50
+ return f'[project]\nname = "{name}"\nversion = "{version}"\n'
51
+
52
+
53
+ def _stack_pyproject(pins: dict[str, str] | None) -> str:
54
+ """Stack pyproject with the generated pins block carrying ``pins``."""
55
+ lines = [
56
+ "[build-system]",
57
+ 'requires = ["setuptools>=68", "wheel"]',
58
+ 'build-backend = "setuptools.build_meta"',
59
+ "",
60
+ "[project]",
61
+ 'name = "workstate-stack"',
62
+ 'version = "0.1.0"',
63
+ 'description = "fixture"',
64
+ 'requires-python = ">=3.11"',
65
+ "dependencies = [",
66
+ " # >>> STACK PINS (generated by scripts/stack_pins.py; make stack-pins-sync) >>>",
67
+ ]
68
+ for distribution, version in (pins or {}).items():
69
+ lines.append(f' "{distribution}=={version}",')
70
+ lines.extend(
71
+ [
72
+ " # <<< STACK PINS <<<",
73
+ "]",
74
+ "",
75
+ "[tool.setuptools.packages.find]",
76
+ 'where = ["src"]',
77
+ "",
78
+ ]
79
+ )
80
+ return "\n".join(lines)
81
+
82
+
83
+ def _build_repo(
84
+ tmp_path: Path,
85
+ *,
86
+ member_versions: dict[str, str] | None = None,
87
+ stack_pins: dict[str, str] | None = None,
88
+ omit_stack_block: bool = False,
89
+ ) -> Path:
90
+ """Synthetic monorepo: release manifest, member pyprojects, stack pyproject."""
91
+ repo = tmp_path / "repo"
92
+ versions = dict(member_versions or {})
93
+ for member in EXPECTED_MEMBERS:
94
+ versions.setdefault(member, "1.0.0")
95
+ # Non-member packages prove the member set is closed.
96
+ versions.setdefault("mcp-workstate-canvas", "9.9.9")
97
+ versions.setdefault("workstate-codex-bridge", "9.9.9")
98
+
99
+ packages = []
100
+ for name, version in versions.items():
101
+ path = f"packages/{name}"
102
+ _write(repo / path / "pyproject.toml", _member_pyproject(name, version))
103
+ packages.append(
104
+ {
105
+ "name": name,
106
+ "path": path,
107
+ "distribution": name,
108
+ "artifact_prefix": name.replace("-", "_"),
109
+ "publish": name != "mcp-workstate-canvas",
110
+ "test_command": "python -m pytest -q",
111
+ "changelog": f"{path}/CHANGELOG.md",
112
+ }
113
+ )
114
+ _write(
115
+ repo / "config" / "release" / "packages.json",
116
+ json.dumps({"packages": packages}, indent=2) + "\n",
117
+ )
118
+
119
+ if omit_stack_block:
120
+ stack_text = _stack_pyproject(None).replace(
121
+ " # >>> STACK PINS (generated by scripts/stack_pins.py; make stack-pins-sync) >>>\n",
122
+ "",
123
+ ).replace(" # <<< STACK PINS <<<\n", "")
124
+ else:
125
+ pins = stack_pins
126
+ if pins is None:
127
+ pins = {member: versions[member] for member in EXPECTED_MEMBERS}
128
+ stack_text = _stack_pyproject(pins)
129
+ _write(repo / "packages" / "workstate-stack" / "pyproject.toml", stack_text)
130
+ return repo
131
+
132
+
133
+ def test_member_set_is_exactly_the_published_runtime_stack():
134
+ module = _load_module()
135
+ assert tuple(module.STACK_MEMBERS) == EXPECTED_MEMBERS
136
+ assert "mcp-workstate-canvas" not in module.STACK_MEMBERS
137
+ assert "workstate-codex-bridge" not in module.STACK_MEMBERS
138
+
139
+
140
+ def test_check_passes_when_pins_match_member_versions(tmp_path: Path):
141
+ module = _load_module()
142
+ repo = _build_repo(tmp_path, member_versions={"workstate-system": "0.2.1"})
143
+ ok, messages = module.check(repo)
144
+ assert ok, messages
145
+
146
+
147
+ def test_check_flags_drifted_pin(tmp_path: Path):
148
+ module = _load_module()
149
+ versions = {member: "1.0.0" for member in EXPECTED_MEMBERS}
150
+ stale = dict(versions)
151
+ stale["workstate-system"] = "0.9.0"
152
+ repo = _build_repo(tmp_path, member_versions=versions, stack_pins=stale)
153
+ ok, messages = module.check(repo)
154
+ assert not ok
155
+ blob = "\n".join(messages)
156
+ assert "workstate-system" in blob
157
+ assert "0.9.0" in blob and "1.0.0" in blob
158
+ assert "stack-pins-sync" in blob # remediation is named, not implied
159
+
160
+
161
+ def test_check_flags_missing_member_pin(tmp_path: Path):
162
+ module = _load_module()
163
+ pins = {member: "1.0.0" for member in EXPECTED_MEMBERS}
164
+ del pins["mcp-workstate-handoff"]
165
+ repo = _build_repo(tmp_path, stack_pins=pins)
166
+ ok, messages = module.check(repo)
167
+ assert not ok
168
+ assert any("mcp-workstate-handoff" in line for line in messages)
169
+
170
+
171
+ def test_sync_rewrites_drifted_pins_then_check_passes(tmp_path: Path):
172
+ module = _load_module()
173
+ versions = {member: "2.3.4" for member in EXPECTED_MEMBERS}
174
+ stale = {member: "0.0.1" for member in EXPECTED_MEMBERS}
175
+ repo = _build_repo(tmp_path, member_versions=versions, stack_pins=stale)
176
+
177
+ changed = module.sync(repo)
178
+ assert changed
179
+
180
+ text = (repo / "packages" / "workstate-stack" / "pyproject.toml").read_text()
181
+ for member in EXPECTED_MEMBERS:
182
+ assert f'"{member}==2.3.4"' in text
183
+ ok, messages = module.check(repo)
184
+ assert ok, messages
185
+
186
+
187
+ def test_sync_is_idempotent_and_preserves_surrounding_content(tmp_path: Path):
188
+ module = _load_module()
189
+ repo = _build_repo(tmp_path)
190
+ pyproject = repo / "packages" / "workstate-stack" / "pyproject.toml"
191
+ before = pyproject.read_text()
192
+
193
+ assert module.sync(repo) is False # already in sync -> no rewrite
194
+ after = pyproject.read_text()
195
+ assert after == before
196
+ assert 'name = "workstate-stack"' in after
197
+ assert "[tool.setuptools.packages.find]" in after
198
+
199
+
200
+ def test_missing_sentinel_block_is_a_clear_error(tmp_path: Path):
201
+ module = _load_module()
202
+ repo = _build_repo(tmp_path, omit_stack_block=True)
203
+ ok, messages = module.check(repo)
204
+ assert not ok
205
+ assert any("STACK PINS" in line for line in messages)
206
+
207
+
208
+ def test_cli_check_exit_codes(tmp_path: Path):
209
+ module = _load_module()
210
+ repo = _build_repo(tmp_path)
211
+ assert module.main(["check", "--repo-root", str(repo)]) == 0
212
+
213
+ stale = {member: "0.0.1" for member in EXPECTED_MEMBERS}
214
+ drifted = _build_repo(tmp_path / "drift", stack_pins=stale)
215
+ assert module.main(["check", "--repo-root", str(drifted)]) == 1
216
+ assert module.main(["sync", "--repo-root", str(drifted)]) == 0
217
+ assert module.main(["check", "--repo-root", str(drifted)]) == 0
218
+
219
+
220
+ def test_real_repo_pins_are_in_sync():
221
+ """The committed meta-package pins always match sibling versions."""
222
+ module = _load_module()
223
+ ok, messages = module.check(REPO_ROOT)
224
+ assert ok, messages