codex-plus-patcher 0.6.0 → 0.7.1

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.
Files changed (50) hide show
  1. package/README.md +3 -1
  2. package/package.json +5 -3
  3. package/src/cli.js +88 -0
  4. package/src/core/dev-mode.js +274 -0
  5. package/src/core/plugin-audit.js +1267 -0
  6. package/src/patches/26.623.41415-4505.js +44 -0
  7. package/src/patches/index.js +8 -1
  8. package/src/patches/lib/common-patches.js +411 -248
  9. package/src/patches/lib/hooks/about.js +7 -0
  10. package/src/patches/lib/hooks/diagnostics.js +7 -0
  11. package/src/patches/lib/hooks/mermaid.js +7 -0
  12. package/src/patches/lib/hooks/message-composer.js +7 -0
  13. package/src/patches/lib/hooks/native-main.js +7 -0
  14. package/src/patches/lib/hooks/project-selector.js +12 -0
  15. package/src/patches/lib/hooks/review.js +9 -0
  16. package/src/patches/lib/hooks/settings-commands.js +13 -0
  17. package/src/patches/lib/hooks/sidebar.js +7 -0
  18. package/src/patches/lib/hooks/thread-header.js +7 -0
  19. package/src/patches/lib/hooks/worker.js +7 -0
  20. package/src/patches/lib/project-selector-shortcut-patch.js +84 -8
  21. package/src/runtime/api/about.js +16 -0
  22. package/src/runtime/api/commands.js +85 -0
  23. package/src/runtime/api/composer.js +14 -0
  24. package/src/runtime/api/diagnostics.js +38 -0
  25. package/src/runtime/api/errors.js +20 -0
  26. package/src/runtime/api/index.js +82 -0
  27. package/src/runtime/api/mermaid.js +14 -0
  28. package/src/runtime/api/message.js +14 -0
  29. package/src/runtime/api/modules.js +57 -0
  30. package/src/runtime/api/native.js +14 -0
  31. package/src/runtime/api/patches.js +31 -0
  32. package/src/runtime/api/review.js +20 -0
  33. package/src/runtime/api/settings.js +76 -0
  34. package/src/runtime/api/sidebar.js +24 -0
  35. package/src/runtime/api/styles.js +28 -0
  36. package/src/runtime/api/threadHeader.js +41 -0
  37. package/src/runtime/assets.js +59 -18
  38. package/src/runtime/host/messageComposer.js +16 -0
  39. package/src/runtime/host/nativeMain.js +159 -0
  40. package/src/runtime/host/projectSelector.js +58 -0
  41. package/src/runtime/host/review.js +62 -0
  42. package/src/runtime/host/sidebar.js +21 -0
  43. package/src/runtime/host/threadHeader.js +9 -0
  44. package/src/runtime/{worker.js → host/worker.js} +7 -0
  45. package/src/runtime/plugins/mermaidFullscreen.js +19 -6
  46. package/src/runtime/plugins/nestedRepositories.js +72 -11
  47. package/src/runtime/plugins/projectColors.js +94 -7
  48. package/src/runtime/plugins/projectSelectorShortcut.js +67 -12
  49. package/src/runtime/plugins/sidebarNameBlur.js +1 -1
  50. package/src/runtime/runtime.js +23 -441
