@zerox1/sdk 0.1.4 → 0.1.5

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/dist/index.d.ts CHANGED
@@ -71,6 +71,7 @@ export declare class Zerox1Agent {
71
71
  private handlers;
72
72
  private port;
73
73
  private nodeUrl;
74
+ private _reconnectDelay;
74
75
  private constructor();
75
76
  /**
76
77
  * Create an Zerox1Agent instance.
package/dist/index.js CHANGED
@@ -59,6 +59,7 @@ const ws_1 = __importDefault(require("ws"));
59
59
  // [5] uint role (0..1)
60
60
  // ============================================================================
61
61
  function cborInt(n) {
62
+ n = Math.trunc(n);
62
63
  if (n >= 0 && n <= 23)
63
64
  return Buffer.from([n]);
64
65
  if (n >= 24 && n <= 255)
@@ -120,7 +121,11 @@ function resolveKeypairPath(keypair) {
120
121
  }
121
122
  // Caller passed raw bytes — write to a temp file with restrictive permissions.
122
123
  // mode 0o600: owner read/write only — prevents other users from reading the key.
123
- const tmpPath = path.join(os.tmpdir(), `zerox1-identity-${Date.now()}.key`);
124
+ // Create a private temp directory first (mode 0o700) to prevent symlink
125
+ // race attacks on world-writable /tmp before writing the key file.
126
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'zerox1-'));
127
+ fs.chmodSync(tmpDir, 0o700);
128
+ const tmpPath = path.join(tmpDir, 'identity.key');
124
129
  fs.writeFileSync(tmpPath, Buffer.from(keypair), { mode: 0o600 });
125
130
  return tmpPath;
126
131
  }
@@ -146,6 +151,7 @@ class Zerox1Agent {
146
151
  this.handlers = new Map();
147
152
  this.port = 0;
148
153
  this.nodeUrl = '';
154
+ this._reconnectDelay = 1000;
149
155
  }
150
156
  // ── Factory ───────────────────────────────────────────────────────────────
151
157
  /**
@@ -259,6 +265,8 @@ class Zerox1Agent {
259
265
  * Protocol rule 9 requires CBOR — this method handles the encoding.
260
266
  */
261
267
  async sendFeedback(params) {
268
+ if (params.score < -100 || params.score > 100)
269
+ throw new RangeError(`score must be in [-100, 100], got ${params.score}`);
262
270
  const outcomeMap = { negative: 0, neutral: 1, positive: 2 };
263
271
  const roleMap = { participant: 0, notary: 1 };
264
272
  const payload = encodeFeedbackCbor(params.conversationId, params.targetAgent, params.score, outcomeMap[params.outcome], false, roleMap[params.role]);
@@ -290,6 +298,7 @@ class Zerox1Agent {
290
298
  const wsUrl = `ws://127.0.0.1:${this.port}/ws/inbox`;
291
299
  const ws = new ws_1.default(wsUrl);
292
300
  this.ws = ws;
301
+ ws.on('open', () => { this._reconnectDelay = 1000; });
293
302
  ws.on('message', (data) => {
294
303
  try {
295
304
  const raw = JSON.parse(data.toString());
@@ -320,9 +329,11 @@ class Zerox1Agent {
320
329
  catch { /* malformed — ignore */ }
321
330
  });
322
331
  ws.on('close', () => {
323
- // Reconnect only if the process is still running.
324
- if (this.proc)
325
- setTimeout(() => this._connectInbox(), 1000);
332
+ // Reconnect with exponential backoff (1s 2s → 4s … capped at 30s).
333
+ if (this.proc) {
334
+ setTimeout(() => { this._reconnectDelay = 1000; this._connectInbox(); }, this._reconnectDelay);
335
+ this._reconnectDelay = Math.min(this._reconnectDelay * 2, 30000);
336
+ }
326
337
  });
327
338
  ws.on('error', () => { });
328
339
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerox1/sdk",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "0x01 mesh agent SDK — zero-config, binary bundled, works on every platform",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -12,9 +12,9 @@
12
12
  "ws": "^8.18.0"
13
13
  },
14
14
  "optionalDependencies": {
15
- "@zerox1/sdk-darwin-arm64": "0.1.4",
16
- "@zerox1/sdk-darwin-x64": "0.1.4",
17
- "@zerox1/sdk-linux-x64": "0.1.4"
15
+ "@zerox1/sdk-darwin-arm64": "0.1.5",
16
+ "@zerox1/sdk-darwin-x64": "0.1.5",
17
+ "@zerox1/sdk-linux-x64": "0.1.5"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@types/node": "^22.0.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerox1/sdk-darwin-arm64",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "zerox1-node binary for macOS ARM64 (Apple Silicon)",
5
5
  "os": [
6
6
  "darwin"
Binary file
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerox1/sdk-darwin-x64",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "zerox1-node binary for macOS x64 (Intel)",
5
5
  "os": [
6
6
  "darwin"
Binary file
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerox1/sdk-linux-x64",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "zerox1-node binary for Linux x64",
5
5
  "os": [
6
6
  "linux"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerox1/sdk-win32-x64",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "zerox1-node binary for Windows x64",
5
5
  "os": [
6
6
  "win32"
package/src/index.ts CHANGED
@@ -107,6 +107,7 @@ export interface SendFeedbackParams {
107
107
  // ============================================================================
108
108
 
109
109
  function cborInt(n: number): Buffer {
110
+ n = Math.trunc(n)
110
111
  if (n >= 0 && n <= 23) return Buffer.from([n])
111
112
  if (n >= 24 && n <= 255) return Buffer.from([0x18, n])
112
113
  if (n >= -24 && n < 0) return Buffer.from([0x20 + (-n - 1)])
@@ -177,7 +178,11 @@ function resolveKeypairPath(keypair: Uint8Array | string): string {
177
178
  }
178
179
  // Caller passed raw bytes — write to a temp file with restrictive permissions.
179
180
  // mode 0o600: owner read/write only — prevents other users from reading the key.
180
- const tmpPath = path.join(os.tmpdir(), `zerox1-identity-${Date.now()}.key`)
181
+ // Create a private temp directory first (mode 0o700) to prevent symlink
182
+ // race attacks on world-writable /tmp before writing the key file.
183
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'zerox1-'))
184
+ fs.chmodSync(tmpDir, 0o700)
185
+ const tmpPath = path.join(tmpDir, 'identity.key')
181
186
  fs.writeFileSync(tmpPath, Buffer.from(keypair), { mode: 0o600 })
182
187
  return tmpPath
183
188
  }
@@ -203,11 +208,12 @@ async function waitForReady(port: number, timeoutMs = 15_000): Promise<void> {
203
208
  type Handler = (env: InboundEnvelope) => void | Promise<void>
204
209
 
205
210
  export class Zerox1Agent {
206
- private proc: ChildProcess | null = null
207
- private ws: WebSocket | null = null
208
- private handlers: Map<string, Handler[]> = new Map()
209
- private port: number = 0
210
- private nodeUrl: string = ''
211
+ private proc: ChildProcess | null = null
212
+ private ws: WebSocket | null = null
213
+ private handlers: Map<string, Handler[]> = new Map()
214
+ private port: number = 0
215
+ private nodeUrl: string = ''
216
+ private _reconnectDelay: number = 1000
211
217
 
212
218
  private constructor() {}
213
219
 
@@ -342,6 +348,9 @@ export class Zerox1Agent {
342
348
  * Protocol rule 9 requires CBOR — this method handles the encoding.
343
349
  */
344
350
  async sendFeedback(params: SendFeedbackParams): Promise<SentConfirmation> {
351
+ if (params.score < -100 || params.score > 100)
352
+ throw new RangeError(`score must be in [-100, 100], got ${params.score}`)
353
+
345
354
  const outcomeMap = { negative: 0, neutral: 1, positive: 2 } as const
346
355
  const roleMap = { participant: 0, notary: 1 } as const
347
356
 
@@ -388,6 +397,8 @@ export class Zerox1Agent {
388
397
  const ws = new WebSocket(wsUrl)
389
398
  this.ws = ws
390
399
 
400
+ ws.on('open', () => { this._reconnectDelay = 1000 })
401
+
391
402
  ws.on('message', (data) => {
392
403
  try {
393
404
  const raw = JSON.parse(data.toString())
@@ -418,8 +429,11 @@ export class Zerox1Agent {
418
429
  })
419
430
 
420
431
  ws.on('close', () => {
421
- // Reconnect only if the process is still running.
422
- if (this.proc) setTimeout(() => this._connectInbox(), 1000)
432
+ // Reconnect with exponential backoff (1s 2s → 4s … capped at 30s).
433
+ if (this.proc) {
434
+ setTimeout(() => { this._reconnectDelay = 1000; this._connectInbox() }, this._reconnectDelay)
435
+ this._reconnectDelay = Math.min(this._reconnectDelay * 2, 30_000)
436
+ }
423
437
  })
424
438
 
425
439
  ws.on('error', () => { /* close event handles reconnect */ })