@zcloak/ai-agent 1.0.23 → 1.0.25

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 (66) hide show
  1. package/SKILL.md +88 -117
  2. package/dist/bind.js +9 -8
  3. package/dist/bind.js.map +1 -1
  4. package/dist/cli.d.ts +1 -1
  5. package/dist/cli.js +61 -37
  6. package/dist/cli.js.map +1 -1
  7. package/dist/compat.d.ts +32 -0
  8. package/dist/compat.js +91 -0
  9. package/dist/compat.js.map +1 -0
  10. package/dist/config.js +1 -1
  11. package/dist/config.js.map +1 -1
  12. package/dist/daemon.d.ts +14 -24
  13. package/dist/daemon.js +44 -83
  14. package/dist/daemon.js.map +1 -1
  15. package/dist/delete.js +8 -7
  16. package/dist/delete.js.map +1 -1
  17. package/dist/doc.js +4 -3
  18. package/dist/doc.js.map +1 -1
  19. package/dist/feed.js +2 -1
  20. package/dist/feed.js.map +1 -1
  21. package/dist/identity.js +2 -1
  22. package/dist/identity.js.map +1 -1
  23. package/dist/identity_cmd.js +2 -1
  24. package/dist/identity_cmd.js.map +1 -1
  25. package/dist/log.js +3 -6
  26. package/dist/log.js.map +1 -1
  27. package/dist/mailbox-store.d.ts +92 -0
  28. package/dist/mailbox-store.js +166 -0
  29. package/dist/mailbox-store.js.map +1 -0
  30. package/dist/paths.d.ts +39 -0
  31. package/dist/paths.js +77 -0
  32. package/dist/paths.js.map +1 -0
  33. package/dist/pow.js +2 -1
  34. package/dist/pow.js.map +1 -1
  35. package/dist/pre-check.d.ts +4 -4
  36. package/dist/pre-check.js +25 -9
  37. package/dist/pre-check.js.map +1 -1
  38. package/dist/register.js +200 -35
  39. package/dist/register.js.map +1 -1
  40. package/dist/rpc.d.ts +4 -6
  41. package/dist/rpc.js +3 -3
  42. package/dist/rpc.js.map +1 -1
  43. package/dist/serve.d.ts +4 -30
  44. package/dist/serve.js +22 -90
  45. package/dist/serve.js.map +1 -1
  46. package/dist/session.js +4 -3
  47. package/dist/session.js.map +1 -1
  48. package/dist/sign.js +9 -8
  49. package/dist/sign.js.map +1 -1
  50. package/dist/social.js +6 -5
  51. package/dist/social.js.map +1 -1
  52. package/dist/types/registry.d.ts +1 -1
  53. package/dist/types/registry.js +1 -1
  54. package/dist/types/sign-event.d.ts +1 -1
  55. package/dist/types/sign-event.js +1 -1
  56. package/dist/utils.js +1 -1
  57. package/dist/utils.js.map +1 -1
  58. package/dist/verify.js +3 -2
  59. package/dist/verify.js.map +1 -1
  60. package/dist/vetkey.d.ts +18 -15
  61. package/dist/vetkey.js +182 -91
  62. package/dist/vetkey.js.map +1 -1
  63. package/dist/zmail.d.ts +7 -3
  64. package/dist/zmail.js +316 -20
  65. package/dist/zmail.js.map +1 -1
  66. package/package.json +1 -1
package/dist/verify.js CHANGED
@@ -17,6 +17,7 @@
17
17
  import fs from 'fs';
18
18
  import path from 'path';
19
19
  import { hashFile, verifyManifestEntries, formatSignEvent, formatSignEvents, } from './utils.js';
20
+ import * as log from './log.js';
20
21
  // ========== Help Information ==========
21
22
  function showHelp() {
22
23
  console.log('zCloak.ai Verification Tool');
@@ -135,7 +136,7 @@ async function cmdVerifyFolder(session, folderPath) {
135
136
  }
136
137
  }
137
138
  if (!allPassed) {
138
- console.error('\nLocal verification failed! Some files may have been modified.');
139
+ log.error('Local verification failed! Some files may have been modified.');
139
140
  process.exit(1);
140
141
  }
141
142
  console.log('\nLocal verification passed!');
@@ -194,7 +195,7 @@ export async function run(session) {
194
195
  }
195
196
  }
196
197
  catch (err) {
197
- console.error(`Operation failed: ${err instanceof Error ? err.message : String(err)}`);
198
+ log.error(`Operation failed: ${err instanceof Error ? err.message : String(err)}`);
198
199
  process.exit(1);
199
200
  }
200
201
  }
