@wibeco/bridge 0.1.0
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 +46 -0
- package/dist/chunk-5CBPZCBE.js +427 -0
- package/dist/chunk-BL74PDGC.js +591 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +71 -0
- package/dist/codex-hook.d.ts +1 -0
- package/dist/codex-hook.js +22 -0
- package/dist/index.d.ts +272 -0
- package/dist/index.js +48 -0
- package/package.json +42 -0
- package/templates/claude-code/README.md +14 -0
- package/templates/claude-code/mcp.json.example +8 -0
- package/templates/claude-code/settings.json.example +77 -0
- package/templates/codex/README.md +13 -0
- package/templates/codex/config.toml.example +6 -0
- package/templates/codex/hooks.json.example +76 -0
- package/templates/cursor/README.md +13 -0
- package/templates/cursor/hooks.json.example +60 -0
- package/templates/cursor/mcp.json.example +7 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const agentSourceSchema: z.ZodEnum<{
|
|
4
|
+
cursor: "cursor";
|
|
5
|
+
"claude-code": "claude-code";
|
|
6
|
+
codex: "codex";
|
|
7
|
+
}>;
|
|
8
|
+
type AgentSource = z.infer<typeof agentSourceSchema>;
|
|
9
|
+
declare const hookEventKindSchema: z.ZodEnum<{
|
|
10
|
+
"session.started": "session.started";
|
|
11
|
+
"session.ended": "session.ended";
|
|
12
|
+
"lifecycle.before": "lifecycle.before";
|
|
13
|
+
"lifecycle.after": "lifecycle.after";
|
|
14
|
+
"tool.started": "tool.started";
|
|
15
|
+
"tool.completed": "tool.completed";
|
|
16
|
+
"file.changed": "file.changed";
|
|
17
|
+
"shell.started": "shell.started";
|
|
18
|
+
"shell.completed": "shell.completed";
|
|
19
|
+
"mcp.started": "mcp.started";
|
|
20
|
+
"mcp.completed": "mcp.completed";
|
|
21
|
+
unknown: "unknown";
|
|
22
|
+
}>;
|
|
23
|
+
type HookEventKind = z.infer<typeof hookEventKindSchema>;
|
|
24
|
+
declare const safeScalarSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>;
|
|
25
|
+
type SafeValue = z.infer<typeof safeScalarSchema> | SafeValue[] | {
|
|
26
|
+
[key: string]: SafeValue;
|
|
27
|
+
};
|
|
28
|
+
declare const safeValueSchema: z.ZodType<SafeValue>;
|
|
29
|
+
declare const canonicalHookEventSchema: z.ZodObject<{
|
|
30
|
+
id: z.ZodString;
|
|
31
|
+
version: z.ZodLiteral<1>;
|
|
32
|
+
source: z.ZodEnum<{
|
|
33
|
+
cursor: "cursor";
|
|
34
|
+
"claude-code": "claude-code";
|
|
35
|
+
codex: "codex";
|
|
36
|
+
}>;
|
|
37
|
+
kind: z.ZodEnum<{
|
|
38
|
+
"session.started": "session.started";
|
|
39
|
+
"session.ended": "session.ended";
|
|
40
|
+
"lifecycle.before": "lifecycle.before";
|
|
41
|
+
"lifecycle.after": "lifecycle.after";
|
|
42
|
+
"tool.started": "tool.started";
|
|
43
|
+
"tool.completed": "tool.completed";
|
|
44
|
+
"file.changed": "file.changed";
|
|
45
|
+
"shell.started": "shell.started";
|
|
46
|
+
"shell.completed": "shell.completed";
|
|
47
|
+
"mcp.started": "mcp.started";
|
|
48
|
+
"mcp.completed": "mcp.completed";
|
|
49
|
+
unknown: "unknown";
|
|
50
|
+
}>;
|
|
51
|
+
occurredAt: z.ZodString;
|
|
52
|
+
sessionId: z.ZodOptional<z.ZodString>;
|
|
53
|
+
repo: z.ZodOptional<z.ZodObject<{
|
|
54
|
+
root: z.ZodString;
|
|
55
|
+
remote: z.ZodOptional<z.ZodString>;
|
|
56
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
57
|
+
commit: z.ZodOptional<z.ZodString>;
|
|
58
|
+
}, z.core.$strip>>;
|
|
59
|
+
outcome: z.ZodOptional<z.ZodEnum<{
|
|
60
|
+
unknown: "unknown";
|
|
61
|
+
success: "success";
|
|
62
|
+
failure: "failure";
|
|
63
|
+
cancelled: "cancelled";
|
|
64
|
+
}>>;
|
|
65
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
66
|
+
metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<SafeValue, unknown, z.core.$ZodTypeInternals<SafeValue, unknown>>>>;
|
|
67
|
+
}, z.core.$strip>;
|
|
68
|
+
type CanonicalHookEvent = z.infer<typeof canonicalHookEventSchema>;
|
|
69
|
+
declare function createHookEvent(input: Omit<CanonicalHookEvent, "id" | "version" | "occurredAt"> & Partial<Pick<CanonicalHookEvent, "id" | "occurredAt">>): CanonicalHookEvent;
|
|
70
|
+
|
|
71
|
+
declare function mapClaudeCodeHook(eventName: string, input: unknown): {
|
|
72
|
+
id: string;
|
|
73
|
+
version: 1;
|
|
74
|
+
source: "cursor" | "claude-code" | "codex";
|
|
75
|
+
kind: "session.started" | "session.ended" | "lifecycle.before" | "lifecycle.after" | "tool.started" | "tool.completed" | "file.changed" | "shell.started" | "shell.completed" | "mcp.started" | "mcp.completed" | "unknown";
|
|
76
|
+
occurredAt: string;
|
|
77
|
+
metadata: Record<string, SafeValue>;
|
|
78
|
+
sessionId?: string | undefined;
|
|
79
|
+
repo?: {
|
|
80
|
+
root: string;
|
|
81
|
+
remote?: string | undefined;
|
|
82
|
+
branch?: string | undefined;
|
|
83
|
+
commit?: string | undefined;
|
|
84
|
+
} | undefined;
|
|
85
|
+
outcome?: "unknown" | "success" | "failure" | "cancelled" | undefined;
|
|
86
|
+
durationMs?: number | undefined;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
declare function mapCodexHook(eventName: string, input: unknown): {
|
|
90
|
+
id: string;
|
|
91
|
+
version: 1;
|
|
92
|
+
source: "cursor" | "claude-code" | "codex";
|
|
93
|
+
kind: "session.started" | "session.ended" | "lifecycle.before" | "lifecycle.after" | "tool.started" | "tool.completed" | "file.changed" | "shell.started" | "shell.completed" | "mcp.started" | "mcp.completed" | "unknown";
|
|
94
|
+
occurredAt: string;
|
|
95
|
+
metadata: Record<string, SafeValue>;
|
|
96
|
+
sessionId?: string | undefined;
|
|
97
|
+
repo?: {
|
|
98
|
+
root: string;
|
|
99
|
+
remote?: string | undefined;
|
|
100
|
+
branch?: string | undefined;
|
|
101
|
+
commit?: string | undefined;
|
|
102
|
+
} | undefined;
|
|
103
|
+
outcome?: "unknown" | "success" | "failure" | "cancelled" | undefined;
|
|
104
|
+
durationMs?: number | undefined;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
declare function mapCursorHook(eventName: string, input: unknown): {
|
|
108
|
+
id: string;
|
|
109
|
+
version: 1;
|
|
110
|
+
source: "cursor" | "claude-code" | "codex";
|
|
111
|
+
kind: "session.started" | "session.ended" | "lifecycle.before" | "lifecycle.after" | "tool.started" | "tool.completed" | "file.changed" | "shell.started" | "shell.completed" | "mcp.started" | "mcp.completed" | "unknown";
|
|
112
|
+
occurredAt: string;
|
|
113
|
+
metadata: Record<string, SafeValue>;
|
|
114
|
+
sessionId?: string | undefined;
|
|
115
|
+
repo?: {
|
|
116
|
+
root: string;
|
|
117
|
+
remote?: string | undefined;
|
|
118
|
+
branch?: string | undefined;
|
|
119
|
+
commit?: string | undefined;
|
|
120
|
+
} | undefined;
|
|
121
|
+
outcome?: "unknown" | "success" | "failure" | "cancelled" | undefined;
|
|
122
|
+
durationMs?: number | undefined;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
declare const deviceAuthorizationSchema: z.ZodObject<{
|
|
126
|
+
device_code: z.ZodString;
|
|
127
|
+
user_code: z.ZodString;
|
|
128
|
+
verification_uri: z.ZodString;
|
|
129
|
+
verification_uri_complete: z.ZodOptional<z.ZodString>;
|
|
130
|
+
expires_at: z.ZodString;
|
|
131
|
+
interval: z.ZodDefault<z.ZodNumber>;
|
|
132
|
+
}, z.core.$strip>;
|
|
133
|
+
declare const deviceTokenResponseSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
134
|
+
status: z.ZodLiteral<"approved">;
|
|
135
|
+
accessToken: z.ZodString;
|
|
136
|
+
projectId: z.ZodString;
|
|
137
|
+
organizationId: z.ZodString;
|
|
138
|
+
repositoryId: z.ZodOptional<z.ZodString>;
|
|
139
|
+
deviceId: z.ZodString;
|
|
140
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
141
|
+
status: z.ZodEnum<{
|
|
142
|
+
pending: "pending";
|
|
143
|
+
denied: "denied";
|
|
144
|
+
}>;
|
|
145
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
146
|
+
status: z.ZodEnum<{
|
|
147
|
+
expired: "expired";
|
|
148
|
+
invalid: "invalid";
|
|
149
|
+
}>;
|
|
150
|
+
}, z.core.$strip>], "status">;
|
|
151
|
+
type DeviceAuthorization = z.infer<typeof deviceAuthorizationSchema>;
|
|
152
|
+
type DeviceTokenResponse = z.infer<typeof deviceTokenResponseSchema>;
|
|
153
|
+
interface CredentialStore {
|
|
154
|
+
get(service: string, account: string): Promise<string | undefined>;
|
|
155
|
+
set(service: string, account: string, value: string): Promise<void>;
|
|
156
|
+
delete(service: string, account: string): Promise<void>;
|
|
157
|
+
}
|
|
158
|
+
type StoredCredential = {
|
|
159
|
+
appUrl: string;
|
|
160
|
+
accessToken: string;
|
|
161
|
+
projectId: string;
|
|
162
|
+
organizationId: string;
|
|
163
|
+
repositoryId?: string;
|
|
164
|
+
deviceId: string;
|
|
165
|
+
};
|
|
166
|
+
declare class SystemCredentialStore implements CredentialStore {
|
|
167
|
+
get(service: string, account: string): Promise<string | undefined>;
|
|
168
|
+
set(service: string, account: string, value: string): Promise<void>;
|
|
169
|
+
delete(service: string, account: string): Promise<void>;
|
|
170
|
+
}
|
|
171
|
+
declare function requestDeviceAuthorization(input: {
|
|
172
|
+
appUrl: string;
|
|
173
|
+
projectId: string;
|
|
174
|
+
deviceName: string;
|
|
175
|
+
agentName: AgentName;
|
|
176
|
+
}): Promise<{
|
|
177
|
+
device_code: string;
|
|
178
|
+
user_code: string;
|
|
179
|
+
verification_uri: string;
|
|
180
|
+
expires_at: string;
|
|
181
|
+
interval: number;
|
|
182
|
+
verification_uri_complete?: string | undefined;
|
|
183
|
+
}>;
|
|
184
|
+
declare function pollDeviceToken(input: {
|
|
185
|
+
appUrl: string;
|
|
186
|
+
deviceCode: string;
|
|
187
|
+
}): Promise<{
|
|
188
|
+
status: "approved";
|
|
189
|
+
accessToken: string;
|
|
190
|
+
projectId: string;
|
|
191
|
+
organizationId: string;
|
|
192
|
+
deviceId: string;
|
|
193
|
+
repositoryId?: string | undefined;
|
|
194
|
+
} | {
|
|
195
|
+
status: "pending" | "denied";
|
|
196
|
+
} | {
|
|
197
|
+
status: "expired" | "invalid";
|
|
198
|
+
}>;
|
|
199
|
+
type AgentName = "cursor" | "claude-code" | "codex";
|
|
200
|
+
|
|
201
|
+
interface OfflineQueue {
|
|
202
|
+
enqueue(events: readonly CanonicalHookEvent[]): Promise<void>;
|
|
203
|
+
peek(limit: number): Promise<CanonicalHookEvent[]>;
|
|
204
|
+
remove(ids: readonly string[]): Promise<void>;
|
|
205
|
+
size(): Promise<number>;
|
|
206
|
+
}
|
|
207
|
+
declare class MemoryOfflineQueue implements OfflineQueue {
|
|
208
|
+
private events;
|
|
209
|
+
enqueue(events: readonly CanonicalHookEvent[]): Promise<void>;
|
|
210
|
+
peek(limit: number): Promise<CanonicalHookEvent[]>;
|
|
211
|
+
remove(ids: readonly string[]): Promise<void>;
|
|
212
|
+
size(): Promise<number>;
|
|
213
|
+
}
|
|
214
|
+
declare class JsonFileOfflineQueue implements OfflineQueue {
|
|
215
|
+
private readonly filePath;
|
|
216
|
+
private operation;
|
|
217
|
+
constructor(filePath: string);
|
|
218
|
+
enqueue(events: readonly CanonicalHookEvent[]): Promise<void>;
|
|
219
|
+
peek(limit: number): Promise<CanonicalHookEvent[]>;
|
|
220
|
+
remove(ids: readonly string[]): Promise<void>;
|
|
221
|
+
size(): Promise<number>;
|
|
222
|
+
private read;
|
|
223
|
+
private update;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
interface SignedBatchClientOptions {
|
|
227
|
+
endpoint: string;
|
|
228
|
+
accessToken: string;
|
|
229
|
+
organizationId: string;
|
|
230
|
+
projectId: string;
|
|
231
|
+
repositoryId?: string;
|
|
232
|
+
deviceId: string;
|
|
233
|
+
queue: OfflineQueue;
|
|
234
|
+
fetch?: typeof globalThis.fetch;
|
|
235
|
+
batchSize?: number;
|
|
236
|
+
timeoutMs?: number;
|
|
237
|
+
}
|
|
238
|
+
interface FlushResult {
|
|
239
|
+
sent: number;
|
|
240
|
+
remaining: number;
|
|
241
|
+
error?: string;
|
|
242
|
+
}
|
|
243
|
+
declare class SignedBatchClient {
|
|
244
|
+
private readonly options;
|
|
245
|
+
private readonly request;
|
|
246
|
+
private readonly batchSize;
|
|
247
|
+
private readonly timeoutMs;
|
|
248
|
+
constructor(options: SignedBatchClientOptions);
|
|
249
|
+
capture(event: CanonicalHookEvent): Promise<FlushResult>;
|
|
250
|
+
flush(): Promise<FlushResult>;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
interface RedactionOptions {
|
|
254
|
+
allowContent?: boolean;
|
|
255
|
+
homeDirectory?: string;
|
|
256
|
+
replacement?: string;
|
|
257
|
+
}
|
|
258
|
+
declare function redact(value: unknown, options?: RedactionOptions): SafeValue;
|
|
259
|
+
declare function safeMetadata(input: Record<string, unknown>, allowedKeys: readonly string[]): Record<string, SafeValue>;
|
|
260
|
+
|
|
261
|
+
interface RepositoryInfo {
|
|
262
|
+
root: string;
|
|
263
|
+
remote?: string;
|
|
264
|
+
branch?: string;
|
|
265
|
+
commit?: string;
|
|
266
|
+
}
|
|
267
|
+
declare function detectRepository(cwd?: string): Promise<RepositoryInfo | undefined>;
|
|
268
|
+
declare function sanitizeRemote(remote: string): string;
|
|
269
|
+
declare function normalizeGitHubRepository(value: string): string | undefined;
|
|
270
|
+
declare function matchesGitHubRepository(remote: string | undefined, expected: string): boolean;
|
|
271
|
+
|
|
272
|
+
export { type AgentSource, type CanonicalHookEvent, type CredentialStore, type DeviceAuthorization, type DeviceTokenResponse, type FlushResult, type HookEventKind, JsonFileOfflineQueue, MemoryOfflineQueue, type OfflineQueue, type RedactionOptions, type RepositoryInfo, type SafeValue, SignedBatchClient, type SignedBatchClientOptions, type StoredCredential, SystemCredentialStore, agentSourceSchema, canonicalHookEventSchema, createHookEvent, detectRepository, deviceAuthorizationSchema, deviceTokenResponseSchema, hookEventKindSchema, mapClaudeCodeHook, mapCodexHook, mapCursorHook, matchesGitHubRepository, normalizeGitHubRepository, pollDeviceToken, redact, requestDeviceAuthorization, safeMetadata, safeValueSchema, sanitizeRemote };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
JsonFileOfflineQueue,
|
|
3
|
+
MemoryOfflineQueue,
|
|
4
|
+
SignedBatchClient,
|
|
5
|
+
SystemCredentialStore,
|
|
6
|
+
agentSourceSchema,
|
|
7
|
+
canonicalHookEventSchema,
|
|
8
|
+
createHookEvent,
|
|
9
|
+
detectRepository,
|
|
10
|
+
deviceAuthorizationSchema,
|
|
11
|
+
deviceTokenResponseSchema,
|
|
12
|
+
hookEventKindSchema,
|
|
13
|
+
mapClaudeCodeHook,
|
|
14
|
+
mapCodexHook,
|
|
15
|
+
mapCursorHook,
|
|
16
|
+
matchesGitHubRepository,
|
|
17
|
+
normalizeGitHubRepository,
|
|
18
|
+
pollDeviceToken,
|
|
19
|
+
redact,
|
|
20
|
+
requestDeviceAuthorization,
|
|
21
|
+
safeMetadata,
|
|
22
|
+
safeValueSchema,
|
|
23
|
+
sanitizeRemote
|
|
24
|
+
} from "./chunk-BL74PDGC.js";
|
|
25
|
+
export {
|
|
26
|
+
JsonFileOfflineQueue,
|
|
27
|
+
MemoryOfflineQueue,
|
|
28
|
+
SignedBatchClient,
|
|
29
|
+
SystemCredentialStore,
|
|
30
|
+
agentSourceSchema,
|
|
31
|
+
canonicalHookEventSchema,
|
|
32
|
+
createHookEvent,
|
|
33
|
+
detectRepository,
|
|
34
|
+
deviceAuthorizationSchema,
|
|
35
|
+
deviceTokenResponseSchema,
|
|
36
|
+
hookEventKindSchema,
|
|
37
|
+
mapClaudeCodeHook,
|
|
38
|
+
mapCodexHook,
|
|
39
|
+
mapCursorHook,
|
|
40
|
+
matchesGitHubRepository,
|
|
41
|
+
normalizeGitHubRepository,
|
|
42
|
+
pollDeviceToken,
|
|
43
|
+
redact,
|
|
44
|
+
requestDeviceAuthorization,
|
|
45
|
+
safeMetadata,
|
|
46
|
+
safeValueSchema,
|
|
47
|
+
sanitizeRemote
|
|
48
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@wibeco/bridge",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Privacy-first live activity bridge for Cursor, Claude Code, and Codex.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/wibe-co/wibe.git",
|
|
8
|
+
"directory": "packages/bridge"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://trywibe.com",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/wibe-co/wibe/issues"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"bin": {
|
|
16
|
+
"wibe": "dist/cli.js",
|
|
17
|
+
"wibe-bridge": "dist/cli.js"
|
|
18
|
+
},
|
|
19
|
+
"exports": {
|
|
20
|
+
".": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"templates",
|
|
25
|
+
"README.md"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "node scripts/copy-templates.mjs && tsup src/index.ts src/cli.ts src/codex-hook.ts --format esm --target node20 --dts --clean --tsconfig tsconfig.json",
|
|
29
|
+
"prepack": "npm run build",
|
|
30
|
+
"test": "vitest run test --config vitest.config.ts"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"zod": "^4.0.0"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=20"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"license": "MIT"
|
|
42
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Claude Code template
|
|
2
|
+
|
|
3
|
+
These files are inert examples. Review and merge `settings.json.example` into the appropriate
|
|
4
|
+
Claude Code settings file. It uses command hooks because the local bridge must normalize and redact
|
|
5
|
+
the payload before network delivery. Do not point an HTTP hook directly at a collector: Claude hook
|
|
6
|
+
payloads can include prompts, tool inputs/results, and other raw content.
|
|
7
|
+
|
|
8
|
+
Configure `WIBE_COLLECTOR_URL`, `WIBE_KEY_ID`, and `WIBE_SIGNING_SECRET` in the hook environment.
|
|
9
|
+
Store the secret in an OS keychain/secret manager. The bridge allow-list excludes prompt, content,
|
|
10
|
+
messages, command text, tool arguments/results, and transcripts.
|
|
11
|
+
|
|
12
|
+
`mcp.json.example` is only a config shape. Replace `WIBE_MCP_COMMAND` with an installed MCP server
|
|
13
|
+
executable and inject `WIBE_MCP_TOKEN_FROM_KEYCHAIN` at launch. The bridge does not yet implement an
|
|
14
|
+
MCP server.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"hooks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "command",
|
|
8
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter claude-code --event session-start"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"SessionEnd": [
|
|
14
|
+
{
|
|
15
|
+
"hooks": [
|
|
16
|
+
{
|
|
17
|
+
"type": "command",
|
|
18
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter claude-code --event session-end"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"UserPromptSubmit": [
|
|
24
|
+
{
|
|
25
|
+
"hooks": [
|
|
26
|
+
{
|
|
27
|
+
"type": "command",
|
|
28
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter claude-code --event user-prompt-submit"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"PreToolUse": [
|
|
34
|
+
{
|
|
35
|
+
"matcher": ".*",
|
|
36
|
+
"hooks": [
|
|
37
|
+
{
|
|
38
|
+
"type": "command",
|
|
39
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter claude-code --event pre-tool-use"
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"PostToolUse": [
|
|
45
|
+
{
|
|
46
|
+
"matcher": ".*",
|
|
47
|
+
"hooks": [
|
|
48
|
+
{
|
|
49
|
+
"type": "command",
|
|
50
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter claude-code --event post-tool-use"
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"PostToolUseFailure": [
|
|
56
|
+
{
|
|
57
|
+
"matcher": ".*",
|
|
58
|
+
"hooks": [
|
|
59
|
+
{
|
|
60
|
+
"type": "command",
|
|
61
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter claude-code --event post-tool-use-failure"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"Stop": [
|
|
67
|
+
{
|
|
68
|
+
"hooks": [
|
|
69
|
+
{
|
|
70
|
+
"type": "command",
|
|
71
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter claude-code --event stop"
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Codex template
|
|
2
|
+
|
|
3
|
+
This is an inert config fragment. Review and merge `config.toml.example` into Codex's configuration.
|
|
4
|
+
The `notify` command receives Codex's JSON notification argument, maps allow-listed fields in-process,
|
|
5
|
+
and queues or sends only the canonical event. Prompt text, messages, tool data, command text, file
|
|
6
|
+
content, and transcripts are not retained.
|
|
7
|
+
|
|
8
|
+
Configure `WIBE_COLLECTOR_URL`, `WIBE_KEY_ID`, and `WIBE_SIGNING_SECRET` in the Codex environment,
|
|
9
|
+
with the signing secret supplied by an OS keychain/secret manager.
|
|
10
|
+
|
|
11
|
+
The MCP block is only a config shape. Replace `WIBE_MCP_COMMAND` with an installed MCP server
|
|
12
|
+
executable and inject `WIBE_MCP_TOKEN_FROM_KEYCHAIN` at launch. The bridge does not yet implement an
|
|
13
|
+
MCP server. Codex notification coverage is narrower than Cursor or Claude Code lifecycle hooks.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Codex passes one JSON notification argument to this command. The adapter only keeps allow-listed
|
|
2
|
+
# operational metadata and never forwards the full argument.
|
|
3
|
+
notify = ["npx", "-y", "@wibeco/bridge@latest", "emit", "--adapter", "codex", "--event", "notify"]
|
|
4
|
+
|
|
5
|
+
[mcp_servers.wibe]
|
|
6
|
+
url = "${WIBE_APP_URL}/api/mcp"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"hooks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "command",
|
|
8
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter codex --event session-start"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"UserPromptSubmit": [
|
|
14
|
+
{
|
|
15
|
+
"hooks": [
|
|
16
|
+
{
|
|
17
|
+
"type": "command",
|
|
18
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter codex --event user-prompt-submit"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"PreToolUse": [
|
|
24
|
+
{
|
|
25
|
+
"matcher": ".*",
|
|
26
|
+
"hooks": [
|
|
27
|
+
{
|
|
28
|
+
"type": "command",
|
|
29
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter codex --event pre-tool-use"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"PostToolUse": [
|
|
35
|
+
{
|
|
36
|
+
"matcher": ".*",
|
|
37
|
+
"hooks": [
|
|
38
|
+
{
|
|
39
|
+
"type": "command",
|
|
40
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter codex --event post-tool-use"
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"SubagentStart": [
|
|
46
|
+
{
|
|
47
|
+
"hooks": [
|
|
48
|
+
{
|
|
49
|
+
"type": "command",
|
|
50
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter codex --event subagent-start"
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"SubagentStop": [
|
|
56
|
+
{
|
|
57
|
+
"hooks": [
|
|
58
|
+
{
|
|
59
|
+
"type": "command",
|
|
60
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter codex --event subagent-stop"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"Stop": [
|
|
66
|
+
{
|
|
67
|
+
"hooks": [
|
|
68
|
+
{
|
|
69
|
+
"type": "command",
|
|
70
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter codex --event stop"
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Cursor template
|
|
2
|
+
|
|
3
|
+
These files are inert examples. Review Cursor's hook schema for your installed release, then merge
|
|
4
|
+
`hooks.json.example` into `.cursor/hooks.json`; hook names can change between releases. Commands use
|
|
5
|
+
`npx --no-install`, so they never download packages during a hook.
|
|
6
|
+
|
|
7
|
+
Configure `WIBE_COLLECTOR_URL`, `WIBE_KEY_ID`, and `WIBE_SIGNING_SECRET` in the process environment.
|
|
8
|
+
Prefer an OS keychain/secret manager for the signing secret. The mapper drops prompt, content, file
|
|
9
|
+
body, command text, tool arguments/results, and transcripts.
|
|
10
|
+
|
|
11
|
+
`mcp.json.example` is only a config shape. Replace `WIBE_MCP_COMMAND` with an installed MCP server
|
|
12
|
+
executable and inject `WIBE_MCP_TOKEN_FROM_KEYCHAIN` at launch. The bridge does not yet implement an
|
|
13
|
+
MCP server and this template must not be enabled unchanged.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"hooks": {
|
|
4
|
+
"sessionStart": [
|
|
5
|
+
{
|
|
6
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter cursor --event session-start"
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"sessionEnd": [
|
|
10
|
+
{
|
|
11
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter cursor --event session-end"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"beforeSubmitPrompt": [
|
|
15
|
+
{
|
|
16
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter cursor --event before-submit-prompt"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"afterAgentResponse": [
|
|
20
|
+
{
|
|
21
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter cursor --event after-agent-response"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"preToolUse": [
|
|
25
|
+
{
|
|
26
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter cursor --event before-tool"
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"postToolUse": [
|
|
30
|
+
{
|
|
31
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter cursor --event after-tool"
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"afterFileEdit": [
|
|
35
|
+
{
|
|
36
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter cursor --event after-file-edit"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"beforeShellExecution": [
|
|
40
|
+
{
|
|
41
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter cursor --event before-shell-execution"
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"afterShellExecution": [
|
|
45
|
+
{
|
|
46
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter cursor --event after-shell-execution"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"beforeMCPExecution": [
|
|
50
|
+
{
|
|
51
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter cursor --event before-mcp-execution"
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"afterMCPExecution": [
|
|
55
|
+
{
|
|
56
|
+
"command": "npx -y @wibeco/bridge@latest emit --adapter cursor --event after-mcp-execution"
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
}
|