@makaio/client-codex 1.0.0-dev-1781368534585 → 1.0.0-dev-1783940945655

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.
@@ -40,7 +40,37 @@ export declare const clientDefinition: {
40
40
  description?: string | undefined;
41
41
  glob?: string | undefined;
42
42
  }[] | undefined;
43
- defaultProviderId?: string | undefined;
43
+ authMethods: ({
44
+ id: string;
45
+ mode: "explicit";
46
+ label: string;
47
+ description?: string | undefined;
48
+ fields: {
49
+ id: string;
50
+ label: string;
51
+ description?: string | undefined;
52
+ required: boolean;
53
+ secret: boolean;
54
+ sourceHints: {
55
+ kind: "environment";
56
+ variable: string;
57
+ }[];
58
+ }[];
59
+ } | {
60
+ id: string;
61
+ mode: "inferred";
62
+ label: string;
63
+ description?: string | undefined;
64
+ } | {
65
+ id: string;
66
+ mode: "none";
67
+ label: string;
68
+ description?: string | undefined;
69
+ })[];
70
+ defaultAuth?: {
71
+ providerDefinitionId: string;
72
+ methodId: string;
73
+ } | undefined;
44
74
  runtimeCapabilities: {
45
75
  supportsHooks: boolean;
46
76
  supportsStatusline: boolean;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as CodexNativeHooksFileSchema, a as CodexWiringSchemas, b as clientDefinition, c as CodexConfigHooksAddResponseSchema, d as CodexConfigHooksRemoveRequestSchema, f as CodexConfigHooksRemoveResponseSchema, g as CodexNativeHookMatcherGroupSchema, h as CodexNativeCommandHookSchema, l as CodexConfigHooksListRequestSchema, m as CodexHookEntrySchema, o as AbsolutePathSchema, p as CodexConfigSchemas, r as CodexClientSubjects, s as CodexConfigHooksAddRequestSchema, t as CodexClientSessionService, u as CodexConfigHooksListResponseSchema, v as CodexScopeHookRecordSchema, y as CodexScopeSchema } from "./codex-client-session-service-C2F6rQDS.mjs";
2
- import { t as codexPackage } from "./src-CUFX-QsP.mjs";
1
+ import { C as clientDefinition, S as CodexScopeSchema, _ as CodexHookEntrySchema, b as CodexNativeHooksFileSchema, c as CodexWiringSchemas, d as CodexConfigHooksAddResponseSchema, f as CodexConfigHooksListRequestSchema, g as CodexConfigSchemas, h as CodexConfigHooksRemoveResponseSchema, l as AbsolutePathSchema, m as CodexConfigHooksRemoveRequestSchema, o as CodexClientSubjects, p as CodexConfigHooksListResponseSchema, t as CodexClientSessionService, u as CodexConfigHooksAddRequestSchema, v as CodexNativeCommandHookSchema, x as CodexScopeHookRecordSchema, y as CodexNativeHookMatcherGroupSchema } from "./codex-client-session-service-ddd3K0rw.mjs";
2
+ import { t as codexPackage } from "./src-B_UWVcLO.mjs";
3
3
 
4
4
  export { AbsolutePathSchema, CodexClientSessionService, CodexClientSubjects, CodexConfigHooksAddRequestSchema, CodexConfigHooksAddResponseSchema, CodexConfigHooksListRequestSchema, CodexConfigHooksListResponseSchema, CodexConfigHooksRemoveRequestSchema, CodexConfigHooksRemoveResponseSchema, CodexConfigSchemas, CodexHookEntrySchema, CodexNativeCommandHookSchema, CodexNativeHookMatcherGroupSchema, CodexNativeHooksFileSchema, CodexScopeHookRecordSchema, CodexScopeSchema, CodexWiringSchemas, clientDefinition, codexPackage };
@@ -11,8 +11,8 @@
11
11
  * Codex config root, falling back to native `~/.codex` paths when no resolver
12
12
  * or global binary is available. Wiring requests use the same settings path
13
13
  * resolution. The service also handles the blocking `client:codex.config.prime`
14
- * lifecycle hook and the `client:codex.sessionConfig.setup` delegation subject
15
- * for per-session config directory initialization.
14
+ * lifecycle hook and the `client:codex.sessionConfig.setup` / `.destroy`
15
+ * delegation subjects for refresh-safe per-session config isolation.
16
16
  *
17
17
  * Unknown or not-yet-modeled event names are silently dropped — they stay
18
18
  * raw-only inside the `client:codex.*` namespace and are never forwarded to
@@ -41,6 +41,7 @@
41
41
  import type { IMakaioBus } from '@makaio/framework/bus';