@@ -1 +1 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EACL,QAAQ,EACR,qBAAqB,EACrB,eAAe,EACf,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,yCAAyC;AACzC,SAAS,QAAQ;IACf,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC;IAClF,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;IACxF,OAAO,CAAC,GAAG,CAAC,mFAAmF,CAAC,CAAC;IACjG,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAC;IACzF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,cAAc,CAAC,OAAgB,EAAE,MAAmB;IACjE,MAAM,WAAW,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAE5C,4BAA4B;IAC5B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,yBAAyB,EAAE,CAAC;IAExD,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;QAE1C,mBAAmB;QACnB,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC;YAE/D,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;gBAChC,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,EAAE,CAAC,CAAC;gBACvC,OAAO,CAAC,GAAG,CAAC,gBAAgB,WAAW,GAAG,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC5E,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;AACH,CAAC;AAED,gDAAgD;AAEhD,6BAA6B;AAC7B,KAAK,UAAU,gBAAgB,CAAC,OAAgB,EAAE,OAA2B;IAC3E,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,qBAAqB,EAAE,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAEnD,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IACtC,MAAM,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC;AAED,mCAAmC;AACnC,KAAK,UAAU,aAAa,CAAC,OAAgB,EAAE,QAA4B;IACzE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,oBAAoB;IACpB,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,WAAW,QAAQ,EAAE,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,wBAAwB;IACxB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,qBAAqB,EAAE,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAEtD,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IACtC,MAAM,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC;AAED,4CAA4C;AAC5C,KAAK,UAAU,eAAe,CAAC,OAAgB,EAAE,UAA8B;IAC7E,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACzE,OAAO,CAAC,KAAK,CAAC,oCAAoC,UAAU,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAC1D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,iCAAiC,YAAY,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,yEAAyE;IACzE,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,MAAM,eAAe,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,qBAAqB,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;IAEnE,IAAI,SAAS,GAAG,IAAI,CAAC;IACrB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,YAAY,GAAG,MAAM,EAAE,CAAC,CAAC;YAClD,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;IACH,CAAC;IAED,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,GAAG,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;QAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAE5C,oDAAoD;IACpD,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,oBAAoB,YAAY,EAAE,CAAC,CAAC;IAEhD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,qBAAqB,EAAE,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAE1D,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IACtC,MAAM,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC;AAED,oCAAoC;AACpC,KAAK,UAAU,gBAAgB,CAAC,OAAgB,EAAE,SAA6B;IAC7E,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,qBAAqB,EAAE,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,4BAA4B,CAAC,SAAS,CAAC,CAAC;IAEnE,mCAAmC;IACnC,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,QAAQ,eAAe,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,CAAC;IACtD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED,0DAA0D;AAE1D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,OAAgB;IACxC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEtC,IAAI,CAAC;QACH,QAAQ,OAAO,EAAE,CAAC;YAChB,KAAK,SAAS;gBACZ,MAAM,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvD,MAAM;YACR,KAAK,MAAM;gBACT,MAAM,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpD,MAAM;YACR,KAAK,QAAQ;gBACX,MAAM,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtD,MAAM;YACR,KAAK,SAAS;gBACZ,MAAM,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvD,MAAM;YACR;gBACE,QAAQ,EAAE,CAAC;gBACX,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,CAAC,KAAK,CAAC,sBAAsB,OAAO,EAAE,CAAC,CAAC;gBACjD,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAC,qBAAqB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
package/dist/vetkey.d.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  * decrypt Decrypt Kind5 PrivatePost by event ID
12
12
  * encrypt-only Encrypt locally without canister sign
13
13
  * pubkey Get IBE public key from canister
14
- * serve Start daemon (UDS or stdio mode)
14
+ * serve Start daemon (Unix Domain Socket)
15
15
  * stop Stop a running daemon
16
16
  * status Query daemon status
17
17
  * grant Grant Kind5 decryption access to another user
@@ -31,24 +31,27 @@ import type { Session } from './session.js';
31
31
  * @param session - CLI session with parsed args and canister access
32
32
  */
33
33
  export declare function run(session: Session): Promise<void>;
