@dyyz1993/create-agent 1.9.0 → 2.0.1
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/package.json +23 -23
- package/src/lib/copy.ts +260 -245
- package/templates/agent/eslint.config.mjs +14 -0
- package/templates/agent/package.json +8 -1
- package/templates/agent/src/__tests__/hybrid-mode.test.ts +126 -0
- package/templates/agent/src/__tests__/server-config-security.test.ts +55 -0
- package/templates/agent/src/bun/index.ts +96 -41
- package/templates/agent/src/bun/three.d.ts +1 -0
- package/templates/agent/src/gateway/__tests__/ws-handler-token.test.ts +118 -0
- package/templates/agent/src/gateway/http-routes.ts +1 -1
- package/templates/agent/src/gateway/ws-handler.ts +84 -56
- package/templates/agent/src/mainview/__tests__/i18n/i18n.test.ts +1 -0
- package/templates/agent/src/mainview/__tests__/setup.ts +32 -29
- package/templates/agent/src/mainview/__tests__/theme-variables.test.ts +36 -0
- package/templates/agent/src/mainview/components/common/ErrorBoundary.tsx +1 -58
- package/templates/agent/src/mainview/components/common/LanguageSwitcher.tsx +1 -0
- package/templates/agent/src/mainview/components/common/ThemeToggle.tsx +1 -0
- package/templates/agent/src/mainview/components/feed/FeedPanel.tsx +232 -210
- package/templates/agent/src/mainview/components/layout/AppLayout.tsx +3 -1
- package/templates/agent/src/mainview/components/todo/TodoPanel.tsx +149 -122
- package/templates/agent/src/mainview/lib/api-client.ts +182 -172
- package/templates/agent/src/server-config.ts +34 -32
- package/templates/agent/src/server.ts +43 -54
- package/templates/agent/src/shared/handlers/__tests__/chat-concurrency.test.ts +127 -0
- package/templates/agent/src/shared/handlers/__tests__/handler-isolation.test.ts +244 -0
- package/templates/agent/src/shared/handlers/bash.ts +65 -65
- package/templates/agent/src/shared/handlers/chat.ts +189 -155
- package/templates/agent/src/shared/handlers/debug.ts +8 -0
- package/templates/agent/src/shared/handlers/feed.ts +31 -32
- package/templates/agent/src/shared/handlers/index.ts +1 -0
- package/templates/agent/src/shared/handlers/rules.ts +31 -31
- package/templates/agent/src/shared/handlers/todo.ts +31 -31
- package/templates/agent/src/shared/http-routes.ts +250 -0
- package/templates/agent/src/shared/lib/__tests__/web-server.test.ts +190 -0
- package/templates/agent/src/shared/lib/logger.ts +117 -95
- package/templates/agent/src/shared/lib/web-server.ts +128 -0
- package/templates/agent/src/shared/modules/debug.ts +8 -0
- package/templates/agent/src/shared/rpc-schema.ts +16 -3
- package/templates/agent/test-upload.txt +0 -0
- package/templates/agent/tsconfig.ipc.json +10 -0
- package/templates/agent/tsconfig.json +10 -2
- package/templates/chat/eslint.config.mjs +14 -0
- package/templates/chat/package.json +8 -1
- package/templates/chat/src/__tests__/hybrid-mode.test.ts +125 -0
- package/templates/chat/src/__tests__/server-config-security.test.ts +55 -0
- package/templates/chat/src/__tests__/server-config.test.ts +46 -44
- package/templates/chat/src/bun/index.ts +94 -44
- package/templates/chat/src/bun/three.d.ts +1 -0
- package/templates/chat/src/gateway/http-routes.ts +1 -1
- package/templates/chat/src/gateway/ws-handler.ts +84 -56
- package/templates/chat/src/mainview/App.tsx +6 -0
- package/templates/chat/src/mainview/__tests__/i18n/i18n.test.ts +1 -0
- package/templates/chat/src/mainview/__tests__/theme-variables.test.ts +36 -0
- package/templates/chat/src/mainview/components/common/LanguageSwitcher.tsx +1 -0
- package/templates/chat/src/mainview/components/common/ThemeToggle.tsx +1 -0
- package/templates/chat/src/mainview/lib/api-client.ts +183 -156
- package/templates/chat/src/mainview/lib/rpc-cache.ts +84 -0
- package/templates/chat/src/mainview/main.tsx +4 -3
- package/templates/chat/src/server-config.ts +33 -31
- package/templates/chat/src/server.ts +43 -60
- package/templates/chat/src/shared/handlers/chat.ts +196 -162
- package/templates/chat/src/shared/handlers/debug.ts +8 -0
- package/templates/chat/src/shared/handlers/index.ts +1 -0
- package/templates/chat/src/shared/http-routes.ts +250 -0
- package/templates/chat/src/shared/lib/__tests__/logger.test.ts +92 -0
- package/templates/chat/src/shared/lib/logger.ts +108 -95
- package/templates/chat/src/shared/lib/web-server.ts +128 -0
- package/templates/chat/src/shared/modules/debug.ts +8 -0
- package/templates/chat/src/shared/rpc-schema.ts +3 -2
- package/templates/chat/test-upload.txt +0 -0
- package/templates/chat/tsconfig.ipc.json +10 -0
- package/templates/general/eslint.config.mjs +14 -0
- package/templates/general/package.json +8 -1
- package/templates/general/src/__tests__/hybrid-mode.test.ts +125 -0
- package/templates/general/src/__tests__/server-config-security.test.ts +55 -0
- package/templates/general/src/__tests__/server-config.test.ts +46 -44
- package/templates/general/src/bun/index.ts +94 -44
- package/templates/general/src/bun/three.d.ts +1 -0
- package/templates/general/src/gateway/http-routes.ts +1 -1
- package/templates/general/src/gateway/ws-handler.ts +84 -56
- package/templates/general/src/mainview/__tests__/i18n/i18n.test.ts +1 -0
- package/templates/general/src/mainview/__tests__/theme-variables.test.ts +36 -0
- package/templates/general/src/mainview/components/common/LanguageSwitcher.tsx +1 -0
- package/templates/general/src/mainview/components/common/ThemeToggle.tsx +1 -0
- package/templates/general/src/mainview/components/feed/FeedPanel.tsx +241 -219
- package/templates/general/src/mainview/components/layout/AppLayout.tsx +6 -0
- package/templates/general/src/mainview/lib/api-client.ts +183 -156
- package/templates/general/src/mainview/lib/rpc-cache.ts +84 -0
- package/templates/general/src/mainview/main.tsx +4 -3
- package/templates/general/src/server-config.ts +33 -31
- package/templates/general/src/server.ts +43 -60
- package/templates/general/src/shared/handlers/__tests__/chat.test.ts +165 -160
- package/templates/general/src/shared/handlers/chat.ts +189 -155
- package/templates/general/src/shared/handlers/debug.ts +8 -0
- package/templates/general/src/shared/handlers/feed.ts +38 -40
- package/templates/general/src/shared/handlers/index.ts +1 -0
- package/templates/general/src/shared/http-routes.ts +250 -0
- package/templates/general/src/shared/lib/__tests__/logger.test.ts +92 -0
- package/templates/general/src/shared/lib/logger.ts +117 -95
- package/templates/general/src/shared/lib/web-server.ts +128 -0
- package/templates/general/src/shared/modules/debug.ts +8 -0
- package/templates/general/src/shared/rpc-schema.ts +12 -2
- package/templates/general/test-upload.txt +0 -0
- package/templates/general/tsconfig.ipc.json +10 -0
- package/templates/shared/__tests__/cors-security.test.ts +165 -0
- package/templates/shared/__tests__/file-path-security.test.ts +260 -0
- package/templates/shared/__tests__/http-routes.test.ts +174 -0
- package/templates/shared/__tests__/logger.test.ts +186 -0
- package/templates/shared/components/ErrorBoundary.tsx +58 -0
- package/templates/shared/env.d.ts +11 -0
- package/templates/shared/http-routes.ts +230 -0
- package/templates/shared/logger.ts +129 -0
- package/templates/shared/test-upload.txt +0 -0
- package/templates/shared/vite-base.config.ts +92 -0
- package/templates/shared/vitest-base.config.ts +42 -0
- package/templates/agent/bun.lock +0 -1279
- package/templates/agent/package-lock.json +0 -3670
- package/templates/chat/bun.lock +0 -1203
- package/templates/chat/package-lock.json +0 -3670
- package/templates/general/bun.lock +0 -1266
- package/templates/general/package-lock.json +0 -3670
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { appendFile, mkdir as mkdirAsync, readdir as readdirAsync, unlink as unlinkAsync, stat as statAsync } from "fs/promises";
|
|
2
|
+
import { existsSync, mkdirSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
|
|
5
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
6
|
+
|
|
7
|
+
interface LogEntry {
|
|
8
|
+
timestamp: string;
|
|
9
|
+
level: LogLevel;
|
|
10
|
+
module: string;
|
|
11
|
+
message: string;
|
|
12
|
+
data?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let _logDir: string | null = null;
|
|
16
|
+
let _maxAgeDays = 30;
|
|
17
|
+
|
|
18
|
+
export function configureLogDir(dir: string, options?: { maxAgeDays?: number }): void {
|
|
19
|
+
_logDir = dir;
|
|
20
|
+
if (options?.maxAgeDays !== undefined) {
|
|
21
|
+
_maxAgeDays = options.maxAgeDays;
|
|
22
|
+
}
|
|
23
|
+
if (!existsSync(dir)) {
|
|
24
|
+
mkdirSync(dir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
cleanOldLogs(dir, _maxAgeDays);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getLogDir(): string {
|
|
30
|
+
if (!_logDir) {
|
|
31
|
+
_logDir = "logs";
|
|
32
|
+
if (!existsSync(_logDir)) {
|
|
33
|
+
mkdirSync(_logDir, { recursive: true });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return _logDir;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function cleanOldLogs(dir: string, maxAgeDays: number): Promise<void> {
|
|
40
|
+
try {
|
|
41
|
+
if (!existsSync(dir)) return;
|
|
42
|
+
const files = await readdirAsync(dir);
|
|
43
|
+
const cutoff = Date.now() - maxAgeDays * 86400000;
|
|
44
|
+
for (const f of files) {
|
|
45
|
+
if (!f.endsWith(".log")) continue;
|
|
46
|
+
const filePath = join(dir, f);
|
|
47
|
+
const s = await statAsync(filePath);
|
|
48
|
+
if (s.mtimeMs < cutoff) {
|
|
49
|
+
await unlinkAsync(filePath);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
} catch { /* ignore */ }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function formatLine(entry: LogEntry): string {
|
|
56
|
+
const base = `[${entry.timestamp}] [${entry.level.toUpperCase()}] [${entry.module}] ${entry.message}`;
|
|
57
|
+
return entry.data ? `${base} ${JSON.stringify(entry.data)}` : base;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let writeQueue: Promise<void> = Promise.resolve();
|
|
61
|
+
|
|
62
|
+
function writeToFile(line: string): void {
|
|
63
|
+
writeQueue = writeQueue.then(async () => {
|
|
64
|
+
try {
|
|
65
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
66
|
+
const dir = getLogDir();
|
|
67
|
+
if (!existsSync(dir)) {
|
|
68
|
+
await mkdirAsync(dir, { recursive: true });
|
|
69
|
+
}
|
|
70
|
+
await appendFile(join(dir, `${date}.log`), `${line}\n`);
|
|
71
|
+
} catch { /* ignore */ }
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export class Logger {
|
|
76
|
+
private readonly module: string;
|
|
77
|
+
|
|
78
|
+
constructor(module: string) {
|
|
79
|
+
this.module = module;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
debug(message: string, data?: Record<string, unknown>): void {
|
|
83
|
+
this.write("debug", message, data);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
info(message: string, data?: Record<string, unknown>): void {
|
|
87
|
+
this.write("info", message, data);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
warn(message: string, data?: Record<string, unknown>): void {
|
|
91
|
+
this.write("warn", message, data);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
error(message: string, data?: Record<string, unknown>): void {
|
|
95
|
+
this.write("error", message, data);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private write(level: LogLevel, message: string, data?: Record<string, unknown>): void {
|
|
99
|
+
const entry: LogEntry = {
|
|
100
|
+
timestamp: new Date().toISOString(),
|
|
101
|
+
level,
|
|
102
|
+
module: this.module,
|
|
103
|
+
message,
|
|
104
|
+
...(data ? { data } : {}),
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const line = formatLine(entry);
|
|
108
|
+
|
|
109
|
+
if (level === "error") {
|
|
110
|
+
console.error(line);
|
|
111
|
+
} else if (level === "warn") {
|
|
112
|
+
console.warn(line);
|
|
113
|
+
} else {
|
|
114
|
+
console.log(line);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (process.env.NODE_ENV !== "production" || level !== "debug") {
|
|
118
|
+
writeToFile(line);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function createLogger(module: string): Logger {
|
|
124
|
+
return new Logger(module);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function flushLogs(): Promise<void> {
|
|
128
|
+
return writeQueue;
|
|
129
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { defineConfig } from "vite";
|
|
2
|
+
import react from "@vitejs/plugin-react";
|
|
3
|
+
import { resolve } from "path";
|
|
4
|
+
import { readFileSync, existsSync } from "fs";
|
|
5
|
+
export function createViteConfig(dirname: string) {
|
|
6
|
+
const PORT_FILE = resolve(dirname, ".server-port");
|
|
7
|
+
|
|
8
|
+
function getBackendPort(): number {
|
|
9
|
+
if (existsSync(PORT_FILE)) {
|
|
10
|
+
try {
|
|
11
|
+
return parseInt(readFileSync(PORT_FILE, "utf-8").trim());
|
|
12
|
+
} catch {
|
|
13
|
+
/* fall through */
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return parseInt(process.env.PORT || "3100");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const backendPort = getBackendPort();
|
|
20
|
+
|
|
21
|
+
return defineConfig({
|
|
22
|
+
plugins: [react()],
|
|
23
|
+
root: "src/mainview",
|
|
24
|
+
build: {
|
|
25
|
+
outDir: "../../dist",
|
|
26
|
+
emptyOutDir: true,
|
|
27
|
+
target: "es2020",
|
|
28
|
+
cssMinify: true,
|
|
29
|
+
minify: "esbuild",
|
|
30
|
+
reportCompressedSize: true,
|
|
31
|
+
chunkSizeWarningLimit: 1000,
|
|
32
|
+
rollupOptions: {
|
|
33
|
+
output: {
|
|
34
|
+
manualChunks: {
|
|
35
|
+
"vendor-react": ["react", "react-dom"],
|
|
36
|
+
"vendor-state": ["zustand"],
|
|
37
|
+
"vendor-i18n": ["i18next", "react-i18next"],
|
|
38
|
+
},
|
|
39
|
+
compact: true,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
css: {
|
|
44
|
+
devSourcemap: false,
|
|
45
|
+
},
|
|
46
|
+
server: {
|
|
47
|
+
port: parseInt(process.env.VITE_PORT || "5173"),
|
|
48
|
+
strictPort: false,
|
|
49
|
+
watch: {
|
|
50
|
+
ignored: [".workspace/**"],
|
|
51
|
+
},
|
|
52
|
+
proxy: {
|
|
53
|
+
"/health": {
|
|
54
|
+
target: `http://localhost:${backendPort}`,
|
|
55
|
+
changeOrigin: true,
|
|
56
|
+
},
|
|
57
|
+
"/info": {
|
|
58
|
+
target: `http://localhost:${backendPort}`,
|
|
59
|
+
changeOrigin: true,
|
|
60
|
+
},
|
|
61
|
+
"/file": {
|
|
62
|
+
target: `http://localhost:${backendPort}`,
|
|
63
|
+
changeOrigin: true,
|
|
64
|
+
},
|
|
65
|
+
"/upload": {
|
|
66
|
+
target: `http://localhost:${backendPort}`,
|
|
67
|
+
changeOrigin: true,
|
|
68
|
+
},
|
|
69
|
+
"/api": {
|
|
70
|
+
target: `http://localhost:${backendPort}`,
|
|
71
|
+
changeOrigin: true,
|
|
72
|
+
ws: true,
|
|
73
|
+
},
|
|
74
|
+
"/ws": { target: `ws://localhost:${backendPort}`, ws: true },
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
resolve: {
|
|
78
|
+
alias: {
|
|
79
|
+
"@dyyz1993/rpc-core": resolve(
|
|
80
|
+
dirname,
|
|
81
|
+
"..",
|
|
82
|
+
"..",
|
|
83
|
+
"packages",
|
|
84
|
+
"rpc-core",
|
|
85
|
+
"src",
|
|
86
|
+
"index.ts"
|
|
87
|
+
),
|
|
88
|
+
"@shared": resolve(dirname, "..", "shared"),
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { defineConfig } from "vitest/config";
|
|
2
|
+
import react from "@vitejs/plugin-react";
|
|
3
|
+
import { resolve } from "path";
|
|
4
|
+
|
|
5
|
+
export function createVitestConfig(dirname: string) {
|
|
6
|
+
return defineConfig({
|
|
7
|
+
plugins: [react()],
|
|
8
|
+
test: {
|
|
9
|
+
globals: true,
|
|
10
|
+
environment: "happy-dom",
|
|
11
|
+
setupFiles: ["./src/mainview/__tests__/setup.ts"],
|
|
12
|
+
include: [
|
|
13
|
+
"src/mainview/**/*.{test,spec}.{ts,tsx}",
|
|
14
|
+
"src/shared/**/*.{test,spec}.{ts,tsx}",
|
|
15
|
+
"src/__tests__/**/*.{test,spec}.{ts,tsx}",
|
|
16
|
+
"src/gateway/**/*.{test,spec}.{ts,tsx}",
|
|
17
|
+
"../shared/**/*.{test,spec}.{ts,tsx}",
|
|
18
|
+
],
|
|
19
|
+
css: false,
|
|
20
|
+
coverage: {
|
|
21
|
+
provider: "v8",
|
|
22
|
+
reporter: ["text", "lcov"],
|
|
23
|
+
include: ["src/mainview/**/*.{ts,tsx}"],
|
|
24
|
+
exclude: ["src/mainview/**/types/**", "src/mainview/**/*.d.ts", "src/mainview/main.tsx"],
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
resolve: {
|
|
28
|
+
alias: {
|
|
29
|
+
"@dyyz1993/rpc-core": resolve(
|
|
30
|
+
dirname,
|
|
31
|
+
"..",
|
|
32
|
+
"..",
|
|
33
|
+
"packages",
|
|
34
|
+
"rpc-core",
|
|
35
|
+
"src",
|
|
36
|
+
"index.ts"
|
|
37
|
+
),
|
|
38
|
+
"@shared": resolve(dirname, "..", "shared"),
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|