42
42
  import { BaseService } from '@makaio/framework/service-base';
43
43
  import { CodexClientSettings } from './client-settings.js';
44
+ import { CodexSessionConfigHandler } from './session-config-handler.js';
44
45
  /**
45
46
  * Maximum number of adapter-managed session IDs retained in
46
47
  * {@link CodexClientSessionService.managedAdapterSessionIds}.
@@ -61,7 +62,7 @@ export declare const MANAGED_SESSION_CAP = 10000;
61
62
  * `client.runtime.started` for the adapter-managed session gate, and
62
63
  * registers request handlers for `config.hooks.list`, `config.hooks.add`,
63
64
  * `config.hooks.remove`, `config.prime`, `wiring.list`, `wiring.apply`,
64
- * `wiring.remove`, and `sessionConfig.setup`.
65
+ * `wiring.remove`, `sessionConfig.setup`, and `sessionConfig.destroy`.
65
66
  * 2. On each incoming raw event, calls {@link normalizeCodexHook}.
66
67
  * 3. Emits the normalized subject when the event is recognized; silently
67
68
  * ignores unknown events. Normalized `client.session.*` events are
@@ -74,6 +75,15 @@ export declare class CodexClientSessionService extends BaseService {
74
75
  private readonly settingsOverride;
75
76
  /** Cached active config-dir resolution; reset when the active Codex version changes. */
76
77
  private cachedConfigDir;
78
+ /**
79
+ * Stable runtime identity of the machine that owns the client sessions
80
+ * observed by this service. Stamped onto `client.session.started` payloads
81
+ * so downstream storage receives the owning machine's identity without
82
+ * deriving it from the writer process.
83
+ */
84
+ private readonly machineId;
85
+ /** Client-owned native auth materialization and refresh reconciliation. */
86
+ private readonly sessionConfigHandler;
77
87
  /**
78
88
  * Set of `adapterSessionId` values known to be owned by an adapter-managed
79
89
  * Codex runtime. Populated by {@link handleRuntimeStarted} when a
@@ -93,12 +103,16 @@ export declare class CodexClientSessionService extends BaseService {
93
103
  * @param settings - Optional {@link CodexClientSettings} instance for tests
94
104
  * that need exact filesystem paths. Production callers should omit it so
95
105
  * the service can resolve the active managed config dir via the bus.
106
+ * @param machineId - Stable runtime identity of the observing machine,
107
+ * caller-supplied from the extension context. Omit in tests or when the
108
+ * identity is unavailable.
109
+ * @param sessionConfigHandler - Optional native auth lease handler override.
96
110
  */
97
- constructor(bus?: IMakaioBus, settings?: CodexClientSettings);
111
+ constructor(bus?: IMakaioBus, settings?: CodexClientSettings, machineId?: string, sessionConfigHandler?: CodexSessionConfigHandler);
98
112
  /**
99
113
  * Register the raw hook ingress handler, config management request handlers,
100
114
  * wiring management request handlers, the config-prime lifecycle handler,
101
- * and the session config setup handler on the bus.
115
+ * and the session config setup/teardown handlers on the bus.
102
116
  *
103
117
  * Also subscribes to `client.runtime.started` to track adapter-managed
104
118
  * sessions for the {@link handleHookReceived} suppression gate.
@@ -72,7 +72,11 @@ export type CodexNormalizedEvent = {
72
72
  * Returns `null` for unknown or not-yet-modeled event names so the caller
73
73
  * skips global emission and keeps the event raw-only in `client:codex.*`.
74
74
  * @param raw - Raw hook payload delivered on `client:codex.hook.received`
75
+ * @param machineId - Stable runtime identity of the observing machine,
76
+ * caller-supplied by the owning client runtime. Stamped onto
77
+ * `client.session.started` so downstream storage receives the owning
78
+ * machine's identity without deriving it from the writer process.
75
79
  * @returns Normalized event with subject and typed payload, or `null` when
76
80
  * the event name is unknown
77
81
  */
78
- export declare function normalizeCodexHook(raw: RawClientHookPayload): CodexNormalizedEvent | null;
82
+ export declare function normalizeCodexHook(raw: RawClientHookPayload, machineId?: string): CodexNormalizedEvent | null;
@@ -15,6 +15,7 @@
15
15
  * - `wiring.apply` — install wiring entries into the target scope
16
16
  * - `wiring.remove` — uninstall wiring entries from the target scope
17
17
  * - `sessionConfig.setup` — seed an isolated session config directory
18
+ * - `sessionConfig.destroy` — reconcile and clear isolated native auth
18
19
  *
19
20
  * **Subject conventions:**
20
21
  * - Raw Codex-native events flow in the `client:codex.*` namespace only.
