@askdkc/kiokuko 0.1.15 → 0.1.17
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/README.ja.md +5 -5
- package/README.ko.md +4 -4
- package/README.md +22 -16
- package/README.zh-CN.md +5 -5
- package/dist/agent-file/render.js +2 -2
- package/dist/agent-file/render.js.map +1 -1
- package/dist/akinator/agent-task.d.ts +4 -3
- package/dist/akinator/agent-task.d.ts.map +1 -1
- package/dist/akinator/agent-task.js +8 -6
- package/dist/akinator/agent-task.js.map +1 -1
- package/dist/akinator/capabilities.d.ts +36 -3
- package/dist/akinator/capabilities.d.ts.map +1 -1
- package/dist/akinator/capabilities.js +171 -10
- package/dist/akinator/capabilities.js.map +1 -1
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +57 -14
- package/dist/cli.js.map +1 -1
- package/dist/commands/setup.d.ts +6 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +62 -8
- package/dist/commands/setup.js.map +1 -1
- package/dist/context/broker.d.ts +2 -0
- package/dist/context/broker.d.ts.map +1 -1
- package/dist/context/broker.js +39 -20
- package/dist/context/broker.js.map +1 -1
- package/dist/context/delivery.d.ts +2 -1
- package/dist/context/delivery.d.ts.map +1 -1
- package/dist/context/delivery.js +12 -9
- package/dist/context/delivery.js.map +1 -1
- package/dist/context/feedback.d.ts.map +1 -1
- package/dist/context/feedback.js +21 -7
- package/dist/context/feedback.js.map +1 -1
- package/dist/context/origin.d.ts +9 -0
- package/dist/context/origin.d.ts.map +1 -0
- package/dist/context/origin.js +15 -0
- package/dist/context/origin.js.map +1 -0
- package/dist/context/ranking.d.ts +3 -1
- package/dist/context/ranking.d.ts.map +1 -1
- package/dist/context/ranking.js +9 -2
- package/dist/context/ranking.js.map +1 -1
- package/dist/context/scoped-broker.d.ts +4 -3
- package/dist/context/scoped-broker.d.ts.map +1 -1
- package/dist/context/scoped-broker.js +27 -34
- package/dist/context/scoped-broker.js.map +1 -1
- package/dist/ledger/archive.d.ts.map +1 -1
- package/dist/ledger/archive.js +58 -16
- package/dist/ledger/archive.js.map +1 -1
- package/dist/ledger/maintenance.d.ts.map +1 -1
- package/dist/ledger/maintenance.js +17 -4
- package/dist/ledger/maintenance.js.map +1 -1
- package/dist/mcp/bounded-stdio-transport.d.ts +23 -0
- package/dist/mcp/bounded-stdio-transport.d.ts.map +1 -0
- package/dist/mcp/bounded-stdio-transport.js +109 -0
- package/dist/mcp/bounded-stdio-transport.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +12 -27
- package/dist/mcp/server.js.map +1 -1
- package/dist/memory/curator.d.ts +45 -1
- package/dist/memory/curator.d.ts.map +1 -1
- package/dist/memory/curator.js +178 -32
- package/dist/memory/curator.js.map +1 -1
- package/dist/memory/federated-retrieval.d.ts +67 -0
- package/dist/memory/federated-retrieval.d.ts.map +1 -0
- package/dist/memory/federated-retrieval.js +328 -0
- package/dist/memory/federated-retrieval.js.map +1 -0
- package/dist/memory/portability.d.ts +10 -0
- package/dist/memory/portability.d.ts.map +1 -0
- package/dist/memory/portability.js +44 -0
- package/dist/memory/portability.js.map +1 -0
- package/dist/memory/retrieval.d.ts +11 -0
- package/dist/memory/retrieval.d.ts.map +1 -1
- package/dist/memory/retrieval.js +29 -9
- package/dist/memory/retrieval.js.map +1 -1
- package/dist/memory/scoped-memory.d.ts +6 -12
- package/dist/memory/scoped-memory.d.ts.map +1 -1
- package/dist/memory/scoped-memory.js +24 -48
- package/dist/memory/scoped-memory.js.map +1 -1
- package/dist/memory/structured-memory.d.ts +6 -0
- package/dist/memory/structured-memory.d.ts.map +1 -1
- package/dist/memory/structured-memory.js +23 -1
- package/dist/memory/structured-memory.js.map +1 -1
- package/dist/repository/project-fingerprint.d.ts +21 -0
- package/dist/repository/project-fingerprint.d.ts.map +1 -0
- package/dist/repository/project-fingerprint.js +150 -0
- package/dist/repository/project-fingerprint.js.map +1 -0
- package/dist/setup/client-detection.d.ts +4 -0
- package/dist/setup/client-detection.d.ts.map +1 -1
- package/dist/setup/client-detection.js +17 -6
- package/dist/setup/client-detection.js.map +1 -1
- package/dist/setup/render.js +2 -2
- package/dist/setup/render.js.map +1 -1
- package/dist/web/i18n.d.ts +24 -8
- package/dist/web/i18n.d.ts.map +1 -1
- package/dist/web/i18n.js +96 -32
- package/dist/web/i18n.js.map +1 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +72 -4
- package/dist/web/server.js.map +1 -1
- package/dist/web/ui.d.ts.map +1 -1
- package/dist/web/ui.js +317 -57
- package/dist/web/ui.js.map +1 -1
- package/migrations/008_federated_memory.sql +46 -0
- package/package.json +3 -1
- package/templates/AGENTS.md +2 -2
package/dist/web/ui.js
CHANGED
|
@@ -65,11 +65,18 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
65
65
|
.entry-card:hover,.entry-card.selected { border-color:#93c5fd; box-shadow:0 8px 20px rgba(37,99,235,.10); }
|
|
66
66
|
.entry-meta { display:flex; gap:7px; align-items:center; flex-wrap:wrap; color:var(--muted); font-size:12px; }
|
|
67
67
|
.badge { border-radius:999px; padding:3px 8px; background:#f1f5f9; color:#475569; font-weight:700; }
|
|
68
|
+
.badge.origin-project { background:#dbeafe; color:#1d4ed8; }
|
|
69
|
+
.badge.origin-ecosystem { background:#dcfce7; color:#166534; }
|
|
70
|
+
.badge.origin-global { background:#fef3c7; color:#92400e; }
|
|
68
71
|
.badge.verified { background:#dcfce7; color:#166534; }
|
|
69
72
|
.badge.candidate { background:#fef3c7; color:#92400e; }
|
|
70
73
|
.badge.superseded { background:#fee2e2; color:#991b1b; }
|
|
71
74
|
.entry-card h3 { margin:9px 0 6px; font-size:16px; }
|
|
72
75
|
.snippet { margin:0; color:var(--muted); display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; white-space:pre-wrap; }
|
|
76
|
+
.federated-card { border-left:4px solid #22c55e; }
|
|
77
|
+
.federated-card.global { border-left-color:#f59e0b; }
|
|
78
|
+
.federated-source,.selection-reasons { margin-top:8px; color:var(--muted); font-size:12px; white-space:pre-wrap; overflow-wrap:anywhere; }
|
|
79
|
+
.federated-detail { display:grid; gap:12px; }
|
|
73
80
|
.tags { display:flex; gap:6px; flex-wrap:wrap; margin-top:10px; }
|
|
74
81
|
.tag { border:0; background:transparent; color:var(--accent); font-size:12px; padding:0; }
|
|
75
82
|
.tag:hover { text-decoration:underline; }
|
|
@@ -106,19 +113,33 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
106
113
|
.curator-close { display:grid; place-items:center; flex:0 0 auto; width:44px; height:44px; border:1px solid var(--line); border-radius:12px; background:var(--panel); color:var(--muted); font-size:26px; line-height:1; }
|
|
107
114
|
.curator-close:hover { border-color:#93c5fd; background:var(--accent-soft); color:var(--accent); }
|
|
108
115
|
.curator-status { margin:0 0 12px; }
|
|
116
|
+
.curator-filters { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:8px; margin:0 0 14px; padding:12px; border:1px solid var(--line); border-radius:12px; background:var(--surface); }
|
|
117
|
+
.curator-filter { display:grid; gap:4px; color:var(--muted); font-size:11px; font-weight:800; }
|
|
118
|
+
.curator-filter-check { display:flex; align-items:center; gap:6px; color:var(--muted); font-size:12px; font-weight:700; }
|
|
119
|
+
.curator-filter-check input { width:16px; height:16px; }
|
|
120
|
+
.curator-filter-tags { grid-column:1 / -1; display:flex; flex-wrap:wrap; gap:7px; padding-top:4px; }
|
|
121
|
+
.curator-filter-tags .tag.active { font-weight:800; text-decoration:underline; }
|
|
109
122
|
.curator-list { display:grid; gap:12px; }
|
|
110
123
|
.curator-card { border:1px solid var(--line); border-radius:14px; padding:16px; background:var(--panel); }
|
|
111
|
-
.curator-card.selected { border-color:#93c5fd; box-shadow:0 8px 20px rgba(37,99,235,.10); }
|
|
112
|
-
.curator-select { display:flex; gap:8px; align-items:center; color:var(--muted); font-size:13px; font-weight:700; }
|
|
113
|
-
.curator-select input { width:17px; height:17px; accent-color:#2563eb; }
|
|
114
124
|
.curator-workspace { overflow-wrap:anywhere; }
|
|
115
125
|
.curator-card h3 { margin:8px 0; font-size:17px; }
|
|
116
126
|
.curator-overview { margin:8px 0 12px; color:var(--muted); white-space:pre-wrap; line-height:1.55; }
|
|
127
|
+
.curator-card-actions { display:flex; flex-wrap:wrap; gap:8px; margin:12px 0 0; }
|
|
128
|
+
.curator-review-details { margin-top:12px; }
|
|
117
129
|
.curator-draft { margin:12px 0; padding:12px; border:1px solid var(--line); border-radius:12px; background:var(--surface); }
|
|
118
130
|
.curator-draft h4 { margin:0 0 10px; font-size:14px; }
|
|
119
131
|
.curator-draft-label { margin:10px 0 4px; color:var(--muted); font-size:12px; font-weight:700; }
|
|
120
132
|
.curator-draft-value { margin:0; white-space:pre-wrap; overflow-wrap:anywhere; font:inherit; font-size:13px; line-height:1.5; }
|
|
121
133
|
.curator-reasons { color:var(--muted); font-size:12px; white-space:pre-wrap; }
|
|
134
|
+
.curator-confirm-modal { position:absolute; inset:0; z-index:2; display:grid; place-items:center; padding:24px; background:rgba(15,23,42,.58); }
|
|
135
|
+
.curator-confirm-dialog { width:min(680px,calc(100vw - 32px)); max-height:min(760px,calc(100vh - 48px)); display:flex; flex-direction:column; min-height:0; background:var(--panel); box-shadow:0 28px 90px rgba(15,23,42,.34); }
|
|
136
|
+
.curator-confirm-dialog .panel-body { min-height:0; overflow-y:auto; }
|
|
137
|
+
.curator-confirm-grid { display:grid; grid-template-columns:1fr 1fr; gap:10px; margin:0 0 14px; }
|
|
138
|
+
.curator-confirm-field { min-width:0; padding:11px 12px; border:1px solid var(--line); border-radius:12px; background:var(--surface); }
|
|
139
|
+
.curator-confirm-field dt { margin:0 0 5px; color:var(--muted); font-size:12px; font-weight:800; }
|
|
140
|
+
.curator-confirm-field dd { margin:0; overflow-wrap:anywhere; white-space:pre-wrap; }
|
|
141
|
+
.curator-confirm-draft { max-height:280px; overflow:auto; margin:0; padding:12px; border:1px solid var(--line); border-radius:12px; background:var(--surface); white-space:pre-wrap; overflow-wrap:anywhere; font:inherit; font-size:13px; line-height:1.5; }
|
|
142
|
+
.curator-confirm-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:14px; }
|
|
122
143
|
@keyframes curator-backdrop-in { from { opacity:0; } to { opacity:1; } }
|
|
123
144
|
@keyframes curator-backdrop-out { from { opacity:1; } to { opacity:0; } }
|
|
124
145
|
@keyframes curator-dialog-in { from { opacity:0; transform:translateY(10px) scale(.98); } to { opacity:1; transform:translateY(0) scale(1); } }
|
|
@@ -128,7 +149,7 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
128
149
|
}
|
|
129
150
|
@media (max-width:680px) { .operator-grid { grid-template-columns:1fr; } }
|
|
130
151
|
@media (max-width:1050px) { .layout { grid-template-columns:180px minmax(280px,1fr); } .editor-panel { grid-column:1 / -1; } }
|
|
131
|
-
@media (max-width:680px) { .shell { padding:16px; } .topbar { display:block; position:relative; } .brand { padding-right:56px; } .topbar-side { margin-top:16px; align-self:auto; } .language-picker { position:absolute; top:0; right:0; } .toolbar { justify-content:stretch; margin-top:0; } .topbar-side .control,.topbar-side .search { flex:1 1 100%; width:100%; } .search { min-width:0; } .layout { grid-template-columns:1fr; } .genres-panel { order:0; } .list-panel { order:1; } .editor-panel { order:2; } .entry-list { max-height:none; } .curator-dialog-head { flex-wrap:wrap; } .curator-header-actions { flex:1 1 100%; width:100%; margin-left:0; } .curator-actions { justify-content:flex-end; } }
|
|
152
|
+
@media (max-width:680px) { .shell { padding:16px; } .topbar { display:block; position:relative; } .brand { padding-right:56px; } .topbar-side { margin-top:16px; align-self:auto; } .language-picker { position:absolute; top:0; right:0; } .toolbar { justify-content:stretch; margin-top:0; } .topbar-side .control,.topbar-side .search { flex:1 1 100%; width:100%; } .search { min-width:0; } .layout { grid-template-columns:1fr; } .genres-panel { order:0; } .list-panel { order:1; } .editor-panel { order:2; } .entry-list { max-height:none; } .curator-dialog-head { flex-wrap:wrap; } .curator-header-actions { flex:1 1 100%; width:100%; margin-left:0; } .curator-actions { justify-content:flex-end; } .curator-confirm-grid { grid-template-columns:1fr; } .curator-confirm-actions { flex-direction:column-reverse; } .curator-confirm-actions .button { width:100%; } }
|
|
132
153
|
</style>
|
|
133
154
|
</head>
|
|
134
155
|
<body>
|
|
@@ -188,11 +209,34 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
188
209
|
</div>
|
|
189
210
|
<div class="panel-body">
|
|
190
211
|
<p id="curator-description" class="subtitle" data-i18n="curatorDescription">Review reusable knowledge candidates and add them to global memory.</p>
|
|
191
|
-
<div id="curator-
|
|
212
|
+
<div id="curator-filters" class="curator-filters" aria-label="Curator filters"></div>
|
|
213
|
+
<div class="curator-selection-summary"><span id="curator-result-count" class="curator-selection-count">0 candidates</span></div>
|
|
192
214
|
<div id="curator-status" class="status" role="status" aria-live="polite"></div>
|
|
193
215
|
<div id="curator-list" class="curator-list"></div>
|
|
194
216
|
</div>
|
|
195
217
|
</section>
|
|
218
|
+
<div id="curator-confirm-modal" class="curator-confirm-modal" hidden>
|
|
219
|
+
<section id="curator-confirm-panel" class="panel curator-confirm-dialog" role="alertdialog" aria-modal="true" aria-labelledby="curator-confirm-title" aria-describedby="curator-confirm-description">
|
|
220
|
+
<div class="panel-head">
|
|
221
|
+
<h2 id="curator-confirm-title" data-i18n="curatorConfirmTitle">Confirm Global memory addition</h2>
|
|
222
|
+
</div>
|
|
223
|
+
<div class="panel-body">
|
|
224
|
+
<p id="curator-confirm-description" class="subtitle" data-i18n="curatorConfirmDescription">Verify the source, applicability, and complete regenerated draft.</p>
|
|
225
|
+
<dl class="curator-confirm-grid">
|
|
226
|
+
<div class="curator-confirm-field"><dt data-i18n="curatorConfirmSource">Source project</dt><dd id="curator-confirm-source"></dd></div>
|
|
227
|
+
<div class="curator-confirm-field"><dt data-i18n="curatorConfirmSkill">Skill</dt><dd id="curator-confirm-skill"></dd></div>
|
|
228
|
+
<div class="curator-confirm-field"><dt data-i18n="curatorConfirmApplicability">Applicability</dt><dd id="curator-confirm-applicability"></dd></div>
|
|
229
|
+
</dl>
|
|
230
|
+
<h3 data-i18n="curatorConfirmDraft">Draft to add</h3>
|
|
231
|
+
<pre id="curator-confirm-draft" class="curator-confirm-draft"></pre>
|
|
232
|
+
<div id="curator-confirm-status" class="status curator-status" role="status" aria-live="polite"></div>
|
|
233
|
+
<div class="curator-confirm-actions">
|
|
234
|
+
<button id="curator-confirm-cancel" class="button" type="button" data-i18n="curatorCancel">Cancel</button>
|
|
235
|
+
<button id="curator-confirm-submit" class="button primary" type="button" data-i18n="curatorConfirmAction">Add this draft to Global</button>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
</section>
|
|
239
|
+
</div>
|
|
196
240
|
</div>
|
|
197
241
|
<script>
|
|
198
242
|
const i18n = ${WEB_I18N_CONFIG};
|
|
@@ -217,7 +261,8 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
217
261
|
const botModes = [
|
|
218
262
|
['bot:common', 'bot.common'], ['bot:researcher', 'bot.researcher'], ['bot:builder', 'bot.builder'], ['bot:reviewer', 'bot.reviewer'], ['bot:devops', 'bot.devops'], ['bot:writer', 'bot.writer'], ['bot:analyst', 'bot.analyst']
|
|
219
263
|
];
|
|
220
|
-
const
|
|
264
|
+
const curatorUrl = new URLSearchParams(location.search);
|
|
265
|
+
const state = { locale: initialLocale, workspace: '', kind: 'all', tag: '', query: '', entries: [], recallItems: [], tags: [], selected: null, selectedRecall: null, runs: [], selectedRun: null, curatorCandidates: [], curatorGlobalized: new Set(), curatorNextCursor: null, curatorTotalApproximate: 0, curatorOpen: false, curatorPreviousFocus: null, curatorPendingCandidate: null, curatorConfirmationTrigger: null, curatorGlobalizeBusy: false, localizedStatus: null, curatorSearch: curatorUrl.get('search') || '', curatorProject: curatorUrl.get('project') || '', curatorTags: new Set(curatorUrl.getAll('tag')), curatorFramework: curatorUrl.get('framework') || '', curatorLanguage: curatorUrl.get('language') || '', curatorMemoryClass: curatorUrl.get('memoryClass') || '', curatorTier: curatorUrl.get('tier') || '', curatorReady: curatorUrl.get('ready') === 'true', curatorIncludeGlobalized: curatorUrl.get('includeGlobalized') === 'true', curatorFacets: null };
|
|
221
266
|
const $ = (id) => document.getElementById(id);
|
|
222
267
|
const t = (key, parameters = {}) => {
|
|
223
268
|
const template = i18n.messages[state.locale]?.[key] ?? i18n.messages[i18n.defaultLocale]?.[key] ?? key;
|
|
@@ -230,6 +275,7 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
230
275
|
const setI18nText = (element, key) => { element.dataset.i18n = key; element.textContent = t(key); return element; };
|
|
231
276
|
const labelForKind = (kind) => { const item = kinds.find(([value]) => value === kind); return item ? t(item[1]) : kind; };
|
|
232
277
|
const labelForStatus = (status) => i18n.messages[state.locale]?.['status.' + status] ?? status;
|
|
278
|
+
const labelForOrigin = (origin) => t(origin === 'ecosystem' ? 'originEcosystem' : origin === 'global' ? 'originGlobal' : 'originProject');
|
|
233
279
|
const updateEditorState = () => {
|
|
234
280
|
const element = $('editor-state');
|
|
235
281
|
if (state.selected) { delete element.dataset.i18n; element.dataset.i18nStatus = state.selected.status; element.textContent = labelForStatus(state.selected.status); }
|
|
@@ -298,6 +344,55 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
298
344
|
if (blocked) appMain.setAttribute('aria-hidden', 'true');
|
|
299
345
|
else appMain.removeAttribute('aria-hidden');
|
|
300
346
|
};
|
|
347
|
+
function restoreCuratorUrl() {
|
|
348
|
+
const params = new URLSearchParams(location.search);
|
|
349
|
+
state.curatorSearch = params.get('search') || '';
|
|
350
|
+
state.curatorProject = params.get('project') || '';
|
|
351
|
+
state.curatorTags = new Set(params.getAll('tag'));
|
|
352
|
+
state.curatorFramework = params.get('framework') || '';
|
|
353
|
+
state.curatorLanguage = params.get('language') || '';
|
|
354
|
+
state.curatorMemoryClass = params.get('memoryClass') || '';
|
|
355
|
+
state.curatorTier = params.get('tier') || '';
|
|
356
|
+
state.curatorReady = params.get('ready') === 'true';
|
|
357
|
+
state.curatorIncludeGlobalized = params.get('includeGlobalized') === 'true';
|
|
358
|
+
}
|
|
359
|
+
function syncCuratorUrl(push = false) {
|
|
360
|
+
const params = new URLSearchParams(location.search);
|
|
361
|
+
for (const key of ['search', 'project', 'framework', 'language', 'memoryClass', 'tier', 'ready', 'includeGlobalized', 'tag']) params.delete(key);
|
|
362
|
+
if (state.curatorSearch) params.set('search', state.curatorSearch);
|
|
363
|
+
if (state.curatorProject) params.set('project', state.curatorProject);
|
|
364
|
+
if (state.curatorFramework) params.set('framework', state.curatorFramework);
|
|
365
|
+
if (state.curatorLanguage) params.set('language', state.curatorLanguage);
|
|
366
|
+
if (state.curatorMemoryClass) params.set('memoryClass', state.curatorMemoryClass);
|
|
367
|
+
if (state.curatorTier) params.set('tier', state.curatorTier);
|
|
368
|
+
if (state.curatorReady) params.set('ready', 'true');
|
|
369
|
+
if (state.curatorIncludeGlobalized) params.set('includeGlobalized', 'true');
|
|
370
|
+
for (const tag of state.curatorTags) params.append('tag', tag);
|
|
371
|
+
const nextUrl = location.pathname + (params.toString() ? '?' + params.toString() : '');
|
|
372
|
+
if (push) history.pushState(null, '', nextUrl); else history.replaceState(null, '', nextUrl);
|
|
373
|
+
}
|
|
374
|
+
function curatorFilterSelect(label, values, value, onChange) {
|
|
375
|
+
const wrapper = document.createElement('label'); wrapper.className = 'curator-filter';
|
|
376
|
+
const text = document.createElement('span'); text.textContent = label;
|
|
377
|
+
const select = document.createElement('select');
|
|
378
|
+
const all = document.createElement('option'); all.value = ''; all.textContent = 'All'; select.append(all);
|
|
379
|
+
for (const item of values || []) { const option = document.createElement('option'); option.value = item.value || item.workspace; option.textContent = item.name || item.value || item.workspace; select.append(option); }
|
|
380
|
+
select.value = value || ''; select.addEventListener('change', () => onChange(select.value)); wrapper.append(text, select); return wrapper;
|
|
381
|
+
}
|
|
382
|
+
function renderCuratorFilters() {
|
|
383
|
+
const root = $('curator-filters'); if (!root) return;
|
|
384
|
+
const facets = state.curatorFacets || {};
|
|
385
|
+
const search = document.createElement('input'); search.type = 'search'; search.placeholder = 'Search candidates'; search.value = state.curatorSearch; search.addEventListener('input', () => { state.curatorSearch = search.value.trim(); clearTimeout(state.curatorSearchTimer); state.curatorSearchTimer = setTimeout(() => { syncCuratorUrl(true); loadCurator(); }, 180); });
|
|
386
|
+
const project = curatorFilterSelect('Project', facets.projects, state.curatorProject, (value) => { state.curatorProject = value; syncCuratorUrl(true); loadCurator(); });
|
|
387
|
+
const framework = curatorFilterSelect('Framework', facets.frameworks, state.curatorFramework, (value) => { state.curatorFramework = value; syncCuratorUrl(true); loadCurator(); });
|
|
388
|
+
const language = curatorFilterSelect('Language', facets.languages, state.curatorLanguage, (value) => { state.curatorLanguage = value; syncCuratorUrl(true); loadCurator(); });
|
|
389
|
+
const memoryClass = curatorFilterSelect('Memory class', facets.memoryClasses, state.curatorMemoryClass, (value) => { state.curatorMemoryClass = value; syncCuratorUrl(true); loadCurator(); });
|
|
390
|
+
const readiness = curatorFilterSelect('Readiness', [{ value: 'portable', name: 'Portable' }, { value: 'repeated', name: 'Repeated' }, { value: 'observed', name: 'Observed' }], state.curatorTier, (value) => { state.curatorTier = value; syncCuratorUrl(true); loadCurator(); });
|
|
391
|
+
const ready = document.createElement('label'); ready.className = 'curator-filter-check'; const readyInput = document.createElement('input'); readyInput.type = 'checkbox'; readyInput.checked = state.curatorReady; readyInput.addEventListener('change', () => { state.curatorReady = readyInput.checked; syncCuratorUrl(true); loadCurator(); }); ready.append(readyInput, document.createTextNode('Skill-ready'));
|
|
392
|
+
const globalized = document.createElement('label'); globalized.className = 'curator-filter-check'; const globalizedInput = document.createElement('input'); globalizedInput.type = 'checkbox'; globalizedInput.checked = state.curatorIncludeGlobalized; globalizedInput.addEventListener('change', () => { state.curatorIncludeGlobalized = globalizedInput.checked; syncCuratorUrl(true); loadCurator(); }); globalized.append(globalizedInput, document.createTextNode('Show already globalized'));
|
|
393
|
+
const tags = document.createElement('div'); tags.className = 'curator-filter-tags'; for (const facet of facets.tags || []) { const button = document.createElement('button'); button.type = 'button'; button.className = 'tag' + (state.curatorTags.has(facet.value) ? ' active' : ''); button.textContent = '#' + facet.value + ' (' + facet.count + ')'; button.addEventListener('click', () => { if (state.curatorTags.has(facet.value)) state.curatorTags.delete(facet.value); else state.curatorTags.add(facet.value); syncCuratorUrl(true); loadCurator(); }); tags.append(button); }
|
|
394
|
+
root.replaceChildren(search, project, framework, language, memoryClass, readiness, ready, globalized, tags);
|
|
395
|
+
}
|
|
301
396
|
function openCurator() {
|
|
302
397
|
if (state.curatorOpen) { $('curator-close')?.focus(); return; }
|
|
303
398
|
state.curatorPreviousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
@@ -309,6 +404,8 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
309
404
|
requestAnimationFrame(() => $('curator-close')?.focus());
|
|
310
405
|
}
|
|
311
406
|
function closeCurator() {
|
|
407
|
+
if (state.curatorGlobalizeBusy) return;
|
|
408
|
+
if (state.curatorPendingCandidate) closeCuratorConfirmation(false);
|
|
312
409
|
const modal = $('curator-modal');
|
|
313
410
|
if (modal.hidden) return;
|
|
314
411
|
state.curatorOpen = false;
|
|
@@ -369,10 +466,34 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
369
466
|
if (tagButtons.length > 0) root.append(filterGroup(t('crossTagFilterTitle'), tagButtons));
|
|
370
467
|
}
|
|
371
468
|
|
|
469
|
+
function renderFederatedItems() {
|
|
470
|
+
const list = $('entry-list');
|
|
471
|
+
list.replaceChildren(...state.recallItems.map((item) => {
|
|
472
|
+
const card = document.createElement('article'); card.className = 'entry-card federated-card ' + (item.origin === 'global' ? 'global' : '');
|
|
473
|
+
const meta = document.createElement('div'); meta.className = 'entry-meta';
|
|
474
|
+
const origin = document.createElement('span'); origin.className = 'badge origin-' + item.origin; origin.textContent = labelForOrigin(item.origin);
|
|
475
|
+
const kind = document.createElement('span'); kind.className = 'badge'; kind.textContent = labelForKind(item.kind);
|
|
476
|
+
const status = document.createElement('span'); status.className = 'badge ' + item.status; status.textContent = labelForStatus(item.status);
|
|
477
|
+
meta.append(origin, kind, status);
|
|
478
|
+
const title = document.createElement('h3'); title.textContent = item.title;
|
|
479
|
+
const snippet = document.createElement('p'); snippet.className = 'snippet'; snippet.textContent = item.snippet;
|
|
480
|
+
const source = document.createElement('div'); source.className = 'federated-source';
|
|
481
|
+
const sourceLines = [];
|
|
482
|
+
if (item.sourceWorkspace) sourceLines.push(t('sourceWorkspace', { workspace: item.sourceWorkspace }));
|
|
483
|
+
if (item.sourceProject) sourceLines.push(t('sourceProject', { project: item.sourceProject }));
|
|
484
|
+
source.textContent = sourceLines.join('\n');
|
|
485
|
+
const tags = document.createElement('div'); tags.className = 'tags'; item.tags.forEach((tag) => { const tagItem = document.createElement('span'); tagItem.className = 'tag'; tagItem.textContent = '#' + tag; tags.append(tagItem); });
|
|
486
|
+
const reasons = document.createElement('div'); reasons.className = 'selection-reasons'; reasons.textContent = [t('selectionReasons'), ...item.selectionReasons.map((reason) => '• ' + reason)].join('\n');
|
|
487
|
+
card.append(meta, title, snippet, source, tags, reasons); card.addEventListener('click', () => { state.selected = null; state.selectedRecall = item; renderEntries(); renderEditor(); }); return card;
|
|
488
|
+
}));
|
|
489
|
+
}
|
|
490
|
+
|
|
372
491
|
function renderEntries() {
|
|
373
|
-
|
|
374
|
-
$('
|
|
492
|
+
const displayed = state.recallItems.length > 0 ? state.recallItems.length : state.entries.length;
|
|
493
|
+
$('result-count').textContent = tp('entryCount', displayed);
|
|
494
|
+
$('list-title').textContent = state.recallItems.length > 0 ? t('entriesTitle') : (state.tag ? '#' + state.tag : (state.kind === 'all' ? t('entriesTitle') : labelForKind(state.kind)));
|
|
375
495
|
const list = $('entry-list');
|
|
496
|
+
if (state.recallItems.length > 0) { renderFederatedItems(); return; }
|
|
376
497
|
if (!state.entries.length) {
|
|
377
498
|
const empty = document.createElement('div'); empty.className = 'editor-empty'; setI18nText(empty, 'noEntries'); list.replaceChildren(empty); return;
|
|
378
499
|
}
|
|
@@ -390,7 +511,26 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
390
511
|
}));
|
|
391
512
|
}
|
|
392
513
|
|
|
514
|
+
function renderFederatedDetail() {
|
|
515
|
+
const editor = $('editor'); const item = state.selectedRecall;
|
|
516
|
+
if (!item) return;
|
|
517
|
+
const origin = document.createElement('span'); origin.className = 'badge origin-' + item.origin; origin.textContent = labelForOrigin(item.origin);
|
|
518
|
+
const heading = document.createElement('h3'); heading.textContent = item.title;
|
|
519
|
+
const meta = document.createElement('div'); meta.className = 'entry-meta'; meta.append(origin);
|
|
520
|
+
if (item.sourceWorkspace) { const source = document.createElement('span'); source.className = 'badge'; source.textContent = t('sourceWorkspace', { workspace: item.sourceWorkspace }); meta.append(source); }
|
|
521
|
+
if (item.sourceProject) { const source = document.createElement('span'); source.className = 'badge'; source.textContent = t('sourceProject', { project: item.sourceProject }); meta.append(source); }
|
|
522
|
+
const notice = document.createElement('div'); notice.className = 'notice'; notice.textContent = t('federatedReadOnly');
|
|
523
|
+
const detail = document.createElement('div'); detail.className = 'federated-detail';
|
|
524
|
+
const snippet = document.createElement('div'); snippet.className = 'detail-text'; snippet.textContent = item.snippet;
|
|
525
|
+
const reasons = detailBlock('selectionReasons', item.selectionReasons.join('\n'));
|
|
526
|
+
const tags = detailBlock('commaSeparatedTags', item.tags.map((tag) => '#' + tag).join(' '));
|
|
527
|
+
detail.append(snippet, reasons, tags);
|
|
528
|
+
const stateBadge = $('editor-state'); delete stateBadge.dataset.i18n; delete stateBadge.dataset.i18nStatus; stateBadge.textContent = labelForOrigin(item.origin);
|
|
529
|
+
editor.replaceChildren(meta, heading, notice, detail);
|
|
530
|
+
}
|
|
531
|
+
|
|
393
532
|
function renderEditor() {
|
|
533
|
+
if (state.selectedRecall) { renderFederatedDetail(); return; }
|
|
394
534
|
const editor = $('editor');
|
|
395
535
|
const entry = state.selected;
|
|
396
536
|
updateEditorState();
|
|
@@ -418,34 +558,106 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
418
558
|
}); editor.replaceChildren(form);
|
|
419
559
|
}
|
|
420
560
|
|
|
421
|
-
async function selectEntry(id) { try { const result = await api('/api/entries/' + encodeURIComponent(id) + '?workspace=' + encodeURIComponent(state.workspace)); state.selected = result.entry; renderEntries(); renderEditor(); } catch (error) { setStatus(error.message, true); } }
|
|
561
|
+
async function selectEntry(id) { try { const result = await api('/api/entries/' + encodeURIComponent(id) + '?workspace=' + encodeURIComponent(state.workspace)); state.selectedRecall = null; state.selected = result.entry; renderEntries(); renderEditor(); } catch (error) { setStatus(error.message, true); } }
|
|
422
562
|
|
|
423
563
|
const curatorCandidateKey = (candidate) => candidate.workspace + '\u0000' + candidate.entryId;
|
|
424
564
|
|
|
425
|
-
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
565
|
+
function setCuratorConfirmationStatus(message, error = false) {
|
|
566
|
+
const element = $('curator-confirm-status');
|
|
567
|
+
element.textContent = message;
|
|
568
|
+
element.className = error ? 'status notice error curator-status' : 'status curator-status';
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
function openCuratorConfirmation(candidate, trigger) {
|
|
572
|
+
if (state.curatorGlobalizeBusy || state.curatorGlobalized.has(curatorCandidateKey(candidate))) return;
|
|
573
|
+
state.curatorPendingCandidate = candidate;
|
|
574
|
+
state.curatorConfirmationTrigger = trigger instanceof HTMLElement ? trigger : null;
|
|
575
|
+
$('curator-confirm-source').textContent = candidate.projectName || candidate.workspace;
|
|
576
|
+
$('curator-confirm-skill').textContent = candidate.skillName;
|
|
577
|
+
$('curator-confirm-applicability').textContent = candidate.applicability ? JSON.stringify(candidate.applicability, null, 2) : t('curatorApplicabilityNone');
|
|
578
|
+
$('curator-confirm-draft').textContent = [
|
|
579
|
+
t('curatorDraftTitle') + '\n' + candidate.draft.title,
|
|
580
|
+
t('curatorDraftSummary') + '\n' + candidate.draft.summary,
|
|
581
|
+
t('curatorDraftBody') + '\n' + candidate.draft.body,
|
|
582
|
+
t('curatorDraftVersion') + '\n' + candidate.draft.version,
|
|
583
|
+
].join('\n\n');
|
|
584
|
+
setCuratorConfirmationStatus('');
|
|
585
|
+
const panel = $('curator-panel');
|
|
586
|
+
panel.inert = true;
|
|
587
|
+
panel.setAttribute('aria-hidden', 'true');
|
|
588
|
+
const submit = $('curator-confirm-submit');
|
|
589
|
+
submit.disabled = false;
|
|
590
|
+
setI18nText(submit, 'curatorConfirmAction');
|
|
591
|
+
$('curator-confirm-cancel').disabled = false;
|
|
592
|
+
$('curator-confirm-modal').hidden = false;
|
|
593
|
+
requestAnimationFrame(() => submit.focus());
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
function closeCuratorConfirmation(restoreFocus = true) {
|
|
597
|
+
if (state.curatorGlobalizeBusy) return;
|
|
598
|
+
$('curator-confirm-modal').hidden = true;
|
|
599
|
+
const panel = $('curator-panel');
|
|
600
|
+
panel.inert = false;
|
|
601
|
+
panel.removeAttribute('aria-hidden');
|
|
602
|
+
const trigger = state.curatorConfirmationTrigger;
|
|
603
|
+
state.curatorPendingCandidate = null;
|
|
604
|
+
state.curatorConfirmationTrigger = null;
|
|
605
|
+
setCuratorConfirmationStatus('');
|
|
606
|
+
if (restoreFocus) requestAnimationFrame(() => {
|
|
607
|
+
if (trigger?.isConnected) trigger.focus();
|
|
608
|
+
else $('curator-close')?.focus();
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
function handleCuratorConfirmationKeydown(event) {
|
|
613
|
+
event.stopPropagation();
|
|
614
|
+
if (event.key === 'Escape') { event.preventDefault(); closeCuratorConfirmation(); return; }
|
|
615
|
+
if (event.key !== 'Tab') return;
|
|
616
|
+
const panel = $('curator-confirm-panel');
|
|
617
|
+
const focusable = [...panel.querySelectorAll('button:not([disabled]), [tabindex]:not([tabindex="-1"])')];
|
|
618
|
+
if (!focusable.length) { event.preventDefault(); return; }
|
|
619
|
+
const first = focusable[0];
|
|
620
|
+
const last = focusable.at(-1);
|
|
621
|
+
if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); }
|
|
622
|
+
else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); }
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
async function globalizePendingCurator() {
|
|
626
|
+
const candidate = state.curatorPendingCandidate;
|
|
627
|
+
if (!candidate || state.curatorGlobalizeBusy) return;
|
|
628
|
+
state.curatorGlobalizeBusy = true;
|
|
629
|
+
const panel = $('curator-confirm-panel');
|
|
630
|
+
const cancel = $('curator-confirm-cancel');
|
|
631
|
+
const submit = $('curator-confirm-submit');
|
|
632
|
+
panel.setAttribute('aria-busy', 'true');
|
|
633
|
+
cancel.disabled = true;
|
|
634
|
+
submit.disabled = true;
|
|
635
|
+
setI18nText(submit, 'curatorGlobalizing');
|
|
636
|
+
setCuratorConfirmationStatus(t('curatorGlobalizing'));
|
|
637
|
+
try {
|
|
638
|
+
await api('/api/curator/globalize?workspace=' + encodeURIComponent(candidate.workspace), {
|
|
639
|
+
method: 'POST',
|
|
640
|
+
headers: { 'content-type': 'application/json' },
|
|
641
|
+
body: JSON.stringify({ workspace: candidate.workspace, entryId: candidate.entryId, expectedRevision: candidate.revision }),
|
|
642
|
+
});
|
|
643
|
+
state.curatorGlobalized.add(curatorCandidateKey(candidate));
|
|
644
|
+
state.curatorGlobalizeBusy = false;
|
|
645
|
+
closeCuratorConfirmation(false);
|
|
646
|
+
await loadCurator();
|
|
647
|
+
await loadEntries();
|
|
648
|
+
setLocalizedStatus('curatorAdded');
|
|
649
|
+
setCuratorStatus(t('curatorAdded'));
|
|
650
|
+
requestAnimationFrame(() => $('curator-close')?.focus());
|
|
651
|
+
} catch (error) {
|
|
652
|
+
const message = error instanceof Error ? error.message : t('curatorGlobalizeFailed');
|
|
653
|
+
setCuratorConfirmationStatus(t('curatorGlobalizeFailed') + ' ' + message, true);
|
|
654
|
+
} finally {
|
|
655
|
+
state.curatorGlobalizeBusy = false;
|
|
656
|
+
panel.removeAttribute('aria-busy');
|
|
657
|
+
cancel.disabled = false;
|
|
658
|
+
submit.disabled = false;
|
|
659
|
+
setI18nText(submit, 'curatorConfirmAction');
|
|
443
660
|
}
|
|
444
|
-
state.curatorSelected.clear();
|
|
445
|
-
await loadCurator();
|
|
446
|
-
await loadEntries();
|
|
447
|
-
if (added > 0 && failed === 0) { setLocalizedStatus('curatorBatchAdded', { count: added }); setCuratorStatus(t('curatorBatchAdded', { count: added })); }
|
|
448
|
-
else if (added > 0) { setLocalizedStatus('curatorBatchPartial', { added, failed }, true); setCuratorStatus(t('curatorBatchPartial', { added, failed }), true); }
|
|
449
661
|
}
|
|
450
662
|
|
|
451
663
|
function renderCurator() {
|
|
@@ -453,25 +665,16 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
453
665
|
const modal = $('curator-modal');
|
|
454
666
|
modal.hidden = false;
|
|
455
667
|
const root = $('curator-list');
|
|
456
|
-
|
|
457
|
-
$('curator-selection-count').textContent = t('curatorSelected', { count: state.curatorSelected.size });
|
|
668
|
+
$('curator-result-count').textContent = t('curatorResultCount', { count: state.curatorTotalApproximate || state.curatorCandidates.length });
|
|
458
669
|
const actionRoot = $('curator-actions'); actionRoot.replaceChildren();
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
clearSelection.addEventListener('click', () => { state.curatorSelected.clear(); renderCurator(); });
|
|
463
|
-
const apply = document.createElement('button'); apply.type = 'button'; apply.className = 'button primary'; setI18nText(apply, 'curatorApplySelected'); apply.disabled = state.curatorSelected.size === 0;
|
|
464
|
-
apply.addEventListener('click', () => applySelectedCurator());
|
|
465
|
-
actionRoot.append(selectAll, clearSelection, apply);
|
|
670
|
+
if (state.curatorNextCursor) {
|
|
671
|
+
const more = document.createElement('button'); more.type = 'button'; more.className = 'button'; setI18nText(more, 'curatorLoadMore'); more.addEventListener('click', () => loadCurator(true)); actionRoot.append(more);
|
|
672
|
+
}
|
|
466
673
|
if (!state.curatorCandidates.length) { const empty = document.createElement('div'); empty.className = 'editor-empty'; setI18nText(empty, 'noCuratorCandidates'); root.replaceChildren(empty); return; }
|
|
467
|
-
const cards = state.curatorCandidates.map((candidate) => {
|
|
674
|
+
const cards = state.curatorCandidates.map((candidate, index) => {
|
|
468
675
|
const card = document.createElement('article'); card.className = 'curator-card';
|
|
469
676
|
const candidateKey = curatorCandidateKey(candidate);
|
|
470
677
|
const done = state.curatorGlobalized.has(candidateKey);
|
|
471
|
-
const selectLabel = document.createElement('label'); selectLabel.className = 'curator-select';
|
|
472
|
-
const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.checked = state.curatorSelected.has(candidateKey); checkbox.disabled = done;
|
|
473
|
-
checkbox.addEventListener('change', () => { if (checkbox.checked) state.curatorSelected.add(candidateKey); else state.curatorSelected.delete(candidateKey); renderCurator(); });
|
|
474
|
-
const selectText = document.createElement('span'); selectText.textContent = done ? t('globalized') : t('curatorSelectSkill'); selectLabel.append(checkbox, selectText);
|
|
475
678
|
const meta = document.createElement('div'); meta.className = 'entry-meta';
|
|
476
679
|
const kind = document.createElement('span'); kind.className = 'badge'; kind.textContent = labelForKind(candidate.kind);
|
|
477
680
|
const score = document.createElement('span'); score.className = 'badge'; score.textContent = t('curatorScore', { score: candidate.score });
|
|
@@ -480,6 +683,7 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
480
683
|
if (candidate.knowledge && candidate.knowledge.skillReady) { const ready = document.createElement('span'); ready.className = 'badge'; setI18nText(ready, 'curatorSkillReady'); meta.append(ready); }
|
|
481
684
|
const heading = document.createElement('h3'); heading.textContent = candidate.skillName;
|
|
482
685
|
const overview = document.createElement('div'); overview.className = 'curator-overview'; overview.textContent = candidate.overview.join('\n');
|
|
686
|
+
const tags = document.createElement('div'); tags.className = 'tags'; (candidate.tags || []).forEach((tag) => { const tagItem = document.createElement('span'); tagItem.className = 'tag'; tagItem.textContent = '#' + tag; tags.append(tagItem); });
|
|
483
687
|
const knowledge = document.createElement('div'); knowledge.className = 'curator-reasons'; knowledge.textContent = candidate.knowledge ? [
|
|
484
688
|
t('curatorEvidence', { hits: candidate.knowledge.qualifiedHits, runs: candidate.knowledge.independentRuns, workspaces: candidate.knowledge.independentWorkspaces }),
|
|
485
689
|
t('curatorSilo', { value: candidate.knowledge.averageCompleteness }),
|
|
@@ -506,22 +710,52 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
506
710
|
draft.append(label, content);
|
|
507
711
|
}
|
|
508
712
|
const reasons = document.createElement('div'); reasons.className = 'curator-reasons'; reasons.textContent = [...(candidate.reasons || []), ...(candidate.warnings || []).map((warning) => t('curatorWarning', { warning }))].join('\n');
|
|
509
|
-
|
|
510
|
-
|
|
713
|
+
const details = document.createElement('div'); details.id = 'curator-review-' + index; details.className = 'curator-review-details'; details.hidden = true; details.append(knowledge, draft, reasons);
|
|
714
|
+
const actions = document.createElement('div'); actions.className = 'curator-card-actions';
|
|
715
|
+
const review = document.createElement('button'); review.type = 'button'; review.className = 'button'; review.setAttribute('aria-controls', details.id); review.setAttribute('aria-expanded', 'false'); setI18nText(review, 'curatorReview');
|
|
716
|
+
review.addEventListener('click', () => { details.hidden = !details.hidden; review.setAttribute('aria-expanded', String(!details.hidden)); setI18nText(review, details.hidden ? 'curatorReview' : 'curatorHideReview'); });
|
|
717
|
+
const globalize = document.createElement('button'); globalize.type = 'button'; globalize.className = 'button primary'; globalize.disabled = done; setI18nText(globalize, done ? 'globalized' : 'curatorGlobalizeCandidate');
|
|
718
|
+
globalize.addEventListener('click', () => openCuratorConfirmation(candidate, globalize));
|
|
719
|
+
actions.append(review, globalize);
|
|
720
|
+
card.append(meta, heading, overview, tags, actions, details); return card;
|
|
511
721
|
});
|
|
512
|
-
root.replaceChildren(
|
|
722
|
+
root.replaceChildren(...cards);
|
|
513
723
|
}
|
|
514
724
|
|
|
515
|
-
async function loadCurator() {
|
|
516
|
-
|
|
725
|
+
async function loadCurator(append = false) {
|
|
726
|
+
// Keep the documented legacy URL shape recognizable for clients: /api/curator/candidates?limit=50
|
|
727
|
+
if (!append) {
|
|
728
|
+
openCurator();
|
|
729
|
+
state.curatorCandidates = [];
|
|
730
|
+
state.curatorNextCursor = null;
|
|
731
|
+
state.curatorTotalApproximate = 0;
|
|
732
|
+
} else if (!state.curatorNextCursor) return;
|
|
517
733
|
const panel = $('curator-panel');
|
|
518
734
|
panel.setAttribute('aria-busy', 'true');
|
|
519
735
|
setCuratorStatus(t('curatorLoading'));
|
|
520
736
|
try {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
737
|
+
if (!append) {
|
|
738
|
+
const facetParams = new URLSearchParams({ workspace: 'all' });
|
|
739
|
+
if (state.curatorIncludeGlobalized) facetParams.set('includeGlobalized', 'true');
|
|
740
|
+
const facetResult = await api('/api/curator/facets?' + facetParams);
|
|
741
|
+
state.curatorFacets = facetResult.facets || {};
|
|
742
|
+
renderCuratorFilters();
|
|
743
|
+
}
|
|
744
|
+
const params = new URLSearchParams({ workspace: 'all', limit: '50' });
|
|
745
|
+
if (state.curatorProject) params.set('project', state.curatorProject);
|
|
746
|
+
if (state.curatorSearch) params.set('search', state.curatorSearch);
|
|
747
|
+
if (state.curatorFramework) params.set('framework', state.curatorFramework);
|
|
748
|
+
if (state.curatorLanguage) params.set('language', state.curatorLanguage);
|
|
749
|
+
if (state.curatorMemoryClass) params.set('memoryClass', state.curatorMemoryClass);
|
|
750
|
+
if (state.curatorTier) params.set('tier', state.curatorTier);
|
|
751
|
+
if (state.curatorReady) params.set('skillReadyOnly', 'true');
|
|
752
|
+
if (state.curatorIncludeGlobalized) params.set('includeGlobalized', 'true');
|
|
753
|
+
for (const tag of state.curatorTags) params.append('tag', tag);
|
|
754
|
+
if (append && state.curatorNextCursor) params.set('cursor', state.curatorNextCursor);
|
|
755
|
+
const result = await api('/api/curator/candidates?' + params);
|
|
756
|
+
state.curatorCandidates = append ? [...state.curatorCandidates, ...(result.candidates || [])] : (result.candidates || []);
|
|
757
|
+
state.curatorNextCursor = result.nextCursor || null;
|
|
758
|
+
state.curatorTotalApproximate = Number(result.totalApproximate || state.curatorCandidates.length);
|
|
525
759
|
setCuratorStatus('');
|
|
526
760
|
renderCurator();
|
|
527
761
|
}
|
|
@@ -582,7 +816,29 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
582
816
|
} catch (error) { setStatus(error.message, true); }
|
|
583
817
|
}
|
|
584
818
|
|
|
585
|
-
async function loadEntries() {
|
|
819
|
+
async function loadEntries() {
|
|
820
|
+
if (!state.workspace) return;
|
|
821
|
+
try {
|
|
822
|
+
const params = new URLSearchParams({ workspace: state.workspace });
|
|
823
|
+
if (state.kind !== 'all') params.set('kind', state.kind);
|
|
824
|
+
if (state.tag) params.set('tag', state.tag);
|
|
825
|
+
if (state.query) params.set('q', state.query);
|
|
826
|
+
const result = await api('/api/entries?' + params);
|
|
827
|
+
state.entries = result.entries;
|
|
828
|
+
state.recallItems = [];
|
|
829
|
+
state.selectedRecall = null;
|
|
830
|
+
if (state.query && state.kind === 'all' && !state.tag) {
|
|
831
|
+
const recallParams = new URLSearchParams({ workspace: state.workspace, q: state.query, limit: '100' });
|
|
832
|
+
const recalled = await api('/api/memory/recall?' + recallParams);
|
|
833
|
+
state.recallItems = recalled.combined?.items || [];
|
|
834
|
+
state.selected = null;
|
|
835
|
+
} else if (state.selected && !state.entries.some((entry) => entry.id === state.selected.id)) state.selected = null;
|
|
836
|
+
renderEntries(); renderFilters();
|
|
837
|
+
if (!state.recallItems.length && !state.selected && state.entries[0]) await selectEntry(state.entries[0].id);
|
|
838
|
+
else renderEditor();
|
|
839
|
+
setLocalizedCountStatus('displayedCount', state.recallItems.length || result.entries.length);
|
|
840
|
+
} catch (error) { setStatus(error.message, true); }
|
|
841
|
+
}
|
|
586
842
|
async function loadTags() { if (!state.workspace) return; try { const result = await api('/api/tags?workspace=' + encodeURIComponent(state.workspace)); state.tags = result.tags; renderFilters(); } catch (error) { setStatus(error.message, true); } }
|
|
587
843
|
async function loadWorkspaces() { try { const result = await api('/api/workspaces'); const select = $('workspace'); select.replaceChildren(...result.workspaces.map((item) => { const option = document.createElement('option'); option.value = item.workspace; option.textContent = (item.displayName || item.workspace) + ' (' + item.count + ')'; return option; })); if (!state.workspace && result.workspaces[0]) state.workspace = result.workspaces[0].workspace; select.value = state.workspace; if (state.workspace) { await loadTags(); await loadEntries(); await loadRuns(); } if (state.curatorOpen) await loadCurator(); else if (!state.workspace) setLocalizedStatus('noWorkspace', {}, true); } catch (error) { setStatus(error.message, true); } }
|
|
588
844
|
$('language-toggle').addEventListener('click', () => {
|
|
@@ -606,10 +862,14 @@ export const WEB_HTML = String.raw `<!doctype html>
|
|
|
606
862
|
});
|
|
607
863
|
document.addEventListener('click', (event) => { if (!$('language-picker')?.contains(event.target)) setLanguageMenuOpen(false); });
|
|
608
864
|
document.addEventListener('focusin', (event) => { if (!$('language-picker')?.contains(event.target)) setLanguageMenuOpen(false); });
|
|
609
|
-
$('workspace').addEventListener('change', (event) => { if (state.curatorOpen) closeCurator(); state.workspace = event.target.value; state.selected = null; state.selectedRun = null; state.runs = []; state.tag = ''; state.curatorCandidates = []; state.
|
|
865
|
+
$('workspace').addEventListener('change', (event) => { if (state.curatorOpen) closeCurator(); state.workspace = event.target.value; state.selected = null; state.selectedRecall = null; state.selectedRun = null; state.runs = []; state.tag = ''; state.curatorCandidates = []; state.curatorGlobalized = new Set(); state.curatorNextCursor = null; state.curatorTotalApproximate = 0; state.curatorOpen = false; loadTags().then(loadEntries).then(loadRuns); });
|
|
610
866
|
$('curator-button').addEventListener('click', () => loadCurator());
|
|
611
867
|
$('curator-close').addEventListener('click', () => closeCurator());
|
|
868
|
+
$('curator-confirm-cancel').addEventListener('click', () => closeCuratorConfirmation());
|
|
869
|
+
$('curator-confirm-submit').addEventListener('click', () => globalizePendingCurator());
|
|
870
|
+
$('curator-confirm-modal').addEventListener('keydown', handleCuratorConfirmationKeydown);
|
|
612
871
|
$('curator-modal').addEventListener('keydown', handleCuratorKeydown);
|
|
872
|
+
window.addEventListener('popstate', () => { restoreCuratorUrl(); if (state.curatorOpen) loadCurator(); });
|
|
613
873
|
$('refresh').addEventListener('click', () => loadWorkspaces());
|
|
614
874
|
let searchTimer; $('search').addEventListener('input', (event) => { clearTimeout(searchTimer); state.query = event.target.value.trim(); searchTimer = setTimeout(() => loadEntries(), 180); });
|
|
615
875
|
applyTranslations();
|
package/dist/web/ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/web/ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE7F,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC;IACrC,aAAa,EAAE,kBAAkB;IACjC,YAAY,EAAE,iBAAiB;IAC/B,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,YAAY;CACvB,CAAC;KACC,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;KAC1B,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;KAC1B,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;KAC1B,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC;KAC/B,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAEnC,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAA
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/web/ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE7F,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC;IACrC,aAAa,EAAE,kBAAkB;IACjC,YAAY,EAAE,iBAAiB;IAC/B,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,YAAY;CACvB,CAAC;KACC,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;KAC1B,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;KAC1B,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC;KAC1B,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC;KAC/B,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAEnC,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAqOf,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6nB1B,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
-- Federated retrieval metadata. Existing structured scopes remain valid and
|
|
2
|
+
-- legacy project entries stay project-only unless explicit applicability is
|
|
3
|
+
-- present; no entry rows are rewritten by this migration.
|
|
4
|
+
CREATE TABLE repository_fingerprints (
|
|
5
|
+
repository_id TEXT PRIMARY KEY
|
|
6
|
+
REFERENCES repositories(repository_id)
|
|
7
|
+
ON DELETE CASCADE,
|
|
8
|
+
fingerprint_json TEXT NOT NULL,
|
|
9
|
+
manifest_digest TEXT NOT NULL,
|
|
10
|
+
updated_at TEXT NOT NULL
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
CREATE INDEX IF NOT EXISTS idx_entry_search_signals_type_value_entry
|
|
14
|
+
ON entry_search_signals(signal_type, normalized_value, entry_id);
|
|
15
|
+
|
|
16
|
+
CREATE INDEX IF NOT EXISTS idx_entries_workspace_status
|
|
17
|
+
ON entries(workspace, status);
|
|
18
|
+
|
|
19
|
+
-- Version 2 only allowed project/global delivery origins. Rebuild the small
|
|
20
|
+
-- projection table so context deliveries can retain ecosystem provenance.
|
|
21
|
+
CREATE TABLE context_delivery_entries_federated (
|
|
22
|
+
delivery_id TEXT NOT NULL REFERENCES context_deliveries(delivery_id) ON DELETE CASCADE,
|
|
23
|
+
entry_id TEXT NOT NULL,
|
|
24
|
+
entry_revision INTEGER NOT NULL CHECK (entry_revision > 0),
|
|
25
|
+
rank INTEGER NOT NULL CHECK (rank > 0),
|
|
26
|
+
score_components_json TEXT NOT NULL,
|
|
27
|
+
selection_reason_json TEXT NOT NULL,
|
|
28
|
+
origin_scope TEXT NOT NULL DEFAULT 'project' CHECK (origin_scope IN ('project', 'ecosystem', 'global')),
|
|
29
|
+
PRIMARY KEY (delivery_id, entry_id),
|
|
30
|
+
FOREIGN KEY (entry_id, entry_revision)
|
|
31
|
+
REFERENCES entry_revisions(entry_id, revision)
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
INSERT INTO context_delivery_entries_federated (
|
|
35
|
+
delivery_id, entry_id, entry_revision, rank,
|
|
36
|
+
score_components_json, selection_reason_json, origin_scope
|
|
37
|
+
)
|
|
38
|
+
SELECT delivery_id, entry_id, entry_revision, rank,
|
|
39
|
+
score_components_json, selection_reason_json, origin_scope
|
|
40
|
+
FROM context_delivery_entries;
|
|
41
|
+
|
|
42
|
+
DROP TABLE context_delivery_entries;
|
|
43
|
+
ALTER TABLE context_delivery_entries_federated RENAME TO context_delivery_entries;
|
|
44
|
+
|
|
45
|
+
CREATE INDEX idx_context_delivery_entries_entry
|
|
46
|
+
ON context_delivery_entries(entry_id, entry_revision);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askdkc/kiokuko",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "Model-agnostic external memory for AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -36,11 +36,13 @@
|
|
|
36
36
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
37
37
|
"commander": "^14.0.1",
|
|
38
38
|
"jsonc-parser": "^3.3.1",
|
|
39
|
+
"semver": "^7.8.5",
|
|
39
40
|
"yaml": "^2.9.0",
|
|
40
41
|
"zod": "^4.4.3"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"@types/node": "^24.0.0",
|
|
45
|
+
"@types/semver": "^7.8.0",
|
|
44
46
|
"tsx": "^4.20.3",
|
|
45
47
|
"typescript": "^5.9.2"
|
|
46
48
|
}
|