coherence-cli 0.8.3 → 0.9.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/bin/cc.mjs +27 -0
- package/lib/commands/assets.mjs +18 -5
- package/lib/commands/contributors.mjs +19 -5
- package/lib/commands/deploy.mjs +163 -0
- package/lib/commands/friction.mjs +45 -11
- package/lib/commands/governance.mjs +25 -5
- package/lib/commands/ideas.mjs +24 -8
- package/lib/commands/lineage.mjs +12 -6
- package/lib/commands/listen.mjs +106 -0
- package/lib/commands/news.mjs +26 -9
- package/lib/commands/nodes.mjs +28 -130
- package/lib/commands/providers.mjs +55 -10
- package/lib/commands/services.mjs +14 -6
- package/lib/commands/specs.mjs +13 -5
- package/lib/commands/status.mjs +60 -1
- package/lib/identity.mjs +100 -19
- package/package.json +1 -1
package/lib/identity.mjs
CHANGED
|
@@ -1,46 +1,102 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Identity-first onboarding — runs on first use if no contributor_id in config.
|
|
3
|
+
*
|
|
4
|
+
* Interactive: asks for name + primary identity (e.g. github:seeker71)
|
|
5
|
+
* Non-interactive: auto-generates from COHERENCE_CONTRIBUTOR env, git config,
|
|
6
|
+
* or hostname — then registers with the network.
|
|
3
7
|
*/
|
|
4
8
|
|
|
5
9
|
import { createInterface } from "node:readline/promises";
|
|
6
10
|
import { stdin, stdout } from "node:process";
|
|
11
|
+
import { execSync } from "node:child_process";
|
|
12
|
+
import { hostname } from "node:os";
|
|
13
|
+
import { createHash } from "node:crypto";
|
|
7
14
|
import { getContributorId, saveConfig } from "./config.mjs";
|
|
8
15
|
import { post } from "./api.mjs";
|
|
9
16
|
|
|
10
|
-
const ONBOARD_PROVIDERS = ["github", "ethereum", "x", "email"];
|
|
17
|
+
const ONBOARD_PROVIDERS = ["github", "ethereum", "x", "discord", "email"];
|
|
11
18
|
|
|
12
19
|
async function prompt(rl, question) {
|
|
13
20
|
const answer = await rl.question(question);
|
|
14
21
|
return answer.trim();
|
|
15
22
|
}
|
|
16
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Try to detect identity from environment:
|
|
26
|
+
* 1. COHERENCE_CONTRIBUTOR env var
|
|
27
|
+
* 2. git config user.name (most developers have this)
|
|
28
|
+
* 3. hostname-based hash (last resort)
|
|
29
|
+
*/
|
|
30
|
+
function detectIdentity() {
|
|
31
|
+
// 1. Explicit env var
|
|
32
|
+
if (process.env.COHERENCE_CONTRIBUTOR) {
|
|
33
|
+
return { id: process.env.COHERENCE_CONTRIBUTOR, source: "env" };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 2. Git config
|
|
37
|
+
try {
|
|
38
|
+
const gitUser = execSync("git config user.name", { encoding: "utf8", timeout: 3000 }).trim();
|
|
39
|
+
if (gitUser) {
|
|
40
|
+
return { id: gitUser, source: "git" };
|
|
41
|
+
}
|
|
42
|
+
} catch {}
|
|
43
|
+
|
|
44
|
+
// 3. Hostname hash
|
|
45
|
+
const hash = createHash("sha256").update(hostname()).digest("hex").slice(0, 8);
|
|
46
|
+
return { id: `node-${hostname().split(".")[0].toLowerCase()}-${hash}`, source: "hostname" };
|
|
47
|
+
}
|
|
48
|
+
|
|
17
49
|
/**
|
|
18
50
|
* Ensure the user has a contributor identity.
|
|
19
|
-
* If not, run guided onboarding
|
|
51
|
+
* If not, run guided onboarding (interactive) or auto-detect (non-interactive).
|
|
20
52
|
*/
|
|
21
53
|
export async function ensureIdentity() {
|
|
22
54
|
let id = getContributorId();
|
|
23
55
|
if (id) return id;
|
|
24
56
|
|
|
25
|
-
// Non-interactive environment —
|
|
57
|
+
// Non-interactive environment — auto-detect and register silently
|
|
26
58
|
if (!stdin.isTTY) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
59
|
+
const detected = detectIdentity();
|
|
60
|
+
saveConfig({ contributor_id: detected.id });
|
|
61
|
+
|
|
62
|
+
// Register with the network
|
|
63
|
+
await post("/api/identity/link", {
|
|
64
|
+
contributor_id: detected.id,
|
|
65
|
+
provider: "name",
|
|
66
|
+
provider_id: detected.id,
|
|
67
|
+
display_name: detected.id,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Try to link git identity too
|
|
71
|
+
try {
|
|
72
|
+
const gitUser = execSync("git config user.name", { encoding: "utf8", timeout: 3000 }).trim();
|
|
73
|
+
const gitEmail = execSync("git config user.email", { encoding: "utf8", timeout: 3000 }).trim();
|
|
74
|
+
if (gitEmail) {
|
|
75
|
+
await post("/api/identity/link", {
|
|
76
|
+
contributor_id: detected.id,
|
|
77
|
+
provider: "email",
|
|
78
|
+
provider_id: gitEmail,
|
|
79
|
+
display_name: gitUser || detected.id,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
} catch {}
|
|
83
|
+
|
|
84
|
+
console.error(`Registered as: ${detected.id} (from ${detected.source})`);
|
|
85
|
+
console.error(`Link identity: cc identity link github <handle>`);
|
|
86
|
+
return detected.id;
|
|
30
87
|
}
|
|
31
88
|
|
|
89
|
+
// Interactive — guided onboarding
|
|
32
90
|
const rl = createInterface({ input: stdin, output: stdout });
|
|
33
91
|
|
|
34
92
|
console.log();
|
|
35
93
|
console.log("\x1b[1mWelcome to the Coherence Network.\x1b[0m");
|
|
94
|
+
console.log("Every contribution is traced, scored, and fairly attributed.");
|
|
36
95
|
console.log();
|
|
37
96
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
rl.close();
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
97
|
+
// Suggest detected identity
|
|
98
|
+
const detected = detectIdentity();
|
|
99
|
+
const name = await prompt(rl, `Your name [${detected.id}]: `) || detected.id;
|
|
44
100
|
|
|
45
101
|
saveConfig({ contributor_id: name });
|
|
46
102
|
id = name;
|
|
@@ -53,12 +109,36 @@ export async function ensureIdentity() {
|
|
|
53
109
|
display_name: name,
|
|
54
110
|
});
|
|
55
111
|
|
|
112
|
+
console.log();
|
|
113
|
+
console.log("Link an identity to get credit for your work.");
|
|
114
|
+
console.log("Format: provider:handle (e.g. github:seeker71)");
|
|
56
115
|
console.log();
|
|
57
116
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
117
|
+
// Ask for primary identity
|
|
118
|
+
const primary = await prompt(rl, "Primary identity (e.g. github:seeker71): ");
|
|
119
|
+
if (primary && primary.includes(":")) {
|
|
120
|
+
const [provider, handle] = primary.split(":", 2);
|
|
121
|
+
if (provider && handle) {
|
|
122
|
+
const result = await post("/api/identity/link", {
|
|
123
|
+
contributor_id: name,
|
|
124
|
+
provider: provider.toLowerCase(),
|
|
125
|
+
provider_id: handle,
|
|
126
|
+
display_name: handle,
|
|
127
|
+
});
|
|
128
|
+
if (result) {
|
|
129
|
+
console.log(` \x1b[32m✓\x1b[0m Linked ${provider}:${handle}`);
|
|
130
|
+
} else {
|
|
131
|
+
console.log(` \x1b[33m!\x1b[0m Could not link. Try later: cc identity link ${provider} ${handle}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Offer additional providers
|
|
137
|
+
console.log();
|
|
138
|
+
const more = await prompt(rl, "Link more accounts? (y/n): ");
|
|
139
|
+
if (more.toLowerCase() === "y" || more.toLowerCase() === "yes") {
|
|
140
|
+
for (const provider of ONBOARD_PROVIDERS) {
|
|
141
|
+
const value = await prompt(rl, ` ${provider} handle (enter to skip): `);
|
|
62
142
|
if (value) {
|
|
63
143
|
const result = await post("/api/identity/link", {
|
|
64
144
|
contributor_id: name,
|
|
@@ -69,15 +149,16 @@ export async function ensureIdentity() {
|
|
|
69
149
|
if (result) {
|
|
70
150
|
console.log(` \x1b[32m✓\x1b[0m Linked ${provider}:${value}`);
|
|
71
151
|
} else {
|
|
72
|
-
console.log(` \x1b[33m!\x1b[0m Could not link
|
|
152
|
+
console.log(` \x1b[33m!\x1b[0m Could not link. Try later: cc identity link ${provider} ${value}`);
|
|
73
153
|
}
|
|
74
154
|
}
|
|
75
155
|
}
|
|
76
156
|
}
|
|
77
157
|
|
|
78
158
|
console.log();
|
|
79
|
-
console.log(
|
|
80
|
-
console.log(`
|
|
159
|
+
console.log(`\x1b[32m✓\x1b[0m Registered as: ${name}`);
|
|
160
|
+
console.log(`Config saved to ~/.coherence-network/config.json`);
|
|
161
|
+
console.log(`Link more anytime: cc identity link <provider> <handle>`);
|
|
81
162
|
console.log();
|
|
82
163
|
|
|
83
164
|
rl.close();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coherence-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
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": {
|