coherence-cli 0.6.2 → 0.7.1
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/README.md +106 -1
- package/bin/cc.mjs +2 -0
- package/lib/commands/nodes.mjs +10 -1
- package/lib/commands/setup.mjs +133 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -159,6 +159,35 @@ Every part of the network links to every other. Jump in wherever makes sense for
|
|
|
159
159
|
|
|
160
160
|
---
|
|
161
161
|
|
|
162
|
+
## API key — what it's for and how to get one
|
|
163
|
+
|
|
164
|
+
**No key needed for:** Browsing ideas, searching specs, viewing lineage, checking ledgers, reading node status, exploring the network.
|
|
165
|
+
|
|
166
|
+
**Key needed for:** Updating idea status, recording contributions, linking identities, voting on governance, creating specs, managing federation.
|
|
167
|
+
|
|
168
|
+
Most people start without a key. You only need one when you're ready to contribute.
|
|
169
|
+
|
|
170
|
+
### Get a key (interactive)
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
cc setup
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
This walks you through choosing a name, linking an identity (GitHub, Discord, Ethereum, etc.), and generates a key tied to your identity. Stored in `~/.coherence-network/config.json`.
|
|
177
|
+
|
|
178
|
+
### Manual setup
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
export COHERENCE_API_KEY=your-key
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Or set it permanently:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
cc identity set myname
|
|
188
|
+
# Key is auto-generated and stored in ~/.coherence-network/config.json
|
|
189
|
+
```
|
|
190
|
+
|
|
162
191
|
## Configuration
|
|
163
192
|
|
|
164
193
|
By default, `cc` talks to the public API at `https://api.coherencycoin.com`. Override with environment variables:
|
|
@@ -167,7 +196,7 @@ By default, `cc` talks to the public API at `https://api.coherencycoin.com`. Ove
|
|
|
167
196
|
# Point to a local node
|
|
168
197
|
export COHERENCE_API_URL=http://localhost:8000
|
|
169
198
|
|
|
170
|
-
#
|
|
199
|
+
# Set API key for write operations
|
|
171
200
|
export COHERENCE_API_KEY=your-key
|
|
172
201
|
```
|
|
173
202
|
|
|
@@ -175,6 +204,82 @@ Config is stored in `~/.coherence-network/config.json`.
|
|
|
175
204
|
|
|
176
205
|
---
|
|
177
206
|
|
|
207
|
+
## Search, filter, and CRUD
|
|
208
|
+
|
|
209
|
+
Every resource in the network is accessible from the CLI. Here's how to find what you need:
|
|
210
|
+
|
|
211
|
+
### Ideas — the core unit
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
cc ideas # Top 20 by free-energy score (ROI × confidence)
|
|
215
|
+
cc ideas 50 # Top 50
|
|
216
|
+
cc idea <id> # Full detail: scores, open questions, children, tasks
|
|
217
|
+
cc idea create <id> <name> # Create a new idea
|
|
218
|
+
--desc "..." # Description
|
|
219
|
+
--value 50 --cost 5 # Potential value and estimated cost
|
|
220
|
+
--parent <parent-id> # Parent idea (fractal hierarchy)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Specs — blueprints linked to ideas
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
cc specs # List specs with ROI and value gap
|
|
227
|
+
cc specs 50 # More results
|
|
228
|
+
cc spec <id> # Full spec: summary, pseudocode, implementation status
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Tasks — the work queue
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
cc tasks # All pending tasks
|
|
235
|
+
cc tasks running # In-progress tasks
|
|
236
|
+
cc tasks completed 20 # Last 20 completed
|
|
237
|
+
cc task <id> # Full task: direction, idea link, output, provider
|
|
238
|
+
cc task next # Claim the highest-priority task
|
|
239
|
+
cc task seed <idea-id> spec # Create a task for an idea
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Contributors and identity
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
cc identity # Your linked accounts and CC balance
|
|
246
|
+
cc identity lookup github <handle> # Find any contributor by provider identity
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Nodes and federation
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
cc nodes # All nodes: status, SHA, providers, last seen
|
|
253
|
+
cc inbox # Messages from other nodes
|
|
254
|
+
cc msg <node> <text> # Send a message
|
|
255
|
+
cc cmd <node> status # Remote diagnostics
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Searching and filtering
|
|
259
|
+
|
|
260
|
+
Most list commands accept a limit. For deeper filtering, use the API directly:
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# Search ideas by keyword
|
|
264
|
+
curl -s "$CN_API/api/ideas/cards?search=treasury&limit=10" | jq '.items[] | {id, name}'
|
|
265
|
+
|
|
266
|
+
# Search specs by keyword
|
|
267
|
+
curl -s "$CN_API/api/spec-registry/cards?search=auth&limit=10" | jq '.items[] | {spec_id, title}'
|
|
268
|
+
|
|
269
|
+
# Filter tasks by type and status
|
|
270
|
+
curl -s "$CN_API/api/agent/tasks?status=completed&task_type=review&limit=10" | jq '.tasks[] | {id, task_type}'
|
|
271
|
+
|
|
272
|
+
# Contributor ledger
|
|
273
|
+
curl -s "$CN_API/api/contributions/ledger/seeker71" | jq '.balance'
|
|
274
|
+
|
|
275
|
+
# Ideas by parent (fractal drill-down)
|
|
276
|
+
curl -s "$CN_API/api/ideas/<parent-id>" | jq '.child_idea_ids'
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
The full API has 215 endpoints across 20 resource groups — see [api.coherencycoin.com/docs](https://api.coherencycoin.com/docs) for the complete reference. The CLI covers the most common operations; the API covers everything.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
178
283
|
## All commands
|
|
179
284
|
|
|
180
285
|
```
|
package/bin/cc.mjs
CHANGED
|
@@ -15,6 +15,7 @@ import { showStatus, showResonance } from "../lib/commands/status.mjs";
|
|
|
15
15
|
import { showIdentity, linkIdentity, unlinkIdentity, lookupIdentity, setupIdentity, setIdentity } from "../lib/commands/identity.mjs";
|
|
16
16
|
import { listNodes, sendMessage, readMessages, sendCommand } from "../lib/commands/nodes.mjs";
|
|
17
17
|
import { listTasks, showTask, claimTask, claimNext, reportTask, seedTask } from "../lib/commands/tasks.mjs";
|
|
18
|
+
import { setup } from "../lib/commands/setup.mjs";
|
|
18
19
|
|
|
19
20
|
// Version check — non-blocking, runs in background
|
|
20
21
|
const require = createRequire(import.meta.url);
|
|
@@ -69,6 +70,7 @@ const COMMANDS = {
|
|
|
69
70
|
inbox: () => readMessages(args),
|
|
70
71
|
tasks: () => listTasks(args),
|
|
71
72
|
task: () => handleTask(args),
|
|
73
|
+
setup: () => setup(args),
|
|
72
74
|
update: () => selfUpdate(),
|
|
73
75
|
version: () => console.log(`cc v${LOCAL_VERSION}`),
|
|
74
76
|
help: () => showHelp(),
|
package/lib/commands/nodes.mjs
CHANGED
|
@@ -119,7 +119,16 @@ export async function listNodes() {
|
|
|
119
119
|
|
|
120
120
|
const ago = ageMin < 1 ? "now" : ageMin < 60 ? `${ageMin}m ago` : `${Math.floor(ageMin / 60)}h ago`;
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
// Git version from capabilities
|
|
123
|
+
const git = node.capabilities?.git || {};
|
|
124
|
+
const sha = git.local_sha || "?";
|
|
125
|
+
const originSha = git.origin_sha || "?";
|
|
126
|
+
const upToDate = git.up_to_date === "yes";
|
|
127
|
+
const versionTag = upToDate
|
|
128
|
+
? `\x1b[32m${sha}\x1b[0m`
|
|
129
|
+
: `\x1b[31m${sha} (origin: ${originSha})\x1b[0m`;
|
|
130
|
+
|
|
131
|
+
console.log(` ${dot} ${icon} \x1b[1m${node.hostname || "?"}\x1b[0m ${ago} sha:${versionTag}`);
|
|
123
132
|
console.log(` ${providers.join(", ")}`);
|
|
124
133
|
console.log(` id: ${node.node_id}`);
|
|
125
134
|
console.log();
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive onboarding: cc setup
|
|
3
|
+
*
|
|
4
|
+
* Guides a new contributor through identity + API key setup.
|
|
5
|
+
* Non-interactive mode: cc setup --name <name> --provider <p> --id <id>
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { get, post } from "../api.mjs";
|
|
9
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { createInterface } from "node:readline";
|
|
13
|
+
|
|
14
|
+
const CONFIG_DIR = join(homedir(), ".coherence-network");
|
|
15
|
+
const KEYS_FILE = join(CONFIG_DIR, "keys.json");
|
|
16
|
+
|
|
17
|
+
function ask(rl, question) {
|
|
18
|
+
return new Promise((resolve) => rl.question(question, resolve));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function loadKeys() {
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(readFileSync(KEYS_FILE, "utf-8"));
|
|
24
|
+
} catch {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function saveKeys(keys) {
|
|
30
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
31
|
+
writeFileSync(KEYS_FILE, JSON.stringify(keys, null, 2), { mode: 0o600 });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function setup(args) {
|
|
35
|
+
// Check if already set up
|
|
36
|
+
const keys = loadKeys();
|
|
37
|
+
if (keys.api_key && keys.contributor_id) {
|
|
38
|
+
console.log(`\n\x1b[32m✓\x1b[0m Already set up as \x1b[1m${keys.contributor_id}\x1b[0m`);
|
|
39
|
+
console.log(` API key: ${keys.api_key.slice(0, 12)}...`);
|
|
40
|
+
console.log(` Provider: ${keys.provider}:${keys.provider_id}`);
|
|
41
|
+
console.log(`\n To reconfigure: rm ${KEYS_FILE} && cc setup`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Non-interactive mode
|
|
46
|
+
const nameIdx = args.indexOf("--name");
|
|
47
|
+
const providerIdx = args.indexOf("--provider");
|
|
48
|
+
const idIdx = args.indexOf("--id");
|
|
49
|
+
|
|
50
|
+
if (nameIdx >= 0 && providerIdx >= 0 && idIdx >= 0) {
|
|
51
|
+
const name = args[nameIdx + 1];
|
|
52
|
+
const provider = args[providerIdx + 1];
|
|
53
|
+
const providerId = args[idIdx + 1];
|
|
54
|
+
return await completeSetup(name, provider, providerId);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Interactive mode
|
|
58
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
59
|
+
|
|
60
|
+
console.log(`
|
|
61
|
+
\x1b[1mCoherence Network — Contributor Setup\x1b[0m
|
|
62
|
+
|
|
63
|
+
This will create your contributor identity and generate a personal API key.
|
|
64
|
+
Everything you create, contribute, and invest will be attributed to you.
|
|
65
|
+
`);
|
|
66
|
+
|
|
67
|
+
const name = await ask(rl, " Your name (will be your contributor ID): ");
|
|
68
|
+
if (!name.trim()) {
|
|
69
|
+
console.log("\x1b[31m✗\x1b[0m Name is required");
|
|
70
|
+
rl.close();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
console.log(`
|
|
75
|
+
Link an identity so others can find and verify you.
|
|
76
|
+
Providers: github, email, ethereum, discord, x, linkedin, telegram, ...
|
|
77
|
+
`);
|
|
78
|
+
|
|
79
|
+
const provider = await ask(rl, " Provider (e.g. github): ");
|
|
80
|
+
const providerId = await ask(rl, ` Your ${provider || "provider"} handle/address: `);
|
|
81
|
+
|
|
82
|
+
rl.close();
|
|
83
|
+
|
|
84
|
+
if (!provider.trim() || !providerId.trim()) {
|
|
85
|
+
console.log("\x1b[31m✗\x1b[0m Provider and handle are required");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
await completeSetup(name.trim(), provider.trim().toLowerCase(), providerId.trim());
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function completeSetup(name, provider, providerId) {
|
|
93
|
+
console.log(`\n Setting up \x1b[1m${name}\x1b[0m with ${provider}:${providerId}...`);
|
|
94
|
+
|
|
95
|
+
// Generate API key
|
|
96
|
+
const result = await post("/api/auth/keys", {
|
|
97
|
+
contributor_id: name,
|
|
98
|
+
provider,
|
|
99
|
+
provider_id: providerId,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
if (!result || !result.api_key) {
|
|
103
|
+
console.log(`\x1b[31m✗\x1b[0m Setup failed: ${JSON.stringify(result)}`);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Save to config
|
|
108
|
+
const keys = {
|
|
109
|
+
contributor_id: name,
|
|
110
|
+
api_key: result.api_key,
|
|
111
|
+
provider,
|
|
112
|
+
provider_id: providerId,
|
|
113
|
+
created_at: result.created_at,
|
|
114
|
+
scopes: result.scopes,
|
|
115
|
+
};
|
|
116
|
+
saveKeys(keys);
|
|
117
|
+
|
|
118
|
+
console.log(`
|
|
119
|
+
\x1b[32m✓\x1b[0m Setup complete!
|
|
120
|
+
|
|
121
|
+
Contributor: \x1b[1m${name}\x1b[0m
|
|
122
|
+
Identity: ${provider}:${providerId}
|
|
123
|
+
API key: ${result.api_key.slice(0, 20)}...
|
|
124
|
+
Saved to: ${KEYS_FILE}
|
|
125
|
+
|
|
126
|
+
You can now:
|
|
127
|
+
cc ideas Browse ideas
|
|
128
|
+
cc share Submit a new idea
|
|
129
|
+
cc contribute Record a contribution
|
|
130
|
+
cc stake <id> <cc> Invest in an idea
|
|
131
|
+
cc status Check network health
|
|
132
|
+
`);
|
|
133
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coherence-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Coherence Network CLI \u2014 trace ideas from inception to payout, with fair attribution, coherence scoring, and 37 identity providers. No signup needed.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|