@dp-pcs/ogp 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +45 -15
  2. package/dist/cli/federation.d.ts +14 -0
  3. package/dist/cli/federation.d.ts.map +1 -1
  4. package/dist/cli/federation.js +216 -19
  5. package/dist/cli/federation.js.map +1 -1
  6. package/dist/cli/project.d.ts +4 -3
  7. package/dist/cli/project.d.ts.map +1 -1
  8. package/dist/cli/project.js +34 -24
  9. package/dist/cli/project.js.map +1 -1
  10. package/dist/cli/setup.d.ts +4 -0
  11. package/dist/cli/setup.d.ts.map +1 -1
  12. package/dist/cli/setup.js +57 -4
  13. package/dist/cli/setup.js.map +1 -1
  14. package/dist/cli.js +11 -4
  15. package/dist/cli.js.map +1 -1
  16. package/dist/daemon/agent-comms.js +1 -1
  17. package/dist/daemon/agent-comms.js.map +1 -1
  18. package/dist/daemon/heartbeat.d.ts +22 -0
  19. package/dist/daemon/heartbeat.d.ts.map +1 -0
  20. package/dist/daemon/heartbeat.js +142 -0
  21. package/dist/daemon/heartbeat.js.map +1 -0
  22. package/dist/daemon/intent-registry.d.ts.map +1 -1
  23. package/dist/daemon/intent-registry.js +12 -6
  24. package/dist/daemon/intent-registry.js.map +1 -1
  25. package/dist/daemon/keypair.d.ts +1 -0
  26. package/dist/daemon/keypair.d.ts.map +1 -1
  27. package/dist/daemon/keypair.js +119 -7
  28. package/dist/daemon/keypair.js.map +1 -1
  29. package/dist/daemon/message-handler.js +148 -16
  30. package/dist/daemon/message-handler.js.map +1 -1
  31. package/dist/daemon/notify.d.ts.map +1 -1
  32. package/dist/daemon/notify.js +47 -0
  33. package/dist/daemon/notify.js.map +1 -1
  34. package/dist/daemon/peers.d.ts +24 -0
  35. package/dist/daemon/peers.d.ts.map +1 -1
  36. package/dist/daemon/peers.js +77 -6
  37. package/dist/daemon/peers.js.map +1 -1
  38. package/dist/daemon/projects.d.ts +9 -6
  39. package/dist/daemon/projects.d.ts.map +1 -1
  40. package/dist/daemon/projects.js +23 -16
  41. package/dist/daemon/projects.js.map +1 -1
  42. package/dist/daemon/server.d.ts +1 -0
  43. package/dist/daemon/server.d.ts.map +1 -1
  44. package/dist/daemon/server.js +85 -44
  45. package/dist/daemon/server.js.map +1 -1
  46. package/dist/shared/help.js +2 -1
  47. package/dist/shared/help.js.map +1 -1
  48. package/docs/CLI-REFERENCE.md +1 -0
  49. package/docs/GETTING-STARTED.md +12 -1
  50. package/docs/cloudflare-named-tunnel-setup.md +126 -0
  51. package/docs/federation-flow.md +6 -6
  52. package/docs/project-intent-testing.md +97 -0
  53. package/docs/quickstart.md +12 -4
  54. package/docs/scopes.md +13 -13
  55. package/package.json +4 -4
  56. package/scripts/install-skills.js +19 -1
  57. package/scripts/test-project-intents.mjs +614 -0
  58. package/skills/ogp/SKILL.md +1 -1
  59. package/skills/ogp-agent-comms/SKILL.md +1 -1
  60. package/skills/ogp-expose/SKILL.md +103 -8
  61. package/skills/ogp-project/SKILL.md +47 -33
