@monster-orange/den 0.2.8 → 0.4.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 +1731 -0
- package/README.md +4 -2
- package/bin/den +2 -1
- package/docs/distributions.md +730 -6
- 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 +12 -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/agents/default-pack/be-dev.md +20 -0
- package/src/shared/agents/default-pack/devops.md +14 -0
- package/src/shared/agents/default-pack/fe-dev.md +20 -0
- package/src/shared/agents/default-pack/orchestrator.md +16 -0
- package/src/shared/agents/default-pack/planner.md +17 -0
- package/src/shared/agents/default-pack/reviewer.md +14 -0
- package/src/shared/agents/default-pack/ux-designer.md +15 -0
- package/src/shared/agents/den-claude.ts +173 -0
- package/src/shared/agents/generic.ts +52 -0
- package/src/shared/agents/personas.ts +218 -0
- package/src/shared/agents/records.ts +118 -0
- package/src/shared/agents/runtime.ts +192 -0
- package/src/shared/agents/runtimes.ts +47 -0
- 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 +257 -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/engine.ts +23 -0
- 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/environment-manager/workspaces.ts +19 -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/secret-env.ts +70 -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/sessions/client.ts +277 -0
- package/src/shared/sessions/den-pty.ts +97 -0
- package/src/shared/sessions/env.ts +79 -0
- package/src/shared/sessions/host.ts +667 -0
- package/src/shared/sessions/names.ts +85 -0
- package/src/shared/sessions/paths.ts +27 -0
- package/src/shared/sessions/protocol.ts +72 -0
- package/src/shared/sessions/pty.ts +141 -0
- package/src/shared/sessions/ring-buffer.ts +160 -0
- package/src/shared/sessions/types.ts +81 -0
- 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/agents-command.ts +812 -0
- package/src/ui/cli/create.ts +24 -7
- package/src/ui/cli/doctor-command.ts +260 -0
- package/src/ui/cli/edge-command.ts +56 -10
- package/src/ui/cli/env-probe.ts +266 -0
- package/src/ui/cli/flag-parser.ts +18 -5
- package/src/ui/cli/health-display.ts +25 -0
- package/src/ui/cli/index.ts +580 -60
- package/src/ui/cli/notice.ts +20 -0
- package/src/ui/cli/plugin-command.ts +849 -0
- package/src/ui/cli/sessions-command.ts +718 -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 +145 -20
- package/src/ui/mcp/server.ts +27 -2
- package/src/ui/mcp/tools.ts +94 -12
- package/src/ui/server/appearance-prefs.ts +95 -0
- package/src/ui/server/audit.ts +35 -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 +539 -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 +37 -3
- 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 +48 -18
- package/themes/den/den-theme.json +72 -0
- package/themes/den/favicon.ico +0 -0
- package/themes/den/mark.svg +6 -0
|
@@ -10,13 +10,23 @@ import { readCatalog } from "../environment-manager/catalog.js";
|
|
|
10
10
|
import { readEdgeConfig } from "../edge/config.js";
|
|
11
11
|
import { routeUrl } from "../edge/render.js";
|
|
12
12
|
import {
|
|
13
|
+
getActiveWorkspaces,
|
|
13
14
|
getFocusedWorkspaceName,
|
|
14
15
|
getWorkspaceByName,
|
|
15
16
|
listWorkspaceServices,
|
|
16
17
|
} from "../environment-manager/workspaces.js";
|
|
17
18
|
import { readManifestStacks, readStacks } from "./config.js";
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
19
|
+
import { STACK_NAMESPACE_RE } from "../den-config.js";
|
|
20
|
+
import {
|
|
21
|
+
resolveStackNamespace,
|
|
22
|
+
type StackNamespaceSource,
|
|
23
|
+
} from "./namespace.js";
|
|
24
|
+
import { projectName } from "./render.js";
|
|
25
|
+
import {
|
|
26
|
+
rejoinEdgeNetworks,
|
|
27
|
+
stackHealth,
|
|
28
|
+
type StackContext,
|
|
29
|
+
} from "./runtime.js";
|
|
20
30
|
|
|
21
31
|
export interface StackRoute {
|
|
22
32
|
name: string;
|
|
@@ -38,40 +48,81 @@ export interface StackStatus {
|
|
|
38
48
|
health?: { ok: boolean | null; detail: string };
|
|
39
49
|
}
|
|
40
50
|
|
|
41
|
-
const WS_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
|
|
42
|
-
|
|
43
51
|
/**
|
|
44
52
|
* The den workspace stacks read their manifests from, and the Compose
|
|
45
53
|
* project suffix they run under. `denWorkspace` defaults to the CLI's
|
|
46
|
-
* -w override, then the focused workspace, then `default`.
|
|
54
|
+
* -w override, then the focused workspace, then `default`. The suffix is
|
|
55
|
+
* the workspace's stack namespace (namespace.ts); DEN_STACK_WORKSPACE, a
|
|
56
|
+
* per-command override, wins over it for this one process (source `env`).
|
|
57
|
+
*
|
|
58
|
+
* The one place a den workspace becomes a Compose project suffix: every
|
|
59
|
+
* stack path (status, runtime, health, container lookup) comes through here.
|
|
47
60
|
*/
|
|
48
61
|
export function resolveStackWorkspaces(
|
|
49
62
|
denWorkspace?: string | null,
|
|
50
63
|
env: NodeJS.ProcessEnv = process.env,
|
|
51
|
-
): {
|
|
64
|
+
): {
|
|
65
|
+
denWorkspace: string;
|
|
66
|
+
stackWorkspace: string;
|
|
67
|
+
source: StackNamespaceSource | "env";
|
|
68
|
+
} {
|
|
52
69
|
const fkWs =
|
|
53
70
|
denWorkspace ||
|
|
54
71
|
env.DEN_WORKSPACE_OVERRIDE ||
|
|
55
72
|
getFocusedWorkspaceName() ||
|
|
56
73
|
"default";
|
|
57
|
-
const
|
|
58
|
-
|
|
74
|
+
const override = env.DEN_STACK_WORKSPACE;
|
|
75
|
+
const resolved = override ? null : resolveStackNamespace(fkWs);
|
|
76
|
+
const ws = override || resolved!.namespace;
|
|
77
|
+
if (!STACK_NAMESPACE_RE.test(ws))
|
|
59
78
|
throw new Error(
|
|
60
79
|
`workspace "${ws}" must be lowercase letters, digits and dashes`,
|
|
61
80
|
);
|
|
62
|
-
return {
|
|
81
|
+
return {
|
|
82
|
+
denWorkspace: fkWs,
|
|
83
|
+
stackWorkspace: ws,
|
|
84
|
+
source: resolved ? resolved.source : "env",
|
|
85
|
+
};
|
|
63
86
|
}
|
|
64
87
|
|
|
65
88
|
/** The edge, the known stacks and the project suffix for one workspace. */
|
|
66
89
|
export function loadStackContext(denWorkspace?: string | null): StackContext {
|
|
67
|
-
const {
|
|
68
|
-
|
|
90
|
+
const {
|
|
91
|
+
denWorkspace: fkWs,
|
|
92
|
+
stackWorkspace: ws,
|
|
93
|
+
source,
|
|
94
|
+
} = resolveStackWorkspaces(denWorkspace);
|
|
69
95
|
const edge = readEdgeConfig();
|
|
70
96
|
// Repo manifests come from that den workspace's checkouts.
|
|
71
97
|
const stacks = readStacks(undefined, {
|
|
72
98
|
workspace: getWorkspaceByName(fkWs) ? fkWs : undefined,
|
|
73
99
|
});
|
|
74
|
-
return {
|
|
100
|
+
return {
|
|
101
|
+
edge,
|
|
102
|
+
stacks,
|
|
103
|
+
workspace: ws,
|
|
104
|
+
denWorkspace: fkWs,
|
|
105
|
+
namespaceSource: source,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* After edge up: the edge back on the routed networks of every running
|
|
111
|
+
* stack it routes (rejoinEdgeNetworks), across the focused and active
|
|
112
|
+
* workspaces' stack namespaces. A workspace whose stacks cannot be read is
|
|
113
|
+
* skipped.
|
|
114
|
+
*/
|
|
115
|
+
export function rejoinRunningStacks(
|
|
116
|
+
onLine: (line: string) => void = console.log,
|
|
117
|
+
): string[] {
|
|
118
|
+
const contexts: StackContext[] = [];
|
|
119
|
+
for (const ws of new Set([null, ...getActiveWorkspaces()]))
|
|
120
|
+
try {
|
|
121
|
+
contexts.push(loadStackContext(ws));
|
|
122
|
+
} catch {
|
|
123
|
+
/* unreadable: nothing of it to rejoin */
|
|
124
|
+
}
|
|
125
|
+
return rejoinEdgeNetworks(contexts, onLine);
|
|
75
126
|
}
|
|
76
127
|
|
|
77
128
|
/** Each stack's name, project, routes and (optionally) container health. */
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strategy registry: every concern that varies by distribution (secrets
|
|
3
|
+
* backend today; TLS and others next) is a strategy, and Den's built-ins
|
|
4
|
+
* register here exactly as a plugin would. An entry is
|
|
5
|
+
* `{ id, kind, detect(), capabilities }`:
|
|
6
|
+
*
|
|
7
|
+
* - `kind` names the concern ("secrets"); ids are unique per kind;
|
|
8
|
+
* - `detect()` is cheap and side-effect free: it never prompts, never
|
|
9
|
+
* spawns a CLI that could prompt, and never prints a secret. It says
|
|
10
|
+
* whether the strategy can work on this machine, and why not;
|
|
11
|
+
* - `capabilities` is the kind's own interface (a factory, optional setup,
|
|
12
|
+
* optional env injection, ...).
|
|
13
|
+
*
|
|
14
|
+
* No plugin loading happens here: a future plugin kind calls
|
|
15
|
+
* registerStrategy() with its entry.
|
|
16
|
+
*/
|
|
17
|
+
import * as fs from "fs";
|
|
18
|
+
import * as path from "path";
|
|
19
|
+
|
|
20
|
+
export interface DetectResult {
|
|
21
|
+
available: boolean;
|
|
22
|
+
/** Why the strategy is unavailable, or a note (e.g. "not configured"). */
|
|
23
|
+
reason?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface StrategyEntry<K extends string = string, C = unknown> {
|
|
27
|
+
id: string;
|
|
28
|
+
kind: K;
|
|
29
|
+
detect(env?: NodeJS.ProcessEnv): DetectResult;
|
|
30
|
+
capabilities: C;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const registries = new Map<string, Map<string, StrategyEntry>>();
|
|
34
|
+
|
|
35
|
+
/** Register (or replace) a strategy under its kind. */
|
|
36
|
+
export function registerStrategy<K extends string, C>(
|
|
37
|
+
entry: StrategyEntry<K, C>,
|
|
38
|
+
): void {
|
|
39
|
+
let byId = registries.get(entry.kind);
|
|
40
|
+
if (!byId) {
|
|
41
|
+
byId = new Map();
|
|
42
|
+
registries.set(entry.kind, byId);
|
|
43
|
+
}
|
|
44
|
+
byId.set(entry.id, entry as StrategyEntry);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The strategy `id` of `kind`, or undefined. */
|
|
48
|
+
export function getStrategy<K extends string, C>(
|
|
49
|
+
kind: K,
|
|
50
|
+
id: string,
|
|
51
|
+
): StrategyEntry<K, C> | undefined {
|
|
52
|
+
return registries.get(kind)?.get(id) as StrategyEntry<K, C> | undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Every kind with a registered strategy, in registration order. */
|
|
56
|
+
export function strategyKinds(): string[] {
|
|
57
|
+
return [...registries.keys()];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Every registered id of `kind`, in registration order. */
|
|
61
|
+
export function strategyIds(kind: string): string[] {
|
|
62
|
+
return [...(registries.get(kind)?.keys() ?? [])];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* True when an executable named `bin` is on `env.PATH`. A file check only:
|
|
67
|
+
* nothing is run, so it can never prompt (Touch ID, a login) or print.
|
|
68
|
+
*/
|
|
69
|
+
export function onPath(
|
|
70
|
+
bin: string,
|
|
71
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
72
|
+
): boolean {
|
|
73
|
+
const exts =
|
|
74
|
+
process.platform === "win32"
|
|
75
|
+
? (env.PATHEXT ?? ".EXE;.CMD;.BAT").split(";")
|
|
76
|
+
: [""];
|
|
77
|
+
for (const dir of (env.PATH ?? "").split(path.delimiter)) {
|
|
78
|
+
if (!dir) continue;
|
|
79
|
+
for (const ext of exts) {
|
|
80
|
+
try {
|
|
81
|
+
fs.accessSync(path.join(dir, bin + ext), fs.constants.X_OK);
|
|
82
|
+
if (fs.statSync(path.join(dir, bin + ext)).isFile()) return true;
|
|
83
|
+
} catch {
|
|
84
|
+
/* not here */
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|