@newtype-ai/nit 0.4.14 → 0.4.16
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 +11 -14
- package/dist/chunk-4HRQSCNQ.js +163 -0
- package/dist/{chunk-S2PBPDRY.js → chunk-VFH4LLX2.js} +24 -137
- package/dist/cli.js +81 -5
- package/dist/config-H77K4C4M.js +25 -0
- package/dist/index.js +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,18 +65,17 @@ polymarket.com → { skills: [research, trading], description: "Market analys
|
|
|
65
65
|
|
|
66
66
|
Data in one branch never pollutes another. Switch environments cleanly.
|
|
67
67
|
|
|
68
|
-
###
|
|
68
|
+
### On-chain identity
|
|
69
69
|
|
|
70
|
-
One keypair, multiple chains.
|
|
70
|
+
One keypair, multiple chains. Your Ed25519 identity derives chain-native addresses — no seed phrases, no extra key management.
|
|
71
71
|
|
|
72
72
|
- **Solana** — your Ed25519 public key *is* your Solana address
|
|
73
|
-
- **EVM** (Ethereum, BSC, Polygon, Arbitrum, etc.) — deterministic secp256k1 derivation from your Ed25519
|
|
74
|
-
|
|
73
|
+
- **EVM** (Ethereum, BSC, Polygon, Arbitrum, etc.) — deterministic secp256k1 derivation from your Ed25519 identity
|
|
74
|
+
|
|
75
|
+
Agents prove identity and sign on any chain using the same cryptographic root.
|
|
75
76
|
|
|
76
77
|
```bash
|
|
77
|
-
nit status # shows your
|
|
78
|
-
nit sign-tx --chain evm <hash> # sign a transaction
|
|
79
|
-
nit broadcast --chain evm <tx> # broadcast to RPC
|
|
78
|
+
nit status # shows your chain addresses
|
|
80
79
|
```
|
|
81
80
|
|
|
82
81
|
### Skill resolution
|
|
@@ -107,7 +106,7 @@ Pure Node.js builtins. No bloat.
|
|
|
107
106
|
| Command | Description |
|
|
108
107
|
|---------|-------------|
|
|
109
108
|
| `nit init` | Create `.nit/`, generate Ed25519 keypair, initial commit |
|
|
110
|
-
| `nit status` | Identity info, current branch,
|
|
109
|
+
| `nit status` | Identity info, current branch, chain addresses, uncommitted changes |
|
|
111
110
|
| `nit commit -m "msg"` | Snapshot agent-card.json |
|
|
112
111
|
| `nit log` | Commit history for current branch |
|
|
113
112
|
| `nit diff [target]` | JSON diff vs HEAD, branch, or commit |
|
|
@@ -145,7 +144,7 @@ Platforms verify your identity by challenging you to sign a nonce — no shared
|
|
|
145
144
|
|
|
146
145
|
`publicKey` is managed by nit automatically — injected from your keypair at every commit. You don't need to set or modify it.
|
|
147
146
|
|
|
148
|
-
nit also derives
|
|
147
|
+
nit also derives chain-native addresses from your keypair — Solana (Ed25519 native) and EVM chains (Ethereum, BSC, Polygon, etc.) via a deterministic secp256k1 derivation. Run `nit status` to see your addresses.
|
|
149
148
|
|
|
150
149
|
### Login
|
|
151
150
|
|
|
@@ -191,7 +190,7 @@ your-project/
|
|
|
191
190
|
```typescript
|
|
192
191
|
import {
|
|
193
192
|
init, commit, checkout, branch, push, status, sign, loginPayload,
|
|
194
|
-
loadRawKeyPair, getWalletAddresses, signTx,
|
|
193
|
+
loadRawKeyPair, getWalletAddresses, signTx, rpcSetUrl,
|
|
195
194
|
authSet, authShow, reset, show, pull,
|
|
196
195
|
} from '@newtype-ai/nit';
|
|
197
196
|
|
|
@@ -209,16 +208,14 @@ await push({ all: true });
|
|
|
209
208
|
const keypair = await loadRawKeyPair('/path/to/.nit');
|
|
210
209
|
// → Uint8Array(64) — compatible with Solana and other Ed25519 libraries
|
|
211
210
|
|
|
212
|
-
// Get
|
|
211
|
+
// Get chain addresses (derived from your identity)
|
|
213
212
|
const addresses = await getWalletAddresses('/path/to/.nit');
|
|
214
213
|
// → { solana: "C54kvW3...", ethereum: "0x2317..." }
|
|
215
214
|
|
|
216
|
-
// Sign
|
|
215
|
+
// Sign data with identity-derived keys
|
|
217
216
|
await rpcSetUrl('evm', 'https://eth.llamarpc.com');
|
|
218
217
|
const sig = await signTx('evm', '0x<32-byte-keccak256-hash>');
|
|
219
218
|
// → { chain: 'evm', signature: '0x...', recovery: 0, address: '0x...' }
|
|
220
|
-
await broadcast('evm', '0x<signed-tx-hex>');
|
|
221
|
-
// → { chain: 'evm', txHash: '0x...', rpcUrl: 'https://...' }
|
|
222
219
|
```
|
|
223
220
|
|
|
224
221
|
## License
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// nit — version control for agent cards
|
|
2
|
+
|
|
3
|
+
// src/config.ts
|
|
4
|
+
import { promises as fs } from "fs";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
var CONFIG_FILE = "config";
|
|
7
|
+
async function readConfig(nitDir) {
|
|
8
|
+
const configPath = join(nitDir, CONFIG_FILE);
|
|
9
|
+
let raw;
|
|
10
|
+
try {
|
|
11
|
+
raw = await fs.readFile(configPath, "utf-8");
|
|
12
|
+
} catch {
|
|
13
|
+
return { remotes: {} };
|
|
14
|
+
}
|
|
15
|
+
return parseConfig(raw);
|
|
16
|
+
}
|
|
17
|
+
async function writeConfig(nitDir, config) {
|
|
18
|
+
const configPath = join(nitDir, CONFIG_FILE);
|
|
19
|
+
await fs.writeFile(configPath, serializeConfig(config), "utf-8");
|
|
20
|
+
}
|
|
21
|
+
async function getRemoteCredential(nitDir, remoteName) {
|
|
22
|
+
const config = await readConfig(nitDir);
|
|
23
|
+
return config.remotes[remoteName]?.credential ?? null;
|
|
24
|
+
}
|
|
25
|
+
async function setRemoteCredential(nitDir, remoteName, credential) {
|
|
26
|
+
const config = await readConfig(nitDir);
|
|
27
|
+
if (!config.remotes[remoteName]) {
|
|
28
|
+
config.remotes[remoteName] = {};
|
|
29
|
+
}
|
|
30
|
+
config.remotes[remoteName].credential = credential;
|
|
31
|
+
await writeConfig(nitDir, config);
|
|
32
|
+
}
|
|
33
|
+
async function getRemoteUrl(nitDir, remoteName) {
|
|
34
|
+
const config = await readConfig(nitDir);
|
|
35
|
+
return config.remotes[remoteName]?.url ?? null;
|
|
36
|
+
}
|
|
37
|
+
async function setRemoteUrl(nitDir, remoteName, url) {
|
|
38
|
+
const config = await readConfig(nitDir);
|
|
39
|
+
if (!config.remotes[remoteName]) {
|
|
40
|
+
config.remotes[remoteName] = {};
|
|
41
|
+
}
|
|
42
|
+
config.remotes[remoteName].url = url;
|
|
43
|
+
await writeConfig(nitDir, config);
|
|
44
|
+
}
|
|
45
|
+
async function getSkillsDir(nitDir) {
|
|
46
|
+
const config = await readConfig(nitDir);
|
|
47
|
+
return config.skillsDir ?? null;
|
|
48
|
+
}
|
|
49
|
+
async function setSkillsDir(nitDir, dir) {
|
|
50
|
+
const config = await readConfig(nitDir);
|
|
51
|
+
config.skillsDir = dir;
|
|
52
|
+
await writeConfig(nitDir, config);
|
|
53
|
+
}
|
|
54
|
+
async function getRpcUrl(nitDir, chain) {
|
|
55
|
+
const config = await readConfig(nitDir);
|
|
56
|
+
return config.rpc?.[chain]?.url ?? null;
|
|
57
|
+
}
|
|
58
|
+
async function setRpcUrl(nitDir, chain, url) {
|
|
59
|
+
const config = await readConfig(nitDir);
|
|
60
|
+
if (!config.rpc) {
|
|
61
|
+
config.rpc = {};
|
|
62
|
+
}
|
|
63
|
+
config.rpc[chain] = { url };
|
|
64
|
+
await writeConfig(nitDir, config);
|
|
65
|
+
}
|
|
66
|
+
function parseConfig(raw) {
|
|
67
|
+
const remotes = {};
|
|
68
|
+
const rpc = {};
|
|
69
|
+
let currentSection = null;
|
|
70
|
+
let currentRemote = null;
|
|
71
|
+
let currentRpcChain = null;
|
|
72
|
+
let skillsDir;
|
|
73
|
+
for (const line of raw.split("\n")) {
|
|
74
|
+
const trimmed = line.trim();
|
|
75
|
+
if (trimmed === "" || trimmed.startsWith("#")) continue;
|
|
76
|
+
const remoteMatch = trimmed.match(/^\[remote\s+"([^"]+)"\]$/);
|
|
77
|
+
if (remoteMatch) {
|
|
78
|
+
currentSection = "remote";
|
|
79
|
+
currentRemote = remoteMatch[1];
|
|
80
|
+
currentRpcChain = null;
|
|
81
|
+
if (!remotes[currentRemote]) {
|
|
82
|
+
remotes[currentRemote] = {};
|
|
83
|
+
}
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const rpcMatch = trimmed.match(/^\[rpc\s+"([^"]+)"\]$/);
|
|
87
|
+
if (rpcMatch) {
|
|
88
|
+
currentSection = "rpc";
|
|
89
|
+
currentRpcChain = rpcMatch[1];
|
|
90
|
+
currentRemote = null;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (trimmed === "[skills]") {
|
|
94
|
+
currentSection = "skills";
|
|
95
|
+
currentRemote = null;
|
|
96
|
+
currentRpcChain = null;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const kvMatch = trimmed.match(/^(\w+)\s*=\s*(.+)$/);
|
|
100
|
+
if (kvMatch) {
|
|
101
|
+
const [, key, value] = kvMatch;
|
|
102
|
+
if (currentSection === "remote" && currentRemote !== null) {
|
|
103
|
+
if (key === "url") {
|
|
104
|
+
remotes[currentRemote].url = value.trim();
|
|
105
|
+
} else if (key === "credential") {
|
|
106
|
+
remotes[currentRemote].credential = value.trim();
|
|
107
|
+
}
|
|
108
|
+
} else if (currentSection === "rpc" && currentRpcChain !== null) {
|
|
109
|
+
if (key === "url") {
|
|
110
|
+
rpc[currentRpcChain] = { url: value.trim() };
|
|
111
|
+
}
|
|
112
|
+
} else if (currentSection === "skills") {
|
|
113
|
+
if (key === "dir") {
|
|
114
|
+
skillsDir = value.trim();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const config = { remotes, skillsDir };
|
|
120
|
+
if (Object.keys(rpc).length > 0) {
|
|
121
|
+
config.rpc = rpc;
|
|
122
|
+
}
|
|
123
|
+
return config;
|
|
124
|
+
}
|
|
125
|
+
function serializeConfig(config) {
|
|
126
|
+
const lines = [];
|
|
127
|
+
for (const [name, remote] of Object.entries(config.remotes)) {
|
|
128
|
+
lines.push(`[remote "${name}"]`);
|
|
129
|
+
if (remote.url) {
|
|
130
|
+
lines.push(` url = ${remote.url}`);
|
|
131
|
+
}
|
|
132
|
+
if (remote.credential) {
|
|
133
|
+
lines.push(` credential = ${remote.credential}`);
|
|
134
|
+
}
|
|
135
|
+
lines.push("");
|
|
136
|
+
}
|
|
137
|
+
if (config.rpc) {
|
|
138
|
+
for (const [chain, rpcConfig] of Object.entries(config.rpc)) {
|
|
139
|
+
lines.push(`[rpc "${chain}"]`);
|
|
140
|
+
lines.push(` url = ${rpcConfig.url}`);
|
|
141
|
+
lines.push("");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (config.skillsDir) {
|
|
145
|
+
lines.push("[skills]");
|
|
146
|
+
lines.push(` dir = ${config.skillsDir}`);
|
|
147
|
+
lines.push("");
|
|
148
|
+
}
|
|
149
|
+
return lines.join("\n");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export {
|
|
153
|
+
readConfig,
|
|
154
|
+
writeConfig,
|
|
155
|
+
getRemoteCredential,
|
|
156
|
+
setRemoteCredential,
|
|
157
|
+
getRemoteUrl,
|
|
158
|
+
setRemoteUrl,
|
|
159
|
+
getSkillsDir,
|
|
160
|
+
setSkillsDir,
|
|
161
|
+
getRpcUrl,
|
|
162
|
+
setRpcUrl
|
|
163
|
+
};
|
|
@@ -10,10 +10,17 @@ import {
|
|
|
10
10
|
saveAgentId,
|
|
11
11
|
signMessage
|
|
12
12
|
} from "./chunk-M6SR6QMR.js";
|
|
13
|
+
import {
|
|
14
|
+
getRemoteUrl,
|
|
15
|
+
getSkillsDir,
|
|
16
|
+
readConfig,
|
|
17
|
+
setRpcUrl,
|
|
18
|
+
writeConfig
|
|
19
|
+
} from "./chunk-4HRQSCNQ.js";
|
|
13
20
|
|
|
14
21
|
// src/index.ts
|
|
15
|
-
import { promises as
|
|
16
|
-
import { join as
|
|
22
|
+
import { promises as fs5, statSync } from "fs";
|
|
23
|
+
import { join as join5, basename as basename2, dirname as dirname2, resolve as resolve2 } from "path";
|
|
17
24
|
|
|
18
25
|
// src/objects.ts
|
|
19
26
|
import { createHash } from "crypto";
|
|
@@ -3197,126 +3204,6 @@ function formatValue(val) {
|
|
|
3197
3204
|
return JSON.stringify(val);
|
|
3198
3205
|
}
|
|
3199
3206
|
|
|
3200
|
-
// src/config.ts
|
|
3201
|
-
import { promises as fs5 } from "fs";
|
|
3202
|
-
import { join as join5 } from "path";
|
|
3203
|
-
var CONFIG_FILE = "config";
|
|
3204
|
-
async function readConfig(nitDir) {
|
|
3205
|
-
const configPath = join5(nitDir, CONFIG_FILE);
|
|
3206
|
-
let raw;
|
|
3207
|
-
try {
|
|
3208
|
-
raw = await fs5.readFile(configPath, "utf-8");
|
|
3209
|
-
} catch {
|
|
3210
|
-
return { remotes: {} };
|
|
3211
|
-
}
|
|
3212
|
-
return parseConfig(raw);
|
|
3213
|
-
}
|
|
3214
|
-
async function writeConfig(nitDir, config) {
|
|
3215
|
-
const configPath = join5(nitDir, CONFIG_FILE);
|
|
3216
|
-
await fs5.writeFile(configPath, serializeConfig(config), "utf-8");
|
|
3217
|
-
}
|
|
3218
|
-
async function getRemoteUrl(nitDir, remoteName) {
|
|
3219
|
-
const config = await readConfig(nitDir);
|
|
3220
|
-
return config.remotes[remoteName]?.url ?? null;
|
|
3221
|
-
}
|
|
3222
|
-
async function getSkillsDir(nitDir) {
|
|
3223
|
-
const config = await readConfig(nitDir);
|
|
3224
|
-
return config.skillsDir ?? null;
|
|
3225
|
-
}
|
|
3226
|
-
async function setRpcUrl(nitDir, chain, url) {
|
|
3227
|
-
const config = await readConfig(nitDir);
|
|
3228
|
-
if (!config.rpc) {
|
|
3229
|
-
config.rpc = {};
|
|
3230
|
-
}
|
|
3231
|
-
config.rpc[chain] = { url };
|
|
3232
|
-
await writeConfig(nitDir, config);
|
|
3233
|
-
}
|
|
3234
|
-
function parseConfig(raw) {
|
|
3235
|
-
const remotes = {};
|
|
3236
|
-
const rpc = {};
|
|
3237
|
-
let currentSection = null;
|
|
3238
|
-
let currentRemote = null;
|
|
3239
|
-
let currentRpcChain = null;
|
|
3240
|
-
let skillsDir;
|
|
3241
|
-
for (const line of raw.split("\n")) {
|
|
3242
|
-
const trimmed = line.trim();
|
|
3243
|
-
if (trimmed === "" || trimmed.startsWith("#")) continue;
|
|
3244
|
-
const remoteMatch = trimmed.match(/^\[remote\s+"([^"]+)"\]$/);
|
|
3245
|
-
if (remoteMatch) {
|
|
3246
|
-
currentSection = "remote";
|
|
3247
|
-
currentRemote = remoteMatch[1];
|
|
3248
|
-
currentRpcChain = null;
|
|
3249
|
-
if (!remotes[currentRemote]) {
|
|
3250
|
-
remotes[currentRemote] = {};
|
|
3251
|
-
}
|
|
3252
|
-
continue;
|
|
3253
|
-
}
|
|
3254
|
-
const rpcMatch = trimmed.match(/^\[rpc\s+"([^"]+)"\]$/);
|
|
3255
|
-
if (rpcMatch) {
|
|
3256
|
-
currentSection = "rpc";
|
|
3257
|
-
currentRpcChain = rpcMatch[1];
|
|
3258
|
-
currentRemote = null;
|
|
3259
|
-
continue;
|
|
3260
|
-
}
|
|
3261
|
-
if (trimmed === "[skills]") {
|
|
3262
|
-
currentSection = "skills";
|
|
3263
|
-
currentRemote = null;
|
|
3264
|
-
currentRpcChain = null;
|
|
3265
|
-
continue;
|
|
3266
|
-
}
|
|
3267
|
-
const kvMatch = trimmed.match(/^(\w+)\s*=\s*(.+)$/);
|
|
3268
|
-
if (kvMatch) {
|
|
3269
|
-
const [, key, value] = kvMatch;
|
|
3270
|
-
if (currentSection === "remote" && currentRemote !== null) {
|
|
3271
|
-
if (key === "url") {
|
|
3272
|
-
remotes[currentRemote].url = value.trim();
|
|
3273
|
-
} else if (key === "credential") {
|
|
3274
|
-
remotes[currentRemote].credential = value.trim();
|
|
3275
|
-
}
|
|
3276
|
-
} else if (currentSection === "rpc" && currentRpcChain !== null) {
|
|
3277
|
-
if (key === "url") {
|
|
3278
|
-
rpc[currentRpcChain] = { url: value.trim() };
|
|
3279
|
-
}
|
|
3280
|
-
} else if (currentSection === "skills") {
|
|
3281
|
-
if (key === "dir") {
|
|
3282
|
-
skillsDir = value.trim();
|
|
3283
|
-
}
|
|
3284
|
-
}
|
|
3285
|
-
}
|
|
3286
|
-
}
|
|
3287
|
-
const config = { remotes, skillsDir };
|
|
3288
|
-
if (Object.keys(rpc).length > 0) {
|
|
3289
|
-
config.rpc = rpc;
|
|
3290
|
-
}
|
|
3291
|
-
return config;
|
|
3292
|
-
}
|
|
3293
|
-
function serializeConfig(config) {
|
|
3294
|
-
const lines = [];
|
|
3295
|
-
for (const [name, remote2] of Object.entries(config.remotes)) {
|
|
3296
|
-
lines.push(`[remote "${name}"]`);
|
|
3297
|
-
if (remote2.url) {
|
|
3298
|
-
lines.push(` url = ${remote2.url}`);
|
|
3299
|
-
}
|
|
3300
|
-
if (remote2.credential) {
|
|
3301
|
-
lines.push(` credential = ${remote2.credential}`);
|
|
3302
|
-
}
|
|
3303
|
-
lines.push("");
|
|
3304
|
-
}
|
|
3305
|
-
if (config.rpc) {
|
|
3306
|
-
for (const [chain, rpcConfig] of Object.entries(config.rpc)) {
|
|
3307
|
-
lines.push(`[rpc "${chain}"]`);
|
|
3308
|
-
lines.push(` url = ${rpcConfig.url}`);
|
|
3309
|
-
lines.push("");
|
|
3310
|
-
}
|
|
3311
|
-
}
|
|
3312
|
-
if (config.skillsDir) {
|
|
3313
|
-
lines.push("[skills]");
|
|
3314
|
-
lines.push(` dir = ${config.skillsDir}`);
|
|
3315
|
-
lines.push("");
|
|
3316
|
-
}
|
|
3317
|
-
return lines.join("\n");
|
|
3318
|
-
}
|
|
3319
|
-
|
|
3320
3207
|
// src/tx.ts
|
|
3321
3208
|
async function signTx(nitDir, chain, data) {
|
|
3322
3209
|
const hex = data.startsWith("0x") ? data.slice(2) : data;
|
|
@@ -3385,7 +3272,7 @@ var DEFAULT_API_BASE = "https://api.newtype-ai.org";
|
|
|
3385
3272
|
function findNitDir(startDir) {
|
|
3386
3273
|
let dir = resolve2(startDir || process.cwd());
|
|
3387
3274
|
while (true) {
|
|
3388
|
-
const candidate =
|
|
3275
|
+
const candidate = join5(dir, NIT_DIR);
|
|
3389
3276
|
try {
|
|
3390
3277
|
const s = statSync(candidate);
|
|
3391
3278
|
if (s.isDirectory()) return candidate;
|
|
@@ -3404,17 +3291,17 @@ function projectDir(nitDir) {
|
|
|
3404
3291
|
return resolve2(nitDir, "..");
|
|
3405
3292
|
}
|
|
3406
3293
|
async function readWorkingCard(nitDir) {
|
|
3407
|
-
const cardPath =
|
|
3294
|
+
const cardPath = join5(projectDir(nitDir), CARD_FILE);
|
|
3408
3295
|
try {
|
|
3409
|
-
const raw = await
|
|
3296
|
+
const raw = await fs5.readFile(cardPath, "utf-8");
|
|
3410
3297
|
return JSON.parse(raw);
|
|
3411
3298
|
} catch {
|
|
3412
3299
|
throw new Error(`Cannot read ${CARD_FILE}. Does it exist?`);
|
|
3413
3300
|
}
|
|
3414
3301
|
}
|
|
3415
3302
|
async function writeWorkingCard(nitDir, card) {
|
|
3416
|
-
const cardPath =
|
|
3417
|
-
await
|
|
3303
|
+
const cardPath = join5(projectDir(nitDir), CARD_FILE);
|
|
3304
|
+
await fs5.writeFile(cardPath, JSON.stringify(card, null, 2) + "\n", "utf-8");
|
|
3418
3305
|
}
|
|
3419
3306
|
async function getCardAtCommit(nitDir, commitHash) {
|
|
3420
3307
|
const commitRaw = await readObject(nitDir, commitHash);
|
|
@@ -3432,27 +3319,27 @@ async function getAuthorName(nitDir) {
|
|
|
3432
3319
|
}
|
|
3433
3320
|
async function init(options) {
|
|
3434
3321
|
const projDir = resolve2(options?.projectDir || process.cwd());
|
|
3435
|
-
const nitDir =
|
|
3322
|
+
const nitDir = join5(projDir, NIT_DIR);
|
|
3436
3323
|
try {
|
|
3437
|
-
await
|
|
3324
|
+
await fs5.access(nitDir);
|
|
3438
3325
|
throw new Error("Already initialized. .nit/ directory exists.");
|
|
3439
3326
|
} catch (err) {
|
|
3440
3327
|
if (err instanceof Error && err.message.startsWith("Already")) throw err;
|
|
3441
3328
|
}
|
|
3442
|
-
await
|
|
3443
|
-
await
|
|
3444
|
-
await
|
|
3445
|
-
await
|
|
3446
|
-
await
|
|
3329
|
+
await fs5.mkdir(join5(nitDir, "objects"), { recursive: true });
|
|
3330
|
+
await fs5.mkdir(join5(nitDir, "refs", "heads"), { recursive: true });
|
|
3331
|
+
await fs5.mkdir(join5(nitDir, "refs", "remote"), { recursive: true });
|
|
3332
|
+
await fs5.mkdir(join5(nitDir, "identity"), { recursive: true });
|
|
3333
|
+
await fs5.mkdir(join5(nitDir, "logs"), { recursive: true });
|
|
3447
3334
|
const { publicKey: pubBase64 } = await generateKeypair(nitDir);
|
|
3448
3335
|
const publicKeyField = formatPublicKeyField(pubBase64);
|
|
3449
3336
|
const agentId = deriveAgentId(publicKeyField);
|
|
3450
3337
|
await saveAgentId(nitDir, agentId);
|
|
3451
|
-
const cardPath =
|
|
3338
|
+
const cardPath = join5(projDir, CARD_FILE);
|
|
3452
3339
|
let card;
|
|
3453
3340
|
let skillsFound = [];
|
|
3454
3341
|
try {
|
|
3455
|
-
const raw = await
|
|
3342
|
+
const raw = await fs5.readFile(cardPath, "utf-8");
|
|
3456
3343
|
card = JSON.parse(raw);
|
|
3457
3344
|
card.publicKey = publicKeyField;
|
|
3458
3345
|
skillsFound = card.skills.map((s) => s.id);
|
|
@@ -3491,7 +3378,7 @@ async function init(options) {
|
|
|
3491
3378
|
const commitHash = await writeObject(nitDir, "commit", commitContent);
|
|
3492
3379
|
await setBranch(nitDir, "main", commitHash);
|
|
3493
3380
|
await setHead(nitDir, "main");
|
|
3494
|
-
await
|
|
3381
|
+
await fs5.writeFile(join5(nitDir, "logs", "HEAD"), "", "utf-8");
|
|
3495
3382
|
const skillsDir = await discoverSkillsDir(projDir);
|
|
3496
3383
|
await writeConfig(nitDir, {
|
|
3497
3384
|
remotes: { origin: { url: DEFAULT_API_BASE } },
|
package/dist/cli.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
checkout,
|
|
9
9
|
commit,
|
|
10
10
|
diff,
|
|
11
|
+
findNitDir,
|
|
11
12
|
formatDiff,
|
|
12
13
|
init,
|
|
13
14
|
log,
|
|
@@ -24,8 +25,9 @@ import {
|
|
|
24
25
|
sign,
|
|
25
26
|
signTx,
|
|
26
27
|
status
|
|
27
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-VFH4LLX2.js";
|
|
28
29
|
import "./chunk-M6SR6QMR.js";
|
|
30
|
+
import "./chunk-4HRQSCNQ.js";
|
|
29
31
|
|
|
30
32
|
// src/update-check.ts
|
|
31
33
|
import { execSync } from "child_process";
|
|
@@ -38,7 +40,7 @@ var FETCH_TIMEOUT_MS = 3e3;
|
|
|
38
40
|
var REGISTRY_URL = "https://registry.npmjs.org/@newtype-ai/nit/latest";
|
|
39
41
|
function getCurrentVersion() {
|
|
40
42
|
try {
|
|
41
|
-
return "0.4.
|
|
43
|
+
return "0.4.16";
|
|
42
44
|
} catch {
|
|
43
45
|
return "0.0.0";
|
|
44
46
|
}
|
|
@@ -96,7 +98,7 @@ async function autoUpdate() {
|
|
|
96
98
|
const update = await checkForUpdate().catch(() => null);
|
|
97
99
|
if (!update) return;
|
|
98
100
|
const { current, latest } = update;
|
|
99
|
-
process.stderr.write(`nit: updating ${current} \u2192 ${latest}
|
|
101
|
+
process.stderr.write(`nit: updating ${current} \u2192 ${latest} \u2014 https://github.com/newtype-ai/nit/releases/tag/v${latest}
|
|
100
102
|
`);
|
|
101
103
|
try {
|
|
102
104
|
execSync("npm install -g @newtype-ai/nit@latest", {
|
|
@@ -171,6 +173,9 @@ async function main() {
|
|
|
171
173
|
case "auth":
|
|
172
174
|
await cmdAuth(args);
|
|
173
175
|
break;
|
|
176
|
+
case "wallet":
|
|
177
|
+
await cmdWallet();
|
|
178
|
+
break;
|
|
174
179
|
case "reset":
|
|
175
180
|
await cmdReset(args);
|
|
176
181
|
break;
|
|
@@ -211,7 +216,7 @@ async function cmdInit() {
|
|
|
211
216
|
console.log(` Public key: ${dim(result.publicKey)}`);
|
|
212
217
|
console.log(` Card URL: ${result.cardUrl}`);
|
|
213
218
|
console.log();
|
|
214
|
-
console.log(` ${bold("
|
|
219
|
+
console.log(` ${bold("Chain addresses:")}`);
|
|
215
220
|
console.log(` Solana: ${result.walletAddresses.solana}`);
|
|
216
221
|
console.log(` Ethereum: ${result.walletAddresses.ethereum}`);
|
|
217
222
|
console.log();
|
|
@@ -237,7 +242,7 @@ async function cmdStatus() {
|
|
|
237
242
|
console.log(` Public key: ${dim(s.publicKey)}`);
|
|
238
243
|
console.log(` Card URL: ${s.cardUrl}`);
|
|
239
244
|
console.log();
|
|
240
|
-
console.log(` ${bold("
|
|
245
|
+
console.log(` ${bold("Chain addresses:")}`);
|
|
241
246
|
console.log(` Solana: ${s.walletAddresses.solana}`);
|
|
242
247
|
console.log(` Ethereum: ${s.walletAddresses.ethereum}`);
|
|
243
248
|
console.log();
|
|
@@ -554,6 +559,77 @@ async function cmdAuth(args) {
|
|
|
554
559
|
console.error(" nit auth show [domain]");
|
|
555
560
|
process.exit(1);
|
|
556
561
|
}
|
|
562
|
+
async function cmdWallet() {
|
|
563
|
+
const s = await status();
|
|
564
|
+
const sol = s.walletAddresses.solana;
|
|
565
|
+
const evm = s.walletAddresses.ethereum;
|
|
566
|
+
const agent = s.agentId;
|
|
567
|
+
const network = "devnet";
|
|
568
|
+
let solBalance = "";
|
|
569
|
+
try {
|
|
570
|
+
const { readConfig: rc } = await import("./config-H77K4C4M.js");
|
|
571
|
+
const nitDir = findNitDir();
|
|
572
|
+
const config = await rc(nitDir);
|
|
573
|
+
const rpcUrl = config.rpc?.solana?.url || "https://api.devnet.solana.com";
|
|
574
|
+
{
|
|
575
|
+
const res = await fetch(rpcUrl, {
|
|
576
|
+
method: "POST",
|
|
577
|
+
headers: { "Content-Type": "application/json" },
|
|
578
|
+
body: JSON.stringify({
|
|
579
|
+
jsonrpc: "2.0",
|
|
580
|
+
id: 1,
|
|
581
|
+
method: "getBalance",
|
|
582
|
+
params: [sol]
|
|
583
|
+
})
|
|
584
|
+
});
|
|
585
|
+
const data = await res.json();
|
|
586
|
+
if (data.result?.value !== void 0) {
|
|
587
|
+
const lamports = data.result.value;
|
|
588
|
+
solBalance = (lamports / 1e9).toFixed(4) + " SOL";
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
} catch {
|
|
592
|
+
}
|
|
593
|
+
const rows = [
|
|
594
|
+
["Solana", sol],
|
|
595
|
+
["EVM", evm],
|
|
596
|
+
null,
|
|
597
|
+
["Agent", agent],
|
|
598
|
+
["Network", network, green]
|
|
599
|
+
];
|
|
600
|
+
if (solBalance) {
|
|
601
|
+
rows.splice(2, 0, ["Balance", solBalance, green]);
|
|
602
|
+
}
|
|
603
|
+
printCard(rows);
|
|
604
|
+
}
|
|
605
|
+
function printCard(rows) {
|
|
606
|
+
const labelW = 10;
|
|
607
|
+
const contentLines = [];
|
|
608
|
+
const plainLines = [];
|
|
609
|
+
for (const row of rows) {
|
|
610
|
+
if (!row) {
|
|
611
|
+
contentLines.push("");
|
|
612
|
+
plainLines.push("");
|
|
613
|
+
} else {
|
|
614
|
+
const plain = ` ${row[0].padEnd(labelW)}${row[1]}`;
|
|
615
|
+
const display = row[2] ? ` ${row[0].padEnd(labelW)}${row[2](row[1])}` : plain;
|
|
616
|
+
contentLines.push(display);
|
|
617
|
+
plainLines.push(plain);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
const maxLen = Math.max(...plainLines.map((l) => l.length));
|
|
621
|
+
const w = maxLen + 2;
|
|
622
|
+
console.log();
|
|
623
|
+
console.log(` \u250C${"\u2500".repeat(w)}\u2510`);
|
|
624
|
+
console.log(` \u2502${"".padEnd(w)}\u2502`);
|
|
625
|
+
for (let i = 0; i < contentLines.length; i++) {
|
|
626
|
+
const pad = w - plainLines[i].length;
|
|
627
|
+
console.log(` \u2502${contentLines[i]}${" ".repeat(pad)}\u2502`);
|
|
628
|
+
}
|
|
629
|
+
console.log(` \u2502${"".padEnd(w)}\u2502`);
|
|
630
|
+
console.log(` \u2514${"\u2500".repeat(w)}\u2518`);
|
|
631
|
+
console.log();
|
|
632
|
+
}
|
|
557
633
|
function printUsage() {
|
|
558
634
|
console.log(`
|
|
559
635
|
${bold("nit")} \u2014 version control for agent cards
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// nit — version control for agent cards
|
|
2
|
+
import {
|
|
3
|
+
getRemoteCredential,
|
|
4
|
+
getRemoteUrl,
|
|
5
|
+
getRpcUrl,
|
|
6
|
+
getSkillsDir,
|
|
7
|
+
readConfig,
|
|
8
|
+
setRemoteCredential,
|
|
9
|
+
setRemoteUrl,
|
|
10
|
+
setRpcUrl,
|
|
11
|
+
setSkillsDir,
|
|
12
|
+
writeConfig
|
|
13
|
+
} from "./chunk-4HRQSCNQ.js";
|
|
14
|
+
export {
|
|
15
|
+
getRemoteCredential,
|
|
16
|
+
getRemoteUrl,
|
|
17
|
+
getRpcUrl,
|
|
18
|
+
getSkillsDir,
|
|
19
|
+
readConfig,
|
|
20
|
+
setRemoteCredential,
|
|
21
|
+
setRemoteUrl,
|
|
22
|
+
setRpcUrl,
|
|
23
|
+
setSkillsDir,
|
|
24
|
+
writeConfig
|
|
25
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
signSolanaBytes,
|
|
33
33
|
signTx,
|
|
34
34
|
status
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-VFH4LLX2.js";
|
|
36
36
|
import {
|
|
37
37
|
NIT_NAMESPACE,
|
|
38
38
|
deriveAgentId,
|
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
signChallenge,
|
|
45
45
|
signMessage
|
|
46
46
|
} from "./chunk-M6SR6QMR.js";
|
|
47
|
+
import "./chunk-4HRQSCNQ.js";
|
|
47
48
|
export {
|
|
48
49
|
NIT_NAMESPACE,
|
|
49
50
|
authSet,
|