@linzumi/cli 0.0.109-beta → 0.0.110-beta

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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +100 -29
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -58,7 +58,7 @@ Install the CLI or run it with `npx`:
58
58
  ```bash
59
59
  npm install -g @linzumi/cli@latest
60
60
  npx -y @linzumi/cli@latest signup
61
- npx -y @linzumi/cli@0.0.109-beta --version
61
+ npx -y @linzumi/cli@0.0.110-beta --version
62
62
  linzumi --version
63
63
  ```
64
64
 
package/dist/index.js CHANGED
@@ -20078,7 +20078,7 @@ var linzumiCliVersion, linzumiCliVersionText;
20078
20078
  var init_version = __esm({
20079
20079
  "src/version.ts"() {
20080
20080
  "use strict";
20081
- linzumiCliVersion = "0.0.109-beta";
20081
+ linzumiCliVersion = "0.0.110-beta";
20082
20082
  linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
20083
20083
  }
20084
20084
  });
@@ -23182,24 +23182,52 @@ import { mkdtempSync as mkdtempSync3, readFileSync as readFileSync16, rmSync as
23182
23182
  import { tmpdir as tmpdir2 } from "node:os";
23183
23183
  import { join as join20 } from "node:path";
23184
23184
  async function suggestSignupTasksWithCodex(args) {
23185
- const attempts = 2;
23185
+ const model = resolveTaskSuggestionModel(args.model, args.modelProvider);
23186
+ const startedAt = Date.now();
23186
23187
  let previousResponse;
23187
- for (let attempt = 1; attempt <= attempts; attempt += 1) {
23188
- const response = await runCodexTaskSuggestion({
23189
- projectPath: args.projectPath,
23190
- codexBin: args.codexBin,
23191
- model: args.model ?? process.env.LINZUMI_SIGNUP_TASK_MODEL ?? "gpt-5.4-mini",
23192
- previousResponse
23193
- });
23188
+ let lastFailure;
23189
+ for (let attempt = 0; attempt <= MAX_SCHEMA_REPAIR_ATTEMPTS; attempt += 1) {
23190
+ const elapsed = Date.now() - startedAt;
23191
+ const remaining = SUGGESTION_TIMEOUT_MS - elapsed;
23192
+ if (remaining <= 0) {
23193
+ break;
23194
+ }
23195
+ let response;
23196
+ try {
23197
+ response = await runCodexTaskSuggestion({
23198
+ projectPath: args.projectPath,
23199
+ codexBin: args.codexBin,
23200
+ model,
23201
+ modelProvider: args.modelProvider,
23202
+ previousResponse,
23203
+ timeoutMs: remaining
23204
+ });
23205
+ } catch (error) {
23206
+ throw error instanceof Error ? error : new Error(String(error));
23207
+ }
23194
23208
  const tasks = parseTaskSuggestionResponse(response);
23195
23209
  if (tasks !== void 0) {
23196
23210
  return tasks;
23197
23211
  }
23198
23212
  previousResponse = response;
23213
+ lastFailure = new Error(
23214
+ "Codex returned a response that did not match the task suggestion schema"
23215
+ );
23199
23216
  }
23200
- throw new Error(
23201
- "Codex did not return valid task suggestions after 2 attempts"
23202
- );
23217
+ throw lastFailure ?? new Error("Codex did not return valid task suggestions in the time budget");
23218
+ }
23219
+ function resolveTaskSuggestionModel(explicitModel, modelProvider) {
23220
+ const envModel = process.env.LINZUMI_SIGNUP_TASK_MODEL;
23221
+ if (explicitModel !== void 0 && explicitModel !== "") {
23222
+ return explicitModel;
23223
+ }
23224
+ if (envModel !== void 0 && envModel !== "") {
23225
+ return envModel;
23226
+ }
23227
+ if (modelProvider !== void 0) {
23228
+ return DEFAULT_WAFER_SUGGESTION_MODEL;
23229
+ }
23230
+ return DEFAULT_CODEX_AUTH_SUGGESTION_MODEL;
23203
23231
  }
23204
23232
  async function runCodexTaskSuggestion(args) {
23205
23233
  const tempRoot = mkdtempSync3(join20(tmpdir2(), "linzumi-signup-codex-tasks-"));
@@ -23217,10 +23245,12 @@ async function runCodexTaskSuggestion(args) {
23217
23245
  codexTaskSuggestionProcess({
23218
23246
  command: args.codexBin,
23219
23247
  model: args.model,
23248
+ modelProvider: args.modelProvider,
23220
23249
  projectPath: args.projectPath,
23221
23250
  schemaPath,
23222
23251
  outputPath,
23223
- prompt
23252
+ prompt,
23253
+ timeoutMs: args.timeoutMs
23224
23254
  })
23225
23255
  );
23226
23256
  return readFileSync16(outputPath, "utf8");
@@ -23236,9 +23266,19 @@ function codexTaskSuggestionProcess(args) {
23236
23266
  "--model",
23237
23267
  args.model,
23238
23268
  "-c",
23239
- 'model_reasoning_effort="low"',
23269
+ // RELIABILITY: minimal reasoning effort keeps the agentic turn fast and
23270
+ // far less flaky while still producing repo-specific tasks (it still
23271
+ // inspects the real repo below). The latency/flake budget was the main
23272
+ // driver of runner_task_suggestion_failed.
23273
+ 'model_reasoning_effort="minimal"',
23240
23274
  "-c",
23241
23275
  'approval_policy="never"',
23276
+ // Wafer routing: render the `-c model_providers.linzumi.*` config args
23277
+ // plus `-c model_provider=linzumi`, identical to the main per-thread codex
23278
+ // app-server start (codexModelProviderConfigArgs). Secrets stay in env via
23279
+ // env_key/env_http_headers, never argv. Omitted for native-codex-auth
23280
+ // users, who keep their own provider.
23281
+ ...args.modelProvider === void 0 ? [] : codexModelProviderConfigArgs(args.modelProvider.config),
23242
23282
  "--sandbox",
23243
23283
  "read-only",
23244
23284
  "--skip-git-repo-check",
@@ -23254,7 +23294,8 @@ function codexTaskSuggestionProcess(args) {
23254
23294
  ],
23255
23295
  cwd: args.projectPath,
23256
23296
  stdin: args.prompt,
23257
- timeoutMs: 55e3
23297
+ ...args.modelProvider === void 0 ? {} : { env: args.modelProvider.env },
23298
+ timeoutMs: args.timeoutMs ?? SUGGESTION_TIMEOUT_MS
23258
23299
  };
23259
23300
  }
23260
23301
  function taskSuggestionPrompt(previousResponse) {
@@ -23272,16 +23313,13 @@ function taskSuggestionPrompt(previousResponse) {
23272
23313
  "Task:",
23273
23314
  "Inspect this repository read-only and suggest exactly 5 useful quick starter tasks for Codex agents.",
23274
23315
  "",
23275
- "GitHub context:",
23276
- "- First check whether the GitHub CLI is available and authenticated with a cheap command such as `gh auth status`.",
23277
- "- If `gh` is missing, unauthenticated, or this repository has no GitHub remote, skip GitHub context and rely on local files.",
23278
- "- When `gh` is authenticated, use bounded reads such as `gh pr list --limit 30 --state all` and `gh issue list --limit 30 --state all` to inspect recent open and closed pull requests and issues.",
23279
- "- Be mindful of GitHub rate limits, CPU usage, and network usage; prefer one or two small calls and do not paginate or crawl exhaustively.",
23280
- "- If a GitHub call returns unauthorized, forbidden, or not found for this repository, stop GitHub lookups for this repository.",
23281
- "- Use pull request and issue titles, states, labels, and recent activity to infer what the repo is about, what the user has been working on, and likely next tasks.",
23316
+ "How to inspect (be fast - aim to answer within a single short pass):",
23317
+ "- Read the repo locally: top-level files, README, package manifests, and a shallow look at the main source directories are enough to infer what the project is.",
23318
+ "- Base the suggestions on the ACTUAL repository contents you observe, not on generic templates.",
23319
+ "- Do NOT crawl GitHub. Skip `gh` entirely; local files are sufficient and far faster.",
23282
23320
  "",
23283
23321
  "Constraints:",
23284
- "- Prefer tasks that are small, concrete, and likely to produce useful first results.",
23322
+ "- Prefer tasks that are small, concrete, and specific to THIS repository (reference real files, modules, or features you saw).",
23285
23323
  "- Do not modify files.",
23286
23324
  "- Do not include markdown fences or prose outside the JSON response.",
23287
23325
  "- Keep each task title under 120 characters.",
@@ -23347,6 +23385,9 @@ function runProcess2(args) {
23347
23385
  return new Promise((resolveProcess, rejectProcess) => {
23348
23386
  const child = spawn7(args.command, [...args.args], {
23349
23387
  cwd: args.cwd,
23388
+ // Inherit the runner env (codex auth, PATH, etc.) and layer the wafer
23389
+ // proxy credential (LINZUMI_LLM_PROXY_TOKEN) on top when wafer-routed.
23390
+ ...args.env === void 0 ? {} : { env: { ...process.env, ...args.env } },
23350
23391
  stdio: ["pipe", "ignore", "pipe"]
23351
23392
  });
23352
23393
  let stderr = "";
@@ -23387,9 +23428,15 @@ function runProcess2(args) {
23387
23428
  child.stdin?.end(args.stdin);
23388
23429
  });
23389
23430
  }
23431
+ var DEFAULT_CODEX_AUTH_SUGGESTION_MODEL, DEFAULT_WAFER_SUGGESTION_MODEL, SUGGESTION_TIMEOUT_MS, MAX_SCHEMA_REPAIR_ATTEMPTS;
23390
23432
  var init_signupTaskSuggestions = __esm({
23391
23433
  "src/signupTaskSuggestions.ts"() {
23392
23434
  "use strict";
23435
+ init_codexAppServer();
23436
+ DEFAULT_CODEX_AUTH_SUGGESTION_MODEL = "gpt-5.4-mini";
23437
+ DEFAULT_WAFER_SUGGESTION_MODEL = "GLM-5.2";
23438
+ SUGGESTION_TIMEOUT_MS = 15e4;
23439
+ MAX_SCHEMA_REPAIR_ATTEMPTS = 1;
23393
23440
  }
23394
23441
  });
23395
23442
 
@@ -27033,7 +27080,10 @@ async function openLocalCodexRunner(options, log2, cleanup, close, runnerDrainHo
27033
27080
  const entries = parseResumeReconcileEntries(reconcileValue);
27034
27081
  for (const entry of entries) {
27035
27082
  if (entry.leaseEpoch !== void 0) {
27036
- const adopted = leaseEpochRegistry.adopt(entry.threadId, entry.leaseEpoch);
27083
+ const adopted = leaseEpochRegistry.adopt(
27084
+ entry.threadId,
27085
+ entry.leaseEpoch
27086
+ );
27037
27087
  if (adopted) {
27038
27088
  log2("runner.resume_reconcile_lease_adopted", {
27039
27089
  kandanThreadId: entry.threadId,
@@ -27896,10 +27946,7 @@ function appliedSourceSeqStorePath(runnerId) {
27896
27946
  const sanitized = runnerId.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^[-.]+|[-.]+$/g, "").slice(0, 80);
27897
27947
  const digest = createHash7("sha256").update(runnerId).digest("hex").slice(0, 8);
27898
27948
  const stem = sanitized === "" ? "runner" : sanitized;
27899
- return join22(
27900
- controlCursorsDir(),
27901
- `${stem}.${digest}.source-seq.json`
27902
- );
27949
+ return join22(controlCursorsDir(), `${stem}.${digest}.source-seq.json`);
27903
27950
  }
27904
27951
  function startTurnWatermarkKey(topic, threadId) {
27905
27952
  return `${topic} ${threadId}`;
@@ -33486,6 +33533,26 @@ function projectPathExists(projectPath) {
33486
33533
  throw error;
33487
33534
  }
33488
33535
  }
33536
+ function resolveSuggestTasksModelProvider(control) {
33537
+ if (stringValue(control.modelProvider)?.trim() !== "wafer") {
33538
+ return void 0;
33539
+ }
33540
+ const llmProxy = objectValue(control.llmProxy);
33541
+ const baseUrl = stringValue(llmProxy?.baseUrl)?.trim();
33542
+ const token = stringValue(llmProxy?.token)?.trim();
33543
+ if (baseUrl === void 0 || baseUrl === "" || token === void 0 || token === "") {
33544
+ return void 0;
33545
+ }
33546
+ const runtime = {
33547
+ provider: "wafer",
33548
+ llmProxyBaseUrl: baseUrl,
33549
+ llmProxyToken: token
33550
+ };
33551
+ return {
33552
+ config: linzumiCodexModelProviderConfig(runtime),
33553
+ env: codexModelProviderAppServerEnv(runtime)
33554
+ };
33555
+ }
33489
33556
  async function suggestRunnerTasks(control, options, allowedCwds) {
33490
33557
  const requestId = stringValue(control.requestId) ?? null;
33491
33558
  const cwd = resolveAllowedCwd(control.cwd, allowedCwds);
@@ -33498,10 +33565,14 @@ async function suggestRunnerTasks(control, options, allowedCwds) {
33498
33565
  error: cwd.reason
33499
33566
  };
33500
33567
  }
33568
+ const modelProvider = resolveSuggestTasksModelProvider(control);
33569
+ const model = stringValue(control.model)?.trim();
33501
33570
  try {
33502
33571
  const tasks = await suggestSignupTasksWithCodex({
33503
33572
  projectPath: cwd.cwd,
33504
- codexBin: options.codexBin
33573
+ codexBin: options.codexBin,
33574
+ ...model === void 0 || model === "" ? {} : { model },
33575
+ ...modelProvider === void 0 ? {} : { modelProvider }
33505
33576
  });
33506
33577
  return {
33507
33578
  instanceId: options.runnerId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linzumi/cli",
3
- "version": "0.0.109-beta",
3
+ "version": "0.0.110-beta",
4
4
  "description": "Linzumi CLI \u2014 point a Codex agent at the real code on your laptop, with your team watching and steering from shared threads.",
5
5
  "type": "module",
6
6
  "bin": {