@devxcrew/core-framework 0.1.7

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 ADDED
@@ -0,0 +1,88 @@
1
+ # framework
2
+
3
+ Own reusable configuration validation and native HTTP primitives.
4
+
5
+ Use the sibling workspace layout. Shared framework and UI keep their existing public exports and
6
+ build contracts.
7
+
8
+ ## Run
9
+
10
+ Use Node 26.10 or newer and the package manifest requirements. Clone the sibling tools and
11
+ mcp-governance repositories along with this repository.
12
+
13
+ ```powershell
14
+ npm install
15
+ npm run check
16
+ ```
17
+
18
+ Cxsun runs npm run build:framework using its compiler to build this package.
19
+
20
+ ## Repository records
21
+
22
+ - `AGENTS.md`: repository instructions and ownership rules.
23
+ - `agent/SKILLS.md`: repository capabilities.
24
+ - `agent/TASK.md`: current task and status.
25
+ - `agent/PLAN.md`: next steps.
26
+ - `agent/CHANGELOG.md`: versioned changes and validation results.
27
+
28
+ ## Shared guidance
29
+
30
+ Retrieve shared documentation and rules only from `https://mcp.codexsun.com/mcp` using `npm run mcp:connect`.
31
+ A successful authenticated connection is required before repository work. Stop and report connection failures.
32
+ Do not use local guides or cached instructions as fallback. Instruction retrieval does not authorize actions.
33
+
34
+ Retrieve shared documentation and rules only from `https://mcp.codexsun.com/mcp` using `npm run mcp:connect`.
35
+ A successful authenticated connection is required before repository work. Stop and report connection failures.
36
+ Do not use local guides or cached instructions as fallback. Instruction retrieval does not authorize actions.
37
+
38
+ Configure these values with `.env.example`:
39
+
40
+ - `MCP_SERVER_URL`
41
+ - `MCP_SERVER_SECRET`
42
+ - `APP_ID`
43
+ - `APP_USER`
44
+
45
+ Keep the secret in ignored `.env` files.
46
+
47
+ ```powershell
48
+ npm run mcp:connect
49
+ npm run mcp:verify
50
+ ```
51
+
52
+ Use `mcp:connect` to retrieve instructions. Use `mcp:verify` for a strict connection test.
53
+ Connection failures do not block application work. Editor registration uses the central connection
54
+ template and depends on the editor.
55
+
56
+ ## Maintenance
57
+
58
+ ```powershell
59
+ npm run version-bump -- --dry-run
60
+ npm run version-bump -- --title "Release title" --note "Change details"
61
+ npm run check:versions
62
+ npm run fix:line-endings
63
+ npm run lines:check
64
+ npm run github:now -- --dry-run
65
+ ```
66
+
67
+ Version bumps align `package.json`, `package-lock.json`, and `agent/CHANGELOG.md`. Record changes
68
+ and validation before committing.
69
+
70
+ Commit subjects use `#<patch> - <release title>`. For example:
71
+ `#5 - Central governance and repository agent layout`.
72
+
73
+ Review the changed files before an authorized `npm run github:now`. Do not bump again when the
74
+ release version is already prepared.
75
+
76
+ ## Tools source and publication
77
+
78
+ Workspace maintenance delegates to `shared/tools`. The installed npm package remains pinned at
79
+ `0.1.3` until agent changelog support is published.
80
+
81
+ GitHub source releases use `github:now`. Npm publication requires separate authorization.
82
+
83
+ ## npm package
84
+
85
+ Framework publishes compiled ESM JavaScript and TypeScript declarations. Run npm run build before local development consumption.
86
+
87
+ Run `npm run release:check`, then `npm publish --access public` from this repository.
88
+ Only public exports are supported. App manifests use npm versions.
@@ -0,0 +1,8 @@
1
+ import { type RequestListener } from "node:http";
2
+ import type { ApplicationConfig } from "../runtime/config.js";
3
+ export interface ApplicationServerOptions {
4
+ config: ApplicationConfig;
5
+ frontendDirectory: string;
6
+ developmentHandler?: RequestListener;
7
+ }
8
+ export declare function createApplicationServer(options: ApplicationServerOptions): import("node:http").Server<typeof import("node:http").IncomingMessage, typeof import("node:http").ServerResponse>;
@@ -0,0 +1,63 @@
1
+ import { createServer } from "node:http";
2
+ import { readFile } from "node:fs/promises";
3
+ import { extname, resolve, sep } from "node:path";
4
+ const contentTypes = {
5
+ ".html": "text/html; charset=utf-8",
6
+ ".js": "text/javascript; charset=utf-8",
7
+ ".css": "text/css; charset=utf-8",
8
+ ".json": "application/json",
9
+ ".svg": "image/svg+xml",
10
+ ".png": "image/png",
11
+ ".ico": "image/x-icon",
12
+ ".woff2": "font/woff2",
13
+ };
14
+ export function createApplicationServer(options) {
15
+ return createServer((request, response) => {
16
+ if (options.developmentHandler)
17
+ return options.developmentHandler(request, response);
18
+ void serveFrontend(options.frontendDirectory, request.url || "/", request.method || "GET", response);
19
+ });
20
+ }
21
+ async function serveFrontend(root, requestUrl, method, response) {
22
+ if (method !== "GET" && method !== "HEAD") {
23
+ response.writeHead(405, { Allow: "GET, HEAD" });
24
+ response.end();
25
+ return;
26
+ }
27
+ let pathname;
28
+ try {
29
+ pathname = decodeURIComponent(new URL(requestUrl, "http://localhost").pathname);
30
+ }
31
+ catch {
32
+ response.writeHead(400);
33
+ response.end("Invalid URL");
34
+ return;
35
+ }
36
+ if (pathname === "/api" || pathname.startsWith("/api/")) {
37
+ response.writeHead(404);
38
+ response.end("No backend APIs are configured.");
39
+ return;
40
+ }
41
+ const resolvedRoot = resolve(root);
42
+ const file = resolve(root, `.${pathname}`);
43
+ if ((file !== resolvedRoot && !file.startsWith(`${resolvedRoot}${sep}`)) ||
44
+ pathname.includes("\\")) {
45
+ response.writeHead(403);
46
+ response.end("Forbidden");
47
+ return;
48
+ }
49
+ const target = extname(pathname) ? file : resolve(root, "index.html");
50
+ try {
51
+ const content = await readFile(target);
52
+ response.writeHead(200, {
53
+ "Content-Type": contentTypes[extname(target)] || "application/octet-stream",
54
+ "Cache-Control": "no-cache",
55
+ });
56
+ response.end(method === "HEAD" ? undefined : content);
57
+ }
58
+ catch (error) {
59
+ const missing = error.code === "ENOENT";
60
+ response.writeHead(missing ? 404 : 500);
61
+ response.end(missing ? "Not found" : "Unable to load frontend");
62
+ }
63
+ }
@@ -0,0 +1,2 @@
1
+ export { readApplicationConfig, type ApplicationConfig, } from "./runtime/config.js";
2
+ export { createApplicationServer, type ApplicationServerOptions, } from "./http/server.js";
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { readApplicationConfig, } from "./runtime/config.js";
2
+ export { createApplicationServer, } from "./http/server.js";
@@ -0,0 +1,8 @@
1
+ export interface ApplicationConfig {
2
+ name: string;
3
+ port: number;
4
+ url: string;
5
+ host: string;
6
+ mode: "development" | "production";
7
+ }
8
+ export declare function readApplicationConfig(env: Record<string, string | undefined>): ApplicationConfig;
@@ -0,0 +1,33 @@
1
+ export function readApplicationConfig(env) {
2
+ const name = required(env, "APP_NAME");
3
+ const portValue = required(env, "APP_PORT");
4
+ const port = Number(portValue);
5
+ if (!/^\d+$/.test(portValue) || port < 1 || port > 65535)
6
+ throw new Error("APP_PORT must be an integer between 1 and 65535.");
7
+ const mode = required(env, "APP_MODE");
8
+ if (mode !== "development" && mode !== "production")
9
+ throw new Error("APP_MODE must be development or production.");
10
+ const url = new URL(required(env, "APP_URL"));
11
+ if (!["http:", "https:"].includes(url.protocol) ||
12
+ url.username ||
13
+ url.password ||
14
+ url.pathname !== "/" ||
15
+ url.search ||
16
+ url.hash)
17
+ throw new Error("APP_URL must be an HTTP origin without credentials or a path.");
18
+ if (Number(url.port || (url.protocol === "https:" ? 443 : 80)) !== port)
19
+ throw new Error("APP_URL must use APP_PORT.");
20
+ return {
21
+ name,
22
+ port,
23
+ url: url.origin,
24
+ host: env.APP_HOST?.trim() || url.hostname,
25
+ mode,
26
+ };
27
+ }
28
+ function required(env, key) {
29
+ const value = env[key]?.trim();
30
+ if (!value)
31
+ throw new Error(`${key} is required.`);
32
+ return value;
33
+ }
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@devxcrew/core-framework",
3
+ "version": "0.1.7",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "default": "./dist/index.js"
9
+ }
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "engines": {
16
+ "node": ">=26.10.0"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/devxcrew/framework.git"
21
+ },
22
+ "devDependencies": {
23
+ "@devxcrew/tools": "0.1.3",
24
+ "@types/node": "^26.0.0",
25
+ "typescript": "6.0.3"
26
+ },
27
+ "scripts": {
28
+ "github:now": "node ../../shared/mcp-governance/client/repository.mjs github:now",
29
+ "version:update": "node ../../shared/mcp-governance/client/repository.mjs version:bump",
30
+ "fix:line-endings": "node ../../shared/mcp-governance/client/repository.mjs lines:fix",
31
+ "check:versions": "node ../../shared/mcp-governance/client/repository.mjs check:versions",
32
+ "version:show": "node ../../shared/mcp-governance/client/repository.mjs version:show",
33
+ "version:bump": "node ../../shared/mcp-governance/client/repository.mjs version:bump",
34
+ "changelog:append": "node ../../shared/mcp-governance/client/repository.mjs changelog:append",
35
+ "changelog:show": "node ../../shared/mcp-governance/client/repository.mjs changelog:show",
36
+ "tools:lines:fix": "node ../../shared/mcp-governance/client/repository.mjs lines:fix",
37
+ "lines:check": "node ../../shared/mcp-governance/client/repository.mjs lines:check",
38
+ "tools:check": "devxcrew-tools dependencies:order && node ../../shared/mcp-governance/client/repository.mjs check:versions && devxcrew-tools lines:check",
39
+ "check": "npm run tools:check",
40
+ "mcp:connect": "node agent/connect.mjs",
41
+ "mcp:verify": "node agent/connect.mjs --strict",
42
+ "version-bump": "node ../../shared/mcp-governance/client/repository.mjs version:bump",
43
+ "prepublishOnly": "npm run release:check",
44
+ "build": "tsc -p tsconfig.json",
45
+ "prepack": "npm run build",
46
+ "release:check": "npm run check && npm run build && npm pack --dry-run --ignore-scripts"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public",
50
+ "registry": "https://registry.npmjs.org/"
51
+ }
52
+ }