@@ -37,6 +38,7 @@
37
38
  * - `CodexClientSubjects.wiring.apply` → `client:codex.wiring.apply`
38
39
  * - `CodexClientSubjects.wiring.remove` → `client:codex.wiring.remove`
39
40
  * - `CodexClientSubjects.sessionConfig.setup` → `client:codex.sessionConfig.setup`
41
+ * - `CodexClientSubjects.sessionConfig.destroy` → `client:codex.sessionConfig.destroy`
40
42
  */
41
43
  export declare const CodexClientSubjects: import("@makaio/framework/core").BusSubjects<import("@makaio/framework/core").FlatSubjectDefinitions<`client:${string}`, {
42
44
  'hook.received': import("zod").ZodObject<{
@@ -194,6 +196,20 @@ export declare const CodexClientSubjects: import("@makaio/framework/core").BusSu
194
196
  }, import("zod/v4/core").$strip>;
195
197
  response: import("zod").ZodObject<{
196
198
  env: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
199
+ authMaterialized: import("zod").ZodBoolean;
200
+ }, import("zod/v4/core").$strip>;
201
+ };
202
+ 'sessionConfig.destroy': {
203
+ request: import("zod").ZodObject<{
204
+ sessionDir: import("zod").ZodString;
205
+ platform: import("zod").ZodEnum<{
206
+ darwin: "darwin";
207
+ linux: "linux";
208
+ win32: "win32";
209
+ }>;
210
+ }, import("zod/v4/core").$strip>;
211
+ response: import("zod").ZodObject<{
212
+ success: import("zod").ZodBoolean;
197
213
  }, import("zod/v4/core").$strip>;
198
214
  };
199
215
  }>, `client:${string}`>;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Secret-safe error helpers for Codex native authentication storage.
