@younndai/lyt 0.9.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.
Files changed (96) hide show
  1. package/LICENSE +200 -0
  2. package/NOTICE +23 -0
  3. package/README.md +117 -0
  4. package/dist/automator-bodies/arc-builder.d.ts +13 -0
  5. package/dist/automator-bodies/arc-builder.d.ts.map +1 -0
  6. package/dist/automator-bodies/arc-builder.js +34 -0
  7. package/dist/automator-bodies/arc-builder.js.map +1 -0
  8. package/dist/automator-bodies/index.d.ts +20 -0
  9. package/dist/automator-bodies/index.d.ts.map +1 -0
  10. package/dist/automator-bodies/index.js +32 -0
  11. package/dist/automator-bodies/index.js.map +1 -0
  12. package/dist/automator-bodies/lane-builder.d.ts +12 -0
  13. package/dist/automator-bodies/lane-builder.d.ts.map +1 -0
  14. package/dist/automator-bodies/lane-builder.js +34 -0
  15. package/dist/automator-bodies/lane-builder.js.map +1 -0
  16. package/dist/automator-bodies/metadata-filler.d.ts +34 -0
  17. package/dist/automator-bodies/metadata-filler.d.ts.map +1 -0
  18. package/dist/automator-bodies/metadata-filler.js +211 -0
  19. package/dist/automator-bodies/metadata-filler.js.map +1 -0
  20. package/dist/automator-run.d.ts +27 -0
  21. package/dist/automator-run.d.ts.map +1 -0
  22. package/dist/automator-run.js +137 -0
  23. package/dist/automator-run.js.map +1 -0
  24. package/dist/bench/graded-corpus.d.ts +5 -0
  25. package/dist/bench/graded-corpus.d.ts.map +1 -0
  26. package/dist/bench/graded-corpus.js +121 -0
  27. package/dist/bench/graded-corpus.js.map +1 -0
  28. package/dist/bench/invariant-corpus.d.ts +18 -0
  29. package/dist/bench/invariant-corpus.d.ts.map +1 -0
  30. package/dist/bench/invariant-corpus.js +181 -0
  31. package/dist/bench/invariant-corpus.js.map +1 -0
  32. package/dist/bench/ir-metrics.d.ts +33 -0
  33. package/dist/bench/ir-metrics.d.ts.map +1 -0
  34. package/dist/bench/ir-metrics.js +79 -0
  35. package/dist/bench/ir-metrics.js.map +1 -0
  36. package/dist/bench/latency-bench.d.ts +15 -0
  37. package/dist/bench/latency-bench.d.ts.map +1 -0
  38. package/dist/bench/latency-bench.js +68 -0
  39. package/dist/bench/latency-bench.js.map +1 -0
  40. package/dist/bench/latency-corpus.d.ts +4 -0
  41. package/dist/bench/latency-corpus.d.ts.map +1 -0
  42. package/dist/bench/latency-corpus.js +109 -0
  43. package/dist/bench/latency-corpus.js.map +1 -0
  44. package/dist/bench/pod-harness.d.ts +16 -0
  45. package/dist/bench/pod-harness.d.ts.map +1 -0
  46. package/dist/bench/pod-harness.js +127 -0
  47. package/dist/bench/pod-harness.js.map +1 -0
  48. package/dist/bench/run-bench.d.ts +20 -0
  49. package/dist/bench/run-bench.d.ts.map +1 -0
  50. package/dist/bench/run-bench.js +86 -0
  51. package/dist/bench/run-bench.js.map +1 -0
  52. package/dist/cli-automator-run.d.ts +7 -0
  53. package/dist/cli-automator-run.d.ts.map +1 -0
  54. package/dist/cli-automator-run.js +80 -0
  55. package/dist/cli-automator-run.js.map +1 -0
  56. package/dist/cli.d.ts +3 -0
  57. package/dist/cli.d.ts.map +1 -0
  58. package/dist/cli.js +161 -0
  59. package/dist/cli.js.map +1 -0
  60. package/dist/commands/bench.d.ts +3 -0
  61. package/dist/commands/bench.d.ts.map +1 -0
  62. package/dist/commands/bench.js +92 -0
  63. package/dist/commands/bench.js.map +1 -0
  64. package/dist/commands/capture.d.ts +4 -0
  65. package/dist/commands/capture.d.ts.map +1 -0
  66. package/dist/commands/capture.js +251 -0
  67. package/dist/commands/capture.js.map +1 -0
  68. package/dist/commands/init.d.ts +12 -0
  69. package/dist/commands/init.d.ts.map +1 -0
  70. package/dist/commands/init.js +741 -0
  71. package/dist/commands/init.js.map +1 -0
  72. package/dist/commands/primer.d.ts +3 -0
  73. package/dist/commands/primer.d.ts.map +1 -0
  74. package/dist/commands/primer.js +199 -0
  75. package/dist/commands/primer.js.map +1 -0
  76. package/dist/commands/reindex.d.ts +3 -0
  77. package/dist/commands/reindex.d.ts.map +1 -0
  78. package/dist/commands/reindex.js +105 -0
  79. package/dist/commands/reindex.js.map +1 -0
  80. package/dist/commands/search.d.ts +3 -0
  81. package/dist/commands/search.d.ts.map +1 -0
  82. package/dist/commands/search.js +224 -0
  83. package/dist/commands/search.js.map +1 -0
  84. package/dist/flows/heal.d.ts +29 -0
  85. package/dist/flows/heal.d.ts.map +1 -0
  86. package/dist/flows/heal.js +146 -0
  87. package/dist/flows/heal.js.map +1 -0
  88. package/dist/flows/init-bootstrap.d.ts +93 -0
  89. package/dist/flows/init-bootstrap.d.ts.map +1 -0
  90. package/dist/flows/init-bootstrap.js +561 -0
  91. package/dist/flows/init-bootstrap.js.map +1 -0
  92. package/dist/index.d.ts +11 -0
  93. package/dist/index.d.ts.map +1 -0
  94. package/dist/index.js +27 -0
  95. package/dist/index.js.map +1 -0
  96. package/package.json +81 -0
