vault-go 0.32.0 → 0.33.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/dist/local-dashboard.js +46 -7
- package/dist/server.js +13 -1
- package/package.json +1 -1
package/dist/local-dashboard.js
CHANGED
|
@@ -6,7 +6,7 @@ export function dashboardHtml() {
|
|
|
6
6
|
|
|
7
7
|
/* Same identity tokens and glass surfaces as the Vault portal. */
|
|
8
8
|
:root{--c-canvas:8 11 18;--c-surface:24 29 45;--c-surface-2:32 38 56;--c-line:53 61 81;--c-fg:241 243 252;--c-muted:172 180 203;--c-faint:148 159 187;--c-accent:185 182 255;color:rgb(var(--c-fg));background:rgb(var(--c-canvas))}body{background:radial-gradient(ellipse at 85% 8%,#534ca02e,transparent 45%),linear-gradient(145deg,#080b12,#101321 58%,#080b12)}[hidden]{display:none!important}.shell{grid-template-columns:258px 1fr;max-width:1600px}.rail{background:linear-gradient(160deg,#1c2135f5,#101522f5);border-color:#cdd8ff26}.brand{font-size:15px;letter-spacing:-.3px;gap:10px;white-space:nowrap}.brand img,.onboarding-logo{object-fit:contain;filter:drop-shadow(0 5px 12px #7775c533)}.brand-sub{display:block;font-size:9px;letter-spacing:1.7px;color:#acb4cb;margin-top:7px}.card,.panel,.onboarding,.step,.notice{background:linear-gradient(135deg,#272c3ed1,#131724e0);border-color:#cdd8ff26;box-shadow:0 24px 70px -30px #0009,inset 0 1px 0 #ffffff0c;backdrop-filter:blur(28px) saturate(135%)}.nav a.active,.nav a:hover{background:#b9b6ff20;color:#d3d1ff}.eyebrow,.step-number,.empty-symbol{color:#b9b6ff}p,.card-label{color:#acb4cb}.card-note,.row-meta,.rail-footer,.rail-label,.footer{color:#949fbb}.pulse{color:#b9b6ff;border-color:#b9b6ff30;background:#b9b6ff0d}.button{background:#202638;color:#f1f3fc;border-color:#cdd8ff26;text-decoration:none;justify-content:center}.button:hover{border-color:#b9b6ff88}.primary{background:linear-gradient(135deg,#c8c5ff,#9d9bed);color:#15152f;border-color:transparent;font-weight:650;padding:13px 20px;font-size:14px}.primary:hover{background:#d3d1ff}.onboarding{border:1px solid #cdd8ff26;border-radius:20px;overflow:hidden;margin-top:30px;animation:arrive .6s ease both}.onboarding-hero{position:relative;padding:38px;background:radial-gradient(ellipse at 100% 0%,#7370d02c,transparent 62%)}.onboarding-logo{width:86px;height:86px;margin-bottom:24px}.onboarding h1{font-size:36px;max-width:600px;line-height:1.12;margin:12px 0 18px}.onboarding-hero>p{max-width:570px;font-size:14px;line-height:1.8}.actions{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-top:25px}.link{color:#d3d1ff;text-decoration:none;font-size:12px}.link:hover{text-decoration:underline}.onboarding-hint{font-size:11px!important;color:#949fbb;margin-top:15px!important}.steps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));border-top:1px solid #cdd8ff26}.step{padding:25px;background:#080b122b;box-shadow:none;border-right:1px solid #cdd8ff16}.step:last-child{border:0}.step-number{font-family:monospace;font-size:11px;margin-bottom:13px}.step h2{margin-bottom:9px}.step p{font-size:12px}.terminal-fallback{padding:22px 30px;border-top:1px solid #cdd8ff26;background:#080b1233}.terminal-fallback p{font-size:12px}.terminal-fallback code{display:block;margin-top:10px;font-size:12px;color:#d3d1ff;overflow-wrap:anywhere}.connection-message{margin-top:18px;font-size:12px;color:#d3d1ff;min-height:18px}.next-step{display:flex;justify-content:space-between;align-items:center;gap:20px;margin-top:22px;padding:23px;border:1px solid #b9b6ff30;border-radius:14px;background:#b9b6ff09}.next-step h2{margin-bottom:8px}.next-step p{font-size:12px}.next-step .actions{margin:0;flex-shrink:0}button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible{outline-color:#b9b6ff}.notice code{color:#d3d1ff}.search{border-color:#cdd8ff26;background:#0307117a}.breadcrumb b{color:#f1f3fc}.rail-footer .dot{background:#b9b6ff}.footer{margin-top:28px}@media(max-width:1100px){.shell{grid-template-columns:225px 1fr}.brand{font-size:13px}.main{padding:25px}.onboarding-hero{padding:30px}.next-step{align-items:flex-start;flex-direction:column}}@media(max-width:680px){.shell{display:block}.brand{font-size:16px}.onboarding{margin-top:22px}.onboarding-hero{padding:26px}.onboarding h1{font-size:30px}.onboarding-logo{width:65px;height:65px;margin-bottom:15px}.steps{grid-template-columns:1fr}.step{padding:20px 26px;border-right:0;border-bottom:1px solid #cdd8ff16}.step-number{margin-bottom:8px}.terminal-fallback{padding:22px 26px}.main{padding:20px}.next-step .actions{flex-shrink:1}.onboarding .actions .button{width:100%}.onboarding .actions .link{padding:8px 0}.card-value{overflow-wrap:anywhere}.nav{padding-bottom:2px}}
|
|
9
|
-
.danger{border-color:#ed9a9a66;color:#ffb5b5;background:#53272d55}.danger:hover{border-color:#ffb5b5}.danger-title{color:#ffb5b5}.pagination{display:flex;gap:9px;align-items:center;flex-wrap:wrap;border-top:1px solid #cdd8ff20;margin-top:15px;padding-top:15px;color:#acb4cb;font-size:11px}.pagination label{display:flex;align-items:center;gap:7px}.pagination .page-summary{flex:1;min-width:95px}.pagination select{padding:7px}.pagination .button{padding:7px 10px}.pagination button:disabled{cursor:default}.row-open{background:transparent;border:0;text-align:left;padding:0;color:#d3d1ff;cursor:pointer;font:inherit}.row-open:hover{text-decoration:underline}.row-actions{padding-top:5px}.detail-dialog{color:#f1f3fc;background:linear-gradient(135deg,#272c3e,#131724);border:1px solid #cdd8ff40;border-radius:18px;max-width:800px;width:calc(100% - 32px);max-height:85vh;padding:26px;box-shadow:0 30px 100px #0009}.detail-dialog::backdrop{background:#050710bd;backdrop-filter:blur(5px)}.detail-dialog h2{font-size:20px;overflow-wrap:anywhere}.detail-fields{margin:0}.detail-fields dt{color:#acb4cb;font-size:11px;margin:20px 0 8px}.detail-fields dd{margin:0;font-size:13px;line-height:1.7;white-space:pre-wrap;overflow-wrap:anywhere}.detail-fields pre{font:inherit;white-space:pre-wrap;margin:0}.clamped{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:8;overflow:hidden}.row-title.clamped{-webkit-line-clamp:3}.show-more{background:transparent;border:0;padding:6px 0 0;color:#b9b6ff;font:inherit;font-size:12px;cursor:pointer}.show-more:hover{text-decoration:underline}.show-more:focus-visible{outline:2px solid #b9b6ff;outline-offset:3px;border-radius:4px}.engine-options{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-top:18px}.engine-keys{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px;margin-top:16px}.engine-keys label{display:block;font-size:12px;margin-bottom:8px}.engine-keys input{width:100%;background:#0307117a;color:#f1f3fc;border:1px solid #cdd8ff26;border-radius:9px;padding:10px 12px;font:inherit;font-size:13px;margin-bottom:8px}.engine-option{display:block;padding:17px;border:1px solid #cdd8ff26;border-radius:10px;background:#080b1233;cursor:pointer}.engine-option:has(input:checked){border-color:#b9b6ff;background:#b9b6ff12}.engine-option:has(input:disabled){opacity:.7;cursor:default}.engine-option input{accent-color:#b9b6ff;margin-right:8px}.engine-option strong{font-size:12px}.engine-option p{font-size:11px;margin-top:9px}.engine-message{margin-top:13px;font-size:12px;color:#d3d1ff}.context-editor{margin-top:20px}.context-editor label{display:block;font-size:12px;margin-bottom:8px}.context-editor textarea{width:100%;min-height:130px;resize:vertical;background:#0307117a;color:#f1f3fc;border:1px solid #cdd8ff26;border-radius:9px;padding:12px;font:inherit;font-size:13px}.context-editor textarea:focus-visible{outline:2px solid #b9b6ff;outline-offset:3px}.mcp-clients{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:10px;margin-top:14px}.mcp-client{display:flex;align-items:center;justify-content:space-between;gap:10px;border:1px solid #cdd8ff26;border-radius:10px;padding:10px 12px;background:#080b1233;font-size:13px;flex-wrap:wrap}.mcp-client strong{font-size:13px;font-weight:600}.mcp-state{font-size:11px;color:#8edbc8;white-space:nowrap}.mcp-dim{opacity:.75}.mcp-evidence{font-size:10px;color:#949fbb;width:100%}.mcp-note{color:#949fbb;font-size:12px}.mcp-message{color:#ed9a9a;font-size:12px;margin-top:10px}.mcp-message:empty{display:none}.mcp-fallback{color:#949fbb;font-size:11px;margin-top:12px}.mcp-fallback code{font-size:11px;color:#c7d4df;background:#0307117a;border-radius:6px;padding:2px 6px}@media(max-width:800px){.engine-options{grid-template-columns:1fr}}@media(prefers-reduced-motion:reduce){.detail-dialog::backdrop{backdrop-filter:none}}</style><script src="/app.js" defer></script></head><body><div class="shell"><aside class="rail"><div class="brand"><img src="/logo.png" alt="" width="46" height="46"><div>AI Vault Memory<span class="brand-sub">LOCAL AGENT</span></div></div><div class="rail-label" data-i18n="workspace">WORKSPACE</div><nav class="nav" aria-label="Navigation"><a class="active" href="#overview"><span class="icon">◈</span><span data-i18n="overview">Overview</span></a><a href="#activity"><span class="icon">⌁</span><span data-i18n="activity">Activity</span></a><a href="#memories"><span class="icon">▤</span><span data-i18n="memories">Memories</span></a><a href="#context"><span class="icon">✧</span><span data-i18n="contextEngine">Context engine</span></a><a href="#projects"><span class="icon">▱</span><span data-i18n="projects">Projects</span></a></nav><div class="rail-footer"><span class="dot"></span><span data-i18n="localWorkspace">Your local workspace</span><br><span data-i18n="privacy">Activity metadata stays local.</span></div></aside><main class="main" id="overview"><header class="top"><div class="breadcrumb">Vault <span aria-hidden="true"> / </span><b data-i18n="localMonitor">Local monitor</b></div><div class="controls"><select id="locale" aria-label="Language"><option value="en">English</option><option value="pt">Português</option><option value="es">Español</option></select><button class="button" id="logout" type="button" hidden data-i18n="logout">Sign out of dashboard</button><button class="button" id="reconnect" type="button" hidden data-i18n="reconnect">Reconnect account</button><button class="button" id="refresh" type="button"><span aria-hidden="true">↻</span><span data-i18n="refresh">Refresh cloud</span></button></div></header><div id="error" class="error" role="status" aria-live="polite"></div><section class="onboarding" id="onboarding"><div class="onboarding-hero"><img class="onboarding-logo" src="/logo.png" alt="" width="86" height="86"><div class="eyebrow" data-i18n="connectEyebrow">AI VAULT MEMORY · LOCAL</div><h1 data-i18n="connectTitle">Your memory. Connected to this machine.</h1><p data-i18n="connectIntro">Connect your Vault account to see your memories, projects and recent activity in one place.</p><div class="actions"><button type="button" class="button primary" id="connect" data-i18n="connect">Connect to Vault</button><a class="link" href="${VAULT_WEB_APP_URL}" target="_blank" rel="noopener noreferrer" data-i18n="openPortal">Open Vault portal ↗</a></div><p class="onboarding-hint" data-i18n="connectHint">Sign in securely in a separate window. Your password stays with the Vault portal.</p><div class="connection-message" id="connection-message" role="status" aria-live="polite"></div><a id="auth-fallback" class="button" hidden target="_blank" rel="noopener noreferrer" data-i18n="continueAuth">Continue sign-in ↗</a></div><div class="steps"><article class="step"><div class="step-number">01 / VAULT</div><h2 data-i18n="stepAccount">Connect your account</h2><p data-i18n="stepAccountBody">Sign in to Vault and authorize this local agent.</p></article><article class="step"><div class="step-number">02 / MCP</div><h2 data-i18n="stepClient">Connect your AI clients</h2><p data-i18n="stepClientBody">After signing in, connect Claude, Codex and other clients with one click, right here.</p></article><article class="step"><div class="step-number">03 / MEMORY</div><h2 data-i18n="stepMemory">Build your first memory</h2><p data-i18n="stepMemoryBody">Ask your connected client to save useful context, then follow its activity here.</p></article></div><div class="terminal-fallback"><button class="button" id="verify-connection" type="button" data-i18n="verifyConnection">Already signed in? Check connection</button><p style="margin-top:16px" data-i18n="terminalFallback">Already connected through the CLI? Open a secure local session:</p><code>bunx --bun vault-go@latest local open</code></div></section><div id="dashboard" hidden><div class="welcome"><div><div class="eyebrow" data-i18n="eyebrow">YOUR KNOWLEDGE, CONNECTED</div><h1 data-i18n="title">Your local workspace.</h1><p data-i18n="subtitle">Your Vault account, memories and activity on this machine.</p></div><img src="/logo.png" alt="" width="56" height="56"></div><div id="session-notice" hidden></div><section class="cards" aria-label="Status"><article class="card"><div class="card-label"><span data-i18n="localService">Local service</span><span aria-hidden="true">◈</span></div><div class="card-value" id="local-status">—</div><div class="card-note" id="local-note">localhost:38850</div></article><article class="card"><div class="card-label"><span data-i18n="cloudConnection">Cloud connection</span><span aria-hidden="true">↗</span></div><div class="card-value" id="cloud-status">—</div><div class="card-note" id="cloud-note">—</div></article><article class="card"><div class="card-label"><span data-i18n="recentOperations">Recent operations</span><span aria-hidden="true">⌁</span></div><div class="card-value" id="activity-total">—</div><div class="card-note" data-i18n="operationsNote">Recent MCP request metadata</div></article></section><section class="next-step" id="first-memory"><div><h2 data-i18n="firstTitle">Connect your AI clients</h2><p data-i18n="firstBody">Connect Claude, Codex and other clients here in one click, then ask them to save context. Memories appear after a cloud refresh.</p><div class="mcp-clients" id="mcp-clients" role="group" aria-label="AI clients"></div><p id="mcp-message" role="status" aria-live="polite" class="mcp-message"></p><p data-i18n="rememberPrompt" style="margin-top:10px"></p><p class="mcp-fallback"><span data-i18n="mcpFallback"></span> <code>bunx --bun vault-go@latest install</code></p></div><div class="actions"><a class="link" href="${VAULT_WEB_MCP_URL}" target="_blank" rel="noopener noreferrer" data-i18n="otherClients">Other clients ↗</a><a class="link" href="${VAULT_WEB_MEMORY_URL}" target="_blank" rel="noopener noreferrer" data-i18n="openMemories">Open memories ↗</a></div></section><div class="layout"><section class="panel wide" id="security"><div class="panel-head"><h2 data-i18n="securityTitle">Security on this machine</h2></div><div id="security-facts"></div><div class="actions"><button class="button danger" id="disconnect-device" type="button" data-i18n="disconnectDevice">Disconnect device</button></div></section><section class="panel wide" id="context"><div class="panel-head"><h2 data-i18n="contextEngine">Context engine</h2></div><p data-i18n="engineIntro">Choose how Vault prepares your context.</p><div class="engine-options" id="engine-options" role="radiogroup" aria-label="Context engine"></div><div class="engine-options" id="model-options" role="radiogroup" aria-label="Context model"></div><div class="engine-keys" id="engine-keys"></div><div class="engine-message" id="engine-message" role="status" aria-live="polite"></div><div class="context-editor"><label for="context-text" data-i18n="contextText">Text to prepare</label><textarea id="context-text" maxlength="16000" aria-describedby="context-note"></textarea><p id="context-note" data-i18n="contextNote"></p><div class="actions"><button class="button primary" id="context-preview" type="button" data-i18n="contextPreview"></button><button class="button" id="context-stop" type="button" data-i18n="cancel" hidden></button></div><p id="context-progress" role="status" aria-live="polite"></p></div></section><section class="panel" id="activity"><div class="panel-head"><h2 data-i18n="activity">Activity</h2><span class="count" id="activity-count">0</span></div><input class="search" id="activity-search" type="search" data-placeholder="searchActivity" aria-label="Search activity"><div id="activity-list"></div><div class="pagination" id="activity-pagination"></div></section><section class="panel" id="memories"><div class="panel-head"><h2 data-i18n="memories">Memories</h2><span class="count" id="memory-count">0</span></div><input class="search" id="memory-search" type="search" data-placeholder="searchMemories" aria-label="Search memories"><div id="memory-list"></div><div class="pagination" id="memory-pagination"></div></section><section class="panel wide" id="projects"><div class="panel-head"><h2 data-i18n="projects">Projects</h2><span class="count" id="project-count">0</span></div><input class="search" id="project-search" type="search" data-placeholder="searchProjects" aria-label="Search projects"><div id="project-list"></div><div class="pagination" id="project-pagination"></div></section></div></div><footer class="footer"><span data-i18n="footer">Vault Local · Context with a place to call home.</span><span id="updated" aria-live="off">—</span></footer></main></div><dialog class="detail-dialog" id="detail-dialog" aria-labelledby="detail-title"><div class="panel-head"><h2 id="detail-title"></h2><button class="button" type="button" id="detail-copy" hidden data-i18n="copyResult">Copy result</button><button class="button" type="button" id="detail-close" data-i18n="close">Close</button></div><dl class="detail-fields" id="detail-fields"></dl></dialog><dialog class="detail-dialog" id="logout-dialog" aria-labelledby="logout-title" aria-describedby="logout-description"><h2 id="logout-title" data-i18n="logout"></h2><p id="logout-description" data-i18n="logoutDescription" style="margin-top:16px"></p><div class="actions"><button class="button" type="button" id="logout-cancel" data-i18n="cancel"></button><button class="button primary" type="button" id="logout-confirm" data-i18n="logoutConfirm"></button></div></dialog><dialog class="detail-dialog" id="context-confirm-dialog" aria-labelledby="context-confirm-title" aria-describedby="context-confirm-note"><h2 id="context-confirm-title" data-i18n="contextPreview"></h2><p id="context-confirm-engine" style="margin-top:16px"></p><p id="context-confirm-billing"></p><p id="context-confirm-note" data-i18n="contextConsentNote" style="margin-top:16px"></p><pre id="context-confirm-text" style="white-space:pre-wrap;overflow-wrap:anywhere;max-height:32vh;overflow:auto;font-size:12px;line-height:1.7"></pre><label style="display:flex;gap:10px;align-items:flex-start;font-size:12px"><input id="context-consent" type="checkbox"><span data-i18n="contextConsent"></span></label><div class="actions"><button class="button" id="context-cancel" type="button" data-i18n="cancel"></button><button class="button primary" id="context-generate" type="button" disabled data-i18n="contextGenerate"></button></div></dialog><dialog class="detail-dialog" id="disconnect-dialog" aria-labelledby="disconnect-title" aria-describedby="disconnect-description"><h2 class="danger-title" id="disconnect-title" data-i18n="disconnectDevice"></h2><p id="disconnect-description" data-i18n="disconnectDescription" style="margin-top:16px"></p><p id="disconnect-error" class="error" role="alert"></p><div class="actions"><button class="button" type="button" id="disconnect-cancel" data-i18n="cancel"></button><button class="button danger" type="button" id="disconnect-confirm" data-i18n="disconnectConfirm"></button></div></dialog></body></html>`;
|
|
9
|
+
.danger{border-color:#ed9a9a66;color:#ffb5b5;background:#53272d55}.danger:hover{border-color:#ffb5b5}.danger-title{color:#ffb5b5}.pagination{display:flex;gap:9px;align-items:center;flex-wrap:wrap;border-top:1px solid #cdd8ff20;margin-top:15px;padding-top:15px;color:#acb4cb;font-size:11px}.pagination label{display:flex;align-items:center;gap:7px}.pagination .page-summary{flex:1;min-width:95px}.pagination select{padding:7px}.pagination .button{padding:7px 10px}.pagination button:disabled{cursor:default}.row-open{background:transparent;border:0;text-align:left;padding:0;color:#d3d1ff;cursor:pointer;font:inherit}.row-open:hover{text-decoration:underline}.row-actions{padding-top:5px}.detail-dialog{color:#f1f3fc;background:linear-gradient(135deg,#272c3e,#131724);border:1px solid #cdd8ff40;border-radius:18px;max-width:800px;width:calc(100% - 32px);max-height:85vh;padding:26px;box-shadow:0 30px 100px #0009}.detail-dialog::backdrop{background:#050710bd;backdrop-filter:blur(5px)}.detail-dialog h2{font-size:20px;overflow-wrap:anywhere}.detail-fields{margin:0}.detail-fields dt{color:#acb4cb;font-size:11px;margin:20px 0 8px}.detail-fields dd{margin:0;font-size:13px;line-height:1.7;white-space:pre-wrap;overflow-wrap:anywhere}.detail-fields pre{font:inherit;white-space:pre-wrap;margin:0}.clamped{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:8;overflow:hidden}.row-title.clamped{-webkit-line-clamp:3}.show-more{background:transparent;border:0;padding:6px 0 0;color:#b9b6ff;font:inherit;font-size:12px;cursor:pointer}.show-more:hover{text-decoration:underline}.show-more:focus-visible{outline:2px solid #b9b6ff;outline-offset:3px;border-radius:4px}.row-tags{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}.tag{font-size:10px;letter-spacing:.02em;color:#c9c6ff;background:#b9b6ff14;border:1px solid #b9b6ff33;border-radius:999px;padding:2px 8px}.detail-list{margin:0;padding-left:18px}.detail-list li{margin:2px 0}.detail-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:22px}.engine-options{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-top:18px}.engine-keys{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px;margin-top:16px}.engine-keys label{display:block;font-size:12px;margin-bottom:8px}.engine-keys input{width:100%;background:#0307117a;color:#f1f3fc;border:1px solid #cdd8ff26;border-radius:9px;padding:10px 12px;font:inherit;font-size:13px;margin-bottom:8px}.engine-option{display:block;padding:17px;border:1px solid #cdd8ff26;border-radius:10px;background:#080b1233;cursor:pointer}.engine-option:has(input:checked){border-color:#b9b6ff;background:#b9b6ff12}.engine-option:has(input:disabled){opacity:.7;cursor:default}.engine-option input{accent-color:#b9b6ff;margin-right:8px}.engine-option strong{font-size:12px}.engine-option p{font-size:11px;margin-top:9px}.engine-message{margin-top:13px;font-size:12px;color:#d3d1ff}.context-editor{margin-top:20px}.context-editor label{display:block;font-size:12px;margin-bottom:8px}.context-editor textarea{width:100%;min-height:130px;resize:vertical;background:#0307117a;color:#f1f3fc;border:1px solid #cdd8ff26;border-radius:9px;padding:12px;font:inherit;font-size:13px}.context-editor textarea:focus-visible{outline:2px solid #b9b6ff;outline-offset:3px}.mcp-clients{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:10px;margin-top:14px}.mcp-client{display:flex;align-items:center;justify-content:space-between;gap:10px;border:1px solid #cdd8ff26;border-radius:10px;padding:10px 12px;background:#080b1233;font-size:13px;flex-wrap:wrap}.mcp-client strong{font-size:13px;font-weight:600}.mcp-state{font-size:11px;color:#8edbc8;white-space:nowrap}.mcp-dim{opacity:.75}.mcp-evidence{font-size:10px;color:#949fbb;width:100%}.mcp-note{color:#949fbb;font-size:12px}.mcp-message{color:#ed9a9a;font-size:12px;margin-top:10px}.mcp-message:empty{display:none}.mcp-fallback{color:#949fbb;font-size:11px;margin-top:12px}.mcp-fallback code{font-size:11px;color:#c7d4df;background:#0307117a;border-radius:6px;padding:2px 6px}@media(max-width:800px){.engine-options{grid-template-columns:1fr}}@media(prefers-reduced-motion:reduce){.detail-dialog::backdrop{backdrop-filter:none}}</style><script src="/app.js" defer></script></head><body><div class="shell"><aside class="rail"><div class="brand"><img src="/logo.png" alt="" width="46" height="46"><div>AI Vault Memory<span class="brand-sub">LOCAL AGENT</span></div></div><div class="rail-label" data-i18n="workspace">WORKSPACE</div><nav class="nav" aria-label="Navigation"><a class="active" href="#overview"><span class="icon">◈</span><span data-i18n="overview">Overview</span></a><a href="#activity"><span class="icon">⌁</span><span data-i18n="activity">Activity</span></a><a href="#memories"><span class="icon">▤</span><span data-i18n="memories">Memories</span></a><a href="#context"><span class="icon">✧</span><span data-i18n="contextEngine">Context engine</span></a><a href="#projects"><span class="icon">▱</span><span data-i18n="projects">Projects</span></a></nav><div class="rail-footer"><span class="dot"></span><span data-i18n="localWorkspace">Your local workspace</span><br><span data-i18n="privacy">Activity metadata stays local.</span></div></aside><main class="main" id="overview"><header class="top"><div class="breadcrumb">Vault <span aria-hidden="true"> / </span><b data-i18n="localMonitor">Local monitor</b></div><div class="controls"><select id="locale" aria-label="Language"><option value="en">English</option><option value="pt">Português</option><option value="es">Español</option></select><button class="button" id="logout" type="button" hidden data-i18n="logout">Sign out of dashboard</button><button class="button" id="reconnect" type="button" hidden data-i18n="reconnect">Reconnect account</button><button class="button" id="refresh" type="button"><span aria-hidden="true">↻</span><span data-i18n="refresh">Refresh cloud</span></button></div></header><div id="error" class="error" role="status" aria-live="polite"></div><section class="onboarding" id="onboarding"><div class="onboarding-hero"><img class="onboarding-logo" src="/logo.png" alt="" width="86" height="86"><div class="eyebrow" data-i18n="connectEyebrow">AI VAULT MEMORY · LOCAL</div><h1 data-i18n="connectTitle">Your memory. Connected to this machine.</h1><p data-i18n="connectIntro">Connect your Vault account to see your memories, projects and recent activity in one place.</p><div class="actions"><button type="button" class="button primary" id="connect" data-i18n="connect">Connect to Vault</button><a class="link" href="${VAULT_WEB_APP_URL}" target="_blank" rel="noopener noreferrer" data-i18n="openPortal">Open Vault portal ↗</a></div><p class="onboarding-hint" data-i18n="connectHint">Sign in securely in a separate window. Your password stays with the Vault portal.</p><div class="connection-message" id="connection-message" role="status" aria-live="polite"></div><a id="auth-fallback" class="button" hidden target="_blank" rel="noopener noreferrer" data-i18n="continueAuth">Continue sign-in ↗</a></div><div class="steps"><article class="step"><div class="step-number">01 / VAULT</div><h2 data-i18n="stepAccount">Connect your account</h2><p data-i18n="stepAccountBody">Sign in to Vault and authorize this local agent.</p></article><article class="step"><div class="step-number">02 / MCP</div><h2 data-i18n="stepClient">Connect your AI clients</h2><p data-i18n="stepClientBody">After signing in, connect Claude, Codex and other clients with one click, right here.</p></article><article class="step"><div class="step-number">03 / MEMORY</div><h2 data-i18n="stepMemory">Build your first memory</h2><p data-i18n="stepMemoryBody">Ask your connected client to save useful context, then follow its activity here.</p></article></div><div class="terminal-fallback"><button class="button" id="verify-connection" type="button" data-i18n="verifyConnection">Already signed in? Check connection</button><p style="margin-top:16px" data-i18n="terminalFallback">Already connected through the CLI? Open a secure local session:</p><code>bunx --bun vault-go@latest local open</code></div></section><div id="dashboard" hidden><div class="welcome"><div><div class="eyebrow" data-i18n="eyebrow">YOUR KNOWLEDGE, CONNECTED</div><h1 data-i18n="title">Your local workspace.</h1><p data-i18n="subtitle">Your Vault account, memories and activity on this machine.</p></div><img src="/logo.png" alt="" width="56" height="56"></div><div id="session-notice" hidden></div><section class="cards" aria-label="Status"><article class="card"><div class="card-label"><span data-i18n="localService">Local service</span><span aria-hidden="true">◈</span></div><div class="card-value" id="local-status">—</div><div class="card-note" id="local-note">localhost:38850</div></article><article class="card"><div class="card-label"><span data-i18n="cloudConnection">Cloud connection</span><span aria-hidden="true">↗</span></div><div class="card-value" id="cloud-status">—</div><div class="card-note" id="cloud-note">—</div></article><article class="card"><div class="card-label"><span data-i18n="recentOperations">Recent operations</span><span aria-hidden="true">⌁</span></div><div class="card-value" id="activity-total">—</div><div class="card-note" data-i18n="operationsNote">Recent MCP request metadata</div></article></section><section class="next-step" id="first-memory"><div><h2 data-i18n="firstTitle">Connect your AI clients</h2><p data-i18n="firstBody">Connect Claude, Codex and other clients here in one click, then ask them to save context. Memories appear after a cloud refresh.</p><div class="mcp-clients" id="mcp-clients" role="group" aria-label="AI clients"></div><p id="mcp-message" role="status" aria-live="polite" class="mcp-message"></p><p data-i18n="rememberPrompt" style="margin-top:10px"></p><p class="mcp-fallback"><span data-i18n="mcpFallback"></span> <code>bunx --bun vault-go@latest install</code></p></div><div class="actions"><a class="link" href="${VAULT_WEB_MCP_URL}" target="_blank" rel="noopener noreferrer" data-i18n="otherClients">Other clients ↗</a><a class="link" href="${VAULT_WEB_MEMORY_URL}" target="_blank" rel="noopener noreferrer" data-i18n="openMemories">Open memories ↗</a></div></section><div class="layout"><section class="panel wide" id="security"><div class="panel-head"><h2 data-i18n="securityTitle">Security on this machine</h2></div><div id="security-facts"></div><div class="actions"><button class="button danger" id="disconnect-device" type="button" data-i18n="disconnectDevice">Disconnect device</button></div></section><section class="panel wide" id="context"><div class="panel-head"><h2 data-i18n="contextEngine">Context engine</h2></div><p data-i18n="engineIntro">Choose how Vault prepares your context.</p><div class="engine-options" id="engine-options" role="radiogroup" aria-label="Context engine"></div><div class="engine-options" id="model-options" role="radiogroup" aria-label="Context model"></div><div class="engine-keys" id="engine-keys"></div><div class="engine-message" id="engine-message" role="status" aria-live="polite"></div><div class="context-editor"><label for="context-text" data-i18n="contextText">Text to prepare</label><textarea id="context-text" maxlength="16000" aria-describedby="context-note"></textarea><p id="context-note" data-i18n="contextNote"></p><div class="actions"><button class="button primary" id="context-preview" type="button" data-i18n="contextPreview"></button><button class="button" id="context-stop" type="button" data-i18n="cancel" hidden></button></div><p id="context-progress" role="status" aria-live="polite"></p></div></section><section class="panel" id="activity"><div class="panel-head"><h2 data-i18n="activity">Activity</h2><span class="count" id="activity-count">0</span></div><input class="search" id="activity-search" type="search" data-placeholder="searchActivity" aria-label="Search activity"><div id="activity-list"></div><div class="pagination" id="activity-pagination"></div></section><section class="panel" id="memories"><div class="panel-head"><h2 data-i18n="memories">Memories</h2><span class="count" id="memory-count">0</span></div><input class="search" id="memory-search" type="search" data-placeholder="searchMemories" aria-label="Search memories"><div id="memory-list"></div><div class="pagination" id="memory-pagination"></div></section><section class="panel wide" id="projects"><div class="panel-head"><h2 data-i18n="projects">Projects</h2><span class="count" id="project-count">0</span></div><input class="search" id="project-search" type="search" data-placeholder="searchProjects" aria-label="Search projects"><div id="project-list"></div><div class="pagination" id="project-pagination"></div></section></div></div><footer class="footer"><span data-i18n="footer">Vault Local · Context with a place to call home.</span><span id="updated" aria-live="off">—</span></footer></main></div><dialog class="detail-dialog" id="detail-dialog" aria-labelledby="detail-title"><div class="panel-head"><h2 id="detail-title"></h2><a class="button" id="detail-open" hidden target="_blank" rel="noopener noreferrer" data-i18n="openInVault">Open in Vault ↗</a><button class="button" type="button" id="detail-copy" hidden data-i18n="copyResult">Copy result</button><button class="button" type="button" id="detail-close" data-i18n="close">Close</button></div><dl class="detail-fields" id="detail-fields"></dl></dialog><dialog class="detail-dialog" id="logout-dialog" aria-labelledby="logout-title" aria-describedby="logout-description"><h2 id="logout-title" data-i18n="logout"></h2><p id="logout-description" data-i18n="logoutDescription" style="margin-top:16px"></p><div class="actions"><button class="button" type="button" id="logout-cancel" data-i18n="cancel"></button><button class="button primary" type="button" id="logout-confirm" data-i18n="logoutConfirm"></button></div></dialog><dialog class="detail-dialog" id="context-confirm-dialog" aria-labelledby="context-confirm-title" aria-describedby="context-confirm-note"><h2 id="context-confirm-title" data-i18n="contextPreview"></h2><p id="context-confirm-engine" style="margin-top:16px"></p><p id="context-confirm-billing"></p><p id="context-confirm-note" data-i18n="contextConsentNote" style="margin-top:16px"></p><pre id="context-confirm-text" style="white-space:pre-wrap;overflow-wrap:anywhere;max-height:32vh;overflow:auto;font-size:12px;line-height:1.7"></pre><label style="display:flex;gap:10px;align-items:flex-start;font-size:12px"><input id="context-consent" type="checkbox"><span data-i18n="contextConsent"></span></label><div class="actions"><button class="button" id="context-cancel" type="button" data-i18n="cancel"></button><button class="button primary" id="context-generate" type="button" disabled data-i18n="contextGenerate"></button></div></dialog><dialog class="detail-dialog" id="disconnect-dialog" aria-labelledby="disconnect-title" aria-describedby="disconnect-description"><h2 class="danger-title" id="disconnect-title" data-i18n="disconnectDevice"></h2><p id="disconnect-description" data-i18n="disconnectDescription" style="margin-top:16px"></p><p id="disconnect-error" class="error" role="alert"></p><div class="actions"><button class="button" type="button" id="disconnect-cancel" data-i18n="cancel"></button><button class="button danger" type="button" id="disconnect-confirm" data-i18n="disconnectConfirm"></button></div></dialog></body></html>`;
|
|
10
10
|
}
|
|
11
11
|
export function dashboardScript() {
|
|
12
12
|
return `"use strict";
|
|
@@ -35,7 +35,12 @@ export function dashboardScript() {
|
|
|
35
35
|
es:{engineUpdateCli:'Actualiza el CLI oficial a una versión compatible con la generación aislada de contexto.',engineClaudeLogin:'Inicia sesión con tu suscripción Claude usando claude auth login.',engineCodexLogin:'Inicia sesión con tu cuenta ChatGPT usando codex login.',engineCliUnavailable:'CLI oficial o sesión de la suscripción no disponible. Instala el CLI del proveedor o inicia sesión mediante él.',engineVaultUnavailable:'Vault AI Resume no está configurado o no está disponible para esta cuenta.',engineProviderCheck:'La disponibilidad del proveedor se comprobará al generar.',engineObserverMissing:'El observador administrado no está configurado.',engineOpenrouterKey:'Configura una clave OpenRouter con vault-go engine key openrouter.',engineGeminiKey:'Configura una clave Gemini con vault-go engine key gemini.',billingVault:'Usa la cuota del observador de Vault.',billingClaude:'Usa la cuota del proveedor para ejecuciones no interactivas de Claude Code; pueden aplicarse límites y cargos adicionales.',billingOpenai:'Usa tu suscripción ChatGPT mediante Codex. Pueden aplicarse límites o créditos de uso del proveedor.',billingOpenrouter:'Usa tu clave y créditos de OpenRouter. Pueden aplicarse límites del proveedor.',billingGemini:'Usa tu clave de la API Gemini. Pueden aplicarse límites o facturación de Google.',openrouterKey:'Clave OpenRouter',geminiKey:'Clave Gemini',saveKey:'Guardar clave',keyConfigured:'Clave configurada en este equipo',keyMissing:'Pega la clave y guarda',keySaved:'Clave guardada con permisos privados.',keyFailed:'No se pudo guardar la clave. Inténtalo de nuevo.',keyOs:'Llavero del sistema operativo',keyFile:'Archivo local protegido por permisos',keyEphemeral:'Solo en memoria durante esta ejecución',keyUnavailable:'No disponible'}
|
|
36
36
|
};
|
|
37
37
|
const disclosureCopy={en:{showMore:'Show more',showLess:'Show less'},pt:{showMore:'Mostrar mais',showLess:'Mostrar menos'},es:{showMore:'Mostrar más',showLess:'Mostrar menos'}};
|
|
38
|
-
|
|
38
|
+
const memoryCopy={
|
|
39
|
+
en:{openInVault:'Open in Vault ↗',fieldContent:'Content',fieldFacts:'Facts',fieldConcepts:'Concepts',fieldFilesRead:'Files read',fieldFilesModified:'Files modified',fieldType:'Type',fieldProject:'Project',fieldSource:'Source',fieldCreated:'Created',fieldId:'ID',typeDecision:'Decision',typeDiscovery:'Discovery',typeFix:'Fix',typeFeature:'Feature',typeRefactor:'Refactor',typeChange:'Change',typeTask:'Task',typeQuestion:'Question',typeInstruction:'Instruction',kindPrompt:'Prompt',kindSummary:'Summary',kindObservation:'Observation'},
|
|
40
|
+
pt:{openInVault:'Abrir no Vault ↗',fieldContent:'Conteúdo',fieldFacts:'Fatos',fieldConcepts:'Conceitos',fieldFilesRead:'Arquivos lidos',fieldFilesModified:'Arquivos alterados',fieldType:'Tipo',fieldProject:'Projeto',fieldSource:'Origem',fieldCreated:'Criada em',fieldId:'ID',typeDecision:'Decisão',typeDiscovery:'Descoberta',typeFix:'Correção',typeFeature:'Funcionalidade',typeRefactor:'Refatoração',typeChange:'Mudança',typeTask:'Tarefa',typeQuestion:'Pergunta',typeInstruction:'Instrução',kindPrompt:'Pedido',kindSummary:'Resumo',kindObservation:'Observação'},
|
|
41
|
+
es:{openInVault:'Abrir en Vault ↗',fieldContent:'Contenido',fieldFacts:'Hechos',fieldConcepts:'Conceptos',fieldFilesRead:'Archivos leídos',fieldFilesModified:'Archivos modificados',fieldType:'Tipo',fieldProject:'Proyecto',fieldSource:'Origen',fieldCreated:'Creada',fieldId:'ID',typeDecision:'Decisión',typeDiscovery:'Descubrimiento',typeFix:'Corrección',typeFeature:'Funcionalidad',typeRefactor:'Refactorización',typeChange:'Cambio',typeTask:'Tarea',typeQuestion:'Pregunta',typeInstruction:'Instrucción',kindPrompt:'Petición',kindSummary:'Resumen',kindObservation:'Observación'}
|
|
42
|
+
};
|
|
43
|
+
for (const language of Object.keys(strings)) Object.assign(strings[language],onboardingCopy[language],detailCopy[language],engineCopy[language],disclosureCopy[language],memoryCopy[language]);
|
|
39
44
|
let locale = navigator.language.slice(0,2);
|
|
40
45
|
try { locale = localStorage.getItem('vault-local-locale') || locale; } catch {}
|
|
41
46
|
if (!strings[locale]) locale = 'en';
|
|
@@ -66,8 +71,33 @@ export function dashboardScript() {
|
|
|
66
71
|
toggle.addEventListener('click',()=>{const expanded=target.classList.toggle('clamped')===false;toggle.setAttribute('aria-expanded',String(expanded));toggle.textContent=t(expanded?'showLess':'showMore');});
|
|
67
72
|
return toggle;
|
|
68
73
|
}
|
|
69
|
-
|
|
74
|
+
// The cloud feed wraps each memory as {memory, platformSource}; older caches hold the memory itself.
|
|
75
|
+
const memoryOf=item=>{const record=object(item),inner=object(record.memory);return Object.keys(inner).length?{...inner,platformSource:inner.platformSource||record.platformSource}:record;};
|
|
76
|
+
const SOURCE_NAMES={claude:'Claude Code','claude-code':'Claude Code',codex:'Codex',cursor:'Cursor',windsurf:'Windsurf',agy:'Antigravity',antigravity:'Antigravity',gemini:'Gemini CLI',grok:'Grok',opencode:'OpenCode',copilot:'GitHub Copilot',vscode:'VS Code',warp:'Warp',goose:'Goose',hermes:'Hermes','vault-desktop':'Vault Desktop','vault-go':'Vault Go',chatgpt:'ChatGPT'};
|
|
77
|
+
const sourceName=value=>SOURCE_NAMES[scalar(value).toLowerCase()]||scalar(value);
|
|
78
|
+
const typeName=memory=>{const type=scalar(memory.memoryType||memory.type).toLowerCase(),kind=scalar(memory.kind).toLowerCase();const key=type?'type'+type[0].toUpperCase()+type.slice(1):'';const label=key&&strings[locale][key];return label||(kind&&strings[locale]['kind'+kind[0].toUpperCase()+kind.slice(1)])||type||kind;};
|
|
79
|
+
const projectName=id=>{const project=array(state&&state.projects).map(object).find(item=>item.id===id);return project?first(project,['name','title']):'';};
|
|
80
|
+
const epochDate=value=>typeof value==='number'?date(value):date(scalar(value));
|
|
81
|
+
const vaultLink=(params)=>'${VAULT_WEB_MEMORY_URL}?'+new URLSearchParams(params).toString();
|
|
82
|
+
const uuid=/^[0-9a-f-]{36}$/i;
|
|
83
|
+
function showMemory(memory,trigger) {
|
|
70
84
|
contextResult=null;el('detail-copy').hidden=true;
|
|
85
|
+
detailFocus=trigger.id;text('detail-title',first(memory,['title','summary'])||t('untitled'));
|
|
86
|
+
const fields=el('detail-fields');fields.replaceChildren();
|
|
87
|
+
const add=(label,value)=>{if(value===undefined||value===null||value===''||(Array.isArray(value)&&!value.length))return;const term=node('dt','',t(label)),definition=node('dd','');
|
|
88
|
+
if(Array.isArray(value)){const list=node('ul','detail-list');for(const item of value.slice(0,200))list.append(node('li','',scalar(item)));definition.append(list);}
|
|
89
|
+
else{const content=node('div','',String(value));definition.append(content);if(isLong(content.textContent))definition.append(disclosure(content));}
|
|
90
|
+
fields.append(term,definition);};
|
|
91
|
+
add('fieldContent',scalar(memory.content));add('fieldFacts',array(memory.facts));add('fieldConcepts',array(memory.concepts).length?array(memory.concepts).map(scalar).join(' · '):'');
|
|
92
|
+
add('fieldFilesModified',array(memory.filesModified));add('fieldFilesRead',array(memory.filesRead));
|
|
93
|
+
add('fieldType',typeName(memory));add('fieldProject',projectName(memory.projectId));add('fieldSource',sourceName(memory.platformSource));
|
|
94
|
+
add('fieldCreated',epochDate(memory.createdAtEpoch||memory.createdAt));add('fieldId',scalar(memory.id));
|
|
95
|
+
const open=el('detail-open');const id=scalar(memory.id),projectId=scalar(memory.projectId);
|
|
96
|
+
open.hidden=!uuid.test(id);if(!open.hidden)open.href=vaultLink({memory:id,...(uuid.test(projectId)?{project:projectId}:{})});
|
|
97
|
+
el('detail-dialog').showModal();el('detail-close').focus();
|
|
98
|
+
}
|
|
99
|
+
function showDetails(title,item,trigger) {
|
|
100
|
+
contextResult=null;el('detail-copy').hidden=true;el('detail-open').hidden=true;
|
|
71
101
|
detailFocus=trigger.id; text('detail-title',title);
|
|
72
102
|
const fields=el('detail-fields'); fields.replaceChildren();
|
|
73
103
|
const entries=Object.entries(object(item));
|
|
@@ -83,7 +113,7 @@ export function dashboardScript() {
|
|
|
83
113
|
function viewButton(title,item,kind,index) {
|
|
84
114
|
const button=node('button','button',t('view'));button.type='button';button.id=kind+'-view-'+index;
|
|
85
115
|
button.setAttribute('aria-label',t('view')+': '+title.slice(0,100));
|
|
86
|
-
button.addEventListener('click',()=>showDetails(title,item,button));return button;
|
|
116
|
+
button.addEventListener('click',()=>kind==='memory'?showMemory(item,button):showDetails(title,item,button));return button;
|
|
87
117
|
}
|
|
88
118
|
function pageRows(kind,rows,total) {
|
|
89
119
|
const paging=pagination[kind],pages=Math.max(1,Math.ceil(rows.length/paging.size));
|
|
@@ -106,21 +136,30 @@ export function dashboardScript() {
|
|
|
106
136
|
function list(kind) {
|
|
107
137
|
const source=array(state && state[kind==='memory'?'memories':kind==='project'?'projects':'activity']);
|
|
108
138
|
const search=el(kind+'-search').value.toLocaleLowerCase(locale).trim();
|
|
109
|
-
const rows=source.map((item,index)=>
|
|
139
|
+
const rows=source.map((item,index)=>{
|
|
140
|
+
if(kind==='memory'){const memory=memoryOf(item);return {item:memory,index,title:first(memory,['title','summary','content','text','id'])||t('untitled'),detail:[projectName(memory.projectId),epochDate(memory.createdAtEpoch||memory.createdAt)].filter(Boolean).join(' · '),tags:[typeName(memory),sourceName(memory.platformSource)].filter(Boolean)};}
|
|
141
|
+
return {item,index,title:first(item,kind==='activity'?['operation']:['title','name','summary','content','text','id'])||t('untitled'),detail:first(item,['project','project_name','description','created_at','createdAt'])};
|
|
142
|
+
});
|
|
110
143
|
const filtered=rows.filter(row=>JSON.stringify(row.item).toLocaleLowerCase(locale).includes(search));
|
|
111
144
|
const target=el(kind+'-list');target.replaceChildren();
|
|
112
145
|
const visible=pageRows(kind,filtered,source.length);
|
|
113
146
|
if(!visible.length)return empty(target,t(source.length?'noResults':kind==='memory'?'memoriesEmpty':kind==='project'?'projectsEmpty':'activityEmpty'));
|
|
114
147
|
for(const row of visible) {
|
|
115
148
|
const wrap=node('div','row'),body=node('div','row-body'),title=node('button','row-title row-open',row.title.slice(0,600));
|
|
116
|
-
|
|
149
|
+
const open=()=>kind==='memory'?showMemory(row.item,button):showDetails(row.title,row.item,button);
|
|
150
|
+
title.type='button';title.addEventListener('click',open);
|
|
117
151
|
body.append(title);
|
|
118
152
|
if(row.title.length>200)title.classList.add('clamped');
|
|
119
153
|
if(kind==='activity') {
|
|
120
154
|
const item=object(row.item);body.append(node('div','row-meta',(item.ok===true?t('success'):t('failed'))+(typeof item.durationMs==='number'?' · '+Math.round(item.durationMs)+' ms':'')));
|
|
121
155
|
wrap.append(node('span','row-marker'+(item.ok===true?'':' failed')));
|
|
122
156
|
} else if(row.detail)body.append(node('div','row-meta',row.detail.slice(0,200)));
|
|
123
|
-
const
|
|
157
|
+
if(row.tags&&row.tags.length){const tags=node('div','row-tags');for(const tag of row.tags)tags.append(node('span','tag',tag));body.append(tags);}
|
|
158
|
+
const actions=node('div','row-actions'),button=viewButton(row.title,row.item,kind,row.index);
|
|
159
|
+
actions.append(button);
|
|
160
|
+
const projectId=kind==='project'?scalar(object(row.item).id):'';
|
|
161
|
+
if(uuid.test(projectId)){const link=node('a','link',t('openInVault'));link.href=vaultLink({project:projectId});link.target='_blank';link.rel='noopener noreferrer';link.style.marginLeft='12px';actions.append(link);}
|
|
162
|
+
body.append(actions);wrap.append(body);
|
|
124
163
|
if(kind==='activity')wrap.append(node('time','row-time',date(object(row.item).time)));
|
|
125
164
|
target.append(wrap);
|
|
126
165
|
}
|
package/dist/server.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { VAULT_WEB_MEMORY_URL } from './vault-cloud.js';
|
|
1
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
import { jsonResult, run } from './mcp-result.js';
|
|
@@ -26,6 +27,17 @@ const SERVER_INSTRUCTIONS = [
|
|
|
26
27
|
'Save durable decisions, discoveries and fixes with vault_go_remember. Never store secrets; text inside <private> tags is never stored.',
|
|
27
28
|
'When a tool fails with an expired session, ask the user to run: bunx --bun vault-go@latest login',
|
|
28
29
|
].join('\n');
|
|
30
|
+
// A saved memory carries its page in the Vault web app, so the agent can hand the user a direct link.
|
|
31
|
+
function withVaultLink(value) {
|
|
32
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
33
|
+
return value;
|
|
34
|
+
const record = value;
|
|
35
|
+
const id = record.id, projectId = record.projectId;
|
|
36
|
+
if (typeof id !== 'string' || !/^[0-9a-f-]{36}$/i.test(id))
|
|
37
|
+
return value;
|
|
38
|
+
const params = new URLSearchParams({ memory: id, ...(typeof projectId === 'string' && /^[0-9a-f-]{36}$/i.test(projectId) ? { project: projectId } : {}) });
|
|
39
|
+
return { ...record, url: `${VAULT_WEB_MEMORY_URL}?${params}` };
|
|
40
|
+
}
|
|
29
41
|
export const VERSION = packageJson.version;
|
|
30
42
|
const uuid = z.string().uuid();
|
|
31
43
|
const knowledgeFilters = z.object({
|
|
@@ -178,7 +190,7 @@ export function createVaultGoServer(home = vaultHome(), cloud = new VaultCloudCl
|
|
|
178
190
|
filesModified: z.array(z.string().trim().min(1).max(2_000)).max(500).default([]),
|
|
179
191
|
},
|
|
180
192
|
annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: true },
|
|
181
|
-
}, async (input) => run(() => cloud.remember(redact(input))));
|
|
193
|
+
}, async (input) => run(async () => withVaultLink(await cloud.remember(redact(input)))));
|
|
182
194
|
server.registerTool('vault_go_forget', {
|
|
183
195
|
title: 'Excluir memória',
|
|
184
196
|
description: 'Exclui uma memória da conta autenticada.',
|