# prts-terrarchive (English)

The optional **Rhine Lab Archive** skin combines a continuous 3D retrieval array,
persistent investigation boards, a per-board evidence inbox, and a two-level archive rack
with 24 sources per page. The Agent adds clues and relationships and publishes versioned
reports; it decides whether a follow-up continues an investigation or starts a new one.
Browsing candidates stay in the array. Sources delivered to the Agent and manual bookmarks enter the rack; original-reading and citation states remain separate.
Users can stage important material in a chosen board's inbox, edit matching paper cards,
and connect clues with red strings.

`investigation_get` recalls clue text, versioned reports, the archive rack, evidence inboxes,
and saved source bodies. Manual bookmarks now persist in session storage; existing browser
bookmarks are imported automatically. User additions and edits appear in the Agent's next
model context, or its next conversation when idle, without starting a new turn. Reminders
remain pending until the corresponding content is successfully returned to the Agent;
browser reads and unrelated pages do not acknowledge them.

Enable it in Settings → Plugins → PRTS Corpus → Skin, then open the archive from
a session header. Local and cloud search, Markdown reading, excerpts and tool activity
share the workspace. Returning from a source restores the previous view and position.
Investigation tools and their skill are enabled only with the Rhine Lab skin. Other skins
use ordinary retrieval and reply directly in the conversation. Switching skins updates the
tools in the same PRTS session; no new session is required. Saved clues, reports and archives
remain available when you return to Rhine Lab.
Manual browsing holds the current source until the next Agent read. Explicitly pausing
following keeps it paused until resumed. Visible room models also navigate between stations. A text reader remains available without WebGL.

For local development, use Node.js 22.19 or newer, then run `npm ci`,
`npm run build:rhine`, and `npm run preview:rhine`. See the
[workspace guide](docs/rhine-lab.md) and [interaction rules](docs/rhine-interaction-flow.md).

PRTS.chat corpus plugin for DeepSeek Harness (DSH). Provides local corpus
search, source reading and an activity-timeline tool, plus optional
PRTS.cloud hybrid retrieval. The plugin first obtains the approved current
release and per-file digests from the fixed `https://prts.chat` trust origin,
then downloads the local corpus from ModelScope or a configurable byte-only fallback;
the optional cloud service discovers candidates that can be mapped back to
local source text for verification. Anonymous cloud retrieval currently has an
allowance of 1,000 calls per user per day for DSH clients; this policy may
change as service capacity evolves.

- Registers DSH `ToolDefinition`s through the host plugin interface.
- Host-resident settings UI and data manager, with Agent tools composed into
  PRTS mode or user-defined presets. PRTS mode inherits the full standard toolset.
- The fixed `https://prts.chat` origin is the trust source for latest-release
  resolution and manifests; ModelScope and the configurable fallback only serve
  bytes for that fixed release and cannot select or attest a version.
- Three optional skins (PRTS Agent, Endfield AIC terminal, Rhine Lab Archive) on top of the
  native Harness UI.

## Data sources

