app
Chip Fetcher (cf)
Public Made by Adomby adom
Crawls the web on your behalf to gather everything about the chips you care about: datasheets, symbols, footprints, 3D models, stock and pricing, straight from the manufacturer first, into your EDA tool. Say "cf" to your AI.
master
John Lauer
1.3.0: Dock Bar contract (serve --print-url, /api/status LEDs, CORS, say strip), settings modal, taskbar progress, pup vault for logins, adom-bridge + pup_* transport, dashboard overhaul per adom-ui-design, doctor for first run
83b2ae8
1mo ago
Dashboard API contract (server side, implemented in src/serve.rs + src/dock.rs)
Every /api/*, /ui/*, /state, /console, /health response carries
Access-Control-Allow-Origin: *; OPTIONS on any path answers 204. All paths
are relative to the app root; inside a webview the page MUST use relative URLs
(API_BASE + '/api/...', where API_BASE is derived from location.pathname
as today).
Existing (unchanged)
GET /api/library,GET /api/sources,GET /api/validate,GET /api/projectsGET /api/chip/<MPN>,POST /api/reveal,POST /api/open,POST /api/orientation,POST /api/deliver,POST /api/validate/<MPN>,POST /api/thumbnails/<MPN>,POST /api/refetch/<MPN>?format=&source=GET /asset/*,GET /thumb/*,GET /svg/*
Live channel (poll based; 1 s)
GET /api/activity-> the heartbeat payload as today PLUS:_toasts: [{t, message, kind}](kind:ok|err|info), drained on read. The page renders each one as a toast._ui: [{cmd, ...}]drained on read. Commands the page MUST handle:{cmd:"toast", message, kind}(same as above, alternative path){cmd:"click", id}->document.getElementById(id).click(){cmd:"select", mpn}-> select that card (open detail){cmd:"view", view}->grid|validation|sources{cmd:"open_settings"}/{cmd:"close_settings"}{cmd:"zoom", mpn}/{cmd:"unzoom"}{cmd:"reload"}->location.reload()
_state_version: <u64>bumps whenever the library changed on disk (use it to refresh the grid instead of refetching /api/library every 4 s).
Observability
GET /state->{ok, app, version, activity, library_count, complete_count, active_project, selected_mpn, view, settings_open, ui_reported_at}. The page reports its client state withPOST /state/ui {selected_mpn, view, settings_open, zoom_mpn}whenever it changes (cheap; fire and forget) so the server copy is truth for the AI.GET /console?limit=200->{ok, count, items:[{t, level, msg, source}]}.POST /console {level, msg}-> the page overridesconsole.log/warn/error,window.onerror,unhandledrejectionand posts each line here (source = "ui").
Dock contract
GET /health->{ok:true, app:"adom-chip-fetcher", version}.GET /api/status->{ok, app, version, state: ok|warn|fail, leds:{<key>:{label, state, detail, _hint}}, say:[...], missing_tools:[...]}. Facet keys:dashboard,skill,tools,bridge,library. Cached 10 s;?force=1recomputes.GET /api/say->{ok, phrases:[...]}(from dockbar.json).POST /api/say/try {phrase}->{staged: bool, where?, reason?}.
Settings (settings-layout skill)
GET /api/settings->{ok, settings:{...}, defaults:{...}}.POST /api/settings {<key>: <value>, ...}-> merge + persist, returns the fullsettings. Typed by the default's type; enum values validated.POST /api/settings/reset-> restore defaults.
Keys (with defaults and the label the UI shows):
| key | default | label | type |
|---|---|---|---|
taskbar_progress |
"indeterminate" |
Taskbar progress during a lookup | enum indeterminate / off |
auto_zoom |
false |
Auto-zoom the active card | bool |
auto_select_active |
true |
Follow the active lookup | bool |
show_stock_badges |
true |
Stock and lifecycle badges on cards | bool |
activity_stale_seconds |
90 |
Heartbeat considered stale after | int |
Credentials (pup's vault is the store; chip-fetcher keeps none)
GET /api/credentials->{ok, source:"pup", credentials:[{host, username}], _hint}(passwords never returned). When the desktop is not connected:{ok:false, error, _hint}.POST /api/credentials/import {hostFilter:[...]}-> starts a job (below) running pup's browser-login import (one consent dialog + one UAC prompt on the desktop).POST /api/login {source}-> opens that vendor's sign-in page in the chip-fetcher pup profile and asks pup to autofill from its vault; returns{ok, url, job?}.DELETE /api/credentials/<host>-> removes from pup's vault.
Jobs (for Install / Update rows with live consoles)
POST /api/jobs {action}where action is one ofinstall_tools(adom-wiki pkg install adom/adom-chip-fetcher),install_skill(adom-chip-fetcher install),import_logins(pup import, optionalhostFilter),refresh_status. Returns{ok, id}.GET /api/jobs/<id>->{ok, id, action, state: running|done|failed, exit_code, lines:[...], started, ended}; poll every 700 ms and streamlinesinto the row's console box.
UI driving (the CLI calls these; the page only consumes _ui)
POST /ui/toast {message, kind}POST /ui/command {cmd, ...}
CLI verbs that map to the above
adom-chip-fetcher serve [--port 8786] [--print-url]
adom-chip-fetcher health | status | doctor [--fix] | say | try "<phrase>"
adom-chip-fetcher ui toast "<msg>" [--kind ok|err|info]
adom-chip-fetcher ui click <id> | select <MPN> | view <grid|validation|sources>
adom-chip-fetcher ui settings open|close | zoom <MPN> | reload
adom-chip-fetcher settings get | set <key> <value> | reset
adom-chip-fetcher login <source|list|all|import>
# Dashboard API contract (server side, implemented in src/serve.rs + src/dock.rs)
Every `/api/*`, `/ui/*`, `/state`, `/console`, `/health` response carries
`Access-Control-Allow-Origin: *`; `OPTIONS` on any path answers 204. All paths
are relative to the app root; inside a webview the page MUST use relative URLs
(`API_BASE + '/api/...'`, where `API_BASE` is derived from `location.pathname`
as today).
## Existing (unchanged)
- `GET /api/library`, `GET /api/sources`, `GET /api/validate`, `GET /api/projects`
- `GET /api/chip/<MPN>`, `POST /api/reveal`, `POST /api/open`, `POST /api/orientation`,
`POST /api/deliver`, `POST /api/validate/<MPN>`, `POST /api/thumbnails/<MPN>`,
`POST /api/refetch/<MPN>?format=&source=`
- `GET /asset/*`, `GET /thumb/*`, `GET /svg/*`
## Live channel (poll based; 1 s)
- `GET /api/activity` -> the heartbeat payload as today PLUS:
- `_toasts: [{t, message, kind}]` (kind: `ok` | `err` | `info`), drained on read.
The page renders each one as a toast.
- `_ui: [{cmd, ...}]` drained on read. Commands the page MUST handle:
- `{cmd:"toast", message, kind}` (same as above, alternative path)
- `{cmd:"click", id}` -> `document.getElementById(id).click()`
- `{cmd:"select", mpn}` -> select that card (open detail)
- `{cmd:"view", view}` -> `grid` | `validation` | `sources`
- `{cmd:"open_settings"}` / `{cmd:"close_settings"}`
- `{cmd:"zoom", mpn}` / `{cmd:"unzoom"}`
- `{cmd:"reload"}` -> `location.reload()`
- `_state_version: <u64>` bumps whenever the library changed on disk (use it to
refresh the grid instead of refetching /api/library every 4 s).
## Observability
- `GET /state` -> `{ok, app, version, activity, library_count, complete_count,
active_project, selected_mpn, view, settings_open, ui_reported_at}`. The page
reports its client state with `POST /state/ui {selected_mpn, view, settings_open,
zoom_mpn}` whenever it changes (cheap; fire and forget) so the server copy is truth
for the AI.
- `GET /console?limit=200` -> `{ok, count, items:[{t, level, msg, source}]}`.
- `POST /console {level, msg}` -> the page overrides `console.log/warn/error`,
`window.onerror`, `unhandledrejection` and posts each line here (source = "ui").
## Dock contract
- `GET /health` -> `{ok:true, app:"adom-chip-fetcher", version}`.
- `GET /api/status` -> `{ok, app, version, state: ok|warn|fail, leds:{<key>:{label,
state, detail, _hint}}, say:[...], missing_tools:[...]}`. Facet keys: `dashboard`,
`skill`, `tools`, `bridge`, `library`. Cached 10 s; `?force=1` recomputes.
- `GET /api/say` -> `{ok, phrases:[...]}` (from dockbar.json).
- `POST /api/say/try {phrase}` -> `{staged: bool, where?, reason?}`.
## Settings (settings-layout skill)
- `GET /api/settings` -> `{ok, settings:{...}, defaults:{...}}`.
- `POST /api/settings {<key>: <value>, ...}` -> merge + persist, returns the full
`settings`. Typed by the default's type; enum values validated.
- `POST /api/settings/reset` -> restore defaults.
Keys (with defaults and the label the UI shows):
| key | default | label | type |
|---|---|---|---|
| `taskbar_progress` | `"indeterminate"` | Taskbar progress during a lookup | enum `indeterminate` / `off` |
| `auto_zoom` | `false` | Auto-zoom the active card | bool |
| `auto_select_active` | `true` | Follow the active lookup | bool |
| `show_stock_badges` | `true` | Stock and lifecycle badges on cards | bool |
| `activity_stale_seconds` | `90` | Heartbeat considered stale after | int |
## Credentials (pup's vault is the store; chip-fetcher keeps none)
- `GET /api/credentials` -> `{ok, source:"pup", credentials:[{host, username}],
_hint}` (passwords never returned). When the desktop is not connected:
`{ok:false, error, _hint}`.
- `POST /api/credentials/import {hostFilter:[...]}` -> starts a job (below) running
pup's browser-login import (one consent dialog + one UAC prompt on the desktop).
- `POST /api/login {source}` -> opens that vendor's sign-in page in the
chip-fetcher pup profile and asks pup to autofill from its vault; returns
`{ok, url, job?}`.
- `DELETE /api/credentials/<host>` -> removes from pup's vault.
## Jobs (for Install / Update rows with live consoles)
- `POST /api/jobs {action}` where action is one of `install_tools`
(`adom-wiki pkg install adom/adom-chip-fetcher`), `install_skill`
(`adom-chip-fetcher install`), `import_logins` (pup import, optional
`hostFilter`), `refresh_status`. Returns `{ok, id}`.
- `GET /api/jobs/<id>` -> `{ok, id, action, state: running|done|failed, exit_code,
lines:[...], started, ended}`; poll every 700 ms and stream `lines` into the
row's console box.
## UI driving (the CLI calls these; the page only consumes `_ui`)
- `POST /ui/toast {message, kind}`
- `POST /ui/command {cmd, ...}`
## CLI verbs that map to the above
```
adom-chip-fetcher serve [--port 8786] [--print-url]
adom-chip-fetcher health | status | doctor [--fix] | say | try "<phrase>"
adom-chip-fetcher ui toast "<msg>" [--kind ok|err|info]
adom-chip-fetcher ui click <id> | select <MPN> | view <grid|validation|sources>
adom-chip-fetcher ui settings open|close | zoom <MPN> | reload
adom-chip-fetcher settings get | set <key> <value> | reset
adom-chip-fetcher login <source|list|all|import>
```