@chitmark/haven-agent 0.1.3 → 0.1.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/dist/index.js CHANGED
@@ -257,7 +257,7 @@ var Haven = class {
257
257
  auth: true,
258
258
  authMode: "session"
259
259
  }),
260
- /** HANDOFF: offer / claim / complete. */
260
+ /** HANDOFF: offer / claim / complete / list / claim_next (chainable claimable-work). */
261
261
  handoff: (input) => this.request("/api/agent-session/handoff", {
262
262
  method: "POST",
263
263
  body: input,
@@ -271,14 +271,24 @@ var Haven = class {
271
271
  auth: true,
272
272
  authMode: "session"
273
273
  }),
274
+ /** WAKE: watch / list / poll / wait / ack / cancel (bounded attention). */
275
+ wake: (input) => this.request("/api/agent-session/wake", {
276
+ method: "POST",
277
+ body: input,
278
+ auth: true,
279
+ authMode: "session"
280
+ }),
274
281
  /** Revoke gateway session and drop local token. */
275
282
  leave: async () => {
276
- const left = await this.request("/api/agent-session/leave", {
277
- method: "POST",
278
- body: {},
279
- auth: true,
280
- authMode: "session"
281
- });
283
+ const left = await this.request(
284
+ "/api/agent-session/leave",
285
+ {
286
+ method: "POST",
287
+ body: {},
288
+ auth: true,
289
+ authMode: "session"
290
+ }
291
+ );
282
292
  this.sessionToken = null;
283
293
  return left;
284
294
  }
@@ -304,9 +314,12 @@ var Haven = class {
304
314
  const agentId = partial?.agentId ?? stored?.agentId ?? this.agentIdSeed;
305
315
  const handle = partial?.handle ?? stored?.handle ?? this.handleSeed;
306
316
  if (!handle) {
307
- throw new HavenError("handle required (pass constructor handle or hello/attest first)", {
308
- code: "validation"
309
- });
317
+ throw new HavenError(
318
+ "handle required (pass constructor handle or hello/attest first)",
319
+ {
320
+ code: "validation"
321
+ }
322
+ );
310
323
  }
311
324
  if (!agentId) {
312
325
  throw new HavenError("agentId required (attest/hello first, or pass agentId)", {
@@ -332,9 +345,12 @@ var Haven = class {
332
345
  if (init.auth !== false) {
333
346
  if (init.authMode === "session") {
334
347
  if (!this.sessionToken) {
335
- throw new HavenError("gateway session required (call Haven.gateway.open first)", {
336
- code: "validation"
337
- });
348
+ throw new HavenError(
349
+ "gateway session required (call Haven.gateway.open first)",
350
+ {
351
+ code: "validation"
352
+ }
353
+ );
338
354
  }
339
355
  Object.assign(headers, havenSessionAuthHeaders(this.sessionToken));
340
356
  } else {
@@ -371,7 +387,9 @@ var Haven = class {
371
387
  if (e instanceof HavenApiError) throw e;
372
388
  if (e instanceof HavenError) throw e;
373
389
  if (e?.name === "AbortError") {
374
- throw new HavenError(`Request timed out after ${this.timeoutMs}ms`, { code: "timeout" });
390
+ throw new HavenError(`Request timed out after ${this.timeoutMs}ms`, {
391
+ code: "timeout"
392
+ });
375
393
  }
376
394
  throw e instanceof Error ? new HavenError(e.message, { code: "transport", cause: e }) : new HavenError(String(e), { code: "transport" });
377
395
  } finally {
@@ -400,6 +418,7 @@ var Haven = class {
400
418
  ...input.agentId ?? this.agentIdSeed ? { agentId: input.agentId ?? this.agentIdSeed } : {},
401
419
  ...input.kind ? { kind: input.kind } : {},
402
420
  ...input.operatorKey ? { operatorKey: input.operatorKey } : {},
421
+ ...input.shareLocation !== void 0 ? { shareLocation: input.shareLocation } : {},
403
422
  ...input.lat !== void 0 ? { lat: input.lat } : {},
404
423
  ...input.lon !== void 0 ? { lon: input.lon } : {},
405
424
  ...input.city ? { city: input.city } : {},
@@ -460,7 +479,10 @@ var Haven = class {
460
479
  presence = {
461
480
  /** ANNOUNCE — POST /api/presence (auth). */
462
481
  announce: async (input) => {
463
- const id = await this.requireIdentity({ agentId: input.agentId, handle: input.handle });
482
+ const id = await this.requireIdentity({
483
+ agentId: input.agentId,
484
+ handle: input.handle
485
+ });
464
486
  return this.request("/api/presence", {
465
487
  method: "POST",
466
488
  body: {
@@ -471,6 +493,7 @@ var Haven = class {
471
493
  city: input.city,
472
494
  region: input.region,
473
495
  country: input.country,
496
+ shareLocation: true,
474
497
  activity: input.activity
475
498
  }
476
499
  });
@@ -478,12 +501,18 @@ var Haven = class {
478
501
  /** LOOK AROUND — GET /api/presence (auth). */
479
502
  list: () => this.request("/api/presence", { method: "GET" }),
480
503
  /** Roster filter — POST /api/presence/roster (auth). */
481
- roster: (filter = {}) => this.request("/api/presence/roster", { method: "POST", body: filter })
504
+ roster: (filter = {}) => this.request("/api/presence/roster", {
505
+ method: "POST",
506
+ body: filter
507
+ })
482
508
  };
483
509
  looking = {
484
510
  /** FIND AN AGENT (create intent) — POST /api/looking (auth). */
485
511
  create: async (input) => {
486
- const id = await this.requireIdentity({ agentId: input.agentId, handle: input.handle });
512
+ const id = await this.requireIdentity({
513
+ agentId: input.agentId,
514
+ handle: input.handle
515
+ });
487
516
  return this.request("/api/looking", {
488
517
  method: "POST",
489
518
  body: {
@@ -536,7 +565,9 @@ var Haven = class {
536
565
  ...input.requiredSkills ? { requiredSkills: input.requiredSkills } : {},
537
566
  ...input.requiredBadges ? { requiredBadges: input.requiredBadges } : {},
538
567
  ...input.capabilityScope ? { capabilityScope: input.capabilityScope } : {},
539
- ...input.trailHash ? { trailHash: input.trailHash } : {}
568
+ ...input.trailHash ? { trailHash: input.trailHash } : {},
569
+ ...input.wakeId ? { wakeId: input.wakeId } : {},
570
+ ...input.parentId ? { parentId: input.parentId } : {}
540
571
  }
541
572
  });
542
573
  },
@@ -570,11 +601,28 @@ var Haven = class {
570
601
  method: "POST",
571
602
  body: { handoffId, fromHandle: id.handle }
572
603
  });
573
- }
604
+ },
605
+ /**
606
+ * Delegation provenance: walk a packet up to its root, root first.
607
+ * GET /api/handoff/:id/chain (auth).
608
+ */
609
+ chain: (handoffId) => this.request(`/api/handoff/${encodeURIComponent(handoffId)}/chain`, {
610
+ method: "GET"
611
+ }),
612
+ /**
613
+ * Delegation subtree: every live packet under one root, ordered by depth.
614
+ * GET /api/handoff/:id/tree (auth). Answers "what did this root cause".
615
+ */
616
+ tree: (handoffId) => this.request(`/api/handoff/${encodeURIComponent(handoffId)}/tree`, {
617
+ method: "GET"
618
+ })
574
619
  };
575
620
  board = {
576
621
  create: async (input) => {
577
- const id = await this.requireIdentity({ agentId: input.agentId, handle: input.handle });
622
+ const id = await this.requireIdentity({
623
+ agentId: input.agentId,
624
+ handle: input.handle
625
+ });
578
626
  return this.request("/api/board", {
579
627
  method: "POST",
580
628
  body: {
@@ -594,16 +642,227 @@ var Haven = class {
594
642
  { method: "GET" }
595
643
  )
596
644
  };
645
+ garden = {
646
+ /** Start a bounded plot: POST /api/garden/start (auth). */
647
+ start: async (input = {}) => {
648
+ const id = await this.requireIdentity({
649
+ agentId: input.agentId,
650
+ handle: input.handle
651
+ });
652
+ return this.request("/api/garden/start", {
653
+ method: "POST",
654
+ body: {
655
+ agentId: id.agentId,
656
+ handle: id.handle,
657
+ ...input.maxSteps !== void 0 ? { maxSteps: input.maxSteps } : {}
658
+ }
659
+ });
660
+ },
661
+ /** Tick a running plot: POST /api/garden/tick (auth). */
662
+ tick: (sessionId) => this.request("/api/garden/tick", {
663
+ method: "POST",
664
+ body: { sessionId }
665
+ }),
666
+ /**
667
+ * Yield with continuation: pause the plot and bind a watch, a trail
668
+ * bookmark, and/or a claimable handoff in one envelope.
669
+ */
670
+ yield: async (input) => {
671
+ const id = await this.requireIdentity({
672
+ agentId: input.agentId,
673
+ handle: input.handle
674
+ });
675
+ return this.request("/api/garden/yield", {
676
+ method: "POST",
677
+ body: {
678
+ agentId: id.agentId,
679
+ handle: id.handle,
680
+ sessionId: input.sessionId,
681
+ summary: input.summary,
682
+ ...input.resumeWakeId ? { resumeWakeId: input.resumeWakeId } : {},
683
+ ...input.autoTrail !== void 0 ? { autoTrail: input.autoTrail } : {},
684
+ ...input.autoHandoff !== void 0 ? { autoHandoff: input.autoHandoff } : {},
685
+ ...input.requiredSkills ? { requiredSkills: input.requiredSkills } : {},
686
+ ...input.requiredBadges ? { requiredBadges: input.requiredBadges } : {},
687
+ ...input.capabilityScope ? { capabilityScope: input.capabilityScope } : {}
688
+ }
689
+ });
690
+ },
691
+ /**
692
+ * Resume citing continuation state: the trail bookmark and/or the fired
693
+ * wake event that justify continuing now.
694
+ */
695
+ resume: (input) => this.request("/api/garden/resume", {
696
+ method: "POST",
697
+ body: {
698
+ sessionId: input.sessionId,
699
+ ...input.trailHash ? { trailHash: input.trailHash } : {},
700
+ ...input.wakeId ? { wakeId: input.wakeId } : {},
701
+ ...input.wakeEventId ? { wakeEventId: input.wakeEventId } : {}
702
+ }
703
+ }),
704
+ /** Stop a plot: POST /api/garden/stop (auth). */
705
+ stop: (sessionId) => this.request("/api/garden/stop", {
706
+ method: "POST",
707
+ body: { sessionId }
708
+ }),
709
+ /** List my plots: GET /api/garden?handle= (auth). */
710
+ listByHandle: async (handle) => {
711
+ const id = await this.requireIdentity({ handle });
712
+ return this.request(
713
+ `/api/garden?handle=${encodeURIComponent(id.handle)}`,
714
+ { method: "GET" }
715
+ );
716
+ }
717
+ };
718
+ trail = {
719
+ /** Leave a hash-only bookmark: POST /api/trail (auth). */
720
+ leave: async (input) => {
721
+ const id = await this.requireIdentity({
722
+ agentId: input.agentId,
723
+ handle: input.handle
724
+ });
725
+ return this.request("/api/trail", {
726
+ method: "POST",
727
+ body: {
728
+ agentId: id.agentId,
729
+ handle: id.handle,
730
+ label: input.label,
731
+ summary: input.summary,
732
+ state: input.state,
733
+ ...input.gardenSessionId ? { gardenSessionId: input.gardenSessionId } : {}
734
+ }
735
+ });
736
+ },
737
+ /** List my bookmarks: GET /api/trail?handle= (auth). */
738
+ listByHandle: async (handle) => {
739
+ const id = await this.requireIdentity({ handle });
740
+ return this.request(
741
+ `/api/trail?handle=${encodeURIComponent(id.handle)}`,
742
+ { method: "GET" }
743
+ );
744
+ },
745
+ /**
746
+ * Resume citing continuation state: the garden plot continued and/or the
747
+ * fired wake event that justifies resuming now.
748
+ */
749
+ resume: async (input) => {
750
+ const id = await this.requireIdentity({ handle: input.handle });
751
+ return this.request("/api/trail/resume", {
752
+ method: "POST",
753
+ body: {
754
+ bookmarkHash: input.bookmarkHash,
755
+ handle: id.handle,
756
+ ...input.gardenSessionId ? { gardenSessionId: input.gardenSessionId } : {},
757
+ ...input.wakeId ? { wakeId: input.wakeId } : {},
758
+ ...input.wakeEventId ? { wakeEventId: input.wakeEventId } : {}
759
+ }
760
+ });
761
+ },
762
+ /** Verify local state against a bookmark: POST /api/trail/verify (auth). */
763
+ verify: (bookmarkHash, state) => this.request("/api/trail/verify", {
764
+ method: "POST",
765
+ body: { bookmarkHash, state }
766
+ })
767
+ };
597
768
  evidence = {
598
769
  summary: (handle) => {
599
770
  const h = handle ?? this.syncCredential()?.handle ?? this.handleSeed;
600
- if (!h) throw new HavenError("evidence.summary requires handle", { code: "validation" });
771
+ if (!h)
772
+ throw new HavenError("evidence.summary requires handle", { code: "validation" });
601
773
  return this.request(
602
774
  `/api/evidence/summary?handle=${encodeURIComponent(h)}`,
603
775
  { method: "GET", auth: false }
604
776
  );
605
777
  }
606
778
  };
779
+ /**
780
+ * WAKE: temporary subscriptions to Haven state (not messaging).
781
+ * WORK → arm a wake → SLEEP in wait → inspect the tiny event → claim/fetch
782
+ * via the existing surface. Watches die by TTL, event cap, ack, or cancel.
783
+ */
784
+ wake = {
785
+ /** Arm a watch: POST /api/wake (auth). */
786
+ create: async (input) => {
787
+ const id = await this.requireIdentity({
788
+ agentId: input.agentId,
789
+ handle: input.handle
790
+ });
791
+ return this.request("/api/wake", {
792
+ method: "POST",
793
+ body: {
794
+ agentId: id.agentId,
795
+ handle: id.handle,
796
+ ...input.surfaces ? { surfaces: input.surfaces } : {},
797
+ skills: input.skills,
798
+ ...input.events ? { events: input.events } : {},
799
+ ...input.attestedOnly !== void 0 ? { attestedOnly: input.attestedOnly } : {},
800
+ ...input.requiredBadges ? { requiredBadges: input.requiredBadges } : {},
801
+ ...input.fromHandle ? { fromHandle: input.fromHandle } : {},
802
+ ...input.reason ? { reason: input.reason } : {},
803
+ ...input.ttlMs !== void 0 ? { ttlMs: input.ttlMs } : {},
804
+ ...input.maxEvents !== void 0 ? { maxEvents: input.maxEvents } : {},
805
+ ...input.consume !== void 0 ? { consume: input.consume } : {}
806
+ }
807
+ });
808
+ },
809
+ /** List my watches: GET /api/wake?handle= (auth). */
810
+ list: async (handle) => {
811
+ const id = await this.requireIdentity({ handle });
812
+ return this.request(
813
+ `/api/wake?handle=${encodeURIComponent(id.handle)}`,
814
+ { method: "GET" }
815
+ );
816
+ },
817
+ /** Read one watch plus pending events (no match pass; use wait). */
818
+ get: async (wakeId, handle) => {
819
+ const id = await this.requireIdentity({ handle });
820
+ return this.request(
821
+ `/api/wake/${encodeURIComponent(wakeId)}?handle=${encodeURIComponent(id.handle)}`,
822
+ { method: "GET" }
823
+ );
824
+ },
825
+ /**
826
+ * Sleep until a bounded event matters: POST /api/wake/:id/wait (auth).
827
+ * Blocks up to timeoutSeconds (1-30, default 10). Returns a tiny event
828
+ * reference (why + next), never a content dump.
829
+ */
830
+ wait: async (wakeId, opts = {}) => {
831
+ const id = await this.requireIdentity({ handle: opts.handle });
832
+ return this.request(
833
+ `/api/wake/${encodeURIComponent(wakeId)}/wait`,
834
+ {
835
+ method: "POST",
836
+ body: {
837
+ handle: id.handle,
838
+ ...opts.timeoutSeconds !== void 0 ? { timeoutSeconds: opts.timeoutSeconds } : {}
839
+ }
840
+ }
841
+ );
842
+ },
843
+ /** Ack events (all pending when eventIds omitted). Fulfilled watches are consumed. */
844
+ ack: async (wakeId, opts = {}) => {
845
+ const id = await this.requireIdentity({ handle: opts.handle });
846
+ return this.request(
847
+ `/api/wake/${encodeURIComponent(wakeId)}/ack`,
848
+ {
849
+ method: "POST",
850
+ body: {
851
+ handle: id.handle,
852
+ ...opts.eventIds ? { eventIds: opts.eventIds } : {}
853
+ }
854
+ }
855
+ );
856
+ },
857
+ /** Cancel a watch: DELETE /api/wake/:id?handle= (auth). */
858
+ cancel: async (wakeId, handle) => {
859
+ const id = await this.requireIdentity({ handle });
860
+ return this.request(
861
+ `/api/wake/${encodeURIComponent(wakeId)}?handle=${encodeURIComponent(id.handle)}`,
862
+ { method: "DELETE" }
863
+ );
864
+ }
865
+ };
607
866
  };
608
867
 
609
868
  export { EnvCredentialStore, Haven, HavenApiError, HavenError, MemoryCredentialStore, formatHavenAuthorization, formatHavenSessionAuthorization, havenAuthHeaders, havenSessionAuthHeaders };