@teamclaws/teamclaw 2026.3.24-3 → 2026.3.24-5

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/cli.mjs CHANGED
@@ -1,14 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { spawnSync } from "node:child_process";
4
+ import fsSync from "node:fs";
4
5
  import fs from "node:fs/promises";
6
+ import { createRequire } from "node:module";
5
7
  import os from "node:os";
6
8
  import path from "node:path";
7
9
  import process from "node:process";
8
10
  import { createInterface } from "node:readline/promises";
9
11
  import JSON5 from "json5";
10
12
 
11
- const PACKAGE_NAME = "@teamclaws/teamclaw";
13
+ const require = createRequire(import.meta.url);
14
+ const packageMetadata = require("./package.json");
15
+ const PACKAGE_ROOT = path.dirname(require.resolve("./package.json"));
16
+ const PACKAGE_NAME = packageMetadata.name;
17
+ const PACKAGE_VERSION = packageMetadata.version;
18
+ const PACKAGE_INSTALL_SPEC = `${PACKAGE_NAME}@${PACKAGE_VERSION}`;
12
19
  const PLUGIN_ID = "teamclaw";
13
20
  const DEFAULT_TEAMCLAW_IMAGE = "ghcr.io/topcheer/teamclaw-openclaw:latest";
14
21
  const DEFAULT_CONTROLLER_PORT = 9527;
@@ -539,54 +546,132 @@ function installPluginWithCommand(command, args, env) {
539
546
  };
540
547
  }
541
548
 
