feat: Phase 1 — extract the client (web SPA + desktop) to dtoro/oikos-web
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled

Problem: the hexagonal refactor churns the backend tree for nine more
phases; the UI delivery stack (web/ SPA, cmd/desktop Wails wrapper,
compose/web image) must move to its own repo first so doc/layout
rewrites land once on a backend-only tree.

Change:
- New repo git.hubris.network/dtoro/oikos-web (v0.33.0): web/, desktop/
  (updateURL repointed to oikos-web releases), compose/, own CI (web +
  desktop jobs), own deploy script (CI-green gate, TOCTOU guard,
  version-tagged images, prune-to-3), own webhook receiver on :9798 +
  launchd unit, own compose project publishing the same 8091:80.
- Cutover executed on mac-mini in order: oikos stack's web service
  stopped+removed, oikos-web project brought up on 8091; outer Caddy
  untouched (targets the published port) — serving + Authentik flow +
  /wails 404 quirk verified post-cutover.
- Stripped from oikos: web/, cmd/desktop/, compose/web/, desktop CI
  workflow, ci.yml web job, Makefile ui/desktop/desktop-package/install
  targets, the compose web service, oikos-web from deploy.sh's fallback
  prune list; wails + go-keyring dropped from go.mod, vendor synced.
- README / CONTRIBUTING / AGENTS.md / .agents dev+operations docs now
  point at the new repo; mbse + mascot design docs carry a path note.

Risk: production SPA serving depends on the new pipeline now; rollback
is versioned-image re-up of the old web service from a pre-split
checkout (port 8091). Desktop builds installed before the split still
check dtoro/oikos releases — one manual reinstall, noted in the
oikos-web release notes.

Verification: go vet, make test (race), make generate-check, golangci
(no new findings; baseline down 400→365); post-cutover curls —
localhost:8091 200, /wails/runtime.js 404, outer Caddy 302 Authentik.
This commit is contained in:
2026-08-15 22:27:52 +02:00
parent e074f04bdf
commit d4d99a7473
18854 changed files with 2615729 additions and 173735 deletions

170
web/node_modules/vitest/dist/chunks/console.BYGVloWk.js generated vendored Normal file
View File

@@ -0,0 +1,170 @@
import { Console } from 'node:console';
import { relative } from 'node:path';
import { Writable } from 'node:stream';
import { getSafeTimers } from '@vitest/utils';
import c from 'tinyrainbow';
import { R as RealDate } from './date.W2xKR2qe.js';
import { g as getWorkerState } from './utils.C8RiOc4B.js';
const UNKNOWN_TEST_ID = "__vitest__unknown_test__";
function getTaskIdByStack(root) {
const stack = new Error("STACK_TRACE_ERROR").stack?.split("\n");
if (!stack) {
return UNKNOWN_TEST_ID;
}
const index = stack.findIndex((line2) => line2.includes("at Console.value"));
const line = index === -1 ? null : stack[index + 2];
if (!line) {
return UNKNOWN_TEST_ID;
}
const filepath = line.match(/at\s(.*)\s?/)?.[1];
if (filepath) {
return relative(root, filepath);
}
return UNKNOWN_TEST_ID;
}
function createCustomConsole(defaultState) {
const stdoutBuffer = /* @__PURE__ */ new Map();
const stderrBuffer = /* @__PURE__ */ new Map();
const timers = /* @__PURE__ */ new Map();
const { setTimeout, clearTimeout } = getSafeTimers();
const state = () => defaultState || getWorkerState();
function schedule(taskId) {
const timer = timers.get(taskId);
const { stdoutTime, stderrTime } = timer;
clearTimeout(timer.timer);
timer.timer = setTimeout(() => {
if (stderrTime < stdoutTime) {
sendStderr(taskId);
sendStdout(taskId);
} else {
sendStdout(taskId);
sendStderr(taskId);
}
});
}
function sendStdout(taskId) {
sendBuffer("stdout", taskId);
}
function sendStderr(taskId) {
sendBuffer("stderr", taskId);
}
function sendBuffer(type, taskId) {
const buffers = type === "stdout" ? stdoutBuffer : stderrBuffer;
const buffer = buffers.get(taskId);
if (!buffer) {
return;
}
if (state().config.printConsoleTrace) {
buffer.forEach(([buffer2, origin]) => {
sendLog(type, taskId, String(buffer2), buffer2.length, origin);
});
} else {
const content = buffer.map((i) => String(i[0])).join("");
sendLog(type, taskId, content, buffer.length);
}
const timer = timers.get(taskId);
buffers.delete(taskId);
if (type === "stderr") {
timer.stderrTime = 0;
} else {
timer.stdoutTime = 0;
}
}
function sendLog(type, taskId, content, size, origin) {
const timer = timers.get(taskId);
const time = type === "stderr" ? timer.stderrTime : timer.stdoutTime;
state().rpc.onUserConsoleLog({
type,
content: content || "<empty line>",
taskId,
time: time || RealDate.now(),
size,
origin
});
}
const stdout = new Writable({
write(data, encoding, callback) {
const s = state();
const id = s?.current?.id || s?.current?.suite?.id || s.current?.file.id || getTaskIdByStack(s.config.root);
let timer = timers.get(id);
if (timer) {
timer.stdoutTime = timer.stdoutTime || RealDate.now();
} else {
timer = {
stdoutTime: RealDate.now(),
stderrTime: RealDate.now(),
timer: 0
};
timers.set(id, timer);
}
let buffer = stdoutBuffer.get(id);
if (!buffer) {
buffer = [];
stdoutBuffer.set(id, buffer);
}
if (state().config.printConsoleTrace) {
const limit = Error.stackTraceLimit;
Error.stackTraceLimit = limit + 6;
const stack = new Error("STACK_TRACE").stack;
const trace = stack?.split("\n").slice(7).join("\n");
Error.stackTraceLimit = limit;
buffer.push([data, trace]);
} else {
buffer.push([data, void 0]);
}
schedule(id);
callback();
}
});
const stderr = new Writable({
write(data, encoding, callback) {
const s = state();
const id = s?.current?.id || s?.current?.suite?.id || s.current?.file.id || getTaskIdByStack(s.config.root);
let timer = timers.get(id);
if (timer) {
timer.stderrTime = timer.stderrTime || RealDate.now();
} else {
timer = {
stderrTime: RealDate.now(),
stdoutTime: RealDate.now(),
timer: 0
};
timers.set(id, timer);
}
let buffer = stderrBuffer.get(id);
if (!buffer) {
buffer = [];
stderrBuffer.set(id, buffer);
}
if (state().config.printConsoleTrace) {
const limit = Error.stackTraceLimit;
Error.stackTraceLimit = limit + 6;
const stack = new Error("STACK_TRACE").stack?.split("\n");
Error.stackTraceLimit = limit;
const isTrace = stack?.some(
(line) => line.includes("at Console.trace")
);
if (isTrace) {
buffer.push([data, void 0]);
} else {
const trace = stack?.slice(7).join("\n");
Error.stackTraceLimit = limit;
buffer.push([data, trace]);
}
} else {
buffer.push([data, void 0]);
}
schedule(id);
callback();
}
});
return new Console({
stdout,
stderr,
colorMode: c.isColorSupported,
groupIndentation: 2
});
}
export { UNKNOWN_TEST_ID, createCustomConsole };