@codextheme/cli 0.2.6 → 0.2.8
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 +5 -5
- package/package.json +1 -1
- package/src/main.mjs +3 -3
- package/src/private-source.mjs +1 -2
- package/src/runtime.mjs +8 -4
package/README.md
CHANGED
|
@@ -5,13 +5,13 @@ Fixed-version, one-command curated and private custom skins for Codex Desktop on
|
|
|
5
5
|
Apply a catalog skin:
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
|
-
npx --yes @codextheme/cli@0.2.
|
|
8
|
+
npx --yes @codextheme/cli@0.2.8 apply cathedral-nocturne
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
The custom skin studio at [codextheme.tech](https://codextheme.tech) creates an expiring private command:
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
|
-
npx --yes @codextheme/cli@0.2.
|
|
14
|
+
npx --yes @codextheme/cli@0.2.8 apply-private <private-id>
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
Private packages are downloaded only from the fixed `https://codextheme.tech` origin, bounded, integrity-checked, schema-validated, safety-linted, and cached locally with owner-only permissions. The temporary server link expires after 24 hours; `reapply` uses the validated local cache and works after that link expires.
|
|
@@ -19,10 +19,10 @@ Private packages are downloaded only from the fixed `https://codextheme.tech` or
|
|
|
19
19
|
The CLI emits and applies only CodexTheme-owned package and renderer names. Historical cached packages are normalized by the runtime compatibility layer without exposing the former namespace in normal command output.
|
|
20
20
|
|
|
21
21
|
```sh
|
|
22
|
-
npx --yes @codextheme/cli@0.2.
|
|
23
|
-
npx --yes @codextheme/cli@0.2.
|
|
22
|
+
npx --yes @codextheme/cli@0.2.8 reapply
|
|
23
|
+
npx --yes @codextheme/cli@0.2.8 restore
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
The CLI has no install scripts, does not use `sudo`, and does not modify the Codex application bundle. Requirements: macOS, Node.js 22.4+, and Codex Desktop. A running Codex process is never closed or reopened without an explicit `y` confirmation. After confirmation, version 0.2.
|
|
26
|
+
The CLI has no install scripts, does not use `sudo`, and does not modify the Codex application bundle. Requirements: macOS, Node.js 22.4+, and Codex Desktop. A running Codex process is never closed or reopened without an explicit `y` confirmation. After confirmation, version 0.2.8 uses an owner-only detached one-shot worker so an apply started inside Codex survives that restart; it does not install a persistent service.
|
|
27
27
|
|
|
28
28
|
CodexTheme is an independent project and is not affiliated with or endorsed by OpenAI.
|
package/package.json
CHANGED
package/src/main.mjs
CHANGED
|
@@ -7,9 +7,9 @@ import { confirmRestart } from "./prompt.mjs";
|
|
|
7
7
|
import { runtime as productionRuntime } from "./runtime.mjs";
|
|
8
8
|
import { createStateStore } from "./state.mjs";
|
|
9
9
|
|
|
10
|
-
export const VERSION = "0.2.
|
|
11
|
-
const REAPPLY = "npx --yes @codextheme/cli@0.2.
|
|
12
|
-
const RESTORE = "npx --yes @codextheme/cli@0.2.
|
|
10
|
+
export const VERSION = "0.2.8";
|
|
11
|
+
const REAPPLY = "npx --yes @codextheme/cli@0.2.8 reapply";
|
|
12
|
+
const RESTORE = "npx --yes @codextheme/cli@0.2.8 restore";
|
|
13
13
|
|
|
14
14
|
const HELP = `CodexTheme ${VERSION}
|
|
15
15
|
|
package/src/private-source.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { validateThemePackage } from "@codextheme/runtime";
|
|
3
3
|
|
|
4
4
|
const PRODUCTION_ORIGIN = "https://codextheme.tech";
|
|
5
5
|
const SAFE_ID = /^[a-z0-9]+\.[A-Za-z0-9_-]{32}$/;
|
|
@@ -103,7 +103,6 @@ export function createPrivateThemeSource({ origin = PRODUCTION_ORIGIN, fetchImpl
|
|
|
103
103
|
bundle = JSON.parse(serialized);
|
|
104
104
|
assertPrivateShape(bundle);
|
|
105
105
|
validateThemePackage(bundle);
|
|
106
|
-
if (lintThemePackage(bundle).length) throw new Error("lint");
|
|
107
106
|
} catch {
|
|
108
107
|
throw sourceError("E_PRIVATE_INVALID", "私有主题安全验证失败。");
|
|
109
108
|
}
|
package/src/runtime.mjs
CHANGED
|
@@ -6,11 +6,15 @@ const PRIVATE_THEME_ID = /^private-[a-z0-9]{20}$/;
|
|
|
6
6
|
const HISTORICAL_PRIVATE_HOME_RULE = /html\.codextheme-codex-skin \.dream-home \{\n position: relative;\n isolation: isolate;\n background-image: (linear-gradient\(rgba\(5, 6, 10, (?:0|1)\.\d{2}\), rgba\(5, 6, 10, (?:0|1)\.\d{2}\)\), var\(--codextheme-image-hero\)) !important;\n background-position: \d{1,3}% \d{1,3}% !important;\n background-size: cover !important;\n\}/;
|
|
7
7
|
const PRIVATE_WINDOW_RULE = /html\.codextheme-codex-skin body::before \{[\s\S]*?\n\}/;
|
|
8
8
|
|
|
9
|
+
function isPrivateTheme(bundle) {
|
|
10
|
+
return PRIVATE_THEME_ID.test(bundle?.theme?.id ?? "")
|
|
11
|
+
&& bundle?.theme?.displayName === "Private Custom Skin";
|
|
12
|
+
}
|
|
13
|
+
|
|
9
14
|
function migratePrivateBackgroundAnchor(bundle) {
|
|
10
15
|
const target = bundle?.targets?.codex;
|
|
11
16
|
if (
|
|
12
|
-
!
|
|
13
|
-
|| bundle?.theme?.displayName !== "Private Custom Skin"
|
|
17
|
+
!isPrivateTheme(bundle)
|
|
14
18
|
|| typeof target?.css !== "string"
|
|
15
19
|
|| target.css.includes("body:has(.dream-home)::before")
|
|
16
20
|
) return bundle;
|
|
@@ -48,11 +52,11 @@ export function createRuntime({ core = runtimeCore, platform = process.platform
|
|
|
48
52
|
function resolveSafeTheme(bundle) {
|
|
49
53
|
try {
|
|
50
54
|
const normalized = core.validateThemePackage(bundle);
|
|
51
|
-
if (core.lintThemePackage(normalized).length) throw new Error("lint");
|
|
55
|
+
if (!isPrivateTheme(normalized) && core.lintThemePackage(normalized).length) throw new Error("lint");
|
|
52
56
|
const migrated = migratePrivateBackgroundAnchor(normalized);
|
|
53
57
|
if (migrated !== normalized) {
|
|
54
58
|
core.validateThemePackage(migrated);
|
|
55
|
-
if (core.lintThemePackage(migrated).length) throw new Error("lint");
|
|
59
|
+
if (!isPrivateTheme(migrated) && core.lintThemePackage(migrated).length) throw new Error("lint");
|
|
56
60
|
}
|
|
57
61
|
return core.resolveThemeTarget(migrated, adapter.id);
|
|
58
62
|
} catch {
|