@anmol-srv/sigil 0.10.3 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +18 -12
- package/README.md +90 -82
- package/dist/cli.js +758 -507
- package/dist/daemon.js +724 -0
- package/dist/hooks/post-tool-use.js +20 -22
- package/dist/hooks/session-end.js +63 -61
- package/dist/hooks/stop.js +76 -74
- package/dist/hooks/user-prompt-submit.js +55 -47
- package/dist/server.js +45 -554
- package/integrations/hermes/README.md +4 -4
- package/integrations/hermes/plugin/README.md +8 -8
- package/knexfile.js +29 -8
- package/package.json +11 -5
- package/src/db/migrations/20260601000000_create-device-table.cjs +34 -0
- package/src/db/migrations/20260601000001_create-pairing-code-table.cjs +27 -0
- package/src/db/migrations/20260601000002_add-fact-provenance.cjs +31 -0
- package/src/db/migrations/20260601000003_add-device-revoked-reason.cjs +19 -0
- package/src/db/migrations/20260601000004_create-trace-event-table.cjs +35 -0
- package/src/db/migrations/20260601000005_add-fact-agent-provenance.cjs +25 -0
- package/src/gui/web/api.js +37 -0
- package/src/gui/web/app.css +947 -0
- package/src/gui/web/app.js +1230 -0
- package/src/gui/web/components.js +90 -0
- package/src/gui/web/design/colors_and_type.css +178 -0
- package/src/gui/web/design/sigil-mark-mono.svg +8 -0
- package/src/gui/web/design/sigil-mark.svg +26 -0
- package/src/gui/web/index.html +536 -0
- package/src/gui/web/sigil.svg +31 -0
- package/src/gui/web/toast.js +62 -0
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Sigil</title>
|
|
7
|
+
<link rel="icon" type="image/svg+xml" href="/static/design/sigil-mark.svg">
|
|
8
|
+
<!-- Sigil design system tokens (color, type, spacing, geometry) — loaded
|
|
9
|
+
BEFORE app.css so the dashboard re-skins onto the brand. -->
|
|
10
|
+
<link rel="stylesheet" href="/static/design/colors_and_type.css">
|
|
11
|
+
<link rel="stylesheet" href="/static/app.css">
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
<!-- Toast stack — central status/error feedback (see toast.js) -->
|
|
15
|
+
<div id="toasts" class="toast-stack" aria-live="polite"></div>
|
|
16
|
+
|
|
17
|
+
<!-- ════════════════════════════════════════════════════════════════════
|
|
18
|
+
ONBOARDING WIZARD (shown until SETUP_COMPLETE)
|
|
19
|
+
════════════════════════════════════════════════════════════════════ -->
|
|
20
|
+
<div class="onboarding" id="onboarding" hidden>
|
|
21
|
+
<aside class="onboarding-sidebar">
|
|
22
|
+
<div class="brand">
|
|
23
|
+
<img class="brand-mark" src="/static/design/sigil-mark.svg" alt="Sigil" width="20" height="20">
|
|
24
|
+
<div class="brand-name">Sigil</div>
|
|
25
|
+
<div class="brand-badge">setup</div>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<ol class="onboarding-steps" id="ob-steps">
|
|
29
|
+
<li class="onboarding-step active" data-ob-step="connectors">
|
|
30
|
+
<div class="num">1</div>
|
|
31
|
+
<div>
|
|
32
|
+
<div class="label">Connectors</div>
|
|
33
|
+
<div class="desc">Editors & tools</div>
|
|
34
|
+
</div>
|
|
35
|
+
</li>
|
|
36
|
+
<li class="onboarding-step future" data-ob-step="llm">
|
|
37
|
+
<div class="num">2</div>
|
|
38
|
+
<div>
|
|
39
|
+
<div class="label">Provider</div>
|
|
40
|
+
<div class="desc">Fact extraction + reasoning</div>
|
|
41
|
+
</div>
|
|
42
|
+
</li>
|
|
43
|
+
<li class="onboarding-step future" data-ob-step="embedding">
|
|
44
|
+
<div class="num">3</div>
|
|
45
|
+
<div>
|
|
46
|
+
<div class="label">Embeddings</div>
|
|
47
|
+
<div class="desc">Semantic search</div>
|
|
48
|
+
</div>
|
|
49
|
+
</li>
|
|
50
|
+
<li class="onboarding-step future" data-ob-step="database">
|
|
51
|
+
<div class="num">4</div>
|
|
52
|
+
<div>
|
|
53
|
+
<div class="label">Database</div>
|
|
54
|
+
<div class="desc">Where memory lives</div>
|
|
55
|
+
</div>
|
|
56
|
+
</li>
|
|
57
|
+
<li class="onboarding-step future" data-ob-step="finish">
|
|
58
|
+
<div class="num">5</div>
|
|
59
|
+
<div>
|
|
60
|
+
<div class="label">All set</div>
|
|
61
|
+
<div class="desc">Open the dashboard</div>
|
|
62
|
+
</div>
|
|
63
|
+
</li>
|
|
64
|
+
</ol>
|
|
65
|
+
|
|
66
|
+
<div class="spacer"></div>
|
|
67
|
+
<p class="text-xs muted">Running locally on this machine. No telemetry; no cloud account.</p>
|
|
68
|
+
</aside>
|
|
69
|
+
|
|
70
|
+
<main class="onboarding-content">
|
|
71
|
+
<!-- ── Step 1: Connectors ──────────────────────────────────────── -->
|
|
72
|
+
<section class="wizard-step active" data-step="connectors">
|
|
73
|
+
<h1>Connect your tools.</h1>
|
|
74
|
+
<p class="lede">Sigil installs memory hooks into the AI coding tools you already use — one shared brain across Claude Code, Cursor, Codex, Kiro, and any MCP client. Click to connect; you can change this any time.</p>
|
|
75
|
+
|
|
76
|
+
<div class="connector-grid" id="ob-connectors"><div class="muted">detecting installed tools…</div></div>
|
|
77
|
+
|
|
78
|
+
<div class="wizard-actions">
|
|
79
|
+
<div class="spacer"></div>
|
|
80
|
+
<button class="btn ghost" data-ob-next="llm" id="ob-connectors-skip">Skip for now</button>
|
|
81
|
+
<button class="btn primary large" data-ob-next="llm">Continue</button>
|
|
82
|
+
</div>
|
|
83
|
+
</section>
|
|
84
|
+
|
|
85
|
+
<!-- ── Step 4: Database (linear guided flow) ───────────────────── -->
|
|
86
|
+
<section class="wizard-step" data-step="database">
|
|
87
|
+
<h1>Set up your database.</h1>
|
|
88
|
+
<p class="lede">Sigil stores every fact, document, and embedding in Postgres with pgvector. Let Sigil create a local one for you, or point it at a database you control.</p>
|
|
89
|
+
|
|
90
|
+
<div class="provider-card-grid" id="db-mode-cards">
|
|
91
|
+
<label class="provider-card" data-db-mode="docker" id="ob-db-mode-docker" hidden>
|
|
92
|
+
<input type="radio" name="db-mode" value="docker" hidden>
|
|
93
|
+
<span class="name">Local (automatic) <span class="badge info" style="margin-left:8px;">RECOMMENDED</span></span>
|
|
94
|
+
<span class="hint">Sigil runs a pgvector Postgres in Docker for you. Zero config.</span>
|
|
95
|
+
</label>
|
|
96
|
+
<label class="provider-card" data-db-mode="url">
|
|
97
|
+
<input type="radio" name="db-mode" value="url" hidden checked>
|
|
98
|
+
<span class="name">Connection URL</span>
|
|
99
|
+
<span class="hint">Neon, Supabase, RDS, Render, Railway, CockroachDB.</span>
|
|
100
|
+
</label>
|
|
101
|
+
<label class="provider-card" data-db-mode="fields">
|
|
102
|
+
<input type="radio" name="db-mode" value="fields" hidden>
|
|
103
|
+
<span class="name">Local Postgres install</span>
|
|
104
|
+
<span class="hint">Existing host + port + user + password.</span>
|
|
105
|
+
</label>
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<p class="muted text-sm" id="ob-db-docker-note" style="margin-top: var(--s-2);" hidden></p>
|
|
109
|
+
|
|
110
|
+
<div id="ob-db-url" style="margin-top: var(--s-5);">
|
|
111
|
+
<label class="field">
|
|
112
|
+
<span class="label">Postgres connection URL</span>
|
|
113
|
+
<input type="text" id="ob-db-url-input" placeholder="postgres://user:pass@host.neon.tech/db?sslmode=require" autocomplete="off">
|
|
114
|
+
<span class="help">Paste from Neon dashboard / Supabase settings / RDS endpoint.</span>
|
|
115
|
+
</label>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<div id="ob-db-fields" style="display:none; margin-top: var(--s-5);">
|
|
119
|
+
<div class="row-2col">
|
|
120
|
+
<label class="field"><span class="label">Host</span><input type="text" id="ob-db-host" value="localhost" autocomplete="off"></label>
|
|
121
|
+
<label class="field"><span class="label">Port</span><input type="number" id="ob-db-port" value="5432"></label>
|
|
122
|
+
</div>
|
|
123
|
+
<div class="row-2col">
|
|
124
|
+
<label class="field"><span class="label">Database</span><input type="text" id="ob-db-db" value="sigil" autocomplete="off"></label>
|
|
125
|
+
<label class="field"><span class="label">User</span><input type="text" id="ob-db-user" value="sigil_app" autocomplete="off"></label>
|
|
126
|
+
</div>
|
|
127
|
+
<label class="field"><span class="label">Password</span><input type="password" id="ob-db-pass" autocomplete="off"></label>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
<div class="flex-row" style="margin-top: var(--s-4);">
|
|
131
|
+
<button class="btn primary" id="ob-db-setup">Set up database</button>
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
<!-- Linear flow rows (filled by JS) — replaces the old toggling buttons -->
|
|
135
|
+
<div class="db-flow" id="ob-db-flow" hidden></div>
|
|
136
|
+
|
|
137
|
+
<div class="wizard-actions">
|
|
138
|
+
<button class="btn ghost" data-ob-back="embedding">Back</button>
|
|
139
|
+
<div class="spacer"></div>
|
|
140
|
+
<button class="btn primary" data-ob-next="finish" id="ob-db-next" disabled>Continue</button>
|
|
141
|
+
</div>
|
|
142
|
+
</section>
|
|
143
|
+
|
|
144
|
+
<!-- ── Step 3: LLM provider ────────────────────────────────────── -->
|
|
145
|
+
<section class="wizard-step" data-step="llm">
|
|
146
|
+
<h1>Pick an LLM provider.</h1>
|
|
147
|
+
<p class="lede">Sigil uses an LLM to extract facts from your conversations, decide whether new memory contradicts old, and synthesize search results.</p>
|
|
148
|
+
|
|
149
|
+
<div class="provider-card-grid" id="ob-llm-cards"><div class="muted">loading providers…</div></div>
|
|
150
|
+
|
|
151
|
+
<div id="ob-llm-fields" style="margin-top: var(--s-5);"></div>
|
|
152
|
+
|
|
153
|
+
<div class="flex-row" style="margin-top: var(--s-3);">
|
|
154
|
+
<button class="btn primary" id="ob-llm-save">Save and test</button>
|
|
155
|
+
</div>
|
|
156
|
+
<pre id="ob-llm-result" class="result" hidden></pre>
|
|
157
|
+
|
|
158
|
+
<div class="wizard-actions">
|
|
159
|
+
<button class="btn ghost" data-ob-back="connectors">Back</button>
|
|
160
|
+
<div class="spacer"></div>
|
|
161
|
+
<button class="btn primary" data-ob-next="embedding" id="ob-llm-next" disabled>Continue</button>
|
|
162
|
+
</div>
|
|
163
|
+
</section>
|
|
164
|
+
|
|
165
|
+
<!-- ── Step 4: Embeddings ──────────────────────────────────────── -->
|
|
166
|
+
<section class="wizard-step" data-step="embedding">
|
|
167
|
+
<h1>Pick an embedding provider.</h1>
|
|
168
|
+
<p class="lede">Vector embeddings power semantic search across your memory. The model choice fixes the vector shape — changing it later requires re-embedding every fact.</p>
|
|
169
|
+
|
|
170
|
+
<div class="provider-card-grid" id="ob-emb-cards"><div class="muted">loading providers…</div></div>
|
|
171
|
+
<div id="ob-emb-fields" style="margin-top: var(--s-5);"></div>
|
|
172
|
+
|
|
173
|
+
<div class="flex-row" style="margin-top: var(--s-3);">
|
|
174
|
+
<button class="btn primary" id="ob-emb-save">Save and test</button>
|
|
175
|
+
</div>
|
|
176
|
+
<pre id="ob-emb-result" class="result" hidden></pre>
|
|
177
|
+
|
|
178
|
+
<div class="wizard-actions">
|
|
179
|
+
<button class="btn ghost" data-ob-back="llm">Back</button>
|
|
180
|
+
<div class="spacer"></div>
|
|
181
|
+
<button class="btn primary" data-ob-next="database" id="ob-emb-next" disabled>Continue</button>
|
|
182
|
+
</div>
|
|
183
|
+
</section>
|
|
184
|
+
|
|
185
|
+
<!-- ── Step 5: Finish ──────────────────────────────────────────── -->
|
|
186
|
+
<section class="wizard-step" data-step="finish">
|
|
187
|
+
<h1>You're set up.</h1>
|
|
188
|
+
<p class="lede">Sigil's daemon is running on this machine. Open the dashboard to add memories, browse the knowledge base, and (later) connect more devices.</p>
|
|
189
|
+
|
|
190
|
+
<div class="kv" style="margin-bottom: var(--s-5);">
|
|
191
|
+
<div class="row"><div class="k">Daemon</div><div class="v" id="ob-finish-daemon">—</div></div>
|
|
192
|
+
<div class="row"><div class="k">Database</div><div class="v" id="ob-finish-db">—</div></div>
|
|
193
|
+
<div class="row"><div class="k">LLM</div><div class="v" id="ob-finish-llm">—</div></div>
|
|
194
|
+
<div class="row"><div class="k">Embeddings</div><div class="v" id="ob-finish-emb">—</div></div>
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<h2>Next steps</h2>
|
|
198
|
+
<ul class="kv">
|
|
199
|
+
<div class="row"><div class="k">CLI</div><div class="v" style="font-family: var(--font-ui);"><code>sigil remember "..."</code>, <code>sigil search "..."</code>, <code>sigil status</code></div></div>
|
|
200
|
+
<div class="row"><div class="k">Claude Code</div><div class="v" style="font-family: var(--font-ui);">Run <code>sigil register</code> on the command line to add Sigil as an MCP server.</div></div>
|
|
201
|
+
<div class="row"><div class="k">Other devices</div><div class="v" style="font-family: var(--font-ui);">From the Devices tab in the dashboard, create a pairing code and run <code>sigil join …</code> on the joining device.</div></div>
|
|
202
|
+
</ul>
|
|
203
|
+
|
|
204
|
+
<label class="field" style="flex-direction:row; align-items:center; gap: var(--s-2); margin-top: var(--s-5);">
|
|
205
|
+
<input type="checkbox" id="ob-always-up" checked>
|
|
206
|
+
<span class="label" style="text-transform:none; letter-spacing:0;">Keep Sigil always running — start on login, auto-restart on crash or reboot (recommended)</span>
|
|
207
|
+
</label>
|
|
208
|
+
|
|
209
|
+
<div class="wizard-actions">
|
|
210
|
+
<div class="spacer"></div>
|
|
211
|
+
<button class="btn primary large" id="ob-complete">Open the dashboard →</button>
|
|
212
|
+
</div>
|
|
213
|
+
</section>
|
|
214
|
+
</main>
|
|
215
|
+
</div>
|
|
216
|
+
|
|
217
|
+
<!-- ════════════════════════════════════════════════════════════════════
|
|
218
|
+
MAIN DASHBOARD
|
|
219
|
+
════════════════════════════════════════════════════════════════════ -->
|
|
220
|
+
<header>
|
|
221
|
+
<div class="header-inner">
|
|
222
|
+
<div class="brand">
|
|
223
|
+
<img class="brand-mark" src="/static/design/sigil-mark.svg" alt="Sigil" width="20" height="20">
|
|
224
|
+
<div class="brand-name">Sigil</div>
|
|
225
|
+
<div class="brand-badge" id="brand-badge">local</div>
|
|
226
|
+
</div>
|
|
227
|
+
<nav>
|
|
228
|
+
<a href="#health" data-route="health" class="active">Overview</a>
|
|
229
|
+
<a href="#kb" data-route="kb">Knowledge Base</a>
|
|
230
|
+
<a href="#devices" data-route="devices">Devices</a>
|
|
231
|
+
<a href="#activity" data-route="activity">Activity</a>
|
|
232
|
+
<a href="#setup" data-route="setup">Setup</a>
|
|
233
|
+
<a href="#settings" data-route="settings">Settings</a>
|
|
234
|
+
<a href="#methods" data-route="methods">RPC</a>
|
|
235
|
+
</nav>
|
|
236
|
+
<div class="conn-status" id="conn">connecting…</div>
|
|
237
|
+
</div>
|
|
238
|
+
</header>
|
|
239
|
+
|
|
240
|
+
<main>
|
|
241
|
+
<!-- ── Overview ─────────────────────────────────────────────── -->
|
|
242
|
+
<section id="view-health" class="view active">
|
|
243
|
+
<div class="section-head">
|
|
244
|
+
<div class="title-block">
|
|
245
|
+
<h2>Overview</h2>
|
|
246
|
+
<p>This Sigil install — its daemon process, identity, and where memory lives.</p>
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
|
|
250
|
+
<div class="stat-grid">
|
|
251
|
+
<div class="stat"><span class="lbl">Daemon</span><span class="val" id="hc-pid">—</span><span class="sub" id="hc-uptime">—</span></div>
|
|
252
|
+
<div class="stat"><span class="lbl">Mode</span><span class="val" id="hc-mode">—</span><span class="sub" id="hc-driver">—</span></div>
|
|
253
|
+
<div class="stat"><span class="lbl">Identity</span><span class="val" id="hc-nodeid">—</span><span class="sub" id="hc-relay">—</span></div>
|
|
254
|
+
</div>
|
|
255
|
+
|
|
256
|
+
<h3 class="section-sub">Details</h3>
|
|
257
|
+
<div class="kv" id="health-pane"><div class="row"><div class="k">pid</div><div class="v">—</div></div></div>
|
|
258
|
+
</section>
|
|
259
|
+
|
|
260
|
+
<!-- ── Knowledge Base ───────────────────────────────────────── -->
|
|
261
|
+
<section id="view-kb" class="view">
|
|
262
|
+
<div class="section-head">
|
|
263
|
+
<div class="title-block">
|
|
264
|
+
<h2>Knowledge Base</h2>
|
|
265
|
+
<p>Current document, chunk, fact, and entity counts. Hot facts power the Active Context block injected into every Claude Code session.</p>
|
|
266
|
+
</div>
|
|
267
|
+
<div class="actions"><button class="btn" id="kb-refresh">Refresh</button></div>
|
|
268
|
+
</div>
|
|
269
|
+
|
|
270
|
+
<div class="kv" id="kb-pane"><div class="row"><div class="k">facts</div><div class="v">—</div></div></div>
|
|
271
|
+
|
|
272
|
+
<h3 class="section-sub">Hot facts</h3>
|
|
273
|
+
<ul id="hot-facts" class="methods-grid"></ul>
|
|
274
|
+
</section>
|
|
275
|
+
|
|
276
|
+
<!-- ── Devices ──────────────────────────────────────────────── -->
|
|
277
|
+
<section id="view-devices" class="view">
|
|
278
|
+
<div class="section-head">
|
|
279
|
+
<div class="title-block">
|
|
280
|
+
<h2>Devices</h2>
|
|
281
|
+
<p>Other Sigil installs paired with this one. Identity is an Ed25519 NodeID — revoke locks a device out without losing the data it wrote.</p>
|
|
282
|
+
</div>
|
|
283
|
+
<div class="actions">
|
|
284
|
+
<button class="btn" id="dev-refresh">Refresh</button>
|
|
285
|
+
<button class="btn primary" id="dev-new">+ Add device</button>
|
|
286
|
+
</div>
|
|
287
|
+
</div>
|
|
288
|
+
|
|
289
|
+
<div class="row-meta"><span id="dev-count">—</span></div>
|
|
290
|
+
|
|
291
|
+
<div class="table-wrap">
|
|
292
|
+
<table id="dev-table">
|
|
293
|
+
<thead>
|
|
294
|
+
<tr>
|
|
295
|
+
<th>Device</th>
|
|
296
|
+
<th>NodeID</th>
|
|
297
|
+
<th>Role</th>
|
|
298
|
+
<th>Namespaces</th>
|
|
299
|
+
<th>Last seen</th>
|
|
300
|
+
<th>Status</th>
|
|
301
|
+
<th style="text-align:right">Actions</th>
|
|
302
|
+
</tr>
|
|
303
|
+
</thead>
|
|
304
|
+
<tbody><tr><td colspan="7" class="empty">loading…</td></tr></tbody>
|
|
305
|
+
</table>
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
<h3 class="section-sub">Pending pairing codes</h3>
|
|
309
|
+
<div class="table-wrap">
|
|
310
|
+
<table id="dev-codes">
|
|
311
|
+
<thead><tr><th>Code id</th><th>Device name</th><th>Role</th><th>Expires</th><th>Status</th><th style="text-align:right">Actions</th></tr></thead>
|
|
312
|
+
<tbody><tr><td colspan="6" class="empty">loading…</td></tr></tbody>
|
|
313
|
+
</table>
|
|
314
|
+
</div>
|
|
315
|
+
</section>
|
|
316
|
+
|
|
317
|
+
<!-- ── Activity ─────────────────────────────────────────────── -->
|
|
318
|
+
<section id="view-activity" class="view">
|
|
319
|
+
<div class="section-head">
|
|
320
|
+
<div class="title-block">
|
|
321
|
+
<h2>Activity</h2>
|
|
322
|
+
<p>Complete causal log. Every search records its routing decision, matched entity, and per-fact scores — cosine similarity, RRF fusion, ACT-R activation (recency + frequency decay), and final ranking. Every ingest records classification, per-fact AUDM verdicts with the similarity that drove them, and entity links. Persisted and replayable.</p>
|
|
323
|
+
</div>
|
|
324
|
+
<div class="actions">
|
|
325
|
+
<button class="btn" id="trace-refresh">Refresh</button>
|
|
326
|
+
<button class="btn danger" id="trace-clear">Clear log</button>
|
|
327
|
+
<span class="conn-status" id="activity-status">disconnected</span>
|
|
328
|
+
</div>
|
|
329
|
+
</div>
|
|
330
|
+
|
|
331
|
+
<div class="trace-filters" id="trace-filters">
|
|
332
|
+
<button class="chip active" type="button" data-trace-filter="">All</button>
|
|
333
|
+
<button class="chip" type="button" data-trace-filter="search">Search</button>
|
|
334
|
+
<button class="chip" type="button" data-trace-filter="ingest">Ingest</button>
|
|
335
|
+
<button class="chip" type="button" data-trace-filter="lifecycle">Lifecycle</button>
|
|
336
|
+
</div>
|
|
337
|
+
|
|
338
|
+
<ul id="trace-list" class="trace-list"></ul>
|
|
339
|
+
<div class="empty" id="activity-empty">no activity yet — run <code>sigil search "..."</code> or <code>sigil remember "..."</code> and it'll appear here</div>
|
|
340
|
+
</section>
|
|
341
|
+
|
|
342
|
+
<!-- ── Setup (legacy DB test tab; same as onboarding) ─────────── -->
|
|
343
|
+
<section id="view-setup" class="view">
|
|
344
|
+
<div class="section-head">
|
|
345
|
+
<div class="title-block">
|
|
346
|
+
<h2>Database</h2>
|
|
347
|
+
<p>Re-test or re-configure your Postgres connection. Use this if you switched providers or need to install pgvector.</p>
|
|
348
|
+
</div>
|
|
349
|
+
</div>
|
|
350
|
+
|
|
351
|
+
<form id="db-form" class="panel" style="padding: var(--s-5);">
|
|
352
|
+
<label class="field">
|
|
353
|
+
<span class="label">Mode</span>
|
|
354
|
+
<select id="db-mode">
|
|
355
|
+
<option value="url">Connection URL</option>
|
|
356
|
+
<option value="fields">Host / Port / Database / User / Password</option>
|
|
357
|
+
</select>
|
|
358
|
+
</label>
|
|
359
|
+
|
|
360
|
+
<div id="db-url-pane">
|
|
361
|
+
<label class="field">
|
|
362
|
+
<span class="label">Postgres URL</span>
|
|
363
|
+
<input type="text" id="db-url" placeholder="postgres://user:pass@host.neon.tech/db?sslmode=require" autocomplete="off">
|
|
364
|
+
</label>
|
|
365
|
+
</div>
|
|
366
|
+
|
|
367
|
+
<div id="db-fields-pane" style="display:none">
|
|
368
|
+
<div class="row-2col">
|
|
369
|
+
<label class="field"><span class="label">Host</span><input type="text" id="db-host" value="localhost" autocomplete="off"></label>
|
|
370
|
+
<label class="field"><span class="label">Port</span><input type="number" id="db-port" value="5432"></label>
|
|
371
|
+
</div>
|
|
372
|
+
<div class="row-2col">
|
|
373
|
+
<label class="field"><span class="label">Database</span><input type="text" id="db-database" value="sigil" autocomplete="off"></label>
|
|
374
|
+
<label class="field"><span class="label">User</span><input type="text" id="db-user" value="sigil_app" autocomplete="off"></label>
|
|
375
|
+
</div>
|
|
376
|
+
<label class="field"><span class="label">Password</span><input type="password" id="db-password" autocomplete="off"></label>
|
|
377
|
+
</div>
|
|
378
|
+
|
|
379
|
+
<div class="flex-row">
|
|
380
|
+
<button type="button" class="btn primary" id="db-test">Test connection</button>
|
|
381
|
+
<button type="button" class="btn" id="db-pgvector" disabled hidden>Install pgvector</button>
|
|
382
|
+
<button type="button" class="btn" id="db-migrate" disabled>Run migrations</button>
|
|
383
|
+
</div>
|
|
384
|
+
</form>
|
|
385
|
+
|
|
386
|
+
<pre id="db-result" class="result" style="display:none"></pre>
|
|
387
|
+
</section>
|
|
388
|
+
|
|
389
|
+
<!-- ── Settings ─────────────────────────────────────────────── -->
|
|
390
|
+
<section id="view-settings" class="view">
|
|
391
|
+
<div class="section-head">
|
|
392
|
+
<div class="title-block">
|
|
393
|
+
<h2>Configuration</h2>
|
|
394
|
+
<p>Switch your database, LLM, or embedding provider any time. Changes apply after the daemon restarts (automatic).</p>
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
|
|
398
|
+
<!-- Current config + switch controls -->
|
|
399
|
+
<div class="panel" style="padding: var(--s-5); margin-bottom: var(--s-4);">
|
|
400
|
+
<div class="row"><div class="k">Database</div><div class="v" id="cfg-db">…</div></div>
|
|
401
|
+
<div class="row"><div class="k">LLM provider</div><div class="v" id="cfg-llm">…</div></div>
|
|
402
|
+
<div class="row"><div class="k">Embedding</div><div class="v" id="cfg-emb">…</div></div>
|
|
403
|
+
<div class="flex-row" style="margin-top: var(--s-4);">
|
|
404
|
+
<button type="button" class="btn" id="cfg-change-llm">Change LLM</button>
|
|
405
|
+
<button type="button" class="btn" id="cfg-change-emb">Change embedding</button>
|
|
406
|
+
<a href="#setup" class="btn" data-route="setup">Change database</a>
|
|
407
|
+
</div>
|
|
408
|
+
</div>
|
|
409
|
+
|
|
410
|
+
<!-- Inline provider switcher (hidden until "Change" clicked) -->
|
|
411
|
+
<div id="cfg-switch" class="panel" style="padding: var(--s-5); display:none; margin-bottom: var(--s-4);">
|
|
412
|
+
<h3 id="cfg-switch-title" style="margin-top:0;">Change provider</h3>
|
|
413
|
+
<div class="provider-card-grid" id="cfg-switch-cards"></div>
|
|
414
|
+
<div id="cfg-switch-fields" style="margin-top: var(--s-4);"></div>
|
|
415
|
+
<div id="cfg-switch-conflict"></div>
|
|
416
|
+
<div class="flex-row" style="margin-top: var(--s-4);">
|
|
417
|
+
<button type="button" class="btn primary" id="cfg-switch-apply">Apply & restart</button>
|
|
418
|
+
<button type="button" class="btn" id="cfg-switch-cancel">Cancel</button>
|
|
419
|
+
</div>
|
|
420
|
+
<pre id="cfg-switch-result" class="result" style="display:none"></pre>
|
|
421
|
+
</div>
|
|
422
|
+
|
|
423
|
+
<!-- Raw env (advanced, collapsed) -->
|
|
424
|
+
<details class="panel" style="padding: var(--s-5);">
|
|
425
|
+
<summary style="cursor:pointer;">Advanced — raw <code>~/.sigil/.env</code></summary>
|
|
426
|
+
<p class="muted text-sm">Secret keys (KEY / PASSWORD / TOKEN / SECRET) are masked.</p>
|
|
427
|
+
<div class="table-wrap">
|
|
428
|
+
<table id="env-table">
|
|
429
|
+
<thead><tr><th>Key</th><th>Value</th></tr></thead>
|
|
430
|
+
<tbody><tr><td colspan="2" class="empty">loading…</td></tr></tbody>
|
|
431
|
+
</table>
|
|
432
|
+
</div>
|
|
433
|
+
</details>
|
|
434
|
+
</section>
|
|
435
|
+
|
|
436
|
+
<!-- ── RPC ──────────────────────────────────────────────────── -->
|
|
437
|
+
<section id="view-methods" class="view">
|
|
438
|
+
<div class="section-head">
|
|
439
|
+
<div class="title-block">
|
|
440
|
+
<h2>RPC methods</h2>
|
|
441
|
+
<p>All methods registered on this daemon. CLI, MCP server, and this GUI dispatch through the same registry.</p>
|
|
442
|
+
</div>
|
|
443
|
+
</div>
|
|
444
|
+
<ul id="methods-list" class="methods-grid"></ul>
|
|
445
|
+
</section>
|
|
446
|
+
</main>
|
|
447
|
+
|
|
448
|
+
<footer>
|
|
449
|
+
<div class="footer-inner">
|
|
450
|
+
<span>Sigil GUI · loopback only · auth via <code>gui.token</code></span>
|
|
451
|
+
<span><span id="footer-version">v?</span> · pid <span id="footer-pid">—</span></span>
|
|
452
|
+
</div>
|
|
453
|
+
</footer>
|
|
454
|
+
|
|
455
|
+
<!-- ── Pair-create modal ──────────────────────────────────────── -->
|
|
456
|
+
<div id="dev-modal" class="modal" hidden>
|
|
457
|
+
<div class="modal-body" role="dialog" aria-modal="true">
|
|
458
|
+
<div class="modal-header">
|
|
459
|
+
<h3>Add device</h3>
|
|
460
|
+
<button class="modal-close" data-close-modal="dev-modal" aria-label="Close">×</button>
|
|
461
|
+
</div>
|
|
462
|
+
<div class="modal-content">
|
|
463
|
+
<form id="dev-form">
|
|
464
|
+
<label class="field"><span class="label">Device name</span><input type="text" id="dev-name" placeholder="laptop-b" autocomplete="off"></label>
|
|
465
|
+
<div class="row-2col">
|
|
466
|
+
<label class="field"><span class="label">Role</span>
|
|
467
|
+
<select id="dev-role">
|
|
468
|
+
<option value="reader">reader — read only</option>
|
|
469
|
+
<option value="writer" selected>writer — read + write</option>
|
|
470
|
+
<option value="admin">admin — full access</option>
|
|
471
|
+
</select>
|
|
472
|
+
</label>
|
|
473
|
+
<label class="field"><span class="label">TTL (seconds)</span><input type="number" id="dev-ttl" value="600"></label>
|
|
474
|
+
</div>
|
|
475
|
+
<label class="field"><span class="label">Namespaces <span class="muted">(comma-separated; empty = all)</span></span><input type="text" id="dev-ns" autocomplete="off"></label>
|
|
476
|
+
</form>
|
|
477
|
+
|
|
478
|
+
<div id="dev-result-view" hidden>
|
|
479
|
+
<div class="code-card">
|
|
480
|
+
<div class="lbl">Pairing code</div>
|
|
481
|
+
<div class="code" id="dev-result-code">—<button class="copy-btn" data-copy="dev-result-code">copy</button></div>
|
|
482
|
+
</div>
|
|
483
|
+
<div class="code-card">
|
|
484
|
+
<div class="lbl">Master NodeID</div>
|
|
485
|
+
<div class="code mono" style="font-size: var(--t-base);" id="dev-result-master">—<button class="copy-btn" data-copy="dev-result-master">copy</button></div>
|
|
486
|
+
</div>
|
|
487
|
+
<p class="muted text-sm">On the joining device, run:</p>
|
|
488
|
+
<div class="join-cmd" id="dev-result-cmd">—</div>
|
|
489
|
+
<button class="copy-btn" data-copy="dev-result-cmd" style="margin-top: var(--s-2);">copy command</button>
|
|
490
|
+
<p class="muted text-xs" style="margin-top: var(--s-3);">Expires <span id="dev-result-expiry" class="mono">—</span></p>
|
|
491
|
+
</div>
|
|
492
|
+
</div>
|
|
493
|
+
<div class="modal-footer">
|
|
494
|
+
<button type="button" class="btn ghost" data-close-modal="dev-modal" id="dev-cancel">Cancel</button>
|
|
495
|
+
<button type="button" class="btn primary" id="dev-create">Create pairing code</button>
|
|
496
|
+
<button type="button" class="btn primary" id="dev-done" hidden data-close-modal="dev-modal">Done</button>
|
|
497
|
+
</div>
|
|
498
|
+
</div>
|
|
499
|
+
</div>
|
|
500
|
+
|
|
501
|
+
<!-- ── Revoke modal ───────────────────────────────────────────── -->
|
|
502
|
+
<div id="revoke-modal" class="modal" hidden>
|
|
503
|
+
<div class="modal-body" role="dialog" aria-modal="true">
|
|
504
|
+
<div class="modal-header">
|
|
505
|
+
<h3>Revoke device</h3>
|
|
506
|
+
<button class="modal-close" data-close-modal="revoke-modal" aria-label="Close">×</button>
|
|
507
|
+
</div>
|
|
508
|
+
<div class="modal-content">
|
|
509
|
+
<p style="margin: 0 0 var(--s-3); color: var(--fg-2);">Revoke <strong id="revoke-target-name">—</strong>?</p>
|
|
510
|
+
<div class="radio-card-group">
|
|
511
|
+
<label class="radio-card selected">
|
|
512
|
+
<input type="radio" name="revoke-reason" value="paused" checked>
|
|
513
|
+
<div>
|
|
514
|
+
<div class="rc-title">Paused</div>
|
|
515
|
+
<div class="rc-desc">Temporary. The device can be re-activated from this dashboard.</div>
|
|
516
|
+
</div>
|
|
517
|
+
</label>
|
|
518
|
+
<label class="radio-card danger">
|
|
519
|
+
<input type="radio" name="revoke-reason" value="compromised">
|
|
520
|
+
<div>
|
|
521
|
+
<div class="rc-title">Compromised</div>
|
|
522
|
+
<div class="rc-desc">Terminal. The keypair leaked — re-activation is blocked.</div>
|
|
523
|
+
</div>
|
|
524
|
+
</label>
|
|
525
|
+
</div>
|
|
526
|
+
</div>
|
|
527
|
+
<div class="modal-footer">
|
|
528
|
+
<button type="button" class="btn ghost" data-close-modal="revoke-modal">Cancel</button>
|
|
529
|
+
<button type="button" class="btn danger" id="revoke-confirm">Revoke</button>
|
|
530
|
+
</div>
|
|
531
|
+
</div>
|
|
532
|
+
</div>
|
|
533
|
+
|
|
534
|
+
<script type="module" src="/static/app.js"></script>
|
|
535
|
+
</body>
|
|
536
|
+
</html>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
2
|
+
<!-- SVG created with Arrow, by QuiverAI (https://quiver.ai) -->
|
|
3
|
+
<style type="text/css">.cls-0 {fill:url(#SVGID_1_);}
|
|
4
|
+
.cls-1 {fill:url(#SVGID_2_);}
|
|
5
|
+
.cls-2 {fill:url(#SVGID_3_);}
|
|
6
|
+
.cls-3 {fill:url(#SVGID_4_);}</style>
|
|
7
|
+
<linearGradient id="SVGID_1_" x1="54.74" x2="98.29" y1="23.07" y2="10.4" gradientUnits="userSpaceOnUse">
|
|
8
|
+
<stop stop-color="#99D5FF" offset="0"/>
|
|
9
|
+
<stop stop-color="#0084FF" offset=".3602"/>
|
|
10
|
+
<stop stop-color="#004CE6" offset="1"/>
|
|
11
|
+
</linearGradient>
|
|
12
|
+
<path class="cls-0" d="m54.7 21.7v8.9h3.3l19.9-9.7 1.4-0.1 0.1 1.8-9.7 19.9v3.1h9.6l16.2-12.7 2.7-2.8v-27.9h-28.6l-14.9 19.5z"/>
|
|
13
|
+
<linearGradient id="SVGID_2_" x1="1.691" x2="45.24" y1="10.02" y2="32.95" gradientUnits="userSpaceOnUse">
|
|
14
|
+
<stop stop-color="#005CE6" offset=".3602"/>
|
|
15
|
+
<stop stop-color="#0084FF" offset=".7432"/>
|
|
16
|
+
<stop stop-color="#C9E7FF" offset="1"/>
|
|
17
|
+
</linearGradient>
|
|
18
|
+
<path class="cls-1" d="m2.2 2.2v27.9l2.7 2.2 15.8 13.4h9.5v-3.2l-9.8-20 0.1-1.8 1.6 0.1 19.9 9.8h3.2v-8.9l-14.9-19.5z"/>
|
|
19
|
+
<linearGradient id="SVGID_3_" x1="2.223" x2="45.24" y1="89.56" y2="67.06" gradientUnits="userSpaceOnUse">
|
|
20
|
+
<stop stop-color="#005CE6" offset=".3602"/>
|
|
21
|
+
<stop stop-color="#0084FF" offset=".7432"/>
|
|
22
|
+
<stop stop-color="#C9E7FF" offset="1"/>
|
|
23
|
+
</linearGradient>
|
|
24
|
+
<path class="cls-2" d="m20.6 54.4-17.2 13.2-1.2 1.6v28.7h28.1l14.9-19.4v-9.7h-3.3l-19.9 10.5-1.5 0.1v-1.8l9.7-19.8v-3.4z"/>
|
|
25
|
+
<linearGradient id="SVGID_4_" x1="54.74" x2="98.29" y1="78.41" y2="89.91" gradientUnits="userSpaceOnUse">
|
|
26
|
+
<stop stop-color="#99D5FF" offset="0"/>
|
|
27
|
+
<stop stop-color="#0084FF" offset=".3602"/>
|
|
28
|
+
<stop stop-color="#004CE6" offset="1"/>
|
|
29
|
+
</linearGradient>
|
|
30
|
+
<path class="cls-3" d="m54.7 68.8v9.7l14.9 19.4h28.7v-28.7l-19.1-14.8h-9.5v3.3l9.7 19.9-0.1 1.7h-1.4l-19.7-10.5z"/>
|
|
31
|
+
</svg>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central toast feedback — the only channel for transient status/errors.
|
|
3
|
+
* Design-system styled: a sharp surface-1 panel with a hairline border, a 7px
|
|
4
|
+
* status square (red/green/amber/brand) and an optional mono error code.
|
|
5
|
+
* Errors are sticky (no auto-dismiss); info/success fade. Replaces every
|
|
6
|
+
* inline `out.textContent = …` / `alert()` in the old GUI.
|
|
7
|
+
*/
|
|
8
|
+
function host() {
|
|
9
|
+
return document.getElementById('toasts');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function toast({ variant = 'info', message = '', hint, code, timeout } = {}) {
|
|
13
|
+
const stack = host();
|
|
14
|
+
if (!stack) return () => {};
|
|
15
|
+
|
|
16
|
+
const el = document.createElement('div');
|
|
17
|
+
el.className = `toast toast-${variant}`;
|
|
18
|
+
el.setAttribute('role', variant === 'error' ? 'alert' : 'status');
|
|
19
|
+
|
|
20
|
+
const sq = document.createElement('span');
|
|
21
|
+
sq.className = 'toast-sq';
|
|
22
|
+
|
|
23
|
+
const body = document.createElement('div');
|
|
24
|
+
body.className = 'toast-body';
|
|
25
|
+
|
|
26
|
+
const msg = document.createElement('div');
|
|
27
|
+
msg.className = 'toast-msg';
|
|
28
|
+
msg.textContent = message;
|
|
29
|
+
body.appendChild(msg);
|
|
30
|
+
|
|
31
|
+
if (hint) {
|
|
32
|
+
const h = document.createElement('div');
|
|
33
|
+
h.className = 'toast-hint';
|
|
34
|
+
h.textContent = hint;
|
|
35
|
+
body.appendChild(h);
|
|
36
|
+
}
|
|
37
|
+
if (code) {
|
|
38
|
+
const c = document.createElement('span');
|
|
39
|
+
c.className = 'toast-code';
|
|
40
|
+
c.textContent = code;
|
|
41
|
+
body.appendChild(c);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const x = document.createElement('button');
|
|
45
|
+
x.className = 'toast-x';
|
|
46
|
+
x.type = 'button';
|
|
47
|
+
x.textContent = '×';
|
|
48
|
+
x.setAttribute('aria-label', 'dismiss');
|
|
49
|
+
const remove = () => { el.remove(); };
|
|
50
|
+
x.onclick = remove;
|
|
51
|
+
|
|
52
|
+
el.append(sq, body, x);
|
|
53
|
+
stack.appendChild(el);
|
|
54
|
+
|
|
55
|
+
const ttl = timeout != null ? timeout : (variant === 'error' ? 0 : 4000);
|
|
56
|
+
if (ttl > 0) setTimeout(remove, ttl);
|
|
57
|
+
return remove;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const toastError = (o) => toast({ ...o, variant: 'error' });
|
|
61
|
+
export const toastOk = (o) => toast({ ...o, variant: 'success' });
|
|
62
|
+
export const toastInfo = (o) => toast({ ...o, variant: 'info' });
|