@@ -0,0 +1,97 @@
1
+ # Project Intent Testing
2
+
3
+ This repo now includes a runnable local project-intent harness:
4
+
5
+ ```bash
6
+ npm run test:project-intents
7
+ ```
8
+
9
+ The harness creates two isolated local gateways with separate `OGP_HOME` directories, federates them over localhost, and exercises the real project commands:
10
+
11
+ - `federation request`
12
+ - `federation approve`
13
+ - `project create`
14
+ - `project contribute --local-only`
15
+ - `project request-join`
16
+ - `project send-contribution`
17
+ - `project query-peer`
18
+ - `project status-peer`
19
+
20
+ ## What It Verifies
21
+
22
+ The automated run checks these behaviors:
23
+
24
+ 1. Two local daemons can boot independently.
25
+ 2. Federation approval completes between them.
26
+ 3. The project owner can create a local project and persist local contributions.
27
+ 4. A non-member peer cannot query the project before joining.
28
+ 5. The peer can join the project through `project.join`.
29
+ 6. The joined peer can send a remote contribution through `project.contribute`.
30
+ 7. The joined peer can query the owner project through `project.query`.
31
+ 8. The status request path for `project.status` succeeds at the transport level.
32
+
33
+ ## Useful Variants
34
+
35
+ Keep the temp state and logs for inspection:
36
+
37
+ ```bash
38
+ npm run test:project-intents -- --keep-state
39
+ ```
40
+
41
+ Use a custom root or ports:
42
+
43
+ ```bash
44
+ npm run test:project-intents -- \
45
+ --root /tmp/ogp-project-intent-test \
46
+ --alpha-port 18990 \
47
+ --beta-port 18991
48
+ ```
49
+
50
+ Skip the TypeScript rebuild when `dist/` is already current:
51
+
52
+ ```bash
53
+ npm run test:project-intents -- --skip-build
54
+ ```
55
+
56
+ ## Manual Checks
57
+
58
+ If you want to replay the flow by hand, the harness prints the exact commands it used. These are the most valuable checks:
59
+
60
+ 1. Membership isolation:
61
+ `project query-peer` should fail before `project request-join`.
62
+ 2. Membership grant:
63
+ `project request-join` should create or update the project on the requester and add the remote member on the owner.
64
+ 3. Data flow:
65
+ `project send-contribution` should create a new contribution on the owner gateway.
66
+ 4. Remote visibility:
67
+ `project query-peer` should return the contribution after join succeeds.
68
+ 5. Local persistence:
69
+ `projects.json` under each `OGP_HOME` should reflect the expected project and topic state.
70
+
71
+ ## Interpreting Success
72
+
73
+ Project intents are working if all of the following are true:
74
+
75
+ - both daemons answer `/.well-known/ogp`
76
+ - both peers end up `approved` in `peers.json`
77
+ - the owner `projects.json` contains the remote member after join
78
+ - the owner `projects.json` contains the remote contribution after send
79
+ - pre-join query fails and post-join query succeeds
80
+
81
+ ## Known Testing Nuance
82
+
83
+ `project status-peer` currently confirms that the request was sent, but it is not the best content-verification command because the CLI does not format the returned status payload. Treat it as a transport-path check, and use `project query-peer`, `project status`, `projects.json`, and daemon logs for stronger validation.
84
+
85
+ For controlled runs, `project contribute --local-only` is still useful when you want to inspect local state before any federation traffic. The default auto-sync path now limits fan-out to approved peers who are explicit members of the project.
86
+
87
+ ## File Transfer
88
+
89
+ OGP project intents do not currently implement first-class file transfer. Small structured metadata is fine, but real file movement would need explicit protocol support such as:
90
+
91
+ - file manifests with name, size, MIME type, and hash
92
+ - signed download URLs
93
+ - chunking or streaming for larger payloads
94
+ - size limits and approval controls
95
+ - storage and retention rules
96
+
97
+ For now, the practical pattern is to transfer references, hashes, and URLs through project intents rather than raw file contents.
@@ -20,6 +20,14 @@ After installation, install the OGP skills for Claude Code:
20
20
  ogp-install-skills
