oacp-cli 0.1.2__tar.gz → 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.
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/CHANGELOG.md +22 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/PKG-INFO +9 -5
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/QUICKSTART.md +4 -2
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/README.md +8 -4
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/SPEC.md +40 -25
- oacp_cli-0.2.0/docs/protocol/agent_profiles.md +160 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/cross_runtime_sync.md +8 -3
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/runtime_capabilities.md +1 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/session_init.md +4 -1
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/oacp/cli.py +9 -1
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/pyproject.toml +9 -1
- oacp_cli-0.2.0/scripts/_oacp_constants.py +58 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/add_agent.py +70 -37
- oacp_cli-0.2.0/scripts/agent_profile.py +351 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/codex_session_init.py +3 -1
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/handoff_schema.py +8 -4
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/init_project_workspace.py +15 -8
- oacp_cli-0.2.0/scripts/memory_archive_common.py +67 -0
- oacp_cli-0.2.0/scripts/memory_cli.py +109 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/oacp_doctor.py +5 -22
- oacp_cli-0.2.0/scripts/oacp_inbox.py +245 -0
- oacp_cli-0.2.0/scripts/promote_to_archive.py +106 -0
- oacp_cli-0.2.0/scripts/restore_from_archive.py +96 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/send_inbox_message.py +129 -18
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/session_lifecycle_hooks.py +3 -3
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/setup_runtime.py +4 -31
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/update_workspace.sh +23 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/validate_agent_card.py +54 -20
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/validate_message.py +11 -4
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/write_event.py +3 -1
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/agent_card.template.yaml +15 -0
- oacp_cli-0.2.0/templates/agent_profile.template.yaml +40 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_add_agent.py +46 -0
- oacp_cli-0.2.0/tests/test_agent_profile.py +610 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_codex_session_init.py +30 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_handoff_schema.py +17 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_init_project_workspace.py +17 -1
- oacp_cli-0.2.0/tests/test_memory_archive.py +222 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_oacp_cli.py +22 -0
- oacp_cli-0.2.0/tests/test_oacp_constants.py +56 -0
- oacp_cli-0.2.0/tests/test_oacp_inbox.py +166 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_send_inbox_message.py +169 -2
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_update_workspace.py +31 -2
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_validate_agent_card.py +79 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_validate_message.py +6 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/.github/workflows/ci.yml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/.github/workflows/release.yml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/.gitignore +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/CONTRIBUTING.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/LICENSE +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/Makefile +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/SECURITY.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/guides/adoption.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/guides/doctor.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/guides/prompt_caching.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/guides/runtime_capability_matrix.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/guides/setup.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/guides/unified_skill_spec.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/guides/versioning.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/agent_safety_defaults.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/credential_scoping.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/dispatch_states.yaml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/inbox_outbox.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/mcp_integration.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/multi_agent_shared_workspace.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/org_memory.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/packet_states.yaml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/review_loop.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/skills_manifest.yaml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/docs/protocol/task_negotiation.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/examples/quickstart/README.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/mcp_servers/oacp_coordinator.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/oacp/__init__.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/_oacp_env.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/check_quality_gate.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/create_handoff_packet.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/init_org_memory.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/init_packet.sh +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/init_project_workspace.sh +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/normalize_findings.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/scripts/preflight.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/agent_status.template.yaml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/checkpoint.template.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/claude/agents/role_agent.template.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/claude/rules/guardrail.template.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/findings_packet.template.yaml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/github_actions_quality_gate.yaml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/guardrails/coding_standards.template.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/guardrails/safe_commands.template.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/guardrails/secrets_rules.template.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/handoff_packet.template.yaml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/inbox_message.template.yaml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/manual_validation.template.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/merge_decision.template.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/org-memory/decisions.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/org-memory/events/.gitkeep +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/org-memory/events/20260317-170120-example-api-convention.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/org-memory/recent.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/org-memory/rules.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/review_packet.template.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/roles/role_baseline.template.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/roles/role_definition.template.yaml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/runtime_capabilities.yaml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/skills_manifest.template.yaml +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/templates/test_packet.template.md +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_create_handoff_packet.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_github_workflows.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_oacp_coordinator.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_oacp_doctor.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_oacp_env.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_preflight.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_review_loop.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_session_lifecycle_hooks.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_setup_runtime.py +0 -0
- {oacp_cli-0.1.2 → oacp_cli-0.2.0}/tests/test_workspace_discovery.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
|
+
## [0.2.0] - 2026-03-20
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `oacp inbox` command for listing agent inboxes with table and `--json` output
|
|
13
|
+
- Sender inference for `oacp send` — `--from` is now optional when `OACP_AGENT`, `AGENT_NAME`, or agent card runtime can identify the sender
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Consolidated shared script constants into `_oacp_constants.py` — canonical `AGENT_RE`, runtime tuples, timestamp/template helpers
|
|
18
|
+
- Agent name validation now requires an alphanumeric first character (names starting with `_`, `.`, `-` are rejected)
|
|
19
|
+
- Message ID and filename suffixes use `secrets.token_hex` instead of `random.choices`
|
|
20
|
+
|
|
21
|
+
## [0.1.9] - 2026-03-20
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Memory archive layer with `oacp archive` CLI command for active/archive split (#62, #11)
|
|
26
|
+
- Declarative agent profiles with YAML schema and `oacp agent init|show|list` CLI commands (#52, #48)
|
|
27
|
+
- `known_debt.md` as standard memory file for tracking technical debt (#53, #32)
|
|
28
|
+
|
|
8
29
|
## [0.1.2] - 2026-03-18
|
|
9
30
|
|
|
10
31
|
### Added
|
|
@@ -65,6 +86,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
65
86
|
- Checkout step in github-release workflow job (#19)
|
|
66
87
|
- Pre-release audit fixes: SHA-pinned actions, dangling doc refs (#15, #16)
|
|
67
88
|
|
|
89
|
+
[0.1.9]: https://github.com/kiloloop/oacp/compare/v0.1.2...v0.1.9
|
|
68
90
|
[0.1.2]: https://github.com/kiloloop/oacp/compare/v0.1.1...v0.1.2
|
|
69
91
|
[0.1.1]: https://github.com/kiloloop/oacp/compare/v0.1.0...v0.1.1
|
|
70
92
|
[0.1.0]: https://github.com/kiloloop/oacp/releases/tag/v0.1.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: oacp-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.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
|
|
@@ -68,7 +68,7 @@ Doctor checks your CLI tools, and with `--project` it audits workspace structure
|
|
|
68
68
|
|
|
69
69
|
- **Inbox/outbox messaging** — async YAML-based communication with threading, broadcast, and expiry
|
|
70
70
|
- **Structured review loop** — severity-graded findings, quality gates, and multi-round review
|
|
71
|
-
- **Durable shared memory** — project facts, decisions,
|
|
71
|
+
- **Durable shared memory** — project facts, decisions, open threads, and known debt with an explicit active/archive split
|
|
72
72
|
- **Dispatch state machine** — full task lifecycle tracking from assignment to merge
|
|
73
73
|
- **Agent safety defaults** — baseline rules for git, credentials, staging, and scope discipline
|
|
74
74
|
- **Runtime-agnostic** — works with any agent runtime that can read/write files
|
|
@@ -151,6 +151,7 @@ uv tool install .
|
|
|
151
151
|
## Commands
|
|
152
152
|
|
|
153
153
|
- `oacp init` creates a project workspace under `$OACP_HOME/projects/`
|
|
154
|
+
- `oacp memory` archives or restores project memory files
|
|
154
155
|
- `oacp send` sends a protocol-compliant inbox message
|
|
155
156
|
- `oacp doctor` checks environment and workspace health
|
|
156
157
|
- `oacp validate` validates an inbox/outbox YAML message
|
|
@@ -164,7 +165,7 @@ If `OACP_HOME` is unset, workspace commands default to `~/oacp` (underscore).
|
|
|
164
165
|
| **Inbox/Outbox** | Async messaging between agents via YAML files in `agents/<name>/inbox/` |
|
|
165
166
|
| **Review Loop** | Structured code review: `review_request` → `review_feedback` → `review_addressed` → `review_lgtm` |
|
|
166
167
|
| **Quality Gate** | Merge-readiness criteria: no unresolved P0/P1 findings, deferred nits tracked |
|
|
167
|
-
| **Durable Memory** | Shared `memory/` directory with
|
|
168
|
+
| **Durable Memory** | Shared `memory/` directory with an active working set plus `memory/archive/` for historical memory |
|
|
168
169
|
| **Dispatch States** | Task lifecycle: `received` → `accepted` → `working` → `pr_opened` → `in_review` → `done` |
|
|
169
170
|
| **Safety Defaults** | Baseline rules all agents follow: no force push, no secrets in commits, stage hygiene |
|
|
170
171
|
|
|
@@ -175,7 +176,7 @@ oacp/
|
|
|
175
176
|
├── docs/
|
|
176
177
|
│ ├── protocol/ # Canonical protocol specifications (13 specs)
|
|
177
178
|
│ └── guides/ # Setup, adoption, versioning
|
|
178
|
-
├── scripts/ #
|
|
179
|
+
├── scripts/ # 18 kernel scripts (Python + shell)
|
|
179
180
|
├── templates/ # Packet, role, and guardrail templates (19)
|
|
180
181
|
├── tests/ # Test suite
|
|
181
182
|
├── Makefile # Task runner (make help for all targets)
|
|
@@ -214,6 +215,7 @@ OACP ships kernel scripts — the key CLI commands you'll use most:
|
|
|
214
215
|
|
|
215
216
|
- **`oacp init`** — create a new project workspace (the first command you run)
|
|
216
217
|
- **`oacp add-agent`** — add an agent to an existing project workspace
|
|
218
|
+
- **`oacp memory`** — archive or restore project memory files
|
|
217
219
|
- **`oacp setup`** — generate runtime-specific config files (Claude, Codex, Gemini)
|
|
218
220
|
- **`oacp send`** — send protocol-compliant messages between agents
|
|
219
221
|
- **`oacp doctor`** — environment and workspace health check
|
|
@@ -257,7 +259,9 @@ $OACP_HOME/projects/<project>/
|
|
|
257
259
|
├── memory/ # Shared durable memory
|
|
258
260
|
│ ├── project_facts.md
|
|
259
261
|
│ ├── decision_log.md
|
|
260
|
-
│
|
|
262
|
+
│ ├── open_threads.md
|
|
263
|
+
│ ├── known_debt.md
|
|
264
|
+
│ └── archive/
|
|
261
265
|
├── packets/ # Review/findings artifacts
|
|
262
266
|
└── workspace.json # Project metadata
|
|
263
267
|
```
|
|
@@ -55,7 +55,9 @@ $OACP_HOME/projects/my-first-project/
|
|
|
55
55
|
├── memory/
|
|
56
56
|
│ ├── project_facts.md
|
|
57
57
|
│ ├── decision_log.md
|
|
58
|
-
│
|
|
58
|
+
│ ├── open_threads.md
|
|
59
|
+
│ ├── known_debt.md
|
|
60
|
+
│ └── archive/
|
|
59
61
|
├── packets/
|
|
60
62
|
│ ├── review/
|
|
61
63
|
│ └── findings/
|
|
@@ -82,7 +84,7 @@ Check inbox: ls $OACP_HOME/projects/my-first-project/agents/claude/inbox/
|
|
|
82
84
|
OACP workspace: $OACP_HOME/projects/my-first-project/
|
|
83
85
|
```
|
|
84
86
|
|
|
85
|
-
**Other runtimes** — point your agent's system prompt at the workspace path and instruct it to read `memory
|
|
87
|
+
**Other runtimes** — point your agent's system prompt at the workspace path and instruct it to read the standard `memory/` files at session start.
|
|
86
88
|
|
|
87
89
|
For full runtime setup (role templates, guardrails, skills), see [docs/guides/setup.md](docs/guides/setup.md).
|
|
88
90
|
|
|
@@ -42,7 +42,7 @@ Doctor checks your CLI tools, and with `--project` it audits workspace structure
|
|
|
42
42
|
|
|
43
43
|
- **Inbox/outbox messaging** — async YAML-based communication with threading, broadcast, and expiry
|
|
44
44
|
- **Structured review loop** — severity-graded findings, quality gates, and multi-round review
|
|
45
|
-
- **Durable shared memory** — project facts, decisions,
|
|
45
|
+
- **Durable shared memory** — project facts, decisions, open threads, and known debt with an explicit active/archive split
|
|
46
46
|
- **Dispatch state machine** — full task lifecycle tracking from assignment to merge
|
|
47
47
|
- **Agent safety defaults** — baseline rules for git, credentials, staging, and scope discipline
|
|
48
48
|
- **Runtime-agnostic** — works with any agent runtime that can read/write files
|
|
@@ -125,6 +125,7 @@ uv tool install .
|
|
|
125
125
|
## Commands
|
|
126
126
|
|
|
127
127
|
- `oacp init` creates a project workspace under `$OACP_HOME/projects/`
|
|
128
|
+
- `oacp memory` archives or restores project memory files
|
|
128
129
|
- `oacp send` sends a protocol-compliant inbox message
|
|
129
130
|
- `oacp doctor` checks environment and workspace health
|
|
130
131
|
- `oacp validate` validates an inbox/outbox YAML message
|
|
@@ -138,7 +139,7 @@ If `OACP_HOME` is unset, workspace commands default to `~/oacp` (underscore).
|
|
|
138
139
|
| **Inbox/Outbox** | Async messaging between agents via YAML files in `agents/<name>/inbox/` |
|
|
139
140
|
| **Review Loop** | Structured code review: `review_request` → `review_feedback` → `review_addressed` → `review_lgtm` |
|
|
140
141
|
| **Quality Gate** | Merge-readiness criteria: no unresolved P0/P1 findings, deferred nits tracked |
|
|
141
|
-
| **Durable Memory** | Shared `memory/` directory with
|
|
142
|
+
| **Durable Memory** | Shared `memory/` directory with an active working set plus `memory/archive/` for historical memory |
|
|
142
143
|
| **Dispatch States** | Task lifecycle: `received` → `accepted` → `working` → `pr_opened` → `in_review` → `done` |
|
|
143
144
|
| **Safety Defaults** | Baseline rules all agents follow: no force push, no secrets in commits, stage hygiene |
|
|
144
145
|
|
|
@@ -149,7 +150,7 @@ oacp/
|
|
|
149
150
|
├── docs/
|
|
150
151
|
│ ├── protocol/ # Canonical protocol specifications (13 specs)
|
|
151
152
|
│ └── guides/ # Setup, adoption, versioning
|
|
152
|
-
├── scripts/ #
|
|
153
|
+
├── scripts/ # 18 kernel scripts (Python + shell)
|
|
153
154
|
├── templates/ # Packet, role, and guardrail templates (19)
|
|
154
155
|
├── tests/ # Test suite
|
|
155
156
|
├── Makefile # Task runner (make help for all targets)
|
|
@@ -188,6 +189,7 @@ OACP ships kernel scripts — the key CLI commands you'll use most:
|
|
|
188
189
|
|
|
189
190
|
- **`oacp init`** — create a new project workspace (the first command you run)
|
|
190
191
|
- **`oacp add-agent`** — add an agent to an existing project workspace
|
|
192
|
+
- **`oacp memory`** — archive or restore project memory files
|
|
191
193
|
- **`oacp setup`** — generate runtime-specific config files (Claude, Codex, Gemini)
|
|
192
194
|
- **`oacp send`** — send protocol-compliant messages between agents
|
|
193
195
|
- **`oacp doctor`** — environment and workspace health check
|
|
@@ -231,7 +233,9 @@ $OACP_HOME/projects/<project>/
|
|
|
231
233
|
├── memory/ # Shared durable memory
|
|
232
234
|
│ ├── project_facts.md
|
|
233
235
|
│ ├── decision_log.md
|
|
234
|
-
│
|
|
236
|
+
│ ├── open_threads.md
|
|
237
|
+
│ ├── known_debt.md
|
|
238
|
+
│ └── archive/
|
|
235
239
|
├── packets/ # Review/findings artifacts
|
|
236
240
|
└── workspace.json # Project metadata
|
|
237
241
|
```
|
|
@@ -29,28 +29,36 @@ Full specification: [`docs/protocol/inbox_outbox.md`](docs/protocol/inbox_outbox
|
|
|
29
29
|
Agents communicate through a shared filesystem using YAML messages. Each agent has an inbox and outbox directory within a project workspace:
|
|
30
30
|
|
|
31
31
|
```
|
|
32
|
-
$OACP_HOME/
|
|
33
|
-
├── agents/
|
|
32
|
+
$OACP_HOME/
|
|
33
|
+
├── agents/ # Global agent profiles
|
|
34
34
|
│ ├── claude/
|
|
35
|
-
│ │
|
|
36
|
-
│
|
|
37
|
-
│
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
│
|
|
41
|
-
│ │ ├──
|
|
42
|
-
│ │
|
|
43
|
-
│
|
|
44
|
-
│
|
|
45
|
-
├──
|
|
46
|
-
│ ├──
|
|
47
|
-
│ ├──
|
|
48
|
-
│ └──
|
|
49
|
-
|
|
50
|
-
│
|
|
51
|
-
|
|
52
|
-
├──
|
|
53
|
-
|
|
35
|
+
│ │ └── profile.yaml # Global identity defaults
|
|
36
|
+
│ └── codex/
|
|
37
|
+
│ └── profile.yaml
|
|
38
|
+
└── projects/<project>/
|
|
39
|
+
├── agents/
|
|
40
|
+
│ ├── claude/
|
|
41
|
+
│ │ ├── inbox/ # Other agents write here
|
|
42
|
+
│ │ ├── outbox/ # Claude's sent messages (copies)
|
|
43
|
+
│ │ ├── status.yaml # Dynamic agent state
|
|
44
|
+
│ │ └── agent_card.yaml # Static agent identity (overrides global)
|
|
45
|
+
│ ├── codex/
|
|
46
|
+
│ │ ├── inbox/
|
|
47
|
+
│ │ ├── outbox/
|
|
48
|
+
│ │ └── ...
|
|
49
|
+
│ └── gemini/
|
|
50
|
+
│ └── ...
|
|
51
|
+
├── memory/ # Shared durable memory
|
|
52
|
+
│ ├── project_facts.md
|
|
53
|
+
│ ├── decision_log.md
|
|
54
|
+
│ ├── open_threads.md
|
|
55
|
+
│ └── known_debt.md
|
|
56
|
+
│ └── archive/
|
|
57
|
+
├── packets/ # Review/findings artifacts
|
|
58
|
+
│ ├── review/
|
|
59
|
+
│ └── findings/
|
|
60
|
+
├── merges/ # Merge decision records
|
|
61
|
+
└── workspace.json # Project metadata
|
|
54
62
|
```
|
|
55
63
|
|
|
56
64
|
### Message Format
|
|
@@ -315,8 +323,11 @@ Location: `$OACP_HOME/projects/<project>/memory/`
|
|
|
315
323
|
| `project_facts.md` | Agent roles, repo structure, architecture, conventions |
|
|
316
324
|
| `decision_log.md` | Timestamped decisions with rationale |
|
|
317
325
|
| `open_threads.md` | Unresolved issues, blocked epics, cross-agent coordination |
|
|
326
|
+
| `known_debt.md` | Verified unresolved debt and recurring cleanup items |
|
|
318
327
|
|
|
319
|
-
|
|
328
|
+
The top-level `memory/` files are the active working set. Historical memory can be moved into `memory/archive/`, which is not loaded at session start by default.
|
|
329
|
+
|
|
330
|
+
All runtimes read the active memory files at session start. Only stable, verified outcomes are written here. Promotion flows through merge decisions via a project-defined durable-memory promotion mechanism.
|
|
320
331
|
|
|
321
332
|
#### 2. Handoff Messages with Context Keys (ephemeral)
|
|
322
333
|
|
|
@@ -330,7 +341,7 @@ Review packets, findings packets, and merge decisions form a structured audit tr
|
|
|
330
341
|
|
|
331
342
|
| Sync Point | Direction | Action |
|
|
332
343
|
|------------|-----------|--------|
|
|
333
|
-
| Session start | Memory → Agent | Read all
|
|
344
|
+
| Session start | Memory → Agent | Read all 4 active memory files (not `memory/archive/`) |
|
|
334
345
|
| Task completion | Agent → Memory | Write stable outcomes via merge decision |
|
|
335
346
|
| Handoff | Agent → Agent | Include `conversation_id` + `context_keys` |
|
|
336
347
|
| Review cycle start | Packets → Agent | Read relevant packet history |
|
|
@@ -342,7 +353,7 @@ Agents follow a 6-step init sequence at session start:
|
|
|
342
353
|
|
|
343
354
|
1. **Load global rules** (required) — safety defaults, tool preferences
|
|
344
355
|
2. **Load project rules** (required) — repo structure, conventions
|
|
345
|
-
3. **Load durable memory** (required) — project facts, decisions, open threads
|
|
356
|
+
3. **Load durable memory** (required) — project facts, decisions, open threads, known debt
|
|
346
357
|
4. **Check inbox** (optional) — summarize pending messages
|
|
347
358
|
5. **Load skills/tools** (optional) — runtime-specific capabilities
|
|
348
359
|
6. **Report status** (required) — update `status.yaml`
|
|
@@ -445,7 +456,7 @@ The kernel boundary was established through a classification audit of all projec
|
|
|
445
456
|
|
|
446
457
|
OACP ships a **kernel** — the minimal set of scripts, templates, and docs needed to adopt the protocol. Everything else is internal tooling for advanced orchestration workflows.
|
|
447
458
|
|
|
448
|
-
### Kernel Scripts (
|
|
459
|
+
### Kernel Scripts (18)
|
|
449
460
|
|
|
450
461
|
These scripts ship with the OSS release. Most are stdlib-only Python or POSIX shell with no external dependencies beyond `python3`, `git`, and `gh`. Exception: `preflight.py` also requires `ruff`, `shellcheck`, and optionally `pyyaml` for YAML validation.
|
|
451
462
|
|
|
@@ -458,9 +469,13 @@ These scripts ship with the OSS release. Most are stdlib-only Python or POSIX sh
|
|
|
458
469
|
| `init_packet.sh` | Bootstraps review/findings/merge packet directories |
|
|
459
470
|
| `init_project_workspace.py` | Creates a new project workspace — CLI: `oacp init` |
|
|
460
471
|
| `add_agent.py` | Add an agent to an existing project workspace — CLI: `oacp add-agent` |
|
|
472
|
+
| `agent_profile.py` | Two-tier agent profile management — CLI: `oacp agent` |
|
|
473
|
+
| `memory_cli.py` | Archive or restore project memory files — CLI: `oacp memory` |
|
|
461
474
|
| `setup_runtime.py` | Generate runtime-specific config files — CLI: `oacp setup` |
|
|
462
475
|
| `normalize_findings.py` | Converts raw reviewer output to canonical findings YAML |
|
|
463
476
|
| `preflight.py` | Unified quality checks — CI runs this on every PR |
|
|
477
|
+
| `promote_to_archive.py` | Move a non-standard memory file into `memory/archive/` |
|
|
478
|
+
| `restore_from_archive.py` | Restore an archived memory file into the active `memory/` working set |
|
|
464
479
|
| `send_inbox_message.py` | CLI for all inbox messaging — CLI: `oacp send` |
|
|
465
480
|
| `update_workspace.sh` | Idempotent workspace sync across protocol versions |
|
|
466
481
|
| `validate_agent_card.py` | Validates agent card YAML against the schema |
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Agent Profiles — Two-Tier Identity System
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Agent profiles provide a two-tier identity system: **global profiles** declare stable defaults for an agent across all projects, while **project-level agent cards** override those defaults for a specific project context. The merge produces a single resolved view used for routing, discovery, and authorization.
|
|
6
|
+
|
|
7
|
+
The model mirrors how Claude Code handles instructions: a global `~/.claude/CLAUDE.md` sets baseline behavior, and a project-level `CLAUDE.md` overrides or extends it per repository. Profiles work the same way — define an agent's identity once, specialize per project.
|
|
8
|
+
|
|
9
|
+
## Directory Layout
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
$OACP_HOME/
|
|
13
|
+
├── agents/ # Global agent profiles
|
|
14
|
+
│ ├── claude/
|
|
15
|
+
│ │ └── profile.yaml
|
|
16
|
+
│ └── codex/
|
|
17
|
+
│ └── profile.yaml
|
|
18
|
+
└── projects/<project>/
|
|
19
|
+
└── agents/
|
|
20
|
+
└── claude/
|
|
21
|
+
├── agent_card.yaml # Project-level overrides
|
|
22
|
+
├── status.yaml
|
|
23
|
+
├── inbox/
|
|
24
|
+
└── outbox/
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- **Global profiles** (`agents/<name>/profile.yaml`) are created once per agent and rarely change.
|
|
28
|
+
- **Project cards** (`projects/<project>/agents/<name>/agent_card.yaml`) carry project-specific overrides — permissions, skills, routing rules — and are the authoritative resolved identity for that project.
|
|
29
|
+
- **Status files** (`status.yaml`) remain separate; they track dynamic session state, not static identity.
|
|
30
|
+
|
|
31
|
+
## Merge Rules
|
|
32
|
+
|
|
33
|
+
When both a global profile and a project card exist, they are merged with the following rules:
|
|
34
|
+
|
|
35
|
+
### Scalars
|
|
36
|
+
|
|
37
|
+
Project value wins if non-empty. Empty or null project values fall through to the global default.
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
# Global profile # Project card # Merged result
|
|
41
|
+
model: "claude-opus-4-6" model: "claude-sonnet-4" model: "claude-sonnet-4"
|
|
42
|
+
description: "Implementer" description: "" description: "Implementer"
|
|
43
|
+
trust_level: standard trust_level: elevated trust_level: elevated
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Dict Sections
|
|
47
|
+
|
|
48
|
+
Key-level merge within the dict. Project keys override matching global keys; global-only keys are preserved.
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
# Global profile # Project card # Merged result
|
|
52
|
+
capabilities: capabilities: capabilities:
|
|
53
|
+
tools: [Bash, Read] tools: [Bash, Read, Edit] tools: [Bash, Read, Edit]
|
|
54
|
+
languages: [python] domains: [trading] languages: [python]
|
|
55
|
+
domains: [backend] domains: [trading]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Note: `tools`, `languages`, and `domains` within `capabilities` are list sub-fields and follow list replacement (see below). The dict-level merge applies to the `capabilities` section itself — project can add or override keys without erasing global-only keys.
|
|
59
|
+
|
|
60
|
+
### Lists
|
|
61
|
+
|
|
62
|
+
Full replacement. If the project card defines a list field, it replaces the global list entirely. This prevents ambiguous merge semantics (append? deduplicate? reorder?).
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
# Global profile # Project card # Merged result
|
|
66
|
+
skills: skills: skills:
|
|
67
|
+
- id: code_review - id: security_audit - id: security_audit
|
|
68
|
+
name: Code Review name: Security Audit name: Security Audit
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Missing Sections
|
|
72
|
+
|
|
73
|
+
If the project card omits a section entirely, the global profile's value is used verbatim.
|
|
74
|
+
|
|
75
|
+
## Profile Schema Reference
|
|
76
|
+
|
|
77
|
+
Global profiles use `agent_profile.template.yaml`. Fields:
|
|
78
|
+
|
|
79
|
+
| Field | Type | Required | Description |
|
|
80
|
+
|-------|------|----------|-------------|
|
|
81
|
+
| `version` | string | yes | Schema version (semver, currently `0.2.0`) |
|
|
82
|
+
| `name` | string | yes | Agent identifier (matches directory name) |
|
|
83
|
+
| `runtime` | string | yes | One of: `claude`, `codex`, `gemini`, `human` |
|
|
84
|
+
| `model` | string | no | Model version identifier |
|
|
85
|
+
| `description` | string | no | One-line role summary |
|
|
86
|
+
| `routing_rules` | dict | no | `primary` (preferred targets) and `avoid` (agents to skip) |
|
|
87
|
+
| `trust_level` | string | no | `untrusted`, `standard`, `elevated`, or `admin` |
|
|
88
|
+
| `quota` | dict | no | `max_cost_usd_per_month`, `reset_day`, `warn_threshold` |
|
|
89
|
+
| `capabilities` | dict | no | `tools`, `languages`, `domains` lists |
|
|
90
|
+
| `skills` | list | no | Structured skill declarations (A2A-compatible) |
|
|
91
|
+
|
|
92
|
+
Project-level agent cards extend this schema with additional sections: `permissions`, `availability`, and `protocol`. See `templates/agent_card.template.yaml` for the full card schema.
|
|
93
|
+
|
|
94
|
+
## CLI Reference
|
|
95
|
+
|
|
96
|
+
The CLI wraps `scripts/agent_profile.py`. All commands auto-discover `$OACP_HOME`.
|
|
97
|
+
|
|
98
|
+
### `oacp agent init`
|
|
99
|
+
|
|
100
|
+
Scaffold a global agent profile from the template.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
oacp agent init claude --runtime claude
|
|
104
|
+
# Created global profile: $OACP_HOME/agents/claude/profile.yaml
|
|
105
|
+
|
|
106
|
+
oacp agent init codex --runtime codex
|
|
107
|
+
# Created global profile: $OACP_HOME/agents/codex/profile.yaml
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
If the profile already exists, the command skips without overwriting.
|
|
111
|
+
|
|
112
|
+
### `oacp agent show`
|
|
113
|
+
|
|
114
|
+
Print the resolved profile YAML. Without `--project`, prints the global profile. With `--project`, prints the merged result.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
oacp agent show claude
|
|
118
|
+
# Prints global profile for claude
|
|
119
|
+
|
|
120
|
+
oacp agent show claude --project my-app
|
|
121
|
+
# Prints merged profile (global + project card overrides)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### `oacp agent list`
|
|
125
|
+
|
|
126
|
+
List known agents with their tier tags.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
oacp agent list
|
|
130
|
+
# claude (global)
|
|
131
|
+
# codex (global)
|
|
132
|
+
|
|
133
|
+
oacp agent list --project my-app
|
|
134
|
+
# claude (global, project)
|
|
135
|
+
# codex (global)
|
|
136
|
+
# gemini (project)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Relationship to Existing Agent Cards
|
|
140
|
+
|
|
141
|
+
Agent cards predate global profiles and remain the authoritative per-project identity. The profile system adds a global defaults layer underneath:
|
|
142
|
+
|
|
143
|
+
| Concern | Global Profile | Project Agent Card |
|
|
144
|
+
|---------|---------------|--------------------|
|
|
145
|
+
| **Location** | `$OACP_HOME/agents/<name>/profile.yaml` | `$OACP_HOME/projects/<project>/agents/<name>/agent_card.yaml` |
|
|
146
|
+
| **Scope** | All projects | Single project |
|
|
147
|
+
| **Updates** | Rarely (identity changes) | Per project as needed |
|
|
148
|
+
| **Authority** | Defaults only | Authoritative for the project |
|
|
149
|
+
| **Extra sections** | None | `permissions`, `availability`, `protocol` |
|
|
150
|
+
|
|
151
|
+
When both exist, the merged result is what other systems (routing, doctor checks, discovery) should consume. When only a project card exists (no global profile), the card is used as-is. When only a global profile exists (no project card), the profile is used as-is.
|
|
152
|
+
|
|
153
|
+
## Cross-References
|
|
154
|
+
|
|
155
|
+
- **Runtime Capabilities**: `docs/protocol/runtime_capabilities.md` — capability keys, status schema, health checks
|
|
156
|
+
- **Inbox Protocol**: `docs/protocol/inbox_outbox.md` — agent messaging format
|
|
157
|
+
- **Profile Script**: `scripts/agent_profile.py` — implementation with merge logic
|
|
158
|
+
- **Profile Template**: `templates/agent_profile.template.yaml` — global profile scaffold
|
|
159
|
+
- **Card Template**: `templates/agent_card.template.yaml` — project card scaffold
|
|
160
|
+
- **Card Validator**: `scripts/validate_agent_card.py` — schema validation
|
|
@@ -23,11 +23,16 @@ The protocol defines three complementary sync mechanisms, ordered from most dura
|
|
|
23
23
|
| `project_facts.md` | Agent roles, repo structure, architecture, conventions | Any agent via the project's durable-memory promotion flow |
|
|
24
24
|
| `decision_log.md` | Timestamped decisions with rationale | Any agent via the project's durable-memory promotion flow |
|
|
25
25
|
| `open_threads.md` | Unresolved issues, blocked epics, cross-agent coordination | Any agent via the project's durable-memory promotion flow |
|
|
26
|
+
| `known_debt.md` | Verified unresolved debt that should persist across sessions | Any agent via the project's durable-memory promotion flow |
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
The top-level files in `memory/` are the active working set. Historical memory can be moved into `memory/archive/`, which is not loaded during session init unless an agent explicitly opts in.
|
|
29
|
+
|
|
30
|
+
These files are the **source of truth** for stable project knowledge. All runtimes read the active working set at session start. Only verified, stable outcomes should be written here.
|
|
28
31
|
|
|
29
32
|
**Promotion flow**: Merge decisions contain a "Durable Memory Updates" section. Each implementation should provide a promotion mechanism that extracts approved entries from merge artifacts and appends them to the appropriate memory file, deduplicating against existing content.
|
|
30
33
|
|
|
34
|
+
**Archive flow**: Users or coordinator agents may move non-standard memory files into `memory/archive/` for historical retention, then restore them back into `memory/` when they become active again.
|
|
35
|
+
|
|
31
36
|
### 2. Handoff Messages with Context Keys
|
|
32
37
|
|
|
33
38
|
**Location**: `agents/<agent>/inbox/`
|
|
@@ -57,7 +62,7 @@ Agents synchronize knowledge at well-defined points in the workflow:
|
|
|
57
62
|
|
|
58
63
|
| Sync Point | Action | Direction |
|
|
59
64
|
|------------|--------|-----------|
|
|
60
|
-
| **Session start** | Read `memory/project_facts.md`, `decision_log.md`, `open_threads.md` | Memory -> Agent |
|
|
65
|
+
| **Session start** | Read `memory/project_facts.md`, `decision_log.md`, `open_threads.md`, `known_debt.md` (not `memory/archive/`) | Memory -> Agent |
|
|
61
66
|
| **Task completion** | Write stable outcomes to memory via merge decision + durable-memory promotion flow | Agent -> Memory |
|
|
62
67
|
| **Handoff** | Include `conversation_id` + `context_keys` in handoff message | Agent -> Agent |
|
|
63
68
|
| **Review cycle start** | Read relevant packet history | Packets -> Agent |
|
|
@@ -104,7 +109,7 @@ Each project should provide a durable-memory promotion mechanism that:
|
|
|
104
109
|
|
|
105
110
|
1. Scans merge decisions or equivalent terminal artifacts
|
|
106
111
|
2. Extracts entries from the "Durable Memory Updates" section
|
|
107
|
-
3. Appends new entries to `decision_log.md`, `open_threads.md`, or `
|
|
112
|
+
3. Appends new entries to `decision_log.md`, `open_threads.md`, `project_facts.md`, or `known_debt.md`
|
|
108
113
|
4. Deduplicates against existing content
|
|
109
114
|
|
|
110
115
|
This ensures that knowledge flows from ephemeral review artifacts into durable memory that persists across sessions and runtimes, without requiring a specific helper script name.
|
|
@@ -269,6 +269,7 @@ The card schema is inspired by Google's A2A Agent Card spec (v0.3.0). Key differ
|
|
|
269
269
|
|
|
270
270
|
## Cross-References
|
|
271
271
|
|
|
272
|
+
- **Agent Profiles**: `docs/protocol/agent_profiles.md` — two-tier global profile + project card system
|
|
272
273
|
- **Parity Matrix**: `docs/guides/runtime_capability_matrix.md` — detailed per-runtime capability comparison
|
|
273
274
|
- **Inbox Protocol**: `docs/protocol/inbox_outbox.md` — agent messaging format
|
|
274
275
|
- **Session Lifecycle**: `scripts/session_lifecycle_hooks.py` (reference implementation) — session boundary hooks
|
|
@@ -60,11 +60,14 @@ The init sequence has 6 steps in a fixed order. Each step is classified as **req
|
|
|
60
60
|
|
|
61
61
|
**Location:** `$OACP_HOME/projects/<project>/memory/`
|
|
62
62
|
|
|
63
|
+
The top-level files in `memory/` are the active working set. `memory/archive/` is historical storage and is not loaded by default at session start.
|
|
64
|
+
|
|
63
65
|
**Loading order:**
|
|
64
66
|
|
|
65
67
|
1. `project_facts.md` — agent roles, repo structure, architecture, conventions. Read first because it provides the mental model for everything else.
|
|
66
68
|
2. `decision_log.md` — timestamped decisions with rationale. Read second to understand what has been decided and why.
|
|
67
|
-
3. `open_threads.md` — unresolved issues, blocked epics, cross-agent coordination. Read
|
|
69
|
+
3. `open_threads.md` — unresolved issues, blocked epics, cross-agent coordination. Read third because it builds on the context from facts and decisions.
|
|
70
|
+
4. `known_debt.md` — verified unresolved debt, recurring pain points, and cleanup items that future sessions should keep in view.
|
|
68
71
|
|
|
69
72
|
**Conflict resolution:** If memory files contradict project rules (e.g., `project_facts.md` says "use pytest" but `CLAUDE.md` says "use make test"), project rules win. Memory files may be stale; project rules are maintained alongside the code.
|
|
70
73
|
|
|
@@ -21,6 +21,9 @@ Installable Open Agent Coordination Protocol (OACP) CLI.
|
|
|
21
21
|
Commands:
|
|
22
22
|
init Create a project workspace under $OACP_HOME/projects/
|
|
23
23
|
add-agent Add an agent to an existing project workspace
|
|
24
|
+
agent Manage global agent profiles (init, show, list)
|
|
25
|
+
inbox List pending inbox messages
|
|
26
|
+
memory Archive or restore project memory files
|
|
24
27
|
setup Generate runtime-specific config files in a repo
|
|
25
28
|
send Send a protocol-compliant inbox message
|
|
26
29
|
org-memory Initialize org-level memory at $OACP_HOME/org-memory/
|
|
@@ -32,8 +35,10 @@ Examples:
|
|
|
32
35
|
oacp init my-project --repo /path/to/repo
|
|
33
36
|
oacp init my-project --agents claude,codex
|
|
34
37
|
oacp add-agent my-project alice --runtime claude
|
|
38
|
+
oacp inbox my-project --agent claude
|
|
39
|
+
oacp memory archive my-project research_notes.md
|
|
35
40
|
oacp setup claude --project my-project
|
|
36
|
-
oacp send my-project --
|
|
41
|
+
oacp send my-project --to iris --type notification --subject "Done" --body "Completed"
|
|
37
42
|
oacp org-memory init
|
|
38
43
|
oacp write-event --agent claude --project my-project --type decision --slug api-convention --body "Use REST for public APIs"
|
|
39
44
|
oacp doctor
|
|
@@ -43,6 +48,9 @@ Examples:
|
|
|
43
48
|
SCRIPT_NAMES = {
|
|
44
49
|
"init": "init_project_workspace.py",
|
|
45
50
|
"add-agent": "add_agent.py",
|
|
51
|
+
"agent": "agent_profile.py",
|
|
52
|
+
"inbox": "oacp_inbox.py",
|
|
53
|
+
"memory": "memory_cli.py",
|
|
46
54
|
"setup": "setup_runtime.py",
|
|
47
55
|
"send": "send_inbox_message.py",
|
|
48
56
|
"org-memory": "init_org_memory.py",
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "oacp-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.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"
|
|
@@ -50,6 +50,7 @@ packages = ["oacp"]
|
|
|
50
50
|
|
|
51
51
|
[tool.hatch.build.targets.wheel.force-include]
|
|
52
52
|
"scripts/codex_session_init.py" = "oacp/_scripts/codex_session_init.py"
|
|
53
|
+
"scripts/_oacp_constants.py" = "oacp/_scripts/_oacp_constants.py"
|
|
53
54
|
"scripts/_oacp_env.py" = "oacp/_scripts/_oacp_env.py"
|
|
54
55
|
"scripts/handoff_schema.py" = "oacp/_scripts/handoff_schema.py"
|
|
55
56
|
"scripts/oacp_doctor.py" = "oacp/_scripts/oacp_doctor.py"
|
|
@@ -58,6 +59,12 @@ packages = ["oacp"]
|
|
|
58
59
|
"scripts/session_lifecycle_hooks.py" = "oacp/_scripts/session_lifecycle_hooks.py"
|
|
59
60
|
"scripts/validate_message.py" = "oacp/_scripts/validate_message.py"
|
|
60
61
|
"scripts/add_agent.py" = "oacp/_scripts/add_agent.py"
|
|
62
|
+
"scripts/agent_profile.py" = "oacp/_scripts/agent_profile.py"
|
|
63
|
+
"scripts/oacp_inbox.py" = "oacp/_scripts/oacp_inbox.py"
|
|
64
|
+
"scripts/memory_cli.py" = "oacp/_scripts/memory_cli.py"
|
|
65
|
+
"scripts/memory_archive_common.py" = "oacp/_scripts/memory_archive_common.py"
|
|
66
|
+
"scripts/promote_to_archive.py" = "oacp/_scripts/promote_to_archive.py"
|
|
67
|
+
"scripts/restore_from_archive.py" = "oacp/_scripts/restore_from_archive.py"
|
|
61
68
|
"scripts/setup_runtime.py" = "oacp/_scripts/setup_runtime.py"
|
|
62
69
|
"scripts/init_org_memory.py" = "oacp/_scripts/init_org_memory.py"
|
|
63
70
|
"scripts/write_event.py" = "oacp/_scripts/write_event.py"
|
|
@@ -66,6 +73,7 @@ packages = ["oacp"]
|
|
|
66
73
|
"templates/org-memory/decisions.md" = "oacp/_templates/org-memory/decisions.md"
|
|
67
74
|
"templates/org-memory/rules.md" = "oacp/_templates/org-memory/rules.md"
|
|
68
75
|
"templates/agent_card.template.yaml" = "oacp/_templates/agent_card.template.yaml"
|
|
76
|
+
"templates/agent_profile.template.yaml" = "oacp/_templates/agent_profile.template.yaml"
|
|
69
77
|
"templates/claude/agents/role_agent.template.md" = "oacp/_templates/claude/agents/role_agent.template.md"
|
|
70
78
|
|
|
71
79
|
[tool.ruff]
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Kiloloop
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
"""Shared constants and helpers for OACP scripts."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import datetime as dt
|
|
8
|
+
import re
|
|
9
|
+
from contextlib import nullcontext
|
|
10
|
+
from importlib import resources
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
AGENT_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$")
|
|
14
|
+
CREATABLE_RUNTIMES = ("claude", "codex", "gemini")
|
|
15
|
+
ALL_RUNTIMES = ("claude", "codex", "gemini", "human", "unknown")
|
|
16
|
+
CANONICAL_CAPABILITIES = {
|
|
17
|
+
"headless",
|
|
18
|
+
"mcp_tools",
|
|
19
|
+
"shell_access",
|
|
20
|
+
"git_ops",
|
|
21
|
+
"github_cli",
|
|
22
|
+
"subagents",
|
|
23
|
+
"parallel_teams",
|
|
24
|
+
"web_search",
|
|
25
|
+
"browser",
|
|
26
|
+
"session_memory",
|
|
27
|
+
"notifications",
|
|
28
|
+
"async_tasks",
|
|
29
|
+
"image_generation",
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def utc_now_iso(now: dt.datetime | None = None) -> str:
|
|
34
|
+
"""Return a UTC RFC3339 timestamp with seconds precision."""
|
|
35
|
+
base = now or dt.datetime.now(dt.timezone.utc)
|
|
36
|
+
if base.tzinfo is None:
|
|
37
|
+
base = base.replace(tzinfo=dt.timezone.utc)
|
|
38
|
+
else:
|
|
39
|
+
base = base.astimezone(dt.timezone.utc)
|
|
40
|
+
return base.strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _write_if_missing(path: Path, content: str) -> bool:
|
|
44
|
+
"""Write content to *path* only if it does not already exist."""
|
|
45
|
+
if path.exists():
|
|
46
|
+
return False
|
|
47
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
48
|
+
path.write_text(content, encoding="utf-8")
|
|
49
|
+
return True
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _template_path(relative: str):
|
|
53
|
+
"""Resolve a template file from the repo tree or installed package."""
|
|
54
|
+
repo_template = Path(__file__).resolve().parent.parent / "templates" / relative
|
|
55
|
+
if repo_template.is_file():
|
|
56
|
+
return nullcontext(repo_template)
|
|
57
|
+
resource = resources.files("oacp").joinpath("_templates", relative)
|
|
58
|
+
return resources.as_file(resource)
|