@kw-yeh/vibeflow 4.11.1 → 4.11.3

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.md CHANGED
@@ -91,6 +91,8 @@ vibeflow update
91
91
 
92
92
  更新完成後,若 VibeFlow 正在執行,請自行關閉並重新啟動 host,才會載入新版。此指令只適用於全域 npm 安裝;從原始碼、`npx` 或專案本地安裝執行時不會更動套件。
93
93
 
94
+ 以 npm 套件執行時,VibeFlow 啟動後及每兩小時會檢查 npm 是否有新版;有新版會在看板上方提示。**設定** 視窗會顯示目前執行中的版本。從原始碼執行時只顯示版本,不查 npm 更新。
95
+
94
96
  ### 安裝時出現 `EACCES: permission denied`
95
97
 
96
98
  代表 npm 的全域目錄屬於系統管理員(從 nodejs.org 下載安裝檔裝 Node 時常見)。建議不要用 `sudo`,改成讓全域套件裝在你自己的家目錄:
package/dist/vibeflow.mjs CHANGED
@@ -257,6 +257,9 @@ var init_pty = __esm({
257
257
  scrollback(key) {
258
258
  return this.scrollbacks.get(key) ?? null;
259
259
  }
260
+ discardScrollback(key) {
261
+ this.scrollbacks.delete(key);
262
+ }
260
263
  async isScrolledBack() {
261
264
  return false;
262
265
  }
@@ -2448,6 +2451,8 @@ function createBridge(t) {
2448
2451
  getState: () => t.invoke("vibeflow:getState"),
2449
2452
  /** Running app version (package.json version baked into the build). */
2450
2453
  getVersion: () => t.invoke("app:getVersion"),
2454
+ getUpdateStatus: () => t.invoke("host:updateStatus"),
2455
+ onUpdateAvailable: (callback) => t.on("update:available", (payload) => callback(payload)),
2451
2456
  /**
2452
2457
  * Fired when an external write (e.g. CLI) changes the store backing file.
2453
2458
  * The main process debounces and emits the fresh state so the board can
@@ -2574,6 +2579,7 @@ function createBridge(t) {
2574
2579
  * `sessionKey` defaults to `taskId`.
2575
2580
  */
2576
2581
  start: (payload) => t.invoke("pty:start", payload),
2582
+ startStandalone: (payload) => t.invoke("terminal:start", payload),
2577
2583
  /** Join a running session without restarting it. */
2578
2584
  peek: (sessionKey) => t.invoke("pty:peek", sessionKey),
2579
2585
  /** Which session backend runs terminals, and the sessions it has running. */
@@ -4632,8 +4638,8 @@ async function taskCommand(argv) {
4632
4638
  }
4633
4639
 
4634
4640
  // packages/cli/src/host.ts
4635
- import fs20 from "fs";
4636
- import path24 from "path";
4641
+ import fs21 from "fs";
4642
+ import path25 from "path";
4637
4643
  import { randomBytes as randomBytes2 } from "crypto";
4638
4644
 
4639
4645
  // packages/core/src/events.ts
@@ -6784,6 +6790,7 @@ function validBoard(value) {
6784
6790
  function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatus, acliRunner, jiraAuthStatus, modelCatalog }) {
6785
6791
  const sink = bus.sink();
6786
6792
  const models = modelCatalog ?? createModelCatalog({ version });
6793
+ const standaloneTerminals = /* @__PURE__ */ new Map();
6787
6794
  let libraryCodexHome = null;
6788
6795
  void libraryRoot().then((root) => {
6789
6796
  libraryCodexHome = libraryPaths(root).codexHome;
@@ -6838,7 +6845,10 @@ function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatu
6838
6845
  } catch {
6839
6846
  }
6840
6847
  async function teardownSession(key) {
6848
+ const standalone = standaloneTerminals.has(key);
6841
6849
  await sessions.kill(key);
6850
+ if (standalone) sessions.discardScrollback?.(key);
6851
+ standaloneTerminals.delete(key);
6842
6852
  unwatchSubAgents(key);
6843
6853
  }
6844
6854
  async function teardownTask(taskId) {
@@ -6853,6 +6863,7 @@ function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatu
6853
6863
  }
6854
6864
  function requireSessionKey(sessionKey) {
6855
6865
  const key = str(sessionKey, "sessionKey");
6866
+ if (standaloneTerminals.has(key)) return key;
6856
6867
  requireTask(key.split(":")[0]);
6857
6868
  return key;
6858
6869
  }
@@ -7188,6 +7199,26 @@ function createCore({ sessions, bus, version, homeDir, ghRunner, githubAuthStatu
7188
7199
  }
7189
7200
  return result;
7190
7201
  },
7202
+ "terminal:start": async (payload) => {
7203
+ const p = obj(payload, "payload");
7204
+ const key = str(p.sessionKey, "sessionKey");
7205
+ if (!/^terminal_[0-9a-f-]{36}$/.test(key)) invalid("invalid standalone terminal key");
7206
+ if (Boolean(p.taskId) === Boolean(p.projectPath)) invalid("provide taskId or projectPath");
7207
+ const cwd = str(p.taskId ? requireTask(p.taskId).projectPath : p.projectPath, "projectPath");
7208
+ if (!path22.isAbsolute(cwd) || !fs18.existsSync(cwd) || !fs18.statSync(cwd).isDirectory()) {
7209
+ invalid("projectPath must be an existing absolute directory");
7210
+ }
7211
+ const previous = standaloneTerminals.get(key);
7212
+ if (previous && previous !== cwd) invalid("terminal key already belongs to another directory");
7213
+ const result = await sessions.start(key, {
7214
+ cwd,
7215
+ cols: typeof p.cols === "number" ? p.cols : void 0,
7216
+ rows: typeof p.rows === "number" ? p.rows : void 0
7217
+ });
7218
+ standaloneTerminals.set(key, cwd);
7219
+ if (!p.taskId) recordRecentProject(getStore(), cwd);
7220
+ return result;
7221
+ },
7191
7222
  // Join a session as it is: no restart, for a frontend that attaches
7192
7223
  // after it started (the TUI's terminal view).
7193
7224
  "pty:peek": async (sessionKey) => {
@@ -7720,6 +7751,101 @@ Content-Length: 0\r
7720
7751
  };
7721
7752
  }
7722
7753
 
7754
+ // packages/cli/src/update-command.ts
7755
+ import fs20 from "node:fs";
7756
+ import path24 from "node:path";
7757
+ import { spawnSync } from "node:child_process";
7758
+ function npmRunner(args, inherit) {
7759
+ const windows = process.platform === "win32";
7760
+ return spawnSync(windows ? "npm.cmd" : "npm", args, {
7761
+ encoding: "utf8",
7762
+ stdio: inherit ? "inherit" : ["ignore", "pipe", "inherit"],
7763
+ windowsHide: true,
7764
+ shell: windows
7765
+ });
7766
+ }
7767
+ function packageName(packageRoot) {
7768
+ try {
7769
+ const pkg = JSON.parse(fs20.readFileSync(path24.join(packageRoot, "package.json"), "utf8"));
7770
+ if (typeof pkg.name !== "string") return null;
7771
+ return /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/i.test(pkg.name) ? pkg.name : null;
7772
+ } catch {
7773
+ return null;
7774
+ }
7775
+ }
7776
+ function runUpdate(options) {
7777
+ const log = options.log ?? console.log;
7778
+ const error = options.error ?? console.error;
7779
+ const runNpm = options.runNpm ?? npmRunner;
7780
+ if (options.sourceRoot || !options.cliEntry) {
7781
+ error("vibeflow update \u53EA\u9069\u7528\u65BC\u5168\u57DF npm \u5B89\u88DD\uFF1B\u76EE\u524D\u662F\u539F\u59CB\u78BC\u7248\u672C\u3002");
7782
+ return 1;
7783
+ }
7784
+ const packageRoot = path24.dirname(path24.dirname(options.cliEntry));
7785
+ const name = packageName(packageRoot);
7786
+ if (!name) {
7787
+ error("\u7121\u6CD5\u8FA8\u8B58\u76EE\u524D VibeFlow \u7684 npm \u5957\u4EF6\u540D\u7A31\uFF0C\u5DF2\u53D6\u6D88\u66F4\u65B0\u3002");
7788
+ return 1;
7789
+ }
7790
+ const root = runNpm(["root", "-g"], false);
7791
+ if (root.error || root.status !== 0 || !String(root.stdout ?? "").trim()) {
7792
+ error(`\u7121\u6CD5\u67E5\u8A62 npm \u5168\u57DF\u5B89\u88DD\u76EE\u9304\uFF1A${root.error?.message ?? `npm \u7D50\u675F\u78BC ${root.status ?? "unknown"}`}`);
7793
+ return 1;
7794
+ }
7795
+ try {
7796
+ const globalPackage = path24.join(String(root.stdout).trim(), ...name.split("/"));
7797
+ if (fs20.lstatSync(globalPackage).isSymbolicLink() || fs20.realpathSync(globalPackage) !== fs20.realpathSync(packageRoot)) {
7798
+ error("vibeflow update \u53EA\u9069\u7528\u65BC\u5168\u57DF npm \u5B89\u88DD\uFF1B\u76EE\u524D\u57F7\u884C\u7684\u5957\u4EF6\u4F86\u81EA\u5176\u4ED6\u4F4D\u7F6E\u3002");
7799
+ return 1;
7800
+ }
7801
+ } catch {
7802
+ error("vibeflow update \u53EA\u9069\u7528\u65BC\u5168\u57DF npm \u5B89\u88DD\uFF1B\u76EE\u524D\u57F7\u884C\u7684\u5957\u4EF6\u4E0D\u662F npm \u5168\u57DF\u5B89\u88DD\u3002");
7803
+ return 1;
7804
+ }
7805
+ log(`\u6B63\u5728\u66F4\u65B0 ${name} \u81F3 npm latest\u2026`);
7806
+ const result = runNpm(["install", "-g", `${name}@latest`], true);
7807
+ if (result.error || result.status !== 0) {
7808
+ error(`\u66F4\u65B0\u5931\u6557\uFF1A${result.error?.message ?? `npm \u7D50\u675F\u78BC ${result.status ?? "unknown"}`}`);
7809
+ return result.status && result.status > 0 ? result.status : 1;
7810
+ }
7811
+ log("\u66F4\u65B0\u5B8C\u6210\u3002\u82E5 VibeFlow host \u6B63\u5728\u57F7\u884C\uFF0C\u8ACB\u81EA\u884C\u91CD\u65B0\u555F\u52D5\u4EE5\u8F09\u5165\u65B0\u7248\u672C\u3002");
7812
+ return 0;
7813
+ }
7814
+
7815
+ // packages/cli/src/update-check.ts
7816
+ import { execFile as execFile9 } from "node:child_process";
7817
+ import { promisify as promisify6 } from "node:util";
7818
+ var execFileAsync = promisify6(execFile9);
7819
+ var UPDATE_CHECK_INTERVAL_MS = 2 * 60 * 60 * 1e3;
7820
+ function versionParts(value) {
7821
+ const match = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(value);
7822
+ if (!match) return null;
7823
+ return { numbers: match.slice(1, 4).map(Number), prerelease: !!match[4] };
7824
+ }
7825
+ function isNewerVersion(latest, current) {
7826
+ const next = versionParts(latest);
7827
+ const installed = versionParts(current);
7828
+ if (!next || !installed) return false;
7829
+ for (let index = 0; index < 3; index++) {
7830
+ if (next.numbers[index] !== installed.numbers[index]) {
7831
+ return next.numbers[index] > installed.numbers[index];
7832
+ }
7833
+ }
7834
+ return installed.prerelease && !next.prerelease;
7835
+ }
7836
+ async function checkForUpdate(packageName2, currentVersion, query = async (name) => {
7837
+ const { stdout } = await execFileAsync(
7838
+ process.platform === "win32" ? "npm.cmd" : "npm",
7839
+ ["view", `${name}@latest`, "version", "--json"],
7840
+ { timeout: 1e4, windowsHide: true, shell: process.platform === "win32" }
7841
+ );
7842
+ return stdout;
7843
+ }) {
7844
+ const latest = JSON.parse(await query(packageName2));
7845
+ if (typeof latest !== "string" || !isNewerVersion(latest, currentVersion)) return null;
7846
+ return { currentVersion, latestVersion: latest };
7847
+ }
7848
+
7723
7849
  // packages/cli/src/host.ts
7724
7850
  var DEFAULT_HOST_PORT = 47820;
7725
7851
  async function waitForPort(userDataDir, timeoutMs = 1e4) {
@@ -7761,6 +7887,22 @@ async function startHost(options) {
7761
7887
  stateDir: options.userDataDir
7762
7888
  });
7763
7889
  const core = createCore({ sessions, bus, version: options.version });
7890
+ let availableUpdate = null;
7891
+ let updateTimer = null;
7892
+ let stopped = false;
7893
+ const installedPackage = options.sourceRoot || !options.cliEntry ? null : packageName(path25.dirname(path25.dirname(options.cliEntry)));
7894
+ const checkUpdates = async () => {
7895
+ if (!installedPackage) return;
7896
+ try {
7897
+ const next = await checkForUpdate(installedPackage, options.version);
7898
+ if (stopped) return;
7899
+ if (next?.latestVersion !== availableUpdate?.latestVersion) {
7900
+ availableUpdate = next;
7901
+ bus.emit("update:available", next);
7902
+ }
7903
+ } catch {
7904
+ }
7905
+ };
7764
7906
  let stopping = null;
7765
7907
  const handlers = {
7766
7908
  ...core.handlers,
@@ -7773,7 +7915,8 @@ async function startHost(options) {
7773
7915
  version: options.version,
7774
7916
  backend: sessions.kind,
7775
7917
  startedAt: lock.startedAt
7776
- })
7918
+ }),
7919
+ "host:updateStatus": () => availableUpdate
7777
7920
  };
