@saltpub/xiaojiu-agent-bridge 0.1.0 → 0.1.1

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,25 @@
1
1
  # xiaojiu-agent-bridge
2
2
 
3
+ ## 0.1.1
4
+
5
+ ### Highlights
6
+
7
+ - Harden npm update checks, terminal output, and semantic version handling.
8
+ - Keep release artifacts free of private repository metadata.
9
+
10
+ ### Changed
11
+
12
+ - Run automatic update checks after interactive commands finish and keep explicit checks separate.
13
+ - Require strict SemVer comparison for release discovery.
14
+ - Sanitize and bound release metadata before writing it to the terminal.
15
+
16
+ ### Fixed
17
+
18
+ - Show security-update metadata and keep manual update output on stdout.
19
+ - Avoid caching failed Registry checks for 24 hours.
20
+ - Match changelog versions exactly while retaining historical entries.
21
+ - Stop persisting write-capable GitHub credentials during release dependency installation.
22
+
3
23
  ## 0.1.0
4
24
 
5
25
  ### Highlights
@@ -23,3 +43,18 @@
23
43
  ### Fixed
24
44
 
25
45
  - Prevent private repository URLs, credentials, and source artifacts from entering the npm package.
46
+
47
+ ## 0.0.2
48
+
49
+ ### Highlights
50
+
51
+ - Omit repository metadata from the published npm package and reject source files in the tarball.
52
+
53
+ ### Added
54
+
55
+ - Align Xiaojiu IM APIs with the handbook.
56
+
57
+ ### Fixed
58
+
59
+ - Add `removeReaction` support for typecheck compatibility.
60
+ - Stream Markdown replies as cards.
package/README.md CHANGED
@@ -66,6 +66,7 @@ pnpm build
66
66
  npm install -g .
67
67
  ```
68
68
 
69
+
69
70
  ### 启动第一个 profile
70
71
 
71
72
  把占位符换成你的 Bot 凭据与 Bot Owner 工号:
@@ -131,10 +132,10 @@ xiaojiu-agent-bridge stop
131
132
 
132
133
  ## 版本更新
133
134
 
134
- CLI 在交互式终端中每 24 小时异步检查一次 npm Registry,不阻塞当前命令。也可以手动检查和查看随包发布的更新记录:
135
+ CLI 在交互式终端中每 24 小时检查一次 npm Registry,不阻塞命令启动。为避免干扰首次配置或交互式界面,提示只会在支持的终端会话中显示,并可随时手动检查和查看随包发布的更新记录:
135
136
 
136
137
  ```bash
137
- xiaojiu-agent-bridge update --check
138
+ xiaojiu-agent-bridge update
138
139
  xiaojiu-agent-bridge changelog
139
140
  npm install -g @saltpub/xiaojiu-agent-bridge@latest
