@monster-orange/den 0.2.8 → 0.3.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 +1547 -0
- package/README.md +4 -2
- package/bin/den +2 -1
- package/docs/distributions.md +507 -4
- package/make/den.mk +19 -4
- package/make/journeys.mk +2 -1
- package/make/local_dev.mk +6 -13
- package/make/secrets-1password.mk +18 -0
- package/make/test.mk +1 -1
- package/package.json +9 -2
- package/schemas/den.plugin.v1.json +156 -0
- package/schemas/den.theme.v1.json +269 -0
- package/scripts/auth-configure.ts +16 -8
- package/scripts/heal-config.ts +0 -5
- package/scripts/setup-1password.ts +41 -19
- package/scripts/setup-secrets.ts +67 -101
- package/src/pillars/api/global-setup.ts +1 -1
- package/src/pillars/journeys/sandbox.ts +23 -18
- package/src/pillars/journeys/tools/browser-session.ts +2 -2
- package/src/scripts/setup-default-workspace.ts +2 -2
- package/src/shared/auth/headless-login.ts +1 -1
- package/src/shared/auth/sudo-vault.ts +93 -31
- package/src/shared/auth/token-providers/index.ts +7 -3
- package/src/shared/brand.ts +7 -0
- package/src/shared/config-error.ts +33 -3
- package/src/shared/constants.ts +3 -24
- package/src/shared/den-config.ts +141 -5
- package/src/shared/edge/config.ts +147 -21
- package/src/shared/edge/exec.ts +31 -0
- package/src/shared/edge/included.ts +169 -0
- package/src/shared/edge/render.ts +69 -14
- package/src/shared/edge/runtime.ts +128 -121
- package/src/shared/edge/status.ts +68 -8
- package/src/shared/edge/tls.ts +328 -0
- package/src/shared/edge/types.ts +25 -9
- package/src/shared/environment-manager/default-workspace.ts +16 -1
- package/src/shared/environment-manager/health.ts +73 -38
- package/src/shared/environment-manager/scope.ts +168 -0
- package/src/shared/environment-manager/service-runner.ts +789 -43
- package/src/shared/environment-manager/up-targets.ts +132 -0
- package/src/shared/health/rollup.ts +48 -0
- package/src/shared/open-url.ts +21 -2
- package/src/shared/org-sources.ts +78 -59
- package/src/shared/org.ts +53 -5
- package/src/shared/plugins/manifest.ts +406 -0
- package/src/shared/plugins/store.ts +358 -0
- package/src/shared/process/legacy-adopt.ts +285 -0
- package/src/shared/process/process-group.ts +202 -0
- package/src/shared/process/spawn-streaming.ts +7 -0
- package/src/shared/secrets/doppler.ts +1 -1
- package/src/shared/secrets/index.ts +279 -50
- package/src/shared/secrets/none.ts +56 -0
- package/src/shared/secrets/strategies.ts +202 -0
- package/src/shared/secrets/types.ts +1 -1
- package/src/shared/smoke/git-remote.ts +40 -0
- package/src/shared/stacks/manifest-commands.ts +1 -1
- package/src/shared/stacks/namespace.ts +178 -0
- package/src/shared/stacks/owners.ts +303 -0
- package/src/shared/stacks/render.ts +8 -3
- package/src/shared/stacks/runtime.ts +100 -16
- package/src/shared/stacks/status.ts +63 -12
- package/src/shared/strategies/registry.ts +89 -0
- package/src/shared/theme/contract.ts +538 -0
- package/src/shared/types/index.ts +12 -3
- package/src/ui/cli/create.ts +24 -7
- package/src/ui/cli/doctor-command.ts +131 -0
- package/src/ui/cli/edge-command.ts +56 -10
- package/src/ui/cli/flag-parser.ts +7 -2
- package/src/ui/cli/health-display.ts +25 -0
- package/src/ui/cli/index.ts +548 -60
- package/src/ui/cli/notice.ts +20 -0
- package/src/ui/cli/plugin-command.ts +849 -0
- package/src/ui/cli/stack-command.ts +63 -2
- package/src/ui/cli/test-runner.ts +11 -9
- package/src/ui/cli/theme-command.ts +136 -0
- package/src/ui/cli/web-command.ts +47 -23
- package/src/ui/mcp/api.ts +28 -2
- package/src/ui/mcp/scope.ts +22 -1
- package/src/ui/mcp/tools.ts +50 -7
- package/src/ui/server/appearance-prefs.ts +95 -0
- package/src/ui/server/daemon-reaper.ts +29 -1
- package/src/ui/server/engine-stamp.ts +83 -0
- package/src/ui/server/github-service.ts +23 -44
- package/src/ui/server/graph-page.ts +20 -0
- package/src/ui/server/graph-prefs.ts +44 -1
- package/src/ui/server/http-errors.ts +293 -0
- package/src/ui/server/http-helpers.ts +22 -3
- package/src/ui/server/index.ts +532 -51
- package/src/ui/server/public/appearance.js +531 -0
- package/src/ui/server/public/edge-page.js +248 -0
- package/src/ui/server/public/edge.html +251 -0
- package/src/ui/server/public/environments.html +65 -83
- package/src/ui/server/public/error-page.js +247 -0
- package/src/ui/server/public/error.html +260 -0
- package/src/ui/server/public/graph-model.js +332 -14
- package/src/ui/server/public/graph.css +141 -47
- package/src/ui/server/public/graph.js +223 -44
- package/src/ui/server/public/header.js +396 -600
- package/src/ui/server/public/health-fit.js +248 -0
- package/src/ui/server/public/health-rollup.js +128 -0
- package/src/ui/server/public/i18n/es.js +287 -0
- package/src/ui/server/public/i18n/ja.js +276 -0
- package/src/ui/server/public/index.html +139 -438
- package/src/ui/server/public/local-dev.html +3468 -4044
- package/src/ui/server/public/logs.html +71 -208
- package/src/ui/server/public/panel.js +14 -2
- package/src/ui/server/public/release.html +175 -389
- package/src/ui/server/public/services.html +596 -770
- package/src/ui/server/public/settings-page.js +759 -0
- package/src/ui/server/public/settings-registry.js +521 -0
- package/src/ui/server/public/settings.html +590 -0
- package/src/ui/server/public/shell.js +3869 -0
- package/src/ui/server/public/topbar.js +1413 -0
- package/src/ui/server/public/version-label.js +12 -0
- package/src/ui/server/public/workspace-picker.js +74 -34
- package/src/ui/server/readonly-routes.ts +12 -1
- package/src/ui/server/services-list.ts +94 -17
- package/src/ui/server/settings-distribution.ts +74 -0
- package/src/ui/server/shell-prefs.ts +192 -0
- package/src/ui/server/theme-routes.ts +292 -0
- package/src/ui/server/theme-runtime.ts +407 -0
- package/src/ui/server/ui-assets.ts +16 -1
- package/src/ui/server/ui-language.ts +50 -0
- package/src/ui/server/workspace-routes.ts +45 -3
- package/themes/den/den-theme.json +72 -0
- package/themes/den/favicon.ico +0 -0
- package/themes/den/mark.svg +6 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Static assets the graph needs beyond the pages themselves:
|
|
3
|
-
* - the
|
|
3
|
+
* - the UI's own modules in public/ (UI_MODULES: the graph, the appearance
|
|
4
|
+
* controls, the version label, the top bar's chips and overlays),
|
|
5
|
+
* served like header.js;
|
|
4
6
|
* - browser libraries the UI loads, served by Den's own server from
|
|
5
7
|
* node_modules (never a CDN), so the UI works offline. Each is a pinned
|
|
6
8
|
* dependency in package.json. npm hoists Den's dependencies into a
|
|
@@ -19,7 +21,20 @@ export const UI_MODULES: readonly string[] = [
|
|
|
19
21
|
"/graph-model.js",
|
|
20
22
|
"/panel.js",
|
|
21
23
|
"/graph.css",
|
|
24
|
+
"/appearance.js",
|
|
25
|
+
"/version-label.js",
|
|
22
26
|
"/changelog-view.js",
|
|
27
|
+
"/health-fit.js",
|
|
28
|
+
"/health-rollup.js",
|
|
29
|
+
"/shell.js",
|
|
30
|
+
"/settings-registry.js",
|
|
31
|
+
"/settings-page.js",
|
|
32
|
+
"/topbar.js",
|
|
33
|
+
"/edge-page.js",
|
|
34
|
+
"/error-page.js",
|
|
35
|
+
// The UI's catalogs other than English (R19; en is in shell.js).
|
|
36
|
+
"/i18n/ja.js",
|
|
37
|
+
"/i18n/es.js",
|
|
23
38
|
];
|
|
24
39
|
|
|
25
40
|
/** URL path → file inside node_modules. */
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The web UI's language (R19, 0.3.0-dev.39): a user pref, stored as
|
|
3
|
+
* `language:` in config/local/user.yml and served by /api/settings, like
|
|
4
|
+
* `editor`. Absent means English.
|
|
5
|
+
*
|
|
6
|
+
* The catalogs are public/shell.js's MESSAGES (en, the fallback) and one
|
|
7
|
+
* classic script per other language, public/i18n/<lang>.js, which adds its
|
|
8
|
+
* table to window.denMessages before shell.js runs. A page served in a
|
|
9
|
+
* language other than English gets that script and `<html lang>` from
|
|
10
|
+
* localizePage, so the first paint is already in that language. An English
|
|
11
|
+
* page is served exactly as it is on disk.
|
|
12
|
+
*
|
|
13
|
+
* Only Den's own words are translated: names (services, workspaces, repos,
|
|
14
|
+
* themes, languages), logs and command output never are.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Every language the UI ships a catalog for; the first is the fallback. */
|
|
18
|
+
export const UI_LANGUAGES = ["en", "ja", "es"] as const;
|
|
19
|
+
export type UiLanguage = (typeof UI_LANGUAGES)[number];
|
|
20
|
+
export const DEFAULT_UI_LANGUAGE: UiLanguage = "en";
|
|
21
|
+
|
|
22
|
+
export function isUiLanguage(v: unknown): v is UiLanguage {
|
|
23
|
+
return (
|
|
24
|
+
typeof v === "string" && (UI_LANGUAGES as readonly string[]).includes(v)
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The stored value, normalised: an unknown or missing one is English. */
|
|
29
|
+
export function uiLanguage(stored: unknown): UiLanguage {
|
|
30
|
+
return isUiLanguage(stored) ? stored : DEFAULT_UI_LANGUAGE;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** The catalog script a language's pages load before shell.js (none for en). */
|
|
34
|
+
export function catalogPath(lang: UiLanguage): string | null {
|
|
35
|
+
return lang === DEFAULT_UI_LANGUAGE ? null : `/i18n/${lang}.js`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A page in `lang`: `<html lang>` set, and the language's catalog loaded
|
|
40
|
+
* just before shell.js, so the shell draws in it from the first paint.
|
|
41
|
+
* English, or a page without the shell, comes back unchanged.
|
|
42
|
+
*/
|
|
43
|
+
export function localizePage(html: string, lang: UiLanguage): string {
|
|
44
|
+
const src = catalogPath(lang);
|
|
45
|
+
const shell = '<script src="/shell.js"></script>';
|
|
46
|
+
if (!src || !html.includes(shell)) return html;
|
|
47
|
+
return html
|
|
48
|
+
.replace(/<html lang="[^"]*"/, () => `<html lang="${lang}"`)
|
|
49
|
+
.replace(shell, () => `<script src="${src}"></script>${shell}`);
|
|
50
|
+
}
|
|
@@ -19,6 +19,7 @@ import type { ResolvedService } from "../../shared/types/index.js";
|
|
|
19
19
|
import type { EditorManager } from "./editor-manager.js";
|
|
20
20
|
import type { GitHubService } from "./github-service.js";
|
|
21
21
|
import { JETBRAINS_EDITORS } from "./editor-manager.js";
|
|
22
|
+
import { stackNamespaceRows } from "../../shared/stacks/namespace.js";
|
|
22
23
|
import {
|
|
23
24
|
readWorkspacesFile,
|
|
24
25
|
writeWorkspacesFile,
|
|
@@ -44,6 +45,7 @@ import {
|
|
|
44
45
|
import {
|
|
45
46
|
checkServiceHealth,
|
|
46
47
|
claimHealthyService,
|
|
48
|
+
settledDaemonRecord,
|
|
47
49
|
runServiceCommand,
|
|
48
50
|
prepareServiceSecretEnv,
|
|
49
51
|
resolveService,
|
|
@@ -552,7 +554,21 @@ export async function handleWorkspaceRoutes(
|
|
|
552
554
|
syncJetBrainsWorkspaceSymlinks(wsFile);
|
|
553
555
|
}
|
|
554
556
|
|
|
555
|
-
|
|
557
|
+
// Each workspace's stack namespace, resolved, with where it came from
|
|
558
|
+
// (workspace, blueprint or default) and whether it differs from the
|
|
559
|
+
// default suffix: the page's "stacks: <ns>" chip.
|
|
560
|
+
const stackNamespaces = Object.fromEntries(
|
|
561
|
+
stackNamespaceRows(Object.keys(wsFile.workspaces)).map((r) => [
|
|
562
|
+
r.workspace,
|
|
563
|
+
r,
|
|
564
|
+
]),
|
|
565
|
+
);
|
|
566
|
+
return sendJson(res, {
|
|
567
|
+
...wsFile,
|
|
568
|
+
resolvedDirs,
|
|
569
|
+
codeWorkspacePaths,
|
|
570
|
+
stackNamespaces,
|
|
571
|
+
});
|
|
556
572
|
}
|
|
557
573
|
|
|
558
574
|
// ── API: rename workspace ─────────────────────────────────────────────────
|
|
@@ -1775,10 +1791,31 @@ export async function handleWorkspaceRoutes(
|
|
|
1775
1791
|
if (cmd === "up") {
|
|
1776
1792
|
const health = await checkServiceHealth(resolved, "local");
|
|
1777
1793
|
if (cancelled) return;
|
|
1778
|
-
|
|
1794
|
+
// `conflict`: a shared stack namespace runs another checkout's
|
|
1795
|
+
// project; the real up refuses it, naming both.
|
|
1796
|
+
const claim =
|
|
1797
|
+
health.health === "ok"
|
|
1798
|
+
? claimHealthyService(resolved, ws.name, (text) =>
|
|
1799
|
+
emit({ type: "line", text }),
|
|
1800
|
+
)
|
|
1801
|
+
: "untracked";
|
|
1802
|
+
// Another process answers on its port (said above): nothing is
|
|
1803
|
+
// claimed and nothing started on top of it (0.3.0-dev.39).
|
|
1804
|
+
if (health.health === "ok" && claim === "busy") {
|
|
1805
|
+
overallExit = 1;
|
|
1806
|
+
emit({
|
|
1807
|
+
type: "svc-done",
|
|
1808
|
+
address,
|
|
1809
|
+
exitCode: 1,
|
|
1810
|
+
repoName: svcRepoName,
|
|
1811
|
+
subsystem: svcSubsystem,
|
|
1812
|
+
});
|
|
1813
|
+
safeRunNext(i + 1);
|
|
1814
|
+
return;
|
|
1815
|
+
}
|
|
1816
|
+
if (health.health === "ok" && claim !== "conflict") {
|
|
1779
1817
|
// Skipping must not lose the refcount — this workspace is an
|
|
1780
1818
|
// owner of what's running, whether den tracked it or not.
|
|
1781
|
-
const claim = claimHealthyService(resolved, ws.name);
|
|
1782
1819
|
emit({
|
|
1783
1820
|
type: "line",
|
|
1784
1821
|
text:
|
|
@@ -1801,6 +1838,11 @@ export async function handleWorkspaceRoutes(
|
|
|
1801
1838
|
return;
|
|
1802
1839
|
}
|
|
1803
1840
|
} else {
|
|
1841
|
+
// A pre-dev.37 record is settled before the skip decides
|
|
1842
|
+
// (0.3.0-dev.39): adopted, it is running; stale, it is dropped.
|
|
1843
|
+
settledDaemonRecord(resolved, ws.name, (text) =>
|
|
1844
|
+
emit({ type: "line", text }),
|
|
1845
|
+
);
|
|
1804
1846
|
let running = hasRunningOpctlContainers(resolved);
|
|
1805
1847
|
if (!running) {
|
|
1806
1848
|
// Not opctl-visible but still responding (host-run process)?
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/Monster-Orange/den/main/schemas/den.theme.v1.json",
|
|
3
|
+
"schema": "den.theme/v1",
|
|
4
|
+
"id": "den",
|
|
5
|
+
"name": "Den",
|
|
6
|
+
"version": "2.0.0",
|
|
7
|
+
"description": "Den's default: a sheltered workspace in walnut and umber neutrals with a moss-green accent. System fonts.",
|
|
8
|
+
"author": "Monster Orange",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"homepage": "https://github.com/Monster-Orange/den-themes/tree/main/themes/den",
|
|
11
|
+
"default_mode": "dark",
|
|
12
|
+
"type": {
|
|
13
|
+
"sans": "-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
|
|
14
|
+
"mono": "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, monospace",
|
|
15
|
+
"display": "-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
|
|
16
|
+
"ja": "\"Hiragino Sans\", \"Hiragino Kaku Gothic ProN\", \"Noto Sans JP\", \"Yu Gothic\", Meiryo, sans-serif"
|
|
17
|
+
},
|
|
18
|
+
"shape": {
|
|
19
|
+
"radius": "8px",
|
|
20
|
+
"radius-button": "6px",
|
|
21
|
+
"density": "comfortable"
|
|
22
|
+
},
|
|
23
|
+
"mark": {
|
|
24
|
+
"svg": "mark.svg",
|
|
25
|
+
"shape": "rounded"
|
|
26
|
+
},
|
|
27
|
+
"favicon": "favicon.ico",
|
|
28
|
+
"modes": {
|
|
29
|
+
"light": {
|
|
30
|
+
"bg": "#f2eee8",
|
|
31
|
+
"surface": "#fbf9f6",
|
|
32
|
+
"raised": "#ffffff",
|
|
33
|
+
"sunken": "#e8e2d9",
|
|
34
|
+
"text": "#241e18",
|
|
35
|
+
"muted": "#5c5247",
|
|
36
|
+
"faint": "#6d6358",
|
|
37
|
+
"border": "#dcd3c7",
|
|
38
|
+
"border-strong": "#8d7f6d",
|
|
39
|
+
"accent": "#557a2a",
|
|
40
|
+
"accent-text": "#4a6b23",
|
|
41
|
+
"accent-fill": "#4a6b23",
|
|
42
|
+
"on-accent": "#ffffff",
|
|
43
|
+
"ok": "#2e7246",
|
|
44
|
+
"warn": "#8c5a10",
|
|
45
|
+
"bad": "#b0392a",
|
|
46
|
+
"remote": "#23677a",
|
|
47
|
+
"shadow": "0 8px 24px rgb(48 36 24 / 0.14)",
|
|
48
|
+
"bar": "linear-gradient(90deg, #557a2a 0%, #8a6a48 100%)"
|
|
49
|
+
},
|
|
50
|
+
"dark": {
|
|
51
|
+
"bg": "#1a1612",
|
|
52
|
+
"surface": "#221d18",
|
|
53
|
+
"raised": "#2b251f",
|
|
54
|
+
"sunken": "#14110e",
|
|
55
|
+
"text": "#ede6dc",
|
|
56
|
+
"muted": "#b5aa9b",
|
|
57
|
+
"faint": "#978b7e",
|
|
58
|
+
"border": "#3a322a",
|
|
59
|
+
"border-strong": "#7a6d5d",
|
|
60
|
+
"accent": "#9bbb63",
|
|
61
|
+
"accent-text": "#a8c672",
|
|
62
|
+
"accent-fill": "#9bbb63",
|
|
63
|
+
"on-accent": "#1a1612",
|
|
64
|
+
"ok": "#6fc28f",
|
|
65
|
+
"warn": "#e0a84e",
|
|
66
|
+
"bad": "#ef7f6a",
|
|
67
|
+
"remote": "#74b8c8",
|
|
68
|
+
"shadow": "0 12px 30px rgb(0 0 0 / 0.5)",
|
|
69
|
+
"bar": "linear-gradient(90deg, #9bbb63 0%, #a07c55 100%)"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32" role="img" aria-label="Den">
|
|
2
|
+
<rect width="32" height="32" rx="7" fill="#3a2e22"/>
|
|
3
|
+
<path d="M5 26.5h22" stroke="#9bbb63" stroke-width="2" stroke-linecap="round"/>
|
|
4
|
+
<path d="M8 26V15a8 8 0 0 1 16 0v11h-4.5V15.5a3.5 3.5 0 0 0-7 0V26z" fill="#f2eee8"/>
|
|
5
|
+
<path d="M13 26v-9.5a3 3 0 0 1 6 0V26z" fill="#c8a46a" opacity="0.9"/>
|
|
6
|
+
</svg>
|