@amalgm/core 0.1.1 → 0.1.2

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/PURPOSE.md CHANGED
@@ -78,6 +78,10 @@ source until each module is cut over.
78
78
  12. **A snapshot names its resume point.** Resource readers share one
79
79
  per-attempt context and a snapshot is stable only when its sequence is
80
80
  unchanged across the read; a racing write causes a complete retry.
81
+ 13. **Credential discovery reports evidence, never credentials.** Local
82
+ harness discovery may expose auth type and a bounded hint, but secret
83
+ values cross only an explicit authenticated resolution call and never
84
+ enter discovery, logs, or state snapshots.
81
85
 
82
86
  ## Five surfaces, one behavior
83
87
 
@@ -9,6 +9,7 @@ export * from './ports.js';
9
9
  export * from './labels.js';
10
10
  export * from './layout.js';
11
11
  export * from './product-state.js';
12
+ export * from './local/index.js';
12
13
  export * from './ids.js';
13
14
  export * from './auth-records.js';
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC"}
@@ -9,6 +9,7 @@ export * from './ports.js';
9
9
  export * from './labels.js';
10
10
  export * from './layout.js';
11
11
  export * from './product-state.js';
12
+ export * from './local/index.js';
12
13
  export * from './ids.js';
13
14
  export * from './auth-records.js';