@@ -0,0 +1,7 @@
1
+ function aboutMetadataRequire() {
2
+ return 'require("./codex-plus-aboutMetadata.js")';
3
+ }
4
+
5
+ module.exports = {
6
+ aboutMetadataRequire,
7
+ };
@@ -0,0 +1,7 @@
1
+ function diagnosticDetailsHook() {
2
+ return "function CPXDiagnosticDetails(e){return window.CodexPlus?.ui?.errors?.renderDetails?.(e)??null}";
3
+ }
4
+
5
+ module.exports = {
6
+ diagnosticDetailsHook,
7
+ };
@@ -0,0 +1,7 @@
1
+ function mermaidDiagramHook() {
2
+ return "function CPXMermaidDiagramProps(e){return window.CodexPlus?.ui?.mermaid?.diagramProps?.(e)}";
3
+ }
4
+
5
+ module.exports = {
6
+ mermaidDiagramHook,
7
+ };
@@ -0,0 +1,7 @@
1
+ function messageComposerHook() {
2
+ return "var CPXMC=window.CodexPlusHost.adapters.messageComposer,CPXBubbleProps=e=>CPXMC.userBubbleProps(e),CPXSurfaceProps=e=>CPXMC.composerSurfaceProps(e);";
3
+ }
4
+
5
+ module.exports = {
6
+ messageComposerHook,
7
+ };
@@ -0,0 +1,7 @@
1
+ function nativeMainHook() {
2
+ return 'let CPXNative=require("./codex-plus-native-main.js").create({electron:a});';
3
+ }
4
+
5
+ module.exports = {
6
+ nativeMainHook,
7
+ };
@@ -0,0 +1,12 @@
1
+ function projectSelectorSearchHook() {
2
+ return "let CPXP=window.CodexPlusHost.adapters.projectSelector;";
3
+ }
4
+
5
+ function projectSelectorTriggerHook(reactIdentifier = "Me") {
6
+ return `function CPXPST(e,t){return CPXP.trigger(e,t,${reactIdentifier})}`;
7
+ }
8
+
9
+ module.exports = {
10
+ projectSelectorSearchHook,
11
+ projectSelectorTriggerHook,
12
+ };
@@ -0,0 +1,9 @@
1
+ function reviewHook(depsExpression) {
2
+ const deps =
3
+ depsExpression || "[$,Q,s,l,ft,Or,Dr,kr,jr,y,B,of,Y,Ae,Je,yi,vi,CPXBranchPickerDropdownContent,dp,xr,Ma]";
4
+ return `let CPXR=window.CodexPlusHost.adapters.review,CPXRM=e=>CPXR.renderBodyFromHost(e,${deps});`;
5
+ }
6
+
7
+ module.exports = {
8
+ reviewHook,
9
+ };
@@ -0,0 +1,13 @@
1
+ function appearanceSettingsHook(depsExpression) {
2
+ const deps = depsExpression || "{React:X,jsx:Z.jsx,SettingRow:J,ColorInput:sn,Switch:q}";
3
+ return `function CPXAppearanceRows(e){return window.CodexPlus?.ui?.settings?.appearance?.renderRows?.({deps:${deps},variant:e})??[]}`;
4
+ }
5
+
6
+ function commandMenuItemsExpression(group, jsx, menuItem, register) {
7
+ return `window.CodexPlus?.ui?.commands?.renderMenuItems?.({group:\`${group}\`,deps:{jsx:${jsx},MenuItem:${menuItem},register:${register}}})??[]`;
8
+ }
9
+
10
+ module.exports = {
11
+ appearanceSettingsHook,
12
+ commandMenuItemsExpression,
13
+ };
@@ -0,0 +1,7 @@
1
+ function projectColorHook() {
2
+ return "var CPXS=window.CodexPlusHost.adapters.sidebar,CPXPR=e=>CPXS.projectRowProps(e);";
3
+ }
4
+
5
+ module.exports = {
6
+ projectColorHook,
7
+ };
@@ -0,0 +1,7 @@
1
+ function threadHeaderHook() {
2
+ return "let CPXTH=window.CodexPlusHost.adapters.threadHeader;function CPXThreadHeaderAccessories(e){return CPXTH.accessories(e.context,e.deps)}";
3
+ }
4
+
5
+ module.exports = {
6
+ threadHeaderHook,
7
+ };
@@ -0,0 +1,7 @@
1
+ function workerHook() {
2
+ return 'const CPXW=require("./codex-plus-worker.js"),CPXT=e=>CPXW.traceRequest(e),CPXR=(e,t,n,r)=>CPXW.repositoryTargetsFromHost(e,t,n,r,pae),CPXB=(e,t)=>CPXW.isReadOnlyBranchRequest(e,t);';
3
+ }
4
+
5
+ module.exports = {
6
+ workerHook,
7
+ };
@@ -1,54 +1,130 @@
1
1
  const { replaceOnce } = require("./replace");
2
+ const { projectSelectorSearchHook, projectSelectorTriggerHook } = require("./hooks/project-selector");
2
3
 
