happy2 0.0.16 → 0.0.17
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/Dockerfile +30 -0
- package/README.md +170 -0
- package/deploy/config.yaml +56 -0
- package/deploy/happy2-server.yaml +140 -0
- package/deploy/happy2-web.yaml +87 -0
- package/package.json +3 -2
- package/packages/happy2-server/README.md +70 -15
- package/packages/happy2-server/dist/backend.d.ts +12 -0
- package/packages/happy2-server/dist/backend.d.ts.map +1 -0
- package/packages/happy2-server/dist/backend.js +48 -0
- package/packages/happy2-server/dist/backend.js.map +1 -0
- package/packages/happy2-server/dist/cli.js +6 -25
- package/packages/happy2-server/dist/cli.js.map +1 -1
- package/packages/happy2-server/dist/index.d.ts +2 -0
- package/packages/happy2-server/dist/index.d.ts.map +1 -1
- package/packages/happy2-server/dist/index.js +2 -0
- package/packages/happy2-server/dist/index.js.map +1 -1
- package/packages/happy2-server/dist/modules/agents/daemon.d.ts +4 -0
- package/packages/happy2-server/dist/modules/agents/daemon.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agents/daemon.js +40 -0
- package/packages/happy2-server/dist/modules/agents/daemon.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/defaults.d.ts +4 -4
- package/packages/happy2-server/dist/modules/config/defaults.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/config/defaults.js +8 -8
- package/packages/happy2-server/dist/modules/config/defaults.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/loader.d.ts +2 -2
- package/packages/happy2-server/dist/modules/config/loader.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/config/loader.js +83 -73
- package/packages/happy2-server/dist/modules/config/loader.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/loader.test.js +35 -0
- package/packages/happy2-server/dist/modules/config/loader.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/runtime.d.ts +1 -1
- package/packages/happy2-server/dist/modules/config/runtime.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/config/runtime.js +17 -4
- package/packages/happy2-server/dist/modules/config/runtime.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/runtime.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/config/runtime.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/config/runtime.test.js +99 -0
- package/packages/happy2-server/dist/modules/config/runtime.test.js.map +1 -0
- package/packages/happy2-server/dist/runner.js +29 -12
- package/packages/happy2-server/dist/runner.js.map +1 -1
- package/packages/happy2-server/dist/runnerCommand.d.ts +21 -0
- package/packages/happy2-server/dist/runnerCommand.d.ts.map +1 -0
- package/packages/happy2-server/dist/runnerCommand.js +97 -0
- package/packages/happy2-server/dist/runnerCommand.js.map +1 -0
- package/packages/happy2-server/dist/runnerCommand.test.d.ts +2 -0
- package/packages/happy2-server/dist/runnerCommand.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/runnerCommand.test.js +59 -0
- package/packages/happy2-server/dist/runnerCommand.test.js.map +1 -0
- package/packages/happy2-server/dist/standalone.d.ts +2 -5
- package/packages/happy2-server/dist/standalone.d.ts.map +1 -1
- package/packages/happy2-server/dist/standalone.js +14 -65
- package/packages/happy2-server/dist/standalone.js.map +1 -1
- package/packages/happy2-server/dist/web/assets/index-B51jYSrY.css +2 -0
- package/packages/happy2-server/dist/web/assets/index-szUjvBO1.js +39 -0
- package/packages/happy2-server/dist/web/index.html +2 -2
- package/packages/happy2-server/dist/web.d.ts +12 -0
- package/packages/happy2-server/dist/web.d.ts.map +1 -0
- package/packages/happy2-server/dist/web.js +89 -0
- package/packages/happy2-server/dist/web.js.map +1 -0
- package/packages/happy2-server/happy2.example.toml +3 -5
- package/packages/happy2-server/Dockerfile +0 -18
- package/packages/happy2-server/dist/web/assets/index-BxtJtZpt.js +0 -39
- package/packages/happy2-server/dist/web/assets/index-m8C1tSYV.css +0 -2
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
background: #131217;
|
|
14
14
|
}
|
|
15
15
|
</style>
|
|
16
|
-
<script type="module" crossorigin src="/assets/index-
|
|
17
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
16
|
+
<script type="module" crossorigin src="/assets/index-szUjvBO1.js"></script>
|
|
17
|
+
<link rel="stylesheet" crossorigin href="/assets/index-B51jYSrY.css">
|
|
18
18
|
</head>
|
|
19
19
|
<body>
|
|
20
20
|
<div id="root"></div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RunningHappy2 } from "./backend.js";
|
|
2
|
+
export interface WebOptions {
|
|
3
|
+
backendUrl: string;
|
|
4
|
+
host?: string;
|
|
5
|
+
logger?: boolean;
|
|
6
|
+
port?: number;
|
|
7
|
+
trustedProxyHops?: number;
|
|
8
|
+
webRoot?: string;
|
|
9
|
+
}
|
|
10
|
+
/** Serves the Happy (2) SPA and proxies its versioned API to a separate backend origin. */
|
|
11
|
+
export declare function startWebHappy2(options: WebOptions): Promise<RunningHappy2>;
|
|
12
|
+
//# sourceMappingURL=web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../sources/web.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,UAAU;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2FAA2F;AAC3F,wBAAsB,cAAc,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,CAgEhF"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import Fastify from "fastify";
|
|
4
|
+
import proxy from "@fastify/http-proxy";
|
|
5
|
+
import staticFiles from "@fastify/static";
|
|
6
|
+
/** Serves the Happy (2) SPA and proxies its versioned API to a separate backend origin. */
|
|
7
|
+
export async function startWebHappy2(options) {
|
|
8
|
+
const backendUrl = normalizedBackendUrl(options.backendUrl);
|
|
9
|
+
const webRoot = options.webRoot ?? join(import.meta.dirname, "web");
|
|
10
|
+
await access(join(webRoot, "index.html"));
|
|
11
|
+
const gateway = Fastify({
|
|
12
|
+
logger: options.logger ?? true,
|
|
13
|
+
trustProxy: options.trustedProxyHops ?? 0,
|
|
14
|
+
});
|
|
15
|
+
try {
|
|
16
|
+
await gateway.register(proxy, {
|
|
17
|
+
upstream: backendUrl,
|
|
18
|
+
prefix: "/v0",
|
|
19
|
+
rewritePrefix: "/v0",
|
|
20
|
+
httpMethods: ["GET", "POST"],
|
|
21
|
+
replyOptions: {
|
|
22
|
+
rewriteRequestHeaders: (request, headers) => {
|
|
23
|
+
const forwarded = { ...headers };
|
|
24
|
+
delete forwarded["x-forwarded-host"];
|
|
25
|
+
return {
|
|
26
|
+
...forwarded,
|
|
27
|
+
"x-forwarded-for": request.ip,
|
|
28
|
+
"x-forwarded-proto": request.protocol,
|
|
29
|
+
...(request.host ? { "x-forwarded-host": request.host } : {}),
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
await gateway.register(staticFiles, {
|
|
35
|
+
root: webRoot,
|
|
36
|
+
wildcard: false,
|
|
37
|
+
index: "index.html",
|
|
38
|
+
});
|
|
39
|
+
gateway.setNotFoundHandler((request, reply) => {
|
|
40
|
+
if ((request.method === "GET" || request.method === "HEAD") &&
|
|
41
|
+
!request.url.startsWith("/v0") &&
|
|
42
|
+
request.headers.accept?.includes("text/html")) {
|
|
43
|
+
return reply.type("text/html; charset=utf-8").sendFile("index.html");
|
|
44
|
+
}
|
|
45
|
+
return reply.code(404).send({ error: "not_found" });
|
|
46
|
+
});
|
|
47
|
+
const url = await gateway.listen({
|
|
48
|
+
host: options.host ?? "127.0.0.1",
|
|
49
|
+
port: options.port ?? 3000,
|
|
50
|
+
});
|
|
51
|
+
let closed = false;
|
|
52
|
+
const close = async () => {
|
|
53
|
+
if (closed)
|
|
54
|
+
return;
|
|
55
|
+
closed = true;
|
|
56
|
+
await gateway.close();
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
url,
|
|
60
|
+
close,
|
|
61
|
+
async [Symbol.asyncDispose]() {
|
|
62
|
+
await close();
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
await gateway.close().catch(() => undefined);
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function normalizedBackendUrl(value) {
|
|
72
|
+
let url;
|
|
73
|
+
try {
|
|
74
|
+
url = new URL(value);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
throw new Error("Happy (2) web backend URL must be an absolute HTTP(S) URL.");
|
|
78
|
+
}
|
|
79
|
+
if ((url.protocol !== "http:" && url.protocol !== "https:") ||
|
|
80
|
+
url.username ||
|
|
81
|
+
url.password ||
|
|
82
|
+
url.pathname !== "/" ||
|
|
83
|
+
url.search ||
|
|
84
|
+
url.hash) {
|
|
85
|
+
throw new Error("Happy (2) web backend URL must be an HTTP(S) origin without credentials, path, query, or fragment.");
|
|
86
|
+
}
|
|
87
|
+
return url.origin;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../sources/web.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,9 @@ public_url = "http://127.0.0.1:3000"
|
|
|
10
10
|
trusted_proxy_hops = 0
|
|
11
11
|
|
|
12
12
|
[plugins]
|
|
13
|
+
# Immutable installed package snapshots live here. Keep this persistent so a
|
|
14
|
+
# bundled plugin continues to run until an explicit upgrade replaces it.
|
|
15
|
+
directory = "plugins"
|
|
13
16
|
# Dedicated capability-only listener reached by plugin containers through the
|
|
14
17
|
# happy2.host.internal container-host mapping.
|
|
15
18
|
# The cross-platform host-gateway path requires a non-loopback bind. Firewall
|
|
@@ -56,11 +59,6 @@ malware_scan_timeout_seconds = 120
|
|
|
56
59
|
# "deny" quarantines files when the scanner is unavailable; "allow" fails open.
|
|
57
60
|
malware_scan_failure_mode = "deny"
|
|
58
61
|
|
|
59
|
-
[plugins]
|
|
60
|
-
# Immutable installed package snapshots live here. Keep this persistent so a
|
|
61
|
-
# bundled plugin continues to run until an explicit upgrade replaces it.
|
|
62
|
-
directory = "plugins"
|
|
63
|
-
|
|
64
62
|
[security]
|
|
65
63
|
integration_secret_env = "HAPPY2_INTEGRATION_SECRET"
|
|
66
64
|
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# Build from the repository root:
|
|
2
|
-
# docker build -f packages/happy2-server/Dockerfile -t slopus/happy2 .
|
|
3
|
-
FROM node:22-bookworm-slim AS build
|
|
4
|
-
WORKDIR /workspace
|
|
5
|
-
RUN corepack enable
|
|
6
|
-
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
|
7
|
-
COPY packages/happy2-server/package.json packages/happy2-server/package.json
|
|
8
|
-
RUN pnpm install --frozen-lockfile
|
|
9
|
-
COPY packages/happy2-server packages/happy2-server
|
|
10
|
-
RUN pnpm --filter happy2-server build:server \
|
|
11
|
-
&& pnpm --filter happy2-server --prod deploy /app
|
|
12
|
-
|
|
13
|
-
FROM node:22-bookworm-slim
|
|
14
|
-
ENV NODE_ENV=production
|
|
15
|
-
WORKDIR /app
|
|
16
|
-
COPY --from=build /app ./
|
|
17
|
-
EXPOSE 3000
|
|
18
|
-
ENTRYPOINT ["node", "dist/cli.js"]
|