21
21
  ```
22
22
 
23
+ Then verify the installed skill versions:
24
+
25
+ ```bash
26
+ rg -n '^version:' ~/.openclaw/skills/ogp*/SKILL.md ~/.claude/skills/ogp*/SKILL.md 2>/dev/null
27
+ ```
28
+
29
+ For the current `0.4.2` release line, expect `ogp` `2.6.0`, `ogp-agent-comms` `0.6.0`, and `ogp-project` `2.2.0`.
30
+
23
31
  ## Step 2: Configure
24
32
 
25
33
  Run the interactive setup:
@@ -137,8 +145,8 @@ You should see:
137
145
  "gatewayUrl": "https://abc-def-123.trycloudflare.com",
138
146
  "publicKey": "302a300506032b6570032100...",
139
147
  "capabilities": {
140
- "intents": ["message", "task-request", "status-update", "agent-comms"],
141
- "features": ["scope-negotiation", "reply-callback", "project-intent"]
148
+ "intents": ["message", "task-request", "status-update", "agent-comms", "project.join", "project.contribute", "project.query", "project.status"],
149
+ "features": ["scope-negotiation", "reply-callback"]
142
150
  },
143
151
  "endpoints": {
144
152
  "request": "https://abc-def-123.trycloudflare.com/federation/request",
@@ -426,8 +434,8 @@ ogp federation scopes <peer-id>
426
434
 
427
435
  # Projects
428
436
  ogp project create <id> <name> [--description "..."]
429
- ogp project contribute <id> <topic> <summary>
430
- ogp project query <id> [--limit 10] [--topic <topic>]
437
+ ogp project contribute <id> <type> <summary>
438
+ ogp project query <id> [--limit 10] [--type <type>]
431
439
  ogp project status <id>
432
440
 
433
441
  # Intents
package/docs/scopes.md CHANGED
@@ -19,8 +19,8 @@ Your gateway advertises its capabilities in the federation card at `/.well-known
19
19
  "version": "0.2.3",
20
20
  "displayName": "David's Gateway",
21
21
  "capabilities": {
22
- "intents": ["message", "task-request", "status-update", "agent-comms", "project"],
23
- "features": ["scope-negotiation", "reply-callback", "project-intent"]
22
+ "intents": ["message", "task-request", "status-update", "agent-comms", "project.join", "project.contribute", "project.query", "project.status"],
23
+ "features": ["scope-negotiation", "reply-callback"]
24
24
  }
25
25
  }
26
26
  ```
@@ -28,7 +28,7 @@ Your gateway advertises its capabilities in the federation card at `/.well-known
28
28
  This tells other gateways what you **can** support, not what you **will** grant.
29
29
 
30
30
  Capabilities are automatically populated from:
31
- - **Built-in intents**: `message`, `task-request`, `status-update`, `agent-comms`, `project`
31
+ - **Built-in intents**: `message`, `task-request`, `status-update`, `agent-comms`, `project.join`, `project.contribute`, `project.query`, `project.status`
32
32
  - **Custom intents**: Registered via `ogp intent register`
33
33
  - **Features**: Protocol features your gateway supports
34
34
 
@@ -205,25 +205,25 @@ ogp federation approve alice \
205
205
  --rate 50/3600
206
206
  ```
207
207
 
208
- ## Project Intent
208
+ ## Project Intents
209
209
 
210
- The `project` intent enables collaborative project management across federated peers.
210
+ Project collaboration is enforced through four exact runtime intents, not a singular `project` scope.
211
211
 
212
212
  ### Project Actions
213
213
 
214
214
  | Action | Description | Rate Limit Recommended |
215
215
  |--------|-------------|------------------------|
216
- | `contribute` | Send contribution to peer's project | 100/hour |
217
- | `query` | Query peer's project contributions | 50/hour |
218
- | `request-join` | Request to join peer's project | 10/hour |
219
- | `status` | Get project status from peer | 20/hour |
216
+ | `project.join` | Join or create a shared project context | 10/hour |
217
+ | `project.contribute` | Send a contribution to a peer's project | 100/hour |
218
+ | `project.query` | Query peer project contributions | 50/hour |
219
+ | `project.status` | Get peer project status | 20/hour |
220
220
 
221
221
  ### Grant Project Access
222
222
 
223
223
  ```bash
224
- # Grant project collaboration access
224
+ # Grant full project collaboration access
225
225
  ogp federation approve alice \