34
+ /** Key names for the two standard daemons that should always be kept alive */
35
+ export declare const STANDARD_DAEMON_KEY_NAMES: readonly ["default", "Mail"];
34
36
  /**
35
- * Background daemon health check fire-and-forget.
37
+ * Stop ALL running daemons by scanning the runtime directory for .sock files.
36
38
  *
37
- * Called by cli.ts after Session creation to keep both standard daemons
38
- * ("default" and "Mail") alive. If a daemon is dead, spawns it in the
39
- * background WITHOUT waiting for it to be ready (non-blocking).
40
- *
41
- * Prerequisites:
42
- * - The PEM file must exist (user has already created an identity)
43
- * - If PEM doesn't exist, silently skips (no identity = no daemon possible)
39
+ * This covers all daemons regardless of principal or key name (standard,
40
+ * custom, or any --identity), ensuring no stale daemon survives a CLI upgrade.
41
+ * Errors are silently ignored (best-effort shutdown).
42
+ */
43
+ export declare function stopAllDaemons(): Promise<void>;
44
+ /**
45
+ * Spawn a daemon process in the background for the given key name.
44
46
  *
45
- * All errors are silently swallowed this is a best-effort health check
46
- * and must never block or fail the main command.
47
+ * The child process is fully detached (survives parent exit) with stderr
48
+ * redirected to a log file under ~/.config/zcloak/run/.
47
49
  *
48
- * @param pemPath - Path to the identity PEM file
49
- * @param principal - The principal ID derived from the PEM
50
+ * @param pemPath - Path to the identity PEM file
51
+ * @param keyName - Daemon key name (e.g. "default", "Mail")
52
+ * @returns The child process PID (or undefined if spawn failed)
50
53
  */
51
- export declare function ensureDaemonsBackground(pemPath: string, principal: string): void;
54
+ export declare function startDaemonBackground(pemPath: string, keyName: string): number | undefined;
52
55
  /** Tag entry in a Kind17 envelope: ["to", principal], ["payload_type", "text"], etc. */
53
56
  export type EnvelopeTag = [string, ...string[]];
54
57
  /**
@@ -70,7 +73,7 @@ export interface Kind17Envelope {
70
73
  created_at: number;
71
74
  /** Tags carrying recipient and optional metadata */
72
75
  tags: EnvelopeTag[];
73
- /** Encrypted content: base64 IBE ciphertext (string for single recipient) */
76
+ /** Encrypted content: JSON string per zmail-skill spec {"v":1,"type":"text"|"file","ct":"<base64>"} */
74
77
  content: string;
75
78
  /** BIP-340 Schnorr signature over the envelope ID */
76
79
  sig: string;
package/dist/vetkey.js CHANGED
@@ -11,7 +11,7 @@
11
11
  * decrypt Decrypt Kind5 PrivatePost by event ID
12
12
  * encrypt-only Encrypt locally without canister sign
13
13
  * pubkey Get IBE public key from canister
14
- * serve Start daemon (UDS or stdio mode)
14
+ * serve Start daemon (Unix Domain Socket)
15
15
  * stop Stop a running daemon
16
16
  * status Query daemon status
17
17
  * grant Grant Kind5 decryption access to another user
@@ -23,11 +23,11 @@
23
23
  *
24
24
  * Usage: zcloak-ai vetkey <sub-command> [options]
25
25
  */
26
- import { readFileSync, statSync, writeFileSync, existsSync, mkdirSync, openSync, closeSync } from 'fs';
26
+ import { readFileSync, readdirSync, statSync, writeFileSync, existsSync, mkdirSync, openSync, closeSync, unlinkSync } from 'fs';
27
27
  import { basename, dirname } from 'path';
28
28
  import { createConnection } from 'net';
29
29
  import { spawn } from 'child_process';
30
- import { homedir } from 'os';
30
+ import { daemonLogPath } from './paths.js';
31
31
  import { join } from 'path';
32
32
  import { fileURLToPath } from 'url';
33
33
  import { createInterface } from 'readline';
@@ -37,12 +37,13 @@ import { schnorr } from '@noble/curves/secp256k1';
37
37
  import { hexToBytes, bytesToHex } from '@noble/hashes/utils';
38
38
  import * as cryptoOps from './crypto.js';
39
39
  import { KeyStore } from './key-store.js';
40
- import { runDaemonUds, runDaemonStdio } from './serve.js';
41
- import { findRunningDaemon, isDaemonAlive, socketPath } from './daemon.js';
40
+ import { runDaemonUds } from './serve.js';
41
+ import { isDaemonAlive, socketPath, runtimeDir } from './daemon.js';
42
42
  import { canisterCallError } from './error.js';