3
+ * @packageDocumentation
4
+ */
5
+ /**
6
+ * Build an error that preserves a safe discriminator but never the secret-bearing message.
7
+ * @param operation - Safe operation label.
8
+ * @param error - Original failure, whose message is deliberately discarded.
9
+ * @returns Sanitized error safe for bus propagation and logs.
10
+ */
11
+ export declare function sanitizedNativeAuthError(operation: string, error: unknown): Error;
12
+ /**
13
+ * Preserve both sanitized failures when cleanup follows an earlier error.
14
+ * @param existing - Earlier failure, when present.
15
+ * @param next - Newly observed sanitized failure.
16
+ * @param message - Safe aggregate description.
17
+ * @returns The new failure or an aggregate retaining both failures.
18
+ */
19
+ export declare function mergeNativeAuthErrors(existing: unknown, next: Error, message: string): unknown;
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Canonical Codex native-auth identity and source-lock primitives.
3
+ * @packageDocumentation
4
+ */
5
+ /** Secret-free cross-process lock-directory suffix beside canonical CODEX_HOME. */
6
+ export declare const CODEX_AUTH_CAS_LOCK_FILE = ".makaio-codex-auth-cas.lock";
7
+ /** Lock finalization failed after the guarded native-auth operation committed. */
8
+ export declare class CodexNativeAuthSourceLockFinalizationError extends Error {
9
+ constructor();
10
+ }
11
+ /** Result retaining a committed operation across lock-finalization failure. */
12
+ export interface CodexNativeAuthSourceLockExecution<T> {
13
+ /** Guarded operation result. */
14
+ readonly value: T;
15
+ /** Whether the source lock released without compromise or cleanup failure. */
16
+ readonly coordination: 'released' | 'uncertain';
17
+ }
18
+ /** Canonical CODEX_HOME identity used by both file and keyring stores. */
19
+ export interface CodexAuthHomeIdentity {
20
+ /** Canonical absolute CODEX_HOME path. */
21
+ readonly canonicalPath: string;
22
+ /** Codex keyring account derived from {@link canonicalPath}. */
23
+ readonly keyringAccount: string;
24
+ }
25
+ /** Result of inspecting a lease target without following an unsafe final symlink. */
26
+ export type CodexLeaseTargetInspection = {
27
+ readonly status: 'safe';
28
+ readonly identity: CodexAuthHomeIdentity;
29
+ } | {
30
+ readonly status: 'missing' | 'unsafe';
31
+ readonly fallbackIdentity: CodexAuthHomeIdentity;
32
+ };
33
+ /**
34
+ * Build Codex 0.130's keyring account for a CODEX_HOME.
35
+ * @param codexHome - CODEX_HOME path; canonicalized when it exists.
36
+ * @returns `cli|` followed by the first 16 hex characters of the path digest.
37
+ */
38
+ export declare function buildCodexAuthKeyringAccount(codexHome: string): Promise<string>;
39
+ /**
40
+ * Resolve the canonical identity shared by Codex file and keyring auth stores.
41
+ * @param codexHome - CODEX_HOME path.
42
+ * @returns Canonical path plus Codex's derived keyring account.
43
+ */
44
+ export declare function identifyCodexAuthHome(codexHome: string): Promise<CodexAuthHomeIdentity>;
45
+ /**
46
+ * Derive a cleanup-only identity from the normalized input path.
47
+ *
48
+ * This deliberately performs no `realpath` lookup. A lease directory may have
49
+ * disappeared or been replaced by a symlink before restart cleanup; following
50
+ * that new target could delete an unrelated canonical keyring credential.
51
+ * @param codexHome - Original lease CODEX_HOME path.
52
+ * @returns Lexically normalized identity safe for conservative keyring cleanup.
53
+ */
54
+ export declare function identifyCodexAuthHomeLexically(codexHome: string): CodexAuthHomeIdentity;
55
+ /**
56
+ * Inspect a lease target while rejecting a symlink or non-directory final path.
57
+ * @param codexHome - Isolated lease CODEX_HOME path.
58
+ * @returns Stable canonical identity, or a cleanup-only lexical fallback.
59
+ */
60
+ export declare function inspectCodexLeaseTarget(codexHome: string): Promise<CodexLeaseTargetInspection>;
61
+ /**
62
+ * Serialize one canonical Codex native-auth mutation by CODEX_HOME.
63
+ *
64
+ * Account integrations and session-lease compare-and-swap operations must use
65
+ * this same lock so a lease cannot overwrite a concurrently selected account.
66
+ * @param codexHome - Canonical Codex config home whose auth source is mutated.
67
+ * @param operation - Source operation that must retain exclusive ownership.
68
+ * @returns Operation result after the source lock is released.
69
+ */
70
+ export declare function withCodexNativeAuthSourceLock<T>(codexHome: string, operation: () => Promise<T>): Promise<T>;
71
+ /**
72
+ * Execute against one CODEX_HOME while preserving committed operation results
73
+ * when lock finalization becomes uncertain.
74
+ * @param codexHome - Canonical Codex config home.
75
+ * @param operation - Native-auth operation guarded by the source lock.
76
+ * @returns Operation value plus released/uncertain coordination state.
77
+ */
78
+ export declare function executeCodexNativeAuthSourceLock<T>(codexHome: string, operation: () => Promise<T>): Promise<CodexNativeAuthSourceLockExecution<T>>;
79
+ /**
80
+ * Serialize one operation against an already-pinned Codex auth identity.
81
+ * @param identity - Canonical source CODEX_HOME identity.
82
+ * @param operation - Source operation that must retain exclusive ownership.
83
+ * @returns Operation result after the source lock is released.
84
+ */
85
+ export declare function withIdentifiedCodexNativeAuthSourceLock<T>(identity: CodexAuthHomeIdentity, operation: () => Promise<T>): Promise<T>;
86
+ /**
87
+ * Execute against an already-pinned identity and retain post-commit lock state.
88
+ * @param identity - Canonical source CODEX_HOME identity.
89
+ * @param operation - Native-auth operation guarded by the source lock.
90
+ * @returns Operation value plus released/uncertain coordination state.
91
+ */
92
+ export declare function executeIdentifiedCodexNativeAuthSourceLock<T>(identity: CodexAuthHomeIdentity, operation: () => Promise<T>): Promise<CodexNativeAuthSourceLockExecution<T>>;
93
+ /**
94
+ * Build a sibling lock anchor that survives CODEX_HOME rename/replacement.
95
+ * @param canonicalPath - Canonical CODEX_HOME path.
96
+ * @returns Secret-free sibling lock directory path.
97
+ */
98
+ export declare function buildCodexNativeAuthSourceLockPath(canonicalPath: string): string;
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Codex native authentication storage primitives.
3
+ *
4
+ * Mirrors Codex App Server 0.130's `file`, `keyring`, and `auto` credential
5
+ * store semantics without interpreting credential payloads. Credential values
6
+ * remain inside this client-owned runtime boundary; the only persisted lease
7
+ * state contains store identities and SHA-256 digests.
8
+ * @packageDocumentation
9
+ */
10
+ import { z } from 'zod';
11
+ import { type CodexKeyringCredentialStore } from './native-keyring-credential-store.js';
12
+ import { type CodexAuthHomeIdentity } from './native-auth-source-lock.js';
13
+ export { CODEX_AUTH_CAS_LOCK_FILE, buildCodexAuthKeyringAccount, buildCodexNativeAuthSourceLockPath, executeCodexNativeAuthSourceLock, identifyCodexAuthHome, identifyCodexAuthHomeLexically, inspectCodexLeaseTarget, withCodexNativeAuthSourceLock, } from './native-auth-source-lock.js';
14
+ export type { CodexAuthHomeIdentity, CodexLeaseTargetInspection } from './native-auth-source-lock.js';
15
+ /** Codex 0.130's native CLI credential store configuration values. */
16
+ export type CodexAuthStoreMode = 'file' | 'keyring' | 'auto';
17
+ /** Concrete store that contained a credential at one point in the lease. */
18
+ export type CodexAuthStoreBackend = 'file' | 'keyring';
19
+ /** Codex's fixed keyring service name for CLI authentication. */
20
+ export declare const CODEX_AUTH_KEYRING_SERVICE = "Codex Auth";
21
+ /** Non-secret lease metadata file stored inside the isolated CODEX_HOME. */
22
+ export declare const CODEX_AUTH_LEASE_METADATA_FILE = ".makaio-codex-auth-lease.json";
23
+ /** Result of resolving Codex's effective credential store. */
24
+ export interface CodexEffectiveCredentialRead {
25
+ /** Credential and concrete backend, or `null` when no native auth exists. */
26
+ readonly credential: {
27
+ readonly backend: CodexAuthStoreBackend;
28
+ readonly value: string;
29
+ } | null;
30
+ /** Whether an `auto` read fell back because the keyring was unavailable. */
31
+ readonly keyringUnavailable: boolean;
32
+ }
33
+ /** Strict schema for the secret-free native auth lease generation. */
34
+ export declare const CodexAuthLeaseMetadataSchema: z.ZodObject<{
35
+ version: z.ZodLiteral<1>;
36
+ backend: z.ZodObject<{
37
+ configured: z.ZodEnum<{
38
+ auto: "auto";
39
+ file: "file";
40
+ keyring: "keyring";
41
+ none: "none";
42
+ }>;
43
+ effective: z.ZodEnum<{
44
+ file: "file";
45
+ keyring: "keyring";
46
+ none: "none";
47
+ }>;
48
+ }, z.core.$strict>;
49
+ canonicalIdentity: z.ZodNullable<z.ZodObject<{
50
+ canonicalPath: z.ZodString;
51
+ keyringAccount: z.ZodString;
52
+ }, z.core.$strict>>;
53
+ targetIdentity: z.ZodObject<{
54
+ canonicalPath: z.ZodString;
55
+ keyringAccount: z.ZodString;
56
+ }, z.core.$strict>;
57
+ sourceGenerationDigest: z.ZodNullable<z.ZodString>;
58
+ initialTargetDigest: z.ZodNullable<z.ZodString>;
59
+ }, z.core.$strict>;
60
+ /** Secret-free native auth lease state. */
61
+ export type CodexAuthLeaseMetadata = z.infer<typeof CodexAuthLeaseMetadataSchema>;
62
+ /** Parsed metadata outcome used to distinguish safe absence from corruption. */
63
+ export type CodexAuthLeaseMetadataRead = {
64
+ readonly status: 'found';
65
+ readonly metadata: CodexAuthLeaseMetadata;
66
+ } | {
67
+ readonly status: 'missing';
68
+ } | {
69
+ readonly status: 'invalid';
70
+ };
71
+ /**
72
+ * Compute a stable SHA-256 digest without interpreting the credential value.
73
+ * @param value - Opaque credential payload.
74
+ * @returns Lowercase hexadecimal SHA-256 digest.
75
+ */
76
+ export declare function digestCodexCredential(value: string): string;
77
+ /**
78
+ * Local native auth store used by the session config handler.
79
+ */
80
+ export declare class CodexNativeAuthStore {
81
+ private readonly keyring;
82
+ /**
83
+ * @param keyring - Cross-platform keyring implementation.
84
+ */
85
+ constructor(keyring?: CodexKeyringCredentialStore);
86
+ /**
87
+ * Resolve `cli_auth_credentials_store` from the canonical config.
88
+ * Codex 0.130 defaults this setting to `file`.
89
+ * @param identity - Canonical CODEX_HOME identity.
90
+ * @returns Configured credential store mode.
91
+ */
92
+ resolveMode(identity: CodexAuthHomeIdentity): Promise<CodexAuthStoreMode>;
93
+ /**
94
+ * Load a credential using Codex 0.130's configured store order.
95
+ * @param identity - Canonical CODEX_HOME identity.
96
+ * @param mode - Configured store mode.
97
+ * @returns Effective credential plus keyring-fallback status.
98
+ */
99
+ readEffective(identity: CodexAuthHomeIdentity, mode: CodexAuthStoreMode): Promise<CodexEffectiveCredentialRead>;
100
+ /**
101
+ * Read the credential generation that should be considered for lease refresh.
102
+ *
103
+ * `auto` normally prefers keyring. During a running process, however, a
104
+ * transient keyring save failure can put a fresher generation in `auth.json`
105
+ * while the unchanged keyring entry remains. Detect that exact fallback by
106
+ * comparing both stores to the lease's initial generation.
107
+ * @param identity - Isolated target CODEX_HOME identity.
108
+ * @param mode - Configured store mode.
109
+ * @param initialDigest - Digest materialized when the lease was created.
110
+ * @returns Refresh candidate plus keyring availability status.
111
+ */
112
+ readRefreshCandidate(identity: CodexAuthHomeIdentity, mode: CodexAuthStoreMode, initialDigest: string): Promise<CodexEffectiveCredentialRead>;
113
+ /**
114
+ * Read one concrete backend without fallback.
115
+ * @param identity - Canonical CODEX_HOME identity.
116
+ * @param backend - Concrete store to read.
117
+ * @returns Credential value, or `null` when absent.
118
+ */
119
+ readBackend(identity: CodexAuthHomeIdentity, backend: CodexAuthStoreBackend): Promise<string | null>;
120
+ /**
121
+ * Clone an opaque value into one concrete target backend.
122
+ * @param identity - Target CODEX_HOME identity.
123
+ * @param backend - Concrete target store.
124
+ * @param value - Opaque credential payload.
125
+ */
126
+ writeBackend(identity: CodexAuthHomeIdentity, backend: CodexAuthStoreBackend, value: string): Promise<void>;
127
+ /**
128
+ * Persist a refreshed credential using Codex 0.130's save semantics.
129
+ * @param identity - Canonical CODEX_HOME identity.
130
+ * @param mode - Configured store mode.
131
+ * @param value - Refreshed opaque credential payload.
132
+ */
133
+ saveConfigured(identity: CodexAuthHomeIdentity, mode: CodexAuthStoreMode, value: string): Promise<void>;
134
+ /**
135
+ * Run a generation check and conditional write under one cross-process lock.
136
+ * @param identity - Canonical source CODEX_HOME identity.
137
+ * @param operation - CAS operation to execute while the lock is held.
138
+ * @returns Operation result.
139
+ */
140
+ withSourceLock<T>(identity: CodexAuthHomeIdentity, operation: () => Promise<T>): Promise<T>;
141
+ /**
142
+ * Remove a target keyring credential.
143
+ * @param identity - Target CODEX_HOME identity.
144
+ */
145
+ deleteKeyring(identity: CodexAuthHomeIdentity): Promise<void>;
146
+ /**
147
+ * Remove the file credential from a target CODEX_HOME.
148
+ * @param identity - Target CODEX_HOME identity.
149
+ */
150
+ deleteFile(identity: CodexAuthHomeIdentity): Promise<void>;
151
+ /**
152
+ * Atomically persist strict secret-free lease metadata with mode `0600`.
153
+ * @param sessionDir - Isolated CODEX_HOME.
154
+ * @param metadata - Validated metadata generation.
155
+ */
156
+ writeLeaseMetadata(sessionDir: string, metadata: CodexAuthLeaseMetadata): Promise<void>;
157
+ /**
158
+ * Read and strictly parse secret-free lease metadata.
159
+ * @param sessionDir - Isolated CODEX_HOME.
160
+ * @returns Found, missing, or invalid outcome without echoing file contents.
161
+ */
162
+ readLeaseMetadata(sessionDir: string): Promise<CodexAuthLeaseMetadataRead>;
163
+ private readFileCredential;
164
+ private readKeyringCredential;
165
+ private writeKeyring;
166
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Lazy native-keyring bridge for Codex authentication storage.
3
+ * @packageDocumentation
4
+ */
5
+ /** Keyring operations used by the Codex native auth store. */
6
+ export interface CodexKeyringCredentialStore {
7
+ /**
8
+ * Read one credential.
9
+ * @param service - Keyring service name.
10
+ * @param account - Keyring account name.
11
+ * @returns Stored value, or `null` when absent.
12
+ */
13
+ read(service: string, account: string): Promise<string | null>;
14
+ /**
15
+ * Write one credential.
16
+ * @param service - Keyring service name.
17
+ * @param account - Keyring account name.
18
+ * @param value - Opaque credential payload.
19
+ */
20
+ write(service: string, account: string, value: string): Promise<void>;
21
+ /**
22
+ * Delete one credential, treating absence as success.
23
+ * @param service - Keyring service name.
24
+ * @param account - Keyring account name.
25
+ */
26
+ delete(service: string, account: string): Promise<void>;
27
+ }
28
+ /** Native cross-platform keyring implementation matching Codex's keyring-rs store. */
29
+ export declare const nativeKeyringCredentialStore: CodexKeyringCredentialStore;
@@ -11,6 +11,8 @@ export { CodexClientSubjects, CODEX_CLIENT_NAMESPACE } from './namespace.js';
11
11
  export { CodexClientSessionService } from './codex-client-session-service.js';
12
12
  export { normalizeCodexHook } from './hook-normalizer.js';
13
13
  export type { CodexNormalizedEvent, CodexNormalizedSubject } from './hook-normalizer.js';
14
+ export { buildCodexNativeAuthSourceLockPath, executeCodexNativeAuthSourceLock, withCodexNativeAuthSourceLock, } from './native-auth-source-lock.js';
15
+ export type { CodexNativeAuthSourceLockExecution } from './native-auth-source-lock.js';
14
16
  /**
15
17
  * MakaioExtension manifest for the Codex client session normalization service.
16
18
  *
@@ -1,4 +1,4 @@
1
- import { i as normalizeCodexHook, n as CODEX_CLIENT_NAMESPACE, r as CodexClientSubjects, t as CodexClientSessionService } from "../codex-client-session-service-C2F6rQDS.mjs";
1
+ import { a as CODEX_CLIENT_NAMESPACE, i as withCodexNativeAuthSourceLock, n as buildCodexNativeAuthSourceLockPath, o as CodexClientSubjects, r as executeCodexNativeAuthSourceLock, s as normalizeCodexHook, t as CodexClientSessionService } from "../codex-client-session-service-ddd3K0rw.mjs";
2
2
  import { dep } from "@makaio/framework/contracts";
3
3
 
4
4
  //#region src/runtime/package.ts
@@ -26,8 +26,8 @@ const codexClientRuntimePackage = {
26
26
  * @param ctx - Runtime package context
27
27
  * @returns Uninitialized Codex client session service
28
28
  */
29
- create: (ctx) => new CodexClientSessionService(ctx.bus)
29
+ create: (ctx) => new CodexClientSessionService(ctx.bus, void 0, ctx.machineId)
30
30
  };
