@makaio/client-codex 1.0.0-dev-1779051654000
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +103 -0
- package/descriptor.json +21 -0
- package/dist/codex-client-session-service-DD2LkxP1.mjs +1551 -0
- package/dist/definition.d.ts +90 -0
- package/dist/definition.d.ts.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +4 -0
- package/dist/package.d.ts +18 -0
- package/dist/package.d.ts.map +1 -0
- package/dist/runtime/client-settings.d.ts +149 -0
- package/dist/runtime/client-settings.d.ts.map +1 -0
- package/dist/runtime/codex-client-session-service.d.ts +148 -0
- package/dist/runtime/codex-client-session-service.d.ts.map +1 -0
- package/dist/runtime/config-prime-handler.d.ts +37 -0
- package/dist/runtime/config-prime-handler.d.ts.map +1 -0
- package/dist/runtime/hook-normalizer.d.ts +79 -0
- package/dist/runtime/hook-normalizer.d.ts.map +1 -0
- package/dist/runtime/namespace.d.ts +193 -0
- package/dist/runtime/namespace.d.ts.map +1 -0
- package/dist/runtime/package.d.ts +22 -0
- package/dist/runtime/package.d.ts.map +1 -0
- package/dist/runtime/package.mjs +33 -0
- package/dist/runtime/schemas.d.ts +26 -0
- package/dist/runtime/schemas.d.ts.map +1 -0
- package/dist/runtime/session-config-handler.d.ts +40 -0
- package/dist/runtime/session-config-handler.d.ts.map +1 -0
- package/dist/runtime/settings-paths.d.ts +43 -0
- package/dist/runtime/settings-paths.d.ts.map +1 -0
- package/dist/runtime/wiring.d.ts +88 -0
- package/dist/runtime/wiring.d.ts.map +1 -0
- package/dist/schemas/config.d.ts +306 -0
- package/dist/schemas/config.d.ts.map +1 -0
- package/dist/schemas/index.d.ts +9 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/wiring.d.ts +108 -0
- package/dist/schemas/wiring.d.ts.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.mjs +8 -0
- package/dist/src-DkIyzWF3.mjs +19 -0
- package/package.json +49 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client definition for the OpenAI Codex CLI.
|
|
3
|
+
*
|
|
4
|
+
* Codex is a first-party agentic coding assistant binary (`codex`) that
|
|
5
|
+
* Makaio harnesses via the codex-app-server adapter. Capability annotations
|
|
6
|
+
* are derived from `codexCapabilityMap` in `@makaio/contracts` to keep
|
|
7
|
+
* capability taxonomy in a single canonical location.
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Static client definition for `@makaio/client-codex`.
|
|
12
|
+
*
|
|
13
|
+
* Declares the two native tools the `codex` binary exposes (`bash` and
|
|
14
|
+
* `patch`) and the recommended default approval policy for new harnesses
|
|
15
|
+
* targeting this client.
|
|
16
|
+
*/
|
|
17
|
+
export declare const clientDefinition: {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
version: string;
|
|
21
|
+
description?: string | undefined;
|
|
22
|
+
binary?: {
|
|
23
|
+
name: string;
|
|
24
|
+
supportedVersions: string;
|
|
25
|
+
} | undefined;
|
|
26
|
+
nativeTools: {
|
|
27
|
+
name: string;
|
|
28
|
+
friendlyName: string;
|
|
29
|
+
description?: string | undefined;
|
|
30
|
+
category?: string | undefined;
|
|
31
|
+
capabilities: {
|
|
32
|
+
tag: string;
|
|
33
|
+
description?: string | undefined;
|
|
34
|
+
}[];
|
|
35
|
+
}[];
|
|
36
|
+
defaultApprovalPolicy: "always-ask" | "full-access" | "reject";
|
|
37
|
+
logSources?: {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
description?: string | undefined;
|
|
41
|
+
glob?: string | undefined;
|
|
42
|
+
}[] | undefined;
|
|
43
|
+
defaultProviderId?: string | undefined;
|
|
44
|
+
runtimeCapabilities: {
|
|
45
|
+
supportsHooks: boolean;
|
|
46
|
+
supportsStatusline: boolean;
|
|
47
|
+
supportsSupervisorLaunch: boolean;
|
|
48
|
+
supportsManagedBinary: boolean;
|
|
49
|
+
hookEvents: {
|
|
50
|
+
name: string;
|
|
51
|
+
frameworkSubject?: string | undefined;
|
|
52
|
+
}[];
|
|
53
|
+
};
|
|
54
|
+
managedInstall?: {
|
|
55
|
+
type: "npm";
|
|
56
|
+
package: string;
|
|
57
|
+
version: string;
|
|
58
|
+
} | {
|
|
59
|
+
type: "signed-binary-bucket";
|
|
60
|
+
version: string;
|
|
61
|
+
config: {
|
|
62
|
+
baseUrl: string;
|
|
63
|
+
manifestPathTemplate: string;
|
|
64
|
+
manifestSignaturePathTemplate: string;
|
|
65
|
+
publicKeyUrl: string;
|
|
66
|
+
publicKeyFingerprint: string;
|
|
67
|
+
binaryPathTemplate: string;
|
|
68
|
+
platforms: Record<string, string>;
|
|
69
|
+
};
|
|
70
|
+
} | undefined;
|
|
71
|
+
versionCommand?: {
|
|
72
|
+
executable: string | {
|
|
73
|
+
default: string;
|
|
74
|
+
darwin?: string | undefined;
|
|
75
|
+
linux?: string | undefined;
|
|
76
|
+
win32?: string | undefined;
|
|
77
|
+
};
|
|
78
|
+
args: string[];
|
|
79
|
+
} | undefined;
|
|
80
|
+
postInstall?: {
|
|
81
|
+
kind: string;
|
|
82
|
+
payload?: Record<string, unknown> | undefined;
|
|
83
|
+
} | undefined;
|
|
84
|
+
configIsolation?: {
|
|
85
|
+
envVar: string;
|
|
86
|
+
defaultPath: string;
|
|
87
|
+
pathKind: "directory" | "file";
|
|
88
|
+
} | undefined;
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=definition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../src/definition.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwD3B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { clientDefinition } from './definition.js';
|
|
2
|
+
/** Codex client package descriptor for unified package discovery. */
|
|
3
|
+
export { codexPackage } from './package.js';
|
|
4
|
+
export { AbsolutePathSchema, CodexConfigHooksAddRequestSchema, CodexConfigHooksAddResponseSchema, CodexConfigHooksListRequestSchema, CodexConfigHooksListResponseSchema, CodexConfigHooksRemoveRequestSchema, CodexConfigHooksRemoveResponseSchema, CodexConfigSchemas, CodexHookEntrySchema, CodexNativeCommandHookSchema, CodexNativeHookMatcherGroupSchema, CodexNativeHooksFileSchema, CodexScopeHookRecordSchema, CodexScopeSchema, CodexWiringSchemas, } from './schemas/index.js';
|
|
5
|
+
export type { CodexConfigHooksAddRequest, CodexConfigHooksAddResponse, CodexConfigHooksListRequest, CodexConfigHooksListResponse, CodexConfigHooksRemoveRequest, CodexConfigHooksRemoveResponse, CodexHookEntry, CodexNativeCommandHook, CodexNativeHookMatcherGroup, CodexNativeHooksFile, CodexScope, CodexScopeHookRecord, CodexWiringApplyRequest, CodexWiringListRequest, CodexWiringRemoveRequest, } from './schemas/index.js';
|
|
6
|
+
export { CodexClientSessionService } from './runtime/codex-client-session-service.js';
|
|
7
|
+
export { CodexClientSubjects } from './runtime/namespace.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EACL,kBAAkB,EAClB,gCAAgC,EAChC,iCAAiC,EACjC,iCAAiC,EACjC,kCAAkC,EAClC,mCAAmC,EACnC,oCAAoC,EACpC,kBAAkB,EAClB,oBAAoB,EACpB,4BAA4B,EAC5B,iCAAiC,EACjC,0BAA0B,EAC1B,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,0BAA0B,EAC1B,2BAA2B,EAC3B,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,EAC7B,8BAA8B,EAC9B,cAAc,EACd,sBAAsB,EACtB,2BAA2B,EAC3B,oBAAoB,EACpB,UAAU,EACV,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +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-DD2LkxP1.mjs";
|
|
2
|
+
import { t as codexPackage } from "./src-DkIyzWF3.mjs";
|
|
3
|
+
|
|
4
|
+
export { AbsolutePathSchema, CodexClientSessionService, CodexClientSubjects, CodexConfigHooksAddRequestSchema, CodexConfigHooksAddResponseSchema, CodexConfigHooksListRequestSchema, CodexConfigHooksListResponseSchema, CodexConfigHooksRemoveRequestSchema, CodexConfigHooksRemoveResponseSchema, CodexConfigSchemas, CodexHookEntrySchema, CodexNativeCommandHookSchema, CodexNativeHookMatcherGroupSchema, CodexNativeHooksFileSchema, CodexScopeHookRecordSchema, CodexScopeSchema, CodexWiringSchemas, clientDefinition, codexPackage };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IMakaioBus } from '@makaio/framework/bus';
|
|
2
|
+
/**
|
|
3
|
+
* MakaioNodeExtension<IMakaioBus> descriptor for the Codex client.
|
|
4
|
+
*
|
|
5
|
+
* Wraps the existing {@link clientDefinition} in the standard
|
|
6
|
+
* `MakaioNodeExtension<IMakaioBus>` shape so the runtime coordinator can discover and
|
|
7
|
+
* register this client through the unified client contribution surface.
|
|
8
|
+
*/
|
|
9
|
+
import type { MakaioNodeExtension } from '@makaio/framework/contracts';
|
|
10
|
+
/**
|
|
11
|
+
* Package descriptor for the Codex client.
|
|
12
|
+
*
|
|
13
|
+
* Declares the OpenAI Codex CLI binary (`codex`) as a first-party agentic
|
|
14
|
+
* coding assistant client with hook and supervisor-launch support and a
|
|
15
|
+
* default `full-access` approval policy.
|
|
16
|
+
*/
|
|
17
|
+
export declare const codexPackage: MakaioNodeExtension<IMakaioBus>;
|
|
18
|
+
//# sourceMappingURL=package.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../src/package.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG7D;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,mBAAmB,CAAC,UAAU,CAKxD,CAAC"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex client settings I/O.
|
|
3
|
+
*
|
|
4
|
+
* Provides filesystem read/write operations for Codex `hooks.json`
|
|
5
|
+
* configuration files. Handles both global and project-scoped config files
|
|
6
|
+
* with atomic writes and per-path write serialization to prevent concurrent
|
|
7
|
+
* modification.
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import type { CodexScope, CodexConfigHooksListResponse, CodexConfigHooksAddResponse, CodexConfigHooksRemoveResponse } from '../schemas/config.js';
|
|
11
|
+
/**
|
|
12
|
+
* Optional path override injected during testing.
|
|
13
|
+
* When provided, {@link CodexClientSettings} uses these paths instead of
|
|
14
|
+
* calling {@link resolveCodexSettingsPaths}.
|
|
15
|
+
*/
|
|
16
|
+
export interface CodexClientSettingsPathsOverride {
|
|
17
|
+
/**
|
|
18
|
+
* Absolute path to the global `hooks.json` file.
|
|
19
|
+
*/
|
|
20
|
+
readonly globalHooks: string;
|
|
21
|
+
/**
|
|
22
|
+
* Absolute path to the project-scoped `hooks.json` file, or `null`.
|
|
23
|
+
*/
|
|
24
|
+
readonly projectHooks: string | null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Path resolution options for {@link CodexClientSettings}.
|
|
28
|
+
*/
|
|
29
|
+
export interface CodexClientSettingsOptions {
|
|
30
|
+
/** Optional managed Codex config root used for global-scope hooks. */
|
|
31
|
+
readonly configDir?: string;
|
|
32
|
+
/** Optional exact path override used by tests. */
|
|
33
|
+
readonly pathsOverride?: CodexClientSettingsPathsOverride;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Handles reading and writing Codex `hooks.json` configuration files.
|
|
37
|
+
*
|
|
38
|
+
* This is a plain composed component — not a `BaseService` — intended to be
|
|
39
|
+
* instantiated inside `CodexClientSessionService` or a similar host.
|
|
40
|
+
*
|
|
41
|
+
* ## Atomic writes
|
|
42
|
+
* All writes go through a temp-file + `fs.rename()` sequence so that readers
|
|
43
|
+
* never see a partially written file.
|
|
44
|
+
*
|
|
45
|
+
* ## Write serialization
|
|
46
|
+
* A module-scoped per-path mutex ensures that concurrent callers modifying
|
|
47
|
+
* the same file are serialized rather than racing, even across instances.
|
|
48
|
+
*/
|
|
49
|
+
export declare class CodexClientSettings {
|
|
50
|
+
/**
|
|
51
|
+
* Optional path override used in tests. When `undefined`, paths are
|
|
52
|
+
* resolved dynamically via {@link resolveCodexSettingsPaths}.
|
|
53
|
+
*/
|
|
54
|
+
private readonly pathsOverride;
|
|
55
|
+
/** Optional managed Codex config root for global-scope hooks. */
|
|
56
|
+
private readonly configDir;
|
|
57
|
+
/**
|
|
58
|
+
* Creates a new `CodexClientSettings` instance.
|
|
59
|
+
* @param options - Optional path override or config-root options. Passing
|
|
60
|
+
* `{ globalHooks, projectHooks }` remains supported for existing tests.
|
|
61
|
+
*/
|
|
62
|
+
constructor(options?: CodexClientSettingsPathsOverride | CodexClientSettingsOptions);
|
|
63
|
+
/**
|
|
64
|
+
* List the effective hook configuration for a project directory.
|
|
65
|
+
*
|
|
66
|
+
* Reads both the global and (when available) project-scoped config files,
|
|
67
|
+
* concatenates their hooks into an effective list, and returns the per-scope
|
|
68
|
+
* breakdown alongside it.
|
|
69
|
+
* @param req - Request options. `projectDir` is the optional absolute path to
|
|
70
|
+
* the project root (when omitted only the global scope is read).
|
|
71
|
+
* `eventName` is an optional event name filter; when omitted all hooks are
|
|
72
|
+
* returned.
|
|
73
|
+
* @returns Effective merged hook list and per-scope breakdown.
|
|
74
|
+
*/
|
|
75
|
+
listHooks(req: {
|
|
76
|
+
projectDir?: string;
|
|
77
|
+
eventName?: string;
|
|
78
|
+
}): Promise<CodexConfigHooksListResponse>;
|
|
79
|
+
/**
|
|
80
|
+
* Add a new hook entry to the specified config scope.
|
|
81
|
+
*
|
|
82
|
+
* The operation is idempotent: if a hook with the same `event`, `command`,
|
|
83
|
+
* and `matcher` already exists in the target file, the file is left
|
|
84
|
+
* unchanged and `{ added: false }` is returned.
|
|
85
|
+
* @param req - Hook entry and targeting options. `scope` selects the config
|
|
86
|
+
* file; `projectDir` is required when `scope` is `'project'`. `event`,
|
|
87
|
+
* `command`, and optional `matcher` / `timeout` form the hook entry.
|
|
88
|
+
* @returns `{ added: true }` when the hook was appended, `{ added: false }`
|
|
89
|
+
* when an identical hook already exists.
|
|
90
|
+
*/
|
|
91
|
+
addHook(req: {
|
|
92
|
+
projectDir?: string;
|
|
93
|
+
scope: CodexScope;
|
|
94
|
+
event: string;
|
|
95
|
+
matcher?: string;
|
|
96
|
+
command: string;
|
|
97
|
+
timeout?: number;
|
|
98
|
+
}): Promise<CodexConfigHooksAddResponse>;
|
|
99
|
+
/**
|
|
100
|
+
* Remove hook entries from the specified config scope.
|
|
101
|
+
*
|
|
102
|
+
* Removes all hooks where `entry.event === req.event` and
|
|
103
|
+
* `entry.command.includes(req.match.commandContains)`.
|
|
104
|
+
* @param req - Removal criteria and targeting options. `scope` selects the
|
|
105
|
+
* config file; `projectDir` is required when `scope` is `'project'`.
|
|
106
|
+
* `event` is the event name to match. `match.commandContains` is the
|
|
107
|
+
* command substring filter — any hook whose command contains this string
|
|
108
|
+
* is removed.
|
|
109
|
+
* @returns `{ removed: n }` where `n` is the count of removed hooks.
|
|
110
|
+
*/
|
|
111
|
+
removeHook(req: {
|
|
112
|
+
projectDir?: string;
|
|
113
|
+
scope: CodexScope;
|
|
114
|
+
event: string;
|
|
115
|
+
match: {
|
|
116
|
+
commandContains: string;
|
|
117
|
+
};
|
|
118
|
+
}): Promise<CodexConfigHooksRemoveResponse>;
|
|
119
|
+
/**
|
|
120
|
+
* Resolve config file path for a given scope.
|
|
121
|
+
*
|
|
122
|
+
* For `'project'` scope, `projectDir` must be provided. For `'global'`
|
|
123
|
+
* scope, `projectDir` is ignored.
|
|
124
|
+
* @param scope - Target config scope.
|
|
125
|
+
* @param projectDir - Optional absolute path to the project root.
|
|
126
|
+
* @returns Absolute path to the `hooks.json` file for the given scope.
|
|
127
|
+
* @throws When `scope === 'project'` and `projectDir` is absent.
|
|
128
|
+
*/
|
|
129
|
+
private resolvePathForScope;
|
|
130
|
+
/**
|
|
131
|
+
* Resolve settings paths, applying the optional test override when present.
|
|
132
|
+
* @param projectDir - Optional project root passed through to
|
|
133
|
+
* {@link resolveCodexSettingsPaths} when no override is active.
|
|
134
|
+
* @returns Resolved settings paths.
|
|
135
|
+
*/
|
|
136
|
+
private resolvePaths;
|
|
137
|
+
private isWritable;
|
|
138
|
+
private readHooksFile;
|
|
139
|
+
private readHooksDocument;
|
|
140
|
+
/**
|
|
141
|
+
* Flatten a native Codex hooks document into the public command-hook view.
|
|
142
|
+
* @param document - Native Codex hooks document.
|
|
143
|
+
* @returns Flat command-hook entries ordered by event, matcher group, then
|
|
144
|
+
* handler order.
|
|
145
|
+
*/
|
|
146
|
+
private flattenHooksFile;
|
|
147
|
+
private modifyHooksFile;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=client-settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-settings.d.ts","sourceRoot":"","sources":["../../src/runtime/client-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAEV,UAAU,EAGV,4BAA4B,EAC5B,2BAA2B,EAC3B,8BAA8B,EAC/B,MAAM,sBAAsB,CAAC;AAiB9B;;;;GAIG;AACH,MAAM,WAAW,gCAAgC;IAC/C;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,sEAAsE;IACtE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,aAAa,CAAC,EAAE,gCAAgC,CAAC;CAC3D;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,mBAAmB;IAC9B;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA+C;IAC7E,iEAAiE;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAE/C;;;;OAIG;IACH,YAAmB,OAAO,CAAC,EAAE,gCAAgC,GAAG,0BAA0B,EAQzF;IAMD;;;;;;;;;;;OAWG;IACU,SAAS,CAAC,GAAG,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,4BAA4B,CAAC,CA+B9G;IAED;;;;;;;;;;;OAWG;IACU,OAAO,CAAC,GAAG,EAAE;QACxB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,UAAU,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAsDvC;IAED;;;;;;;;;;;OAWG;IACU,UAAU,CAAC,GAAG,EAAE;QAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,UAAU,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE;YAAE,eAAe,EAAE,MAAM,CAAA;SAAE,CAAC;KACpC,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAqC1C;IAMD;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;YAmBN,UAAU;YAmCV,aAAa;YAeb,iBAAiB;IAmB/B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;YAoCV,eAAe;CAsB9B"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex client session normalization service.
|
|
3
|
+
*
|
|
4
|
+
* Subscribes to raw Codex hook events on `client:codex.hook.received` and
|
|
5
|
+
* emits the corresponding normalized `client.session.*` observations via
|
|
6
|
+
* {@link normalizeCodexHook}.
|
|
7
|
+
*
|
|
8
|
+
* Also handles config management requests on `client:codex.config.hooks.*`
|
|
9
|
+
* subjects. Before constructing settings I/O, the service resolves the active
|
|
10
|
+
* config directory via `client.resolveBinary` and uses that as the global
|
|
11
|
+
* Codex config root, falling back to native `~/.codex` paths when no resolver
|
|
12
|
+
* or global binary is available. Wiring requests use the same settings path
|
|
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.
|
|
16
|
+
*
|
|
17
|
+
* Unknown or not-yet-modeled event names are silently dropped — they stay
|
|
18
|
+
* raw-only inside the `client:codex.*` namespace and are never forwarded to
|
|
19
|
+
* the global `client.*` namespace.
|
|
20
|
+
*
|
|
21
|
+
* ## Adapter-managed session gate
|
|
22
|
+
*
|
|
23
|
+
* When both the native-hook ingress and the adapter-derived path are active for
|
|
24
|
+
* the same Codex process, `client.session.started` would otherwise be emitted
|
|
25
|
+
* twice. The service listens to `client.runtime.started` events: when an event
|
|
26
|
+
* arrives with `clientId === CLIENT_ID`, `source.layer === 'adapter'`, and a
|
|
27
|
+
* non-empty `adapterSessionId`, that session ID is recorded as adapter-managed.
|
|
28
|
+
* Any subsequent normalized hook for the same `adapterSessionId` is then
|
|
29
|
+
* silently dropped — the adapter path already owns the canonical emission.
|
|
30
|
+
* Sessions whose `adapterSessionId` is absent or not yet registered emit as
|
|
31
|
+
* before (fail-open). Events from other clients (e.g. `'claude-code'`,
|
|
32
|
+
* `'gemini'`) are ignored unconditionally — their adapter sessions must not
|
|
33
|
+
* suppress Codex hook emissions.
|
|
34
|
+
*
|
|
35
|
+
* The managed-session set is bounded at {@link MANAGED_SESSION_CAP} entries to
|
|
36
|
+
* prevent unbounded growth in long-lived processes. When the cap is reached,
|
|
37
|
+
* the oldest recorded session ID is evicted before inserting the new one
|
|
38
|
+
* (FIFO).
|
|
39
|
+
* @packageDocumentation
|
|
40
|
+
*/
|
|
41
|
+
import type { IMakaioBus } from '@makaio/framework/bus';
|
|
42
|
+
import { BaseService } from '@makaio/framework/service-base';
|
|
43
|
+
import { CodexClientSettings } from './client-settings.js';
|
|
44
|
+
/**
|
|
45
|
+
* Maximum number of adapter-managed session IDs retained in
|
|
46
|
+
* {@link CodexClientSessionService.managedAdapterSessionIds}.
|
|
47
|
+
*
|
|
48
|
+
* Concurrent active Codex sessions are typically single-digit, so this
|
|
49
|
+
* cap is a safety net against unbounded growth in long-lived processes. When
|
|
50
|
+
* the cap is reached, the oldest recorded ID is evicted (FIFO) before the new
|
|
51
|
+
* one is inserted.
|
|
52
|
+
*/
|
|
53
|
+
export declare const MANAGED_SESSION_CAP = 10000;
|
|
54
|
+
/**
|
|
55
|
+
* Service that normalizes raw Codex hook events into global
|
|
56
|
+
* `client.session.*` observed-semantics events and handles Codex config
|
|
57
|
+
* management requests on `client:codex.config.hooks.*`.
|
|
58
|
+
*
|
|
59
|
+
* Lifecycle:
|
|
60
|
+
* 1. `init()` — subscribes to `client:codex.hook.received`, subscribes to
|
|
61
|
+
* `client.runtime.started` for the adapter-managed session gate, and
|
|
62
|
+
* registers request handlers for `config.hooks.list`, `config.hooks.add`,
|
|
63
|
+
* `config.hooks.remove`, `config.prime`, `wiring.list`, `wiring.apply`,
|
|
64
|
+
* `wiring.remove`, and `sessionConfig.setup`.
|
|
65
|
+
* 2. On each incoming raw event, calls {@link normalizeCodexHook}.
|
|
66
|
+
* 3. Emits the normalized subject when the event is recognized; silently
|
|
67
|
+
* ignores unknown events. Normalized `client.session.*` events are
|
|
68
|
+
* suppressed when the `adapterSessionId` is already in the adapter-managed
|
|
69
|
+
* set.
|
|
70
|
+
* 4. `destroy()` — unsubscribes all handlers automatically via `BaseService`.
|
|
71
|
+
*/
|
|
72
|
+
export declare class CodexClientSessionService extends BaseService {
|
|
73
|
+
/** Optional injected settings I/O delegate for tests. */
|
|
74
|
+
private readonly settingsOverride;
|
|
75
|
+
/** Cached active config-dir resolution; reset when the active Codex version changes. */
|
|
76
|
+
private cachedConfigDir;
|
|
77
|
+
/**
|
|
78
|
+
* Set of `adapterSessionId` values known to be owned by an adapter-managed
|
|
79
|
+
* Codex runtime. Populated by {@link handleRuntimeStarted} when a
|
|
80
|
+
* `client.runtime.started` event arrives with `clientId === CLIENT_ID` and
|
|
81
|
+
* `source.layer === 'adapter'`.
|
|
82
|
+
*
|
|
83
|
+
* Bounded at {@link MANAGED_SESSION_CAP} entries — the oldest ID is evicted
|
|
84
|
+
* (FIFO) when the cap is reached.
|
|
85
|
+
*
|
|
86
|
+
* Used by {@link handleHookReceived} to gate duplicate `client.session.*`
|
|
87
|
+
* emissions for sessions that the adapter path already covers.
|
|
88
|
+
*/
|
|
89
|
+
private readonly managedAdapterSessionIds;
|
|
90
|
+
/**
|
|
91
|
+
* Creates a new Codex client session service.
|
|
92
|
+
* @param bus - Bus instance used for subscribing and emitting events
|
|
93
|
+
* @param settings - Optional {@link CodexClientSettings} instance for tests
|
|
94
|
+
* that need exact filesystem paths. Production callers should omit it so
|
|
95
|
+
* the service can resolve the active managed config dir via the bus.
|
|
96
|
+
*/
|
|
97
|
+
constructor(bus?: IMakaioBus, settings?: CodexClientSettings);
|
|
98
|
+
/**
|
|
99
|
+
* Register the raw hook ingress handler, config management request handlers,
|
|
100
|
+
* wiring management request handlers, the config-prime lifecycle handler,
|
|
101
|
+
* and the session config setup handler on the bus.
|
|
102
|
+
*
|
|
103
|
+
* Also subscribes to `client.runtime.started` to track adapter-managed
|
|
104
|
+
* sessions for the {@link handleHookReceived} suppression gate.
|
|
105
|
+
*/
|
|
106
|
+
protected onInit(): void;
|
|
107
|
+
/**
|
|
108
|
+
* Clear the adapter-managed session ID set on teardown.
|
|
109
|
+
*/
|
|
110
|
+
protected onDestroy(): void;
|
|
111
|
+
private createSettings;
|
|
112
|
+
/**
|
|
113
|
+
* Return the cached config directory promise, resolving it on first access.
|
|
114
|
+
*
|
|
115
|
+
* Missing binary resolution is a graceful fallback so config reads/writes can
|
|
116
|
+
* still target native Codex config paths in framework-only or global-only
|
|
117
|
+
* setups.
|
|
118
|
+
* @returns Absolute managed config dir, or `undefined` to use native paths.
|
|
119
|
+
*/
|
|
120
|
+
private resolveConfigDir;
|
|
121
|
+
private doResolveConfigDir;
|
|
122
|
+
/**
|
|
123
|
+
* Record a runtime as adapter-managed when the evidence source is an adapter.
|
|
124
|
+
*
|
|
125
|
+
* Called for every `client.runtime.started` event. Only events whose
|
|
126
|
+
* `clientId` equals `'codex'`, whose `source.layer` is `'adapter'`, and
|
|
127
|
+
* that carry a non-empty `adapterSessionId` update the managed-sessions gate.
|
|
128
|
+
* Events from other clients (e.g. `'claude-code'`, `'gemini'`) are ignored
|
|
129
|
+
* unconditionally — their adapter sessions must not suppress Codex hook
|
|
130
|
+
* emissions. Non-adapter sources (e.g. `'supervisor'`, `'statusline'`) are
|
|
131
|
+
* also ignored to prevent accidental suppression of native hook paths.
|
|
132
|
+
*
|
|
133
|
+
* When the set reaches {@link MANAGED_SESSION_CAP}, the oldest entry is
|
|
134
|
+
* evicted before the new ID is inserted.
|
|
135
|
+
* @param payload - `client.runtime.started` payload
|
|
136
|
+
*/
|
|
137
|
+
private handleRuntimeStarted;
|
|
138
|
+
private handleHookReceived;
|
|
139
|
+
/**
|
|
140
|
+
* Determine whether a normalized native hook belongs to an adapter-managed
|
|
141
|
+
* session whose global observed-semantics events are already emitted by the
|
|
142
|
+
* adapter layer.
|
|
143
|
+
* @param adapterSessionId - Adapter/session identifier from the normalized hook
|
|
144
|
+
* @returns True when the native hook should remain raw-only
|
|
145
|
+
*/
|
|
146
|
+
private isAdapterManagedSession;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=codex-client-session-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-client-session-service.d.ts","sourceRoot":"","sources":["../../src/runtime/codex-client-session-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAU3D;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAE1C;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,yBAA0B,SAAQ,WAAW;IACxD,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkC;IACnE,wFAAwF;IACxF,OAAO,CAAC,eAAe,CAA0C;IAEjE;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAqB;IAE9D;;;;;;OAMG;IACH,YAAmB,GAAG,GAAE,UAAsB,EAAE,QAAQ,CAAC,EAAE,mBAAmB,EAG7E;IAED;;;;;;;OAOG;IACH,UAAmB,MAAM,IAAI,IAAI,CA+DhC;IAED;;OAEG;IACH,UAAmB,SAAS,IAAI,IAAI,CAGnC;YAMa,cAAc;IAQ5B;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;YA0BV,kBAAkB;IAgBhC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,oBAAoB;YA0Bd,kBAAkB;IAgChC;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;CAGhC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex config-prime handler.
|
|
3
|
+
*
|
|
4
|
+
* Handles the `client:codex.config.prime` delegation subject fired by the
|
|
5
|
+
* framework at three lifecycle phases: `managed-install`, `profile-create`,
|
|
6
|
+
* and `session-create`.
|
|
7
|
+
*
|
|
8
|
+
* The handler ensures that `check_for_update_on_startup = false` is present
|
|
9
|
+
* in the Codex `config.toml` file inside the target directory so that managed
|
|
10
|
+
* Codex processes never attempt to auto-update during a Makaio-controlled
|
|
11
|
+
* session. All other existing config keys are preserved; the key is replaced
|
|
12
|
+
* when it already exists with any value, and appended when absent.
|
|
13
|
+
*
|
|
14
|
+
* Writes are atomic (tmp-file + rename) to prevent readers from observing a
|
|
15
|
+
* partially written file. The operation is idempotent: when the file already
|
|
16
|
+
* contains the correct value the write is skipped entirely.
|
|
17
|
+
* @packageDocumentation
|
|
18
|
+
*/
|
|
19
|
+
import type { ClientConfigPrimeRequest, ClientConfigPrimeResponse } from '@makaio/framework/contracts/client';
|
|
20
|
+
/**
|
|
21
|
+
* Prime the Codex `config.toml` in the target config directory.
|
|
22
|
+
*
|
|
23
|
+
* Ensures that `check_for_update_on_startup = false` is set, preserving all
|
|
24
|
+
* other existing key-value pairs. Existing occurrences of the key (with any
|
|
25
|
+
* value) are replaced; the key is appended when absent. Empty lines are
|
|
26
|
+
* stripped to keep the file compact.
|
|
27
|
+
*
|
|
28
|
+
* The write is atomic via a temporary file + `fs.rename()` to prevent readers
|
|
29
|
+
* from observing a partially written file. The operation is idempotent: when
|
|
30
|
+
* the file already contains the correct value the disk is not touched.
|
|
31
|
+
* @param payload - Config prime request containing `clientId`, `configDir`,
|
|
32
|
+
* and `phase`. Additional optional fields (`binaryVersion`, `adapterName`,
|
|
33
|
+
* `projectDir`) are accepted but not used by the Codex prime handler.
|
|
34
|
+
* @returns `{ primed: true }` on success.
|
|
35
|
+
*/
|
|
36
|
+
export declare function handleCodexConfigPrime(payload: ClientConfigPrimeRequest): Promise<ClientConfigPrimeResponse>;
|
|
37
|
+
//# sourceMappingURL=config-prime-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-prime-handler.d.ts","sourceRoot":"","sources":["../../src/runtime/config-prime-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAMpG;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAmClH"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure normalizer for Codex CLI hook events.
|
|
3
|
+
*
|
|
4
|
+
* Maps the Codex-native hook event names emitted on
|
|
5
|
+
* `client:codex.hook.received` to their corresponding
|
|
6
|
+
* `client.session.*` observed-semantics subjects.
|
|
7
|
+
*
|
|
8
|
+
* **Mapping table** (Codex event → global subject):
|
|
9
|
+
*
|
|
10
|
+
* | Codex event name | Global subject |
|
|
11
|
+
* |--------------------------|------------------------------------------|
|
|
12
|
+
* | `SessionStart` | `client.session.started` |
|
|
13
|
+
* | `UserPromptSubmit` | `client.session.userPrompt.submitted` |
|
|
14
|
+
* | `Stop` | `client.session.turn.completed` |
|
|
15
|
+
* | `PreToolUse` | `client.session.tool.pre` |
|
|
16
|
+
* | `PostToolUse` | `client.session.tool.post` |
|
|
17
|
+
*
|
|
18
|
+
* All other event names are returned as `null` — they are kept raw only and
|
|
19
|
+
* are never emitted into the global `client.*` namespace.
|
|
20
|
+
*
|
|
21
|
+
* **Source notes:** The Codex CLI hook event names above reflect the OpenAI
|
|
22
|
+
* Codex CLI hook system as documented at the time of authoring. If the binary
|
|
23
|
+
* changes its hook names, update {@link CODEX_EVENT_MAP} accordingly.
|
|
24
|
+
* @packageDocumentation
|
|
25
|
+
*/
|
|
26
|
+
import { ClientSubjects } from '@makaio/framework/clients';
|
|
27
|
+
import type { ClientSessionStarted, ClientSessionUserPromptSubmitted, ClientSessionTurnCompleted, ClientSessionToolPre, ClientSessionToolPost } from '@makaio/framework/contracts/client';
|
|
28
|
+
import type { RawClientHookPayload } from './schemas.js';
|
|
29
|
+
/**
|
|
30
|
+
* Union of all normalized subject definitions the Codex normalizer can emit.
|
|
31
|
+
*
|
|
32
|
+
* Used as the return type of {@link normalizeCodexHook} to keep downstream
|
|
33
|
+
* consumers type-safe without wide `SubjectDefinition` casts.
|
|
34
|
+
*/
|
|
35
|
+
export type CodexNormalizedSubject = typeof ClientSubjects.session.started | typeof ClientSubjects.session.userPrompt.submitted | typeof ClientSubjects.session.turn.completed | typeof ClientSubjects.session.tool.pre | typeof ClientSubjects.session.tool.post;
|
|
36
|
+
/**
|
|
37
|
+
* Union of all normalized payload types the Codex normalizer can produce.
|
|
38
|
+
*
|
|
39
|
+
* Mirrors the `client.session.*` schema union so callers do not need to
|
|
40
|
+
* import individual payload types from `@makaio/contracts`.
|
|
41
|
+
*/
|
|
42
|
+
export type CodexNormalizedPayload = ClientSessionStarted | ClientSessionUserPromptSubmitted | ClientSessionTurnCompleted | ClientSessionToolPre | ClientSessionToolPost;
|
|
43
|
+
/**
|
|
44
|
+
* Discriminated union of normalized Codex hook event results.
|
|
45
|
+
*
|
|
46
|
+
* Each variant pairs a specific `client.session.*` subject with its
|
|
47
|
+
* corresponding strongly-typed payload. The caller switches on `subject`
|
|
48
|
+
* to obtain a narrowed payload type and call `bus.emit` without casts.
|
|
49
|
+
*
|
|
50
|
+
* When the event name is unknown, {@link normalizeCodexHook} returns `null`
|
|
51
|
+
* to signal that the event must stay raw-only.
|
|
52
|
+
*/
|
|
53
|
+
export type CodexNormalizedEvent = {
|
|
54
|
+
readonly subject: typeof ClientSubjects.session.started;
|
|
55
|
+
readonly payload: ClientSessionStarted;
|
|
56
|
+
} | {
|
|
57
|
+
readonly subject: typeof ClientSubjects.session.userPrompt.submitted;
|
|
58
|
+
readonly payload: ClientSessionUserPromptSubmitted;
|
|
59
|
+
} | {
|
|
60
|
+
readonly subject: typeof ClientSubjects.session.turn.completed;
|
|
61
|
+
readonly payload: ClientSessionTurnCompleted;
|
|
62
|
+
} | {
|
|
63
|
+
readonly subject: typeof ClientSubjects.session.tool.pre;
|
|
64
|
+
readonly payload: ClientSessionToolPre;
|
|
65
|
+
} | {
|
|
66
|
+
readonly subject: typeof ClientSubjects.session.tool.post;
|
|
67
|
+
readonly payload: ClientSessionToolPost;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Normalize a raw Codex hook payload into a `client.session.*` event.
|
|
71
|
+
*
|
|
72
|
+
* Returns `null` for unknown or not-yet-modeled event names so the caller
|
|
73
|
+
* skips global emission and keeps the event raw-only in `client:codex.*`.
|
|
74
|
+
* @param raw - Raw hook payload delivered on `client:codex.hook.received`
|
|
75
|
+
* @returns Normalized event with subject and typed payload, or `null` when
|
|
76
|
+
* the event name is unknown
|
|
77
|
+
*/
|
|
78
|
+
export declare function normalizeCodexHook(raw: RawClientHookPayload): CodexNormalizedEvent | null;
|
|
79
|
+
//# sourceMappingURL=hook-normalizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-normalizer.d.ts","sourceRoot":"","sources":["../../src/runtime/hook-normalizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,cAAc,EAAsB,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EACV,oBAAoB,EACpB,gCAAgC,EAChC,0BAA0B,EAC1B,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAC9B,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,GACrC,OAAO,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,GAClD,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,GAC5C,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,GACtC,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAC9B,oBAAoB,GACpB,gCAAgC,GAChC,0BAA0B,GAC1B,oBAAoB,GACpB,qBAAqB,CAAC;AAE1B;;;;;;;;;GASG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAA;CAAE,GACnG;IACE,QAAQ,CAAC,OAAO,EAAE,OAAO,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC;IACrE,QAAQ,CAAC,OAAO,EAAE,gCAAgC,CAAC;CACpD,GACD;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,0BAA0B,CAAA;CAAE,GAChH;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAA;CAAE,GACpG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAA;CAAE,CAAC;AAqE3G;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,oBAAoB,GAAG,oBAAoB,GAAG,IAAI,CAkDzF"}
|