briefops 1.0.0
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.
- package/CHANGELOG.md +36 -0
- package/CODE_OF_CONDUCT.md +13 -0
- package/CONTRIBUTING.md +53 -0
- package/LICENSE +21 -0
- package/README.md +801 -0
- package/SECURITY.md +59 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +54 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/approve.d.ts +2 -0
- package/dist/commands/approve.js +38 -0
- package/dist/commands/approve.js.map +1 -0
- package/dist/commands/brief.d.ts +2 -0
- package/dist/commands/brief.js +81 -0
- package/dist/commands/brief.js.map +1 -0
- package/dist/commands/codex.d.ts +2 -0
- package/dist/commands/codex.js +163 -0
- package/dist/commands/codex.js.map +1 -0
- package/dist/commands/compare.d.ts +2 -0
- package/dist/commands/compare.js +48 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/continue.d.ts +2 -0
- package/dist/commands/continue.js +66 -0
- package/dist/commands/continue.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +90 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/eval.d.ts +2 -0
- package/dist/commands/eval.js +89 -0
- package/dist/commands/eval.js.map +1 -0
- package/dist/commands/export.d.ts +2 -0
- package/dist/commands/export.js +105 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/finish.d.ts +2 -0
- package/dist/commands/finish.js +71 -0
- package/dist/commands/finish.js.map +1 -0
- package/dist/commands/handoff.d.ts +2 -0
- package/dist/commands/handoff.js +77 -0
- package/dist/commands/handoff.js.map +1 -0
- package/dist/commands/inbox.d.ts +2 -0
- package/dist/commands/inbox.js +36 -0
- package/dist/commands/inbox.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +13 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/inspect.d.ts +2 -0
- package/dist/commands/inspect.js +226 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/log.d.ts +2 -0
- package/dist/commands/log.js +96 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/memory.d.ts +2 -0
- package/dist/commands/memory.js +236 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/pack.d.ts +2 -0
- package/dist/commands/pack.js +42 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/prime.d.ts +4 -0
- package/dist/commands/prime.js +44 -0
- package/dist/commands/prime.js.map +1 -0
- package/dist/commands/project.d.ts +2 -0
- package/dist/commands/project.js +50 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/shared.d.ts +3 -0
- package/dist/commands/shared.js +24 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/commands/skill.d.ts +2 -0
- package/dist/commands/skill.js +146 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/worker.d.ts +2 -0
- package/dist/commands/worker.js +128 -0
- package/dist/commands/worker.js.map +1 -0
- package/dist/core/adapter.d.ts +22 -0
- package/dist/core/adapter.js +167 -0
- package/dist/core/adapter.js.map +1 -0
- package/dist/core/approval.d.ts +26 -0
- package/dist/core/approval.js +86 -0
- package/dist/core/approval.js.map +1 -0
- package/dist/core/brief.d.ts +47 -0
- package/dist/core/brief.js +411 -0
- package/dist/core/brief.js.map +1 -0
- package/dist/core/codex.d.ts +53 -0
- package/dist/core/codex.js +286 -0
- package/dist/core/codex.js.map +1 -0
- package/dist/core/codexPlugin.d.ts +51 -0
- package/dist/core/codexPlugin.js +228 -0
- package/dist/core/codexPlugin.js.map +1 -0
- package/dist/core/compatibility.d.ts +2 -0
- package/dist/core/compatibility.js +16 -0
- package/dist/core/compatibility.js.map +1 -0
- package/dist/core/config.d.ts +19 -0
- package/dist/core/config.js +77 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/contextBudget.d.ts +12 -0
- package/dist/core/contextBudget.js +22 -0
- package/dist/core/contextBudget.js.map +1 -0
- package/dist/core/contextCompare.d.ts +27 -0
- package/dist/core/contextCompare.js +97 -0
- package/dist/core/contextCompare.js.map +1 -0
- package/dist/core/continuity.d.ts +25 -0
- package/dist/core/continuity.js +73 -0
- package/dist/core/continuity.js.map +1 -0
- package/dist/core/errors.d.ts +4 -0
- package/dist/core/errors.js +12 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/eval.d.ts +38 -0
- package/dist/core/eval.js +180 -0
- package/dist/core/eval.js.map +1 -0
- package/dist/core/exportPolicy.d.ts +7 -0
- package/dist/core/exportPolicy.js +17 -0
- package/dist/core/exportPolicy.js.map +1 -0
- package/dist/core/exportTargets.d.ts +25 -0
- package/dist/core/exportTargets.js +292 -0
- package/dist/core/exportTargets.js.map +1 -0
- package/dist/core/handoff.d.ts +48 -0
- package/dist/core/handoff.js +611 -0
- package/dist/core/handoff.js.map +1 -0
- package/dist/core/inbox.d.ts +15 -0
- package/dist/core/inbox.js +56 -0
- package/dist/core/inbox.js.map +1 -0
- package/dist/core/lock.d.ts +11 -0
- package/dist/core/lock.js +99 -0
- package/dist/core/lock.js.map +1 -0
- package/dist/core/log.d.ts +38 -0
- package/dist/core/log.js +93 -0
- package/dist/core/log.js.map +1 -0
- package/dist/core/memory.d.ts +86 -0
- package/dist/core/memory.js +353 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/memoryHygiene.d.ts +25 -0
- package/dist/core/memoryHygiene.js +95 -0
- package/dist/core/memoryHygiene.js.map +1 -0
- package/dist/core/memoryProposal.d.ts +40 -0
- package/dist/core/memoryProposal.js +279 -0
- package/dist/core/memoryProposal.js.map +1 -0
- package/dist/core/output.d.ts +7 -0
- package/dist/core/output.js +18 -0
- package/dist/core/output.js.map +1 -0
- package/dist/core/patch.d.ts +37 -0
- package/dist/core/patch.js +220 -0
- package/dist/core/patch.js.map +1 -0
- package/dist/core/paths.d.ts +33 -0
- package/dist/core/paths.js +84 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/prime.d.ts +17 -0
- package/dist/core/prime.js +298 -0
- package/dist/core/prime.js.map +1 -0
- package/dist/core/privacyDoctor.d.ts +14 -0
- package/dist/core/privacyDoctor.js +59 -0
- package/dist/core/privacyDoctor.js.map +1 -0
- package/dist/core/project.d.ts +16 -0
- package/dist/core/project.js +73 -0
- package/dist/core/project.js.map +1 -0
- package/dist/core/securityDoctor.d.ts +14 -0
- package/dist/core/securityDoctor.js +96 -0
- package/dist/core/securityDoctor.js.map +1 -0
- package/dist/core/skill.d.ts +16 -0
- package/dist/core/skill.js +81 -0
- package/dist/core/skill.js.map +1 -0
- package/dist/core/storage.d.ts +20 -0
- package/dist/core/storage.js +112 -0
- package/dist/core/storage.js.map +1 -0
- package/dist/core/tokens.d.ts +5 -0
- package/dist/core/tokens.js +24 -0
- package/dist/core/tokens.js.map +1 -0
- package/dist/core/worker.d.ts +51 -0
- package/dist/core/worker.js +312 -0
- package/dist/core/worker.js.map +1 -0
- package/dist/core/workflow.d.ts +61 -0
- package/dist/core/workflow.js +308 -0
- package/dist/core/workflow.js.map +1 -0
- package/dist/core/workspace.d.ts +7 -0
- package/dist/core/workspace.js +214 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/brief.d.ts +12 -0
- package/dist/schemas/brief.js +2 -0
- package/dist/schemas/brief.js.map +1 -0
- package/dist/schemas/eval.d.ts +96 -0
- package/dist/schemas/eval.js +30 -0
- package/dist/schemas/eval.js.map +1 -0
- package/dist/schemas/handoff.d.ts +33 -0
- package/dist/schemas/handoff.js +13 -0
- package/dist/schemas/handoff.js.map +1 -0
- package/dist/schemas/log.d.ts +51 -0
- package/dist/schemas/log.js +19 -0
- package/dist/schemas/log.js.map +1 -0
- package/dist/schemas/memory.d.ts +112 -0
- package/dist/schemas/memory.js +21 -0
- package/dist/schemas/memory.js.map +1 -0
- package/dist/schemas/memoryProposal.d.ts +181 -0
- package/dist/schemas/memoryProposal.js +46 -0
- package/dist/schemas/memoryProposal.js.map +1 -0
- package/dist/schemas/patch.d.ts +38 -0
- package/dist/schemas/patch.js +15 -0
- package/dist/schemas/patch.js.map +1 -0
- package/dist/schemas/project.d.ts +23 -0
- package/dist/schemas/project.js +8 -0
- package/dist/schemas/project.js.map +1 -0
- package/dist/schemas/skill.d.ts +26 -0
- package/dist/schemas/skill.js +9 -0
- package/dist/schemas/skill.js.map +1 -0
- package/dist/schemas/worker.d.ts +29 -0
- package/dist/schemas/worker.js +12 -0
- package/dist/schemas/worker.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/docs/codex-resume.md +13 -0
- package/docs/compatibility.md +49 -0
- package/docs/concept.md +13 -0
- package/docs/evals.md +18 -0
- package/docs/file-format.md +67 -0
- package/docs/handoff-briefs.md +9 -0
- package/docs/integrations/harnesses.md +74 -0
- package/docs/memory-lifecycle.md +23 -0
- package/docs/persistent-worker.md +15 -0
- package/docs/privacy-model.md +40 -0
- package/docs/quickstart.md +74 -0
- package/docs/release-checklist.md +68 -0
- package/docs/roadmap.md +33 -0
- package/docs/superpowers/plans/2026-06-08-briefops-oss-readiness.md +1272 -0
- package/docs/superpowers/plans/2026-06-08-codex-first-context-optimization.md +1176 -0
- package/docs/token-budget.md +63 -0
- package/examples/atlas-q/README.md +15 -0
- package/examples/codex-first-context/README.md +48 -0
- package/examples/codex-first-context/after-briefops-prime.md +40 -0
- package/examples/codex-first-context/before-manual-history-dump.md +18 -0
- package/examples/persistent-worker-demo/README.md +15 -0
- package/examples/persistent-worker-demo/after-codex-resume.md +17 -0
- package/examples/persistent-worker-demo/before-context-dump.md +5 -0
- package/examples/persistent-worker-demo/briefops-workspace/codex/prompts/resume_demo.md +29 -0
- package/examples/persistent-worker-demo/briefops-workspace/handoffs/handoff_demo.md +50 -0
- package/examples/persistent-worker-demo/briefops-workspace/logs/log_20260604_001.yaml +14 -0
- package/examples/persistent-worker-demo/briefops-workspace/logs/log_20260604_002.yaml +12 -0
- package/examples/persistent-worker-demo/briefops-workspace/memory/decisions.yaml +12 -0
- package/examples/persistent-worker-demo/briefops-workspace/memory/deprecated.yaml +1 -0
- package/examples/persistent-worker-demo/briefops-workspace/memory/facts.yaml +12 -0
- package/examples/persistent-worker-demo/briefops-workspace/memory/incidents.yaml +12 -0
- package/examples/persistent-worker-demo/briefops-workspace/memory/lessons.yaml +12 -0
- package/examples/persistent-worker-demo/briefops-workspace/memory-proposals/memprop_demo_001.memory-proposal.yaml +23 -0
- package/examples/persistent-worker-demo/briefops-workspace/projects/atlas-q.project.md +18 -0
- package/examples/persistent-worker-demo/briefops-workspace/skills/backtest-validation.skill.md +13 -0
- package/examples/persistent-worker-demo/briefops-workspace/skills/risk-review.skill.md +15 -0
- package/examples/persistent-worker-demo/briefops-workspace/workers/quant-reviewer.worker.yaml +12 -0
- package/examples/persistent-worker-demo/briefops-workspace/workers/summaries/quant-reviewer.summary.md +44 -0
- package/package.json +59 -0
- package/plugins/briefops-codex/.codex-plugin/plugin.json +39 -0
- package/plugins/briefops-codex/README.md +44 -0
- package/plugins/briefops-codex/skills/briefops-continue-worker/SKILL.md +22 -0
- package/plugins/briefops-codex/skills/briefops-finish-task/SKILL.md +22 -0
- package/plugins/briefops-codex/skills/briefops-prime-context/SKILL.md +24 -0
- package/plugins/briefops-codex/skills/briefops-review-memory/SKILL.md +27 -0
|
@@ -0,0 +1,1176 @@
|
|
|
1
|
+
# Codex First Context Optimization Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Make BriefOps the first local context layer Codex can invoke at the start of any project or thread, reducing token waste from repeated history/context discovery while preserving the local-first open source model.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Keep BriefOps Core as a local file-backed CLI and add a thin Codex-facing layer: a skill-only plugin package, a compact `prime` context command, ergonomic default-worker setup, and safety controls for concurrent local history writes. Hosted servers, cloud sync, vector databases, and required marketplaces stay out of scope.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** TypeScript, Commander, YAML, Zod, Vitest, Codex skill plugin packaging, local Markdown/YAML files under `.briefops/`.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Product Outcome
|
|
14
|
+
|
|
15
|
+
After Stage 4, a user should be able to install BriefOps from source or npm, initialize a repository, install Codex guidance/plugin assets, and start a new Codex thread with a compact BriefOps prime context before Codex spends tokens re-reading history.
|
|
16
|
+
|
|
17
|
+
Primary happy path:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
briefops init
|
|
21
|
+
briefops codex install
|
|
22
|
+
briefops codex plugin install
|
|
23
|
+
briefops worker use <worker>
|
|
24
|
+
briefops prime --task "Continue the work from the last thread." --format codex
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Codex plugin happy path:
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
$briefops-prime-context
|
|
31
|
+
Start this task with the smallest useful BriefOps context before inspecting history.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Success metrics:
|
|
35
|
+
|
|
36
|
+
- `briefops prime --max-tokens 800` emits no more than 800 estimated tokens in normal ready workspaces.
|
|
37
|
+
- Missing `.briefops` workspaces produce a short setup response instead of a long error.
|
|
38
|
+
- Pending memory proposals are visible but never applied automatically.
|
|
39
|
+
- Private memory is local by default; export behavior is explicit and test-covered.
|
|
40
|
+
- Concurrent writes cannot silently corrupt memory, proposals, worker summaries, logs, handoffs, or packs.
|
|
41
|
+
|
|
42
|
+
## 4-Stage Development Goals
|
|
43
|
+
|
|
44
|
+
### Stage 1: Codex Skill-Only Plugin And Installer
|
|
45
|
+
|
|
46
|
+
Goal: Make BriefOps discoverable and habit-forming inside Codex without running a server.
|
|
47
|
+
|
|
48
|
+
Done when:
|
|
49
|
+
|
|
50
|
+
- A local plugin bundle exists in the repository.
|
|
51
|
+
- `briefops codex plugin install` writes a deterministic plugin copy inside `.briefops/codex/plugin/briefops`.
|
|
52
|
+
- The plugin has skills for prime, finish, review-memory, and continue workflows.
|
|
53
|
+
- `npm test -- tests/codex-plugin.test.ts tests/cli-workflow.test.ts` passes.
|
|
54
|
+
|
|
55
|
+
### Stage 2: Compact First-Context Prime Workflow
|
|
56
|
+
|
|
57
|
+
Goal: Add the actual token-saving start-of-thread context primitive.
|
|
58
|
+
|
|
59
|
+
Done when:
|
|
60
|
+
|
|
61
|
+
- `briefops prime` works with or without a selected worker.
|
|
62
|
+
- `briefops prime --format codex --max-tokens 800` emits a compact context contract, not a full resume pack.
|
|
63
|
+
- `briefops worker use <worker>` stores a safe default worker for future thread starts.
|
|
64
|
+
- Token-budget tests prove prime output is bounded and avoids full history dumps.
|
|
65
|
+
|
|
66
|
+
### Stage 3: Safety, Conflict, And Export Controls
|
|
67
|
+
|
|
68
|
+
Goal: Prevent local data corruption and accidental context leakage as usage increases across threads/projects.
|
|
69
|
+
|
|
70
|
+
Done when:
|
|
71
|
+
|
|
72
|
+
- Write-heavy flows use workspace-level locking and atomic file writes.
|
|
73
|
+
- Memory export policy is explicit for packs and prime output.
|
|
74
|
+
- `briefops doctor --security` reports unsafe config, stale locks, invalid YAML, and pending proposals.
|
|
75
|
+
- Race-condition and export-policy tests pass.
|
|
76
|
+
|
|
77
|
+
### Stage 4: Open Source Accessibility And Validation
|
|
78
|
+
|
|
79
|
+
Goal: Make the workflow easy to adopt and maintain as an open source local-first tool.
|
|
80
|
+
|
|
81
|
+
Done when:
|
|
82
|
+
|
|
83
|
+
- README and quickstart show a 5-minute Codex App path with no hosted service.
|
|
84
|
+
- Example fixture demonstrates before/after token savings.
|
|
85
|
+
- Evals verify prime context quality and bounded-token behavior.
|
|
86
|
+
- Release packaging includes plugin files and docs.
|
|
87
|
+
|
|
88
|
+
## File Structure
|
|
89
|
+
|
|
90
|
+
Create:
|
|
91
|
+
|
|
92
|
+
- `plugins/briefops-codex/.codex-plugin/plugin.json` - Codex plugin manifest.
|
|
93
|
+
- `plugins/briefops-codex/README.md` - local install and usage notes.
|
|
94
|
+
- `plugins/briefops-codex/skills/briefops-prime-context/SKILL.md` - mandatory start-of-thread skill.
|
|
95
|
+
- `plugins/briefops-codex/skills/briefops-finish-task/SKILL.md` - end-of-task recording workflow.
|
|
96
|
+
- `plugins/briefops-codex/skills/briefops-review-memory/SKILL.md` - human-approved memory review workflow.
|
|
97
|
+
- `plugins/briefops-codex/skills/briefops-continue-worker/SKILL.md` - fresh-thread resume workflow.
|
|
98
|
+
- `src/core/codexPlugin.ts` - plugin manifest/render/install helpers.
|
|
99
|
+
- `src/core/config.ts` - typed `.briefops/config.yaml` read/write helpers.
|
|
100
|
+
- `src/core/prime.ts` - compact first-context builder.
|
|
101
|
+
- `src/core/lock.ts` - workspace lock helper with stale-lock detection.
|
|
102
|
+
- `src/commands/prime.ts` - root `briefops prime` command.
|
|
103
|
+
- `tests/codex-plugin.test.ts` - plugin rendering/install tests.
|
|
104
|
+
- `tests/prime.test.ts` - compact context tests.
|
|
105
|
+
- `tests/safety.test.ts` - lock, atomic write, export policy tests.
|
|
106
|
+
- `examples/codex-first-context/README.md` - adoption scenario and expected token savings.
|
|
107
|
+
|
|
108
|
+
Modify:
|
|
109
|
+
|
|
110
|
+
- `package.json` - include `plugins`, docs, and examples in published files.
|
|
111
|
+
- `src/cli.ts` - register prime and config/worker default commands.
|
|
112
|
+
- `src/commands/codex.ts` - add `codex plugin install`, `codex plugin doctor`, and `codex prime`.
|
|
113
|
+
- `src/commands/worker.ts` - add `worker use <name>` and `worker current`.
|
|
114
|
+
- `src/commands/doctor.ts` - add `--security` mode.
|
|
115
|
+
- `src/core/storage.ts` - add atomic text/YAML writes.
|
|
116
|
+
- `src/core/workspace.ts` - initialize expanded config safely.
|
|
117
|
+
- `src/core/workflow.ts` - use locks in finish/continue/pack flows.
|
|
118
|
+
- `src/core/memory.ts` - use atomic writes and export filters.
|
|
119
|
+
- `src/core/memoryProposal.ts` - lock proposal apply/reject paths.
|
|
120
|
+
- `src/core/patch.ts` - lock skill patch apply paths.
|
|
121
|
+
- `README.md`, `docs/quickstart.md`, `docs/token-budget.md`, `docs/roadmap.md` - document the new workflow.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Task 1: Add Codex Plugin Rendering Core
|
|
126
|
+
|
|
127
|
+
**Files:**
|
|
128
|
+
|
|
129
|
+
- Create: `src/core/codexPlugin.ts`
|
|
130
|
+
- Create: `tests/codex-plugin.test.ts`
|
|
131
|
+
- Create: `plugins/briefops-codex/.codex-plugin/plugin.json`
|
|
132
|
+
- Create: `plugins/briefops-codex/skills/briefops-prime-context/SKILL.md`
|
|
133
|
+
- Create: `plugins/briefops-codex/skills/briefops-finish-task/SKILL.md`
|
|
134
|
+
- Create: `plugins/briefops-codex/skills/briefops-review-memory/SKILL.md`
|
|
135
|
+
- Create: `plugins/briefops-codex/skills/briefops-continue-worker/SKILL.md`
|
|
136
|
+
|
|
137
|
+
- [ ] **Step 1: Write failing plugin manifest tests**
|
|
138
|
+
|
|
139
|
+
Add tests that require a deterministic manifest and four skill files.
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
import { promises as fs } from "node:fs";
|
|
143
|
+
import path from "node:path";
|
|
144
|
+
import { describe, expect, it } from "vitest";
|
|
145
|
+
import {
|
|
146
|
+
buildCodexPluginManifest,
|
|
147
|
+
codexPluginFiles
|
|
148
|
+
} from "../src/core/codexPlugin.js";
|
|
149
|
+
|
|
150
|
+
describe("Codex plugin package", () => {
|
|
151
|
+
it("builds a local-first skill-only plugin manifest", () => {
|
|
152
|
+
const manifest = buildCodexPluginManifest();
|
|
153
|
+
|
|
154
|
+
expect(manifest.name).toBe("briefops");
|
|
155
|
+
expect(manifest.skills).toBe("./skills/");
|
|
156
|
+
expect(manifest.interface.displayName).toBe("BriefOps");
|
|
157
|
+
expect(manifest.interface.category).toBe("Developer Tools");
|
|
158
|
+
expect(manifest.interface.capabilities).toEqual(["Read", "Write"]);
|
|
159
|
+
expect(manifest.interface.shortDescription).toContain("local-first");
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("ships every Codex skill used by the manifest", async () => {
|
|
163
|
+
const files = codexPluginFiles();
|
|
164
|
+
const skillFiles = files.map((file) => file.relativePath).filter((file) => file.endsWith("SKILL.md"));
|
|
165
|
+
|
|
166
|
+
expect(skillFiles).toEqual([
|
|
167
|
+
"skills/briefops-prime-context/SKILL.md",
|
|
168
|
+
"skills/briefops-finish-task/SKILL.md",
|
|
169
|
+
"skills/briefops-review-memory/SKILL.md",
|
|
170
|
+
"skills/briefops-continue-worker/SKILL.md"
|
|
171
|
+
]);
|
|
172
|
+
|
|
173
|
+
for (const file of files) {
|
|
174
|
+
expect(file.content.trim().length).toBeGreaterThan(40);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it("keeps committed plugin files in sync with generated content", async () => {
|
|
179
|
+
const root = path.join(process.cwd(), "plugins/briefops-codex");
|
|
180
|
+
|
|
181
|
+
for (const file of codexPluginFiles()) {
|
|
182
|
+
const disk = await fs.readFile(path.join(root, file.relativePath), "utf8");
|
|
183
|
+
expect(disk).toBe(file.content);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
- [ ] **Step 2: Run tests and confirm failure**
|
|
190
|
+
|
|
191
|
+
Run:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
npm test -- tests/codex-plugin.test.ts
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Expected: fail because `src/core/codexPlugin.ts` does not exist.
|
|
198
|
+
|
|
199
|
+
- [ ] **Step 3: Implement `src/core/codexPlugin.ts`**
|
|
200
|
+
|
|
201
|
+
Implement pure render helpers first. Do not read or write the filesystem in these functions.
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
export type CodexPluginManifest = {
|
|
205
|
+
name: string;
|
|
206
|
+
version: string;
|
|
207
|
+
description: string;
|
|
208
|
+
author: { name: string; url: string };
|
|
209
|
+
homepage: string;
|
|
210
|
+
repository: string;
|
|
211
|
+
license: string;
|
|
212
|
+
keywords: string[];
|
|
213
|
+
skills: string;
|
|
214
|
+
interface: {
|
|
215
|
+
displayName: string;
|
|
216
|
+
shortDescription: string;
|
|
217
|
+
longDescription: string;
|
|
218
|
+
developerName: string;
|
|
219
|
+
category: string;
|
|
220
|
+
capabilities: string[];
|
|
221
|
+
defaultPrompt: string[];
|
|
222
|
+
websiteURL: string;
|
|
223
|
+
brandColor: string;
|
|
224
|
+
screenshots: string[];
|
|
225
|
+
};
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export type CodexPluginFile = {
|
|
229
|
+
relativePath: string;
|
|
230
|
+
content: string;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export function buildCodexPluginManifest(): CodexPluginManifest {
|
|
234
|
+
return {
|
|
235
|
+
name: "briefops",
|
|
236
|
+
version: "0.2.0-alpha.0",
|
|
237
|
+
description: "Local-first, token-aware persistent work history for Codex workflows.",
|
|
238
|
+
author: {
|
|
239
|
+
name: "Simon",
|
|
240
|
+
url: "https://github.com/simony-816/briefops"
|
|
241
|
+
},
|
|
242
|
+
homepage: "https://github.com/simony-816/briefops",
|
|
243
|
+
repository: "https://github.com/simony-816/briefops",
|
|
244
|
+
license: "MIT",
|
|
245
|
+
keywords: ["codex", "local-first", "context", "memory", "handoff", "workflow"],
|
|
246
|
+
skills: "./skills/",
|
|
247
|
+
interface: {
|
|
248
|
+
displayName: "BriefOps",
|
|
249
|
+
shortDescription: "Local-first context priming and continuity for Codex",
|
|
250
|
+
longDescription:
|
|
251
|
+
"Use BriefOps to prime Codex with compact local context, record task outcomes, review durable memory proposals, and resume persistent workers without hosted services.",
|
|
252
|
+
developerName: "BriefOps contributors",
|
|
253
|
+
category: "Developer Tools",
|
|
254
|
+
capabilities: ["Read", "Write"],
|
|
255
|
+
defaultPrompt: [
|
|
256
|
+
"Start this task with the smallest useful BriefOps context.",
|
|
257
|
+
"Finish this task and prepare memory for the next thread."
|
|
258
|
+
],
|
|
259
|
+
websiteURL: "https://github.com/simony-816/briefops",
|
|
260
|
+
brandColor: "#2563EB",
|
|
261
|
+
screenshots: []
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
- [ ] **Step 4: Add skill content renderers**
|
|
268
|
+
|
|
269
|
+
Each skill must preserve the local-first model and avoid auto-approval.
|
|
270
|
+
|
|
271
|
+
`briefops-prime-context` core instructions:
|
|
272
|
+
|
|
273
|
+
```md
|
|
274
|
+
---
|
|
275
|
+
name: briefops-prime-context
|
|
276
|
+
description: Use when starting work in any Codex project or fresh thread to load the smallest useful BriefOps context before reading large history files
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
# BriefOps Prime Context
|
|
280
|
+
|
|
281
|
+
Use BriefOps before broad repo/history inspection when a `.briefops` workspace exists or may exist.
|
|
282
|
+
|
|
283
|
+
Run:
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
briefops prime --format codex --task "<current user task>" --max-tokens 800
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
If the command reports that no workspace exists, keep the response short and suggest `briefops init`.
|
|
290
|
+
|
|
291
|
+
Never apply memory automatically. If pending proposals exist, show the review command.
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
- [ ] **Step 5: Commit static plugin files**
|
|
295
|
+
|
|
296
|
+
Write generated content to:
|
|
297
|
+
|
|
298
|
+
```text
|
|
299
|
+
plugins/briefops-codex/.codex-plugin/plugin.json
|
|
300
|
+
plugins/briefops-codex/skills/*/SKILL.md
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
- [ ] **Step 6: Verify tests pass**
|
|
304
|
+
|
|
305
|
+
Run:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
npm test -- tests/codex-plugin.test.ts
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Expected: pass.
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Task 2: Add Local Plugin Install And Doctor Commands
|
|
316
|
+
|
|
317
|
+
**Files:**
|
|
318
|
+
|
|
319
|
+
- Modify: `src/core/codexPlugin.ts`
|
|
320
|
+
- Modify: `src/commands/codex.ts`
|
|
321
|
+
- Modify: `tests/codex-plugin.test.ts`
|
|
322
|
+
- Modify: `tests/cli-workflow.test.ts`
|
|
323
|
+
|
|
324
|
+
- [ ] **Step 1: Write failing installer tests**
|
|
325
|
+
|
|
326
|
+
Add tests that install the plugin into the workspace, not into user-global Codex folders.
|
|
327
|
+
|
|
328
|
+
```ts
|
|
329
|
+
import { installCodexPlugin } from "../src/core/codexPlugin.js";
|
|
330
|
+
import { initWorkspace } from "../src/core/workspace.js";
|
|
331
|
+
import { withTempDir } from "./helpers.js";
|
|
332
|
+
|
|
333
|
+
it("installs a local Codex plugin bundle under .briefops", async () => {
|
|
334
|
+
await withTempDir(async (dir) => {
|
|
335
|
+
await initWorkspace(dir);
|
|
336
|
+
const result = await installCodexPlugin({ cwd: dir });
|
|
337
|
+
|
|
338
|
+
expect(result.root).toContain(".briefops/codex/plugin/briefops");
|
|
339
|
+
expect(result.files).toContain(".codex-plugin/plugin.json");
|
|
340
|
+
expect(result.files).toContain("skills/briefops-prime-context/SKILL.md");
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
- [ ] **Step 2: Implement installer with no global side effects**
|
|
346
|
+
|
|
347
|
+
Add:
|
|
348
|
+
|
|
349
|
+
```ts
|
|
350
|
+
export async function installCodexPlugin(options: { cwd?: string; force?: boolean } = {}): Promise<{
|
|
351
|
+
root: string;
|
|
352
|
+
files: string[];
|
|
353
|
+
}> {
|
|
354
|
+
const cwd = options.cwd ?? process.cwd();
|
|
355
|
+
await requireWorkspace(cwd);
|
|
356
|
+
const root = path.join(workspacePaths(cwd).codex, "plugin", "briefops");
|
|
357
|
+
const files: string[] = [];
|
|
358
|
+
|
|
359
|
+
for (const file of codexPluginFiles()) {
|
|
360
|
+
const target = path.join(root, file.relativePath);
|
|
361
|
+
await writeTextFile(target, file.content, { force: options.force ?? true });
|
|
362
|
+
files.push(file.relativePath);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return { root, files };
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
- [ ] **Step 3: Add `briefops codex plugin install`**
|
|
370
|
+
|
|
371
|
+
In `src/commands/codex.ts`, add:
|
|
372
|
+
|
|
373
|
+
```ts
|
|
374
|
+
const plugin = codex.command("plugin").description("Manage local BriefOps Codex plugin assets.");
|
|
375
|
+
|
|
376
|
+
plugin
|
|
377
|
+
.command("install")
|
|
378
|
+
.description("Install the BriefOps Codex plugin bundle into .briefops/codex/plugin.")
|
|
379
|
+
.option("--force", "Overwrite generated plugin files.")
|
|
380
|
+
.action(async (options: Record<string, unknown>) => {
|
|
381
|
+
const result = await installCodexPlugin({ force: Boolean(options.force) });
|
|
382
|
+
console.log("BriefOps Codex plugin bundle installed.");
|
|
383
|
+
console.log(`Plugin: ${result.root}`);
|
|
384
|
+
console.log("Next: install this local plugin folder in Codex, or use the generated skills as repo guidance.");
|
|
385
|
+
});
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
- [ ] **Step 4: Add plugin doctor**
|
|
389
|
+
|
|
390
|
+
`briefops codex plugin doctor` should compare generated files with installed files and report `ok`, `missing`, or `changed`.
|
|
391
|
+
|
|
392
|
+
- [ ] **Step 5: Verify CLI workflow**
|
|
393
|
+
|
|
394
|
+
Run:
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
npm test -- tests/codex-plugin.test.ts tests/cli-workflow.test.ts
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Expected: pass.
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## Task 3: Add Typed Config And Default Worker Selection
|
|
405
|
+
|
|
406
|
+
**Files:**
|
|
407
|
+
|
|
408
|
+
- Create: `src/core/config.ts`
|
|
409
|
+
- Modify: `src/core/workspace.ts`
|
|
410
|
+
- Modify: `src/commands/worker.ts`
|
|
411
|
+
- Create: `tests/config.test.ts`
|
|
412
|
+
|
|
413
|
+
- [ ] **Step 1: Write failing config tests**
|
|
414
|
+
|
|
415
|
+
```ts
|
|
416
|
+
import { readBriefOpsConfig, setDefaultWorker } from "../src/core/config.js";
|
|
417
|
+
|
|
418
|
+
it("stores a default worker for thread starts", async () => {
|
|
419
|
+
await withTempDir(async (dir) => {
|
|
420
|
+
await seedContinuityWorkspace(dir);
|
|
421
|
+
await setDefaultWorker({ cwd: dir, worker: "quant-reviewer" });
|
|
422
|
+
|
|
423
|
+
const config = await readBriefOpsConfig(dir);
|
|
424
|
+
expect(config.defaults.worker).toBe("quant-reviewer");
|
|
425
|
+
expect(config.defaults.project).toBe("atlas-q");
|
|
426
|
+
});
|
|
427
|
+
});
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
- [ ] **Step 2: Implement config schema**
|
|
431
|
+
|
|
432
|
+
Config shape:
|
|
433
|
+
|
|
434
|
+
```yaml
|
|
435
|
+
version: 0.2.0
|
|
436
|
+
created_at: "2026-06-08T00:00:00.000Z"
|
|
437
|
+
defaults:
|
|
438
|
+
project: atlas-q
|
|
439
|
+
worker: quant-reviewer
|
|
440
|
+
token_budgets:
|
|
441
|
+
prime: 800
|
|
442
|
+
resume: 3000
|
|
443
|
+
memory_categories:
|
|
444
|
+
- facts
|
|
445
|
+
- decisions
|
|
446
|
+
- lessons
|
|
447
|
+
- incidents
|
|
448
|
+
- deprecated
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
- [ ] **Step 3: Add `worker use` and `worker current`**
|
|
452
|
+
|
|
453
|
+
Commands:
|
|
454
|
+
|
|
455
|
+
```bash
|
|
456
|
+
briefops worker use quant-reviewer
|
|
457
|
+
briefops worker current
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
`worker use` must fail if the worker does not exist.
|
|
461
|
+
|
|
462
|
+
- [ ] **Step 4: Preserve backward compatibility**
|
|
463
|
+
|
|
464
|
+
When reading old config files without `defaults` or `token_budgets`, return defaults in memory and write the expanded shape only when a command changes config.
|
|
465
|
+
|
|
466
|
+
- [ ] **Step 5: Verify**
|
|
467
|
+
|
|
468
|
+
Run:
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
npm test -- tests/config.test.ts tests/persistent-worker.test.ts
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
Expected: pass.
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
## Task 4: Implement Compact Prime Context Core
|
|
479
|
+
|
|
480
|
+
**Files:**
|
|
481
|
+
|
|
482
|
+
- Create: `src/core/prime.ts`
|
|
483
|
+
- Create: `tests/prime.test.ts`
|
|
484
|
+
- Modify: `src/core/continuity.ts`
|
|
485
|
+
- Modify: `src/core/inbox.ts`
|
|
486
|
+
|
|
487
|
+
- [ ] **Step 1: Write failing prime tests**
|
|
488
|
+
|
|
489
|
+
```ts
|
|
490
|
+
import { primeContext } from "../src/core/prime.js";
|
|
491
|
+
|
|
492
|
+
it("returns a short setup response when no workspace exists", async () => {
|
|
493
|
+
await withTempDir(async (dir) => {
|
|
494
|
+
const result = await primeContext({
|
|
495
|
+
cwd: dir,
|
|
496
|
+
task: "Start work.",
|
|
497
|
+
maxTokens: 300,
|
|
498
|
+
format: "codex"
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
expect(result.status).toBe("setup-required");
|
|
502
|
+
expect(result.content).toContain("briefops init");
|
|
503
|
+
expect(result.tokens).toBeLessThanOrEqual(300);
|
|
504
|
+
});
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it("emits compact ready context without full resume pack content", async () => {
|
|
508
|
+
await withTempDir(async (dir) => {
|
|
509
|
+
await seedContinuityWorkspace(dir);
|
|
510
|
+
await setDefaultWorker({ cwd: dir, worker: "quant-reviewer" });
|
|
511
|
+
|
|
512
|
+
const result = await primeContext({
|
|
513
|
+
cwd: dir,
|
|
514
|
+
task: "Continue unresolved slippage checks.",
|
|
515
|
+
maxTokens: 800,
|
|
516
|
+
format: "codex"
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
expect(result.status).toBe("ready");
|
|
520
|
+
expect(result.content).toContain("# BriefOps Prime Context");
|
|
521
|
+
expect(result.content).toContain("quant-reviewer");
|
|
522
|
+
expect(result.content).toContain("Token Budget");
|
|
523
|
+
expect(result.content).not.toContain("# BriefOps Portable Resume Pack");
|
|
524
|
+
expect(result.tokens).toBeLessThanOrEqual(800);
|
|
525
|
+
});
|
|
526
|
+
});
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
- [ ] **Step 2: Implement prime options**
|
|
530
|
+
|
|
531
|
+
```ts
|
|
532
|
+
export type PrimeContextOptions = {
|
|
533
|
+
cwd?: string;
|
|
534
|
+
worker?: string;
|
|
535
|
+
project?: string;
|
|
536
|
+
task?: string;
|
|
537
|
+
maxTokens?: number;
|
|
538
|
+
format?: "markdown" | "codex";
|
|
539
|
+
exportPolicy?: "local-private" | "shared-only";
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
export type PrimeContextResult = {
|
|
543
|
+
status: "ready" | "attention-required" | "setup-required";
|
|
544
|
+
content: string;
|
|
545
|
+
tokens: number;
|
|
546
|
+
warnings: string[];
|
|
547
|
+
};
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
- [ ] **Step 3: Resolve worker with low-token rules**
|
|
551
|
+
|
|
552
|
+
Resolution order:
|
|
553
|
+
|
|
554
|
+
1. `--worker`.
|
|
555
|
+
2. `.briefops/config.yaml` `defaults.worker`.
|
|
556
|
+
3. The only active worker if exactly one exists.
|
|
557
|
+
4. Setup response asking the user to run `briefops worker use <worker>`.
|
|
558
|
+
|
|
559
|
+
- [ ] **Step 4: Render compact context**
|
|
560
|
+
|
|
561
|
+
Output sections:
|
|
562
|
+
|
|
563
|
+
```md
|
|
564
|
+
# BriefOps Prime Context
|
|
565
|
+
|
|
566
|
+
## Current Task
|
|
567
|
+
|
|
568
|
+
## Worker
|
|
569
|
+
|
|
570
|
+
## Continuity Status
|
|
571
|
+
|
|
572
|
+
## Highest-Value Memory
|
|
573
|
+
|
|
574
|
+
## Open Risks And Next Steps
|
|
575
|
+
|
|
576
|
+
## Pending User Review
|
|
577
|
+
|
|
578
|
+
## Recommended Commands
|
|
579
|
+
|
|
580
|
+
## Token Budget
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
Do not include full handoff, full resume, full logs, or file dumps.
|
|
584
|
+
|
|
585
|
+
- [ ] **Step 5: Verify token budget behavior**
|
|
586
|
+
|
|
587
|
+
Use `truncateToTokenBudget` and existing `estimateTokens`. When content exceeds budget, trim memory/log sections before trimming required safety sections.
|
|
588
|
+
|
|
589
|
+
- [ ] **Step 6: Run tests**
|
|
590
|
+
|
|
591
|
+
```bash
|
|
592
|
+
npm test -- tests/prime.test.ts tests/persistent-worker.test.ts
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
Expected: pass.
|
|
596
|
+
|
|
597
|
+
---
|
|
598
|
+
|
|
599
|
+
## Task 5: Add Prime CLI And Codex Alias
|
|
600
|
+
|
|
601
|
+
**Files:**
|
|
602
|
+
|
|
603
|
+
- Create: `src/commands/prime.ts`
|
|
604
|
+
- Modify: `src/cli.ts`
|
|
605
|
+
- Modify: `src/commands/codex.ts`
|
|
606
|
+
- Modify: `tests/cli-workflow.test.ts`
|
|
607
|
+
|
|
608
|
+
- [ ] **Step 1: Add root command**
|
|
609
|
+
|
|
610
|
+
Command:
|
|
611
|
+
|
|
612
|
+
```bash
|
|
613
|
+
briefops prime --task "..." --worker quant-reviewer --max-tokens 800 --format codex
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
Options:
|
|
617
|
+
|
|
618
|
+
```text
|
|
619
|
+
--task <task>
|
|
620
|
+
--worker <worker>
|
|
621
|
+
--project <project>
|
|
622
|
+
--max-tokens <tokens>
|
|
623
|
+
--format <markdown|codex>
|
|
624
|
+
--export-policy <local-private|shared-only>
|
|
625
|
+
--save
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
- [ ] **Step 2: Add Codex alias**
|
|
629
|
+
|
|
630
|
+
Command:
|
|
631
|
+
|
|
632
|
+
```bash
|
|
633
|
+
briefops codex prime --task "..." --max-tokens 800
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
This calls the same core function with `format: "codex"`.
|
|
637
|
+
|
|
638
|
+
- [ ] **Step 3: Register command**
|
|
639
|
+
|
|
640
|
+
In `src/cli.ts`:
|
|
641
|
+
|
|
642
|
+
```ts
|
|
643
|
+
import { registerPrimeCommand } from "./commands/prime.js";
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
Register immediately after `registerDoctorCommand(program)` so it is visible near the top of help output.
|
|
647
|
+
|
|
648
|
+
- [ ] **Step 4: CLI test**
|
|
649
|
+
|
|
650
|
+
Add a test that runs:
|
|
651
|
+
|
|
652
|
+
```bash
|
|
653
|
+
briefops prime --task "Continue unresolved checks." --max-tokens 800
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
Expected stdout contains:
|
|
657
|
+
|
|
658
|
+
```text
|
|
659
|
+
BriefOps Prime Context
|
|
660
|
+
Token Budget
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
Expected stderr contains:
|
|
664
|
+
|
|
665
|
+
```text
|
|
666
|
+
Estimated tokens:
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
- [ ] **Step 5: Verify**
|
|
670
|
+
|
|
671
|
+
```bash
|
|
672
|
+
npm test -- tests/prime.test.ts tests/cli-workflow.test.ts
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
Expected: pass.
|
|
676
|
+
|
|
677
|
+
---
|
|
678
|
+
|
|
679
|
+
## Task 6: Add Atomic Writes And Workspace Locks
|
|
680
|
+
|
|
681
|
+
**Files:**
|
|
682
|
+
|
|
683
|
+
- Create: `src/core/lock.ts`
|
|
684
|
+
- Modify: `src/core/storage.ts`
|
|
685
|
+
- Modify: `tests/safety.test.ts`
|
|
686
|
+
|
|
687
|
+
- [ ] **Step 1: Write failing lock tests**
|
|
688
|
+
|
|
689
|
+
```ts
|
|
690
|
+
import { withWorkspaceLock } from "../src/core/lock.js";
|
|
691
|
+
|
|
692
|
+
it("prevents two writers from holding the same workspace lock", async () => {
|
|
693
|
+
await withTempDir(async (dir) => {
|
|
694
|
+
await initWorkspace(dir);
|
|
695
|
+
const first = withWorkspaceLock({ cwd: dir, name: "memory" }, async () => {
|
|
696
|
+
await expect(
|
|
697
|
+
withWorkspaceLock({ cwd: dir, name: "memory", timeoutMs: 50 }, async () => "second")
|
|
698
|
+
).rejects.toThrow("BriefOps workspace lock is already held");
|
|
699
|
+
return "first";
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
await expect(first).resolves.toBe("first");
|
|
703
|
+
});
|
|
704
|
+
});
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
- [ ] **Step 2: Implement `withWorkspaceLock`**
|
|
708
|
+
|
|
709
|
+
Use local lock files under `.briefops/.locks/<name>.lock`.
|
|
710
|
+
|
|
711
|
+
Rules:
|
|
712
|
+
|
|
713
|
+
- Create lock using exclusive file creation.
|
|
714
|
+
- Include pid, command name when available, and timestamp.
|
|
715
|
+
- Treat locks older than 30 minutes as stale.
|
|
716
|
+
- Always remove the lock in `finally`.
|
|
717
|
+
|
|
718
|
+
- [ ] **Step 3: Add atomic write helpers**
|
|
719
|
+
|
|
720
|
+
In `src/core/storage.ts`:
|
|
721
|
+
|
|
722
|
+
```ts
|
|
723
|
+
export async function writeTextFileAtomic(filePath: string, content: string): Promise<void>
|
|
724
|
+
export async function writeYamlFileAtomic(filePath: string, value: unknown): Promise<void>
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
Implementation writes to sibling temp file and renames it into place.
|
|
728
|
+
|
|
729
|
+
- [ ] **Step 4: Verify**
|
|
730
|
+
|
|
731
|
+
```bash
|
|
732
|
+
npm test -- tests/safety.test.ts
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
Expected: pass.
|
|
736
|
+
|
|
737
|
+
---
|
|
738
|
+
|
|
739
|
+
## Task 7: Apply Locks To Write-Heavy Flows
|
|
740
|
+
|
|
741
|
+
**Files:**
|
|
742
|
+
|
|
743
|
+
- Modify: `src/core/memory.ts`
|
|
744
|
+
- Modify: `src/core/memoryProposal.ts`
|
|
745
|
+
- Modify: `src/core/patch.ts`
|
|
746
|
+
- Modify: `src/core/workflow.ts`
|
|
747
|
+
- Modify: `src/core/worker.ts`
|
|
748
|
+
- Modify: `src/core/handoff.ts`
|
|
749
|
+
- Modify: `tests/safety.test.ts`
|
|
750
|
+
|
|
751
|
+
- [ ] **Step 1: Lock memory mutation**
|
|
752
|
+
|
|
753
|
+
Wrap these operations:
|
|
754
|
+
|
|
755
|
+
```text
|
|
756
|
+
addMemory
|
|
757
|
+
updateMemoryStatus
|
|
758
|
+
applyMemoryProposal
|
|
759
|
+
rejectMemoryProposal
|
|
760
|
+
approveMemory
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
Use lock name:
|
|
764
|
+
|
|
765
|
+
```text
|
|
766
|
+
memory
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
- [ ] **Step 2: Lock workflow mutation**
|
|
770
|
+
|
|
771
|
+
Wrap:
|
|
772
|
+
|
|
773
|
+
```text
|
|
774
|
+
finishWork
|
|
775
|
+
continueWork
|
|
776
|
+
packResume when writing output
|
|
777
|
+
refreshWorkerSummary
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
Use lock names:
|
|
781
|
+
|
|
782
|
+
```text
|
|
783
|
+
workflow
|
|
784
|
+
worker-summary
|
|
785
|
+
pack
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
- [ ] **Step 3: Keep read-only commands lock-free**
|
|
789
|
+
|
|
790
|
+
Do not lock:
|
|
791
|
+
|
|
792
|
+
```text
|
|
793
|
+
primeContext
|
|
794
|
+
inspectContinuityHealth
|
|
795
|
+
getInboxSummary
|
|
796
|
+
listMemory
|
|
797
|
+
generateWorkerIntelligence when save=false
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
- [ ] **Step 4: Regression tests**
|
|
801
|
+
|
|
802
|
+
Run:
|
|
803
|
+
|
|
804
|
+
```bash
|
|
805
|
+
npm test -- tests/safety.test.ts tests/persistent-worker.test.ts tests/cli-workflow.test.ts
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
Expected: pass.
|
|
809
|
+
|
|
810
|
+
---
|
|
811
|
+
|
|
812
|
+
## Task 8: Add Export Policy Controls
|
|
813
|
+
|
|
814
|
+
**Files:**
|
|
815
|
+
|
|
816
|
+
- Modify: `src/core/prime.ts`
|
|
817
|
+
- Modify: `src/core/workflow.ts`
|
|
818
|
+
- Modify: `src/commands/pack.ts`
|
|
819
|
+
- Modify: `src/commands/prime.ts`
|
|
820
|
+
- Modify: `tests/prime.test.ts`
|
|
821
|
+
- Modify: `tests/safety.test.ts`
|
|
822
|
+
|
|
823
|
+
- [ ] **Step 1: Define export policy**
|
|
824
|
+
|
|
825
|
+
Policy values:
|
|
826
|
+
|
|
827
|
+
```text
|
|
828
|
+
local-private: default; allowed for local terminal/Codex use
|
|
829
|
+
shared-only: include only memory items with visibility=shared and exportable=true
|
|
830
|
+
```
|
|
831
|
+
|
|
832
|
+
- [ ] **Step 2: Test shared-only filtering**
|
|
833
|
+
|
|
834
|
+
```ts
|
|
835
|
+
it("filters private memory when export policy is shared-only", async () => {
|
|
836
|
+
await withTempDir(async (dir) => {
|
|
837
|
+
await seedContinuityWorkspace(dir);
|
|
838
|
+
await addMemory({
|
|
839
|
+
cwd: dir,
|
|
840
|
+
type: "lessons",
|
|
841
|
+
project: "atlas-q",
|
|
842
|
+
skill: "risk-review",
|
|
843
|
+
content: "Private local lesson.",
|
|
844
|
+
visibility: "private",
|
|
845
|
+
exportable: false
|
|
846
|
+
});
|
|
847
|
+
await addMemory({
|
|
848
|
+
cwd: dir,
|
|
849
|
+
type: "lessons",
|
|
850
|
+
project: "atlas-q",
|
|
851
|
+
skill: "risk-review",
|
|
852
|
+
content: "Shared exportable lesson.",
|
|
853
|
+
visibility: "shared",
|
|
854
|
+
exportable: true
|
|
855
|
+
});
|
|
856
|
+
|
|
857
|
+
const result = await primeContext({
|
|
858
|
+
cwd: dir,
|
|
859
|
+
worker: "quant-reviewer",
|
|
860
|
+
task: "Continue review.",
|
|
861
|
+
exportPolicy: "shared-only"
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
expect(result.content).toContain("Shared exportable lesson.");
|
|
865
|
+
expect(result.content).not.toContain("Private local lesson.");
|
|
866
|
+
});
|
|
867
|
+
});
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
- [ ] **Step 3: Add command options**
|
|
871
|
+
|
|
872
|
+
Commands:
|
|
873
|
+
|
|
874
|
+
```bash
|
|
875
|
+
briefops prime --export-policy shared-only
|
|
876
|
+
briefops pack resume --export-policy shared-only
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
- [ ] **Step 4: Add warning text**
|
|
880
|
+
|
|
881
|
+
When using `local-private`, include:
|
|
882
|
+
|
|
883
|
+
```text
|
|
884
|
+
This context may include private local BriefOps memory. Review before sharing outside this machine.
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
- [ ] **Step 5: Verify**
|
|
888
|
+
|
|
889
|
+
```bash
|
|
890
|
+
npm test -- tests/prime.test.ts tests/safety.test.ts tests/persistent-worker.test.ts
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
Expected: pass.
|
|
894
|
+
|
|
895
|
+
---
|
|
896
|
+
|
|
897
|
+
## Task 9: Add `doctor --security`
|
|
898
|
+
|
|
899
|
+
**Files:**
|
|
900
|
+
|
|
901
|
+
- Modify: `src/commands/doctor.ts`
|
|
902
|
+
- Create: `src/core/securityDoctor.ts`
|
|
903
|
+
- Modify: `tests/safety.test.ts`
|
|
904
|
+
|
|
905
|
+
- [ ] **Step 1: Add security checks**
|
|
906
|
+
|
|
907
|
+
Report:
|
|
908
|
+
|
|
909
|
+
```text
|
|
910
|
+
Workspace exists
|
|
911
|
+
Config YAML valid
|
|
912
|
+
Memory YAML files valid
|
|
913
|
+
Pending memory proposals
|
|
914
|
+
Pending skill patches
|
|
915
|
+
Stale lock files
|
|
916
|
+
Private exportable memory items
|
|
917
|
+
Missing default worker
|
|
918
|
+
Default worker points to missing file
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
- [ ] **Step 2: Exit behavior**
|
|
922
|
+
|
|
923
|
+
Exit code:
|
|
924
|
+
|
|
925
|
+
- `0` when all checks are ok or advisory.
|
|
926
|
+
- `1` when invalid YAML, stale lock, or missing default worker target is found.
|
|
927
|
+
|
|
928
|
+
- [ ] **Step 3: Verify**
|
|
929
|
+
|
|
930
|
+
```bash
|
|
931
|
+
npm test -- tests/safety.test.ts
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
Expected: pass.
|
|
935
|
+
|
|
936
|
+
---
|
|
937
|
+
|
|
938
|
+
## Task 10: Add Token-Savings Fixture And Eval
|
|
939
|
+
|
|
940
|
+
**Files:**
|
|
941
|
+
|
|
942
|
+
- Create: `examples/codex-first-context/README.md`
|
|
943
|
+
- Create: `examples/codex-first-context/before-manual-history-dump.md`
|
|
944
|
+
- Create: `examples/codex-first-context/after-briefops-prime.md`
|
|
945
|
+
- Create: `.briefops/evals/prime-context.eval.yaml` if evals are intended to live in a workspace fixture.
|
|
946
|
+
- Modify: `docs/evals.md`
|
|
947
|
+
- Modify: `tests/prime.test.ts`
|
|
948
|
+
|
|
949
|
+
- [ ] **Step 1: Create example scenario**
|
|
950
|
+
|
|
951
|
+
Use the same `atlas-q` style fixture and compare:
|
|
952
|
+
|
|
953
|
+
```text
|
|
954
|
+
Manual history dump: project README + logs + memory files + handoff
|
|
955
|
+
BriefOps prime: compact selected context
|
|
956
|
+
```
|
|
957
|
+
|
|
958
|
+
- [ ] **Step 2: Add token comparison**
|
|
959
|
+
|
|
960
|
+
Use existing `estimateTokens` in a test to assert:
|
|
961
|
+
|
|
962
|
+
```ts
|
|
963
|
+
expect(primeTokens).toBeLessThan(manualTokens * 0.35);
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
- [ ] **Step 3: Document eval command**
|
|
967
|
+
|
|
968
|
+
Add to docs:
|
|
969
|
+
|
|
970
|
+
```bash
|
|
971
|
+
npm test -- tests/prime.test.ts
|
|
972
|
+
briefops eval run prime-context
|
|
973
|
+
```
|
|
974
|
+
|
|
975
|
+
- [ ] **Step 4: Verify**
|
|
976
|
+
|
|
977
|
+
```bash
|
|
978
|
+
npm test -- tests/prime.test.ts tests/token.test.ts
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
Expected: pass.
|
|
982
|
+
|
|
983
|
+
---
|
|
984
|
+
|
|
985
|
+
## Task 11: Update Open Source Docs And Packaging
|
|
986
|
+
|
|
987
|
+
**Files:**
|
|
988
|
+
|
|
989
|
+
- Modify: `README.md`
|
|
990
|
+
- Modify: `docs/quickstart.md`
|
|
991
|
+
- Modify: `docs/token-budget.md`
|
|
992
|
+
- Modify: `docs/roadmap.md`
|
|
993
|
+
- Modify: `package.json`
|
|
994
|
+
- Create: `plugins/briefops-codex/README.md`
|
|
995
|
+
|
|
996
|
+
- [ ] **Step 1: Update package files**
|
|
997
|
+
|
|
998
|
+
`package.json` `files` should include:
|
|
999
|
+
|
|
1000
|
+
```json
|
|
1001
|
+
[
|
|
1002
|
+
"dist",
|
|
1003
|
+
"plugins",
|
|
1004
|
+
"examples",
|
|
1005
|
+
"docs",
|
|
1006
|
+
"README.md",
|
|
1007
|
+
"LICENSE"
|
|
1008
|
+
]
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
- [ ] **Step 2: Update README positioning**
|
|
1012
|
+
|
|
1013
|
+
Keep the boundary explicit:
|
|
1014
|
+
|
|
1015
|
+
```md
|
|
1016
|
+
BriefOps is not a hosted memory service, agent runtime, vector database, or cloud sync product.
|
|
1017
|
+
```
|
|
1018
|
+
|
|
1019
|
+
Add:
|
|
1020
|
+
|
|
1021
|
+
```md
|
|
1022
|
+
BriefOps can ship Codex skill-plugin assets, but the plugin calls the local CLI and local `.briefops/` workspace.
|
|
1023
|
+
```
|
|
1024
|
+
|
|
1025
|
+
- [ ] **Step 3: Add 5-minute Codex App path**
|
|
1026
|
+
|
|
1027
|
+
Commands:
|
|
1028
|
+
|
|
1029
|
+
```bash
|
|
1030
|
+
npm install -g briefops
|
|
1031
|
+
briefops init
|
|
1032
|
+
briefops codex install
|
|
1033
|
+
briefops codex plugin install
|
|
1034
|
+
briefops worker use <worker>
|
|
1035
|
+
briefops prime --task "Start this task." --format codex
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
- [ ] **Step 4: Update roadmap**
|
|
1039
|
+
|
|
1040
|
+
Move these into near-term priorities:
|
|
1041
|
+
|
|
1042
|
+
```text
|
|
1043
|
+
Codex skill-only plugin
|
|
1044
|
+
compact prime context
|
|
1045
|
+
local safety/lock controls
|
|
1046
|
+
token-savings eval fixture
|
|
1047
|
+
```
|
|
1048
|
+
|
|
1049
|
+
Keep out of scope:
|
|
1050
|
+
|
|
1051
|
+
```text
|
|
1052
|
+
hosted server
|
|
1053
|
+
cloud sync
|
|
1054
|
+
required marketplace
|
|
1055
|
+
agent runtime
|
|
1056
|
+
vector database
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
- [ ] **Step 5: Verify package**
|
|
1060
|
+
|
|
1061
|
+
Run:
|
|
1062
|
+
|
|
1063
|
+
```bash
|
|
1064
|
+
npm run build
|
|
1065
|
+
npm test
|
|
1066
|
+
npm pack --dry-run
|
|
1067
|
+
```
|
|
1068
|
+
|
|
1069
|
+
Expected:
|
|
1070
|
+
|
|
1071
|
+
- Build passes.
|
|
1072
|
+
- Tests pass.
|
|
1073
|
+
- Dry run includes `plugins/briefops-codex`.
|
|
1074
|
+
|
|
1075
|
+
---
|
|
1076
|
+
|
|
1077
|
+
## Task 12: Final Integration Pass
|
|
1078
|
+
|
|
1079
|
+
**Files:**
|
|
1080
|
+
|
|
1081
|
+
- All files touched above.
|
|
1082
|
+
|
|
1083
|
+
- [ ] **Step 1: Run full verification**
|
|
1084
|
+
|
|
1085
|
+
```bash
|
|
1086
|
+
npm run build
|
|
1087
|
+
npm test
|
|
1088
|
+
```
|
|
1089
|
+
|
|
1090
|
+
Expected: pass.
|
|
1091
|
+
|
|
1092
|
+
- [ ] **Step 2: Manual smoke test in temp repo**
|
|
1093
|
+
|
|
1094
|
+
```bash
|
|
1095
|
+
tmpdir="$(mktemp -d)"
|
|
1096
|
+
cd "$tmpdir"
|
|
1097
|
+
briefops init
|
|
1098
|
+
briefops skill create risk-review
|
|
1099
|
+
briefops project create atlas-q
|
|
1100
|
+
briefops worker create quant-reviewer --project atlas-q --skills risk-review
|
|
1101
|
+
briefops worker use quant-reviewer
|
|
1102
|
+
briefops codex install
|
|
1103
|
+
briefops codex plugin install
|
|
1104
|
+
briefops prime --task "Continue unresolved checks." --format codex --max-tokens 800
|
|
1105
|
+
briefops finish --worker quant-reviewer --task "Review work" --result "Found unresolved risk." --lesson "Check unresolved risk before finishing."
|
|
1106
|
+
briefops prime --task "Continue unresolved risk review." --format codex --max-tokens 800
|
|
1107
|
+
```
|
|
1108
|
+
|
|
1109
|
+
Expected:
|
|
1110
|
+
|
|
1111
|
+
- Plugin bundle path is printed.
|
|
1112
|
+
- Prime output is compact.
|
|
1113
|
+
- Pending memory proposal is reported after finish.
|
|
1114
|
+
- Memory is not auto-approved.
|
|
1115
|
+
|
|
1116
|
+
- [ ] **Step 3: Review git diff**
|
|
1117
|
+
|
|
1118
|
+
```bash
|
|
1119
|
+
git diff --stat
|
|
1120
|
+
git diff -- plugins src tests docs examples package.json README.md
|
|
1121
|
+
```
|
|
1122
|
+
|
|
1123
|
+
Expected:
|
|
1124
|
+
|
|
1125
|
+
- No generated local `.briefops/` workspace content is committed unless intentionally part of examples.
|
|
1126
|
+
- No absolute local paths are committed in docs or plugin files.
|
|
1127
|
+
- No secret, token, or personal data appears.
|
|
1128
|
+
|
|
1129
|
+
- [ ] **Step 4: Commit in stage-sized commits**
|
|
1130
|
+
|
|
1131
|
+
Commit order:
|
|
1132
|
+
|
|
1133
|
+
```bash
|
|
1134
|
+
git add plugins src/core/codexPlugin.ts tests/codex-plugin.test.ts
|
|
1135
|
+
git commit -m "feat: add codex plugin assets"
|
|
1136
|
+
|
|
1137
|
+
git add src/core/config.ts src/core/prime.ts src/commands/prime.ts src/cli.ts src/commands/worker.ts tests/config.test.ts tests/prime.test.ts
|
|
1138
|
+
git commit -m "feat: add compact prime context workflow"
|
|
1139
|
+
|
|
1140
|
+
git add src/core/lock.ts src/core/storage.ts src/core/workflow.ts src/core/memory.ts src/core/memoryProposal.ts src/core/patch.ts src/commands/doctor.ts tests/safety.test.ts
|
|
1141
|
+
git commit -m "feat: harden local continuity writes"
|
|
1142
|
+
|
|
1143
|
+
git add README.md docs examples package.json
|
|
1144
|
+
git commit -m "docs: document codex first-context workflow"
|
|
1145
|
+
```
|
|
1146
|
+
|
|
1147
|
+
## Security And Exception Handling Notes
|
|
1148
|
+
|
|
1149
|
+
- Do not make any command write to `~/.codex`, `~/.agents`, or another global plugin folder by default.
|
|
1150
|
+
- Do not add hosted services, telemetry, or network calls.
|
|
1151
|
+
- Do not auto-apply memory proposals from any Codex skill.
|
|
1152
|
+
- Do not include private memory when `--export-policy shared-only` is set.
|
|
1153
|
+
- Do not let output paths silently overwrite files unless the command has explicit `--force`.
|
|
1154
|
+
- Do not resolve user-provided worker/project/skill names without `normalizeName`.
|
|
1155
|
+
- Do not treat plugin install as marketplace publishing; it is a local deterministic artifact.
|
|
1156
|
+
- Do not let stale lock files permanently block the workspace; stale locks must be reported and removable by `doctor --security`.
|
|
1157
|
+
|
|
1158
|
+
## Self-Review
|
|
1159
|
+
|
|
1160
|
+
Spec coverage:
|
|
1161
|
+
|
|
1162
|
+
- Four-stage development goal: covered by Stage 1 through Stage 4.
|
|
1163
|
+
- Token waste reduction: covered by compact `prime` workflow, token tests, and eval fixture.
|
|
1164
|
+
- Open source and accessible: covered by local plugin assets, npm packaging, docs, no hosted services.
|
|
1165
|
+
- Security and conflict management: covered by locks, atomic writes, export policy, and `doctor --security`.
|
|
1166
|
+
|
|
1167
|
+
Placeholder scan:
|
|
1168
|
+
|
|
1169
|
+
- No task depends on unspecified hosted infrastructure.
|
|
1170
|
+
- All new files and modified files are named explicitly.
|
|
1171
|
+
- Test commands and expected outcomes are included.
|
|
1172
|
+
|
|
1173
|
+
Type consistency:
|
|
1174
|
+
|
|
1175
|
+
- `PrimeContextOptions`, `PrimeContextResult`, `CodexPluginManifest`, and `CodexPluginFile` are defined before later tasks rely on them.
|
|
1176
|
+
- Command names stay consistent: `briefops prime`, `briefops codex prime`, `briefops codex plugin install`, `briefops worker use`, and `briefops doctor --security`.
|