31
31
 
32
32
  //#endregion
33
- export { CODEX_CLIENT_NAMESPACE, CodexClientSessionService, CodexClientSubjects, codexClientRuntimePackage, normalizeCodexHook };
33
+ export { CODEX_CLIENT_NAMESPACE, CodexClientSessionService, CodexClientSubjects, buildCodexNativeAuthSourceLockPath, codexClientRuntimePackage, executeCodexNativeAuthSourceLock, normalizeCodexHook, withCodexNativeAuthSourceLock };
@@ -1,39 +1,51 @@
1
1
  /**
2
- * Codex session config setup handler.
2
+ * Codex session config lease handler.
3
3
  *
4
- * Implements the `client:codex.sessionConfig.setup` delegation request by
5
- * materializing the Codex config files needed for an isolated session
6
- * directory.
7
- *
8
- * The handler copies `config.toml` and `auth.json` from the base config
9
- * directory (when present) into the session-scoped directory, then primes the
10
- * session directory to ensure `check_for_update_on_startup = false` is set.
11
- *
12
- * When `sessionDir` and `baseConfigDir` resolve to the same path (the
13
- * framework passes `sessionDir` as `baseConfigDir` when no profile is
14
- * configured) the copy step is skipped and only the prime step runs.
15
- *
16
- * Returns `{ env: { CODEX_HOME: sessionDir } }` so the spawned Codex process
17
- * inherits the isolated session directory as its configuration root.
4
+ * Materializes file/keyring native auth into an isolated CODEX_HOME and
5
+ * reconciles refreshes on teardown with a generation-checked write-back.
6
+ * `empty` inheritance never reads or clones canonical native credentials.
18
7
  * @packageDocumentation
19
8
  */
