@lorekit/cli 1.25.0 → 1.26.0
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 +45 -2
- package/bin/lorekit.mjs +67 -5
- package/package.json +1 -1
- package/src/core/lessons.mjs +22 -12
- package/src/deeplink-pure.mjs +194 -0
- package/src/doctor.mjs +50 -16
- package/src/hook.mjs +7 -1
- package/src/link.mjs +139 -0
- package/src/list.mjs +13 -0
- package/src/mcp-server.mjs +49 -6
- package/src/origin.mjs +186 -0
- package/src/search.mjs +13 -0
- package/src/show.mjs +9 -0
- package/src/store/format.mjs +7 -0
- package/src/store/local.mjs +15 -1
- package/src/store/remote.mjs +11 -1
- package/src/telemetry.mjs +4 -4
- package/src/tree.mjs +13 -0
- package/src/write.mjs +39 -0
package/src/write.mjs
CHANGED
|
@@ -16,6 +16,16 @@
|
|
|
16
16
|
// --ttl-days <n> Days until the memory auto-expires (1–365)
|
|
17
17
|
// --org <slug> Write to this org (remote only)
|
|
18
18
|
//
|
|
19
|
+
// Provenance — where the lesson is being recorded FROM. Derived automatically
|
|
20
|
+
// from git + the CI environment (repo, branch, commit, and the pull request
|
|
21
|
+
// from LOREKIT_PR / GITHUB_REF); the dashboard turns it into links back to the
|
|
22
|
+
// PR, branch and commit. Each can be overridden, and the whole thing skipped:
|
|
23
|
+
// --origin-repo <owner/name> Override the derived repository
|
|
24
|
+
// --origin-branch <name> Override the derived branch
|
|
25
|
+
// --origin-commit <sha> Override the derived commit
|
|
26
|
+
// --origin-pr <n> The pull request this lesson came out of
|
|
27
|
+
// --no-origin Record no provenance at all
|
|
28
|
+
//
|
|
19
29
|
// Store targeting (default: remote if configured, else local):
|
|
20
30
|
// --remote Force write to the remote store
|
|
21
31
|
// --local Force write to the local offline store
|
|
@@ -32,6 +42,7 @@ import { resolveDenies } from './control.mjs';
|
|
|
32
42
|
import { resolveStores, remoteUnavailableReason } from './stores.mjs';
|
|
33
43
|
import { log, err, heading, status, c } from './util.mjs';
|
|
34
44
|
import { parseScopeKey } from './lessons-view.mjs';
|
|
45
|
+
import { deriveOrigin, mergeOrigin } from './origin.mjs';
|
|
35
46
|
|
|
36
47
|
// Read all of stdin to a string. Resolves to '' when stdin IS a TTY (no pipe).
|
|
37
48
|
function readStdin() {
|
|
@@ -100,6 +111,32 @@ export async function write(args) {
|
|
|
100
111
|
const ttlDays = args['ttl-days'] ? Number(args['ttl-days']) : undefined;
|
|
101
112
|
const orgSlug = typeof args.org === 'string' ? args.org : undefined;
|
|
102
113
|
|
|
114
|
+
// ── Provenance ────────────────────────────────────────────────────────────
|
|
115
|
+
// Derived from git + CI unless --no-origin; explicit --origin-* flags win.
|
|
116
|
+
// A field that is neither supplied nor derivable is omitted, never sent as
|
|
117
|
+
// null — the server keeps the last KNOWN origin per field, so an omission
|
|
118
|
+
// must not erase what an earlier write recorded.
|
|
119
|
+
// An explicitly supplied PR number is a caller assertion, so a malformed one
|
|
120
|
+
// is a usage error — silently ignoring it would record no provenance while
|
|
121
|
+
// the user believes they set it. Derived values, by contrast, degrade quietly.
|
|
122
|
+
let originPr = null;
|
|
123
|
+
if (args['origin-pr'] !== undefined) {
|
|
124
|
+
originPr = Number(args['origin-pr']);
|
|
125
|
+
if (!Number.isInteger(originPr) || originPr < 1) {
|
|
126
|
+
err(`${c.red('Error:')} --origin-pr must be a positive integer (got ${args['origin-pr']})`);
|
|
127
|
+
return 1;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const origin = args['no-origin']
|
|
132
|
+
? {}
|
|
133
|
+
: mergeOrigin(deriveOrigin({ cwd: root, env }), {
|
|
134
|
+
origin_repo: typeof args['origin-repo'] === 'string' ? args['origin-repo'] : null,
|
|
135
|
+
origin_branch: typeof args['origin-branch'] === 'string' ? args['origin-branch'] : null,
|
|
136
|
+
origin_commit: typeof args['origin-commit'] === 'string' ? args['origin-commit'] : null,
|
|
137
|
+
origin_pr: originPr,
|
|
138
|
+
});
|
|
139
|
+
|
|
103
140
|
// ── Resolve deny constraints ───────────────────────────────────────────────
|
|
104
141
|
const { localDenied, remoteDenied } = resolveDenies(root, { env });
|
|
105
142
|
|
|
@@ -162,6 +199,7 @@ export async function write(args) {
|
|
|
162
199
|
...(trigger ? { trigger } : {}),
|
|
163
200
|
...(ttlDays ? { ttl_days: ttlDays } : {}),
|
|
164
201
|
...(orgSlug ? { org: orgSlug } : {}),
|
|
202
|
+
...origin,
|
|
165
203
|
};
|
|
166
204
|
|
|
167
205
|
let result;
|
|
@@ -192,6 +230,7 @@ export async function write(args) {
|
|
|
192
230
|
tags,
|
|
193
231
|
source_agent: sourceAgent || null,
|
|
194
232
|
trigger: trigger || null,
|
|
233
|
+
origin,
|
|
195
234
|
}, null, 2));
|
|
196
235
|
} else {
|
|
197
236
|
const verb = inserted === true ? 'Created' : inserted === false ? 'Updated' : 'Written';
|