@mirasoth/soothe-client 0.4.0 → 0.4.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/dist/index.cjs CHANGED
@@ -51,7 +51,7 @@ var init_errors = __esm({
51
51
  }
52
52
  };
53
53
  DaemonError = class extends Error {
54
- /** Numeric error code from the RFC-450 §7.3 registry. */
54
+ /** Numeric error code from the daemon error registry. */
55
55
  code;
56
56
  /** The daemon's error message text. */
57
57
  daemonMessage;
@@ -357,7 +357,7 @@ var init_protocol = __esm({
357
357
  import_node_crypto = require("crypto");
358
358
  PROTO_VERSION = "1";
359
359
  DEFAULT_CLIENT_CAPABILITIES = ["streaming", "batch", "heartbeat", "receipts"];
360
- CLIENT_VERSION = "0.4.0";
360
+ CLIENT_VERSION = "0.4.1";
361
361
  }
362
362
  });
363
363
 
@@ -895,7 +895,7 @@ var init_client = __esm({
895
895
  inboundDroppedCount = 0;
896
896
  onStreamDegraded = null;
897
897
  resolvers = [];
898
- // Protocol-1 handshake state (RFC-450 §8.2)
898
+ // Protocol-1 handshake state
899
899
  handshakeComplete = false;
900
900
  negotiatedCapabilities = /* @__PURE__ */ new Set();
901
901
  protocolVersion = null;
@@ -903,12 +903,12 @@ var init_client = __esm({
903
903
  heartbeatIntervalMs = 0;
904
904
  heartbeatTimer = null;
905
905
  lastPongMonotonic = 0;
906
- // Mid-session drop signal (RFC-450 §8.3). The 'disconnected' event is
906
+ // Mid-session drop signal. The 'disconnected' event is
907
907
  // emitted exactly once when the connection drops, carrying a DisconnectCause
908
908
  // that distinguishes clean (peer `disconnect`) from unclean (read/write
909
909
  // error or missed pong). `disconnFired` guards the once-only delivery.
910
910
  disconnFired = false;
911
- // Pending-request/subscription multiplexer (RFC-629 constraint #1). Routes
911
+ // Pending-request/subscription multiplexer. Routes
912
912
  // inbound frames by (type, id) instead of discarding non-matching events.
913
913
  mux = new Multiplexer();
914
914
  deliveryRecvSeq = /* @__PURE__ */ new Map();
@@ -1025,7 +1025,7 @@ var init_client = __esm({
1025
1025
  return this.ws !== null && this.ws.readyState === import_ws.default.OPEN && this.handshakeComplete;
1026
1026
  }
1027
1027
  // ---------------------------------------------------------------------------
1028
- // Mid-session drop signal + reconnect/reattach (RFC-450 §8.3, RFC-629 L0)
1028
+ // Mid-session drop signal + reconnect/reattach
1029
1029
  // ---------------------------------------------------------------------------
1030
1030
  /**
1031
1031
  * Returns whether the connection has dropped (the `'disconnected'` event has
@@ -1060,8 +1060,8 @@ var init_client = __esm({
1060
1060
  }
1061
1061
  }
1062
1062
  /**
1063
- * Re-dials the daemon and re-handshakes after a connection drop (RFC-450
1064
- * §8.3). Does not re-establish loop subscriptions; follow with
1063
+ * Re-dials the daemon and re-handshakes after a connection drop.
1064
+ * Does not re-establish loop subscriptions; follow with
1065
1065
  * `reattachAndProbe()` to resume a loop session. The caller should invoke
1066
1066
  * this after the `'disconnected'` event fires. Reuses the same Client,
1067
1067
  * resetting the drop signal and multiplexer.
@@ -1095,7 +1095,7 @@ var init_client = __esm({
1095
1095
  * Returns a `StaleLoopError` when the probe fails; callers should fall back
1096
1096
  * to a fresh `loop_new` bootstrap.
1097
1097
  *
1098
- * Per RFC-629: connection-level readiness is the handshake's readiness_state
1098
+ * Note: connection-level readiness is the handshake's readiness_state
1099
1099
  * (+ daemon_status); loop_get is a loop-scoped probe only, not a readiness
1100
1100
  * probe.
1101
1101
  */
@@ -1136,7 +1136,7 @@ var init_client = __esm({
1136
1136
  }
1137
1137
  }
1138
1138
  // ---------------------------------------------------------------------------
1139
- // Protocol-1 handshake (RFC-450 §8.2)
1139
+ // Protocol-1 handshake
1140
1140
  // ---------------------------------------------------------------------------
1141
1141
  /** Send connection_init and wait for connection_ack with readiness "ready". */
1142
1142
  async _performHandshake() {
@@ -1185,7 +1185,7 @@ var init_client = __esm({
1185
1185
  throw new Error(`timeout after ${this.config.daemonReadyTimeout}ms waiting for connection_ack`);
1186
1186
  }
1187
1187
  // ---------------------------------------------------------------------------
1188
- // Heartbeat (RFC-450 §8.3)
1188
+ // Heartbeat
1189
1189
  // ---------------------------------------------------------------------------
1190
1190
  _startHeartbeat() {
1191
1191
  if (!this.negotiatedCapabilities.has("heartbeat")) return;
@@ -1380,7 +1380,7 @@ var init_client = __esm({
1380
1380
  }
1381
1381
  }
1382
1382
  // ---------------------------------------------------------------------------
1383
- // Protocol-1 RPC primitives (RFC-450 §5/§9)
1383
+ // Protocol-1 RPC primitives
1384
1384
  // ---------------------------------------------------------------------------
1385
1385
  /**
1386
1386
  * Reads the next frame directly from the live socket (via a resolver),
@@ -1406,16 +1406,16 @@ var init_client = __esm({
1406
1406
  });
1407
1407
  }
1408
1408
  /**
1409
- * Sends a `request` envelope and waits for the matching `response` (or
1410
- * `error`) correlated by `id` (RFC-450 §5/§9). Returns the `result` object.
1411
- *
1412
- * Multiplexer-aware (RFC-629 constraint #1): registers a pending RPC wait
1413
- * keyed by the request id so that, even when a `receiveMessages()` reader
1414
- * is concurrently active, the matching `response`/`error` is routed to
1415
- * this caller instead of being discarded or buffered behind a stream.
1416
- * Non-matching frames are routed to their own waiters by the multiplexer
1417
- * or flow on to the resolver queue for stream readers.
1418
- */
1409
+ * Sends a `request` envelope and waits for the matching `response` (or
1410
+ * `error`) correlated by `id`. Returns the `result` object.
1411
+ *
1412
+ * Multiplexer-aware: registers a pending RPC wait
1413
+ * keyed by the request id so that, even when a `receiveMessages()` reader
1414
+ * is concurrently active, the matching `response`/`error` is routed to
1415
+ * this caller instead of being discarded or buffered behind a stream.
1416
+ * Non-matching frames are routed to their own waiters by the multiplexer
1417
+ * or flow on to the resolver queue for stream readers.
1418
+ */
1419
1419
  async requestResponse(method, params, responseType, timeout = 15e3) {
1420
1420
  const req = requestEnvelope(method, params);
1421
1421
  const rid = req.id;
@@ -1566,7 +1566,7 @@ var init_client = __esm({
1566
1566
  return ev;
1567
1567
  }
1568
1568
  // ---------------------------------------------------------------------------
1569
- // High-level API methods (Loop-first, RFC-503)
1569
+ // High-level API methods
1570
1570
  // ---------------------------------------------------------------------------
1571
1571
  /** Sends user input to the daemon (loop_input notification; requires loopID). */
1572
1572
  sendInput(text, options) {
@@ -1605,7 +1605,7 @@ var init_client = __esm({
1605
1605
  return this.notify("slash_command", { cmd });
1606
1606
  }
1607
1607
  // ---------------------------------------------------------------------------
1608
- // Loop lifecycle methods (RFC-503)
1608
+ // Loop lifecycle methods
1609
1609
  // ---------------------------------------------------------------------------
1610
1610
  /** Requests the daemon to create a new StrangeLoop and waits for the response. */
1611
1611
  sendLoopNew(opts) {
@@ -1700,7 +1700,7 @@ var init_client = __esm({
1700
1700
  sendLoopCardsFetch(loopID) {
1701
1701
  return this.sendMessage(requestEnvelope("loop_cards_fetch", { loop_id: loopID }));
1702
1702
  }
1703
- /** Requests the full loop history (RFC-631). */
1703
+ /** Requests the full loop history. */
1704
1704
  sendLoopHistoryFetch(loopID) {
1705
1705
  return this.sendMessage(requestEnvelope("loop_history_fetch", { loop_id: loopID }));
1706
1706
  }
@@ -1795,7 +1795,7 @@ var init_client = __esm({
1795
1795
  );
1796
1796
  }
1797
1797
  // ---------------------------------------------------------------------------
1798
- // RFC-228 Job IPC methods
1798
+ // Job IPC methods
1799
1799
  // ---------------------------------------------------------------------------
1800
1800
  /** Creates an autopilot job and waits for the response. */
1801
1801
  createJob(goal, verificationRules, workspace, timeout) {
@@ -1830,6 +1830,98 @@ var init_client = __esm({
1830
1830
  if (goalId) params.goal_id = goalId;
1831
1831
  return this.requestResponse("job_guidance", params, "job_guidance", timeout ?? 3e4);
1832
1832
  }
1833
+ // ---------------------------------------------------------------------------
1834
+ // Autopilot goal RPCs (protocol-1 request methods)
1835
+ // ---------------------------------------------------------------------------
1836
+ /** Return autopilot scheduler status (running / dreaming / pool). */
1837
+ autopilotStatus(timeout) {
1838
+ return this.requestResponse("autopilot_status", {}, "autopilot_status", timeout ?? 15e3);
1839
+ }
1840
+ /** Submit a new autopilot goal (returns goal_id). */
1841
+ autopilotSubmit(description, opts) {
1842
+ const params = {
1843
+ description,
1844
+ priority: opts?.priority ?? 50
1845
+ };
1846
+ if (opts?.workspace) params.workspace = opts.workspace;
1847
+ return this.requestResponse(
1848
+ "autopilot_submit",
1849
+ params,
1850
+ "autopilot_submit",
1851
+ opts?.timeout ?? 15e3
1852
+ );
1853
+ }
1854
+ /** List all goals (including non-root children). */
1855
+ autopilotListGoals(timeout) {
1856
+ return this.requestResponse(
1857
+ "autopilot_list_goals",
1858
+ {},
1859
+ "autopilot_list_goals",
1860
+ timeout ?? 15e3
1861
+ );
1862
+ }
1863
+ /** Fetch one goal by id. */
1864
+ autopilotGetGoal(goalId, timeout) {
1865
+ return this.requestResponse(
1866
+ "autopilot_get_goal",
1867
+ { goal_id: goalId },
1868
+ "autopilot_get_goal",
1869
+ timeout ?? 15e3
1870
+ );
1871
+ }
1872
+ /** Cancel a goal and its non-terminal descendants. */
1873
+ autopilotCancelGoal(goalId, timeout) {
1874
+ return this.requestResponse(
1875
+ "autopilot_cancel_goal",
1876
+ { goal_id: goalId },
1877
+ "autopilot_cancel_goal",
1878
+ timeout ?? 15e3
1879
+ );
1880
+ }
1881
+ /** Cancel every open (non-terminal) goal. */
1882
+ autopilotCancelAll(timeout) {
1883
+ return this.requestResponse(
1884
+ "autopilot_cancel_all",
1885
+ {},
1886
+ "autopilot_cancel_all",
1887
+ timeout ?? 15e3
1888
+ );
1889
+ }
1890
+ /** Exit dreaming mode and resume scheduling. */
1891
+ autopilotWake(timeout) {
1892
+ return this.requestResponse("autopilot_wake", {}, "autopilot_wake", timeout ?? 15e3);
1893
+ }
1894
+ /** Force dreaming mode. */
1895
+ autopilotDream(timeout) {
1896
+ return this.requestResponse("autopilot_dream", {}, "autopilot_dream", timeout ?? 15e3);
1897
+ }
1898
+ /** Resume a suspended or blocked goal. */
1899
+ autopilotResume(goalId, timeout) {
1900
+ return this.requestResponse(
1901
+ "autopilot_resume",
1902
+ { goal_id: goalId },
1903
+ "autopilot_resume",
1904
+ timeout ?? 15e3
1905
+ );
1906
+ }
1907
+ /** List root goals only (jobs). Prefer createJob / getJobStatus for job control. */
1908
+ autopilotListJobs(timeout) {
1909
+ return this.requestResponse(
1910
+ "autopilot_list_jobs",
1911
+ {},
1912
+ "autopilot_list_jobs",
1913
+ timeout ?? 15e3
1914
+ );
1915
+ }
1916
+ /** Get a root job with DAG snapshot. Prefer getJobStatus / getJobDag. */
1917
+ autopilotGetJob(jobId, timeout) {
1918
+ return this.requestResponse(
1919
+ "autopilot_get_job",
1920
+ { job_id: jobId },
1921
+ "autopilot_get_job",
1922
+ timeout ?? 15e3
1923
+ );
1924
+ }
1833
1925
  /** Subscribes to autopilot worker events. */
1834
1926
  autopilotSubscribe(timeout) {
1835
1927
  return this.subscribe("autopilot_events", {}, timeout ?? 15e3);
@@ -1840,7 +1932,7 @@ var init_client = __esm({
1840
1932
  return this._requestResponseForEnvelope(req, "autopilot_unsubscribe", timeout ?? 15e3);
1841
1933
  }
1842
1934
  // ---------------------------------------------------------------------------
1843
- // RFC-229 Cron IPC methods
1935
+ // Cron IPC methods
1844
1936
  // ---------------------------------------------------------------------------
1845
1937
  /** Creates a scheduled job from natural language. */
1846
1938
  cronAdd(text, priority, timeout) {
@@ -2180,6 +2272,55 @@ var CommandClient = class {
2180
2272
  async jobCancel(jobId) {
2181
2273
  return this.request("job_cancel", { job_id: jobId });
2182
2274
  }
2275
+ /** Return autopilot scheduler status (running / dreaming / pool). */
2276
+ async autopilotStatus() {
2277
+ return this.request("autopilot_status");
2278
+ }
2279
+ /** Submit a new autopilot goal (returns goal_id). */
2280
+ async autopilotSubmit(description, opts) {
2281
+ const params = {
2282
+ description,
2283
+ priority: opts?.priority ?? 50
2284
+ };
2285
+ if (opts?.workspace) params.workspace = opts.workspace;
2286
+ return this.request("autopilot_submit", params);
2287
+ }
2288
+ /** List all goals (including non-root children). */
2289
+ async autopilotListGoals() {
2290
+ return this.request("autopilot_list_goals");
2291
+ }
2292
+ /** Fetch one goal by id. */
2293
+ async autopilotGetGoal(goalId) {
2294
+ return this.request("autopilot_get_goal", { goal_id: goalId });
2295
+ }
2296
+ /** Cancel a goal and its non-terminal descendants. */
2297
+ async autopilotCancelGoal(goalId) {
2298
+ return this.request("autopilot_cancel_goal", { goal_id: goalId });
2299
+ }
2300
+ /** Cancel every open (non-terminal) goal. */
2301
+ async autopilotCancelAll() {
2302
+ return this.request("autopilot_cancel_all");
2303
+ }
2304
+ /** Exit dreaming mode and resume scheduling. */
2305
+ async autopilotWake() {
2306
+ return this.request("autopilot_wake");
2307
+ }
2308
+ /** Force dreaming mode. */
2309
+ async autopilotDream() {
2310
+ return this.request("autopilot_dream");
2311
+ }
2312
+ /** Resume a suspended or blocked goal. */
2313
+ async autopilotResume(goalId) {
2314
+ return this.request("autopilot_resume", { goal_id: goalId });
2315
+ }
2316
+ /** List root goals only (jobs). Prefer job* for job control. */
2317
+ async autopilotListJobs() {
2318
+ return this.request("autopilot_list_jobs");
2319
+ }
2320
+ /** Get a root job with DAG snapshot. Prefer jobStatus / getJobDag. */
2321
+ async autopilotGetJob(jobId) {
2322
+ return this.request("autopilot_get_job", { job_id: jobId });
2323
+ }
2183
2324
  async cronAdd(text, priority = 0) {
2184
2325
  const params = { text };
2185
2326
  if (priority > 0) params.priority = priority;