140
141
  ```
package/dist/cli.js CHANGED
@@ -578,13 +578,30 @@ function compareVersions(left, right) {
578
578
  const difference = (a.numbers[index] ?? 0) - (b.numbers[index] ?? 0);
579
579
  if (difference !== 0) return difference;
580
580
  }
581
- if (a.prerelease === b.prerelease) return 0;
582
- if (!a.prerelease) return 1;
583
- if (!b.prerelease) return -1;
584
- return a.prerelease.localeCompare(b.prerelease, void 0, { numeric: true });
581
+ if (a.prerelease.length === 0 && b.prerelease.length === 0) return 0;
582
+ if (a.prerelease.length === 0) return 1;
583
+ if (b.prerelease.length === 0) return -1;
584
+ const length = Math.max(a.prerelease.length, b.prerelease.length);
585
+ for (let index = 0; index < length; index += 1) {
586
+ const leftPart = a.prerelease[index];
587
+ const rightPart = b.prerelease[index];
588
+ if (leftPart === void 0) return -1;
589
+ if (rightPart === void 0) return 1;
590
+ if (leftPart === rightPart) continue;
591
+ const leftNumeric = /^\d+$/.test(leftPart);
592
+ const rightNumeric = /^\d+$/.test(rightPart);
593
+ if (leftNumeric && rightNumeric) return Number(leftPart) - Number(rightPart);
594
+ if (leftNumeric) return -1;
595
+ if (rightNumeric) return 1;
596
+ return leftPart < rightPart ? -1 : 1;
597
+ }
598
+ return 0;
585
599
  }
586
600
  function parseUpdateInfo(metadata, currentVersion = version) {
587
- if (typeof metadata.version !== "string" || compareVersions(metadata.version, currentVersion) <= 0) {
601
+ if (typeof metadata.version !== "string") return void 0;
602
+ try {
603
+ if (compareVersions(metadata.version, currentVersion) <= 0) return void 0;
604
+ } catch {
588
605
  return void 0;
589
606
  }
590
607
  const update = metadata.xiaojiu?.update;
@@ -608,10 +625,14 @@ async function fetchUpdateInfo(options = {}) {
608
625
  headers: { accept: "application/json" },
609
626
  signal: controller.signal
610
627
  });
611
- if (!response.ok) return void 0;
628
+ if (!response.ok) {
629
+ if (options.throwOnError) throw new Error(`npm Registry returned ${response.status}`);
630
+ return void 0;
631
+ }
612
632
  const metadata = await response.json();
613
633
  return parseUpdateInfo(metadata, options.currentVersion ?? version);
614
- } catch {
634
+ } catch (error) {
635
+ if (options.throwOnError) throw error;
615
636
  return void 0;
616
637
  } finally {
617
638
  clearTimeout(timer);
@@ -622,19 +643,25 @@ async function maybeShowUpdateNotice() {
622
643
  const state = await readState();
623
644
  const lastChecked = Date.parse(state.lastCheckedAt ?? "");
624
645
  if (Number.isFinite(lastChecked) && Date.now() - lastChecked < CHECK_INTERVAL_MS) return;
625
- const info = await fetchUpdateInfo();
626
- await writeState({ ...state, lastCheckedAt: (/* @__PURE__ */ new Date()).toISOString() });
646
+ let info;
647
+ try {
648
+ info = await fetchUpdateInfo({ throwOnError: true });
649
+ } catch {
650
+ return;
651
+ }
652
+ const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
653
+ await writeState({ ...state, lastCheckedAt: checkedAt });
627
654
  if (!info || info.latestVersion === state.lastNotifiedVersion || info.latestVersion === state.skippedVersion) return;
628
- await writeState({ ...state, lastCheckedAt: (/* @__PURE__ */ new Date()).toISOString(), lastNotifiedVersion: info.latestVersion });
629
- printUpdateNotice(info);
655
+ await writeState({ ...state, lastCheckedAt: checkedAt, lastNotifiedVersion: info.latestVersion });
656
+ printUpdateNotice(info, process.stderr);
630
657
  }
631
658
  async function runUpdateCheck() {
632
659
  const info = await fetchUpdateInfo();
633
660
  if (!info) {
634
- console.log(`xiaojiu-agent-bridge ${version} is up to date, or the npm Registry is unavailable.`);
661
+ console.log(`${packageName} ${version} is up to date, or the npm Registry is unavailable.`);
635
662
  return;
636
663
  }
637
- printUpdateNotice(info);
664
+ printUpdateNotice(info, process.stdout);
638
665
  }
639
666
  async function runChangelog(requestedVersion) {
640
667
  const changelog = await readFile(changelogPath(), "utf8");
@@ -647,21 +674,24 @@ async function runChangelog(requestedVersion) {
647
674
  `);
648
675
  }
