@jagilber-org/index-server 1.27.0 → 1.28.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/CHANGELOG.md +63 -1
- package/CONTRIBUTING.md +3 -3
- package/dist/dashboard/client/admin.html +58 -28
- package/dist/dashboard/client/css/admin.css +54 -0
- package/dist/dashboard/client/js/admin.config.js +3 -6
- package/dist/dashboard/client/js/admin.embeddings.js +63 -4
- package/dist/dashboard/client/js/admin.events.js +256 -0
- package/dist/dashboard/client/js/admin.feedback.js +1 -1
- package/dist/dashboard/client/js/admin.instructions.js +1 -1
- package/dist/dashboard/client/js/admin.maintenance.js +75 -32
- package/dist/dashboard/client/js/admin.sessions.js +1 -1
- package/dist/dashboard/security/SecurityMonitor.js +2 -2
- package/dist/dashboard/server/AdminPanel.js +83 -6
- package/dist/dashboard/server/AdminPanelConfig.d.ts +11 -0
- package/dist/dashboard/server/AdminPanelConfig.js +47 -17
- package/dist/dashboard/server/AdminPanelState.js +5 -1
- package/dist/dashboard/server/ApiRoutes.js +2 -1
- package/dist/dashboard/server/DashboardServer.js +13 -0
- package/dist/dashboard/server/MetricsCollector.js +3 -2
- package/dist/dashboard/server/WebSocketManager.js +2 -2
- package/dist/dashboard/server/middleware/ensureLoadedMiddleware.d.ts +1 -1
- package/dist/dashboard/server/middleware/ensureLoadedMiddleware.js +1 -1
- package/dist/dashboard/server/routes/admin.routes.js +143 -17
- package/dist/dashboard/server/routes/api.usage.routes.js +5 -1
- package/dist/dashboard/server/routes/embeddings.routes.js +91 -1
- package/dist/dashboard/server/routes/instructions.routes.js +142 -12
- package/dist/dashboard/server/routes/scripts.routes.js +1 -1
- package/dist/dashboard/server/routes/sqlite.routes.js +74 -0
- package/dist/models/instruction.d.ts +1 -1
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.js +1 -1
- package/dist/server/sdkServer.js +12 -4
- package/dist/services/auditLog.d.ts +1 -1
- package/dist/services/auditLog.js +1 -1
- package/dist/services/embeddingService.d.ts +2 -0
- package/dist/services/embeddingService.js +16 -4
- package/dist/services/embeddingTrigger.d.ts +33 -0
- package/dist/services/embeddingTrigger.js +86 -0
- package/dist/services/eventBuffer.d.ts +45 -0
- package/dist/services/eventBuffer.js +110 -0
- package/dist/services/feedbackStorage.js +1 -1
- package/dist/services/handlers/instructions.add.js +36 -3
- package/dist/services/handlers/instructions.import.js +71 -13
- package/dist/services/handlers.dashboardConfig.js +81 -0
- package/dist/services/handlers.feedback.js +1 -1
- package/dist/services/handlers.instructionSchema.js +4 -4
- package/dist/services/handlers.search.js +3 -3
- package/dist/services/indexContext.d.ts +18 -0
- package/dist/services/indexContext.js +133 -24
- package/dist/services/instructionRecordValidation.d.ts +3 -0
- package/dist/services/instructionRecordValidation.js +64 -4
- package/dist/services/logger.js +9 -0
- package/dist/services/manifestManager.js +11 -1
- package/dist/services/seedBootstrap.js +7 -3
- package/dist/services/storage/factory.d.ts +2 -0
- package/dist/services/storage/factory.js +12 -1
- package/dist/services/toolRegistry.js +8 -8
- package/dist/services/toolRegistry.zod.js +3 -3
- package/dist/services/tracing.js +3 -1
- package/dist/versioning/schemaVersion.d.ts +1 -1
- package/dist/versioning/schemaVersion.js +47 -2
- package/package.json +54 -40
- package/schemas/index-server.code-schema.json +1 -1
- package/schemas/instruction.schema.json +3 -3
- package/schemas/json-schema/instruction-content-type.schema.json +1 -1
- package/schemas/json-schema/instruction-instruction-entry.schema.json +1 -1
- package/scripts/README.md +48 -0
- package/scripts/{generate-certs.mjs → build/generate-certs.mjs} +1 -1
- package/scripts/{setup-wizard.mjs → build/setup-wizard.mjs} +1 -1
- package/scripts/{setup-hooks.cjs → hooks/setup-hooks.cjs} +3 -3
- package/server.json +3 -3
- /package/scripts/{copy-dashboard-assets.mjs → build/copy-dashboard-assets.mjs} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,68 @@ The format is based on Keep a Changelog and this project adheres to Semantic Ver
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Release workflow**: added `scripts/Invoke-ReleaseWorkflow.ps1` as the canonical release/publish front door. It loads `.env`, resolves tag/remote/clean-room defaults, runs release preflight checks, optionally pushes and verifies the internal branch/tags, waits for internal GitHub Actions checks, prepares the clean-room mirror copy, and either prints or explicitly invokes the human-only public mirror delivery path.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **Publish scripts**: restored root-level entrypoints for `New-CleanRoomCopy.ps1`, `Publish-ToMirror.ps1`, and `publish-direct-to-remote.cjs` after the scripts reorganization so documented/template paths continue to work without introducing alternate release workflow names.
|
|
16
|
+
- **Public publish/security gates**: clean-room publish now keeps ambient exact env-value leak detection active, GitHub Action scanner uploads fail visibly instead of being hidden, ggshield quota exhaustion fails closed, and internal release branch/tag verification compares exact local/remote SHAs.
|
|
17
|
+
- **Tool classification docs**: clarified that registry `stable` vs `mutation` is a visibility/gating contract, so `feedback_submit` remains stable/core while still persisting feedback and audit entries.
|
|
18
|
+
- **Instruction content type migration**: bumped instruction schema version to v5 and added a compatibility path mapping legacy `contentType: "chat-session"` records and writes to `workflow`, preserving workflow/runbook semantics instead of falling back to `instruction`.
|
|
19
|
+
|
|
20
|
+
## [1.28.0] - 2026-05-04
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **Integrity probes**: pre-push hook runs 12-probe mutation integrity test and 4-client concurrent SQLite write test before every push (`scripts/hooks/pre-push-integrity.ps1`). Skip with `SKIP_INTEGRITY_PREPUSH=1`.
|
|
25
|
+
- **Adhoc diagnostics**: disk-state monitor (`scripts/diagnostics/adhoc-disk-state-monitor.mjs`), mutation integrity probe (`scripts/diagnostics/adhoc-mutation-integrity.mjs`), and concurrent write test (`scripts/perf/adhoc-concurrent-integrity.mjs`) for ad-hoc and CI use.
|
|
26
|
+
- **SQLite validation endpoint**: `/sqlite/validate` dashboard route and client script (`scripts/diagnostics/sqlite-validate.ps1`) for on-demand WAL integrity checks.
|
|
27
|
+
- **Enum validation in migration**: `migrateInstructionRecord()` now validates all 6 enum fields (audience, requirement, contentType, status, priorityTier, classification) with legacy coercion maps aligned with the loader, falling back to safe defaults for truly unknown values.
|
|
28
|
+
- **Negative enum tests**: 19 unit tests covering input-surface rejection and migration correction of invalid enum values.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- **Lax mode defaults** (`instructions.add`): `contentType` now defaults to `"instruction"` in lax mode so agents omitting it no longer fail silently (#312).
|
|
33
|
+
- **Enum coercion ordering**: legacy enum values (e.g., `audience:"developers"`, `requirement:"SHOULD"`) are now coerced before validation instead of being rejected at the input surface (#312).
|
|
34
|
+
- **Scripts reorg paths**: fixed `$PSScriptRoot` references across 10+ PowerShell scripts after `scripts/` subdirectory reorganization (#311). Fixed Dockerfile, `.dockerignore`, `sync-constitution.ps1`, and `setup-wizard-config-validate.mjs` paths.
|
|
35
|
+
- **PII scanner self-detection**: added pre-commit hook files to `PII_FILE_ALLOWLIST` so SAS-token regex definitions aren't flagged as leaks.
|
|
36
|
+
- **Constitution sync**: regenerated `constitution.md` and `.specify/memory/constitution.md` from `constitution.json`.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- **Scripts reorganization**: all scripts moved from `scripts/` root into purpose-based subdirectories (`build/`, `client/`, `deploy/`, `diagnostics/`, `governance/`, `hooks/`, `migration/`, `perf/`, `testing/`, `ci/`) (#311).
|
|
41
|
+
- **Security hardening**: input validation hardening for `index_add` (#307), security triage blockers (#309), CodeQL and Trivy dependency bumps (#298, #299).
|
|
42
|
+
|
|
43
|
+
## [1.27.2] - 2026-05-01
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- **Release workflow** (`.github/workflows/release.yml`): trim `description` in `package.json` and `server.json` from 146 to 98 chars to satisfy the MCP Registry validator (`expected length <= 100` on `body.description`). The MCP Registry publish step had been failing on every release since v1.26.3 with HTTP 422.
|
|
48
|
+
- **Release workflow** (`scripts/Invoke-ReleaseWorkflow.ps1`): add a fail-fast parity guard that aborts before tagging when `package.json.version` does not match the `-Tag` argument (sans `v` prefix). The v1.27.1 release shipped a tag whose `package.json` still said `1.27.0`, which caused the `Check npmjs version status` step to skip publish (it found `1.27.0` already on npmjs and set `already_published=true`). This guard prevents the same class of mismatch from reaching the public mirror again.
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- **Release workflow** (`.github/workflows/release.yml`): publish to the GitHub Packages npm registry (`https://npm.pkg.github.com`) in addition to npmjs, so `https://github.com/jagilber-org/index-server/pkgs/npm/index-server` populates on each release. Auth uses the workflow-scoped `GITHUB_TOKEN` (no extra secret needed).
|
|
53
|
+
|
|
54
|
+
### Notes
|
|
55
|
+
|
|
56
|
+
- v1.27.1 was tagged on the public mirror but is **incomplete**: the npmjs publish step was skipped (stale version in tag), the GitHub Packages registry was never wired (now fixed), and the MCP Registry rejected the description (now fixed). v1.27.2 is the corrected release. v1.27.1 will not be retroactively republished.
|
|
57
|
+
|
|
58
|
+
## [1.27.1] - 2026-05-01
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
|
|
62
|
+
- **Security**: pin `mermaid` and `@mermaid-js/layout-elk` transitive `uuid` to `^14.0.0` via npm overrides to clear GHSA-w5hq-g745-h8pq. Server-side bundle has no mermaid imports; dashboard remains lazy-loaded.
|
|
63
|
+
- **Build**: pin `@types/express-serve-static-core` to `5.0.7` to keep dashboard route handler signatures stable after lockfile regen pulled `5.1.1` (which changed `req.params` typing).
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
|
|
67
|
+
- **Deploy** (`scripts/deploy-local.ps1`): runtime `package.json` written to the deploy target now preserves the `overrides` block from the source manifest. Without it, `npm ci --omit=dev` failed with `EUSAGE Missing: uuid@11.1.1 from lock file` because the override-resolved lockfile didn't match the unstripped manifest.
|
|
68
|
+
- **CodeQL pre-push gate** (`scripts/run-codeql-pre-push.ps1`): now sources `scripts/Load-RepoEnv.ps1` and honors absolute paths from `.env` (`CODEQL_DB_PATH`, `CODEQL_LOG_DIR`, `CODEQL_OUTPUT_PATH`, `CODEQL_LANGUAGE`, `CODEQL_THREADS`, `CODEQL_RAM`). Reuses pre-built databases instead of always rebuilding in-repo.
|
|
69
|
+
- **Publish workflow** (`scripts/Publish-ToMirror.ps1`): after opening a publish PR via `-CreatePR`, now prints a copy-pasteable next-steps block (`gh api …/git/refs` + `gh release create --generate-notes`) so the operator can tag the merge commit and kick off the GitHub release in one shot. The `-WaitForMerge` success path also surfaces the `gh release create` command.
|
|
70
|
+
|
|
9
71
|
## [1.27.0] - 2026-04-30
|
|
10
72
|
|
|
11
73
|
### Changed (BREAKING)
|
|
@@ -77,7 +139,7 @@ Also removed: `DashboardHttpConfig.rateLimitEnabled / rateLimitWindowMs / rateLi
|
|
|
77
139
|
|
|
78
140
|
### Removed (breaking — MCP feedback surface)
|
|
79
141
|
|
|
80
|
-
- **MCP feedback tools collapsed to `feedback_submit` only (#111)**. The following MCP tools have been removed with no deprecation alias and no compatibility shim: `feedback_list`, `feedback_get`, `feedback_update`, `feedback_delete`, `feedback_stats`, `feedback_health`, `feedback_dispatch`. Agents must use `feedback_submit` to file entries. Human-operator CRUD now lives behind dashboard authentication at `GET/POST /admin/feedback`, `GET/PATCH/DELETE /admin/feedback/:id`, sharing the same `feedback/feedback-entries.json` store as the MCP submit path. GitHub issue handoff from the dashboard is browser-side, human-triggered, token-free, and targets `jagilber-org/index-server`. Spec: `specs/111-feedback-mcp-rip-down.md`.
|
|
142
|
+
- **MCP feedback tools collapsed to `feedback_submit` only (#111)**. The following MCP tools have been removed with no deprecation alias and no compatibility shim: `feedback_list`, `feedback_get`, `feedback_update`, `feedback_delete`, `feedback_stats`, `feedback_health`, `feedback_dispatch`. Agents must use the stable, core-visible `feedback_submit` tool to file entries. Human-operator CRUD now lives behind dashboard authentication at `GET/POST /admin/feedback`, `GET/PATCH/DELETE /admin/feedback/:id`, sharing the same `feedback/feedback-entries.json` store as the MCP submit path. GitHub issue handoff from the dashboard is browser-side, human-triggered, token-free, and targets `jagilber-org/index-server`. Spec: `specs/111-feedback-mcp-rip-down.md`.
|
|
81
143
|
|
|
82
144
|
## [1.24.0] - 2026-04-24
|
|
83
145
|
|
package/CONTRIBUTING.md
CHANGED
|
@@ -39,14 +39,14 @@ If any code or tests in the PR were generated or materially edited by an AI agen
|
|
|
39
39
|
- [ ] Claimed test counts match real coverage and assertions
|
|
40
40
|
- [ ] No hardcoded success values such as `verified: true` or `created: true` were added unless computed from a real check
|
|
41
41
|
- [ ] Agent attestation metadata present on agent-authored commits (AG-4)
|
|
42
|
-
- [ ] Copilot `Co-authored-by: Copilot <
|
|
42
|
+
- [ ] Copilot `Co-authored-by: Copilot <copilot-noreply-email>` trailer present on Copilot-authored commits
|
|
43
43
|
- [ ] Tests added for behavioral changes (unit + integration where the change crosses a layer boundary)
|
|
44
44
|
- [ ] No hardcoded paths or secrets — all tunables routed through `src/config/runtimeConfig.ts` (`npm run guard:env` passes)
|
|
45
45
|
- [ ] `logAudit()` invoked on every mutation success and side-effecting error path
|
|
46
46
|
- [ ] `src/services/toolRegistry.ts` updated for new/changed tools (INPUT_SCHEMAS + STABLE + MUTATION + describeTool) and registered via `src/services/toolHandlers.ts`
|
|
47
47
|
- [ ] Conventional Commit subjects on every commit
|
|
48
|
-
- [ ] If `constitution.json` changed: `pwsh -File scripts/sync-constitution.ps1 -Check` passes and rendered `.md` files are regenerated
|
|
49
|
-
- [ ] Security-sensitive changes carry explicit
|
|
48
|
+
- [ ] If `constitution.json` changed: `pwsh -File scripts/build/sync-constitution.ps1 -Check` passes and rendered `.md` files are regenerated
|
|
49
|
+
- [ ] Security-sensitive changes carry explicit security + testing consensus approvals or a linked decision record
|
|
50
50
|
- [ ] Imported external code has a documented source and a `LICENSE`-compatible license, with attribution recorded in `THIRD-PARTY-LICENSES.md` where required
|
|
51
51
|
|
|
52
52
|
PRs that fail any AI-generated code/test review item must be sent back for correction before merge.
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
|
-
<meta name="dashboard-build-version" content="1.
|
|
4
|
+
<meta name="dashboard-build-version" content="1.28.0-0009101e">
|
|
5
5
|
<meta charset="UTF-8">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
7
|
<title>Index Server Admin</title>
|
|
8
|
-
<link rel="stylesheet" href="css/admin.css?v=1.
|
|
9
|
-
<script defer src="js/admin.utils.js?v=1.
|
|
10
|
-
<script defer src="js/admin.auth.js?v=1.
|
|
11
|
-
<script defer src="js/admin.overview.js?v=1.
|
|
12
|
-
<script defer src="js/admin.sessions.js?v=1.
|
|
13
|
-
<script defer src="js/admin.monitor.js?v=1.
|
|
14
|
-
<script defer src="js/admin.
|
|
8
|
+
<link rel="stylesheet" href="css/admin.css?v=1.28.0-0009101e">
|
|
9
|
+
<script defer src="js/admin.utils.js?v=1.28.0-0009101e"></script>
|
|
10
|
+
<script defer src="js/admin.auth.js?v=1.28.0-0009101e"></script>
|
|
11
|
+
<script defer src="js/admin.overview.js?v=1.28.0-0009101e"></script>
|
|
12
|
+
<script defer src="js/admin.sessions.js?v=1.28.0-0009101e"></script>
|
|
13
|
+
<script defer src="js/admin.monitor.js?v=1.28.0-0009101e"></script>
|
|
14
|
+
<script defer src="js/admin.events.js?v=1.28.0-0009101e"></script>
|
|
15
|
+
<script defer src="js/admin.graph.js?v=1.28.0-0009101e"></script>
|
|
15
16
|
<script defer src="js/marked.umd.js"></script>
|
|
16
|
-
<script defer src="js/admin.instructions.js?v=1.
|
|
17
|
-
<script defer src="js/admin.logs.js?v=1.
|
|
18
|
-
<script defer src="js/admin.maintenance.js?v=1.
|
|
19
|
-
<script defer src="js/admin.config.js?v=1.
|
|
20
|
-
<script defer src="js/admin.performance.js?v=1.
|
|
21
|
-
<script defer src="js/admin.instances.js?v=1.
|
|
22
|
-
<script defer src="js/admin.embeddings.js?v=1.
|
|
23
|
-
<script defer src="js/admin.messaging.js?v=1.
|
|
24
|
-
<script defer src="js/admin.sqlite.js?v=1.
|
|
25
|
-
<script defer src="js/admin.boot.js?v=1.
|
|
26
|
-
<script defer src="js/admin.feedback.js?v=1.
|
|
17
|
+
<script defer src="js/admin.instructions.js?v=1.28.0-0009101e"></script>
|
|
18
|
+
<script defer src="js/admin.logs.js?v=1.28.0-0009101e"></script>
|
|
19
|
+
<script defer src="js/admin.maintenance.js?v=1.28.0-0009101e"></script>
|
|
20
|
+
<script defer src="js/admin.config.js?v=1.28.0-0009101e"></script>
|
|
21
|
+
<script defer src="js/admin.performance.js?v=1.28.0-0009101e"></script>
|
|
22
|
+
<script defer src="js/admin.instances.js?v=1.28.0-0009101e"></script>
|
|
23
|
+
<script defer src="js/admin.embeddings.js?v=1.28.0-0009101e"></script>
|
|
24
|
+
<script defer src="js/admin.messaging.js?v=1.28.0-0009101e"></script>
|
|
25
|
+
<script defer src="js/admin.sqlite.js?v=1.28.0-0009101e"></script>
|
|
26
|
+
<script defer src="js/admin.boot.js?v=1.28.0-0009101e"></script>
|
|
27
|
+
<script defer src="js/admin.feedback.js?v=1.28.0-0009101e"></script>
|
|
27
28
|
</head>
|
|
28
29
|
<body>
|
|
29
30
|
<div class="admin-container admin-root">
|
|
@@ -48,7 +49,7 @@
|
|
|
48
49
|
<button class="nav-btn" data-section="config" onclick="window.showSection && window.showSection('config')">Configuration</button>
|
|
49
50
|
<button id="nav-sessions" class="nav-btn" data-section="sessions" onclick="window.showSection && window.showSection('sessions')">Sessions</button>
|
|
50
51
|
<button class="nav-btn" data-section="maintenance" onclick="window.showSection && window.showSection('maintenance')">Maintenance</button>
|
|
51
|
-
<button class="nav-btn" data-section="monitoring" onclick="window.showSection && window.showSection('monitoring')">Monitoring
|
|
52
|
+
<button class="nav-btn" data-section="monitoring" onclick="window.showSection && window.showSection('monitoring')">Monitoring<span id="nav-events-bubble" class="nav-bubble" hidden></span></button>
|
|
52
53
|
<button class="nav-btn" data-section="instructions" onclick="window.showSection && window.showSection('instructions')">Instructions</button>
|
|
53
54
|
<button class="nav-btn" data-section="graph" onclick="window.showSection && window.showSection('graph')">Graph</button>
|
|
54
55
|
<button class="nav-btn" data-section="embeddings" onclick="window.showSection && window.showSection('embeddings')">Embeddings</button>
|
|
@@ -328,6 +329,34 @@
|
|
|
328
329
|
<!-- Monitoring Section -->
|
|
329
330
|
<div id="monitoring-section" class="admin-section hidden">
|
|
330
331
|
<div class="admin-card">
|
|
332
|
+
<div class="card-header">
|
|
333
|
+
<div class="card-icon">⚠️</div>
|
|
334
|
+
<div class="card-title">Recent Events <span id="events-counts-summary" class="muted small"></span></div>
|
|
335
|
+
<div class="card-actions">
|
|
336
|
+
<input id="events-search" class="form-input form-input-sm events-search" type="search" placeholder="Search msg/detail…" />
|
|
337
|
+
<select id="events-level-filter" class="form-input form-input-sm">
|
|
338
|
+
<option value="">All severities</option>
|
|
339
|
+
<option value="WARN">WARN only</option>
|
|
340
|
+
<option value="ERROR">ERROR only</option>
|
|
341
|
+
</select>
|
|
342
|
+
<select id="events-page-size" class="form-input form-input-sm" title="Page size">
|
|
343
|
+
<option value="25">25 / page</option>
|
|
344
|
+
<option value="50" selected>50 / page</option>
|
|
345
|
+
<option value="100">100 / page</option>
|
|
346
|
+
<option value="200">200 / page</option>
|
|
347
|
+
</select>
|
|
348
|
+
<button id="events-refresh-btn" class="action-btn-sm" onclick="window.loadEvents && window.loadEvents()">Refresh</button>
|
|
349
|
+
<button id="events-clear-btn" class="action-btn-sm" onclick="window.clearEvents && window.clearEvents()">Mark All Read</button>
|
|
350
|
+
</div>
|
|
351
|
+
</div>
|
|
352
|
+
<div id="events-panel" class="loading">Loading events…</div>
|
|
353
|
+
<div id="events-pager" class="events-pager hidden">
|
|
354
|
+
<button id="events-prev" class="action-btn-sm" type="button">‹ Newer</button>
|
|
355
|
+
<span id="events-page-info" class="muted small"></span>
|
|
356
|
+
<button id="events-next" class="action-btn-sm" type="button">Older ›</button>
|
|
357
|
+
</div>
|
|
358
|
+
</div>
|
|
359
|
+
<div class="admin-card mt-xxl">
|
|
331
360
|
<div class="card-header">
|
|
332
361
|
<div class="card-icon"><svg viewBox="0 0 24 24" fill="none" stroke="#3b82f6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 14 10 14 12 10 16 20 18 14 22 14"/><circle cx="6" cy="6" r="2"/></svg></div>
|
|
333
362
|
<div class="card-title">Real-time Monitoring <a class="doc-link" href="/api/docs/monitoring" target="_blank" title="Panel documentation">?</a></div>
|
|
@@ -404,6 +433,7 @@
|
|
|
404
433
|
|
|
405
434
|
<!-- Embeddings Visualization Section -->
|
|
406
435
|
<div id="embeddings-section" class="admin-section hidden">
|
|
436
|
+
<div id="emb-status-banner" class="emb-status-banner hidden" role="status" aria-live="polite"></div>
|
|
407
437
|
<div class="admin-card" style="padding:0;overflow:hidden">
|
|
408
438
|
<div class="emb-layout">
|
|
409
439
|
<!-- Sidebar -->
|
|
@@ -879,10 +909,10 @@
|
|
|
879
909
|
}
|
|
880
910
|
}
|
|
881
911
|
|
|
882
|
-
// Graph logic was extracted to js/admin.graph.js?v=1.
|
|
912
|
+
// Graph logic was extracted to js/admin.graph.js?v=1.28.0-0009101e
|
|
883
913
|
// Functions available globally: reloadGraphMermaid, initGraphScopeDefaults, copyMermaidSource, toggleGraphEdit, applyGraphEdit, cancelGraphEdit, refreshDrillCategories, loadDrillInstructions, clearSelections
|
|
884
914
|
|
|
885
|
-
<!-- overview functions moved to js/admin.overview.js?v=1.
|
|
915
|
+
<!-- overview functions moved to js/admin.overview.js?v=1.28.0-0009101e -->
|
|
886
916
|
|
|
887
917
|
// Lightweight overview-level maintenance display (optional)
|
|
888
918
|
// Intentionally minimal to avoid blocking overview rendering.
|
|
@@ -1067,7 +1097,7 @@
|
|
|
1067
1097
|
}
|
|
1068
1098
|
|
|
1069
1099
|
// --- Backup / Restore ---
|
|
1070
|
-
// Extracted to js/admin.maintenance.js?v=1.
|
|
1100
|
+
// Extracted to js/admin.maintenance.js?v=1.28.0-0009101e
|
|
1071
1101
|
|
|
1072
1102
|
async function performBackup() {
|
|
1073
1103
|
try {
|
|
@@ -1133,7 +1163,7 @@
|
|
|
1133
1163
|
}
|
|
1134
1164
|
|
|
1135
1165
|
async function loadConfiguration() {
|
|
1136
|
-
// Primary implementation in js/admin.config.js?v=1.
|
|
1166
|
+
// Primary implementation in js/admin.config.js?v=1.28.0-0009101e (loaded via defer).
|
|
1137
1167
|
// This inline fallback only fires if the external script failed to load.
|
|
1138
1168
|
if (window.__configExternalLoaded) return;
|
|
1139
1169
|
try {
|
|
@@ -1193,10 +1223,10 @@
|
|
|
1193
1223
|
return false;
|
|
1194
1224
|
}
|
|
1195
1225
|
|
|
1196
|
-
// Monitoring functions moved to js/admin.monitor.js?v=1.
|
|
1226
|
+
// Monitoring functions moved to js/admin.monitor.js?v=1.28.0-0009101e
|
|
1197
1227
|
|
|
1198
1228
|
// ===== Log Viewer =====
|
|
1199
|
-
// Extracted to js/admin.logs.js?v=1.
|
|
1229
|
+
// Extracted to js/admin.logs.js?v=1.28.0-0009101e
|
|
1200
1230
|
|
|
1201
1231
|
// ===== Instruction Management =====
|
|
1202
1232
|
let instructionEditing = null;
|
|
@@ -1621,7 +1651,7 @@
|
|
|
1621
1651
|
categories: ['general'],
|
|
1622
1652
|
primaryCategory: 'general',
|
|
1623
1653
|
reviewIntervalDays: 180,
|
|
1624
|
-
schemaVersion: '
|
|
1654
|
+
schemaVersion: '5',
|
|
1625
1655
|
description: 'Describe purpose and scope.',
|
|
1626
1656
|
createdAt: now,
|
|
1627
1657
|
updatedAt: now
|
|
@@ -1693,7 +1723,7 @@
|
|
|
1693
1723
|
setInterval(fetchResourceTrends, 10000);
|
|
1694
1724
|
})();
|
|
1695
1725
|
|
|
1696
|
-
// Instruction management logic extracted to js/admin.instructions.js?v=1.
|
|
1726
|
+
// Instruction management logic extracted to js/admin.instructions.js?v=1.28.0-0009101e
|
|
1697
1727
|
// Functions exposed globally: loadInstructions, renderInstructionList, editInstruction, saveInstruction, deleteInstruction, etc.
|
|
1698
1728
|
|
|
1699
1729
|
function startAutoRefresh() {
|
|
@@ -1159,6 +1159,36 @@ a.mermaid-link { color: var(--admin-accent); }
|
|
|
1159
1159
|
font-size: 12px;
|
|
1160
1160
|
color: var(--admin-text-dim);
|
|
1161
1161
|
}
|
|
1162
|
+
.emb-status-banner {
|
|
1163
|
+
margin: 0 0 12px 0;
|
|
1164
|
+
padding: 12px 16px;
|
|
1165
|
+
border-radius: 6px;
|
|
1166
|
+
border-left: 4px solid var(--admin-text-dim);
|
|
1167
|
+
background: rgba(255,255,255,0.04);
|
|
1168
|
+
font-size: 13px;
|
|
1169
|
+
line-height: 1.45;
|
|
1170
|
+
color: var(--admin-text);
|
|
1171
|
+
}
|
|
1172
|
+
.emb-status-banner.hidden { display: none; }
|
|
1173
|
+
.emb-status-banner .title {
|
|
1174
|
+
font-weight: 600;
|
|
1175
|
+
margin-bottom: 4px;
|
|
1176
|
+
display: flex;
|
|
1177
|
+
align-items: center;
|
|
1178
|
+
gap: 8px;
|
|
1179
|
+
}
|
|
1180
|
+
.emb-status-banner .meta {
|
|
1181
|
+
color: var(--admin-text-dim);
|
|
1182
|
+
font-size: 12px;
|
|
1183
|
+
margin-top: 6px;
|
|
1184
|
+
font-family: var(--mcp-font-mono);
|
|
1185
|
+
word-break: break-all;
|
|
1186
|
+
}
|
|
1187
|
+
.emb-status-banner.state-ready { border-left-color: var(--admin-success); }
|
|
1188
|
+
.emb-status-banner.state-will-download { border-left-color: var(--admin-accent); }
|
|
1189
|
+
.emb-status-banner.state-no-embeddings { border-left-color: var(--admin-warn); }
|
|
1190
|
+
.emb-status-banner.state-missing,
|
|
1191
|
+
.emb-status-banner.state-disabled { border-left-color: var(--admin-danger); }
|
|
1162
1192
|
.emb-stat {
|
|
1163
1193
|
margin-bottom: 4px;
|
|
1164
1194
|
font-size: 13px;
|
|
@@ -1736,3 +1766,27 @@ a.mermaid-link { color: var(--admin-accent); }
|
|
|
1736
1766
|
#backup-warning-banner {
|
|
1737
1767
|
animation: rl-fade-in 0.3s ease-out;
|
|
1738
1768
|
}
|
|
1769
|
+
|
|
1770
|
+
|
|
1771
|
+
/* Events panel + nav bubble (added for issue #282 events buffer) */
|
|
1772
|
+
.nav-bubble { display:inline-block; min-width:18px; padding:0 6px; margin-left:6px; border-radius:9px; background:var(--admin-warn); color:var(--admin-white); font-size:11px; line-height:18px; text-align:center; vertical-align:middle; }
|
|
1773
|
+
.nav-bubble.has-error { background:var(--admin-danger-dark); }
|
|
1774
|
+
.events-table { width:100%; border-collapse:collapse; }
|
|
1775
|
+
.events-table th, .events-table td { padding:6px 8px; text-align:left; border-bottom:1px solid var(--admin-border); font-size:13px; vertical-align:top; }
|
|
1776
|
+
.events-table th { color:var(--admin-text-dim); font-weight:500; }
|
|
1777
|
+
.event-badge { display:inline-block; padding:1px 6px; border-radius:3px; font-size:11px; font-weight:600; }
|
|
1778
|
+
.event-badge.level-warn { background:var(--admin-warn-dark); color:var(--admin-drill-gold); }
|
|
1779
|
+
.event-badge.level-error { background:var(--admin-danger-darker); color:var(--admin-red-bright); }
|
|
1780
|
+
.event-row.level-error { background:rgba(220,38,38,0.06); }
|
|
1781
|
+
.event-row.level-warn { background:rgba(245,158,11,0.04); }
|
|
1782
|
+
.event-detail { font-family:var(--mcp-font-mono); font-size:11px; white-space:pre-wrap; margin-top:3px; }
|
|
1783
|
+
.event-ts { white-space:nowrap; color:var(--admin-text-dim); font-family:var(--mcp-font-mono); font-size:12px; }
|
|
1784
|
+
.event-row .event-msg { cursor: pointer; }
|
|
1785
|
+
.event-row .event-detail { display: none; max-height: 240px; overflow: auto; }
|
|
1786
|
+
.event-row.expanded .event-detail { display: block; }
|
|
1787
|
+
.event-row .toggle-caret { display:inline-block; width:14px; color:var(--admin-text-dim); transition: transform 0.15s; }
|
|
1788
|
+
.event-row.expanded .toggle-caret { transform: rotate(90deg); }
|
|
1789
|
+
.events-pager { display:flex; align-items:center; gap:12px; padding:8px 4px; }
|
|
1790
|
+
.events-pager.hidden { display:none; }
|
|
1791
|
+
.events-search { min-width: 180px; }
|
|
1792
|
+
.events-table tr.event-row mark { background: var(--admin-drill-gold); color: var(--admin-text); padding: 0 1px; border-radius: 2px; }
|
|
@@ -90,10 +90,8 @@
|
|
|
90
90
|
+ '<div class="form-group"><label class="form-label">Enable Mutation</label>'
|
|
91
91
|
+ '<select class="form-input" id="cfg-mutation"><option value="1"' + (cfg.serverSettings.enableMutation ? ' selected' : '') + '>Enabled</option>'
|
|
92
92
|
+ '<option value="0"' + (!cfg.serverSettings.enableMutation ? ' selected' : '') + '>Disabled</option></select></div>'
|
|
93
|
-
+ '<div class="form-group"><label class="form-label">Rate Limit
|
|
94
|
-
+ '<input class="form-input" type="number" id="cfg-
|
|
95
|
-
+ '<div class="form-group"><label class="form-label">Rate Limit Max Requests</label>'
|
|
96
|
-
+ '<input class="form-input" type="number" id="cfg-maxRequests" value="' + cfg.serverSettings.rateLimit.maxRequests + '" /></div>'
|
|
93
|
+
+ '<div class="form-group"><label class="form-label">Rate Limit (req/min, 0 = off)</label>'
|
|
94
|
+
+ '<input class="form-input" type="number" min="0" id="cfg-rateLimitPerMinute" value="' + (cfg.serverSettings.rateLimit && cfg.serverSettings.rateLimit.perMinute != null ? cfg.serverSettings.rateLimit.perMinute : 0) + '" /></div>'
|
|
97
95
|
+ '</div>'
|
|
98
96
|
+ '<div class="cfg-save-row"><button class="action-btn" type="submit">💾 Save Config</button></div>'
|
|
99
97
|
+ '</form>'
|
|
@@ -173,8 +171,7 @@
|
|
|
173
171
|
enableVerboseLogging: document.getElementById('cfg-verbose').value === '1',
|
|
174
172
|
enableMutation: document.getElementById('cfg-mutation').value === '1',
|
|
175
173
|
rateLimit: {
|
|
176
|
-
|
|
177
|
-
maxRequests: parseInt(document.getElementById('cfg-maxRequests').value)
|
|
174
|
+
perMinute: parseInt(document.getElementById('cfg-rateLimitPerMinute').value) || 0
|
|
178
175
|
}
|
|
179
176
|
},
|
|
180
177
|
featureFlags: featureFlags
|
|
@@ -378,8 +378,61 @@
|
|
|
378
378
|
var origShowSection = window.showSection;
|
|
379
379
|
window.showSection = function (name) {
|
|
380
380
|
if (origShowSection) origShowSection(name);
|
|
381
|
-
if (name === 'embeddings'
|
|
382
|
-
|
|
381
|
+
if (name === 'embeddings') {
|
|
382
|
+
window.loadEmbeddingsStatus();
|
|
383
|
+
if (!embData) setTimeout(init, 50);
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
function escapeHtml(s) {
|
|
388
|
+
if (s == null) return '';
|
|
389
|
+
return String(s)
|
|
390
|
+
.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
|
391
|
+
.replace(/"/g, '"').replace(/'/g, ''');
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function renderStatusBanner(status) {
|
|
395
|
+
var banner = document.getElementById('emb-status-banner');
|
|
396
|
+
if (!banner) return;
|
|
397
|
+
banner.className = 'emb-status-banner';
|
|
398
|
+
if (!status || status.success === false) {
|
|
399
|
+
banner.classList.add('hidden');
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
var state = status.state || 'unknown';
|
|
403
|
+
var titleText = '', icon = '';
|
|
404
|
+
if (state === 'disabled') { icon = '🚫'; titleText = 'Semantic embeddings are disabled'; }
|
|
405
|
+
else if (state === 'missing') { icon = '⛔'; titleText = 'Model not available — compute will fail'; }
|
|
406
|
+
else if (state === 'will-download') { icon = '⬇️'; titleText = 'Model will download on first compute'; }
|
|
407
|
+
else if (state === 'no-embeddings') { icon = '⚠️'; titleText = 'No embeddings computed yet'; }
|
|
408
|
+
else if (state === 'ready') { icon = '✅'; titleText = 'Embeddings ready'; }
|
|
409
|
+
else { icon = 'ℹ️'; titleText = 'Embeddings status'; }
|
|
410
|
+
banner.classList.add('state-' + state);
|
|
411
|
+
var parts = [];
|
|
412
|
+
parts.push('<div class="title">' + icon + ' <span>' + escapeHtml(titleText) + '</span></div>');
|
|
413
|
+
if (status.message) parts.push('<div>' + escapeHtml(status.message) + '</div>');
|
|
414
|
+
var meta = [];
|
|
415
|
+
if (status.model) meta.push('model=' + status.model);
|
|
416
|
+
if (status.device) meta.push('device=' + status.device);
|
|
417
|
+
if (typeof status.localOnly === 'boolean') meta.push('localOnly=' + status.localOnly);
|
|
418
|
+
if (typeof status.modelCached === 'boolean') meta.push('modelCached=' + status.modelCached);
|
|
419
|
+
if (typeof status.embeddingsCount === 'number') meta.push('embeddings=' + status.embeddingsCount);
|
|
420
|
+
if (status.cacheDir) meta.push('cacheDir=' + status.cacheDir);
|
|
421
|
+
if (status.embeddingPath) meta.push('embeddingPath=' + status.embeddingPath);
|
|
422
|
+
if (meta.length) parts.push('<div class="meta">' + escapeHtml(meta.join(' · ')) + '</div>');
|
|
423
|
+
banner.innerHTML = parts.join('');
|
|
424
|
+
banner.classList.remove('hidden');
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
window.loadEmbeddingsStatus = async function loadEmbeddingsStatus() {
|
|
428
|
+
try {
|
|
429
|
+
var res = await adminAuth.adminFetch('/api/embeddings/status');
|
|
430
|
+
if (!res.ok) { renderStatusBanner(null); return; }
|
|
431
|
+
var data = await res.json();
|
|
432
|
+
renderStatusBanner(data);
|
|
433
|
+
} catch (_err) {
|
|
434
|
+
void _err;
|
|
435
|
+
renderStatusBanner(null);
|
|
383
436
|
}
|
|
384
437
|
};
|
|
385
438
|
|
|
@@ -391,12 +444,18 @@
|
|
|
391
444
|
var res = await adminAuth.adminFetch('/api/embeddings/compute', { method: 'POST', headers: { 'Content-Type': 'application/json' } });
|
|
392
445
|
if (!res.ok) {
|
|
393
446
|
var err = await res.json().catch(function () { return {}; });
|
|
394
|
-
|
|
447
|
+
var detail = err.error || res.statusText;
|
|
448
|
+
if (err.hint) detail += ' — ' + err.hint;
|
|
449
|
+
else if (err.message) detail += ' — ' + err.message;
|
|
450
|
+
if (statusEl) statusEl.textContent = 'Error: ' + detail;
|
|
451
|
+
// Refresh banner so user sees the actionable state machine.
|
|
452
|
+
window.loadEmbeddingsStatus();
|
|
395
453
|
return;
|
|
396
454
|
}
|
|
397
455
|
var result = await res.json();
|
|
398
456
|
if (statusEl) statusEl.textContent = 'Computed ' + result.count + ' embeddings (' + result.model + ', ' + result.elapsedMs + 'ms). Loading visualization…';
|
|
399
|
-
// Auto-load the projection
|
|
457
|
+
// Auto-load the projection + refresh banner
|
|
458
|
+
window.loadEmbeddingsStatus();
|
|
400
459
|
await window.loadEmbeddings();
|
|
401
460
|
} catch (e) {
|
|
402
461
|
if (statusEl) statusEl.textContent = 'Compute failed: ' + e.message;
|