@younndai/lyt-skills 0.9.7 → 0.9.9
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/package.json +2 -2
- package/skills/lyt-capture/SKILL.md +12 -2
- package/skills/lyt-mesh-explore/SKILL.md +3 -1
- package/skills/lyt-pod/SKILL.md +3 -0
- package/skills/lyt-primer-context/SKILL.md +2 -0
- package/skills/lyt-recall/SKILL.md +79 -55
- package/skills/lyt-search/SKILL.md +50 -4
- package/skills/lyt-sync/SKILL.md +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@younndai/lyt-skills",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.9",
|
|
4
4
|
"description": "Lyt harness skills — 16 skills (/lyt-plan, /lyt-progress, /lyt-result, /lyt-retro, /lyt-insight, /lyt-handoff, /lyt-decision, /lyt-pattern, /lyt-capture, /lyt-recall, /lyt-pod, /lyt-mesh-explore, /lyt-primer-context, /lyt-search, /lyt-sync, /lyt-alias) symlinked tri-runtime into ~/.claude/skills/, ~/.codex/skills/, ~/.agents/skills/. Composed into the `lyt skills install` and `lyt skills list` meta-CLI verbs.",
|
|
5
5
|
"homepage": "https://linkyourthink.com",
|
|
6
6
|
"repository": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"prepublishOnly": "node ../../scripts/check-no-vendored-deps.mjs --root ../.. && node ../../scripts/public-release/scan-tarball.mjs lyt-skills"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@younndai/lyt-vault": "^0.9.
|
|
52
|
+
"@younndai/lyt-vault": "^0.9.9",
|
|
53
53
|
"commander": "^12.1.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
@@ -27,6 +27,16 @@ When the user runs `/lyt-capture`, or says something like:
|
|
|
27
27
|
|
|
28
28
|
If the user pastes content and only says "save it," interpret as `/lyt-capture` on the pasted content.
|
|
29
29
|
|
|
30
|
+
## When NOT to invoke
|
|
31
|
+
|
|
32
|
+
`/lyt-capture` writes a **plain Figment note** — not a work-management artifact. When the durable thing is a structured type, defer to the dedicated skill (each writes the same 8-field ceremony to its own home, with type-specific framing):
|
|
33
|
+
|
|
34
|
+
- A distilled, durable **project lesson** ("this is an insight", "lesson learned about Lyt") → `/lyt-insight`.
|
|
35
|
+
- A locked **decision** ("lock this decision", "record the decision") → `/lyt-decision`.
|
|
36
|
+
- A **plan / progress / result / retro / handoff** → the matching `/lyt-plan` · `/lyt-progress` · `/lyt-result` · `/lyt-retro` · `/lyt-handoff`.
|
|
37
|
+
|
|
38
|
+
Use `/lyt-capture` only for a free-form note that doesn't fit one of those work-management types. When in doubt between a plain note and a typed artifact, prefer the typed skill — it carries the right frontmatter and lands in the right folder.
|
|
39
|
+
|
|
30
40
|
## Phase 1 — Resolve the target vault
|
|
31
41
|
|
|
32
42
|
Follow this chain, in order, and stop at the first success:
|
|
@@ -103,7 +113,7 @@ e.g. `lyt capture --index-only notes/2026-06-10-my-note.md --vault personal/main
|
|
|
103
113
|
|
|
104
114
|
> Captured to `<relative-path-from-vault-root>` in `<vault-path>`.
|
|
105
115
|
|
|
106
|
-
4. Do **not** run any git operations.
|
|
116
|
+
4. Do **not** run any git operations. Capture writes the file only — it does NOT git. Sync is a separate step: `/lyt-sync` (or the `lyt sync --watch` foreground daemon, which auto-commits watched vaults) handles commits.
|
|
107
117
|
|
|
108
118
|
## Rules
|
|
109
119
|
|
|
@@ -113,7 +123,7 @@ e.g. `lyt capture --index-only notes/2026-06-10-my-note.md --vault personal/main
|
|
|
113
123
|
- **User Figments are plain Obsidian-flavored markdown.** Wikilinks (`[[other-note]]`), tags (`#tag`), callouts, embeds — all fine. **Do NOT write YON inside user Figments.** YON is reserved for system files (`.lyt/vault.yon`, `.lyt/memscope.yon`, pattern.yon).
|
|
114
124
|
- **Never overwrite an existing Figment.** Always pick a fresh slug suffix.
|
|
115
125
|
- **Never touch files outside `<vault>/notes/`** unless the user explicitly says so.
|
|
116
|
-
- **Never run `git add`/`git commit`** — sync is a
|
|
126
|
+
- **Never run `git add`/`git commit`** — sync is a separate step (`/lyt-sync` or `lyt sync --watch`).
|
|
117
127
|
- If the user's content references other Figments by name, use `[[wikilinks]]` so Obsidian resolves them; don't expand them yourself.
|
|
118
128
|
|
|
119
129
|
## Direct CLI path (when no content yet)
|
|
@@ -35,6 +35,8 @@ When the user runs `/lyt-mesh-explore <mesh>`, or says something like:
|
|
|
35
35
|
|
|
36
36
|
If the user wants a survey across _all_ their meshes (the pod-level view), prefer `/lyt-pod`. If the user wants to search content _inside_ the mesh's vaults, prefer `/lyt-search --mesh <name>`. This skill is the mesh-scoped drill-down between those two surfaces.
|
|
37
37
|
|
|
38
|
+
**Disambiguator vs `/lyt-primer-context`.** "**structure / metadata / what's IN** mesh `<name>`" (which vaults, rid, push target) → `/lyt-mesh-explore` (this skill — static mesh shape). "**state / active arcs / what's happening / lately** in mesh `<name>`" (recent activity, top keywords, in-progress arcs) → `/lyt-primer-context --scope mesh --target <name>` (dynamic priming context). The split is static-shape-vs-live-state: if the user asks what the mesh _contains_, route here; if they ask what's _going on_ in it, route to `/lyt-primer-context`.
|
|
39
|
+
|
|
38
40
|
## Phase 1 — Resolve mesh name from user signal
|
|
39
41
|
|
|
40
42
|
The CLI verb takes one required positional `<mesh>` (the mesh name). Pick by the user's wording:
|
|
@@ -135,7 +137,7 @@ Synthesis rules:
|
|
|
135
137
|
- **MUST pass `--json`** on every invocation. Human-readable output is not a contract this skill parses.
|
|
136
138
|
- **MUST resolve mesh names via `lyt mesh list --json` before passing them.** The canonical mesh-enumeration verb is `lyt mesh list`. Do not guess names.
|
|
137
139
|
- **MUST reject `--`-leading resolved mesh names** before passing them to the positional `<mesh>` argument (the flag-injection defense family).
|
|
138
|
-
- **MUST NOT cite `lyt mesh status
|
|
140
|
+
- **MUST NOT cite `lyt mesh status` for single-mesh inspection.** It DOES exist, but it renders the local mesh graph (vault list grouped by parent_vault subtrees), not one mesh's metadata. The canonical mesh-listing verb is `lyt mesh list`; the canonical single-mesh-inspection verb is `lyt mesh info` (this skill).
|
|
139
141
|
- **MUST NOT modify or write any vault file.** This is a read-only skill (`requires_writable_vault: false`). If the user wants the mesh overview persisted to a Figment, run `/lyt-capture` separately on the formatted output.
|
|
140
142
|
- **MUST NOT pass `--remote` by default.** LOCAL is the default; pass `--remote` only on explicit user signal ("without cloning", "from GitHub", "peek at the published mesh.yon", "remote").
|
|
141
143
|
- **MUST NOT invent edge or subscription bullets.** `lyt mesh info` does not emit them. For pod-wide subscription overview use `/lyt-pod`; for cross-mesh edges, inspect `.lyt/mesh.yon` directly (out of scope for this skill).
|
package/skills/lyt-pod/SKILL.md
CHANGED
|
@@ -37,6 +37,8 @@ Invoke this skill **proactively** as the first move whenever the user asks a pod
|
|
|
37
37
|
|
|
38
38
|
If the user wants to drill into a single mesh (vault list + edges for one mesh), prefer `/lyt-mesh-explore`. If the user wants per-vault writable status or agent priming, use `/lyt-primer-context`.
|
|
39
39
|
|
|
40
|
+
**Disambiguator vs `/lyt-search`.** A bare **inventory** request ("what's in my pod", "list my vaults", "what meshes do I have") → `/lyt-pod` (this skill — enumerates the pod's structure). A **content query with a topic** ("what's in my pod **about X**", "...about `<topic>`", "find anything on `<topic>`") → `/lyt-search` (queries figment content across the pod). The split is structure-vs-content: if the user names a subject they want found, route to `/lyt-search`, not here.
|
|
41
|
+
|
|
40
42
|
## Phase 1 — Determine pod-scope intent
|
|
41
43
|
|
|
42
44
|
The default is **full pod overview** — both verbs run, every mesh and vault rendered. Pick by the user's wording:
|
|
@@ -130,6 +132,7 @@ The CLI emits stable, deterministically key-ordered JSON on stdout:
|
|
|
130
132
|
"verifyFailCount": 0
|
|
131
133
|
}
|
|
132
134
|
],
|
|
135
|
+
"displayNames": { "<ridHex>": "<mesh>/<vault>" }, // ridHex → canonical qualified display name
|
|
133
136
|
"rollupTombstones": { ... }, // only when --include-tombstones is passed
|
|
134
137
|
"rollupThresholdDays": <int>, // only when --include-tombstones is passed
|
|
135
138
|
"rollupThresholdIso": "<iso>" // only when --include-tombstones is passed
|
|
@@ -32,6 +32,8 @@ When the user runs `/lyt-primer-context`, or says something like:
|
|
|
32
32
|
|
|
33
33
|
Invoke this skill **proactively** before a knowledge-work task whenever the agent needs scope-wide situational awareness (recent activity, dominant themes, in-progress arcs). Don't bypass it and start fabricating context.
|
|
34
34
|
|
|
35
|
+
**Disambiguator vs `/lyt-mesh-explore`** (mesh-scope only). "**state / active arcs / what's happening / lately** in mesh `<name>`" (recent activity, top keywords, in-progress arcs) → `/lyt-primer-context --scope mesh --target <name>` (this skill — dynamic live state). "**structure / metadata / what's IN** mesh `<name>`" (which vaults, rid, push target) → `/lyt-mesh-explore` (static mesh shape). The split is live-state-vs-static-shape: if the user asks what's _going on_ in the mesh, route here; if they ask what the mesh _contains_, route to `/lyt-mesh-explore`.
|
|
36
|
+
|
|
35
37
|
## Phase 1 — Determine scope + target from user signal
|
|
36
38
|
|
|
37
39
|
The `lyt primer` verb requires `--scope` and rejects ambiguity. Pick by the user's wording (default is federation when no scope signal):
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lyt-recall
|
|
3
3
|
description: >
|
|
4
|
-
Search a Lyt vault
|
|
4
|
+
Search a SINGLE Lyt vault using the tiered-cascade engine (`lyt search --vault`) — Tier 0 arcs (0.95) → Tier 1 lanes (0.90) → Tier 2 FTS5 (0.70) (single-vault scope skips Tier 3 edges), with confidence ranking. Trigger when the user runs /lyt-recall <query>, or asks "what did I write about X", "find my notes on X", "recall X from my vault", "remind me what my <topic> notes say", "have I captured anything about X", or similar single-vault recall phrasing. Wraps `lyt search "<query>" --vault <name> --json`. Returns ranked Figments with path, snippet, and confidence. For a pod-wide search across every vault/mesh, use /lyt-search instead. Companion to lyt-capture.
|
|
5
5
|
visibility: public
|
|
6
|
-
lyt-version: 0.
|
|
6
|
+
lyt-version: 0.9.8
|
|
7
7
|
capabilities: [search]
|
|
8
8
|
runtimes: [claude, codex, agents]
|
|
9
9
|
requires_writable_vault: false
|
|
@@ -11,88 +11,112 @@ requires_writable_vault: false
|
|
|
11
11
|
|
|
12
12
|
# /lyt-recall
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Recall content from a **single** Lyt vault using the tiered-cascade search engine. The skill is a thin LLM-driven wrapper around the `lyt search` CLI verb with `--vault` scope; the heavy lifting — arc/lane/FTS5/edge cascade, confidence scoring, deterministic JSON — already lives in the CLI. The skill resolves which one vault to search, invokes `lyt search "<query>" --vault <name> --json`, parses the stable output, and presents ranked results.
|
|
15
|
+
|
|
16
|
+
`/lyt-recall` is the **single-vault** member of the search pair; `/lyt-search` is the **pod-wide** member (federation/mesh/vault scope). They share one engine — recall just always pins `--vault`.
|
|
17
|
+
|
|
18
|
+
> **Do NOT use filesystem search.** Never answer a recall with the `Grep`/`rg`/`find`/`Get-ChildItem` tools, or by walking the vault directory yourself. The vault's libSQL FTS5 index (whole-vault since 0.9.7, not just `notes/`) is the source of truth, and `lyt search` is the only sanctioned access path. Filesystem grep bypasses the engine's ranking, tier provenance, and confidence scoring, and misses index-only signal. Read a specific file directly ONLY after `lyt search` has returned it as a hit (to quote it in full), or when the user gives an explicit path.
|
|
15
19
|
|
|
16
20
|
## When to invoke
|
|
17
21
|
|
|
18
22
|
When the user runs `/lyt-recall <query>`, or says something like:
|
|
19
23
|
|
|
20
|
-
- "what did I write about <topic>"
|
|
24
|
+
- "what did I write about <topic>" — _single-vault case; if the user's pod has multiple vaults and they want all of them, prefer `/lyt-search`_
|
|
21
25
|
- "find my notes on <topic>"
|
|
22
26
|
- "recall <topic> from my vault"
|
|
23
|
-
- "
|
|
27
|
+
- "remind me what my <topic> notes say"
|
|
24
28
|
- "have I captured anything about <topic>"
|
|
25
29
|
|
|
26
|
-
If the user
|
|
30
|
+
If the user's question depends on prior captured knowledge, invoke this skill proactively — don't fabricate; check the vault first.
|
|
27
31
|
|
|
28
|
-
## Phase 1 — Resolve the target vault
|
|
32
|
+
## Phase 1 — Resolve the single target vault
|
|
29
33
|
|
|
30
|
-
|
|
34
|
+
Recall always searches exactly one vault. Resolve which one, in order:
|
|
31
35
|
|
|
32
|
-
1. `--vault <
|
|
33
|
-
2.
|
|
34
|
-
3. cwd-based detection via `lyt vault info --by-path <cwd
|
|
35
|
-
4.
|
|
36
|
+
1. **Explicit `--vault <name>` arg** the user supplied.
|
|
37
|
+
2. **`$LYT_ACTIVE_VAULT`** env var, if set.
|
|
38
|
+
3. **cwd-based detection** via `lyt vault info --by-path <cwd> --json` — if the cwd is inside a registered vault, use it.
|
|
39
|
+
4. **Sole vault** — run `lyt vault list --json`; if the pod has exactly one active vault, use it.
|
|
40
|
+
5. **Ambiguous** (multiple vaults, no signal) — surface the vault names from `lyt vault list --json` and ask which one, or suggest `/lyt-search` for a pod-wide search. Do NOT guess.
|
|
36
41
|
|
|
37
|
-
|
|
42
|
+
**Resolve + sanitize the name before passing it.** Match the user's term to a listed vault name (exact, then case-insensitive, then prefix). **Reject any resolved name that begins with `-` or `--`** before passing it to `--vault <name>` — closes the flag-injection surface (same defense as `/lyt-search` Phase 1 and `/lyt-sync` Phase 1). If no match, list the available names and stop — do not invent a name.
|
|
38
43
|
|
|
39
|
-
## Phase 2 —
|
|
44
|
+
## Phase 2 — Invoke the CLI verb
|
|
40
45
|
|
|
41
|
-
|
|
46
|
+
Run the verb via the Bash tool (or your runtime's shell equivalent). **Pass the query as a single quoted argv argument; never shell-compose the command** — the query CAN contain shell metacharacters (backticks, `$()`, `;`, `&&`), which MUST travel as one argv element, not template-interpolated into a shell string.
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
- `output_mode`: `content`
|
|
47
|
-
- `-i`: `true`
|
|
48
|
-
- `-n`: `true`
|
|
49
|
-
- `-C`: `2` (two lines of context around each match)
|
|
50
|
-
- `head_limit`: 30
|
|
48
|
+
```
|
|
49
|
+
# Shell-syntax (DOCUMENTATION ONLY — do NOT compose this as a string):
|
|
50
|
+
lyt search "<user-query>" --vault <name> --json [--limit <n>]
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
# Actual exec shape (argv array; cross-platform-safe):
|
|
53
|
+
spawnSync("lyt", ["search", userQuery, "--vault", vaultName, "--json"]);
|
|
54
|
+
```
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
56
|
+
Key rules:
|
|
57
|
+
|
|
58
|
+
- The first positional argument is the query — a single string. Multi-word queries are implicit AND. Quote it so the shell treats it as one argv element.
|
|
59
|
+
- `--vault <name>` is **mandatory for recall** (that is what makes this single-vault). Never run bare `lyt search` from this skill (that searches the whole pod — that's `/lyt-search`'s job).
|
|
60
|
+
- `--json` is **mandatory**. It yields the deterministic, stable key-ordered output parsed below.
|
|
61
|
+
- `--limit <n>` defaults to 20 (CLI default), capped at 1000. Apply a caller cap only on explicit signal ("top 5"); else rely on the default.
|
|
62
|
+
|
|
63
|
+
## Phase 3 — Parse the JSON output
|
|
64
|
+
|
|
65
|
+
The CLI emits stable, deterministically key-ordered JSON on stdout (exit 0 on success). Expected shape (scope = `vault`):
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"query": "<the query>",
|
|
70
|
+
"scope": "vault",
|
|
71
|
+
"scopeTarget": "<vault-name>",
|
|
72
|
+
"limit": 20,
|
|
73
|
+
"results": [
|
|
74
|
+
{
|
|
75
|
+
"confidence": 0.70,
|
|
76
|
+
"tier": 2,
|
|
77
|
+
"vault_name": "<vault>",
|
|
78
|
+
"mesh_name": "<mesh>",
|
|
79
|
+
"figment_path": "<relative/path.md>",
|
|
80
|
+
"snippet": "<snippet with <mark>…</mark> highlights>"
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"trace": { "tiersRun": [0, 1, 2], "perTierHitCount": [0, 0, 4, 0], "vaultsSearched": ["<vault>"] },
|
|
84
|
+
"durationMs": 41
|
|
85
|
+
}
|
|
86
|
+
```
|
|
58
87
|
|
|
59
|
-
|
|
88
|
+
Failure modes (CLI emits to stderr; exit non-zero):
|
|
60
89
|
|
|
61
|
-
|
|
90
|
+
- **Empty query** (exit 1) → `{ "error": "empty-query", "message": "..." }`. Surface verbatim; ask the user to refine.
|
|
91
|
+
- **Invalid limit** (exit 1) → `{ "error": "invalid-limit", ... }`. Re-invoke with the CLI default.
|
|
92
|
+
- **Cascade error** (exit 2) → `{ "error": "cascade-error", "message": "..." }`. Surface verbatim. Only if `lyt search` itself fails this way may you fall back to reading files directly — and you MUST label the answer as a fallback, not engine-ranked.
|
|
62
93
|
|
|
63
|
-
|
|
64
|
-
- **Title** — read the file's frontmatter `title:` if present; otherwise the filename slug
|
|
65
|
-
- **Snippet** — the matched line plus 1 line of context above/below
|
|
94
|
+
## Phase 4 — Present results
|
|
66
95
|
|
|
67
|
-
|
|
96
|
+
Order by descending confidence (the CLI emits them ranked). One line per result. Show each as `[<confidence>] <figment_path> — <snippet>`; strip the `<mark>…</mark>` tags or render them as emphasis; truncate snippets to ~80 characters.
|
|
68
97
|
|
|
69
|
-
Format
|
|
98
|
+
Format:
|
|
70
99
|
|
|
71
|
-
> **Found
|
|
100
|
+
> **Found N matches for `"<query>"` in `<vault-name>` (<durationMs>ms):**
|
|
72
101
|
>
|
|
73
|
-
>
|
|
74
|
-
>
|
|
75
|
-
> 2. **notes/2026-05-23-auth-decisions.md** — "Auth rewrite decisions"
|
|
76
|
-
> > ...moving to OAuth, deprecating session tokens by EOQ...
|
|
102
|
+
> - `[0.95]` `writing/publication-voice.md` — _…the voice inside it is mine. I write jazz…_
|
|
103
|
+
> - `[0.70]` `writing/voice-guides.md` — _…copy-paste prompts for authorship-voice and publication-voice…_
|
|
77
104
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
If the user wants the recall results saved (e.g., for inclusion in a `/lyt-plan` or `/lyt-result`), run:
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
lyt pattern run knowledge-capture recall --vault <vault> --slug <query-as-slug>
|
|
84
|
-
```
|
|
105
|
+
On **empty results**: surface _"No matches for `"<query>"` in `<vault-name>`."_ and offer to widen with `/lyt-search` (pod-wide) or try a broader term. If you expected a hit, the vault's FTS index may be stale — suggest rebuilding it with `lyt vault rebuild-index <vault-name>` (or `lyt reindex`), then re-running the recall.
|
|
85
106
|
|
|
86
|
-
|
|
107
|
+
To quote a hit in full, read the returned `figment_path` directly **after** the engine has surfaced it (that is sanctioned — it's reading a known source, not discovery-by-grep).
|
|
87
108
|
|
|
88
109
|
## Rules
|
|
89
110
|
|
|
90
|
-
- **
|
|
91
|
-
- **
|
|
92
|
-
- **
|
|
93
|
-
- **
|
|
94
|
-
-
|
|
111
|
+
- **MUST search via `lyt search "<query>" --vault <name> --json`.** MUST NOT discover content with `Grep`/`rg`/`find`/`Get-ChildItem` or by walking the vault tree. Filesystem grep is only an explicit, labeled fallback after a `cascade-error`.
|
|
112
|
+
- **MUST pass the query as a single quoted argv argument**, not interpolated into a shell string.
|
|
113
|
+
- **MUST pass `--vault <name>` and `--json`** on every invocation. Bare `lyt search` (pod-wide) is `/lyt-search`, not this skill.
|
|
114
|
+
- **MUST resolve + sanitize the vault name** via `lyt vault list --json`; reject any `--`-leading name; never guess a name.
|
|
115
|
+
- **MUST NOT widen scope silently.** If the named vault is missing, surface the miss and stop — do not fall back to a pod-wide search without the user.
|
|
116
|
+
- **MUST NOT modify or write any vault file.** Read-only (`requires_writable_vault: false`). To persist results to a Figment, run `/lyt-capture` on the formatted output.
|
|
117
|
+
- **MUST NOT re-interpret confidence tiers.** Display the CLI's confidence verbatim (`0.95 / 0.90 / 0.70` — the Tier-3 `0.50` only appears in pod/mesh scope, never single-vault); do not round or invent a derived score.
|
|
95
118
|
|
|
96
|
-
## Companion
|
|
119
|
+
## Companion skills
|
|
97
120
|
|
|
98
|
-
|
|
121
|
+
- **`/lyt-search`** — the pod-wide sibling (federation/mesh/vault scope) using the same cascade engine. Use it when the user wants every vault, a whole mesh, or hasn't pinned a single vault.
|
|
122
|
+
- **`/lyt-capture`** — write a Figment. Pair with `/lyt-recall` to persist what you found.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lyt-search
|
|
3
3
|
description: >
|
|
4
|
-
Search a Lyt pod (or a single mesh or vault) using the tiered-cascade engine — Tier 0 arcs (0.95) → Tier 1 lanes (0.90) → Tier 2 FTS5 (0.70) → Tier 3 edges (0.50) — with confidence ranking. Trigger when the user runs /lyt-search <query>, or says "search my pod for X", "find anything about X across my vaults", "search across all meshes for X", "what's in my pod about X", or similar phrasing on a query wider than a single vault. Wraps the `lyt search` CLI verb — federation scope by default; --vault / --mesh narrow scope; --limit caps results. Returns ranked Figments with vault, mesh, snippet, and confidence. Companion to lyt-recall (single-vault
|
|
4
|
+
Search a Lyt pod (or a single mesh or vault) using the tiered-cascade engine — Tier 0 arcs (0.95) → Tier 1 lanes (0.90) → Tier 2 FTS5 (0.70) → Tier 3 edges (0.50) — with confidence ranking. Trigger when the user runs /lyt-search <query>, or says "search my pod for X", "find anything about X across my vaults", "search across all meshes for X", "what's in my pod about X", or similar phrasing on a query wider than a single vault. Wraps the `lyt search` CLI verb — federation scope by default; --vault / --mesh narrow scope; --limit caps results. Returns ranked Figments with vault, mesh, snippet, and confidence. Companion to lyt-recall (single-vault scope) for narrower local searches.
|
|
5
5
|
visibility: public
|
|
6
6
|
lyt-version: 0.5.0
|
|
7
7
|
capabilities: [search]
|
|
@@ -21,12 +21,14 @@ When the user runs `/lyt-search <query>`, or says something like:
|
|
|
21
21
|
- "search across all my vaults for <topic>"
|
|
22
22
|
- "find anything about <topic>"
|
|
23
23
|
- "what's in my pod about <topic>"
|
|
24
|
-
- "what did I write about <topic>" — _if the user's pod has multiple vaults_; for
|
|
24
|
+
- "what did I write about <topic>" — _if the user's pod has multiple vaults_; for single-vault recall, prefer `/lyt-recall`
|
|
25
25
|
- "search the `<mesh-name>` mesh for <topic>"
|
|
26
26
|
- "search vault `<vault-name>` for <topic>"
|
|
27
27
|
|
|
28
28
|
If the user's question depends on prior captured knowledge across multiple vaults, invoke this skill proactively — don't fabricate; check the pod first.
|
|
29
29
|
|
|
30
|
+
**Disambiguator vs `/lyt-pod`.** A **content query with a topic** ("what's in my pod **about X**", "...about `<topic>`", "find anything on `<topic>`") → `/lyt-search` (this skill — queries figment content). A bare **inventory** request ("what's in my pod", "list my vaults", "what meshes do I have") → `/lyt-pod` (enumerates the pod's structure, no content query). The split is content-vs-structure: if the user names a subject they want found, this is the right skill; if they want a survey of what exists, route to `/lyt-pod`.
|
|
31
|
+
|
|
30
32
|
## Phase 1 — Determine scope from user signal
|
|
31
33
|
|
|
32
34
|
The CLI verb supports three mutually-exclusive scope flags; the default (no flag) is federation. Pick by the user's wording:
|
|
@@ -124,7 +126,49 @@ Format:
|
|
|
124
126
|
|
|
125
127
|
Show each result as `[<confidence>] <vault>/<figment_path> — <snippet>`. Truncate snippets to ~80 characters with an ellipsis. The top-of-output tier-hit summary uses the CLI's `trace.perTierHitCount` map (`{0:N, 1:M, 2:K, 3:L}`) so the handler sees confidence distribution at a glance.
|
|
126
128
|
|
|
127
|
-
On **empty results**: surface _"No matches for `"<query>"` across <scope>."_ and offer scope-widening hints (`--mesh` → federation; `--vault` → `--mesh`).
|
|
129
|
+
On **empty results**: surface _"No matches for `"<query>"` across <scope>."_ and offer scope-widening hints (`--mesh` → federation; `--vault` → `--mesh`). If a vault that should contain the figment still returns nothing, its FTS index may be stale — suggest rebuilding it with `lyt vault rebuild-index <name>` (or `lyt reindex` across the pod), then re-running the search.
|
|
130
|
+
|
|
131
|
+
## Phase 5 — Concept-search discovery nudge (only when `trace.nudge.eligible` is true)
|
|
132
|
+
|
|
133
|
+
The `--json` output may carry a `trace.nudge` block. It is the signal for a one-time offer to enable **concept search** — finding notes by meaning, not just keywords. Read it; only voice the offer when it explicitly says to.
|
|
134
|
+
|
|
135
|
+
```json
|
|
136
|
+
"trace": {
|
|
137
|
+
"nudge": {
|
|
138
|
+
"eligible": true,
|
|
139
|
+
"state": "not-yet-asked",
|
|
140
|
+
"reason": null,
|
|
141
|
+
"declines": 0,
|
|
142
|
+
"daysSince": null,
|
|
143
|
+
"searchesSince": 1
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
- **`eligible: true`** → voice the offer once (see below). A null `reason` confirms it.
|
|
149
|
+
- **`eligible: false`** → say nothing about it. The `reason` explains why (`model-present` = already set up; `disabled` = the user chose never to be asked; `auto-quiet` = declined enough times; `cadence` = asked recently). Never override an ineligible verdict.
|
|
150
|
+
- **`trace.nudge` absent** → nothing to do; proceed normally.
|
|
151
|
+
|
|
152
|
+
### Voicing the offer (only when eligible)
|
|
153
|
+
|
|
154
|
+
Relay it to the user in plain language, **framed as a benefit to them — never "to help improve Lyt"**:
|
|
155
|
+
|
|
156
|
+
> _"I can also search your notes by meaning, not just keywords. It needs a one-time local setup (nothing leaves your machine). Want me to set it up?"_
|
|
157
|
+
|
|
158
|
+
Then **capture an explicit yes or no** before doing anything else.
|
|
159
|
+
|
|
160
|
+
### Response-capture contract — map the reply to exactly one verb
|
|
161
|
+
|
|
162
|
+
| User reply | Do |
|
|
163
|
+
|---|---|
|
|
164
|
+
| **Yes** (set it up) | `lyt model fetch` — runs the one-time local setup and marks the offer resolved. |
|
|
165
|
+
| **No** (explicit decline) | `lyt model nudge --decline` — records ONE decline (three declines → auto-quiet). |
|
|
166
|
+
| **"Never ask again"** | `lyt model nudge --never` — turns the offer off permanently. |
|
|
167
|
+
| **Surfaced / bookkeeping only** | `lyt model nudge --asked` — records that the offer was shown (stamps the ask, resets the cadence counter) when you voiced it without yet capturing a yes/no. |
|
|
168
|
+
|
|
169
|
+
- **A non-response is NOT a decline.** If the user doesn't answer the offer, record nothing — do not run `nudge --decline`. Only an explicit "no" counts as a decline.
|
|
170
|
+
- **Inspect anytime** with `lyt model nudge --status` (read-only; prints the current offer-state).
|
|
171
|
+
- Honor a `disabled` / `auto-quiet` state — once the user has opted out, never re-raise the offer.
|
|
128
172
|
|
|
129
173
|
## Rules
|
|
130
174
|
|
|
@@ -133,12 +177,14 @@ On **empty results**: surface _"No matches for `"<query>"` across <scope>."_ and
|
|
|
133
177
|
- **MUST resolve mesh/vault names via `lyt vault list --json` or `lyt mesh list --json` before passing `--vault` or `--mesh`.** Do not guess names.
|
|
134
178
|
- **MUST NOT pass `--all` explicitly.** Federation is the default; `--all` is a redundant alias. Use no scope flag instead.
|
|
135
179
|
- **MUST NOT combine `--vault` and `--mesh`.** The CLI exits 1 with `conflicting-scope-flags`.
|
|
180
|
+
- **`--no-self-heal` is a no-op under `--json`** — the empty-result self-heal (reindex stale vaults + re-query on 0 hits) is auto-disabled whenever `--json` is set, so passing `--no-self-heal` alongside the mandatory `--json` changes nothing. (`--no-semantic`, which forces the pure lexical cascade, is NOT auto-disabled under `--json` — pass it explicitly if you need to suppress dense-embedding fusion.)
|
|
136
181
|
- **MUST NOT re-interpret confidence tiers.** The CLI emits them as `0.95 / 0.90 / 0.70 / 0.50` per Tier 0/1/2/3 spec. Display verbatim; do not "smooth" or "round" or invent a derived score.
|
|
137
182
|
- **MUST NOT modify or write any vault file.** This is a read-only skill (`requires_writable_vault: false`). If the user wants results persisted to a Figment, run `/lyt-capture` separately on the formatted output.
|
|
138
183
|
- **MUST NOT widen scope without user signal.** If the user said "in my work vault", do not silently fall back to federation when the named vault is missing — surface the miss and stop.
|
|
184
|
+
- **MUST voice the concept-search offer ONLY when `trace.nudge.eligible` is true**, and MUST capture an explicit yes/no before acting. A non-response records nothing — never run `lyt model nudge --decline` on silence. Honor a `disabled` / `auto-quiet` state and never re-raise.
|
|
139
185
|
|
|
140
186
|
## Companion skills
|
|
141
187
|
|
|
142
|
-
- **`/lyt-recall`** — single-vault
|
|
188
|
+
- **`/lyt-recall`** — single-vault recall. Use when the user has only one vault in mind; same tiered-cascade engine as `/lyt-search`, pinned to `--vault` scope.
|
|
143
189
|
- **`/lyt-sync`** — pull-then-push a vault. Run before `/lyt-search` if the user has unpushed local edits and wants the FTS5 index reflect them (the cascade reads the local vault's libSQL state).
|
|
144
190
|
- **`/lyt-capture`** — write a Figment. Pair with `/lyt-search` if the user wants the recall results persisted.
|
package/skills/lyt-sync/SKILL.md
CHANGED
|
@@ -26,6 +26,8 @@ When the user runs `/lyt-sync`, or says something like:
|
|
|
26
26
|
|
|
27
27
|
If the user says "save and sync" or "/lyt-capture then sync", run /lyt-capture first, then /lyt-sync on the destination vault.
|
|
28
28
|
|
|
29
|
+
**Pod-wide sync: the `lyt sync` verb.** This skill's per-vault git flow (below) is the documented default for a **single named vault**. When the user wants to **sync everything** ("sync all my vaults", "sync my whole pod", "sync everything"), there is a real pod-wide CLI verb: `lyt sync` (no vault argument) syncs all registered active vaults — commit + push + pull --rebase — and also runs the federation publish pass. `lyt sync --watch` is a foreground daemon that auto-commits watched vaults (event-driven). `lyt sync --check` reports per-vault freshness without writing. There is **no** `lyt sync --mesh` flag; mesh-scoped sync is not a current verb.
|
|
30
|
+
|
|
29
31
|
## Phase 1 — Resolve the target vault
|
|
30
32
|
|
|
31
33
|
Follow this chain, in order, and stop at the first success (mirrors /lyt-capture Phase 1):
|
|
@@ -111,7 +113,7 @@ The actual reason strings emitted by `vault info --json` are listed in the **emi
|
|
|
111
113
|
| `subscriber-default-false` | (subscriber) | `false` | Skip push. Report: _"Skipped push: this is a subscriber vault. Subscriber vaults pull but don't push. Capture into your home vault instead."_ |
|
|
112
114
|
| `gh-unavailable` | (gh-offline) | `"unknown"` | Skip push. Report: _"Skipped push: gh CLI is unavailable (offline / rate-limited / not authenticated). Re-try when network is available."_ |
|
|
113
115
|
| `no-remote` | (no-remote) | `"unknown"` | Skip push. Report: _"Skipped push: vault has no git remote configured. Configure a remote with `gh repo create` or `git remote add origin <url>`."_ |
|
|
114
|
-
| `orphan-vault` | (orphan) | `"unknown"` | Skip push. Report: _"Skipped push: vault has no mesh role (orphan).
|
|
116
|
+
| `orphan-vault` | (orphan) | `"unknown"` | Skip push. Report: _"Skipped push: vault has no mesh role (orphan). Re-attach it with `lyt repair --target <vault> --apply --mesh <mesh>` (the single-orphan-vault verb; `lyt mesh adopt --cluster` is for orphan-MESH clusters, not one vault)."_ |
|
|
115
117
|
|
|
116
118
|
**Note on emitted vs semantic names.** The semantic names `home-pushable-true` and `home-not-pushable-false` are documentation aliases for the actual emitted strings `gh-viewerCanPush-true` and `gh-viewerCanPush-false`, kept so future renames of the underlying enum don't silently break the skill prose. The 4 other reason strings (`subscriber-default-false`, `gh-unavailable`, `no-remote`, `orphan-vault`) are identical in both surfaces.
|
|
117
119
|
|
|
@@ -135,7 +137,7 @@ Final handler-facing result shape:
|
|
|
135
137
|
- **MUST gate push on `vault.writable` / `vault.writableDetermination`.** Never `git push` unless `writableDetermination === "gh-viewerCanPush-true"` (equivalently, `writable === true`). The other 5 reasons all skip push.
|
|
136
138
|
- **MUST branch on all 6 reasons.** Each has a distinct handler-facing message; collapsing them into a generic "can't push" message loses semantic signal the handler needs to recover.
|
|
137
139
|
- **MUST NOT add a `Co-Authored-By` trailer** to the auto-commit. Per the project's `CLAUDE.md` commit conventions, unless the user explicitly requests one.
|
|
138
|
-
- **MUST NOT touch any vault other than the resolved target.**
|
|
140
|
+
- **MUST NOT touch any vault other than the resolved target.** This skill's per-vault flow is single-vault. A pod-wide multi-vault sweep is the `lyt sync` verb (no vault argument — see "Pod-wide sync" above) or `mesh clone-all`, not this skill's per-vault path. There is no `lyt sync --mesh` flag.
|
|
139
141
|
- **MUST NOT modify `.lyt/vault.yon`, `.lyt/mesh.yon`, ledger YONs, or `@STAMP` blocks.** Those are runner / writer concerns; sync only commits handler-authored content as-is.
|
|
140
142
|
- **MUST NOT silently degrade `writable === "unknown"` to push.** Surface the reason to the handler.
|
|
141
143
|
|