sigild 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +142 -33
- package/THREAT_MODEL.md +47 -19
- package/dist/src/bin/sigil-hook-post.d.ts +3 -0
- package/dist/src/bin/sigil-hook-post.d.ts.map +1 -0
- package/dist/src/bin/sigil-hook-post.js +15 -0
- package/dist/src/bin/sigil-hook-post.js.map +1 -0
- package/dist/src/bin/sigil-hook-pre.d.ts +3 -0
- package/dist/src/bin/sigil-hook-pre.d.ts.map +1 -0
- package/dist/src/bin/sigil-hook-pre.js +18 -0
- package/dist/src/bin/sigil-hook-pre.js.map +1 -0
- package/dist/src/bin/sigil-mcp.d.ts +3 -0
- package/dist/src/bin/sigil-mcp.d.ts.map +1 -0
- package/dist/src/bin/sigil-mcp.js +90 -0
- package/dist/src/bin/sigil-mcp.js.map +1 -0
- package/dist/src/bin/sigil.d.ts +3 -0
- package/dist/src/bin/sigil.d.ts.map +1 -0
- package/dist/src/bin/sigil.js +9 -0
- package/dist/src/bin/sigil.js.map +1 -0
- package/dist/src/cli/args.d.ts +26 -0
- package/dist/src/cli/args.d.ts.map +1 -0
- package/dist/src/cli/args.js +36 -0
- package/dist/src/cli/args.js.map +1 -0
- package/dist/src/cli/index.d.ts +7 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +7 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/main.d.ts +26 -0
- package/dist/src/cli/main.d.ts.map +1 -0
- package/dist/src/cli/main.js +197 -0
- package/dist/src/cli/main.js.map +1 -0
- package/dist/src/cli/paths.d.ts +18 -0
- package/dist/src/cli/paths.d.ts.map +1 -0
- package/dist/src/cli/paths.js +13 -0
- package/dist/src/cli/paths.js.map +1 -0
- package/dist/src/cli/portal.d.ts +59 -0
- package/dist/src/cli/portal.d.ts.map +1 -0
- package/dist/src/cli/portal.js +112 -0
- package/dist/src/cli/portal.js.map +1 -0
- package/dist/src/cli/status.d.ts +28 -0
- package/dist/src/cli/status.d.ts.map +1 -0
- package/dist/src/cli/status.js +59 -0
- package/dist/src/cli/status.js.map +1 -0
- package/dist/src/cli/unlock.d.ts +36 -0
- package/dist/src/cli/unlock.d.ts.map +1 -0
- package/dist/src/cli/unlock.js +77 -0
- package/dist/src/cli/unlock.js.map +1 -0
- package/dist/src/control/client.d.ts +26 -0
- package/dist/src/control/client.d.ts.map +1 -0
- package/dist/src/control/client.js +76 -0
- package/dist/src/control/client.js.map +1 -0
- package/dist/src/control/index.d.ts +4 -0
- package/dist/src/control/index.d.ts.map +1 -0
- package/dist/src/control/index.js +4 -0
- package/dist/src/control/index.js.map +1 -0
- package/dist/src/control/protocol.d.ts +54 -0
- package/dist/src/control/protocol.d.ts.map +1 -0
- package/dist/src/control/protocol.js +60 -0
- package/dist/src/control/protocol.js.map +1 -0
- package/dist/src/control/server.d.ts +52 -0
- package/dist/src/control/server.d.ts.map +1 -0
- package/dist/src/control/server.js +199 -0
- package/dist/src/control/server.js.map +1 -0
- package/dist/src/daemon/handles.d.ts +35 -6
- package/dist/src/daemon/handles.d.ts.map +1 -1
- package/dist/src/daemon/handles.js +83 -28
- package/dist/src/daemon/handles.js.map +1 -1
- package/dist/src/daemon/index.d.ts +2 -3
- package/dist/src/daemon/index.d.ts.map +1 -1
- package/dist/src/daemon/index.js +2 -3
- package/dist/src/daemon/index.js.map +1 -1
- package/dist/src/daemon/methods.d.ts +13 -0
- package/dist/src/daemon/methods.d.ts.map +1 -1
- package/dist/src/daemon/methods.js +50 -1
- package/dist/src/daemon/methods.js.map +1 -1
- package/dist/src/hooks/command-scanner.d.ts +5 -0
- package/dist/src/hooks/command-scanner.d.ts.map +1 -0
- package/dist/src/hooks/command-scanner.js +117 -0
- package/dist/src/hooks/command-scanner.js.map +1 -0
- package/dist/src/hooks/glob.d.ts +8 -0
- package/dist/src/hooks/glob.d.ts.map +1 -0
- package/dist/src/hooks/glob.js +98 -0
- package/dist/src/hooks/glob.js.map +1 -0
- package/dist/src/hooks/index.d.ts +9 -0
- package/dist/src/hooks/index.d.ts.map +1 -0
- package/dist/src/hooks/index.js +9 -0
- package/dist/src/hooks/index.js.map +1 -0
- package/dist/src/hooks/install.d.ts +29 -0
- package/dist/src/hooks/install.d.ts.map +1 -0
- package/dist/src/hooks/install.js +86 -0
- package/dist/src/hooks/install.js.map +1 -0
- package/dist/src/hooks/path-blocker.d.ts +29 -0
- package/dist/src/hooks/path-blocker.d.ts.map +1 -0
- package/dist/src/hooks/path-blocker.js +59 -0
- package/dist/src/hooks/path-blocker.js.map +1 -0
- package/dist/src/hooks/post-tool-use.d.ts +13 -0
- package/dist/src/hooks/post-tool-use.d.ts.map +1 -0
- package/dist/src/hooks/post-tool-use.js +45 -0
- package/dist/src/hooks/post-tool-use.js.map +1 -0
- package/dist/src/hooks/pre-tool-use.d.ts +8 -0
- package/dist/src/hooks/pre-tool-use.d.ts.map +1 -0
- package/dist/src/hooks/pre-tool-use.js +38 -0
- package/dist/src/hooks/pre-tool-use.js.map +1 -0
- package/dist/src/hooks/protocol.d.ts +41 -0
- package/dist/src/hooks/protocol.d.ts.map +1 -0
- package/dist/src/hooks/protocol.js +27 -0
- package/dist/src/hooks/protocol.js.map +1 -0
- package/dist/src/hooks/redactor.d.ts +19 -0
- package/dist/src/hooks/redactor.d.ts.map +1 -0
- package/dist/src/hooks/redactor.js +71 -0
- package/dist/src/hooks/redactor.js.map +1 -0
- package/dist/src/mcp/index.d.ts +4 -0
- package/dist/src/mcp/index.d.ts.map +1 -0
- package/dist/src/mcp/index.js +4 -0
- package/dist/src/mcp/index.js.map +1 -0
- package/dist/src/mcp/protocol.d.ts +98 -0
- package/dist/src/mcp/protocol.d.ts.map +1 -0
- package/dist/src/mcp/protocol.js +79 -0
- package/dist/src/mcp/protocol.js.map +1 -0
- package/dist/src/mcp/server.d.ts +46 -0
- package/dist/src/mcp/server.d.ts.map +1 -0
- package/dist/src/mcp/server.js +108 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/tools.d.ts +16 -0
- package/dist/src/mcp/tools.d.ts.map +1 -0
- package/dist/src/mcp/tools.js +117 -0
- package/dist/src/mcp/tools.js.map +1 -0
- package/dist/src/policy/evaluate.d.ts +13 -0
- package/dist/src/policy/evaluate.d.ts.map +1 -0
- package/dist/src/policy/evaluate.js +73 -0
- package/dist/src/policy/evaluate.js.map +1 -0
- package/dist/src/policy/index.d.ts +5 -0
- package/dist/src/policy/index.d.ts.map +1 -0
- package/dist/src/policy/index.js +5 -0
- package/dist/src/policy/index.js.map +1 -0
- package/dist/src/policy/loader.d.ts +33 -0
- package/dist/src/policy/loader.d.ts.map +1 -0
- package/dist/src/policy/loader.js +170 -0
- package/dist/src/policy/loader.js.map +1 -0
- package/dist/src/policy/template.d.ts +10 -0
- package/dist/src/policy/template.d.ts.map +1 -0
- package/dist/src/policy/template.js +69 -0
- package/dist/src/policy/template.js.map +1 -0
- package/dist/src/policy/types.d.ts +62 -0
- package/dist/src/policy/types.d.ts.map +1 -0
- package/dist/src/policy/types.js +10 -0
- package/dist/src/policy/types.js.map +1 -0
- package/package.json +9 -3
- package/dist/src/bin/sigild.d.ts +0 -3
- package/dist/src/bin/sigild.d.ts.map +0 -1
- package/dist/src/bin/sigild.js +0 -30
- package/dist/src/bin/sigild.js.map +0 -1
- package/dist/src/daemon/rpc.d.ts +0 -61
- package/dist/src/daemon/rpc.d.ts.map +0 -1
- package/dist/src/daemon/rpc.js +0 -76
- package/dist/src/daemon/rpc.js.map +0 -1
- package/dist/src/daemon/runtime.d.ts +0 -40
- package/dist/src/daemon/runtime.d.ts.map +0 -1
- package/dist/src/daemon/runtime.js +0 -61
- package/dist/src/daemon/runtime.js.map +0 -1
- package/dist/src/daemon/server.d.ts +0 -53
- package/dist/src/daemon/server.d.ts.map +0 -1
- package/dist/src/daemon/server.js +0 -103
- package/dist/src/daemon/server.js.map +0 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { resolvePaths } from './paths.js';
|
|
2
|
+
export { ArgsError, parseSubcommand } from './args.js';
|
|
3
|
+
export { portalAdd, portalListFromDisk, portalRemove, } from './portal.js';
|
|
4
|
+
export { status } from './status.js';
|
|
5
|
+
export { formatResult, lock, unlock, } from './unlock.js';
|
|
6
|
+
export { runCli } from './main.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAIL,SAAS,EACT,kBAAkB,EAClB,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAqB,MAAM,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAIL,YAAY,EACZ,IAAI,EACJ,MAAM,GACP,MAAM,aAAa,CAAC;AACrB,OAAO,EAAiC,MAAM,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { KdfParams } from '../crypto/index.js';
|
|
2
|
+
export interface RunCliOpts {
|
|
3
|
+
argv: string[];
|
|
4
|
+
/** Override the passphrase reader for tests. */
|
|
5
|
+
passphrase?: () => Promise<Buffer> | Buffer;
|
|
6
|
+
/** Override stdout / stderr for tests. */
|
|
7
|
+
stdout?: NodeJS.WritableStream;
|
|
8
|
+
stderr?: NodeJS.WritableStream;
|
|
9
|
+
/** Override the home/socket paths (defaults to env-resolved). */
|
|
10
|
+
env?: NodeJS.ProcessEnv;
|
|
11
|
+
/**
|
|
12
|
+
* Internal test-only override for the KDF cost during portal add.
|
|
13
|
+
* The CLI binary never sets this. See PortalAddOpts.kdfParams.
|
|
14
|
+
*/
|
|
15
|
+
kdfParams?: KdfParams;
|
|
16
|
+
}
|
|
17
|
+
export interface CliExit {
|
|
18
|
+
code: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Pure dispatcher: takes argv (without the node binary or script path),
|
|
22
|
+
* returns an exit code. Side effects route through the injected streams
|
|
23
|
+
* and passphrase reader so tests don't poke at process.stdout etc.
|
|
24
|
+
*/
|
|
25
|
+
export declare function runCli(opts: RunCliOpts): Promise<CliExit>;
|
|
26
|
+
//# sourceMappingURL=main.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/cli/main.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AA8BpD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAC5C,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAkJ/D"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { readPassphrase } from '../daemon/passphrase.js';
|
|
4
|
+
import { installInto } from '../hooks/install.js';
|
|
5
|
+
import { parsePolicy } from '../policy/index.js';
|
|
6
|
+
import { ArgsError, parseSubcommand } from './args.js';
|
|
7
|
+
import { resolvePaths } from './paths.js';
|
|
8
|
+
import { portalAdd, portalListFromDisk, portalRemove } from './portal.js';
|
|
9
|
+
import { status } from './status.js';
|
|
10
|
+
import { formatResult, lock, unlock } from './unlock.js';
|
|
11
|
+
const USAGE = `sigil — local signing control for Claude Code
|
|
12
|
+
|
|
13
|
+
Usage:
|
|
14
|
+
sigil init [--user]
|
|
15
|
+
sigil status
|
|
16
|
+
sigil portal add <handle> --key-file <path> [--no-remove-source] [--strict]
|
|
17
|
+
sigil portal list
|
|
18
|
+
sigil portal remove <handle>
|
|
19
|
+
sigil policy show <handle>
|
|
20
|
+
sigil unlock
|
|
21
|
+
sigil lock
|
|
22
|
+
|
|
23
|
+
"sigil init" writes the MCP server registration + tool hooks into
|
|
24
|
+
.claude/settings.json (or ~/.claude/settings.json with --user).
|
|
25
|
+
"sigil portal add" writes a permissive policy by default; pass --strict
|
|
26
|
+
to get a locked-down template you fill in before any sign succeeds.
|
|
27
|
+
"sigil unlock" prompts for the passphrase and pushes it to the running
|
|
28
|
+
sigil-mcp process (spawned by Claude Code) over the control socket.
|
|
29
|
+
Set SIGIL_HOME to override ~/.sigil.
|
|
30
|
+
`;
|
|
31
|
+
/**
|
|
32
|
+
* Pure dispatcher: takes argv (without the node binary or script path),
|
|
33
|
+
* returns an exit code. Side effects route through the injected streams
|
|
34
|
+
* and passphrase reader so tests don't poke at process.stdout etc.
|
|
35
|
+
*/
|
|
36
|
+
export async function runCli(opts) {
|
|
37
|
+
const out = opts.stdout ?? process.stdout;
|
|
38
|
+
const err = opts.stderr ?? process.stderr;
|
|
39
|
+
const paths = resolvePaths(opts.env ?? process.env);
|
|
40
|
+
const askPassphrase = opts.passphrase ?? (() => readPassphrase('sigil passphrase: '));
|
|
41
|
+
if (opts.argv.length === 0 || opts.argv[0] === '--help' || opts.argv[0] === '-h') {
|
|
42
|
+
out.write(USAGE);
|
|
43
|
+
return { code: 0 };
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const [head, ...rest] = opts.argv;
|
|
47
|
+
if (head === 'init') {
|
|
48
|
+
const sub = parseSubcommand(['init', ...rest], {
|
|
49
|
+
init: { options: { user: { type: 'boolean' } } },
|
|
50
|
+
});
|
|
51
|
+
const scope = sub.options['user'] === true ? 'user' : 'project';
|
|
52
|
+
const result = installInto({ scope });
|
|
53
|
+
if (result.changed)
|
|
54
|
+
out.write(`updated ${result.settingsPath}\n`);
|
|
55
|
+
else
|
|
56
|
+
out.write(`${result.settingsPath} is already up to date\n`);
|
|
57
|
+
return { code: 0 };
|
|
58
|
+
}
|
|
59
|
+
if (head === 'status') {
|
|
60
|
+
const report = await status(paths);
|
|
61
|
+
out.write(JSON.stringify(report, null, 2) + '\n');
|
|
62
|
+
return { code: 0 };
|
|
63
|
+
}
|
|
64
|
+
if (head === 'unlock') {
|
|
65
|
+
const passphrase = await askPassphrase();
|
|
66
|
+
try {
|
|
67
|
+
const result = await unlock({ paths, passphrase });
|
|
68
|
+
const { message, code } = formatResult('unlock', result);
|
|
69
|
+
(code === 0 ? out : err).write(message + '\n');
|
|
70
|
+
return { code };
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
passphrase.fill(0);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (head === 'lock') {
|
|
77
|
+
const result = await lock({ paths });
|
|
78
|
+
const { message, code } = formatResult('lock', result);
|
|
79
|
+
(code === 0 ? out : err).write(message + '\n');
|
|
80
|
+
return { code };
|
|
81
|
+
}
|
|
82
|
+
if (head === 'portal') {
|
|
83
|
+
const sub = parseSubcommand(rest, {
|
|
84
|
+
add: {
|
|
85
|
+
options: {
|
|
86
|
+
'key-file': { type: 'string' },
|
|
87
|
+
'no-remove-source': { type: 'boolean' },
|
|
88
|
+
'strict': { type: 'boolean' },
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
list: { options: {} },
|
|
92
|
+
remove: { options: {} },
|
|
93
|
+
});
|
|
94
|
+
if (sub.command === 'add') {
|
|
95
|
+
const handle = sub.positionals[0];
|
|
96
|
+
const keyFile = sub.options['key-file'];
|
|
97
|
+
if (!handle)
|
|
98
|
+
throw new ArgsError('portal add: missing handle');
|
|
99
|
+
if (typeof keyFile !== 'string' || keyFile.length === 0) {
|
|
100
|
+
throw new ArgsError('portal add: --key-file is required');
|
|
101
|
+
}
|
|
102
|
+
const policyMode = sub.options['strict'] === true ? 'strict' : 'permissive';
|
|
103
|
+
const passphrase = await askPassphrase();
|
|
104
|
+
try {
|
|
105
|
+
const { address, keyfilePath, policyPath } = portalAdd(paths, {
|
|
106
|
+
handle,
|
|
107
|
+
keyFile,
|
|
108
|
+
passphrase,
|
|
109
|
+
policyMode,
|
|
110
|
+
...(sub.options['no-remove-source'] === true ? { removeSource: false } : {}),
|
|
111
|
+
...(opts.kdfParams ? { kdfParams: opts.kdfParams } : {}),
|
|
112
|
+
});
|
|
113
|
+
out.write(`added ${handle} (${address}) → ${keyfilePath}\n`);
|
|
114
|
+
out.write(`policy: ${policyMode} → ${policyPath}\n`);
|
|
115
|
+
if (policyMode === 'strict') {
|
|
116
|
+
out.write(`note: strict policy denies everything until you edit ${policyPath}\n`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
passphrase.fill(0);
|
|
121
|
+
}
|
|
122
|
+
return { code: 0 };
|
|
123
|
+
}
|
|
124
|
+
if (sub.command === 'list') {
|
|
125
|
+
const passphrase = await askPassphrase();
|
|
126
|
+
try {
|
|
127
|
+
const portals = portalListFromDisk(paths, passphrase);
|
|
128
|
+
if (portals.length === 0) {
|
|
129
|
+
out.write('(no portals)\n');
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
for (const p of portals)
|
|
133
|
+
out.write(`${p.handle}\t${p.address}\n`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
passphrase.fill(0);
|
|
138
|
+
}
|
|
139
|
+
return { code: 0 };
|
|
140
|
+
}
|
|
141
|
+
if (sub.command === 'remove') {
|
|
142
|
+
const handle = sub.positionals[0];
|
|
143
|
+
if (!handle)
|
|
144
|
+
throw new ArgsError('portal remove: missing handle');
|
|
145
|
+
const result = portalRemove(paths, handle);
|
|
146
|
+
if (result.removed)
|
|
147
|
+
out.write(`removed ${handle} (${result.path})\n`);
|
|
148
|
+
else
|
|
149
|
+
out.write(`portal "${handle}" not found at ${result.path}\n`);
|
|
150
|
+
return { code: result.removed ? 0 : 1 };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (head === 'policy') {
|
|
154
|
+
const sub = parseSubcommand(rest, { show: { options: {} } });
|
|
155
|
+
if (sub.command === 'show') {
|
|
156
|
+
const handle = sub.positionals[0];
|
|
157
|
+
if (!handle)
|
|
158
|
+
throw new ArgsError('policy show: missing handle');
|
|
159
|
+
const policyPath = join(paths.policyDir, `${handle}.toml`);
|
|
160
|
+
let source;
|
|
161
|
+
try {
|
|
162
|
+
source = readFileSync(policyPath, 'utf8');
|
|
163
|
+
}
|
|
164
|
+
catch (e) {
|
|
165
|
+
if (e.code === 'ENOENT') {
|
|
166
|
+
err.write(`policy: no file at ${policyPath}\n`);
|
|
167
|
+
return { code: 1 };
|
|
168
|
+
}
|
|
169
|
+
throw e;
|
|
170
|
+
}
|
|
171
|
+
// Validate by parsing — surface schema errors as exit 1.
|
|
172
|
+
try {
|
|
173
|
+
parsePolicy(source);
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
err.write(`policy: ${e.message}\n`);
|
|
177
|
+
err.write(`(file at ${policyPath} is on disk but doesn't parse — fix it before signing)\n`);
|
|
178
|
+
return { code: 1 };
|
|
179
|
+
}
|
|
180
|
+
out.write(source);
|
|
181
|
+
out.write(`# ${policyPath}\n`);
|
|
182
|
+
return { code: 0 };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
throw new ArgsError(`unknown subcommand "${head}"`);
|
|
186
|
+
}
|
|
187
|
+
catch (e) {
|
|
188
|
+
if (e instanceof ArgsError) {
|
|
189
|
+
err.write(`sigil: ${e.message}\n`);
|
|
190
|
+
err.write('\n' + USAGE);
|
|
191
|
+
return { code: 2 };
|
|
192
|
+
}
|
|
193
|
+
err.write(`sigil: ${e.message}\n`);
|
|
194
|
+
return { code: 1 };
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/cli/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the locations sigil cares about, honouring SIGIL_HOME env override.
|
|
3
|
+
* One source of truth used by the CLI, daemon entrypoint, and tests.
|
|
4
|
+
*
|
|
5
|
+
* The control socket is where the running sigil-mcp listens for unlock/lock/
|
|
6
|
+
* status commands from the `sigil` CLI. It lives inside ~/.sigil so it
|
|
7
|
+
* inherits the 0o700 directory permission; the socket file itself is also
|
|
8
|
+
* chmod'd to 0o600 by the server on bind.
|
|
9
|
+
*/
|
|
10
|
+
export interface SigilPaths {
|
|
11
|
+
readonly home: string;
|
|
12
|
+
readonly keysDir: string;
|
|
13
|
+
readonly policyDir: string;
|
|
14
|
+
readonly controlSocket: string;
|
|
15
|
+
readonly auditLog: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function resolvePaths(env?: NodeJS.ProcessEnv): SigilPaths;
|
|
18
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/cli/paths.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,UAAU,CAS7E"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
export function resolvePaths(env = process.env) {
|
|
4
|
+
const home = env['SIGIL_HOME'] ?? join(homedir(), '.sigil');
|
|
5
|
+
return {
|
|
6
|
+
home,
|
|
7
|
+
keysDir: join(home, 'keys'),
|
|
8
|
+
policyDir: join(home, 'policy'),
|
|
9
|
+
controlSocket: env['SIGIL_CONTROL_SOCK'] ?? join(home, 'control.sock'),
|
|
10
|
+
auditLog: join(home, 'audit.log'),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/cli/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAmBjC,MAAM,UAAU,YAAY,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC/D,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC5D,OAAO;QACL,IAAI;QACJ,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;QAC3B,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC;QAC/B,aAAa,EAAE,GAAG,CAAC,oBAAoB,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC;QACtE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC;KAClC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type KdfParams, SecretBuffer } from '../crypto/index.js';
|
|
2
|
+
import { type PolicyMode } from '../policy/index.js';
|
|
3
|
+
import type { SigilPaths } from './paths.js';
|
|
4
|
+
export interface PortalAddOpts {
|
|
5
|
+
handle: string;
|
|
6
|
+
keyFile: string;
|
|
7
|
+
passphrase: Buffer;
|
|
8
|
+
/**
|
|
9
|
+
* If true, the source key file is deleted after successful encryption.
|
|
10
|
+
* Defaults to true — leaving plaintext keys lying around is the whole
|
|
11
|
+
* thing sigil is trying to prevent.
|
|
12
|
+
*/
|
|
13
|
+
removeSource?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Override KDF parameters. Production code path uses DEFAULT_KDF_PARAMS
|
|
16
|
+
* (64MiB / 3 iters / 4 parallelism). Tests pass weaker params to keep
|
|
17
|
+
* the suite fast. The CLI binary never sets this.
|
|
18
|
+
*/
|
|
19
|
+
kdfParams?: KdfParams;
|
|
20
|
+
/**
|
|
21
|
+
* Policy template to write at provisioning time. Defaults to "permissive"
|
|
22
|
+
* (signs anything the agent asks — same UX as today, key still protected
|
|
23
|
+
* from context). Pass "strict" to write a locked-down template the user
|
|
24
|
+
* must edit before signing succeeds.
|
|
25
|
+
*/
|
|
26
|
+
policyMode?: PolicyMode;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Reads a private key from disk, encrypts it with the passphrase, writes it
|
|
30
|
+
* to the keys directory under <handle>.sigil, and (by default) deletes the
|
|
31
|
+
* source file. Returns the derived address.
|
|
32
|
+
*
|
|
33
|
+
* Accepts the key file as either:
|
|
34
|
+
* - 32 raw bytes (binary)
|
|
35
|
+
* - 64 hex characters (optionally 0x-prefixed, optionally with trailing whitespace)
|
|
36
|
+
*/
|
|
37
|
+
export declare function portalAdd(paths: SigilPaths, opts: PortalAddOpts): {
|
|
38
|
+
address: string;
|
|
39
|
+
keyfilePath: string;
|
|
40
|
+
policyPath: string;
|
|
41
|
+
};
|
|
42
|
+
export interface PortalInfo {
|
|
43
|
+
handle: string;
|
|
44
|
+
kind: 'eth';
|
|
45
|
+
address: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Lists portals by reading the keys directory and decrypting each keyfile
|
|
49
|
+
* just long enough to derive the address. Requires the passphrase.
|
|
50
|
+
* Returns an empty list if the directory doesn't exist.
|
|
51
|
+
*/
|
|
52
|
+
export declare function portalListFromDisk(paths: SigilPaths, passphrase: Buffer): PortalInfo[];
|
|
53
|
+
export interface PortalRemoveResult {
|
|
54
|
+
removed: boolean;
|
|
55
|
+
path: string;
|
|
56
|
+
}
|
|
57
|
+
export declare function portalRemove(paths: SigilPaths, handle: string): PortalRemoveResult;
|
|
58
|
+
export { SecretBuffer };
|
|
59
|
+
//# sourceMappingURL=portal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../../../src/cli/portal.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAW,YAAY,EAAa,MAAM,oBAAoB,CAAC;AAGtF,OAAO,EAAE,KAAK,UAAU,EAAkB,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,aAAa,GAClB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAqC9D;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,CAgBtF;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAalF;AAqBD,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { sealKey, SecretBuffer, unsealKey } from '../crypto/index.js';
|
|
4
|
+
import { addressFromPrivateKey } from '../eth/index.js';
|
|
5
|
+
import { HandleTable } from '../daemon/handles.js';
|
|
6
|
+
import { policyTemplate } from '../policy/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Reads a private key from disk, encrypts it with the passphrase, writes it
|
|
9
|
+
* to the keys directory under <handle>.sigil, and (by default) deletes the
|
|
10
|
+
* source file. Returns the derived address.
|
|
11
|
+
*
|
|
12
|
+
* Accepts the key file as either:
|
|
13
|
+
* - 32 raw bytes (binary)
|
|
14
|
+
* - 64 hex characters (optionally 0x-prefixed, optionally with trailing whitespace)
|
|
15
|
+
*/
|
|
16
|
+
export function portalAdd(paths, opts) {
|
|
17
|
+
HandleTable.parseHandle(opts.handle); // validates format
|
|
18
|
+
mkdirSync(paths.keysDir, { recursive: true, mode: 0o700 });
|
|
19
|
+
mkdirSync(paths.policyDir, { recursive: true, mode: 0o700 });
|
|
20
|
+
const destPath = join(paths.keysDir, `${opts.handle}.sigil`);
|
|
21
|
+
if (existsSync(destPath)) {
|
|
22
|
+
throw new Error(`portal "${opts.handle}" already exists at ${destPath}; remove it first`);
|
|
23
|
+
}
|
|
24
|
+
const policyPath = join(paths.policyDir, `${opts.handle}.toml`);
|
|
25
|
+
if (existsSync(policyPath)) {
|
|
26
|
+
throw new Error(`policy file for "${opts.handle}" already exists at ${policyPath}; remove it first`);
|
|
27
|
+
}
|
|
28
|
+
const raw = readFileSync(opts.keyFile);
|
|
29
|
+
const priv = normalizePrivateKey(raw);
|
|
30
|
+
let address;
|
|
31
|
+
try {
|
|
32
|
+
address = addressFromPrivateKey(priv);
|
|
33
|
+
const sealed = opts.kdfParams
|
|
34
|
+
? sealKey(priv, opts.passphrase, opts.kdfParams)
|
|
35
|
+
: sealKey(priv, opts.passphrase);
|
|
36
|
+
writeFileSync(destPath, sealed, { mode: 0o600 });
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
priv.fill(0);
|
|
40
|
+
}
|
|
41
|
+
// Write the policy file alongside the keyfile. Mode 0o600 — it's not secret
|
|
42
|
+
// per se, but it does describe what this key can sign, which is sensitive.
|
|
43
|
+
writeFileSync(policyPath, policyTemplate(opts.policyMode ?? 'permissive'), { mode: 0o600 });
|
|
44
|
+
if (opts.removeSource !== false) {
|
|
45
|
+
try {
|
|
46
|
+
unlinkSync(opts.keyFile);
|
|
47
|
+
}
|
|
48
|
+
catch { /* best-effort cleanup; file may already be gone */ }
|
|
49
|
+
}
|
|
50
|
+
return { address, keyfilePath: destPath, policyPath };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Lists portals by reading the keys directory and decrypting each keyfile
|
|
54
|
+
* just long enough to derive the address. Requires the passphrase.
|
|
55
|
+
* Returns an empty list if the directory doesn't exist.
|
|
56
|
+
*/
|
|
57
|
+
export function portalListFromDisk(paths, passphrase) {
|
|
58
|
+
if (!existsSync(paths.keysDir))
|
|
59
|
+
return [];
|
|
60
|
+
const entries = readdirSync(paths.keysDir).sort();
|
|
61
|
+
const out = [];
|
|
62
|
+
for (const filename of entries) {
|
|
63
|
+
const handle = HandleTable.handleFromFilename(filename);
|
|
64
|
+
if (handle === null)
|
|
65
|
+
continue;
|
|
66
|
+
const blob = readFileSync(join(paths.keysDir, filename));
|
|
67
|
+
const sb = unsealKey(blob, passphrase);
|
|
68
|
+
try {
|
|
69
|
+
out.push({ handle, kind: 'eth', address: addressFromPrivateKey(sb.bytes()) });
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
sb.dispose();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
export function portalRemove(paths, handle) {
|
|
78
|
+
HandleTable.parseHandle(handle); // validates format
|
|
79
|
+
const destPath = join(paths.keysDir, `${handle}.sigil`);
|
|
80
|
+
const policyPath = join(paths.policyDir, `${handle}.toml`);
|
|
81
|
+
const keyfileExisted = existsSync(destPath);
|
|
82
|
+
if (keyfileExisted)
|
|
83
|
+
unlinkSync(destPath);
|
|
84
|
+
// Best-effort policy cleanup. We don't fail the remove if the keyfile is
|
|
85
|
+
// missing but the policy file isn't, or vice versa — better to err on the
|
|
86
|
+
// side of cleaning up orphans.
|
|
87
|
+
if (existsSync(policyPath)) {
|
|
88
|
+
try {
|
|
89
|
+
unlinkSync(policyPath);
|
|
90
|
+
}
|
|
91
|
+
catch { /* ignore */ }
|
|
92
|
+
}
|
|
93
|
+
return { removed: keyfileExisted, path: destPath };
|
|
94
|
+
}
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// Helpers
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
function normalizePrivateKey(raw) {
|
|
99
|
+
if (raw.length === 32)
|
|
100
|
+
return Buffer.from(raw); // raw 32 bytes
|
|
101
|
+
// Otherwise: expect ASCII hex, possibly with 0x prefix + trailing whitespace.
|
|
102
|
+
const text = raw.toString('utf8').trim();
|
|
103
|
+
const stripped = text.startsWith('0x') ? text.slice(2) : text;
|
|
104
|
+
if (!/^[0-9a-fA-F]{64}$/.test(stripped)) {
|
|
105
|
+
throw new Error('key file must be either 32 raw bytes or 64 hex chars (with optional 0x prefix)');
|
|
106
|
+
}
|
|
107
|
+
return Buffer.from(stripped, 'hex');
|
|
108
|
+
}
|
|
109
|
+
// Re-export SecretBuffer so tests can assert it disposes correctly without
|
|
110
|
+
// reaching into the crypto module directly.
|
|
111
|
+
export { SecretBuffer };
|
|
112
|
+
//# sourceMappingURL=portal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portal.js","sourceRoot":"","sources":["../../../src/cli/portal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type PortalSummary } from '../control/index.js';
|
|
2
|
+
import type { SigilPaths } from './paths.js';
|
|
3
|
+
export interface StatusReport {
|
|
4
|
+
/** Number of *.sigil files in the keys directory. */
|
|
5
|
+
keyfilesOnDisk: number;
|
|
6
|
+
/** Path the audit log lives at. Useful for `tail`-ing during incidents. */
|
|
7
|
+
auditLog: string;
|
|
8
|
+
/** True if the control socket responded — i.e. sigil-mcp is alive. */
|
|
9
|
+
mcpRunning: boolean;
|
|
10
|
+
/** Process ID of the running sigil-mcp; null when not running. */
|
|
11
|
+
mcpPid: number | null;
|
|
12
|
+
/** True if the HandleTable has been unlocked. False when mcp is down or locked. */
|
|
13
|
+
unlocked: boolean;
|
|
14
|
+
/** Portals currently loaded in the running sigil-mcp. Empty when locked or down. */
|
|
15
|
+
portals: PortalSummary[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Reports the on-disk + live state of sigil. Does NOT require the passphrase.
|
|
19
|
+
*
|
|
20
|
+
* Disk side: counts encrypted keyfiles.
|
|
21
|
+
* Live side: probes the control socket. If the server is unreachable, marks
|
|
22
|
+
* mcpRunning=false; this is the common case when no Claude Code session is
|
|
23
|
+
* open. Any other client error is also treated as not-running — the user
|
|
24
|
+
* can re-run "sigil unlock" or check the socket file directly for more
|
|
25
|
+
* detailed diagnosis.
|
|
26
|
+
*/
|
|
27
|
+
export declare function status(paths: SigilPaths): Promise<StatusReport>;
|
|
28
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/status.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,cAAc,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,UAAU,EAAE,OAAO,CAAC;IACpB,kEAAkE;IAClE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,mFAAmF;IACnF,QAAQ,EAAE,OAAO,CAAC;IAClB,oFAAoF;IACpF,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CA8BrE"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import { ControlClientError, controlRequest, isControlError, } from '../control/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Reports the on-disk + live state of sigil. Does NOT require the passphrase.
|
|
5
|
+
*
|
|
6
|
+
* Disk side: counts encrypted keyfiles.
|
|
7
|
+
* Live side: probes the control socket. If the server is unreachable, marks
|
|
8
|
+
* mcpRunning=false; this is the common case when no Claude Code session is
|
|
9
|
+
* open. Any other client error is also treated as not-running — the user
|
|
10
|
+
* can re-run "sigil unlock" or check the socket file directly for more
|
|
11
|
+
* detailed diagnosis.
|
|
12
|
+
*/
|
|
13
|
+
export async function status(paths) {
|
|
14
|
+
const keyfilesOnDisk = countKeyfiles(paths.keysDir);
|
|
15
|
+
let mcpRunning = false;
|
|
16
|
+
let mcpPid = null;
|
|
17
|
+
let unlocked = false;
|
|
18
|
+
let portals = [];
|
|
19
|
+
try {
|
|
20
|
+
const resp = await controlRequest({
|
|
21
|
+
socketPath: paths.controlSocket,
|
|
22
|
+
request: { method: 'status' },
|
|
23
|
+
timeoutMs: 1_000,
|
|
24
|
+
});
|
|
25
|
+
if (!isControlError(resp)) {
|
|
26
|
+
mcpRunning = true;
|
|
27
|
+
mcpPid = resp.pid;
|
|
28
|
+
unlocked = resp.unlocked;
|
|
29
|
+
portals = resp.portals;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
if (!(err instanceof ControlClientError))
|
|
34
|
+
throw err;
|
|
35
|
+
// SERVER_DOWN / CONNECT_FAILED / TIMEOUT all → mcpRunning=false.
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
keyfilesOnDisk,
|
|
39
|
+
auditLog: paths.auditLog,
|
|
40
|
+
mcpRunning,
|
|
41
|
+
mcpPid,
|
|
42
|
+
unlocked,
|
|
43
|
+
portals,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function countKeyfiles(dir) {
|
|
47
|
+
if (!existsSync(dir))
|
|
48
|
+
return 0;
|
|
49
|
+
try {
|
|
50
|
+
const stat = statSync(dir);
|
|
51
|
+
if (!stat.isDirectory())
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
return readdirSync(dir).filter((f) => f.endsWith('.sigil')).length;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,cAAc,GAEf,MAAM,qBAAqB,CAAC;AAkB7B;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAiB;IAC5C,MAAM,cAAc,GAAG,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpD,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,OAAO,GAAoB,EAAE,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC;YAChC,UAAU,EAAE,KAAK,CAAC,aAAa;YAC/B,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE;YAC7B,SAAS,EAAE,KAAK;SACjB,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,UAAU,GAAG,IAAI,CAAC;YAClB,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC;YAClB,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YACzB,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QACzB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,CAAC,GAAG,YAAY,kBAAkB,CAAC;YAAE,MAAM,GAAG,CAAC;QACpD,iEAAiE;IACnE,CAAC;IACD,OAAO;QACL,cAAc;QACd,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,UAAU;QACV,MAAM;QACN,QAAQ;QACR,OAAO;KACR,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ControlClientError, type ControlResponse } from '../control/index.js';
|
|
2
|
+
import type { SigilPaths } from './paths.js';
|
|
3
|
+
export interface UnlockOpts {
|
|
4
|
+
paths: SigilPaths;
|
|
5
|
+
/** Buffer holding the passphrase. Caller is responsible for zeroizing it. */
|
|
6
|
+
passphrase: Buffer;
|
|
7
|
+
/** Optional connect timeout in ms (default 5000). */
|
|
8
|
+
timeoutMs?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface UnlockResult {
|
|
11
|
+
/** Server-side response, or null if the server is unreachable. */
|
|
12
|
+
response: ControlResponse | null;
|
|
13
|
+
/** Set when the control socket couldn't be reached. */
|
|
14
|
+
clientError?: ControlClientError;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Send an unlock request to the running sigil-mcp. Encodes the passphrase as
|
|
18
|
+
* base64 for transport; does NOT clear the caller's buffer (the caller owns
|
|
19
|
+
* lifetime). Returns the parsed response, or a client error if the server
|
|
20
|
+
* was unreachable.
|
|
21
|
+
*/
|
|
22
|
+
export declare function unlock(opts: UnlockOpts): Promise<UnlockResult>;
|
|
23
|
+
export interface LockOpts {
|
|
24
|
+
paths: SigilPaths;
|
|
25
|
+
timeoutMs?: number;
|
|
26
|
+
}
|
|
27
|
+
export declare function lock(opts: LockOpts): Promise<UnlockResult>;
|
|
28
|
+
/**
|
|
29
|
+
* Format a result for human-readable CLI output. Returns the message and the
|
|
30
|
+
* exit code the CLI should use.
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatResult(action: 'unlock' | 'lock', result: UnlockResult): {
|
|
33
|
+
message: string;
|
|
34
|
+
code: number;
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=unlock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlock.d.ts","sourceRoot":"","sources":["../../../src/cli/unlock.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAGlB,KAAK,eAAe,EACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,uDAAuD;IACvD,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAapE;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAYhE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd,CAkCA"}
|