@openpalm/lib 0.11.0-beta.14 → 0.11.0-beta.16

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpalm/lib",
3
- "version": "0.11.0-beta.14",
3
+ "version": "0.11.0-beta.16",
4
4
  "license": "MPL-2.0",
5
5
  "type": "module",
6
6
  "description": "Shared control-plane library for OpenPalm — lifecycle, staging, secrets, channels, connections, scheduler",
@@ -56,7 +56,7 @@ const ENV_FILE_MODE = 0o600;
56
56
 
57
57
  /**
58
58
  * Build the env that points akm at the shared OpenPalm stash. We mirror the
59
- * layout that the assistant/admin containers use (see
59
+ * layout that the assistant container uses (see
60
60
  * `.openpalm/config/stack/core.compose.yml`) so host-side and container-side
61
61
  * runs resolve to the same files.
62
62
  *
@@ -14,6 +14,7 @@ import { ensureSecret } from './secrets-files.js';
14
14
  import type { ControlPlaneState, ArtifactMeta } from "./types.js";
15
15
  import { listEnabledAddonIds } from "./registry.js";
16
16
  import { resolveOperatorIds, hasUsableOperatorId } from "./operator-ids.js";
17
+ import { SPEC_DEFAULTS } from "./stack-spec.js";
17
18
 
18
19
  import {
19
20
  readCoreCompose,
@@ -130,9 +131,8 @@ function generateFallbackSystemEnv(state: ControlPlaneState): string {
130
131
  "# ── Ports (38XX range) ──────────────────────────────────────────────",
131
132
  "# Guardian is network-only (no host port) — channels reach it via",
132
133
  "# http://guardian:8080 over the channel_lan Docker network.",
133
- `OP_ASSISTANT_PORT=3800`,
134
- `OP_ADMIN_PORT=3880`,
135
- `OP_ADMIN_OPENCODE_PORT=3881`,
134
+ `OP_ASSISTANT_PORT=${SPEC_DEFAULTS.ports.assistant}`,
135
+ `OP_HOST_UI_PORT=${SPEC_DEFAULTS.ports.hostUi}`,
136
136
  ""
137
137
  ].join("\n");
138
138
  }
@@ -5,7 +5,7 @@
5
5
  * config/ — user-editable config + system config files (akm/)
6
6
  * config/stack/ — compose runtime + stack config (stack.env, stack.yml, auth.json, fixed compose files)
7
7
  * data/ — persistent service data, logs, backups, rollback
8
- * knowledge/ — akm knowledge (skills, vaults, agents)
8
+ * knowledge/ — akm knowledge (env, secrets, tasks)
9
9
  * workspace/ — shared assistant work area
10
10
  * config/stack/ — compose runtime assets + stack config (stack.env, stack.yml)
11
11
  */