20
- import type { SessionConfigSetupRequest, SessionConfigSetupResponse } from '@makaio/framework/contracts/client';
9
+ import type { SessionConfigSetupRequest, SessionConfigSetupResponse, SessionConfigTeardownRequest, SessionConfigTeardownResponse } from '@makaio/framework/contracts/client';
10
+ import { CodexNativeAuthStore } from './native-auth-store.js';
21
11
  /**
22
- * Handle `client:codex.sessionConfig.setup` by seeding the session-scoped
23
- * directory with the appropriate Codex config files.
24
- *
25
- * Steps:
26
- * 1. Create `sessionDir` (recursive, no-op when it already exists).
27
- * 2. When `sessionDir` and `baseConfigDir` are distinct paths, copy
28
- * `config.toml` and `auth.json` from `baseConfigDir` into `sessionDir`
29
- * (each copy is skipped when the source file does not exist).
30
- * 3. Prime `sessionDir` via {@link handleCodexConfigPrime} to ensure
31
- * `check_for_update_on_startup = false` is set.
32
- * @param payload - Session config setup delegation payload. Only `sessionDir`,
33
- * `baseConfigDir`, and `projectDir` are used; `platform` and
34
- * `configInheritance` are accepted for interface compatibility but are not
35
- * required for Codex's simpler config model.
36
- * @returns Environment variables for the spawned Codex process: `CODEX_HOME`
37
- * pointing to `sessionDir`.
12
+ * Codex-owned setup and teardown component for isolated config leases.
38
13
  */
