@monster-orange/den 0.0.0 → 0.2.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 +204 -0
- package/LICENSE +21 -0
- package/README.md +165 -1
- package/bin/den +68 -0
- package/docs/distributions.md +499 -0
- package/make/demo.mk +82 -0
- package/make/den.mk +80 -0
- package/make/journeys.mk +57 -0
- package/make/local_dev.mk +154 -0
- package/make/security.mk +59 -0
- package/make/test.mk +405 -0
- package/package.json +101 -4
- package/scripts/auth-configure.ts +415 -0
- package/scripts/heal-config.ts +92 -0
- package/scripts/jsonl-playwright-reporter.js +70 -0
- package/scripts/manifest-read.cjs +91 -0
- package/scripts/setup-1password.ts +570 -0
- package/scripts/setup-secrets.ts +149 -0
- package/scripts/view-results.js +156 -0
- package/service/install.sh +112 -0
- package/src/pillars/api/fixtures/index.ts +128 -0
- package/src/pillars/api/fixtures/openapi-validator.ts +111 -0
- package/src/pillars/api/global-setup.ts +103 -0
- package/src/pillars/api/playwright.config.ts +105 -0
- package/src/pillars/api/schemas/example-api.json +110 -0
- package/src/pillars/api/tests/health/health.spec.ts +19 -0
- package/src/pillars/api/tests/health/manifest.yml +6 -0
- package/src/pillars/browser/fixtures/index.ts +232 -0
- package/src/pillars/browser/fixtures/package.json +10 -0
- package/src/pillars/browser/global-setup.ts +140 -0
- package/src/pillars/browser/global-teardown.ts +48 -0
- package/src/pillars/browser/playwright.config.ts +212 -0
- package/src/pillars/browser/setup.ts +219 -0
- package/src/pillars/journeys/app-config.ts +237 -0
- package/src/pillars/journeys/discover.ts +160 -0
- package/src/pillars/journeys/hooks/deny-shell.cjs +44 -0
- package/src/pillars/journeys/observability/events.ts +288 -0
- package/src/pillars/journeys/observability/sdk-mapper.ts +306 -0
- package/src/pillars/journeys/report/friction.ts +304 -0
- package/src/pillars/journeys/report/junit.ts +105 -0
- package/src/pillars/journeys/report/render.ts +273 -0
- package/src/pillars/journeys/report/results.ts +323 -0
- package/src/pillars/journeys/run.ts +673 -0
- package/src/pillars/journeys/runner.ts +1025 -0
- package/src/pillars/journeys/sandbox.ts +403 -0
- package/src/pillars/journeys/spec/loader.ts +152 -0
- package/src/pillars/journeys/spec/schema.ts +208 -0
- package/src/pillars/journeys/teardown.ts +98 -0
- package/src/pillars/journeys/tools/browser-session.ts +219 -0
- package/src/pillars/journeys/tools/browser-tool.ts +914 -0
- package/src/pillars/journeys/tools/http-tool.ts +564 -0
- package/src/pillars/journeys/tools/ledger.ts +278 -0
- package/src/pillars/journeys/tools/snapshot-store.ts +117 -0
- package/src/pillars/journeys/verify/assertions.ts +502 -0
- package/src/pillars/journeys/verify/verdict.ts +71 -0
- package/src/pillars/perf/build-report.ts +36 -0
- package/src/pillars/perf/k6.config.js +112 -0
- package/src/pillars/perf/run.ts +345 -0
- package/src/pillars/perf/scenarios/load-profile.js +97 -0
- package/src/pillars/perf/staging.ts +73 -0
- package/src/pillars/security/discover.ts +124 -0
- package/src/pillars/security/findings.ts +151 -0
- package/src/pillars/security/plan.ts +355 -0
- package/src/pillars/security/run.ts +757 -0
- package/src/pillars/smoke/admin-probe.ts +68 -0
- package/src/pillars/smoke/base-url.ts +56 -0
- package/src/pillars/smoke/cleanup.ts +8 -0
- package/src/pillars/smoke/discover.ts +237 -0
- package/src/pillars/smoke/ensure-smoke-teardown.ts +40 -0
- package/src/pillars/smoke/fixture-manager.ts +217 -0
- package/src/pillars/smoke/fixtures.ts +468 -0
- package/src/pillars/smoke/global-setup-all.ts +262 -0
- package/src/pillars/smoke/global-setup-global.ts +262 -0
- package/src/pillars/smoke/global-setup.ts +273 -0
- package/src/pillars/smoke/global-teardown-all.ts +8 -0
- package/src/pillars/smoke/global-teardown-global.ts +8 -0
- package/src/pillars/smoke/global-teardown.ts +139 -0
- package/src/pillars/smoke/playwright-all.config.ts +147 -0
- package/src/pillars/smoke/playwright-global.config.ts +141 -0
- package/src/pillars/smoke/playwright.config.ts +162 -0
- package/src/pillars/smoke/setup-env.ts +132 -0
- package/src/pillars/smoke/setup-global.ts +126 -0
- package/src/pillars/smoke/setup.ts +115 -0
- package/src/pillars/smoke/smoke-repo.ts +16 -0
- package/src/pillars/smoke/staging.ts +49 -0
- package/src/pillars/suites/run.ts +147 -0
- package/src/scripts/configure-aws-profiles.ts +114 -0
- package/src/scripts/register-repos.ts +307 -0
- package/src/scripts/setup-default-workspace.ts +203 -0
- package/src/shared/agent-actor.ts +77 -0
- package/src/shared/applications.ts +138 -0
- package/src/shared/auth/api-token.ts +416 -0
- package/src/shared/auth/auth0-helper.ts +284 -0
- package/src/shared/auth/headless-login.ts +265 -0
- package/src/shared/auth/jwt-helper.ts +186 -0
- package/src/shared/auth/sudo-vault.ts +69 -0
- package/src/shared/auth/test-accounts.ts +98 -0
- package/src/shared/auth/token-injection.ts +184 -0
- package/src/shared/auth/token-providers/auth0.ts +80 -0
- package/src/shared/auth/token-providers/index.ts +182 -0
- package/src/shared/auth/token-refresh.ts +273 -0
- package/src/shared/banner.ts +15 -0
- package/src/shared/brand.ts +79 -0
- package/src/shared/cli-tabs.ts +131 -0
- package/src/shared/constants.ts +128 -0
- package/src/shared/den-config.ts +688 -0
- package/src/shared/dev-metrics/emit.ts +354 -0
- package/src/shared/edge/config.ts +229 -0
- package/src/shared/edge/render.ts +221 -0
- package/src/shared/edge/runtime.ts +268 -0
- package/src/shared/edge/status.ts +74 -0
- package/src/shared/edge/types.ts +62 -0
- package/src/shared/engine.ts +67 -0
- package/src/shared/environment/aws-profiles.ts +49 -0
- package/src/shared/environment/env-selector.ts +161 -0
- package/src/shared/environment/playwright-env.ts +82 -0
- package/src/shared/environment-manager/catalog.ts +77 -0
- package/src/shared/environment-manager/clone-guard.ts +163 -0
- package/src/shared/environment-manager/dag.ts +286 -0
- package/src/shared/environment-manager/default-workspace.ts +182 -0
- package/src/shared/environment-manager/derivation/alias.ts +90 -0
- package/src/shared/environment-manager/derivation/cache.ts +97 -0
- package/src/shared/environment-manager/derivation/derive-graph.ts +421 -0
- package/src/shared/environment-manager/derivation/derived-up.ts +354 -0
- package/src/shared/environment-manager/derivation/load-alias.ts +11 -0
- package/src/shared/environment-manager/derivation/rules-compose.ts +42 -0
- package/src/shared/environment-manager/derivation/rules-events.ts +50 -0
- package/src/shared/environment-manager/derivation/rules-http.ts +247 -0
- package/src/shared/environment-manager/derivation/rules-infra.ts +64 -0
- package/src/shared/environment-manager/derivation/rules-readiness.ts +96 -0
- package/src/shared/environment-manager/derivation/scan.ts +160 -0
- package/src/shared/environment-manager/derivation/text.ts +40 -0
- package/src/shared/environment-manager/derivation/types.ts +69 -0
- package/src/shared/environment-manager/health.ts +635 -0
- package/src/shared/environment-manager/index.ts +6 -0
- package/src/shared/environment-manager/load-applications.ts +108 -0
- package/src/shared/environment-manager/log-tail.ts +213 -0
- package/src/shared/environment-manager/make-targets.ts +78 -0
- package/src/shared/environment-manager/opctl.ts +335 -0
- package/src/shared/environment-manager/readiness.ts +93 -0
- package/src/shared/environment-manager/register-local.ts +72 -0
- package/src/shared/environment-manager/secrets-check.ts +260 -0
- package/src/shared/environment-manager/service-container.ts +47 -0
- package/src/shared/environment-manager/service-env.ts +110 -0
- package/src/shared/environment-manager/service-runner.ts +1603 -0
- package/src/shared/environment-manager/sync-targets.ts +66 -0
- package/src/shared/environment-manager/up-plan.ts +326 -0
- package/src/shared/environment-manager/workspace-manager.ts +905 -0
- package/src/shared/environment-manager/workspaces.ts +860 -0
- package/src/shared/manifest/deps.ts +27 -0
- package/src/shared/manifest/merge-override.ts +75 -0
- package/src/shared/manifest/migrate-manifest.ts +101 -0
- package/src/shared/manifest/placement.ts +321 -0
- package/src/shared/manifest/read-manifest.ts +278 -0
- package/src/shared/manifest/schema.ts +313 -0
- package/src/shared/manifest/service-links.ts +93 -0
- package/src/shared/manifest/validate-layers.ts +229 -0
- package/src/shared/manifest/validate-manifest.ts +200 -0
- package/src/shared/manifest/workspace-manifests.ts +92 -0
- package/src/shared/open-url.ts +122 -0
- package/src/shared/org.ts +44 -0
- package/src/shared/paths.ts +190 -0
- package/src/shared/perf/optional-fields.ts +105 -0
- package/src/shared/perf/report-normalizer.ts +404 -0
- package/src/shared/perf/report-paths.ts +19 -0
- package/src/shared/perf/report-store.ts +110 -0
- package/src/shared/perf/report-types.ts +70 -0
- package/src/shared/perf/test-paths.ts +25 -0
- package/src/shared/process/log-rotation.ts +147 -0
- package/src/shared/process/spawn-streaming.ts +229 -0
- package/src/shared/product.ts +92 -0
- package/src/shared/profile.ts +141 -0
- package/src/shared/redact.ts +107 -0
- package/src/shared/repo-kind.ts +32 -0
- package/src/shared/reporting/jsonl-reporter.ts +131 -0
- package/src/shared/reporting/slack-reporter.ts +340 -0
- package/src/shared/results/result-reader.ts +266 -0
- package/src/shared/results/result-writer.ts +168 -0
- package/src/shared/secrets/doppler.ts +126 -0
- package/src/shared/secrets/env.ts +48 -0
- package/src/shared/secrets/index.ts +197 -0
- package/src/shared/secrets/keys.ts +33 -0
- package/src/shared/secrets/onepassword.ts +75 -0
- package/src/shared/secrets/types.ts +52 -0
- package/src/shared/service-url.ts +119 -0
- package/src/shared/smoke/branch-resolver.ts +141 -0
- package/src/shared/smoke/git-remote.ts +70 -0
- package/src/shared/smoke/repo-cloner.ts +151 -0
- package/src/shared/stacks/config.ts +137 -0
- package/src/shared/stacks/manifest-commands.ts +118 -0
- package/src/shared/stacks/render.ts +253 -0
- package/src/shared/stacks/runtime.ts +334 -0
- package/src/shared/stacks/status.ts +99 -0
- package/src/shared/stacks/types.ts +53 -0
- package/src/shared/terminal/tabs.ts +212 -0
- package/src/shared/test-discovery/module-scanner.ts +569 -0
- package/src/shared/types/index.ts +701 -0
- package/src/shared/ui-marker.ts +19 -0
- package/src/ui/cli/applications-command.ts +148 -0
- package/src/ui/cli/config-command.ts +68 -0
- package/src/ui/cli/create-main.ts +9 -0
- package/src/ui/cli/create.ts +360 -0
- package/src/ui/cli/edge-command.ts +81 -0
- package/src/ui/cli/flag-parser.ts +246 -0
- package/src/ui/cli/graph-command.ts +570 -0
- package/src/ui/cli/health-display.ts +63 -0
- package/src/ui/cli/index.ts +3742 -0
- package/src/ui/cli/init.ts +855 -0
- package/src/ui/cli/invocation-target.ts +175 -0
- package/src/ui/cli/logs-command.ts +104 -0
- package/src/ui/cli/mcp-main.ts +13 -0
- package/src/ui/cli/mcp-stdout-guard.ts +10 -0
- package/src/ui/cli/module-selection.ts +31 -0
- package/src/ui/cli/prompts.ts +767 -0
- package/src/ui/cli/results-viewer.ts +436 -0
- package/src/ui/cli/secrets-preflight.ts +91 -0
- package/src/ui/cli/stack-command.ts +117 -0
- package/src/ui/cli/stalled-setup-recovery.ts +129 -0
- package/src/ui/cli/test-runner.ts +1319 -0
- package/src/ui/cli/web-command.ts +1073 -0
- package/src/ui/mcp/api.ts +284 -0
- package/src/ui/mcp/guards.ts +141 -0
- package/src/ui/mcp/server.ts +147 -0
- package/src/ui/mcp/tools.ts +565 -0
- package/src/ui/server/audit.ts +71 -0
- package/src/ui/server/changelog-parser.ts +105 -0
- package/src/ui/server/daemon-reaper.ts +129 -0
- package/src/ui/server/editor-manager.ts +301 -0
- package/src/ui/server/github-service.ts +223 -0
- package/src/ui/server/graph-prefs.ts +89 -0
- package/src/ui/server/health-row.ts +15 -0
- package/src/ui/server/http-helpers.ts +98 -0
- package/src/ui/server/index.ts +3350 -0
- package/src/ui/server/log-history.ts +453 -0
- package/src/ui/server/perf-report.ts +42 -0
- package/src/ui/server/public/environments.html +496 -0
- package/src/ui/server/public/favicon.ico +0 -0
- package/src/ui/server/public/graph-model.js +416 -0
- package/src/ui/server/public/graph.css +976 -0
- package/src/ui/server/public/graph.js +986 -0
- package/src/ui/server/public/header.js +1373 -0
- package/src/ui/server/public/index.html +2595 -0
- package/src/ui/server/public/local-dev.html +5344 -0
- package/src/ui/server/public/logs.html +1496 -0
- package/src/ui/server/public/panel.js +787 -0
- package/src/ui/server/public/perf-report.js +359 -0
- package/src/ui/server/public/release.html +2111 -0
- package/src/ui/server/public/services.html +1103 -0
- package/src/ui/server/public/workspace-picker.js +69 -0
- package/src/ui/server/readonly-routes.ts +200 -0
- package/src/ui/server/release-deploy-session.ts +246 -0
- package/src/ui/server/release-service.ts +1125 -0
- package/src/ui/server/sudo-store.ts +111 -0
- package/src/ui/server/ui-assets.ts +73 -0
- package/src/ui/server/workspace-routes.ts +2185 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Den are documented here. Each release lists the
|
|
4
|
+
config and manifest changes a distribution must make to move to it under
|
|
5
|
+
**Migrations**.
|
|
6
|
+
|
|
7
|
+
## [0.2.0] - 2026-11-04
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Manifest overrides.** An optional `manifests/<repo>.override.yml` in the
|
|
12
|
+
distribution is deep-merged onto the repo's base manifest (its own, or the
|
|
13
|
+
held one): maps merge by key, lists and scalars replace, and an explicit
|
|
14
|
+
`null` deletes a key. An override may only name services and keys the base
|
|
15
|
+
has, and an override with no base is an error. See "Overriding a manifest"
|
|
16
|
+
in `docs/distributions.md`.
|
|
17
|
+
- **Manifest layers are visible.** `/api/services` returns `manifestLayers`
|
|
18
|
+
per service (`["repo"]`, `["held", "override"]`, …) and the Services cards
|
|
19
|
+
show them; `GET /api/manifest/validate?path=<repo dir>` returns each layer's
|
|
20
|
+
result.
|
|
21
|
+
- **`validate` checks each layer.** For a repo folder it validates the base
|
|
22
|
+
and the override separately, each error naming its file, then the merged
|
|
23
|
+
result.
|
|
24
|
+
- **`<cli> mcp`: an MCP server over stdio** for agents, a thin client of the
|
|
25
|
+
running web server (it never starts it, and says how when it is down). Read
|
|
26
|
+
tools are always on, including the new `stacks` and `edge_status`; the
|
|
27
|
+
actions `service_up`, `service_down`, `service_restart`, `workspace_sync`
|
|
28
|
+
and `run_tests` are opt-in per org with `mcp.actions`. Guards: lifecycle
|
|
29
|
+
commands and env=local only, locally run services only, `run_tests` limited
|
|
30
|
+
to `mcp.run_tests.envs` (default `[local]`, never production), security runs
|
|
31
|
+
must pass the owned-host plan and `full` is local only, log tools read
|
|
32
|
+
local sources unless `mcp.logs.remote: true`, and all text returned is
|
|
33
|
+
secret-redacted. No deploy tool. Pinned `@modelcontextprotocol/sdk` 1.32.1.
|
|
34
|
+
See "MCP server" in `docs/distributions.md`.
|
|
35
|
+
- **Agent audit trail.** Every service exec, test run and sync is recorded
|
|
36
|
+
with who asked: an agent's actions carry actor `agent`, the MCP client's
|
|
37
|
+
self-reported name and version, and the MCP pid and session id, and show as
|
|
38
|
+
`[agent]` lines in the web server log on the Logs page.
|
|
39
|
+
- **Read-only status endpoints:** `/api/stacks` (what `stack ls/health` show),
|
|
40
|
+
`/api/edge` (what `edge status` shows) and `/api/security/plan` (the
|
|
41
|
+
security CLI's own dry run). `stack ls` and `edge status` now print from the
|
|
42
|
+
same code.
|
|
43
|
+
- **Graph: cards and a details panel.** The Local Dev graph is laid out by
|
|
44
|
+
ELK (layered, compound org or application › repo › service, orthogonal
|
|
45
|
+
edges; elkjs vendored and served by Den, so it works offline). Cards are
|
|
46
|
+
full size (detailed or compact) on a canvas you pan and zoom; Fit zooms out
|
|
47
|
+
to 35%. A card shows status, name, repo, placement and health, and its main
|
|
48
|
+
actions on hover. Clicking a card or a repo opens a side panel: one primary
|
|
49
|
+
action (Start when down, Open when up, else Logs), two common ones, and More
|
|
50
|
+
(manifest commands, tools, and careful actions that confirm on a second
|
|
51
|
+
click); tabs Overview, Logs (live tail), Config and Activity (the audit
|
|
52
|
+
trail, yours and agents'). ⤢ pops the panel out as a dialog. Layout
|
|
53
|
+
direction, grouping, card density and panel width are remembered per user
|
|
54
|
+
(`/api/settings` `graph`). Find highlights and centres on matches. The
|
|
55
|
+
panel is built from registries (actions, tabs, sections) a distribution or
|
|
56
|
+
later release can add to.
|
|
57
|
+
- `GET /api/activity`: the audit trail, filtered by service or repo.
|
|
58
|
+
- **One secret redactor** (`src/shared/redact.ts`), shared by the journeys and
|
|
59
|
+
security pillars and the MCP server.
|
|
60
|
+
- **Placement (R13): what runs here and what runs in the cloud.** A
|
|
61
|
+
manifest's service may say `runs: { local: remote, dev: remote }` (per env,
|
|
62
|
+
`local` or `remote`) and `target: { env, account?, url?, expect? }`.
|
|
63
|
+
Without `runs`, a service is local when it or any service of its repo has
|
|
64
|
+
local commands (or the repo is a compose stack), remote when it has only an
|
|
65
|
+
HTTP health URL and nothing in its repo runs here, and otherwise has no
|
|
66
|
+
placement. `/api/services`
|
|
67
|
+
and `/api/health` rows carry `runs` and `target`; `/api/applications`
|
|
68
|
+
carries `placements` per service address, and per application `placement`
|
|
69
|
+
(`local | remote | hybrid | none`) and a `summary`
|
|
70
|
+
(`shop-frontend local · shop-core remote (dev)`). `<cli> status`,
|
|
71
|
+
`services` and `apps` suffix remote services `☁ remote (dev)`, and
|
|
72
|
+
`<cli> graph` marks remote and hybrid nodes. See "Placement" in
|
|
73
|
+
`docs/distributions.md`.
|
|
74
|
+
- **Remote health.** A remote service is checked by the health declared for
|
|
75
|
+
its `target.env`; only when there is none does Den GET `target.url`, up when
|
|
76
|
+
the status is one of `target.expect` (a code or a list, 100–599; default
|
|
77
|
+
any 2xx). Its health row's label names the target (`dev · AWS`).
|
|
78
|
+
- **`production_envs`** in the org config: the envs that count as production
|
|
79
|
+
(default `[prod, production]`).
|
|
80
|
+
|
|
81
|
+
### Changed
|
|
82
|
+
|
|
83
|
+
- **`/api/health` rows: `url` is only ever a URL.** A shell health check's
|
|
84
|
+
command (a compose stack's `<cli> stack health …`, or any declared shell
|
|
85
|
+
check) is now in a new `check` field and `url` is null; the UI shows the
|
|
86
|
+
same tooltips as before. Clients that read the command from `url` should
|
|
87
|
+
read `check`.
|
|
88
|
+
- `/api/server-info` returns Den's `version`.
|
|
89
|
+
- **Nothing runs a command on a remote service.** `/api/service/exec`,
|
|
90
|
+
`<cli> up|down|restart`, workspace up and down, and `<cli> up`'s plan refuse
|
|
91
|
+
it (`runs in dev (AWS); nothing to start here`; a `down` succeeds with
|
|
92
|
+
nothing to stop). The MCP guard `runsLocally()` reads `runs`. Security
|
|
93
|
+
`auto_targets` excludes remote services explicitly, a remote service is
|
|
94
|
+
never scanned as if it were local, and one whose `target.env` counts as
|
|
95
|
+
production is never scanned at all.
|
|
96
|
+
- **Overrides may add placement.** `runs` and `target` are the one thing a
|
|
97
|
+
`manifests/<repo>.override.yml` may add to a service its base has.
|
|
98
|
+
- `validate` checks env names: a `runs` key or `target.env` that is not one of
|
|
99
|
+
the org's `environments` is an error.
|
|
100
|
+
- `<cli> status` keeps a hybrid repo's remote service as its own row instead
|
|
101
|
+
of rolling it into the entrypoint.
|
|
102
|
+
|
|
103
|
+
### Fixed
|
|
104
|
+
|
|
105
|
+
- **Logs of compose-stack services.** The live tail (`/api/service/taillog`,
|
|
106
|
+
so the UI's log view and `logs_tail`), log history and search
|
|
107
|
+
(`logs_search`) and `<cli> logs` now find a stack service's container,
|
|
108
|
+
`<stack>-<workspace>-<service>-1`, through the stacks naming helpers. They
|
|
109
|
+
looked only for opctl containers, so they fell back to the startup log
|
|
110
|
+
("container log unavailable") or found nothing.
|
|
111
|
+
- **`<cli> mcp` against an older web server.** A tool whose route the web
|
|
112
|
+
server predates (`stacks`, `edge_status`, a security `run_tests`) now says
|
|
113
|
+
`web server is Den <x>; <tool> needs >= <y>: run <cli> web restart`
|
|
114
|
+
instead of a bare 404; other 404s name the tool and the route.
|
|
115
|
+
- Sync never touches a dev-managed checkout: a managed entry whose path is,
|
|
116
|
+
holds or sits inside one is refused with the reason, and naming a
|
|
117
|
+
dev-managed repo says so instead of doing nothing.
|
|
118
|
+
- The What's new dialog showed every changelog bullet cut off mid-sentence.
|
|
119
|
+
- With nothing run yet, the empty output pane no longer takes 200px from the
|
|
120
|
+
Local Dev page.
|
|
121
|
+
- A security run's mode chosen on the Tests page (`api`, `full`) now reaches
|
|
122
|
+
the scan; it always ran `baseline` before.
|
|
123
|
+
|
|
124
|
+
### Security
|
|
125
|
+
|
|
126
|
+
- Dependency advisories: `npm audit fix` plus `@cursor/sdk` 1.0.23 → 1.0.40
|
|
127
|
+
(drops its `undici` 5 / `zod` 3 tree) clear every critical and high
|
|
128
|
+
advisory. Left: a `minimatch` ReDoS under `openapi-typescript` (only fix is
|
|
129
|
+
a downgrade to 6.x; it matches local config globs only) and dev-only
|
|
130
|
+
tooling (jest, eslint) moderates.
|
|
131
|
+
|
|
132
|
+
### Migrations
|
|
133
|
+
|
|
134
|
+
- None required: with no override files, manifests resolve as in 0.1.0.
|
|
135
|
+
- To let agents act through `<cli> mcp`, add `mcp.actions` to the org config.
|
|
136
|
+
- Placement needs no change: without `runs`, services keep working as
|
|
137
|
+
before. A service with an HTTP health URL, no commands, and nothing else
|
|
138
|
+
in its repo that runs here now shows as remote; add `runs: { local: local }`
|
|
139
|
+
if it is really on this machine. To
|
|
140
|
+
mark more envs as production than `prod` and `production`, set
|
|
141
|
+
`production_envs`.
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
## [0.1.0] - 2026-11-04
|
|
145
|
+
|
|
146
|
+
The first Den release: one engine for local development, tests and releases
|
|
147
|
+
across an organisation's repos, shipped as `@monster-orange/den` and used
|
|
148
|
+
through thin distributions that pin an exact version.
|
|
149
|
+
|
|
150
|
+
### Added
|
|
151
|
+
|
|
152
|
+
- **`den create <name> [dir]`** (also `npx @monster-orange/den create`)
|
|
153
|
+
scaffolds a distribution: `den.yml`, a `package.json` pinning this exact
|
|
154
|
+
Den, a `bin/<cli>` shim, a Makefile including `make/den.mk`, an org config
|
|
155
|
+
with a brand, and empty `manifests/` and `tests/pillars/`.
|
|
156
|
+
`examples/distribution/` is its output for `acme`. See
|
|
157
|
+
`docs/distributions.md`.
|
|
158
|
+
- **Den runs as an installed package.** Den's own files resolve from the
|
|
159
|
+
engine root (`node_modules/@monster-orange/den`), the distribution's from
|
|
160
|
+
its root; scripts run with Den's tsx, never through `npx` or the current
|
|
161
|
+
directory. The package ships `src/` and runs it with tsx (a dependency
|
|
162
|
+
now); CI proves it with `scripts/dist-smoke.sh`.
|
|
163
|
+
- **Org > Application > Repo > Services.** Declared applications (config
|
|
164
|
+
`applications:` or a manifest's `application:`) group repos; the Local Dev
|
|
165
|
+
graph boxes each one inside its org's frame, next to the connected groups of
|
|
166
|
+
repos that are their own application.
|
|
167
|
+
- **Security scans keep a latest record.** Every run writes
|
|
168
|
+
`reports/security/<env>/latest-<mode>.json`; the Tests page shows it, with
|
|
169
|
+
findings marked new since the previous run.
|
|
170
|
+
- **Repo suites** (`tests:` in a manifest) run from the Tests page and CLI.
|
|
171
|
+
- **Edge opt-ins**: a project CA and route certificates are opt-in; with none
|
|
172
|
+
set, the rendered edge is unchanged.
|
|
173
|
+
|
|
174
|
+
- **launchd service from a distribution.** `service/install.sh` ships in the
|
|
175
|
+
package and runs from `DEN_ROOT`; `DEN_SERVICE_LABEL` and `DEN_SERVICE_LOGS`
|
|
176
|
+
keep an existing label and log folder; `print` shows the plist.
|
|
177
|
+
|
|
178
|
+
### Migrations
|
|
179
|
+
|
|
180
|
+
From the engine this release was generalised from:
|
|
181
|
+
|
|
182
|
+
- Run Den from the package: a `bin/<cli>` shim that sets `DEN_ROOT` to the
|
|
183
|
+
distribution and execs `node_modules/@monster-orange/den/bin/den`, and a
|
|
184
|
+
Makefile that does `include node_modules/@monster-orange/den/make/den.mk`
|
|
185
|
+
(`den create` writes both; `docs/distributions.md` shows them).
|
|
186
|
+
- Add `den.yml` at the distribution root with `product: { name: <your name> }`.
|
|
187
|
+
Env vars, the config and manifest file names, the state, managed-clone and
|
|
188
|
+
workspace directories all derive from that name, so an existing install
|
|
189
|
+
keeps every on-disk and env name by naming itself as before.
|
|
190
|
+
- Workspace mode `<name>-managed` is now `managed`. Old values are still
|
|
191
|
+
read, and rewritten on the next save.
|
|
192
|
+
- The CLI command `use-<name>` is now `use-managed`.
|
|
193
|
+
- `github_org` has no default: set it in the org config.
|
|
194
|
+
- The shared local-infra repo is configuration: `graph.infra: { repo,
|
|
195
|
+
signals }`. Without it no infra edges are derived. The default-workspace
|
|
196
|
+
entry repo is `defaults.workspace.entry`.
|
|
197
|
+
- Perf suites come from the distribution (`tests/pillars/perf/<module>/test.js`)
|
|
198
|
+
or from repo manifests; Den ships none.
|
|
199
|
+
- Service and setup make targets are `<prefix>-up`, `-status`, … where the
|
|
200
|
+
prefix is `DEN_TARGET_PREFIX` (set before including `make/den.mk`; `den
|
|
201
|
+
create` sets it to the CLI name, so `make <name>-up` keeps working).
|
|
202
|
+
- `service_env` has no built-in entries: a shared-infra secrets file is
|
|
203
|
+
configured as `service_env: { <KEY>: "{repo:<infra repo>}/<path>" }`.
|
|
204
|
+
- The smoke and browser make targets have no default repo: pass `repo=<repo>`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Monster Orange
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,167 @@
|
|
|
1
1
|
# Den
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Den is a config-driven local development appliance. It starts the repos you
|
|
4
|
+
work on in dependency order, puts them behind a local HTTPS edge, gives you a
|
|
5
|
+
web UI and a CLI over all of it, and runs smoke, browser, API, journey,
|
|
6
|
+
security and performance suites against the environments you declare.
|
|
7
|
+
|
|
8
|
+
Den knows nothing about any particular organisation. Everything specific to
|
|
9
|
+
yours — product name, repos, environments, hosts, secrets backend, test
|
|
10
|
+
accounts — lives in **your distribution**, not in Den.
|
|
11
|
+
|
|
12
|
+
> **Status: 0.2.0**: `npm install @monster-orange/den`. Den is pre-1.0; each release lists the changes a distribution makes under **Migrations** in [CHANGELOG.md](CHANGELOG.md).
|
|
13
|
+
|
|
14
|
+
## Make it your own
|
|
15
|
+
|
|
16
|
+
1. **Create** a distribution named after your product:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npx @monster-orange/den create acme # → ./acme
|
|
20
|
+
cd acme && npm install
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
2. **Name** it: `den.yml` holds `product: { name: acme }`, so the CLI is
|
|
24
|
+
`./bin/acme`, env vars are `ACME_*`, state lives in `~/.acme`. Pass
|
|
25
|
+
`--cli`, `--env-prefix` or `--title` to `create`, or edit `den.yml`.
|
|
26
|
+
3. **Brand** it: `brand:` in `config/acme.yml` sets the name, tagline and
|
|
27
|
+
banner people see in the CLI and web UI.
|
|
28
|
+
4. **Point it at your repos**: set `github_org` in `config/acme.yml`, then
|
|
29
|
+
`./bin/acme register ../shop-api` (or add a manifest per repo under
|
|
30
|
+
`manifests/`).
|
|
31
|
+
5. **Run** it: `./bin/acme up`, `./bin/acme web`, `make test`.
|
|
32
|
+
|
|
33
|
+
Every field, the bin shim, the make fragment and upgrading are in
|
|
34
|
+
[docs/distributions.md](docs/distributions.md);
|
|
35
|
+
[examples/distribution/](examples/distribution) is what `create acme` writes.
|
|
36
|
+
|
|
37
|
+
## Distributions
|
|
38
|
+
|
|
39
|
+
You run Den through a small repo of your own (a _distribution_):
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
my-dev/
|
|
43
|
+
├── den.yml # who this distribution is (below)
|
|
44
|
+
├── package.json # pins an exact @monster-orange/den version
|
|
45
|
+
├── config/<name>.yml # your org config
|
|
46
|
+
├── config/environments/ # one <env>.json per environment
|
|
47
|
+
├── manifests/ # manifests for repos that don't carry their own
|
|
48
|
+
├── tests/pillars/<pillar>/ # your own suites (e.g. tests/pillars/perf/<module>/test.js)
|
|
49
|
+
├── bin/<cli> # shim: DEN_ROOT=<this dir> exec node_modules/@monster-orange/den/bin/den
|
|
50
|
+
└── Makefile # include node_modules/@monster-orange/den/make/den.mk
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`den.yml` names the product. Every runtime name derives from it:
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
product:
|
|
57
|
+
name:
|
|
58
|
+
acme # CLI "acme", env vars ACME_*, config/acme.yml,
|
|
59
|
+
# manifests .acme.yml, state ~/.acme,
|
|
60
|
+
# managed clones .acme-services/, workspaces acme-workspaces/
|
|
61
|
+
# Override any of them: cli, env_prefix, config, manifest, state_dir,
|
|
62
|
+
# services_dir, workspaces_dir
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Den's own checkout is a distribution named `den`, so in this repo the CLI is
|
|
66
|
+
`./bin/den`, the config is `config/den.yml`, and env vars are `DEN_*`.
|
|
67
|
+
|
|
68
|
+
## Repos opt in with a manifest
|
|
69
|
+
|
|
70
|
+
A repo joins by carrying a manifest at its root (`.<name>.yml`, e.g.
|
|
71
|
+
`.den.yml`) whose commands delegate to the repo's own targets. Den never
|
|
72
|
+
reaches inside a repo beyond that. When a repo has no manifest, the
|
|
73
|
+
distribution can hold one for it in `manifests/<repo>.<name>.yml`; the repo's
|
|
74
|
+
own manifest always wins.
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
# demo-api: a self-contained service. Nothing it calls, so it starts alone.
|
|
78
|
+
version: 1
|
|
79
|
+
name: demo-api
|
|
80
|
+
application: shop # the application this repo belongs to (den apps)
|
|
81
|
+
compose:
|
|
82
|
+
files: [docker-compose.yml]
|
|
83
|
+
routes:
|
|
84
|
+
api: api:8080 # https://api.demo-api.<edge domain>
|
|
85
|
+
services:
|
|
86
|
+
demo-api:
|
|
87
|
+
commands:
|
|
88
|
+
local:
|
|
89
|
+
setup: make setup
|
|
90
|
+
preflight: make test
|
|
91
|
+
# OWASP ZAP target for the security pillar (`make test-sec-api env=local`).
|
|
92
|
+
security:
|
|
93
|
+
api:
|
|
94
|
+
hosts:
|
|
95
|
+
local: ["https://api.demo-api.globex.localhost"]
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
That is `examples/demo/demo-api/.den.yml`; the other demo repos are in
|
|
99
|
+
[`examples/demo/`](examples/demo/).
|
|
100
|
+
|
|
101
|
+
## What it does
|
|
102
|
+
|
|
103
|
+
- **Workspaces.** A workspace is a set of repos. Each is either
|
|
104
|
+
_dev-managed_ (your checkout, your branch) or _managed_ (cloned by Den and
|
|
105
|
+
kept on a tracking branch).
|
|
106
|
+
- **Derived dependency graph.** Start and stop order comes from real signals in
|
|
107
|
+
each repo — SDK imports, `*_URL` env vars, IaC references, event rules,
|
|
108
|
+
readiness probes — tuned in config with `graph.aliases`, `graph.edges` and
|
|
109
|
+
an optional shared local-infra repo (`graph.infra`).
|
|
110
|
+
- **Local HTTPS edge.** One local proxy routes `https://<route>.<domain>` to
|
|
111
|
+
each service, with an optional project CA.
|
|
112
|
+
- **Test pillars.** `smoke`, `browser` (synthetic Playwright), `api`,
|
|
113
|
+
`journeys` (agent-driven), `perf` (k6), `security` (OWASP ZAP against hosts
|
|
114
|
+
you own) and `suites` (a repo's own commands).
|
|
115
|
+
- **Releases.** A release view over the repos and deploy workflows your config
|
|
116
|
+
lists.
|
|
117
|
+
- **Web UI and CLI** over the same state.
|
|
118
|
+
|
|
119
|
+
## Strategies
|
|
120
|
+
|
|
121
|
+
Concerns that vary by org are strategies selected in config, never hard-wired:
|
|
122
|
+
|
|
123
|
+
| Concern | Built-in choices | Chosen in |
|
|
124
|
+
| ---------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
125
|
+
| Secrets backend | `env`, `doppler`, `1password` | `secrets.provider` in the org config; per engineer in `config/local/user.yml`; per shell `<PREFIX>_SECRETS_PROVIDER` |
|
|
126
|
+
| Test-user tokens | `local-jwt`, `cognito`, `auth0`, `none` | `auth.provider` in `config/environments/<env>.json` |
|
|
127
|
+
|
|
128
|
+
A new secrets backend implements `SecretsProvider`
|
|
129
|
+
(`src/shared/secrets/types.ts`); a new identity provider implements a token
|
|
130
|
+
provider in `src/shared/auth/token-providers/`.
|
|
131
|
+
|
|
132
|
+
## CLI
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
den up [repo] # start the repo's derived dependency closure (-x deps only, -n dry run)
|
|
136
|
+
den down [repo] # stop it cleanly
|
|
137
|
+
den status # service health for the active workspace
|
|
138
|
+
den apps # Org > Application > Repo > Services
|
|
139
|
+
den graph [repo] # the derived dependency graph
|
|
140
|
+
den logs [repo] # tail a repo's local logs
|
|
141
|
+
den use-local [repo] # use your checkout · use-managed [repo] to switch back
|
|
142
|
+
den workspace list # workspaces (activate · deactivate · use · create · delete)
|
|
143
|
+
den run # run test suites (interactive, or with options)
|
|
144
|
+
den web # the web UI
|
|
145
|
+
den --help # everything else
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
In a distribution the command is that distribution's `cli` name.
|
|
149
|
+
|
|
150
|
+
## Developing Den
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
npm ci
|
|
154
|
+
npm run typecheck
|
|
155
|
+
npm run lint
|
|
156
|
+
npm test
|
|
157
|
+
DEN_ORG_NAMES_FILE=<patterns file> node scripts/org-name-gate.mjs
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
CI runs the same gates. The org-name gate fails the build when any file names
|
|
161
|
+
an organisation, product, host or account; its patterns are kept out of this
|
|
162
|
+
repo (a CI secret) so the list itself is never published. See
|
|
163
|
+
[CONTRIBUTING.md](CONTRIBUTING.md).
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
[MIT](LICENSE)
|
package/bin/den
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Two roots (see src/shared/paths.ts):
|
|
5
|
+
# DEN_ENGINE_ROOT Den's own package: this script's parent directory, which
|
|
6
|
+
# in a distribution is node_modules/@monster-orange/den.
|
|
7
|
+
# DEN_ROOT the distribution: the directory holding den.yml. A
|
|
8
|
+
# distribution's bin/<cli> shim sets it; in Den's own
|
|
9
|
+
# checkout (where the engine dir holds den.yml) it is set
|
|
10
|
+
# here. Otherwise it is left unset and Den walks up from
|
|
11
|
+
# the entry script to find den.yml.
|
|
12
|
+
DEN_ENGINE_ROOT="$(cd "$(dirname "$(realpath "$0")")/.." && pwd)"
|
|
13
|
+
export DEN_ENGINE_ROOT
|
|
14
|
+
if [ -z "${DEN_ROOT:-}" ] && [ -f "$DEN_ENGINE_ROOT/den.yml" ]; then
|
|
15
|
+
DEN_ROOT="$DEN_ENGINE_ROOT"
|
|
16
|
+
export DEN_ROOT
|
|
17
|
+
fi
|
|
18
|
+
export DEN_INVOKE_CWD="$PWD"
|
|
19
|
+
export OP_ACCOUNT="${OP_ACCOUNT:-example.1password.com}"
|
|
20
|
+
|
|
21
|
+
# tsx: Den's own (a checkout) or hoisted into the distribution's node_modules.
|
|
22
|
+
find_tsx() {
|
|
23
|
+
local dir="$DEN_ENGINE_ROOT"
|
|
24
|
+
while :; do
|
|
25
|
+
if [ -x "$dir/node_modules/.bin/tsx" ]; then
|
|
26
|
+
printf '%s\n' "$dir/node_modules/.bin/tsx"
|
|
27
|
+
return 0
|
|
28
|
+
fi
|
|
29
|
+
[ "$dir" = "/" ] && return 1
|
|
30
|
+
dir="$(dirname "$dir")"
|
|
31
|
+
done
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# `create` scaffolds a new distribution: it needs no den.yml, so it runs on
|
|
35
|
+
# its own entry point rather than the full CLI.
|
|
36
|
+
entry="src/ui/cli/index.ts"
|
|
37
|
+
built="dist/src/ui/cli/index.js"
|
|
38
|
+
if [ "${1:-}" = "create" ]; then
|
|
39
|
+
shift
|
|
40
|
+
entry="src/ui/cli/create-main.ts"
|
|
41
|
+
built="dist/src/ui/cli/create-main.js"
|
|
42
|
+
fi
|
|
43
|
+
# `mcp` speaks the MCP protocol on stdout: its own entry point, so nothing
|
|
44
|
+
# the full CLI prints can reach the protocol stream.
|
|
45
|
+
if [ "${1:-}" = "mcp" ]; then
|
|
46
|
+
shift
|
|
47
|
+
entry="src/ui/cli/mcp-main.ts"
|
|
48
|
+
built="dist/src/ui/cli/mcp-main.js"
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Escape hatch: force the compiled build (e.g. to test the prod artifact).
|
|
52
|
+
if [ "${DEN_USE_DIST:-}" = "1" ] && [ -f "$DEN_ENGINE_ROOT/$built" ]; then
|
|
53
|
+
exec node "$DEN_ENGINE_ROOT/$built" "$@"
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Prefer live TypeScript source (the package ships src/ and runs it with tsx).
|
|
57
|
+
# A built dist/ is gitignored and only refreshed by `npm run build`, so
|
|
58
|
+
# preferring it would silently shadow local source edits with a stale build.
|
|
59
|
+
if tsx="$(find_tsx)"; then
|
|
60
|
+
exec "$tsx" "$DEN_ENGINE_ROOT/$entry" "$@"
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
if [ -f "$DEN_ENGINE_ROOT/$built" ]; then
|
|
64
|
+
exec node "$DEN_ENGINE_ROOT/$built" "$@"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
echo "den: no runnable entrypoint: run 'npm install'" >&2
|
|
68
|
+
exit 1
|