@openpalm/lib 0.11.0-beta.1 → 0.11.0-beta.2
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 +1 -1
- package/src/control-plane/akm-vault.test.ts +1 -4
- package/src/control-plane/compose-args.test.ts +0 -3
- package/src/control-plane/compose-errors.test.ts +106 -0
- package/src/control-plane/compose-errors.ts +117 -0
- package/src/control-plane/config-persistence.ts +1 -2
- package/src/control-plane/host-opencode.test.ts +0 -3
- package/src/control-plane/install-edge-cases.test.ts +26 -66
- package/src/control-plane/lifecycle.ts +8 -40
- package/src/control-plane/migrate-0110.test.ts +177 -0
- package/src/control-plane/migrate-0110.ts +99 -0
- package/src/control-plane/paths.ts +8 -1
- package/src/control-plane/registry-components.test.ts +3 -2
- package/src/control-plane/secret-backend.test.ts +5 -8
- package/src/control-plane/secret-mappings.ts +2 -3
- package/src/control-plane/secrets.ts +13 -7
- package/src/control-plane/setup-config.schema.json +3 -3
- package/src/control-plane/setup-status.ts +6 -1
- package/src/control-plane/setup-validation.ts +2 -2
- package/src/control-plane/setup.test.ts +18 -14
- package/src/control-plane/setup.ts +22 -36
- package/src/control-plane/spec-to-env.ts +12 -1
- package/src/control-plane/types.ts +0 -18
- package/src/control-plane/validate.ts +1 -1
- package/src/index.ts +9 -4
- package/src/logger.ts +1 -1
- package/src/control-plane/audit.ts +0 -41
|
@@ -51,12 +51,18 @@ export function deriveSystemEnvFromSpec(
|
|
|
51
51
|
export type VoiceVarsConfig = {
|
|
52
52
|
tts?: {
|
|
53
53
|
enabled?: boolean;
|
|
54
|
+
/** Engine name (e.g. "kokoro", "elevenlabs", "browser"). */
|
|
55
|
+
engine?: string;
|
|
56
|
+
/** Optional sub-provider qualifier when an engine fronts multiple providers. */
|
|
57
|
+
provider?: string;
|
|
54
58
|
baseURL?: string;
|
|
55
59
|
model?: string;
|
|
56
60
|
voice?: string;
|
|
57
61
|
};
|
|
58
62
|
stt?: {
|
|
59
63
|
enabled?: boolean;
|
|
64
|
+
engine?: string;
|
|
65
|
+
provider?: string;
|
|
60
66
|
baseURL?: string;
|
|
61
67
|
model?: string;
|
|
62
68
|
language?: string;
|
|
@@ -65,7 +71,8 @@ export type VoiceVarsConfig = {
|
|
|
65
71
|
|
|
66
72
|
/**
|
|
67
73
|
* Write TTS/STT env vars to stack.env for the voice channel container.
|
|
68
|
-
*
|
|
74
|
+
* `engine` always writes (even if it's the only field) so picking an
|
|
75
|
+
* engine without filling in URL/model still persists.
|
|
69
76
|
*/
|
|
70
77
|
export function writeVoiceVars(config: VoiceVarsConfig, stackDir: string): void {
|
|
71
78
|
const stackEnvPath = `${stackDir}/stack.env`;
|
|
@@ -74,11 +81,15 @@ export function writeVoiceVars(config: VoiceVarsConfig, stackDir: string): void
|
|
|
74
81
|
|
|
75
82
|
const { tts, stt } = config;
|
|
76
83
|
if (tts?.enabled !== false) {
|
|
84
|
+
if (tts?.engine) vars["TTS_ENGINE"] = tts.engine;
|
|
85
|
+
if (tts?.provider) vars["TTS_PROVIDER"] = tts.provider;
|
|
77
86
|
if (tts?.baseURL) vars["TTS_BASE_URL"] = tts.baseURL;
|
|
78
87
|
if (tts?.model) vars["TTS_MODEL"] = tts.model;
|
|
79
88
|
if (tts?.voice) vars["TTS_VOICE"] = tts.voice;
|
|
80
89
|
}
|
|
81
90
|
if (stt?.enabled !== false) {
|
|
91
|
+
if (stt?.engine) vars["STT_ENGINE"] = stt.engine;
|
|
92
|
+
if (stt?.provider) vars["STT_PROVIDER"] = stt.provider;
|
|
82
93
|
if (stt?.baseURL) vars["STT_BASE_URL"] = stt.baseURL;
|
|
83
94
|
if (stt?.model) vars["STT_MODEL"] = stt.model;
|
|
84
95
|
if (stt?.language) vars["STT_LANGUAGE"] = stt.language;
|
|
@@ -12,11 +12,6 @@ export type OptionalServiceName = never;
|
|
|
12
12
|
|
|
13
13
|
export type AccessScope = "host" | "lan";
|
|
14
14
|
export type CallerType = "assistant" | "cli" | "ui" | "system" | "test" | "unknown";
|
|
15
|
-
export type AuditContext = {
|
|
16
|
-
actor: string;
|
|
17
|
-
requestId?: string;
|
|
18
|
-
callerType?: CallerType;
|
|
19
|
-
};
|
|
20
15
|
|
|
21
16
|
/** Info about a discovered channel */
|
|
22
17
|
export type ChannelInfo = {
|
|
@@ -24,16 +19,6 @@ export type ChannelInfo = {
|
|
|
24
19
|
ymlPath: string;
|
|
25
20
|
};
|
|
26
21
|
|
|
27
|
-
export type AuditEntry = {
|
|
28
|
-
at: string;
|
|
29
|
-
requestId: string;
|
|
30
|
-
actor: string;
|
|
31
|
-
callerType: CallerType;
|
|
32
|
-
action: string;
|
|
33
|
-
args: Record<string, unknown>;
|
|
34
|
-
ok: boolean;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
22
|
export type ArtifactMeta = {
|
|
38
23
|
name: string;
|
|
39
24
|
sha256: string;
|
|
@@ -42,8 +27,6 @@ export type ArtifactMeta = {
|
|
|
42
27
|
};
|
|
43
28
|
|
|
44
29
|
export type ControlPlaneState = {
|
|
45
|
-
adminToken: string;
|
|
46
|
-
assistantToken: string;
|
|
47
30
|
homeDir: string;
|
|
48
31
|
configDir: string;
|
|
49
32
|
stashDir: string; // homeDir/stash
|
|
@@ -56,7 +39,6 @@ export type ControlPlaneState = {
|
|
|
56
39
|
compose: string;
|
|
57
40
|
};
|
|
58
41
|
artifactMeta: ArtifactMeta[];
|
|
59
|
-
audit: AuditEntry[];
|
|
60
42
|
};
|
|
61
43
|
|
|
62
44
|
// ── Constants ──────────────────────────────────────────────────────────
|
|
@@ -15,7 +15,7 @@ import type { ControlPlaneState } from "./types.js";
|
|
|
15
15
|
// Stack-scoped env keys that must always exist and carry a non-empty value
|
|
16
16
|
// for the platform to boot. Keep this list small — anything optional
|
|
17
17
|
// belongs in the warning bucket instead.
|
|
18
|
-
const REQUIRED_STACK_KEYS = ["
|
|
18
|
+
const REQUIRED_STACK_KEYS = ["OP_UI_LOGIN_PASSWORD"] as const;
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Validate the live configuration files.
|
package/src/index.ts
CHANGED
|
@@ -29,7 +29,6 @@ export type {
|
|
|
29
29
|
ChannelInfo,
|
|
30
30
|
CallerType,
|
|
31
31
|
ArtifactMeta,
|
|
32
|
-
AuditEntry,
|
|
33
32
|
} from "./control-plane/types.js";
|
|
34
33
|
export {
|
|
35
34
|
CORE_SERVICES,
|
|
@@ -96,9 +95,6 @@ export {
|
|
|
96
95
|
RELEASE_TAG_REGEX,
|
|
97
96
|
} from "./control-plane/env.js";
|
|
98
97
|
|
|
99
|
-
// ── Audit ───────────────────────────────────────────────────────────────
|
|
100
|
-
export { appendAudit } from "./control-plane/audit.js";
|
|
101
|
-
|
|
102
98
|
// ── OpenCode Client ─────────────────────────────────────────────────────
|
|
103
99
|
export { createOpenCodeClient } from "./control-plane/opencode-client.js";
|
|
104
100
|
export type { ProxyResult, OpenCodeProvider } from "./control-plane/opencode-client.js";
|
|
@@ -114,6 +110,8 @@ export {
|
|
|
114
110
|
maskSecretValue,
|
|
115
111
|
ensureOpenCodeConfig,
|
|
116
112
|
} from "./control-plane/secrets.js";
|
|
113
|
+
export { migrateAuth0110 } from "./control-plane/migrate-0110.js";
|
|
114
|
+
export type { MigrateAuth0110Result } from "./control-plane/migrate-0110.js";
|
|
117
115
|
export {
|
|
118
116
|
detectSecretBackend,
|
|
119
117
|
validatePassEntryName,
|
|
@@ -234,6 +232,13 @@ export {
|
|
|
234
232
|
buildComposeCliArgs,
|
|
235
233
|
} from "./control-plane/compose-args.js";
|
|
236
234
|
|
|
235
|
+
// ── Compose Error Parsing ────────────────────────────────────────────────
|
|
236
|
+
export type { ComposeServiceFailure } from "./control-plane/compose-errors.js";
|
|
237
|
+
export {
|
|
238
|
+
parseComposeStderr,
|
|
239
|
+
summarizeComposeStderr,
|
|
240
|
+
} from "./control-plane/compose-errors.js";
|
|
241
|
+
|
|
237
242
|
// ── Stack Spec (v2) ──────────────────────────────────────────────────────
|
|
238
243
|
export type {
|
|
239
244
|
StackSpec,
|
package/src/logger.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
|
13
13
|
* with un-anchored alternations was sloppy enough to invite future bugs).
|
|
14
14
|
*
|
|
15
15
|
* Examples:
|
|
16
|
-
*
|
|
16
|
+
* OP_UI_LOGIN_PASSWORD → sensitive (suffix _PASSWORD)
|
|
17
17
|
* CHANNEL_API_KEY → sensitive (suffix _KEY)
|
|
18
18
|
* CHANNEL_FOO_HMAC → sensitive (suffix _HMAC)
|
|
19
19
|
* HMAC_KEY → sensitive (prefix HMAC_, suffix _KEY)
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Audit logging for the OpenPalm control plane.
|
|
3
|
-
*/
|
|
4
|
-
import { mkdirSync, appendFileSync } from "node:fs";
|
|
5
|
-
import type { ControlPlaneState, AuditEntry, CallerType } from "./types.js";
|
|
6
|
-
|
|
7
|
-
const MAX_AUDIT_MEMORY = 1000;
|
|
8
|
-
|
|
9
|
-
export function appendAudit(
|
|
10
|
-
state: ControlPlaneState,
|
|
11
|
-
actor: string,
|
|
12
|
-
action: string,
|
|
13
|
-
args: Record<string, unknown>,
|
|
14
|
-
ok: boolean,
|
|
15
|
-
requestId = "",
|
|
16
|
-
callerType: CallerType = "unknown"
|
|
17
|
-
): void {
|
|
18
|
-
const entry: AuditEntry = {
|
|
19
|
-
at: new Date().toISOString(),
|
|
20
|
-
requestId,
|
|
21
|
-
actor,
|
|
22
|
-
callerType,
|
|
23
|
-
action,
|
|
24
|
-
args,
|
|
25
|
-
ok
|
|
26
|
-
};
|
|
27
|
-
state.audit.push(entry);
|
|
28
|
-
if (state.audit.length > MAX_AUDIT_MEMORY) {
|
|
29
|
-
state.audit = state.audit.slice(-MAX_AUDIT_MEMORY);
|
|
30
|
-
}
|
|
31
|
-
try {
|
|
32
|
-
const logsDir = `${state.stateDir}/logs`;
|
|
33
|
-
mkdirSync(logsDir, { recursive: true });
|
|
34
|
-
appendFileSync(
|
|
35
|
-
`${logsDir}/admin-audit.jsonl`,
|
|
36
|
-
JSON.stringify(entry) + "\n"
|
|
37
|
-
);
|
|
38
|
-
} catch {
|
|
39
|
-
// best-effort persistence
|
|
40
|
-
}
|
|
41
|
-
}
|