@botconnector/bccli 0.4.0-beta.52 → 0.4.0-beta.54

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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/version.ts
4
- var VERSION = true ? "0.4.0-beta.52" : "0.0.0-dev";
4
+ var VERSION = true ? "0.4.0-beta.54" : "0.0.0-dev";
5
5
 
6
6
  export {
7
7
  VERSION
package/dist/cli.js CHANGED
@@ -12,7 +12,7 @@ import "./chunk-YATYUXV7.js";
12
12
  import "./chunk-PSO7R5AD.js";
13
13
  import {
14
14
  VERSION
15
- } from "./chunk-6R2PPFNJ.js";
15
+ } from "./chunk-LBNANSVM.js";
16
16
  import {
17
17
  helpText,
18
18
  parseCliArgs
@@ -108,7 +108,7 @@ async function main() {
108
108
  return runModelsCommand(args, { env: process.env, cwd, out: (s) => console.log(s), err: (s) => console.error(s), fetch: globalThis.fetch });
109
109
  }
110
110
  if (args.command === "update") {
111
- const { runUpdateCommand } = await import("./update-4SHBDS75.js");
111
+ const { runUpdateCommand } = await import("./update-XDZMIKBE.js");
112
112
  return runUpdateCommand({ env: process.env });
113
113
  }
114
114
  if (args.command === "acp") {
@@ -117,7 +117,7 @@ async function main() {
117
117
  return 0;
118
118
  }
119
119
  if (args.command === "serve") {
120
- const { startServe } = await import("./serve-GNXXNI6U.js");
120
+ const { startServe } = await import("./serve-2MQ3XLGL.js");
121
121
  const handle = await startServe({ port: args.port, host: args.host, token: args.token, cwd, env: process.env });
122
122
  process.stderr.write(`bccli serve ${handle.url} \u2014 Authorization: Bearer ${handle.token}
123
123
  `);
@@ -193,16 +193,17 @@ async function main() {
193
193
  }
194
194
  }
195
195
  if (!process.stdin.isTTY) throw new ConfigError(t('Interactive mode needs a terminal. For scripts/CI use: bccli -p "task"'));
196
+ let updateMessage;
196
197
  if (rt.config.updateCheck !== "off" && !process.env.BCCLI_NO_UPDATE_CHECK) {
197
198
  try {
198
- const { checkForUpdate } = await import("./update-4SHBDS75.js");
199
+ const { checkForUpdate } = await import("./update-XDZMIKBE.js");
199
200
  const update = await checkForUpdate({ home: rt.home, fetch: globalThis.fetch, now: /* @__PURE__ */ new Date() });
200
- if (update) console.error(update);
201
+ updateMessage = update;
201
202
  } catch {
202
203
  }
203
204
  }
204
- const { startInteractive } = await import("./ui-XDLB6OW7.js");
205
- return startInteractive(rt, { initialPrompt: args.prompt, resume: args.resume, version: VERSION });
205
+ const { startInteractive } = await import("./ui-WJQWXRPP.js");
206
+ return startInteractive(rt, { initialPrompt: args.prompt, resume: args.resume, version: VERSION, updateMessage });
206
207
  }
207
208
  main().then(
208
209
  (code) => settleExit(code),
@@ -8,7 +8,7 @@ import "./chunk-YATYUXV7.js";
8
8
  import "./chunk-PSO7R5AD.js";
9
9
  import {
10
10
  VERSION
11
- } from "./chunk-6R2PPFNJ.js";
11
+ } from "./chunk-LBNANSVM.js";
12
12
  import {
13
13
  LOOPBACK_BIND,
14
14
  MAX_FRAME_BYTES,
@@ -1535,10 +1535,10 @@ function helpText(runtime) {
1535
1535
  }
1536
1536
  var INIT_PROMPT = "Study this project (folder structure, package/build files, test and lint commands, visible code conventions). Then create AGENTS.md in the project root, or update it if it already exists, covering: how to build, test, and lint; a short structure overview; important conventions. Keep it concise and factual, only what actually exists in the project.";
1537
1537
  var labelFor = (runtime, ref) => `${ref.slice(ref.indexOf("/") + 1)} \xB7 ${runtime.providerLabel()}`;
1538
- function App({ runtime, initialPrompt, version }) {
1538
+ function App({ runtime, initialPrompt, version, updateMessage }) {
1539
1539
  const { exit } = useApp();
1540
1540
  const [transcript, setTranscript] = useState8(() => ({
1541
- done: [entry({ kind: "header" }), ...runtime.agent.messages.length ? replayEntries(runtime.session.loadHistory()) : []],
1541
+ done: [entry({ kind: "header" }), ...updateMessage ? [entry({ kind: "notice", text: updateMessage, tone: "warn" })] : [], ...runtime.agent.messages.length ? replayEntries(runtime.session.loadHistory()) : []],
1542
1542
  live: []
1543
1543
  }));
1544
1544
  const [busy, setBusy] = useState8(false);
@@ -2355,7 +2355,7 @@ async function startInteractive(rt, opts) {
2355
2355
  void rt.startMcp(plan.start).catch((error) => {
2356
2356
  console.error(t("Could not start MCP servers: {error}", { error: error instanceof Error ? error.message : String(error) }));
2357
2357
  });
2358
- const instance = render(/* @__PURE__ */ jsx17(App, { runtime: rt, initialPrompt: opts.initialPrompt, version: opts.version }), { exitOnCtrlC: true });
2358
+ const instance = render(/* @__PURE__ */ jsx17(App, { runtime: rt, initialPrompt: opts.initialPrompt, version: opts.version, updateMessage: opts.updateMessage }), { exitOnCtrlC: true });
2359
2359
  await instance.waitUntilExit();
2360
2360
  await rt.mcp.stop();
2361
2361
  return 0;
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  VERSION
4
- } from "./chunk-6R2PPFNJ.js";
4
+ } from "./chunk-LBNANSVM.js";
5
5
  import {
6
6
  t
7
7
  } from "./chunk-LUTJZME3.js";
8
8
 
9
9
  // src/update.ts
10
10
  import { spawnSync } from "child_process";
11
- import { mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
12
- import { join } from "path";
11
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
12
+ import { dirname, join } from "path";
13
13
  var REGISTRY_URL = "https://registry.npmjs.org/-/package/@botconnector/bccli/dist-tags";
14
14
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
15
15
  function splitVersion(v) {
@@ -74,29 +74,44 @@ function dueForCheck(cache, now, intervalMs = CHECK_INTERVAL_MS) {
74
74
  return now.getTime() - at >= intervalMs;
75
75
  }
76
76
  function updateNotice(current, latest) {
77
- if (!latest || compareVersions(current, latest) >= 0) return void 0;
77
+ if (!latest || latest.length > 64 || !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(latest) || compareVersions(current, latest) >= 0) return void 0;
78
78
  return t("A new bccli is available: {latest} (you have {current}). Run: bccli update", { latest, current });
79
79
  }
80
+ function notifyOnce(home, cache) {
81
+ const message = updateNotice(VERSION, cache?.latest);
82
+ if (!message || !cache?.latest || cache.notified === cache.latest) return void 0;
83
+ writeCache(home, { ...cache, notified: cache.latest });
84
+ return message;
85
+ }
80
86
  async function checkForUpdate(deps) {
81
87
  try {
82
88
  const cached = readCache(deps.home);
83
- if (!dueForCheck(cached, deps.now)) return updateNotice(VERSION, cached?.latest);
89
+ if (!dueForCheck(cached, deps.now)) return notifyOnce(deps.home, cached);
84
90
  const res = await deps.fetch(REGISTRY_URL, { signal: AbortSignal.timeout(deps.timeoutMs ?? 3e3) });
85
- if (!res.ok) return updateNotice(VERSION, cached?.latest);
91
+ if (!res.ok) return notifyOnce(deps.home, cached);
86
92
  const tags = await res.json();
87
93
  const latest = tags[channelFor(VERSION)] ?? tags.latest;
88
- writeCache(deps.home, { checkedAt: deps.now.toISOString(), latest });
89
- return updateNotice(VERSION, latest);
94
+ const updated = { checkedAt: deps.now.toISOString(), latest, notified: cached?.notified };
95
+ writeCache(deps.home, updated);
96
+ return notifyOnce(deps.home, updated);
90
97
  } catch {
91
98
  return void 0;
92
99
  }
93
100
  }
94
- async function runUpdateCommand(deps) {
95
- const version = deps.env.BCCLI_VERSION_OVERRIDE ?? VERSION;
101
+ function updateSpawnCommand(version, platform = process.platform, nodeExecPath = process.execPath) {
96
102
  const spec = `@botconnector/bccli@${channelFor(version)}`;
97
- const spawnFn = deps.spawn ?? spawnSync;
98
- const cmd = process.platform === "win32" ? "npm.cmd" : "npm";
99
- const r = spawnFn(cmd, ["i", "-g", spec], { stdio: "inherit", env: deps.env });
103
+ if (platform !== "win32") return { command: "npm", args: ["i", "-g", spec] };
104
+ const npmCli = join(dirname(nodeExecPath), "node_modules", "npm", "bin", "npm-cli.js");
105
+ return { command: nodeExecPath, args: [npmCli, "i", "-g", spec], npmCli };
106
+ }
107
+ async function runUpdateCommand(deps) {
108
+ const spec = updateSpawnCommand(deps.env.BCCLI_VERSION_OVERRIDE ?? VERSION, deps.platform, deps.nodeExecPath);
109
+ if (spec.npmCli && !existsSync(spec.npmCli)) {
110
+ console.error(`npm CLI was not found at ${spec.npmCli}. Update manually with: npm install -g @botconnector/bccli@${channelFor(deps.env.BCCLI_VERSION_OVERRIDE ?? VERSION)}`);
111
+ return 1;
112
+ }
113
+ const r = (deps.spawn ?? spawnSync)(spec.command, spec.args, { stdio: "inherit", env: deps.env, shell: false });
114
+ if (r.error) console.error(`BCCLI update failed: ${r.error.message}. Try: npm install -g @botconnector/bccli@${channelFor(deps.env.BCCLI_VERSION_OVERRIDE ?? VERSION)}`);
100
115
  return typeof r.status === "number" ? r.status : 1;
101
116
  }
102
117
  export {
@@ -105,5 +120,6 @@ export {
105
120
  compareVersions,
106
121
  dueForCheck,
107
122
  runUpdateCommand,
108
- updateNotice
123
+ updateNotice,
124
+ updateSpawnCommand
109
125
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botconnector/bccli",
3
- "version": "0.4.0-beta.52",
3
+ "version": "0.4.0-beta.54",
4
4
  "description": "BCCLI — BotConnector AI coding agent for the terminal",
5
5
  "type": "module",
6
6
  "bin": {