39
- export declare function handleCodexSessionConfigSetup(payload: SessionConfigSetupRequest): Promise<SessionConfigSetupResponse>;
14
+ export declare class CodexSessionConfigHandler {
15
+ private readonly authStore;
16
+ private readonly nativeConfigDir;
17
+ /** Runtime copy of metadata used when a lease directory disappeared early. */
18
+ private readonly activeMetadata;
19
+ /**
20
+ * @param authStore - Native file/keyring storage implementation.
21
+ * @param nativeConfigDir - Native CODEX_HOME used when no profile source exists.
22
+ */
23
+ constructor(authStore?: CodexNativeAuthStore, nativeConfigDir?: string);
24
+ /**
25
+ * Seed an isolated CODEX_HOME according to the requested inheritance policy.
26
+ * @param payload - Validated setup delegation payload.
27
+ * @returns Process environment and truthful native-auth materialization status.
28
+ */
29
+ setup(payload: SessionConfigSetupRequest): Promise<SessionConfigSetupResponse>;
30
+ /**
31
+ * Compare-and-swap refreshed native auth back to its canonical store, then
32
+ * remove the session-specific keyring entry.
33
+ * @param payload - Validated teardown delegation payload.
34
+ * @returns Successful client-owned teardown result.
35
+ */
36
+ teardown(payload: SessionConfigTeardownRequest): Promise<SessionConfigTeardownResponse>;
37
+ private inspectLeaseForTeardown;
38
+ private reconcileInspectedLease;
39
+ /**
40
+ * Resolve profile source or the native CODEX_HOME fallback.
41
+ * @param payload - Setup payload carrying source and target paths.
42
+ * @returns Canonical source candidate selected for this lease.
43
+ */
44
+ private resolveSourceConfigDir;
45
+ private materializeGeneralConfig;
46
+ private materializeNativeAuthLocked;
47
+ private recordMetadata;
48
+ private rollbackFailedSetup;
49
+ private collectTargetCleanupErrors;
50
+ private reconcileRefresh;
51
+ }
package/dist/server.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as codexPackage } from "./src-CUFX-QsP.mjs";
1
+ import { t as codexPackage } from "./src-B_UWVcLO.mjs";
2
2
  import { codexClientRuntimePackage } from "./runtime/package.mjs";
