@phyzess/pappra 0.0.0-stage → 0.1.0-beta.10
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/LICENSE +21 -0
- package/README.md +99 -2
- package/THIRD_PARTY_NOTICES.md +16 -0
- package/assets/integrations/skills/pappra/SKILL.md +71 -0
- package/assets/integrations/skills/pappra/references/hosts.md +40 -0
- package/assets/integrations/skills/pappra/references/lifecycle.md +41 -0
- package/assets/integrations/skills/pappra/references/operations.md +27 -0
- package/assets/manifest.json +4 -0
- package/dist/app/collaboration.d.ts +170 -0
- package/dist/app/collaboration.js +1643 -0
- package/dist/app/doctor.d.ts +9 -0
- package/dist/app/doctor.js +1030 -0
- package/dist/app/init.d.ts +171 -0
- package/dist/app/init.js +1442 -0
- package/dist/cli/commands/code.d.ts +16 -0
- package/dist/cli/commands/code.js +127 -0
- package/dist/cli/commands/collaboration.d.ts +13 -0
- package/dist/cli/commands/collaboration.js +186 -0
- package/dist/cli/commands/continuity.d.ts +29 -0
- package/dist/cli/commands/continuity.js +133 -0
- package/dist/cli/commands/docs.d.ts +12 -0
- package/dist/cli/commands/docs.js +234 -0
- package/dist/cli/commands/doctor.d.ts +14 -0
- package/dist/cli/commands/doctor.js +57 -0
- package/dist/cli/commands/host.d.ts +17 -0
- package/dist/cli/commands/host.js +199 -0
- package/dist/cli/commands/init.d.ts +59 -0
- package/dist/cli/commands/init.js +845 -0
- package/dist/cli/commands/runtime.d.ts +14 -0
- package/dist/cli/commands/runtime.js +263 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +10 -0
- package/dist/cli/output.d.ts +4 -0
- package/dist/cli/output.js +1 -0
- package/dist/cli/run.d.ts +2 -0
- package/dist/cli/run.js +749 -0
- package/dist/code/budget.d.ts +14 -0
- package/dist/code/budget.js +39 -0
- package/dist/code/exec.d.ts +23 -0
- package/dist/code/exec.js +133 -0
- package/dist/code/identity.d.ts +13 -0
- package/dist/code/identity.js +214 -0
- package/dist/code/index.d.ts +6 -0
- package/dist/code/index.js +3 -0
- package/dist/code/providers/codegraph.d.ts +59 -0
- package/dist/code/providers/codegraph.js +567 -0
- package/dist/code/registration.d.ts +9 -0
- package/dist/code/registration.js +293 -0
- package/dist/code/service.d.ts +53 -0
- package/dist/code/service.js +633 -0
- package/dist/code/text.d.ts +3 -0
- package/dist/code/text.js +202 -0
- package/dist/collab/admission.d.ts +450 -0
- package/dist/collab/admission.js +797 -0
- package/dist/collab/canonical.d.ts +26 -0
- package/dist/collab/canonical.js +136 -0
- package/dist/collab/contracts.d.ts +73 -0
- package/dist/collab/contracts.js +76 -0
- package/dist/collab/envelope.d.ts +52 -0
- package/dist/collab/envelope.js +241 -0
- package/dist/collab/fingerprint.d.ts +7 -0
- package/dist/collab/fingerprint.js +58 -0
- package/dist/collab/handoff.d.ts +350 -0
- package/dist/collab/handoff.js +513 -0
- package/dist/collab/index.d.ts +9 -0
- package/dist/collab/index.js +8 -0
- package/dist/collab/lifecycle.d.ts +449 -0
- package/dist/collab/lifecycle.js +534 -0
- package/dist/collab/messages.d.ts +148 -0
- package/dist/collab/messages.js +583 -0
- package/dist/collab/notify.d.ts +47 -0
- package/dist/collab/notify.js +140 -0
- package/dist/collab/preflight.d.ts +31 -0
- package/dist/collab/preflight.js +271 -0
- package/dist/collab/resources.d.ts +119 -0
- package/dist/collab/resources.js +451 -0
- package/dist/collab/store.d.ts +143 -0
- package/dist/collab/store.js +606 -0
- package/dist/collab/types.d.ts +354 -0
- package/dist/collab/types.js +1 -0
- package/dist/collab/validation.d.ts +10 -0
- package/dist/collab/validation.js +303 -0
- package/dist/continuity/context.d.ts +24 -0
- package/dist/continuity/context.js +179 -0
- package/dist/continuity/index.d.ts +3 -0
- package/dist/continuity/index.js +1 -0
- package/dist/continuity/paths.d.ts +37 -0
- package/dist/continuity/paths.js +258 -0
- package/dist/continuity/service.d.ts +59 -0
- package/dist/continuity/service.js +1258 -0
- package/dist/hosts/claude/native.d.ts +79 -0
- package/dist/hosts/claude/native.js +853 -0
- package/dist/hosts/codex/native.d.ts +345 -0
- package/dist/hosts/codex/native.js +1528 -0
- package/dist/hosts/codex/protocol.d.ts +51 -0
- package/dist/hosts/codex/protocol.js +42 -0
- package/dist/hosts/detect.d.ts +29 -0
- package/dist/hosts/detect.js +73 -0
- package/dist/hosts/index.d.ts +10 -0
- package/dist/hosts/index.js +10 -0
- package/dist/hosts/integration/bundle-export.d.ts +24 -0
- package/dist/hosts/integration/bundle-export.js +128 -0
- package/dist/hosts/integration/bundle.d.ts +19 -0
- package/dist/hosts/integration/bundle.js +99 -0
- package/dist/hosts/integration/hook-entry.d.ts +1 -0
- package/dist/hosts/integration/hook-entry.js +68 -0
- package/dist/hosts/integration/hook.d.ts +32 -0
- package/dist/hosts/integration/hook.js +781 -0
- package/dist/hosts/integration/pappra-extension-runtime.mjs +24610 -0
- package/dist/hosts/integration/pappra-hook.mjs +24728 -0
- package/dist/hosts/integration/pi-extension-runtime.d.ts +18 -0
- package/dist/hosts/integration/pi-extension-runtime.js +89 -0
- package/dist/hosts/integration/pi-template.d.ts +3 -0
- package/dist/hosts/integration/pi-template.js +5 -0
- package/dist/hosts/integration/service.d.ts +49 -0
- package/dist/hosts/integration/service.js +1421 -0
- package/dist/hosts/integration/support.d.ts +59 -0
- package/dist/hosts/integration/support.js +66 -0
- package/dist/hosts/integration/templates.d.ts +22 -0
- package/dist/hosts/integration/templates.js +75 -0
- package/dist/hosts/pi/protocol.d.ts +22 -0
- package/dist/hosts/pi/protocol.js +28 -0
- package/dist/hosts/pi/query-result.d.ts +22 -0
- package/dist/hosts/pi/query-result.js +710 -0
- package/dist/hosts/pi/rpc.d.ts +939 -0
- package/dist/hosts/pi/rpc.js +1659 -0
- package/dist/hosts/pilot.d.ts +485 -0
- package/dist/hosts/pilot.js +593 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +4 -0
- package/dist/infra/fs.d.ts +27 -0
- package/dist/infra/fs.js +130 -0
- package/dist/infra/git.d.ts +60 -0
- package/dist/infra/git.js +358 -0
- package/dist/infra/owned-process-group.d.ts +173 -0
- package/dist/infra/owned-process-group.js +571 -0
- package/dist/install/apply.d.ts +65 -0
- package/dist/install/apply.js +663 -0
- package/dist/install/index.d.ts +5 -0
- package/dist/install/index.js +5 -0
- package/dist/install/ownership.d.ts +85 -0
- package/dist/install/ownership.js +430 -0
- package/dist/install/plan.d.ts +39 -0
- package/dist/install/plan.js +97 -0
- package/dist/install/rollback.d.ts +18 -0
- package/dist/install/rollback.js +544 -0
- package/dist/install/runtime.d.ts +76 -0
- package/dist/install/runtime.js +1252 -0
- package/dist/knowledge/catalog.d.ts +47 -0
- package/dist/knowledge/catalog.js +308 -0
- package/dist/knowledge/context.d.ts +28 -0
- package/dist/knowledge/context.js +61 -0
- package/dist/knowledge/index.d.ts +3 -0
- package/dist/knowledge/index.js +1 -0
- package/dist/knowledge/journal.d.ts +16 -0
- package/dist/knowledge/journal.js +109 -0
- package/dist/knowledge/lifecycle.d.ts +8 -0
- package/dist/knowledge/lifecycle.js +1001 -0
- package/dist/knowledge/paths.d.ts +37 -0
- package/dist/knowledge/paths.js +236 -0
- package/dist/knowledge/refs.d.ts +36 -0
- package/dist/knowledge/refs.js +267 -0
- package/dist/knowledge/service.d.ts +21 -0
- package/dist/knowledge/service.js +393 -0
- package/dist/knowledge/types.d.ts +171 -0
- package/dist/knowledge/types.js +1 -0
- package/dist/knowledge/write.d.ts +8 -0
- package/dist/knowledge/write.js +1223 -0
- package/dist/package-info.d.ts +8 -0
- package/dist/package-info.js +25 -0
- package/dist/schemas/code.d.ts +377 -0
- package/dist/schemas/code.js +145 -0
- package/dist/schemas/collaboration.d.ts +115 -0
- package/dist/schemas/collaboration.js +106 -0
- package/dist/schemas/continuity.d.ts +315 -0
- package/dist/schemas/continuity.js +199 -0
- package/dist/schemas/diagnostics.d.ts +28 -0
- package/dist/schemas/diagnostics.js +27 -0
- package/dist/schemas/doctor.d.ts +157 -0
- package/dist/schemas/doctor.js +75 -0
- package/dist/schemas/document.d.ts +644 -0
- package/dist/schemas/document.js +296 -0
- package/dist/schemas/errors.d.ts +177 -0
- package/dist/schemas/errors.js +176 -0
- package/dist/schemas/evidence.d.ts +24 -0
- package/dist/schemas/evidence.js +16 -0
- package/dist/schemas/host.d.ts +436 -0
- package/dist/schemas/host.js +203 -0
- package/dist/schemas/index.d.ts +15 -0
- package/dist/schemas/index.js +15 -0
- package/dist/schemas/init.d.ts +121 -0
- package/dist/schemas/init.js +94 -0
- package/dist/schemas/install.d.ts +227 -0
- package/dist/schemas/install.js +147 -0
- package/dist/schemas/machine.d.ts +43 -0
- package/dist/schemas/machine.js +96 -0
- package/dist/schemas/outcome.d.ts +23 -0
- package/dist/schemas/outcome.js +17 -0
- package/dist/schemas/paths.d.ts +19 -0
- package/dist/schemas/paths.js +63 -0
- package/dist/schemas/workspace.d.ts +120 -0
- package/dist/schemas/workspace.js +201 -0
- package/dist/workspace/config-file.d.ts +36 -0
- package/dist/workspace/config-file.js +237 -0
- package/dist/workspace/config.d.ts +28 -0
- package/dist/workspace/config.js +79 -0
- package/dist/workspace/discover.d.ts +34 -0
- package/dist/workspace/discover.js +195 -0
- package/dist/workspace/documents.d.ts +21 -0
- package/dist/workspace/documents.js +395 -0
- package/dist/workspace/ignore.d.ts +10 -0
- package/dist/workspace/ignore.js +48 -0
- package/dist/workspace/index.d.ts +7 -0
- package/dist/workspace/index.js +3 -0
- package/dist/workspace/repositories.d.ts +24 -0
- package/dist/workspace/repositories.js +411 -0
- package/dist/workspace/resolve.d.ts +24 -0
- package/dist/workspace/resolve.js +268 -0
- package/dist/workspace/types.d.ts +71 -0
- package/dist/workspace/types.js +1 -0
- package/dist/workspace/validation.d.ts +18 -0
- package/dist/workspace/validation.js +197 -0
- package/package.json +111 -4
- package/skills/pappra/SKILL.md +71 -0
- package/skills/pappra/references/hosts.md +40 -0
- package/skills/pappra/references/lifecycle.md +41 -0
- package/skills/pappra/references/operations.md +27 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 phyzess
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,100 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Pappra
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Pappra is a portable workspace manager for coding-agent workflows. It keeps workspace configuration, selected project knowledge, checkpoints, recovery context and bounded code navigation in files owned by the workspace rather than in one chat transcript.
|
|
4
|
+
|
|
5
|
+
Pappra is the manager. External coding hosts, code-graph engines and collaboration controllers are optional integrations, not installation prerequisites.
|
|
6
|
+
|
|
7
|
+
## Quick start
|
|
8
|
+
|
|
9
|
+
Requirements: Node.js 24 or later. `pnpm` 12.3.4 is required only for development inside this repository; Git is required only when a command observes repository identity.
|
|
10
|
+
|
|
11
|
+
The package is published as `@phyzess/pappra`. Run it with `npx` from the target workspace, or install it globally when you use it every day.
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
# In an empty target workspace
|
|
15
|
+
mkdir -p /tmp/pappra-demo
|
|
16
|
+
cd /tmp/pappra-demo
|
|
17
|
+
curl -fsSL https://raw.githubusercontent.com/phyzess/pappra/main/examples/minimal-choices.json -o ./minimal-choices.json
|
|
18
|
+
|
|
19
|
+
# Preview first. JSON/config mode is non-interactive and does not prompt.
|
|
20
|
+
npx @phyzess/pappra@beta init --config ./minimal-choices.json --json
|
|
21
|
+
|
|
22
|
+
# Apply the same choices. Apply also installs and binds a durable runtime copy,
|
|
23
|
+
# so this converges with exit code 0; add --no-runtime to leave it pending.
|
|
24
|
+
npx @phyzess/pappra@beta init --config ./minimal-choices.json --apply --json
|
|
25
|
+
npx @phyzess/pappra@beta doctor --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`examples/minimal-choices.json` is complete for a host-free, no-graph, single-directory workspace. The example intentionally has no repositories or optional hosts.
|
|
29
|
+
|
|
30
|
+
For a non-interactive derived setup, `npx @phyzess/pappra@beta init --yes --apply --json` derives repositories, knowledge sources, code engine, validation commands, excludes and hosts from discovery. `--print-choices` prints that `pappra/init-choices/1` document and writes nothing, and `init --json` without selections returns the discovery candidates plus the suggested document. JSON mode never prompts; only a TTY without selections opens the wizard.
|
|
31
|
+
|
|
32
|
+
Development from a checkout works the same way: `pnpm install --frozen-lockfile`, `pnpm build`, then invoke `dist/cli/main.js` by absolute path from the target workspace.
|
|
33
|
+
|
|
34
|
+
`init --apply` also installs a durable runtime copy of the executing package under the
|
|
35
|
+
Pappra data directory and binds it in `machine.json`, so an npx/dlx bootstrap survives
|
|
36
|
+
cache eviction and the command converges with exit code `0`. Pass `--no-runtime` to leave
|
|
37
|
+
that action pending instead; the result is then `ok:true` with
|
|
38
|
+
`status:"external-actions-pending"` and a nonzero exit, which is a partial configuration
|
|
39
|
+
write rather than a claim that a runtime exists.
|
|
40
|
+
|
|
41
|
+
The runtime copy can be managed directly:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npx @phyzess/pappra@beta runtime install --apply [--from self|tarball|registry]
|
|
45
|
+
npx @phyzess/pappra@beta runtime status --json
|
|
46
|
+
npx @phyzess/pappra@beta runtime verify --json
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
A workspace that already has a valid `.pappra/workspace.json` is never rewritten silently.
|
|
50
|
+
`init --yes --reconfigure --apply` rebuilds it from discovery (for example to move the
|
|
51
|
+
recorded runtime version to the running package), backing the previous file up under
|
|
52
|
+
`.pappra/local/backups`. Apply also reports advisory `nextActions`: `pappra code prepare`
|
|
53
|
+
for a selected code engine and `pappra docs scan --apply` to register documents from the
|
|
54
|
+
configured knowledge sources.
|
|
55
|
+
|
|
56
|
+
Optional examples have prerequisites rather than generated files: code-graph and
|
|
57
|
+
host commands require the selected external CLI/support, and collaboration
|
|
58
|
+
requires an explicit controller. `--controller pi-rpc` is the host-directs/Pi-executes
|
|
59
|
+
path, verified end to end against Pi 1.3.0; see [Pi RPC collaboration](docs/pi-rpc.md).
|
|
60
|
+
They are not needed for the core workflow above.
|
|
61
|
+
|
|
62
|
+
## What it manages
|
|
63
|
+
|
|
64
|
+
- **Workspace configuration:** `.pappra/workspace.json` and checkout-local `.pappra/local/machine.json`.
|
|
65
|
+
- **Knowledge:** workspace and private document catalogs with explicit preview/apply operations.
|
|
66
|
+
- **Continuity:** private task checkpoints and bounded advisory resume packets. Resume never grants execution by itself.
|
|
67
|
+
- **Code intelligence:** status, explicit preparation and bounded query for selected repositories. Text/structure fallback is available when the optional graph engine is absent.
|
|
68
|
+
- **Host integrations:** optional Pi, Codex and Claude Code adapters that merge Pappra-owned entries without taking over user configuration. Hooks are copied as a dependency-free bundle; Claude Code uses `${CLAUDE_PROJECT_DIR}` and Pi imports its runtime relatively, while Codex 0.163.0 loads hooks only from `$CODEX_HOME/hooks.json` (`host install --host codex --scope user`). `host bundle --marketplace` exports a marketplace that Claude Code and Codex accept without registering it. Plugin hooks are verified for Pi 1.3.0 and Claude Code 2.1.292 (startup) and unsupported for Codex, so `host install --mode plugin` fails closed with the per-host registration commands. See [host plugin validation](docs/host-plugin-validation.md).
|
|
69
|
+
- **Bounded collaboration:** an optional, explicitly controlled one-request workflow. It is not a scheduler or daemon.
|
|
70
|
+
|
|
71
|
+
## Optional integrations and support
|
|
72
|
+
|
|
73
|
+
| Capability | Requirement | Default |
|
|
74
|
+
| ----------------------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------- |
|
|
75
|
+
| Workspace, init, doctor, checkpoint/resume, knowledge | Node.js only; Git for repository identity | Core |
|
|
76
|
+
| Code graph status/prepare/query | Optional external code-graph engine | Disabled unless selected; text fallback remains available |
|
|
77
|
+
| Host hooks | Explicitly selected Pi, Codex or Claude Code integration | Not installed automatically |
|
|
78
|
+
| Collaboration controller | Explicit `--controller <fixture\|pi-rpc>` | No implicit controller |
|
|
79
|
+
|
|
80
|
+
Host names and external protocol identifiers describe supported integration surfaces. They do not make any host, model, graph engine or private workspace a prerequisite for core use.
|
|
81
|
+
|
|
82
|
+
## Development checks
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
pnpm check
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The check runs the source policy, type checks, formatting, deterministic tests and a local package smoke test. The package smoke test prefers an offline local tarball (falling back to registry resolution when the runner has no offline metadata) and an isolated fixture home/state; it does not install a model or contact a model provider.
|
|
89
|
+
|
|
90
|
+
## Status and limits
|
|
91
|
+
|
|
92
|
+
Pappra is development software (`0.1.0-beta.10`) published as `@phyzess/pappra` under the `beta` dist-tag. Releases are published from GitHub Actions with npm trusted publishing (OIDC), so no npm token is stored in this repository. Pin either the moving `beta` tag or an exact version such as `@phyzess/pappra@0.1.0-beta.10`, because pre-release versions are never republished.
|
|
93
|
+
|
|
94
|
+
The deterministic suite covers synthetic workspaces, fixtures and local process boundaries. It does not establish real-model behavior, native host callability on every platform, CodeGraph completeness, Windows/Linux parity or production performance. A host adapter version pin is an observed support claim, not proof that a particular native installation will load or run correctly.
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
Pappra is licensed under the MIT License. See [LICENSE](LICENSE) and [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
|
|
99
|
+
|
|
100
|
+
More detail: [quick start](docs/quickstart.md), [API boundaries](docs/api.md), [support and limitations](docs/support.md).
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
Pappra depends on the following packages. Runtime dependencies are installed by
|
|
4
|
+
the consumer and are not copied into Pappra source files.
|
|
5
|
+
|
|
6
|
+
| Package | Version | License | Role |
|
|
7
|
+
| ---------------- | ------- | ---------- | ---------------------- |
|
|
8
|
+
| `@clack/prompts` | 1.8.1 | MIT | Interactive prompts |
|
|
9
|
+
| `zod` | 4.6.6 | MIT | Runtime validation |
|
|
10
|
+
| `@types/node` | 24.19.1 | MIT | Development types |
|
|
11
|
+
| `prettier` | 3.9.9 | MIT | Development formatting |
|
|
12
|
+
| `typescript` | 7.0.2 | Apache-2.0 | Development compiler |
|
|
13
|
+
|
|
14
|
+
The package manager `pnpm` is a development tool and is not shipped in the
|
|
15
|
+
published package contents. This notice is informational; it does not replace
|
|
16
|
+
the license texts or attribution supplied by the projects above.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pappra
|
|
3
|
+
description: Use Pappra workspace knowledge, checkpoint/resume, and selected-repository code intelligence from any supported coding agent. Use when a task needs durable handoff context, workspace documents, or bounded code navigation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Pappra
|
|
7
|
+
|
|
8
|
+
Pappra keeps workspace knowledge, continuity, and code navigation outside the
|
|
9
|
+
host transcript. Use the installed `pappra` CLI for durable operations; hooks
|
|
10
|
+
only record bounded lifecycle observations and never start a model, download,
|
|
11
|
+
index, or new writer.
|
|
12
|
+
|
|
13
|
+
## Start here
|
|
14
|
+
|
|
15
|
+
1. Read `references/lifecycle.md` before relying on a host lifecycle event.
|
|
16
|
+
2. Read `references/hosts.md` when the host surface is Pi, Codex, or Claude.
|
|
17
|
+
3. Use `pappra checkpoint` / `pappra resume` for handoffs. A stored checkpoint
|
|
18
|
+
is context, not permission to execute or to trust a previous session.
|
|
19
|
+
4. Use `pappra docs`, `pappra code`, `pappra runtime` and `pappra host` only for
|
|
20
|
+
the workspace selected by the current root. Never infer a workspace from an
|
|
21
|
+
unrelated session. `pappra docs scan --apply` registers discovered documents;
|
|
22
|
+
`pappra runtime install --apply` keeps a durable copy of this package.
|
|
23
|
+
5. For a new bounded collaboration request, build an explicit
|
|
24
|
+
`pappra/collaboration-goal/1` from the user's objective and named choices,
|
|
25
|
+
run `pappra collab prepare --goal <file> --domain-root <dir>`, admit against a fresh capability
|
|
26
|
+
card, then use `pappra collab run` with the reviewed controller. `--controller
|
|
27
|
+
pi-rpc` launches a real owned Pi session and is verified for Pi 1.3.0. Never
|
|
28
|
+
turn prose into identity, approval, or capability claims.
|
|
29
|
+
|
|
30
|
+
## One-request collaboration
|
|
31
|
+
|
|
32
|
+
`pappra collab prepare --goal <file> --domain-root <dir>` requires an explicit
|
|
33
|
+
shared domain. It validates the canonical domain/tasks/task/private namespace
|
|
34
|
+
before writing any task metadata and again around each write, so a task-root or
|
|
35
|
+
mid-write directory redirect fails closed instead of scattering artifacts. It
|
|
36
|
+
then writes a private task record, assignment, prompt, and resource claims; read
|
|
37
|
+
resources stay read claims. The captured identities also guard live query, finish, disposal and lower RPC artifact writes; after a redirect, no new query/execution/proof/current-result pathname is written. `pappra collab run` requires an explicit `--controller <fixture|pi-rpc>`,
|
|
38
|
+
performs the single admitted launch, and accepts bounded
|
|
39
|
+
`pappra/collaboration-command/1` JSONL on stdin; it emits
|
|
40
|
+
`pappra/collaboration-event/1` JSONL. `query` reads persisted history only and
|
|
41
|
+
reports live ownership as unknown. A `finish` produces one deterministic REPORT;
|
|
42
|
+
only a result whose stored classification was `applied` for the same fixed
|
|
43
|
+
identity/attempt/input may repeat successfully as a duplicate — repeated
|
|
44
|
+
rejections stay rejected. Cancel records and validates intent first: a denied
|
|
45
|
+
intent never calls the native controller. Claims are retained and stop proof is
|
|
46
|
+
never invented.
|
|
47
|
+
|
|
48
|
+
Use `--controller fixture` only for deterministic, no-model tests; it is a
|
|
49
|
+
restricted explicit fixture, never a silent default. The optional `pi-rpc` controller
|
|
50
|
+
uses the existing owned Pi RPC daily path and preserves required skills, tools,
|
|
51
|
+
MCP, hooks, and model settings; missing capabilities or stale/forged admission
|
|
52
|
+
fail before launch. A native run reports only the current prompt-correlated
|
|
53
|
+
result: terminal success requires a supported terminal reason and no pending
|
|
54
|
+
tool call, so text-plus-toolUse/intermediate, tool-only, empty, old, malformed or
|
|
55
|
+
missing answers are `unknown`; an explicit error is `failed` and an abort is
|
|
56
|
+
`cancelled`. The current result must be published as validated
|
|
57
|
+
`native-current-result/1` evidence; EIO/conflict/symlink/partial publication
|
|
58
|
+
makes delivery `unknown`, not success, and repeated finish reuses verified
|
|
59
|
+
content instead of overwriting it. A clean transport exit is not task success.
|
|
60
|
+
No approval is auto-answered, no cancel is inferred from an acknowledgement, and no new thread or
|
|
61
|
+
arbitrary PID is adopted. Do not launch a model or real user session without
|
|
62
|
+
the task's explicit authorization.
|
|
63
|
+
|
|
64
|
+
## Boundaries
|
|
65
|
+
|
|
66
|
+
- Hooks are local and bounded. They do not read transcripts, run commands,
|
|
67
|
+
call models, fetch the network, or continue a conversation.
|
|
68
|
+
- Missing semantic context stays missing; do not fabricate summaries.
|
|
69
|
+
- Treat unknown ownership, stale bundles, untrusted hooks, and changed host
|
|
70
|
+
versions as visible conditions, not silent fallbacks.
|
|
71
|
+
- Preserve user settings and unrelated keys when integrating a host.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Host surfaces
|
|
2
|
+
|
|
3
|
+
## Pi
|
|
4
|
+
|
|
5
|
+
The project integration installs an extension plus a copied `pappra` skill; the
|
|
6
|
+
generated entrypoint imports the fixed Pappra runtime by absolute file URL.
|
|
7
|
+
`pappra host bundle --host pi` exports a self-contained package instead: the
|
|
8
|
+
entry imports `./runtime.mjs` next to it, so the package survives a moved
|
|
9
|
+
checkout. Pi 1.3.0 was verified in a real session through the packaged extension
|
|
10
|
+
(`pi install <dir> -l -a` + `pi -p -a`).
|
|
11
|
+
|
|
12
|
+
## Codex
|
|
13
|
+
|
|
14
|
+
Codex 0.163.0 loads command hooks only from its user configuration directory.
|
|
15
|
+
Wire it with `pappra host install --host codex --scope user`, which merges only
|
|
16
|
+
Pappra-owned entries into `$CODEX_HOME/hooks.json` (existing hooks and unrelated
|
|
17
|
+
keys are preserved) and copies the bundled hook there. Project
|
|
18
|
+
`.codex/hooks.json` and plugin-bundle hooks are not loaded at this version.
|
|
19
|
+
Codex hook definitions are trusted individually; installation is not trust.
|
|
20
|
+
Observed 0.163.0 hook keys do not include a compact event, so compact and
|
|
21
|
+
automatic checkpoint requests remain unsupported.
|
|
22
|
+
|
|
23
|
+
## Claude Code
|
|
24
|
+
|
|
25
|
+
The project integration installs a command-hook entry and merges only
|
|
26
|
+
Pappra-owned entries into `settings.json`; the command uses
|
|
27
|
+
`${CLAUDE_PROJECT_DIR}`. `pappra host bundle --host claude --marketplace` exports
|
|
28
|
+
a plugin whose hook uses `${CLAUDE_PLUGIN_ROOT}`; the marketplace validates with
|
|
29
|
+
`claude plugin validate` and startup was verified in a real session. `SessionStart`
|
|
30
|
+
and `PostCompact` are distinct; matchers, trust, timeout, and output behavior
|
|
31
|
+
remain host/version-specific. Installing a command is not proof it ran.
|
|
32
|
+
|
|
33
|
+
## Common safety
|
|
34
|
+
|
|
35
|
+
All surfaces use the event's canonical cwd/root, bounded stdin, a one-second
|
|
36
|
+
local deadline, no transcript reads, no arbitrary configured commands, and no
|
|
37
|
+
network/model/index/session side effects. Paths with spaces or Unicode are
|
|
38
|
+
passed as argv/file URLs, never interpolated into a shell. Plugin registration is
|
|
39
|
+
host-specific; never claim a hook is loaded because files were written or a
|
|
40
|
+
validator passed.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Lifecycle reference
|
|
2
|
+
|
|
3
|
+
## Supported mapping
|
|
4
|
+
|
|
5
|
+
Pappra distinguishes four local lifecycle intents:
|
|
6
|
+
|
|
7
|
+
| Intent | Pi | Codex | Claude |
|
|
8
|
+
| -------------------- | ---------------------------- | ------------------------------------------ | ------------------------------------------ |
|
|
9
|
+
| `startup` | `session_start` | `SessionStart` with source `startup`/`new` | `SessionStart` with source `startup`/`new` |
|
|
10
|
+
| `resume` | `session_start` | `SessionStart` with source `resume` | `SessionStart` with source `resume` |
|
|
11
|
+
| `compact` | `session_before_compact` | unsupported in observed 0.163.0 hook keys | `PostCompact` |
|
|
12
|
+
| `checkpoint-request` | explicit Pappra command/hook | unsupported automatic event | unsupported automatic event |
|
|
13
|
+
|
|
14
|
+
The matrix is version-specific. A host version outside the observed support
|
|
15
|
+
range is `unsupported`/`unknown`, not a fallback to name similarity.
|
|
16
|
+
|
|
17
|
+
Codex 0.163.0 loads these hook keys only from its user configuration directory
|
|
18
|
+
(`$CODEX_HOME/hooks.json`); project `.codex/hooks.json` and plugin bundles are
|
|
19
|
+
not loaded by that version. Claude Code and Pi wire hooks in project scope.
|
|
20
|
+
|
|
21
|
+
## What a hook does
|
|
22
|
+
|
|
23
|
+
A hook validates the host payload, resolves the current workspace from the
|
|
24
|
+
event cwd (never from a last-session cache), derives a bounded event identity,
|
|
25
|
+
suppresses a duplicate identity, and records a private local event observation.
|
|
26
|
+
It may print a short advisory context. It never starts a model, fetches,
|
|
27
|
+
indexes, runs arbitrary commands, creates a new agent, or writes a checkpoint
|
|
28
|
+
with invented semantics.
|
|
29
|
+
|
|
30
|
+
## Manual continuity
|
|
31
|
+
|
|
32
|
+
`pappra checkpoint --task <id> ...` and `pappra resume <id>` remain available
|
|
33
|
+
without hooks. A hook observation is not a checkpoint and does not grant
|
|
34
|
+
`executionAllowed`. A resume packet is read-only context; an unknown or
|
|
35
|
+
non-stopped writer fails closed.
|
|
36
|
+
|
|
37
|
+
## Reload and trust
|
|
38
|
+
|
|
39
|
+
Installing files does not prove the host loaded them or trusted their exact
|
|
40
|
+
definition. Report reload-needed and trust-needed separately. Do not approve a
|
|
41
|
+
host trust prompt on the user's behalf.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Operations reference
|
|
2
|
+
|
|
3
|
+
- `pappra init` plans or applies workspace configuration. `--yes` derives
|
|
4
|
+
selections from discovery, `--print-choices` prints that document without
|
|
5
|
+
writing, `--reconfigure` rebuilds an existing valid `workspace.json`, and
|
|
6
|
+
`--no-runtime` leaves the durable runtime action pending.
|
|
7
|
+
- `pappra runtime <install|status|verify|remove>` manages the durable runtime
|
|
8
|
+
copy. `install --apply` defaults to `--from self`; writes require `--apply`.
|
|
9
|
+
- `pappra doctor` is passive: it does not install hooks, start hosts, or fix
|
|
10
|
+
state. `runtime verify` is the active runtime check.
|
|
11
|
+
- `pappra checkpoint` writes a task checkpoint; `pappra resume` reads a stored
|
|
12
|
+
snapshot and reports whether execution is allowed.
|
|
13
|
+
- `pappra docs <list|check|archive|scan>` manages the knowledge catalog.
|
|
14
|
+
`scan --apply` registers documents found under the configured sources.
|
|
15
|
+
- `pappra code` operates on an explicitly selected repository and keeps index
|
|
16
|
+
mutations behind an explicit `--apply`.
|
|
17
|
+
- `pappra host <detect|describe|plan|install|verify|bundle>` wires an optional
|
|
18
|
+
host. Codex 0.163.0 loads hooks only from `$CODEX_HOME/hooks.json`, so use
|
|
19
|
+
`install --host codex --scope user`; `bundle --marketplace` exports a plugin
|
|
20
|
+
directory without registering it, and `install --mode plugin` fails closed.
|
|
21
|
+
- `pappra collab <prepare|run|query>` runs one bounded collaboration request.
|
|
22
|
+
`run` requires `--controller fixture|pi-rpc`; `pi-rpc` launches a real Pi RPC
|
|
23
|
+
session.
|
|
24
|
+
|
|
25
|
+
Preserve user bytes. If an operation reports a conflict or residual path,
|
|
26
|
+
inspect that path and resolve ownership before retrying. Never delete an
|
|
27
|
+
unknown file to make a retry succeed.
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import type { Diagnostic } from '../schemas/diagnostics.js';
|
|
2
|
+
import { type CollaborationEvent, type CollaborationGoal, type CollaborationPrepared } from '../schemas/collaboration.js';
|
|
3
|
+
import { admitLaunch } from '../collab/admission.js';
|
|
4
|
+
import type { Assignment } from '../collab/contracts.js';
|
|
5
|
+
export type CollaborationFailureStatus = 'invalid' | 'needs_input' | 'conflict' | 'unsupported' | 'failed';
|
|
6
|
+
export interface CollaborationFailure {
|
|
7
|
+
readonly ok: false;
|
|
8
|
+
readonly status: CollaborationFailureStatus;
|
|
9
|
+
readonly code: string;
|
|
10
|
+
readonly message: string;
|
|
11
|
+
readonly nextAction: string | null;
|
|
12
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
13
|
+
}
|
|
14
|
+
export type CollaborationResult<T> = {
|
|
15
|
+
readonly ok: true;
|
|
16
|
+
readonly value: T;
|
|
17
|
+
} | CollaborationFailure;
|
|
18
|
+
export interface PrepareOptions {
|
|
19
|
+
readonly domainRoot: string;
|
|
20
|
+
readonly clock?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface PreparedBundle {
|
|
23
|
+
readonly prepared: CollaborationPrepared;
|
|
24
|
+
readonly goal: CollaborationGoal;
|
|
25
|
+
readonly assignment: Assignment;
|
|
26
|
+
}
|
|
27
|
+
export interface StartOptions {
|
|
28
|
+
readonly capabilitiesFile: string;
|
|
29
|
+
readonly controller: CollaborationController;
|
|
30
|
+
readonly controllerId: string;
|
|
31
|
+
readonly clock?: number;
|
|
32
|
+
}
|
|
33
|
+
export interface ControllerStartRequest {
|
|
34
|
+
readonly prepared: CollaborationPrepared;
|
|
35
|
+
readonly goal: CollaborationGoal;
|
|
36
|
+
readonly assignment: Assignment;
|
|
37
|
+
readonly capabilitiesFile: string;
|
|
38
|
+
readonly prompt: string;
|
|
39
|
+
readonly promptFile: string;
|
|
40
|
+
readonly taskRoot: string;
|
|
41
|
+
readonly evidenceDir: string;
|
|
42
|
+
readonly namespace?: PrivateNamespace;
|
|
43
|
+
}
|
|
44
|
+
export interface ControllerObservation {
|
|
45
|
+
readonly status: string;
|
|
46
|
+
readonly detail: string | null;
|
|
47
|
+
readonly data: unknown;
|
|
48
|
+
}
|
|
49
|
+
export interface ControllerCancel {
|
|
50
|
+
readonly acknowledged: boolean;
|
|
51
|
+
readonly terminal_observed: boolean;
|
|
52
|
+
readonly stop_evidence: unknown;
|
|
53
|
+
}
|
|
54
|
+
export interface ControllerFinish {
|
|
55
|
+
readonly outcome: string;
|
|
56
|
+
readonly status: string;
|
|
57
|
+
readonly exitCode: number | null;
|
|
58
|
+
readonly sessionId: string | null;
|
|
59
|
+
readonly outputs: readonly unknown[];
|
|
60
|
+
readonly nativeRef: unknown;
|
|
61
|
+
readonly evidenceRef: string | null;
|
|
62
|
+
}
|
|
63
|
+
export interface ControllerSession {
|
|
64
|
+
query(): Promise<ControllerObservation>;
|
|
65
|
+
cancel(): Promise<ControllerCancel>;
|
|
66
|
+
finish(): Promise<ControllerFinish>;
|
|
67
|
+
dispose?(): Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
export interface CollaborationController {
|
|
70
|
+
readonly id: string;
|
|
71
|
+
start(token: object, request: ControllerStartRequest): Promise<{
|
|
72
|
+
readonly ok: true;
|
|
73
|
+
readonly session: ControllerSession;
|
|
74
|
+
} | {
|
|
75
|
+
readonly ok: false;
|
|
76
|
+
readonly status: CollaborationFailureStatus;
|
|
77
|
+
readonly code: string;
|
|
78
|
+
readonly message: string;
|
|
79
|
+
readonly nextAction: string | null;
|
|
80
|
+
readonly possible_start?: boolean;
|
|
81
|
+
}>;
|
|
82
|
+
}
|
|
83
|
+
interface NamespaceIdentity {
|
|
84
|
+
readonly path: string;
|
|
85
|
+
readonly canonical: string;
|
|
86
|
+
readonly dev: number;
|
|
87
|
+
readonly ino: number;
|
|
88
|
+
}
|
|
89
|
+
export interface PrivateNamespace {
|
|
90
|
+
readonly domain: NamespaceIdentity;
|
|
91
|
+
readonly taskRoot: NamespaceIdentity;
|
|
92
|
+
readonly privateDir: NamespaceIdentity;
|
|
93
|
+
}
|
|
94
|
+
export declare function validateLaunchToken(token: unknown, expected: {
|
|
95
|
+
readonly taskRoot: string;
|
|
96
|
+
readonly assignmentDigest: string;
|
|
97
|
+
readonly subtaskId: string;
|
|
98
|
+
readonly attempt: number;
|
|
99
|
+
}): boolean;
|
|
100
|
+
export declare function prepareCollaboration(input: unknown, options: PrepareOptions): Promise<CollaborationResult<PreparedBundle>>;
|
|
101
|
+
export interface AdmissionResult {
|
|
102
|
+
readonly prepared: CollaborationPrepared;
|
|
103
|
+
readonly goal: CollaborationGoal;
|
|
104
|
+
readonly assignment: Assignment;
|
|
105
|
+
readonly admission: Awaited<ReturnType<typeof admitLaunch>>;
|
|
106
|
+
readonly token: object;
|
|
107
|
+
}
|
|
108
|
+
export declare function admitPrepared(preparedFile: string, capabilitiesFile: string, options?: {
|
|
109
|
+
readonly clock?: number;
|
|
110
|
+
}): Promise<CollaborationResult<AdmissionResult>>;
|
|
111
|
+
export interface StartedRun {
|
|
112
|
+
readonly prepared: CollaborationPrepared;
|
|
113
|
+
readonly goal: CollaborationGoal;
|
|
114
|
+
readonly assignment: Assignment;
|
|
115
|
+
readonly token: object;
|
|
116
|
+
readonly controller: CollaborationController;
|
|
117
|
+
readonly session: ControllerSession;
|
|
118
|
+
readonly reservationId: string | null;
|
|
119
|
+
}
|
|
120
|
+
export declare function startPrepared(preparedFile: string, options: StartOptions): Promise<CollaborationResult<StartedRun>>;
|
|
121
|
+
export interface ReportResult {
|
|
122
|
+
readonly ok: boolean;
|
|
123
|
+
readonly messageId: string;
|
|
124
|
+
readonly duplicate: boolean;
|
|
125
|
+
readonly classification: string | null;
|
|
126
|
+
readonly detail: string | null;
|
|
127
|
+
}
|
|
128
|
+
export declare function submitResultReport(started: StartedRun, finish: ControllerFinish, { clock }?: {
|
|
129
|
+
clock?: number;
|
|
130
|
+
}): ReportResult;
|
|
131
|
+
export declare function finishStarted(started: StartedRun): Promise<CollaborationResult<ControllerFinish>>;
|
|
132
|
+
export declare function driveRun(started: StartedRun, commands: AsyncIterable<unknown>, emit: (event: CollaborationEvent) => void, { clock }?: {
|
|
133
|
+
clock?: number;
|
|
134
|
+
}): Promise<CollaborationResult<ReportResult>>;
|
|
135
|
+
export declare class FixtureController implements CollaborationController {
|
|
136
|
+
private readonly options;
|
|
137
|
+
readonly id = "fixture";
|
|
138
|
+
constructor(options?: {
|
|
139
|
+
readonly status?: 'completed' | 'failed' | 'cancelled' | 'needs_input';
|
|
140
|
+
readonly outputs?: readonly unknown[];
|
|
141
|
+
readonly sessionId?: string;
|
|
142
|
+
});
|
|
143
|
+
start(token: object, request: ControllerStartRequest): Promise<{
|
|
144
|
+
readonly ok: true;
|
|
145
|
+
readonly session: ControllerSession;
|
|
146
|
+
} | {
|
|
147
|
+
readonly ok: false;
|
|
148
|
+
readonly status: CollaborationFailureStatus;
|
|
149
|
+
readonly code: string;
|
|
150
|
+
readonly message: string;
|
|
151
|
+
readonly nextAction: string | null;
|
|
152
|
+
readonly possible_start?: boolean;
|
|
153
|
+
}>;
|
|
154
|
+
}
|
|
155
|
+
export declare class PiRpcController implements CollaborationController {
|
|
156
|
+
readonly id = "pi-rpc";
|
|
157
|
+
start(token: object, request: ControllerStartRequest): Promise<{
|
|
158
|
+
readonly ok: true;
|
|
159
|
+
readonly session: ControllerSession;
|
|
160
|
+
} | {
|
|
161
|
+
readonly ok: false;
|
|
162
|
+
readonly status: CollaborationFailureStatus;
|
|
163
|
+
readonly code: string;
|
|
164
|
+
readonly message: string;
|
|
165
|
+
readonly nextAction: string | null;
|
|
166
|
+
readonly possible_start?: boolean;
|
|
167
|
+
}>;
|
|
168
|
+
}
|
|
169
|
+
export declare function inspectPreparedHistory(preparedFile: string): CollaborationResult<Record<string, unknown>>;
|
|
170
|
+
export {};
|