7778
7921
  const server = await startWebServer({
7779
7922
  handlers,
@@ -7787,7 +7930,13 @@ async function startHost(options) {
7787
7930
  updateLock(options.userDataDir, lock);
7788
7931
  const stopWatch = core.watchStore();
7789
7932
  core.warmModelCatalog();
7933
+ if (installedPackage) {
7934
+ void checkUpdates();
7935
+ updateTimer = setInterval(() => void checkUpdates(), UPDATE_CHECK_INTERVAL_MS);
7936
+ }
7790
7937
  const stop = () => stopping ??= (async () => {
7938
+ stopped = true;
7939
+ if (updateTimer) clearInterval(updateTimer);
7791
7940
  stopWatch();
7792
7941
  core.shutdown();
7793
7942
  await server.close();
@@ -7803,7 +7952,7 @@ function loginUrl(lock, pathname = "/home/") {
7803
7952
  return `http://127.0.0.1:${lock.port}${pathname}?token=${encodeURIComponent(lock.token)}`;
7804
7953
  }
7805
7954
  function isWebDir(dir) {
7806
- return fs20.existsSync(path24.join(dir, "home", "index.html"));
7955
+ return fs21.existsSync(path25.join(dir, "home", "index.html"));
7807
7956
  }
7808
7957
 
7809
7958
  // packages/cli/src/remote.ts
@@ -7920,14 +8069,14 @@ function connectToHost(lock) {
7920
8069
  }
7921
8070
 
7922
8071
  // packages/cli/src/doctor.ts
7923
- import fs21 from "fs";
7924
- import path25 from "path";
7925
- import { execFile as execFile9 } from "child_process";
7926
- import { promisify as promisify6 } from "util";
8072
+ import fs22 from "fs";
8073
+ import path26 from "path";
8074
+ import { execFile as execFile10 } from "child_process";
8075
+ import { promisify as promisify7 } from "util";
7927
8076
  init_env();
7928
8077
  init_git_bash();
7929
8078
  init_tmux_backend();
7930
- var pexec6 = promisify6(execFile9);
8079
+ var pexec6 = promisify7(execFile10);
7931
8080
  function parseVersion(text) {
7932
8081
  const m = /(\d+)\.(\d+)(?:\.(\d+))?/.exec(text);
7933
8082
  return m ? [Number(m[1]), Number(m[2]), Number(m[3] ?? 0)] : [];
@@ -8061,10 +8210,10 @@ async function runDoctor(options) {
8061
8210
  });
8062
8211
  }
8063
8212
  try {
8064
- fs21.mkdirSync(options.userDataDir, { recursive: true });
8065
- const probe = path25.join(options.userDataDir, `.doctor-${process.pid}`);
8066
- fs21.writeFileSync(probe, "");
8067
- fs21.rmSync(probe);
8213
+ fs22.mkdirSync(options.userDataDir, { recursive: true });
8214
+ const probe = path26.join(options.userDataDir, `.doctor-${process.pid}`);
8215
+ fs22.writeFileSync(probe, "");
8216
+ fs22.rmSync(probe);
8068
8217
  checks.push({ id: "data", name: "\u8CC7\u6599\u76EE\u9304", level: "ok", detail: options.userDataDir });
8069
8218
  } catch (err) {
8070
8219
  checks.push({
@@ -8090,67 +8239,6 @@ function formatChecks(checks) {
8090
8239
  return lines.join("\n");
8091
8240
  }
8092
8241
 
8093
- // packages/cli/src/update-command.ts
8094
- import fs22 from "node:fs";
8095
- import path26 from "node:path";
8096
- import { spawnSync } from "node:child_process";
8097
- function npmRunner(args, inherit) {
8098
- const windows = process.platform === "win32";
8099
- return spawnSync(windows ? "npm.cmd" : "npm", args, {
8100
- encoding: "utf8",
8101
- stdio: inherit ? "inherit" : ["ignore", "pipe", "inherit"],
8102
- windowsHide: true,
8103
- shell: windows
8104
- });
8105
- }
8106
- function packageName(packageRoot) {
8107
- try {
8108
- const pkg = JSON.parse(fs22.readFileSync(path26.join(packageRoot, "package.json"), "utf8"));
8109
- if (typeof pkg.name !== "string") return null;
8110
- return /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/i.test(pkg.name) ? pkg.name : null;
8111
- } catch {
8112
- return null;
8113
- }
8114
- }
8115
- function runUpdate(options) {
8116
- const log = options.log ?? console.log;
8117
- const error = options.error ?? console.error;
8118
- const runNpm = options.runNpm ?? npmRunner;
8119
- if (options.sourceRoot || !options.cliEntry) {
8120
- error("vibeflow update \u53EA\u9069\u7528\u65BC\u5168\u57DF npm \u5B89\u88DD\uFF1B\u76EE\u524D\u662F\u539F\u59CB\u78BC\u7248\u672C\u3002");
8121
- return 1;
8122
- }
8123
- const packageRoot = path26.dirname(path26.dirname(options.cliEntry));
8124
- const name = packageName(packageRoot);
8125
- if (!name) {
8126
- error("\u7121\u6CD5\u8FA8\u8B58\u76EE\u524D VibeFlow \u7684 npm \u5957\u4EF6\u540D\u7A31\uFF0C\u5DF2\u53D6\u6D88\u66F4\u65B0\u3002");
8127
- return 1;
8128
- }
8129
- const root = runNpm(["root", "-g"], false);
8130
- if (root.error || root.status !== 0 || !String(root.stdout ?? "").trim()) {
8131
- error(`\u7121\u6CD5\u67E5\u8A62 npm \u5168\u57DF\u5B89\u88DD\u76EE\u9304\uFF1A${root.error?.message ?? `npm \u7D50\u675F\u78BC ${root.status ?? "unknown"}`}`);
8132
- return 1;
8133
- }
8134
- try {
8135
- const globalPackage = path26.join(String(root.stdout).trim(), ...name.split("/"));
8136
- if (fs22.lstatSync(globalPackage).isSymbolicLink() || fs22.realpathSync(globalPackage) !== fs22.realpathSync(packageRoot)) {
8137
- error("vibeflow update \u53EA\u9069\u7528\u65BC\u5168\u57DF npm \u5B89\u88DD\uFF1B\u76EE\u524D\u57F7\u884C\u7684\u5957\u4EF6\u4F86\u81EA\u5176\u4ED6\u4F4D\u7F6E\u3002");
8138
- return 1;
8139
- }
8140
- } catch {
8141
- error("vibeflow update \u53EA\u9069\u7528\u65BC\u5168\u57DF npm \u5B89\u88DD\uFF1B\u76EE\u524D\u57F7\u884C\u7684\u5957\u4EF6\u4E0D\u662F npm \u5168\u57DF\u5B89\u88DD\u3002");
8142
- return 1;
8143
- }
8144
- log(`\u6B63\u5728\u66F4\u65B0 ${name} \u81F3 npm latest\u2026`);
8145
- const result = runNpm(["install", "-g", `${name}@latest`], true);
8146
- if (result.error || result.status !== 0) {
8147
- error(`\u66F4\u65B0\u5931\u6557\uFF1A${result.error?.message ?? `npm \u7D50\u675F\u78BC ${result.status ?? "unknown"}`}`);
8148
- return result.status && result.status > 0 ? result.status : 1;
8149
- }
8150
- log("\u66F4\u65B0\u5B8C\u6210\u3002\u82E5 VibeFlow host \u6B63\u5728\u57F7\u884C\uFF0C\u8ACB\u81EA\u884C\u91CD\u65B0\u555F\u52D5\u4EE5\u8F09\u5165\u65B0\u7248\u672C\u3002");
8151
- return 0;
8152
- }
8153
-
8154
8242
  // packages/cli/src/main.ts
8155
8243
  var USAGE = `
8156
8244
  VibeFlow \u2014 intent-driven kanban for coding agents
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/9d4fa221b4133d92.css" as="style"/><link rel="stylesheet" href="/_next/static/css/9d4fa221b4133d92.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-ab090e0b95efc7ae.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/sVCe3iO4fTLCxTOdzqdP8/_buildManifest.js" defer=""></script><script src="/_next/static/sVCe3iO4fTLCxTOdzqdP8/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"sVCe3iO4fTLCxTOdzqdP8","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/9b4fcf22ca8f6bc9.css" as="style"/><link rel="stylesheet" href="/_next/static/css/9b4fcf22ca8f6bc9.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-70ce066e3ac8e039.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/sZPeIltIrJDddiLXt5zx1/_buildManifest.js" defer=""></script><script src="/_next/static/sZPeIltIrJDddiLXt5zx1/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"sZPeIltIrJDddiLXt5zx1","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
package/dist/web/404.html CHANGED
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/9d4fa221b4133d92.css" as="style"/><link rel="stylesheet" href="/_next/static/css/9d4fa221b4133d92.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-ab090e0b95efc7ae.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/sVCe3iO4fTLCxTOdzqdP8/_buildManifest.js" defer=""></script><script src="/_next/static/sVCe3iO4fTLCxTOdzqdP8/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"sVCe3iO4fTLCxTOdzqdP8","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><link rel="icon" href="/favicon.ico" sizes="any" data-next-head=""/><link rel="icon" href="/logo.svg" type="image/svg+xml" data-next-head=""/><link rel="apple-touch-icon" href="/apple-touch-icon.png" data-next-head=""/><title data-next-head="">404: This page could not be found</title><link rel="preload" href="/_next/static/css/9b4fcf22ca8f6bc9.css" as="style"/><link rel="stylesheet" href="/_next/static/css/9b4fcf22ca8f6bc9.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-33344f7100190436.js" defer=""></script><script src="/_next/static/chunks/framework-b92a367cf1ad4bf7.js" defer=""></script><script src="/_next/static/chunks/main-ec7fd4c371d06729.js" defer=""></script><script src="/_next/static/chunks/pages/_app-70ce066e3ac8e039.js" defer=""></script><script src="/_next/static/chunks/pages/_error-8f65b0f8749f42d2.js" defer=""></script><script src="/_next/static/sZPeIltIrJDddiLXt5zx1/_buildManifest.js" defer=""></script><script src="/_next/static/sZPeIltIrJDddiLXt5zx1/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"sZPeIltIrJDddiLXt5zx1","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>