openpalm 0.10.2 → 0.11.0-beta.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/README.md +11 -19
- package/package.json +13 -3
- package/e2e/start-wizard-server.ts +0 -59
- package/playwright.config.ts +0 -16
- package/src/commands/addon.ts +0 -130
- 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/install.ts +0 -487
- package/src/commands/logs.ts +0 -25
- package/src/commands/restart.ts +0 -36
- package/src/commands/rollback.ts +0 -43
- package/src/commands/scan.ts +0 -47
- package/src/commands/self-update.ts +0 -148
- package/src/commands/service.ts +0 -75
- package/src/commands/start.ts +0 -39
- package/src/commands/status.ts +0 -14
- package/src/commands/stop.ts +0 -36
- package/src/commands/uninstall.ts +0 -45
- package/src/commands/update.ts +0 -25
- package/src/commands/upgrade.ts +0 -12
- package/src/commands/validate.ts +0 -46
- package/src/install-flow.test.ts +0 -387
- package/src/lib/cli-compose.ts +0 -78
- package/src/lib/cli-state.ts +0 -26
- package/src/lib/docker.ts +0 -249
- package/src/lib/embedded-assets.ts +0 -115
- package/src/lib/env.ts +0 -130
- package/src/lib/host-info.ts +0 -47
- package/src/lib/opencode-subprocess.ts +0 -113
- package/src/lib/paths.ts +0 -31
- package/src/lib/varlock.ts +0 -126
- package/src/main.test.ts +0 -715
- package/src/main.ts +0 -48
- 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.10
|
|
3
|
+
"version": "0.11.0-beta.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"description": "OpenPalm CLI — install and manage a self-hosted OpenPalm stack",
|
|
@@ -12,11 +12,18 @@
|
|
|
12
12
|
"bin": {
|
|
13
13
|
"openpalm": "./bin/openpalm.js"
|
|
14
14
|
},
|
|
15
|
+
"files": [
|
|
16
|
+
"bin",
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
15
20
|
"scripts": {
|
|
16
21
|
"start": "bun run src/main.ts",
|
|
17
22
|
"test": "bun test",
|
|
18
23
|
"test:e2e": "npx playwright test",
|
|
19
|
-
"wizard:
|
|
24
|
+
"wizard:local": "bun run src/main.ts install --no-start --force",
|
|
25
|
+
"_build_note": "CI runs 'bun run ui:build:tar' from repo root before any build:* target. The prebuild hook below is npm-only; Bun does not run lifecycle hooks.",
|
|
26
|
+
"prebuild": "cd ../ui && npm run build && npm run build:tar",
|
|
20
27
|
"build": "bun build src/main.ts --compile --outfile dist/openpalm-cli",
|
|
21
28
|
"build:linux-x64": "bun build src/main.ts --compile --target=bun-linux-x64 --outfile dist/openpalm-cli-linux-x64",
|
|
22
29
|
"build:linux-arm64": "bun build src/main.ts --compile --target=bun-linux-arm64 --outfile dist/openpalm-cli-linux-arm64",
|
|
@@ -25,8 +32,11 @@
|
|
|
25
32
|
"build:windows-x64": "bun build src/main.ts --compile --target=bun-windows-x64 --outfile dist/openpalm-cli-windows-x64.exe",
|
|
26
33
|
"build:windows-arm64": "bun build src/main.ts --compile --target=bun-windows-arm64 --outfile dist/openpalm-cli-windows-arm64.exe"
|
|
27
34
|
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"bun": ">=1.0.0"
|
|
37
|
+
},
|
|
28
38
|
"dependencies": {
|
|
29
|
-
"@openpalm/lib": ">=0.
|
|
39
|
+
"@openpalm/lib": ">=0.11.0-beta.9 <1.0.0",
|
|
30
40
|
"citty": "^0.2.1",
|
|
31
41
|
"yaml": "^2.8.0"
|
|
32
42
|
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bun-only launcher for the CLI setup wizard server.
|
|
3
|
-
*
|
|
4
|
-
* Called from Playwright tests as a child process:
|
|
5
|
-
* bun run packages/cli/e2e/start-wizard-server.ts <port>
|
|
6
|
-
*
|
|
7
|
-
* Starts the wizard server on the given port with a temp config directory
|
|
8
|
-
* so tests do not affect real dev state. Prints "WIZARD_READY:<port>" to
|
|
9
|
-
* stdout when listening, which the Playwright test waits for.
|
|
10
|
-
*/
|
|
11
|
-
import { createSetupServer } from "../src/setup-wizard/server.ts";
|
|
12
|
-
import { mkdirSync, writeFileSync } from "node:fs";
|
|
13
|
-
|
|
14
|
-
const port = parseInt(Bun.argv[2] || "18100", 10);
|
|
15
|
-
const tmpBase = `/tmp/openpalm-wizard-test-${port}`;
|
|
16
|
-
|
|
17
|
-
// Create minimal directory structure so the server can start.
|
|
18
|
-
// API endpoints that need real files are mocked at the browser level
|
|
19
|
-
// by Playwright's page.route(), so these dirs just prevent crashes.
|
|
20
|
-
mkdirSync(`${tmpBase}/config`, { recursive: true });
|
|
21
|
-
mkdirSync(`${tmpBase}/config/automations`, { recursive: true });
|
|
22
|
-
mkdirSync(`${tmpBase}/data`, { recursive: true });
|
|
23
|
-
mkdirSync(`${tmpBase}/data/assistant`, { recursive: true });
|
|
24
|
-
mkdirSync(`${tmpBase}/registry/automations`, { recursive: true });
|
|
25
|
-
mkdirSync(`${tmpBase}/stack`, { recursive: true });
|
|
26
|
-
mkdirSync(`${tmpBase}/vault/stack`, { recursive: true });
|
|
27
|
-
mkdirSync(`${tmpBase}/vault/user`, { recursive: true });
|
|
28
|
-
|
|
29
|
-
writeFileSync(`${tmpBase}/vault/stack/stack.env`, "OP_SETUP_COMPLETE=false\n");
|
|
30
|
-
writeFileSync(`${tmpBase}/vault/user/user.env`, "# test\n");
|
|
31
|
-
|
|
32
|
-
// Seed minimal asset files so performSetup() can read them if invoked
|
|
33
|
-
writeFileSync(`${tmpBase}/stack/core.compose.yml`, "services:\n admin:\n image: admin:latest\n");
|
|
34
|
-
writeFileSync(`${tmpBase}/data/assistant/opencode.jsonc`, '{"$schema":"https://opencode.ai/config.json"}\n');
|
|
35
|
-
writeFileSync(`${tmpBase}/data/assistant/AGENTS.md`, "# Agents\n");
|
|
36
|
-
writeFileSync(`${tmpBase}/vault/user/user.env.schema`, "OP_ADMIN_TOKEN=string\n");
|
|
37
|
-
writeFileSync(`${tmpBase}/vault/stack/stack.env.schema`, "OP_IMAGE_TAG=string\n");
|
|
38
|
-
writeFileSync(`${tmpBase}/registry/automations/cleanup-logs.yml`, "name: cleanup-logs\nschedule: daily\n");
|
|
39
|
-
writeFileSync(`${tmpBase}/registry/automations/cleanup-data.yml`, "name: cleanup-data\nschedule: weekly\n");
|
|
40
|
-
writeFileSync(`${tmpBase}/registry/automations/validate-config.yml`, "name: validate-config\nschedule: hourly\n");
|
|
41
|
-
|
|
42
|
-
// Override state/config home so the server doesn't touch real dirs.
|
|
43
|
-
process.env.OP_HOME = tmpBase;
|
|
44
|
-
|
|
45
|
-
const { server } = createSetupServer(port, {
|
|
46
|
-
configDir: `${tmpBase}/config`,
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
console.log(`WIZARD_READY:${port}`);
|
|
50
|
-
|
|
51
|
-
// Keep alive until killed
|
|
52
|
-
process.on("SIGTERM", () => {
|
|
53
|
-
server.stop();
|
|
54
|
-
process.exit(0);
|
|
55
|
-
});
|
|
56
|
-
process.on("SIGINT", () => {
|
|
57
|
-
server.stop();
|
|
58
|
-
process.exit(0);
|
|
59
|
-
});
|
package/playwright.config.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from '@playwright/test';
|
|
2
|
-
|
|
3
|
-
const WIZARD_PORT = 18200;
|
|
4
|
-
|
|
5
|
-
export default defineConfig({
|
|
6
|
-
testDir: 'e2e',
|
|
7
|
-
webServer: {
|
|
8
|
-
command: `bun run e2e/start-wizard-server.ts ${WIZARD_PORT}`,
|
|
9
|
-
port: WIZARD_PORT,
|
|
10
|
-
stdout: 'pipe',
|
|
11
|
-
reuseExistingServer: !process.env.CI,
|
|
12
|
-
},
|
|
13
|
-
use: {
|
|
14
|
-
baseURL: `http://localhost:${WIZARD_PORT}`,
|
|
15
|
-
},
|
|
16
|
-
});
|
package/src/commands/addon.ts
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { defineCommand } from 'citty';
|
|
2
|
-
import {
|
|
3
|
-
getAddonServiceNames,
|
|
4
|
-
listAvailableAddonIds,
|
|
5
|
-
listEnabledAddonIds,
|
|
6
|
-
setAddonEnabled,
|
|
7
|
-
} from '@openpalm/lib';
|
|
8
|
-
import { ensureValidState } from '../lib/cli-state.ts';
|
|
9
|
-
import { fullComposeArgs, runComposeWithPreflight } from '../lib/cli-compose.ts';
|
|
10
|
-
import { runDockerCompose } from '../lib/docker.ts';
|
|
11
|
-
|
|
12
|
-
function requireKnownAddon(name: string): void {
|
|
13
|
-
const available = listAvailableAddonIds();
|
|
14
|
-
const hint = available.length > 0 ? ` Run \`openpalm addon list\` to see the available addons.` : '';
|
|
15
|
-
if (!available.includes(name)) {
|
|
16
|
-
throw new Error(`Addon "${name}" is not available. Known addons: ${available.join(', ') || '(none)'}.${hint}`);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export async function runAddonListAction(): Promise<void> {
|
|
21
|
-
const state = ensureValidState();
|
|
22
|
-
const enabled = new Set(listEnabledAddonIds(state.homeDir));
|
|
23
|
-
const available = listAvailableAddonIds();
|
|
24
|
-
|
|
25
|
-
if (available.length === 0) {
|
|
26
|
-
console.log('No registry addons are available.');
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
for (const name of available) {
|
|
31
|
-
console.log(`${enabled.has(name) ? '[enabled]' : '[disabled]'} ${name}`);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export async function runAddonEnableAction(name: string): Promise<void> {
|
|
36
|
-
requireKnownAddon(name);
|
|
37
|
-
const state = ensureValidState();
|
|
38
|
-
const mutation = setAddonEnabled(state.homeDir, state.vaultDir, name, true);
|
|
39
|
-
if (!mutation.ok) throw new Error(mutation.error);
|
|
40
|
-
|
|
41
|
-
if (!mutation.changed) {
|
|
42
|
-
console.log(`Addon "${name}" is already enabled.`);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
console.log(`Enabled addon "${name}".`);
|
|
47
|
-
|
|
48
|
-
if (mutation.services.length === 0) return;
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
const nextState = ensureValidState();
|
|
52
|
-
await runComposeWithPreflight(nextState, ['up', '-d', ...mutation.services]);
|
|
53
|
-
console.log(`Started services: ${mutation.services.join(', ')}`);
|
|
54
|
-
} catch (err) {
|
|
55
|
-
console.warn(
|
|
56
|
-
`Warning: addon "${name}" was enabled but its services were not started automatically: ${err instanceof Error ? err.message : String(err)}`,
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export async function runAddonDisableAction(name: string): Promise<void> {
|
|
62
|
-
requireKnownAddon(name);
|
|
63
|
-
const state = ensureValidState();
|
|
64
|
-
const services = getAddonServiceNames(state.homeDir, name);
|
|
65
|
-
const wasEnabled = listEnabledAddonIds(state.homeDir).includes(name);
|
|
66
|
-
|
|
67
|
-
if (wasEnabled && services.length > 0) {
|
|
68
|
-
try {
|
|
69
|
-
await runDockerCompose([...fullComposeArgs(state), 'stop', ...services]);
|
|
70
|
-
console.log(`Stopped services: ${services.join(', ')}`);
|
|
71
|
-
} catch (err) {
|
|
72
|
-
console.warn(
|
|
73
|
-
`Warning: failed to stop services for addon "${name}" before disabling it: ${err instanceof Error ? err.message : String(err)}`,
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const mutation = setAddonEnabled(state.homeDir, state.vaultDir, name, false);
|
|
79
|
-
if (!mutation.ok) throw new Error(mutation.error);
|
|
80
|
-
|
|
81
|
-
if (!mutation.changed) {
|
|
82
|
-
console.log(`Addon "${name}" is already disabled.`);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
console.log(`Disabled addon "${name}".`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const enableCmd = defineCommand({
|
|
90
|
-
meta: { name: 'enable', description: 'Enable a registry addon' },
|
|
91
|
-
args: {
|
|
92
|
-
name: { type: 'positional', description: 'Addon name', required: true },
|
|
93
|
-
},
|
|
94
|
-
async run({ args }) {
|
|
95
|
-
const name = String(args._?.[0] ?? '').trim();
|
|
96
|
-
if (!name) throw new Error('Addon name is required. Run `openpalm addon list` to see the available addons.');
|
|
97
|
-
await runAddonEnableAction(name);
|
|
98
|
-
},
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
const disableCmd = defineCommand({
|
|
102
|
-
meta: { name: 'disable', description: 'Disable a registry addon' },
|
|
103
|
-
args: {
|
|
104
|
-
name: { type: 'positional', description: 'Addon name', required: true },
|
|
105
|
-
},
|
|
106
|
-
async run({ args }) {
|
|
107
|
-
const name = String(args._?.[0] ?? '').trim();
|
|
108
|
-
if (!name) throw new Error('Addon name is required. Run `openpalm addon list` to see the available addons.');
|
|
109
|
-
await runAddonDisableAction(name);
|
|
110
|
-
},
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
const listCmd = defineCommand({
|
|
114
|
-
meta: { name: 'list', description: 'List registry addons and whether they are enabled' },
|
|
115
|
-
async run() {
|
|
116
|
-
await runAddonListAction();
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
export default defineCommand({
|
|
121
|
-
meta: {
|
|
122
|
-
name: 'addon',
|
|
123
|
-
description: 'Enable, disable, or list registry addons',
|
|
124
|
-
},
|
|
125
|
-
subCommands: {
|
|
126
|
-
list: listCmd,
|
|
127
|
-
enable: enableCmd,
|
|
128
|
-
disable: disableCmd,
|
|
129
|
-
},
|
|
130
|
-
});
|
package/src/commands/admin.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { defineCommand } from 'citty';
|
|
2
|
-
import { listEnabledAddonIds } from '@openpalm/lib';
|
|
3
|
-
import { ensureValidState } from '../lib/cli-state.ts';
|
|
4
|
-
import { runAddonDisableAction, runAddonEnableAction } from './addon.ts';
|
|
5
|
-
|
|
6
|
-
async function runAdminStatusAction(): Promise<void> {
|
|
7
|
-
const state = ensureValidState();
|
|
8
|
-
const enabled = listEnabledAddonIds(state.homeDir).includes('admin');
|
|
9
|
-
console.log(enabled ? 'Admin addon is enabled.' : 'Admin addon is disabled.');
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const enableCmd = defineCommand({
|
|
13
|
-
meta: { name: 'enable', description: 'Enable the admin addon' },
|
|
14
|
-
async run() {
|
|
15
|
-
await runAddonEnableAction('admin');
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const disableCmd = defineCommand({
|
|
20
|
-
meta: { name: 'disable', description: 'Disable the admin addon' },
|
|
21
|
-
async run() {
|
|
22
|
-
await runAddonDisableAction('admin');
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const statusCmd = defineCommand({
|
|
27
|
-
meta: { name: 'status', description: 'Show whether the admin addon is enabled' },
|
|
28
|
-
async run() {
|
|
29
|
-
await runAdminStatusAction();
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
export default defineCommand({
|
|
34
|
-
meta: {
|
|
35
|
-
name: 'admin',
|
|
36
|
-
description: 'Enable, disable, or inspect the admin addon',
|
|
37
|
-
},
|
|
38
|
-
subCommands: {
|
|
39
|
-
enable: enableCmd,
|
|
40
|
-
disable: disableCmd,
|
|
41
|
-
status: statusCmd,
|
|
42
|
-
},
|
|
43
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test';
|
|
2
|
-
import { buildDeployStatusEntries } from './install-services.ts';
|
|
3
|
-
|
|
4
|
-
describe('install service helpers', () => {
|
|
5
|
-
it('builds deploy status entries for the install service list', () => {
|
|
6
|
-
const services = ['memory', 'assistant'];
|
|
7
|
-
|
|
8
|
-
expect(buildDeployStatusEntries(services, 'pending', 'Waiting...')).toEqual([
|
|
9
|
-
{ service: 'memory', status: 'pending', label: 'Waiting...' },
|
|
10
|
-
{ service: 'assistant', status: 'pending', label: 'Waiting...' },
|
|
11
|
-
]);
|
|
12
|
-
});
|
|
13
|
-
});
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export type DeployStatusState = 'pending' | 'pulling' | 'error';
|
|
2
|
-
|
|
3
|
-
export function buildDeployStatusEntries(
|
|
4
|
-
services: string[],
|
|
5
|
-
status: DeployStatusState,
|
|
6
|
-
label: string,
|
|
7
|
-
): Array<{ service: string; status: DeployStatusState; label: string }> {
|
|
8
|
-
return services.map(service => ({ service, status, label }));
|
|
9
|
-
}
|