43
+ import * as log from './log.js';
43
44
  /**
44
45
  * Absolute path to cli.js (the CLI entry script).
45
- * Used by spawnDaemonBackground() to spawn daemon child processes via
46
+ * Used by startDaemonBackground() to spawn daemon child processes via
46
47
  * `process.execPath` (the current Node binary) + this script path, so that
47
48
  * daemon spawning works regardless of how the CLI was invoked (global install,
48
49
  * npx, node dist/cli.js, etc.).
@@ -115,11 +116,6 @@ function showHelp() {
115
116
  console.log(' encrypt-only Encrypt locally without canister sign');
116
117
  console.log(' pubkey Get IBE public key from canister');
117
118
  console.log('');
118
- console.log('Daemon Commands (AES-256-GCM):');
119
- console.log(' serve Start encryption daemon');
120
- console.log(' stop Stop a running daemon');
121
- console.log(' status Query daemon status');
122
- console.log('');
123
119
  console.log('Kind5 Access Control:');
124
120
  console.log(' grant Grant decryption access to another user');
125
121
  console.log(' revoke Revoke an access grant');
@@ -135,8 +131,7 @@ function showHelp() {
135
131
  console.log(' --file=<path> File to encrypt');
136
132
  console.log(' --event-id=<id> Event ID for decryption');
137
133
  console.log(' --output=<path> Output file path');
138
- console.log(' --key-name=<name> Daemon key name (default: "default")');
139
- console.log(' --stdio Use stdin/stdout mode for daemon');
134
+ // --key-name is an internal daemon option, not shown to users
140
135
  console.log(' --public-key=<hex> IBE public key for offline encryption');
141
136
  console.log(' --ibe-identity=<id> IBE identity for offline encryption');
142
137
  console.log(' --tags=<json> Tags as JSON array');
@@ -146,6 +141,7 @@ function showHelp() {
146
141
  console.log(' --duration=<dur> Grant duration: 30d, 1y, permanent (for grant)');
147
142
  console.log(' --grant-id=<id> Grant ID (for revoke)');
148
143
  console.log(' --to=<AI-ID|principal> Recipient AI-ID or principal (for send-msg)');
144
+ console.log(' --reply=<msg_id> Reply to a parent message (for send-msg)');
149
145
  console.log(' --data=<json> Encrypted message JSON envelope (for recv-msg)');
150
146
  console.log(' --no-zmail Skip auto-POST to zMail (send-msg only)');
151
147
  console.log(' --zmail-url=<url> Override zMail server URL');
@@ -394,19 +390,22 @@ async function cmdGetPubkey(session) {
394
390
  }
395
391
  }
396
392
  /**
397
- * serve: Start daemon in UDS or stdio mode.
393
+ * serve: Start daemon over Unix Domain Socket.
398
394
  *
399
395
  * Creates its own long-lived actor for the daemon lifecycle,
400
396
  * using the Session's identity for authentication.
401
397
  */
402
398
  async function cmdServe(session) {
403
399
  const args = session.args;
400
+ // --stdio mode has been removed; reject explicitly so old callers fail fast
401
+ if (args['stdio']) {
402
+ throw new Error("--stdio mode is no longer supported. The daemon now uses Unix Domain Socket (UDS) exclusively.");
403
+ }
404
404
  const rawKeyName = args['key-name'];
405
- // Guard against boolean flag (e.g. --key-name --stdio parses --key-name as true)
405
+ // Guard against boolean flag (e.g. --key-name without value parses as true)
406
406
  if (rawKeyName === true)
407
407
  throw new Error("--key-name requires a value (e.g. --key-name=mykey)");
408
408
  const keyName = rawKeyName || 'default';
409
- const stdio = !!args['stdio'];
410
409
  // Validate key_name
411
410
  if (keyName.includes(":"))
412
411
  throw new Error("key_name must not contain ':' (reserved as separator)");
@@ -418,15 +417,10 @@ async function cmdServe(session) {
418
417
  throw new Error(`derivation_id exceeds 256 bytes (${derivationId.length}); use a shorter key_name`);
419
418
  }
420
419
  // Derive AES-256 key from VetKey via the sign actor
421
- console.error(`Deriving AES-256 key from VetKey (derivation_id: ${derivationId})...`);
420
+ log.info(`Deriving AES-256 key from VetKey (derivation_id: ${derivationId})...`);
422
421
  const keyStore = await KeyStore.deriveFromActor(actor, derivationId);
423
- console.error("Key derived successfully. Starting JSON-RPC daemon...");
424
- if (stdio) {
425
- await runDaemonStdio(keyStore, principal, derivationId);
426
- }
427
- else {
428
- await runDaemonUds(keyStore, principal, derivationId);
429
- }
422
+ log.info("Key derived successfully. Starting JSON-RPC daemon...");
423
+ await runDaemonUds(keyStore, principal, derivationId);
430
424
  }
