@kidsinai/kids-client 0.0.25 → 0.0.26

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,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@kidsinai/kids-client",
4
- "version": "0.0.25",
4
+ "version": "0.0.26",
5
5
  "type": "module",
6
6
  "description": "Own-client TUI for Kids OpenCode — talks to local `opencode serve` via @opencode-ai/sdk v2 with kid-warm rendering, mission progress, permission dialog, and stderr-tail audit pipeline.",
7
7
  "license": "MIT",
@@ -56,6 +56,16 @@ export interface ServeManagerOptions {
56
56
  */
57
57
  serverUsername: string
58
58
  opencodeBin: string
59
+ /**
60
+ * Inline opencode config (JSON string) passed to the spawned serve via
61
+ * OPENCODE_CONFIG_CONTENT. opencode otherwise reads the empty global config
62
+ * and falls back to a default model the ChatGPT-account auth can't use
63
+ * (gpt-5.5-pro) with permissions unset. Passing a curated `{ model,
64
+ * permission }` here pins a usable default model AND enforces the kid-safety
65
+ * "ask before write/edit" gate at the source. (OPENCODE_CONFIG as a file
66
+ * path is unreliable; the inline content var is what opencode honors.)
67
+ */
68
+ opencodeConfigContent?: string
59
69
  /** Max total wait for readiness in ms. Default {@link DEFAULT_READY_TIMEOUT_MS}. */
60
70
  readyTimeoutMs?: number
61
71
  /** Per-probe abort ceiling in ms. Default {@link DEFAULT_PROBE_TIMEOUT_MS}. */
@@ -101,6 +111,9 @@ export class ServeManager {
101
111
  ...process.env,
102
112
  OPENCODE_SERVER_PASSWORD: this.opts.serverPassword,
103
113
  OPENCODE_SERVER_USERNAME: this.opts.serverUsername,
114
+ ...(this.opts.opencodeConfigContent
115
+ ? { OPENCODE_CONFIG_CONTENT: this.opts.opencodeConfigContent }
116
+ : {}),
104
117
  },
105
118
  stdout: "pipe",
106
119
  stderr: "pipe",
package/src/index.tsx CHANGED
@@ -20,6 +20,7 @@
20
20
  import React from "react"
21
21
  import { render } from "ink"
22
22
  import { join } from "node:path"
23
+ import { readFileSync } from "node:fs"
23
24
  import { readEnv, validateEnv, type KidsClientEnv } from "./core/env.ts"
24
25
  import { ServeManager } from "./core/serve-manager.ts"
25
26
  import { createKidsClient, type OpencodeClient } from "./core/connection.ts"
@@ -344,6 +345,7 @@ async function bootServices(env: KidsClientEnv, store: Store): Promise<ServiceSe
344
345
  serverPassword: env.opencodeServerPassword,
345
346
  serverUsername: env.opencodeServerUsername,
346
347
  opencodeBin: env.opencodeBin,
348
+ opencodeConfigContent: buildServeConfig(env.configDir),
347
349
  onAuditLine: (event) => {
348
350
  audit.push(event)
349
351
  store.pushAudit(event)
@@ -915,6 +917,34 @@ function errMessage(err: unknown): string {
915
917
  return String(err)
916
918
  }
917
919
 
920
+ /**
921
+ * Build the inline opencode config passed to the spawned serve. opencode's
922
+ * own global config is effectively empty, so without this it defaults the
923
+ * openai provider to gpt-5.5-pro (rejected by ChatGPT-account auth) with no
924
+ * permission gate. We forward a curated, schema-clean subset of the kids
925
+ * preset: a usable default model + the kid-safety "ask before acting" gate.
926
+ *
927
+ * Deliberately NOT forwarded: the preset's `agent.tools` / `_comment` keys —
928
+ * they fail opencode's config schema (which silently drops the whole config).
929
+ * The tool whitelist is enforced by the kids plugin regardless, so nothing is
930
+ * lost. Returns undefined if the preset is missing/unreadable (serve then
931
+ * falls back to its own config — same as before this change).
932
+ */
933
+ function buildServeConfig(configDir: string): string | undefined {
934
+ let model = "openai/gpt-5.4-mini"
935
+ try {
936
+ const preset = JSON.parse(readFileSync(join(configDir, "opencode.json"), "utf8")) as { model?: string }
937
+ if (typeof preset.model === "string" && preset.model.includes("/")) model = preset.model
938
+ } catch {
939
+ return undefined
940
+ }
941
+ return JSON.stringify({
942
+ $schema: "https://opencode.ai/config.json",
943
+ model,
944
+ permission: { edit: "ask", write: "ask", bash: "ask", webfetch: "ask" },
945
+ })
946
+ }
947
+
918
948
  void main().catch((err) => {
919
949
  console.error("kids-client: fatal startup error:", err)
920
950
  process.exit(1)