@masstensor/anotify 0.0.0-stage → 0.5.8

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 (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +14 -2
  3. package/dist/src/adapters.js +97 -0
  4. package/dist/src/adapters.js.map +1 -0
  5. package/dist/src/claude-question-wait.js +67 -0
  6. package/dist/src/claude-question-wait.js.map +1 -0
  7. package/dist/src/claude-question.js +22 -0
  8. package/dist/src/claude-question.js.map +1 -0
  9. package/dist/src/claude.js +23 -0
  10. package/dist/src/claude.js.map +1 -0
  11. package/dist/src/cli.js +294 -0
  12. package/dist/src/cli.js.map +1 -0
  13. package/dist/src/codex-readiness.js +37 -0
  14. package/dist/src/codex-readiness.js.map +1 -0
  15. package/dist/src/config.js +21 -0
  16. package/dist/src/config.js.map +1 -0
  17. package/dist/src/crypto.js +26 -0
  18. package/dist/src/crypto.js.map +1 -0
  19. package/dist/src/daemon.js +356 -0
  20. package/dist/src/daemon.js.map +1 -0
  21. package/dist/src/demand.js +89 -0
  22. package/dist/src/demand.js.map +1 -0
  23. package/dist/src/device-name.js +12 -0
  24. package/dist/src/device-name.js.map +1 -0
  25. package/dist/src/http.js +38 -0
  26. package/dist/src/http.js.map +1 -0
  27. package/dist/src/install.js +254 -0
  28. package/dist/src/install.js.map +1 -0
  29. package/dist/src/integration.js +184 -0
  30. package/dist/src/integration.js.map +1 -0
  31. package/dist/src/mcp.js +48 -0
  32. package/dist/src/mcp.js.map +1 -0
  33. package/dist/src/native-owner.js +44 -0
  34. package/dist/src/native-owner.js.map +1 -0
  35. package/dist/src/npm-cli.js +24 -0
  36. package/dist/src/npm-cli.js.map +1 -0
  37. package/dist/src/owners.js +57 -0
  38. package/dist/src/owners.js.map +1 -0
  39. package/dist/src/pairing-cli.js +125 -0
  40. package/dist/src/pairing-cli.js.map +1 -0
  41. package/dist/src/pairing.js +57 -0
  42. package/dist/src/pairing.js.map +1 -0
  43. package/dist/src/preferences.js +18 -0
  44. package/dist/src/preferences.js.map +1 -0
  45. package/dist/src/protocol.js +40 -0
  46. package/dist/src/protocol.js.map +1 -0
  47. package/dist/src/question-crypto.js +29 -0
  48. package/dist/src/question-crypto.js.map +1 -0
  49. package/dist/src/readiness.js +58 -0
  50. package/dist/src/readiness.js.map +1 -0
  51. package/dist/src/service.js +54 -0
  52. package/dist/src/service.js.map +1 -0
  53. package/dist/src/sessions.js +217 -0
  54. package/dist/src/sessions.js.map +1 -0
  55. package/dist/src/setup-cli.js +59 -0
  56. package/dist/src/setup-cli.js.map +1 -0
  57. package/dist/src/terminal.js +68 -0
  58. package/dist/src/terminal.js.map +1 -0
  59. package/dist/src/vault.js +49 -0
  60. package/dist/src/vault.js.map +1 -0
  61. package/dist/src/wizard.js +43 -0
  62. package/dist/src/wizard.js.map +1 -0
  63. package/npm-shrinkwrap.json +1919 -0
  64. package/package.json +26 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.js","sourceRoot":"","sources":["../../src/integration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { z } from 'zod';
4
+ import { nativeBinding } from './adapters.js';
5
+ export async function serveMcp(post, host, instanceId, passive = false) {
6
+ const server = new McpServer({ name: 'agent-notify', version: '0.1.0' });
7
+ if (passive) {
8
+ await server.connect(new StdioServerTransport());
9
+ return;
10
+ }
11
+ const reserved = host === 'gemini-cli' ? { _notifyCapability: z.string().optional().describe('Reserved: supplied by the BeforeTool hook; omit this field.') } : {};
12
+ async function binding(meta, injected) {
13
+ const native = host === 'gemini-cli' ? { capability: z.string().uuid().parse(injected) } : nativeBinding(host, meta);
14
+ const context = await post('/lookup', { capability: native.capability, instanceId });
15
+ if (context.host !== host || (native.context && (native.context.sessionId !== context.sessionId || native.context.turnId !== context.turnId)))
16
+ throw new Error('MCP metadata does not match the registered hook context');
17
+ return { capability: native.capability, context };
18
+ }
19
+ const failure = (e) => ({ isError: true, content: [{ type: 'text', text: e instanceof Error ? e.message : 'Notification failed' }] });
20
+ server.registerTool('notify', {
21
+ description: 'Send progress, explicit content, or action_required when the user must act before work can continue (login, answer a question, configure a service). Tell them what to do on their Mac; no phone reply or permission approval is performed. Final replies are delivered by hooks. Session identity is supplied by the host adapter.',
22
+ inputSchema: { kind: z.enum(['progress', 'content', 'action_required']), title: z.string().min(1).max(200), markdown: z.string().max(1048576), ...reserved },
23
+ }, async (input, extra) => {
24
+ try {
25
+ const bound = await binding(extra._meta, z.object({ _notifyCapability: z.string().optional() }).parse(input)._notifyCapability);
26
+ const result = await post('/mcp', { capability: bound.capability, callId: bound.capability, instanceId, content: { kind: input.kind, title: input.title, markdown: input.markdown } });
27
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
28
+ }
29
+ catch (e) {
30
+ return failure(e);
31
+ }
32
+ });
33
+ server.registerTool('set_notification_policy', {
34
+ description: 'Change automatic notifications for this session: all, off, or next_turn. Explicitly requested content remains available. Setting next_turn does not notify for this setting turn.',
35
+ inputSchema: { mode: z.enum(['all', 'next_turn', 'off']), ...reserved },
36
+ }, async (input, extra) => {
37
+ try {
38
+ const { context } = await binding(extra._meta, z.object({ _notifyCapability: z.string().optional() }).parse(input)._notifyCapability);
39
+ await post('/policy', { host: context.host, sessionId: context.sessionId, mode: input.mode === 'next_turn' ? 'once' : input.mode, armedTurn: context.turnId });
40
+ return { content: [{ type: 'text', text: JSON.stringify({ mode: input.mode, sessionId: context.sessionId, status: 'saved' }) }] };
41
+ }
42
+ catch (e) {
43
+ return failure(e);
44
+ }
45
+ });
46
+ await server.connect(new StdioServerTransport());
47
+ }
48
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { basename } from 'node:path';
3
+ import { processOwner } from './owners.js';
4
+ function inspect(pid) {
5
+ const owner = processOwner(pid);
6
+ if (!owner)
7
+ return;
8
+ try {
9
+ const read = (field) => execFileSync('/bin/ps', ['-p', String(pid), '-o', field + '='], { encoding: 'utf8', timeout: 2000, stdio: ['ignore', 'pipe', 'ignore'] }).trim();
10
+ const parent = Number(read('ppid')), command = read('comm'), args = read('args');
11
+ if (processOwner(pid)?.start !== owner.start)
12
+ return;
13
+ return { owner, parent, command, args };
14
+ }
15
+ catch {
16
+ return;
17
+ }
18
+ }
19
+ /** Shared servers cannot identify one logical conversation by their PID. */
20
+ export function standaloneAgent(host, command, args) {
21
+ const name = basename(command), expected = host === 'claude-code' ? 'claude' : host === 'codex' ? 'codex' : 'gemini';
22
+ if (name !== expected)
23
+ return false;
24
+ if (/(?:^|\s)(?:app-server|exec-server|--remote|--sdk-url)(?:\s|=|$)/.test(args))
25
+ return false;
26
+ return true;
27
+ }
28
+ export function nativeHookOwner(host, parent = process.ppid, read = inspect) {
29
+ for (let depth = 0; depth < 3; depth++) {
30
+ const info = read(parent);
31
+ if (!info)
32
+ return;
33
+ if (standaloneAgent(host, info.command, info.args)) {
34
+ const launcher = read(info.parent);
35
+ if (!launcher || !['sh', 'bash', 'zsh', 'dash', 'fish', 'expect', 'Terminal'].includes(basename(launcher.command)))
36
+ return;
37
+ return info.owner;
38
+ }
39
+ if (!['sh', 'bash', 'zsh', 'dash'].includes(basename(info.command)))
40
+ return;
41
+ parent = info.parent;
42
+ }
43
+ }
44
+ //# sourceMappingURL=native-owner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-owner.js","sourceRoot":"","sources":["../../src/native-owner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAC,QAAQ,EAAC,MAAM,WAAW,CAAC;AAEnC,OAAO,EAAC,YAAY,EAAmB,MAAM,aAAa,CAAC;AAG3D,SAAS,OAAO,CAAC,GAAU;IAC1B,MAAM,KAAK,GAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAAA,IAAG,CAAC,KAAK;QAAC,OAAO;IAC/C,IAAG,CAAC;QACH,MAAM,IAAI,GAAC,CAAC,KAAY,EAAC,EAAE,CAAA,YAAY,CAAC,SAAS,EAAC,CAAC,IAAI,EAAC,MAAM,CAAC,GAAG,CAAC,EAAC,IAAI,EAAC,KAAK,GAAC,GAAG,CAAC,EAAC,EAAC,QAAQ,EAAC,MAAM,EAAC,OAAO,EAAC,IAAI,EAAC,KAAK,EAAC,CAAC,QAAQ,EAAC,MAAM,EAAC,QAAQ,CAAC,EAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5J,MAAM,MAAM,GAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAC,OAAO,GAAC,IAAI,CAAC,MAAM,CAAC,EAAC,IAAI,GAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzE,IAAG,YAAY,CAAC,GAAG,CAAC,EAAE,KAAK,KAAG,KAAK,CAAC,KAAK;YAAC,OAAO;QACjD,OAAO,EAAC,KAAK,EAAC,MAAM,EAAC,OAAO,EAAC,IAAI,EAAC,CAAC;IACpC,CAAC;IAAA,MAAK,CAAC;QAAA,OAAO;IAAA,CAAC;AAChB,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAAC,IAAS,EAAC,OAAc,EAAC,IAAW;IACnE,MAAM,IAAI,GAAC,QAAQ,CAAC,OAAO,CAAC,EAAC,QAAQ,GAAC,IAAI,KAAG,aAAa,CAAA,CAAC,CAAA,QAAQ,CAAA,CAAC,CAAA,IAAI,KAAG,OAAO,CAAA,CAAC,CAAA,OAAO,CAAA,CAAC,CAAA,QAAQ,CAAC;IACpG,IAAG,IAAI,KAAG,QAAQ;QAAC,OAAO,KAAK,CAAC;IAChC,IAAG,iEAAiE,CAAC,IAAI,CAAC,IAAI,CAAC;QAAC,OAAO,KAAK,CAAC;IAC7F,OAAO,IAAI,CAAC;AACb,CAAC;AACD,MAAM,UAAU,eAAe,CAAC,IAAS,EAAC,MAAM,GAAC,OAAO,CAAC,IAAI,EAAC,IAAI,GAAC,OAAO;IACzE,KAAI,IAAI,KAAK,GAAC,CAAC,EAAC,KAAK,GAAC,CAAC,EAAC,KAAK,EAAE,EAAC,CAAC;QAChC,MAAM,IAAI,GAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAAA,IAAG,CAAC,IAAI;YAAC,OAAO;QACxC,IAAG,eAAe,CAAC,IAAI,EAAC,IAAI,CAAC,OAAO,EAAC,IAAI,CAAC,IAAI,CAAC,EAAC,CAAC;YAChD,MAAM,QAAQ,GAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjC,IAAG,CAAC,QAAQ,IAAE,CAAC,CAAC,IAAI,EAAC,MAAM,EAAC,KAAK,EAAC,MAAM,EAAC,MAAM,EAAC,QAAQ,EAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAAC,OAAO;YACjH,OAAO,IAAI,CAAC,KAAK,CAAC;QACnB,CAAC;QACD,IAAG,CAAC,CAAC,IAAI,EAAC,MAAM,EAAC,KAAK,EAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAAC,OAAO;QACvE,MAAM,GAAC,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;AACF,CAAC"}
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from 'node:child_process';
3
+ import { existsSync, readFileSync } from 'node:fs';
4
+ import { homedir } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ const args = process.argv.slice(2);
8
+ const home = homedir();
9
+ const launcher = join(home, '.local', 'bin', 'anotify');
10
+ const manifest = join(home, 'Library', 'Application Support', 'AgentNotify', 'installation.json');
11
+ let installed = false;
12
+ try {
13
+ const state = JSON.parse(readFileSync(manifest, 'utf8'));
14
+ installed = state.owner === 'agent-notify' && state.installed === true && existsSync(launcher);
15
+ }
16
+ catch { }
17
+ const useLauncher = installed && args[0] !== 'install';
18
+ const target = useLauncher ? launcher : process.execPath;
19
+ const forwarded = useLauncher ? args : [fileURLToPath(new URL('./cli.js', import.meta.url)), ...args];
20
+ const result = spawnSync(target, forwarded, { stdio: 'inherit' });
21
+ if (result.error)
22
+ throw result.error;
23
+ process.exitCode = result.status ?? 1;
24
+ //# sourceMappingURL=npm-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-cli.js","sourceRoot":"","sources":["../../src/npm-cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAC,UAAU,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;AAChD,OAAO,EAAC,OAAO,EAAC,MAAM,SAAS,CAAC;AAChC,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAC;AAEvC,MAAM,IAAI,GAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjC,MAAM,IAAI,GAAC,OAAO,EAAE,CAAC;AACrB,MAAM,QAAQ,GAAC,IAAI,CAAC,IAAI,EAAC,QAAQ,EAAC,KAAK,EAAC,SAAS,CAAC,CAAC;AACnD,MAAM,QAAQ,GAAC,IAAI,CAAC,IAAI,EAAC,SAAS,EAAC,qBAAqB,EAAC,aAAa,EAAC,mBAAmB,CAAC,CAAC;AAC5F,IAAI,SAAS,GAAC,KAAK,CAAC;AACpB,IAAI,CAAC;IACJ,MAAM,KAAK,GAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAC,MAAM,CAAC,CAAuC,CAAC;IAC5F,SAAS,GAAC,KAAK,CAAC,KAAK,KAAG,cAAc,IAAE,KAAK,CAAC,SAAS,KAAG,IAAI,IAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;AACtF,CAAC;AAAC,MAAM,CAAC,CAAA,CAAC;AACV,MAAM,WAAW,GAAC,SAAS,IAAE,IAAI,CAAC,CAAC,CAAC,KAAG,SAAS,CAAC;AACjD,MAAM,MAAM,GAAC,WAAW,CAAA,CAAC,CAAA,QAAQ,CAAA,CAAC,CAAA,OAAO,CAAC,QAAQ,CAAC;AACnD,MAAM,SAAS,GAAC,WAAW,CAAA,CAAC,CAAA,IAAI,CAAA,CAAC,CAAA,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,UAAU,EAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAC,GAAG,IAAI,CAAC,CAAC;AAC9F,MAAM,MAAM,GAAC,SAAS,CAAC,MAAM,EAAC,SAAS,EAAC,EAAC,KAAK,EAAC,SAAS,EAAC,CAAC,CAAC;AAC3D,IAAG,MAAM,CAAC,KAAK;IAAC,MAAM,MAAM,CAAC,KAAK,CAAC;AACnC,OAAO,CAAC,QAAQ,GAAC,MAAM,CAAC,MAAM,IAAE,CAAC,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { z } from 'zod';
3
+ export const ownerSchema = z.object({ pid: z.number().int().positive(), start: z.string().min(1).max(100) }).strict();
4
+ export function processOwner(pid) {
5
+ if (!Number.isSafeInteger(pid) || pid < 1)
6
+ return;
7
+ try {
8
+ const start = execFileSync('/bin/ps', ['-p', String(pid), '-o', 'lstart='], { encoding: 'utf8', timeout: 2000, stdio: ['ignore', 'pipe', 'ignore'], env: { ...process.env, LC_ALL: 'C', TZ: 'UTC' } }).trim();
9
+ if (start)
10
+ return { pid, start };
11
+ }
12
+ catch { }
13
+ }
14
+ export function ownerLife(owner) {
15
+ const current = processOwner(owner.pid);
16
+ if (current)
17
+ return current.start === owner.start ? 'alive' : 'dead';
18
+ try {
19
+ process.kill(owner.pid, 0);
20
+ return 'unknown';
21
+ }
22
+ catch (error) {
23
+ return error.code === 'ESRCH' ? 'dead' : 'unknown';
24
+ }
25
+ }
26
+ export function ownersTable(db) { db.exec('CREATE TABLE IF NOT EXISTS client_owners(client TEXT PRIMARY KEY,wrapper TEXT NOT NULL,agent TEXT)'); }
27
+ export function recordOwners(db, id, wrapper, agent) {
28
+ ownersTable(db);
29
+ db.prepare('INSERT OR REPLACE INTO client_owners VALUES(?,?,?)').run(id, JSON.stringify(ownerSchema.parse(wrapper)), agent ? JSON.stringify(ownerSchema.parse(agent)) : null);
30
+ }
31
+ export function attachAgent(db, id, agent) {
32
+ ownersTable(db);
33
+ if (!db.prepare('SELECT 1 FROM client_owners WHERE client=?').get(id))
34
+ throw Error('Client has no process ownership record');
35
+ db.prepare('UPDATE client_owners SET agent=? WHERE client=?').run(JSON.stringify(ownerSchema.parse(agent)), id);
36
+ }
37
+ export function reconcileClients(db, probe = ownerLife) {
38
+ ownersTable(db);
39
+ let closed = 0;
40
+ for (const row of db.prepare('SELECT o.* FROM client_owners o JOIN clients c ON c.id=o.client WHERE c.closed=0').all()) {
41
+ // Pending/legacy ownership and permission failures are not proof of death.
42
+ if (!row.agent)
43
+ continue;
44
+ let wrapper, agent;
45
+ try {
46
+ wrapper = ownerSchema.safeParse(JSON.parse(row.wrapper));
47
+ agent = ownerSchema.safeParse(JSON.parse(row.agent));
48
+ }
49
+ catch {
50
+ continue;
51
+ }
52
+ if (wrapper.success && agent.success && probe(wrapper.data) === 'dead' && probe(agent.data) === 'dead')
53
+ closed += Number(db.prepare('UPDATE clients SET closed=1 WHERE id=? AND closed=0').run(row.client).changes);
54
+ }
55
+ return closed;
56
+ }
57
+ //# sourceMappingURL=owners.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owners.js","sourceRoot":"","sources":["../../src/owners.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ import { randomUUID, randomBytes } from 'node:crypto';
2
+ import { computerName } from './device-name.js';
3
+ import { mkdirSync, rmSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import qr from 'qrcode-terminal';
6
+ import { generateKeys } from './crypto.js';
7
+ import { validateRelay, token, hash } from './protocol.js';
8
+ import { request, HttpError } from './http.js';
9
+ import { parsePairingURL, pairingURL, decryptResponse, handshake, verifyProof, encryptLabel } from './pairing.js';
10
+ import { serviceLease } from './service.js';
11
+ export async function pairPhone(vault, io, relay = 'https://anotify.fenginwind.com', cancel = false) {
12
+ // A separate lease prevents two pairing commands from replacing each other's saved state.
13
+ mkdirSync(join(vault.dir, 'pairing-lock'), { recursive: true, mode: 0o700 });
14
+ const lease = serviceLease(join(vault.dir, 'pairing-lock'));
15
+ const clear = () => rmSync(join(vault.dir, 'pairing-pending.sealed'), { force: true });
16
+ try {
17
+ let p = vault.load('pairing-pending');
18
+ if (cancel) {
19
+ if (p) {
20
+ try {
21
+ await request(p.offer.relay + '/v2/pairings/' + p.offer.pairingId, p.pollToken, 'DELETE');
22
+ }
23
+ catch (e) {
24
+ io.write('Remote cancellation could not be confirmed; the attempt will expire. Revoke any completed device on iPhone.');
25
+ }
26
+ clear();
27
+ }
28
+ io.write('Pending local pairing cleared; existing pairing kept.');
29
+ return;
30
+ }
31
+ let announced = false;
32
+ if (p && p.offer.expiresAt <= Date.now() && (!p.confirmed || p.offer.expiresAt + 86400000 <= Date.now())) {
33
+ clear();
34
+ p = undefined;
35
+ }
36
+ if (!p) {
37
+ if (vault.load('sender') && (await io.ask('Replace this Mac’s existing phone pairing after successful confirmation? [y/N]: ')).trim().toLowerCase() !== 'y') {
38
+ io.write('Pairing cancelled; existing pairing kept.');
39
+ return;
40
+ }
41
+ relay = validateRelay(relay, process.env.AGENT_NOTIFY_ALLOW_LOCAL === '1');
42
+ const keys = await generateKeys(), temporary = await generateKeys(), senderToken = token();
43
+ p = { offer: { v: 2, relay, pairingId: randomUUID(), senderPublicKey: keys.publicKey, temporaryPublicKey: temporary.publicKey, senderTokenHash: hash(senderToken), claimToken: token(), expiresAt: Date.now() + 600000 }, temporary, keys, senderToken, pollToken: token() };
44
+ vault.save('pairing-pending', p);
45
+ }
46
+ const pending = p;
47
+ const endpoint = p.offer.relay + '/v2/pairings';
48
+ // Creation is idempotent, including recovery after a lost response.
49
+ if (p.offer.expiresAt > Date.now())
50
+ await request(endpoint, p.pollToken, 'POST', { offer: p.offer, pollToken: p.pollToken });
51
+ if (!p.confirmed) {
52
+ parsePairingURL(pairingURL(p.offer), process.env.AGENT_NOTIFY_ALLOW_LOCAL === '1');
53
+ io.write('On iPhone, scan this code using Agent Notify. If the app is not installed, install it, then scan again inside the app.');
54
+ qr.generate(pairingURL(p.offer), { small: true }, code => io.write(code));
55
+ io.write('Waiting for your iPhone. Code expires in 10 minutes.');
56
+ }
57
+ while (Date.now() < pending.offer.expiresAt + (pending.confirmed ? 86400000 : 0)) {
58
+ const state = await request(endpoint + '/' + pending.offer.pairingId, pending.pollToken);
59
+ if (['expired', 'cancelled'].includes(state.state)) {
60
+ clear();
61
+ throw Error('Pairing expired or cancelled. Run anotify pair for a new code.');
62
+ }
63
+ if (state.response) {
64
+ if (pending.response && JSON.stringify(pending.response) !== JSON.stringify(state.response))
65
+ throw Error('Pairing response changed. Cancel and start again.');
66
+ const phone = decryptResponse(pending.offer, state.response, pending.temporary);
67
+ const proofs = handshake(pending.offer, state.response, pending.temporary.privateKey, state.response.publicKey);
68
+ if (!pending.confirmed) {
69
+ pending.response = state.response;
70
+ vault.save('pairing-pending', pending);
71
+ io.write('\nVerification code: ' + proofs.code + '\nCompare all 8 digits with Agent Notify on your own iPhone.');
72
+ if ((await io.ask('Do both codes match? [y/N]: ')).trim().toLowerCase() !== 'y') {
73
+ await request(endpoint + '/' + pending.offer.pairingId, pending.pollToken, 'DELETE');
74
+ clear();
75
+ io.write('Pairing cancelled; existing pairing kept.');
76
+ return;
77
+ }
78
+ if (Date.now() >= pending.offer.expiresAt)
79
+ throw Error('Pairing expired during confirmation. Run anotify pair again.');
80
+ pending.confirmed = true;
81
+ vault.save('pairing-pending', pending);
82
+ }
83
+ if (state.state === 'complete') {
84
+ if (!state.ack || !verifyProof(state.ack, proofs.ack))
85
+ throw Error('Invalid phone confirmation; pairing not saved.');
86
+ vault.save('sender', { relay: pending.offer.relay, deviceId: phone.deviceId, senderId: pending.offer.pairingId, senderToken: pending.senderToken, keys: pending.keys, recipientPublicKey: phone.recipientPublicKey });
87
+ clear();
88
+ io.write('Mac paired. Next: anotify test');
89
+ return;
90
+ }
91
+ if (!pending.label) {
92
+ const name = computerName();
93
+ if (name) {
94
+ pending.label = encryptLabel(pending.offer, state.response, pending.temporary.privateKey, state.response.publicKey, name, randomBytes(12));
95
+ vault.save('pairing-pending', pending);
96
+ }
97
+ }
98
+ if (pending.label)
99
+ try {
100
+ await request(endpoint + '/' + pending.offer.pairingId + '/label', pending.pollToken, 'POST', pending.label);
101
+ }
102
+ catch (e) {
103
+ if (!(e instanceof HttpError && e.status === 404))
104
+ throw e;
105
+ }
106
+ await request(endpoint + '/' + pending.offer.pairingId + '/finish', pending.pollToken, 'POST', { proof: proofs.finish });
107
+ if (!announced) {
108
+ io.write('Mac confirmed. Tap “Codes match” on your iPhone to finish.');
109
+ announced = true;
110
+ }
111
+ }
112
+ await new Promise(done => setTimeout(done, 1500));
113
+ }
114
+ clear();
115
+ throw Error('Pairing expired. Run anotify pair to try again.');
116
+ }
117
+ catch (e) {
118
+ io.write('Pairing was not completed. Run anotify pair to resume, or anotify pair --cancel to discard this attempt. Existing pairing is kept.');
119
+ throw e;
120
+ }
121
+ finally {
122
+ lease.close();
123
+ }
124
+ }
125
+ //# sourceMappingURL=pairing-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairing-cli.js","sourceRoot":"","sources":["../../src/pairing-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { createECDH, createCipheriv, createDecipheriv, hkdfSync, createHmac, timingSafeEqual } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ import { publicKey, id, b64, hash, validateRelay } from './protocol.js';
4
+ export const secret = b64.refine(s => Buffer.from(s, 'base64url').length === 32, 'Expected 256-bit value');
5
+ export const offerSchema = z.object({ v: z.literal(2), relay: z.string().url(), pairingId: id, senderPublicKey: publicKey, temporaryPublicKey: publicKey, senderTokenHash: z.string().regex(/^[a-f0-9]{64}$/), claimToken: secret, expiresAt: z.number().int().positive() }).strict();
6
+ export const responseSchema = z.object({ publicKey, iv: b64.refine(s => Buffer.from(s, 'base64url').length === 12), ct: b64.refine(s => s.length <= 8192) }).strict();
7
+ export const labelSchema = z.object({ iv: b64.refine(s => Buffer.from(s, 'base64url').length === 12), ct: b64.refine(s => s.length <= 1024) }).strict();
8
+ export const payloadSchema = z.object({ deviceId: id, recipientPublicKey: publicKey, nonce: secret }).strict();
9
+ export function transcript(q) { return JSON.stringify(['AgentNotify/pair/v2', q.relay, q.pairingId, q.senderPublicKey, q.temporaryPublicKey, q.senderTokenHash, q.claimToken, q.expiresAt]); }
10
+ export function offerHash(q) { return hash(transcript(q)); }
11
+ export function pairingURL(q) { offerSchema.parse(q); return q.relay + '/pair#' + Buffer.from(JSON.stringify([2, q.pairingId, q.senderPublicKey, q.temporaryPublicKey, q.senderTokenHash, q.claimToken, q.expiresAt])).toString('base64url'); }
12
+ export function parsePairingURL(text, allowLocal = false) {
13
+ if (text.length > 4096)
14
+ throw Error('Invalid pairing code');
15
+ const u = new URL(text);
16
+ const fields = z.tuple([z.literal(2), id, publicKey, publicKey, z.string(), secret, z.number()]).parse(JSON.parse(Buffer.from(u.hash.slice(1), 'base64url').toString()));
17
+ const q = offerSchema.parse({ v: fields[0], relay: u.origin, pairingId: fields[1], senderPublicKey: fields[2], temporaryPublicKey: fields[3], senderTokenHash: fields[4], claimToken: fields[5], expiresAt: fields[6] });
18
+ if (u.username || u.password || u.pathname !== '/pair' || u.search || validateRelay(u.origin, allowLocal) !== q.relay || validateRelay(q.relay, allowLocal) !== q.relay)
19
+ throw Error('Pairing origin mismatch');
20
+ if (q.expiresAt <= Date.now() || q.expiresAt > Date.now() + 600000)
21
+ throw Error('Pairing expired or invalid. Scan a fresh code.');
22
+ return q;
23
+ }
24
+ function shared(privateKey, publicKey) { const ecdh = createECDH('prime256v1'); ecdh.setPrivateKey(Buffer.from(privateKey, 'base64url')); return ecdh.computeSecret(Buffer.from(publicKey, 'base64url')); }
25
+ function key(q, privateKey, publicKey) { return Buffer.from(hkdfSync('sha256', shared(privateKey, publicKey), Buffer.from(offerHash(q), 'hex'), Buffer.from('AgentNotify/pair/v2/response'), 32)); }
26
+ export function encryptLabel(q, r, privateKey, peer, name, iv) {
27
+ const k = Buffer.from(hkdfSync('sha256', shared(privateKey, peer), Buffer.from(offerHash(q), 'hex'), Buffer.from('AgentNotify/pair/v2/device-name'), 32));
28
+ const cipher = createCipheriv('aes-256-gcm', k, iv);
29
+ cipher.setAAD(Buffer.from(JSON.stringify([offerHash(q), r.publicKey, r.iv, r.ct, 'device-name'])));
30
+ const ct = Buffer.concat([cipher.update(JSON.stringify({ name })), cipher.final(), cipher.getAuthTag()]);
31
+ return { iv: iv.toString('base64url'), ct: ct.toString('base64url') };
32
+ }
33
+ export function encryptResponse(q, payload, phone, iv) {
34
+ payloadSchema.parse(payload);
35
+ const cipher = createCipheriv('aes-256-gcm', key(q, phone.privateKey, q.temporaryPublicKey), iv);
36
+ cipher.setAAD(Buffer.from(transcript(q)));
37
+ const ct = Buffer.concat([cipher.update(JSON.stringify(payload)), cipher.final(), cipher.getAuthTag()]);
38
+ return { publicKey: phone.publicKey, iv: iv.toString('base64url'), ct: ct.toString('base64url') };
39
+ }
40
+ export function decryptResponse(q, response, temporary) {
41
+ response = responseSchema.parse(response);
42
+ const ct = Buffer.from(response.ct, 'base64url');
43
+ const decipher = createDecipheriv('aes-256-gcm', key(q, temporary.privateKey, response.publicKey), Buffer.from(response.iv, 'base64url'));
44
+ decipher.setAAD(Buffer.from(transcript(q)));
45
+ decipher.setAuthTag(ct.subarray(-16));
46
+ return payloadSchema.parse(JSON.parse(Buffer.concat([decipher.update(ct.subarray(0, -16)), decipher.final()]).toString()));
47
+ }
48
+ export function handshake(q, r, privateKey, peer) {
49
+ const k = key(q, privateKey, peer);
50
+ const context = JSON.stringify([offerHash(q), r.publicKey, r.iv, r.ct]);
51
+ const proof = (label) => createHmac('sha256', k).update(JSON.stringify(['AgentNotify/pair/v2', label, context])).digest('base64url');
52
+ const digits = Buffer.from(proof('verification'), 'base64url').readUInt32BE(0) % 100000000;
53
+ const code = String(digits).padStart(8, '0');
54
+ return { code: code.slice(0, 4) + ' ' + code.slice(4), finish: proof('mac-confirmed'), ack: proof('phone-confirmed') };
55
+ }
56
+ export function verifyProof(actual, expected) { const a = Buffer.from(actual, 'base64url'), b = Buffer.from(expected, 'base64url'); return a.length === b.length && timingSafeEqual(a, b); }
57
+ //# sourceMappingURL=pairing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairing.js","sourceRoot":"","sources":["../../src/pairing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { z } from 'zod';
2
+ import { DatabaseSync } from 'node:sqlite';
3
+ import { hostSchema } from './protocol.js';
4
+ import { existsSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ export const preferencesSchema = z.object({ version: z.literal(1), defaultMode: z.enum(['all', 'off']), paused: z.boolean(), permissionAlerts: z.boolean().default(false), hosts: z.array(hostSchema).min(1).refine(hosts => new Set(hosts).size === hosts.length, 'Duplicate host') }).strict();
7
+ export const DEFAULT_PREFERENCES = { version: 1, defaultMode: 'all', paused: false, permissionAlerts: false, hosts: ['claude-code', 'codex', 'gemini-cli'] };
8
+ export function preferencesTable(db) { db.exec('CREATE TABLE IF NOT EXISTS preferences(id INTEGER PRIMARY KEY CHECK(id=1),value TEXT NOT NULL)'); }
9
+ export function readPreferences(db) { const row = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='preferences'").get() ? db.prepare('SELECT value FROM preferences WHERE id=1').get() : undefined; return row ? preferencesSchema.parse(JSON.parse(row.value)) : { ...DEFAULT_PREFERENCES, hosts: [...DEFAULT_PREFERENCES.hosts] }; }
10
+ export function loadPreferences(dir) { const path = join(dir, 'local.sqlite'); if (!existsSync(path))
11
+ return { ...DEFAULT_PREFERENCES, hosts: [...DEFAULT_PREFERENCES.hosts] }; const db = new DatabaseSync(path, { readOnly: true }); try {
12
+ return readPreferences(db);
13
+ }
14
+ finally {
15
+ db.close();
16
+ } }
17
+ export function writePreferences(db, input) { preferencesTable(db); const value = preferencesSchema.parse(input); db.prepare('INSERT OR REPLACE INTO preferences VALUES(1,?)').run(JSON.stringify(value)); return value; }
18
+ //# sourceMappingURL=preferences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preferences.js","sourceRoot":"","sources":["../../src/preferences.ts"],"names":[],"mappings":"AAAA,OAAM,EAAC,CAAC,EAAC,MAAI,KAAK,CAAC;AAAA,OAAM,EAAC,YAAY,EAAC,MAAI,aAAa,CAAC;AAAA,OAAM,EAAC,UAAU,EAAC,MAAI,eAAe,CAAC;AAAA,OAAM,EAAC,UAAU,EAAC,MAAI,SAAS,CAAC;AAAA,OAAM,EAAC,IAAI,EAAC,MAAI,WAAW,CAAC;AAC3J,MAAM,CAAC,MAAM,iBAAiB,GAAC,CAAC,CAAC,MAAM,CAAC,EAAC,OAAO,EAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAC,WAAW,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAC,KAAK,CAAC,CAAC,EAAC,MAAM,EAAC,CAAC,CAAC,OAAO,EAAE,EAAC,gBAAgB,EAAC,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAC,KAAK,EAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA,EAAE,CAAA,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAG,KAAK,CAAC,MAAM,EAAC,gBAAgB,CAAC,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC;AAE9Q,MAAM,CAAC,MAAM,mBAAmB,GAAa,EAAC,OAAO,EAAC,CAAC,EAAC,WAAW,EAAC,KAAK,EAAC,MAAM,EAAC,KAAK,EAAC,gBAAgB,EAAC,KAAK,EAAC,KAAK,EAAC,CAAC,aAAa,EAAC,OAAO,EAAC,YAAY,CAAC,EAAC,CAAC;AAC1J,MAAM,UAAU,gBAAgB,CAAC,EAAe,IAAE,EAAE,CAAC,IAAI,CAAC,gGAAgG,CAAC,CAAC,CAAA,CAAC;AAC7J,MAAM,UAAU,eAAe,CAAC,EAAe,IAAc,MAAM,GAAG,GAAC,EAAE,CAAC,OAAO,CAAC,uEAAuE,CAAC,CAAC,GAAG,EAAE,CAAA,CAAC,CAAA,EAAE,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC,GAAG,EAAE,CAAA,CAAC,CAAA,SAAS,CAAC,CAAA,OAAO,GAAG,CAAA,CAAC,CAAA,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAe,CAAC,CAAC,CAAA,CAAC,CAAA,EAAC,GAAG,mBAAmB,EAAC,KAAK,EAAC,CAAC,GAAG,mBAAmB,CAAC,KAAK,CAAC,EAAC,CAAC,CAAA,CAAC;AAC3W,MAAM,UAAU,eAAe,CAAC,GAAU,IAAE,MAAM,IAAI,GAAC,IAAI,CAAC,GAAG,EAAC,cAAc,CAAC,CAAC,CAAA,IAAG,CAAC,UAAU,CAAC,IAAI,CAAC;IAAC,OAAO,EAAC,GAAG,mBAAmB,EAAC,KAAK,EAAC,CAAC,GAAG,mBAAmB,CAAC,KAAK,CAAC,EAAC,CAAC,CAAA,MAAM,EAAE,GAAC,IAAI,YAAY,CAAC,IAAI,EAAC,EAAC,QAAQ,EAAC,IAAI,EAAC,CAAC,CAAC,CAAA,IAAG,CAAC;IAAA,OAAO,eAAe,CAAC,EAAE,CAAC,CAAC;AAAA,CAAC;QAAO,CAAC;IAAA,EAAE,CAAC,KAAK,EAAE,CAAC;AAAA,CAAC,CAAA,CAAC;AAC/Q,MAAM,UAAU,gBAAgB,CAAC,EAAe,EAAC,KAAa,IAAE,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAA,MAAM,KAAK,GAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA,EAAE,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA,OAAO,KAAK,CAAC,CAAA,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { z } from 'zod';
2
+ import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';
3
+ export const id = z.string().uuid();
4
+ export const b64 = z.string().regex(/^[A-Za-z0-9_-]+$/);
5
+ export const publicKey = b64.refine(s => Buffer.from(s, 'base64url').length === 65, 'Expected uncompressed P-256 key');
6
+ export const hostSchema = z.enum(['claude-code', 'codex', 'gemini-cli']);
7
+ export const headerSchema = z.object({ v: z.literal(1), deviceId: id, senderId: id, messageId: id, revision: z.number().int().positive(), expiresAt: z.number().int().positive() }).strict();
8
+ const boxSchema = z.object({ enc: b64, ct: b64 }).strict();
9
+ export const envelopeSchema = z.object({ header: headerSchema, body: boxSchema, preview: boxSchema }).strict();
10
+ export const questionSchema = z.object({ id: z.string().min(1).max(200), question: z.string().min(1).max(2000), header: z.string().max(200), options: z.array(z.object({ label: z.string().min(1).max(200), description: z.string().max(1000) }).strict()).max(4), multiSelect: z.boolean() }).strict();
11
+ export const contentSchema = z.object({
12
+ kind: z.enum(['turn_end', 'progress', 'content', 'attention', 'action_required', 'question']),
13
+ title: z.string().min(1).max(200),
14
+ markdown: z.string().max(1_048_576).refine(s => Buffer.byteLength(s) <= 1_048_576, 'Markdown exceeds 1 MiB'),
15
+ host: hostSchema.optional(), sessionId: z.string().optional(), turnId: z.string().optional(), project: z.string().optional(),
16
+ deviceName: z.string().min(1).max(120).optional(),
17
+ questions: z.array(questionSchema).min(1).max(4).optional(),
18
+ }).strict().refine(value => value.kind === 'question' ? !!value.questions : value.questions === undefined, 'Question content is required only for questions');
19
+ export const inviteSchema = z.object({ v: z.literal(1), relay: z.string().url(), deviceId: id, recipientPublicKey: publicKey, enrollmentToken: b64, expiresAt: z.number().int() }).strict();
20
+ export const confirmationSchema = z.object({ v: z.literal(1), relay: z.string().url(), deviceId: id, pairingId: id, senderId: id, senderPublicKey: publicKey, recipientFingerprint: b64 }).strict();
21
+ export const registrationSchema = z.object({ deviceId: id, readTokenHash: z.string().regex(/^[a-f0-9]{64}$/), enrollmentHash: z.string().regex(/^[a-f0-9]{64}$/), inviteExpiresAt: z.number().int(), apnsToken: z.string().regex(/^[a-f0-9]{64,200}$/i).optional() }).strict();
22
+ export function hash(s) { return createHash('sha256').update(s).digest('hex'); }
23
+ export function token() { return randomBytes(32).toString('base64url'); }
24
+ export function equalSecret(a, b) { const aa = Buffer.from(hash(a)); const bb = Buffer.from(hash(b)); return timingSafeEqual(aa, bb); }
25
+ export function aad(h, purpose) {
26
+ return new TextEncoder().encode(JSON.stringify(['agent-notify', h.v, h.deviceId, h.senderId, h.messageId, h.revision, h.expiresAt, purpose]));
27
+ }
28
+ export function info(purpose) { return new TextEncoder().encode('AgentNotify/v1/' + purpose); }
29
+ export function encodeLink(kind, value) { return `agentnotify://${kind}?data=${Buffer.from(JSON.stringify(value)).toString('base64url')}`; }
30
+ export function parseLink(text, kind, schema) { const url = new URL(text); if (url.protocol !== 'agentnotify:' || url.hostname !== kind)
31
+ throw new Error('Invalid connection link'); return schema.parse(JSON.parse(Buffer.from(url.searchParams.get('data') ?? '', 'base64url').toString())); }
32
+ export function validateRelay(url, allowLocal = false) {
33
+ const parsed = new URL(url);
34
+ if (parsed.username || parsed.password || parsed.search || parsed.hash)
35
+ throw new Error('Invalid relay address');
36
+ if (parsed.protocol !== 'https:' && !(allowLocal && parsed.protocol === 'http:' && ['127.0.0.1', 'localhost'].includes(parsed.hostname)))
37
+ throw new Error('Relay requires HTTPS');
38
+ return parsed.origin;
39
+ }
40
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;AACpC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;AACxD,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,MAAM,KAAK,EAAE,EAAE,iCAAiC,CAAC,CAAC;AACvH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAC,OAAO,EAAC,YAAY,CAAC,CAAC,CAAC;AACvE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAC7L,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAC3D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAC/G,MAAM,CAAC,MAAM,cAAc,GAAC,CAAC,CAAC,MAAM,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAC,QAAQ,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAC,MAAM,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAC,OAAO,EAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,KAAK,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAC,WAAW,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,WAAW,EAAC,CAAC,CAAC,OAAO,EAAE,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC;AACtR,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAC,UAAU,EAAC,SAAS,EAAC,WAAW,EAAC,iBAAiB,EAAC,UAAU,CAAC,CAAC;IACxF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACjC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,wBAAwB,CAAC;IAC5G,IAAI,EAAE,UAAU,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5H,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IACjD,SAAS,EAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC3D,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,CAAA,EAAE,CAAA,KAAK,CAAC,IAAI,KAAG,UAAU,CAAA,CAAC,CAAA,CAAC,CAAC,KAAK,CAAC,SAAS,CAAA,CAAC,CAAA,KAAK,CAAC,SAAS,KAAG,SAAS,EAAC,iDAAiD,CAAC,CAAC;AAMnJ,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAC,EAAE,EAAE,kBAAkB,EAAC,SAAS,EAAE,eAAe,EAAC,GAAG,EAAE,SAAS,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAEtL,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAC,EAAE,EAAE,SAAS,EAAC,EAAE,EAAE,QAAQ,EAAC,EAAE,EAAE,eAAe,EAAC,SAAS,EAAE,oBAAoB,EAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAE7L,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAC,EAAE,EAAE,aAAa,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,cAAc,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,eAAe,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAC1Q,MAAM,UAAU,IAAI,CAAC,CAAQ,IAAW,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9F,MAAM,UAAU,KAAK,KAAY,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAChF,MAAM,UAAU,WAAW,CAAC,CAAQ,EAAC,CAAQ,IAAY,MAAM,EAAE,GAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA,MAAM,EAAE,GAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA,OAAO,eAAe,CAAC,EAAE,EAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACrJ,MAAM,UAAU,GAAG,CAAC,CAAQ,EAAC,OAAwB;IACnD,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,EAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,QAAQ,EAAC,CAAC,CAAC,QAAQ,EAAC,CAAC,CAAC,SAAS,EAAC,CAAC,CAAC,QAAQ,EAAC,CAAC,CAAC,SAAS,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACzI,CAAC;AACD,MAAM,UAAU,IAAI,CAAC,OAAwB,IAA4B,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,iBAAiB,GAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACtI,MAAM,UAAU,UAAU,CAAC,IAAuB,EAAC,KAAyB,IAAW,OAAO,iBAAiB,IAAI,SAAS,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;AACzL,MAAM,UAAU,SAAS,CAAI,IAAW,EAAC,IAAW,EAAC,MAAmB,IAAM,MAAM,GAAG,GAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA,IAAG,GAAG,CAAC,QAAQ,KAAG,cAAc,IAAE,GAAG,CAAC,QAAQ,KAAG,IAAI;IAAC,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAA,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAE,EAAE,EAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/S,MAAM,UAAU,aAAa,CAAC,GAAU,EAAC,UAAU,GAAC,KAAK;IACvD,MAAM,MAAM,GAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAG,MAAM,CAAC,QAAQ,IAAE,MAAM,CAAC,QAAQ,IAAE,MAAM,CAAC,MAAM,IAAE,MAAM,CAAC,IAAI;QAAC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACzG,IAAG,MAAM,CAAC,QAAQ,KAAG,QAAQ,IAAE,CAAC,CAAC,UAAU,IAAE,MAAM,CAAC,QAAQ,KAAG,OAAO,IAAE,CAAC,WAAW,EAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAAC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACrK,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { CipherSuite, DhkemP256HkdfSha256, HkdfSha256, Aes256Gcm } from '@hpke/core';
2
+ import { z } from 'zod';
3
+ import { b64, id } from './protocol.js';
4
+ const suite = new CipherSuite({ kem: new DhkemP256HkdfSha256(), kdf: new HkdfSha256(), aead: new Aes256Gcm() });
5
+ const bytes = (value) => new Uint8Array(Buffer.from(value, 'base64url'));
6
+ const encode = (value) => Buffer.from(value).toString('base64url');
7
+ const headerSchema = z.object({ v: z.literal(1), deviceId: id, senderId: id, questionId: id, expiresAt: z.number().int().positive() }).strict();
8
+ const answersSchema = z.array(z.object({ id: z.string().min(1).max(200), values: z.array(z.string().min(1).max(4000)).min(1).max(10) }).strict()).min(1).max(4).refine(values => new Set(values.map(value => value.id)).size === values.length, 'Duplicate question ID');
9
+ export const encryptedAnswerSchema = z.object({ header: headerSchema, enc: b64, ct: b64 }).strict();
10
+ const info = new TextEncoder().encode('AgentNotify/question-answer/v1');
11
+ const aad = (h) => new TextEncoder().encode(JSON.stringify(['AgentNotify/question-answer/v1', h.deviceId, h.senderId, h.questionId, h.expiresAt]));
12
+ export async function sealAnswer(header, answers, phone, macPublicKey) {
13
+ const h = headerSchema.parse(header), values = answersSchema.parse(answers);
14
+ if (h.expiresAt <= Date.now())
15
+ throw Error('Question expired');
16
+ const context = await suite.createSenderContext({ recipientPublicKey: await suite.kem.deserializePublicKey(bytes(macPublicKey)), senderKey: await suite.kem.deserializePrivateKey(bytes(phone.privateKey)), info });
17
+ return { header: h, enc: encode(context.enc), ct: encode(await context.seal(new TextEncoder().encode(JSON.stringify({ answers: values })), aad(h))) };
18
+ }
19
+ export async function openAnswer(envelope, expected, mac, phonePublicKey) {
20
+ const value = encryptedAnswerSchema.parse(envelope), target = headerSchema.parse(expected);
21
+ if (target.expiresAt <= Date.now())
22
+ throw Error('Question expired');
23
+ if (JSON.stringify(value.header) !== JSON.stringify(target))
24
+ throw Error('Answer does not match this question');
25
+ const context = await suite.createRecipientContext({ recipientKey: await suite.kem.deserializePrivateKey(bytes(mac.privateKey)), senderPublicKey: await suite.kem.deserializePublicKey(bytes(phonePublicKey)), enc: bytes(value.enc), info });
26
+ const raw = await context.open(bytes(value.ct), aad(target));
27
+ return z.object({ answers: answersSchema }).strict().parse(JSON.parse(new TextDecoder().decode(raw))).answers;
28
+ }
29
+ //# sourceMappingURL=question-crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-crypto.js","sourceRoot":"","sources":["../../src/question-crypto.ts"],"names":[],"mappings":"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"}