workstate-bootstrap 0.6.0__tar.gz → 0.7.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.
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/CHANGELOG.md +52 -20
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/PKG-INFO +3 -2
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/pyproject.toml +8 -2
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/src/workstate_bootstrap/cli.py +53 -13
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/src/workstate_bootstrap/install.py +526 -243
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/src/workstate_bootstrap/mcp_sync.py +2 -4
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/src/workstate_bootstrap/subcommands.py +79 -83
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_bootstrap_install_rehearsal.py +15 -15
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_cli_profile.py +5 -5
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_doctor_repair_sync.py +3 -3
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_ensure_hooks_path_make.py +1 -1
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_install.py +343 -30
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_install_manifest_walker.py +2 -2
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_install_profile_all_lifecycle.py +2 -2
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_install_profiles.py +5 -5
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_manifest_build.py +1 -1
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_mcp_sync_cli.py +59 -2
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_mcp_sync_e2e.py +2 -2
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_mcp_sync_malformed.py +1 -1
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_mcp_sync_prune.py +1 -1
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_mcp_sync_unit.py +1 -1
- workstate_bootstrap-0.7.0/tests/test_package_source.py +196 -0
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_render_seam.py +1 -1
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_root_visible_task_plans.py +2 -2
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_subcommands.py +123 -7
- workstate_bootstrap-0.6.0/docs/tasks/AHMCP-48-skills-imply-lifecycle-hoist-task-plan.md +0 -263
- workstate_bootstrap-0.6.0/docs/tasks/AHMCP-49-managed-server-versions-constant-task-plan.md +0 -186
- workstate_bootstrap-0.6.0/docs/tasks/AHMCP-50-mcp-sync-config-only-subcommand-task-plan.md +0 -246
- workstate_bootstrap-0.6.0/docs/tasks/AHMCP-56-cross-harness-install-manifest-task-plan.md +0 -355
- workstate_bootstrap-0.6.0/docs/tasks/AHMCP-57-stale-symlink-repoint-task-plan.md +0 -274
- workstate_bootstrap-0.6.0/tests/test_mcp_legacy_rename.py +0 -375
- workstate_bootstrap-0.6.0/tests/test_runtime_path_migration.py +0 -269
- workstate_bootstrap-0.6.0/uv.lock +0 -1754
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/.gitignore +0 -0
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/README.md +0 -0
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/src/workstate_bootstrap/__init__.py +0 -0
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/src/workstate_bootstrap/__main__.py +0 -0
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/__init__.py +0 -0
- {workstate_bootstrap-0.6.0 → workstate_bootstrap-0.7.0}/tests/test_package_metadata.py +0 -0
|
@@ -2,11 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## [0.7.0] — 2026-06-01
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Package-source overlay delivery (WS-PKG-DELIVERY-01).** `install` /
|
|
10
|
+
`update` can resolve the harness overlay from an installed
|
|
11
|
+
`workstate-system` distribution (`source_kind="package"`) instead of a git
|
|
12
|
+
clone, writing a `package`-kind `BootstrapManifest`. `update` / `repair`
|
|
13
|
+
reject a package-source manifest with a clear error rather than
|
|
14
|
+
dereferencing a `remote_url` that package manifests do not carry.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **MCP launch decoupled from resolution (implementation note Theme A,
|
|
19
|
+
WS-MCP-LAUNCH-01).** Generated serve commands now use `uv run --no-sync`
|
|
20
|
+
and the server venvs are pre-built at install time
|
|
21
|
+
(`_presync_local_mcp_envs`), eliminating the cold-start re-sync race that
|
|
22
|
+
overran the harness's 30s MCP connection timeout and registered zero tools.
|
|
23
|
+
The `--no-sync` invariant is enforced at the shared render seam
|
|
24
|
+
(`_canonicalize_managed_servers`), so `install` / `update` / `repair` /
|
|
25
|
+
`mcp-sync` all rewrite an older launcher; the earlier preserve-path
|
|
26
|
+
`_normalize_local_mcp_server_specs` patch is retired.
|
|
27
|
+
|
|
28
|
+
### Removed
|
|
29
|
+
|
|
30
|
+
- **Runtime-path migration shim retired (implementation note Slice D cutover complete).**
|
|
31
|
+
The legacy-runtime-tree migration helpers (`migrate_runtime_paths()`,
|
|
32
|
+
`plan_runtime_path_migration()`) and the `legacy_runtime_path` `doctor` check
|
|
33
|
+
are removed. `.workstate/` / `docs/workstate/` are the sole runtime paths with
|
|
34
|
+
no backward compatibility — a consumer still carrying the pre-rebrand runtime
|
|
35
|
+
tree must reinstall cleanly.
|
|
36
|
+
|
|
5
37
|
## [0.6.0] — 2026-05-30
|
|
6
38
|
|
|
7
39
|
### Changed
|
|
8
40
|
|
|
9
|
-
- **MCP server identity cutover (
|
|
41
|
+
- **MCP server identity cutover (implementation note Slice B).** Default managed servers
|
|
10
42
|
register under the canonical `workstate-handoff-mcp` /
|
|
11
43
|
`workstate-orchestrator-mcp` names. `LEGACY_MCP_SERVER_RENAMES` +
|
|
12
44
|
`_legacy_prune_for()` dedup and forward-rewrite a stale `agent-*-mcp`
|
|
@@ -20,8 +52,8 @@
|
|
|
20
52
|
|
|
21
53
|
### Added
|
|
22
54
|
|
|
23
|
-
- **Runtime path migration `.
|
|
24
|
-
`docs/
|
|
55
|
+
- **Runtime path migration `.workstate/` → `.workstate/` and
|
|
56
|
+
`docs/workstate/` → `docs/workstate/` (implementation note Slice D).**
|
|
25
57
|
`migrate_runtime_paths()` / `plan_runtime_path_migration()` run on
|
|
26
58
|
`install`/`update`: idempotent, archive-backed (a both-present collision
|
|
27
59
|
moves the legacy tree aside rather than overwriting), dry-run-capable, and
|
|
@@ -41,11 +73,11 @@
|
|
|
41
73
|
|
|
42
74
|
### Fixed
|
|
43
75
|
|
|
44
|
-
- **
|
|
76
|
+
- **WORKSTATE-REF-57 — stale shared-surface symlinks now repointed on rerun.**
|
|
45
77
|
When a consumer was installed pre-v0.2.0 (legacy root layout
|
|
46
78
|
`<clone>/<surface>`) and the layout subsequently moved into
|
|
47
79
|
`<clone>/packages/workstate-system/<surface>`, the target-side
|
|
48
|
-
`scripts/hooks -> ../.
|
|
80
|
+
`scripts/hooks -> ../.workstate/remote/scripts/hooks` symlink survived
|
|
49
81
|
every subsequent `workstate-bootstrap install` because the pre-fix
|
|
50
82
|
`points_into_clone` check still passed lexically for the broken
|
|
51
83
|
resolved path. `_materialize_surfaces` now classifies each existing
|
|
@@ -61,7 +93,7 @@
|
|
|
61
93
|
|
|
62
94
|
### Changed
|
|
63
95
|
|
|
64
|
-
- **
|
|
96
|
+
- **WORKSTATE-REF-56 — cross-harness install manifest is now the single source of
|
|
65
97
|
truth for hook adapter wiring.** `config/agent-workflows/portable_commands.json`
|
|
66
98
|
schema v2 introduces a top-level `hooks[]` array; install dispatches
|
|
67
99
|
adapter rows through a manifest-driven walker (closed-set operation
|
|
@@ -99,17 +131,17 @@
|
|
|
99
131
|
|
|
100
132
|
- **Bump default managed MCP server pins** to `mcp-workstate-handoff@0.11.1`
|
|
101
133
|
and `mcp-workstate-orchestrator@0.4.5` so consumer repos pick up the
|
|
102
|
-
|
|
134
|
+
WORKSTATE-REF-54 (multi-active CURRENT_TASK projection, import/export
|
|
103
135
|
malformed-payload rejection, target_branch/worktree_path/plan_path
|
|
104
|
-
preservation) and
|
|
105
|
-
consolidation under `AGENT_HANDOFF_COMPACTION_*` with `
|
|
136
|
+
preservation) and WORKSTATE-REF-55 (compaction env-var namespace
|
|
137
|
+
consolidation under `AGENT_HANDOFF_COMPACTION_*` with `WORKSTATE_*` kept
|
|
106
138
|
as a deprecated alias) fixes by default.
|
|
107
139
|
|
|
108
140
|
## [0.4.1] — 2026-05-09
|
|
109
141
|
|
|
110
142
|
### Fixed
|
|
111
143
|
|
|
112
|
-
- **`--profile all` now performs the lifecycle hoist** (
|
|
144
|
+
- **`--profile all` now performs the lifecycle hoist** (WORKSTATE-REF-48). The
|
|
113
145
|
legacy default profile shipped lifecycle-referencing skills
|
|
114
146
|
(`branch-lifecycle`, `tdd`, `incremental-implementation`,
|
|
115
147
|
`branch-review`, `handoff-lifecycle`) but did not install the
|
|
@@ -142,11 +174,11 @@
|
|
|
142
174
|
### Added
|
|
143
175
|
|
|
144
176
|
- **Install profile contract: `--profile {minimal,lifecycle,all}`**
|
|
145
|
-
(
|
|
177
|
+
(implementation note / WORKSTATE-REF-40 implementation note.5.a). The CLI now accepts an explicit
|
|
146
178
|
install profile flag and honors it across the manifest layers, so
|
|
147
179
|
consumer repos can pick a smaller hoist surface than the default.
|
|
148
|
-
- **Hoist `Makefile.d/plans.mk` + `git-plan-cat.sh` stub** (
|
|
149
|
-
|
|
180
|
+
- **Hoist `Makefile.d/plans.mk` + `git-plan-cat.sh` stub** (implementation note /
|
|
181
|
+
WORKSTATE-REF-38 implementation note). Consumer repos installed via `workstate-bootstrap`
|
|
150
182
|
pick up `make plan-show / plan-edit / plans-list / plan-register`
|
|
151
183
|
out of the box; the targets shell out to `uvx mcp-workstate-handoff`
|
|
152
184
|
under the hood.
|
|
@@ -160,14 +192,14 @@
|
|
|
160
192
|
|
|
161
193
|
## [0.3.1] — 2026-05-03
|
|
162
194
|
|
|
163
|
-
- **
|
|
195
|
+
- **implementation note BR-01 — raise `workstate-protocol` lower bound to
|
|
164
196
|
`>=0.1.2,<0.2.0`.** Bootstrap's default install path invokes
|
|
165
197
|
`uvx mcp-workstate-handoff`, which imports `workstate_protocol.branch_naming`
|
|
166
198
|
at startup; the previous `>=0.1.0` floor let `uvx` resolve a protocol
|
|
167
199
|
release missing the module, crashing init-state on a fresh install. A
|
|
168
200
|
new packaging test (`tests/test_package_metadata.py`) pins the floor
|
|
169
201
|
so the declaration cannot silently drift back below the contract.
|
|
170
|
-
- **
|
|
202
|
+
- **implementation note implementation note — install rehearsal pins six-hook surface +
|
|
171
203
|
helper materialization.** `SHARED_GIT_HOOK_NAMES` now includes
|
|
172
204
|
`pre-commit` (in addition to `post-checkout`, `post-commit`,
|
|
173
205
|
`post-merge`, `post-rewrite`, `pre-push`); the install rehearsal
|
|
@@ -177,7 +209,7 @@
|
|
|
177
209
|
post-checkout / pre-commit / pre-push hooks `exec`) is materialized
|
|
178
210
|
alongside them. Without the helper, every branch-naming gate
|
|
179
211
|
silently no-ops. The shared surface itself is unchanged
|
|
180
|
-
(`scripts/hooks` is symlinked from `.
|
|
212
|
+
(`scripts/hooks` is symlinked from `.workstate/remote`); the new
|
|
181
213
|
assertion catches a future regression where the upstream package
|
|
182
214
|
drops the helper.
|
|
183
215
|
- **Manifest renamed: `.workstate-overlay.json` → `.workstate-bootstrap.json`
|
|
@@ -195,7 +227,7 @@
|
|
|
195
227
|
--workspace-root . serve-stdio` into `.mcp.json`,
|
|
196
228
|
`.vscode/mcp.json`, and `.codex/config.toml`, so external clients
|
|
197
229
|
start runnable MCP servers from a fresh install or update.
|
|
198
|
-
- **`regenerate-task-views` harness hook contract dropped (
|
|
230
|
+
- **`regenerate-task-views` harness hook contract dropped (implementation note).**
|
|
199
231
|
Bootstrap no longer materializes any Claude / VS Code / Codex hook
|
|
200
232
|
wiring that invokes `regenerate-task-views`; `DASHBOARD.txt` is now
|
|
201
233
|
auto-regenerated server-side inside `mcp-workstate-handoff` on every
|
|
@@ -208,7 +240,7 @@
|
|
|
208
240
|
|
|
209
241
|
## 0.3.0 — 2026-04-28
|
|
210
242
|
|
|
211
|
-
- **Install-time state provisioning (
|
|
243
|
+
- **Install-time state provisioning (implementation note).** `install` now runs
|
|
212
244
|
the handoff server's `init-state` after surface/config materialization
|
|
213
245
|
but before `core.hooksPath` is set, so a fresh install ends with a
|
|
214
246
|
schema-current `.task-state/handoff.db` and `.task-state/exports/`
|
|
@@ -232,7 +264,7 @@
|
|
|
232
264
|
gated on `.mcp.json` being present in the manifest's `configs` array
|
|
233
265
|
so config-only installs (`--no-mcp-servers`) do not produce
|
|
234
266
|
false-positive drift.
|
|
235
|
-
- **`switch_task` cold-start fix.**
|
|
267
|
+
- **`switch_task` cold-start fix.** implementation note implementation note (in
|
|
236
268
|
`mcp-workstate-handoff` 0.5.0+) drops `BranchMismatchError` from
|
|
237
269
|
`switch_task`; the cold-start cycle (register task → `switch_task`
|
|
238
270
|
→ first content write) now completes from any branch. Branch
|
|
@@ -255,7 +287,7 @@
|
|
|
255
287
|
`packages/workstate-system/` (the workstate monorepo layout) with
|
|
256
288
|
fallback to the clone root for legacy hoisted overlays. Fixes
|
|
257
289
|
`BootstrapManifestValidationError: required surface 'scripts/hooks' was
|
|
258
|
-
not materialized` against monorepo refs at or after
|
|
290
|
+
not materialized` against monorepo refs at or after implementation note step 1.
|
|
259
291
|
- Rehearsal fixture (`fake_remote_with_generator`) now mirrors the real
|
|
260
292
|
monorepo layout so this regression cannot return silently.
|
|
261
293
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: workstate-bootstrap
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Bootstrap CLI that hoists the shared workstate-system surface into consumer repos.
|
|
5
5
|
Project-URL: Homepage, https://github.com/darce/workstate
|
|
6
6
|
Project-URL: Source, https://github.com/darce/workstate/tree/main/packages/workstate-bootstrap
|
|
@@ -11,7 +11,8 @@ License: Proprietary
|
|
|
11
11
|
Requires-Python: >=3.11
|
|
12
12
|
Requires-Dist: pyyaml>=6
|
|
13
13
|
Requires-Dist: tomlkit>=0.13
|
|
14
|
-
Requires-Dist: workstate-protocol<0.2.0,>=0.1.
|
|
14
|
+
Requires-Dist: workstate-protocol<0.2.0,>=0.1.7
|
|
15
|
+
Requires-Dist: workstate-system<0.2.0,>=0.1.0
|
|
15
16
|
Provides-Extra: dev
|
|
16
17
|
Requires-Dist: mcp-workstate-handoff; (python_version >= '3.12') and extra == 'dev'
|
|
17
18
|
Requires-Dist: pytest>=8; extra == 'dev'
|
|
@@ -4,13 +4,18 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "workstate-bootstrap"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.7.0"
|
|
8
8
|
description = "Bootstrap CLI that hoists the shared workstate-system surface into consumer repos."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
11
11
|
license = { text = "Proprietary" }
|
|
12
12
|
authors = [{ name = "darce" }]
|
|
13
|
-
dependencies = [
|
|
13
|
+
dependencies = [
|
|
14
|
+
"tomlkit>=0.13",
|
|
15
|
+
"pyyaml>=6",
|
|
16
|
+
"workstate-protocol>=0.1.7,<0.2.0",
|
|
17
|
+
"workstate-system>=0.1.0,<0.2.0",
|
|
18
|
+
]
|
|
14
19
|
|
|
15
20
|
[project.scripts]
|
|
16
21
|
workstate-bootstrap = "workstate_bootstrap.cli:main"
|
|
@@ -27,6 +32,7 @@ dev = ["pytest>=8", "mcp-workstate-handoff; python_version >= '3.12'"]
|
|
|
27
32
|
[tool.uv.sources]
|
|
28
33
|
mcp-workstate-handoff = { path = "../mcp-workstate-handoff", editable = true }
|
|
29
34
|
workstate-protocol = { path = "../workstate-protocol", editable = true }
|
|
35
|
+
workstate-system = { path = "../workstate-system", editable = true }
|
|
30
36
|
|
|
31
37
|
[tool.hatch.build.targets.wheel]
|
|
32
38
|
packages = ["src/workstate_bootstrap"]
|
|
@@ -13,6 +13,7 @@ from workstate_bootstrap.install import (
|
|
|
13
13
|
PROFILE_ALL,
|
|
14
14
|
PROFILE_LIFECYCLE,
|
|
15
15
|
PROFILE_MINIMAL,
|
|
16
|
+
_build_local_default_mcp_servers,
|
|
16
17
|
install,
|
|
17
18
|
)
|
|
18
19
|
from workstate_bootstrap.mcp_sync import (
|
|
@@ -23,11 +24,11 @@ from workstate_bootstrap.mcp_sync import (
|
|
|
23
24
|
)
|
|
24
25
|
from workstate_bootstrap.subcommands import doctor, repair, status, update
|
|
25
26
|
|
|
26
|
-
#
|
|
27
|
+
# implementation note: CLI default flips to ``minimal``. The library
|
|
27
28
|
# ``install()`` API keeps ``profile="all"`` for back-compat with
|
|
28
29
|
# pre-Plan-0009 callers.
|
|
29
30
|
INSTALL_PROFILE_CHOICES: tuple[str, ...] = (PROFILE_MINIMAL, PROFILE_LIFECYCLE, PROFILE_ALL)
|
|
30
|
-
#
|
|
31
|
+
# WORKSTATE-REF-56 implementation note: flipped from PROFILE_MINIMAL back to PROFILE_ALL so
|
|
31
32
|
# a no-argument ``workstate-bootstrap install`` materializes the full
|
|
32
33
|
# surface set out of the box. ``--profile minimal`` and
|
|
33
34
|
# ``--profile lifecycle`` remain opt-in for lean installs.
|
|
@@ -45,7 +46,7 @@ def _resolve_mcp_servers(
|
|
|
45
46
|
- ``no_servers=True``: explicit opt-out → ``None`` (no config files written).
|
|
46
47
|
- ``raw is None``: behavior depends on ``default_when_unset``. ``install``
|
|
47
48
|
passes ``True`` so an unset flag falls back to :data:`DEFAULT_MCP_SERVERS`
|
|
48
|
-
(
|
|
49
|
+
(implementation note step 2a — single-command, no-hand-edits install). ``doctor`` /
|
|
49
50
|
``update`` / ``repair`` pass ``False`` so an unset flag means
|
|
50
51
|
"don't check / refresh configs at all".
|
|
51
52
|
- ``raw == "default"``: use :data:`DEFAULT_MCP_SERVERS`.
|
|
@@ -64,8 +65,29 @@ def _resolve_mcp_servers(
|
|
|
64
65
|
return doc
|
|
65
66
|
|
|
66
67
|
|
|
68
|
+
def _resolve_managed_servers(
|
|
69
|
+
target: Path, raw: str | None
|
|
70
|
+
) -> Mapping[str, Mapping[str, Any]] | None:
|
|
71
|
+
"""Resolve ``--mcp-servers``, making ``default`` profile-aware.
|
|
72
|
+
|
|
73
|
+
On a ``git_overlay`` install with local MCP packages, ``default`` resolves
|
|
74
|
+
the LOCAL ``uv run --no-sync --project ...`` launchers (via
|
|
75
|
+
:func:`_build_local_default_mcp_servers`) instead of the uvx package map, so
|
|
76
|
+
``mcp-sync`` and ``repair`` converge on the same launchers as
|
|
77
|
+
``install``/``update`` and never silently downgrade a local install. Falls
|
|
78
|
+
back to the uvx map when no local packages are present. implementation note A1.
|
|
79
|
+
"""
|
|
80
|
+
servers = _resolve_mcp_servers(raw)
|
|
81
|
+
if raw == "default":
|
|
82
|
+
local = _build_local_default_mcp_servers(target)
|
|
83
|
+
if local is not None:
|
|
84
|
+
return local
|
|
85
|
+
return servers
|
|
86
|
+
|
|
87
|
+
|
|
67
88
|
DEFAULT_REMOTE_URL = "git@github.com:darce/workstate.git"
|
|
68
89
|
DEFAULT_REMOTE_REF = "main"
|
|
90
|
+
INSTALL_SOURCE_CHOICES: tuple[str, ...] = ("git_overlay", "package")
|
|
69
91
|
|
|
70
92
|
|
|
71
93
|
def _build_parser() -> argparse.ArgumentParser:
|
|
@@ -80,7 +102,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
80
102
|
|
|
81
103
|
p_install = sub.add_parser(
|
|
82
104
|
"install",
|
|
83
|
-
help="
|
|
105
|
+
help="Materialize the shared workstate-system overlay and write the manifest.",
|
|
84
106
|
)
|
|
85
107
|
p_install.add_argument(
|
|
86
108
|
"--target",
|
|
@@ -98,6 +120,16 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
98
120
|
default=DEFAULT_REMOTE_REF,
|
|
99
121
|
help=f"Tag or branch to check out (default: {DEFAULT_REMOTE_REF}).",
|
|
100
122
|
)
|
|
123
|
+
p_install.add_argument(
|
|
124
|
+
"--source",
|
|
125
|
+
choices=INSTALL_SOURCE_CHOICES,
|
|
126
|
+
default="git_overlay",
|
|
127
|
+
help=(
|
|
128
|
+
"Overlay source. 'git_overlay' keeps the existing clone-backed "
|
|
129
|
+
"default; 'package' resolves payload data from the installed "
|
|
130
|
+
"workstate-system distribution."
|
|
131
|
+
),
|
|
132
|
+
)
|
|
101
133
|
p_install.add_argument(
|
|
102
134
|
"--mcp-servers",
|
|
103
135
|
default=None,
|
|
@@ -160,7 +192,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
160
192
|
choices=INSTALL_PROFILE_CHOICES,
|
|
161
193
|
default=INSTALL_PROFILE_DEFAULT,
|
|
162
194
|
help=(
|
|
163
|
-
"Install profile. 'all' (default,
|
|
195
|
+
"Install profile. 'all' (default, WORKSTATE-REF-56 implementation note) materializes "
|
|
164
196
|
"per-agent surfaces, runs the workflow generator, writes MCP "
|
|
165
197
|
"config surfaces, and performs the lifecycle hoist. 'minimal' "
|
|
166
198
|
"clones the remote, writes the manifest, and sets core.hooksPath "
|
|
@@ -439,6 +471,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
439
471
|
target=args.target,
|
|
440
472
|
remote_url=args.remote_url,
|
|
441
473
|
remote_ref=args.remote_ref,
|
|
474
|
+
source=args.source,
|
|
442
475
|
mcp_servers=_resolve_mcp_servers(
|
|
443
476
|
args.mcp_servers,
|
|
444
477
|
no_servers=args.no_mcp_servers,
|
|
@@ -454,11 +487,18 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
454
487
|
install_codex_stop_hook=args.install_codex_stop_hook,
|
|
455
488
|
install_vscode_stop_hook=args.install_vscode_stop_hook,
|
|
456
489
|
)
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
490
|
+
if manifest.get("source_kind") == "package":
|
|
491
|
+
print(
|
|
492
|
+
f"installed workstate-system overlay: "
|
|
493
|
+
f"workstate-system=={manifest['package_version']} -> {args.target}",
|
|
494
|
+
file=sys.stdout,
|
|
495
|
+
)
|
|
496
|
+
else:
|
|
497
|
+
print(
|
|
498
|
+
f"installed workstate-system overlay: "
|
|
499
|
+
f"{args.remote_url}@{manifest['remote_sha']} -> {args.target}",
|
|
500
|
+
file=sys.stdout,
|
|
501
|
+
)
|
|
462
502
|
if isinstance(manifest.get("override_backup_path"), str):
|
|
463
503
|
print(f"override backup: {manifest['override_backup_path']}", file=sys.stdout)
|
|
464
504
|
if isinstance(manifest.get("state_backup_path"), str):
|
|
@@ -503,7 +543,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
503
543
|
backup_overrides=args.backup,
|
|
504
544
|
enforce_required_surfaces=not args.no_enforce_required_surfaces,
|
|
505
545
|
)
|
|
506
|
-
except FileNotFoundError as exc:
|
|
546
|
+
except (FileNotFoundError, ValueError) as exc:
|
|
507
547
|
print(str(exc), file=sys.stderr)
|
|
508
548
|
return 1
|
|
509
549
|
print(
|
|
@@ -520,7 +560,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
520
560
|
report = repair(
|
|
521
561
|
target=args.target,
|
|
522
562
|
force_dirty=args.force_dirty,
|
|
523
|
-
mcp_servers=
|
|
563
|
+
mcp_servers=_resolve_managed_servers(args.target, args.mcp_servers),
|
|
524
564
|
plugin_overrides=args.plugin_overrides,
|
|
525
565
|
)
|
|
526
566
|
except FileNotFoundError as exc:
|
|
@@ -540,7 +580,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
540
580
|
|
|
541
581
|
if args.command == "mcp-sync":
|
|
542
582
|
try:
|
|
543
|
-
servers =
|
|
583
|
+
servers = _resolve_managed_servers(args.target, args.mcp_servers)
|
|
544
584
|
except (FileNotFoundError, json.JSONDecodeError) as exc:
|
|
545
585
|
print(f"mcp-sync: --mcp-servers: {exc}", file=sys.stderr)
|
|
546
586
|
return 2
|