development-engine-vector 0.5.0__tar.gz → 0.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/PKG-INFO +1 -1
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/changelog.md +19 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/kernel/kernel_core.py +2 -1
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/kernel/otk_kernel.py +14 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/actions.py +1 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/routes.py +20 -4
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/static/web.js +91 -23
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/templates.py +7 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/workflow/release.py +2 -2
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/workflow/versioning.py +7 -3
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/pyproject.toml +1 -1
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/tests/test_dev_cli.py +4 -6
- development_engine_vector-0.5.1/version +1 -0
- development_engine_vector-0.5.0/version +0 -1
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/.flake8 +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/.gitignore +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/contributing.md +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/__init__.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/__main__.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/cli/__init__.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/cli/cli.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/kernel/__init__.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/kernel/config.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/kernel/db.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/kernel/paths.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/kernel/pmf_kernel.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/kernel/selfcheck.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/__init__.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/db/__init__.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/db/base.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/db/checks.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/db/events.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/db/health.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/db/identity.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/db/manifest.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/db/overview.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/db/runs.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/static/__init__.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/static/web.css +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/web.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/utils.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/vcs/__init__.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/vcs/git.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/vcs/github.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/workflow/__init__.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/workflow/cda.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/workflow/changelog.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/workflow/preflight.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev-cli.toml.example +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/docs/architecture.md +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/license +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/readme.md +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/tests/__init__.py +0 -0
- {development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/tests/test_cda_preflight.py +0 -0
|
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.5.1] - 2026-05-12
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- UI service status stuck on `"starting"` — `_refresh()` now advances to `"running"` and persists state when the process is confirmed alive
|
|
12
|
+
- `VersionManager.get_sync_targets()` removed stale `vscode_ark/__init__.py` and `setup.py` targets; now resolves `dev/__init__.py` from the project tree
|
|
13
|
+
- `ReleaseOrchestrator.commit_and_tag()` staged `vscode_ark/__init__.py` and `setup.py` (copy-paste from cda); corrected to `dev/__init__.py`
|
|
14
|
+
- `get_recent_runs` unused import in `routes.py` removed (lint failure)
|
|
15
|
+
- Release page showed always-empty kernel run history; now shows real action states (pass/fail, exit code, timestamps)
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- `/api/kernel/logs?service=X&lines=N` endpoint — tails any service log file from the UI
|
|
19
|
+
- OTK page **Logs** button per service opens a modal with the last 100 log lines
|
|
20
|
+
- Action buttons now poll to completion and display a result toast with exit code and captured output
|
|
21
|
+
- Raw Query page has a database selector: `control.db` (vet history) or `dev.db` (kernel/projects)
|
|
22
|
+
- `sync` OTK task service added — bootstrap/editable-install from the OTK page
|
|
23
|
+
- Setup page shows `dev otk install` guidance when the LaunchAgent is not installed
|
|
24
|
+
- Git page shows "Clean — no commits since vX.Y.Z" on a clean repo instead of a blank panel
|
|
25
|
+
- `vet.py` writes `vet.start` / `vet.pass` / `vet.fail` events to the `events` table and refreshes `identity.version` on every passing run
|
|
26
|
+
|
|
8
27
|
## [0.5.0] - 2026-05-11
|
|
9
28
|
|
|
10
29
|
### Added
|
{development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/kernel/kernel_core.py
RENAMED
|
@@ -150,9 +150,10 @@ class KernelCore:
|
|
|
150
150
|
|
|
151
151
|
pid = state.get("pid")
|
|
152
152
|
if pid and self._is_alive(pid):
|
|
153
|
-
if state["status"]
|
|
153
|
+
if state["status"] != "running":
|
|
154
154
|
state["status"] = "running"
|
|
155
155
|
state["updated_at"] = self._now_iso()
|
|
156
|
+
self._save_state()
|
|
156
157
|
return state
|
|
157
158
|
|
|
158
159
|
if spec.pid_file and spec.pid_file.exists():
|
{development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/kernel/otk_kernel.py
RENAMED
|
@@ -174,6 +174,10 @@ def _vet_command(options: Optional[Dict[str, str]] = None) -> List[str]:
|
|
|
174
174
|
return [sys.executable, str(_CONTROL_SCRIPTS / "vet.py")]
|
|
175
175
|
|
|
176
176
|
|
|
177
|
+
def _sync_command(options: Optional[Dict[str, str]] = None) -> List[str]:
|
|
178
|
+
return [sys.executable, "-m", "dev.cli.cli", "sync", "--project", _project_arg(options)]
|
|
179
|
+
|
|
180
|
+
|
|
177
181
|
def _publish_check_command(options: Optional[Dict[str, str]] = None) -> List[str]:
|
|
178
182
|
return [sys.executable, str(_CONTROL_SCRIPTS / "push.py"), "--dry-run", "--skip-vet"]
|
|
179
183
|
|
|
@@ -243,6 +247,16 @@ SERVICE_SPECS: Dict[str, ServiceSpec] = {
|
|
|
243
247
|
log_file=LOG_DIR / "release-dryrun.log",
|
|
244
248
|
allowed_actions=["start", "status", "logs"],
|
|
245
249
|
),
|
|
250
|
+
"sync": ServiceSpec(
|
|
251
|
+
service_id="sync",
|
|
252
|
+
label="Sync",
|
|
253
|
+
service_type="task",
|
|
254
|
+
description="Bootstrap or sync project dependencies (editable install + requirements).",
|
|
255
|
+
command_builder=_sync_command,
|
|
256
|
+
cwd=_SOURCE_ROOT,
|
|
257
|
+
log_file=LOG_DIR / "sync.log",
|
|
258
|
+
allowed_actions=["start", "status", "logs"],
|
|
259
|
+
),
|
|
246
260
|
}
|
|
247
261
|
|
|
248
262
|
|
|
@@ -6,7 +6,7 @@ from urllib.parse import parse_qs
|
|
|
6
6
|
|
|
7
7
|
from dev import __version__ as DEV_VERSION
|
|
8
8
|
from dev.kernel.config import DevConfig
|
|
9
|
-
from dev.kernel.db import get_projects
|
|
9
|
+
from dev.kernel.db import get_projects
|
|
10
10
|
from dev.kernel.paths import (
|
|
11
11
|
DEV_HOME, DATA_DIR, RUN_DIR, LOG_DIR, CONFIG_DIR, PMF_DIR,
|
|
12
12
|
GOCOSMIX_HOME, GOCOSMIX_APPS, GOCOSMIX_TOOLS, GOCOSMIX_SYSTEM,
|
|
@@ -125,6 +125,13 @@ def application(environ, start_response):
|
|
|
125
125
|
start_response("200 OK", [("Content-Type", "application/json")])
|
|
126
126
|
return [json.dumps({"events": data}).encode("utf-8")]
|
|
127
127
|
|
|
128
|
+
elif path == "/api/kernel/logs":
|
|
129
|
+
service_id = query.get("service", [""])[0]
|
|
130
|
+
lines = int(query.get("lines", ["50"])[0])
|
|
131
|
+
output = _KERNEL.tail_log(service_id, lines=lines)
|
|
132
|
+
start_response("200 OK", [("Content-Type", "application/json")])
|
|
133
|
+
return _json_ok({"service": service_id, "lines": lines, "output": output})
|
|
134
|
+
|
|
128
135
|
elif path == "/api/kernel/start" and method == "POST":
|
|
129
136
|
body = environ["wsgi.input"].read()
|
|
130
137
|
payload = json.loads(body.decode("utf-8"))
|
|
@@ -220,8 +227,7 @@ def application(environ, start_response):
|
|
|
220
227
|
current_version = VersionManager(_SOURCE_DIR).read()
|
|
221
228
|
start_response("200 OK", [("Content-Type", "application/json")])
|
|
222
229
|
return _json_ok({
|
|
223
|
-
"
|
|
224
|
-
"recent_runs": get_recent_runs(limit=10),
|
|
230
|
+
"action_states": list_action_states(limit=20),
|
|
225
231
|
"projects": get_projects(),
|
|
226
232
|
"version": current_version,
|
|
227
233
|
})
|
|
@@ -265,7 +271,17 @@ def application(environ, start_response):
|
|
|
265
271
|
body = environ["wsgi.input"].read()
|
|
266
272
|
payload = json.loads(body.decode("utf-8"))
|
|
267
273
|
sql = payload.get("sql", "")
|
|
268
|
-
|
|
274
|
+
db_target = payload.get("db", "control")
|
|
275
|
+
if db_target == "kernel":
|
|
276
|
+
import sqlite3 as _sqlite3
|
|
277
|
+
conn = _sqlite3.connect(str(DB_PATH))
|
|
278
|
+
conn.row_factory = _sqlite3.Row
|
|
279
|
+
try:
|
|
280
|
+
rows = [dict(r) for r in conn.execute(sql).fetchall()]
|
|
281
|
+
finally:
|
|
282
|
+
conn.close()
|
|
283
|
+
else:
|
|
284
|
+
rows = query_rows(sql)
|
|
269
285
|
start_response("200 OK", [("Content-Type", "application/json")])
|
|
270
286
|
return [json.dumps({"rows": rows}).encode("utf-8")]
|
|
271
287
|
|
|
@@ -496,7 +496,7 @@ function initRelease() {
|
|
|
496
496
|
if (!container) return;
|
|
497
497
|
container.innerHTML = '<div class="spinner"></div> Loading release state...';
|
|
498
498
|
fetch('/api/dev/release').then(r => r.json()).then(data => {
|
|
499
|
-
const
|
|
499
|
+
const actions = safeArray(data.action_states);
|
|
500
500
|
const projects = safeArray(data.projects);
|
|
501
501
|
container.innerHTML = `
|
|
502
502
|
<div class="card mb-20">
|
|
@@ -507,30 +507,23 @@ function initRelease() {
|
|
|
507
507
|
<button class="button button-primary" onclick="triggerAction('build').then(() => initRelease())">Build</button>
|
|
508
508
|
<button class="button button-secondary" onclick="triggerAction('publish-check').then(() => initRelease())">Publish Check</button>
|
|
509
509
|
<button class="button button-secondary" onclick="triggerAction('release-dryrun').then(() => initRelease())">Release Dry-Run</button>
|
|
510
|
+
<button class="button button-secondary" onclick="triggerAction('sync').then(() => initRelease())">Sync</button>
|
|
510
511
|
</div>
|
|
511
512
|
</div>
|
|
512
|
-
<div class="grid-
|
|
513
|
+
<div class="grid-3">
|
|
513
514
|
<div class="card"><div class="card-header">Version</div><div class="card-value">${data.version || '—'}</div></div>
|
|
514
|
-
<div class="card"><div class="card-header">
|
|
515
|
+
<div class="card"><div class="card-header">Action History</div><div class="card-value">${actions.length}</div></div>
|
|
515
516
|
<div class="card"><div class="card-header">Registered Projects</div><div class="card-value">${projects.length}</div></div>
|
|
516
|
-
<div class="card"><div class="card-header">Project Runs</div><div class="card-value">${safeArray(data.project_runs).length}</div></div>
|
|
517
517
|
</div>
|
|
518
518
|
<div class="card mt-20">
|
|
519
|
-
<div class="card-header">Recent
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
<td>${r.version || '—'}</td>
|
|
528
|
-
<td><span class="badge ${r.outcome === 'pass' ? 'badge-success' : r.outcome === 'running' ? 'badge-warning' : 'badge-danger'}">${r.outcome}</span></td>
|
|
529
|
-
<td>${r.started_at ? new Date(r.started_at).toLocaleString() : '—'}</td>
|
|
530
|
-
</tr>
|
|
531
|
-
`).join('')}
|
|
532
|
-
</tbody>
|
|
533
|
-
</table>
|
|
519
|
+
<div class="card-header">Recent Actions</div>
|
|
520
|
+
${actions.length ? `<table class="table"><thead><tr><th>Action</th><th>Status</th><th>Exit</th><th>Started</th><th>Completed</th></tr></thead><tbody>${actions.map(a => {
|
|
521
|
+
const ok = a.status === 'completed' && a.returncode === 0;
|
|
522
|
+
const fail = a.status === 'failed' || (a.status === 'completed' && a.returncode !== 0);
|
|
523
|
+
const badge = ok ? 'badge-success' : fail ? 'badge-danger' : 'badge-warning';
|
|
524
|
+
const label = ok ? 'PASS' : fail ? 'FAIL' : a.status || '—';
|
|
525
|
+
return `<tr><td><strong>${a.action_id || '—'}</strong><div class="text-muted">${a.service_id || ''}</div></td><td><span class="badge ${badge}">${label}</span></td><td>${a.returncode !== null && a.returncode !== undefined ? a.returncode : '—'}</td><td>${a.started_at ? new Date(a.started_at).toLocaleString() : '—'}</td><td>${a.completed_at ? new Date(a.completed_at).toLocaleString() : '—'}</td></tr>`;
|
|
526
|
+
}).join('')}</tbody></table>` : '<div class="text-muted">No actions run this session.</div>'}
|
|
534
527
|
</div>
|
|
535
528
|
`;
|
|
536
529
|
}).catch(() => {
|
|
@@ -586,7 +579,7 @@ function initGit() {
|
|
|
586
579
|
</div>
|
|
587
580
|
<div class="card mt-20">
|
|
588
581
|
<div class="card-header">Commits Since Tag</div>
|
|
589
|
-
${commits.length ? `<ul class="drawer-list">${commits.map(c => `<li><span>${c.replace(/</g, '<')}</span></li>`).join('')}</ul>` :
|
|
582
|
+
${commits.length ? `<ul class="drawer-list">${commits.map(c => `<li><span>${c.replace(/</g, '<')}</span></li>`).join('')}</ul>` : `<div class="text-muted">Clean — no commits since ${data.last_tag || 'last tag'}.</div>`}
|
|
590
583
|
</div>
|
|
591
584
|
`;
|
|
592
585
|
}).catch(() => {
|
|
@@ -630,6 +623,7 @@ function initOtk() {
|
|
|
630
623
|
<button class="button button-small" data-service="${s.service_id}" data-op="start">Start</button>
|
|
631
624
|
<button class="button button-small" data-service="${s.service_id}" data-op="stop">Stop</button>
|
|
632
625
|
<button class="button button-small" data-service="${s.service_id}" data-op="restart">Restart</button>
|
|
626
|
+
<button class="button button-small" data-service="${s.service_id}" data-op="logs">Logs</button>
|
|
633
627
|
</div>
|
|
634
628
|
</td>
|
|
635
629
|
</tr>
|
|
@@ -652,7 +646,11 @@ function initOtk() {
|
|
|
652
646
|
btn.addEventListener('click', () => {
|
|
653
647
|
const service = btn.dataset.service;
|
|
654
648
|
const op = btn.dataset.op;
|
|
655
|
-
|
|
649
|
+
if (op === 'logs') {
|
|
650
|
+
_showServiceLogs(service);
|
|
651
|
+
} else {
|
|
652
|
+
controlKernelService(service, op).then(() => initOtk());
|
|
653
|
+
}
|
|
656
654
|
});
|
|
657
655
|
});
|
|
658
656
|
}).catch(() => {
|
|
@@ -675,6 +673,7 @@ function initSetup() {
|
|
|
675
673
|
<div class="card"><div class="card-header">Installed</div><div class="card-value">${data.launch_agent_installed ? 'Yes' : 'No'}</div></div>
|
|
676
674
|
<div class="card"><div class="card-header">Port</div><div class="card-value">${data.default_port || '—'}</div></div>
|
|
677
675
|
</div>
|
|
676
|
+
${!data.launch_agent_installed ? `<div class="alert alert-info mt-20" style="font-size:13px;">LaunchAgent not installed — <code>dev</code> will not auto-start on login. Run: <code>dev otk install</code></div>` : ''}
|
|
678
677
|
<div class="card mt-20">
|
|
679
678
|
<div class="card-header">Runtime Paths</div>
|
|
680
679
|
<table class="table">
|
|
@@ -809,6 +808,8 @@ function initQuery() {
|
|
|
809
808
|
|
|
810
809
|
function executeQuery() {
|
|
811
810
|
const sql = document.getElementById('query-input').value;
|
|
811
|
+
const dbSelect = document.getElementById('query-db');
|
|
812
|
+
const db = dbSelect ? dbSelect.value : 'control';
|
|
812
813
|
if (!sql) return alert('Enter a SQL query');
|
|
813
814
|
const results = document.getElementById('query-results');
|
|
814
815
|
if (!results) return;
|
|
@@ -817,7 +818,7 @@ function executeQuery() {
|
|
|
817
818
|
fetch('/api/query', {
|
|
818
819
|
method: 'POST',
|
|
819
820
|
headers: {'Content-Type': 'application/json'},
|
|
820
|
-
body: JSON.stringify({sql}),
|
|
821
|
+
body: JSON.stringify({sql, db}),
|
|
821
822
|
}).then(r => r.json()).then(data => {
|
|
822
823
|
if (data.error) {
|
|
823
824
|
results.innerHTML = '<div class="alert alert-danger">Error: ' + data.error + '</div>';
|
|
@@ -855,12 +856,62 @@ function runVet() {
|
|
|
855
856
|
});
|
|
856
857
|
}
|
|
857
858
|
|
|
859
|
+
// ── Action polling ───────────────────────────────────────────────────────────
|
|
860
|
+
|
|
858
861
|
function triggerAction(action) {
|
|
859
862
|
return fetch('/api/action', {
|
|
860
863
|
method: 'POST',
|
|
861
864
|
headers: {'Content-Type': 'application/json'},
|
|
862
865
|
body: JSON.stringify({action}),
|
|
863
|
-
}).then(r => r.json())
|
|
866
|
+
}).then(r => r.json()).then(data => {
|
|
867
|
+
if (data.action_id) {
|
|
868
|
+
return _pollActionToast(action, data.action_id);
|
|
869
|
+
}
|
|
870
|
+
return data;
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
function _pollActionToast(action, actionId) {
|
|
875
|
+
const toast = _showActionToast(action);
|
|
876
|
+
return new Promise(resolve => {
|
|
877
|
+
const interval = setInterval(() => {
|
|
878
|
+
fetch('/api/action/status?action_id=' + encodeURIComponent(actionId))
|
|
879
|
+
.then(r => r.json())
|
|
880
|
+
.then(state => {
|
|
881
|
+
const done = state.status === 'completed' || state.status === 'failed';
|
|
882
|
+
if (done) {
|
|
883
|
+
clearInterval(interval);
|
|
884
|
+
_updateActionToast(toast, action, state);
|
|
885
|
+
resolve(state);
|
|
886
|
+
}
|
|
887
|
+
})
|
|
888
|
+
.catch(() => { clearInterval(interval); resolve({}); });
|
|
889
|
+
}, 1200);
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
function _showActionToast(action) {
|
|
894
|
+
let container = document.getElementById('action-toasts');
|
|
895
|
+
if (!container) {
|
|
896
|
+
container = document.createElement('div');
|
|
897
|
+
container.id = 'action-toasts';
|
|
898
|
+
container.style.cssText = 'position:fixed;bottom:20px;right:20px;z-index:9999;display:flex;flex-direction:column;gap:8px;max-width:420px;';
|
|
899
|
+
document.body.appendChild(container);
|
|
900
|
+
}
|
|
901
|
+
const toast = document.createElement('div');
|
|
902
|
+
toast.style.cssText = 'background:#1e2130;border:1px solid #3a3f55;border-radius:8px;padding:12px 16px;color:#e2e8f0;font-size:13px;box-shadow:0 4px 16px rgba(0,0,0,.4);';
|
|
903
|
+
toast.innerHTML = `<div style="display:flex;align-items:center;gap:8px;"><span class="spinner" style="width:14px;height:14px;border-width:2px;margin:0;"></span><strong>${action}</strong> running…</div><div class="toast-output" style="margin-top:6px;font-size:11px;color:#8892a4;max-height:120px;overflow-y:auto;white-space:pre-wrap;word-break:break-all;"></div>`;
|
|
904
|
+
container.appendChild(toast);
|
|
905
|
+
return toast;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
function _updateActionToast(toast, action, state) {
|
|
909
|
+
const ok = state.status === 'completed' && (state.returncode === 0 || state.returncode === null);
|
|
910
|
+
const badge = ok ? 'badge-success' : 'badge-danger';
|
|
911
|
+
const label = ok ? 'PASS' : 'FAIL';
|
|
912
|
+
const output = (state.output || '').replace(/</g, '<').replace(/>/g, '>');
|
|
913
|
+
toast.innerHTML = `<div style="display:flex;align-items:center;justify-content:space-between;gap:8px;"><span><strong>${action}</strong> <span class="badge ${badge}">${label}</span></span><button onclick="this.closest('div[style]').remove()" style="background:none;border:none;color:#8892a4;cursor:pointer;font-size:16px;line-height:1;">×</button></div>${output ? `<pre style="margin-top:6px;font-size:11px;color:#8892a4;max-height:180px;overflow-y:auto;white-space:pre-wrap;word-break:break-all;">${output}</pre>` : ''}`;
|
|
914
|
+
setTimeout(() => { if (toast.parentNode) toast.remove(); }, ok ? 8000 : 30000);
|
|
864
915
|
}
|
|
865
916
|
|
|
866
917
|
function controlKernelService(service, operation) {
|
|
@@ -870,3 +921,20 @@ function controlKernelService(service, operation) {
|
|
|
870
921
|
body: JSON.stringify({service}),
|
|
871
922
|
}).then(r => r.json());
|
|
872
923
|
}
|
|
924
|
+
|
|
925
|
+
function _showServiceLogs(serviceId) {
|
|
926
|
+
fetch('/api/kernel/logs?service=' + encodeURIComponent(serviceId) + '&lines=100')
|
|
927
|
+
.then(r => r.json())
|
|
928
|
+
.then(data => {
|
|
929
|
+
let modal = document.getElementById('log-modal');
|
|
930
|
+
if (!modal) {
|
|
931
|
+
modal = document.createElement('div');
|
|
932
|
+
modal.id = 'log-modal';
|
|
933
|
+
modal.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.7);z-index:9998;display:flex;align-items:center;justify-content:center;';
|
|
934
|
+
modal.innerHTML = '<div style="background:#161926;border:1px solid #3a3f55;border-radius:10px;width:80vw;max-width:900px;max-height:80vh;display:flex;flex-direction:column;overflow:hidden;"><div style="display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-bottom:1px solid #3a3f55;"><strong id="log-modal-title" style="color:#e2e8f0;font-size:14px;"></strong><button onclick="document.getElementById(\'log-modal\').remove()" style="background:none;border:none;color:#8892a4;cursor:pointer;font-size:20px;line-height:1;">×</button></div><pre id="log-modal-body" style="margin:0;padding:16px;overflow-y:auto;font-size:12px;color:#c5cdd9;white-space:pre-wrap;word-break:break-all;flex:1;"></pre></div>';
|
|
935
|
+
document.body.appendChild(modal);
|
|
936
|
+
}
|
|
937
|
+
document.getElementById('log-modal-title').textContent = serviceId + ' — last 100 lines';
|
|
938
|
+
document.getElementById('log-modal-body').textContent = data.output || '(no output)';
|
|
939
|
+
});
|
|
940
|
+
}
|
|
@@ -326,6 +326,13 @@ def render_query():
|
|
|
326
326
|
</div>
|
|
327
327
|
</div>
|
|
328
328
|
<div class="card mb-20">
|
|
329
|
+
<div class="form-group">
|
|
330
|
+
<label class="form-label">Database</label>
|
|
331
|
+
<select id="query-db" class="form-input" style="max-width:220px;">
|
|
332
|
+
<option value="control">control.db (vet history)</option>
|
|
333
|
+
<option value="kernel">dev.db (kernel / projects)</option>
|
|
334
|
+
</select>
|
|
335
|
+
</div>
|
|
329
336
|
<div class="form-group">
|
|
330
337
|
<label class="form-label">SQL Query</label>
|
|
331
338
|
<textarea id="query-input" class="form-textarea" placeholder="SELECT * FROM runs ORDER BY id DESC LIMIT 10"></textarea>
|
|
@@ -78,8 +78,8 @@ class ReleaseOrchestrator:
|
|
|
78
78
|
"version",
|
|
79
79
|
"changelog.md",
|
|
80
80
|
"pyproject.toml",
|
|
81
|
-
"
|
|
82
|
-
"
|
|
81
|
+
"dev/__init__.py",
|
|
82
|
+
"source/dev/__init__.py",
|
|
83
83
|
]
|
|
84
84
|
|
|
85
85
|
existing = [path for path in files_to_stage if (self.project_dir / path).exists()]
|
{development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/workflow/versioning.py
RENAMED
|
@@ -80,8 +80,12 @@ class VersionManager:
|
|
|
80
80
|
|
|
81
81
|
def get_sync_targets(self):
|
|
82
82
|
"""Return standard sync target patterns for common files."""
|
|
83
|
-
|
|
83
|
+
targets = {
|
|
84
84
|
"pyproject.toml": r'(^version\s*=\s*")' + self.VERSION_PATTERN + r'(")',
|
|
85
|
-
"setup.py": r'(\s*version\s*=\s*")' + self.VERSION_PATTERN + r'(",)',
|
|
86
|
-
"vscode_ark/__init__.py": r'(\s*__version__\s*=\s*")' + self.VERSION_PATTERN + r'(")',
|
|
87
85
|
}
|
|
86
|
+
# include __init__.py only if it exists under the source package
|
|
87
|
+
for candidate in ["dev/__init__.py", "source/dev/__init__.py"]:
|
|
88
|
+
if (self.project_dir / candidate).exists():
|
|
89
|
+
targets[candidate] = r'(\s*__version__\s*=\s*")' + self.VERSION_PATTERN + r'(")' # noqa: E501
|
|
90
|
+
break
|
|
91
|
+
return targets
|
|
@@ -16,12 +16,11 @@ class TestVersionManager(unittest.TestCase):
|
|
|
16
16
|
self.version_file = self.temp_dir / "version"
|
|
17
17
|
self.version_file.write_text("1.2.3\n")
|
|
18
18
|
self.pyproject = self.temp_dir / "pyproject.toml"
|
|
19
|
-
self.setup_py = self.temp_dir / "setup.py"
|
|
20
|
-
self.init_py = self.temp_dir / "vscode_ark"
|
|
21
|
-
self.init_py.mkdir()
|
|
22
|
-
self.init_file = self.init_py / "__init__.py"
|
|
23
19
|
self.pyproject.write_text('version = "1.2.3"\n')
|
|
24
|
-
|
|
20
|
+
# create dev/__init__.py as the canonical sync target for this project
|
|
21
|
+
dev_pkg = self.temp_dir / "dev"
|
|
22
|
+
dev_pkg.mkdir()
|
|
23
|
+
self.init_file = dev_pkg / "__init__.py"
|
|
25
24
|
self.init_file.write_text('__version__ = "1.2.3"\n')
|
|
26
25
|
|
|
27
26
|
def tearDown(self):
|
|
@@ -45,7 +44,6 @@ class TestVersionManager(unittest.TestCase):
|
|
|
45
44
|
|
|
46
45
|
vm.sync_to_files("2.1.0", vm.get_sync_targets())
|
|
47
46
|
self.assertIn('version = "2.1.0"', self.pyproject.read_text())
|
|
48
|
-
self.assertIn('setup(version="2.1.0",)', self.setup_py.read_text())
|
|
49
47
|
self.assertIn('__version__ = "2.1.0"', self.init_file.read_text())
|
|
50
48
|
|
|
51
49
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.5.1
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.5.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/kernel/pmf_kernel.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/ui/static/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/workflow/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/workflow/changelog.py
RENAMED
|
File without changes
|
{development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/dev/workflow/preflight.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{development_engine_vector-0.5.0 → development_engine_vector-0.5.1}/tests/test_cda_preflight.py
RENAMED
|
File without changes
|