226
- --intents project \
226
+ --intents project.join,project.contribute,project.query,project.status \
227
227
  --rate 100/3600
228
228
  ```
229
229
 
@@ -260,9 +260,9 @@ ogp federation approve bob \
260
260
  ### Project Collaboration
261
261
 
262
262
  ```bash
263
- # Grant project and agent-comms for team collaboration
263
+ # Grant project collaboration intents plus agent-comms for team coordination
264
264
  ogp federation approve charlie \
265
- --intents agent-comms,project \
265
+ --intents agent-comms,project.join,project.contribute,project.query,project.status \
266
266
  --topics project-updates,planning \
267
267
  --rate 200/3600
268
268
  ```
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@dp-pcs/ogp",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "Open Gateway Protocol (OGP) - Peer-to-peer federation daemon for OpenClaw AI gateways with cryptographic signatures",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
8
  "bin": {
9
- "ogp": "./dist/cli.js",
10
- "ogp-install-skills": "./scripts/install-skills.js"
9
+ "ogp": "dist/cli.js",
10
+ "ogp-install-skills": "scripts/install-skills.js"
11
11
  },
12
12
  "scripts": {
13
13
  "build": "tsc",
@@ -31,7 +31,7 @@
31
31
  "license": "MIT",
32
32
  "repository": {
33
33
  "type": "git",
34
- "url": "https://github.com/dp-pcs/ogp.git"
34
+ "url": "git+https://github.com/dp-pcs/ogp.git"
35
35
  },
36
36
  "homepage": "https://github.com/dp-pcs/ogp#readme",
37
37
  "bugs": {
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync, mkdirSync, cpSync, readdirSync } from 'node:fs';
2
+ import { existsSync, mkdirSync, cpSync, readdirSync, rmSync, readFileSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
4
  import { homedir } from 'node:os';
5
5
  import { fileURLToPath } from 'node:url';
@@ -55,6 +55,13 @@ const availableSkills = readdirSync(skillsSrc, { withFileTypes: true })
55
55
  .filter(d => d.isDirectory() && existsSync(join(skillsSrc, d.name, 'SKILL.md')))
56
56
  .map(d => d.name);
57
57
 
58
+ function getSkillVersion(skill) {
59
+ const skillFile = join(skillsSrc, skill, 'SKILL.md');
60
+ const content = readFileSync(skillFile, 'utf8');
61
+ const match = content.match(/^version:\s*(.+)$/m);
62
+ return match?.[1]?.trim() ?? 'unknown';
63
+ }
64
+
58
65
  if (availableSkills.length === 0) {
59
66
  console.log('No skills found in the skills/ directory.');
60
67
  process.exit(0);
@@ -176,6 +183,9 @@ async function main() {
176
183
  const src = join(skillsSrc, skill);
177
184
  const dest = join(platform.skillsDir, skill);
178
185
  try {
186
+ // Replace the installed skill directory wholesale so stale files from
187
+ // previous package versions do not survive upgrades.
188
+ rmSync(dest, { recursive: true, force: true });
179
189
  cpSync(src, dest, { recursive: true });
180
190
  console.log(` ✓ ${skill}`);
181
191
  installed++;
@@ -192,6 +202,14 @@ async function main() {
192
202
  console.log(`\n✅ Successfully installed ${totalInstalled} skill(s) to ${selectedPlatforms.length} platform(s)`);
193
203
  console.log('');
194
204
 
205
+ const installedVersions = selectedSkills
206
+ .map(skill => `${skill}@${getSkillVersion(skill)}`)
207
+ .join(', ');
208
+ console.log(`Installed skill versions: ${installedVersions}`);
209
+ console.log('Verify installed copies with:');
210
+ console.log(" rg -n '^version:' ~/.openclaw/skills/ogp*/SKILL.md ~/.claude/skills/ogp*/SKILL.md 2>/dev/null");
211
+ console.log('');
212
+
195
213
  // Platform-specific restart instructions
196
214
  const platformNames = selectedPlatforms.map(p => p.name);
197
215
  if (platformNames.includes('OpenClaw')) {