MarshalFleet 0.2.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 (126) hide show
  1. marshalfleet-0.2.0/.claude-plugin/marketplace.json +25 -0
  2. marshalfleet-0.2.0/.claude-plugin/plugin.json +39 -0
  3. marshalfleet-0.2.0/.github/ISSUE_TEMPLATE/bug_report.yml +71 -0
  4. marshalfleet-0.2.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  5. marshalfleet-0.2.0/.github/ISSUE_TEMPLATE/feature_request.yml +40 -0
  6. marshalfleet-0.2.0/.github/dependabot.yml +23 -0
  7. marshalfleet-0.2.0/.github/pull_request_template.md +16 -0
  8. marshalfleet-0.2.0/.github/workflows/ci.yml +49 -0
  9. marshalfleet-0.2.0/.github/workflows/release.yml +108 -0
  10. marshalfleet-0.2.0/.gitignore +58 -0
  11. marshalfleet-0.2.0/.python-version +1 -0
  12. marshalfleet-0.2.0/CHANGELOG.md +1056 -0
  13. marshalfleet-0.2.0/CLAUDE.md +130 -0
  14. marshalfleet-0.2.0/CODE_OF_CONDUCT.md +116 -0
  15. marshalfleet-0.2.0/CONTRIBUTING.md +189 -0
  16. marshalfleet-0.2.0/LICENSE +21 -0
  17. marshalfleet-0.2.0/PKG-INFO +207 -0
  18. marshalfleet-0.2.0/README.md +171 -0
  19. marshalfleet-0.2.0/SECURITY.md +188 -0
  20. marshalfleet-0.2.0/SETUP.md +246 -0
  21. marshalfleet-0.2.0/assets/README.md +35 -0
  22. marshalfleet-0.2.0/assets/architecture.svg +124 -0
  23. marshalfleet-0.2.0/assets/logo-dark.svg +8 -0
  24. marshalfleet-0.2.0/assets/logo-mono.svg +8 -0
  25. marshalfleet-0.2.0/assets/logo.svg +8 -0
  26. marshalfleet-0.2.0/assets/wordmark.png +0 -0
  27. marshalfleet-0.2.0/docs/chauffeur-future.md +163 -0
  28. marshalfleet-0.2.0/docs/config.md +182 -0
  29. marshalfleet-0.2.0/docs/design.md +557 -0
  30. marshalfleet-0.2.0/docs/mcp-tools.md +573 -0
  31. marshalfleet-0.2.0/docs/model-playbook.md +129 -0
  32. marshalfleet-0.2.0/docs/nerds.md +143 -0
  33. marshalfleet-0.2.0/docs/sources.md +32 -0
  34. marshalfleet-0.2.0/docs/status.md +188 -0
  35. marshalfleet-0.2.0/docs/usage.md +534 -0
  36. marshalfleet-0.2.0/examples/README.md +42 -0
  37. marshalfleet-0.2.0/examples/adversarial_review.py +107 -0
  38. marshalfleet-0.2.0/examples/benchmark-output.md +42 -0
  39. marshalfleet-0.2.0/examples/library_quickstart.py +40 -0
  40. marshalfleet-0.2.0/examples/multi_workspace.py +117 -0
  41. marshalfleet-0.2.0/examples/per_client_env.yaml +20 -0
  42. marshalfleet-0.2.0/examples/pipelined_review.py +95 -0
  43. marshalfleet-0.2.0/examples/read_paths.py +91 -0
  44. marshalfleet-0.2.0/examples/workflows/build-adapters.yaml +73 -0
  45. marshalfleet-0.2.0/examples/workflows/compare.yaml +14 -0
  46. marshalfleet-0.2.0/examples/workflows/review.yaml +19 -0
  47. marshalfleet-0.2.0/fleet.config.example.yaml +136 -0
  48. marshalfleet-0.2.0/fleet.config.yaml.bak +95 -0
  49. marshalfleet-0.2.0/pyproject.toml +118 -0
  50. marshalfleet-0.2.0/skills/marshal-adversarial-review/SKILL.md +121 -0
  51. marshalfleet-0.2.0/skills/marshal-benchmark/SKILL.md +45 -0
  52. marshalfleet-0.2.0/skills/marshal-orchestrate/SKILL.md +187 -0
  53. marshalfleet-0.2.0/skills/marshal-plan-consensus/SKILL.md +91 -0
  54. marshalfleet-0.2.0/skills/marshal-review-gate/SKILL.md +103 -0
  55. marshalfleet-0.2.0/skills/marshal-workflow/SKILL.md +82 -0
  56. marshalfleet-0.2.0/src/marshal_engine/__init__.py +45 -0
  57. marshalfleet-0.2.0/src/marshal_engine/backends/__init__.py +10 -0
  58. marshalfleet-0.2.0/src/marshal_engine/backends/antigravity.py +633 -0
  59. marshalfleet-0.2.0/src/marshal_engine/backends/base.py +383 -0
  60. marshalfleet-0.2.0/src/marshal_engine/backends/claude_code.py +224 -0
  61. marshalfleet-0.2.0/src/marshal_engine/backends/codex.py +201 -0
  62. marshalfleet-0.2.0/src/marshal_engine/backends/command_code.py +206 -0
  63. marshalfleet-0.2.0/src/marshal_engine/backends/cursor.py +620 -0
  64. marshalfleet-0.2.0/src/marshal_engine/backends/goose.py +442 -0
  65. marshalfleet-0.2.0/src/marshal_engine/backends/opencode.py +452 -0
  66. marshalfleet-0.2.0/src/marshal_engine/budgets.py +460 -0
  67. marshalfleet-0.2.0/src/marshal_engine/cli.py +962 -0
  68. marshalfleet-0.2.0/src/marshal_engine/config.py +564 -0
  69. marshalfleet-0.2.0/src/marshal_engine/doctor.py +505 -0
  70. marshalfleet-0.2.0/src/marshal_engine/eastrouter.py +290 -0
  71. marshalfleet-0.2.0/src/marshal_engine/env.py +191 -0
  72. marshalfleet-0.2.0/src/marshal_engine/fleet.py +2566 -0
  73. marshalfleet-0.2.0/src/marshal_engine/layout.py +41 -0
  74. marshalfleet-0.2.0/src/marshal_engine/logs.py +87 -0
  75. marshalfleet-0.2.0/src/marshal_engine/mcp_server.py +867 -0
  76. marshalfleet-0.2.0/src/marshal_engine/py.typed +0 -0
  77. marshalfleet-0.2.0/src/marshal_engine/registry.py +41 -0
  78. marshalfleet-0.2.0/src/marshal_engine/retry.py +88 -0
  79. marshalfleet-0.2.0/src/marshal_engine/scaffold.py +147 -0
  80. marshalfleet-0.2.0/src/marshal_engine/service.py +979 -0
  81. marshalfleet-0.2.0/src/marshal_engine/state.py +303 -0
  82. marshalfleet-0.2.0/src/marshal_engine/teams.py +680 -0
  83. marshalfleet-0.2.0/src/marshal_engine/types.py +209 -0
  84. marshalfleet-0.2.0/src/marshal_engine/usage.py +429 -0
  85. marshalfleet-0.2.0/src/marshal_engine/workflow.py +479 -0
  86. marshalfleet-0.2.0/src/marshal_engine/workspaces.py +767 -0
  87. marshalfleet-0.2.0/src/marshal_engine/worktree.py +710 -0
  88. marshalfleet-0.2.0/tests/conftest.py +47 -0
  89. marshalfleet-0.2.0/tests/test_antigravity.py +86 -0
  90. marshalfleet-0.2.0/tests/test_antigravity_backend.py +742 -0
  91. marshalfleet-0.2.0/tests/test_backend_contract.py +112 -0
  92. marshalfleet-0.2.0/tests/test_base_run.py +382 -0
  93. marshalfleet-0.2.0/tests/test_budgets.py +553 -0
  94. marshalfleet-0.2.0/tests/test_cancel.py +197 -0
  95. marshalfleet-0.2.0/tests/test_ci_workflows.py +207 -0
  96. marshalfleet-0.2.0/tests/test_claude_code_backend.py +224 -0
  97. marshalfleet-0.2.0/tests/test_cli.py +1122 -0
  98. marshalfleet-0.2.0/tests/test_client_env.py +165 -0
  99. marshalfleet-0.2.0/tests/test_codex_backend.py +199 -0
  100. marshalfleet-0.2.0/tests/test_command_code_backend.py +272 -0
  101. marshalfleet-0.2.0/tests/test_config.py +626 -0
  102. marshalfleet-0.2.0/tests/test_cursor_backend.py +772 -0
  103. marshalfleet-0.2.0/tests/test_docs_sync.py +162 -0
  104. marshalfleet-0.2.0/tests/test_doctor.py +627 -0
  105. marshalfleet-0.2.0/tests/test_eastrouter.py +273 -0
  106. marshalfleet-0.2.0/tests/test_edge_cases.py +469 -0
  107. marshalfleet-0.2.0/tests/test_env.py +522 -0
  108. marshalfleet-0.2.0/tests/test_fleet.py +4819 -0
  109. marshalfleet-0.2.0/tests/test_goose_backend.py +388 -0
  110. marshalfleet-0.2.0/tests/test_invariants.py +352 -0
  111. marshalfleet-0.2.0/tests/test_logs.py +94 -0
  112. marshalfleet-0.2.0/tests/test_mcp_server.py +809 -0
  113. marshalfleet-0.2.0/tests/test_opencode_backend.py +586 -0
  114. marshalfleet-0.2.0/tests/test_retry.py +105 -0
  115. marshalfleet-0.2.0/tests/test_run_many_then.py +414 -0
  116. marshalfleet-0.2.0/tests/test_service.py +1476 -0
  117. marshalfleet-0.2.0/tests/test_skills.py +54 -0
  118. marshalfleet-0.2.0/tests/test_state.py +354 -0
  119. marshalfleet-0.2.0/tests/test_teams.py +680 -0
  120. marshalfleet-0.2.0/tests/test_teams_service.py +379 -0
  121. marshalfleet-0.2.0/tests/test_usage.py +496 -0
  122. marshalfleet-0.2.0/tests/test_workflow.py +525 -0
  123. marshalfleet-0.2.0/tests/test_workflow_service.py +117 -0
  124. marshalfleet-0.2.0/tests/test_workspaces.py +1595 -0
  125. marshalfleet-0.2.0/tests/test_worktree.py +951 -0
  126. marshalfleet-0.2.0/uv.lock +1243 -0
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "marshal",
3
+ "description": "Marshal: run a fleet of headless coding agents in parallel, each isolated in its own git worktree, with per-provider cost tracking and measured routing benchmarks.",
4
+ "owner": {
5
+ "name": "chiruu12",
6
+ "url": "https://github.com/chiruu12"
7
+ },
8
+ "plugins": [
9
+ {
10
+ "name": "marshal",
11
+ "source": "./",
12
+ "description": "Drive a fleet of headless coding agents (Cursor, OpenCode, Codex, Antigravity, Claude Code, Command Code, Goose) from one driver: parallel git-worktree isolation, per-provider cost tracking, and measured routing benchmarks. Bundles the marshal-orchestrate, marshal-benchmark, marshal-workflow, marshal-review-gate, marshal-plan-consensus, and marshal-adversarial-review skills and the Marshal MCP server (see docs/mcp-tools.md; multi-workspace).",
13
+ "version": "0.2.0",
14
+ "license": "MIT",
15
+ "homepage": "https://github.com/chiruu12/marshal",
16
+ "keywords": [
17
+ "ai",
18
+ "coding-agents",
19
+ "orchestration",
20
+ "mcp",
21
+ "cost-tracking"
22
+ ]
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "marshal",
3
+ "version": "0.2.0",
4
+ "description": "The control plane for AI coding agents. Drive a fleet of headless workers (Cursor, OpenCode, Codex, Antigravity, Claude Code, Command Code, Goose) from one driver: each task runs isolated in its own git worktree, in parallel, with per-provider cost tracking and measured routing benchmarks. Bundles the marshal-orchestrate, marshal-benchmark, marshal-workflow, marshal-review-gate, marshal-plan-consensus, and marshal-adversarial-review skills plus the Marshal MCP server (see docs/mcp-tools.md; multi-workspace: one server drives several repos, registered in ~/.marshal/workspaces.yaml).",
5
+ "author": {
6
+ "name": "chiruu12",
7
+ "url": "https://github.com/chiruu12"
8
+ },
9
+ "homepage": "https://github.com/chiruu12/marshal",
10
+ "repository": "https://github.com/chiruu12/marshal",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "ai",
14
+ "coding-agents",
15
+ "orchestration",
16
+ "mcp",
17
+ "fleet",
18
+ "cost-tracking",
19
+ "cursor",
20
+ "opencode",
21
+ "codex",
22
+ "antigravity",
23
+ "claude-code"
24
+ ],
25
+ "mcpServers": {
26
+ "marshal": {
27
+ "command": "uv",
28
+ "args": [
29
+ "run",
30
+ "--project",
31
+ "${CLAUDE_PLUGIN_ROOT}",
32
+ "--extra",
33
+ "mcp",
34
+ "marshal",
35
+ "mcp"
36
+ ]
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,71 @@
1
+ name: Bug report
2
+ description: Report a problem with Marshal
3
+ labels: ["bug"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thanks for filing a bug. Please do **not** report security vulnerabilities here - see SECURITY.md.
9
+ - type: input
10
+ id: version
11
+ attributes:
12
+ label: Marshal version / commit
13
+ description: Output of `uv run marshal --version` or the git commit SHA.
14
+ validations:
15
+ required: true
16
+ - type: input
17
+ id: environment
18
+ attributes:
19
+ label: OS and Python version
20
+ placeholder: "e.g. macOS 14.5, Python 3.12.11"
21
+ validations:
22
+ required: true
23
+ - type: dropdown
24
+ id: backend
25
+ attributes:
26
+ label: Which backend(s)?
27
+ multiple: true
28
+ options:
29
+ - cursor
30
+ - opencode
31
+ - codex
32
+ - antigravity
33
+ - claude-code
34
+ - not backend-specific
35
+ validations:
36
+ required: true
37
+ - type: input
38
+ id: auth
39
+ attributes:
40
+ label: How is that backend authenticated?
41
+ placeholder: "e.g. opencode auth login / codex login / OPENAI_API_KEY env"
42
+ - type: textarea
43
+ id: doctor
44
+ attributes:
45
+ label: Output of `uv run marshal doctor`
46
+ render: text
47
+ - type: textarea
48
+ id: config
49
+ attributes:
50
+ label: fleet.config.yaml (redact any secrets / client names you don't want public)
51
+ render: yaml
52
+ - type: textarea
53
+ id: repro
54
+ attributes:
55
+ label: Steps to reproduce
56
+ placeholder: |
57
+ 1. ...
58
+ 2. ...
59
+ validations:
60
+ required: true
61
+ - type: textarea
62
+ id: expected_actual
63
+ attributes:
64
+ label: Expected vs actual behavior
65
+ validations:
66
+ required: true
67
+ - type: textarea
68
+ id: logs
69
+ attributes:
70
+ label: Relevant logs / error output
71
+ render: text
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Security vulnerability
4
+ url: https://github.com/chiruu12/marshal/security/advisories/new
5
+ about: Report security issues privately. Do not open a public issue. See SECURITY.md.
@@ -0,0 +1,40 @@
1
+ name: Feature request
2
+ description: Suggest an improvement or new capability
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: Problem
9
+ description: What are you trying to do, and what's getting in the way?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: proposal
14
+ attributes:
15
+ label: Proposed solution
16
+ validations:
17
+ required: true
18
+ - type: textarea
19
+ id: alternatives
20
+ attributes:
21
+ label: Alternatives considered
22
+ - type: dropdown
23
+ id: area
24
+ attributes:
25
+ label: Area
26
+ options:
27
+ - new backend adapter
28
+ - MCP tool surface
29
+ - usage / cost tracking
30
+ - benchmark / report
31
+ - worktree / integrate
32
+ - CLI
33
+ - docs
34
+ - other
35
+ validations:
36
+ required: true
37
+ - type: textarea
38
+ id: context
39
+ attributes:
40
+ label: Additional context
@@ -0,0 +1,23 @@
1
+ version: 2
2
+ updates:
3
+ # GitHub Actions used by the CI/release workflows.
4
+ - package-ecosystem: "github-actions"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "weekly"
8
+ commit-message:
9
+ prefix: "ci"
10
+ groups:
11
+ actions:
12
+ patterns: ["*"]
13
+
14
+ # Python dependencies, resolved from pyproject.toml + uv.lock.
15
+ - package-ecosystem: "uv"
16
+ directory: "/"
17
+ schedule:
18
+ interval: "weekly"
19
+ commit-message:
20
+ prefix: "deps"
21
+ groups:
22
+ python:
23
+ patterns: ["*"]
@@ -0,0 +1,16 @@
1
+ ## Summary
2
+
3
+ <!-- One line describing WHAT this change ships (not how, not iteration history). -->
4
+
5
+ ## Details
6
+
7
+ <!-- What changed and why, if not obvious from the summary. -->
8
+
9
+ ## Checklist
10
+
11
+ - [ ] Ran the gate locally: `uv run pytest -q && uv run ruff check src tests && uv run mypy`
12
+ - [ ] Updated docs (`README.md` / `docs/` / `CLAUDE.md`) if behavior changed
13
+ - [ ] Added a `## [Unreleased]` entry to `CHANGELOG.md`
14
+ - [ ] No internal process / planning notes / cost figures in commits, PR text, or docs
15
+ - [ ] **New backend?** Added contract tests for `build_invocation` and `map_permission`, and
16
+ registered the factory in `registry.py`
@@ -0,0 +1,49 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ concurrency:
10
+ group: ci-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ gate:
18
+ name: gate (${{ matrix.os }} py${{ matrix.python-version }})
19
+ runs-on: ${{ matrix.os }}
20
+ strategy:
21
+ fail-fast: false
22
+ matrix:
23
+ os: ["ubuntu-latest"]
24
+ python-version: ["3.11", "3.12", "3.13"]
25
+ # Also exercise the POSIX process-group logic (killpg / start_new_session / worktrees) on
26
+ # macOS, the platform Marshal is developed on, for one Python version.
27
+ include:
28
+ - os: "macos-latest"
29
+ python-version: "3.12"
30
+ steps:
31
+ - uses: actions/checkout@v7
32
+
33
+ - name: Install uv
34
+ uses: astral-sh/setup-uv@v9.0.0
35
+ with:
36
+ python-version: ${{ matrix.python-version }}
37
+ enable-cache: true
38
+
39
+ - name: Sync dependencies
40
+ run: uv sync --frozen --extra mcp --extra dev
41
+
42
+ - name: Tests (with coverage gate)
43
+ run: uv run pytest -q --cov=marshal_engine --cov-report=term-missing --cov-fail-under=90
44
+
45
+ - name: Lint (ruff)
46
+ run: uv run ruff check src tests
47
+
48
+ - name: Type-check (mypy strict)
49
+ run: uv run mypy
@@ -0,0 +1,108 @@
1
+ name: Release
2
+
3
+ # Publish to PyPI only when a GitHub Release is published, or via manual
4
+ # workflow_dispatch. Never on push to a branch / tag.
5
+ #
6
+ # Maintainer setup (one-time) for PyPI Trusted Publishing (OIDC) — no API token:
7
+ # 1. Create a GitHub Environment named `PYPI` on this repo AND configure protection
8
+ # rules (required reviewers, deployment branches limited to `v*` tags).
9
+ # Treat this as REQUIRED, not optional. `workflow_dispatch` runs the workflow
10
+ # file as it exists ON THE SELECTED REF, so the tag/version guard below — and
11
+ # the gate above it — can be edited away on an attacker-controlled branch. PyPI
12
+ # validates the workflow *filename* and environment, never the step contents.
13
+ # Environment protection is the only gate that lives outside the ref being built.
14
+ # 2. On https://pypi.org/manage/account/publishing/ (or the project’s Publishing
15
+ # settings once it exists), add a Trusted Publisher:
16
+ # PyPI project name: MarshalFleet # must equal [project].name in pyproject.toml
17
+ # Owner: chiruu12
18
+ # Repository: marshal
19
+ # Workflow: release.yml
20
+ # Environment: PYPI
21
+ # 3. First upload can create the project if you registered a *pending* publisher
22
+ # before the name exists. Confirm the name is still free (or switch
23
+ # pyproject `[project].name` to the fallback) before cutting the first release.
24
+
25
+ on:
26
+ release:
27
+ types: [published]
28
+ workflow_dispatch:
29
+
30
+ permissions:
31
+ contents: read
32
+ id-token: write # required for PyPI Trusted Publishing (OIDC)
33
+
34
+ # A PyPI version can never be replaced, so two runs racing the same upload is not a retry - it is
35
+ # one confusing partial failure. Never cancel in progress: killing a run mid-upload is worse.
36
+ concurrency:
37
+ group: release-${{ github.ref }}
38
+ cancel-in-progress: false
39
+
40
+ jobs:
41
+ release:
42
+ runs-on: ubuntu-latest
43
+ environment:
44
+ # MUST match the GitHub Environment name EXACTLY - they are case-sensitive, and a mismatch
45
+ # silently resolves to a different (non-existent) environment, so its protection rules would
46
+ # not apply and its secrets would not be in scope. The configured environment is `PYPI`.
47
+ name: PYPI
48
+ url: https://pypi.org/p/MarshalFleet
49
+ steps:
50
+ # Every action in this job is pinned by commit SHA. The job holds `id-token: write`, so any
51
+ # step in it can reach the publishing credential - a mutable tag anywhere here is a way in.
52
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
53
+
54
+ - name: Install uv
55
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
56
+ with:
57
+ python-version: "3.12"
58
+ enable-cache: true
59
+
60
+ - name: Gate
61
+ run: |
62
+ uv sync --frozen --extra mcp --extra dev
63
+ uv run pytest -q --cov=marshal_engine --cov-fail-under=90 && uv run ruff check src tests && uv run mypy
64
+
65
+ - name: Build sdist + wheel
66
+ run: uv build
67
+
68
+ # A publish is irreversible: PyPI never lets a version be replaced. `workflow_dispatch` lets
69
+ # a maintainer pick ANY ref, so without this a mis-selected branch publishes whatever it
70
+ # happens to contain under whatever version it happens to declare. Refuse unless the ref is a
71
+ # tag and the built version is exactly that tag - which also catches the far likelier mistake
72
+ # of cutting a release without bumping `[project].version`.
73
+ - name: Refuse to publish a ref whose version is not the tag
74
+ # A git tag may legally contain shell metacharacters, so `github.ref_name` reaches the
75
+ # script through `env` and is only ever read as "$TAG". Interpolating it into the script
76
+ # body would let a crafted tag run commands here - in a job holding `id-token: write`,
77
+ # before this very check.
78
+ env:
79
+ TAG: ${{ github.ref_name }}
80
+ REF_TYPE: ${{ github.ref_type }}
81
+ run: |
82
+ set -euo pipefail
83
+ if [ "$REF_TYPE" != "tag" ]; then
84
+ echo "::error::refusing to publish from $REF_TYPE '$TAG' - release from a tag"
85
+ exit 1
86
+ fi
87
+ # Read the version off the BUILT WHEEL, not the source tree. hatchling builds from
88
+ # `[project].version` in pyproject.toml, so checking `marshal_engine.__version__` would
89
+ # verify a value the artifact does not necessarily carry: if the two drift, the guard
90
+ # passes while PyPI receives a different version than the tag claims.
91
+ wheel="$(ls dist/*.whl)"
92
+ version="$(basename "$wheel" | cut -d- -f2)"
93
+ if [ -z "$version" ]; then
94
+ echo "::error::could not read a version from the built wheel '$wheel'"
95
+ exit 1
96
+ fi
97
+ if [ "$TAG" != "v$version" ] && [ "$TAG" != "$version" ]; then
98
+ echo "::error::tag '$TAG' does not match built version '$version' - bump [project].version or retag"
99
+ exit 1
100
+ fi
101
+ echo "publishing $version from tag $TAG"
102
+
103
+ - name: Publish to PyPI
104
+ # OIDC trusted publishing — do not add password / API-token secrets.
105
+ # Pinned to a commit SHA, not the `v1.14.0` tag: a tag is mutable, and this step runs in a
106
+ # job holding `id-token: write`, so whatever it resolves to can publish as us. Bump the SHA
107
+ # and the trailing version comment together.
108
+ uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1
@@ -0,0 +1,58 @@
1
+ # OS
2
+ .DS_Store
3
+
4
+ # Dependencies
5
+ node_modules/
6
+ .venv/
7
+ __pycache__/
8
+ *.pyc
9
+
10
+ # Build
11
+ dist/
12
+ build/
13
+ .next/
14
+ .turbo/
15
+
16
+ # Environment
17
+ .env
18
+ .env.local
19
+ .env.*.local
20
+
21
+ # IDE
22
+ .idea/
23
+ .vscode/settings.json
24
+ *.swp
25
+ *.swo
26
+
27
+ # Claude Code (local tooling - the public driver Skills live in skills/, not here)
28
+ .context/
29
+ .claude/
30
+ .commandcode/
31
+ tmp/
32
+
33
+ # Internal notes - strategy / decisions / plans, kept local, not part of the public docs set
34
+ docs/internal/
35
+
36
+ # Python
37
+ .ruff_cache/
38
+ .pytest_cache/
39
+ .mypy_cache/
40
+ .coverage
41
+ *.egg-info/
42
+
43
+ # A user's real fleet config (copied from fleet.config.example.yaml) - never commit it
44
+ fleet.config.yaml
45
+
46
+ # A user's own workflow recipes (they reference local client names). Templates ship in
47
+ # examples/workflows/; user recipes live in the repo-root workflows/, local-only.
48
+ /workflows/
49
+
50
+ # Marshal runtime state (worktrees, fleet.json, usage)
51
+ .marshal/
52
+
53
+ # Live agent-run artifacts + playground (review locally, don't commit)
54
+ marshal-runs/
55
+
56
+ # Local dogfood review panels (they reference clients from the gitignored fleet.config.yaml).
57
+ # Shareable starters live in examples/teams/.
58
+ teams/
@@ -0,0 +1 @@
1
+ 3.12