deepvista-cli 0.1.2__tar.gz → 0.1.4__tar.gz
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.
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/PKG-INFO +38 -4
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/README.md +37 -3
- deepvista_cli-0.1.4/deepvista_cli/commands/lint.py +190 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/commands/notes.py +74 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/commands/skill.py +167 -1
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/main.py +2 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/install.sh +0 -1
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/pyproject.toml +1 -1
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/SKILL.md +12 -10
- deepvista_cli-0.1.4/skills/deepvista/reference/lint.md +107 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/notes.md +22 -0
- deepvista_cli-0.1.4/skills/deepvista/reference/skill-create-from-note.md +93 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/skill.md +13 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/uv.lock +1 -1
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/.github/workflows/ci.yml +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/.github/workflows/publish.yml +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/.gitignore +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/.pre-commit-config.yaml +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/CHANGELOG.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/CLAUDE.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/LICENSE +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/__init__.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/auth/__init__.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/auth/callback_server.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/auth/login.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/auth/tokens.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/client/__init__.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/client/http.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/client/origin.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/commands/__init__.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/commands/agents.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/commands/auth.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/commands/card.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/commands/chat.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/commands/config.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/commands/memory.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/commands/upgrade.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/commands/vistabase.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/commands/vistabook.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/config.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/output/__init__.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/output/formatter.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/tui/__init__.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/deepvista_cli/tui/app.py +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/docs/assets/deepvista-banner.png +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/hooks/deepvista-autocapture.sh +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/chat.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/memory.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/openclaw.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/persona-knowledge-worker.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/shared.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/skill-analyze-notes.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/skill-export-knowledge.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/skill-import-files.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/skill-research-to-skill.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/vistabase-card.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/vistabase.md +0 -0
- {deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/uninstall.sh +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepvista-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: CLI for DeepVista — chat, notes, skills, and memory from your terminal.
|
|
5
5
|
Project-URL: Homepage, https://deepvista.ai
|
|
6
6
|
Project-URL: Repository, https://github.com/DeepVista-AI/deepvista-cli
|
|
@@ -31,10 +31,12 @@ Description-Content-Type: text/markdown
|
|
|
31
31
|
<img src="https://raw.githubusercontent.com/DeepVista-AI/deepvista-cli/main/docs/assets/deepvista-banner.png" alt="DeepVista" width="600">
|
|
32
32
|
</p>
|
|
33
33
|
|
|
34
|
-
<h1 align="center">Your
|
|
34
|
+
<h1 align="center">Turn Your Agents into a Self-Evolving Team</h1>
|
|
35
35
|
|
|
36
36
|
<p align="center">
|
|
37
|
-
<strong>CLI
|
|
37
|
+
<strong>DeepVista CLI connects your coding agents to a shared knowledge base —<br>
|
|
38
|
+
so they don’t just execute, but learn, remember, and build on past work.
|
|
39
|
+
</strong>
|
|
38
40
|
</p>
|
|
39
41
|
|
|
40
42
|
<div align="center">
|
|
@@ -52,7 +54,7 @@ Description-Content-Type: text/markdown
|
|
|
52
54
|
<br>
|
|
53
55
|
|
|
54
56
|
<p align="center">
|
|
55
|
-
|
|
57
|
+
⭐ If this direction resonates, consider <b>starring the repo</b> — it helps more people discover it.
|
|
56
58
|
</p>
|
|
57
59
|
|
|
58
60
|
<br>
|
|
@@ -62,6 +64,27 @@ Description-Content-Type: text/markdown
|
|
|
62
64
|
|
|
63
65
|
---
|
|
64
66
|
|
|
67
|
+
## Who this is for
|
|
68
|
+
|
|
69
|
+
- Builders working with coding agents (Claude Code, Cursor, OpenCode)
|
|
70
|
+
- People experimenting with agent workflows and skills
|
|
71
|
+
- Anyone trying to turn scattered interactions into compounding knowledge
|
|
72
|
+
|
|
73
|
+
## What this enables
|
|
74
|
+
|
|
75
|
+
Modern coding agents are powerful — but each interaction is stateless and isolated.
|
|
76
|
+
|
|
77
|
+
DeepVista changes that.
|
|
78
|
+
|
|
79
|
+
- Agents **remember** past work
|
|
80
|
+
- Agents **share context** through a common knowledge base
|
|
81
|
+
- Agents **build on previous decisions and insights**
|
|
82
|
+
|
|
83
|
+
Over time, this turns isolated executions into a:
|
|
84
|
+
|
|
85
|
+
→ **a self-evolving team of agents that compound knowledge over time**
|
|
86
|
+
|
|
87
|
+
|
|
65
88
|
## Why DeepVista CLI?
|
|
66
89
|
|
|
67
90
|
Most knowledge tools trap your data in a GUI. DeepVista CLI gives you **full access to your knowledge base from the terminal** — and lets your AI agents use it too.
|
|
@@ -73,6 +96,17 @@ Most knowledge tools trap your data in a GUI. DeepVista CLI gives you **full acc
|
|
|
73
96
|
- 💬 **Chat** — talk to the DeepVista AI agent in your terminal
|
|
74
97
|
- 🖥️ **Full TUI** — four-panel terminal UI for chat, notes, skills, and memory
|
|
75
98
|
|
|
99
|
+
## Related Ideas
|
|
100
|
+
|
|
101
|
+
This repo is part of a broader exploration of how agent skills are structured and executed.
|
|
102
|
+
|
|
103
|
+
If you're interested in:
|
|
104
|
+
- how different types of skills should be modeled
|
|
105
|
+
- how to handle stateless vs stateful execution
|
|
106
|
+
- how to make agent workflows more reliable
|
|
107
|
+
|
|
108
|
+
→ Read more: https://go.deepvista.ai/agent-skills-2d
|
|
109
|
+
|
|
76
110
|
---
|
|
77
111
|
|
|
78
112
|
## Quick Start
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
<img src="https://raw.githubusercontent.com/DeepVista-AI/deepvista-cli/main/docs/assets/deepvista-banner.png" alt="DeepVista" width="600">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<h1 align="center">Your
|
|
5
|
+
<h1 align="center">Turn Your Agents into a Self-Evolving Team</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<strong>CLI
|
|
8
|
+
<strong>DeepVista CLI connects your coding agents to a shared knowledge base —<br>
|
|
9
|
+
so they don’t just execute, but learn, remember, and build on past work.
|
|
10
|
+
</strong>
|
|
9
11
|
</p>
|
|
10
12
|
|
|
11
13
|
<div align="center">
|
|
@@ -23,7 +25,7 @@
|
|
|
23
25
|
<br>
|
|
24
26
|
|
|
25
27
|
<p align="center">
|
|
26
|
-
|
|
28
|
+
⭐ If this direction resonates, consider <b>starring the repo</b> — it helps more people discover it.
|
|
27
29
|
</p>
|
|
28
30
|
|
|
29
31
|
<br>
|
|
@@ -33,6 +35,27 @@
|
|
|
33
35
|
|
|
34
36
|
---
|
|
35
37
|
|
|
38
|
+
## Who this is for
|
|
39
|
+
|
|
40
|
+
- Builders working with coding agents (Claude Code, Cursor, OpenCode)
|
|
41
|
+
- People experimenting with agent workflows and skills
|
|
42
|
+
- Anyone trying to turn scattered interactions into compounding knowledge
|
|
43
|
+
|
|
44
|
+
## What this enables
|
|
45
|
+
|
|
46
|
+
Modern coding agents are powerful — but each interaction is stateless and isolated.
|
|
47
|
+
|
|
48
|
+
DeepVista changes that.
|
|
49
|
+
|
|
50
|
+
- Agents **remember** past work
|
|
51
|
+
- Agents **share context** through a common knowledge base
|
|
52
|
+
- Agents **build on previous decisions and insights**
|
|
53
|
+
|
|
54
|
+
Over time, this turns isolated executions into a:
|
|
55
|
+
|
|
56
|
+
→ **a self-evolving team of agents that compound knowledge over time**
|
|
57
|
+
|
|
58
|
+
|
|
36
59
|
## Why DeepVista CLI?
|
|
37
60
|
|
|
38
61
|
Most knowledge tools trap your data in a GUI. DeepVista CLI gives you **full access to your knowledge base from the terminal** — and lets your AI agents use it too.
|
|
@@ -44,6 +67,17 @@ Most knowledge tools trap your data in a GUI. DeepVista CLI gives you **full acc
|
|
|
44
67
|
- 💬 **Chat** — talk to the DeepVista AI agent in your terminal
|
|
45
68
|
- 🖥️ **Full TUI** — four-panel terminal UI for chat, notes, skills, and memory
|
|
46
69
|
|
|
70
|
+
## Related Ideas
|
|
71
|
+
|
|
72
|
+
This repo is part of a broader exploration of how agent skills are structured and executed.
|
|
73
|
+
|
|
74
|
+
If you're interested in:
|
|
75
|
+
- how different types of skills should be modeled
|
|
76
|
+
- how to handle stateless vs stateful execution
|
|
77
|
+
- how to make agent workflows more reliable
|
|
78
|
+
|
|
79
|
+
→ Read more: https://go.deepvista.ai/agent-skills-2d
|
|
80
|
+
|
|
47
81
|
---
|
|
48
82
|
|
|
49
83
|
## Quick Start
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"""deepvista lint — LLM health checks over the vistabase.
|
|
2
|
+
|
|
3
|
+
Invokes the DeepVista agent with a curated prompt asking it to audit the
|
|
4
|
+
knowledge base for: duplicates, contradictions, stale claims, orphan pages,
|
|
5
|
+
missing cross-references, and data gaps that could be filled with a web search.
|
|
6
|
+
|
|
7
|
+
Inspired by karpathy's "LLM health checks" over the wiki:
|
|
8
|
+
https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f
|
|
9
|
+
|
|
10
|
+
Streams the agent's response as NDJSON (same format as `chat +send`).
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
import click
|
|
19
|
+
|
|
20
|
+
from deepvista_cli.client.http import DeepVistaClient
|
|
21
|
+
from deepvista_cli.output.formatter import format_output
|
|
22
|
+
|
|
23
|
+
LINT_CHECKS = [
|
|
24
|
+
"duplicates",
|
|
25
|
+
"contradictions",
|
|
26
|
+
"stale",
|
|
27
|
+
"orphans",
|
|
28
|
+
"missing-refs",
|
|
29
|
+
"gaps",
|
|
30
|
+
"all",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
_CHECK_INSTRUCTIONS = {
|
|
34
|
+
"duplicates": (
|
|
35
|
+
"Find duplicate or near-duplicate cards in the vistabase. "
|
|
36
|
+
"Use `find_similar_cards` to detect semantic duplicates. "
|
|
37
|
+
"For each pair, report which one is canonical and why."
|
|
38
|
+
),
|
|
39
|
+
"contradictions": (
|
|
40
|
+
"Find cards that contradict each other — claims on one card that "
|
|
41
|
+
"newer cards or sources have superseded. Cite both card IDs."
|
|
42
|
+
),
|
|
43
|
+
"stale": (
|
|
44
|
+
"Find stale claims: cards whose content is likely out of date relative "
|
|
45
|
+
"to newer cards or general knowledge. Suggest updates."
|
|
46
|
+
),
|
|
47
|
+
"orphans": (
|
|
48
|
+
"Find orphan cards — cards with no inbound references from other cards "
|
|
49
|
+
"and no relationships in the knowledge graph. Suggest where they could "
|
|
50
|
+
"be linked."
|
|
51
|
+
),
|
|
52
|
+
"missing-refs": (
|
|
53
|
+
"Find concepts mentioned in card content that lack their own card, "
|
|
54
|
+
"or that are not cross-referenced where they should be. List candidate "
|
|
55
|
+
"new cards to create."
|
|
56
|
+
),
|
|
57
|
+
"gaps": (
|
|
58
|
+
"Find data gaps that could be filled with a web search — important "
|
|
59
|
+
"entities or topics that are mentioned but under-described. Suggest "
|
|
60
|
+
"search queries."
|
|
61
|
+
),
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
_FIX_INSTRUCTION = (
|
|
65
|
+
"\n\nAfter identifying issues, FIX them: merge duplicates by calling "
|
|
66
|
+
"`upsert_context_card` on the canonical card and deleting the loser, "
|
|
67
|
+
"update stale cards with current info, and link orphans. Confirm each "
|
|
68
|
+
"change as you go."
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
_REPORT_INSTRUCTION = (
|
|
72
|
+
"\n\nReport findings only — do NOT modify, merge, or delete any cards. "
|
|
73
|
+
"List each issue with card IDs and a recommended action."
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _resolve_checks(checks: tuple[str, ...]) -> list[str]:
|
|
78
|
+
"""Expand "all" to the full check set. "all" + others => all (with a warning)."""
|
|
79
|
+
if not checks or "all" in checks:
|
|
80
|
+
explicit = [c for c in checks if c not in ("all", "")]
|
|
81
|
+
if explicit:
|
|
82
|
+
click.echo(
|
|
83
|
+
f"warning: --check all supersedes {', '.join(explicit)}; running the full check set.",
|
|
84
|
+
err=True,
|
|
85
|
+
)
|
|
86
|
+
return [k for k in _CHECK_INSTRUCTIONS if k != "all"]
|
|
87
|
+
# Preserve caller order; de-dup while keeping first occurrence.
|
|
88
|
+
seen: set[str] = set()
|
|
89
|
+
return [c for c in checks if not (c in seen or seen.add(c))]
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _build_prompt(selected: list[str], fix: bool) -> str:
|
|
93
|
+
lines = [
|
|
94
|
+
"Run an LLM health check over the vistabase. For each check below, "
|
|
95
|
+
"use your search and graph tools to investigate, then produce a "
|
|
96
|
+
"numbered list of findings with card IDs."
|
|
97
|
+
]
|
|
98
|
+
for i, key in enumerate(selected, 1):
|
|
99
|
+
lines.append(f"{i}. [{key}] {_CHECK_INSTRUCTIONS[key]}")
|
|
100
|
+
|
|
101
|
+
lines.append(_FIX_INSTRUCTION if fix else _REPORT_INSTRUCTION)
|
|
102
|
+
return "\n".join(lines)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _client(ctx: click.Context) -> DeepVistaClient:
|
|
106
|
+
return ctx.obj._client
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@click.command("lint")
|
|
110
|
+
@click.option(
|
|
111
|
+
"--check",
|
|
112
|
+
"checks",
|
|
113
|
+
type=click.Choice(LINT_CHECKS, case_sensitive=False),
|
|
114
|
+
multiple=True,
|
|
115
|
+
default=("all",),
|
|
116
|
+
help="Which checks to run. Repeatable. Default: all.",
|
|
117
|
+
)
|
|
118
|
+
@click.option(
|
|
119
|
+
"--fix",
|
|
120
|
+
is_flag=True,
|
|
121
|
+
default=False,
|
|
122
|
+
help="Let the agent apply fixes (merge duplicates, etc.) instead of only reporting.",
|
|
123
|
+
)
|
|
124
|
+
@click.option(
|
|
125
|
+
"--yes",
|
|
126
|
+
"-y",
|
|
127
|
+
"assume_yes",
|
|
128
|
+
is_flag=True,
|
|
129
|
+
default=False,
|
|
130
|
+
help="Skip the --fix confirmation prompt. Use only in scripts/cron.",
|
|
131
|
+
)
|
|
132
|
+
@click.option("--chat-id", default=None, help="Continue an existing lint session.")
|
|
133
|
+
@click.option("--dry-run", is_flag=True, default=False, help="Preview the prompt without calling the agent.")
|
|
134
|
+
@click.pass_context
|
|
135
|
+
def lint_command(
|
|
136
|
+
ctx: click.Context,
|
|
137
|
+
checks: tuple[str, ...],
|
|
138
|
+
fix: bool,
|
|
139
|
+
assume_yes: bool,
|
|
140
|
+
chat_id: str | None,
|
|
141
|
+
dry_run: bool,
|
|
142
|
+
) -> None:
|
|
143
|
+
"""Health-check the vistabase with the DeepVista agent.
|
|
144
|
+
|
|
145
|
+
Checks for duplicates, contradictions, stale claims, orphan cards, missing
|
|
146
|
+
cross-references, and web-fillable data gaps. Reports by default; pass
|
|
147
|
+
`--fix` to let the agent merge/update/link cards.
|
|
148
|
+
|
|
149
|
+
> [!CAUTION] With `--fix`, this is a write command — the agent may merge,
|
|
150
|
+
> update, or delete cards. Confirm with the user before executing.
|
|
151
|
+
"""
|
|
152
|
+
selected = _resolve_checks(checks)
|
|
153
|
+
prompt = _build_prompt(selected, fix)
|
|
154
|
+
body: dict[str, Any] = {"user_instruction": prompt}
|
|
155
|
+
if chat_id:
|
|
156
|
+
body["chat_id"] = chat_id
|
|
157
|
+
|
|
158
|
+
if dry_run:
|
|
159
|
+
format_output(
|
|
160
|
+
{
|
|
161
|
+
"dry_run": True,
|
|
162
|
+
"would": "send lint prompt to DeepVista agent",
|
|
163
|
+
"checks": selected,
|
|
164
|
+
"fix": fix,
|
|
165
|
+
"payload": body,
|
|
166
|
+
},
|
|
167
|
+
ctx.obj.output_format,
|
|
168
|
+
entity_type="chat",
|
|
169
|
+
base_url=ctx.obj.auth_url,
|
|
170
|
+
)
|
|
171
|
+
return
|
|
172
|
+
|
|
173
|
+
if fix and not assume_yes:
|
|
174
|
+
click.confirm(
|
|
175
|
+
"--fix lets the agent merge, update, and delete cards. Continue?",
|
|
176
|
+
abort=True,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
try:
|
|
180
|
+
for event in _client(ctx).stream_sse("/imagine", body):
|
|
181
|
+
click.echo(json.dumps(event, default=str))
|
|
182
|
+
except (KeyboardInterrupt, click.Abort):
|
|
183
|
+
click.echo(json.dumps({"type": "interrupted", "message": "lint stream aborted by user"}), err=True)
|
|
184
|
+
raise
|
|
185
|
+
except Exception as exc:
|
|
186
|
+
click.echo(
|
|
187
|
+
json.dumps({"type": "error", "message": f"lint stream failed: {exc}"}),
|
|
188
|
+
err=True,
|
|
189
|
+
)
|
|
190
|
+
raise
|
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Notes are a special case of context cards with type="note".
|
|
4
4
|
The +quick helper creates a note from a single text argument.
|
|
5
|
+
The index command triggers entity extraction on notes not yet processed.
|
|
5
6
|
"""
|
|
6
7
|
|
|
7
8
|
from __future__ import annotations
|
|
8
9
|
|
|
9
10
|
import json as _json
|
|
11
|
+
from typing import Any
|
|
10
12
|
|
|
11
13
|
import click
|
|
12
14
|
|
|
@@ -182,6 +184,78 @@ def notes_delete(ctx: click.Context, note_id: str, dry_run: bool) -> None:
|
|
|
182
184
|
format_output(data, ctx.obj.output_format, entity_type="note", base_url=ctx.obj.auth_url)
|
|
183
185
|
|
|
184
186
|
|
|
187
|
+
# ---------------------------------------------------------------------------
|
|
188
|
+
# index — trigger entity extraction on notes
|
|
189
|
+
# ---------------------------------------------------------------------------
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@notes_group.command("index")
|
|
193
|
+
@click.option(
|
|
194
|
+
"--limit",
|
|
195
|
+
type=click.IntRange(1, 500),
|
|
196
|
+
default=50,
|
|
197
|
+
help="Max notes to re-index (default 50, max 500).",
|
|
198
|
+
)
|
|
199
|
+
@click.option("--note-id", "note_ids", multiple=True, help="Index specific note(s) by ID. Repeatable.")
|
|
200
|
+
@click.option(
|
|
201
|
+
"--all",
|
|
202
|
+
"include_enriched",
|
|
203
|
+
is_flag=True,
|
|
204
|
+
default=False,
|
|
205
|
+
help=(
|
|
206
|
+
"Re-enrich every note up to --limit, not just those with a null embedding. "
|
|
207
|
+
"Ignored when --note-id is set (explicit IDs always re-enrich)."
|
|
208
|
+
),
|
|
209
|
+
)
|
|
210
|
+
@click.option("--dry-run", is_flag=True, default=False, help="Preview what would happen without making any changes.")
|
|
211
|
+
@click.pass_context
|
|
212
|
+
def notes_index(
|
|
213
|
+
ctx: click.Context,
|
|
214
|
+
limit: int,
|
|
215
|
+
note_ids: tuple[str, ...],
|
|
216
|
+
include_enriched: bool,
|
|
217
|
+
dry_run: bool,
|
|
218
|
+
) -> None:
|
|
219
|
+
"""Trigger entity extraction on notes that need processing.
|
|
220
|
+
|
|
221
|
+
Calls the server-side `/index_notes` route. By default, finds notes that
|
|
222
|
+
have never been enriched (null embedding) and enqueues the DeepVista
|
|
223
|
+
agent to extract entities, create graph relationships, and refresh
|
|
224
|
+
embeddings. Pass `--note-id` (repeatable) to target specific cards, or
|
|
225
|
+
`--all` to re-enrich everything up to `--limit`.
|
|
226
|
+
|
|
227
|
+
> [!CAUTION] This is a write command — it kicks off background agent runs
|
|
228
|
+
> that may create/update related cards. Confirm before executing.
|
|
229
|
+
"""
|
|
230
|
+
# Explicit IDs always bypass the unenriched filter — the user asked for those cards specifically.
|
|
231
|
+
only_unenriched = not include_enriched and not note_ids
|
|
232
|
+
body: dict[str, Any] = {
|
|
233
|
+
"card_type": "note",
|
|
234
|
+
"limit": limit,
|
|
235
|
+
"only_unenriched": only_unenriched,
|
|
236
|
+
}
|
|
237
|
+
if note_ids:
|
|
238
|
+
body["card_ids"] = list(note_ids)
|
|
239
|
+
|
|
240
|
+
if dry_run:
|
|
241
|
+
format_output(
|
|
242
|
+
{"dry_run": True, "would": "POST /index_notes", "payload": body},
|
|
243
|
+
ctx.obj.output_format,
|
|
244
|
+
entity_type="note",
|
|
245
|
+
base_url=ctx.obj.auth_url,
|
|
246
|
+
)
|
|
247
|
+
return
|
|
248
|
+
|
|
249
|
+
data = _client(ctx).post("/index_notes", body)
|
|
250
|
+
format_output(
|
|
251
|
+
data,
|
|
252
|
+
ctx.obj.output_format,
|
|
253
|
+
title="Indexed Notes",
|
|
254
|
+
entity_type="note",
|
|
255
|
+
base_url=ctx.obj.auth_url,
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
|
|
185
259
|
# ---------------------------------------------------------------------------
|
|
186
260
|
# Helper: +quick
|
|
187
261
|
# ---------------------------------------------------------------------------
|
|
@@ -11,6 +11,7 @@ from __future__ import annotations
|
|
|
11
11
|
|
|
12
12
|
import json
|
|
13
13
|
import re
|
|
14
|
+
from typing import Any
|
|
14
15
|
|
|
15
16
|
import click
|
|
16
17
|
|
|
@@ -19,6 +20,10 @@ from deepvista_cli.output.formatter import format_output, output_error
|
|
|
19
20
|
|
|
20
21
|
SKILL_COLUMNS = ["id", "title", "display_status", "updated_at"]
|
|
21
22
|
|
|
23
|
+
SKILL_KINDS = ("persona", "workflow")
|
|
24
|
+
|
|
25
|
+
_UUID_RE = re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", re.IGNORECASE)
|
|
26
|
+
|
|
22
27
|
|
|
23
28
|
def _client(ctx: click.Context) -> DeepVistaClient:
|
|
24
29
|
return ctx.obj._client
|
|
@@ -95,7 +100,6 @@ def skill_run(ctx: click.Context, skill_id: str, user_input: str | None, dry_run
|
|
|
95
100
|
|
|
96
101
|
Output is NDJSON (one JSON object per line) as the agent streams its response.
|
|
97
102
|
"""
|
|
98
|
-
_UUID_RE = re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", re.IGNORECASE)
|
|
99
103
|
if not _UUID_RE.match(skill_id):
|
|
100
104
|
output_error(3, "Invalid skill ID", f"Expected UUID format, got: {skill_id!r}")
|
|
101
105
|
|
|
@@ -226,3 +230,165 @@ def skill_install(ctx: click.Context, skill_id: str, dry_run: bool) -> None:
|
|
|
226
230
|
click.echo(json.dumps({"status": "already_installed", "card": data.get("card", {})}, indent=2, default=str))
|
|
227
231
|
else:
|
|
228
232
|
click.echo(json.dumps({"status": "installed", "card": data.get("card", {})}, indent=2, default=str))
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
# ---------------------------------------------------------------------------
|
|
236
|
+
# create-from-note — synthesize skills from a source note via the agent
|
|
237
|
+
# ---------------------------------------------------------------------------
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
_CREATE_FROM_NOTE_INSTRUCTIONS = {
|
|
241
|
+
"persona": (
|
|
242
|
+
"A **persona skill** named `persona-<interviewee-slug>` that captures the "
|
|
243
|
+
"interviewee's philosophy, voice, and decision-making lens. When loaded, "
|
|
244
|
+
"the agent should respond in their voice and apply their frameworks. "
|
|
245
|
+
"Include: who they are, core mental models drawn from the note, voice/"
|
|
246
|
+
"tone rules, and a 3-5 phase advising sequence using <accordion>/<nli> "
|
|
247
|
+
"shortcodes."
|
|
248
|
+
),
|
|
249
|
+
"workflow": (
|
|
250
|
+
"A **workflow skill** named `workflow-<topic-slug>` that turns the "
|
|
251
|
+
"interviewee's frameworks or steps into an executable workflow. The user "
|
|
252
|
+
"provides inputs; the workflow classifies, recommends, and returns a "
|
|
253
|
+
"prioritized plan. Include: purpose, **a `## Workflow` section with a "
|
|
254
|
+
"`mermaid` flowchart diagram that visualises the decision graph — "
|
|
255
|
+
"ALWAYS open the fence with the `mermaid` info string (```mermaid) "
|
|
256
|
+
"and use `flowchart TD`**, input schema, 4-6 phases using "
|
|
257
|
+
"<accordion>/<nli> shortcodes, cheat sheet, and output format template. "
|
|
258
|
+
"**Mermaid animation is REQUIRED, not optional.** For every edge in "
|
|
259
|
+
"the flowchart, give it an ID using mermaid v11 syntax "
|
|
260
|
+
"(`A e1@--> B`, `B e2@--> C`, …) and turn animation on with "
|
|
261
|
+
"`e1@{ animation: slow }` for happy-path edges and "
|
|
262
|
+
"`e1@{ animation: fast }` for tight loops. Every edge must have an "
|
|
263
|
+
"ID and every ID must have an animation directive — a static "
|
|
264
|
+
"diagram is a rendering bug, not an acceptable output. "
|
|
265
|
+
"**Node-label rules (critical for rendering): every node label must "
|
|
266
|
+
"be a single short line, ≤ 30 characters. Do NOT use `<br/>`, "
|
|
267
|
+
"`\\n`, `<b>`, `<i>`, or any HTML tags inside `[ ... ]`, `( ... )`, "
|
|
268
|
+
"or `{ ... }`. If you need a sub-description, chain a second node "
|
|
269
|
+
"below instead of stuffing two lines into one node — mermaid's "
|
|
270
|
+
"HTML-label sizing clips wrapped text and multi-line content will "
|
|
271
|
+
"render cut off.** Keep the diagram under ~15 nodes — split into "
|
|
272
|
+
"multiple diagrams if the workflow is larger."
|
|
273
|
+
),
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def _build_create_from_note_prompt(note_id: str, kinds: tuple[str, ...]) -> str:
|
|
278
|
+
lines = [
|
|
279
|
+
f'Look up the note with id "{note_id}" using `read_context_card`. Read '
|
|
280
|
+
"its full content. From that note, generate the skill(s) listed below. "
|
|
281
|
+
"Ground every detail in the note — do not invent frameworks or advice "
|
|
282
|
+
"the note doesn't contain.",
|
|
283
|
+
"",
|
|
284
|
+
"Skills to generate:",
|
|
285
|
+
]
|
|
286
|
+
for i, kind in enumerate(kinds, 1):
|
|
287
|
+
lines.append(f"{i}. {_CREATE_FROM_NOTE_INSTRUCTIONS[kind]}")
|
|
288
|
+
lines.append("")
|
|
289
|
+
lines.append(
|
|
290
|
+
"**You MUST persist each skill by calling `upsert_context_card` with "
|
|
291
|
+
'`card_type="skill"`.** Do not write the skill content to a local '
|
|
292
|
+
"file, do not paste it in the chat response, do not skip the tool "
|
|
293
|
+
"call. One `upsert_context_card` invocation per skill."
|
|
294
|
+
)
|
|
295
|
+
lines.append("")
|
|
296
|
+
lines.append(
|
|
297
|
+
"For each `upsert_context_card` call: set `title` to the skill name, "
|
|
298
|
+
"put the full SKILL.md body in `description`, add relevant `tags` "
|
|
299
|
+
"including the kind (`persona` or `workflow`), and link the source "
|
|
300
|
+
f'note via `related_context_card_ids=["{note_id}"]`. After each call, '
|
|
301
|
+
"confirm the returned card id in the chat response."
|
|
302
|
+
)
|
|
303
|
+
return "\n".join(lines)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
@skill_group.command("create-from-note")
|
|
307
|
+
@click.argument("note_id")
|
|
308
|
+
@click.option(
|
|
309
|
+
"--kind",
|
|
310
|
+
"kinds",
|
|
311
|
+
type=click.Choice(SKILL_KINDS, case_sensitive=False),
|
|
312
|
+
multiple=True,
|
|
313
|
+
default=SKILL_KINDS,
|
|
314
|
+
help="Which skill kinds to synthesize. Repeatable. Default: persona and workflow.",
|
|
315
|
+
)
|
|
316
|
+
@click.option("--chat-id", default=None, help="Continue an existing synthesis session.")
|
|
317
|
+
@click.option(
|
|
318
|
+
"--yes",
|
|
319
|
+
"-y",
|
|
320
|
+
"assume_yes",
|
|
321
|
+
is_flag=True,
|
|
322
|
+
default=False,
|
|
323
|
+
help="Skip the write confirmation prompt. Use only in scripts/batch conversion.",
|
|
324
|
+
)
|
|
325
|
+
@click.option("--dry-run", is_flag=True, default=False, help="Preview the prompt without calling the agent.")
|
|
326
|
+
@click.pass_context
|
|
327
|
+
def skill_create_from_note(
|
|
328
|
+
ctx: click.Context,
|
|
329
|
+
note_id: str,
|
|
330
|
+
kinds: tuple[str, ...],
|
|
331
|
+
chat_id: str | None,
|
|
332
|
+
assume_yes: bool,
|
|
333
|
+
dry_run: bool,
|
|
334
|
+
) -> None:
|
|
335
|
+
"""Synthesize skill card(s) from a note via the DeepVista agent.
|
|
336
|
+
|
|
337
|
+
Reads the note identified by `note_id` and invokes the agent with a curated
|
|
338
|
+
prompt that produces one `persona` skill (interviewee's voice + frameworks)
|
|
339
|
+
and/or one `workflow` skill (executable steps), grounded in the note's
|
|
340
|
+
content. Each generated skill is stored as a context card of `type=skill`.
|
|
341
|
+
|
|
342
|
+
Designed for batch-converting podcast / interview notes into reusable
|
|
343
|
+
skills. Streams NDJSON identical to `chat +send` and `skill run`.
|
|
344
|
+
|
|
345
|
+
> [!CAUTION] This is a write command — the agent creates skill cards in
|
|
346
|
+
> the user's project. Confirm before executing.
|
|
347
|
+
"""
|
|
348
|
+
if not _UUID_RE.match(note_id):
|
|
349
|
+
output_error(3, "Invalid note ID", f"Expected UUID format, got: {note_id!r}")
|
|
350
|
+
|
|
351
|
+
# Empty tuple shouldn't happen with default, but guard anyway.
|
|
352
|
+
selected = kinds or SKILL_KINDS
|
|
353
|
+
# De-dup while preserving order.
|
|
354
|
+
seen: set[str] = set()
|
|
355
|
+
selected = tuple(k for k in selected if not (k in seen or seen.add(k)))
|
|
356
|
+
|
|
357
|
+
prompt = _build_create_from_note_prompt(note_id, selected)
|
|
358
|
+
body: dict[str, Any] = {"user_instruction": prompt}
|
|
359
|
+
if chat_id:
|
|
360
|
+
body["chat_id"] = chat_id
|
|
361
|
+
|
|
362
|
+
if dry_run:
|
|
363
|
+
format_output(
|
|
364
|
+
{
|
|
365
|
+
"dry_run": True,
|
|
366
|
+
"would": "synthesize skills from note via DeepVista agent",
|
|
367
|
+
"note_id": note_id,
|
|
368
|
+
"kinds": list(selected),
|
|
369
|
+
"payload": body,
|
|
370
|
+
},
|
|
371
|
+
ctx.obj.output_format,
|
|
372
|
+
entity_type="skill",
|
|
373
|
+
base_url=ctx.obj.auth_url,
|
|
374
|
+
)
|
|
375
|
+
return
|
|
376
|
+
|
|
377
|
+
if not assume_yes:
|
|
378
|
+
click.confirm(
|
|
379
|
+
f"The agent will create {len(selected)} skill card(s) from note {note_id}. Continue?",
|
|
380
|
+
abort=True,
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
try:
|
|
384
|
+
for event in _client(ctx).stream_sse("/imagine", body):
|
|
385
|
+
click.echo(json.dumps(event, default=str))
|
|
386
|
+
except (KeyboardInterrupt, click.Abort):
|
|
387
|
+
click.echo(json.dumps({"type": "interrupted", "message": "skill synthesis aborted by user"}), err=True)
|
|
388
|
+
raise
|
|
389
|
+
except Exception as exc:
|
|
390
|
+
click.echo(
|
|
391
|
+
json.dumps({"type": "error", "message": f"skill synthesis stream failed: {exc}"}),
|
|
392
|
+
err=True,
|
|
393
|
+
)
|
|
394
|
+
raise
|
|
@@ -28,6 +28,7 @@ from deepvista_cli.commands.auth import auth_group
|
|
|
28
28
|
from deepvista_cli.commands.card import card_group
|
|
29
29
|
from deepvista_cli.commands.chat import chat_group
|
|
30
30
|
from deepvista_cli.commands.config import config_group
|
|
31
|
+
from deepvista_cli.commands.lint import lint_command
|
|
31
32
|
from deepvista_cli.commands.memory import vistabase_group
|
|
32
33
|
from deepvista_cli.commands.notes import notes_group
|
|
33
34
|
from deepvista_cli.commands.skill import skill_group
|
|
@@ -89,6 +90,7 @@ cli.add_command(agents_group)
|
|
|
89
90
|
cli.add_command(auth_group)
|
|
90
91
|
cli.add_command(config_group)
|
|
91
92
|
cli.add_command(upgrade_command)
|
|
93
|
+
cli.add_command(lint_command)
|
|
92
94
|
|
|
93
95
|
# Legacy aliases for backward compatibility
|
|
94
96
|
cli.add_command(notes_group) # notes = cards with type=note (explicit knowledge layer)
|
|
@@ -4,15 +4,15 @@ name: deepvista
|
|
|
4
4
|
description: |
|
|
5
5
|
DeepVista CLI — knowledge base, notes, chat, skills, and memory from the terminal.
|
|
6
6
|
One skill for the full `deepvista` CLI. Load when the user wants to: take a note, jot
|
|
7
|
-
this down, save
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
this down, save a fact, or list and edit notes; create, search, pin, archive, edit,
|
|
8
|
+
or grep knowledge-base cards of any type (person, topic, file, note, todo…); view or
|
|
9
|
+
semantic-search implicit memory ("vistabase" / "memory"); chat with the AI agent or
|
|
10
|
+
manage sessions; list, run, export, install, or discover Skills; research then run a
|
|
11
|
+
Skill with synthesized context; analyze / summarize notes; import a folder as file
|
|
12
|
+
cards; run a knowledge-worker daily loop; auto-capture facts (OpenClaw); periodically
|
|
13
|
+
lint the vistabase for duplicates / contradictions / stale claims / orphans / missing
|
|
14
|
+
refs / gaps; or re-index notes to trigger entity extraction. Pick the matching
|
|
15
|
+
reference file in `reference/` for the subcommand.
|
|
16
16
|
metadata:
|
|
17
17
|
openclaw:
|
|
18
18
|
category: service
|
|
@@ -43,7 +43,8 @@ other reference file assumes you know it.
|
|
|
43
43
|
| Subcommand | Use when | Reference |
|
|
44
44
|
|---|---|---|
|
|
45
45
|
| `deepvista auth` / `agents` / `config` / `upgrade` / `ui` | authenticating, registering an agent, switching profiles, checking for updates | [shared.md](reference/shared.md) |
|
|
46
|
-
| `deepvista notes` | taking a note, jotting something down, listing / updating / deleting notes, quick-capture of a single-line fact | [notes.md](reference/notes.md) |
|
|
46
|
+
| `deepvista notes` | taking a note, jotting something down, listing / updating / deleting notes, quick-capture of a single-line fact, re-indexing notes for entity extraction | [notes.md](reference/notes.md) |
|
|
47
|
+
| `deepvista lint` | periodic LLM health check over the vistabase — duplicates, contradictions, stale claims, orphans, missing cross-references, data gaps | [lint.md](reference/lint.md) |
|
|
47
48
|
| `deepvista card` | creating / searching / pinning / archiving / grepping knowledge base cards across any type (person, topic, file, note, todo, etc.) | [vistabase-card.md](reference/vistabase-card.md) |
|
|
48
49
|
| `deepvista vistabase` (alias: `memory`) | viewing or semantic-searching implicit memory accumulated from chat | [vistabase.md](reference/vistabase.md) · [memory.md](reference/memory.md) |
|
|
49
50
|
| `deepvista chat` | sending a message to the AI agent, listing / deleting chat sessions, continuing a conversation | [chat.md](reference/chat.md) |
|
|
@@ -51,6 +52,7 @@ other reference file assumes you know it.
|
|
|
51
52
|
| — analyze notes | searching → reading → synthesizing notes to surface themes / patterns | [skill-analyze-notes.md](reference/skill-analyze-notes.md) |
|
|
52
53
|
| — research → run | finding context in the knowledge base, then running a Skill with synthesized input | [skill-research-to-skill.md](reference/skill-research-to-skill.md) |
|
|
53
54
|
| — export | exporting a DeepVista Skill as a portable `SKILL.md` file for another agent | [skill-export-knowledge.md](reference/skill-export-knowledge.md) |
|
|
55
|
+
| — create from note | synthesizing a persona + workflow skill from a podcast / interview / book note; batch-converting a corpus | [skill-create-from-note.md](reference/skill-create-from-note.md) |
|
|
54
56
|
| — import files | recursively importing a local folder as `type=file` cards | [skill-import-files.md](reference/skill-import-files.md) |
|
|
55
57
|
| persona: knowledge worker | daily workflow — check pinned cards, capture insights, run a Skill, ask the agent to synthesize | [persona-knowledge-worker.md](reference/persona-knowledge-worker.md) |
|
|
56
58
|
| auto-capture for OpenClaw | automatically saving notable facts from conversations without confirmation | [openclaw.md](reference/openclaw.md) |
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Lint — LLM health checks over the vistabase
|
|
2
|
+
|
|
3
|
+
`deepvista lint` asks the DeepVista agent to audit the knowledge base for
|
|
4
|
+
quality issues: duplicates, contradictions, stale claims, orphan cards,
|
|
5
|
+
missing cross-references, and data gaps. Inspired by
|
|
6
|
+
[karpathy's LLM health-check idea](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f).
|
|
7
|
+
|
|
8
|
+
The agent uses `find_similar_cards`, `chat_cypher_search`, and `exa_search`
|
|
9
|
+
to investigate, then streams a numbered findings list back as NDJSON
|
|
10
|
+
(same format as `chat +send`).
|
|
11
|
+
|
|
12
|
+
## Command
|
|
13
|
+
|
|
14
|
+
### `lint` — write (agent invocation)
|
|
15
|
+
|
|
16
|
+
> [!CAUTION] Calls the DeepVista agent. With `--fix`, the agent may merge,
|
|
17
|
+
> update, or delete cards. Confirm with the user before executing.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
deepvista lint [--check KIND]... [--fix] [--chat-id ID] [--dry-run]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
| Flag | Default | Purpose |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| `--check KIND` | `all` | Scope: `duplicates`, `contradictions`, `stale`, `orphans`, `missing-refs`, `gaps`, `all`. Repeatable. |
|
|
26
|
+
| `--fix` | off | Let the agent apply fixes (merge duplicates, update stale cards, link orphans). Default is report-only. |
|
|
27
|
+
| `--chat-id ID` | — | Continue an existing lint session. |
|
|
28
|
+
| `--dry-run` | — | Print the prompt that would be sent to the agent without calling it. |
|
|
29
|
+
|
|
30
|
+
## Checks
|
|
31
|
+
|
|
32
|
+
| Check | What it looks for |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `duplicates` | Near-duplicate cards (semantic). Canonical vs. loser. |
|
|
35
|
+
| `contradictions` | Cards whose claims conflict — newer source supersedes older. |
|
|
36
|
+
| `stale` | Content likely out of date relative to newer cards or general knowledge. |
|
|
37
|
+
| `orphans` | Cards with no inbound refs or graph relationships. |
|
|
38
|
+
| `missing-refs` | Concepts mentioned but lacking their own card. |
|
|
39
|
+
| `gaps` | Under-described entities that could be filled with a web search. |
|
|
40
|
+
|
|
41
|
+
## Examples
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Full health check, report only
|
|
45
|
+
deepvista lint
|
|
46
|
+
|
|
47
|
+
# Just duplicates
|
|
48
|
+
deepvista lint --check duplicates
|
|
49
|
+
|
|
50
|
+
# Duplicates + contradictions, let the agent fix
|
|
51
|
+
deepvista lint --check duplicates --check contradictions --fix
|
|
52
|
+
|
|
53
|
+
# Preview the prompt
|
|
54
|
+
deepvista lint --dry-run
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Scheduling (periodic linting)
|
|
58
|
+
|
|
59
|
+
The whole point of lint is to run it periodically so the vistabase stays
|
|
60
|
+
clean as it grows. Two good cadences:
|
|
61
|
+
|
|
62
|
+
- **Every 4 hours:** catch freshly-added cards before they drift.
|
|
63
|
+
- **Weekly:** full `--fix` pass.
|
|
64
|
+
|
|
65
|
+
### Claude Code — background /loop
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# In a Claude Code session, kick off a self-pacing loop.
|
|
69
|
+
# /loop without an explicit interval runs indefinitely — stop it with /stop.
|
|
70
|
+
/loop deepvista lint --check duplicates
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Or schedule it persistently with the `schedule` skill (survives session end):
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
/schedule "every 4 hours" deepvista lint --check duplicates
|
|
77
|
+
/schedule "weekly" deepvista lint --fix --yes
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
`--fix` normally prompts for confirmation; scheduled runs must pass `--yes`
|
|
81
|
+
to accept the write blast radius non-interactively.
|
|
82
|
+
|
|
83
|
+
### Cursor Agent — cron
|
|
84
|
+
|
|
85
|
+
Cursor doesn't ship a native scheduler. Use system cron. Log into the
|
|
86
|
+
existing CLI config directory so logs live next to credentials and respect
|
|
87
|
+
`DEEPVISTA_CONFIG_DIR`:
|
|
88
|
+
|
|
89
|
+
```cron
|
|
90
|
+
# One-time setup: mkdir -p ~/.config/deepvista/logs
|
|
91
|
+
#
|
|
92
|
+
# Every 4 hours: lint + re-index notes.
|
|
93
|
+
0 */4 * * * deepvista lint --check duplicates >> ~/.config/deepvista/logs/lint.log 2>&1
|
|
94
|
+
15 */4 * * * deepvista notes index --limit 50 >> ~/.config/deepvista/logs/index.log 2>&1
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Any agent — `at` / launchd / systemd
|
|
98
|
+
|
|
99
|
+
`deepvista lint` is stdout-friendly (NDJSON), so pipe it into whatever job
|
|
100
|
+
runner you already have.
|
|
101
|
+
|
|
102
|
+
## See also
|
|
103
|
+
|
|
104
|
+
- [notes.md](notes.md) — `deepvista notes index` triggers entity extraction
|
|
105
|
+
on individual notes; often paired with `lint --check missing-refs`.
|
|
106
|
+
- [chat.md](chat.md) — `lint` is a curated variant of `chat +send`; the
|
|
107
|
+
NDJSON event format is identical.
|
|
@@ -60,6 +60,28 @@ Same content rules as `create`. Only provided fields are changed.
|
|
|
60
60
|
deepvista notes delete <note_id>
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
### `index` — write
|
|
64
|
+
|
|
65
|
+
> [!CAUTION] Queues the DeepVista agent to run entity extraction + graph
|
|
66
|
+
> linking + embedding refresh on unprocessed notes. Confirm first.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
deepvista notes index [--limit N] [--note-id ID]... [--all] [--dry-run]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
| Flag | When |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `--limit N` | Max notes to process (default 50, max 500, newest first) |
|
|
75
|
+
| `--note-id ID` | Target specific note(s). Repeatable. Implies re-enrichment — the unenriched filter is dropped for explicit IDs, and `--all` is redundant. |
|
|
76
|
+
| `--all` | Re-enrich every note up to `--limit`, not just those with a null embedding. Ignored when `--note-id` is set. |
|
|
77
|
+
| `--dry-run` | Preview the request without calling the backend |
|
|
78
|
+
|
|
79
|
+
Posts to the server-side `/index_notes` route, which enqueues one chat task
|
|
80
|
+
per card using the same pipeline `create_context_card` uses. Use after
|
|
81
|
+
bulk-importing notes, after a long offline period, or when entities appear
|
|
82
|
+
missing from the graph. Pair with `deepvista lint --check missing-refs` to
|
|
83
|
+
find concepts that still need their own card.
|
|
84
|
+
|
|
63
85
|
### `+quick` — write
|
|
64
86
|
|
|
65
87
|
> [!CAUTION] Writes a new note. Confirm first (or skip confirmation if the agent is
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Create skills from a note
|
|
2
|
+
|
|
3
|
+
`deepvista skill create-from-note <note_id>` asks the DeepVista agent to read
|
|
4
|
+
a source note (podcast episode, interview transcript, book chapter, research
|
|
5
|
+
summary) and synthesize one or more skill cards grounded in the note's
|
|
6
|
+
content. Two kinds are produced by default:
|
|
7
|
+
|
|
8
|
+
- **`persona`** — captures the interviewee/author's voice, philosophy, and
|
|
9
|
+
decision-making lens. When loaded, the agent responds in their voice and
|
|
10
|
+
applies their frameworks.
|
|
11
|
+
- **`workflow`** — turns the frameworks or steps they shared into an
|
|
12
|
+
executable workflow (inputs → phases → output template).
|
|
13
|
+
|
|
14
|
+
Streams NDJSON identical to `chat +send` and `skill run`. Each generated
|
|
15
|
+
skill is stored as a context card of `type=skill` in the user's project.
|
|
16
|
+
|
|
17
|
+
## Command
|
|
18
|
+
|
|
19
|
+
> [!CAUTION] Write — the agent creates skill cards in the user's project.
|
|
20
|
+
> Confirm before executing, or pass `--yes` for scripted/batch use.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
deepvista skill create-from-note <note_id> \
|
|
24
|
+
[--kind persona|workflow]... [--chat-id ID] [--yes] [--dry-run]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| Flag | Default | Purpose |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `<note_id>` | required | UUID of the source note. Must exist in the caller's project. |
|
|
30
|
+
| `--kind KIND` | `persona` + `workflow` | Repeatable. Restrict to one kind, e.g. `--kind persona`. |
|
|
31
|
+
| `--chat-id ID` | — | Continue an existing synthesis session (iterate on the skills). |
|
|
32
|
+
| `--yes` / `-y` | off | Skip the confirmation prompt. Required for scripts and cron. |
|
|
33
|
+
| `--dry-run` | — | Print the prompt without calling the agent. |
|
|
34
|
+
|
|
35
|
+
## When to use
|
|
36
|
+
|
|
37
|
+
- You've captured a podcast episode / interview / book chapter as a note.
|
|
38
|
+
- You want a reusable persona or workflow skill extracted from it.
|
|
39
|
+
- You want to batch-convert a corpus (e.g. every Lenny's Podcast note tagged
|
|
40
|
+
`lenny`, every FounderCoHo note tagged `foundercoho`) into installable
|
|
41
|
+
skills.
|
|
42
|
+
|
|
43
|
+
## Batch pattern
|
|
44
|
+
|
|
45
|
+
There's no built-in bulk flag — use a shell loop. The `--yes` flag avoids
|
|
46
|
+
per-note confirmation prompts:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Every note tagged "lenny" → persona + workflow skills
|
|
50
|
+
deepvista notes list --limit 100 \
|
|
51
|
+
| jq -r '.notes[] | select(.tags | index("lenny")) | .id' \
|
|
52
|
+
| while read -r note_id; do
|
|
53
|
+
deepvista skill create-from-note "$note_id" --yes \
|
|
54
|
+
>> ~/.config/deepvista/logs/skill-synthesis.log 2>&1
|
|
55
|
+
done
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
For a narrower pass (only the workflow):
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
deepvista skill create-from-note <note_id> --kind workflow --yes
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## After creation
|
|
65
|
+
|
|
66
|
+
Generated skills land with `status=unconfirmed`. Inspect each with
|
|
67
|
+
[`deepvista card get <card_id>`](vistabase-card.md) and verify the SKILL.md
|
|
68
|
+
body before running or exporting. See [skill-export-knowledge.md](skill-export-knowledge.md)
|
|
69
|
+
for turning a stored skill into a portable `SKILL.md` file.
|
|
70
|
+
|
|
71
|
+
## Examples
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Both kinds, interactive confirm
|
|
75
|
+
deepvista skill create-from-note 0d5d1fb2-7414-4593-abc4-fb74984f4b2f
|
|
76
|
+
|
|
77
|
+
# Persona only, scripted
|
|
78
|
+
deepvista skill create-from-note 0d5d1fb2-... --kind persona --yes
|
|
79
|
+
|
|
80
|
+
# Preview prompt
|
|
81
|
+
deepvista skill create-from-note 0d5d1fb2-... --dry-run
|
|
82
|
+
|
|
83
|
+
# Iterate on a prior synthesis
|
|
84
|
+
deepvista skill create-from-note 0d5d1fb2-... --chat-id gmrpoqqw
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## See also
|
|
88
|
+
|
|
89
|
+
- [notes.md](notes.md) — capturing the source note (`deepvista notes create`
|
|
90
|
+
with `--content-file`) and re-indexing.
|
|
91
|
+
- [skill.md](skill.md) — listing, running, exporting the generated skills.
|
|
92
|
+
- [skill-research-to-skill.md](skill-research-to-skill.md) — broader pattern
|
|
93
|
+
(search → synthesize → run) when the source material spans multiple cards.
|
|
@@ -20,6 +20,19 @@ deepvista skill get <skill_id>
|
|
|
20
20
|
|
|
21
21
|
Returns the full Skill definition including every phase and step.
|
|
22
22
|
|
|
23
|
+
### `create-from-note` — write
|
|
24
|
+
|
|
25
|
+
> [!CAUTION] The agent creates skill cards grounded in a source note.
|
|
26
|
+
> Confirm first (or pass `--yes` in batch scripts).
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
deepvista skill create-from-note <note_id> [--kind persona|workflow]... [--yes] [--dry-run]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Synthesizes one `persona` skill and/or one `workflow` skill from a source
|
|
33
|
+
note (podcast, interview, book chapter, research summary). Full guide:
|
|
34
|
+
[skill-create-from-note.md](skill-create-from-note.md).
|
|
35
|
+
|
|
23
36
|
### `run` — write
|
|
24
37
|
|
|
25
38
|
> [!CAUTION] Starts a new Skill run and creates a chat session. Confirm first.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/persona-knowledge-worker.md
RENAMED
|
File without changes
|
|
File without changes
|
{deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/skill-analyze-notes.md
RENAMED
|
File without changes
|
{deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/skill-export-knowledge.md
RENAMED
|
File without changes
|
{deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/skill-import-files.md
RENAMED
|
File without changes
|
{deepvista_cli-0.1.2 → deepvista_cli-0.1.4}/skills/deepvista/reference/skill-research-to-skill.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|