openpalm 0.9.8 → 0.9.10
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 +4 -2
- package/playwright.config.ts +16 -0
- package/src/commands/install-file.test.ts +306 -0
- package/src/commands/install-services.test.ts +12 -7
- package/src/commands/install-services.ts +1 -1
- package/src/commands/install.ts +142 -34
- package/src/commands/restart.ts +2 -35
- package/src/commands/service.ts +0 -17
- package/src/commands/start.ts +5 -43
- package/src/commands/status.ts +0 -9
- package/src/commands/stop.ts +4 -36
- package/src/commands/uninstall.ts +23 -14
- package/src/commands/update.ts +0 -9
- package/src/lib/docker.ts +25 -7
- package/src/lib/env.ts +13 -60
- package/src/lib/paths.ts +11 -1
- package/src/lib/staging.ts +3 -3
- package/src/main.test.ts +118 -80
- package/src/setup-wizard/index.html +114 -180
- package/src/setup-wizard/server-errors.test.ts +429 -0
- package/src/setup-wizard/server-integration.test.ts +511 -0
- package/src/setup-wizard/server.test.ts +6 -6
- package/src/setup-wizard/server.ts +17 -5
- package/src/setup-wizard/standalone.ts +166 -0
- package/src/setup-wizard/wizard.css +892 -299
- package/src/setup-wizard/wizard.js +1172 -559
- package/src/lib/admin.ts +0 -107
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Standalone setup wizard server — no Docker required.
|
|
4
|
+
*
|
|
5
|
+
* Starts the setup wizard HTTP server for manual testing or Playwright
|
|
6
|
+
* automation without running the full `openpalm install` flow.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* bun run packages/cli/src/setup-wizard/standalone.ts
|
|
10
|
+
* WIZARD_PORT=9100 bun run packages/cli/src/setup-wizard/standalone.ts
|
|
11
|
+
*
|
|
12
|
+
* Environment:
|
|
13
|
+
* WIZARD_PORT — Port to listen on (default: ephemeral/random)
|
|
14
|
+
* OPENPALM_CONFIG_HOME — Config dir override (default: temp dir)
|
|
15
|
+
* OPENPALM_DATA_HOME — Data dir override (default: temp dir)
|
|
16
|
+
* OPENPALM_STATE_HOME — State dir override (default: temp dir)
|
|
17
|
+
*/
|
|
18
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
19
|
+
import { tmpdir } from "node:os";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
import type { CoreAssetProvider } from "@openpalm/lib";
|
|
22
|
+
import { createSetupServer } from "./server.ts";
|
|
23
|
+
|
|
24
|
+
// ── Configuration ──────────────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
const port = Number(process.env.WIZARD_PORT) || 0;
|
|
27
|
+
const useDevDirs = !!(
|
|
28
|
+
process.env.OPENPALM_CONFIG_HOME &&
|
|
29
|
+
process.env.OPENPALM_DATA_HOME &&
|
|
30
|
+
process.env.OPENPALM_STATE_HOME
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// ── Directory Setup ────────────────────────────────────────────────────
|
|
34
|
+
|
|
35
|
+
let tempBase: string | null = null;
|
|
36
|
+
let configDir: string;
|
|
37
|
+
let dataDir: string;
|
|
38
|
+
let stateDir: string;
|
|
39
|
+
|
|
40
|
+
if (useDevDirs) {
|
|
41
|
+
// Use caller-provided directories (e.g. .dev/ paths)
|
|
42
|
+
configDir = process.env.OPENPALM_CONFIG_HOME!;
|
|
43
|
+
dataDir = process.env.OPENPALM_DATA_HOME!;
|
|
44
|
+
stateDir = process.env.OPENPALM_STATE_HOME!;
|
|
45
|
+
} else {
|
|
46
|
+
// Create isolated temp directories
|
|
47
|
+
tempBase = mkdtempSync(join(tmpdir(), "openpalm-wizard-dev-"));
|
|
48
|
+
configDir = join(tempBase, "config");
|
|
49
|
+
dataDir = join(tempBase, "data");
|
|
50
|
+
stateDir = join(tempBase, "state");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Ensure required directories exist
|
|
54
|
+
for (const dir of [
|
|
55
|
+
configDir,
|
|
56
|
+
join(configDir, "channels"),
|
|
57
|
+
join(configDir, "connections"),
|
|
58
|
+
join(configDir, "assistant"),
|
|
59
|
+
join(configDir, "automations"),
|
|
60
|
+
join(configDir, "stash"),
|
|
61
|
+
dataDir,
|
|
62
|
+
join(dataDir, "admin"),
|
|
63
|
+
join(dataDir, "memory"),
|
|
64
|
+
join(dataDir, "assistant"),
|
|
65
|
+
join(dataDir, "guardian"),
|
|
66
|
+
join(dataDir, "caddy"),
|
|
67
|
+
join(dataDir, "caddy", "data"),
|
|
68
|
+
join(dataDir, "caddy", "config"),
|
|
69
|
+
join(dataDir, "automations"),
|
|
70
|
+
join(dataDir, "opencode"),
|
|
71
|
+
stateDir,
|
|
72
|
+
join(stateDir, "artifacts"),
|
|
73
|
+
join(stateDir, "audit"),
|
|
74
|
+
join(stateDir, "artifacts", "channels"),
|
|
75
|
+
join(stateDir, "automations"),
|
|
76
|
+
join(stateDir, "opencode"),
|
|
77
|
+
]) {
|
|
78
|
+
mkdirSync(dir, { recursive: true });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Seed minimal env files so the wizard's status endpoint works
|
|
82
|
+
const stackEnvPath = join(stateDir, "artifacts", "stack.env");
|
|
83
|
+
writeFileSync(stackEnvPath, "OPENPALM_SETUP_COMPLETE=false\n");
|
|
84
|
+
|
|
85
|
+
const secretsPath = join(configDir, "secrets.env");
|
|
86
|
+
writeFileSync(
|
|
87
|
+
secretsPath,
|
|
88
|
+
[
|
|
89
|
+
"# OpenPalm Secrets (standalone wizard — dev/test)",
|
|
90
|
+
"export OPENPALM_ADMIN_TOKEN=",
|
|
91
|
+
"export ADMIN_TOKEN=",
|
|
92
|
+
"export OPENAI_API_KEY=",
|
|
93
|
+
"export OPENAI_BASE_URL=",
|
|
94
|
+
"export ANTHROPIC_API_KEY=",
|
|
95
|
+
"export GROQ_API_KEY=",
|
|
96
|
+
"export MISTRAL_API_KEY=",
|
|
97
|
+
"export GOOGLE_API_KEY=",
|
|
98
|
+
"export MEMORY_USER_ID=default_user",
|
|
99
|
+
"export MEMORY_AUTH_TOKEN=dev-wizard-token",
|
|
100
|
+
"export OWNER_NAME=",
|
|
101
|
+
"export OWNER_EMAIL=",
|
|
102
|
+
"",
|
|
103
|
+
].join("\n"),
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
// Point lib's XDG resolvers at our directories
|
|
107
|
+
process.env.OPENPALM_CONFIG_HOME = configDir;
|
|
108
|
+
process.env.OPENPALM_DATA_HOME = dataDir;
|
|
109
|
+
process.env.OPENPALM_STATE_HOME = stateDir;
|
|
110
|
+
|
|
111
|
+
// ── Stub Asset Provider ────────────────────────────────────────────────
|
|
112
|
+
// Provides minimal valid asset content so performSetup() can write config
|
|
113
|
+
// files without needing real downloaded assets.
|
|
114
|
+
|
|
115
|
+
function createStubAssetProvider(): CoreAssetProvider {
|
|
116
|
+
return {
|
|
117
|
+
coreCompose: () => "services:\n caddy:\n image: caddy:latest\n",
|
|
118
|
+
caddyfile: () =>
|
|
119
|
+
":80 {\n @denied not remote_ip 127.0.0.0/8 ::1\n respond @denied 403\n}\n",
|
|
120
|
+
ollamaCompose: () => "services:\n ollama:\n image: ollama/ollama\n",
|
|
121
|
+
adminCompose: () => "services:\n admin:\n image: openpalm/admin\n",
|
|
122
|
+
agentsMd: () => "# Agents\n",
|
|
123
|
+
opencodeConfig: () => '{"$schema":"https://opencode.ai/config.json"}\n',
|
|
124
|
+
adminOpencodeConfig: () =>
|
|
125
|
+
'{"$schema":"https://opencode.ai/config.json","plugin":["@openpalm/admin-tools"]}\n',
|
|
126
|
+
secretsSchema: () => "ADMIN_TOKEN=string\n",
|
|
127
|
+
stackSchema: () => "OPENPALM_IMAGE_TAG=string\n",
|
|
128
|
+
cleanupLogs: () => "name: cleanup-logs\nschedule: daily\n",
|
|
129
|
+
cleanupData: () => "name: cleanup-data\nschedule: weekly\n",
|
|
130
|
+
validateConfig: () => "name: validate-config\nschedule: hourly\n",
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ── Start Server ───────────────────────────────────────────────────────
|
|
135
|
+
|
|
136
|
+
const wizard = createSetupServer(port, {
|
|
137
|
+
assetProvider: createStubAssetProvider(),
|
|
138
|
+
configDir,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const url = `http://localhost:${wizard.server.port}/setup`;
|
|
142
|
+
|
|
143
|
+
console.log("");
|
|
144
|
+
console.log(" Setup wizard running (standalone mode — no Docker)");
|
|
145
|
+
console.log("");
|
|
146
|
+
console.log(` URL: ${url}`);
|
|
147
|
+
console.log(` Config dir: ${configDir}`);
|
|
148
|
+
console.log(` Data dir: ${dataDir}`);
|
|
149
|
+
console.log(` State dir: ${stateDir}`);
|
|
150
|
+
console.log("");
|
|
151
|
+
console.log(" Press Ctrl+C to stop.");
|
|
152
|
+
console.log("");
|
|
153
|
+
|
|
154
|
+
// ── Graceful Shutdown ──────────────────────────────────────────────────
|
|
155
|
+
|
|
156
|
+
function shutdown() {
|
|
157
|
+
console.log("\nStopping wizard server...");
|
|
158
|
+
wizard.stop();
|
|
159
|
+
if (tempBase) {
|
|
160
|
+
rmSync(tempBase, { recursive: true, force: true });
|
|
161
|
+
}
|
|
162
|
+
process.exit(0);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
process.on("SIGINT", shutdown);
|
|
166
|
+
process.on("SIGTERM", shutdown);
|