649
676
  function extractChangelogSection(markdown, requestedVersion) {
650
- const heading = `## ${requestedVersion}`;
651
- const start = markdown.indexOf(heading);
652
- if (start < 0) return void 0;
653
- const after = markdown.slice(start + heading.length);
677
+ const escapedVersion = requestedVersion.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
678
+ const match = new RegExp(`^## ${escapedVersion}\\s*$`, "m").exec(markdown);
679
+ if (!match || match.index === void 0) return void 0;
680
+ const start = match.index;
681
+ const after = markdown.slice(start + match[0].length);
654
682
  const next = after.search(/\n## /);
655
683
  const body = next < 0 ? after : after.slice(0, next);
656
- return `${heading}${body}`.trim();
684
+ return `${match[0]}${body}`.trim();
657
685
  }
658
- function printUpdateNotice(info) {
686
+ function printUpdateNotice(info, stream2) {
659
687
  const lines = [`A new version of ${packageName} is available: ${info.currentVersion} -> ${info.latestVersion}`, "", "Run:", ` npm install -g ${packageName}@latest`];
688
+ if (info.securityFix) lines.push("", "Security update: updating promptly is recommended.");
660
689
  if (info.requiresRestart) lines.push("", "Restart the bridge after updating: `xiaojiu-agent-bridge restart`");
661
690
  if (info.breakingChanges.length > 0) lines.push("", "Breaking changes:", ...info.breakingChanges.map((item) => ` - ${item}`));
662
691
  if (info.highlights.length > 0) lines.push("", "What's new:", ...info.highlights.map((item) => ` - ${item}`));
663
692
  lines.push("", "View details with:", " xiaojiu-agent-bridge changelog");
664
- console.error(lines.join("\n"));
693
+ stream2.write(`${lines.join("\n")}
694
+ `);
665
695
  }
666
696
  function isUpdateCheckDisabled() {
667
697
  return process.env.XIAOJIU_BRIDGE_NO_UPDATE_CHECK === "1" || process.env.CI === "true" || process.env.TERM === "dumb" || !process.stdin.isTTY || !process.stdout.isTTY;
@@ -696,15 +726,18 @@ async function writeState(state) {
696
726
  }
697
727
  }
698
728
  function parseVersion(value) {
699
- const match = value.trim().replace(/^v/, "").match(/^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-([^+]+))?/);
700
- if (!match) return { numbers: [0], prerelease: value };
729
+ const match = value.trim().match(
730
+ /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/
731
+ );
732
+ if (!match) throw new Error(`invalid semantic version: ${value}`);
701
733
  return {
702
- numbers: [Number(match[1]), Number(match[2] ?? 0), Number(match[3] ?? 0)],
703
- prerelease: match[4] ?? ""
734
+ numbers: [Number(match[1]), Number(match[2]), Number(match[3])],
735
+ prerelease: match[4]?.split(".") ?? []
704
736
  };
705
737
  }
706
738
  function stringList(value) {
707
- return Array.isArray(value) ? value.filter((item) => typeof item === "string" && item.trim().length > 0) : [];
739
+ if (!Array.isArray(value)) return [];
740
+ return value.filter((item) => typeof item === "string").map((item) => item.replace(/[\u0000-\u001f\u007f-\u009f]/g, " ").trim().slice(0, 200)).filter((item) => item.length > 0).slice(0, 5);
708
741
  }
709
742
 
710
743
  // src/runtime/listen-sidecar.ts
@@ -16634,7 +16667,7 @@ function openBrowser(url) {
16634
16667
  // src/cli/index.ts
16635
16668
  var program = new Command();
16636
16669
  program.name("xiaojiu-agent-bridge").description(`Bridge Xiaojiu IM with local CLI coding agents (${packageName})`).version(version, "-v, --version");
16637
- program.command("update").description("Check for a newer npm package version").option("--check", "check without installing").action(async (opts) => {
16670
+ program.command("update").description("Check for a newer npm package version").action(async () => {
16638
16671
  await runUpdateCheck();
16639
16672
  });
16640
16673
  program.command("changelog [version]").description("Show release notes for the installed version").action(async (requestedVersion) => {
@@ -16704,8 +16737,11 @@ secrets.command("list").description("List the IDs of secrets in the encrypted ke
16704
16737
  secrets.command("remove").description("Delete an entry from the encrypted keystore").requiredOption("--app-id <id>", "App ID to remove").option("--profile <name>", "profile name (defaults to active profile)").action(async (opts) => {
16705
16738
  await runSecretsRemove(opts.appId, { profile: opts.profile });
16706
16739
  });
16707
- void maybeShowUpdateNotice();
16708
- program.parseAsync(process.argv).catch((err) => {
16740
+ program.parseAsync(process.argv).then(async () => {
16741
+ if (process.argv[2] !== "update" && process.argv[2] !== "changelog") {
16742
+ await maybeShowUpdateNotice();
16743
+ }
16744
+ }).catch((err) => {
16709
16745
  const diagnostic = getAgentPreflightDiagnostic(err);
16710
16746
  if (diagnostic) {
16711
16747
  console.error(formatAgentPreflightDiagnostic(diagnostic));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltpub/xiaojiu-agent-bridge",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Bridge Xiaojiu IM with local CLI coding agents",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.33.0",
@@ -108,11 +108,11 @@
108
108
  "schemaVersion": 1,
109
109
  "channel": "stable",
110
110
  "highlights": [
111
- "Add npm-based update checks and a local changelog command.",
112
- "Publish the first scoped package under the SaltPub organization."
111
+ "Harden npm update checks, terminal output, and semantic version handling.",
112
+ "Keep release artifacts free of private repository metadata."
113
113
  ],
114
114
  "breakingChanges": [],
115
- "securityFix": false,
115
+ "securityFix": true,
116
116
  "requiresRestart": false
117
117
  }
118
118
  }