clawdentity 0.0.14 → 0.0.15

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/dist/index.js CHANGED
@@ -15647,6 +15647,7 @@ var runtimeEnvironmentValues = [
15647
15647
  // ../../packages/sdk/src/config.ts
15648
15648
  var environmentSchema = external_exports.enum(runtimeEnvironmentValues);
15649
15649
  var registrySigningKeyStatusSchema = external_exports.enum(["active", "revoked"]);
15650
+ var registryEventBusBackendSchema = external_exports.enum(["memory", "queue"]);
15650
15651
  var ED25519_PUBLIC_KEY_LENGTH2 = 32;
15651
15652
  var registrySigningPublicKeySchema = external_exports.object({
15652
15653
  kid: external_exports.string().min(1),
@@ -15716,6 +15717,7 @@ var registryConfigSchema = external_exports.object({
15716
15717
  ENVIRONMENT: environmentSchema,
15717
15718
  APP_VERSION: external_exports.string().min(1).optional(),
15718
15719
  PROXY_URL: external_exports.string().url().optional(),
15720
+ EVENT_BUS_BACKEND: registryEventBusBackendSchema.optional(),
15719
15721
  BOOTSTRAP_SECRET: external_exports.string().min(1).optional(),
15720
15722
  REGISTRY_SIGNING_KEY: external_exports.string().min(1).optional(),
15721
15723
  REGISTRY_SIGNING_KEYS: registrySigningKeysEnvSchema.optional()
@@ -18671,6 +18673,7 @@ var DEFAULT_RECONNECT_BACKOFF_FACTOR = 2;
18671
18673
  var DEFAULT_RECONNECT_JITTER_RATIO = 0.2;
18672
18674
  var DEFAULT_CONNECTOR_BASE_URL = "http://127.0.0.1:19400";
18673
18675
  var DEFAULT_CONNECTOR_OUTBOUND_PATH = "/v1/outbound";
18676
+ var DEFAULT_CONNECTOR_STATUS_PATH = "/v1/status";
18674
18677
  var DEFAULT_RELAY_DELIVER_TIMEOUT_MS = 15e3;
18675
18678
  var DEFAULT_OPENCLAW_DELIVER_RETRY_BUDGET_MS = DEFAULT_RELAY_DELIVER_TIMEOUT_MS - 1e3;
18676
18679
  var AGENT_ACCESS_HEADER = "x-claw-agent-access";
@@ -19598,6 +19601,7 @@ async function startConnectorRuntime(input) {
19598
19601
  });
19599
19602
  const outboundBaseUrl = normalizeOutboundBaseUrl(input.outboundBaseUrl);
19600
19603
  const outboundPath = normalizeOutboundPath(input.outboundPath);
19604
+ const statusPath = DEFAULT_CONNECTOR_STATUS_PATH;
19601
19605
  const outboundUrl = new URL(outboundPath, outboundBaseUrl).toString();
19602
19606
  const relayToPeer = async (request) => {
19603
19607
  const peerUrl = new URL(request.peerProxyUrl);
@@ -19665,6 +19669,21 @@ async function startConnectorRuntime(input) {
19665
19669
  };
19666
19670
  const server = createServer(async (req, res) => {
19667
19671
  const requestPath = req.url ? new URL(req.url, outboundBaseUrl).pathname : "/";
19672
+ if (requestPath === statusPath) {
19673
+ if (req.method !== "GET") {
19674
+ res.statusCode = 405;
19675
+ res.setHeader("allow", "GET");
19676
+ writeJson(res, 405, { error: "Method Not Allowed" });
19677
+ return;
19678
+ }
19679
+ writeJson(res, 200, {
19680
+ status: "ok",
19681
+ outboundUrl,
19682
+ websocketUrl: wsUrl,
19683
+ websocketConnected: connectorClient.isConnected()
19684
+ });
19685
+ return;
19686
+ }
19668
19687
  if (requestPath !== outboundPath) {
19669
19688
  writeJson(res, 404, { error: "Not Found" });
19670
19689
  return;
@@ -20921,11 +20940,13 @@ var createInviteCommand = (dependencies = {}) => {
20921
20940
  };
20922
20941
 
20923
20942
  // src/commands/openclaw.ts
20943
+ import { spawn } from "child_process";
20924
20944
  import { randomBytes as randomBytes3 } from "crypto";
20925
20945
  import { existsSync } from "fs";
20926
20946
  import { chmod as chmod3, copyFile, mkdir as mkdir5, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
20927
20947
  import { homedir as homedir3 } from "os";
20928
20948
  import { dirname as dirname4, join as join6, resolve as resolvePath } from "path";
20949
+ import { fileURLToPath as fileURLToPath2 } from "url";
20929
20950
  import { Command as Command7 } from "commander";
20930
20951
  var logger8 = createLogger({ service: "cli", module: "openclaw" });
20931
20952
  var CLAWDENTITY_DIR_NAME = ".clawdentity";
@@ -20960,10 +20981,13 @@ var DEFAULT_OPENCLAW_MAIN_SESSION_KEY = "main";
20960
20981
  var DEFAULT_OPENCLAW_AGENT_ID = "main";
20961
20982
  var DEFAULT_CONNECTOR_PORT = 19400;
20962
20983
  var DEFAULT_CONNECTOR_OUTBOUND_PATH3 = "/v1/outbound";
20984
+ var DEFAULT_CONNECTOR_STATUS_PATH2 = "/v1/status";
20985
+ var DEFAULT_SETUP_WAIT_TIMEOUT_SECONDS = 30;
20963
20986
  var CONNECTOR_HOST_LOOPBACK = "127.0.0.1";
20964
20987
  var CONNECTOR_HOST_DOCKER = "host.docker.internal";
20965
20988
  var CONNECTOR_HOST_DOCKER_GATEWAY = "gateway.docker.internal";
20966
20989
  var CONNECTOR_HOST_LINUX_BRIDGE = "172.17.0.1";
20990
+ var CONNECTOR_RUN_DIR_NAME = "run";
20967
20991
  var PEER_ALIAS_PATTERN = /^[a-zA-Z0-9._-]+$/;
20968
20992
  var FILE_MODE3 = 384;
20969
20993
  var OPENCLAW_HOOK_TOKEN_BYTES = 32;
@@ -21376,6 +21400,256 @@ function buildRelayConnectorBaseUrls(port) {
21376
21400
  buildConnectorBaseUrl(CONNECTOR_HOST_LOOPBACK, port)
21377
21401
  ];
21378
21402
  }
21403
+ function parseOpenclawRuntimeMode(value) {
21404
+ if (typeof value !== "string" || value.trim().length === 0) {
21405
+ return "auto";
21406
+ }
21407
+ const normalized = value.trim().toLowerCase();
21408
+ if (normalized === "auto" || normalized === "service" || normalized === "detached") {
21409
+ return normalized;
21410
+ }
21411
+ throw createCliError6(
21412
+ "CLI_OPENCLAW_SETUP_RUNTIME_MODE_INVALID",
21413
+ "runtimeMode must be one of: auto, service, detached"
21414
+ );
21415
+ }
21416
+ function parseWaitTimeoutSeconds(value) {
21417
+ if (typeof value !== "string" || value.trim().length === 0) {
21418
+ return DEFAULT_SETUP_WAIT_TIMEOUT_SECONDS;
21419
+ }
21420
+ const parsed = Number.parseInt(value, 10);
21421
+ if (!Number.isInteger(parsed) || parsed < 1) {
21422
+ throw createCliError6(
21423
+ "CLI_OPENCLAW_SETUP_TIMEOUT_INVALID",
21424
+ "waitTimeoutSeconds must be a positive integer"
21425
+ );
21426
+ }
21427
+ return parsed;
21428
+ }
21429
+ function resolveConnectorStatusUrl(connectorBaseUrl) {
21430
+ const normalizedBase = connectorBaseUrl.endsWith("/") ? connectorBaseUrl : `${connectorBaseUrl}/`;
21431
+ return new URL(
21432
+ DEFAULT_CONNECTOR_STATUS_PATH2.slice(1),
21433
+ normalizedBase
21434
+ ).toString();
21435
+ }
21436
+ function parseConnectorStatusPayload(payload) {
21437
+ if (!isRecord8(payload) || typeof payload.websocketConnected !== "boolean") {
21438
+ throw createCliError6(
21439
+ "CLI_OPENCLAW_SETUP_CONNECTOR_STATUS_INVALID",
21440
+ "Connector status response is invalid"
21441
+ );
21442
+ }
21443
+ return {
21444
+ websocketConnected: payload.websocketConnected
21445
+ };
21446
+ }
21447
+ async function fetchConnectorHealthStatus(input) {
21448
+ const statusUrl = resolveConnectorStatusUrl(input.connectorBaseUrl);
21449
+ try {
21450
+ const response = await input.fetchImpl(statusUrl, {
21451
+ method: "GET",
21452
+ headers: {
21453
+ accept: "application/json"
21454
+ }
21455
+ });
21456
+ if (!response.ok) {
21457
+ return {
21458
+ connected: false,
21459
+ reachable: false,
21460
+ statusUrl,
21461
+ reason: `HTTP ${response.status}`
21462
+ };
21463
+ }
21464
+ let payload;
21465
+ try {
21466
+ payload = await response.json();
21467
+ } catch {
21468
+ return {
21469
+ connected: false,
21470
+ reachable: false,
21471
+ statusUrl,
21472
+ reason: "invalid JSON payload"
21473
+ };
21474
+ }
21475
+ const parsed = parseConnectorStatusPayload(payload);
21476
+ return {
21477
+ connected: parsed.websocketConnected,
21478
+ reachable: true,
21479
+ statusUrl,
21480
+ reason: parsed.websocketConnected ? void 0 : "connector websocket is disconnected"
21481
+ };
21482
+ } catch {
21483
+ return {
21484
+ connected: false,
21485
+ reachable: false,
21486
+ statusUrl,
21487
+ reason: "connector status endpoint is unreachable"
21488
+ };
21489
+ }
21490
+ }
21491
+ async function waitForConnectorConnected(input) {
21492
+ const deadline = Date.now() + input.waitTimeoutSeconds * 1e3;
21493
+ let latest = await fetchConnectorHealthStatus({
21494
+ connectorBaseUrl: input.connectorBaseUrl,
21495
+ fetchImpl: input.fetchImpl
21496
+ });
21497
+ while (!latest.connected && Date.now() < deadline) {
21498
+ await new Promise((resolve2) => {
21499
+ setTimeout(resolve2, 1e3);
21500
+ });
21501
+ latest = await fetchConnectorHealthStatus({
21502
+ connectorBaseUrl: input.connectorBaseUrl,
21503
+ fetchImpl: input.fetchImpl
21504
+ });
21505
+ }
21506
+ if (!latest.connected) {
21507
+ throw createCliError6(
21508
+ "CLI_OPENCLAW_SETUP_CONNECTOR_NOT_READY",
21509
+ `Connector runtime is not websocket-connected after ${input.waitTimeoutSeconds} seconds`,
21510
+ {
21511
+ connectorBaseUrl: input.connectorBaseUrl,
21512
+ connectorStatusUrl: latest.statusUrl,
21513
+ reason: latest.reason
21514
+ }
21515
+ );
21516
+ }
21517
+ return latest;
21518
+ }
21519
+ function resolveConnectorRunDir(homeDir) {
21520
+ return join6(homeDir, CLAWDENTITY_DIR_NAME, CONNECTOR_RUN_DIR_NAME);
21521
+ }
21522
+ function resolveConnectorPidPath(homeDir, agentName) {
21523
+ return join6(resolveConnectorRunDir(homeDir), `connector-${agentName}.pid`);
21524
+ }
21525
+ async function readConnectorPidFile(pidPath) {
21526
+ try {
21527
+ const raw = (await readFile4(pidPath, "utf8")).trim();
21528
+ if (raw.length === 0) {
21529
+ return void 0;
21530
+ }
21531
+ const parsed = Number.parseInt(raw, 10);
21532
+ if (!Number.isInteger(parsed) || parsed <= 0) {
21533
+ return void 0;
21534
+ }
21535
+ return parsed;
21536
+ } catch (error48) {
21537
+ if (getErrorCode2(error48) === "ENOENT") {
21538
+ return void 0;
21539
+ }
21540
+ throw error48;
21541
+ }
21542
+ }
21543
+ function isPidRunning(pid) {
21544
+ try {
21545
+ process.kill(pid, 0);
21546
+ return true;
21547
+ } catch {
21548
+ return false;
21549
+ }
21550
+ }
21551
+ async function stopDetachedConnectorIfRunning(input) {
21552
+ const pidPath = resolveConnectorPidPath(input.homeDir, input.agentName);
21553
+ const pid = await readConnectorPidFile(pidPath);
21554
+ if (pid === void 0 || !isPidRunning(pid)) {
21555
+ return;
21556
+ }
21557
+ try {
21558
+ process.kill(pid, "SIGTERM");
21559
+ } catch {
21560
+ }
21561
+ }
21562
+ function resolveCliEntryPathForDetachedStart() {
21563
+ const argvEntry = typeof process.argv[1] === "string" ? process.argv[1] : "";
21564
+ if (argvEntry.length > 0 && existsSync(argvEntry)) {
21565
+ return argvEntry;
21566
+ }
21567
+ const modulePath = fileURLToPath2(import.meta.url);
21568
+ return join6(dirname4(modulePath), "..", "bin.js");
21569
+ }
21570
+ async function startDetachedConnectorRuntime(input) {
21571
+ await stopDetachedConnectorIfRunning({
21572
+ homeDir: input.homeDir,
21573
+ agentName: input.agentName
21574
+ });
21575
+ const runDir = resolveConnectorRunDir(input.homeDir);
21576
+ await mkdir5(runDir, { recursive: true });
21577
+ const cliEntryPath = resolveCliEntryPathForDetachedStart();
21578
+ const args = [
21579
+ cliEntryPath,
21580
+ "connector",
21581
+ "start",
21582
+ input.agentName,
21583
+ "--openclaw-base-url",
21584
+ input.openclawBaseUrl
21585
+ ];
21586
+ const child = spawn(process.execPath, args, {
21587
+ detached: true,
21588
+ stdio: "ignore",
21589
+ env: process.env
21590
+ });
21591
+ child.unref();
21592
+ await writeSecureFile3(
21593
+ resolveConnectorPidPath(input.homeDir, input.agentName),
21594
+ `${child.pid}
21595
+ `
21596
+ );
21597
+ }
21598
+ async function startSetupConnectorRuntime(input) {
21599
+ if (input.mode !== "service") {
21600
+ const existingStatus = await fetchConnectorHealthStatus({
21601
+ connectorBaseUrl: input.connectorBaseUrl,
21602
+ fetchImpl: input.fetchImpl
21603
+ });
21604
+ if (existingStatus.connected) {
21605
+ return {
21606
+ runtimeMode: "existing",
21607
+ runtimeStatus: "running",
21608
+ websocketStatus: "connected",
21609
+ connectorStatusUrl: existingStatus.statusUrl
21610
+ };
21611
+ }
21612
+ }
21613
+ let runtimeMode = "service";
21614
+ if (input.mode === "detached") {
21615
+ runtimeMode = "detached";
21616
+ } else {
21617
+ try {
21618
+ await installConnectorServiceForAgent(input.agentName, {
21619
+ platform: "auto",
21620
+ openclawBaseUrl: input.openclawBaseUrl
21621
+ });
21622
+ runtimeMode = "service";
21623
+ } catch (error48) {
21624
+ if (input.mode === "service") {
21625
+ throw error48;
21626
+ }
21627
+ runtimeMode = "detached";
21628
+ logger8.warn("cli.openclaw.setup.service_fallback_detached", {
21629
+ agentName: input.agentName,
21630
+ reason: error48 instanceof Error ? error48.message : "unknown"
21631
+ });
21632
+ }
21633
+ }
21634
+ if (runtimeMode === "detached") {
21635
+ await startDetachedConnectorRuntime({
21636
+ agentName: input.agentName,
21637
+ homeDir: input.homeDir,
21638
+ openclawBaseUrl: input.openclawBaseUrl
21639
+ });
21640
+ }
21641
+ const connectedStatus = await waitForConnectorConnected({
21642
+ connectorBaseUrl: input.connectorBaseUrl,
21643
+ fetchImpl: input.fetchImpl,
21644
+ waitTimeoutSeconds: input.waitTimeoutSeconds
21645
+ });
21646
+ return {
21647
+ runtimeMode,
21648
+ runtimeStatus: "running",
21649
+ websocketStatus: "connected",
21650
+ connectorStatusUrl: connectedStatus.statusUrl
21651
+ };
21652
+ }
21379
21653
  function parseRelayRuntimeConfig(value, relayRuntimeConfigPath) {
21380
21654
  if (!isRecord8(value)) {
21381
21655
  throw createCliError6(
@@ -22054,6 +22328,97 @@ async function runOpenclawDoctor(options = {}) {
22054
22328
  })
22055
22329
  );
22056
22330
  }
22331
+ if (options.includeConnectorRuntimeCheck !== false) {
22332
+ if (selectedAgentName === void 0) {
22333
+ checks.push(
22334
+ toDoctorCheck({
22335
+ id: "state.connectorRuntime",
22336
+ label: "Connector runtime",
22337
+ status: "fail",
22338
+ message: "cannot validate connector runtime without selected agent marker",
22339
+ remediationHint: OPENCLAW_SETUP_COMMAND_HINT
22340
+ })
22341
+ );
22342
+ } else {
22343
+ const connectorAssignmentsPath = resolveConnectorAssignmentsPath(homeDir);
22344
+ try {
22345
+ const connectorAssignments = await loadConnectorAssignments(
22346
+ connectorAssignmentsPath
22347
+ );
22348
+ const assignment = connectorAssignments.agents[selectedAgentName];
22349
+ if (assignment === void 0) {
22350
+ checks.push(
22351
+ toDoctorCheck({
22352
+ id: "state.connectorRuntime",
22353
+ label: "Connector runtime",
22354
+ status: "fail",
22355
+ message: `no connector assignment found for ${selectedAgentName}`,
22356
+ remediationHint: OPENCLAW_SETUP_COMMAND_HINT,
22357
+ details: { connectorAssignmentsPath, selectedAgentName }
22358
+ })
22359
+ );
22360
+ } else {
22361
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
22362
+ if (typeof fetchImpl !== "function") {
22363
+ checks.push(
22364
+ toDoctorCheck({
22365
+ id: "state.connectorRuntime",
22366
+ label: "Connector runtime",
22367
+ status: "fail",
22368
+ message: "fetch implementation is unavailable for connector checks",
22369
+ remediationHint: "Run doctor in a Node runtime with fetch support, or rerun openclaw setup"
22370
+ })
22371
+ );
22372
+ } else {
22373
+ const connectorStatus = await fetchConnectorHealthStatus({
22374
+ connectorBaseUrl: assignment.connectorBaseUrl,
22375
+ fetchImpl
22376
+ });
22377
+ if (connectorStatus.connected) {
22378
+ checks.push(
22379
+ toDoctorCheck({
22380
+ id: "state.connectorRuntime",
22381
+ label: "Connector runtime",
22382
+ status: "pass",
22383
+ message: `connector websocket is connected (${assignment.connectorBaseUrl})`,
22384
+ details: {
22385
+ connectorStatusUrl: connectorStatus.statusUrl,
22386
+ connectorBaseUrl: assignment.connectorBaseUrl
22387
+ }
22388
+ })
22389
+ );
22390
+ } else {
22391
+ const reason = connectorStatus.reason ?? "connector runtime is unavailable";
22392
+ checks.push(
22393
+ toDoctorCheck({
22394
+ id: "state.connectorRuntime",
22395
+ label: "Connector runtime",
22396
+ status: "fail",
22397
+ message: `connector runtime is not ready: ${reason}`,
22398
+ remediationHint: OPENCLAW_SETUP_COMMAND_HINT,
22399
+ details: {
22400
+ connectorStatusUrl: connectorStatus.statusUrl,
22401
+ connectorBaseUrl: assignment.connectorBaseUrl
22402
+ }
22403
+ })
22404
+ );
22405
+ }
22406
+ }
22407
+ }
22408
+ } catch {
22409
+ checks.push(
22410
+ toDoctorCheck({
22411
+ id: "state.connectorRuntime",
22412
+ label: "Connector runtime",
22413
+ status: "fail",
22414
+ message: `unable to read connector assignments at ${connectorAssignmentsPath}`,
22415
+ remediationHint: OPENCLAW_SETUP_COMMAND_HINT,
22416
+ details: { connectorAssignmentsPath }
22417
+ })
22418
+ );
22419
+ }
22420
+ }
22421
+ }
22057
22422
  return toDoctorResult(checks);
22058
22423
  }
22059
22424
  function parseRelayProbeFailure(input) {
@@ -22135,7 +22500,8 @@ async function runOpenclawRelayTest(options) {
22135
22500
  homeDir,
22136
22501
  openclawDir,
22137
22502
  peerAlias,
22138
- resolveConfigImpl: options.resolveConfigImpl
22503
+ resolveConfigImpl: options.resolveConfigImpl,
22504
+ includeConnectorRuntimeCheck: false
22139
22505
  });
22140
22506
  const relayRuntimeConfigPath = resolveRelayRuntimeConfigPath(homeDir);
22141
22507
  let openclawBaseUrl = DEFAULT_OPENCLAW_BASE_URL2;
@@ -22346,6 +22712,42 @@ async function setupOpenclawRelay(agentName, options) {
22346
22712
  relayRuntimeConfigPath
22347
22713
  };
22348
22714
  }
22715
+ async function setupOpenclawSelfReady(agentName, options) {
22716
+ const setup = await setupOpenclawRelay(agentName, options);
22717
+ if (options.noRuntimeStart === true) {
22718
+ return {
22719
+ ...setup,
22720
+ runtimeMode: "none",
22721
+ runtimeStatus: "skipped",
22722
+ websocketStatus: "skipped"
22723
+ };
22724
+ }
22725
+ const fetchImpl = globalThis.fetch;
22726
+ if (typeof fetchImpl !== "function") {
22727
+ throw createCliError6(
22728
+ "CLI_OPENCLAW_SETUP_FETCH_UNAVAILABLE",
22729
+ "Runtime fetch is unavailable for connector readiness checks"
22730
+ );
22731
+ }
22732
+ const resolvedMode = parseOpenclawRuntimeMode(options.runtimeMode);
22733
+ const waitTimeoutSeconds = parseWaitTimeoutSeconds(
22734
+ options.waitTimeoutSeconds
22735
+ );
22736
+ const resolvedHomeDir = resolveHomeDir(options.homeDir);
22737
+ const runtime = await startSetupConnectorRuntime({
22738
+ agentName: assertValidAgentName(agentName),
22739
+ homeDir: resolvedHomeDir,
22740
+ openclawBaseUrl: setup.openclawBaseUrl,
22741
+ connectorBaseUrl: setup.connectorBaseUrl,
22742
+ mode: resolvedMode,
22743
+ waitTimeoutSeconds,
22744
+ fetchImpl
22745
+ });
22746
+ return {
22747
+ ...setup,
22748
+ ...runtime
22749
+ };
22750
+ }
22349
22751
  var createOpenclawCommand = () => {
22350
22752
  const openclawCommand = new Command7("openclaw").description(
22351
22753
  "Manage OpenClaw relay setup"
@@ -22359,11 +22761,20 @@ var createOpenclawCommand = () => {
22359
22761
  ).option(
22360
22762
  "--openclaw-base-url <url>",
22361
22763
  "Base URL for local OpenClaw hook API (default http://127.0.0.1:18789)"
22764
+ ).option(
22765
+ "--runtime-mode <mode>",
22766
+ "Connector runtime mode: auto | service | detached (default auto)"
22767
+ ).option(
22768
+ "--wait-timeout-seconds <seconds>",
22769
+ "Seconds to wait for connector websocket readiness (default 30)"
22770
+ ).option(
22771
+ "--no-runtime-start",
22772
+ "Skip connector runtime startup (advanced/manual mode)"
22362
22773
  ).action(
22363
22774
  withErrorHandling(
22364
22775
  "openclaw setup",
22365
22776
  async (agentName, options) => {
22366
- const result = await setupOpenclawRelay(agentName, options);
22777
+ const result = await setupOpenclawSelfReady(agentName, options);
22367
22778
  writeStdoutLine("Self setup complete");
22368
22779
  writeStdoutLine(
22369
22780
  `Updated OpenClaw config: ${result.openclawConfigPath}`
@@ -22380,6 +22791,14 @@ var createOpenclawCommand = () => {
22380
22791
  writeStdoutLine(
22381
22792
  `Relay runtime config: ${result.relayRuntimeConfigPath}`
22382
22793
  );
22794
+ writeStdoutLine(`Runtime mode: ${result.runtimeMode}`);
22795
+ writeStdoutLine(`Runtime status: ${result.runtimeStatus}`);
22796
+ writeStdoutLine(`WebSocket status: ${result.websocketStatus}`);
22797
+ if (result.connectorStatusUrl) {
22798
+ writeStdoutLine(
22799
+ `Connector status URL: ${result.connectorStatusUrl}`
22800
+ );
22801
+ }
22383
22802
  }
22384
22803
  )
22385
22804
  );
@@ -22472,7 +22891,6 @@ var PEERS_FILE_NAME2 = "peers.json";
22472
22891
  var PAIR_START_PATH = "/pair/start";
22473
22892
  var PAIR_CONFIRM_PATH = "/pair/confirm";
22474
22893
  var PAIR_STATUS_PATH = "/pair/status";
22475
- var OWNER_PAT_HEADER = "x-claw-owner-pat";
22476
22894
  var NONCE_SIZE2 = 24;
22477
22895
  var PAIRING_TICKET_PREFIX = "clwpair1_";
22478
22896
  var PAIRING_QR_MAX_AGE_SECONDS = 900;
@@ -22830,11 +23248,8 @@ async function executePairRequest(input) {
22830
23248
  function mapStartPairError(status, payload) {
22831
23249
  const code = extractErrorCode(payload);
22832
23250
  const message2 = extractErrorMessage(payload);
22833
- if (code === "PROXY_PAIR_OWNER_PAT_INVALID" || status === 401) {
22834
- return message2 ? `Owner PAT is invalid (401): ${message2}` : "Owner PAT is invalid or expired (401).";
22835
- }
22836
- if (code === "PROXY_PAIR_OWNER_PAT_FORBIDDEN" || status === 403) {
22837
- return message2 ? `Owner PAT does not control initiator agent DID (403): ${message2}` : "Owner PAT does not control initiator agent DID (403).";
23251
+ if (code === "PROXY_PAIR_OWNERSHIP_FORBIDDEN" || status === 403) {
23252
+ return message2 ? `Initiator agent ownership check failed (403): ${message2}` : "Initiator agent ownership check failed (403).";
22838
23253
  }
22839
23254
  if (status === 400) {
22840
23255
  return message2 ? `Pair start request is invalid (400): ${message2}` : "Pair start request is invalid (400).";
@@ -23035,16 +23450,6 @@ async function readAgentProofMaterial(agentName, dependencies) {
23035
23450
  secretKey
23036
23451
  };
23037
23452
  }
23038
- function resolveOwnerPat(options) {
23039
- const ownerPat = parseNonEmptyString9(options.explicitOwnerPat) || parseNonEmptyString9(options.config.apiKey);
23040
- if (ownerPat.length > 0) {
23041
- return ownerPat;
23042
- }
23043
- throw createCliError7(
23044
- "CLI_PAIR_START_OWNER_PAT_REQUIRED",
23045
- "Owner PAT is required. Pass --owner-pat <token> or configure API key with `clawdentity invite redeem` / `clawdentity config set apiKey <token>`."
23046
- );
23047
- }
23048
23453
  async function buildSignedHeaders(input) {
23049
23454
  const signed = await signHttpRequest({
23050
23455
  method: input.method,
@@ -23200,10 +23605,6 @@ async function startPairing(agentName, options, dependencies = {}) {
23200
23605
  const nonceFactoryImpl = dependencies.nonceFactoryImpl ?? (() => randomBytes4(NONCE_SIZE2).toString("base64url"));
23201
23606
  const ttlSeconds = parseTtlSeconds(options.ttlSeconds);
23202
23607
  const config2 = await resolveConfigImpl();
23203
- const ownerPat = resolveOwnerPat({
23204
- explicitOwnerPat: options.ownerPat,
23205
- config: config2
23206
- });
23207
23608
  const proxyUrl = await resolveProxyUrl({
23208
23609
  config: config2,
23209
23610
  fetchImpl
@@ -23235,7 +23636,6 @@ async function startPairing(agentName, options, dependencies = {}) {
23235
23636
  headers: {
23236
23637
  authorization: `Claw ${ait}`,
23237
23638
  "content-type": "application/json",
23238
- [OWNER_PAT_HEADER]: ownerPat,
23239
23639
  ...signedHeaders
23240
23640
  },
23241
23641
  body: requestBody
@@ -23479,11 +23879,7 @@ async function getPairingStatus(agentName, options, dependencies = {}) {
23479
23879
  }
23480
23880
  const ticket = parsePairingTicket(ticketRaw);
23481
23881
  if (options.wait !== true) {
23482
- return getPairingStatusOnce(
23483
- agentName,
23484
- { ticket },
23485
- dependencies
23486
- );
23882
+ return getPairingStatusOnce(agentName, { ticket }, dependencies);
23487
23883
  }
23488
23884
  const waitSeconds = parsePositiveIntegerOption({
23489
23885
  value: options.waitSeconds,
@@ -23507,10 +23903,7 @@ var createPairCommand = (dependencies = {}) => {
23507
23903
  const pairCommand = new Command8("pair").description(
23508
23904
  "Manage proxy trust pairing between agents"
23509
23905
  );
23510
- pairCommand.command("start <agentName>").description("Start pairing and issue one-time pairing ticket").option(
23511
- "--owner-pat <token>",
23512
- "Owner PAT override (defaults to configured API key)"
23513
- ).option("--ttl-seconds <seconds>", "Pairing ticket expiry in seconds").option("--qr", "Generate a local QR file for sharing").option("--qr-output <path>", "Write QR PNG to a specific file path").option(
23906
+ pairCommand.command("start <agentName>").description("Start pairing and issue one-time pairing ticket").option("--ttl-seconds <seconds>", "Pairing ticket expiry in seconds").option("--qr", "Generate a local QR file for sharing").option("--qr-output <path>", "Write QR PNG to a specific file path").option(
23514
23907
  "--wait",
23515
23908
  "Wait for responder confirmation and auto-save peer on initiator"
23516
23909
  ).option(
@@ -23566,10 +23959,14 @@ var createPairCommand = (dependencies = {}) => {
23566
23959
  writeStdoutLine("Pairing confirmed");
23567
23960
  writeStdoutLine(`Status: ${status.status}`);
23568
23961
  if (status.initiatorAgentDid) {
23569
- writeStdoutLine(`Initiator Agent DID: ${status.initiatorAgentDid}`);
23962
+ writeStdoutLine(
23963
+ `Initiator Agent DID: ${status.initiatorAgentDid}`
23964
+ );
23570
23965
  }
23571
23966
  if (status.responderAgentDid) {
23572
- writeStdoutLine(`Responder Agent DID: ${status.responderAgentDid}`);
23967
+ writeStdoutLine(
23968
+ `Responder Agent DID: ${status.responderAgentDid}`
23969
+ );
23573
23970
  }
23574
23971
  if (status.peerAlias) {
23575
23972
  writeStdoutLine(`Peer alias saved: ${status.peerAlias}`);
@@ -23609,7 +24006,11 @@ var createPairCommand = (dependencies = {}) => {
23609
24006
  withErrorHandling(
23610
24007
  "pair status",
23611
24008
  async (agentName, options) => {
23612
- const result = await getPairingStatus(agentName, options, dependencies);
24009
+ const result = await getPairingStatus(
24010
+ agentName,
24011
+ options,
24012
+ dependencies
24013
+ );
23613
24014
  logger9.info("cli.pair_status", {
23614
24015
  initiatorAgentDid: result.initiatorAgentDid,
23615
24016
  responderAgentDid: result.responderAgentDid,
@@ -23644,7 +24045,7 @@ import { access as access3, copyFile as copyFile2, mkdir as mkdir7, readdir as r
23644
24045
  import { createRequire } from "module";
23645
24046
  import { homedir as homedir4 } from "os";
23646
24047
  import { dirname as dirname6, join as join8, relative } from "path";
23647
- import { fileURLToPath as fileURLToPath2 } from "url";
24048
+ import { fileURLToPath as fileURLToPath3 } from "url";
23648
24049
  var OPENCLAW_DIR_NAME2 = ".openclaw";
23649
24050
  var SKILL_PACKAGE_NAME = "@clawdentity/openclaw-skill";
23650
24051
  var SKILL_DIR_NAME2 = "clawdentity-openclaw-relay";
@@ -23689,7 +24090,7 @@ function resolveSkillPackageRoot(input) {
23689
24090
  return overriddenRoot.trim();
23690
24091
  }
23691
24092
  const bundledSkillRoot = join8(
23692
- dirname6(fileURLToPath2(import.meta.url)),
24093
+ dirname6(fileURLToPath3(import.meta.url)),
23693
24094
  "..",
23694
24095
  "skill-bundle",
23695
24096
  "openclaw-skill"
@@ -23704,7 +24105,7 @@ function resolveSkillPackageRoot(input) {
23704
24105
  return dirname6(packageJsonPath);
23705
24106
  } catch {
23706
24107
  const workspaceFallbackRoot = join8(
23707
- dirname6(fileURLToPath2(import.meta.url)),
24108
+ dirname6(fileURLToPath3(import.meta.url)),
23708
24109
  "..",
23709
24110
  "..",
23710
24111
  "openclaw-skill"
@@ -23797,11 +24198,7 @@ async function resolveArtifacts(input) {
23797
24198
  }
23798
24199
  });
23799
24200
  }
23800
- const targetSkillRoot = join8(
23801
- input.openclawDir,
23802
- "skills",
23803
- SKILL_DIR_NAME2
23804
- );
24201
+ const targetSkillRoot = join8(input.openclawDir, "skills", SKILL_DIR_NAME2);
23805
24202
  const artifacts = [
23806
24203
  {
23807
24204
  sourcePath: skillDocSource,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawdentity",
3
- "version": "0.0.14",
3
+ "version": "0.0.15",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"