optbrew 0.1.2 → 0.2.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/.claude-plugin/marketplace.json +4 -4
- package/.claude-plugin/plugin.json +2 -1
- package/.codex-plugin/plugin.json +2 -2
- package/AGENT_INSTALL.md +94 -0
- package/CHANGELOG.md +74 -1
- package/README.ko.md +129 -105
- package/README.md +129 -105
- package/THIRD_PARTY_NOTICES.md +88 -0
- package/docs/platforms.md +45 -8
- package/docs/release.md +37 -4
- package/lib/cli.mjs +5 -2
- package/lib/install.mjs +2 -1
- package/lib/records.mjs +2 -1
- package/lib/transaction.mjs +12 -5
- package/lib/update.mjs +3 -2
- package/package.json +29 -9
- package/plugin.json +2 -2
- package/skills/.claude-plugin/icon.png +0 -0
- package/skills/.claude-plugin/plugin.json +23 -0
- package/skills/README.md +27 -0
- package/skills/optbrew/SKILL.md +223 -8
- package/skills/optbrew/THIRD_PARTY_NOTICES.md +88 -0
- package/skills/optbrew/bundle-manifest.json +409 -49
- package/skills/optbrew/modules/naver-searchadvisor/scripts/audit.mjs +4 -4
- package/skills/optbrew/references/ai-crawlers.json +1 -1
- package/skills/optbrew/references/ai-crawlers.md +1 -1
- package/skills/optbrew/references/api.md +6 -4
- package/skills/optbrew/references/check-registry.json +16 -16
- package/skills/optbrew/references/chrome-paths.json +31 -0
- package/skills/optbrew/references/endpoints.json +10 -0
- package/skills/optbrew/references/harness-signals.json +5 -0
- package/skills/optbrew/references/intake.md +76 -5
- package/skills/optbrew/references/judging.md +233 -0
- package/skills/optbrew/references/limits.json +26 -0
- package/skills/optbrew/references/measurement.md +1 -1
- package/skills/optbrew/references/messages.ko.json +170 -0
- package/skills/optbrew/references/report.md +18 -6
- package/skills/optbrew/references/routing.md +2 -2
- package/skills/optbrew/references/runbooks/anthropic-api-key.md +34 -0
- package/skills/optbrew/references/runbooks/chrome-install.md +56 -0
- package/skills/optbrew/references/runbooks/cwv-site-collection.md +38 -0
- package/skills/optbrew/references/runbooks/google-api-key.md +51 -0
- package/skills/optbrew/references/runbooks/gsc-export.md +32 -0
- package/skills/optbrew/references/runbooks/index.json +18 -0
- package/skills/optbrew/references/runbooks/key-set-claude-cloud.md +32 -0
- package/skills/optbrew/references/runbooks/key-set-codex.md +33 -0
- package/skills/optbrew/references/runbooks/key-set-local.md +40 -0
- package/skills/optbrew/references/runbooks/naver-searchadvisor-export.md +32 -0
- package/skills/optbrew/references/runbooks/network-claude-cloud-custom.md +33 -0
- package/skills/optbrew/references/runbooks/network-codex-approval.md +26 -0
- package/skills/optbrew/references/runbooks/network-codex-config.md +36 -0
- package/skills/optbrew/references/runbooks/seranking.md +38 -0
- package/skills/optbrew/references/schemas/contract.schema.json +42 -15
- package/skills/optbrew/references/scoring.md +40 -5
- package/skills/optbrew/references/source-analysis.md +40 -0
- package/skills/optbrew/references/versions.json +9 -0
- package/skills/optbrew/scripts/adapters/anthropic.mjs +5 -5
- package/skills/optbrew/scripts/adapters/imports.mjs +138 -1
- package/skills/optbrew/scripts/audit.mjs +10 -96
- package/skills/optbrew/scripts/cli.mjs +5 -2
- package/skills/optbrew/scripts/core/bundle.mjs +30 -13
- package/skills/optbrew/scripts/core/capabilities.mjs +8 -4
- package/skills/optbrew/scripts/core/cdp.mjs +105 -0
- package/skills/optbrew/scripts/core/checks/canonical-consistency.mjs +56 -0
- package/skills/optbrew/scripts/core/checks/cwv-field.mjs +77 -0
- package/skills/optbrew/scripts/core/checks/discovery.mjs +43 -0
- package/skills/optbrew/scripts/core/checks/document-title.mjs +62 -0
- package/skills/optbrew/scripts/core/checks/entity-identity.mjs +31 -0
- package/skills/optbrew/scripts/core/checks/fact-consistency.mjs +31 -0
- package/skills/optbrew/scripts/core/checks/fetch-response.mjs +18 -0
- package/skills/optbrew/scripts/core/checks/index-policy.mjs +16 -0
- package/skills/optbrew/scripts/core/checks/index.mjs +18 -0
- package/skills/optbrew/scripts/core/checks/internal-navigation.mjs +67 -0
- package/skills/optbrew/scripts/core/checks/locale-links.mjs +55 -0
- package/skills/optbrew/scripts/core/checks/naver-markup.mjs +21 -0
- package/skills/optbrew/scripts/core/checks/observation.mjs +37 -0
- package/skills/optbrew/scripts/core/checks/prepare.mjs +103 -0
- package/skills/optbrew/scripts/core/checks/render-content.mjs +104 -0
- package/skills/optbrew/scripts/core/checks/search-crawl-policy.mjs +29 -0
- package/skills/optbrew/scripts/core/checks/structured-data-truth.mjs +46 -0
- package/skills/optbrew/scripts/core/chrome-temp.mjs +68 -0
- package/skills/optbrew/scripts/core/chrome.mjs +546 -0
- package/skills/optbrew/scripts/core/collector.mjs +65 -59
- package/skills/optbrew/scripts/core/compare.mjs +18 -1
- package/skills/optbrew/scripts/core/config.mjs +31 -0
- package/skills/optbrew/scripts/core/contracts.mjs +31 -2
- package/skills/optbrew/scripts/core/cwv.mjs +100 -0
- package/skills/optbrew/scripts/core/derive.mjs +10 -161
- package/skills/optbrew/scripts/core/evidence-store.mjs +112 -0
- package/skills/optbrew/scripts/core/facts.mjs +203 -19
- package/skills/optbrew/scripts/core/findings.mjs +19 -1
- package/skills/optbrew/scripts/core/html.mjs +41 -3
- package/skills/optbrew/scripts/core/index-targets.mjs +118 -0
- package/skills/optbrew/scripts/core/judgments.mjs +675 -0
- package/skills/optbrew/scripts/core/keys.mjs +86 -0
- package/skills/optbrew/scripts/core/link-graph.mjs +93 -0
- package/skills/optbrew/scripts/core/messages.mjs +23 -0
- package/skills/optbrew/scripts/core/metrics.mjs +4 -2
- package/skills/optbrew/scripts/core/migration.mjs +37 -0
- package/skills/optbrew/scripts/core/page-select.mjs +136 -0
- package/skills/optbrew/scripts/core/probe.mjs +83 -0
- package/skills/optbrew/scripts/core/protocol.mjs +38 -14
- package/skills/optbrew/scripts/core/render.mjs +160 -0
- package/skills/optbrew/scripts/core/report-compose.mjs +377 -0
- package/skills/optbrew/scripts/core/report-html.mjs +198 -0
- package/skills/optbrew/scripts/core/report-page.mjs +14 -0
- package/skills/optbrew/scripts/core/report.mjs +357 -131
- package/skills/optbrew/scripts/core/runbooks.mjs +63 -0
- package/skills/optbrew/scripts/core/scope.mjs +23 -5
- package/skills/optbrew/scripts/core/score.mjs +12 -4
- package/skills/optbrew/scripts/core/secrets.mjs +2 -0
- package/skills/optbrew/scripts/core/stages.mjs +694 -0
- package/skills/optbrew/scripts/core/transport.mjs +157 -0
- package/skills/optbrew/scripts/core/weights.mjs +2 -1
- package/skills/optbrew/scripts/key.mjs +90 -0
- package/skills/optbrew/scripts/preflight.mjs +176 -0
- package/skills/optbrew/scripts/run.mjs +81 -0
- package/skills/optbrew/source-lock.json +1 -1
- package/source-lock.json +1 -1
package/README.md
CHANGED
|
@@ -1,149 +1,173 @@
|
|
|
1
1
|
# optbrew
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/optbrew)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
3
6
|
[한국어](README.ko.md)
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
A search-readiness audit skill for coding agents. optbrew checks a site for Google, Naver and AI answer engines, fixes the local files you approve, checks again under the same conditions, and writes a scored report built from replayable evidence.
|
|
9
|
+
|
|
10
|
+
- One skill for five profiles: **SEO**, **NEO** (Naver), **AEO**, **GEO** and **LLMO**.
|
|
11
|
+
- One call for a beginner: answer one set of start questions, then the agent runs the whole audit and hands you an HTML report.
|
|
12
|
+
- Five pinned audit guide bundles merged into 22 check families. An issue that several guides report is counted once.
|
|
13
|
+
- Every verdict in the report can be recomputed from the raw responses that were collected and hashed.
|
|
14
|
+
- No headline score when the evidence is thin: below 80% coverage the report shows the measured part and its bounds.
|
|
15
|
+
- Works with Codex, Claude Code, Cursor, OpenCode and Pi. Scoring and reports need no API account.
|
|
16
|
+
|
|
17
|
+
## Why optbrew
|
|
18
|
+
|
|
19
|
+
Being found now means three different things: ranking in Google, showing in Naver, and being cited in AI answers. Each has its own guides, and the guides overlap and disagree. An agent asked to "improve SEO" usually picks one checklist, edits files, and reports success without proof.
|
|
20
|
+
|
|
21
|
+
optbrew gives the agent one workflow and one scoring rule for all five profiles. It counts what it measured, marks what it could not measure as unknown instead of passing it, and keeps a local fix separate from a production result. A high readiness score is not a promise of traffic or citations, and the report says so.
|
|
6
22
|
|
|
7
|
-
|
|
23
|
+
## How it works
|
|
24
|
+
|
|
25
|
+
1. **Ask.** You give the URL. optbrew reads the start page, the sitemap and your setup (Chrome, a Google key, network access). Then it sends one message with the start questions: your guidance level, the goal, the questions people search for, the facts it read from the site, and the page limit. The questions, the guides and the report are in Korean. Reply with an answer for each number, or just "시작" (start) to take the defaults. If one thing blocks the audit, such as a network that is closed, you get one setup guide first. Up to three more guides appear as one-line offers; you open one by answering with its word, such as "키" (key).
|
|
26
|
+
2. **Audit.** One command collects the pages, renders up to 10 of them (one of each kind of page) in a headless Chrome of its own, measures speed and runs the code checks. It audits pages from the sitemap and from links on the start page, up to your limit: 50 pages by default, up to 200 if you raise it. The limit counts every request, so redirects and the robots and sitemap files use part of it. It follows a redirect to the `www` or `https` twin of your address and says so in the report. It stores every response with its hash.
|
|
27
|
+
3. **Judge.** The agent reads the page text that code cannot judge, such as claims, answer clarity and freshness. It cites the sentences it relied on. A second call of the same command checks that the cited text exists in the evidence, then scores.
|
|
28
|
+
4. **Report.** You get three files with the same content: `report.html` (open this one; it is a single self-contained file), `report.md` and `report.json`. The text is in Korean. Each problem has one fix with the number of pages it affects. A numbered list of steps tells you how to fill each blank, such as a missing Google key. Blanks are shown as unknown, never as a pass.
|
|
29
|
+
5. **Fix and re-check (optional).** The agent proposes changes to local files. Nothing is edited, deployed or submitted without your approval. After you deploy, the same collection runs again under the same conditions, so the before and after are comparable.
|
|
30
|
+
|
|
31
|
+
What the script measures by itself, and what still needs the guides and the agent's judgment:
|
|
32
|
+
|
|
33
|
+
| Profile | Target | Measured by the script | Left to judgment |
|
|
34
|
+
|---|---|---|---|
|
|
35
|
+
| SEO | Google and web search | Fetch status, `noindex` in meta and `X-Robots-Tag`, titles, robots.txt for Googlebot, canonical, redirect chains, discovery through links and sitemap, JSON-LD syntax | Content quality and intent fit |
|
|
36
|
+
| NEO | Naver | robots.txt for Yeti, Open Graph, description, canonical, viewport, title repetition, blocked CSS or JS | Naver-specific content guidance |
|
|
37
|
+
| AEO, GEO | Answer engines and AI search | robots.txt for the AI search bots in [ai-crawlers.md](skills/optbrew/references/ai-crawlers.md) (training bots are never scored) | Answer structure, claims, authorship, freshness |
|
|
38
|
+
| LLMO | How models describe you | Whether name, address, phone and founding year agree across pages, and whether the pages describe one business | Whether those facts are true |
|
|
39
|
+
| All | Speed and scripts | Whether the text still shows after JavaScript runs in Chrome. Field Core Web Vitals (LCP, INP, CLS) from Google's Chrome UX Report and PageSpeed Insights | Nothing. The Chrome lab values are shown as a run condition and are never scored |
|
|
40
|
+
|
|
41
|
+
Engine-specific checks run for the engines you name as targets. Name the AI answer engines you care about, such as ChatGPT, Claude or Perplexity. Naver is added on its own when the goal names it, you give a Naver export, or the site is Korean (`lang="ko"` or an address ending in `.kr`). Google is always a target. The scoring rule is in [scoring.md](skills/optbrew/references/scoring.md). The 80% coverage threshold is optbrew's own rule, not a search engine standard.
|
|
8
42
|
|
|
9
43
|
## Install
|
|
10
44
|
|
|
11
|
-
Requires Node.js 22 or later.
|
|
45
|
+
Requires [Node.js](https://nodejs.org) 22 or later. Python 3.10 or later is optional; without it, the internal Python audit utilities stay unrun. Pick one of the five methods. The examples install for Codex and Claude Code at user level; the agent IDs are `codex`, `claude-code`, `cursor`, `opencode` and `pi`.
|
|
12
46
|
|
|
13
|
-
|
|
47
|
+
In Windows PowerShell, if `npx` or `optbrew` reports that running scripts is disabled, type `npx.cmd` or `optbrew.cmd` instead.
|
|
14
48
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
49
|
+
### 1. npm
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install -g optbrew@0.2.0
|
|
53
|
+
optbrew install --agents codex,claude-code --scope user --dry-run
|
|
54
|
+
optbrew install --agents codex,claude-code --scope user
|
|
55
|
+
optbrew doctor --agents codex,claude-code --scope user
|
|
19
56
|
```
|
|
20
57
|
|
|
21
|
-
|
|
58
|
+
The dry run prints the folders it will write. `doctor` checks the files and their hashes.
|
|
22
59
|
|
|
23
|
-
|
|
60
|
+
### 2. npx
|
|
24
61
|
|
|
25
|
-
|
|
62
|
+
Runs the same CLI without a global install:
|
|
26
63
|
|
|
27
|
-
|
|
64
|
+
```bash
|
|
65
|
+
npx optbrew@0.2.0 install --agents codex,claude-code --scope user
|
|
66
|
+
npx optbrew@0.2.0 doctor --agents codex,claude-code --scope user
|
|
67
|
+
```
|
|
28
68
|
|
|
29
|
-
|
|
69
|
+
### 3. PowerShell (Windows)
|
|
30
70
|
|
|
31
|
-
|
|
71
|
+
```powershell
|
|
72
|
+
irm https://raw.githubusercontent.com/nowwcastle-sudo/optbrew/v0.2.0/install.ps1 | iex
|
|
73
|
+
```
|
|
32
74
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
75
|
+
The script is pinned to this release. It checks Node.js, shows the target folders, installs for Codex and Claude Code, and stops with an error if `doctor` finds a problem. To read it first, or to choose agents or a project folder:
|
|
76
|
+
|
|
77
|
+
```powershell
|
|
78
|
+
irm https://raw.githubusercontent.com/nowwcastle-sudo/optbrew/v0.2.0/install.ps1 -OutFile install.ps1
|
|
79
|
+
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Agents codex,claude-code,cursor
|
|
37
80
|
```
|
|
38
81
|
|
|
39
|
-
|
|
82
|
+
Add `-Scope project -Project C:\path\to\site` to install into one project.
|
|
40
83
|
|
|
41
|
-
|
|
84
|
+
### 4. Plugin
|
|
42
85
|
|
|
43
|
-
|
|
86
|
+
Claude Code:
|
|
44
87
|
|
|
45
|
-
|
|
88
|
+
```bash
|
|
89
|
+
claude plugin marketplace add nowwcastle-sudo/optbrew
|
|
90
|
+
claude plugin install optbrew@optbrew
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Codex:
|
|
46
94
|
|
|
47
|
-
|
|
95
|
+
```bash
|
|
96
|
+
codex plugin marketplace add nowwcastle-sudo/optbrew
|
|
97
|
+
codex plugin add optbrew@optbrew
|
|
98
|
+
```
|
|
48
99
|
|
|
49
|
-
|
|
100
|
+
claude.ai, Claude Desktop and Cowork: open Customize > Plugins, choose Add > Add marketplace, enter `nowwcastle-sudo/optbrew`, then add `optbrew`.
|
|
50
101
|
|
|
51
|
-
|
|
102
|
+
Plugins follow this repository's `main` branch and update through the host's plugin commands or marketplace sync.
|
|
52
103
|
|
|
53
|
-
|
|
104
|
+
### 5. Ask your agent
|
|
54
105
|
|
|
55
|
-
|
|
106
|
+
Paste this into Codex, Claude Code or another coding agent:
|
|
56
107
|
|
|
57
|
-
|
|
108
|
+
```text
|
|
109
|
+
Install the optbrew skill for me. Read https://raw.githubusercontent.com/nowwcastle-sudo/optbrew/v0.2.0/AGENT_INSTALL.md and follow it step by step. Ask me which agents and which scope to use, and show me the planned changes before you install.
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
[AGENT_INSTALL.md](AGENT_INSTALL.md) gives the agent a command and a pass check for each step, and the cases where it must stop and ask you.
|
|
58
113
|
|
|
59
|
-
|
|
114
|
+
Installing from a source checkout, the Agent Skills CLI, Pi packages and Claude web uploads are covered in [platform support](docs/platforms.md).
|
|
60
115
|
|
|
61
|
-
|
|
116
|
+
## Quick start
|
|
62
117
|
|
|
63
|
-
|
|
118
|
+
Start a new agent session and ask, for example:
|
|
64
119
|
|
|
65
120
|
```text
|
|
66
|
-
|
|
67
|
-
node bin/optbrew.mjs update --scope project --project ./site --json
|
|
68
|
-
node bin/optbrew.mjs rollback --scope project --project ./site --release-version 0.1.0 --json
|
|
121
|
+
Run optbrew on https://example.com. Goal: show up in Naver and get cited in AI answers.
|
|
69
122
|
```
|
|
70
123
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
### Reinstall after a migration_required update
|
|
74
|
-
|
|
75
|
-
Release 0.1.2 uses evaluation version 0.2.0 (0.1.1 used 0.1.0), so scores and baselines made with 0.1.1 are not comparable with 0.1.2: `compare` returns `not_comparable`, and you run the baseline audit again with 0.1.2. For the same reason `optbrew update` on a managed 0.1.1 install stops with `migration_required` and changes nothing; the message lists the paths and commands. There is no `uninstall` command. Replace the install with the blocks below, from the 0.1.2 checkout root. Each block first runs the read-only `reinstall-plan`, which validates the install record (every target must be exactly the agent's `skills/optbrew` path) and refuses a tampered one before anything is deleted. The shell then deletes only the paths it printed, targets first and the managed root last, so the block can be run again after a failure. The commands never touch `.optbrew/runs` (your audit evidence); do not delete the whole `.optbrew` folder. Full explanation: [platform support](docs/platforms.md).
|
|
76
|
-
|
|
77
|
-
User scope:
|
|
78
|
-
|
|
79
|
-
```powershell user
|
|
80
|
-
$ErrorActionPreference = 'Stop'
|
|
81
|
-
[Console]::OutputEncoding = [Text.Encoding]::UTF8
|
|
82
|
-
$plan = @(node bin/optbrew.mjs reinstall-plan --scope user)
|
|
83
|
-
if ($LASTEXITCODE) { exit $LASTEXITCODE }
|
|
84
|
-
foreach ($line in $plan) {
|
|
85
|
-
$f = $line -split "`t"
|
|
86
|
-
if ($f[0] -eq 'delete-link') { [IO.Directory]::Delete($f[1]) }
|
|
87
|
-
elseif ($f[0] -eq 'delete-dir') { Remove-Item -Recurse -Force -LiteralPath $f[1] }
|
|
88
|
-
}
|
|
89
|
-
foreach ($line in $plan) {
|
|
90
|
-
$f = $line -split "`t"
|
|
91
|
-
if ($f[0] -eq 'install') { node bin/optbrew.mjs install --agents $f[1] --scope user --strategy $f[2]; if ($LASTEXITCODE) { exit $LASTEXITCODE } }
|
|
92
|
-
elseif ($f[0] -eq 'agents') { node bin/optbrew.mjs doctor --agents $f[1] --scope user; exit $LASTEXITCODE }
|
|
93
|
-
}
|
|
94
|
-
```
|
|
124
|
+
optbrew then checks your setup and sends the start questions in one message. Answer each number, or reply "시작" (start) to accept the defaults. A missing Google key, Chrome or export file does not stop the audit. The blank is listed in the report with the steps to fill it.
|
|
95
125
|
|
|
96
|
-
|
|
97
|
-
set -e
|
|
98
|
-
plan=$(node bin/optbrew.mjs reinstall-plan --scope user)
|
|
99
|
-
while IFS=$'\t' read -r kind a b; do
|
|
100
|
-
case "$kind" in delete-link | delete-dir) rm -r -- "$a" ;; esac
|
|
101
|
-
done <<< "$plan"
|
|
102
|
-
while IFS=$'\t' read -r kind a b; do
|
|
103
|
-
case "$kind" in
|
|
104
|
-
install) node bin/optbrew.mjs install --agents "$a" --scope user --strategy "$b" ;;
|
|
105
|
-
agents) node bin/optbrew.mjs doctor --agents "$a" --scope user ;;
|
|
106
|
-
esac
|
|
107
|
-
done <<< "$plan"
|
|
108
|
-
```
|
|
126
|
+
The audit takes a few minutes. Everything it writes goes to `optbrew-audit/<site>-<date>` in your working folder: the evidence (every response with its hash) and the three reports. Open `report.html` first. The same name with a number added (`-2`, `-3`) is used when the folder already exists. Private, internal and local addresses (such as `localhost` or `192.168.x.x`) are refused, so audit the public address of the site.
|
|
109
127
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
foreach ($line in $plan) {
|
|
119
|
-
$f = $line -split "`t"
|
|
120
|
-
if ($f[0] -eq 'delete-link') { [IO.Directory]::Delete($f[1]) }
|
|
121
|
-
elseif ($f[0] -eq 'delete-dir') { Remove-Item -Recurse -Force -LiteralPath $f[1] }
|
|
122
|
-
}
|
|
123
|
-
foreach ($line in $plan) {
|
|
124
|
-
$f = $line -split "`t"
|
|
125
|
-
if ($f[0] -eq 'install') { node bin/optbrew.mjs install --agents $f[1] --scope project --project $project --strategy $f[2]; if ($LASTEXITCODE) { exit $LASTEXITCODE } }
|
|
126
|
-
elseif ($f[0] -eq 'agents') { node bin/optbrew.mjs doctor --agents $f[1] --scope project --project $project; exit $LASTEXITCODE }
|
|
127
|
-
}
|
|
128
|
+
### Google API key (optional)
|
|
129
|
+
|
|
130
|
+
A free Google API key makes the real-visitor speed scores (LCP, INP, CLS) fill reliably. When optbrew offers it, answer "키" (key) to see how to get one. Then save it from your own terminal, never in the chat. In Codex and Claude Code cloud, the key guide shows where to save it instead.
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
optbrew key set google
|
|
134
|
+
optbrew key status
|
|
135
|
+
optbrew key remove google
|
|
128
136
|
```
|
|
129
137
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
while IFS=$'\t' read -r kind a b; do
|
|
138
|
-
case "$kind" in
|
|
139
|
-
install) node bin/optbrew.mjs install --agents "$a" --scope project --project "$project" --strategy "$b" ;;
|
|
140
|
-
agents) node bin/optbrew.mjs doctor --agents "$a" --scope project --project "$project" ;;
|
|
141
|
-
esac
|
|
142
|
-
done <<< "$plan"
|
|
138
|
+
`set` asks for the key with hidden input. `status` shows only whether a key exists and the first 8 characters of its hash. `remove` deletes it. If you did not install with npm, use `npx optbrew@0.2.0 key set google`, or answer "키" and copy the exact command from the guide. The skill folder has the same command too: `node <skill folder>/scripts/key.mjs set google`. The key is saved in `.optbrew/credentials.json` in your home folder, outside every project, and the environment variable `OPTBREW_GOOGLE_API_KEY` takes priority if it is set. optbrew sends the key to Google only in a request header, and never writes it to a report, a log or the evidence.
|
|
139
|
+
|
|
140
|
+
## Update
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npm install -g optbrew@latest
|
|
144
|
+
optbrew update --scope user
|
|
143
145
|
```
|
|
144
146
|
|
|
145
|
-
|
|
147
|
+
With npx, run `npx optbrew@latest update --scope user`. `optbrew check-updates --package optbrew` tells you, without changing anything, whether npm has a newer release than the CLI you are running; `optbrew doctor --json` shows the `release_version` installed in your agent folders. `npm update` alone does not touch copies already placed in agent folders; the `update` command does.
|
|
148
|
+
|
|
149
|
+
### Upgrading from 0.1.x
|
|
150
|
+
|
|
151
|
+
0.2.0 changes the evaluation version (0.4.0), the audit protocol (0.2.0) and the contract schema (2.0.0). So:
|
|
152
|
+
|
|
153
|
+
- A managed install of any 0.1.x release stops with `migration_required`, and `optbrew update` changes nothing. Follow [Reinstall after a migration_required update](docs/platforms.md#reinstall-after-a-migration_required-update); the steps delete only paths that a read-only check printed and never touch your audit evidence.
|
|
154
|
+
- A plugin install (Claude Code, Codex, claude.ai) follows `main`, so the plugin update commands of your host work as before.
|
|
155
|
+
- An output folder or evidence packet from a 0.1.x run is refused with one sentence: run the audit again in a new folder. Scores from different evaluation versions are not comparable, so `compare` reports `not_comparable` against a 0.1.x baseline. Run the baseline audit again with 0.2.0.
|
|
156
|
+
|
|
157
|
+
## APIs and cost
|
|
158
|
+
|
|
159
|
+
Nothing here requires a paid account. A direct Anthropic API call or an [SE Ranking](https://seranking.com/api.html) call needs your approval, a recorded budget and a stop condition first; a Claude subscription does not include API billing. The Google key above is your own, and the Google speed services it calls are free. Keys stay in your environment variables or the key file and never go into a report. Details: [API boundaries](skills/optbrew/references/api.md).
|
|
160
|
+
|
|
161
|
+
## Documentation
|
|
162
|
+
|
|
163
|
+
- [Platform support](docs/platforms.md): install paths per agent, checkout commands, reinstall steps
|
|
164
|
+
- [Scoring](skills/optbrew/references/scoring.md), [measurement](skills/optbrew/references/measurement.md) and [report evidence](skills/optbrew/references/report.md)
|
|
165
|
+
- [Changelog](CHANGELOG.md) and [release process](docs/release.md)
|
|
166
|
+
|
|
167
|
+
## Contributing
|
|
168
|
+
|
|
169
|
+
Contributions are welcome: bug reports, false positives from a real site, guide updates, translations and code. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
146
170
|
|
|
147
|
-
|
|
171
|
+
## License
|
|
148
172
|
|
|
149
|
-
|
|
173
|
+
optbrew's own code is [MIT licensed](LICENSE). The bundled guides keep their own licenses, listed in [third-party notices](skills/optbrew/THIRD_PARTY_NOTICES.md). The Naver bundle keeps an index of the official [Search Advisor guides](https://searchadvisor.naver.com/guide) but not the 55 article bodies; follow the official links while online.
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -8,3 +8,91 @@ The files below retain their upstream copyright and permission notices. Service
|
|
|
8
8
|
- **magnus-seo** — magnus919/agent-skills at 2e8fb962819b2b01b270620f92f0cc7213d77ef1; MIT; Git license blob 9745e19f4b20d77c134964ae1bf0af0ace5c4db7; exact notice: [licenses/magnus-seo.txt](skills/optbrew/licenses/magnus-seo.txt). Exclusions: Unselected agent skills.
|
|
9
9
|
- **seranking-seo** — seranking/seo-skills at fd6d1408f2e6a06454d81c07c29e0f04342eb9ba; MIT; Git license blob ca6b9a33c8234bf47cdcfb2dc157b308195845c5; exact notice: [licenses/seranking-seo.txt](skills/optbrew/licenses/seranking-seo.txt). Exclusions: extensions/google/install.sh and extensions/firecrawl/install.sh: upstream installers disabled; scripts/google_auth.py and root scripts: upstream authentication and provider execution disabled; optbrew capability adapters replace active commands; Unselected campaign, ad, social and other upstream skills.
|
|
10
10
|
- **marketing-search** — coreyhaines31/marketingskills at 5b2c0007766c6a1cf1d53fd8fc73e979e0821022; MIT; Git license blob 7c48dd638a9ebed49a8ef0c0c4eea90105381cdf; exact notice: [licenses/marketing-search.txt](skills/optbrew/licenses/marketing-search.txt). Exclusions: Unselected marketing skills, installers and authoring utilities.
|
|
11
|
+
|
|
12
|
+
## Borrowed text
|
|
13
|
+
|
|
14
|
+
These two works are not vendored code. SKILL.md, section "진행 보고", adapts the output rules of caveman. The top sections of the HTML report, added in the same release, follow the approach of eli5 (big picture, few words).
|
|
15
|
+
|
|
16
|
+
### caveman
|
|
17
|
+
|
|
18
|
+
Source: https://github.com/JuliusBrussee/caveman, `skills/caveman/SKILL.md`, version 4.0.1. No upstream commit is recorded: the text was copied from the installed 4.0.1 plugin. License: Apache License, Version 2.0, https://www.apache.org/licenses/LICENSE-2.0. Changes: the rules were translated into Korean, shortened, and rewritten for progress sentences during an audit; SKILL.md marks the paragraph "변경함". Upstream keeps the pre-3.0.0 MIT text in its `LICENSE-MIT` file for contributions made before 3.0.0; that file is not redistributed here. The upstream NOTICE file follows word for word.
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
Caveman
|
|
22
|
+
Copyright 2026 Julius Brussee
|
|
23
|
+
|
|
24
|
+
Before Caveman 3.0.0, the parts of this repository outside the Engine-linked
|
|
25
|
+
runtime were licensed under the MIT License (see LICENSING.md). Contributions
|
|
26
|
+
made to those parts before 3.0.0 were received under the MIT License and remain
|
|
27
|
+
available under it. Its copyright and permission notice is retained in
|
|
28
|
+
LICENSE-MIT.
|
|
29
|
+
|
|
30
|
+
This product includes third-party software:
|
|
31
|
+
|
|
32
|
+
- engine/pixel/ is a Go port of pxpipe (https://github.com/teamchong/pxpipe),
|
|
33
|
+
used under the MIT License.
|
|
34
|
+
Copyright (c) 2026 claude-image-proxy contributors
|
|
35
|
+
|
|
36
|
+
- The glyph atlases embedded in engine/pixel/assets/ are rasterized from:
|
|
37
|
+
- Spleen 5x8, Copyright (c) 2018-2026, Frederic Cambus.
|
|
38
|
+
BSD 2-Clause License.
|
|
39
|
+
- GNU Unifont 16.0.04, dual-licensed under the SIL Open Font License 1.1 and
|
|
40
|
+
the GNU GPL version 2 (or later) with the GNU font-embedding exception.
|
|
41
|
+
|
|
42
|
+
- browse/ links these MIT-licensed Go modules:
|
|
43
|
+
- github.com/chromedp/chromedp, Copyright (c) 2016-2025 Kenneth Shaw
|
|
44
|
+
- github.com/chromedp/cdproto, Copyright (c) 2016-2025 Kenneth Shaw
|
|
45
|
+
- github.com/chromedp/sysutil, Copyright (c) 2016-2017 Kenneth Shaw
|
|
46
|
+
|
|
47
|
+
- The runtime binaries and the container image link third-party Go modules
|
|
48
|
+
under the MIT, BSD-3-Clause and Apache-2.0 licenses. Their license texts, and
|
|
49
|
+
the Go runtime's, ship with every binary release as
|
|
50
|
+
THIRD_PARTY_GO_LICENSES.tar.gz and in the image under /licenses/third_party/.
|
|
51
|
+
|
|
52
|
+
- packages/cli/src/index.ts contains a port, with changes, of Qwen Code
|
|
53
|
+
0.22.3's MCP server and permission-rule matchers and its tool-name
|
|
54
|
+
normalization (https://github.com/QwenLM/qwen-code), used under the Apache
|
|
55
|
+
License, Version 2.0.
|
|
56
|
+
Copyright 2025 Google LLC
|
|
57
|
+
Copyright 2025 Qwen
|
|
58
|
+
|
|
59
|
+
- The @caveman-ai/cli package bundles MIT-licensed npm packages
|
|
60
|
+
(@clack/prompts, @clack/core, sisteransi, fast-string-width,
|
|
61
|
+
fast-string-truncated-width, fast-wrap-ansi); see packages/cli/NOTICE.
|
|
62
|
+
|
|
63
|
+
- extension/fonts/ holds the Geist and Geist Mono fonts,
|
|
64
|
+
Copyright (c) 2023 Vercel, in collaboration with basement.studio,
|
|
65
|
+
under the SIL Open Font License 1.1.
|
|
66
|
+
|
|
67
|
+
Full license texts: engine/pixel/NOTICE, engine/pixel/assets/SPLEEN_LICENSE.txt,
|
|
68
|
+
engine/pixel/assets/UNIFONT_LICENSE.txt, browse/NOTICE, packages/cli/NOTICE, and
|
|
69
|
+
extension/fonts/GEIST_LICENSE.txt.
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### eli5
|
|
73
|
+
|
|
74
|
+
Source: the `eli5` plugin version 1.0.0 by Thariq Shihipar, from the claude-community plugin marketplace. Its `plugin.json` declares `"license": "MIT"`; the plugin ships no separate license file and states no copyright year. Use: only the approach "big pictures, few words" is followed; no upstream text is copied. The text below is the standard MIT License text with the author name taken from `plugin.json`. It is not copied from an upstream file.
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
MIT License
|
|
78
|
+
|
|
79
|
+
Copyright (c) Thariq Shihipar
|
|
80
|
+
|
|
81
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
82
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
83
|
+
in the Software without restriction, including without limitation the rights
|
|
84
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
85
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
86
|
+
furnished to do so, subject to the following conditions:
|
|
87
|
+
|
|
88
|
+
The above copyright notice and this permission notice shall be included in all
|
|
89
|
+
copies or substantial portions of the Software.
|
|
90
|
+
|
|
91
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
92
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
93
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
94
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
95
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
96
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
97
|
+
SOFTWARE.
|
|
98
|
+
```
|
package/docs/platforms.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Platform installation and update paths
|
|
2
2
|
|
|
3
|
-
Optbrew v0.
|
|
3
|
+
Optbrew v0.2.0 contains one skill source at `skills/optbrew`. The managed CLI can place it at five hosts' documented default paths. A file in a host path proves placement, not that the host discovered, loaded, or invoked the skill. Confirm those three steps in a fresh host session before reporting host support as exercised.
|
|
4
4
|
|
|
5
5
|
| Host | Managed project target | Managed user target | Discovery and invocation boundary |
|
|
6
6
|
|---|---|---|---|
|
|
@@ -14,15 +14,51 @@ The CLI maps only these default targets. Custom roots, host policies, remote age
|
|
|
14
14
|
|
|
15
15
|
## Managed checkout and npm paths
|
|
16
16
|
|
|
17
|
-
The [README](../README.md) shows
|
|
17
|
+
The [README](../README.md) shows the npm, npx, PowerShell, plugin and agent install routes. This section holds the parser-checked commands for a source checkout. Clone `https://github.com/nowwcastle-sudo/optbrew`, create an empty `site` folder, and run them from the repository root. With the npm package installed, replace `node bin/optbrew.mjs` with `optbrew`.
|
|
18
|
+
|
|
19
|
+
Install into an isolated project folder, after a dry run:
|
|
20
|
+
|
|
21
|
+
Bash and PowerShell use the same commands:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
node bin/optbrew.mjs install --agents codex,claude-code,cursor,opencode,pi --scope project --project ./site --strategy copy --dry-run --json
|
|
25
|
+
node bin/optbrew.mjs install --agents codex,claude-code,cursor,opencode,pi --scope project --project ./site --strategy copy --json
|
|
26
|
+
node bin/optbrew.mjs doctor --agents codex,claude-code,cursor,opencode,pi --scope project --project ./site --json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`--strategy link` is the default; `copy` also works when links are unavailable. The managed record lives under that project's `.optbrew/install`. For one host, replace the comma-separated list with its exact ID. Use `--scope user` only when you intend to install into user-level host directories. The install command checks the bundle manifest and refuses to replace an unmanaged target.
|
|
30
|
+
|
|
31
|
+
Replay the bundled synthetic fixtures without any provider call. Copy `tests/fixtures/scoring/before.json` and `after.json`, and `tests/fixtures/reports/remote-only.json` with its sibling evidence files, into the current directory first:
|
|
32
|
+
|
|
33
|
+
Bash and PowerShell use the same commands:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
node bin/optbrew.mjs score --input ./before.json --output ./score.json
|
|
37
|
+
node bin/optbrew.mjs compare --before ./before.json --after ./after.json --output ./comparison.json
|
|
38
|
+
node bin/optbrew.mjs report --input ./remote-only.json --output-dir ./report-output
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Check for updates, update, and roll back a managed project install:
|
|
42
|
+
|
|
43
|
+
Bash and PowerShell use the same commands:
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
node bin/optbrew.mjs check-updates --json
|
|
47
|
+
node bin/optbrew.mjs update --scope project --project ./site --json
|
|
48
|
+
node bin/optbrew.mjs rollback --scope project --project ./site --release-version 0.2.0 --json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Rollback works only between releases that share the evaluation version, so no release before 0.2.0 can be rolled back to. The shown command reports that no earlier release is retained on a fresh 0.2.0 install; it applies once a later release that shares evaluation version 0.4.0 has updated the install.
|
|
52
|
+
|
|
53
|
+
The CLI validates bundle hashes before an install or update. `update` replaces every target in one managed record as a unit. An edited target makes the default update stop; the explicit `--local-changes backup-and-replace` policy retains a readable backup. `rollback --release-version VERSION` works only when that version is in the record's retained prior releases. A fresh installation has no older release.
|
|
18
54
|
|
|
19
55
|
After a public npm release, `npm install -g optbrew` and `npm update -g optbrew` manage the package in npm. Neither command rewrites an old copied skill target. Run the installed CLI's managed `update` after the package update, then `doctor` and a new-session invocation check. `check-updates --package optbrew --json` is read-only and compares the installed release with the npm registry; without `--package` it returns `local_only`.
|
|
20
56
|
|
|
21
57
|
## Reinstall after a migration_required update
|
|
22
58
|
|
|
23
|
-
Release 0.
|
|
59
|
+
Release 0.2.0 uses evaluation version 0.4.0, audit protocol 0.2.0 and contract schema 2.0.0. Release 0.1.3 used evaluation version 0.3.0 and 0.1.2 used 0.2.0. The managed updater refuses a change of evaluation version or of a scoring contract file, so `optbrew update` stops with `migration_required` and changes nothing on a managed install of any 0.1.x release. There is no `uninstall` command. Replace the install by hand: the blocks below delete the install's targets and then its managed root, and run `install` again from the 0.2.0 checkout. Scores and baselines made with a 0.1.x release are not comparable with 0.2.0; `compare` returns `not_comparable`, so run the baseline audit again. An output folder or evidence packet from a 0.1.x run is refused with one sentence that tells you to run the audit again in a new folder. A plugin install from a marketplace is not a managed install: it follows the repository and needs no reinstall.
|
|
24
60
|
|
|
25
|
-
The blocks do not trust the install record. Each one first runs the read-only `node bin/optbrew.mjs reinstall-plan`, which resolves the home directory the way the CLI does (`HOME`, else the operating system's home directory), checks that the record belongs to this scope, that every recorded target is exactly the agent's `skills/optbrew` path (absolute, no `..`, no linked folder on the way, inside the scope or project), and that an existing target is a link to the managed bundle or a real folder holding a bundle manifest. If any check fails it prints the reason, exits with a nonzero code, and the block deletes nothing. Otherwise the shell deletes only the paths it printed: the targets first, then `<scope root>/.optbrew/installs/user` (user scope) or `<project>/.optbrew/install` (project scope), which holds the install record. Because the record goes last, you can run the same block again after a failure. The commands never touch `<scope root>/.optbrew/runs`, where
|
|
61
|
+
The blocks do not trust the install record. Each one first runs the read-only `node bin/optbrew.mjs reinstall-plan`, which resolves the home directory the way the CLI does (`HOME`, else the operating system's home directory), checks that the record belongs to this scope, that every recorded target is exactly the agent's `skills/optbrew` path (absolute, no `..`, no linked folder on the way, inside the scope or project), and that an existing target is a link to the managed bundle or a real folder holding a bundle manifest. If any check fails it prints the reason, exits with a nonzero code, and the block deletes nothing. Otherwise the shell deletes only the paths it printed: the targets first, then `<scope root>/.optbrew/installs/user` (user scope) or `<project>/.optbrew/install` (project scope), which holds the install record. Because the record goes last, you can run the same block again after a failure. The commands never touch `<scope root>/.optbrew/runs`, where the audit evidence of 0.1.x lives, and never touch an `optbrew-audit` folder; do not delete the whole `.optbrew` folder, which also holds the Google key file. Each agent is installed again with the strategy (`link` or `copy`) the record had, then `doctor` runs. Run the blocks from the 0.2.0 checkout root. If `reinstall-plan` refuses the record, fix or remove the named path by hand and look at it first; the CLI also refuses to overwrite a target it does not own.
|
|
26
62
|
|
|
27
63
|
User scope:
|
|
28
64
|
|
|
@@ -92,16 +128,17 @@ while IFS=$'\t' read -r kind a b; do
|
|
|
92
128
|
done <<< "$plan"
|
|
93
129
|
```
|
|
94
130
|
|
|
95
|
-
Inside 0.
|
|
131
|
+
Inside 0.2.0 and later releases that keep evaluation version 0.4.0 and the scoring contract files, `update` and `rollback` work as before. The same refusal and steps apply to any future release that changes the evaluation version or a scoring contract file.
|
|
96
132
|
|
|
97
133
|
## Native host routes
|
|
98
134
|
|
|
99
135
|
These are alternatives to the managed CLI. Do not mix their ownership records for the same target path.
|
|
100
136
|
|
|
101
137
|
- **Agent Skills tool:** Current [Vercel Skills CLI](https://github.com/vercel-labs/skills) documents `npx skills add ./` for a local source and `npx skills update optbrew` for an installation it owns. Run from a checkout containing the skill. Confirm its host selection and destination before writing. The public repository is `https://github.com/nowwcastle-sudo/optbrew`.
|
|
102
|
-
- **Claude Code plugin:**
|
|
103
|
-
- **
|
|
104
|
-
- **
|
|
138
|
+
- **Claude Code plugin:** `.claude-plugin/marketplace.json` names the plugin `optbrew@optbrew` and serves the `skills/` folder, whose `skills/.claude-plugin/plugin.json` lists `./optbrew`. Neither file pins a version, so each commit to `main` is a new plugin version. Run `claude plugin marketplace add nowwcastle-sudo/optbrew`, then `claude plugin install optbrew@optbrew` (add `--scope project` to keep it in one project). Later, `claude plugin update optbrew@optbrew` applies the marketplace's newer version and requires a restart. `claude plugin validate .` checks the marketplace and the served plugin from a checkout. The root `.claude-plugin/plugin.json` (version 0.2.0) still loads the whole checkout with `claude --plugin-dir .`. [Claude Code plugin instructions](https://code.claude.com/docs/en/plugins) also describe the interactive `/plugin` path. Marketplace auto-update is a user setting; the marketplace file does not enable it. Verify a fresh-session invocation after a native update.
|
|
139
|
+
- **Codex plugin:** `.agents/plugins/marketplace.json` lists the same `optbrew` plugin. Run `codex plugin marketplace add nowwcastle-sudo/optbrew`, then `codex plugin add optbrew@optbrew`, or choose it in `/plugins`. Start a new Codex task afterwards.
|
|
140
|
+
- **Pi package:** Current [Pi package instructions](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/packages.md) document `pi install ./local-package`, `pi install npm:package-name@version`, `pi list`, and `pi update --extensions`. `pi install ./` installs from a local checkout when Pi is installed; `pi install npm:optbrew@0.2.0` installs the published npm package. The package's `pi.skills` entry points to `./skills/optbrew`. A project-local package declaration uses Pi's `--local` option and is subject to project trust. Check the installed Pi version's help and package list before updating.
|
|
141
|
+
- **Claude web (claude.ai, Claude Desktop, Cowork):** In Customize > Plugins, choose Add > Add marketplace and enter `nowwcastle-sudo/optbrew`, then add `optbrew`. The plugin is saved to your account, so cloud Claude Code sessions receive it too. Turn on Sync automatically for the marketplace, or select Check for updates, to pick up new commits. The marketplace serves `skills/` because claude.ai refuses a plugin with a top-level `bin/` folder. Uploading a ZIP of `skills/` (Add > Upload plugin) also works, but each update needs a new upload.
|
|
105
142
|
- **Ordinary ChatGPT chat:** Attach the relevant skill files or ZIP and give the assistant the target and scope. This is attachment-guided use. It is not the Codex installation path and does not establish Work/desktop plugin discovery.
|
|
106
143
|
|
|
107
144
|
The native syntax above comes from host documentation checked on 2026-10-14. It is documentation evidence, not proof that an installed host accepted the package or called the skill. No host registration, OAuth, account setting, or user-level install is performed by the documentation checks.
|
package/docs/release.md
CHANGED
|
@@ -1,14 +1,47 @@
|
|
|
1
1
|
# Release procedure
|
|
2
2
|
|
|
3
|
-
This checkout is version 0.
|
|
3
|
+
This checkout is version 0.2.0. A package name, local manifest, or generated ZIP does not establish a public release. Publication, a Git tag, a push, and account changes require their own authorization. This page describes the reviewable local release artifacts and the checks to run before that decision.
|
|
4
4
|
|
|
5
5
|
1. Confirm the source commit and clean intended diff. Match `package.json`, the portable plugin, Codex plugin, Claude plugin, marketplace entry, and ZIP name to one release version. Keep `evaluation_version` and `protocol_version` separate from the release version.
|
|
6
6
|
2. Run `npm test` and `python -m unittest discover -s tests/python` on Python 3.10 or later. Run the focused `node --test tests/docs-commands.test.mjs` check when changing examples. The command check runs optbrew against isolated local fixtures; it makes no provider call.
|
|
7
|
-
3. Run `npm run build-bundle`, `node scripts/build-release.mjs --version 0.
|
|
7
|
+
3. Build from a checkout made with `git clone -c core.autocrlf=false`. The root and `skills/` carry no `.gitattributes` (the Claude plugin directory refuses one there), so with `core.autocrlf=true` the skill files are CRLF in the working tree; the bundle hashes still match, but the ZIP and npm verifiers compare exact bytes and refuse them. Run `npm run build-bundle`, `node scripts/build-release.mjs --version 0.2.0 --output-dir dist`, `npm pack --pack-destination dist`, `node scripts/verify-release.mjs --dist dist`, and `npm pack --dry-run --json` from the repository root. Rebuild after changing the README or packaged files. Do not treat an older tarball as containing a later documentation edit.
|
|
8
8
|
4. Inspect the npm file list, the ZIP file list, `bundle-manifest.json`, `source-lock.json`, licenses, and secret scan output. The same skill bytes and version must be traceable across the npm package and ZIP. Source notices belong in both. User run evidence, account configuration, keys, private cards, and authoring materials must stay outside both.
|
|
9
9
|
5. Test a fresh isolated managed install, `doctor`, update from a retained earlier release, rollback, and fresh host discovery or invocation where a host is available. A dry run or manifest check does not prove invocation. Record the untested hosts and capabilities.
|
|
10
|
-
6.
|
|
10
|
+
6. Confirm CI on the exact commit that will be tagged. That commit exists only after the merge: `main` takes changes through a pull request with linear history, so the merge makes a commit that no earlier run has seen, and runs on the release branch or the pull request do not count. Do this after the merge of step 8 and before its tag. The `test` workflow (`.github/workflows/test.yml`) runs `npm test` on `ubuntu-latest` and on `windows-latest` with `core.autocrlf=true`, Chrome integration tests included, and its last step (`scripts/check-skips.mjs`) fails when a Chrome test was skipped or another test was skipped for a reason that is not listed there. The push to `main` starts the first run. Start two more on the same commit, one after the other, each when the previous one has finished (the workflow keeps one run per commit at a time): `gh workflow run test.yml --ref main`. Then `gh run list --workflow test.yml --branch main --commit <merge commit sha> --json event,conclusion,headSha,url` must list three runs (the `push` run and two `workflow_dispatch` runs) with `conclusion` `success`, each green on both systems. Do not rerun a red run until it turns green: one failed Chrome test (a leftover `gpu-process` of its own Chrome was seen once under load) is a flake to investigate. Read the two `Point optbrew at the runner's Chrome` steps of the newest run and add the Chrome version and path each runner printed to [Chrome locations and DevTools names](#chrome-locations-and-devtools-names-2026-10-16) with the date; also record whether the first Ubuntu run needed any sandbox workaround.
|
|
11
|
+
7. Only after a reviewed release decision, and only after step 6 is green on the merge commit, publish or upload the approved artifacts and verify the public npm and repository readback. Do not infer publication from successful local builds. The owner runs these actions, not an agent: `git push`, the merge, the tag and its push, `gh release create`, and `npm publish dist/optbrew-X.Y.Z.tgz`. An agent prepares the artifacts and reads the results back.
|
|
12
|
+
8. `main` is protected by a repository ruleset: no force push, no deletion, changes only through a pull request, linear history. Tags matching `v*` cannot be moved or deleted. Merge the release branch through a pull request, then tag the merge commit `vX.Y.Z`. The README's PowerShell installer and agent prompt load `install.ps1` and `AGENT_INSTALL.md` from that tag, so test both raw URLs after the tag is pushed. Do not push the tag before step 6 is green for that merge commit.
|
|
13
|
+
9. A tag alone is not a GitHub Release. Publish one for the tag, with the CHANGELOG section as notes and the reviewed ZIP attached: `gh release create vX.Y.Z dist/<zip> --title vX.Y.Z --notes-file <notes.md>`. Read it back: `gh api repos/nowwcastle-sudo/optbrew/releases --jq '.[].tag_name'` must list the tag, and `npm view optbrew dist-tags` must show the same version as `latest`.
|
|
14
|
+
10. The Claude marketplace and directory sync on a push to `main`, sent by the repository webhook. After the merge, confirm that the webhook got a push for `refs/heads/main` with the merge commit: `gh api repos/nowwcastle-sudo/optbrew/hooks/<id>/deliveries` lists the delivery, and `.../deliveries/<delivery id>` shows `request.payload.ref` and `request.payload.after`. A branch deletion is answered `ignored_delete` and does not sync. Then check that the claude.ai copy shows the merge commit.
|
|
15
|
+
11. The Codex marketplace file is `.agents/plugins/marketplace.json`. After the merge, in a Codex that has the marketplace (`codex plugin marketplace add nowwcastle-sudo/optbrew` adds it), run `codex plugin marketplace upgrade`, then `codex plugin list --marketplace optbrew` and check that `optbrew` is listed as available (`--json` gives a machine-readable form). A listing shows that the marketplace file is readable. It does not show that a Codex task discovers the skill: start a new Codex task, invoke the skill, and record the Codex version used (`codex --version`).
|
|
11
16
|
|
|
12
17
|
The bundle includes five pinned source bundles plus seven selected marketing guides. The Naver source articles under `references/guide/` (55 original bodies) remain excluded; the index links to official pages and full offline article lookup is unavailable. The published notice must retain upstream MIT/ISC permission texts and modifications. Optbrew's own code uses MIT. These code licenses do not grant service subscriptions or API data rights.
|
|
13
18
|
|
|
14
|
-
The direct Anthropic adapter
|
|
19
|
+
The direct Anthropic adapter keeps its text-only scope and four model IDs in [API boundaries](../skills/optbrew/references/api.md). No live paid result, search indexing, traffic change, or customer adoption is established by a passing package check. See [platform paths](platforms.md) for update mechanisms after release.
|
|
20
|
+
|
|
21
|
+
## Confirmation records
|
|
22
|
+
|
|
23
|
+
Values the code relies on that were confirmed from a primary source, with the date of confirmation. Re-confirm before changing the matching file.
|
|
24
|
+
|
|
25
|
+
### Chrome locations and DevTools names (2026-10-16)
|
|
26
|
+
|
|
27
|
+
Confirmed for `skills/optbrew/references/chrome-paths.json` and `skills/optbrew/scripts/core/chrome.mjs`:
|
|
28
|
+
|
|
29
|
+
- Windows `\Google\Chrome\Application\chrome.exe` and `\Microsoft\Edge\Application\msedge.exe`, tried under `%ProgramFiles%`, `%ProgramFiles(x86)%` and `%LocalAppData%`; macOS `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome` and `/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge`; Linux `/opt/google/chrome/chrome` and `/opt/microsoft/msedge/msedge`. Source: Playwright's channel table and Windows prefix list, https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/registry/index.ts (read 2026-10-16). The Windows prefixes (`LOCALAPPDATA`, `PROGRAMFILES`, `PROGRAMFILES(X86)`) also match Google's `chrome-launcher`, https://github.com/GoogleChrome/chrome-launcher/blob/main/src/chrome-finder.ts.
|
|
30
|
+
- Names searched on `PATH`: `google-chrome-stable`, `google-chrome`, `chromium-browser`, `chromium` (Google's `chrome-launcher`, same file); `microsoft-edge-stable` (Playwright's Edge install script, https://github.com/microsoft/playwright/blob/main/packages/playwright-core/bin/reinstall_msedge_stable_linux.sh); `chrome` and `msedge` (the executable names above).
|
|
31
|
+
- Playwright's Chromium: `<PLAYWRIGHT_BROWSERS_PATH>/chromium-<revision>/chrome-win64/chrome.exe`, `chrome-linux64/chrome`, `chrome-linux-arm64/chrome`, `chrome-mac-{arm64,x64}/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing`; the value `0` means a package-local directory and is ignored (same Playwright file). A Chromium path on macOS (`/Applications/Chromium.app`) was not confirmed and is not listed.
|
|
32
|
+
- `--remote-debugging-pipe`: messages are JSON texts ended by a NUL byte, Chrome reads fd 3 and writes fd 4, so the parent writes `stdio[3]` and reads `stdio[4]`. Sources: Puppeteer's `PipeTransport.ts` and `BrowserLauncher.ts` (https://github.com/puppeteer/puppeteer/tree/main/packages/puppeteer-core/src/node), and Chromium's `content/browser/devtools/devtools_pipe_handler.cc`.
|
|
33
|
+
- DevTools Protocol names (`json/browser_protocol.json` of https://github.com/ChromeDevTools/devtools-protocol, master, read 2026-10-16): `Network.ErrorReason` includes `BlockedByClient`; `Network.ResourceType` values `Document`, `Stylesheet`, `Image`, `Font`, `Script`, `XHR`, `Fetch`; `Fetch.enable` takes `patterns` and `handleAuthRequests`; `Fetch.requestPaused` carries `requestId`, `request`, `frameId`, `resourceType`, `redirectedRequestId`; `Fetch.failRequest` takes `errorReason`; `Fetch.authRequired` carries `authChallenge.source` (`Server` or `Proxy`); `Fetch.continueWithAuth` takes `authChallengeResponse.response` (`Default`, `CancelAuth`, `ProvideCredentials`) with `username` and `password`; `Target.createBrowserContext`, `createTarget`, `attachToTarget` (`flatten`), `closeTarget`, `disposeBrowserContext`; `Browser.close`; `Page.setLifecycleEventsEnabled` and the `networkIdle` lifecycle event.
|
|
34
|
+
- Auto-attach (same protocol JSON, 2026-10-16): `Target.setAutoAttach` takes `autoAttach`, `waitForDebuggerOnStart`, `flatten` and an experimental `filter` (`TargetFilter`: entries are matched in order, the first match wins, a last `{ exclude: true }` drops every other type); `Target.attachedToTarget` carries `sessionId`, `targetInfo` (`targetId`, `type`, `openerId`, `browserContextId`) and `waitingForDebugger`; a paused target runs after `Runtime.runIfWaitingForDebugger`. Observed with Chrome on 2026-10-16: a page-session auto-attach delivers iframes (cross-site ones run in their own process), dedicated workers and service workers, but not popups, which only a browser-level auto-attach delivers (so the render page claims them by `browserContextId`). A dedicated worker session answers `Fetch.enable` with "'Fetch.enable' wasn't found"; its requests are paused on the session of the frame that owns it.
|
|
35
|
+
- Unix socket path limit (Chromium `chrome/browser/process_singleton_posix.cc`, main, read 2026-10-18): the single-instance socket path must be shorter than `sizeof(sun_path)` (108 bytes on Linux; 104 on macOS) or Chrome aborts at start (`LOG(FATAL) << "Socket path too long"`); the socket sits in `<temp folder>/<org.chromium.Chromium.XXXXXX>/SingletonSocket`. `chrome-temp.mjs` therefore redirects Chrome's temp folder into the profile only while that folder path is at most 48 bytes, and otherwise leaves the user's own. First Ubuntu run (CI run 39049765483): every launch from a Hangul profile path and every render test exited at start; the cause was not read from Chrome itself, so the next failing launch prints Chrome's last stderr words in its error message.
|
|
36
|
+
|
|
37
|
+
### Host resolver rules (2026-10-16)
|
|
38
|
+
|
|
39
|
+
Confirmed for `skills/optbrew/scripts/core/render.mjs`: Chromium `net/base/host_mapping_rules.h` (chromium/chromium main, read 2026-10-16) defines the rules as a comma separated list of `MAP <hostname_pattern> <replacement_host>[:<port>]` and `EXCLUDE <hostname_pattern>`; the replacement is a hostname or an IP address literal, and a rule that maps to `^NOTFOUND` yields an invalid URL, so the request fails. Observed with the installed Chrome: a host mapped to `^NOTFOUND` fails to load with `net::ERR_NAME_NOT_RESOLVED`. The header does not say how a bracketed IPv6 replacement is parsed, so IPv6 pinning is not covered by a test.
|
|
40
|
+
|
|
41
|
+
### Harness signals (2026-10-17)
|
|
42
|
+
|
|
43
|
+
Confirmed for `skills/optbrew/references/harness-signals.json` and `skills/optbrew/scripts/core/probe.mjs`:
|
|
44
|
+
|
|
45
|
+
- Claude Code: `CLAUDECODE` is set to `1` in subprocesses Claude Code spawns (Bash and PowerShell tools, hooks, status line, stdio MCP servers; IDE extensions set it in their integrated terminals). `CLAUDE_CODE_REMOTE` is set automatically to `true` when Claude Code runs as a cloud session. Both rows are in https://code.claude.com/docs/en/env-vars (read 2026-10-17); the cloud session page, https://code.claude.com/docs/en/claude-code-on-the-web, is the cross-reference. A cloud session also has `CLAUDECODE`, so `CLAUDE_CODE_REMOTE` is tested first.
|
|
46
|
+
- Codex: `CODEX_SANDBOX_NETWORK_DISABLED` is set to `1` for a process spawned by a shell tool call when the network sandbox policy is restricted; `CODEX_SANDBOX` is set when the process runs under a sandbox (`seatbelt` on macOS, "may change" for other mechanisms). Source: openai/codex `codex-rs/core/src/spawn.rs`, https://github.com/openai/codex/blob/main/codex-rs/core/src/spawn.rs (read 2026-10-17, constants `CODEX_SANDBOX_NETWORK_DISABLED_ENV_VAR` and `CODEX_SANDBOX_ENV_VAR`; the file defines `CODEX_SANDBOX` but does not set it). The variable is marked experimental in that comment. The Codex docs page `docs/sandbox.md` names neither variable.
|
|
47
|
+
- Limits: a Codex run with full network access sets neither variable, so it is detected as `other` and gets the general runbooks. Only `CODEX_SANDBOX_NETWORK_DISABLED` makes a failed DNS lookup a `codex_sandbox` block; with only `CODEX_SANDBOX` set the same failure is `site_down`. No variable separates a Claude Code cloud network level from a down site, so a failed lookup or a refused proxy tunnel in a cloud session is `cloud_network_level`.
|