openpalm 0.10.2 → 0.11.0-beta.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/README.md +11 -19
- package/package.json +4 -2
- package/src/commands/addon.ts +5 -4
- package/src/commands/automations.ts +63 -0
- package/src/commands/install.ts +95 -279
- package/src/commands/logs.ts +1 -1
- package/src/commands/restart.ts +5 -4
- package/src/commands/rollback.ts +4 -3
- package/src/commands/scan.ts +66 -32
- package/src/commands/service.ts +5 -4
- package/src/commands/start.ts +5 -4
- package/src/commands/status.ts +1 -1
- package/src/commands/stop.ts +2 -4
- package/src/commands/uninstall.ts +3 -5
- package/src/commands/update.ts +19 -2
- package/src/commands/validate.ts +16 -34
- package/src/install-flow.test.ts +152 -153
- package/src/lib/admin-skills/index.test.ts +70 -0
- package/src/lib/admin-skills/index.ts +113 -0
- package/src/lib/browser.ts +20 -0
- package/src/lib/cli-compose.ts +2 -20
- package/src/lib/cli-state.ts +1 -1
- package/src/lib/docker.ts +8 -214
- package/src/lib/env.ts +12 -83
- package/src/lib/io.ts +130 -0
- package/src/lib/opencode-subprocess.ts +14 -6
- package/src/lib/paths.ts +2 -2
- package/src/lib/ui-server.ts +147 -0
- package/src/main.test.ts +75 -172
- package/src/main.ts +131 -7
- package/e2e/start-wizard-server.ts +0 -59
- package/src/commands/admin.ts +0 -43
- package/src/commands/install-services.test.ts +0 -13
- package/src/commands/install-services.ts +0 -9
- package/src/commands/upgrade.ts +0 -12
- package/src/lib/embedded-assets.ts +0 -115
- package/src/lib/varlock.ts +0 -126
- package/src/setup-wizard/index.html +0 -321
- package/src/setup-wizard/server-errors.test.ts +0 -418
- package/src/setup-wizard/server-integration.test.ts +0 -511
- package/src/setup-wizard/server.test.ts +0 -508
- package/src/setup-wizard/server.ts +0 -342
- package/src/setup-wizard/wizard-renderers.js +0 -1294
- package/src/setup-wizard/wizard-state.js +0 -346
- package/src/setup-wizard/wizard-validators.js +0 -81
- package/src/setup-wizard/wizard.css +0 -1611
- package/src/setup-wizard/wizard.js +0 -613
package/README.md
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# @openpalm/cli
|
|
2
2
|
|
|
3
|
-
Bun CLI for bootstrapping and managing an OpenPalm installation. The CLI is the primary orchestrator
|
|
3
|
+
Bun CLI for bootstrapping and managing an OpenPalm installation. The CLI is the primary orchestrator — all commands operate directly against Docker Compose. Use `openpalm` to start the UI host process.
|
|
4
4
|
|
|
5
5
|
## Self-Sufficient Mode
|
|
6
6
|
|
|
7
|
-
The CLI operates directly against Docker Compose
|
|
7
|
+
The CLI operates directly against Docker Compose:
|
|
8
8
|
|
|
9
|
-
- **Install** -- creates the `~/.openpalm/` home layout, downloads assets,
|
|
9
|
+
- **Install** -- creates the `~/.openpalm/` home layout, downloads assets, spawns the setup wizard via the admin UI, writes files to their final locations, and starts core services
|
|
10
10
|
- **All lifecycle commands** -- refresh files in `~/.openpalm/` when needed, then run Docker Compose directly
|
|
11
|
-
- **Admin
|
|
12
|
-
|
|
13
|
-
The admin container is optional. Use `--with-admin` to enable the admin addon overlay in the compose file set.
|
|
11
|
+
- **Admin UI** -- start the host admin server with `openpalm` (no container required)
|
|
14
12
|
|
|
15
13
|
## Commands
|
|
16
14
|
|
|
@@ -19,12 +17,10 @@ The admin container is optional. Use `--with-admin` to enable the admin addon ov
|
|
|
19
17
|
| `openpalm install` | Bootstrap `~/.openpalm/`, download assets, run setup wizard, start core services |
|
|
20
18
|
| `openpalm uninstall` | Stop and remove the stack (preserves config and data) |
|
|
21
19
|
| `openpalm update` | Pull latest images and recreate containers |
|
|
22
|
-
| `openpalm upgrade` | Alias for `update` |
|
|
23
20
|
| `openpalm self-update` | Replace the installed CLI binary with the latest release build |
|
|
24
21
|
| `openpalm addon <enable|disable|list>` | Manage registry addons directly from the CLI |
|
|
25
|
-
| `openpalm admin <enable|disable|status>` | Manage the admin addon directly from the CLI |
|
|
26
22
|
| `openpalm start [svc...]` | Start all or named services |
|
|
27
|
-
| `openpalm
|
|
23
|
+
| `openpalm` | Start the UI host process server |
|
|
28
24
|
| `openpalm stop [svc...]` | Stop all or named services |
|
|
29
25
|
| `openpalm restart [svc...]` | Restart all or named services |
|
|
30
26
|
| `openpalm logs [svc...]` | Tail last 100 log lines |
|
|
@@ -37,14 +33,10 @@ The admin container is optional. Use `--with-admin` to enable the admin addon ov
|
|
|
37
33
|
|
|
38
34
|
`--force` skip "already installed" check and create a backup of the current `OP_HOME`, `--version TAG` install a specific ref (default: current CLI version), `--no-start` prepare files only, `--no-open` skip browser launch.
|
|
39
35
|
|
|
40
|
-
### Admin
|
|
41
|
-
|
|
42
|
-
Admin and docker-socket-proxy start only when explicitly requested:
|
|
36
|
+
### Admin commands
|
|
43
37
|
|
|
44
38
|
```bash
|
|
45
|
-
openpalm
|
|
46
|
-
openpalm admin disable # Stop and disable the admin addon
|
|
47
|
-
openpalm admin status # Show whether the admin addon is enabled
|
|
39
|
+
openpalm # Start the UI host process (binds to 127.0.0.1:3880)
|
|
48
40
|
openpalm addon enable chat # Enable a registry addon and start its services
|
|
49
41
|
openpalm addon disable chat # Stop and disable a registry addon
|
|
50
42
|
openpalm addon list # Show available addons and whether they are enabled
|
|
@@ -52,7 +44,7 @@ openpalm addon list # Show available addons and whether they are ena
|
|
|
52
44
|
|
|
53
45
|
## Setup Wizard
|
|
54
46
|
|
|
55
|
-
On first install, the CLI
|
|
47
|
+
On first install, the CLI spawns `openpalm` which serves the setup wizard via the SvelteKit admin UI at `http://localhost:3880/setup`. The wizard runs entirely in the browser and calls `performSetup()` from `@openpalm/lib` to write secrets, connection profiles, memory config, and other files to their final locations.
|
|
56
48
|
|
|
57
49
|
## Environment Variables
|
|
58
50
|
|
|
@@ -60,12 +52,12 @@ On first install, the CLI serves a setup wizard on port `8100` via `Bun.serve()`
|
|
|
60
52
|
|---|---|---|
|
|
61
53
|
| `OP_HOME` | `~/.openpalm` | Root of all OpenPalm state |
|
|
62
54
|
| `OP_WORK_DIR` | `~/openpalm` | Assistant working directory |
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
55
|
+
| `OP_HOST_UI_PORT` | `3880` | Port for the host admin server (`openpalm`) |
|
|
56
|
+
| `OP_UI_TOKEN` | (from `state/admin/token`) | Admin API auth token |
|
|
65
57
|
|
|
66
58
|
## How It Works
|
|
67
59
|
|
|
68
|
-
1. **Bootstrap** (first install) -- creates the `~/.openpalm/` tree, downloads core assets from GitHub, seeds `
|
|
60
|
+
1. **Bootstrap** (first install) -- creates the `~/.openpalm/` tree, downloads core assets from GitHub, seeds `stash/vaults/user.env` and `config/stack/stack.env`, materializes the runtime registry catalog under `state/registry/`, serves the setup wizard, writes `stack/core.compose.yml`, enables requested addons under `stack/addons/`, and starts core services via `docker compose up`
|
|
69
61
|
2. **Running stack** -- commands refresh files in `~/.openpalm/` when needed, then execute Docker Compose directly.
|
|
70
62
|
3. **Admin absent** -- all commands work identically. Admin is never required for any operation.
|
|
71
63
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openpalm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0-beta.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"description": "OpenPalm CLI — install and manage a self-hosted OpenPalm stack",
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
"test": "bun test",
|
|
18
18
|
"test:e2e": "npx playwright test",
|
|
19
19
|
"wizard:dev": "bun run src/main.ts install --no-start --force",
|
|
20
|
+
"_build_note": "Run 'bun run ui:build:tar' from repo root before any build:* target (Bun does not run prebuild hooks)",
|
|
21
|
+
"prebuild": "cd ../ui && npm run build && npm run build:tar",
|
|
20
22
|
"build": "bun build src/main.ts --compile --outfile dist/openpalm-cli",
|
|
21
23
|
"build:linux-x64": "bun build src/main.ts --compile --target=bun-linux-x64 --outfile dist/openpalm-cli-linux-x64",
|
|
22
24
|
"build:linux-arm64": "bun build src/main.ts --compile --target=bun-linux-arm64 --outfile dist/openpalm-cli-linux-arm64",
|
|
@@ -26,7 +28,7 @@
|
|
|
26
28
|
"build:windows-arm64": "bun build src/main.ts --compile --target=bun-windows-arm64 --outfile dist/openpalm-cli-windows-arm64.exe"
|
|
27
29
|
},
|
|
28
30
|
"dependencies": {
|
|
29
|
-
"@openpalm/lib": "
|
|
31
|
+
"@openpalm/lib": "0.11.0",
|
|
30
32
|
"citty": "^0.2.1",
|
|
31
33
|
"yaml": "^2.8.0"
|
|
32
34
|
}
|
package/src/commands/addon.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { defineCommand } from 'citty';
|
|
2
2
|
import {
|
|
3
|
+
buildComposeCliArgs,
|
|
3
4
|
getAddonServiceNames,
|
|
4
5
|
listAvailableAddonIds,
|
|
5
6
|
listEnabledAddonIds,
|
|
6
7
|
setAddonEnabled,
|
|
7
8
|
} from '@openpalm/lib';
|
|
8
9
|
import { ensureValidState } from '../lib/cli-state.ts';
|
|
9
|
-
import {
|
|
10
|
+
import { runComposeWithPreflight } from '../lib/cli-compose.ts';
|
|
10
11
|
import { runDockerCompose } from '../lib/docker.ts';
|
|
11
12
|
|
|
12
13
|
function requireKnownAddon(name: string): void {
|
|
@@ -35,7 +36,7 @@ export async function runAddonListAction(): Promise<void> {
|
|
|
35
36
|
export async function runAddonEnableAction(name: string): Promise<void> {
|
|
36
37
|
requireKnownAddon(name);
|
|
37
38
|
const state = ensureValidState();
|
|
38
|
-
const mutation = setAddonEnabled(state.homeDir, state.
|
|
39
|
+
const mutation = setAddonEnabled(state.homeDir, state.stackDir, name, true);
|
|
39
40
|
if (!mutation.ok) throw new Error(mutation.error);
|
|
40
41
|
|
|
41
42
|
if (!mutation.changed) {
|
|
@@ -66,7 +67,7 @@ export async function runAddonDisableAction(name: string): Promise<void> {
|
|
|
66
67
|
|
|
67
68
|
if (wasEnabled && services.length > 0) {
|
|
68
69
|
try {
|
|
69
|
-
await runDockerCompose([...
|
|
70
|
+
await runDockerCompose([...buildComposeCliArgs(state), 'stop', ...services]);
|
|
70
71
|
console.log(`Stopped services: ${services.join(', ')}`);
|
|
71
72
|
} catch (err) {
|
|
72
73
|
console.warn(
|
|
@@ -75,7 +76,7 @@ export async function runAddonDisableAction(name: string): Promise<void> {
|
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
const mutation = setAddonEnabled(state.homeDir, state.
|
|
79
|
+
const mutation = setAddonEnabled(state.homeDir, state.stackDir, name, false);
|
|
79
80
|
if (!mutation.ok) throw new Error(mutation.error);
|
|
80
81
|
|
|
81
82
|
if (!mutation.changed) {
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { defineCommand } from 'citty';
|
|
2
|
+
import { execFile } from 'node:child_process';
|
|
3
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { resolveOpenPalmHome } from '@openpalm/lib';
|
|
6
|
+
|
|
7
|
+
async function automationsCheck(): Promise<void> {
|
|
8
|
+
const home = resolveOpenPalmHome();
|
|
9
|
+
const tasksDir = join(home, 'stash', 'tasks');
|
|
10
|
+
|
|
11
|
+
if (!existsSync(tasksDir)) {
|
|
12
|
+
console.log('No tasks directory found at', tasksDir);
|
|
13
|
+
process.exit(0);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const taskFiles = readdirSync(tasksDir).filter((f) => f.endsWith('.md'));
|
|
17
|
+
if (taskFiles.length === 0) {
|
|
18
|
+
console.log('No automation tasks installed.');
|
|
19
|
+
process.exit(0);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
console.log(`Found ${taskFiles.length} automation task(s):`);
|
|
23
|
+
for (const file of taskFiles) {
|
|
24
|
+
console.log(` - ${file.replace('.md', '')}`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Check crontab for registered tasks
|
|
28
|
+
await new Promise<void>((resolve) => {
|
|
29
|
+
execFile('crontab', ['-l'], (error, stdout) => {
|
|
30
|
+
if (error) {
|
|
31
|
+
console.log('No crontab found — tasks not yet registered (assistant not started?)');
|
|
32
|
+
resolve();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const registered = taskFiles.filter((f) => stdout.includes(f.replace('.md', '')));
|
|
36
|
+
console.log(`Registered in crontab: ${registered.length}/${taskFiles.length}`);
|
|
37
|
+
if (registered.length < taskFiles.length) {
|
|
38
|
+
console.log(
|
|
39
|
+
"Run 'akm tasks sync' inside the assistant container to register remaining tasks."
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
resolve();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default defineCommand({
|
|
48
|
+
meta: {
|
|
49
|
+
name: 'automations',
|
|
50
|
+
description: 'Manage automation tasks',
|
|
51
|
+
},
|
|
52
|
+
subCommands: {
|
|
53
|
+
check: defineCommand({
|
|
54
|
+
meta: {
|
|
55
|
+
name: 'check',
|
|
56
|
+
description: 'Report automation task registration status',
|
|
57
|
+
},
|
|
58
|
+
async run() {
|
|
59
|
+
await automationsCheck();
|
|
60
|
+
},
|
|
61
|
+
}),
|
|
62
|
+
},
|
|
63
|
+
});
|