431
425
  /**
432
426
  * stop: Send shutdown to a running daemon.
@@ -439,21 +433,60 @@ async function cmdStop(session) {
439
433
  const jsonOutput = !!args['json'];
440
434
  const principal = session.getPrincipal();
441
435
  const derivationId = `${principal}:${keyName}`;
442
- const sockPath = findRunningDaemon(derivationId);
443
- // Connect to socket and send shutdown
444
- const response = await sendRpcToSocket(sockPath, {
445
- id: 1,
446
- method: "shutdown",
447
- });
448
- if (jsonOutput) {
449
- console.log(JSON.stringify(response));
436
+ const sockPath = socketPath(derivationId);
437
+ // Try to stop via socket if:
438
+ // 1. isDaemonAlive() says yes (PID + socket both present), OR
439
+ // 2. PID file is missing/corrupt but socket file still exists — the daemon
440
+ // process may be alive with an orphaned socket. Attempt a shutdown via
441
+ // the socket so we don't leave an unmanageable orphan process.
442
+ const alive = isDaemonAlive(derivationId);
443
+ const socketExists = existsSync(sockPath);
444
+ if (!alive && !socketExists) {
445
+ if (jsonOutput) {
446
+ console.log(JSON.stringify({ status: "not_running", key_name: keyName }));
447
+ }
448
+ else {
449
+ console.log(`Daemon '${keyName}' is not running. Nothing to stop.`);
450
+ }
451
+ return;
450
452
  }
451
- else {
452
- console.log("Daemon stopped successfully.");
453
+ try {
454
+ const response = await sendRpcToSocket(sockPath, {
455
+ id: 1,
456
+ method: "shutdown",
457
+ });
458
+ if (jsonOutput) {
459
+ console.log(JSON.stringify(response));
460
+ }
461
+ else {
462
+ console.log("Daemon stopped successfully.");
463
+ }
464
+ }
465
+ catch (e) {
466
+ // Socket file exists but connection failed — stale socket, clean it up
467
+ if (socketExists && !alive) {
468
+ safeUnlinkPath(sockPath);
469
+ if (jsonOutput) {
470
+ console.log(JSON.stringify({ status: "not_running", key_name: keyName, note: "cleaned up stale socket" }));
471
+ }
472
+ else {
473
+ console.log(`Daemon '${keyName}' is not running (cleaned up stale socket).`);
474
+ }
475
+ }
476
+ else {
477
+ throw e;
478
+ }
453
479
  }
454
480
  }
455
481
  /**
456
- * status: Query a running daemon.
482
+ * status: Query daemon status.
483
+ *
484
+ * For standard daemons (default, Mail): auto-starts if not running, so users
485
+ * never need to manually launch a daemon before querying its status.
486
+ *
487
+ * For custom key names: only reports the current state — does NOT auto-start,
488
+ * since custom daemons require explicit `vetkey serve` to start. This keeps
489
+ * `status` side-effect-free for non-standard daemons.
457
490
  */
