# rsw Build & Completion Notes ## What's done All Go source files are written and structurally complete: ``` scripts/rsw/ ├── main.go # Entry point ├── go.mod # Module definition (needs go mod tidy) └── internal/ ├── cmd/ │ ├── root.go # Root command, global flags, URL helpers │ ├── game.go # osrs/rs3 parent commands + factory registration │ ├── search.go # rsw search │ ├── page.go # rsw page [--section] │ ├── item.go # rsw <game> item <name> [--ironman] │ ├── quest.go # rsw <game> quest <name> [--ironman] │ ├── skill.go # rsw <game> skill <name> [--level] [--ironman] │ └── price.go # rsw <game> price <name> [--ironman] ├── wiki/ │ ├── client.go # HTTP client for MediaWiki API │ ├── search.go # action=query&list=search wrapper │ └── parse.go # action=parse wrapper (wikitext, sections, HTML) ├── prices/ │ ├── client.go # HTTP client for prices.runescape.wiki API │ └── mapping.go # Item ID↔name cache with disk persistence ├── render/ │ └── markdown.go # Markdown output builder (headings, tables, KV, GP formatting) └── extract/ └── infobox.go # Wikitext template parser (handles nesting, wiki links, refs) ``` ## What needs to happen next ### 1. `go mod tidy` + `go mod download` The go.mod declares the cobra dependency but doesn't have a go.sum yet. Run: ```bash cd scripts/rsw go mod tidy ``` This will resolve the full dependency tree and create go.sum. ### 2. Compile & smoke test ```bash go build -o rsw . ./rsw osrs search "dragon scimitar" ./rsw osrs item "abyssal whip" ./rsw osrs quest "Monkey Madness I" ./rsw osrs price "dragon bones" ./rsw rs3 quest "Plague's End" ``` ### 3. Known issues to fix during testing **`strings.Title` is deprecated** — Used in skill.go. Replace with: ```go import "golang.org/x/text/cases" import "golang.org/x/text/language" caser := cases.Title(language.English) trainingTitle := caser.String(strings.ToLower(skillName)) + " training" ``` Or just capitalize the first letter manually since we're dealing with single words. **Template name variations** — The RS wiki uses inconsistent casing for templates (e.g., `Infobox Item` vs `Infobox item`). The extract package does case-insensitive matching, but you may discover new template names while testing (e.g., RS3 might use `Infobox object` for some items). Easy to add — just extend the name list in `findItemInfobox()`. **Drop table templates** — OSRS uses `DropsLine`, RS3 may use different names. Test with both games and add any missing template names to `renderDropSources()`. **Price API for RS3** — The prices.runescape.wiki endpoint for RS3 (`/api/v1/rs/`) may have different availability than OSRS. The mapping endpoint should work but test it. RS3 also has the official Jagex GE API as a fallback if needed: `https://secure.runescape.com/m=itemdb_rs/api/catalogue/detail.json?item=<id>` ### 4. Potential improvements - **Fuzzy search for item command**: Right now `item` uses wiki search which is good but could also cross-reference the price mapping cache for exact matches. - **Structured drop table parsing**: The wikitext drop tables are complex (conditional drops, noted items, etc.). Current parser handles the basics. - **Monster lookup command**: `rsw <game> monster <name>` for combat stats, weaknesses, drop tables. Same pattern as item/quest. - **Category browsing**: MediaWiki has `action=query&list=categorymembers` — could support `rsw <game> list quests` or `rsw <game> list items --category "Melee weapons"`. - **Timeseries charting**: The 5m/1h price data could generate ASCII sparklines for price trends in the terminal. ## Architecture notes **Factory pattern for cobra commands**: Each subcommand uses a `newXxxCmd()` factory function registered via `RegisterCommand()`. This is because cobra doesn't support a command having two parents — we need independent instances for osrs and rs3. `wireCommands()` is called once at `Execute()` time to create and attach all command instances. **Wikitext parser**: The `extract` package implements a lightweight template parser that handles `{{Template|key=value|...}}` with nesting, wiki links `[[Target|Display]]`, and common markup stripping. It doesn't handle parser functions (`#if`, `#switch`) — those are stripped as regular templates. This covers ~80% of useful data extraction from infoboxes and drop tables. **Price mapping cache**: Stored at `~/.rsw/cache/mapping.json` with a 24h TTL. The mapping API returns all items (~4000 for OSRS, ~40000 for RS3) in a single call. Caching avoids hitting this on every price lookup.