3
4
  function patchLocalActiveWorkspaceRootDropdownProjectSelectorShortcut(text) {
5
+ if (text.includes("function Ti(e){let t=(0,Oi.c)(109),")) {
6
+ return replaceOnce(
7
+ text,
8
+ "H=(0,X.jsx)(`button`,{type:`button`,className:`flex min-w-0 items-center gap-1.5 rounded-lg bg-token-foreground/5 px-2 py-0.5 text-base leading-6 font-medium tracking-[-0.13px] text-token-foreground`,disabled:M,children:de})",
9
+ "H=(0,X.jsx)(`button`,{type:`button`,\"data-codex-plus-project-selector-trigger\":!0,\"data-codex-plus-project-selector-variant\":`default`,className:`flex min-w-0 items-center gap-1.5 rounded-lg bg-token-foreground/5 px-2 py-0.5 text-base leading-6 font-medium tracking-[-0.13px] text-token-foreground`,disabled:M,children:de})",
10
+ "project selector shortcut final dropdown trigger anchor",
11
+ );
12
+ }
4
13
  let patched = replaceOnce(
5
14
  text,
6
15
  "Ne=r();function Pe(e){let t=(0,Ne.c)(42),",
7
- "Ne=r();function CPXProjectSelectorFuzzyFilter(e,t){let n=String(t??``).trim().toLowerCase();return window.CodexPlus?.ui?.projectSelector?.fuzzyFilter?.(e,t)??(n?e.filter(e=>[e.label,e.repositoryData?.rootFolder??``,e.path??``,e.hostDisplayName??``].some(e=>String(e??``).toLowerCase().includes(n))):e)}function CPXProjectSelectorFuzzyHighlight(e,t){return window.CodexPlus?.ui?.projectSelector?.fuzzyHighlight?.({text:e,query:t,jsx:H.jsx})??e}function CPXProjectSelectorAcceptFirst(e,t,n,r){let i=t?.[0];if(e?.key!==`Enter`||String(r??``).trim().length===0||i==null)return;e.preventDefault?.(),e.stopPropagation?.(),n(i.projectId)}function Pe(e){let t=(0,Ne.c)(42),",
16
+ `Ne=r();${projectSelectorSearchHook()}function Pe(e){let t=(0,Ne.c)(42),`,
8
17
  "project selector fuzzy search adapter insertion anchor",
9
18
  );
10
19
  patched = replaceOnce(
11
20
  patched,
12
21
  "let e=h.trim().toLowerCase();v=n.filter(t=>{if(!e)return!0;let n=t.repositoryData?.rootFolder??``;return[t.label,n,t.path??``,t.hostDisplayName??``].some(t=>t.toLowerCase().includes(e))});",
13
- "v=CPXProjectSelectorFuzzyFilter(n,h);",
22
+ "v=CPXP.fuzzyFilter(n,h);",
14
23
  "project selector fuzzy search filter anchor",
15
24
  );
16
25
  patched = replaceOnce(
17
26
  patched,
18
27
  "S=(0,H.jsx)(ve,{value:h,onChange:o,placeholder:s,className:`mb-1`})",
19
- "S=(0,H.jsx)(ve,{value:h,onChange:o,onKeyDown:e=>CPXProjectSelectorAcceptFirst(e,v,i,h),placeholder:s,className:`mb-1`})",
28
+ "S=(0,H.jsx)(ve,{value:h,onChange:o,onKeyDown:e=>CPXP.acceptFirst(e,v,i,h),placeholder:s,className:`mb-1`})",
20
29
  "project selector accept first match keydown anchor",
21
30
  );
22
31
  patched = replaceOnce(
23
32
  patched,
24
33
  "(0,H.jsx)(`span`,{className:`truncate`,children:e.label})",
25
- "(0,H.jsx)(`span`,{className:`truncate`,children:CPXProjectSelectorFuzzyHighlight(e.label,h)})",
34
+ "(0,H.jsx)(`span`,{className:`truncate`,children:CPXP.fuzzyHighlight(e.label,h,H.jsx)})",
26
35
  "project selector fuzzy search highlight anchor",
27
36
  );
28
37
  patched = replaceOnce(
29
38
  patched,
30
39
  "function Ie(e){let t=(0,Ne.c)(81),",
31
- "function CPXProjectSelectorTrigger(e,t){return Me.isValidElement(e)?Me.cloneElement(e,{...e.props,\"data-codex-plus-project-selector-trigger\":!0,\"data-codex-plus-project-selector-variant\":t}):e}function Ie(e){let t=(0,Ne.c)(81),",
40
+ `${projectSelectorTriggerHook()}function Ie(e){let t=(0,Ne.c)(81),`,
32
41
  "project selector shortcut helper insertion anchor",
33
42
  );
34
43
  return replaceOnce(
35
44
  patched,
36
45
  "at=(0,H.jsx)(ye,{open:f,onOpenChange:g,onCloseAutoFocus:Y,align:tt,disabled:O,triggerButton:X,contentWidth:`workspace`,contentMaxHeight:`tall`,children:$})",
37
- "at=(0,H.jsx)(ye,{open:f,onOpenChange:g,onCloseAutoFocus:Y,align:tt,disabled:O,triggerButton:CPXProjectSelectorTrigger(X,k),contentWidth:`workspace`,contentMaxHeight:`tall`,children:$})",
46
+ "at=(0,H.jsx)(ye,{open:f,onOpenChange:g,onCloseAutoFocus:Y,align:tt,disabled:O,triggerButton:CPXPST(X,k),contentWidth:`workspace`,contentMaxHeight:`tall`,children:$})",
38
47
  "project selector shortcut final dropdown trigger anchor",
39
48
  );
40
49
  }
