@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.
- package/LICENSE +21 -0
- package/README.md +14 -2
- package/dist/src/adapters.js +97 -0
- package/dist/src/adapters.js.map +1 -0
- package/dist/src/claude-question-wait.js +67 -0
- package/dist/src/claude-question-wait.js.map +1 -0
- package/dist/src/claude-question.js +22 -0
- package/dist/src/claude-question.js.map +1 -0
- package/dist/src/claude.js +23 -0
- package/dist/src/claude.js.map +1 -0
- package/dist/src/cli.js +294 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/codex-readiness.js +37 -0
- package/dist/src/codex-readiness.js.map +1 -0
- package/dist/src/config.js +21 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/crypto.js +26 -0
- package/dist/src/crypto.js.map +1 -0
- package/dist/src/daemon.js +356 -0
- package/dist/src/daemon.js.map +1 -0
- package/dist/src/demand.js +89 -0
- package/dist/src/demand.js.map +1 -0
- package/dist/src/device-name.js +12 -0
- package/dist/src/device-name.js.map +1 -0
- package/dist/src/http.js +38 -0
- package/dist/src/http.js.map +1 -0
- package/dist/src/install.js +254 -0
- package/dist/src/install.js.map +1 -0
- package/dist/src/integration.js +184 -0
- package/dist/src/integration.js.map +1 -0
- package/dist/src/mcp.js +48 -0
- package/dist/src/mcp.js.map +1 -0
- package/dist/src/native-owner.js +44 -0
- package/dist/src/native-owner.js.map +1 -0
- package/dist/src/npm-cli.js +24 -0
- package/dist/src/npm-cli.js.map +1 -0
- package/dist/src/owners.js +57 -0
- package/dist/src/owners.js.map +1 -0
- package/dist/src/pairing-cli.js +125 -0
- package/dist/src/pairing-cli.js.map +1 -0
- package/dist/src/pairing.js +57 -0
- package/dist/src/pairing.js.map +1 -0
- package/dist/src/preferences.js +18 -0
- package/dist/src/preferences.js.map +1 -0
- package/dist/src/protocol.js +40 -0
- package/dist/src/protocol.js.map +1 -0
- package/dist/src/question-crypto.js +29 -0
- package/dist/src/question-crypto.js.map +1 -0
- package/dist/src/readiness.js +58 -0
- package/dist/src/readiness.js.map +1 -0
- package/dist/src/service.js +54 -0
- package/dist/src/service.js.map +1 -0
- package/dist/src/sessions.js +217 -0
- package/dist/src/sessions.js.map +1 -0
- package/dist/src/setup-cli.js +59 -0
- package/dist/src/setup-cli.js.map +1 -0
- package/dist/src/terminal.js +68 -0
- package/dist/src/terminal.js.map +1 -0
- package/dist/src/vault.js +49 -0
- package/dist/src/vault.js.map +1 -0
- package/dist/src/wizard.js +43 -0
- package/dist/src/wizard.js.map +1 -0
- package/npm-shrinkwrap.json +1919 -0
- 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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"}
|
package/dist/src/mcp.js
ADDED
|
@@ -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":"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"}
|
|
@@ -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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"}
|