@lorekit/cli 1.52.0 → 1.52.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -597,7 +597,7 @@ erases your cross-repo home lesson.
|
|
|
597
597
|
> sharing comes from the account/token, so remote needs no second location.
|
|
598
598
|
> Different mechanism, same concept.
|
|
599
599
|
|
|
600
|
-
### `lorekit migrate` —
|
|
600
|
+
### `lorekit migrate` — relocate a store, or push one to the hosted store
|
|
601
601
|
|
|
602
602
|
Moved or renamed a local store (e.g. an old `.lore/`)? `migrate` re-writes its
|
|
603
603
|
entries into the current two-tier layout so lessons are never stranded:
|
|
@@ -612,6 +612,80 @@ Dry-run (preview) by default; `--yes` (or `--apply`) applies. Idempotent — a
|
|
|
612
612
|
re-run is a no-op. It reads LoreKit's own on-disk format only (it does **not**
|
|
613
613
|
import persistent-memory's `~/.agent-memory/<bucket>/` format).
|
|
614
614
|
|
|
615
|
+
#### `--to remote` — bring your local lessons up
|
|
616
|
+
|
|
617
|
+
Started offline and later connected a token? `--to remote` pushes the whole
|
|
618
|
+
local store to the hosted one in a single command, instead of the agent
|
|
619
|
+
re-writing lessons one at a time in remote mode:
|
|
620
|
+
|
|
621
|
+
```bash
|
|
622
|
+
lorekit migrate --from .lorekit --to remote # dry-run: the plan, per scope
|
|
623
|
+
lorekit migrate --from .lorekit --to remote --yes # push it
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
The connection and token come from the same place every other command reads
|
|
627
|
+
them (`.mcp.json` / `.lorekit.json` / `LOREKIT_MCP_URL` + `LOREKIT_TOKEN`), so
|
|
628
|
+
a `deny: remote` constraint still wins. Everything is checked **before** the
|
|
629
|
+
first request rather than mid-push:
|
|
630
|
+
|
|
631
|
+
| Condition | Result |
|
|
632
|
+
|---|---|
|
|
633
|
+
| No usable connection | Fails with the `lorekit install` command to run |
|
|
634
|
+
| Read-only `lk_ro_*` token | Fails — a migration writes |
|
|
635
|
+
| Write-only `lk_wo_*` token | Warns, then pushes without reading: its reads are denied, so the destination is not classified at all and every entry reports as `add` (the hosted upsert is idempotent either way) |
|
|
636
|
+
| Unrecognized token prefix | Warns and proceeds, so a self-hosted or custom token still works |
|
|
637
|
+
| `deny: remote` | Fails, naming the config source that denied it |
|
|
638
|
+
|
|
639
|
+
**What transfers, and what the server owns.** `scope`, `key`, `value`,
|
|
640
|
+
`source_agent` and `trigger` travel as the source states them (`value` is
|
|
641
|
+
trimmed server-side), and the original creation date travels as `created_at` —
|
|
642
|
+
so a migrated lesson keeps the recency its ranking depends on. The rest is not
|
|
643
|
+
verbatim, and every departure is reported per entry, in the dry run as well as
|
|
644
|
+
the apply:
|
|
645
|
+
|
|
646
|
+
| Field | What happens |
|
|
647
|
+
|---|---|
|
|
648
|
+
| `updated` | Re-stamped at the write instant — there is no parameter for it |
|
|
649
|
+
| `seen_count` | Starts at 1 for a key the hosted store has never seen; one it already holds lands at ITS count plus one (the RPC treats a write as a sighting, migration 00059). A local tally of 12 never transfers |
|
|
650
|
+
| `tags` | **Replace** the hosted row's labels, so an untagged local entry clears them |
|
|
651
|
+
| `origin_*` | **Sticky** — the RPC coalesces provenance, so an entry carrying none leaves whatever the hosted row already had |
|
|
652
|
+
| `created` | Honoured only when the lesson is new to the hosted store (the RPC's update clause omits it, so one already there keeps its hosted date); an unusable or future-dated value is dropped for the write instant, and the entry is named |
|
|
653
|
+
| `expires_at` | Converted to the remaining whole `ttl_days`; anything beyond the API's 365-day cap lands shortened |
|
|
654
|
+
|
|
655
|
+
**Archived and expired entries are skipped** and reported as such. Neither can
|
|
656
|
+
be represented: a write against an archived key inserts a second, live row
|
|
657
|
+
beside it rather than reviving it, and any TTL would re-date an expired row
|
|
658
|
+
into the future — so pushing them would resurrect lore you retired.
|
|
659
|
+
|
|
660
|
+
Idempotent, with one nuance: a re-run compares only what a hosted write can
|
|
661
|
+
change, and compares it the way the server stores it — trimmed `value`, only
|
|
662
|
+
the provenance the source carries, and an expiry that still honours the local
|
|
663
|
+
intent (the hosted one is fixed at push time while the local one is measured
|
|
664
|
+
from now, so it is judged on whether at least half the intended life remains —
|
|
665
|
+
matching them instant-for-instant could never converge). Comparing the server-owned fields
|
|
666
|
+
directly would report a change forever and re-push the whole store on every
|
|
667
|
+
run. A remote `unchanged` therefore means "the hosted lesson already says
|
|
668
|
+
this", not "byte-identical row".
|
|
669
|
+
|
|
670
|
+
Rate limits and transient failures are handled rather than surfaced as
|
|
671
|
+
failures. The run paces itself under the hosted 120 req/min limit (and says so
|
|
672
|
+
the first time it has to wait), and retries a `429` on the server's own
|
|
673
|
+
`Retry-After` — plus a 5xx or a dropped connection, which on a push of
|
|
674
|
+
thousands of requests is the likeliest failure and the least worth losing an
|
|
675
|
+
entry to. Any other 4xx is a decision, not a blip, and is never retried.
|
|
676
|
+
|
|
677
|
+
Retrying is bounded, so none of this should be read as "it never fails": an
|
|
678
|
+
entry that exhausts its attempts is reported and the run exits non-zero, and
|
|
679
|
+
five CONSECUTIVE failures of any kind stop the run early with a
|
|
680
|
+
partial-progress report — an outage is not worth grinding a whole store through
|
|
681
|
+
the retry budget for. Every one of those exits is safe to re-run. The memory cap ([5,000 active memories on the
|
|
682
|
+
free plan](../../docs/limits.md)) is returned as a `429` too but is terminal —
|
|
683
|
+
the run stops, reports how many entries landed, and exits non-zero, so you can
|
|
684
|
+
archive or upgrade and re-run to resume.
|
|
685
|
+
|
|
686
|
+
Not in v1: `--org <slug>` org-owned writes (a migration lands as your personal
|
|
687
|
+
lore) and the reverse remote → local direction.
|
|
688
|
+
|
|
615
689
|
### The control model — two layers, deny-wins
|
|
616
690
|
|
|
617
691
|
Two config layers decide the mode:
|
|
@@ -870,7 +944,7 @@ also returns their headroom against the plan's memory cap.
|
|
|
870
944
|
| `--mode <mode>` | Memory mode override for `doctor`: `off` / `local` / `remote` |
|
|
871
945
|
| `--store <path>` | Local project-tier store directory (default `.lorekit`) |
|
|
872
946
|
| `--from <path>` | Source store to migrate from (`migrate`) |
|
|
873
|
-
| `--to <
|
|
947
|
+
| `--to <dest>` | Migration destination: `home` / `project` / `remote` (`migrate`; default routes by scope across the local tiers) |
|
|
874
948
|
| `--apply` | Apply the migration — alias of `--yes` (`migrate`) |
|
|
875
949
|
| `-y, --yes` | Non-interactive / apply; never prompt |
|
|
876
950
|
| `--hooks <mode>` | Lifecycle hooks to wire: `all` / `read-only` / `none` (`install`; `none` removes any already wired) |
|