41
50
 
51
+ function patchHomeProjectDropdownProjectSelectorShortcut(text) {
52
+ let patched = replaceOnce(
53
+ text,
54
+ "function St({activeProjectIdOverride:e,allowLocalProjects:t=!0,allowLocalProjectActions:n=t,allowRemoteProjects:r=!0,disabled:a=!1,hideLabel:o=!1,onWorkspaceRootSelected:s,variant:c=`default`,isOpen:l,onOpenChange:m,triggerButton:_}){",
55
+ `${projectSelectorSearchHook()}${projectSelectorTriggerHook("wt")}function St({activeProjectIdOverride:e,allowLocalProjects:t=!0,allowLocalProjectActions:n=t,allowRemoteProjects:r=!0,disabled:a=!1,hideLabel:o=!1,onWorkspaceRootSelected:s,variant:c=\`default\`,isOpen:l,onOpenChange:m,triggerButton:_}){`,
56
+ "home project selector shortcut helper insertion anchor",
57
+ );
58
+ patched = replaceOnce(
59
+ patched,
60
+ "let e=_.trim().toLowerCase();b=r.filter(t=>{if(!e)return!0;let n=t.repositoryData?.rootFolder??``;return[t.label,n,t.path??``,t.hostDisplayName??``].some(t=>t.toLowerCase().includes(e))});",
61
+ "b=CPXP.fuzzyFilter(r,_);",
62
+ "home project selector fuzzy search filter anchor",
63
+ );
64
+ patched = replaceOnce(
65
+ patched,
66
+ "w=(0,X.jsx)(ie,{value:_,onChange:s,placeholder:c,className:`mb-1`})",
67
+ "w=(0,X.jsx)(ie,{value:_,onChange:s,onKeyDown:e=>CPXP.acceptFirst(e,b,o,_),placeholder:c,className:`mb-1`})",
68
+ "home project selector accept first match keydown anchor",
69
+ );
70
+ patched = replaceOnce(
71
+ patched,
72
+ "(0,X.jsx)(`span`,{className:`truncate`,children:e.label})",
73
+ "(0,X.jsx)(`span`,{className:`truncate`,children:CPXP.fuzzyHighlight(e.label,_,X.jsx)})",
74
+ "home project selector fuzzy search highlight anchor",
75
+ );
76
+ patched = replaceOnce(
77
+ patched,
78
+ "children:(0,$.jsxs)(Ne,{size:`composerSm`,color:`ghost`,className:`min-w-0`,children:",
79
+ "children:(0,$.jsxs)(Ne,{\"data-codex-plus-project-selector-trigger\":!0,\"data-codex-plus-project-selector-variant\":c,size:`composerSm`,color:`ghost`,className:`min-w-0`,children:",
80
+ "home project selector default button marker anchor",
81
+ );
82
+ patched = replaceOnce(
83
+ patched,
84
+ "children:(0,$.jsx)(gt,{categoryLabel:(0,$.jsx)(R,{id:`composer.localCwdDropdown.footerCategory`",
85
+ "children:(0,$.jsx)(gt,{\"data-codex-plus-project-selector-trigger\":!0,\"data-codex-plus-project-selector-variant\":c,categoryLabel:(0,$.jsx)(R,{id:`composer.localCwdDropdown.footerCategory`",
86
+ "home project selector footer button marker anchor",
87
+ );
88
+ patched = replaceOnce(
89
+ patched,
90
+ "Ze=()=>(0,$.jsxs)(`button`,{className:W(`heading-xl text-token-text-tertiary",
91
+ "Ze=()=>(0,$.jsxs)(`button`,{\"data-codex-plus-project-selector-trigger\":!0,\"data-codex-plus-project-selector-variant\":c,className:W(`heading-xl text-token-text-tertiary",
92
+ "home project selector hero button marker anchor",
93
+ );
94
+ patched = replaceOnce(
95
+ patched,
96
+ "triggerButton:_??J(),contentWidth:`menu`",
97
+ "triggerButton:CPXPST(_??J(),c),contentWidth:`menu`",
98
+ "home project selector empty trigger anchor",
99
+ );
100
+ return replaceOnce(
101
+ patched,
102
+ "triggerButton:_??(c===`hero`?Ze():c===`home`?J():Ke()),contentWidth:`workspace`",
103
+ "triggerButton:CPXPST(_??(c===`hero`?Ze():c===`home`?J():Ke()),c),contentWidth:`workspace`",
104
+ "home project selector workspace trigger anchor",
105
+ );
106
+ }
107
+
42
108
  function patchRunCommandProjectSelectorShortcut(text) {
109
+ const runtimeCommandEntries = "...(window.CodexPlus?.commands?.all?.()??[]).map(e=>[e.id,()=>window.CodexPlus?.commands?.run?.(e.id)])";
110
+ if (text.includes("],[`openFolder`,GTt],[`toggleSidebar`,")) {
111
+ return replaceOnce(
112
+ text,
113
+ "],[`openFolder`,GTt],[`toggleSidebar`,",
114
+ `],[\`openFolder\`,GTt],${runtimeCommandEntries},[\`toggleSidebar\`,`,
115
+ "codex plus runtime command dispatch anchor",
116
+ );
117
+ }
43
118
  return replaceOnce(
44
119
  text,
45
120
  "],[`openFolder`,()=>{r()}],[`toggleSidebar`,",
46
- "],[`codexPlus.focusProjectSelector`,()=>{window.CodexPlus?.commands?.run?.(`codexPlus.focusProjectSelector`)}],[`openFolder`,()=>{r()}],[`toggleSidebar`,",
47
- "project selector shortcut command dispatch anchor",
121
+ `],[\`openFolder\`,()=>{r()}],${runtimeCommandEntries},[\`toggleSidebar\`,`,
122
+ "codex plus runtime command dispatch anchor",
48
123
  );
49
124
  }