@@ -0,0 +1,127 @@
1
+ /*
2
+ * Copyright 2026 MARLINK TRADING SRL (YounndAI)
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ // Lane V Workstream 2 — `lyt bench` temp-pod harness.
17
+ //
18
+ // Stands up a THROWAWAY pod under os.tmpdir (never the user's ~/lyt), seeds
19
+ // vaults + figments offline (federation self-heal disabled AND a synthetic
20
+ // identity pinned → no gh, no network, no interactive prompts), reindexes all
21
+ // content tiers, and runs the cascade. Productized from
22
+ // tools/lane-v/quality-probe.mjs (which only PROBED an already-built pod); this
23
+ // also BUILDS the pod, so the bench ships self-contained.
24
+ //
25
+ // Pod safety: LYT_HOME is repointed to a fresh mkdtemp dir for the harness'
26
+ // lifetime and restored on teardown. The dir is created by mkdtemp under
27
+ // os.tmpdir — it can never be ~/lyt — but we assert it (and reject anything
28
+ // under ~/lyt) anyway (defence-in-depth, mirroring quality-probe.mjs's guard).
29
+ import { mkdirSync, mkdtempSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
30
+ import { homedir, tmpdir } from "node:os";
31
+ import { dirname, join, resolve, sep } from "node:path";
32
+ import { initVaultFlow, rebuildVaultFlow, searchCascadeFlow, } from "@younndai/lyt-vault";
33
+ // Fixed clock threaded into reindex so temporal caches (keyword decay,
34
+ // recent-activity) are deterministic — the bench's metrics must not drift with
35
+ // wall-clock time.
36
+ export const BENCH_NOW_ISO = "2026-06-01T00:00:00.000Z";
37
+ const REAL_POD = resolve(homedir(), "lyt");
38
+ const BENCH_PREFIX = "lyt-bench-";
39
+ // Sweep leaked bench pods older than this (Windows libSQL handle lag can defeat
40
+ // the teardown rmSync). Age-gated so a concurrent run's live pod is never hit.
41
+ const STALE_POD_MS = 10 * 60_000;
42
+ // Best-effort reaper for bench pods a prior run failed to delete. Everything it
43
+ // touches is a mkdtemp dir named `lyt-bench-*` under os.tmpdir — junction-free,
44
+ // L0-safe. Age-gated + fully swallowed; never fails the bench.
45
+ function sweepStaleBenchPods(nowMs) {
46
+ let entries;
47
+ try {
48
+ entries = readdirSync(tmpdir());
49
+ }
50
+ catch {
51
+ return;
52
+ }
53
+ for (const name of entries) {
54
+ if (!name.startsWith(BENCH_PREFIX))
55
+ continue;
56
+ const full = join(tmpdir(), name);
57
+ try {
58
+ if (nowMs - statSync(full).mtimeMs < STALE_POD_MS)
59
+ continue;
60
+ rmSync(full, { recursive: true, force: true, maxRetries: 3, retryDelay: 200 });
61
+ }
62
+ catch {
63
+ // leave it; never fail on cleanup
64
+ }
65
+ }
66
+ }
67
+ export function setupBenchPod() {
68
+ sweepStaleBenchPods(Date.now());
69
+ const home = mkdtempSync(join(tmpdir(), BENCH_PREFIX));
70
+ const resolvedHome = resolve(home);
71
+ if (resolvedHome === REAL_POD || resolvedHome.startsWith(REAL_POD + sep)) {
72
+ throw new Error(`bench: refusing to run against the real pod (${REAL_POD}).`);
73
+ }
74
+ const prevLytHome = process.env["LYT_HOME"];
75
+ const prevIdentity = process.env["LYT_IDENTITY_OVERRIDE"];
76
+ process.env["LYT_HOME"] = home;
77
+ // Pin a synthetic identity so vault scaffolding (initVault -> getIdentity)
78
+ // never spawns `gh auth status` / `gh api /user`. WITHOUT this the bench
79
+ // throws on any machine where gh is missing/unauthed (release review C1) — this
80
+ // is what makes it truly offline + safe to run anywhere. Mirrors how every
81
+ // init-touching test pins LYT_IDENTITY_OVERRIDE.
82
+ process.env["LYT_IDENTITY_OVERRIDE"] = "github:lyt-bench";
83
+ return {
84
+ home,
85
+ async seedVault(name, notes) {
86
+ const init = await initVaultFlow({
87
+ name,
88
+ gitInit: false,
89
+ commitInitial: false,
90
+ selfHeal: { federation: { enabled: false } },
91
+ });
92
+ for (const note of notes) {
93
+ const full = join(init.vaultPath, note.rel);
94
+ mkdirSync(dirname(full), { recursive: true });
95
+ writeFileSync(full, `---\n${note.frontmatter}\n---\n${note.body}\n`, "utf8");
96
+ }
97
+ },
98
+ async reindex(name) {
99
+ await rebuildVaultFlow({ vault: name, nowIso: BENCH_NOW_ISO });
100
+ },
101
+ async search(args) {
102
+ return searchCascadeFlow(args);
103
+ },
104
+ teardown() {
105
+ // Restore env FIRST, unconditionally — a cleanup failure must never leave
106
+ // LYT_HOME / LYT_IDENTITY_OVERRIDE dangling.
107
+ if (prevLytHome === undefined)
108
+ delete process.env["LYT_HOME"];
109
+ else
110
+ process.env["LYT_HOME"] = prevLytHome;
111
+ if (prevIdentity === undefined)
112
+ delete process.env["LYT_IDENTITY_OVERRIDE"];
113
+ else
114
+ process.env["LYT_IDENTITY_OVERRIDE"] = prevIdentity;
115
+ // `home` is a fresh mkdtemp dir under os.tmpdir — no junctions, L0-safe.
116
+ // Best-effort: Windows libSQL handle lag can still defeat this; whatever is
117
+ // left is reaped by the next run's sweepStaleBenchPods.
118
+ try {
119
+ rmSync(home, { recursive: true, force: true, maxRetries: 5, retryDelay: 300 });
120
+ }
121
+ catch {
122
+ // leave for the next run's sweep
123
+ }
124
+ },
125
+ };
126
+ }
127
+ //# sourceMappingURL=pod-harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pod-harness.js","sourceRoot":"","sources":["../../src/bench/pod-harness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type InvariantResult } from "./invariant-corpus.js";
2
+ import { type GradedAggregate, type GradedQueryScore } from "./ir-metrics.js";
3
+ export interface GradedReport {
4
+ queries: GradedQueryScore[];
5
+ aggregate: GradedAggregate;
6
+ }
7
+ export interface BenchReport {
8
+ invariants: InvariantResult[];
9
+ graded: GradedReport;
10
+ invariantsPassed: number;
11
+ invariantsTotal: number;
12
+ quick: boolean;
13
+ ok: boolean;
14
+ durationMs: number;
15
+ }
16
+ export interface RunBenchOptions {
17
+ quick?: boolean;
18
+ }
19
+ export declare function runBench(opts?: RunBenchOptions): Promise<BenchReport>;
20
+ //# sourceMappingURL=run-bench.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-bench.d.ts","sourceRoot":"","sources":["../../src/bench/run-bench.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAmC,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,SAAS,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,MAAM,EAAE,YAAY,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IAExB,KAAK,EAAE,OAAO,CAAC;IASf,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAOD,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAmCD,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,WAAW,CAAC,CAgB/E"}
@@ -0,0 +1,86 @@
1
+ /*
2
+ * Copyright 2026 MARLINK TRADING SRL (YounndAI)
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ // Lane V Workstream 2 — `lyt bench` orchestrator.
17
+ //
18
+ // Runs two phases, each in its OWN isolated temp pod (so the invariant corpus
19
+ // and the graded corpus never cross-contaminate each other's queries):
20
+ // D-core — pass/fail retrieval invariants (the regression canary)
21
+ // E-lite — a planted-relevance graded score (nDCG/recall/MRR/P@1 + cleanliness)
22
+ // Metrics-only output — no user content, by construction (synthetic corpora).
23
+ // `--quick` runs only the D-core invariants (the every-CI fast path).
24
+ import { gradedCorpus, GRADED_QUERIES } from "./graded-corpus.js";
25
+ import { INVARIANT_CORPUS, runInvariants } from "./invariant-corpus.js";
26
+ import { aggregateGraded, scoreGradedQuery, } from "./ir-metrics.js";
27
+ import { setupBenchPod } from "./pod-harness.js";
28
+ const EMPTY_GRADED = {
29
+ queries: [],
30
+ aggregate: { queries: 0, ndcg: 0, recall: 0, mrr: 0, pAt1: 0, cleanliness: 0 },
31
+ };
32
+ async function runInvariantPhase() {
33
+ const pod = setupBenchPod();
34
+ try {
35
+ for (const seed of INVARIANT_CORPUS)
36
+ await pod.seedVault(seed.vault, seed.notes);
37
+ for (const seed of INVARIANT_CORPUS)
38
+ await pod.reindex(seed.vault);
39
+ return await runInvariants(pod);
40
+ }
41
+ finally {
42
+ pod.teardown();
43
+ }
44
+ }
45
+ async function runGradedPhase() {
46
+ const pod = setupBenchPod();
47
+ try {
48
+ const seeds = gradedCorpus();
49
+ for (const seed of seeds)
50
+ await pod.seedVault(seed.vault, seed.notes);
51
+ for (const seed of seeds)
52
+ await pod.reindex(seed.vault);
53
+ const queries = [];
54
+ for (const q of GRADED_QUERIES) {
55
+ const res = await pod.search({
56
+ query: q.query,
57
+ scope: q.scope,
58
+ ...(q.scopeTarget !== undefined ? { scopeTarget: q.scopeTarget } : {}),
59
+ limit: 20,
60
+ });
61
+ queries.push(scoreGradedQuery(q, res.results));
62
+ }
63
+ return { queries, aggregate: aggregateGraded(queries) };
64
+ }
65
+ finally {
66
+ pod.teardown();
67
+ }
68
+ }
69
+ export async function runBench(opts = {}) {
70
+ const startedAt = Date.now();
71
+ const quick = opts.quick === true;
72
+ const invariants = await runInvariantPhase();
73
+ const graded = quick ? EMPTY_GRADED : await runGradedPhase();
74
+ const invariantsPassed = invariants.filter((i) => i.passed).length;
75
+ const ok = invariantsPassed === invariants.length && graded.aggregate.cleanliness === 0;
76
+ return {
77
+ invariants,
78
+ graded,
79
+ invariantsPassed,
80
+ invariantsTotal: invariants.length,
81
+ quick,
82
+ ok,
83
+ durationMs: Date.now() - startedAt,
84
+ };
85
+ }
86
+ //# sourceMappingURL=run-bench.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-bench.js","sourceRoot":"","sources":["../../src/bench/run-bench.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Command } from "commander";
2
+ export declare function resolveNoPushOpt(opts: {
3
+ push?: boolean;
4
+ noPush?: boolean;
5
+ }): boolean;
6
+ export declare function buildAutomatorRunSubcommand(): Command;
7
+ //# sourceMappingURL=cli-automator-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-automator-run.d.ts","sourceRoot":"","sources":["../src/cli-automator-run.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAEpF;AAED,wBAAgB,2BAA2B,IAAI,OAAO,CAyDrD"}
@@ -0,0 +1,80 @@
1
+ /*
2
+ * Copyright 2026 MARLINK TRADING SRL (YounndAI)
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ // `lyt automator run <rid|name>` subcommand (block-B Commit 7).
17
+ //
18
+ // Lives in the meta @younndai/lyt CLI because runFiveStep pulls in lyt-runner
19
+ // and lyt-runner depends on lyt-vault — registering `run` inside lyt-vault
20
+ // would create a circular dep. Mirrors the lyt-mesh subcommand-attach pattern
21
+ // at packages/lyt/src/cli.ts.
22
+ //
23
+ // Per Lock 0.3 (SAI-compatible — brief §Conventions L191), --json emits a
24
+ // deterministic JSON envelope so SAIs / Claude Code / Codex can consume the
25
+ // invocation result without screen-scraping.
26
+ import { Command } from "commander";
27
+ import { uuid7BytesToDashedString } from "@younndai/lyt-vault";
28
+ import { runAutomator } from "./automator-run.js";
29
+ // commander stores `--no-push` as push:false (negated-flag convention); the
30
+ // noPush key is only set by test harnesses invoking the action directly.
31
+ // Track C Wave 3 F9: reading only opts.noPush dropped the CLI flag entirely
32
+ // and the run pushed. Exported so the regression test locks the mapping.
33
+ export function resolveNoPushOpt(opts) {
34
+ return opts.push === false || opts.noPush === true;
35
+ }
36
+ export function buildAutomatorRunSubcommand() {
37
+ return new Command("run")
38
+ .description("Run a declared automator end-to-end (5-step protocol: lease → sync → body → commit → release).")
39
+ .argument("<automator>", "Automator name or rid (e.g. 'metadata-filler' or 'automator:metadata-filler')")
40
+ .option("--vault <name>", "Vault name to run against; required when more than one vault is registered")
41
+ .option("--dry-run", "Skip lease acquisition + git pull/push (still invokes the body for inspection)")
42
+ .option("--no-push", "Run the commit step but skip `git push` (still commits locally)")
43
+ .option("--json", "Emit JSON instead of human-readable output")
44
+ .action(async (automator, opts) => {
45
+ const noPush = resolveNoPushOpt(opts);
46
+ const result = await runAutomator({
47
+ automator,
48
+ ...(opts.vault !== undefined ? { vault: opts.vault } : {}),
49
+ ...(opts.dryRun === true ? { dryRun: true } : {}),
50
+ ...(noPush ? { noPush: true } : {}),
51
+ });
52
+ const payload = {
53
+ ok: result.ok,
54
+ automator: result.plan.automatorName,
55
+ automator_version: result.automatorVersion,
56
+ run_id_hex: uuid7BytesToDashedString(result.runId).replace(/-/g, ""),
57
+ vault: {
58
+ name: result.plan.vaultName,
59
+ path: result.plan.vaultPath,
60
+ },
61
+ status: result.status,
62
+ error_summary: result.errorSummary,
63
+ dry_run: opts.dryRun === true,
64
+ no_push: noPush,
65
+ body: result.body ?? null,
66
+ };
67
+ if (opts.json === true) {
68
+ // eslint-disable-next-line no-console
69
+ console.log(JSON.stringify(payload, null, 2));
70
+ }
71
+ else {
72
+ // eslint-disable-next-line no-console
73
+ console.log(`${result.ok ? "✓" : "✗"} automator:${payload.automator} ` +
74
+ `→ status=${payload.status}${payload.error_summary !== null ? ` (${payload.error_summary})` : ""}`);
75
+ }
76
+ if (!result.ok)
77
+ process.exit(1);
78
+ });
79
+ }
80
+ //# sourceMappingURL=cli-automator-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-automator-run.js","sourceRoot":"","sources":["../src/cli-automator-run.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env node
2
+ /*
3
+ * Copyright 2026 MARLINK TRADING SRL (YounndAI)
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { createRequire } from "node:module";
18
+ import { Command } from "commander";
19
+ import { buildMcpSubcommand } from "@younndai/lyt-mcp";
20
+ import { buildCloneAllCommand, buildPodStatusCommand, buildSourceCommand, buildStatusCommand, buildSyncCommand, } from "@younndai/lyt-mesh";
21
+ import { buildSkillsCommand } from "@younndai/lyt-skills";
22
+ import { registerVaultVerbs } from "@younndai/lyt-vault";
23
+ import { buildAgentManualCommand, buildDiscoverCommand, buildRepairCommand, } from "@younndai/lyt-vault";
24
+ import { buildAutomatorRunSubcommand } from "./cli-automator-run.js";
25
+ import { buildBenchCommand } from "./commands/bench.js";
26
+ import { buildCaptureCommand } from "./commands/capture.js";
27
+ import { buildLytInitCommand } from "./commands/init.js";
28
+ import { buildPrimerCommand } from "./commands/primer.js";
29
+ import { buildReindexCommand } from "./commands/reindex.js";
30
+ import { buildSearchCommand } from "./commands/search.js";
31
+ const program = new Command();
32
+ program
33
+ .name("lyt")
34
+ .description("Lyt — federated markdown-vault mesh CLI (vault + mesh + sync + mcp + help + doctor + pattern + machine + identity + audit + friction + provenance + capture-metric + automator)")
35
+ .version(createRequire(import.meta.url)("../package.json").version);
36
+ // release review + block-A.3 Commit 11 — single source of truth for
37
+ // the @younndai/lyt-vault verb surface; sync / mcp are kept here because
38
+ // they live in separate workspaces.
39
+ //
40
+ // v1.B.1 delta: the meta CLI used to compose @younndai/lyt-mesh's
41
+ // `buildMeshSubcommand()` directly, but that registers a `mesh` parent
42
+ // that now collides with @younndai/lyt-vault's new v1.B.1 mesh command
43
+ // (init/join/list). Resolution: registerVaultVerbs registers the v1.B.1
44
+ // mesh parent (the canonical surface per master plan §5 v1.B.1); the
45
+ // surviving lyt-mesh subcommands (clone-all, source, status) are
46
+ // attached AFTER. The legacy lyt-mesh `init` subcommand (manifest-
47
+ // driven Phase 7D) is intentionally NOT re-attached — the v1.B.1 multi-
48
+ // mesh `mesh init <name>` supersedes it per master plan §5 (manifest-
49
+ // driven bulk init moves to v1.B.3).
50
+ //
51
+ // v1.C.1 delta: the legacy lyt-mesh `validate` subcommand (parent_vault
52
+ // FK dangling-check) is ALSO intentionally NOT re-attached — the v1.C.1
53
+ // `lyt mesh validate` (cross-mesh @MESH_EDGE walker, registered by
54
+ // registerVaultVerbs via commands/mesh.ts) supersedes it per master plan
55
+ // §v1.C.1:609 acceptance "lyt mesh validate warns on broken edges". The
56
+ // legacy parent_vault FK check is now repaired by v1.C.4 `lyt repair`
57
+ // per master plan §G-5:277 (validate = read-only / repair = write
58
+ // boundary). Same pattern as the v1.B.1 mesh-init supersession above.
59
+ // v1.C.4 ships `lyt repair` at the meta-CLI top level (federation-design
60
+ // §6:250 lists it next to `lyt init` + `lyt discover`).
61
+ //
62
+ // block-B Commit 7 delta: same composition shape applies to `automator`.
63
+ // registerVaultVerbs registers the v1 automator parent with list/log/status
64
+ // subcommands (lyt-vault has no lyt-runner dep). The meta CLI attaches `run`
65
+ // here, because runFiveStep + the metadata-filler body live in packages that
66
+ // depend on lyt-vault — registering them inside lyt-vault would create a
67
+ // cycle. Mirror of the lyt-mesh subcommand attach pattern above.
68
+ registerVaultVerbs(program);
69
+ const meshCmd = program.commands.find((c) => c.name() === "mesh");
70
+ if (meshCmd === undefined) {
71
+ throw new Error("@younndai/lyt meta CLI: expected registerVaultVerbs to register a 'mesh' command but none was found.");
72
+ }
73
+ meshCmd.addCommand(buildCloneAllCommand());
74
+ meshCmd.addCommand(buildSourceCommand());
75
+ meshCmd.addCommand(buildStatusCommand());
76
+ const automatorCmd = program.commands.find((c) => c.name() === "automator");
77
+ if (automatorCmd === undefined) {
78
+ throw new Error("@younndai/lyt meta CLI: expected registerVaultVerbs to register an 'automator' command but none was found.");
79
+ }
80
+ automatorCmd.addCommand(buildAutomatorRunSubcommand());
81
+ program.addCommand(buildSyncCommand());
82
+ // Brief B (B.4) — `lyt status`: top-level publish-drift trust surface (per-vault
83
+ // + pod unpushed/no-remote/clean). Distinct from `lyt mesh status` (the
84
+ // mesh-graph renderer attached under `mesh` above): different scope, different
85
+ // answer ("is my stuff published?" vs "what's the federation topology?").
86
+ program.addCommand(buildPodStatusCommand());
87
+ program.addCommand(buildMcpSubcommand());
88
+ // v1.D.3b — `lyt search` lives at the meta-CLI level per master-plan
89
+ // §v1.D.3:785 wording "lyt search" (no `vault` subcommand). The
90
+ // default scope is federation; placing it under `vault` would tilt
91
+ // user mental model toward single-vault use. The cascade engine
92
+ // itself lives in @younndai/lyt-vault (data-layer ownership); the
93
+ // command builder here is the CLI-surface adapter.
94
+ program.addCommand(buildSearchCommand());
95
+ // V-C-1 Phase E / V-C-2 — `lyt capture "<text>"`: the frictionless top-level
96
+ // alias for `pattern run knowledge-capture capture` the wizard advertises.
97
+ // True alias (same ceremony: mandatory purpose+topic, 8-field contract) +
98
+ // index-on-write so a capture is searchable immediately. Top-level like
99
+ // search/primer/reindex; the flow lives in @younndai/lyt-vault.
100
+ program.addCommand(buildCaptureCommand());
101
+ // v1.D.4 — `lyt primer` mirrors the meta-CLI posture of `lyt search`.
102
+ // Same rationale: the verb operates at vault | mesh | federation scope
103
+ // per master-plan §v1.D.4:832; placing it under `vault` would tilt
104
+ // mental model. The generator flow lives in @younndai/lyt-vault; the
105
+ // command builder here is the CLI-surface adapter.
106
+ program.addCommand(buildPrimerCommand());
107
+ // Lane V Phase 0 (0.5 / CLI gaps C1+C2) — `lyt reindex [--all|--mesh|--vault]`
108
+ // rebuilds all content-tier caches (lanes+arcs+fts+rollup) across the pod, a
109
+ // mesh, or one vault. Top-level (like search/primer) because its mental model
110
+ // is pod-wide. The reindexFlow lives in @younndai/lyt-vault (data-layer
111
+ // ownership); this is the CLI-surface adapter.
112
+ program.addCommand(buildReindexCommand());
113
+ // Lane V Workstream 2 — `lyt bench`: privacy-trivial retrieval self-test over a
114
+ // synthetic temp pod (never the user's ~/lyt). Top-level like search/primer/
115
+ // reindex. The harness lives in ./bench (productized from tools/lane-v, which is
116
+ // dev-only and not shipped); this is the CLI-surface adapter.
117
+ program.addCommand(buildBenchCommand());
118
+ // v1.B.4 — `lyt init` lives at the meta-CLI top level per OD-1 default +
119
+ // master-plan §v1.B.4:543 + federation-design §5:248. Composes
120
+ // meshInitFlow + federationInitFlow into idempotent bootstrap with
121
+ // three branches (fresh / re-init / discovery) + `--auto` default.
122
+ program.addCommand(buildLytInitCommand());
123
+ // v1.C.3 — `lyt discover` lives at the meta-CLI top level per OD-1 default +
124
+ // federation-design §6:249 (lists `lyt discover` next to `lyt init`).
125
+ // Read-only walk of GH-accessible repos; clusters discovered Lyt vaults
126
+ // by @VAULT_HOME_MESH.mesh_name; per-cluster orphan-recovery prompt
127
+ // (adopt / external / skip) ships in Commit 3. Mirror lyt search / lyt
128
+ // primer / lyt init top-level attach pattern.
129
+ program.addCommand(buildDiscoverCommand());
130
+ // v1.C.4 — `lyt repair` lives at the meta-CLI top level per OD-1 default +
131
+ // federation-design §6:250 (lists `lyt repair` next to `lyt init` +
132
+ // `lyt discover`). Default mode is --dry-run; --apply performs writes
133
+ // across the 4 federation-design §11:515-521 failure classes (broken
134
+ // @MESH_EDGE, broken @MESH_SUBSCRIPTION, mesh.yon parse error → restore
135
+ // from Git, orphan vault re-attach). G-5 contract LOCK: this is the
136
+ // write side of validate = read-only / repair = write per master-plan
137
+ // §G-5:277.
138
+ program.addCommand(buildRepairCommand());
139
+ // v1.F.3 — `lyt skills` lives at the meta-CLI top level per OD-2 default +
140
+ // master-plan §v1.F.3:1033 verb wording ("lyt skills install"). Composes
141
+ // symlinkSkillsTriRuntime + listSkillsTriRuntime into the symlink + runtime-
142
+ // state-reporting surface for the 10 bundled skills across ~/.claude/skills,
143
+ // ~/.codex/skills, ~/.agents/skills. Per OD-5 + OD-16 ratified 2026-06-01,
144
+ // the legacy standalone `lyt-skills` bin + copy-based `installSkills` flow
145
+ // were removed in the same phase (pre-release clean slate).
146
+ program.addCommand(buildSkillsCommand());
147
+ // v1.G.5 — `lyt agent-manual --runtime {claude|codex|agents|generic}
148
+ // [--install] [--dry-run]` at the meta-CLI top level. Mirrors the
149
+ // discover / repair / skills attach pattern above. Generates the Lyt
150
+ // agent manual (~150 lines / ~1.5K tokens) and writes it (or previews
151
+ // it) into agent-runtime global instructions files via the
152
+ // `<!-- lyt-manual v<lyt-version> BEGIN -->...END -->` marker pattern
153
+ // (D9 update-path primitive per the ratified default ratified 2026-06-01).
154
+ program.addCommand(buildAgentManualCommand());
155
+ program.parseAsync(process.argv).catch((err) => {
156
+ const message = err instanceof Error ? err.message : String(err);
157
+ // eslint-disable-next-line no-console
158
+ console.error(`lyt: ${message}`);
159
+ process.exit(1);
160
+ });
161
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function buildBenchCommand(): Command;
3
+ //# sourceMappingURL=bench.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bench.d.ts","sourceRoot":"","sources":["../../src/commands/bench.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,wBAAgB,iBAAiB,IAAI,OAAO,CAsF3C"}
@@ -0,0 +1,92 @@
1
+ /*
2
+ * Copyright 2026 MARLINK TRADING SRL (YounndAI)
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { Command } from "commander";
17
+ import { DEFAULT_LATENCY_COUNT, runLatencyBench } from "../bench/latency-bench.js";
18
+ import { runBench } from "../bench/run-bench.js";
19
+ // Lane V Workstream 2 — `lyt bench`: a privacy-trivial retrieval self-test.
20
+ // Stands up TEMP throwaway pods under os.tmpdir (never the user's ~/lyt), seeds
21
+ // tiny deterministic synthetic corpora, indexes them, and reports:
22
+ // • (default) D-core invariants + E-lite graded quality
23
+ // • --quick invariants only (the fast every-CI path)
24
+ // • --latency index + query p50/p95 on a synthetic corpus (--count to scale)
25
+ // No user content is read, by construction — safe to run anywhere.
26
+ export function buildBenchCommand() {
27
+ return new Command("bench")
28
+ .description("Self-test Lyt's retrieval engine against synthetic corpora (privacy-trivial — reads no user content). Asserts the retrieval invariants and reports a graded quality score; exits non-zero if an invariant or hygiene trap regressed.")
29
+ .option("--json", "Emit a JSON report instead of the human-readable summary")
30
+ .option("--quick", "Run only the pass/fail invariants (skip the graded-quality phase — faster)")
31
+ .option("--latency", "Run the latency benchmark (index + query p50/p95) instead of the quality self-test")
32
+ .option("--count <n>", `Latency corpus size (default ${DEFAULT_LATENCY_COUNT}; use 5000+ for a federation-scale reading)`)
33
+ .action(async (opts) => {
34
+ try {
35
+ if (opts.latency === true) {
36
+ const parsed = opts.count !== undefined ? Number.parseInt(opts.count, 10) : undefined;
37
+ const report = await runLatencyBench(parsed !== undefined && Number.isFinite(parsed) ? { count: parsed } : {});
38
+ if (opts.json === true) {
39
+ // eslint-disable-next-line no-console
40
+ console.log(JSON.stringify(report, null, 2));
41
+ return;
42
+ }
43
+ // eslint-disable-next-line no-console
44
+ console.log([
45
+ `lyt bench --latency — synthetic corpus (${report.durationMs}ms)`,
46
+ ` index: ${report.indexMs}ms (${report.corpusSize} figments, all tiers)`,
47
+ ` query: p50 ${report.queryP50Ms}ms p95 ${report.queryP95Ms}ms mean ${report.queryMeanMs}ms (${report.querySamples} samples)`,
48
+ ].join("\n"));
49
+ return;
50
+ }
51
+ const report = await runBench({ quick: opts.quick === true });
52
+ if (opts.json === true) {
53
+ // eslint-disable-next-line no-console
54
+ console.log(JSON.stringify(report, null, 2));
55
+ if (!report.ok)
56
+ process.exitCode = 1;
57
+ return;
58
+ }
59
+ const lines = [
60
+ `lyt bench — retrieval self-test${report.quick ? " (quick)" : ""} (${report.durationMs}ms)`,
61
+ "",
62
+ `Invariants (${report.invariantsPassed}/${report.invariantsTotal} passed):`,
63
+ ];
64
+ for (const inv of report.invariants) {
65
+ lines.push(` ${inv.passed ? "✓" : "✗"} ${inv.id} ${inv.name}`);
66
+ if (!inv.passed)
67
+ lines.push(` ${inv.detail}`);
68
+ }
69
+ if (!report.quick) {
70
+ const g = report.graded.aggregate;
71
+ lines.push("", `Quality (synthetic graded oracle, ${g.queries} queries):`, ` nDCG@10 ${g.ndcg} recall ${g.recall} MRR ${g.mrr} P@1 ${g.pAt1} cleanliness ${g.cleanliness}`);
72
+ for (const q of report.graded.queries) {
73
+ lines.push(` ${q.id.padEnd(14)} nDCG ${q.ndcg} recall ${q.recall} MRR ${q.mrr}`);
74
+ }
75
+ lines.push(" (nDCG < 1.0 is expected — Q-replica is a deliberate non-aced case: raw BM25 ≠ graded relevance, the known v2 rank-fusion residual.)");
76
+ }
77
+ lines.push("", report.ok
78
+ ? "PASS — invariants hold and no hygiene trap leaked."
79
+ : "FAIL — an invariant or hygiene trap regressed.");
80
+ // eslint-disable-next-line no-console
81
+ console.log(lines.join("\n"));
82
+ if (!report.ok)
83
+ process.exitCode = 1;
84
+ }
85
+ catch (err) {
86
+ // eslint-disable-next-line no-console
87
+ console.error(`lyt bench: ${err instanceof Error ? err.message : String(err)}`);
88
+ process.exitCode = 2;
89
+ }
90
+ });
91
+ }
92
+ //# sourceMappingURL=bench.js.map