flavor-code 1.4.0-beta.5 → 1.4.0-beta.7

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.
@@ -10,7 +10,7 @@ import {
10
10
  useStdout,
11
11
  use_app_default,
12
12
  use_input_default
13
- } from "./chunk-IQAZ42TM.js";
13
+ } from "./chunk-XMRKRPNC.js";
14
14
  import "./chunk-ZJCAQXA7.js";
15
15
  import "./chunk-S32JRDZK.js";
16
16
  export {
package/dist/cli-main.js CHANGED
@@ -3,10 +3,10 @@ import { createRequire } from "node:module"; const require = createRequire(impor
3
3
  import {
4
4
  FlavorRpcServer,
5
5
  TraceRecorder
6
- } from "./chunk-JZVC4477.js";
6
+ } from "./chunk-PT72RZVC.js";
7
7
  import {
8
8
  staticTaskLines
9
- } from "./chunk-2BF7CVWZ.js";
9
+ } from "./chunk-RAYH6K2H.js";
10
10
  import {
11
11
  DEFAULT_MAX_OUTPUT_BYTES,
12
12
  MAX_ALIAS_LENGTH,
@@ -29,7 +29,7 @@ import {
29
29
  redactErrorText,
30
30
  runDoctor,
31
31
  runPalBroker
32
- } from "./chunk-J7TLT6LR.js";
32
+ } from "./chunk-ITKOMJD6.js";
33
33
  import {
34
34
  MEMORY_RESTART_EXIT_CODE
35
35
  } from "./chunk-N5MXHJKD.js";
@@ -85,6 +85,25 @@ async function runUpdate(options = {}) {
85
85
  return exitCode === 0 ? { status: "updated", current, latest } : { status: "install-failed", current, latest, exitCode };
86
86
  }
87
87
 
88
+ // src/ui/user-timing.ts
89
+ import { performance } from "perf_hooks";
90
+ function clearUiUserTimingEntries() {
91
+ performance.clearMarks();
92
+ performance.clearMeasures();
93
+ }
94
+ function installUiUserTimingSweeper(intervalMs = 250) {
95
+ if (!Number.isSafeInteger(intervalMs) || intervalMs <= 0) {
96
+ throw new Error("User Timing sweep interval must be a positive integer");
97
+ }
98
+ clearUiUserTimingEntries();
99
+ const timer = setInterval(clearUiUserTimingEntries, intervalMs);
100
+ timer.unref();
101
+ return () => {
102
+ clearInterval(timer);
103
+ clearUiUserTimingEntries();
104
+ };
105
+ }
106
+
88
107
  // src/skills/manager.ts
89
108
  import { lstat, mkdir, readFile, readdir, realpath, rm, writeFile } from "fs/promises";
90
109
  import { homedir } from "os";
@@ -897,17 +916,22 @@ function createProgram(dependencies = {}) {
897
916
  return program;
898
917
  }
899
918
  async function runInteractiveCli(props) {
900
- const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
901
- import("./claude-ink-ECZ6QF3P.js"),
902
- import("react"),
903
- import("./app-SXNJDSI2.js")
904
- ]);
905
- const instance = await render(createElement(
906
- AlternateScreen,
907
- { mouseTracking: true },
908
- createElement(App, props)
909
- ), { exitOnCtrlC: false });
910
- await instance.waitUntilExit();
919
+ const disposeUserTimingSweeper = installUiUserTimingSweeper();
920
+ try {
921
+ const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
922
+ import("./claude-ink-6EZHF64C.js"),
923
+ import("react"),
924
+ import("./app-H2XGMAOY.js")
925
+ ]);
926
+ const instance = await render(createElement(
927
+ AlternateScreen,
928
+ { mouseTracking: true },
929
+ createElement(App, props)
930
+ ), { exitOnCtrlC: false });
931
+ await instance.waitUntilExit();
932
+ } finally {
933
+ disposeUserTimingSweeper();
934
+ }
911
935
  }