@@ -94,7 +94,6 @@ export function ensureHomeDirs(): void {
94
94
  `${home}/data/assistant/.local/bin`,
95
95
  `${home}/data/assistant/.local/share/opencode`,
96
96
  `${home}/data/assistant/.local/state/opencode`,
97
- `${home}/data/admin`, // admin home bind mount
98
97
  `${home}/data/guardian`, // guardian runtime data
99
98
  `${home}/data/akm/cache`, // akm cache
100
99
  `${home}/data/akm/data`, // akm durable data
@@ -23,7 +23,6 @@ import {
23
23
  performSetup,
24
24
  buildSecretsFromSetup,
25
25
  buildAuthJsonFromSetup,
26
- buildSystemSecretsFromSetup,
27
26
  } from "./setup.js";
28
27
  import type { SetupSpec, SetupConnection } from "./setup.js";
29
28
  import type { ControlPlaneState } from "./types.js";
@@ -113,7 +112,6 @@ function createFullDirTree(): void {
113
112
  stackDir,
114
113
  dataDir,
115
114
  join(dataDir, "assistant"),
116
- join(dataDir, "admin"),
117
115
  join(dataDir, "guardian"),
118
116
  join(dataDir, "akm", "cache"),
119
117
  join(dataDir, "akm", "data"),
@@ -184,10 +184,14 @@ export async function updateStackEnvToLatestImageTag(state: ControlPlaneState):
184
184
  throw new Error(`Invalid image namespace in system.env: ${namespace}`);
185
185
  }
186
186
 
187
+ // `assistant` is the version-of-record image: all platform images
188
+ // (assistant, guardian, channel, voice) are published in lockstep under the
189
+ // same OP_IMAGE_TAG, so its newest tag is the canonical platform version.
190
+
187
191
  let response: Response;
188
192
  try {
189
193
  response = await fetch(
190
- `https://registry.hub.docker.com/v2/repositories/${namespace}/admin/tags?page_size=25&ordering=last_updated`,
194
+ `https://registry.hub.docker.com/v2/repositories/${namespace}/assistant/tags?page_size=25&ordering=last_updated`,
191
195
  { headers: { Accept: "application/json" } }
192
196
  );
193
197
  } catch (e) {
@@ -2,7 +2,7 @@
2
2
  * Shared OpenCode REST API client.
3
3
  *
4
4
  * Factory function that returns typed accessors for an OpenCode server
5
- * at a configurable base URL. Used by both the admin (container) and
5
+ * at a configurable base URL. Used by both the admin UI (host process) and
6
6
  * CLI (host subprocess) to talk to OpenCode.
7
7
  */
8
8
 
@@ -24,7 +24,7 @@ import type { ControlPlaneState } from "./types.js";
24
24
  export const authJsonPath = (s: ControlPlaneState): string => `${s.stashDir}/secrets/auth.json`;
25
25
  /** akm config directory mounted at /etc/akm */
26
26
  export const akmConfigDir = (s: ControlPlaneState): string => `${s.configDir}/akm`;
27
- /** akm setup config file (written by admin on capability save) */
27
+ /** akm setup config file (written by the admin UI AKM action and CLI install) */
28
28
  export const akmConfigPath = (s: ControlPlaneState): string => `${s.configDir}/akm/config.json`;
29
29
  export const tasksDir = (s: ControlPlaneState): string => `${s.stashDir}/tasks`;
30
30
  export const assistantConfigDir = (s: ControlPlaneState): string => `${s.configDir}/assistant`;
@@ -67,14 +67,11 @@ export const logsDir = (s: ControlPlaneState): string => `${s.data
67
67
  * chat + tool activity.
68
68
  */
69
69
  export const guardianAuditPath = (s: ControlPlaneState): string => `${s.dataDir}/logs/guardian-audit.log`;
70
- /** One-shot 0.11.0 migration log (OP_UI_TOKEN → OPENCODE_SERVER_PASSWORD, endpoints.json move) */
71
- export const migration0110LogPath = (s: ControlPlaneState): string => `${s.dataDir}/logs/migration-0.11.0.log`;
72
70
  export const backupsDir = (s: ControlPlaneState): string => `${s.dataDir}/backups`;
73
71
 
74
72
  // ── State directory — persistent service data ───────────────────────────────
75
73
 
76
74
  export const assistantServiceDir = (s: ControlPlaneState): string => `${s.dataDir}/assistant`;
77
- export const adminServiceDir = (s: ControlPlaneState): string => `${s.dataDir}/admin`;
78
75
  export const guardianServiceDir = (s: ControlPlaneState): string => `${s.dataDir}/guardian`;
79
76
  export const guardianAkmDir = (s: ControlPlaneState): string => `${s.dataDir}/guardian/akm`;
80
77
  /** akm durable data — NOT config, which lives in config/akm/ */
@@ -19,7 +19,6 @@ import {
19
19
  updateSecretsEnv,
20
20
  patchSecretsEnvFile,
21
21
  ensureOpenCodeConfig,
22
- readStackEnv,
23
22
  writeAuthJsonProviderKeys,
24
23
  } from "./secrets.js";
25
24
  import { createState } from "./lifecycle.js";
@@ -132,13 +131,9 @@ export function buildAuthJsonFromSetup(
132
131
  *
133
132
  * `OP_OPENCODE_PASSWORD` may be supplied explicitly as a file-based secret in
134
133
  * `knowledge/secrets/op_opencode_password` when OpenCode auth is enabled.
135
- *
136
- * `existingSystemEnv` is unused now but the parameter is kept so callers
137
- * compile unchanged. It can be removed in a follow-up cleanup.
138
134
  */
139
135
  export function buildSystemSecretsFromSetup(
140
136
  uiLoginPassword: string,
141
- _existingSystemEnv: Record<string, string> = {}
142
137
  ): Record<string, string> {
143
138
  return {
144
139
  OP_UI_LOGIN_PASSWORD: uiLoginPassword,
@@ -215,7 +210,6 @@ export async function performSetup(
215
210
  try {
216
211
  ensureHomeDirs();
217
212
  ensureSecrets(state);
218
- const existingSystemEnv = readStackEnv(state.stackDir);
219
213
  const channelSecretUpdates = channelCredentials ? buildChannelCredentialEnvVars(channelCredentials) : {};
220
214
  // Pick up channel credential env vars not already provided in the spec
221
215
  for (const mapping of Object.values(CHANNEL_CREDENTIAL_ENV_MAP)) {
@@ -225,7 +219,7 @@ export async function performSetup(
225
219
  }
226
220
  updateSecretsEnv(state, updates);
227
221
  updateSecretsEnv(state, channelSecretUpdates);
228
- patchSecretsEnvFile(state.stackDir, buildSystemSecretsFromSetup(security.uiLoginPassword, existingSystemEnv));
222
+ patchSecretsEnvFile(state.stackDir, buildSystemSecretsFromSetup(security.uiLoginPassword));
229
223
  // Provider API keys land in OpenCode's auth.json (bind-mounted into
230
224
  // the assistant container) — never in stack.env.
231
225
  writeAuthJsonProviderKeys(state, providerKeys);
@@ -117,7 +117,7 @@ describe("skeleton: .openpalm/knowledge/ structure", () => {
117
117
  // ── data/ service dirs ────────────────────────────────────────────────
118
118
 
119
119
  describe("skeleton: .openpalm/data/ service directories", () => {
120
- const serviceDirs = ["assistant", "admin", "guardian"];
120
+ const serviceDirs = ["assistant", "guardian"];
121
121
 
122
122
  for (const dir of serviceDirs) {
123
123
  test(`data/${dir}/ exists`, () => {
@@ -23,6 +23,13 @@ describe("deriveSystemEnvFromSpec", () => {
23
23
  test("produces default port values", () => {
24
24
  const result = deriveSystemEnvFromSpec("/home/op");
25
25
  expect(result.OP_ASSISTANT_PORT).toBe("3800");
26
+ expect(result.OP_HOST_UI_PORT).toBe("3880");
27
+ });
28
+
29
+ test("does not emit the retired OP_ADMIN_PORT/OP_ADMIN_OPENCODE_PORT vars", () => {
30
+ const result = deriveSystemEnvFromSpec("/home/op");
31
+ expect(result.OP_ADMIN_PORT).toBeUndefined();
32
+ expect(result.OP_ADMIN_OPENCODE_PORT).toBeUndefined();
26
33
  });
27
34
 
28
35
  test("does not emit OP_GUARDIAN_PORT (guardian is network-only, no host mapping)", () => {
@@ -42,8 +42,7 @@ export function deriveSystemEnvFromSpec(homeDir: string): Record<string, string>
42
42
  // network-only (no host port mapping) so OP_GUARDIAN_PORT is no longer
43
43
  // emitted; channels reach it via Docker DNS at http://guardian:8080.
44
44
  result["OP_ASSISTANT_PORT"] = String(ports.assistant);
45
- result["OP_ADMIN_PORT"] = String(ports.admin);
46
- result["OP_ADMIN_OPENCODE_PORT"] = String(ports.adminOpencode);
45
+ result["OP_HOST_UI_PORT"] = String(ports.hostUi);
47
46
  result["OP_ASSISTANT_SSH_PORT"] = String(ports.assistantSsh);
48
47
 
49
48
  return result;
@@ -26,9 +26,7 @@ export const STACK_SPEC_FILENAME = "stack.yml";
26
26
  export const SPEC_DEFAULTS = {
27
27
  ports: {
28
28
  assistant: 3800,
29
- admin: 3880,
30
- adminOpencode: 3881,
31
- guardian: 3899,
29
+ hostUi: 3880,
32
30
  assistantSsh: 2222,
33
31
  },
34
32
  image: {