3
3
 
4
4
  //#region src/server.ts
@@ -1,4 +1,4 @@
1
- import { b as clientDefinition } from "./codex-client-session-service-C2F6rQDS.mjs";
1
+ import { C as clientDefinition } from "./codex-client-session-service-ddd3K0rw.mjs";
2
2
 
3
3
  //#region src/package.ts
4
4
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makaio/client-codex",
3
- "version": "1.0.0-dev-1781368534585",
3
+ "version": "1.0.0-dev-1783940945655",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "exports": {
@@ -25,15 +25,19 @@
25
25
  "@makaio/framework": ">=1.0.0-0 <2.0.0"
26
26
  },
27
27
  "dependencies": {
28
- "zod": "^4.1.13"
28
+ "@napi-rs/keyring": "^1.2.0",
29
+ "proper-lockfile": "^4.1.2",
30
+ "smol-toml": "^1.3.0",
31
+ "zod": "4.4.3"
29
32
  },
30
33
  "devDependencies": {
31
34
  "@makaio/build-tooling": "1.0.0",
32
35
  "@makaio/bus-core": "1.0.0",
33
- "@makaio/contracts": "1.0.0-dev-1781368534585",
36
+ "@makaio/contracts": "1.0.0",
34
37
  "@makaio/core": "1.0.0",
35
38
  "@makaio/service-base": "1.0.0",
36
39
  "@makaio/subsystem-client": "1.0.0",
40
+ "@types/proper-lockfile": "^4.1.4",
37
41
  "tsdown": "0.22.0",
38
42
  "typescript": "^6.0.3"
39
43
  },