traderclaw-cli 1.0.123 → 1.0.124

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.
@@ -1630,6 +1630,29 @@ function getAccessPairForAgent(wizardOpts, agentId) {
1630
1630
  return { at, ats };
1631
1631
  }
1632
1632
 
1633
+ function readPluginOrchestratorUrl(pluginId) {
1634
+ try {
1635
+ const config = JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
1636
+ const entry = config?.plugins?.entries?.[pluginId];
1637
+ const u = entry?.config?.orchestratorUrl;
1638
+ if (typeof u === "string" && u.trim()) return u.trim().replace(/\/+$/, "");
1639
+ } catch {
1640
+ /* keep default */
1641
+ }
1642
+ return "https://api.traderclaw.ai";
1643
+ }
1644
+
1645
+ function readPluginApiKeyForVerify(pluginId) {
1646
+ try {
1647
+ const config = JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
1648
+ const entry = config?.plugins?.entries?.[pluginId];
1649
+ const k = entry?.config?.apiKey;
1650
+ return typeof k === "string" ? k.trim() : "";
1651
+ } catch {
1652
+ return "";
1653
+ }
1654
+ }
1655
+
1633
1656
  function seedXConfig(modeConfig, configPath = CONFIG_FILE, wizardOpts = {}) {
1634
1657
  let config = {};
1635
1658
  try {
@@ -3053,6 +3076,230 @@ export async function tailscaleFunnelOpenclaw18789(options = {}) {
3053
3076
  return { funnelUrl: firstUrl(statusOut) || null, rawStatus: statusOut };
3054
3077
  }
3055
3078
 
3079
+ /**
3080
+ * Re-run installer bootstrap steps (pinned OpenClaw platform, dependency repair, plugin activation,
3081
+ * gateway persistence, scheduling, workspace bootstrap, gateway templates) without LLM or Tailscale flows.
3082
+ * Intended for `traderclaw update --deep` after npm/plugin sync.
3083
+ */
3084
+ export async function runTraderClawDeepUpdate(options = {}) {
3085
+ const modeConfig = options.modeConfig;
3086
+ if (!modeConfig?.pluginId || !modeConfig?.pluginPackage || !modeConfig?.gatewayConfig || !modeConfig?.cliName) {
3087
+ throw new Error("runTraderClawDeepUpdate: modeConfig must include pluginId, pluginPackage, gatewayConfig, cliName");
3088
+ }
3089
+ const skipPluginTarballSync = options.skipPluginTarballSync === true;
3090
+ const onLog = typeof options.hooks?.onLog === "function" ? options.hooks.onLog : () => {};
3091
+ const onStep = typeof options.hooks?.onStepEvent === "function" ? options.hooks.onStepEvent : () => {};
3092
+
3093
+ const emitLog = (stepId, level, text) => {
3094
+ const clean = typeof text === "string" ? stripAnsi(text) : text;
3095
+ onLog({ at: nowIso(), stepId, level, text: clean, urls: [] });
3096
+ };
3097
+
3098
+ async function runDeepStep(stepId, title, handler) {
3099
+ onStep({ at: nowIso(), stepId, status: "in_progress", detail: title });
3100
+ try {
3101
+ const result = await handler();
3102
+ onStep({ at: nowIso(), stepId, status: "completed", detail: title });
3103
+ return result;
3104
+ } catch (err) {
3105
+ const detail = stripAnsi(err?.message || String(err));
3106
+ onStep({ at: nowIso(), stepId, status: "failed", detail });
3107
+ throw err;
3108
+ }
3109
+ }
3110
+
3111
+ await runDeepStep("deep_preflight", "Checking prerequisites", async () => {
3112
+ if (!commandExists("node") || !commandExists("npm")) {
3113
+ throw new Error("node and npm are required for deep update");
3114
+ }
3115
+ return { node: true, npm: true };
3116
+ });
3117
+
3118
+ await runDeepStep("deep_install_openclaw", "Installing or upgrading OpenClaw platform (pinned)", async () =>
3119
+ installOpenClawPlatform((evt) =>
3120
+ emitLog("deep_install_openclaw", evt.type === "stderr" ? "warn" : "info", evt.text),
3121
+ ),
3122
+ );
3123
+
3124
+ await runDeepStep("deep_device_approval_check", "Checking OpenClaw device approval status", async () => {
3125
+ const check = checkOpenClawDeviceApproval();
3126
+ if (!check.ran) {
3127
+ emitLog("deep_device_approval_check", "info", "Device approval check skipped (openclaw CLI unavailable).");
3128
+ return { ran: false };
3129
+ }
3130
+ const needsAction = check.pendingIds.length > 0 || check.repairDetected;
3131
+ if (!needsAction) {
3132
+ emitLog("deep_device_approval_check", "info", "No pending or repair-state devices found.");
3133
+ return { ran: true, ok: true };
3134
+ }
3135
+ const lines = [
3136
+ "ACTION REQUIRED — OpenClaw device approval needed.",
3137
+ "Run: openclaw devices list",
3138
+ ...(check.pendingIds.length > 0
3139
+ ? check.pendingIds.map((id) => ` openclaw devices approve ${id}`)
3140
+ : [" openclaw devices approve <requestId>"]),
3141
+ ];
3142
+ emitLog("deep_device_approval_check", "warn", lines.join("\n"));
3143
+ return { ran: true, ok: false, pendingIds: check.pendingIds };
3144
+ });
3145
+
3146
+ if (!skipPluginTarballSync) {
3147
+ await runDeepStep("deep_install_traderclaw_cli", "Ensuring TraderClaw CLI npm package", async () =>
3148
+ installPlugin(modeConfig, (evt) =>
3149
+ emitLog("deep_install_traderclaw_cli", evt.type === "stderr" ? "warn" : "info", evt.text),
3150
+ ),
3151
+ );
3152
+ await runDeepStep("deep_openclaw_global_deps", "Ensuring OpenClaw global package dependencies", async () =>
3153
+ ensureOpenClawGlobalPackageDependencies(),
3154
+ );
3155
+ await runDeepStep("deep_install_qmd", "Installing QMD memory engine (vector search)", async () => {
3156
+ if (commandExists("qmd")) {
3157
+ const ver = getCommandOutput("qmd --version");
3158
+ emitLog("deep_install_qmd", "info", `QMD already installed: ${ver}`);
3159
+ return { alreadyInstalled: true, version: ver };
3160
+ }
3161
+ emitLog("deep_install_qmd", "info", "Installing @tobilu/qmd globally...");
3162
+ try {
3163
+ await runCommandWithEvents(
3164
+ "npm",
3165
+ ["install", "-g", "--ignore-scripts", "--no-audit", "--no-fund", "--registry", "https://registry.npmjs.org/", "@tobilu/qmd"],
3166
+ {
3167
+ onEvent: (evt) =>
3168
+ emitLog("deep_install_qmd", evt.type === "stderr" ? "warn" : "info", evt.text),
3169
+ },
3170
+ );
3171
+ } catch (err) {
3172
+ emitLog(
3173
+ "deep_install_qmd",
3174
+ "warn",
3175
+ `QMD install failed (non-fatal): ${err?.message || err}. Install manually: npm install -g @tobilu/qmd`,
3176
+ );
3177
+ return { installed: false, error: err?.message || String(err) };
3178
+ }
3179
+ const available = commandExists("qmd");
3180
+ return { installed: available, version: available ? getCommandOutput("qmd --version") : null };
3181
+ });
3182
+
3183
+ const orchUrl = readPluginOrchestratorUrl(modeConfig.pluginId);
3184
+ await runDeepStep("deep_activate_openclaw_plugin", "Installing and enabling TraderClaw inside OpenClaw", async () =>
3185
+ installAndEnableOpenClawPlugin(
3186
+ modeConfig,
3187
+ (evt) =>
3188
+ emitLog("deep_activate_openclaw_plugin", evt.type === "stderr" ? "warn" : "info", evt.text),
3189
+ orchUrl,
3190
+ ),
3191
+ );
3192
+ } else {
3193
+ emitLog(
3194
+ "deep_plugin_sync",
3195
+ "warn",
3196
+ 'Skipping TraderClaw CLI npm install, QMD bootstrap, and plugin activate (--skip-plugins). OpenClaw platform upgrade still ran.',
3197
+ );
3198
+ }
3199
+
3200
+ normalizeOpenClawConfigFileShape(CONFIG_FILE);
3201
+
3202
+ await runDeepStep("deep_gateway_bootstrap_defaults", "Ensuring gateway bootstrap defaults in openclaw.json", async () => {
3203
+ ensureGatewayBootstrapDefaults(CONFIG_FILE, (msg) => emitLog("deep_gateway_bootstrap_defaults", "info", msg));
3204
+ return { ok: true };
3205
+ });
3206
+
3207
+ await runDeepStep("deep_openclaw_config_validate", "Validating OpenClaw config", async () => {
3208
+ try {
3209
+ await runCommandWithEvents("openclaw", ["config", "validate"], {
3210
+ onEvent: (evt) =>
3211
+ emitLog("deep_openclaw_config_validate", evt.type === "stderr" ? "warn" : "info", evt.text),
3212
+ });
3213
+ } catch (err) {
3214
+ const blob = `${err?.message || ""}\n${err?.stderr || ""}\n${err?.stdout || ""}`;
3215
+ if (isOpenClawConfigSchemaFailure(blob)) {
3216
+ throw new Error(gatewayConfigValidationRemediation());
3217
+ }
3218
+ throw err;
3219
+ }
3220
+ return { ok: true };
3221
+ });
3222
+
3223
+ const { ensureLinuxGatewayPersistence } = await import("./gateway-persistence-linux.mjs");
3224
+ await runDeepStep("deep_gateway_persistence", "SSH-safe gateway (systemd user linger)", async () =>
3225
+ ensureLinuxGatewayPersistence({
3226
+ emitLog: (level, text) => emitLog("deep_gateway_persistence", level, text),
3227
+ runPrivileged: (cmd, args) =>
3228
+ runCommandWithEvents(cmd, args, {
3229
+ onEvent: (evt) =>
3230
+ emitLog("deep_gateway_persistence", evt.type === "stderr" ? "warn" : "info", evt.text),
3231
+ }),
3232
+ }),
3233
+ );
3234
+
3235
+ await runDeepStep("deep_enable_responses", "Enabling /v1/responses endpoint", async () => {
3236
+ const configPath = ensureOpenResponsesEnabled(CONFIG_FILE);
3237
+ return { configPath };
3238
+ });
3239
+
3240
+ await runDeepStep("deep_gateway_scheduling", "Configuring heartbeat and cron schedules", async () => {
3241
+ const result = configureGatewayScheduling(modeConfig, CONFIG_FILE);
3242
+ emitLog("deep_gateway_scheduling", "info", `Agents configured: ${result.agentsConfigured}`);
3243
+ if (result.removedLegacyCronJobs) {
3244
+ emitLog("deep_gateway_scheduling", "warn", "Removed legacy 'cron.jobs' from openclaw.json for schema compatibility.");
3245
+ }
3246
+ return result;
3247
+ });
3248
+
3249
+ await runDeepStep("deep_workspace_heartbeat", "Installing HEARTBEAT.md into agent workspace", async () =>
3250
+ deployWorkspaceHeartbeat(modeConfig),
3251
+ );
3252
+
3253
+ await runDeepStep("deep_workspace_bootstrap", "Installing workspace context files", async () =>
3254
+ deployWorkspaceBootstrapFiles(modeConfig),
3255
+ );
3256
+
3257
+ await runDeepStep("deep_gateway_config", "Deploying gateway config template", async () =>
3258
+ deployGatewayConfig(modeConfig),
3259
+ );
3260
+
3261
+ await runDeepStep("deep_x_credentials", "Merging X/Twitter credentials from environment", async () =>
3262
+ seedXConfig(modeConfig, CONFIG_FILE, {}),
3263
+ );
3264
+
3265
+ const telegramEnv =
3266
+ String(process.env.TRADERCLAW_HEADLESS_TELEGRAM_TOKEN || "").trim()
3267
+ || String(process.env.OPENCLAW_TELEGRAM_BOT_TOKEN || "").trim();
3268
+ if (telegramEnv) {
3269
+ await runDeepStep("deep_telegram_env", "Applying Telegram bot token from environment", async () => {
3270
+ writeTelegramChannelConfig(telegramEnv, CONFIG_FILE);
3271
+ const policy = ensureTelegramGroupPolicyOpenForWizard();
3272
+ if (policy.changed) {
3273
+ emitLog("deep_telegram_env", "info", "Set channels.telegram.groupPolicy=open for wizard-compatible groups.");
3274
+ }
3275
+ return { configured: true };
3276
+ });
3277
+ }
3278
+
3279
+ await runDeepStep("deep_openclaw_config_validate_final", "Re-validating OpenClaw config", async () => {
3280
+ normalizeOpenClawConfigFileShape(CONFIG_FILE);
3281
+ await runCommandWithEvents("openclaw", ["config", "validate"], {
3282
+ onEvent: (evt) =>
3283
+ emitLog("deep_openclaw_config_validate_final", evt.type === "stderr" ? "warn" : "info", evt.text),
3284
+ });
3285
+ return { ok: true };
3286
+ });
3287
+
3288
+ await runDeepStep("deep_restart_gateway", "Restarting gateway", async () => restartGateway());
3289
+
3290
+ await runDeepStep("deep_verify", "Verifying installation", async () => {
3291
+ const apiKey = readPluginApiKeyForVerify(modeConfig.pluginId);
3292
+ const checks = verifyInstallation(modeConfig, apiKey);
3293
+ for (const c of checks) {
3294
+ const prefix = c.ok ? "ok" : "warn";
3295
+ emitLog("deep_verify", c.ok ? "info" : "warn", `${prefix}: ${c.label}${c.note ? ` — ${c.note}` : ""}`);
3296
+ }
3297
+ return { checks };
3298
+ });
3299
+
3300
+ return { status: "completed" };
3301
+ }
3302
+
3056
3303
  export function assertWizardXCredentials(modeConfig, options = {}) {
3057
3304
  const t = (s) => (typeof s === "string" ? s.trim() : "");
3058
3305
  const o = options || {};
@@ -4729,11 +4729,14 @@ Commands:
4729
4729
  config View and manage configuration
4730
4730
  test-session Test session auth flow (refresh, rotation, challenge) without reinstalling
4731
4731
  update Update global traderclaw-cli, re-sync the OpenClaw plugin (openclaw.json), force-install solana-traderclaw, and restart the gateway
4732
+ update --deep Same as update, then re-run installer bootstrap (pinned OpenClaw, scheduling, workspace, gateway template, persistence) without LLM/Tailscale
4732
4733
 
4733
4734
  Update options (traderclaw update):
4734
4735
  --beta Use the npm dist-tag "beta" for traderclaw-cli and solana-traderclaw (default: "latest")
4735
4736
  --dry-run Show / simulate actions without fully applying (where supported)
4736
- --skip-plugins Do not run openclaw "plugins update" or "plugins install --force" (only npm + gateway restart)
4737
+ --deep After npm/plugin sync, run installer reconciliation (OpenClaw pin, scheduling, workspace…); omits LLM/Tailscale
4738
+ --skip-plugins Do not run openclaw "plugins update" or "plugins install --force" (only npm + gateway restart).
4739
+ With --deep: skips TraderClaw CLI npm reinstall + plugin activate inside deep sync (pinned OpenClaw upgrade still runs)
4737
4740
 
4738
4741
  Setup options:
4739
4742
  --api-key, -k API key (skip interactive prompt)
@@ -4836,6 +4839,7 @@ Examples:
4836
4839
  traderclaw update
4837
4840
  traderclaw update --beta
4838
4841
  traderclaw update --dry-run
4842
+ traderclaw update --deep
4839
4843
  `);
4840
4844
  }
4841
4845
 
@@ -4843,12 +4847,16 @@ async function cmdUpdate(args) {
4843
4847
  const tag = args.includes("--beta") ? "beta" : "latest";
4844
4848
  const dryRun = args.includes("--dry-run");
4845
4849
  const skipPlugins = args.includes("--skip-plugins");
4850
+ const deep = args.includes("--deep");
4846
4851
 
4847
4852
  print("\nTraderClaw — Update\n");
4848
4853
  print("=".repeat(45));
4849
4854
  if (dryRun) {
4850
4855
  printInfo(" (dry-run: npm install and gateway restart are simulated where noted)\n");
4851
4856
  }
4857
+ if (deep && !dryRun) {
4858
+ printInfo(" (--deep: full installer reconciliation will run after npm/plugin sync)\n");
4859
+ }
4852
4860
 
4853
4861
  let currentVersion = "unknown";
4854
4862
  try {
@@ -4990,6 +4998,45 @@ async function cmdUpdate(args) {
4990
4998
  );
4991
4999
  }
4992
5000
 
5001
+ if (deep) {
5002
+ /** Matches wizard / headless install (TraderClaw v1 multi-agent gateway profile). */
5003
+ const deepModeConfig = {
5004
+ pluginPackage: "solana-traderclaw",
5005
+ pluginId: "solana-trader",
5006
+ cliName: "traderclaw",
5007
+ gatewayConfig: "gateway-v1.json5",
5008
+ agents: ["cto", "onchain-analyst", "alpha-signal-analyst", "risk-officer", "strategy-researcher"],
5009
+ };
5010
+ if (dryRun) {
5011
+ print(
5012
+ `\n [dry-run] Would run installer reconciliation (--deep): pinned OpenClaw platform, config normalize + validate, systemd linger, ` +
5013
+ `responses endpoint, heartbeat/cron/hooks, workspace bootstrap, gateway template, optional Telegram from env, gateway restart, verify.` +
5014
+ `${skipPlugins ? " (--skip-plugins: skip TraderClaw CLI npm + plugin activate inside deep)" : ""}\n`,
5015
+ );
5016
+ } else {
5017
+ print("\n Deep update — installer reconciliation (LLM / Tailscale unchanged)...\n");
5018
+ try {
5019
+ const { runTraderClawDeepUpdate } = await import("./installer-step-engine.mjs");
5020
+ await runTraderClawDeepUpdate({
5021
+ modeConfig: deepModeConfig,
5022
+ skipPluginTarballSync: skipPlugins,
5023
+ hooks: {
5024
+ onLog: ({ text }) => {
5025
+ if (text) print(String(text));
5026
+ },
5027
+ onStepEvent: ({ stepId, status, detail }) => {
5028
+ print(`[deep] ${stepId} ${status}${detail ? ` — ${detail}` : ""}`);
5029
+ },
5030
+ },
5031
+ });
5032
+ printSuccess("\n Deep reconciliation finished.");
5033
+ } catch (err) {
5034
+ printError(err?.message || String(err));
5035
+ process.exit(1);
5036
+ }
5037
+ }
5038
+ }
5039
+
4993
5040
  if (dryRun) {
4994
5041
  print(`\n [dry-run] Would run: systemctl --user enable --now + restart (Linux) or openclaw gateway restart\n`);
4995
5042
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "traderclaw-cli",
3
- "version": "1.0.123",
3
+ "version": "1.0.124",
4
4
  "description": "Global TraderClaw CLI (install --wizard, setup, precheck). Installs solana-traderclaw as a dependency for OpenClaw plugin files.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,7 +17,7 @@
17
17
  "node": ">=22"
18
18
  },
19
19
  "dependencies": {
20
- "solana-traderclaw": "^1.0.123"
20
+ "solana-traderclaw": "^1.0.124"
21
21
  },
22
22
  "keywords": [
23
23
  "traderclaw",