549
+ function createPackageTarball(env) {
550
+ let tempDir = "";
551
+ try {
552
+ tempDir = fsSync.mkdtempSync(path.join(os.tmpdir(), "teamclaw-installer-pack-"));
553
+ const result = spawnSync(
554
+ "npm",
555
+ ["pack", PACKAGE_ROOT, "--pack-destination", tempDir, "--json", "--ignore-scripts"],
556
+ {
557
+ env,
558
+ encoding: "utf8",
559
+ },
560
+ );
561
+ if (result.status !== 0 || result.error) {
562
+ const detail = result.error
563
+ ? result.error.message
564
+ : (result.stderr || result.stdout || `exited with code ${result.status}`).trim();
565
+ throw new Error(detail || "npm pack failed");
566
+ }
567
+ const payload = JSON.parse(result.stdout);
568
+ const filename = Array.isArray(payload) && payload[0] && typeof payload[0].filename === "string"
569
+ ? payload[0].filename.trim()
570
+ : "";
571
+ if (!filename) {
572
+ throw new Error("npm pack did not report a tarball filename");
573
+ }
574
+ const tarballPath = path.join(tempDir, filename);
575
+ if (!fsSync.existsSync(tarballPath)) {
576
+ throw new Error(`tarball was not created at ${tarballPath}`);
577
+ }
578
+ return {
579
+ ok: true,
580
+ tempDir,
581
+ tarballPath,
582
+ };
583
+ } catch (error) {
584
+ if (tempDir) {
585
+ fsSync.rmSync(tempDir, { recursive: true, force: true });
586
+ }
587
+ return {
588
+ ok: false,
589
+ error: error instanceof Error ? error.message : String(error),
590
+ };
591
+ }
592
+ }
593
+
542
594
  function attemptPluginInstall({ configPath }) {
543
595
  const env = {
544
596
  ...process.env,
545
597
  OPENCLAW_CONFIG_PATH: configPath,
546
598
  };
547
- const candidates = [
599
+ const candidates = [];
600
+ const tarballResult = createPackageTarball(env);
601
+ if (tarballResult.ok) {
602
+ console.log(
603
+ `\nPacked ${PACKAGE_INSTALL_SPEC} into ${path.basename(tarballResult.tarballPath)} for local plugin install.`,
604
+ );
605
+ candidates.push(
606
+ {
607
+ label: "openclaw (local tarball)",
608
+ command: "openclaw",
609
+ args: ["plugins", "install", tarballResult.tarballPath],
610
+ targetDescription: tarballResult.tarballPath,
611
+ },
612
+ {
613
+ label: "npm exec fallback (local tarball)",
614
+ command: "npm",
615
+ args: ["exec", "-y", "openclaw@latest", "--", "plugins", "install", tarballResult.tarballPath],
616
+ targetDescription: tarballResult.tarballPath,
617
+ },
618
+ );
619
+ } else {
620
+ console.log(
621
+ `\nCould not pack ${PACKAGE_INSTALL_SPEC} into a local tarball (${tarballResult.error}). Falling back to registry install...`,
622
+ );
623
+ }
624
+ candidates.push(
548
625
  {
549
- label: "openclaw",
626
+ label: "openclaw (exact version fallback)",
550
627
  command: "openclaw",
551
- args: ["plugins", "install", PACKAGE_NAME],
628
+ args: ["plugins", "install", PACKAGE_INSTALL_SPEC],
629
+ targetDescription: PACKAGE_INSTALL_SPEC,
552
630
  },
553
631
  {
554
- label: "npm exec fallback",
632
+ label: "npm exec fallback (exact version fallback)",
555
633
  command: "npm",
556
- args: ["exec", "-y", "openclaw@latest", "--", "plugins", "install", PACKAGE_NAME],
634
+ args: ["exec", "-y", "openclaw@latest", "--", "plugins", "install", PACKAGE_INSTALL_SPEC],
635
+ targetDescription: PACKAGE_INSTALL_SPEC,
557
636
  },
558
- ];
637
+ );
559
638
 
560
- for (let index = 0; index < candidates.length; index += 1) {
561
- const candidate = candidates[index];
562
- console.log(`\nInstalling ${PACKAGE_NAME} with ${candidate.label}...`);
563
- const result = installPluginWithCommand(candidate.command, candidate.args, env);
564
- if (result.status === 0 && !result.error) {
565
- return {
566
- ok: true,
567
- method: candidate.label,
568
- };
569
- }
570
- const errorCode = result.error && typeof result.error === "object" ? result.error.code : "";
571
- if (errorCode === "ENOENT" && index < candidates.length - 1) {
572
- console.log(`${candidate.command} was not found. Trying the npm exec fallback...`);
573
- continue;
639
+ try {
640
+ const failures = [];
641
+ for (let index = 0; index < candidates.length; index += 1) {
642
+ const candidate = candidates[index];
643
+ console.log(`\nInstalling ${candidate.targetDescription} with ${candidate.label}...`);
644
+ const result = installPluginWithCommand(candidate.command, candidate.args, env);
645
+ if (result.status === 0 && !result.error) {
646
+ return {
647
+ ok: true,
648
+ method: candidate.label,
649
+ };
650
+ }
651
+ const errorCode = result.error && typeof result.error === "object" ? result.error.code : "";
652
+ const detail = result.error
653
+ ? result.error.message
654
+ : result.signal
655
+ ? `terminated by signal ${result.signal}`
656
+ : `exited with code ${result.status}`;
657
+ failures.push(`${candidate.label} failed: ${detail}`);
658
+ if (errorCode === "ENOENT" && index < candidates.length - 1) {
659
+ console.log(`${candidate.command} was not found. Trying the next install fallback...`);
660
+ continue;
661
+ }
662
+ if (index < candidates.length - 1) {
663
+ console.log(`${candidate.label} failed (${detail}). Trying the next install fallback...`);
664
+ }
574
665
  }
575
- const detail = result.error
576
- ? result.error.message
577
- : result.signal
578
- ? `terminated by signal ${result.signal}`
579
- : `exited with code ${result.status}`;
580
666
  return {
581
667
  ok: false,
582
- error: `${candidate.label} failed: ${detail}`,
668
+ error: failures.length > 0 ? failures.join("; ") : "No install command was available.",
583
669
  };
670
+ } finally {
671
+ if (tarballResult.ok) {
672
+ fsSync.rmSync(tarballResult.tempDir, { recursive: true, force: true });
673
+ }
584
674
  }
585
-
586
- return {
587
- ok: false,
588
- error: "No install command was available.",
589
- };
590
675
  }
591
676
 
592
677
  async function collectInstallChoices(config, prompter) {
@@ -2,7 +2,7 @@
2
2
  "id": "teamclaw",
3
3
  "name": "TeamClaw",
4
4
  "description": "Virtual team collaboration - multiple OpenClaw instances form a virtual software company with role-based task routing.",
5
- "version": "2026.3.24-3",
5
+ "version": "2026.3.24-5",
6
6
  "uiHints": {
7
7
  "mode": {
8
8
  "label": "Mode",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamclaws/teamclaw",
3
- "version": "2026.3.24-3",
3
+ "version": "2026.3.24-5",
4
4
  "description": "OpenClaw virtual software team orchestration plugin",
5
5
  "private": false,
6
6
  "keywords": [