- **Self-built Wiki data**: sourced from [littlepangding/arknights_lore_wiki](https://github.com/littlepangding/arknights_lore_wiki).
- **Terra timeline data**: sourced from [PRTS Wiki's Terra timeline (泰拉年表)](https://prts.wiki/w/%E6%B3%B0%E6%8B%89%E5%B9%B4%E8%A1%A8) for the plugin's timeline search.

## Install

Web requires Node.js >= 22.19 and DSH >= 0.2.0-rc.1 (declared as `engines.dsh`).
The package has been audited point by point against the DSH 0.2.1-rc.2 source.
An official Electron Desktop installation supplies
its own runtime. Corpus disk usage is shown in Settings before download.

### Official Electron Desktop (recommended)

Recent DSH Desktop builds let you install from the UI without a terminal:

1. Open **Plugins** in the sidebar, then click **+ Add plugin**.
2. Paste the versioned npm package name into **Package name or address**. Enter only the name, **not an `npm install` or `dsh plugin add` command**:

   ```text
   prts-terrarchive@0.2.3
   ```

   Specify a version. With only `prts-terrarchive`, the preview may show npm's `latest` while the installer selects an older version; see the explanation below.
3. Choose the official npm registry or the mainland China mirror under **Registry**, then click **Install**.
4. Click **Enable now** after installation. If you close the dialog instead, turn on the plugin in the installed list.
5. Open **Settings → Plugins → PRTS Corpus** to download the corpus and choose a skin, then start a new session in **PRTS mode**.

The same dialog accepts these alternatives. Choose one; you do not need to install each source:

| Source | Text to enter | Use |
| --- | --- | --- |
| npm (recommended) | `prts-terrarchive@0.2.3` | Install the specified release |
| GitHub | `https://github.com/HTian-qwq/prts-terrarchive.git` | Install repository source; requires access to GitHub |
| Local directory | `D:\ds\prts-terrarchive` | Install a complete downloaded checkout; replace this with its actual absolute path |

An absolute path to a local `.tgz` package is also supported. The checkout and npm package
include the built UI and JavaScript runtime dependencies. Installing or updating the plugin
does not require a separate `js-yaml` / `zod` installation or `npm ci`.

**Registry selection affects npm packages and dependencies, not GitHub downloads or direct tarball URLs.**
If GitHub is unreachable, enter the npm package name and choose a mirror instead. If a mirror
does not yet have a newly published version, try the official npm registry.

**Installation preview and installed version differ:** DSH builds using pnpm 11 default to
preferring versions published at least 24 hours ago, while the preview reads registry metadata.
For example, shortly after 0.2.3 is published, entering only the package name can preview 0.2.3
but install 0.2.1. This difference comes from the installer's version selection; see the
[pnpm release notes](https://pnpm.io/blog/releases/11.0). Follow the upgrade steps below to
uninstall the old version, install `prts-terrarchive@0.2.3`, then check the version in plugin
details. You do not need to clear corpus or session data.

**Upgrades:** the current Desktop installation UI does not provide automatic updates.
For npm or GitHub installs, uninstall from the plugin details, then add and enable the plugin
again; change any pinned version to your target release. For a local checkout, run `git pull`
in the original directory, then fully quit and restart Desktop. Plugin and corpus updates
are separate; manage corpus versions in **PRTS Corpus**.

Older Desktop releases may accept only npm package names; use `prts-terrarchive` and follow
their activation prompts. Electron manages the `desktop` profile: do not run
`node bin/install.js desktop` or `dsh plugin --profile desktop`.

### Local Web installation

Install from a local checkout, or use PRTS Portable with the plugin already included:

```bash
npm install --global @deepseek-ai/dsh@0.2.0-rc.1
git clone https://github.com/HTian-qwq/prts-terrarchive.git
cd prts-terrarchive
node bin/install.js web
```

The checkout and npm package include their built JavaScript runtime dependencies. Installing
the plugin or updating with `git pull` requires no separate `js-yaml` or `zod` installation.
Run `npm ci` when developing and rebuilding, and `npm run build:runtime` when updating these dependencies.
`npm pack` and `npm publish` verify bundled versions and load every Host entry in an isolated
directory without `node_modules` before allowing the package to be created.

The local installer adds the package to the selected profile. DSH 0.1.7 and
later register PRTS mode directly; older DSH versions still create or migrate
the compatibility preset in `$DSH_HOME/.agent-presets/prts`. With no
second argument it uses its own checkout. Another local directory or archive
can be supplied explicitly:

```bash
node bin/install.js web /path/to/prts-terrarchive
```

### Web: install from npm

Install the bundle directly from npm; no additional installer command
or npm lifecycle hook is needed:

```bash
dsh plugin --profile web add prts-terrarchive@0.2.3
```

Restart `dsh web`. On DSH 0.1.7 and later the plugin registers PRTS mode
directly and removes it when disabled or uninstalled. The default mode and
ordinary running sessions stay intact. The new registry does not read old
`$DSH_HOME/.agent-presets/prts` files. Migrate any customized old preset
through the new mode configuration; the old files remain untouched. Older DSH
releases continue using the file template, preserving user edits. npm does not
run `postinstall`.

```bash
dsh plugin --profile web remove prts-terrarchive
```

### Tools and custom modes

PRTS mode inherits the current host's complete standard composition when the plugin activates, including shell, file operations, background jobs, skills, goals, planning, delegation and workflows, then adds PRTS retrieval and investigation tools. Platform conditions, service isolation, disabled optional tools and host permissions are preserved. Restart after changing standard mode and verify in a new session.

In Creative mode, ask the Agent to keep standard capabilities and add PRTS tools to a custom research mode. The globally discoverable `prts-composition` skill explains how to compose `prts-terrarchive/tools` (Agent tools only) and `prts-terrarchive/skill` (retrieval and investigation guidance), or replace PRTS mode's complete tool list. See the [composition guide](skills/prts-composition/SKILL.md).

Legacy hosts seed their own standard composition into unchanged generated presets at startup. Edited or unmarked existing presets remain user-owned and require manual composition. Ordinary standard mode receives no PRTS tools automatically.

### Corpus downloads and Portable

Web and official Desktop share the default `$DSH_HOME` product data while
installing their plugins separately. The plugin package includes its UI,
map models, textures, skills, and presets. It does **not** bundle corpus data,
Node/DSH runtimes, or user data. Open Settings → Plugins → PRTS 语料 and download
the corpus explicitly before using local retrieval. Downloads follow `enabledGames`:
Endfield needs its two packs; Arknights needs its five packs. Enabling another game
and downloading again adds the missing packs and reuses verified files. Disabling
a game does not delete its installed data. Switching skins does not start a
separate model or texture download.

PRTS Portable distributions include the plugin, presets, and the complete corpus,
so no separate corpus download is needed after extraction. Build the official
Electron portable target with `build-electron.ps1`; the original WebView2 build
entry remains available. See the [Portable repository](https://github.com/HTian-qwq/prts-terrarchive-portable).

Portable builders that already placed the plugin can continue running
`node bin/install.js web --preset-only` to create or migrate the compatibility
preset without invoking the DSH CLI.

### Windows

Local Web installation requires `dsh.cmd`. The installer invokes it through
cmd.exe, so plugin paths containing a line break or `%` `!` `&` `|` `<` `>` `^`
`"` are rejected. Use a directory without these characters. The `DSH`
environment variable can locate an absolute `dsh.cmd` path. Official DSH stores
the corpus under `%USERPROFILE%\.dsh\prts-corpus\releases` by default;
Portable stores sessions and settings in its own `userdata` directory, and the
bundled corpus and subsequent corpus updates in `corpus/releases`.

### Retrieval settings

Select PRTS mode in new sessions to load the corpus tools, DSH's native
`web_search` and `web_fetch`, and the retrieval Skill. The preset enables both
`arknights` and `endfield`; Settings stores the effective modules as
`enabledGames` in `$DSH_HOME/prts-corpus.json`. Start a new session after changing
them. The preset enables anonymous cloud retrieval by default. A raw plugin
instance without the cloud configuration keeps it disabled.

Static tokens are bound to the saved service origin. Changing the URL cannot
forward a token to another origin. Re-enter legacy tokens that lack an origin
binding in Settings; they remain unsent until saved again.

After the retrieval Skill loads, matched entities and relationships enter DSH's
dynamic context for the current question. Each new snapshot supersedes the
previous one. Tool titles identify local/cloud retrieval and the game scope.

The retrieval Skill loads its core strategy and enabled game modules. Detailed tool guidance,
procedures, recipes and diagnostics are linked for reading as needed. The investigation Skill
loads its core workflow; recall, collaboration, quotation validation and recovery examples are
in the [board guide](skills/prts-investigation/references/board-guide.md).

## Skins and assets

- **Harness default** keeps the native DSH interface.
- **PRTS Agent** provides the PRTS.chat terminal-style interface.
- **Endfield AIC** provides an optional Arknights: Endfield-inspired terminal
  and 3D map. Its runtime code, models, and textures are pre-compressed and
  installed with the plugin; switching skins does not start another download.

The two optional skins have separate stylesheets. The client keeps only the
active skin stylesheet mounted, plus a small shared stylesheet for plugin
controls, so neither optional skin depends on the other's CSS.

The Endfield AIC plugin code, UI integration, and map-rendering implementation
are licensed under the MIT License. Game-derived models and textures used by
that skin are not covered by the MIT License and are packaged only as parts of
the optional skin. See [GAME_ASSETS.md](GAME_ASSETS.md) for the exact paths.
These assets are independent of corpus version management: corpus datasets are
downloaded from a verified ModelScope mirror or PRTS.chat on request, while skin assets require no separate
download.

## Tools

- `corpus_search` — grep-style search over the local corpus: literal or a
  linear regex subset (anchors, dot, character classes, escapes and fixed
  `{n}` repetitions; no grouping, alternation or variable quantifiers) on NFKC-normalized text, with resource-type /
  character / story / activity / entity / speaker / Wiki-field filters;
  keep the original conditions and pass `page.next_after` back unchanged as
  `after` to continue; the anchor carries a short `data_version` prefix and
  becomes invalid after a corpus release switch. `speakers` expands registered
  aliases; hits keep original punctuation and mark the match with `⟦⟧`
- `corpus_read` — read Arknights stages by `stage_code` (`story_part` is
  optional; ambiguous codes default to the pre-battle part with a note), operator records by character/name/segment, and character
  materials by category; it can stream a whole Arknights activity or Endfield
  mission collection with readable, version-bound continuation positions;
  it can also read a tagged Wiki field or page through a whole document; story
  documents return requested text only (self-built summaries and the
  activity timeline must be fetched explicitly, e.g. via `timeline_search`).
  In a dual-module session, add `game: "arknights"` or `game: "endfield"` only
  when a character locator needs same-name disambiguation.
  Use exactly one primary locator per call. If search returns `document_uid`, it
  replaces `title`; use `{document_uid, line}` or
  `{document_uid, mode:"document"}`, never both locators. A bare `title` reads
  the document from line 1; titles tolerate missing separators and Wiki
  sequence suffixes, and unknown titles list the closest candidates.
  `activity_name` and `collection_name` reroute to the other game when the
  name only exists there
- `timeline_search` — query the Terra calendar timeline; source markers can
  be resolved back to full provenance
- `cloud_search` / `cloud_inspect` — optional PRTS.cloud hybrid retrieval
  (enabled via settings; results are mapped back to local documents)
- `web_search` — native DSH web discovery for external history, etymology,
  folklore, and other non-PRTS sources
- `web_fetch` — read a known public URL for close reading and cross-checking

Repeated and partially reused reads retain the normal page limits and
continuation. Partial reads include `coverage` identifying previously visible
lines and newly returned lines; `page.has_more` still determines whether the
document has more content. Reuse trusts the host's "currently visible surface":
if earlier output was compacted or collapsed out of context, that page can look
present while being unreadable — pass `reuse: false` to force a full resend
instead of tuning `max_lines`.

To continue a document read, pass `start_line` (not `line`): `line` means the
centre line of an `around` window (three lines each way by default) and is
rejected with `mode: "document"`. Every line hit in `corpus_search` also gets a
handle such as `doc_xxxxxxxxxxxxxxxx#L12`; feed it back with
`corpus_read({"citation":"doc_xxxxxxxxxxxxxxxx#L12"})` to return to those exact
lines without looking up a `document_uid` first. Zero-hit searches report the
covered scope (`scope`: documents and lines), and results carry a per-game hit
distribution (`by_game`) so cross-game homonyms can be narrowed with `games`. Cloud answers remain available when local corpus
mapping fails, with a warning to install or repair the corpus before verifying
the original text.

If the corpus changes during a read or search, the request returns a retryable
`PACKAGE_VERSION_MISMATCH`; resolve the locator against the current version
before retrying. Old operations cannot populate the new version's document or
search caches. Reused reads and reads spanning multiple documents enforce the
same version check.

Wiki documents are typed as canonical character pages, story/operator-record
pages, or character-by-activity auxiliary pages. `corpus_search.wiki_sections`
combines those types with character/activity filters, while
`corpus_read({title, section})` reads the exact tagged field. See
`skills/prts-retrieval/references/wiki-schema.md` and `retrieval-recipes.md`
for field semantics and query recipes.

## Compatibility

DSH 0.1.2-alpha.1 and 0.1.2-alpha.2 have completed historical real-host tests
with the web profile. Alpha.1 was built from the official tag and passed
installation, preset resolution, host startup, settings-route, and
client-bundle checks. The declared minimum runtime is DSH 0.2.0-rc.1
(`engines.dsh`), and every contract this plugin relies on — tool registration,
systemPrompt contexts, Connection Fetch routes, skills, presets and the client
module protocol — was checked against the 0.2.1-rc.2 source. Since 0.2.1 exact
Fetch routes admit only the owner principal, so a desktop carrier must declare
that principal; PTC sub-dispatches also persist `presentationMeta`, but the
client never reads it, so evidence cards still come from the plugin's receipt.
The shared Connection Fetch transport supports Web and the official
Electron source implementation; Web also retains HTTP routes. Declarative
registration and legacy file seeding pass this project's unit tests. Tests against
0.1.7-rc.2 (`477b4f420553`) also exercise real Cordis, Tools, SystemPrompt,
Storage Domain and official web tools for scoped events, tool receipts, cold
investigation recovery and disposal. Browser regressions cover all four skins
with official plugin/settings components and current/legacy conversation layouts.
Web receipts retain only text delivered to the model; URL matching merges live
and restored archive entries. Model selection handles both modern `RemoteResult`
and legacy `void` results, keeping the original session on failure. These tests
use a local web-provider fixture without credentials or API calls. A full
0.1.7-rc.2 Host launch and Windows Electron end-to-end test remain to be run.
The default Electron portable builder pins the official 0.1.7-rc.2 tag; the legacy
Electron entry pins 0.1.5-alpha.1 and the original WebView2 builder pins
0.1.3-alpha.1. Release builds still require a real Windows Host smoke test.

Older custom deployments with `includeUserRoot: false` and no other preset root with
`trust: user` receive no generated preset or root changes; their operator must
first enable user preset authoring. The plugin relies on internal host surfaces
(`ctx.tools`, `system-prompt/assemble`, Connection Fetch, agent presets, client
slots/theme); after a DSH major upgrade, re-run the smoke checklist below.

## Development

`presets/` contains the PRTS composition, declarative definition, and legacy user-preset initializer.

```bash
npm run check   # syntax check
npm test        # node --test suite
git diff --check
```

`bin/pack-map-assets.mjs` pre-compresses the Endfield map assets
(brotli q9 + gzip 9, the same scheme as endfield.prts.chat); the bundled
plugin only carries compressed variants. `npm run pack:map:restore`
restores plaintext for development.

## License

This project uses the following licensing boundaries:

- **Original code and documentation:** licensed under the [MIT License](LICENSE).
- **Game-related content:** names, trademarks, images, models, textures, game data, and other materials relating to Arknights or Arknights: Endfield are not covered by the MIT License and belong to their respective rights holders. See [GAME_ASSETS.md](GAME_ASSETS.md) for the exact packaged paths.
- **Corpus datasets:** full datasets are not distributed in this Git repository
  or bundled plugin code. Downloaded PRTS.chat datasets remain subject to the
  licenses, source declarations, and terms on the
  [Arknights dataset](https://modelscope.cn/datasets/HTiantian/prts-agent-corpus-arknights)
  and [Endfield dataset](https://modelscope.cn/datasets/HTiantian/prts-agent-corpus-endfield)
  pages.

This is an unofficial community project and is not affiliated with or endorsed by the games' developers or publishers. See [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) for the complete notice.

### Official Endfield localization lookup

`corpus_i18n({query: "管理员，你来了。", languages: ["EN", "JP", "KR"]})` returns official localized text with source references. Existing search results can be passed as `title` or `document_uid`, optionally with `line`. Raw text IDs remain hidden unless `include_ids: true` is requested. Missing translations are explicit; profile records are aligned as a whole, not by Chinese paragraph number. Requires plugin 0.2.0 and a corpus release containing localization attachments. See [format and build instructions](docs/endfield-official-i18n.md).