912
936
  function parsePalAlias(value) {
913
937
  const alias = value.trim();
package/dist/cli.js CHANGED
@@ -109,7 +109,10 @@ async function launchCli() {
109
109
  }
110
110
  }
111
111
  async function spawnAndWait(mainPath, argv, heapProfile) {
112
- const child = spawn(process.execPath, cliMainArguments(mainPath, argv, heapProfile), { stdio: "inherit" });
112
+ const child = spawn(process.execPath, cliMainArguments(mainPath, argv, heapProfile), {
113
+ stdio: "inherit",
114
+ env: { ...process.env, NODE_ENV: "production" }
115
+ });
113
116
  const ignoreSignal = () => {
114
117
  };
115
118
  process.on("SIGINT", ignoreSignal);
@@ -4234,6 +4234,7 @@ import { mkdirSync as mkdirSync4, readFileSync as readFileSync3, renameSync as r
4234
4234
  import { createHash as createHash21, randomUUID as randomUUID25 } from "crypto";
4235
4235
  import { homedir as homedir3, release as osRelease, tmpdir as tmpdir4, version as osVersion } from "os";
4236
4236
  import { basename as basename9, dirname as dirname22, join as join38, relative as relative25, resolve as resolve36, sep as sep25 } from "path";
4237
+ import { performance } from "perf_hooks";
4237
4238
 
4238
4239
  // src/agent/subagents.ts
4239
4240
  import { z as z10 } from "zod";
@@ -16370,7 +16371,7 @@ function transcriptReducer(state, action) {
16370
16371
  return finishActive(withUsage);
16371
16372
  }
16372
16373
  if (event.type === "text") {
16373
- return { ...state, active: addText(withoutModelActivity(state.active), event.text) };
16374
+ return { ...state, active: addStreamingText(state.active, event.text) };
16374
16375
  }
16375
16376
  if (event.type === "thinking") {
16376
16377
  return { ...state, active: attachThinking(state.active, event.text) };
@@ -16828,6 +16829,17 @@ function addText(turn, text, onNewLine = false) {
16828
16829
  }
16829
16830
  return withBlocks({ ...turn, assistantText }, blocks);
16830
16831
  }
16832
+ function addStreamingText(turn, text) {
16833
+ const activity = turn.blocks.find((block) => block.kind === "status" && block.activity === "model" && block.state === "running");
16834
+ if (activity === void 0) return addText(turn, text);
16835
+ const withoutActivity = withBlocks(turn, turn.blocks.filter((block) => block !== activity));
16836
+ const withText = addText(withoutActivity, text);
16837
+ const { thinkingText: _thinkingText, ...writingActivity } = activity;
16838
+ return withBlocks(withText, [...withText.blocks, {
16839
+ ...writingActivity,
16840
+ text: "Writing response"
16841
+ }]);
16842
+ }
16831
16843
  function boundedTranscriptBlock(block) {
16832
16844
  const presentation = block.presentation === void 0 ? void 0 : boundedTranscriptPresentation(block.presentation);
16833
16845
  const tool = block.tool === void 0 ? void 0 : {
@@ -20310,10 +20322,12 @@ var LspConnection = class {
20310
20322
  this.#disposed = true;
20311
20323
  this.#rejectAll(new Error("LSP connection disposed"));
20312
20324
  this.#shutdownPromise = (async () => {
20325
+ const closed = waitForProcessClose(this.#process);
20313
20326
  await terminateProcessTree3(this.#process.pid);
20314
20327
  this.#process.stdin.destroy();
20315
20328
  this.#process.stdout.destroy();
20316
20329
  this.#process.stderr.destroy();
20330
+ await closed;
20317
20331
  })();
20318
20332
  return this.#shutdownPromise;
20319
20333
  }
@@ -20432,6 +20446,18 @@ var LspConnection = class {
20432
20446
  this.#pending.clear();
20433
20447
  }
20434
20448
  };
20449
+ function waitForProcessClose(child) {
20450
+ if (child.exitCode !== null || child.signalCode !== null) return Promise.resolve();
20451
+ return new Promise((resolveClose) => {
20452
+ const finish = () => {
20453
+ clearTimeout(timer);
20454
+ resolveClose();
20455
+ };
20456
+ const timer = setTimeout(finish, 2e3);
20457
+ timer.unref();
20458
+ child.once("close", finish);
20459
+ });
20460
+ }
20435
20461
  var LspBuffer = class {
20436
20462
  #data = Buffer.alloc(0);
20437
20463
  feed(chunk, onMessage) {
@@ -20462,7 +20488,7 @@ var TYPESCRIPT_CLI = resolve26(
20462
20488
  var KNOWN_SERVERS = [
20463
20489
  {
20464
20490
  language: "typescript",
20465
- extensions: [".ts", ".tsx", ".mts", ".cts"],
20491
+ extensions: [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"],
20466
20492
  command: process.execPath,
20467
20493
  args: [TYPESCRIPT_CLI, "--lsp", "--stdio"],
20468
20494
  rootFiles: ["tsconfig.json", "jsconfig.json"]
@@ -20547,35 +20573,39 @@ var RealLspManager = class {
20547
20573
  if (this.#disposed) throw new Error("LSP manager is disposed");
20548
20574
  const language = this.#languageForUri(uri);
20549
20575
  if (language === void 0) throw new Error(`No language server configured for ${uri}; use Read/Grep or the project compiler`);
20550
- const existing = this.#connections.get(language);
20551
- if (existing !== void 0) return existing;
20552
- const pending2 = this.#pendingStarts.get(language);
20553
- if (pending2 !== void 0) return pending2;
20554
20576
  const config = this.#serverConfigs.find((c) => c.language === language);
20555
20577
  if (config === void 0) throw new Error(`No language server configured for ${language}`);
20556
- const hasRoot = config.rootFiles.some((file) => existsSync5(resolve26(this.#workspace, file)));
20557
- if (!hasRoot) throw new Error(`Cannot start ${language} language server: workspace needs ${config.rootFiles.join(" or ")}`);
20558
- const startPromise = this.#startServer(config);
20559
- this.#pendingStarts.set(language, startPromise);
20578
+ const filePath = uriToPath(uri);
20579
+ const projectRoot = findLanguageServerRoot(filePath, this.#workspace, config.rootFiles);
20580
+ if (projectRoot === void 0) {
20581
+ throw new Error(`Cannot start ${language} language server: no ${config.rootFiles.join(" or ")} found from ${dirname18(filePath)} up to workspace ${this.#workspace}`);
20582
+ }
20583
+ const connectionKey = `${language}:${projectRoot}`;
20584
+ const existing = this.#connections.get(connectionKey);
20585
+ if (existing !== void 0) return existing;
20586
+ const pending2 = this.#pendingStarts.get(connectionKey);
20587
+ if (pending2 !== void 0) return pending2;
20588
+ const startPromise = this.#startServer(config, projectRoot);
20589
+ this.#pendingStarts.set(connectionKey, startPromise);
20560
20590
  try {
20561
20591
  const connection = await startPromise;
20562
20592
  if (this.#disposed) {
20563
20593
  await connection.shutdown();
20564
20594
  throw new Error("LSP manager is disposed");
20565
20595
  }
20566
- this.#connections.set(language, connection);
20596
+ this.#connections.set(connectionKey, connection);
20567
20597
  return connection;
20568
20598
  } finally {
20569
- this.#pendingStarts.delete(language);
20599
+ this.#pendingStarts.delete(connectionKey);
20570
20600
  }
20571
20601
  }
20572
- async #startServer(config) {
20602
+ async #startServer(config, projectRoot) {
20573
20603
  try {
20574
20604
  await access2(config.command, constants10.X_OK);
20575
20605
  } catch {
20576
20606
  }
20577
- const connection = new LspConnection(config.command, config.args, this.#workspace);
20578
- const rootUri = pathToFileURL3(this.#workspace).href;
20607
+ const connection = new LspConnection(config.command, config.args, projectRoot);
20608
+ const rootUri = pathToFileURL3(projectRoot).href;
20579
20609
  try {
20580
20610
  await connection.initialize(rootUri);
20581
20611
  this.#onStatus?.(`${config.language} Language Server ready (${config.command})`);
@@ -20611,7 +20641,21 @@ function createLspTools(workspace, options = {}) {
20611
20641
  const toUri = (filePath) => pathToFileURL3(filePath).href;
20612
20642
  const langTag = (file) => {
20613
20643
  const ext = file.slice(file.lastIndexOf(".")).toLowerCase();
20614
- const map = { ".ts": "ts", ".tsx": "tsx", ".mts": "ts", ".cts": "ts", ".py": "py", ".pyi": "py", ".pyx": "py", ".rs": "rs", ".go": "go" };
20644
+ const map = {
20645
+ ".ts": "ts",
20646
+ ".tsx": "tsx",
20647
+ ".mts": "ts",
20648
+ ".cts": "ts",
20649
+ ".js": "js",
20650
+ ".jsx": "jsx",
20651
+ ".mjs": "js",
20652
+ ".cjs": "js",
20653
+ ".py": "py",
20654
+ ".pyi": "py",
20655
+ ".pyx": "py",
20656
+ ".rs": "rs",
20657
+ ".go": "go"
20658
+ };
20615
20659
  const tag = map[ext];
20616
20660
  return tag === void 0 ? "" : " [" + tag + "]";
20617
20661
  };
@@ -20679,6 +20723,12 @@ function languageIdForPath(filePath) {
20679
20723
  return "typescript";
20680
20724
  case ".cts":
20681
20725
  return "typescript";
20726
+ case ".jsx":
20727
+ return "javascriptreact";
20728
+ case ".js":
20729
+ case ".mjs":
20730
+ case ".cjs":
20731
+ return "javascript";
20682
20732
  case ".py":
20683
20733
  case ".pyi":
20684
20734
  case ".pyx":
@@ -20691,6 +20741,19 @@ function languageIdForPath(filePath) {
20691
20741
  return "typescript";
20692
20742
  }
20693
20743
  }
20744
+ function findLanguageServerRoot(filePath, workspace, rootFiles) {
20745
+ const root = resolve26(workspace);
20746
+ const target = resolve26(filePath);
20747
+ if (!isWithin7(root, target)) return void 0;
20748
+ let current = dirname18(target);
20749
+ while (true) {
20750
+ if (rootFiles.some((file) => existsSync5(resolve26(current, file)))) return current;
20751
+ if (current === root) return void 0;
20752
+ const parent = dirname18(current);
20753
+ if (parent === current || !isWithin7(root, parent)) return void 0;
20754
+ current = parent;
20755
+ }
20756
+ }
20694
20757
  function isWithin7(root, candidate) {
20695
20758
  const delta = relative18(root, candidate);
20696
20759
  return delta === "" || !delta.startsWith(`..${sep18}`) && delta !== ".." && !isAbsolute14(delta);
@@ -27876,6 +27939,12 @@ async function createProductionRuntime(options) {
27876
27939
  holders.transcriptTurns = { entries: transcript.turns };
27877
27940
  } catch {
27878
27941
  }
27942
+ try {
27943
+ holders.userTiming = {
27944
+ entries: performance.getEntriesByType("measure").length + performance.getEntriesByType("mark").length
27945
+ };
27946
+ } catch {
27947
+ }
27879
27948
  return holders;
27880
27949
  };
27881
27950
  const rotateForHeap = (continuation, reading) => {