@hienlh/ppm 0.19.7 → 0.19.8

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.19.8] - 2026-09-13
4
+
5
+ ### Changed
6
+ - **Codex chats now use a balanced model by default** — PPM asked for no particular model, so Codex fell back to its most capable and most expensive one for every chat. Settings → AI Provider and the chat's model picker still override it, and "Auto (default)" hands the choice back to Codex.
7
+
3
8
  ## [0.19.7] - 2026-09-12
4
9
 
5
10
  ### Added
@@ -71,4 +71,4 @@ This skill covers the `ppm` CLI, its HTTP API, and its config DB. It does **not*
71
71
  - Third-party extensions (inspect via `ppm ext list`).
72
72
  - The Claude Agent SDK internals (separate skill).
73
73
 
74
- <!-- Generated for PPM v0.19.7 at build time. Re-run `ppm export skill --install` to refresh. -->
74
+ <!-- Generated for PPM v0.19.8 at build time. Re-run `ppm export skill --install` to refresh. -->
@@ -341,4 +341,4 @@ _Base URL: `http://localhost:8080` (default; override via `ppm config set port <
341
341
  - `ws://<host>/ws/terminal` — PTY terminal multiplexer
342
342
  - `ws://<host>/ws/extensions` — extension host channel
343
343
 
344
- <!-- Generated from src/server/routes/ for PPM v0.19.7 -->
344
+ <!-- Generated from src/server/routes/ for PPM v0.19.8 -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hienlh/ppm",
3
- "version": "0.19.7",
3
+ "version": "0.19.8",
4
4
  "description": "Personal Project Manager — mobile-first web IDE with AI assistance",
5
5
  "author": "hienlh",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -2,6 +2,7 @@ import type { AIProvider } from "./provider.interface.ts";
2
2
  import { MockProvider } from "./mock-provider.ts";
3
3
  import { ClaudeAgentSdkProvider } from "./claude-agent-sdk.ts";
4
4
  import { configService } from "../services/config.service.ts";
5
+ import { CODEX_DEFAULT_MODEL } from "../types/config.ts";
5
6
 
6
7
  export interface ProviderInfo {
7
8
  id: string;
@@ -92,12 +93,22 @@ export async function bootstrapProviders(): Promise<void> {
92
93
  if (await codex.isAvailable()) {
93
94
  providerRegistry.register(codex);
94
95
  const ai = configService.get("ai");
96
+ // Only when codex has never been configured. An absent `model` is a real
97
+ // choice here — the settings picker writes it for "Auto (default)", which
98
+ // hands model selection back to codex — so filling one in on every startup
99
+ // would undo that choice each restart. Existing installs are given the
100
+ // default once, by migration.
95
101
  if (!ai.providers["codex"]) {
96
102
  configService.set("ai", {
97
103
  ...ai,
98
104
  providers: {
99
105
  ...ai.providers,
100
- codex: { type: "cli", cli_command: "codex", permission_mode: "bypassPermissions" },
106
+ codex: {
107
+ type: "cli",
108
+ cli_command: "codex",
109
+ permission_mode: "bypassPermissions",
110
+ model: CODEX_DEFAULT_MODEL,
111
+ },
101
112
  },
102
113
  });
103
114
  }
@@ -5,7 +5,8 @@ import { encrypt, decrypt } from "../lib/account-crypto.ts";
5
5
  import { getPpmDir } from "./ppm-dir.ts";
6
6
  import { assertProdDbAccessAllowed } from "./prod-db-guard.ts";
7
7
  import { backupDbSync } from "./db-backup/db-backup-sync.ts";
8
- export const CURRENT_SCHEMA_VERSION = 44;
8
+ import { CODEX_DEFAULT_MODEL } from "../types/config.ts";
9
+ export const CURRENT_SCHEMA_VERSION = 45;
9
10
 
10
11
  let db: Database | null = null;
11
12
  let dbProfile: string | null = null;
@@ -89,7 +90,8 @@ export function setDb(instance: Database): void {
89
90
  // Schema migrations
90
91
  // ---------------------------------------------------------------------------
91
92
 
92
- function runMigrations(database: Database): void {
93
+ /** Exported so a test can drive an upgrade from a specific older version. */
94
+ export function runMigrations(database: Database): void {
93
95
  const row = database.query("PRAGMA user_version").get() as { user_version: number };
94
96
  const current = row.user_version;
95
97
 
@@ -1047,6 +1049,35 @@ function runMigrations(database: Database): void {
1047
1049
  PRAGMA user_version = 44;
1048
1050
  `);
1049
1051
  }
1052
+
1053
+ if (current < 45) {
1054
+ // Codex was registered without a model, and PPM sends no model when none is
1055
+ // configured, so codex fell back to its own default — its most capable and
1056
+ // most expensive model — for every chat.
1057
+ //
1058
+ // Applied once, here, rather than on each startup: the settings picker
1059
+ // stores "Auto (default)" as an absent model, so a startup check could not
1060
+ // tell that choice apart from never having chosen and would reimpose this
1061
+ // value at every restart.
1062
+ try {
1063
+ const row = database.query("SELECT value FROM config WHERE key = 'ai'").get() as { value: string } | null;
1064
+ if (row?.value) {
1065
+ const ai = JSON.parse(row.value) as {
1066
+ providers?: Record<string, Record<string, unknown> | undefined>;
1067
+ };
1068
+ const codex = ai.providers?.["codex"];
1069
+ if (codex && codex.model == null) {
1070
+ codex.model = CODEX_DEFAULT_MODEL;
1071
+ database.query("UPDATE config SET value = ? WHERE key = 'ai'").run(JSON.stringify(ai));
1072
+ }
1073
+ }
1074
+ } catch {
1075
+ // A config that cannot be read or parsed is not worth failing the upgrade
1076
+ // over; codex keeps choosing for itself, exactly as before.
1077
+ }
1078
+
1079
+ database.exec(`PRAGMA user_version = 45;`);
1080
+ }
1050
1081
  }
1051
1082
 
1052
1083
  // ---------------------------------------------------------------------------
@@ -111,6 +111,20 @@ export interface AIProviderConfig {
111
111
  cli_command?: string;
112
112
  }
113
113
 
114
+ /**
115
+ * Model a new codex session uses unless the picker says otherwise.
116
+ *
117
+ * Codex is registered at runtime rather than shipped in DEFAULT_CONFIG — it only
118
+ * exists once `@openai/codex` is installed — so its default lives here, beside
119
+ * Claude's, instead of being invisible inside the registration code.
120
+ *
121
+ * Deliberately not codex's own default, which is its most capable model and
122
+ * bills accordingly; codex describes this one as its balanced agentic coding
123
+ * model for everyday work, which is what a chat in an IDE mostly does. Changing
124
+ * it in Settings, or per session in the chat's model picker, overrides this.
125
+ */
126
+ export const CODEX_DEFAULT_MODEL = "gpt-5.6-terra";
127
+
114
128
  export const DEFAULT_CONFIG: PpmConfig = {
115
129
  device_name: "",
116
130
  port: 8080,