@youdie006/prodex 0.16.27 → 0.16.28

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/dist/config.js CHANGED
@@ -129,16 +129,54 @@ export async function loadLocalConfig(cwd) {
129
129
  assertServerUrlMatchesConfig(config);
130
130
  return config;
131
131
  }
132
+ // Global browser-selection defaults from the environment, used when a repo has
133
+ // no per-repo default for a field. The MCP server (pro_consult) frequently runs
134
+ // as `prodex mcp` with no --cwd, so it reads whatever directory the agent
135
+ // launched in - a per-repo default set elsewhere is then missed. Setting e.g.
136
+ // PRODEX_DEFAULT_PROJECT=Codex PRODEX_DEFAULT_MODEL=Pro pins a default that
137
+ // applies from ANY cwd so consults stop landing in the general chat.
138
+ export function envBrowserDefaults() {
139
+ const model = process.env.PRODEX_DEFAULT_MODEL?.trim() || undefined;
140
+ const project = process.env.PRODEX_DEFAULT_PROJECT?.trim() || undefined;
141
+ const raw = {};
142
+ if (model)
143
+ raw.model = model;
144
+ if (project)
145
+ raw.project = project;
146
+ const proMode = process.env.PRODEX_DEFAULT_PRO_MODE?.trim();
147
+ if (proMode)
148
+ raw.pro_mode = proMode;
149
+ const effort = process.env.PRODEX_DEFAULT_EFFORT?.trim();
150
+ if (effort)
151
+ raw.effort = effort;
152
+ if (Object.keys(raw).length === 0)
153
+ return undefined;
154
+ const parsed = BrowserDefaultsSchema.safeParse(raw);
155
+ if (parsed.success)
156
+ return parsed.data;
157
+ // A bad enum in pro_mode/effort must not drop a valid model/project.
158
+ const freeText = BrowserDefaultsSchema.safeParse({
159
+ ...(model ? { model } : {}),
160
+ ...(project ? { project } : {})
161
+ });
162
+ return (model || project) && freeText.success ? freeText.data : undefined;
163
+ }
132
164
  // Read persisted browser-selection defaults without failing when the local
133
165
  // config is absent or unrelated to this cwd (defaults are optional convenience).
166
+ // Per-repo config wins field-by-field; PRODEX_DEFAULT_* env vars are the global
167
+ // fallback so a pinned default project/model applies from any cwd.
134
168
  export async function loadBrowserDefaults(cwd) {
169
+ const env = envBrowserDefaults();
170
+ let repo;
135
171
  try {
136
- const config = await loadLocalConfig(cwd);
137
- return config.browser_defaults;
172
+ repo = (await loadLocalConfig(cwd)).browser_defaults;
138
173
  }
139
174
  catch {
140
- return undefined;
175
+ repo = undefined;
141
176
  }
177
+ if (!repo && !env)
178
+ return undefined;
179
+ return { ...(env ?? {}), ...(repo ?? {}) };
142
180
  }
143
181
  export function getTokenExpiryStatus(config, now = new Date()) {
144
182
  if (!config.token_expires_at) {
package/dist/mcp.js CHANGED
@@ -138,7 +138,7 @@ export function createServer(cwd = process.cwd(), options = {}) {
138
138
  const browserConsult = options.browserConsult;
139
139
  if (browserConsult) {
140
140
  server.registerTool("pro_consult", {
141
- description: "Ask the user's logged-in ChatGPT (Pro) in the visible browser and wait for the full answer. This drives a real browser send: it can take minutes (Pro extended reasoning), is human-paced, and records a durable receipt under .bridge/. Requires a running `prodex pro browser login` session. Returns task_id, thread URL, and the answer text.",
141
+ description: "Ask the user's logged-in ChatGPT (Pro) in the visible browser and wait for the full answer. This drives a real browser send: it can take minutes (Pro extended reasoning), is human-paced, and records a durable receipt under .bridge/. Requires a running `prodex pro browser login` session. By DEFAULT the consult continues in the currently-open thread, so consecutive follow-ups on the same topic stay in one conversation (keeps context, avoids sidebar clutter). Pass new_chat:true ONLY to start a fresh thread for a genuinely new topic. `project` and `model` come from saved defaults (per-repo config, or PRODEX_DEFAULT_PROJECT / PRODEX_DEFAULT_MODEL env vars) when omitted - do NOT pass them per-call unless deliberately overriding. Returns task_id, thread URL, and the answer text.",
142
142
  inputSchema: {
143
143
  prompt: McpBridgeTextSchema.min(1),
144
144
  model: McpShortTextSchema.optional(),
@@ -147,7 +147,10 @@ export function createServer(cwd = process.cwd(), options = {}) {
147
147
  project: McpShortTextSchema.optional(),
148
148
  timeout_ms: z.number().int().positive().max(3_600_000).optional(),
149
149
  files: z.array(McpShortTextSchema).max(20).optional(),
150
- new_chat: z.boolean().optional()
150
+ new_chat: z
151
+ .boolean()
152
+ .optional()
153
+ .describe("Start a fresh thread. Omit to continue the current thread (preferred for follow-ups).")
151
154
  }
152
155
  }, async (input, extra) => {
153
156
  // Bridge send progress to MCP progress notifications, but only when
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@youdie006/prodex",
3
- "version": "0.16.27",
3
+ "version": "0.16.28",
4
4
  "description": "Local receipt bus for coordinating Codex execution with ChatGPT Pro/Projects consultation.",
5
5
  "author": "youdie006",
6
6
  "license": "MIT",