@loredotlink/cli 0.1.180

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/LICENSE ADDED
@@ -0,0 +1,111 @@
1
+ Portions of this software are licensed as follows:
2
+
3
+ * All content that resides under the "ee/" directory of this repository, if that directory exists, is licensed under the license defined in "ee/LICENSE".
4
+ * All third party components incorporated into the Tanagram Software are licensed under the original license provided by the owner of the applicable component.
5
+ * Content outside of the above mentioned directories or restrictions above is available under the "FSL-1.1-ALv2" license as defined below.
6
+
7
+ # Functional Source License, Version 1.1, ALv2 Future License
8
+
9
+ ## Abbreviation
10
+
11
+ FSL-1.1-ALv2
12
+
13
+ ## Notice
14
+
15
+ Copyright 2026 Tanagram, Inc.
16
+
17
+ ## Terms and Conditions
18
+
19
+ ### Licensor ("We")
20
+
21
+ The party offering the Software under these Terms and Conditions.
22
+
23
+ ### The Software
24
+
25
+ The "Software" is each version of the software that we make available under
26
+ these Terms and Conditions, as indicated by our inclusion of these Terms and
27
+ Conditions with the Software.
28
+
29
+ ### License Grant
30
+
31
+ Subject to your compliance with this License Grant and the Patents,
32
+ Redistribution and Trademark clauses below, we hereby grant you the right to
33
+ use, copy, modify, create derivative works, publicly perform, publicly display
34
+ and redistribute the Software for any Permitted Purpose identified below.
35
+
36
+ ### Permitted Purpose
37
+
38
+ A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
39
+ means making the Software available to others in a commercial product or
40
+ service that:
41
+
42
+ 1. substitutes for the Software;
43
+
44
+ 2. substitutes for any other product or service we offer using the Software
45
+ that exists as of the date we make the Software available; or
46
+
47
+ 3. offers the same or substantially similar functionality as the Software.
48
+
49
+ Permitted Purposes specifically include using the Software:
50
+
51
+ 1. for your internal use and access;
52
+
53
+ 2. for non-commercial education;
54
+
55
+ 3. for non-commercial research; and
56
+
57
+ 4. in connection with professional services that you provide to a licensee
58
+ using the Software in accordance with these Terms and Conditions.
59
+
60
+ ### Patents
61
+
62
+ To the extent your use for a Permitted Purpose would necessarily infringe our
63
+ patents, the license grant above includes a license under our patents. If you
64
+ make a claim against any party that the Software infringes or contributes to
65
+ the infringement of any patent, then your patent license to the Software ends
66
+ immediately.
67
+
68
+ ### Redistribution
69
+
70
+ The Terms and Conditions apply to all copies, modifications and derivatives of
71
+ the Software.
72
+
73
+ If you redistribute any copies, modifications or derivatives of the Software,
74
+ you must include a copy of or a link to these Terms and Conditions and not
75
+ remove any copyright notices provided in or with the Software.
76
+
77
+ ### Disclaimer
78
+
79
+ THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
80
+ IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
81
+ PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
82
+
83
+ IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
84
+ SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
85
+ EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
86
+
87
+ ### Trademarks
88
+
89
+ Except for displaying the License Details and identifying us as the origin of
90
+ the Software, you have no right under these Terms and Conditions to use our
91
+ trademarks, trade names, service marks or product names.
92
+
93
+ ## Grant of Future License
94
+
95
+ We hereby irrevocably grant you an additional license to use the Software under
96
+ the Apache License, Version 2.0 that is effective on the second anniversary of
97
+ the date we make the Software available. On or after that date, you may use the
98
+ Software under the Apache License, Version 2.0, in which case the following
99
+ will apply:
100
+
101
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
102
+ this file except in compliance with the License.
103
+
104
+ You may obtain a copy of the License at
105
+
106
+ http://www.apache.org/licenses/LICENSE-2.0
107
+
108
+ Unless required by applicable law or agreed to in writing, software distributed
109
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
110
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
111
+ specific language governing permissions and limitations under the License.
package/README.md ADDED
@@ -0,0 +1,308 @@
1
+ # Lore
2
+
3
+ Lore captures your Claude Code, Codex, and Cowork sessions and turns them
4
+ into something your team can search, discuss, and build on.
5
+
6
+ Your AI coding sessions run on your machine. The Lore CLI watches for new
7
+ ones and uploads them to your workspace automatically, so there is no
8
+ copy-paste, no screenshots, no "save this thread" button to remember.
9
+
10
+ ## Get started
11
+
12
+ ```sh
13
+ npm install -g @loredotlink/cli
14
+ lore
15
+ ```
16
+
17
+ `lore` opens a dashboard in your terminal. Sign in there once and, on
18
+ macOS, background uploads start immediately. On Linux, run `lore configure`
19
+ to pick which directories upload.
20
+
21
+ That's it. Keep coding. New sessions show up in your workspace automatically.
22
+
23
+ ## How privacy works
24
+
25
+ **Private by default.** Every session starts visible only to you. You
26
+ choose per session whether to share it with your workspace or make it
27
+ public. Workspace admins cannot override that choice.
28
+
29
+ **You control what uploads.** Lore only uploads sessions from directories
30
+ you allowlist. The first-run wizard pre-checks your three most recent
31
+ projects; nothing outside your allowlist is ever sent. Re-run the picker
32
+ any time with `lore configure`, or edit the list directly:
33
+
34
+ ```sh
35
+ lore listen list # what's currently allowlisted
36
+ lore listen create ~/code/project # start uploading from here
37
+ lore listen delete ~/code/project # stop
38
+ ```
39
+
40
+ **What a session contains.** Your prompts, the assistant's responses,
41
+ tool calls, file edits, and diffs, plus metadata like timestamps, model,
42
+ and the repo it ran in. Diffs include the changed lines of the files you
43
+ edited. Lore does not collect environment variables, secrets, or API keys.
44
+
45
+ **Stop anytime.** `lore disable` halts background uploads. `lore logout`
46
+ removes your stored credentials. You can delete any session, or your whole
47
+ account, from the web app.
48
+
49
+ ---
50
+
51
+ ## Reference: upload filters
52
+
53
+ The Lore background agent evaluates `~/.lore/upload_filters.json`
54
+ (`~/.lore-dev/` in dev) before auto-uploading Claude Code sessions.
55
+ Missing config or an empty `include` allowlist means upload nothing. The `cwd` and `repo`
56
+ allowlists are a union: a session is location-allowed if it matches a
57
+ `cwd` rule OR a `repo` rule (so a non-git directory uploads via its `cwd`
58
+ even when `repo` rules also exist). When set, `include.skills` further
59
+ narrows that set (ANDed). Values within a dimension are ORed, and
60
+ `exclude` rules override includes.
61
+
62
+ The explicit commands (`lore export`, `lore share-codex`,
63
+ `lore share-cowork`) are user-initiated and upload the requested session
64
+ directly.
65
+
66
+ Adding repos and directories through the TUI is a convenience for writing
67
+ `repo` and `cwd` include filters. The post-login wizard shows your
68
+ most-recent Claude Code projects with the top three pre-checked: a project
69
+ inside a git repo is offered as its `origin` remote, and a non-repo
70
+ directory is offered by its path. Pressing Enter accepts them. `lore configure` re-enters that same interactive flow any time
71
+ (it's also one of the quick actions on the `lore` dashboard). For
72
+ scripted/non-interactive edits, use `lore listen` for directory filters;
73
+ `lore listen list` prints the effective repo and cwd upload locations:
74
+
75
+ ```sh
76
+ lore listen create ~/code/projectA # watch ~/code/projectA
77
+ lore listen list # effective repo/cwd locations
78
+ lore listen list --json # for scripts
79
+ lore listen delete ~/code/projectA # stop uploading from
80
+ ```
81
+
82
+ `cwd` matching uses path-separator-aware **prefix-tree** semantics, so adding
83
+ `~/code` covers `~/code/projectA`, `~/code/projectA/src`, etc., but
84
+ deliberately does **not** cover `~/code-other`. The most-specific
85
+ matching entry wins, so you can have a broad personal `~/` allow plus a
86
+ narrower `~/work` override that routes to a different org.
87
+
88
+ If a `cwd` include points at your entire home directory, `lore listen list`
89
+ prints a warning and suggests replacing it with narrower project paths. Lore
90
+ does not rewrite existing allowlists automatically.
91
+
92
+ ## Interactive TUI
93
+
94
+ Running `lore` with no subcommand drops you into an interactive Ink
95
+ dashboard when stdin and stdout are TTYs:
96
+
97
+ ```
98
+ ┌── lore — matt@tanagram.ai · tanagram ─────────────────── v0.1.50 ──┐
99
+ │ │
100
+ │ ╭─ Daemon ──────────────────╮ ╭─ Workspace ─────────────────────╮ │
101
+ │ │ ● Status running │ │ ● User matt@tanagram.ai │ │
102
+ │ │ ● Enabled yes │ │ ● Display Matt │ │
103
+ │ │ ● Running yes │ │ ● Org tanagram │ │
104
+ │ │ ● Heartbeat 12s ago │ │ ● Skills 8 installed · 3 │ │
105
+ │ │ ● Last upload 3m ago │ │ published │ │
106
+ │ ╰────────────────────────────╯ ╰────────────────────────────────╯ │
107
+ │ │
108
+ │ ╭─ Quick actions ───── ↑/↓ or j/k · Enter to choose · q to quit ─╮ │
109
+ │ │ › Share Codex session lore share-codex --session-file … │ │
110
+ │ │ Share Cowork session lore share-cowork │ │
111
+ │ │ Export latest Claude lore export │ │
112
+ │ │ Inspect background daemon lore status │ │
113
+ │ │ List installed skills lore skills list │ │
114
+ │ │ … │ │
115
+ │ ╰─────────────────────────────────────────────────────────────────╯ │
116
+ └────────────────────────────────────────────────────────────────────┘
117
+ ```
118
+
119
+ Picking an action exits the dashboard and re-enters the matching
120
+ subcommand exactly as if you had typed it yourself — auth checks,
121
+ metrics, and error formatting all flow through the same path.
122
+
123
+ The interactive flows (`lore login`, `lore enable` / `disable` /
124
+ `restart` / `status`, and the three share/export commands) also render
125
+ through Ink in TTY mode:
126
+
127
+ - **`lore login`** — three labelled steps (negotiating with WorkOS →
128
+ device code panel → polling), then a success box with the resolved
129
+ LaunchAgent paths. Distinct copy for timed-out / denied / expired.
130
+ On first login the device-code flow is followed by a one-screen
131
+ "Configure uploads" wizard that writes `repo` and `cwd` include
132
+ filters from your recent repos and directories.
133
+ - **`lore enable` / `disable` / `restart`** — spinner with mode-specific
134
+ copy while launchctl works, then a success or error MessageBox.
135
+ - **`lore status`** — two-panel view (health on the left, paths on the
136
+ right) with severity dots and a "Not healthy" callout pointing at
137
+ `lore restart` / `lore logs` when something is off.
138
+ - **`lore export` / `share-codex` / `share-cowork`** — four-step pipeline
139
+ display (resolving → uploading → parsing → updating visibility) with
140
+ the resulting URL highlighted in a success box.
141
+
142
+ ### Disabling the TUI
143
+
144
+ The TUI is presentation only — every command produces identical
145
+ stdout in non-TTY contexts (scripts, CI, piped output). To force the
146
+ plain rendering even in a TTY:
147
+
148
+ - pass `--no-tui` at the top level: `lore --no-tui status`
149
+ - or set `LORE_NO_TUI=1` in the environment.
150
+
151
+ `lore status --json` always prints JSON and never mounts the TUI.
152
+
153
+ The plain path is also taken automatically whenever:
154
+
155
+ - stdout or stdin is not a TTY (piped, redirected, or scripted)
156
+ - `CI` is set to a truthy value
157
+ - `TERM=dumb`
158
+
159
+ ### TUI architecture (for contributors)
160
+
161
+ See [AGENTS.md](./AGENTS.md) for the contributor guide on adding new
162
+ screens, the presentation/handler split, and the TTY-detection contract.
163
+
164
+ ### TUI story runner
165
+
166
+ Use the terminal story runner to review seeded Ink states without touching
167
+ WorkOS, the Lore API, launchd, or local Lore config:
168
+
169
+ ```sh
170
+ pnpm tui:stories # interactive browser
171
+ pnpm tui:stories --story dashboard/healthy
172
+ pnpm tui:stories --list # print available story ids
173
+ ```
174
+
175
+ Stories live under `src/tui/stories/` and import screen components rather
176
+ than `*Entrypoint.tsx` files. Keep new stories fixture-driven: pass explicit
177
+ state, timestamps, and no-op callbacks so story review never performs command
178
+ side effects. In the interactive runner, use ↑/↓ or j/k to choose a story,
179
+ Tab to focus the preview so nested controls own the keyboard, Shift+Tab or
180
+ Esc to return to the sidebar, and q to exit.
181
+
182
+ ## Subcommands
183
+
184
+ - `lore` — opens the interactive dashboard in a TTY; prints help text
185
+ in non-TTY contexts.
186
+ - `lore login` — authorizes the CLI against your Lore workspace using WorkOS
187
+ CLI Auth's device-code flow. On macOS, also auto-runs `lore enable` to
188
+ install and start the background uploader; if that step fails, login still
189
+ succeeds and you can rerun `lore enable` manually.
190
+ - `lore logout` — removes the stored CLI tokens.
191
+ - `lore health` — calls the API health endpoint.
192
+ - `lore logs` — prints recent entries from the log file.
193
+ - `lore version` — prints the CLI version.
194
+ - `lore update` — runs the same update check as the background auto-updater,
195
+ waits for it to finish, and prints the result.
196
+ - `lore enable` — installs and starts the macOS background agent.
197
+ - `lore disable` — stops and removes the macOS background agent.
198
+ - `lore restart` — restarts the macOS background agent.
199
+ - `lore status` / `lore status --json` — shows background-agent health and recent activity. The plain output does not treat an idle process as broken just because there is no active upload at that instant.
200
+ - `lore configure` — re-enter the interactive wizard for picking the
201
+ repos and directories Lore auto-uploads from (the same flow shown on first
202
+ login). Requires an interactive terminal.
203
+ - `lore listen create <path>` — allowlist a directory for background auto-uploads.
204
+ - `lore listen list [--json]` — print the effective repo and cwd locations
205
+ the background agent may auto-upload from.
206
+ - `lore listen delete <path>` — stop uploading from a directory.
207
+ - `lore workspaces list` — calls `/api/whoami` and prints the WorkOS
208
+ workspaces the authenticated user currently belongs to. (Workspaces
209
+ are organizations in the underlying API contract.)
210
+ - `lore skills list` — lists skills visible to the authenticated workspace.
211
+ - `lore skills sync` — runs the foreground skill sync engine once: it scans
212
+ supported local skill roots, captures local changes privately, pulls accepted
213
+ remote updates for installed skills, and preserves subscriber edits as
214
+ proposals instead of overwriting them.
215
+ - `lore skills install <skill-id>` — installs a workspace-visible skill by its
216
+ stable `sk_…` id and records the local installation. Installing is
217
+ non-interactive and pipe-friendly: if the target `SKILL.md` already exists but
218
+ is managed by Lore (the same `sk_…`), it is overwritten with the remote body;
219
+ if it exists and is *not* managed by Lore, the install errors instead of
220
+ clobbering it. Use `lore skills sync` for conflict-preserving updates.
221
+ - `lore skills uninstall <skill-id>` — removes the managed local skill file and
222
+ clears the installation record.
223
+ - `lore skills publish <local-name-or-skill-id>` — publishes an authored skill
224
+ to the workspace, or submits an installed-skill edit as a proposal when the
225
+ caller is not the owner.
226
+ - `lore skills daemon` — hidden long-running worker used by supervised/dev
227
+ environments for skill sync. It does a startup sync, subscribes to skill SSE
228
+ events from `/api/events/stream`, falls back to polling, and performs a full
229
+ catch-up when the stream reports a truncated cursor.
230
+ - `lore export` — uploads a single Claude Code session on demand and prints a
231
+ JSON object with the thread URL. Use `--session-id <id>` to pick a specific
232
+ session, `--project <path>` to override the project lookup, and
233
+ `--visibility private|workspace|public` to set the resulting thread's
234
+ visibility. Use `--highlight <description>` to have the API resolve a
235
+ natural-language share highlight and return a `/thread/<id>#tb_…` block
236
+ anchor or range when it finds a match. The URL is also copied to the system clipboard when a clipboard
237
+ tool is available (`pbcopy` / `wl-copy` / `xclip` / `xsel` / `clip.exe`).
238
+ - `lore share-cowork` — shares a Claude Cowork local-agent-mode session
239
+ to Lore. Defaults to the current session when run from inside one
240
+ (e.g. by the Cowork agent itself); otherwise shares the most recent
241
+ local session under
242
+ `~/Library/Application Support/Claude/local-agent-mode-sessions/`.
243
+ Use `--session <session-id>` to share a specific session by id, or
244
+ `--list` to enumerate local sessions newest-first without sharing.
245
+ Re-running for the same session converges to the same thread (md5
246
+ dedup), so it's safe to retry. Prints the resulting `/thread/<id>`
247
+ URL on success.
248
+
249
+ ## Dev vs prod
250
+
251
+ The CLI is environment-stamped at build time (esbuild `--define`), not via
252
+ runtime env vars. The published `@loredotlink/cli` on npm is pinned to prod;
253
+ anything built locally (`pnpm build`, `tsx`, `pnpm dev`) is pinned to dev.
254
+
255
+ Because both can be installed on the same machine, they keep separate state
256
+ dirs so they don't stomp each other:
257
+
258
+ | Env | State dir | Log file |
259
+ | ---- | --------------- | --------------------- |
260
+ | prod | `~/.lore/` | `~/.lore/log.txt` |
261
+ | dev | `~/.lore-dev/` or `LORE_DEV_STATE_DIR` when set by a supervised local stack | `<state-dir>/log.txt` |
262
+
263
+ `lore login` discovers WorkOS AuthKit from the Lore MCP resource metadata,
264
+ starts WorkOS's device-code flow, prints the verification URL and user code, and
265
+ polls WorkOS until it receives JWT access and refresh tokens. Token persistence,
266
+ legacy migration, OAuth discovery caching, and refresh-token rotation live in
267
+ `@lore/identity-store`, shared with the Lore plugin. The CLI stores the
268
+ canonical token record as `tokens.json` in the active state dir (for example,
269
+ `~/.lore-dev/tokens.json` in standalone local dev or
270
+ `~/.lore-dev-<stack>/tokens.json` under supervised `pnpm dev`) and caches OAuth discovery beside it as
271
+ `discovery-cache.json`. When the access token is expired or will expire within
272
+ 10 seconds, authenticated commands use the refresh token to rotate a new access
273
+ token automatically. Transient refresh failures preserve the refresh token for a
274
+ later retry; only an AuthKit `invalid_grant` response clears local tokens and
275
+ requires login again. The CLI does not read token environment variables; use
276
+ `lore logout` to remove the stored tokens.
277
+
278
+ For local development, `pnpm dev <command>` first attempts
279
+ `pnpm bootstrap:dev-auth` so dev-only tokens are refreshed against the currently
280
+ running API process. If the API is unavailable, the bootstrap logs an error and
281
+ the requested command still runs.
282
+
283
+ Run `lore logs` to print the active log file path. In dev, log lines also
284
+ tee to stderr so you see them while iterating; in prod the file is the only
285
+ sink so installed users don't see noise on every command.
286
+
287
+ `pnpm dev` runs the CLI postinstall hook before starting so bundled dev skills
288
+ are refreshed in `~/.claude/skills` on each dev session.
289
+
290
+ ### Skill sync end-to-end tests
291
+
292
+ Team skill sync has an opt-in acceptance suite that exercises an author's
293
+ computer and a subscriber's computer with isolated temporary homes and project
294
+ roots. It is intentionally separate from the default `pnpm test` glob so CI can
295
+ choose when to run the full acceptance loop explicitly:
296
+
297
+ ```sh
298
+ pnpm --filter @loredotlink/cli test:skill-sync:e2e
299
+ ```
300
+
301
+ The suite covers private capture, workspace publish/install, subscriber update
302
+ pulls, subscriber edit proposals, owner approval, uninstall cleanup, project-root
303
+ isolation, and daemon reconnect/catch-up behavior.
304
+
305
+ To point the CLI at a different API origin (e.g. through a Vite proxy or a
306
+ remote staging deployment), set `LORE_API_ORIGIN`. The override wins over the
307
+ built-in env defaults: `LORE_API_ORIGIN=http://localhost:8080 lore health`
308
+ will route through the web app's Vite proxy on 8080 to the API on 4000.