14
15
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { LocalDiscoveryHost, LocalEnvironmentHost } from './types.js';
2
+ export declare function createLocalApi(options: {
3
+ readonly discovery: LocalDiscoveryHost;
4
+ readonly environment: LocalEnvironmentHost;
5
+ }): (request: Request) => Promise<Response>;
6
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/identity/local/api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE3E,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC;CAC5C,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAmC1C"}
@@ -0,0 +1,40 @@
1
+ import { discoverLocalHarnesses } from './discovery.js';
2
+ import { resolveLocalAgentEnv } from './resolve.js';
3
+ export function createLocalApi(options) {
4
+ return async (request) => {
5
+ const url = new URL(request.url);
6
+ if (request.method === 'GET' && (url.pathname === '/local' || url.pathname === '/local/credentials')) {
7
+ return json(200, {
8
+ agents: discoverLocalHarnesses(options.discovery),
9
+ homedir: options.environment.homedir,
10
+ workspaceRoot: options.environment.workspaceRoot,
11
+ });
12
+ }
13
+ if (request.method === 'POST' && url.pathname === '/local/init') {
14
+ const initialized = options.environment.ensure();
15
+ return json(200, {
16
+ ok: true,
17
+ created: initialized.created,
18
+ amalgmPath: initialized.path,
19
+ homedir: options.environment.homedir,
20
+ workspaceRoot: options.environment.workspaceRoot,
21
+ agents: discoverLocalHarnesses(options.discovery),
22
+ });
23
+ }
24
+ if (request.method === 'POST' && url.pathname === '/local/credentials/resolve') {
25
+ const body = await request.json();
26
+ if (typeof body.agentId !== 'string' || typeof body.authMode !== 'string') {
27
+ return json(400, { error: 'agentId and authMode are required' });
28
+ }
29
+ return json(200, { env: resolveLocalAgentEnv(body.agentId, body.authMode, typeof body.proxyToken === 'string' ? body.proxyToken : undefined, typeof body.proxyBaseUrl === 'string' ? body.proxyBaseUrl : undefined) });
30
+ }
31
+ return json(404, { error: 'not found' });
32
+ };
33
+ }
34
+ function json(status, body) {
35
+ return new Response(JSON.stringify(body), {
36
+ status,
37
+ headers: { 'content-type': 'application/json', 'cache-control': 'no-store' },
38
+ });
39
+ }
40
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/identity/local/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGpD,MAAM,UAAU,cAAc,CAAC,OAG9B;IACC,OAAO,KAAK,EAAE,OAAO,EAAE,EAAE;QACvB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,oBAAoB,CAAC,EAAE,CAAC;YACrG,OAAO,IAAI,CAAC,GAAG,EAAE;gBACf,MAAM,EAAE,sBAAsB,CAAC,OAAO,CAAC,SAAS,CAAC;gBACjD,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,OAAO;gBACpC,aAAa,EAAE,OAAO,CAAC,WAAW,CAAC,aAAa;aACjD,CAAC,CAAC;QACL,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;YAChE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;YACjD,OAAO,IAAI,CAAC,GAAG,EAAE;gBACf,EAAE,EAAE,IAAI;gBACR,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,UAAU,EAAE,WAAW,CAAC,IAAI;gBAC5B,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,OAAO;gBACpC,aAAa,EAAE,OAAO,CAAC,WAAW,CAAC,aAAa;gBAChD,MAAM,EAAE,sBAAsB,CAAC,OAAO,CAAC,SAAS,CAAC;aAClD,CAAC,CAAC;QACL,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,4BAA4B,EAAE,CAAC;YAC/E,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAA6B,CAAC;YAC7D,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC1E,OAAO,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,mCAAmC,EAAE,CAAC,CAAC;YACnE,CAAC;YACD,OAAO,IAAI,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,oBAAoB,CAC1C,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,QAAQ,EACb,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EACjE,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CACtE,EAAE,CAAC,CAAC;QACP,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,IAAI,CAAC,MAAc,EAAE,IAAa;IACzC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;QACxC,MAAM;QACN,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,UAAU,EAAE;KAC7E,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { LocalDiscoveryHost, LocalHarness } from './types.js';
2
+ /** Engine reference: runtime/lib/local/credentialResolver.ts. */
3
+ export declare function discoverLocalHarnesses(host: LocalDiscoveryHost): LocalHarness[];
4
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/identity/local/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEpF,iEAAiE;AACjE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,kBAAkB,GAAG,YAAY,EAAE,CAwE/E"}
@@ -0,0 +1,74 @@
1
+ /** Engine reference: runtime/lib/local/credentialResolver.ts. */
2
+ export function discoverLocalHarnesses(host) {
3
+ const found = [];
4
+ const path = (...parts) => host.join(host.homedir, ...parts);
5
+ const claudeDir = path('.claude');
6
+ if (host.exists(claudeDir)) {
7
+ found.push(harness('claude_code', 'Claude Code', claudeDir, host.authStatus('claude_code')));
8
+ }
9
+ const codexDir = path('.codex');
10
+ const codexAuth = host.readJson(path('.codex', 'auth.json'));
11
+ if (codexAuth) {
12
+ const tokens = codexAuth.tokens;
13
+ const apiKey = typeof codexAuth.OPENAI_API_KEY === 'string' ? codexAuth.OPENAI_API_KEY : '';
14
+ const status = tokens && typeof tokens === 'object'
15
+ ? { hasAuth: true, authDetails: { type: 'oauth', hint: clean(codexAuth.auth_mode) || 'configured' } }
16
+ : apiKey
17
+ ? { hasAuth: true, authDetails: { type: 'api_key', hint: apiKey.slice(-4) } }
18
+ : { hasAuth: false };
19
+ found.push(harness('codex', 'Codex', codexDir, status));
20
+ }
21
+ const openCodeDir = path('.config', 'opencode');
22
+ const openCodeAuth = path('.local', 'share', 'opencode', 'auth.json');
23
+ if (host.exists(openCodeDir) || host.exists(openCodeAuth)) {
24
+ found.push(harness('opencode', 'OpenCode', openCodeDir, host.nonEmptyFile(openCodeAuth)
25
+ ? { hasAuth: true, authDetails: { type: 'oauth', hint: 'configured' } }
26
+ : { hasAuth: false }));
27
+ }
28
+ const piDir = path('.pi');
29
+ const piCredentials = [path('.pi', 'agent', 'auth.json'), path('.pi', 'agent', 'models.json')];
30
+ if (host.exists(piDir) || piCredentials.some((candidate) => host.exists(candidate))) {
31
+ const hasAuth = piCredentials.some((candidate) => host.nonEmptyFile(candidate));
32
+ found.push(harness('pi', 'Pi', piDir, hasAuth
33
+ ? { hasAuth, authDetails: { type: 'unknown', hint: 'configured' } }
34
+ : { hasAuth }));
35
+ }
36
+ const ampDir = path('.config', 'amp');
37
+ const ampKey = host.env('AMP_API_KEY') ?? '';
38
+ const ampCredentials = [path('.config', 'amp', 'settings.json'), path('.amp', 'config.json'), path('.amp', 'auth.json')];
39
+ if (ampKey || host.exists(ampDir) || ampCredentials.some((candidate) => host.exists(candidate))) {
40
+ const hasFile = ampCredentials.some((candidate) => host.nonEmptyFile(candidate));
41
+ const hasAuth = Boolean(ampKey || hasFile);
42
+ found.push(harness('amp', 'Amp', ampDir, hasAuth
43
+ ? { hasAuth, authDetails: { type: ampKey ? 'api_key' : 'unknown', hint: ampKey ? ampKey.slice(-4) : 'configured' } }
44
+ : { hasAuth }));
45
+ }
46
+ const cursorDir = path('.cursor');
47
+ const cursorKey = host.env('CURSOR_API_KEY') ?? '';
48
+ const cursorCredentials = [
49
+ path('.cursor', 'credentials.json'),
50
+ path('.config', 'cursor', 'credentials.json'),
51
+ path('.local', 'share', 'cursor-agent', 'auth.json'),
52
+ ];
53
+ const cursorStatus = host.authStatus('cursor');
54
+ if (cursorKey || cursorStatus?.hasAuth || host.exists(cursorDir)
55
+ || cursorCredentials.some((candidate) => host.exists(candidate))) {
56
+ const hasFile = cursorCredentials.some((candidate) => host.nonEmptyFile(candidate));
57
+ const hasAuth = Boolean(cursorKey || cursorStatus?.hasAuth || hasFile);
58
+ found.push(harness('cursor', 'Cursor', cursorDir, hasAuth
59
+ ? cursorKey
60
+ ? { hasAuth, authDetails: { type: 'api_key', hint: cursorKey.slice(-4) } }
61
+ : cursorStatus?.hasAuth
62
+ ? cursorStatus
63
+ : { hasAuth, authDetails: { type: 'oauth', hint: 'configured' } }
64
+ : { hasAuth }));
65
+ }
66
+ return found;
67
+ }
68
+ function harness(id, name, configDir, status) {
69
+ return { id, name, configDir, ...(status ?? { hasAuth: false }) };
70
+ }
71
+ function clean(value) {
72
+ return typeof value === 'string' ? value.trim() : '';
73
+ }
74
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/identity/local/discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { createLocalApi } from './api.js';
2
+ export { discoverLocalHarnesses } from './discovery.js';
3
+ export { localReauthCommand, resolveLocalAgentEnv } from './resolve.js';
4
+ export type * from './types.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/identity/local/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACxE,mBAAmB,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { createLocalApi } from './api.js';
2
+ export { discoverLocalHarnesses } from './discovery.js';
3
+ export { localReauthCommand, resolveLocalAgentEnv } from './resolve.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/identity/local/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { LocalHarness } from './types.js';
2
+ export declare function resolveLocalAgentEnv(agentId: LocalHarness['id'] | string, authMode: string, proxyToken?: string, proxyBaseUrl?: string): Record<string, string>;
3
+ export declare function localReauthCommand(agentId: string): {
4
+ shell: string;
5
+ description: string;
6
+ } | null;
7
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/identity/local/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,EACpC,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAexB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAajG"}
@@ -0,0 +1,32 @@
1
+ export function resolveLocalAgentEnv(agentId, authMode, proxyToken, proxyBaseUrl) {
2
+ if (authMode !== 'amalgm' || !proxyToken || !proxyBaseUrl)
3
+ return {};
4
+ const base = proxyBaseUrl.replace(/\/+$/, '');
5
+ switch (agentId) {
6
+ case 'claude_code':
7
+ return { ANTHROPIC_API_KEY: proxyToken, ANTHROPIC_BASE_URL: `${base}/anthropic` };
8
+ case 'codex':
9
+ return { OPENAI_API_KEY: proxyToken, OPENAI_BASE_URL: `${base}/openai/v1` };
10
+ case 'opencode':
11
+ return { AI_GATEWAY_API_KEY: proxyToken, AI_GATEWAY_BASE_URL: `${base}/ai_gateway/v3/ai` };
12
+ case 'pi':
13
+ return { AI_GATEWAY_API_KEY: proxyToken, AI_GATEWAY_BASE_URL: `${base}/ai_gateway/v1` };
14
+ default:
15
+ return {};
16
+ }
17
+ }
18
+ export function localReauthCommand(agentId) {
19
+ switch (agentId) {
20
+ case 'claude_code': return { shell: 'claude', description: 'Run `claude`, then type /login to authenticate.' };
21
+ case 'codex': return { shell: 'codex login', description: '`codex login` walks through OAuth or API-key setup.' };
22
+ case 'opencode': return { shell: 'opencode auth login', description: '`opencode auth login` walks through provider setup.' };
23
+ case 'pi': return { shell: 'pi --terminal-login', description: '`pi --terminal-login` authenticates Pi in the terminal.' };
24
+ case 'amp': return { shell: 'amp --setup', description: '`amp --setup` configures Amp credentials.' };
25
+ case 'cursor': return {
26
+ shell: 'if command -v cursor-agent >/dev/null 2>&1; then cursor-agent login; else "$HOME/.local/bin/cursor-agent" login; fi',
27
+ description: '`cursor-agent login` opens the browser login flow.',
28
+ };
29
+ default: return null;
30
+ }
31
+ }
32
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/identity/local/resolve.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,oBAAoB,CAClC,OAAoC,EACpC,QAAgB,EAChB,UAAmB,EACnB,YAAqB;IAErB,IAAI,QAAQ,KAAK,QAAQ,IAAI,CAAC,UAAU,IAAI,CAAC,YAAY;QAAE,OAAO,EAAE,CAAC;IACrE,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9C,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,aAAa;YAChB,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,kBAAkB,EAAE,GAAG,IAAI,YAAY,EAAE,CAAC;QACpF,KAAK,OAAO;YACV,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,GAAG,IAAI,YAAY,EAAE,CAAC;QAC9E,KAAK,UAAU;YACb,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,mBAAmB,EAAE,GAAG,IAAI,mBAAmB,EAAE,CAAC;QAC7F,KAAK,IAAI;YACP,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,mBAAmB,EAAE,GAAG,IAAI,gBAAgB,EAAE,CAAC;QAC1F;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,aAAa,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC;QAC/G,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,qDAAqD,EAAE,CAAC;QAClH,KAAK,UAAU,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,qDAAqD,EAAE,CAAC;QAC7H,KAAK,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,yDAAyD,EAAE,CAAC;QAC3H,KAAK,KAAK,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC;QACtG,KAAK,QAAQ,CAAC,CAAC,OAAO;YACpB,KAAK,EAAE,qHAAqH;YAC5H,WAAW,EAAE,oDAAoD;SAClE,CAAC;QACF,OAAO,CAAC,CAAC,OAAO,IAAI,CAAC;IACvB,CAAC;AACH,CAAC"}
@@ -0,0 +1,30 @@
1
+ export interface LocalAuthStatus {
2
+ readonly hasAuth: boolean;
3
+ readonly authDetails?: {
4
+ readonly type: 'oauth' | 'api_key' | 'unknown';
5
+ readonly hint: string;
6
+ };
7
+ }
8
+ export interface LocalHarness extends LocalAuthStatus {
9
+ readonly id: 'claude_code' | 'codex' | 'opencode' | 'pi' | 'amp' | 'cursor';
10
+ readonly name: string;
11
+ readonly configDir: string;
12
+ }
13
+ export interface LocalDiscoveryHost {
14
+ readonly homedir: string;
15
+ join(...parts: string[]): string;
16
+ exists(path: string): boolean;
17
+ nonEmptyFile(path: string): boolean;
18
+ readJson(path: string): unknown;
19
+ env(name: string): string | undefined;
20
+ authStatus(harnessId: LocalHarness['id']): LocalAuthStatus | null;
21
+ }
22
+ export interface LocalEnvironmentHost {
23
+ readonly homedir: string;
24
+ readonly workspaceRoot: string;
25
+ ensure(): {
26
+ readonly created: boolean;
27
+ readonly path: string;
28
+ };
29
+ }
30
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/identity/local/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAClG;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACnD,QAAQ,CAAC,EAAE,EAAE,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,IAAI,GAAG,KAAK,GAAG,QAAQ,CAAC;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IACjC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACtC,UAAU,CAAC,SAAS,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,eAAe,GAAG,IAAI,CAAC;CACnE;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,MAAM,IAAI;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAChE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/identity/local/types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amalgm/core",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "The Amalgm kernel SDK — identity, transport, supervision, and host capability contracts behind host-injected adapters.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -20,6 +20,10 @@
20
20
  "types": "./dist/identity/index.d.ts",
21
21
  "default": "./dist/identity/index.js"
22
22
  },
23
+ "./local": {
24
+ "types": "./dist/identity/local/index.d.ts",
25
+ "default": "./dist/identity/local/index.js"
26
+ },
23
27
  "./transport": {
24
28
  "types": "./dist/transport/index.d.ts",
25
29
  "default": "./dist/transport/index.js"