oacp-cli 0.2.2__tar.gz → 0.3.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.
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/CHANGELOG.md +23 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/PKG-INFO +6 -6
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/README.md +5 -5
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/SPEC.md +62 -3
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/guides/runtime_capability_matrix.md +28 -16
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/oacp/cli.py +2 -1
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/pyproject.toml +2 -1
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/memory_cli.py +91 -7
- oacp_cli-0.3.0/scripts/memory_sync.py +547 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/oacp_doctor.py +427 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/oacp_watch.py +95 -16
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/setup_runtime.py +159 -2
- oacp_cli-0.3.0/tests/test_memory_archive.py +443 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_oacp_doctor.py +106 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_oacp_watch.py +217 -6
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_setup_runtime.py +57 -0
- oacp_cli-0.2.2/tests/test_memory_archive.py +0 -222
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/.github/workflows/ci.yml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/.github/workflows/release.yml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/.gitignore +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/CONTRIBUTING.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/LICENSE +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/Makefile +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/QUICKSTART.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/SECURITY.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/guides/adoption.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/guides/doctor.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/guides/prompt_caching.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/guides/setup.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/guides/unified_skill_spec.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/guides/versioning.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/agent_profiles.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/agent_safety_defaults.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/credential_scoping.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/cross_runtime_sync.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/dispatch_states.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/inbox_outbox.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/mcp_integration.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/multi_agent_shared_workspace.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/org_memory.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/packet_states.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/review_loop.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/runtime_capabilities.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/session_init.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/skills_manifest.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/docs/protocol/task_negotiation.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/examples/quickstart/README.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/mcp_servers/oacp_coordinator.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/oacp/__init__.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/_oacp_constants.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/_oacp_env.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/add_agent.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/agent_profile.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/check_quality_gate.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/codex_session_init.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/create_handoff_packet.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/handoff_schema.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/init_org_memory.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/init_packet.sh +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/init_project_workspace.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/init_project_workspace.sh +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/memory_archive_common.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/normalize_findings.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/oacp_inbox.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/preflight.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/promote_to_archive.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/restore_from_archive.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/send_inbox_message.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/session_lifecycle_hooks.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/update_workspace.sh +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/validate_agent_card.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/validate_message.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/scripts/write_event.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/agent_card.template.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/agent_profile.template.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/agent_status.template.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/checkpoint.template.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/claude/agents/role_agent.template.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/claude/rules/guardrail.template.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/findings_packet.template.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/github_actions_quality_gate.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/guardrails/coding_standards.template.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/guardrails/safe_commands.template.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/guardrails/secrets_rules.template.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/handoff_packet.template.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/inbox_message.template.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/manual_validation.template.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/merge_decision.template.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/org-memory/decisions.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/org-memory/events/.gitkeep +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/org-memory/events/20260317-170120-example-api-convention.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/org-memory/recent.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/org-memory/rules.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/review_packet.template.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/roles/role_baseline.template.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/roles/role_definition.template.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/runtime_capabilities.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/skills_manifest.template.yaml +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/templates/test_packet.template.md +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_add_agent.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_agent_profile.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_codex_session_init.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_create_handoff_packet.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_github_workflows.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_handoff_schema.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_init_project_workspace.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_oacp_cli.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_oacp_constants.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_oacp_coordinator.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_oacp_env.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_oacp_inbox.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_preflight.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_review_loop.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_send_inbox_message.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_session_lifecycle_hooks.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_update_workspace.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_validate_agent_card.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_validate_message.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_workspace_discovery.py +0 -0
- {oacp_cli-0.2.2 → oacp_cli-0.3.0}/tests/test_write_event.py +0 -0
|
@@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.3.0] - 2026-04-29
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `oacp memory init|clone|pull|push|disable` subcommands for opt-in cross-machine sync of `$OACP_HOME/org-memory/**` and `$OACP_HOME/projects/*/memory/**` via a plain git repo rooted at `$OACP_HOME`. Three-state activation model: Disabled (no marker), Local-only (`init` without `--remote`), and Synced (`init --remote <url>` or `clone <url>`).
|
|
15
|
+
- `oacp doctor --memory` advisory checks (10 checks covering marker presence, allowlist coverage, remote configuration, fetch/divergence state, and signing setup).
|
|
16
|
+
- `oacp setup claude` now installs memory pull/push hook scripts and registers them in `.claude/settings.json` for Claude SessionStart and SessionEnd lifecycle events. Hooks are marker-gated and no-op silently unless `$OACP_HOME/.oacp-memory-repo` is present, so existing workflows are unaffected on machines that have not opted in.
|
|
17
|
+
|
|
18
|
+
## [0.2.3] - 2026-04-26
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- `oacp watch` defaults are now notification-friendly: existing inbox messages are no longer replayed on the first scan for a target, and `message_archived` events are suppressed by default. Pass `--since=epoch` to restore replay and `--show-archived` to re-enable archive events. Reduces noise for `Monitor` and `oacp watch` consumers.
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- `oacp watch --since=<spec>` — controls the first-run baseline cutoff. Accepts `now` (default), `epoch`, relative durations (`30s`, `5m`, `2h`, `7d`), or ISO 8601 timestamps. Only applies on first run for a target (no state file yet).
|
|
27
|
+
- `oacp watch --show-archived` — opt-in flag to emit `message_archived` events. Useful for observer agents tracking another agent's inbox; disabled by default because the watching agent's own deletes are self-loops.
|
|
28
|
+
|
|
8
29
|
## [0.2.2] - 2026-04-17
|
|
9
30
|
|
|
10
31
|
### Added
|
|
@@ -110,6 +131,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
110
131
|
- Checkout step in github-release workflow job (#19)
|
|
111
132
|
- Pre-release audit fixes: SHA-pinned actions, dangling doc refs (#15, #16)
|
|
112
133
|
|
|
134
|
+
[0.3.0]: https://github.com/kiloloop/oacp/compare/v0.2.3...v0.3.0
|
|
135
|
+
[0.2.3]: https://github.com/kiloloop/oacp/compare/v0.2.2...v0.2.3
|
|
113
136
|
[0.2.2]: https://github.com/kiloloop/oacp/compare/v0.2.1...v0.2.2
|
|
114
137
|
[0.2.1]: https://github.com/kiloloop/oacp/compare/v0.2.0...v0.2.1
|
|
115
138
|
[0.2.0]: https://github.com/kiloloop/oacp/compare/v0.1.9...v0.2.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: oacp-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Open Agent Coordination Protocol CLI for file-based multi-agent workflows
|
|
5
5
|
Project-URL: Homepage, https://github.com/kiloloop/oacp
|
|
6
6
|
Project-URL: Repository, https://github.com/kiloloop/oacp
|
|
@@ -152,7 +152,7 @@ uv tool install .
|
|
|
152
152
|
| `oacp send` | Send a protocol-compliant inbox message (`--from` auto-inferred) |
|
|
153
153
|
| `oacp inbox` | List pending messages across agents (table or `--json`) |
|
|
154
154
|
| `oacp watch` | Emit inbox delta events for one agent across selected projects |
|
|
155
|
-
| `oacp memory` | Archive or
|
|
155
|
+
| `oacp memory` | Archive, restore, or git-sync project/org memory files |
|
|
156
156
|
| `oacp agent` | Manage global agent profiles (`init`, `show`, `list`) |
|
|
157
157
|
| `oacp org-memory` | Initialize org-level memory at `$OACP_HOME/org-memory/` |
|
|
158
158
|
| `oacp write-event` | Write an event to `org-memory/events/` |
|
|
@@ -165,11 +165,11 @@ uv tool install .
|
|
|
165
165
|
|
|
166
166
|
**`oacp send`**: `--in-reply-to`, `--expires`, `--body-file`, `--channel`, `--dry-run`, `--json`, `--quiet`
|
|
167
167
|
|
|
168
|
-
**`oacp watch`**: `--agent`, repeatable `--project`, `--all-projects`, `--json`
|
|
168
|
+
**`oacp watch`**: `--agent`, repeatable `--project`, `--all-projects`, `--json`, `--since` (default `now`), `--show-archived`
|
|
169
169
|
|
|
170
|
-
**`oacp doctor`**: `--fix` (auto-fix safe issues), `--json`, `-o/--output`
|
|
170
|
+
**`oacp doctor`**: `--fix` (auto-fix safe issues), `--memory`, `--json`, `-o/--output`
|
|
171
171
|
|
|
172
|
-
**`oacp memory`**: `
|
|
172
|
+
**`oacp memory`**: `init [--remote URL]`, `clone <URL> [--force]`, `pull`, `push`, `disable`, `archive <project> <file>`, `restore <project> <file>`
|
|
173
173
|
|
|
174
174
|
</details>
|
|
175
175
|
|
|
@@ -182,7 +182,7 @@ If `OACP_HOME` is unset, workspace commands default to `~/oacp`.
|
|
|
182
182
|
| **Inbox/Outbox** | Async messaging between agents via YAML files in `agents/<name>/inbox/` |
|
|
183
183
|
| **Review Loop** | Structured code review: `review_request` → `review_feedback` → `review_addressed` → `review_lgtm` |
|
|
184
184
|
| **Quality Gate** | Merge-readiness criteria: no unresolved P0/P1 findings, deferred nits tracked |
|
|
185
|
-
| **Durable Memory** | Shared `memory/` directory with an active working set plus `memory/archive/` for historical memory |
|
|
185
|
+
| **Durable Memory** | Shared `memory/` directory with an active working set plus `memory/archive/` for historical memory; optional `$OACP_HOME` git sync tracks only `org-memory/**` and `projects/*/memory/**` |
|
|
186
186
|
| **Dispatch States** | Task lifecycle: `received` → `accepted` → `working` → `pr_opened` → `in_review` → `done` |
|
|
187
187
|
| **Safety Defaults** | Baseline rules all agents follow: no force push, no secrets in commits, stage hygiene |
|
|
188
188
|
|
|
@@ -126,7 +126,7 @@ uv tool install .
|
|
|
126
126
|
| `oacp send` | Send a protocol-compliant inbox message (`--from` auto-inferred) |
|
|
127
127
|
| `oacp inbox` | List pending messages across agents (table or `--json`) |
|
|
128
128
|
| `oacp watch` | Emit inbox delta events for one agent across selected projects |
|
|
129
|
-
| `oacp memory` | Archive or
|
|
129
|
+
| `oacp memory` | Archive, restore, or git-sync project/org memory files |
|
|
130
130
|
| `oacp agent` | Manage global agent profiles (`init`, `show`, `list`) |
|
|
131
131
|
| `oacp org-memory` | Initialize org-level memory at `$OACP_HOME/org-memory/` |
|
|
132
132
|
| `oacp write-event` | Write an event to `org-memory/events/` |
|
|
@@ -139,11 +139,11 @@ uv tool install .
|
|
|
139
139
|
|
|
140
140
|
**`oacp send`**: `--in-reply-to`, `--expires`, `--body-file`, `--channel`, `--dry-run`, `--json`, `--quiet`
|
|
141
141
|
|
|
142
|
-
**`oacp watch`**: `--agent`, repeatable `--project`, `--all-projects`, `--json`
|
|
142
|
+
**`oacp watch`**: `--agent`, repeatable `--project`, `--all-projects`, `--json`, `--since` (default `now`), `--show-archived`
|
|
143
143
|
|
|
144
|
-
**`oacp doctor`**: `--fix` (auto-fix safe issues), `--json`, `-o/--output`
|
|
144
|
+
**`oacp doctor`**: `--fix` (auto-fix safe issues), `--memory`, `--json`, `-o/--output`
|
|
145
145
|
|
|
146
|
-
**`oacp memory`**: `
|
|
146
|
+
**`oacp memory`**: `init [--remote URL]`, `clone <URL> [--force]`, `pull`, `push`, `disable`, `archive <project> <file>`, `restore <project> <file>`
|
|
147
147
|
|
|
148
148
|
</details>
|
|
149
149
|
|
|
@@ -156,7 +156,7 @@ If `OACP_HOME` is unset, workspace commands default to `~/oacp`.
|
|
|
156
156
|
| **Inbox/Outbox** | Async messaging between agents via YAML files in `agents/<name>/inbox/` |
|
|
157
157
|
| **Review Loop** | Structured code review: `review_request` → `review_feedback` → `review_addressed` → `review_lgtm` |
|
|
158
158
|
| **Quality Gate** | Merge-readiness criteria: no unresolved P0/P1 findings, deferred nits tracked |
|
|
159
|
-
| **Durable Memory** | Shared `memory/` directory with an active working set plus `memory/archive/` for historical memory |
|
|
159
|
+
| **Durable Memory** | Shared `memory/` directory with an active working set plus `memory/archive/` for historical memory; optional `$OACP_HOME` git sync tracks only `org-memory/**` and `projects/*/memory/**` |
|
|
160
160
|
| **Dispatch States** | Task lifecycle: `received` → `accepted` → `working` → `pr_opened` → `in_review` → `done` |
|
|
161
161
|
| **Safety Defaults** | Baseline rules all agents follow: no force push, no secrets in commits, stage hygiene |
|
|
162
162
|
|
|
@@ -16,7 +16,7 @@ OACP is not a framework or SDK. It is a set of conventions, YAML schemas, and sh
|
|
|
16
16
|
3. [Review Loop Protocol](#3-review-loop-protocol)
|
|
17
17
|
4. [Cross-Runtime Sync](#4-cross-runtime-sync)
|
|
18
18
|
5. [Agent Safety Defaults](#5-agent-safety-defaults)
|
|
19
|
-
6. [Org-Level Memory](#6-org-level-memory)
|
|
19
|
+
6. [Org-Level Memory and Sync](#6-org-level-memory-and-sync)
|
|
20
20
|
7. [Kernel Script Inventory](#7-kernel-script-inventory)
|
|
21
21
|
|
|
22
22
|
---
|
|
@@ -451,7 +451,7 @@ Agents operate under least-privilege credentials:
|
|
|
451
451
|
|
|
452
452
|
---
|
|
453
453
|
|
|
454
|
-
## 6. Org-Level Memory
|
|
454
|
+
## 6. Org-Level Memory and Sync
|
|
455
455
|
|
|
456
456
|
Full specification: [`docs/protocol/org_memory.md`](docs/protocol/org_memory.md)
|
|
457
457
|
|
|
@@ -459,6 +459,16 @@ Full specification: [`docs/protocol/org_memory.md`](docs/protocol/org_memory.md)
|
|
|
459
459
|
|
|
460
460
|
Shared, cross-project memory for multi-agent organizations. Agents across projects read org-wide decisions, conventions, and events from a single location. Complements per-project memory — does not replace it.
|
|
461
461
|
|
|
462
|
+
OACP can optionally sync curated memory across machines using one plain git
|
|
463
|
+
repository rooted at `$OACP_HOME`. This feature is opt-in and tracks only:
|
|
464
|
+
|
|
465
|
+
- `$OACP_HOME/org-memory/**`
|
|
466
|
+
- `$OACP_HOME/projects/<project>/memory/**`
|
|
467
|
+
|
|
468
|
+
Cross-machine inbox delivery, `agents/` runtime state, `status.yaml`, concurrent
|
|
469
|
+
writer protocols, encrypted transport, and runtime-specific memory outside
|
|
470
|
+
`$OACP_HOME` are out of scope.
|
|
471
|
+
|
|
462
472
|
### Directory Structure
|
|
463
473
|
|
|
464
474
|
```
|
|
@@ -470,6 +480,28 @@ $OACP_HOME/org-memory/
|
|
|
470
480
|
└── YYYYMMDD-HHMMSS-short-slug.md
|
|
471
481
|
```
|
|
472
482
|
|
|
483
|
+
When memory sync is enabled, `$OACP_HOME` also contains:
|
|
484
|
+
|
|
485
|
+
```text
|
|
486
|
+
$OACP_HOME/
|
|
487
|
+
├── .gitignore # positive allowlist
|
|
488
|
+
├── .oacp-memory-repo # tracked marker; activates hooks
|
|
489
|
+
├── org-memory/ # tracked
|
|
490
|
+
└── projects/*/memory/ # tracked
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
Canonical root `.gitignore`:
|
|
494
|
+
|
|
495
|
+
```gitignore
|
|
496
|
+
*
|
|
497
|
+
!*/
|
|
498
|
+
!.gitignore
|
|
499
|
+
!.oacp-memory-repo
|
|
500
|
+
!org-memory/**
|
|
501
|
+
!projects/*/memory/**
|
|
502
|
+
projects/*/memory/.cache/
|
|
503
|
+
```
|
|
504
|
+
|
|
473
505
|
### Key Concepts
|
|
474
506
|
|
|
475
507
|
- **`recent.md`** is the always-loaded cross-project context. Agents read it at session start via session-init hooks. Kept concise (~150 lines) as a rolling summary of current state, not full history.
|
|
@@ -506,11 +538,37 @@ Agents write events only (append-only). The coordinator curates topical files an
|
|
|
506
538
|
|
|
507
539
|
- **`oacp org-memory init`** — scaffold `$OACP_HOME/org-memory/` with default files
|
|
508
540
|
- **`oacp write-event`** — create an event file with proper frontmatter
|
|
541
|
+
- **`oacp memory init [--remote URL]`** — initialize the `$OACP_HOME` memory git repo, marker, canonical allowlist, optional remote, and initial commit
|
|
542
|
+
- **`oacp memory clone <URL> [--force]`** — clone a memory repo into `$OACP_HOME`; refuses non-empty targets unless `--force` moves the existing directory aside
|
|
543
|
+
- **`oacp memory pull`** — advisory fetch plus fast-forward-only pull; warns loudly on dirty, ahead, behind, diverged, or fetch-failed states and never auto-merges
|
|
544
|
+
- **`oacp memory push`** — stages only the memory allowlist, commits as `memory: <agent>@<host> <date> (N files)`, then pushes when a remote is configured
|
|
545
|
+
- **`oacp memory disable`** — removes `.oacp-memory-repo` locally while leaving `.git/` intact
|
|
546
|
+
- **`oacp doctor --memory`** — runs advisory memory sync checks for marker state, allowlist drift, tracked/untracked leakage, clean/ahead/behind/diverged state, remote reachability, commit staleness, `agents/` leakage, and per-project memory overlay safety
|
|
509
547
|
|
|
510
548
|
### Integration with Session Init
|
|
511
549
|
|
|
512
550
|
Agents can read `org-memory/recent.md` at session start for cross-project context. This integration is runtime-specific — for example, Claude Code loads it via a session-init hook, while other runtimes may read it explicitly. Topical files and `events/` are available for on-demand reading when agents need deeper org context.
|
|
513
551
|
|
|
552
|
+
Memory sync has three activation states:
|
|
553
|
+
|
|
554
|
+
| State | Trigger | Behavior |
|
|
555
|
+
|-------|---------|----------|
|
|
556
|
+
| Disabled | No `.oacp-memory-repo` marker | Hooks no-op silently; `oacp doctor --memory` reports not configured |
|
|
557
|
+
| Local-only | `oacp memory init` | Wrap-up commits memory locally for audit history; no push |
|
|
558
|
+
| Synced | `oacp memory init --remote URL` or `oacp memory clone <URL>` | Session start pulls fast-forward updates; wrap-up commits and pushes |
|
|
559
|
+
|
|
560
|
+
Lifecycle hooks must check for `$OACP_HOME/.oacp-memory-repo` first and exit
|
|
561
|
+
without output when it is absent. Claude runtime setup installs hook scripts for
|
|
562
|
+
`SessionStart` pull and wrap-up/session-end push:
|
|
563
|
+
|
|
564
|
+
1. Session start runs `oacp memory pull`. It exits advisory-successfully, pulls
|
|
565
|
+
only clean behind states with `--ff-only`, and warns loudly when memory is
|
|
566
|
+
dirty, ahead, diverged, behind, or remote fetch fails.
|
|
567
|
+
2. Wrap-up runs `oacp memory push`. It stages only `.gitignore`,
|
|
568
|
+
`.oacp-memory-repo`, `org-memory/**`, and `projects/*/memory/**`; commits
|
|
569
|
+
with the fixed terse message format; pushes when a remote exists; and warns
|
|
570
|
+
loudly when memory is dirty, behind, diverged, or push fails.
|
|
571
|
+
|
|
514
572
|
---
|
|
515
573
|
|
|
516
574
|
## 7. Kernel Script Inventory
|
|
@@ -532,7 +590,8 @@ Scripts marked **CLI** are exposed as `oacp` subcommands. Scripts marked **scrip
|
|
|
532
590
|
| `agent_profile.py` | Two-tier agent profile management | CLI: `oacp agent` |
|
|
533
591
|
| `send_inbox_message.py` | Compose and send inbox messages | CLI: `oacp send` |
|
|
534
592
|
| `oacp_inbox.py` | List pending inbox messages | CLI: `oacp inbox` |
|
|
535
|
-
| `memory_cli.py` | Archive or
|
|
593
|
+
| `memory_cli.py` | Archive, restore, or git-sync project/org memory files | CLI: `oacp memory` |
|
|
594
|
+
| `memory_sync.py` | Shared git allowlist and memory sync helpers | imported by CLI/doctor |
|
|
536
595
|
| `setup_runtime.py` | Generate runtime-specific config files | CLI: `oacp setup` |
|
|
537
596
|
| `init_org_memory.py` | Scaffold org-level memory directory | CLI: `oacp org-memory` |
|
|
538
597
|
| `write_event.py` | Write timestamped events to org-memory | CLI: `oacp write-event` |
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Cross-Runtime Parity Matrix
|
|
2
2
|
|
|
3
|
-
**Date**: 2026-04-
|
|
3
|
+
**Date**: 2026-04-29
|
|
4
4
|
|
|
5
5
|
This is a capability comparison across 3 agent runtimes (Claude Code, Codex, Gemini), compiled from each runtime's self-report and current runtime changelogs. Use this as a reference when deciding which agent to assign for a given task.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Claude was last checked against Claude Code `v2.1.123`.
|
|
8
|
+
|
|
9
|
+
Codex was last checked against app update `26.415`, CLI `0.123.0`, and OpenAI's GPT-5.5 launch note from 2026-04-23.
|
|
8
10
|
|
|
9
11
|
---
|
|
10
12
|
|
|
@@ -15,31 +17,32 @@ Codex was last checked against the official Codex changelog entries for app upda
|
|
|
15
17
|
| Spawn background tasks | Yes — Task tool + Bash `run_in_background` | Yes — shell background processes | Yes — `run_command` async mode |
|
|
16
18
|
| Spawn subagents | Yes — typed agents (Explore, Plan, general-purpose, code-reviewer, etc.) | Yes — native `spawn_agent` lifecycle with `default`, `explorer`, and `worker` agents | Partial — `browser_subagent` only |
|
|
17
19
|
| Parallel agent teams | Yes — TeamCreate, task lists, SendMessage, broadcast | Partial — parallel spawned agents are supported, but there is no team/task-list primitive | No — parallel tool calls but no independent agent instances |
|
|
18
|
-
| MCP tools | Yes — extensible via MCP servers | Yes — MCP/plugin support
|
|
20
|
+
| MCP tools | Yes — extensible via MCP servers | Yes — MCP/plugin support with `/mcp verbose` diagnostics; configuration-dependent | Yes — MCP server support |
|
|
19
21
|
| Web search | Yes — native WebSearch tool | Yes — web search/fetch tools | Yes — native `search_web` tool |
|
|
20
22
|
| Browser interaction | Partial — WebFetch (read-only, HTML→markdown) | Partial — web tools plus early in-app browser for local/public pages without sign-in | Yes — full browser control (click, type, navigate, screenshot, video) |
|
|
21
|
-
| File system access | Sandboxed — configurable read/write allowlists | Policy-dependent per session
|
|
23
|
+
| File system access | Sandboxed — configurable read/write allowlists | Policy-dependent per session; sandbox profiles can include deny-read rules | Full — unrestricted |
|
|
22
24
|
| Git operations | Yes — via Bash (may need sandbox configuration) | Yes — native | Yes — via shell |
|
|
23
25
|
| GitHub CLI (gh) | Yes — via Bash (may need sandbox configuration) | Yes — authenticated | Yes — native |
|
|
24
26
|
| Session memory | Strong — auto-loaded MEMORY.md + optional MCP memory | Partial — app memories where available plus OACP file memory; app memories are not protocol SSOT | Partial — Knowledge Items (not directly writable), conversation logs |
|
|
25
|
-
| Interactive mode | Yes — CLI chat with permissions, plan mode | Yes — desktop app
|
|
26
|
-
| Context window | ~1M with Opus 4.7 (auto-compaction extends indefinitely) |
|
|
27
|
-
| Cost model | Token-based, visible in statusline | Not surfaced
|
|
28
|
-
| Sandbox restrictions | Yes — configurable allowlists | Session-dependent
|
|
27
|
+
| Interactive mode | Yes — CLI chat with permissions, plan mode | Yes — desktop app and CLI/TUI, including Plan Mode and side conversations | Yes — chat with task UI, artifacts |
|
|
28
|
+
| Context window | ~1M with Opus 4.7 (auto-compaction extends indefinitely) | Model-dependent; GPT-5.5 in Codex is documented at 400K, with no auto-compaction guarantee | ~1M tokens |
|
|
29
|
+
| Cost model | Token-based, visible in statusline | Not surfaced per session; GPT-5.5 Fast mode trades 2.5x cost for 1.5x token generation speed | Token-based |
|
|
30
|
+
| Sandbox restrictions | Yes — configurable allowlists | Session-dependent; supports deny-read policies, isolated `codex exec`, and remote sandbox requirements | None — full system access |
|
|
29
31
|
|
|
30
32
|
---
|
|
31
33
|
|
|
32
|
-
## 2.
|
|
34
|
+
## 2. Distinctive Capabilities
|
|
33
35
|
|
|
34
36
|
| Capability | Runtime | Details |
|
|
35
37
|
| -------------------------------- | ------------- | ---------------------------------------------------------------------------- |
|
|
36
38
|
| Typed subagent orchestration | Claude | Multiple agent types with scoped tools and model selection |
|
|
37
39
|
| Team coordination primitive | Claude | TeamCreate + task lists + assignment + broadcast + shutdown |
|
|
38
|
-
| Plan mode | Claude
|
|
40
|
+
| Plan mode | Claude, Codex | Claude has structured explore → plan → approve → implement; Codex CLI can move from planning into fresh-context implementation |
|
|
39
41
|
| Auto-compaction | Claude | Context auto-compresses, enabling unlimited session length |
|
|
40
42
|
| Cross-session semantic search | Claude | MCP-based searchable memory (optional) |
|
|
41
43
|
| Browser automation (full) | Gemini | Click, type, navigate, screenshot, WebP video recording |
|
|
42
|
-
|
|
|
44
|
+
| GPT-5.5 model availability | Codex | Available in Codex for Plus, Pro, Business, Enterprise, Edu, and Go plans with a 400K context window |
|
|
45
|
+
| Image generation | Codex, Gemini | Codex CLI image generation is enabled by default; Gemini has native `generate_image` |
|
|
43
46
|
| URL content reading (no browser) | Gemini | `read_url_content` fetches HTML→markdown or PDF directly |
|
|
44
47
|
| Code outline navigation | Gemini | `view_file_outline`, `view_code_item` for structured exploration |
|
|
45
48
|
| PTY / terminal stdin | Codex, Gemini | Codex: native PTY; Gemini: `send_command_input` (Claude lacks stdin support) |
|
|
@@ -68,9 +71,9 @@ Scope: skills shipped in [`kiloloop/oacp-skills`](https://github.com/kiloloop/oa
|
|
|
68
71
|
|
|
69
72
|
| Dimension | Claude | Codex | Gemini |
|
|
70
73
|
| --------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------- |
|
|
71
|
-
| Best at | Orchestration, multi-agent teams, persistent memory, plan-then-execute | Terminal-native execution, fast iterative patching, app-assisted PR/artifact review, protocol discipline | Web research, browser automation, visual verification, large context |
|
|
72
|
-
| Ideal task type | Team coordination, complex multi-file refactors, long-running sessions | Shell-heavy workflows, targeted file edits, deterministic scripts, PR follow-up, artifact review | External research, UI testing, document review, MCP integrations |
|
|
73
|
-
| Cost profile | Flexible (haiku subagents for cheap tasks, opus for complex) |
|
|
74
|
+
| Best at | Orchestration, multi-agent teams, persistent memory, plan-then-execute | Terminal-native execution, GPT-5.5 agentic coding, fast iterative patching, plan-to-implementation handoff, app-assisted PR/artifact review, protocol discipline | Web research, browser automation, visual verification, large context |
|
|
75
|
+
| Ideal task type | Team coordination, complex multi-file refactors, long-running sessions | Shell-heavy workflows, long-horizon coding, targeted file edits, deterministic scripts, PR follow-up, artifact review, CLI planning passes | External research, UI testing, document review, MCP integrations |
|
|
76
|
+
| Cost profile | Flexible (haiku subagents for cheap tasks, opus for complex) | Per-session cost not visible; GPT-5.5 is described as more token-efficient than GPT-5.4 for Codex tasks | Token-based, web search has additional costs |
|
|
74
77
|
|
|
75
78
|
---
|
|
76
79
|
|
|
@@ -80,11 +83,11 @@ Scope: skills shipped in [`kiloloop/oacp-skills`](https://github.com/kiloloop/oa
|
|
|
80
83
|
| ----------------------------- | ----------------------------- | -------------------------------------------------------------- | ---------------------- |
|
|
81
84
|
| No subagents | — | Yes | Partial (browser only) |
|
|
82
85
|
| No browser automation | Yes (read-only) | Partial (in-app browser is not full automation and excludes sign-in flows) | — |
|
|
83
|
-
| No image generation | Yes |
|
|
86
|
+
| No image generation | Yes | — | — |
|
|
84
87
|
| No persistent writable memory | — | Partial (app memories are not a replacement for OACP durable memory) | Yes |
|
|
85
88
|
| Sandbox friction | Yes (configurable) | Session-dependent | — |
|
|
86
89
|
| No team primitive | — | Yes | Yes |
|
|
87
|
-
| Context limits | Auto-compaction mitigates |
|
|
90
|
+
| Context limits | Auto-compaction mitigates | Model-dependent; GPT-5.5 in Codex is 400K, but there is no documented auto-compaction behavior | Large but finite |
|
|
88
91
|
| No terminal stdin | Yes | — | — |
|
|
89
92
|
| Cost not surfaced | — | Yes | — |
|
|
90
93
|
|
|
@@ -110,6 +113,7 @@ These are the highest-impact gaps where one runtime's limitation blocks effectiv
|
|
|
110
113
|
| Dimension | Claude | Codex | Gemini |
|
|
111
114
|
| ---------------------------- | -------------------------------- | ------------------------------------------ | --------------------------------------------- |
|
|
112
115
|
| Max parallel tool calls | ~10+ | Yes (parallel independent calls) | ~10 (practical) |
|
|
116
|
+
| Side conversations | No | Yes (`/side` in CLI/TUI) | No |
|
|
113
117
|
| Hooks system | Yes (pre/post tool call hooks) | No | No |
|
|
114
118
|
| Automation scheduling | Yes (`CronCreate`, `ScheduleWakeup`, `/loop`, `/schedule` skills) | Yes (desktop app thread automations wake a thread on a schedule, with user request) | No |
|
|
115
119
|
| Notebook editing | Yes (NotebookEdit tool) | No | No |
|
|
@@ -117,6 +121,8 @@ These are the highest-impact gaps where one runtime's limitation blocks effectiv
|
|
|
117
121
|
| Image reading (multimodal) | Yes | Yes (desktop app local image/view support) | Yes |
|
|
118
122
|
| Artifact system | No | Yes (sidebar preview for generated files) | Yes (task.md, implementation plans) |
|
|
119
123
|
| Video recording | No | No | Yes (WebP via browser) |
|
|
124
|
+
| Image generation | No | Yes (enabled by default in CLI) | Yes |
|
|
125
|
+
| MCP diagnostics | Partial | Yes (`/mcp verbose`) | Partial |
|
|
120
126
|
| Multi-file editing primitive | Edit tool (one file at a time) | `apply_patch` (one file) | `multi_replace_file_content` (non-contiguous) |
|
|
121
127
|
| Workflow file format | SKILL.md with YAML frontmatter | SKILL.md with YAML frontmatter | Markdown with YAML frontmatter |
|
|
122
128
|
| Policy visibility at runtime | Partial (sandbox config visible) | Yes (session policy in system context) | Yes (`SafeToAutoRun` flags) |
|
|
@@ -124,4 +130,10 @@ These are the highest-impact gaps where one runtime's limitation blocks effectiv
|
|
|
124
130
|
|
|
125
131
|
---
|
|
126
132
|
|
|
133
|
+
## 8. Source Notes
|
|
134
|
+
|
|
135
|
+
- GPT-5.5 Codex availability, 400K context, Fast mode, token-efficiency, and API timing come from OpenAI's 2026-04-23 release note: <https://openai.com/index/introducing-gpt-5-5/>.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
127
139
|
*Each runtime should update only its own column. Discrepancies should be resolved by the runtime owner.*
|
|
@@ -24,7 +24,7 @@ Commands:
|
|
|
24
24
|
agent Manage global agent profiles (init, show, list)
|
|
25
25
|
inbox List pending inbox messages
|
|
26
26
|
watch Emit inbox delta events for Monitor-friendly polling
|
|
27
|
-
memory Archive or
|
|
27
|
+
memory Archive, restore, or sync memory files
|
|
28
28
|
setup Generate runtime-specific config files in a repo
|
|
29
29
|
send Send a protocol-compliant inbox message
|
|
30
30
|
org-memory Initialize org-level memory at $OACP_HOME/org-memory/
|
|
@@ -38,6 +38,7 @@ Examples:
|
|
|
38
38
|
oacp add-agent my-project alice --runtime claude
|
|
39
39
|
oacp inbox my-project --agent claude
|
|
40
40
|
oacp watch --agent claude --project my-project --json
|
|
41
|
+
oacp memory init --remote git@github.com:<YOUR_ORG>/oacp-memory.git
|
|
41
42
|
oacp memory archive my-project research_notes.md
|
|
42
43
|
oacp setup claude --project my-project
|
|
43
44
|
oacp send my-project --to iris --type notification --subject "Done" --body "Completed"
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "oacp-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Open Agent Coordination Protocol CLI for file-based multi-agent workflows"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -63,6 +63,7 @@ packages = ["oacp"]
|
|
|
63
63
|
"scripts/oacp_inbox.py" = "oacp/_scripts/oacp_inbox.py"
|
|
64
64
|
"scripts/oacp_watch.py" = "oacp/_scripts/oacp_watch.py"
|
|
65
65
|
"scripts/memory_cli.py" = "oacp/_scripts/memory_cli.py"
|
|
66
|
+
"scripts/memory_sync.py" = "oacp/_scripts/memory_sync.py"
|
|
66
67
|
"scripts/memory_archive_common.py" = "oacp/_scripts/memory_archive_common.py"
|
|
67
68
|
"scripts/promote_to_archive.py" = "oacp/_scripts/promote_to_archive.py"
|
|
68
69
|
"scripts/restore_from_archive.py" = "oacp/_scripts/restore_from_archive.py"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# SPDX-FileCopyrightText: 2026 Kiloloop
|
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
"""Namespace CLI for project memory archive/restore operations."""
|
|
4
|
+
"""Namespace CLI for project memory archive/restore and sync operations."""
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
@@ -14,10 +14,56 @@ from typing import Optional, Sequence
|
|
|
14
14
|
def _build_parser() -> argparse.ArgumentParser:
|
|
15
15
|
parser = argparse.ArgumentParser(
|
|
16
16
|
prog="oacp memory",
|
|
17
|
-
description="Archive or
|
|
17
|
+
description="Archive, restore, or sync OACP memory files.",
|
|
18
18
|
)
|
|
19
19
|
sub = parser.add_subparsers(dest="command")
|
|
20
20
|
|
|
21
|
+
init_parser = sub.add_parser("init", help="Initialize git sync at $OACP_HOME")
|
|
22
|
+
init_parser.add_argument(
|
|
23
|
+
"--remote",
|
|
24
|
+
default=None,
|
|
25
|
+
help="Optional git remote URL for cross-machine sync",
|
|
26
|
+
)
|
|
27
|
+
init_parser.add_argument(
|
|
28
|
+
"--oacp-dir",
|
|
29
|
+
default=None,
|
|
30
|
+
help="Override OACP home directory (default: $OACP_HOME or ~/oacp)",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
clone_parser = sub.add_parser("clone", help="Clone a memory repo into $OACP_HOME")
|
|
34
|
+
clone_parser.add_argument("url", help="Git remote URL to clone")
|
|
35
|
+
clone_parser.add_argument(
|
|
36
|
+
"--force",
|
|
37
|
+
action="store_true",
|
|
38
|
+
help="Move a non-empty OACP_HOME aside before cloning",
|
|
39
|
+
)
|
|
40
|
+
clone_parser.add_argument(
|
|
41
|
+
"--oacp-dir",
|
|
42
|
+
default=None,
|
|
43
|
+
help="Override OACP home directory (default: $OACP_HOME or ~/oacp)",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
pull_parser = sub.add_parser("pull", help="Fetch and fast-forward memory sync")
|
|
47
|
+
pull_parser.add_argument(
|
|
48
|
+
"--oacp-dir",
|
|
49
|
+
default=None,
|
|
50
|
+
help="Override OACP home directory (default: $OACP_HOME or ~/oacp)",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
push_parser = sub.add_parser("push", help="Commit allowlisted memory and push")
|
|
54
|
+
push_parser.add_argument(
|
|
55
|
+
"--oacp-dir",
|
|
56
|
+
default=None,
|
|
57
|
+
help="Override OACP home directory (default: $OACP_HOME or ~/oacp)",
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
disable_parser = sub.add_parser("disable", help="Disable memory sync hooks locally")
|
|
61
|
+
disable_parser.add_argument(
|
|
62
|
+
"--oacp-dir",
|
|
63
|
+
default=None,
|
|
64
|
+
help="Override OACP home directory (default: $OACP_HOME or ~/oacp)",
|
|
65
|
+
)
|
|
66
|
+
|
|
21
67
|
archive_parser = sub.add_parser(
|
|
22
68
|
"archive", help="Move a non-standard memory file into memory/archive/"
|
|
23
69
|
)
|
|
@@ -57,6 +103,14 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
57
103
|
|
|
58
104
|
def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
59
105
|
from _oacp_env import resolve_oacp_home
|
|
106
|
+
from memory_sync import (
|
|
107
|
+
MemorySyncError,
|
|
108
|
+
clone_memory_repo,
|
|
109
|
+
disable_memory_repo,
|
|
110
|
+
init_memory_repo,
|
|
111
|
+
pull_memory,
|
|
112
|
+
push_memory,
|
|
113
|
+
)
|
|
60
114
|
from promote_to_archive import archive_memory_file
|
|
61
115
|
from restore_from_archive import restore_memory_file
|
|
62
116
|
|
|
@@ -67,10 +121,37 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
|
67
121
|
parser.print_help()
|
|
68
122
|
return 2
|
|
69
123
|
|
|
124
|
+
json_output = bool(getattr(args, "json_output", False))
|
|
70
125
|
oacp_root = resolve_oacp_home(explicit=args.oacp_dir)
|
|
71
126
|
|
|
72
127
|
try:
|
|
73
|
-
if args.command == "
|
|
128
|
+
if args.command == "init":
|
|
129
|
+
result = {"action": "init"}
|
|
130
|
+
lines = init_memory_repo(oacp_root, remote=args.remote)
|
|
131
|
+
human = "\n".join(lines)
|
|
132
|
+
elif args.command == "clone":
|
|
133
|
+
result = {"action": "clone", "url": args.url, "oacp_root": str(oacp_root)}
|
|
134
|
+
lines = clone_memory_repo(oacp_root, args.url, force=args.force)
|
|
135
|
+
human = "\n".join(lines)
|
|
136
|
+
elif args.command == "pull":
|
|
137
|
+
result = {"action": "pull"}
|
|
138
|
+
lines = pull_memory(oacp_root)
|
|
139
|
+
human = "\n".join(lines)
|
|
140
|
+
elif args.command == "push":
|
|
141
|
+
result = {"action": "push"}
|
|
142
|
+
lines, code = push_memory(oacp_root)
|
|
143
|
+
human = "\n".join(lines)
|
|
144
|
+
if json_output:
|
|
145
|
+
result["exit_code"] = code
|
|
146
|
+
if not json_output and human:
|
|
147
|
+
print(human)
|
|
148
|
+
elif json_output:
|
|
149
|
+
print(json.dumps(result, indent=2, sort_keys=True))
|
|
150
|
+
return code
|
|
151
|
+
elif args.command == "disable":
|
|
152
|
+
result = {"action": "disable"}
|
|
153
|
+
human = "\n".join(disable_memory_repo(oacp_root))
|
|
154
|
+
elif args.command == "archive":
|
|
74
155
|
result = archive_memory_file(
|
|
75
156
|
args.project_name,
|
|
76
157
|
args.memory_file,
|
|
@@ -82,7 +163,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
|
82
163
|
f"memory/{result['memory_file']} -> "
|
|
83
164
|
f"memory/archive/{result['archived_file']}"
|
|
84
165
|
)
|
|
85
|
-
|
|
166
|
+
elif args.command == "restore":
|
|
86
167
|
result = restore_memory_file(
|
|
87
168
|
args.project_name,
|
|
88
169
|
args.archived_file,
|
|
@@ -94,13 +175,16 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
|
94
175
|
f"memory/archive/{result['archived_file']} -> "
|
|
95
176
|
f"memory/{result['restored_file']}"
|
|
96
177
|
)
|
|
97
|
-
|
|
178
|
+
else:
|
|
179
|
+
parser.print_help()
|
|
180
|
+
return 2
|
|
181
|
+
except (MemorySyncError, ValueError) as exc:
|
|
98
182
|
print(f"Error: {exc}", file=sys.stderr)
|
|
99
183
|
return 1
|
|
100
184
|
|
|
101
|
-
if
|
|
185
|
+
if json_output:
|
|
102
186
|
print(json.dumps(result, indent=2, sort_keys=True))
|
|
103
|
-
|
|
187
|
+
elif human:
|
|
104
188
|
print(human)
|
|
105
189
|
return 0
|
|
106
190
|
|