optbrew 0.0.0-stage → 0.1.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.
Files changed (179) hide show
  1. package/.claude-plugin/marketplace.json +6 -0
  2. package/.claude-plugin/plugin.json +6 -0
  3. package/.codex-plugin/plugin.json +13 -0
  4. package/CHANGELOG.md +50 -0
  5. package/LICENSE +21 -0
  6. package/README.ko.md +149 -0
  7. package/README.md +148 -2
  8. package/THIRD_PARTY_NOTICES.md +10 -0
  9. package/bin/optbrew.mjs +4 -0
  10. package/docs/platforms.md +107 -0
  11. package/docs/release.md +14 -0
  12. package/lib/cli.mjs +116 -0
  13. package/lib/doctor.mjs +45 -0
  14. package/lib/install.mjs +158 -0
  15. package/lib/paths.mjs +30 -0
  16. package/lib/records.mjs +44 -0
  17. package/lib/reinstall.mjs +92 -0
  18. package/lib/transaction.mjs +205 -0
  19. package/lib/update.mjs +189 -0
  20. package/package.json +39 -4
  21. package/plugin.json +13 -0
  22. package/skills/optbrew/LICENSE +21 -0
  23. package/skills/optbrew/SKILL.md +17 -0
  24. package/skills/optbrew/THIRD_PARTY_NOTICES.md +10 -0
  25. package/skills/optbrew/agents/openai.yaml +4 -0
  26. package/skills/optbrew/bundle-manifest.json +687 -0
  27. package/skills/optbrew/licenses/firecrawl-seo-audit.txt +15 -0
  28. package/skills/optbrew/licenses/magnus-seo.txt +21 -0
  29. package/skills/optbrew/licenses/marketing-search.txt +21 -0
  30. package/skills/optbrew/licenses/mblode-seo.txt +21 -0
  31. package/skills/optbrew/licenses/naver-searchadvisor.txt +29 -0
  32. package/skills/optbrew/licenses/seranking-seo.txt +21 -0
  33. package/skills/optbrew/modules/firecrawl-seo-audit/GUIDE.md +64 -0
  34. package/skills/optbrew/modules/magnus-seo/GUIDE.md +79 -0
  35. package/skills/optbrew/modules/magnus-seo/README.md +45 -0
  36. package/skills/optbrew/modules/magnus-seo/assets/audit-report-template.md +76 -0
  37. package/skills/optbrew/modules/magnus-seo/references/aeo-methodology.md +105 -0
  38. package/skills/optbrew/modules/magnus-seo/references/agent-readable-content.md +28 -0
  39. package/skills/optbrew/modules/magnus-seo/references/content-and-entity-architecture.md +100 -0
  40. package/skills/optbrew/modules/magnus-seo/references/content-strategy-seo.md +142 -0
  41. package/skills/optbrew/modules/magnus-seo/references/discovery-and-freshness.md +47 -0
  42. package/skills/optbrew/modules/magnus-seo/references/evidence-boundaries.md +75 -0
  43. package/skills/optbrew/modules/magnus-seo/references/ghost-metadata.md +204 -0
  44. package/skills/optbrew/modules/magnus-seo/references/implementation-playbook.md +114 -0
  45. package/skills/optbrew/modules/magnus-seo/references/measurement-and-experimentation.md +47 -0
  46. package/skills/optbrew/modules/magnus-seo/references/onpage-seo.md +154 -0
  47. package/skills/optbrew/modules/magnus-seo/references/platform-guidance.md +30 -0
  48. package/skills/optbrew/modules/magnus-seo/references/schema-markup.md +244 -0
  49. package/skills/optbrew/modules/magnus-seo/references/source-index.md +36 -0
  50. package/skills/optbrew/modules/magnus-seo/references/structured-data.md +56 -0
  51. package/skills/optbrew/modules/magnus-seo/references/technical-seo.md +99 -0
  52. package/skills/optbrew/modules/magnus-seo/scripts/aeo_audit.py +158 -0
  53. package/skills/optbrew/modules/magnus-seo/scripts/build_prompt_matrix.py +52 -0
  54. package/skills/optbrew/modules/magnus-seo/templates/aeo-implementation-plan.md +53 -0
  55. package/skills/optbrew/modules/magnus-seo/templates/citation-observation-log.md +16 -0
  56. package/skills/optbrew/modules/magnus-seo/templates/llms.txt.template +15 -0
  57. package/skills/optbrew/modules/magnus-seo/templates/question-cluster.md +27 -0
  58. package/skills/optbrew/modules/magnus-seo/templates/robots-ai-crawlers.txt +23 -0
  59. package/skills/optbrew/modules/marketing-search/skills/ai-seo/GUIDE.md +483 -0
  60. package/skills/optbrew/modules/marketing-search/skills/ai-seo/references/agent-readiness.md +57 -0
  61. package/skills/optbrew/modules/marketing-search/skills/ai-seo/references/citations-vs-recommendations.md +85 -0
  62. package/skills/optbrew/modules/marketing-search/skills/ai-seo/references/content-patterns.md +287 -0
  63. package/skills/optbrew/modules/marketing-search/skills/ai-seo/references/content-types.md +71 -0
  64. package/skills/optbrew/modules/marketing-search/skills/ai-seo/references/format-volatility.md +98 -0
  65. package/skills/optbrew/modules/marketing-search/skills/ai-seo/references/okf.md +104 -0
  66. package/skills/optbrew/modules/marketing-search/skills/ai-seo/references/platform-ranking-factors.md +154 -0
  67. package/skills/optbrew/modules/marketing-search/skills/ai-seo/references/youtube-ai-citations.md +60 -0
  68. package/skills/optbrew/modules/marketing-search/skills/analytics/GUIDE.md +303 -0
  69. package/skills/optbrew/modules/marketing-search/skills/analytics/references/event-library.md +260 -0
  70. package/skills/optbrew/modules/marketing-search/skills/analytics/references/ga4-implementation.md +300 -0
  71. package/skills/optbrew/modules/marketing-search/skills/analytics/references/gtm-implementation.md +390 -0
  72. package/skills/optbrew/modules/marketing-search/skills/content-strategy/GUIDE.md +432 -0
  73. package/skills/optbrew/modules/marketing-search/skills/content-strategy/references/content-distribution.md +83 -0
  74. package/skills/optbrew/modules/marketing-search/skills/content-strategy/references/headless-cms.md +194 -0
  75. package/skills/optbrew/modules/marketing-search/skills/programmatic-seo/GUIDE.md +231 -0
  76. package/skills/optbrew/modules/marketing-search/skills/programmatic-seo/references/playbooks.md +308 -0
  77. package/skills/optbrew/modules/marketing-search/skills/schema/GUIDE.md +172 -0
  78. package/skills/optbrew/modules/marketing-search/skills/schema/references/schema-examples.md +398 -0
  79. package/skills/optbrew/modules/marketing-search/skills/seo-audit/GUIDE.md +492 -0
  80. package/skills/optbrew/modules/marketing-search/skills/seo-audit/references/ai-writing-detection.md +200 -0
  81. package/skills/optbrew/modules/marketing-search/skills/seo-audit/references/international-seo.md +230 -0
  82. package/skills/optbrew/modules/marketing-search/skills/site-architecture/GUIDE.md +350 -0
  83. package/skills/optbrew/modules/marketing-search/skills/site-architecture/references/mermaid-templates.md +216 -0
  84. package/skills/optbrew/modules/marketing-search/skills/site-architecture/references/navigation-patterns.md +305 -0
  85. package/skills/optbrew/modules/marketing-search/skills/site-architecture/references/site-type-templates.md +293 -0
  86. package/skills/optbrew/modules/mblode-seo/GUIDE.md +74 -0
  87. package/skills/optbrew/modules/mblode-seo/references/answer-engines.md +58 -0
  88. package/skills/optbrew/modules/mblode-seo/references/audit.md +78 -0
  89. package/skills/optbrew/modules/mblode-seo/references/brief-template.md +47 -0
  90. package/skills/optbrew/modules/mblode-seo/references/monitoring.md +56 -0
  91. package/skills/optbrew/modules/mblode-seo/references/nextjs-implementation.md +65 -0
  92. package/skills/optbrew/modules/mblode-seo/references/research-protocol.md +37 -0
  93. package/skills/optbrew/modules/mblode-seo/references/sources.md +47 -0
  94. package/skills/optbrew/modules/mblode-seo/references/validation-evidence.md +21 -0
  95. package/skills/optbrew/modules/naver-searchadvisor/GUIDE.md +75 -0
  96. package/skills/optbrew/modules/naver-searchadvisor/NOTICE.md +59 -0
  97. package/skills/optbrew/modules/naver-searchadvisor/references/INDEX.md +97 -0
  98. package/skills/optbrew/modules/naver-searchadvisor/scripts/audit.mjs +742 -0
  99. package/skills/optbrew/modules/naver-searchadvisor/scripts/robots.mjs +77 -0
  100. package/skills/optbrew/modules/seranking-seo/skills/seo-ai-search-share-of-voice/GUIDE.md +94 -0
  101. package/skills/optbrew/modules/seranking-seo/skills/seo-api/GUIDE.md +186 -0
  102. package/skills/optbrew/modules/seranking-seo/skills/seo-api/references/api-surface-map.md +207 -0
  103. package/skills/optbrew/modules/seranking-seo/skills/seo-api/references/auth-and-keys.md +182 -0
  104. package/skills/optbrew/modules/seranking-seo/skills/seo-api/references/integration-patterns.md +283 -0
  105. package/skills/optbrew/modules/seranking-seo/skills/seo-api/references/rate-limits-and-credits.md +235 -0
  106. package/skills/optbrew/modules/seranking-seo/skills/seo-competitor-gap-analysis/GUIDE.md +117 -0
  107. package/skills/optbrew/modules/seranking-seo/skills/seo-content-audit/GUIDE.md +155 -0
  108. package/skills/optbrew/modules/seranking-seo/skills/seo-content-audit/references/cite.md +84 -0
  109. package/skills/optbrew/modules/seranking-seo/skills/seo-content-audit/references/core-eeat.md +147 -0
  110. package/skills/optbrew/modules/seranking-seo/skills/seo-content-audit/templates/verdict.md +63 -0
  111. package/skills/optbrew/modules/seranking-seo/skills/seo-firecrawl/GUIDE.md +141 -0
  112. package/skills/optbrew/modules/seranking-seo/skills/seo-firecrawl/references/preflight.md +73 -0
  113. package/skills/optbrew/modules/seranking-seo/skills/seo-geo/GUIDE.md +159 -0
  114. package/skills/optbrew/modules/seranking-seo/skills/seo-google/GUIDE.md +393 -0
  115. package/skills/optbrew/modules/seranking-seo/skills/seo-google/assets/templates/cwv-audit-report.md +48 -0
  116. package/skills/optbrew/modules/seranking-seo/skills/seo-google/assets/templates/gsc-performance-report.md +44 -0
  117. package/skills/optbrew/modules/seranking-seo/skills/seo-google/assets/templates/indexation-status-report.md +43 -0
  118. package/skills/optbrew/modules/seranking-seo/skills/seo-google/references/auth-setup.md +160 -0
  119. package/skills/optbrew/modules/seranking-seo/skills/seo-google/references/cross-skill-integration.md +187 -0
  120. package/skills/optbrew/modules/seranking-seo/skills/seo-google/references/ga4-data-api.md +184 -0
  121. package/skills/optbrew/modules/seranking-seo/skills/seo-google/references/indexing-api.md +109 -0
  122. package/skills/optbrew/modules/seranking-seo/skills/seo-google/references/keyword-planner-api.md +66 -0
  123. package/skills/optbrew/modules/seranking-seo/skills/seo-google/references/nlp-api.md +55 -0
  124. package/skills/optbrew/modules/seranking-seo/skills/seo-google/references/pagespeed-crux-api.md +204 -0
  125. package/skills/optbrew/modules/seranking-seo/skills/seo-google/references/rate-limits-quotas.md +75 -0
  126. package/skills/optbrew/modules/seranking-seo/skills/seo-google/references/search-console-api.md +156 -0
  127. package/skills/optbrew/modules/seranking-seo/skills/seo-google/references/supplementary-apis.md +99 -0
  128. package/skills/optbrew/modules/seranking-seo/skills/seo-google/references/youtube-api.md +49 -0
  129. package/skills/optbrew/modules/seranking-seo/skills/seo-keyword-niche/GUIDE.md +174 -0
  130. package/skills/optbrew/modules/seranking-seo/skills/seo-page/GUIDE.md +174 -0
  131. package/skills/optbrew/modules/seranking-seo/skills/seo-plan/GUIDE.md +220 -0
  132. package/skills/optbrew/modules/seranking-seo/skills/seo-schema/GUIDE.md +135 -0
  133. package/skills/optbrew/modules/seranking-seo/skills/seo-schema/references/google-rich-results.md +89 -0
  134. package/skills/optbrew/modules/seranking-seo/skills/seo-schema/templates/article.json +23 -0
  135. package/skills/optbrew/modules/seranking-seo/skills/seo-schema/templates/breadcrumb-list.json +18 -0
  136. package/skills/optbrew/modules/seranking-seo/skills/seo-schema/templates/faq-page.json +22 -0
  137. package/skills/optbrew/modules/seranking-seo/skills/seo-schema/templates/local-business.json +32 -0
  138. package/skills/optbrew/modules/seranking-seo/skills/seo-schema/templates/product.json +25 -0
  139. package/skills/optbrew/modules/seranking-seo/skills/seo-sitemap/GUIDE.md +128 -0
  140. package/skills/optbrew/modules/seranking-seo/skills/seo-technical-audit/GUIDE.md +235 -0
  141. package/skills/optbrew/modules/seranking-seo/skills/seo-technical-audit/references/severity-mapping.md +133 -0
  142. package/skills/optbrew/references/ai-crawlers.json +21 -0
  143. package/skills/optbrew/references/ai-crawlers.md +24 -0
  144. package/skills/optbrew/references/api.md +45 -0
  145. package/skills/optbrew/references/check-registry.json +28 -0
  146. package/skills/optbrew/references/evidence.md +9 -0
  147. package/skills/optbrew/references/intake.md +9 -0
  148. package/skills/optbrew/references/measurement.md +29 -0
  149. package/skills/optbrew/references/policies.md +7 -0
  150. package/skills/optbrew/references/profiles.json +13 -0
  151. package/skills/optbrew/references/remediations.json +12 -0
  152. package/skills/optbrew/references/report.md +29 -0
  153. package/skills/optbrew/references/routing.md +15 -0
  154. package/skills/optbrew/references/schemas/contract.schema.json +51 -0
  155. package/skills/optbrew/references/scoring.md +62 -0
  156. package/skills/optbrew/scripts/adapters/anthropic.mjs +116 -0
  157. package/skills/optbrew/scripts/adapters/imports.mjs +81 -0
  158. package/skills/optbrew/scripts/audit.mjs +124 -0
  159. package/skills/optbrew/scripts/cli.mjs +41 -0
  160. package/skills/optbrew/scripts/core/bootstrap.mjs +31 -0
  161. package/skills/optbrew/scripts/core/bundle.mjs +73 -0
  162. package/skills/optbrew/scripts/core/capabilities.mjs +19 -0
  163. package/skills/optbrew/scripts/core/collector.mjs +250 -0
  164. package/skills/optbrew/scripts/core/compare.mjs +47 -0
  165. package/skills/optbrew/scripts/core/contracts.mjs +144 -0
  166. package/skills/optbrew/scripts/core/cost-ledger.mjs +95 -0
  167. package/skills/optbrew/scripts/core/crawlers.mjs +11 -0
  168. package/skills/optbrew/scripts/core/derive.mjs +168 -0
  169. package/skills/optbrew/scripts/core/facts.mjs +189 -0
  170. package/skills/optbrew/scripts/core/findings.mjs +54 -0
  171. package/skills/optbrew/scripts/core/html.mjs +53 -0
  172. package/skills/optbrew/scripts/core/metrics.mjs +97 -0
  173. package/skills/optbrew/scripts/core/protocol.mjs +125 -0
  174. package/skills/optbrew/scripts/core/report.mjs +742 -0
  175. package/skills/optbrew/scripts/core/scope.mjs +52 -0
  176. package/skills/optbrew/scripts/core/score.mjs +71 -0
  177. package/skills/optbrew/scripts/core/weights.mjs +139 -0
  178. package/skills/optbrew/source-lock.json +2686 -0
  179. package/source-lock.json +2686 -0
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "optbrew-local",
3
+ "description": "Local optbrew plugin source",
4
+ "owner": { "name": "optbrew" },
5
+ "plugins": [{ "name": "optbrew", "source": "./", "version": "0.1.2" }]
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "optbrew",
3
+ "version": "0.1.2",
4
+ "description": "Pinned search audit and improvement skill bundle",
5
+ "skills": ["./skills/optbrew"]
6
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
+ "name": "optbrew",
4
+ "version": "0.1.2",
5
+ "description": "Pinned search audit and improvement skill bundle",
6
+ "license": "MIT",
7
+ "extensions": {
8
+ "com.openai": {
9
+ "skills": ["./skills/optbrew"],
10
+ "release_version": "0.1.2"
11
+ }
12
+ }
13
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,50 @@
1
+ # Changelog
2
+
3
+ ## 0.1.2
4
+
5
+ - The report headline no longer lets a measured score read as a complete one. Each headline score carries its coverage; below the 80% coverage rule the single number is withheld and the report shows `insufficient coverage` with the measured-subset value and the missing-data bounds (`report.json` `headline[]`).
6
+ - The audit now observes from collected responses: duplicate titles (`document-title`), canonical target status and redirect-chain length (`canonical-consistency`), link and declared-sitemap discovery (`discovery`), JSON-LD parse errors (`structured-data-truth`), Naver markup moved from the unreachable direct-fetch path into the collected-evidence path (`naver-markup`: Open Graph, description, canonical, viewport, title repetition, CSS or JS blocked for Yeti), `search-crawl-policy` for Googlebot, Yeti and the AI search bots OAI-SearchBot, Claude-SearchBot and PerplexityBot (`references/ai-crawlers.md`; training bots stay unscored), and cross-page name, address, phone and founding-year comparison with an entity-identity check (`fact-consistency`, `entity-identity`).
7
+ - `search-crawl-policy` now records a pass as well as a fail for every engine that has a robots token. The collector fetches in-scope canonical targets while the request count is under the limit.
8
+ - Report replay derives every collector verdict again from the hashed raw evidence with the same code the audit uses, and rejects a derived observation that is missing, extra or different.
9
+ - Evaluation version 0.2.0 (was 0.1.0). The set of observations the audit and report produce changed, so 0.1.1 and 0.1.2 scores are not comparable: `compare()` returns `not_comparable` (`evaluation_version_changed`) for a 0.1.1 baseline against 0.1.2 inputs, and the current bundle refuses to score a 0.1.1 input. Run the baseline audit again with 0.1.2 before comparing. Scoring contracts, profile weights, the check registry and the protocol version (0.1.0, protocol sources unchanged) are unchanged.
10
+ - A managed install of 0.1.1 cannot be updated to 0.1.2. The updater guard is unchanged, so `optbrew update` stops with `migration_required` and changes nothing. The message now lists the exact paths to delete and the install and doctor commands for PowerShell and POSIX shells. To replace the install by hand, use the copy-paste blocks for user and project scope in the README and `docs/platforms.md`, "Reinstall after a migration_required update". Each block first runs the new read-only `optbrew reinstall-plan`, which resolves the home directory the way the CLI does and refuses a tampered install record (a target that is not exactly the agent's `skills/optbrew` path, a relative or `..` path, a link that leads elsewhere) before anything is deleted; the shell then deletes only the printed paths, targets first and the managed root last, so the block can be run again after a failure, and never touches `.optbrew/runs`. Updates and rollbacks between releases that keep evaluation version 0.2.0 are unaffected.
11
+ - Public clones: the four maintainer-only vendor tests skip with a reason when the upstream source mirror is absent, so `npm test` passes without it.
12
+ - Round-two review fixes. Replay also binds `skipped`, `limit_reached` and the request counts to a hashed request ledger (`ledger.json`) and the response records, requires every module the audit lists to have its output, derives every collector family from the collector evidence even when a module did not run, and compares the reason and evaluator of each observation. Fact comparison reads only Organization or LocalBusiness JSON-LD, `tel:` links and labelled contact fields, normalises addresses, and treats branch pages as separate entities. Discovery decodes entity-encoded links, treats `index.html` as its directory, and stays unknown for sitemap indexes and script-built navigation. JSON-LD inside comments is ignored. The headline also needs a verdict on every core check, and 79.95% coverage is never shown as 80%.
13
+ - Audit evidence from 0.1.1 has no request ledger or module list and is refused by 0.1.2 report replay with an "older optbrew release" error. Run the audit again with 0.1.2.
14
+ - Round-four review fixes. The request ledger rejects a skipped entry that carries requests and binds a failed fetch to the requests it made (`requests_made` in `collection.json`) and its redirect chain, so a forger cannot pad the total to a claimed request limit. Fact comparison: a phone number no longer continues across a line break; a `tel:` link is its own evidence class and counts only on a page with no labelled or JSON-LD phone; addresses compare as whole tokens (`10 Main St` is not `110 Main St`), and a postal code is dropped only in its own position, so a five-digit street number stays part of the address.
15
+ - Discovery: while any collected page has scripts and no anchors, an unlinked page is unknown (that page may link it from the browser) unless a fetched sitemap that lists other pages leaves it out; without such a page the link graph decides as before. `build-bundle` writes `bundle-manifest.json` through a temporary file and a rename, so a concurrent reader never sees an empty file.
16
+ - Round-five review fixes. Request accounting: a failed fetch has no hashed response record, so it always counts as one request in the ledger and in `request_count`, whatever its redirect chain says; report replay requires exactly that, so a forger cannot pad the total to a claimed request limit. The request limit (`max_urls`, at most 50) now decides only whether a fetch may start, and a redirect chain that has started is completed. A chain follows at most min(10, `max_urls`) redirects, so the requests beyond the limit are at most `concurrency` x min(10, `max_urls`) (20 with the defaults, 10 for `max_urls` 5); report replay applies the same bound. A run that hit the limit while a failed fetch had followed redirects can fall short of the limit in the ledger; replay then rejects the report as unprovable, and the audit has to be run again.
17
+ - Phone extraction reads from text in which every tag ends the text before it, so a number in the next span, table cell or list item is never absorbed; a spaced number that is followed by more digits or a bracketed digit is read only up to its dashed or dotted part, and a national number with spaces between its groups is not read at all. The same address words in another order (27 Wausan-ro, Mapo-gu, Seoul and Seoul, Mapo-gu, Wausan-ro 27) are one address.
18
+ - `optbrew reinstall-plan` also refuses a scope, target or agent name that contains a line break, tab or other control character, because one printed path per line is what the documented blocks delete.
19
+ - A failed fetch or a request-limit skip is only accepted for a URL with provenance: a selected or auxiliary URL of the run, or a URL that a hashed page of the collection links to (anchors and canonical). Report replay rejects fabricated entries for never-linked URLs, which could otherwise pad the request total to a false limit claim and so suppress discovery failures. Duplicate entries for linked URLs are not yet rejected; see Known limitations.
20
+ - `build-release` writes `bundle-manifest.json` through the same temporary file and rename as `build-bundle`, and the release tests build on a private copy of the tree.
21
+ - Not scripted yet: the `robots.txt` Sitemap line, og:image size, hreflang, JavaScript-only navigation, answer structure, claim support, authorship and freshness.
22
+
23
+ ### Known limitations
24
+
25
+ - Report replay does not reject a URL that appears in more than one ledger entry, so adding failed-fetch duplicates of already fetched linked URLs to `collection.json`, `ledger.json` and the audit index can prove a false request limit and turn a discovery failure into `unknown`; this needs deliberate edits to local evidence files.
26
+ - A run that reaches the request limit while a failed fetch was following redirects can record fewer requests than the limit, and report replay then refuses it as unprovable; run the audit again.
27
+ - While any collected page has scripts and no anchors, an unlinked page stays `unknown` unless a declared sitemap that lists other pages leaves it out, so an orphan page on such a site is not reported.
28
+ - Phone extraction skips national numbers written with spaces only (for example `02 555 0142`) and numbers shorter than nine digits (for example `1588-1234`), so a wrong number in those forms is not detected.
29
+ - A page whose title or first heading contains "branch", 지점 or 지사 is treated as a separate entity, so a wrong phone or address on such a page stays `unknown`.
30
+ - Requests can exceed `max_urls` by up to concurrency × min(10, `max_urls`) because a redirect chain that has started is completed (20 with the defaults, 10 for `max_urls` 5).
31
+ - The Naver crawler token `Yeti` was not re-read from Naver's official page during the 0.1.2 review (the page could not be fetched); the other AI and search crawler tokens match the vendors' official pages as checked on 2026-10-15.
32
+
33
+ ## 0.1.1 — local release candidate
34
+
35
+ - Verified a real localhost noindex/title baseline, backed-up local edit, same-condition rescan and evidence-bound JSON/Markdown report. The collector emits pass or fail observations for completed index checks, a fail for a missing title and unknown for a present one (uniqueness and descriptiveness need separate evidence), and the report replays title, index and crawl-policy verdicts from the preserved raw bytes.
36
+ - Audit evidence produced before the hashed response records existed must be re-collected; the audit evidence format changed during 0.1.1 development, and report replay now rejects older audit output. Report replay also rejects a selected page that is neither collected nor skipped, and a packet that drops its audit snapshot while collector evidence is indexed. A production resolution now names the evaluator type and source of its resolving observation.
37
+ - Final review round 2: the collector keeps each X-Robots-Tag header line separate and hashes a response record (final URL, redirect chain, header lines) beside every raw body; report replay binds the final URL and headers to that record, requires every planned collector observation, and accepts `verified_local` only through the production-style observation binding of a collector-produced after observation. Native export paths refuse protocol-relative or other-host URLs, a semicolon separates robots meta directives, and the ZIP verifier refuses Windows case-insensitive and trailing dot or space name collisions.
38
+ - Final review fixes: index directives ignore commented or script text and follow the target engine's meta and X-Robots-Tag scope; report replay accepts permitted redirects and header-only noindex findings and re-derives robots verdicts; a byte-hash receipt alone no longer marks a fix verified locally; redirect hops count against the 50-request budget; native path mappings match whole path segments; the release verifier rejects unextractable ZIP layouts.
39
+ - Bound runtime scoring to the installed evaluation/protocol source hashes and versions. The evaluation and observation protocol versions remain 0.1.0. Root notice links resolve to the packaged skill licenses.
40
+ - Fixed direct audit and calculation entrypoints invoked through managed Windows junctions or Unix symlinks. Ordinary imports remain inert.
41
+ - The report separates baseline and after blocker counts. Locally verified fixes now lead to production deployment/reobservation work instead of repeating the original edit instruction.
42
+ - One fresh Codex bare invocation completed on the local 0.1.0 install. Broader native behavior and Claude Code invocation remain unverified for this corrected release.
43
+
44
+ ## 0.1.0 — local prepublication install
45
+
46
+ - Added one pinned optbrew skill source with five selected source bundles and seven marketing guides. Retained notices and modification records; excluded 55 Naver original guide articles while keeping official index links.
47
+ - Added local collection boundaries, evidence-based readiness scoring, before/after comparison, and report generation. Scores distinguish unknown checks, blockers, and actual outcomes.
48
+ - Added managed install, doctor, update, and rollback paths for Codex, Claude Code, Cursor, OpenCode, and Pi; added host plugin and Pi package metadata.
49
+ - Added a text-only direct Anthropic adapter with exact model and token-bound checks. API use remains optional and requires an approved cost decision.
50
+ - Added English and Korean usage, API, platform, and release instructions. This initial local install did not establish public npm/GitHub publication or native host invocation.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 optbrew contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.ko.md ADDED
@@ -0,0 +1,149 @@
1
+ # optbrew
2
+
3
+ [English](README.md)
4
+
5
+ Optbrew는 웹사이트의 검색 준비도를 확인하고, 승인된 로컬 파일을 고친 뒤, 전후 근거를 비교하는 스킬과 CLI입니다. 고정된 원본 묶음 5개(mblode SEO, Naver Search Advisor, Firecrawl SEO Audit, Magnus SEO, SE Ranking SEO)와 선택한 마케팅 가이드 7개를 포함합니다. 최상위 `SKILL.md` 한 파일이 내부 가이드를 안내합니다. 실행 중에 바뀌는 upstream 파일을 가져오지 않습니다.
6
+
7
+ 저장된 JSON으로 점수를 계산하고 보고서를 만드는 데 API 계정은 필요하지 않습니다. 사이트 감사에는 대상과 허용 범위가 필요합니다. 공개 게시, 검색엔진 제출, 원격 사이트 수정, 유료 호출은 각각 별도 권한이 필요합니다. 설치 파일이 놓인 상태와 호스트가 실제로 스킬을 호출한 상태는 [플랫폼 안내](docs/platforms.md)에서 구분합니다.
8
+
9
+ ## 설치
10
+
11
+ Node.js 22 이상이 필요합니다. 내부 Python 감사 도구는 Python 3.10 이상이 필요합니다. Python이 없으면 그 도구는 미실행으로 남깁니다. 이 checkout에서 `site`라는 별도 프로젝트 폴더를 만든 뒤 실행합니다.
12
+
13
+ Bash와 PowerShell에서 같은 명령을 사용합니다.
14
+
15
+ ```text
16
+ node bin/optbrew.mjs install --agents codex,claude-code,cursor,opencode,pi --scope project --project ./site --strategy copy --dry-run --json
17
+ node bin/optbrew.mjs install --agents codex,claude-code,cursor,opencode,pi --scope project --project ./site --strategy copy --json
18
+ node bin/optbrew.mjs doctor --agents codex,claude-code,cursor,opencode,pi --scope project --project ./site --json
19
+ ```
20
+
21
+ 저장소 루트에서 실행하십시오. 기본 전략은 `--strategy link`입니다. 링크를 쓸 수 없으면 `copy`를 선택할 수 있습니다. 관리 기록은 프로젝트의 `.optbrew/install`에 둡니다. 한 호스트만 설치하려면 목록 대신 `codex`, `claude-code`, `cursor`, `opencode`, `pi` 중 한 ID를 적습니다. 사용자 전체 범위에 설치할 때만 `--scope user`를 씁니다. 설치 명령은 번들 manifest를 확인하며 관리 대상이 아닌 기존 폴더를 덮어쓰지 않습니다.
22
+
23
+ checkout은 `https://github.com/nowwcastle-sudo/optbrew`를 clone해서 받고, 위 명령은 그 저장소 최상위에서 실행합니다. `npm install -g optbrew`로 설치하면 같은 CLI를 `optbrew` 명령으로 쓸 수 있습니다. 이때는 위 명령의 `node bin/optbrew.mjs`를 `optbrew`로 바꿉니다. 호스트 고유 설치와 ZIP은 [플랫폼 안내](docs/platforms.md)를 보십시오.
24
+
25
+ ## 첫 실행
26
+
27
+ 호스트에 optbrew를 사용하라고 요청할 때 대상 URL, 목표, 사이트 소유 또는 접근 권한, 허용할 로컬 변경, 보유한 근거를 전달합니다. 로컬 감사 전에 URL 범위를 선언합니다. 기본 수집 상한은 URL 50개, 깊이 3, 동시성 2입니다. 새 요청은 한도 아래에서만 시작합니다. 이미 시작한 리다이렉트 체인은 끝까지 갑니다. 체인은 리다이렉트 min(10, `max_urls`)번까지라서 한도를 넘는 요청은 동시성 × min(10, `max_urls`)건 이하입니다(기본값은 20건). 사설 주소는 명시한 로컬 대상에서만 허용합니다. 작업은 원시 근거, 준비도 관찰, 로컬 변경, 후속 확인을 기록합니다. 로컬 검증 통과를 운영 성과로 해석하지 않습니다.
28
+
29
+ 다음 명령은 포함된 합성 fixture를 재생하며 제공자 호출을 하지 않습니다. 저장소 루트에서 새 출력 경로를 골라 실행합니다.
30
+
31
+ Bash와 PowerShell에서 같은 명령을 사용합니다.
32
+
33
+ ```text
34
+ node bin/optbrew.mjs score --input ./before.json --output ./score.json
35
+ node bin/optbrew.mjs compare --before ./before.json --after ./after.json --output ./comparison.json
36
+ node bin/optbrew.mjs report --input ./remote-only.json --output-dir ./report-output
37
+ ```
38
+
39
+ 명령을 그대로 실행하려면 `tests/fixtures/scoring/before.json`, `after.json`을 현재 폴더로 복사합니다. `tests/fixtures/reports/remote-only.json`과 같은 폴더의 근거 파일도 함께 복사합니다. 실제 작업에서는 자신의 검증된 `ScoreInput` 또는 `ReportPacket` 경로를 넘깁니다. 계약은 [채점](skills/optbrew/references/scoring.md), [측정](skills/optbrew/references/measurement.md), [보고 근거](skills/optbrew/references/report.md)에 있습니다.
40
+
41
+ ## 점수와 보고서
42
+
43
+ 자체 준비도 프로필은 SEO, 네이버가 대상일 때 NEO, AEO, GEO, LLMO입니다. 고유 검사군 22개는 여러 가이드가 같은 문제를 찾아도 한 번만 셉니다. 확인하지 못한 적용 검사는 분모에 남기고, 근거 있는 `not_applicable` 검사만 제외합니다. 결과에는 점수, 측정 범위, 미측정 구간의 상·하한, 차단 요소, 미확인 핵심 검사가 들어갑니다. 측정 범위 80% 기준은 optbrew 자체 규칙이며 검색엔진 기준이 아닙니다. 높은 준비도 점수는 색인, 유입, 인용, 사실 정확성, 전환, 매출을 증명하지 않습니다.
44
+
45
+ 감사 스크립트가 수집한 응답에서 스스로 관찰하는 항목은 다음과 같습니다. 응답 상태, meta 태그와 `X-Robots-Tag`의 색인 지시자(대상 엔진별), 제목 없음·중복, 선언한 엔진별 robots.txt 접근(Googlebot, Yeti, [`ai-crawlers.md`](skills/optbrew/references/ai-crawlers.md)의 AI 검색 봇. 학습 봇은 점수에 넣지 않음), canonical 대상과 리다이렉트 체인 길이, 링크 또는 선언한 사이트맵을 통한 발견성, JSON-LD 문법, 네이버 마크업(Open Graph, 설명, canonical, viewport, 제목 키워드 반복, 막힌 CSS·JS), 이름·주소·전화·설립연도의 페이지 간 일치입니다. 따라서 SEO와 NEO는 접근·색인·마크업 검사를 스크립트로 합니다. AEO와 GEO는 준비도 감사로 남습니다. 답변 구조, 주장 근거, 저자, 최신성은 가이드와 에이전트 판단이 필요합니다. LLMO는 페이지 간 불일치를 보여 주는 검사를 얻지만 사실이 맞다는 것을 증명하지는 않습니다. 심은 결함 시험과 한계는 저장소의 `docs/validation/detection-0.1.2.md`에 있습니다.
46
+
47
+ 측정 범위가 80% 미만이면 보고서는 하나의 대표 점수를 내지 않고 측정된 부분의 값과 상·하한을 보여 줍니다. 모든 대표 점수는 측정 범위와 함께 표시됩니다.
48
+
49
+ 보고서는 준비도, 해결 방안, 실제 성과, 남은 일을 별도 표로 보여 줍니다. 실제 성과에는 소유자 내보내기 자료 또는 고정된 AI 질문 패널이 필요합니다. 일반 성과 비교에는 정의와 필터가 같은 인접한 완결 28일 기간 두 개를 사용합니다. 로컬 수정은 배포와 운영 관찰의 근거가 생기기 전까지 로컬 수정입니다.
50
+
51
+ ## API와 비용
52
+
53
+ API 사용은 선택 사항입니다. Claude 또는 Claude Code 구독에 Anthropic API 과금이 포함되는 것은 아닙니다. 직접 API 키는 [공식 발급 안내](https://platform.claude.com/docs/en/get-api-key)의 Console → Settings → API keys에서 만듭니다. 키는 자신의 셸 또는 비밀 관리 도구에서 `ANTHROPIC_API_KEY`로 설정합니다. 보고서에 실값을 넣지 마십시오. v0.1.0에서 도입한 직접 어댑터는 여러 Anthropic workspace에 걸친 키에 필요할 수 있는 `anthropic-workspace-id` 헤더를 여전히 설정하지 않습니다. 호환 키나 별도로 승인된 호스트 기능을 사용합니다.
54
+
55
+ 직접 어댑터는 텍스트 `{model,max_tokens,messages}` 요청과 정확한 모델 ID `claude-fable-5-1`, `claude-opus-5-5`, `claude-sonnet-5-5`, `claude-haiku-5-5`만 받습니다. `max_tokens` 상한은 128,000입니다. 매 시도에는 `1,000,000 + max_tokens` 이상의 토큰 예약 한 개, 맞는 장부 예산, 승인 참조가 필요합니다. 이 예약은 최악 경우의 용량 상한이며 예상 청구액이 아닙니다. 첫 유료 호출 전에 현재 단가의 출처와 날짜, 예상 지출, 승인된 중단 조건을 기록합니다. 추가 필드, 도구, 검색, 비텍스트 입력, 다른 모델, 통화만으로 설정한 상한은 직접 호출 전에 거부됩니다. 자세한 경계는 [API 안내](skills/optbrew/references/api.md)에 있습니다.
56
+
57
+ SE Ranking은 별도의 [API](https://seranking.com/api.html), [MCP 안내](https://seranking.com/api/integrations/mcp), 계정 상품, 크레딧을 사용합니다. [HTTP MCP 주소](https://api.seranking.com/mcp)는 문서에 따른 OAuth 또는 직접 토큰 경로를 씁니다. `ANTHROPIC_API_KEY`와는 별개입니다. 사용 가능한 도구는 구독에 따라 달라집니다. 오프라인 채점에는 어느 연결도 필요하지 않습니다. 유료 기능을 결정할 때 실제 계정의 단가와 크레딧을 확인합니다.
58
+
59
+ ## 업데이트와 복원
60
+
61
+ 관리 설치를 갱신하려면 먼저 검증된 새 optbrew 번들을 빌드하거나 받습니다. 저장소 루트에서 다음 명령을 실행합니다.
62
+
63
+ Bash와 PowerShell에서 같은 명령을 사용합니다.
64
+
65
+ ```text
66
+ node bin/optbrew.mjs check-updates --json
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
69
+ ```
70
+
71
+ `check-updates --package optbrew`는 npm 레지스트리에서 최신 버전을 읽습니다. `--package`를 빼면 `local_only`를 반환합니다. `update`는 현재 CLI 번들을 검증한 뒤 관리 기록의 모든 대상에 적용합니다. 로컬 편집은 자동으로 덮어쓰지 않습니다. `rollback`은 관리 기록에 해당 이전 버전이 남아 있어야 합니다. 새 0.1.2 설치에서는 위 복원 예시가 실패하며, 로컬 0.1.0을 보존한 관리 설치에 적용됩니다. 출시 후 `npm update -g optbrew`는 npm 패키지를 갱신하지만 이전에 agent 스킬 폴더로 복사한 파일까지 바꾸지는 않습니다. CLI를 갱신한 다음 관리 `update`를 다시 실행합니다. 관리 중인 0.1.1 설치는 0.1.2로 갱신할 수 없고 `update`가 `migration_required`로 멈춥니다(아래 재설치 절차). 호스트 고유 갱신은 [플랫폼 안내](docs/platforms.md)를 보십시오.
72
+
73
+ ### migration_required 뒤 재설치
74
+
75
+ 0.1.2는 평가 버전 0.2.0을 사용합니다(0.1.1은 0.1.0). 그래서 0.1.1로 만든 점수와 기준선은 0.1.2와 비교할 수 없고 `compare`는 `not_comparable`을 반환합니다. 기준선 감사는 0.1.2로 다시 실행하십시오. 같은 이유로 관리 중인 0.1.1 설치에서 `optbrew update`를 실행하면 `migration_required`로 멈추고 아무것도 바꾸지 않으며, 메시지에 경로와 명령이 나옵니다. `uninstall` 명령은 없습니다. 0.1.2 저장소 루트에서 아래 블록으로 교체합니다. 각 블록은 먼저 읽기 전용 `reinstall-plan`을 실행해 설치 기록을 검증하고(모든 대상이 정확히 해당 에이전트의 `skills/optbrew` 경로여야 합니다) 변조된 기록이면 아무것도 지우기 전에 거절합니다. 이후 셸은 그 명령이 출력한 경로만, 대상을 먼저 지우고 관리 루트를 마지막에 지우므로 실패한 뒤 같은 블록을 다시 실행할 수 있습니다. 이 명령은 `.optbrew/runs`(감사 증거)를 건드리지 않습니다. `.optbrew` 폴더 전체를 지우지 마십시오. 자세한 설명은 [플랫폼 안내](docs/platforms.md)를 보십시오.
76
+
77
+ 사용자 범위:
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
+ ```
95
+
96
+ ```bash user
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
+ ```
109
+
110
+ 프로젝트 범위(`./site`를 프로젝트 폴더로 바꾸십시오. 한 곳에만 나옵니다):
111
+
112
+ ```powershell project
113
+ $ErrorActionPreference = 'Stop'
114
+ [Console]::OutputEncoding = [Text.Encoding]::UTF8
115
+ $project = './site'
116
+ $plan = @(node bin/optbrew.mjs reinstall-plan --scope project --project $project)
117
+ if ($LASTEXITCODE) { exit $LASTEXITCODE }
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
+ ```
129
+
130
+ ```bash project
131
+ set -e
132
+ project='./site'
133
+ plan=$(node bin/optbrew.mjs reinstall-plan --scope project --project "$project")
134
+ while IFS=$'\t' read -r kind a b; do
135
+ case "$kind" in delete-link | delete-dir) rm -r -- "$a" ;; esac
136
+ done <<< "$plan"
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"
143
+ ```
144
+
145
+ ## 지원 범위와 라이선스
146
+
147
+ 관리 설치·검사·갱신·복원은 문서화된 기본 경로의 Codex, Claude Code, Cursor, OpenCode, Pi를 대상으로 합니다. 호스트의 사용자 지정 경로, 프로젝트 신뢰 설정, 세션 재시작 조건은 탐색 결과를 바꿀 수 있습니다. 일반 ChatGPT 채팅에서는 파일을 첨부해 안내형으로 사용합니다. 이는 Codex나 Work/desktop 플러그인 설치와 다릅니다. Claude 웹에서는 ZIP을 직접 올리고 갱신 때 다시 올립니다. 호스트 탐색과 실제 호출 성공은 따로 확인해야 합니다.
148
+
149
+ 네이버 묶음은 [Search Advisor 공식 안내](https://searchadvisor.naver.com/guide)의 색인을 포함합니다. 네이버 원문 55개는 제외했으므로 전문을 오프라인에서 읽을 수 없습니다. 온라인에서 공식 링크를 여십시오. 포함한 원본의 라이선스와 변경 내역은 [제삼자 고지](skills/optbrew/THIRD_PARTY_NOTICES.md)에 있습니다. optbrew 자체 코드는 [MIT 라이선스](LICENSE)입니다. 서비스 접근권과 API 자료 이용권은 코드 라이선스와 별개입니다. 묶음 생성·검증 절차는 [릴리스 안내](docs/release.md)에 있습니다.
package/README.md CHANGED
@@ -1,3 +1,149 @@
1
- # Temporary Holding Version
1
+ # optbrew
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [한국어](README.ko.md)
4
+
5
+ Optbrew is a local skill and CLI for checking a site's search readiness, making approved local changes, and comparing evidence before and after. It combines five pinned source bundles—mblode SEO, Naver Search Advisor, Firecrawl SEO Audit, Magnus SEO, and SE Ranking SEO—with seven selected marketing guides. One top-level `SKILL.md` routes to the included guides. The bundle works from its pinned files; it does not fetch a moving upstream revision during a run.
6
+
7
+ The CLI can calculate a score and write a report from stored JSON without an API account. A site audit needs a declared target and scope. Publication, search engine submission, remote site changes, and paid calls require separate authority. Read [platform support](docs/platforms.md) for the difference between installing a file and confirming that a host invoked it.
8
+
9
+ ## Install
10
+
11
+ Requires Node.js 22 or later. The internal Python audit utilities need Python 3.10 or later; missing Python leaves those utilities unrun. From this checkout, first inspect the targets in an isolated project directory named `site`:
12
+
13
+ Bash and PowerShell use the same commands:
14
+
15
+ ```text
16
+ node bin/optbrew.mjs install --agents codex,claude-code,cursor,opencode,pi --scope project --project ./site --strategy copy --dry-run --json
17
+ node bin/optbrew.mjs install --agents codex,claude-code,cursor,opencode,pi --scope project --project ./site --strategy copy --json
18
+ node bin/optbrew.mjs doctor --agents codex,claude-code,cursor,opencode,pi --scope project --project ./site --json
19
+ ```
20
+
21
+ Create `site` first and run these commands from the repository root. `--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: `codex`, `claude-code`, `cursor`, `opencode`, or `pi`. 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.
22
+
23
+ To get the checkout, clone `https://github.com/nowwcastle-sudo/optbrew` and run the commands above from its root. `npm install -g optbrew` installs the same CLI as an `optbrew` command; replace `node bin/optbrew.mjs` with `optbrew` in the commands above. Native host distribution and the ZIP path are described in [platform support](docs/platforms.md).
24
+
25
+ ## First use
26
+
27
+ Ask the host to use optbrew with the target URL, goal, site ownership or access, allowed local changes, and available evidence. For a local audit, declare the URL scope before collection. The default collection ceilings are 50 URLs, depth 3, and concurrency 2. A new fetch starts only while fewer requests than the limit have been made, and a redirect chain that has started is completed; a chain follows at most min(10, `max_urls`) redirects, so the requests beyond the limit are at most concurrency x min(10, `max_urls`), which is 20 with the defaults; private addresses need an explicit local target. The workflow records raw evidence, readiness observations, local changes, and follow-up checks. It does not infer a site's production result from a passing local test.
28
+
29
+ The examples below replay bundled synthetic fixtures. They make no provider call. Run them from the checkout root and choose fresh output paths:
30
+
31
+ Bash and PowerShell use the same commands:
32
+
33
+ ```text
34
+ node bin/optbrew.mjs score --input ./before.json --output ./score.json
35
+ node bin/optbrew.mjs compare --before ./before.json --after ./after.json --output ./comparison.json
36
+ node bin/optbrew.mjs report --input ./remote-only.json --output-dir ./report-output
37
+ ```
38
+
39
+ For those literal commands, copy `tests/fixtures/scoring/before.json` and `after.json` into the current directory, and copy `tests/fixtures/reports/remote-only.json` plus its sibling evidence files into the current directory. For real work, pass your own validated `ScoreInput` or `ReportPacket` paths. See [scoring](skills/optbrew/references/scoring.md), [measurement](skills/optbrew/references/measurement.md), and [report evidence](skills/optbrew/references/report.md) for the contracts.
40
+
41
+ ## Score and report
42
+
43
+ The five optbrew readiness profiles are SEO, NEO when Naver is a target, AEO, GEO, and LLMO. The 22 unique check families are counted once even when several guides find the same issue. An unknown applicable check remains in the denominator; an evidenced `not_applicable` check is excluded. The result includes score, measured coverage, missing-data bounds, blockers, and unresolved core checks. The 80% coverage threshold is an optbrew rule, not a search engine standard. A high readiness score does not prove indexing, traffic, citations, accuracy, conversions, or revenue.
44
+
45
+ What the audit script observes by itself, from the responses it collected: fetch status; indexing directives in meta tags and `X-Robots-Tag`, scoped to each target engine; missing or duplicated titles; robots.txt access per declared engine (Googlebot, Yeti and the AI search bots in [`ai-crawlers.md`](skills/optbrew/references/ai-crawlers.md); training bots are never scored); canonical target and redirect-chain length; discovery through links or a declared sitemap; JSON-LD syntax; Naver markup (Open Graph, description, canonical, viewport, title repetition, blocked CSS or JS); and cross-page consistency of name, address, phone and founding year. SEO and NEO therefore have scripted access, indexing and markup checks. AEO and GEO stay readiness audits: answer structure, claims, authorship and freshness still need the guides and agent judgment. LLMO gets a cross-page consistency check, which shows disagreement between pages but does not prove a fact is true. A seeded-defect test and its limits are in `docs/validation/detection-0.1.2.md` (repository only).
46
+
47
+ When measured coverage is below 80%, the report withholds the single headline number and shows the measured subset with its bounds. Each headline score is printed with its coverage.
48
+
49
+ The report keeps readiness, remedies, actual outcomes, and remaining work in separate tables. Actual outcomes need owner exports or a fixed AI question panel. A normal outcome comparison uses two complete, adjacent 28-day windows with matching definitions and filters. A local edit remains local until deployment and a production observation have their own evidence.
50
+
51
+ ## APIs and cost
52
+
53
+ API access is optional. A Claude or Claude Code subscription does not supply Anthropic API billing. To use a direct API key, follow the [official key guide](https://platform.claude.com/docs/en/get-api-key): Console → Settings → API keys. Put the key in the `ANTHROPIC_API_KEY` environment variable in your own shell or secret manager; never put a real value in a report. A key spanning multiple Anthropic workspaces may require an `anthropic-workspace-id` header. The direct adapter introduced in v0.1.0 still does not set that header, so use a compatible key or a separately approved host capability.
54
+
55
+ The direct adapter accepts only text `{model,max_tokens,messages}` requests for the exact model IDs `claude-fable-5-1`, `claude-opus-5-5`, `claude-sonnet-5-5`, and `claude-haiku-5-5`. `max_tokens` cannot exceed 128,000. Each attempt needs one token reservation of at least `1,000,000 + max_tokens`, a matching ledger budget, and an approval reference. This is a worst-case capacity bound, not a bill estimate. Record the current price source, estimated spend, and approved stop condition before the first paid call. Extra fields, tools, search, non-text input, unknown models, or currency-only bounds make zero direct calls. See [API boundaries](skills/optbrew/references/api.md).
56
+
57
+ SE Ranking has its own [API](https://seranking.com/api.html), [MCP instructions](https://seranking.com/api/integrations/mcp), account plan, and credits. Its [HTTP MCP endpoint](https://api.seranking.com/mcp) uses its documented OAuth or direct-token path, independently of `ANTHROPIC_API_KEY`. Available tools depend on the subscription. Neither connection is required for offline scoring. Use actual account prices and credits when deciding whether to run a paid capability; no price is built into this README.
58
+
59
+ ## Update and rollback
60
+
61
+ For a managed project installation, rebuild or obtain a verified newer optbrew bundle before updating. From the checkout root:
62
+
63
+ Bash and PowerShell use the same commands:
64
+
65
+ ```text
66
+ node bin/optbrew.mjs check-updates --json
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
69
+ ```
70
+
71
+ `check-updates --package optbrew` reads the latest version from the npm registry; without `--package` it reports `local_only`. `update` uses the current CLI bundle, verifies it, and updates all targets in that install record; it does not silently replace local edits. `rollback` needs that version in the record's retained prior releases. The shown rollback will therefore fail on a fresh 0.1.2 install and applies to a managed installation that retains local 0.1.0. `npm update -g optbrew` updates npm's package files after release; it does not rewrite a copy already placed in an agent skills directory. Run the managed `update` command again after updating the CLI. A managed 0.1.1 install cannot be updated to 0.1.2: `update` stops with `migration_required` (see the reinstall steps below). Native plugin and Pi package update paths are in [platform support](docs/platforms.md).
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
+ ```
95
+
96
+ ```bash user
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
+ ```
109
+
110
+ Project scope (replace `./site` with your project folder; it appears once):
111
+
112
+ ```powershell project
113
+ $ErrorActionPreference = 'Stop'
114
+ [Console]::OutputEncoding = [Text.Encoding]::UTF8
115
+ $project = './site'
116
+ $plan = @(node bin/optbrew.mjs reinstall-plan --scope project --project $project)
117
+ if ($LASTEXITCODE) { exit $LASTEXITCODE }
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
+ ```
129
+
130
+ ```bash project
131
+ set -e
132
+ project='./site'
133
+ plan=$(node bin/optbrew.mjs reinstall-plan --scope project --project "$project")
134
+ while IFS=$'\t' read -r kind a b; do
135
+ case "$kind" in delete-link | delete-dir) rm -r -- "$a" ;; esac
136
+ done <<< "$plan"
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"
143
+ ```
144
+
145
+ ## Support and license
146
+
147
+ Managed install, doctor, update, and rollback cover Codex, Claude Code, Cursor, OpenCode, and Pi at the documented default paths. Custom host directories, project trust, and session reload rules can change discovery. Ordinary ChatGPT chat uses attached files and instructions; it is not the same installation path as Codex or a Work/desktop plugin. Claude web requires manual ZIP upload and re-upload for updates. Host discovery and a successful real invocation require separate checks.
148
+
149
+ The Naver bundle retains an index of official [Search Advisor guides](https://searchadvisor.naver.com/guide). It excludes the 55 original Naver article bodies, so full offline article lookup is unavailable. Follow the official links while online. Included source licenses and changes are listed in [third-party notices](skills/optbrew/THIRD_PARTY_NOTICES.md); optbrew's own code is [MIT licensed](LICENSE). Service access and API data rights are separate from those code licenses. Release packaging and verification are in [release instructions](docs/release.md).
@@ -0,0 +1,10 @@
1
+ # Third-party notices
2
+
3
+ The files below retain their upstream copyright and permission notices. Service accounts, API data and Naver guide article bodies are outside these code licenses.
4
+
5
+ - **mblode-seo** — mblode/agent-skills at 872bc83bdb6dd54a9ff456fbf1181beea6db7875; MIT; Git license blob c5a1d56c6d623c72d077f8aab56b31d7dc371cbb; exact notice: [licenses/mblode-seo.txt](skills/optbrew/licenses/mblode-seo.txt). Exclusions: Unselected agent skills in the upstream repository.
6
+ - **naver-searchadvisor** — JaceProgramming/naver-searchadvisor-expert at cd95f6281090416b3dfbf15fb0f66f0ffa67a19c; MIT (limited scope); Git license blob 4434edf30edce0a41c07fbc776b0d5cebd044547; exact notice: [licenses/naver-searchadvisor.txt](skills/optbrew/licenses/naver-searchadvisor.txt). Exclusions: references/guide/*.md: 55 Naver copyrighted article bodies outside MIT scope; official URLs retained in INDEX; README.md: documents upstream offline corpus and is not a runtime guide; tools/fetch-guide.mjs: would retrieve excluded articles; tools/fix-index.mjs and tools/package.json: authoring tools, not runtime.
7
+ - **firecrawl-seo-audit** — firecrawl/firecrawl-workflows at 94cc91229d6cedc0613f140d3d013b150bc8e1b0; ISC; Git license blob ee221a2151d63ddc1db9857f9c5d346a3de9d816; exact notice: [licenses/firecrawl-seo-audit.txt](skills/optbrew/licenses/firecrawl-seo-audit.txt). Exclusions: Unselected Firecrawl workflows.
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
+ - **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
+ - **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.
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { main } from '../lib/cli.mjs';
3
+
4
+ process.exitCode = await main(process.argv.slice(2));
@@ -0,0 +1,107 @@
1
+ # Platform installation and update paths
2
+
3
+ Optbrew v0.1.2 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
+
5
+ | Host | Managed project target | Managed user target | Discovery and invocation boundary |
6
+ |---|---|---|---|
7
+ | Codex | `.agents/skills/optbrew` | `~/.agents/skills/optbrew` | [Codex skills](https://learn.chatgpt.com/docs/build-skills) scans repository and user skills and follows links. Test invocation in a fresh task. |
8
+ | Claude Code | `.claude/skills/optbrew` | `~/.claude/skills/optbrew` | [Claude Code skills](https://code.claude.com/docs/en/skills) scans those roots. This is separate from the Claude web upload. |
9
+ | Cursor | `.cursor/skills/optbrew` | `~/.cursor/skills/optbrew` | [Cursor skills](https://cursor.com/docs/skills) also accepts `.agents/skills`; local user skills are not automatically copied to cloud agents. |
10
+ | OpenCode | `.opencode/skills/optbrew` | `~/.config/opencode/skills/optbrew` | [OpenCode skills](https://opencode.ai/docs/skills/) also discovers compatible `.agents` and `.claude` roots. |
11
+ | Pi | `.pi/skills/optbrew` | `<agent-dir>/skills/optbrew`, normally `~/.pi/agent/skills/optbrew` | [Pi configuration](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/configuration.md) permits `PI_CODING_AGENT_DIR` overrides and requires project trust for project configuration. |
12
+
13
+ The CLI maps only these default targets. Custom roots, host policies, remote agents, and session reload behavior need host-specific checks. `--scope project --project ./site` keeps a managed installation inside an isolated project. `--scope user` addresses the user's default host paths and should be chosen deliberately.
14
+
15
+ ## Managed checkout and npm paths
16
+
17
+ The [README](../README.md) shows parser-checked checkout commands for install, doctor, update, and rollback. 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
+
19
+ 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
+
21
+ ## Reinstall after a migration_required update
22
+
23
+ Release 0.1.2 uses evaluation version 0.2.0; 0.1.1 used 0.1.0. The managed updater refuses a change of evaluation version, so `optbrew update` on a managed 0.1.1 install stops with `migration_required` and changes nothing. 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.1.2 checkout. Scores and baselines made with 0.1.1 are not comparable with 0.1.2; `compare` returns `not_comparable` (`evaluation_version_changed`). Run the baseline audit again with 0.1.2.
24
+
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 your audit evidence lives; do not delete the whole `.optbrew` folder. Each agent is installed again with the strategy (`link` or `copy`) the record had, then `doctor` runs. Run the blocks from the 0.1.2 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
+
27
+ User scope:
28
+
29
+ ```powershell user
30
+ $ErrorActionPreference = 'Stop'
31
+ [Console]::OutputEncoding = [Text.Encoding]::UTF8
32
+ $plan = @(node bin/optbrew.mjs reinstall-plan --scope user)
33
+ if ($LASTEXITCODE) { exit $LASTEXITCODE }
34
+ foreach ($line in $plan) {
35
+ $f = $line -split "`t"
36
+ if ($f[0] -eq 'delete-link') { [IO.Directory]::Delete($f[1]) }
37
+ elseif ($f[0] -eq 'delete-dir') { Remove-Item -Recurse -Force -LiteralPath $f[1] }
38
+ }
39
+ foreach ($line in $plan) {
40
+ $f = $line -split "`t"
41
+ if ($f[0] -eq 'install') { node bin/optbrew.mjs install --agents $f[1] --scope user --strategy $f[2]; if ($LASTEXITCODE) { exit $LASTEXITCODE } }
42
+ elseif ($f[0] -eq 'agents') { node bin/optbrew.mjs doctor --agents $f[1] --scope user; exit $LASTEXITCODE }
43
+ }
44
+ ```
45
+
46
+ ```bash user
47
+ set -e
48
+ plan=$(node bin/optbrew.mjs reinstall-plan --scope user)
49
+ while IFS=$'\t' read -r kind a b; do
50
+ case "$kind" in delete-link | delete-dir) rm -r -- "$a" ;; esac
51
+ done <<< "$plan"
52
+ while IFS=$'\t' read -r kind a b; do
53
+ case "$kind" in
54
+ install) node bin/optbrew.mjs install --agents "$a" --scope user --strategy "$b" ;;
55
+ agents) node bin/optbrew.mjs doctor --agents "$a" --scope user ;;
56
+ esac
57
+ done <<< "$plan"
58
+ ```
59
+
60
+ Project scope (replace `./site` with your project folder; it appears once):
61
+
62
+ ```powershell project
63
+ $ErrorActionPreference = 'Stop'
64
+ [Console]::OutputEncoding = [Text.Encoding]::UTF8
65
+ $project = './site'
66
+ $plan = @(node bin/optbrew.mjs reinstall-plan --scope project --project $project)
67
+ if ($LASTEXITCODE) { exit $LASTEXITCODE }
68
+ foreach ($line in $plan) {
69
+ $f = $line -split "`t"
70
+ if ($f[0] -eq 'delete-link') { [IO.Directory]::Delete($f[1]) }
71
+ elseif ($f[0] -eq 'delete-dir') { Remove-Item -Recurse -Force -LiteralPath $f[1] }
72
+ }
73
+ foreach ($line in $plan) {
74
+ $f = $line -split "`t"
75
+ if ($f[0] -eq 'install') { node bin/optbrew.mjs install --agents $f[1] --scope project --project $project --strategy $f[2]; if ($LASTEXITCODE) { exit $LASTEXITCODE } }
76
+ elseif ($f[0] -eq 'agents') { node bin/optbrew.mjs doctor --agents $f[1] --scope project --project $project; exit $LASTEXITCODE }
77
+ }
78
+ ```
79
+
80
+ ```bash project
81
+ set -e
82
+ project='./site'
83
+ plan=$(node bin/optbrew.mjs reinstall-plan --scope project --project "$project")
84
+ while IFS=$'\t' read -r kind a b; do
85
+ case "$kind" in delete-link | delete-dir) rm -r -- "$a" ;; esac
86
+ done <<< "$plan"
87
+ while IFS=$'\t' read -r kind a b; do
88
+ case "$kind" in
89
+ install) node bin/optbrew.mjs install --agents "$a" --scope project --project "$project" --strategy "$b" ;;
90
+ agents) node bin/optbrew.mjs doctor --agents "$a" --scope project --project "$project" ;;
91
+ esac
92
+ done <<< "$plan"
93
+ ```
94
+
95
+ Inside 0.1.2 and later releases that keep evaluation version 0.2.0, `update` and `rollback` work as before. The same refusal and steps apply to any future release that changes the evaluation version.
96
+
97
+ ## Native host routes
98
+
99
+ These are alternatives to the managed CLI. Do not mix their ownership records for the same target path.
100
+
101
+ - **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:** The local `.claude-plugin/marketplace.json` and `plugin.json` name `optbrew@optbrew-local` at version 0.1.2. The installed Claude CLI help accepts `claude plugin marketplace add --scope project .`, then `claude plugin install --scope project optbrew@optbrew-local` from this checkout. Later, `claude plugin update --scope project optbrew@optbrew-local` applies the marketplace's newer version and requires a restart. These commands change Claude settings, so documentation checks inspect `--help` without registering a marketplace. [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 the selected release version and a fresh-session invocation after a native update.
103
+ - **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.1.2` 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.
104
+ - **Claude web:** Upload the built skill ZIP manually in the supported web interface. Upload a new ZIP again for each update. There is no verified automatic update of that upload.
105
+ - **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
+
107
+ 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.
@@ -0,0 +1,14 @@
1
+ # Release procedure
2
+
3
+ This checkout is version 0.1.2. 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
+
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
+ 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.1.2 --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
+ 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
+ 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. Only after a reviewed release decision, publish or upload the approved artifacts and verify the public npm and repository readback. Do not infer publication from successful local builds.
11
+
12
+ 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
+
14
+ The direct Anthropic adapter retains its v0.1.0 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.