458
491
  async function cmdStatus(session) {
459
492
  const args = session.args;
@@ -461,9 +494,27 @@ async function cmdStatus(session) {
461
494
  throw new Error("--key-name requires a value (e.g. --key-name=mykey)");
462
495
  const keyName = args['key-name'] || 'default';
463
496
  const jsonOutput = !!args['json'];
464
- const principal = session.getPrincipal();
465
- const derivationId = `${principal}:${keyName}`;
466
- const sockPath = findRunningDaemon(derivationId);
497
+ const isStandard = STANDARD_DAEMON_KEY_NAMES.includes(keyName);
498
+ let sockPath;
499
+ if (isStandard) {
500
+ // Standard daemon: auto-start if needed
501
+ sockPath = await ensureDaemon(session, keyName);
502
+ }
503
+ else {
504
+ // Custom daemon: report-only, no auto-start
505
+ const principal = session.getPrincipal();
506
+ const derivationId = `${principal}:${keyName}`;
507
+ if (!isDaemonAlive(derivationId)) {
508
+ if (jsonOutput) {
509
+ console.log(JSON.stringify({ status: "not_running", key_name: keyName }));
510
+ }
511
+ else {
512
+ console.log(`Daemon '${keyName}' is not running. Use 'zcloak-ai vetkey serve --key-name=${keyName}' to start it.`);
513
+ }
514
+ return;
515
+ }
516
+ sockPath = socketPath(derivationId);
517
+ }
467
518
  // Connect to socket and send status
468
519
  const response = await sendRpcToSocket(sockPath, {
469
520
  id: 1,
@@ -480,13 +531,10 @@ async function cmdStatus(session) {
480
531
  console.log(` Derivation ID: ${result.derivation_id}`);
481
532
  console.log(` Principal: ${result.principal}`);
482
533
  console.log(` Started At: ${result.started_at}`);
483
- console.log(` Mode: ${result.mode}`);
484
- if (result.socket_path) {
485
- console.log(` Socket: ${result.socket_path}`);
486
- }
534
+ console.log(` Socket: ${result.socket_path}`);
487
535
  }
488
536
  else if (response.error) {
489
- console.error(`Error: ${response.error}`);
537
+ log.error(`Error: ${response.error}`);
490
538
  }
491
539
  }
492
540
  }
@@ -498,20 +546,48 @@ const DAEMON_READY_TIMEOUT_MS = 30000;
498
546
  /** Polling interval when waiting for daemon socket to appear (ms) */
499
547
  const DAEMON_POLL_INTERVAL_MS = 500;
500
548
  /** Key names for the two standard daemons that should always be kept alive */
501
- const STANDARD_DAEMON_KEY_NAMES = ['default', 'Mail'];
549
+ export const STANDARD_DAEMON_KEY_NAMES = ['default', 'Mail'];
550
+ /**
551
+ * Stop ALL running daemons by scanning the runtime directory for .sock files.
552
+ *
553
+ * This covers all daemons regardless of principal or key name (standard,
554
+ * custom, or any --identity), ensuring no stale daemon survives a CLI upgrade.
555
+ * Errors are silently ignored (best-effort shutdown).
556
+ */
557
+ export async function stopAllDaemons() {
558
+ const dir = runtimeDir();
559
+ let entries;
560
+ try {
561
+ entries = readdirSync(dir);
562
+ }
563
+ catch {
564
+ return; // Runtime directory doesn't exist — no daemons running
565
+ }
566
+ const sockFiles = entries.filter(e => e.endsWith('.sock'));
567
+ for (const sockFile of sockFiles) {
568
+ const sock = join(dir, sockFile);
569
+ try {
570
+ await sendRpcToSocket(sock, { id: 1, method: "shutdown" });
571
+ log.info(`Daemon stopped (${sockFile}) before upgrade.`);
572
+ }
573
+ catch {
574
+ // Best-effort — daemon may already be gone or socket is stale
575
+ }
576
+ }
577
+ }
502
578
  /**
503
579
  * Spawn a daemon process in the background for the given key name.
504
580
  *
505
581
  * The child process is fully detached (survives parent exit) with stderr
506
- * redirected to a log file under ~/.vetkey-tool/.
582
+ * redirected to a log file under ~/.config/zcloak/run/.
507
583
  *
508
584
  * @param pemPath - Path to the identity PEM file
509
585
  * @param keyName - Daemon key name (e.g. "default", "Mail")
510
586
  * @returns The child process PID (or undefined if spawn failed)
511
587
  */
512
- function spawnDaemonBackground(pemPath, keyName) {
513
- const logDir = join(homedir(), '.vetkey-tool');
514
- const logPath = join(logDir, `${keyName.toLowerCase()}-daemon.log`);
588
+ export function startDaemonBackground(pemPath, keyName) {
589
+ const logPath = daemonLogPath(keyName);
590
+ const logDir = dirname(logPath);
515
591
  try {
516
592
  mkdirSync(logDir, { recursive: true });
517
593
  }
@@ -568,59 +644,33 @@ async function ensureDaemon(session, keyName) {
568
644
  if (isDaemonAlive(derivationId)) {
569
645
  return socketPath(derivationId);
570
646
  }
571
- console.error(`[zcloak-ai] ${keyName} daemon is not running. Starting it automatically...`);
572
- const pid = spawnDaemonBackground(session.getPemPath(), keyName);
573
- console.error(`[zcloak-ai] ${keyName} daemon spawned (PID: ${pid ?? 'unknown'}). Waiting for ready...`);
647
+ log.info(`${keyName} daemon is not running. Starting it automatically...`);
648
+ const pid = startDaemonBackground(session.getPemPath(), keyName);
649
+ log.info(`${keyName} daemon spawned (PID: ${pid ?? 'unknown'}). Waiting for ready...`);
574
650
  // Poll for the socket file to appear (daemon writes PID + creates socket on ready)
575
651
  const sock = socketPath(derivationId);
576
- const logPath = join(homedir(), '.vetkey-tool', `${keyName.toLowerCase()}-daemon.log`);
652
+ const logPath = daemonLogPath(keyName);
577
653
  const deadline = Date.now() + DAEMON_READY_TIMEOUT_MS;
578
654
  while (Date.now() < deadline) {
579
655
  await new Promise((resolve) => setTimeout(resolve, DAEMON_POLL_INTERVAL_MS));
580
656
  if (isDaemonAlive(derivationId) && existsSync(sock)) {
581
- console.error(`[zcloak-ai] ${keyName} daemon is ready. Socket: ${sock}`);
657
+ log.info(`${keyName} daemon is ready. Socket: ${sock}`);
582
658
  return sock;
583
659
  }
584
660
  }
585
661
  throw new Error(`${keyName} daemon failed to start within ${DAEMON_READY_TIMEOUT_MS / 1000}s. ` +
586
662
  `Check the log at ${logPath} for details.`);
587
663
  }
588
- /**
589
- * Background daemon health check — fire-and-forget.
590
- *
591
- * Called by cli.ts after Session creation to keep both standard daemons
592
- * ("default" and "Mail") alive. If a daemon is dead, spawns it in the
593
- * background WITHOUT waiting for it to be ready (non-blocking).
594
- *
595
- * Prerequisites:
596
- * - The PEM file must exist (user has already created an identity)
597
- * - If PEM doesn't exist, silently skips (no identity = no daemon possible)
598
- *
599
- * All errors are silently swallowed — this is a best-effort health check
600
- * and must never block or fail the main command.
601
- *
602
- * @param pemPath - Path to the identity PEM file
603
- * @param principal - The principal ID derived from the PEM
604
- */
605
- export function ensureDaemonsBackground(pemPath, principal) {
606
- for (const keyName of STANDARD_DAEMON_KEY_NAMES) {
607
- const derivationId = `${principal}:${keyName}`;
608
- try {
609
- if (!isDaemonAlive(derivationId)) {
610
- const pid = spawnDaemonBackground(pemPath, keyName);
611
- if (pid) {
612
- console.error(`[zcloak-ai] ${keyName} daemon was not running — auto-started (PID: ${pid})`);
613
- }
614
- }
615
- }
616
- catch {
617
- // Silently ignore — daemon health check must never block the main command
618
- }
619
- }
620
- }
621
664
  // ============================================================================
622
665
  // Helper Functions
623
666
  // ============================================================================
667
+ /** Safely delete a file, ignoring errors if it doesn't exist */
668
+ function safeUnlinkPath(filePath) {
669
+ try {
670
+ unlinkSync(filePath);
671
+ }
672
+ catch { /* ignore */ }
673
+ }
624
674
  /**
625
675
  * Generate default output path for encrypted files.
626
676
  * - If an input file was provided, appends ".enc" suffix (e.g. "data.txt" → "data.txt.enc")
@@ -1022,7 +1072,7 @@ export function schnorrPubkeyFromSpki(spkiHex) {
1022
1072
  *
1023
1073
  * @param session - CLI session (provides identity for Schnorr signing)
1024
1074
  * @param tags - Envelope tags (must include at least one ["to", ...])
1025
- * @param content - Encrypted content string (base64 IBE ciphertext)
1075
+ * @param content - Encrypted content JSON string: {"v":1,"type":"text"|"file","ct":"<base64>"}
1026
1076
  * @returns Signed Kind17Envelope ready for JSON serialization
1027
1077
  */
1028
1078
  function buildSignedEnvelope(session, tags, content) {
@@ -1052,6 +1102,7 @@ function buildSignedEnvelope(session, tags, content) {
1052
1102
  * --to=<AI-ID or principal> (required) Recipient identifier
1053
1103
  * --text=<content> Text message to encrypt
1054
1104
  * --file=<path> File to encrypt
1105
+ * --reply=<msg_id> Parent message ID (for reply threads)
1055
1106
  * --json Output in JSON format (default: true for send-msg)
1056
1107
  */
1057
1108
  async function cmdSendMsg(session) {
@@ -1062,6 +1113,13 @@ async function cmdSendMsg(session) {
1062
1113
  const to = rawTo;
1063
1114
  const text = args['text'];
1064
1115
  const file = args['file'];
1116
+ const rawReply = args['reply'];
1117
+ if (rawReply === true)
1118
+ throw new Error('--reply requires a message ID value');
1119
+ if (typeof rawReply === 'string' && rawReply.length === 0) {
1120
+ throw new Error('--reply requires a non-empty message ID');
1121
+ }
1122
+ const replyMsgId = rawReply;
1065
1123
  if (!to) {
1066
1124
  throw new Error('--to=<AI-ID or principal> is required');
1067
1125
  }
@@ -1100,6 +1158,10 @@ async function cmdSendMsg(session) {
1100
1158
  // IBE-encrypt the plaintext for the recipient's Mail identity
1101
1159
  const ciphertext = cryptoOps.ibeEncrypt(dpkBytes, ibeIdentity, plaintext);
1102
1160
  const contentBase64 = Buffer.from(ciphertext).toString('base64');
1161
+ // Wrap ciphertext in the standardized message composition format per zmail-skill spec.
1162
+ // Shape: {"v":1,"type":"text"|"file","ct":"<base64-ciphertext>"}
1163
+ // The outer Kind17 envelope carries routing metadata; only the body is encrypted.
1164
+ const content = JSON.stringify({ v: 1, type: payloadType, ct: contentBase64 });
1103
1165
  // Build tags: recipient + metadata
1104
1166
  const tags = [
1105
1167
  ['to', recipientPrincipal],
@@ -1109,8 +1171,12 @@ async function cmdSendMsg(session) {
1109
1171
  if (filename) {
1110
1172
  tags.push(['filename', filename]);
1111
1173
  }
1174
+ // Include reply tag when responding to an existing message
1175
+ if (replyMsgId) {
1176
+ tags.push(['reply', replyMsgId]);
1177
+ }
1112
1178
  // Build and sign the Kind17 envelope
1113
- const envelope = buildSignedEnvelope(session, tags, contentBase64);
1179
+ const envelope = buildSignedEnvelope(session, tags, content);
1114
1180
  // Output the envelope as JSON (always JSON for machine consumption)
1115
1181
  console.log(JSON.stringify(envelope));
1116
1182
  // Auto-POST to zMail if not explicitly disabled with --no-zmail.
@@ -1126,10 +1192,10 @@ async function cmdSendMsg(session) {
1126
1192
  : (await import('./config.js')).default.zmail_url;
1127
1193
  const { postEnvelopeToZmail } = await import('./zmail.js');
1128
1194
  const result = await postEnvelopeToZmail(zmailUrl, envelope);
1129
- console.error(`zMail: delivered (msg_id=${result.msg_id}, to=${result.delivered_to})`);
1195
+ log.info(`zMail: delivered (msg_id=${result.msg_id}, to=${result.delivered_to})`);
1130
1196
  }
1131
1197
  catch (err) {
1132
- console.error(`zMail: delivery failed — ${err instanceof Error ? err.message : String(err)}`);
1198
+ log.error(`zMail: delivery failed — ${err instanceof Error ? err.message : String(err)}`);
1133
1199
  }
1134
1200
  }
1135
1201
  }
@@ -1175,6 +1241,31 @@ async function cmdRecvMsg(session) {
1175
1241
  // Verify envelope integrity and sender authentication.
1176
1242
  // Returns true only if full Schnorr signature + principal binding was verified.
1177
1243
  const verifiedSender = verifyKind17Signature(envelope);
1244
+ // Extract the IBE ciphertext from the content field.
1245
+ // Content follows the zmail-skill message composition spec:
1246
+ // {"v":1,"type":"text"|"file","ct":"<base64-ciphertext>"}
1247
+ let ciphertextBase64;
1248
+ try {
1249
+ const parsed = JSON.parse(envelope.content);
1250
+ if (!parsed || typeof parsed !== 'object' || parsed.v !== 1 || typeof parsed.ct !== 'string') {
1251
+ throw new Error('Invalid message composition format: missing v=1 or ct field');
1252
+ }
1253
+ // Validate type field exists and matches one of the allowed payload types
1254
+ if (parsed.type !== 'text' && parsed.type !== 'file') {
1255
+ throw new Error(`Invalid message composition format: type must be "text" or "file", got "${String(parsed.type)}"`);
1256
+ }
1257
+ // Verify consistency between the composition type and the envelope payload_type tag
1258
+ if (parsed.type !== payloadType) {
1259
+ throw new Error(`Message composition type "${parsed.type}" does not match envelope payload_type tag "${payloadType}"`);
1260
+ }
1261
+ ciphertextBase64 = parsed.ct;
1262
+ }
1263
+ catch (e) {
1264
+ if (e instanceof SyntaxError) {
1265
+ throw new Error('Invalid message composition format: content is not valid JSON');
1266
+ }
1267
+ throw e;
1268
+ }
1178
1269
  // Ensure Mail daemon is running (auto-start if needed, wait for ready), then decrypt
1179
1270
  const sockPath = await ensureDaemon(session, 'Mail');
1180
1271
  const response = await sendRpcToSocket(sockPath, {
@@ -1182,7 +1273,7 @@ async function cmdRecvMsg(session) {
1182
1273
  method: 'ibe-decrypt',
1183
1274
  params: {
1184
1275
  ibe_identity: ibeId,
1185
- ciphertext_base64: envelope.content,
1276
+ ciphertext_base64: ciphertextBase64,
1186
1277
  },
1187
1278
  });
1188
1279
  if (response.error) {