50
125
 
51
126
  module.exports = {
127
+ patchHomeProjectDropdownProjectSelectorShortcut,
52
128
  patchLocalActiveWorkspaceRootDropdownProjectSelectorShortcut,
53
129
  patchRunCommandProjectSelectorShortcut,
54
130
  };
@@ -0,0 +1,16 @@
1
+ (function () {
2
+ const globalObject = typeof window !== "undefined" ? window : globalThis;
3
+ const { ui } = globalObject.CodexPlus;
4
+
5
+ const buildInfo = [];
6
+
7
+ function addBuildInfo(fn) {
8
+ buildInfo.push(fn);
9
+ return fn;
10
+ }
11
+
12
+ ui.about = {
13
+ addBuildInfo,
14
+ buildInfo,
15
+ };
16
+ })();
@@ -0,0 +1,85 @@
1
+ (function () {
2
+ const globalObject = typeof window !== "undefined" ? window : globalThis;
3
+ const { core, safeId } = globalObject.__CodexPlusRuntime;
4
+
5
+ function register(command) {
6
+ core.commands.set(safeId(command.id), command);
7
+ return command;
8
+ }
9
+
10
+ function run(id, ...args) {
11
+ const command = core.commands.get(id);
12
+ if (!command) throw new Error(`Unknown Codex Plus command: ${id}`);
13
+ return command.run?.(...args);
14
+ }
15
+
16
+ function commandGroups(command) {
17
+ return command.menu?.groups || [];
18
+ }
19
+
20
+ function commandKeybindings(command) {
21
+ return command.shortcut?.defaultKeybindings || [];
22
+ }
23
+
24
+ function commandMetadata() {
25
+ return Array.from(core.commands.values())
26
+ .filter((command) => command.palette?.enabled !== false)
27
+ .map((command) => {
28
+ const groups = commandGroups(command);
29
+ return {
30
+ id: command.id,
31
+ title: command.title,
32
+ description: command.description,
33
+ menuGroups: groups,
34
+ defaultKeybindings: commandKeybindings(command),
35
+ commandMenuGroupKey: groups.includes("panels") ? "panels" : groups[0],
36
+ commandMenu: true,
37
+ electron: {
38
+ menuTitle: command.title,
39
+ defaultKeybindings: commandKeybindings(command),
40
+ },
41
+ };
42
+ });
43
+ }
44
+
45
+ function CommandMenuItemHost({ command, deps, group, close }) {
46
+ const jsx = deps?.jsx;
47
+ const MenuItem = deps?.MenuItem;
48
+ if (typeof jsx !== "function" || MenuItem == null) return null;
49
+ const render = (closeMenu) =>
50
+ jsx(
51
+ MenuItem,
52
+ {
53
+ value: command.title,
54
+ title: command.title,
55
+ description: command.description,
56
+ onSelect() {
57
+ run(command.id);
58
+ closeMenu?.();
59
+ close?.();
60
+ },
61
+ },
62
+ command.id,
63
+ );
64
+ deps?.register?.(command.id, () => run(command.id), {
65
+ menuItem: { id: command.id, groupKey: group, render },
66
+ });
67
+ return null;
68
+ }
69
+
70
+ function renderMenuItems({ group, deps, close } = {}) {
71
+ const jsx = deps?.jsx;
72
+ if (typeof jsx !== "function") return [];
73
+ return Array.from(core.commands.values())
74
+ .filter((command) => commandGroups(command).includes(group))
75
+ .map((command) => jsx(CommandMenuItemHost, { command, deps, group, close }, command.id));
76
+ }
77
+
78
+ globalObject.CodexPlus.commands = {
79
+ register,
80
+ run,
81
+ all: () => Array.from(core.commands.values()),
82
+ menuItems: (group) => Array.from(core.commands.values()).filter((command) => commandGroups(command).includes(group)),
83
+ };
84
+ globalObject.CodexPlus.ui.commands = { renderMenuItems, commandMetadata };
85
+ })();
@@ -0,0 +1,14 @@
1
+ (function () {
2
+ const globalObject = typeof window !== "undefined" ? window : globalThis;
3
+ const { applyDecorators } = globalObject.__CodexPlusRuntime;
4
+ globalObject.CodexPlus.ui.composer = {
5
+ surfaceDecorators: [],
6
+ decorateSurface(fn) {
7
+ this.surfaceDecorators.push(fn);
8
+ return fn;
9
+ },
10
+ surfaceProps(props) {
11
+ return applyDecorators(props, this.surfaceDecorators);
12
+ },
13
+ };
14
+ })();
@@ -0,0 +1,38 @@
1
+ (function () {
2
+ const globalObject = typeof window !== "undefined" ? window : globalThis;
3
+ const { core } = globalObject.__CodexPlusRuntime;
4
+
5
+ function diagnosticsEnabled() {
6
+ try {
7
+ return globalObject.localStorage?.getItem("codex-plus:diagnostics") === "1";
8
+ } catch {
9
+ return false;
10
+ }
11
+ }
12
+
13
+ function log(event, details = {}) {
14
+ const entry = { event, details, time: new Date().toISOString() };
15
+ core.diagnosticEvents.push(entry);
16
+ if (core.diagnosticEvents.length > 200) core.diagnosticEvents.shift();
17
+ if (diagnosticsEnabled()) {
18
+ try {
19
+ console.info("[Codex Plus]", event, details);
20
+ } catch {}
21
+ }
22
+ return entry;
23
+ }
24
+
25
+ const diagnostics = {
26
+ log,
27
+ snapshot() {
28
+ return core.diagnosticEvents.slice();
29
+ },
30
+ clear() {
31
+ core.diagnosticEvents.splice(0, core.diagnosticEvents.length);
32
+ },
33
+ enabled: diagnosticsEnabled,
34
+ };
35
+
36
+ globalObject.CodexPlus.diagnostics = diagnostics;
37
+ globalObject.CodexPlusDiagnostics = diagnostics;
38
+ })();
@@ -0,0 +1,20 @@
1
+ (function () {
2
+ const globalObject = typeof window !== "undefined" ? window : globalThis;
3
+
4
+ function renderDetails({ jsx, error, componentStack } = {}) {
5
+ for (const decorator of globalObject.CodexPlus.ui.errors.boundaryDecorators) {
6
+ const detail = decorator({ jsx, error, componentStack });
7
+ if (detail != null) return detail;
8
+ }
9
+ return null;
10
+ }
11
+
12
+ globalObject.CodexPlus.ui.errors = {
13
+ boundaryDecorators: [],
14
+ decorateBoundary(fn) {
15
+ this.boundaryDecorators.push(fn);
16
+ return fn;
17
+ },
18
+ renderDetails,
19
+ };
20
+ })();
@@ -0,0 +1,82 @@
1
+ (function () {
2
+ const globalObject = typeof window !== "undefined" ? window : globalThis;
3
+ const core = {
4
+ commands: new Map(),
5
+ diagnosticEvents: [],
6
+ hostModules: new Map(),
7
+ patchDescriptors: [],
8
+ plugins: new Map(),
9
+ settingsListeners: new Map(),
10
+ startedPlugins: new Set(),
11
+ storagePrefix: "codex-plus:plugin:",
12
+ styleElements: new Map(),
13
+ waiters: [],
14
+ };
15
+
16
+ function safeId(id) {
17
+ if (typeof id !== "string" || id.trim() === "") throw new Error("Codex Plus plugin ids must be non-empty strings");
18
+ return id.trim();
19
+ }
20
+
21
+ function definePlugin(definition) {
22
+ const id = safeId(definition.id || definition.name);
23
+ return { ...definition, id };
24
+ }
25
+
26
+ function registerPlugin(definition) {
27
+ const plugin = definePlugin(definition);
28
+ core.plugins.set(plugin.id, plugin);
29
+ if (plugin.settings) plugin.settingsStore = CodexPlus.settings.define(plugin.id, plugin.settings);
30
+ for (const descriptor of plugin.patches || []) CodexPlus.patches.register({ ...descriptor, plugin: plugin.id });
31
+ for (const command of plugin.commands || []) CodexPlus.commands.register({ ...command, plugin: plugin.id });
32
+ if (plugin.styles) CodexPlus.styles.register(plugin.id, plugin.styles);
33
+ if (plugin.required || plugin.enabledByDefault) startPlugin(plugin.id);
34
+ CodexPlus.diagnostics.log("plugin.register", { id: plugin.id, started: core.startedPlugins.has(plugin.id) });
35
+ return plugin;
36
+ }
37
+
38
+ function startPlugin(id) {
39
+ const plugin = core.plugins.get(id);
40
+ if (!plugin || core.startedPlugins.has(id)) return;
41
+ plugin.start?.(CodexPlus);
42
+ core.startedPlugins.add(id);
43
+ CodexPlus.diagnostics.log("plugin.start", { id });
44
+ }
45
+
46
+ function stopPlugin(id) {
47
+ const plugin = core.plugins.get(id);
48
+ if (!plugin || !core.startedPlugins.has(id)) return;
49
+ plugin.stop?.(CodexPlus);
50
+ core.startedPlugins.delete(id);
51
+ }
52
+
53
+ function mergeDataAttributes(base, extra) {
54
+ if (extra == null) return base;
55
+ if (base == null) return extra;
56
+ return { ...base, ...extra, style: { ...base.style, ...extra.style } };
57
+ }
58
+
59
+ function applyDecorators(props, decorators) {
60
+ let result;
61
+ for (const decorator of decorators) result = mergeDataAttributes(result, decorator(props));
62
+ return result;
63
+ }
64
+
65
+ core.plugins.list = () => Array.from(core.plugins.values());
66
+
67
+ const CodexPlus = {
68
+ config: globalObject.__CodexPlusRuntimeConfig || {},
69
+ definePlugin,
70
+ registerPlugin,
71
+ startPlugin,
72
+ stopPlugin,
73
+ plugins: core.plugins,
74
+ ui: {},
75
+ };
76
+
77
+ globalObject.CodexPlus = CodexPlus;
78
+ globalObject.CodexPlusDiagnostics = null;
79
+ globalObject.CodexPlusHost ||= {};
80
+ globalObject.CodexPlusHost.adapters ||= {};
81
+ globalObject.__CodexPlusRuntime = { core, safeId, mergeDataAttributes, applyDecorators };
82
+ })();
@@ -0,0 +1,14 @@
1
+ (function () {
2
+ const globalObject = typeof window !== "undefined" ? window : globalThis;
3
+ const { applyDecorators } = globalObject.__CodexPlusRuntime;
4
+ globalObject.CodexPlus.ui.mermaid = {
5
+ diagramDecorators: [],
6
+ decorateDiagram(fn) {
7
+ this.diagramDecorators.push(fn);
8
+ return fn;
9
+ },
10
+ diagramProps(props) {
11
+ return applyDecorators(props, this.diagramDecorators);
12
+ },
13
+ };
14
+ })();
@@ -0,0 +1,14 @@
1
+ (function () {
2
+ const globalObject = typeof window !== "undefined" ? window : globalThis;
3
+ const { applyDecorators } = globalObject.__CodexPlusRuntime;
4
+ globalObject.CodexPlus.ui.message = {
5
+ userBubbleDecorators: [],
6
+ decorateUserBubble(fn) {
7
+ this.userBubbleDecorators.push(fn);
8
+ return fn;
9
+ },
10
+ userBubbleProps(props) {
11
+ return applyDecorators(props, this.userBubbleDecorators);
12
+ },
13
+ };
14
+ })();
@@ -0,0 +1,57 @@
1
+ (function () {
2
+ const globalObject = typeof window !== "undefined" ? window : globalThis;
3
+ const { core } = globalObject.__CodexPlusRuntime;
4
+
5
+ function notifyWaiters(name, value) {
6
+ for (let index = core.waiters.length - 1; index >= 0; index -= 1) {
7
+ const waiter = core.waiters[index];
8
+ if (!waiter.filter(value, name)) continue;
9
+ core.waiters.splice(index, 1);
10
+ waiter.resolve(value);
11
+ }
12
+ }
13
+
14
+ function registerHostModule(name, value) {
15
+ core.hostModules.set(name, value);
16
+ notifyWaiters(name, value);
17
+ return value;
18
+ }
19
+
20
+ function moduleValues() {
21
+ return Array.from(core.hostModules.values());
22
+ }
23
+
24
+ function findByProps(...props) {
25
+ return moduleValues().find((value) => value && props.every((prop) => prop in value));
26
+ }
27
+
28
+ function findByCode(text) {
29
+ return moduleValues().find((value) => {
30
+ try {
31
+ return String(value).includes(text);
32
+ } catch {
33
+ return false;
34
+ }
35
+ });
36
+ }
37
+
38
+ function findComponentByCode(text) {
39
+ return moduleValues().find((value) => {
40
+ try {
41
+ return typeof value === "function" && String(value).includes(text);
42
+ } catch {
43
+ return false;
44
+ }
45
+ });
46
+ }
47
+
48
+ function waitFor(filter) {
49
+ for (const [name, value] of core.hostModules) {
50
+ if (filter(value, name)) return Promise.resolve(value);
51
+ }
52
+ return new Promise((resolve) => core.waiters.push({ filter, resolve }));
53
+ }
54
+
55
+ globalObject.CodexPlus.modules = { registerHostModule, findByCode, findByProps, findComponentByCode, waitFor };
56
+ globalObject.CodexPlusHost.register = registerHostModule;
57
+ })();
@@ -0,0 +1,14 @@
1
+ (function () {
2
+ const globalObject = typeof window !== "undefined" ? window : globalThis;
3
+
4
+ async function request(method, params) {
5
+ return globalObject.codexPlusNative?.request?.(method, params) ?? globalObject.CodexPlusHost?.nativeRequest?.(method, params);
6
+ }
7
+
8
+ function registerNativeMenuItem(item) {
9
+ return globalObject.CodexPlus.native.request("native-menu/register-item", item).catch(() => ({ ok: false }));
10
+ }
11
+
12
+ globalObject.CodexPlus.native = { request };
13
+ globalObject.CodexPlus.nativeMenus = { registerItem: registerNativeMenuItem };
14
+ })();
@@ -0,0 +1,31 @@
1
+ (function () {
2
+ const globalObject = typeof window !== "undefined" ? window : globalThis;
3
+ const { core } = globalObject.__CodexPlusRuntime;
4
+
5
+ function register(descriptor) {
6
+ core.patchDescriptors.push(descriptor);
7
+ return descriptor;
8
+ }
9
+
10
+ function apply(source, descriptors = core.patchDescriptors) {
11
+ let output = source;
12
+ for (const descriptor of descriptors) {
13
+ const moduleMatches =
14
+ typeof descriptor.find === "string" ? output.includes(descriptor.find) : descriptor.find.test(output);
15
+ if (!moduleMatches) continue;
16
+ const replacements = Array.isArray(descriptor.replacement) ? descriptor.replacement : [descriptor.replacement];
17
+ const beforeGroup = output;
18
+ let appliedGroup = true;
19
+ for (const replacement of replacements) {
20
+ const before = output;
21
+ output = output.replace(replacement.match, replacement.replace);
22
+ if (before === output) appliedGroup = false;
23
+ }
24
+ if (descriptor.group && !appliedGroup) output = beforeGroup;
25
+ if (!descriptor.all) break;
26
+ }
27
+ return output;
28
+ }
29
+
30
+ globalObject.CodexPlus.patches = { register, apply, all: core.patchDescriptors };
31
+ })();
@@ -0,0 +1,20 @@
1
+ (function () {
2
+ const globalObject = typeof window !== "undefined" ? window : globalThis;
3
+
4
+ function renderBody({ props, deps, defaultBody } = {}) {
5
+ let body = defaultBody;
6
+ for (const wrapper of globalObject.CodexPlus.ui.review.wrappers) {
7
+ body = wrapper({ ...props, mainReviewContent: body }, deps);
8
+ }
9
+ return body;
10
+ }
11
+
12
+ globalObject.CodexPlus.ui.review = {
13
+ wrappers: [],
14
+ wrapBody(wrapper) {
15
+ this.wrappers.push(wrapper);
16
+ return wrapper;
17
+ },
18
+ renderBody,
19
+ };
20
+ })();