@litfamily/litcodex 1.0.0 → 1.0.2
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 +18 -21
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +2 -38
- package/dist/config-migration/profile-files.d.ts +4 -0
- package/dist/config-migration/profile-files.js +22 -0
- package/dist/install/capability-preflight-error.js +5 -1
- package/dist/install/codex.d.ts +1 -0
- package/dist/install/generated-skill-payload-hashes.d.ts +1 -6
- package/dist/install/generated-skill-payload-hashes.js +1 -6
- package/dist/install/host-capabilities.d.ts +2 -0
- package/dist/install/host-capabilities.js +13 -1
- package/dist/install/index.js +3 -1
- package/dist/install/skill-catalog.d.ts +1 -1
- package/dist/install/skill-catalog.js +1 -6
- package/dist/install/skill-resource-hashes.d.ts +1 -1
- package/dist/install/skill-resource-hashes.js +1 -1
- package/dist/install/strict-config-probe.d.ts +2 -0
- package/dist/install/strict-config-probe.js +34 -5
- package/dist/install/uninstall.d.ts +2 -0
- package/dist/install/uninstall.js +34 -0
- package/marketplace/plugins/litcodex/.codex-plugin/plugin.json +1 -1
- package/marketplace/plugins/litcodex/components/auto-update/package.json +1 -1
- package/marketplace/plugins/litcodex/components/comment-checker/package.json +1 -1
- package/marketplace/plugins/litcodex/components/git-bash/package.json +1 -1
- package/marketplace/plugins/litcodex/components/lit-loop/dist/cli.js +3 -20
- package/marketplace/plugins/litcodex/components/lit-loop/dist/codex-hook.js +1 -8
- package/marketplace/plugins/litcodex/components/lit-loop/dist/hook-cli.d.ts +2 -1
- package/marketplace/plugins/litcodex/components/lit-loop/dist/hook-cli.js +4 -27
- package/marketplace/plugins/litcodex/components/lit-loop/dist/markers.d.ts +0 -2
- package/marketplace/plugins/litcodex/components/lit-loop/dist/markers.js +0 -2
- package/marketplace/plugins/litcodex/components/lit-loop/dist/modes.d.ts +1 -3
- package/marketplace/plugins/litcodex/components/lit-loop/dist/modes.js +1 -10
- package/marketplace/plugins/litcodex/components/lit-loop/package.json +1 -1
- package/marketplace/plugins/litcodex/components/lsp/package.json +1 -1
- package/marketplace/plugins/litcodex/components/rules/dist/static-injection.js +2 -2
- package/marketplace/plugins/litcodex/components/rules/package.json +1 -1
- package/marketplace/plugins/litcodex/components/start-work-continuation/package.json +1 -1
- package/marketplace/plugins/litcodex/components/telemetry/package.json +1 -1
- package/marketplace/plugins/litcodex/components/wikify-knowledge/package.json +1 -1
- package/marketplace/plugins/litcodex/skills/browser-drive/scripts/capability-probe.mjs +13 -5
- package/node_modules/@litcodex/lit-loop/README.md +1 -7
- package/node_modules/@litcodex/lit-loop/dist/cli.js +3 -20
- package/node_modules/@litcodex/lit-loop/dist/codex-hook.js +1 -8
- package/node_modules/@litcodex/lit-loop/dist/hook-cli.d.ts +2 -1
- package/node_modules/@litcodex/lit-loop/dist/hook-cli.js +4 -27
- package/node_modules/@litcodex/lit-loop/dist/markers.d.ts +0 -2
- package/node_modules/@litcodex/lit-loop/dist/markers.js +0 -2
- package/node_modules/@litcodex/lit-loop/dist/modes.d.ts +1 -3
- package/node_modules/@litcodex/lit-loop/dist/modes.js +1 -10
- package/node_modules/@litcodex/lit-loop/package.json +1 -1
- package/node_modules/@litcodex/lit-loop/skills/browser-drive/scripts/capability-probe.mjs +13 -5
- package/package.json +2 -2
- package/readme-assets/badge-version.svg +1 -1
- package/readme-assets/cover-motion.webp +0 -0
- package/marketplace/plugins/litcodex/components/lit-loop/directives/skill-observer.md +0 -105
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/apply.d.ts +0 -16
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/apply.js +0 -227
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/config.d.ts +0 -13
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/config.js +0 -12
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/curator.d.ts +0 -14
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/curator.js +0 -112
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/hook.d.ts +0 -19
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/hook.js +0 -435
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/ownership.d.ts +0 -6
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/ownership.js +0 -145
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/paths.d.ts +0 -18
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/paths.js +0 -43
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/review.d.ts +0 -28
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/review.js +0 -702
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/store.d.ts +0 -32
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/store.js +0 -667
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/transaction.d.ts +0 -26
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/transaction.js +0 -524
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/types.d.ts +0 -81
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/types.js +0 -246
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/usage.d.ts +0 -6
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop/usage.js +0 -119
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop-cli.d.ts +0 -8
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-loop-cli.js +0 -111
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-observer-cli.d.ts +0 -3
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-observer-cli.js +0 -116
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-observer-route.d.ts +0 -6
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-observer-route.js +0 -12
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-observer.d.ts +0 -18
- package/marketplace/plugins/litcodex/components/lit-loop/dist/skill-observer.js +0 -946
- package/marketplace/plugins/litcodex/skills/skill-observer/SKILL.md +0 -215
- package/marketplace/plugins/litcodex/skills/skill-observer/agents/openai.yaml +0 -6
- package/marketplace/plugins/litcodex/skills/skill-observer/references/review-contract.md +0 -77
- package/node_modules/@litcodex/lit-loop/directives/skill-observer.md +0 -105
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/apply.d.ts +0 -16
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/apply.js +0 -227
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/config.d.ts +0 -13
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/config.js +0 -12
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/curator.d.ts +0 -14
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/curator.js +0 -112
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/hook.d.ts +0 -19
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/hook.js +0 -435
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/ownership.d.ts +0 -6
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/ownership.js +0 -145
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/paths.d.ts +0 -18
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/paths.js +0 -43
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/review.d.ts +0 -28
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/review.js +0 -702
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/store.d.ts +0 -32
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/store.js +0 -667
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/transaction.d.ts +0 -26
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/transaction.js +0 -524
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/types.d.ts +0 -81
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/types.js +0 -246
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/usage.d.ts +0 -6
- package/node_modules/@litcodex/lit-loop/dist/skill-loop/usage.js +0 -119
- package/node_modules/@litcodex/lit-loop/dist/skill-loop-cli.d.ts +0 -8
- package/node_modules/@litcodex/lit-loop/dist/skill-loop-cli.js +0 -111
- package/node_modules/@litcodex/lit-loop/dist/skill-observer-cli.d.ts +0 -3
- package/node_modules/@litcodex/lit-loop/dist/skill-observer-cli.js +0 -116
- package/node_modules/@litcodex/lit-loop/dist/skill-observer-route.d.ts +0 -6
- package/node_modules/@litcodex/lit-loop/dist/skill-observer-route.js +0 -12
- package/node_modules/@litcodex/lit-loop/dist/skill-observer.d.ts +0 -18
- package/node_modules/@litcodex/lit-loop/dist/skill-observer.js +0 -946
- package/node_modules/@litcodex/lit-loop/skills/skill-observer/SKILL.md +0 -215
- package/node_modules/@litcodex/lit-loop/skills/skill-observer/references/review-contract.md +0 -77
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
<p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.
|
|
1
|
+
<p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/cover.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/cover-motion.webp" width="100%" alt="LitCodex cover art. An orange signal moves through orbital paths above the CODEX CLI wordmark. The static family cover appears for reduced-motion preference." /></picture></p>
|
|
2
|
+
<p align="center"><a href="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/cover.webp">View the static cover</a></p>
|
|
2
3
|
|
|
3
|
-
<p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.
|
|
4
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/ascii-readme.svg" width="480" alt="LIT ASCII B mark" /></p>
|
|
4
5
|
|
|
5
6
|
<details>
|
|
6
7
|
<summary>Copy ASCII logo</summary>
|
|
@@ -32,12 +33,12 @@ LIT · codex
|
|
|
32
33
|
</details>
|
|
33
34
|
|
|
34
35
|
<p align="center">
|
|
35
|
-
<a href="#install"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.
|
|
36
|
-
<a href="https://github.com/wjgoarxiv/litcodex/blob/main/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.
|
|
36
|
+
<a href="#install"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/badge-version.svg" alt="1.0.2" /></a>
|
|
37
|
+
<a href="https://github.com/wjgoarxiv/litcodex/blob/main/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/badge-license.svg" alt="MIT license" /></a>
|
|
37
38
|
</p>
|
|
38
39
|
|
|
39
40
|
<p align="center">
|
|
40
|
-
<a href="https://github.com/wjgoarxiv/litcodex/blob/main/docs/usage.md"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.
|
|
41
|
+
<a href="https://github.com/wjgoarxiv/litcodex/blob/main/docs/usage.md"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/lucide-book-open.svg" width="16" alt="" /> Docs</a> <a href="#install">Install</a> <a href="https://github.com/wjgoarxiv/litcodex/blob/main/docs/assets/readme/ignition-film.mp4"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/lucide-play.svg" width="16" alt="" /> Ignition</a> <a href="https://github.com/wjgoarxiv/litcodex/blob/main/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/lucide-shield-check.svg" width="16" alt="" /> MIT</a>
|
|
41
42
|
</p>
|
|
42
43
|
|
|
43
44
|
# @litfamily/litcodex
|
|
@@ -79,7 +80,7 @@ Append `lit` to a prompt to activate the Codex CLI hook. It routes the request i
|
|
|
79
80
|
|
|
80
81
|
The hook is an entry signal; it does not prove that a model result or visual check completed.
|
|
81
82
|
|
|
82
|
-
<p align="center"><a href="https://github.com/wjgoarxiv/litcodex/blob/main/docs/assets/readme/ignition-film.mp4"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.
|
|
83
|
+
<p align="center"><a href="https://github.com/wjgoarxiv/litcodex/blob/main/docs/assets/readme/ignition-film.mp4"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/ignition-poster.png" width="720" alt="Ignition motion poster" /></a></p>
|
|
83
84
|
|
|
84
85
|
Select the poster for the optional film; this README keeps motion opt-in.
|
|
85
86
|
|
|
@@ -93,30 +94,30 @@ Host limit: Codex CLI owns hook and agent execution, while authentication, model
|
|
|
93
94
|
and any visual check remain host capabilities. A route mark or static editorial image is not completion
|
|
94
95
|
evidence.
|
|
95
96
|
|
|
96
|
-
<p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.
|
|
97
|
+
<p align="center"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/litcodex-ignition-1600.webp" width="49%" alt="LitCodex ignition editorial cue" /> <img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/litcodex-continuity-1600.webp" width="49%" alt="LitCodex continuity editorial cue" /></p>
|
|
97
98
|
|
|
98
99
|
## What is LitCodex
|
|
99
100
|
|
|
100
101
|
LitCodex adds planning, review, research, and a durable execution loop to Codex CLI. Its `UserPromptSubmit`
|
|
101
|
-
hook routes your request into the right discipline; the bundled library provides
|
|
102
|
+
hook routes your request into the right discipline; the bundled library provides 38 skills. A goal is complete
|
|
102
103
|
only after every success criterion passes. The npm package is self-contained and installs without a GitHub clone.
|
|
103
104
|
|
|
104
105
|
## Install
|
|
105
106
|
|
|
106
|
-
> Install `@litfamily/litcodex@1.0.
|
|
107
|
+
> Install `@litfamily/litcodex@1.0.2` with the scoped command below. See [migration guidance](https://github.com/wjgoarxiv/litcodex/blob/main/docs/npm-migration.md).
|
|
107
108
|
|
|
108
109
|
With **Node.js 22+** and **Codex CLI** installed, run:
|
|
109
110
|
|
|
110
111
|
```sh
|
|
111
|
-
npm exec --yes --package @litfamily/litcodex@1.0.
|
|
112
|
+
npm exec --yes --package @litfamily/litcodex@1.0.2 -- litcodex install
|
|
112
113
|
```
|
|
113
114
|
|
|
114
115
|
The installer registers the plugin, hooks, and agents, then updates managed keys in `~/.codex/config.toml`.
|
|
115
116
|
It asks for the lead model, helper model, and output style. Codex authentication and model access are required
|
|
116
117
|
when you run model work; installation itself does not require GitHub credentials.
|
|
117
118
|
|
|
118
|
-
Preview changes with `npm exec --yes --package @litfamily/litcodex@1.0.
|
|
119
|
-
`npm exec --yes --package @litfamily/litcodex@1.0.
|
|
119
|
+
Preview changes with `npm exec --yes --package @litfamily/litcodex@1.0.2 -- litcodex --dry-run install`. For unattended setup, use
|
|
120
|
+
`npm exec --yes --package @litfamily/litcodex@1.0.2 -- litcodex install --yes`. An explicit `--style <id>` still applies.
|
|
120
121
|
|
|
121
122
|
For a persistent command:
|
|
122
123
|
|
|
@@ -125,7 +126,7 @@ npm install -g @litfamily/litcodex
|
|
|
125
126
|
litcodex install
|
|
126
127
|
```
|
|
127
128
|
|
|
128
|
-
> Without a global install, use `npm exec --yes --package @litfamily/litcodex@1.0.
|
|
129
|
+
> Without a global install, use `npm exec --yes --package @litfamily/litcodex@1.0.2 -- litcodex <command>`, such as `npm exec --yes --package @litfamily/litcodex@1.0.2 -- litcodex doctor`.
|
|
129
130
|
|
|
130
131
|
For an isolated trial apart from existing settings, follow the [isolated trial guide](https://github.com/wjgoarxiv/litcodex/blob/main/docs/npm-migration.md#isolated-local-trial).
|
|
131
132
|
Changing only `CODEX_HOME` can still discover settings in your existing home.
|
|
@@ -205,8 +206,6 @@ from the Codex picker or with a scoped mention, including `$litcodex:lit-handoff
|
|
|
205
206
|
| `litcodex uninstall` | Remove the plugin and LitCodex-managed config |
|
|
206
207
|
| `litcodex config migrate` | Preview or apply managed Codex config keys |
|
|
207
208
|
| `litcodex hook user-prompt-submit` | Run the host hook entrypoint |
|
|
208
|
-
| `litcodex observer` | Record one proposal from bounded JSON on stdin |
|
|
209
|
-
| `litcodex skill-loop <command>` | Review, approve, reject, roll back, or curate agent-owned skill proposals |
|
|
210
209
|
| `litcodex loop create` | Derive goals and criteria from a brief |
|
|
211
210
|
| `litcodex loop status --json` | Inspect loop state as JSON |
|
|
212
211
|
| `litcodex loop run` | Select the next runnable goal |
|
|
@@ -226,7 +225,7 @@ See [state and recovery](https://github.com/wjgoarxiv/litcodex/blob/main/docs/us
|
|
|
226
225
|
## Verify it worked
|
|
227
226
|
|
|
228
227
|
```sh
|
|
229
|
-
npm exec --yes --package @litfamily/litcodex@1.0.
|
|
228
|
+
npm exec --yes --package @litfamily/litcodex@1.0.2 -- litcodex doctor
|
|
230
229
|
```
|
|
231
230
|
|
|
232
231
|
`litcodex doctor` checks registration, hooks, config, and host capabilities. `litcodex loop doctor` checks
|
|
@@ -236,8 +235,6 @@ project loop state. A successful installation check does not prove authenticated
|
|
|
236
235
|
|
|
237
236
|
- Plans and evidence stay reviewable. No criterion is marked complete merely because a test command ran.
|
|
238
237
|
- Installation preserves unrelated Codex settings. Preview changes before `--reconfigure`.
|
|
239
|
-
- Skill learning requires explicit review and apply; `autoApply` stays `false`. Only marked agent-owned skills
|
|
240
|
-
may be changed. [Approval, rollback, and recovery rules](https://github.com/wjgoarxiv/litcodex/blob/main/docs/usage.md#skill-learning-loop).
|
|
241
238
|
- The doctor diagnostic core never modifies Codex config, install state, or plugin state. An eligible interactive
|
|
242
239
|
doctor may show a cached advisory notice. Its detached worker performs a fixed registry refresh at
|
|
243
240
|
`~/.litcodex/update-check.json`; that worker never installs packages.
|
|
@@ -259,7 +256,7 @@ project loop state. A successful installation check does not prove authenticated
|
|
|
259
256
|
## Uninstall
|
|
260
257
|
|
|
261
258
|
```sh
|
|
262
|
-
npm exec --yes --package @litfamily/litcodex@1.0.
|
|
259
|
+
npm exec --yes --package @litfamily/litcodex@1.0.2 -- litcodex uninstall
|
|
263
260
|
```
|
|
264
261
|
|
|
265
262
|
`litcodex uninstall` removes the plugin and LitCodex-managed config while preserving unrelated settings.
|
|
@@ -274,7 +271,7 @@ npm exec --yes --package @litfamily/litcodex@1.0.0 -- litcodex uninstall
|
|
|
274
271
|
The bundled skill library also includes `autoconference`, `autoresearch`, `browser-drive`, `coding-session-audit`,
|
|
275
272
|
`comment-checker`, `debugging`, `frontend-ui-ux`, `lit-commit`, `lit-crucible`, `lit-init`, `lit-korean`, `lit-fetch`,
|
|
276
273
|
`litcodex-contribute-bug-fix`, `litcodex-doctor`, `litcodex-report-bug`, `lsp`, `lsp-setup`, `lit-code`, `refactor`,
|
|
277
|
-
`lit-burnoff`, `
|
|
274
|
+
`lit-burnoff`, `structural-search`, `lit-team`, `visual-qa`, and `wikify`.
|
|
278
275
|
|
|
279
276
|
Tests, fixtures, test helpers, and Vitest configuration remain tracked repository coverage and are excluded from npm and installed marketplace payloads.
|
|
280
277
|
|
|
@@ -284,7 +281,7 @@ Tests, fixtures, test helpers, and Vitest configuration remain tracked repositor
|
|
|
284
281
|
|
|
285
282
|
Select the poster to watch the 10-second film.
|
|
286
283
|
|
|
287
|
-
<p align="center"><a href="https://github.com/wjgoarxiv/litcodex/blob/main/docs/assets/readme/ignition-film.mp4"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.
|
|
284
|
+
<p align="center"><a href="https://github.com/wjgoarxiv/litcodex/blob/main/docs/assets/readme/ignition-film.mp4"><img src="https://cdn.jsdelivr.net/npm/@litfamily/litcodex@1.0.2/readme-assets/ignition-poster.png" width="720" alt="Ignition motion graphic poster" /></a></p>
|
|
288
285
|
|
|
289
286
|
[Animated GIF](https://github.com/wjgoarxiv/litcodex/blob/main/docs/assets/readme/ignition-readme.gif) · [Media and icon credits](https://github.com/wjgoarxiv/litcodex/blob/main/docs/assets/readme/README.md)
|
|
290
287
|
|
package/dist/cli.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare function dispatch(argv: readonly string[]): DispatchResult;
|
|
|
17
17
|
/**
|
|
18
18
|
* Async process entry used by `bin/litcodex.js`. It owns the side-effecting routes: install/doctor/
|
|
19
19
|
* uninstall (install/* modules, which are the ONLY code that ever spawns `codex`), `config migrate`
|
|
20
|
-
* (M13, in-process), and the bundled `@litcodex/lit-loop` runtime routes `loop`/`hook
|
|
20
|
+
* (M13, in-process), and the bundled `@litcodex/lit-loop` runtime routes `loop`/`hook`. Returns the
|
|
21
21
|
* integer exit code; the bin owns `process.exit`. No forwarding, no exec-wrapper, no harness.
|
|
22
22
|
*/
|
|
23
23
|
export declare function runCli(argv: readonly string[]): Promise<number>;
|
package/dist/cli.js
CHANGED
|
@@ -55,19 +55,7 @@ const ROUTES = {
|
|
|
55
55
|
config: configRouteHandler,
|
|
56
56
|
loop: () => ok("litcodex loop\n"),
|
|
57
57
|
hook: () => ok("litcodex hook\n"),
|
|
58
|
-
observer: observerRouteHandler,
|
|
59
|
-
"skill-loop": () => ok("litcodex skill-loop\n"),
|
|
60
58
|
};
|
|
61
|
-
function observerRouteHandler(rest, dryRun) {
|
|
62
|
-
if (dryRun || rest.length > 0) {
|
|
63
|
-
return {
|
|
64
|
-
stdout: "",
|
|
65
|
-
stderr: "litcodex observer: this command accepts no arguments.\n",
|
|
66
|
-
exitCode: CONFIG_USAGE_EXIT_CODE,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
return ok("litcodex observer\n");
|
|
70
|
-
}
|
|
71
59
|
/**
|
|
72
60
|
* Synchronous arm of the `config` route. The real `config migrate` work is async and is run by
|
|
73
61
|
* `runCli` BEFORE `dispatch`; this sync handler only handles routing-level outcomes: an unknown
|
|
@@ -96,8 +84,6 @@ function renderHelp() {
|
|
|
96
84
|
" litcodex config migrate Migrate Codex config for LitCodex",
|
|
97
85
|
" litcodex loop <sub> Run a Lit-Loop subcommand",
|
|
98
86
|
" litcodex hook user-prompt-submit Run the UserPromptSubmit hook",
|
|
99
|
-
" litcodex observer Record one proposal from bounded stdin",
|
|
100
|
-
" litcodex skill-loop <sub> Review, apply, reject, or roll back skill proposals",
|
|
101
87
|
" litcodex --dry-run <command> Resolve a command without applying it",
|
|
102
88
|
" litcodex --help Show this help",
|
|
103
89
|
" litcodex --version Show the @litfamily/litcodex version",
|
|
@@ -167,7 +153,7 @@ export function dispatch(argv) {
|
|
|
167
153
|
/**
|
|
168
154
|
* Async process entry used by `bin/litcodex.js`. It owns the side-effecting routes: install/doctor/
|
|
169
155
|
* uninstall (install/* modules, which are the ONLY code that ever spawns `codex`), `config migrate`
|
|
170
|
-
* (M13, in-process), and the bundled `@litcodex/lit-loop` runtime routes `loop`/`hook
|
|
156
|
+
* (M13, in-process), and the bundled `@litcodex/lit-loop` runtime routes `loop`/`hook`. Returns the
|
|
171
157
|
* integer exit code; the bin owns `process.exit`. No forwarding, no exec-wrapper, no harness.
|
|
172
158
|
*/
|
|
173
159
|
export async function runCli(argv) {
|
|
@@ -176,28 +162,6 @@ export async function runCli(argv) {
|
|
|
176
162
|
const head = rest[0];
|
|
177
163
|
const isHelp = rest.includes("--help") || rest.includes("-h");
|
|
178
164
|
const isVersion = rest.includes("--version") || rest.includes("-v");
|
|
179
|
-
if (!isHelp && !isVersion && head === "observer") {
|
|
180
|
-
const observerResult = observerRouteHandler(rest.slice(1), dryRun);
|
|
181
|
-
if (observerResult.exitCode !== 0)
|
|
182
|
-
return dispatchExit(observerResult);
|
|
183
|
-
const { runSkillObserverCli } = await import("@litcodex/lit-loop/dist/skill-observer-cli.js");
|
|
184
|
-
return runSkillObserverCli(process.stdin, process.stdout, process.stderr);
|
|
185
|
-
}
|
|
186
|
-
if (!isHelp && !isVersion && head === "skill-loop") {
|
|
187
|
-
if (dryRun)
|
|
188
|
-
return dispatchExit({
|
|
189
|
-
stdout: "",
|
|
190
|
-
stderr: "litcodex skill-loop: --dry-run is not supported.\n",
|
|
191
|
-
exitCode: 64,
|
|
192
|
-
});
|
|
193
|
-
const { skillLoopCommand } = await import("@litcodex/lit-loop/dist/skill-loop-cli.js");
|
|
194
|
-
return skillLoopCommand(rest.slice(1), {
|
|
195
|
-
cwd: process.cwd(),
|
|
196
|
-
env: process.env,
|
|
197
|
-
stdout: process.stdout,
|
|
198
|
-
stderr: process.stderr,
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
165
|
if (!isHelp && !isVersion) {
|
|
202
166
|
if (head === "config" && rest[1] === "migrate") {
|
|
203
167
|
const passthrough = dryRun ? [...rest.slice(2), "--dry-run"] : rest.slice(2);
|
|
@@ -231,7 +195,7 @@ export async function runCli(argv) {
|
|
|
231
195
|
}
|
|
232
196
|
const hooks = await import("@litcodex/lit-loop/dist/hook-cli.js");
|
|
233
197
|
return rest[1] === "stop"
|
|
234
|
-
? hooks.
|
|
198
|
+
? hooks.runStopPlanPersistenceHookCli(process.stdin, process.stdout, process.stderr)
|
|
235
199
|
: hooks.runUserPromptSubmitHookCli(process.stdin, process.stdout, process.stderr);
|
|
236
200
|
}
|
|
237
201
|
}
|
|
@@ -9,3 +9,7 @@ export declare function ensureGpt56ProfileFiles(args: {
|
|
|
9
9
|
readonly reconfigure: boolean;
|
|
10
10
|
readonly modelContexts?: Gpt56ModelContexts;
|
|
11
11
|
}): Promise<ProfileFileResult>;
|
|
12
|
+
/** The per-model profile file names LitCodex may write directly under `codexHome`. */
|
|
13
|
+
export declare const GPT56_PROFILE_FILE_NAMES: readonly string[];
|
|
14
|
+
/** True when `content` is exactly what LitCodex would have written for `name` (bare, or with the limits it still recognizes as its own). Used by uninstall to remove only files it authored. */
|
|
15
|
+
export declare function isManagedGpt56ProfileContent(name: string, content: string): boolean;
|
|
@@ -56,6 +56,28 @@ function profileContent() {
|
|
|
56
56
|
"gpt56-luna-max.config.toml": renderProfile(GPT56_MODELS.luna, "max"),
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
+
/** The per-model profile file names LitCodex may write directly under `codexHome`. */
|
|
60
|
+
export const GPT56_PROFILE_FILE_NAMES = Object.keys(profileContent());
|
|
61
|
+
/** True when `content` is exactly what LitCodex would have written for `name` (bare, or with the limits it still recognizes as its own). Used by uninstall to remove only files it authored. */
|
|
62
|
+
export function isManagedGpt56ProfileContent(name, content) {
|
|
63
|
+
const desired = profileContent()[name];
|
|
64
|
+
if (desired === undefined)
|
|
65
|
+
return false;
|
|
66
|
+
if (content === desired)
|
|
67
|
+
return true;
|
|
68
|
+
switch (name) {
|
|
69
|
+
case "gpt56-sol-high.config.toml":
|
|
70
|
+
return isExactGeneratedExplicitSolProfile(content);
|
|
71
|
+
case "gpt56-terra-high.config.toml":
|
|
72
|
+
return isExactGeneratedTerraProfile(content);
|
|
73
|
+
case "gpt56-luna-max.config.toml":
|
|
74
|
+
return isExactGeneratedLunaProfile(content);
|
|
75
|
+
case "gpt6-astra-xhigh.config.toml":
|
|
76
|
+
return isExactGeneratedAstraProfile(content);
|
|
77
|
+
default:
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
59
81
|
function renderProfile(model, effort) {
|
|
60
82
|
return `model = ${JSON.stringify(model)}\nmodel_reasoning_effort = ${JSON.stringify(effort)}\n`;
|
|
61
83
|
}
|
|
@@ -27,7 +27,11 @@ export function capabilityPreflightError(capabilities, codexBin) {
|
|
|
27
27
|
// When that also fails, the existing Codex configuration on this machine is what
|
|
28
28
|
// the resolved binary cannot load, and LitCodex's managed settings are innocent.
|
|
29
29
|
if (reason === "host-config-incompatible") {
|
|
30
|
-
|
|
30
|
+
const detail = capabilities.concurrency.detail;
|
|
31
|
+
const explanation = detail === undefined
|
|
32
|
+
? " This usually means that Codex is older than the one that last wrote the configuration."
|
|
33
|
+
: ` Codex reported: ${detail}.`;
|
|
34
|
+
return new InstallError("LITCODEX_INSTALL_HOST_CONFIG_INCOMPATIBLE", `The existing Codex configuration on this machine could not be loaded by the Codex that ran, with or without LitCodex settings; no install mutation was attempted.${resolved}${explanation}`, { capabilities });
|
|
31
35
|
}
|
|
32
36
|
return new InstallError("LITCODEX_INSTALL_CONFIG_WRITE_FAILED", `Codex strict config rejected LitCodex managed settings; no install mutation was attempted.${resolved}`, { capabilities });
|
|
33
37
|
}
|
package/dist/install/codex.d.ts
CHANGED
|
@@ -6,12 +6,7 @@ export declare const BROWSER_DRIVE_PAYLOAD_HASHES: {
|
|
|
6
6
|
readonly "SKILL.md": "74f89ce0b7462e397952ac9d074b8a29a0133cccbc3e7179e8ec63128d88724f";
|
|
7
7
|
readonly "agents/openai.yaml": "1b9a859e2da403ffc3a526b3d36e9bd6bfd95af087b7ec4ae71f6b615ced7828";
|
|
8
8
|
readonly "references/snapshot-act-loop.md": "7aff2f4145413d61aaac577c2e551e3ed11a14b78dd46d047409c91a522ece1f";
|
|
9
|
-
readonly "scripts/capability-probe.mjs": "
|
|
10
|
-
};
|
|
11
|
-
export declare const SKILL_OBSERVER_PAYLOAD_HASHES: {
|
|
12
|
-
readonly "SKILL.md": "e56a3dd538f2e986f19abbc360f8902551a06e4c38903114ceb2ffba6681458d";
|
|
13
|
-
readonly "agents/openai.yaml": "584a177dd2db92fdeb5a742643de035ff0932dd75cb01192953852df02fad3fe";
|
|
14
|
-
readonly "references/review-contract.md": "f55dc8334f3b8d8498c84d57725fa03af8fbd689b2dd7cce25e49931629ee54f";
|
|
9
|
+
readonly "scripts/capability-probe.mjs": "95bac59fd820e5a1e1d7f43e984ddf9f8ffdcb10b4803d566afe06be316ad953";
|
|
15
10
|
};
|
|
16
11
|
export declare const FRONTEND_UIUX_PAYLOAD_HASHES: {
|
|
17
12
|
readonly "SKILL.md": "b5fdb88106a0e23112686b120f4da0f250ac66c8909afaafbdf00f0ae823c88b";
|
|
@@ -7,12 +7,7 @@ export const BROWSER_DRIVE_PAYLOAD_HASHES = {
|
|
|
7
7
|
"SKILL.md": "74f89ce0b7462e397952ac9d074b8a29a0133cccbc3e7179e8ec63128d88724f",
|
|
8
8
|
"agents/openai.yaml": "1b9a859e2da403ffc3a526b3d36e9bd6bfd95af087b7ec4ae71f6b615ced7828",
|
|
9
9
|
"references/snapshot-act-loop.md": "7aff2f4145413d61aaac577c2e551e3ed11a14b78dd46d047409c91a522ece1f",
|
|
10
|
-
"scripts/capability-probe.mjs": "
|
|
11
|
-
};
|
|
12
|
-
export const SKILL_OBSERVER_PAYLOAD_HASHES = {
|
|
13
|
-
"SKILL.md": "e56a3dd538f2e986f19abbc360f8902551a06e4c38903114ceb2ffba6681458d",
|
|
14
|
-
"agents/openai.yaml": "584a177dd2db92fdeb5a742643de035ff0932dd75cb01192953852df02fad3fe",
|
|
15
|
-
"references/review-contract.md": "f55dc8334f3b8d8498c84d57725fa03af8fbd689b2dd7cce25e49931629ee54f",
|
|
10
|
+
"scripts/capability-probe.mjs": "95bac59fd820e5a1e1d7f43e984ddf9f8ffdcb10b4803d566afe06be316ad953",
|
|
16
11
|
};
|
|
17
12
|
export const FRONTEND_UIUX_PAYLOAD_HASHES = {
|
|
18
13
|
"SKILL.md": "b5fdb88106a0e23112686b120f4da0f250ac66c8909afaafbdf00f0ae823c88b",
|
|
@@ -7,6 +7,8 @@ export interface CapabilityReport {
|
|
|
7
7
|
readonly reason: string;
|
|
8
8
|
readonly observedSource: string;
|
|
9
9
|
readonly limit?: number;
|
|
10
|
+
/** Extra diagnostic text observed from Codex itself: a startup warning on acceptance, or the doctor-reported failure detail on host-config-incompatible rejection. */
|
|
11
|
+
readonly detail?: string;
|
|
10
12
|
}
|
|
11
13
|
export interface HostCapabilities {
|
|
12
14
|
readonly concurrency: CapabilityReport;
|
|
@@ -64,6 +64,10 @@ export function probeHostCapabilities(codexBin, spawn, selection = {}) {
|
|
|
64
64
|
hostConfigRejected: baselineProbe?.kind === "rejected",
|
|
65
65
|
timedOut: isTimeout(versionResult) || rootProbe.kind === "timeout",
|
|
66
66
|
versionSupport,
|
|
67
|
+
...(rootProbe.kind === "accepted" && rootProbe.warning !== undefined ? { rootWarning: rootProbe.warning } : {}),
|
|
68
|
+
...(baselineProbe?.kind === "rejected" && baselineProbe.detail !== undefined
|
|
69
|
+
? { hostConfigDetail: baselineProbe.detail }
|
|
70
|
+
: {}),
|
|
67
71
|
});
|
|
68
72
|
return {
|
|
69
73
|
concurrency,
|
|
@@ -99,14 +103,21 @@ function concurrencyReport(args) {
|
|
|
99
103
|
}
|
|
100
104
|
if (!args.rootAccepted) {
|
|
101
105
|
const reason = args.hostConfigRejected === true ? "host-config-incompatible" : "strict-config-rejected";
|
|
102
|
-
return {
|
|
106
|
+
return {
|
|
107
|
+
status: "unavailable",
|
|
108
|
+
reason,
|
|
109
|
+
observedSource,
|
|
110
|
+
...(args.hostConfigDetail === undefined ? {} : { detail: args.hostConfigDetail }),
|
|
111
|
+
};
|
|
103
112
|
}
|
|
113
|
+
const detail = args.rootWarning === undefined ? {} : { detail: args.rootWarning };
|
|
104
114
|
if (args.versionSupport.kind === "newer-stable") {
|
|
105
115
|
return {
|
|
106
116
|
status: "advisory",
|
|
107
117
|
limit: HARD_CONCURRENCY_LIMIT,
|
|
108
118
|
reason: "strict config accepted on a newer stable Codex; configured concurrency is usable but runtime enforcement is not yet source-verified",
|
|
109
119
|
observedSource,
|
|
120
|
+
...detail,
|
|
110
121
|
};
|
|
111
122
|
}
|
|
112
123
|
return {
|
|
@@ -114,6 +125,7 @@ function concurrencyReport(args) {
|
|
|
114
125
|
limit: HARD_CONCURRENCY_LIMIT,
|
|
115
126
|
reason: "strict-config accepted the reserved collaboration schema, max_concurrent_threads_per_session=20, and agents.max_depth=1",
|
|
116
127
|
observedSource,
|
|
128
|
+
...detail,
|
|
117
129
|
};
|
|
118
130
|
}
|
|
119
131
|
function autoCompactionReport(args) {
|
package/dist/install/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// argv into typed `InstallOptions`, and return an integer exit code. `--dry-run` returns BEFORE any
|
|
6
6
|
// spawn or fs write (renders the plan only). Unknown/bad flags exit 1.
|
|
7
7
|
import { spawnSync } from "node:child_process";
|
|
8
|
-
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, rmdirSync, rmSync, writeFileSync } from "node:fs";
|
|
9
9
|
import { createRequire } from "node:module";
|
|
10
10
|
import { join } from "node:path";
|
|
11
11
|
import readline from "node:readline/promises";
|
|
@@ -40,6 +40,7 @@ const realSpawn = (cmd, args, opts) => {
|
|
|
40
40
|
shell: invocation.shell,
|
|
41
41
|
windowsVerbatimArguments: invocation.windowsVerbatimArguments || opts.windowsVerbatimArguments === true,
|
|
42
42
|
...(opts.env === undefined ? {} : { env: opts.env }),
|
|
43
|
+
...(opts.cwd === undefined ? {} : { cwd: opts.cwd }),
|
|
43
44
|
});
|
|
44
45
|
const out = {
|
|
45
46
|
status: res.status,
|
|
@@ -384,6 +385,7 @@ export function runUninstallCli(args, io = defaultIo()) {
|
|
|
384
385
|
existsSync,
|
|
385
386
|
readdirSync: (path) => readdirSync(path),
|
|
386
387
|
rmSync,
|
|
388
|
+
rmdirSync: (path) => rmdirSync(path),
|
|
387
389
|
readFileSync: (path, enc) => readFileSync(path, enc),
|
|
388
390
|
writeFileSync: (path, data) => {
|
|
389
391
|
writeFileSync(path, data);
|
|
@@ -6,7 +6,7 @@ import type { ReadonlyFsLike } from "./codex.js";
|
|
|
6
6
|
* marketplace has every supported skill entry point, while the companion test
|
|
7
7
|
* compares it with the repository's package contract.
|
|
8
8
|
*/
|
|
9
|
-
export declare const CANONICAL_SKILL_IDS: readonly ["autoconference", "autoresearch", "browser-drive", "coding-session-audit", "comment-checker", "debugging", "deep-interview", "frontend-ui-ux", "lit-burnoff", "lit-burnoff-file", "lit-code", "lit-commit", "lit-comprehend", "lit-crucible", "lit-fetch", "lit-handoff", "lit-init", "lit-korean", "lit-loop", "lit-plan", "lit-recap", "lit-scientific-visualization", "lit-team", "litcodex-contribute-bug-fix", "litcodex-doctor", "litcodex-report-bug", "litgoal", "litresearch", "litwork", "lsp", "lsp-setup", "refactor", "review-work", "rules", "
|
|
9
|
+
export declare const CANONICAL_SKILL_IDS: readonly ["autoconference", "autoresearch", "browser-drive", "coding-session-audit", "comment-checker", "debugging", "deep-interview", "frontend-ui-ux", "lit-burnoff", "lit-burnoff-file", "lit-code", "lit-commit", "lit-comprehend", "lit-crucible", "lit-fetch", "lit-handoff", "lit-init", "lit-korean", "lit-loop", "lit-plan", "lit-recap", "lit-scientific-visualization", "lit-team", "litcodex-contribute-bug-fix", "litcodex-doctor", "litcodex-report-bug", "litgoal", "litresearch", "litwork", "lsp", "lsp-setup", "refactor", "review-work", "rules", "start-work", "structural-search", "visual-qa", "wikify"];
|
|
10
10
|
export declare const CANONICAL_SKILL_RESOURCE_PATHS: readonly ["lsp/references/runtime-triage.md", ...string[]];
|
|
11
11
|
export interface SkillCatalogPayloadReport {
|
|
12
12
|
readonly complete: boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { payloadExact } from "./bundled-skills.js";
|
|
3
|
-
import { AUTOCONFERENCE_PAYLOAD_HASHES, AUTORESEARCH_PAYLOAD_HASHES, BROWSER_DRIVE_PAYLOAD_HASHES, CODING_SESSION_AUDIT_PAYLOAD_HASHES, DEEP_INTERVIEW_PAYLOAD_HASHES, FRONTEND_UIUX_PAYLOAD_HASHES,
|
|
3
|
+
import { AUTOCONFERENCE_PAYLOAD_HASHES, AUTORESEARCH_PAYLOAD_HASHES, BROWSER_DRIVE_PAYLOAD_HASHES, CODING_SESSION_AUDIT_PAYLOAD_HASHES, DEEP_INTERVIEW_PAYLOAD_HASHES, FRONTEND_UIUX_PAYLOAD_HASHES, STRUCTURAL_SEARCH_PAYLOAD_HASHES, VISUAL_QA_PAYLOAD_HASHES, WIKIFY_PAYLOAD_HASHES, } from "./skill-resource-hashes.js";
|
|
4
4
|
/**
|
|
5
5
|
* The Codex-native skill directories shipped in the LitCodex marketplace payload.
|
|
6
6
|
*
|
|
@@ -43,7 +43,6 @@ export const CANONICAL_SKILL_IDS = [
|
|
|
43
43
|
"refactor",
|
|
44
44
|
"review-work",
|
|
45
45
|
"rules",
|
|
46
|
-
"skill-observer",
|
|
47
46
|
"start-work",
|
|
48
47
|
"structural-search",
|
|
49
48
|
"visual-qa",
|
|
@@ -66,9 +65,6 @@ export const CANONICAL_SKILL_RESOURCE_PATHS = [
|
|
|
66
65
|
...Object.keys(FRONTEND_UIUX_PAYLOAD_HASHES)
|
|
67
66
|
.filter((path) => path !== "SKILL.md")
|
|
68
67
|
.map((path) => `frontend-ui-ux/${path}`),
|
|
69
|
-
...Object.keys(SKILL_OBSERVER_PAYLOAD_HASHES)
|
|
70
|
-
.filter((path) => path !== "SKILL.md")
|
|
71
|
-
.map((path) => `skill-observer/${path}`),
|
|
72
68
|
...Object.keys(VISUAL_QA_PAYLOAD_HASHES)
|
|
73
69
|
.filter((path) => path !== "SKILL.md")
|
|
74
70
|
.map((path) => `visual-qa/${path}`),
|
|
@@ -93,7 +89,6 @@ export function probeSkillCatalogPayload(fs, marketplaceRoot) {
|
|
|
93
89
|
["browser-drive", BROWSER_DRIVE_PAYLOAD_HASHES],
|
|
94
90
|
["deep-interview", DEEP_INTERVIEW_PAYLOAD_HASHES],
|
|
95
91
|
["frontend-ui-ux", FRONTEND_UIUX_PAYLOAD_HASHES],
|
|
96
|
-
["skill-observer", SKILL_OBSERVER_PAYLOAD_HASHES],
|
|
97
92
|
["visual-qa", VISUAL_QA_PAYLOAD_HASHES],
|
|
98
93
|
["structural-search", STRUCTURAL_SEARCH_PAYLOAD_HASHES],
|
|
99
94
|
["coding-session-audit", CODING_SESSION_AUDIT_PAYLOAD_HASHES],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { AUTOCONFERENCE_PAYLOAD_HASHES, AUTORESEARCH_PAYLOAD_HASHES, BROWSER_DRIVE_PAYLOAD_HASHES, CODING_SESSION_AUDIT_PAYLOAD_HASHES, DEEP_INTERVIEW_PAYLOAD_HASHES, FRONTEND_UIUX_PAYLOAD_HASHES,
|
|
1
|
+
export { AUTOCONFERENCE_PAYLOAD_HASHES, AUTORESEARCH_PAYLOAD_HASHES, BROWSER_DRIVE_PAYLOAD_HASHES, CODING_SESSION_AUDIT_PAYLOAD_HASHES, DEEP_INTERVIEW_PAYLOAD_HASHES, FRONTEND_UIUX_PAYLOAD_HASHES, STRUCTURAL_SEARCH_PAYLOAD_HASHES, VISUAL_QA_PAYLOAD_HASHES, WIKIFY_PAYLOAD_HASHES, } from "./generated-skill-payload-hashes.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { AUTOCONFERENCE_PAYLOAD_HASHES, AUTORESEARCH_PAYLOAD_HASHES, BROWSER_DRIVE_PAYLOAD_HASHES, CODING_SESSION_AUDIT_PAYLOAD_HASHES, DEEP_INTERVIEW_PAYLOAD_HASHES, FRONTEND_UIUX_PAYLOAD_HASHES,
|
|
1
|
+
export { AUTOCONFERENCE_PAYLOAD_HASHES, AUTORESEARCH_PAYLOAD_HASHES, BROWSER_DRIVE_PAYLOAD_HASHES, CODING_SESSION_AUDIT_PAYLOAD_HASHES, DEEP_INTERVIEW_PAYLOAD_HASHES, FRONTEND_UIUX_PAYLOAD_HASHES, STRUCTURAL_SEARCH_PAYLOAD_HASHES, VISUAL_QA_PAYLOAD_HASHES, WIKIFY_PAYLOAD_HASHES, } from "./generated-skill-payload-hashes.js";
|
|
@@ -13,7 +13,12 @@ export function probeStrictConfig(args) {
|
|
|
13
13
|
if (existsSync(sourceConfig)) {
|
|
14
14
|
writeFileSync(join(probeHome, "config.toml"), readFileSync(sourceConfig), { mode: 0o600 });
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
// cwd matters here: Codex resolves per-project trust/overlay state from the *caller's*
|
|
17
|
+
// cwd, not from CODEX_HOME. Inheriting the real caller cwd let an unrelated trusted
|
|
18
|
+
// project entry in the copied config.toml (e.g. `[projects."$HOME"]`) change how that
|
|
19
|
+
// same config parses, turning a healthy host into a false refusal. Pointing cwd at the
|
|
20
|
+
// disposable probe home keeps the result a function of the config content alone.
|
|
21
|
+
return runProbe({ ...args, env: { ...args.env, CODEX_HOME: probeHome }, cwd: probeHome });
|
|
17
22
|
}
|
|
18
23
|
finally {
|
|
19
24
|
rmSync(probeHome, { recursive: true, force: true, maxRetries: 3, retryDelay: 50 });
|
|
@@ -24,6 +29,7 @@ function runProbe(args) {
|
|
|
24
29
|
stdio: "pipe",
|
|
25
30
|
timeout: STRICT_CONFIG_PROBE_TIMEOUT_MS,
|
|
26
31
|
...(args.env === undefined ? {} : { env: args.env }),
|
|
32
|
+
...(args.cwd === undefined ? {} : { cwd: args.cwd }),
|
|
27
33
|
});
|
|
28
34
|
if (isTimeout(result))
|
|
29
35
|
return { kind: "timeout" };
|
|
@@ -31,7 +37,16 @@ function runProbe(args) {
|
|
|
31
37
|
return { kind: "rejected" };
|
|
32
38
|
try {
|
|
33
39
|
const parsed = JSON.parse(result.stdout ?? "");
|
|
34
|
-
|
|
40
|
+
const load = inspectConfigLoad(parsed);
|
|
41
|
+
if (load === null)
|
|
42
|
+
return { kind: "rejected" };
|
|
43
|
+
// A "warning" config.load status still parsed config.toml successfully — Codex is
|
|
44
|
+
// reporting something advisory (e.g. an ignored project-local key), not a load
|
|
45
|
+
// failure. Only a genuinely unparsable/failed load is a real rejection.
|
|
46
|
+
if (load.status === "ok" || (load.status === "warning" && load.parseOk)) {
|
|
47
|
+
return load.warning === undefined ? { kind: "accepted" } : { kind: "accepted", warning: load.warning };
|
|
48
|
+
}
|
|
49
|
+
return load.detail === undefined ? { kind: "rejected" } : { kind: "rejected", detail: load.detail };
|
|
35
50
|
}
|
|
36
51
|
catch (error) {
|
|
37
52
|
if (error instanceof SyntaxError)
|
|
@@ -42,11 +57,25 @@ function runProbe(args) {
|
|
|
42
57
|
function isTimeout(result) {
|
|
43
58
|
return result.error instanceof Error && "code" in result.error && result.error.code === "ETIMEDOUT";
|
|
44
59
|
}
|
|
45
|
-
function
|
|
60
|
+
function inspectConfigLoad(value) {
|
|
46
61
|
if (!isRecord(value) || !isRecord(value["checks"]) || !isRecord(value["checks"]["config.load"]))
|
|
47
62
|
return null;
|
|
48
|
-
const
|
|
49
|
-
|
|
63
|
+
const check = value["checks"]["config.load"];
|
|
64
|
+
const status = check["status"];
|
|
65
|
+
if (typeof status !== "string")
|
|
66
|
+
return null;
|
|
67
|
+
const details = isRecord(check["details"]) ? check["details"] : {};
|
|
68
|
+
const parseOk = details["config.toml parse"] === "ok";
|
|
69
|
+
const warning = typeof details["startup warning"] === "string" ? details["startup warning"] : undefined;
|
|
70
|
+
const notes = Array.isArray(check["notes"]) ? check["notes"].filter((note) => typeof note === "string") : [];
|
|
71
|
+
const summary = typeof check["summary"] === "string" ? check["summary"] : undefined;
|
|
72
|
+
const detailParts = [summary, ...notes].filter((part) => part !== undefined && part.length > 0);
|
|
73
|
+
return {
|
|
74
|
+
status,
|
|
75
|
+
parseOk,
|
|
76
|
+
...(warning === undefined ? {} : { warning }),
|
|
77
|
+
...(detailParts.length === 0 ? {} : { detail: detailParts.join(": ") }),
|
|
78
|
+
};
|
|
50
79
|
}
|
|
51
80
|
function isRecord(value) {
|
|
52
81
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -6,6 +6,8 @@ export interface UninstallFs {
|
|
|
6
6
|
recursive?: boolean;
|
|
7
7
|
force?: boolean;
|
|
8
8
|
}): void;
|
|
9
|
+
/** Removes an empty directory only; must throw (not silently recurse) if the directory is non-empty. */
|
|
10
|
+
rmdirSync?(path: string): void;
|
|
9
11
|
lstatSync?(path: string): {
|
|
10
12
|
isSymbolicLink(): boolean;
|
|
11
13
|
isDirectory(): boolean;
|
|
@@ -3,6 +3,7 @@ import { lstatSync as nativeLstatSync } from "node:fs";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { removeSubagentDefaults } from "../config-migration/multi-agent-v2-guard.js";
|
|
5
5
|
import { ensureNativeDefaultAgentConfig } from "../config-migration/native-default-route.js";
|
|
6
|
+
import { GPT56_PROFILE_FILE_NAMES, isManagedGpt56ProfileContent } from "../config-migration/profile-files.js";
|
|
6
7
|
import { NATIVE_DEFAULT_AGENT_FILE } from "./agent-routing.js";
|
|
7
8
|
import { prepareAgentSources } from "./agents-install.js";
|
|
8
9
|
import { isSafeManagedMarketplaceRoot, LITCODEX_MARKETPLACE, LITCODEX_PLUGIN_REF, managedMarketplaceRoot, } from "./marketplace.js";
|
|
@@ -25,6 +26,7 @@ export function runUninstall(deps) {
|
|
|
25
26
|
}
|
|
26
27
|
removeManagedAgents(deps);
|
|
27
28
|
removeManagedSubagentDefaults(deps);
|
|
29
|
+
removeManagedProfileFiles(deps);
|
|
28
30
|
return { ok: pluginOk && marketplaceOk, codexHome: deps.codexHome };
|
|
29
31
|
}
|
|
30
32
|
function isSafeUninstallPaths(deps) {
|
|
@@ -102,6 +104,38 @@ function removeManagedAgents(deps) {
|
|
|
102
104
|
catch {
|
|
103
105
|
// Best-effort agent cleanup must not hide the authoritative Codex removal result.
|
|
104
106
|
}
|
|
107
|
+
removeIfEmptyDirectory(deps, agentsDir);
|
|
108
|
+
}
|
|
109
|
+
/** Best-effort per-model profile removal: only files whose content matches what LitCodex generates. */
|
|
110
|
+
function removeManagedProfileFiles(deps) {
|
|
111
|
+
if (!isDirectoryNonSymlink(deps, deps.codexHome) || deps.fs.readFileSync === undefined)
|
|
112
|
+
return;
|
|
113
|
+
for (const name of GPT56_PROFILE_FILE_NAMES) {
|
|
114
|
+
const path = join(deps.codexHome, name);
|
|
115
|
+
if (!isRegularNonSymlink(deps, path))
|
|
116
|
+
continue;
|
|
117
|
+
try {
|
|
118
|
+
const content = deps.fs.readFileSync(path, "utf8");
|
|
119
|
+
if (isManagedGpt56ProfileContent(name, content))
|
|
120
|
+
deps.fs.rmSync(path);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// Preserve unreadable or unremovable profiles while checking the rest.
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/** Non-recursive: only removes a managed directory that install created and that is now empty. */
|
|
128
|
+
function removeIfEmptyDirectory(deps, path) {
|
|
129
|
+
if (deps.fs.rmdirSync === undefined || !isDirectoryNonSymlink(deps, path))
|
|
130
|
+
return;
|
|
131
|
+
try {
|
|
132
|
+
if (deps.fs.readdirSync(path).length > 0)
|
|
133
|
+
return;
|
|
134
|
+
deps.fs.rmdirSync(path);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// A non-empty or otherwise unremovable directory is left in place.
|
|
138
|
+
}
|
|
105
139
|
}
|
|
106
140
|
const MANAGED_DEFAULT_HEADER = [
|
|
107
141
|
'name = "default"',
|