@paigy/harness 0.3.8 → 0.3.9

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.
Files changed (3) hide show
  1. package/dist/cli.js +58 -331
  2. package/dist/main.js +145 -447
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -24062,7 +24062,7 @@ async function subscribeWake(onNudge, opts = {}) {
24062
24062
  }
24063
24063
  };
24064
24064
  }
24065
- var import_undici, require2, __create2, __defProp2, __getOwnPropDesc2, __getOwnPropNames2, __getProtoOf2, __hasOwnProp2, __require2, __commonJS2, __copyProps2, __toESM2, require_nacl_fast, BACKEND_URL, NETWORK_MSG, PROXY_ENV, agent, INSTANCE_ID, WORKSPACE_ID, envSession, SESSION_ID, ignoreOverride, defaultOptions, getDefaultOptions, getRefs, getRelativePath, parseCatchDef, integerDateParser, isJsonSchema7AllOfType, emojiRegex2, zodPatterns, ALPHA_NUMERIC, primitiveMappings, asAnyOf, parseOptionalDef, parsePipelineDef, parseReadonlyDef, selectParser, get$ref, addMeta, zodToJsonSchema, OPTIONS_MIN, OPTIONS_MAX, StartContactSchema, ContactSchema, CONTACT_SCHEMA, CONTACT_DESCRIPTION, CreateGoalSchema, CreateGoalToolSchema, CREATE_GOAL_DESCRIPTION, UpdateGoalSchema, UpdateGoalToolSchema, ClaimGoalSchema, GetGoalSchema, GET_GOAL_DESCRIPTION, UPDATE_GOAL_DESCRIPTION, CLAIM_GOAL_DESCRIPTION, CHECK_REPLIES_DESCRIPTION, CheckRepliesSchema, GetThreadSchema, GET_THREAD_DESCRIPTION, SearchThreadsSchema, SEARCH_THREADS_DESCRIPTION, AGENT_TOOLS, AGENT_TOOL_NAMES, ContextSchema, ParticipantSchema, TransformSchema, OptionSchema, VisualSchema, NotifyLevelSchema, SelectShapeSchema, ReceiptEventSchema, AttentionSchema, NotifyRequestFields, NotifyRequestSchema, NotifyStatusSchema, AgentStateSchema, TurnSchema, UserAnswerSchema, IntentSchema, RideAlongSchema, AwaitItemSchema, CallbackTriggerSchema, NotifyResponseSchema, NotifyPlanUnitSchema, NotifyPlanSchema, UserResponseSchema, VoiceKeySchema, AgendaTurnSchema, CLAIM_STALE_MS, InboxItemSchema, SnoozeRequestSchema, APNS_TOKEN_RE, PushTokenSchema, MissedCallSchema, BrokerTuningSchema, UserSettingsSchema, HistoryItemSchema, ACTIVITY_LINES, ACTIVITY_LINE_MAX, AgentActivitySchema, ConnectionSummarySchema, LedgerItemSchema, AgentLedgerSchema, ReassignResultSchema, MoveRingSchema, MoveSchema, CreateRequestSchema, QueueQuestionSchema, QueueItemSchema, NoteSourceSchema, NoteStatusSchema, NoteRepeatSchema, DecisionSchema, NoteSchema, CreateNoteSchema, RecordDecisionSchema, AssignNoteSchema, TriageVerdictSchema, TriageItemSchema, TriageAssignmentSchema, TriageStatusSchema, SubmitTriageSchema, TriageProposalSchema, AcceptTriageSchema, AcceptTriageResultSchema, DeliveryModeSchema, WAKE_EVENT, wakeChannel, RegisterDeliverySchema, OAuthStartSchema, DeliveryConfigSchema, StatusSchema, EnvelopeRecipientSchema, EnvelopeHeaderSchema, EnvelopeSchema, SealedAnswerSchema, DeviceCredentialSchema, DeviceRosterSchema, WakeNudgeSchema, PairingStatusSchema, PairingRevealSchema, DeviceCodeRequestSchema, DeviceCodeSchema, DeviceInfoSchema, DeviceTokenRequestSchema, DeviceTokenSchema, DeviceCommitRequestSchema, DevicePeerCommitSchema, SupportRequestSchema, NotificationFeedbackKindSchema, NotificationFeedbackSchema, FeedbackResolutionSchema, FeedbackOutcomeSchema, import_tweetnacl, import_tweetnacl2, import_tweetnacl3, import_tweetnacl4, import_tweetnacl5, AGENT_NAME, TOKEN_PATH, KEY_PATH, sleep, UnpairedError, ApiError, AWAIT_WINDOW_MS, tokenOverride, authToken, HEARTBEAT_MS, RETRY_MS, JOIN, lines;
24065
+ var import_undici, require2, __create2, __defProp2, __getOwnPropDesc2, __getOwnPropNames2, __getProtoOf2, __hasOwnProp2, __require2, __commonJS2, __copyProps2, __toESM2, require_nacl_fast, BACKEND_URL, NETWORK_MSG, PROXY_ENV, agent, INSTANCE_ID, WORKSPACE_ID, envSession, SESSION_ID, ignoreOverride, defaultOptions, getDefaultOptions, getRefs, getRelativePath, parseCatchDef, integerDateParser, isJsonSchema7AllOfType, emojiRegex2, zodPatterns, ALPHA_NUMERIC, primitiveMappings, asAnyOf, parseOptionalDef, parsePipelineDef, parseReadonlyDef, selectParser, get$ref, addMeta, zodToJsonSchema, OPTIONS_MIN, OPTIONS_MAX, StartContactSchema, ContactSchema, CONTACT_SCHEMA, CONTACT_DESCRIPTION, CreateGoalSchema, CreateGoalToolSchema, CREATE_GOAL_DESCRIPTION, UpdateGoalSchema, UpdateGoalToolSchema, ClaimGoalSchema, GetGoalSchema, GET_GOAL_DESCRIPTION, UPDATE_GOAL_DESCRIPTION, CLAIM_GOAL_DESCRIPTION, CHECK_REPLIES_DESCRIPTION, CheckRepliesSchema, GetThreadSchema, GET_THREAD_DESCRIPTION, SearchThreadsSchema, SEARCH_THREADS_DESCRIPTION, AGENT_TOOLS, AGENT_TOOL_NAMES, ContextSchema, ParticipantSchema, TransformSchema, OptionSchema, VisualSchema, NotifyLevelSchema, SelectShapeSchema, ReceiptEventSchema, AttentionSchema, NotifyRequestFields, NotifyRequestSchema, NotifyStatusSchema, AgentStateSchema, TurnSchema, UserAnswerSchema, IntentSchema, RideAlongSchema, AwaitItemSchema, VoiceKeySchema, AgendaTurnSchema, CLAIM_STALE_MS, InboxItemSchema, APNS_TOKEN_RE, PushTokenSchema, MissedCallSchema, BrokerTuningSchema, UserSettingsSchema, HistoryItemSchema, ACTIVITY_LINES, ACTIVITY_LINE_MAX, AgentActivitySchema, ConnectionSummarySchema, LedgerItemSchema, AgentLedgerSchema, ReassignResultSchema, MoveRingSchema, MoveSchema, QueueQuestionSchema, QueueItemSchema, NoteSourceSchema, NoteStatusSchema, NoteRepeatSchema, DecisionSchema, NoteSchema, TriageItemSchema, TriageAssignmentSchema, TriageStatusSchema, SubmitTriageSchema, TriageProposalSchema, AcceptTriageSchema, AcceptTriageResultSchema, DeliveryModeSchema, WAKE_EVENT, wakeChannel, RegisterDeliverySchema, OAuthStartSchema, DeliveryConfigSchema, StatusSchema, EnvelopeRecipientSchema, EnvelopeHeaderSchema, EnvelopeSchema, SealedAnswerSchema, DeviceCredentialSchema, DeviceRosterSchema, WakeNudgeSchema, PairingStatusSchema, PairingRevealSchema, DeviceCodeSchema, DeviceInfoSchema, DeviceTokenSchema, SupportRequestSchema, NotificationFeedbackKindSchema, FeedbackResolutionSchema, FeedbackOutcomeSchema, import_tweetnacl, import_tweetnacl2, import_tweetnacl3, import_tweetnacl4, import_tweetnacl5, AGENT_NAME, TOKEN_PATH, KEY_PATH, sleep, UnpairedError, ApiError, AWAIT_WINDOW_MS, tokenOverride, authToken, HEARTBEAT_MS, RETRY_MS, JOIN, lines;
24066
24066
  var init_dist = __esm({
24067
24067
  "../../packages/sdk/dist/index.js"() {
24068
24068
  "use strict";
@@ -26774,9 +26774,9 @@ var init_dist = __esm({
26774
26774
  ClaimGoalSchema = external_exports.object({ goalId: external_exports.string().uuid().optional() }).strict();
26775
26775
  GetGoalSchema = external_exports.object({ goalId: external_exports.string().uuid() }).strict();
26776
26776
  GET_GOAL_DESCRIPTION = "Read the current authorized Goal brief: state, owner, blockers, open decisions, progress, and the next operation. Foreign or sibling-owned Goals are not disclosed.";
26777
- UPDATE_GOAL_DESCRIPTION = "Update an owned Goal at an exact revision. State, ownership, dependencies, children, progress, and review acknowledgement are explicit; stale revisions are rejected. Returns the new revision and a prose summary.";
26777
+ UPDATE_GOAL_DESCRIPTION = "Update an owned Goal at an exact revision. State, ownership, dependencies, children, progress, and review acknowledgement are explicit; stale revisions are rejected. reviewed: true acknowledges new evidence and closes the Deliveries addressed to you on that Goal, never over an open decision. Returns the new revision and a prose summary.";
26778
26778
  CLAIM_GOAL_DESCRIPTION = "Claim the oldest runnable or review-pending Goal you own, or pass goalId to claim that Goal. Returns a Goal-scoped brief, current revision, blockers, and the next valid operation. Claiming creates or renews the execution lease.";
26779
- CHECK_REPLIES_DESCRIPTION = "Your open Deliveries: every Notification or Call currently addressed to you \u2014 a request the user started toward you, an answer relayed to something you asked, a handoff \u2014 each with its durable Entries, accepted decisions and open decision needs, in the same shape a contact read returns. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread it with contact({deliveryId}). Your runnable and review-pending Goals come from claim_goal, not from here.";
26779
+ CHECK_REPLIES_DESCRIPTION = "Your open Deliveries: every Notification or Call currently addressed to you \u2014 a request the user started toward you, an answer relayed to something you asked, a handoff \u2014 one row each: its Goals, the newest words in brief, accepted decisions and open decision needs, without the Entries. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread it in full with contact({deliveryId}). Once you have acted on what arrived, update_goal with reviewed: true closes the Deliveries addressed to you on that Goal. Your runnable and review-pending Goals come from claim_goal, not from here.";
26780
26780
  CheckRepliesSchema = external_exports.object({}).strict();
26781
26781
  GetThreadSchema = external_exports.object({
26782
26782
  parentId: external_exports.string().describe("The Thread to read \u2014 the threadId a Delivery returned, or the parentId of a search hit.")
@@ -27155,67 +27155,6 @@ var init_dist = __esm({
27155
27155
  inFlight: external_exports.boolean().optional()
27156
27156
  })
27157
27157
  ]);
27158
- CallbackTriggerSchema = external_exports.enum(["on_done", "on_blocked", "scheduled"]);
27159
- NotifyResponseSchema = external_exports.object({
27160
- notificationId: external_exports.string(),
27161
- workId: external_exports.string().uuid().optional(),
27162
- decisionId: external_exports.string().uuid().optional(),
27163
- status: NotifyStatusSchema,
27164
- createdAt: external_exports.string().datetime(),
27165
- answer: UserAnswerSchema.optional(),
27166
- answeredAt: external_exports.string().datetime().optional(),
27167
- /** Ride-alongs for THIS agent — pending work it should pick up when it's done with
27168
- * what it came for. Present on any reply, because an unwakeable agent's only
27169
- * reliable moment is one it initiated. Absent/empty = nothing owed. */
27170
- also: external_exports.array(RideAlongSchema).optional()
27171
- });
27172
- NotifyPlanUnitSchema = external_exports.object({
27173
- notificationId: external_exports.string(),
27174
- /** The unit's own heading, so the agent can tell which of its paragraphs this became. */
27175
- title: external_exports.string(),
27176
- /** How loudly this unit was arbitrated to arrive — per unit, which is the point of units. */
27177
- level: NotifyLevelSchema,
27178
- /** Answered from something the user already decided: nobody is interrupted, and a trail card
27179
- * says so. The agent should not wait on this one. */
27180
- settled: external_exports.literal(true).optional(),
27181
- /** What this unit would need to be answerable and does not carry (#894). A PROPOSAL to the
27182
- * agent — nothing here changed the ask, and ignoring it costs nothing. */
27183
- needs: external_exports.array(external_exports.enum(["options", "visuals"])).optional(),
27184
- /** The SHAPE the broker would give this unit, for the agent to ratify (#886/#894). The
27185
- * split layer reads prose and can see that a paragraph is a yes/no or a pick-one — but a
27186
- * broker that DECIDES that destroys the only fact separating a statement from a real ask
27187
- * (#731), so it is offered, never applied: the unit is stored `text` until the agent
27188
- * confirms the shape (POST /notify/:id/confirm). Ignoring it costs nothing. */
27189
- proposal: external_exports.object({
27190
- select: SelectShapeSchema,
27191
- options: external_exports.array(external_exports.object({ label: external_exports.string().min(1) })).optional()
27192
- }).optional(),
27193
- /** What the broker READ this unit as wanting from the human (#952 layer 2): a `decision`
27194
- * between alternatives, an `approval` the agent is blocked on, or `knowledge` it just
27195
- * needs to know. Reported so the agent can correct a misread the same way it ratifies a
27196
- * shape — the read RAISES (a decision always asks) and never silences a question the
27197
- * agent declared (#731, #923). */
27198
- wants: external_exports.enum(["decision", "approval", "knowledge"]).optional()
27199
- });
27200
- NotifyPlanSchema = external_exports.object({
27201
- units: external_exports.array(NotifyPlanUnitSchema),
27202
- /** Which unit is this arrival's ONE interruption (units-design.md D23). Absent means nobody
27203
- * was interrupted — every unit was either settled or quiet enough to sit in the inbox. */
27204
- speaks: external_exports.string().optional()
27205
- });
27206
- UserResponseSchema = external_exports.object({
27207
- requestId: external_exports.string(),
27208
- answer: UserAnswerSchema,
27209
- answeredAt: external_exports.string().datetime(),
27210
- transcript: external_exports.string().optional(),
27211
- /** E2EE: the sealed answer (opaque envelope + plaintext `ignored` hint) when the item was
27212
- * E2EE-sealed. Present → the server persists it opaquely and branches status on `ignored`;
27213
- * the plaintext `answer` is a placeholder (`{ kind: "ignored" }`) the server ignores for a
27214
- * sealed row. Absent = today's plaintext answer, unchanged. */
27215
- sealed: external_exports.lazy(() => SealedAnswerSchema).optional(),
27216
- /** Coverage report (#396): which of the ask's declared `points` were addressed. */
27217
- covered: external_exports.array(external_exports.string()).optional()
27218
- });
27219
27158
  VoiceKeySchema = external_exports.enum(["rachel", "george", "jessica", "brian", "lily"]);
27220
27159
  AgendaTurnSchema = external_exports.object({
27221
27160
  /** THE TURN'S IDENTITY (the first-sentence stream, 2026-09-09): the brain call that wrote
@@ -27399,10 +27338,6 @@ var init_dist = __esm({
27399
27338
  goalState: external_exports.string().optional()
27400
27339
  }).optional()
27401
27340
  });
27402
- SnoozeRequestSchema = external_exports.object({
27403
- requestId: external_exports.string(),
27404
- until: external_exports.string().datetime()
27405
- });
27406
27341
  APNS_TOKEN_RE = /^[0-9a-fA-F]{64}$/;
27407
27342
  PushTokenSchema = external_exports.object({
27408
27343
  voipToken: external_exports.string().min(1).optional(),
@@ -27623,19 +27558,6 @@ var init_dist = __esm({
27623
27558
  * distilled from a clarify ruling (those carry no agent) or one whose source rows are gone. */
27624
27559
  learnedFrom: external_exports.object({ id: external_exports.string(), name: external_exports.string() }).nullable()
27625
27560
  });
27626
- CreateRequestSchema = external_exports.object({
27627
- /** The connection (token id) to send to, from GET /api/tokens. */
27628
- tokenId: external_exports.string(),
27629
- /** The user's message to the agent. */
27630
- text: external_exports.string().min(1),
27631
- /** Land the request on an existing conversation thread (History → "Continue")
27632
- * instead of minting a fresh one. Must belong to the requesting user. */
27633
- parentId: external_exports.string().optional(),
27634
- /** Point the agent at a past conversation (possibly with a different agent) as
27635
- * starting context (History → "New session from this"). A reference, not a copy —
27636
- * the agent reads it via get_thread. Must belong to the requesting user. */
27637
- contextParentId: external_exports.string().optional()
27638
- });
27639
27561
  QueueQuestionSchema = external_exports.object({
27640
27562
  /** The decision need's id — what an answer is accepted against. */
27641
27563
  id: external_exports.string(),
@@ -27727,38 +27649,6 @@ var init_dist = __esm({
27727
27649
  lastRideAt: external_exports.string().nullable().default(null),
27728
27650
  createdAt: external_exports.string()
27729
27651
  });
27730
- CreateNoteSchema = external_exports.object({
27731
- /** The intent, in the user's own words. Stored verbatim; the broker only titles it. */
27732
- text: external_exports.string().min(1).max(4e3),
27733
- /** Capture it as a REMINDER — a note assigned to the user themselves, which rides
27734
- * their next call instead of being handed to an agent. Everything else about the
27735
- * note is identical; this is the one parameter that separates the two. */
27736
- forMe: external_exports.boolean().optional(),
27737
- /** The not-before, when the user already said one. Absent = the very next call. */
27738
- dueAt: external_exports.string().datetime().optional(),
27739
- repeat: NoteRepeatSchema.optional()
27740
- });
27741
- RecordDecisionSchema = external_exports.object({
27742
- /** An open decision (from /clarify) to answer. */
27743
- decisionId: external_exports.string().optional(),
27744
- /** For an ad-hoc decision: what was ambiguous. Required without `decisionId`. */
27745
- question: external_exports.string().min(1).max(500).optional(),
27746
- /** The ruling. */
27747
- answer: external_exports.string().min(1).max(2e3)
27748
- }).refine((d) => d.decisionId || d.question, { message: "decisionId or question required" });
27749
- AssignNoteSchema = external_exports.object({
27750
- /** An EXISTING agent: token id or nickname. Omit when spawning fresh. */
27751
- target: external_exports.string().min(1).optional(),
27752
- /** Spawn a NEW session for this note (companion.md §2.2): the assignee doesn't
27753
- * exist yet — mint it on a live desktop that advertises the harness+workspace,
27754
- * named after the note. The brief arrives as its opening request. */
27755
- spawn: external_exports.object({
27756
- hostTokenId: external_exports.string().uuid(),
27757
- harness: external_exports.string().min(1),
27758
- workspace: external_exports.string().min(1)
27759
- }).optional()
27760
- }).refine((a) => !!a.target !== !!a.spawn, { message: "exactly one of target or spawn" });
27761
- TriageVerdictSchema = external_exports.enum(["keep", "stale", "close", "assign"]);
27762
27652
  TriageItemSchema = external_exports.object({
27763
27653
  noteId: external_exports.string(),
27764
27654
  /** The note's headline at run time. */
@@ -27894,20 +27784,6 @@ var init_dist = __esm({
27894
27784
  ed25519: external_exports.string(),
27895
27785
  nonce: external_exports.string()
27896
27786
  });
27897
- DeviceCodeRequestSchema = external_exports.object({
27898
- /** The agent's suggested name for the pairing — the human sees it pre-filled at
27899
- * approval and can override. Optional; blank → a default silly name server-side. */
27900
- suggestedName: external_exports.string().optional(),
27901
- /** Legacy alias for suggestedName (older MCPs sent `agent`). Accepted for
27902
- * back-compat; `suggestedName` wins when both are present. ponytail: drop once no
27903
- * pre-`name` MCP is in the wild. */
27904
- agent: external_exports.union([external_exports.string(), external_exports.object({ name: external_exports.string().optional() })]).optional(),
27905
- device: external_exports.string().optional(),
27906
- proto: external_exports.string().optional(),
27907
- // compiled-in tag, e.g. "paigy-pair-v2|sas=24"
27908
- commitment: external_exports.string().optional()
27909
- // agent's Ca
27910
- });
27911
27787
  DeviceCodeSchema = external_exports.object({
27912
27788
  device_code: external_exports.string(),
27913
27789
  user_code: external_exports.string(),
@@ -27941,11 +27817,6 @@ var init_dist = __esm({
27941
27817
  phone_reveal: PairingRevealSchema.nullable().optional(),
27942
27818
  uik_pub: external_exports.string().nullable().optional()
27943
27819
  });
27944
- DeviceTokenRequestSchema = external_exports.object({
27945
- device_code: external_exports.string(),
27946
- reveal: PairingRevealSchema.optional()
27947
- // agent's reveal {x25519, ed25519, nonce}
27948
- });
27949
27820
  DeviceTokenSchema = external_exports.object({
27950
27821
  access_token: external_exports.string(),
27951
27822
  /** The pairing's single name (user-typed at approval, the agent's suggestion, or
@@ -27967,14 +27838,6 @@ var init_dist = __esm({
27967
27838
  // present once the phone reveals
27968
27839
  uik_pub: external_exports.string().nullable().optional()
27969
27840
  });
27970
- DeviceCommitRequestSchema = external_exports.object({
27971
- code: external_exports.string(),
27972
- commitment: external_exports.string()
27973
- // Cb
27974
- });
27975
- DevicePeerCommitSchema = external_exports.object({
27976
- commitment: external_exports.string().nullable()
27977
- });
27978
27841
  SupportRequestSchema = external_exports.object({
27979
27842
  email: external_exports.string().email().max(320),
27980
27843
  message: external_exports.string().trim().min(1).max(5e3),
@@ -27994,15 +27857,6 @@ var init_dist = __esm({
27994
27857
  "other"
27995
27858
  // anything else — the note carries it.
27996
27859
  ]);
27997
- NotificationFeedbackSchema = external_exports.object({
27998
- notificationId: external_exports.string(),
27999
- kind: NotificationFeedbackKindSchema,
28000
- /** Optional free-text elaboration for a preset; required (non-empty) for 'other'. */
28001
- note: external_exports.string().trim().max(2e3).optional()
28002
- }).superRefine((r, ctx) => {
28003
- if (r.kind === "other" && !r.note)
28004
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["note"], message: "note is required for 'other' feedback" });
28005
- });
28006
27860
  FeedbackResolutionSchema = external_exports.enum(["broker_fixed", "sent_to_agent"]);
28007
27861
  FeedbackOutcomeSchema = external_exports.object({
28008
27862
  resolution: FeedbackResolutionSchema,
@@ -33273,13 +33127,26 @@ function parseArgs(argv) {
33273
33127
  return args;
33274
33128
  }
33275
33129
  var ENABLE_TOOLS_COMMAND = "npx -y -p @paigy/mcp@latest paigy-enable-tools";
33130
+ function onEnter(input, onLine) {
33131
+ if (!input.isTTY) return () => {
33132
+ };
33133
+ const listen = (chunk) => {
33134
+ if (/[\r\n]/.test(String(chunk))) onLine();
33135
+ };
33136
+ input.on("data", listen);
33137
+ input.resume();
33138
+ return () => {
33139
+ input.off("data", listen);
33140
+ input.pause();
33141
+ };
33142
+ }
33276
33143
 
33277
33144
  // src/cli.ts
33278
33145
  init_dist();
33279
33146
  var import_qrcode = __toESM(require_lib(), 1);
33280
33147
  import { hostname } from "os";
33281
33148
  import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
33282
- import { execSync } from "child_process";
33149
+ import { execFile as execFile2, execSync } from "child_process";
33283
33150
  import { homedir as homedir7 } from "os";
33284
33151
  import { join as join6 } from "path";
33285
33152
 
@@ -34974,9 +34841,9 @@ var UpdateGoalToolSchema2 = UpdateGoalSchema2.omit({ operationId: true }).extend
34974
34841
  var ClaimGoalSchema2 = external_exports.object({ goalId: external_exports.string().uuid().optional() }).strict();
34975
34842
  var GetGoalSchema2 = external_exports.object({ goalId: external_exports.string().uuid() }).strict();
34976
34843
  var GET_GOAL_DESCRIPTION2 = "Read the current authorized Goal brief: state, owner, blockers, open decisions, progress, and the next operation. Foreign or sibling-owned Goals are not disclosed.";
34977
- var UPDATE_GOAL_DESCRIPTION2 = "Update an owned Goal at an exact revision. State, ownership, dependencies, children, progress, and review acknowledgement are explicit; stale revisions are rejected. Returns the new revision and a prose summary.";
34844
+ var UPDATE_GOAL_DESCRIPTION2 = "Update an owned Goal at an exact revision. State, ownership, dependencies, children, progress, and review acknowledgement are explicit; stale revisions are rejected. reviewed: true acknowledges new evidence and closes the Deliveries addressed to you on that Goal, never over an open decision. Returns the new revision and a prose summary.";
34978
34845
  var CLAIM_GOAL_DESCRIPTION2 = "Claim the oldest runnable or review-pending Goal you own, or pass goalId to claim that Goal. Returns a Goal-scoped brief, current revision, blockers, and the next valid operation. Claiming creates or renews the execution lease.";
34979
- var CHECK_REPLIES_DESCRIPTION2 = "Your open Deliveries: every Notification or Call currently addressed to you \u2014 a request the user started toward you, an answer relayed to something you asked, a handoff \u2014 each with its durable Entries, accepted decisions and open decision needs, in the same shape a contact read returns. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread it with contact({deliveryId}). Your runnable and review-pending Goals come from claim_goal, not from here.";
34846
+ var CHECK_REPLIES_DESCRIPTION2 = "Your open Deliveries: every Notification or Call currently addressed to you \u2014 a request the user started toward you, an answer relayed to something you asked, a handoff \u2014 one row each: its Goals, the newest words in brief, accepted decisions and open decision needs, without the Entries. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread it in full with contact({deliveryId}). Once you have acted on what arrived, update_goal with reviewed: true closes the Deliveries addressed to you on that Goal. Your runnable and review-pending Goals come from claim_goal, not from here.";
34980
34847
  var CheckRepliesSchema2 = external_exports.object({}).strict();
34981
34848
  var GetThreadSchema2 = external_exports.object({
34982
34849
  parentId: external_exports.string().describe("The Thread to read \u2014 the threadId a Delivery returned, or the parentId of a search hit.")
@@ -35370,67 +35237,6 @@ var AwaitItemSchema2 = external_exports.discriminatedUnion("type", [
35370
35237
  inFlight: external_exports.boolean().optional()
35371
35238
  })
35372
35239
  ]);
35373
- var CallbackTriggerSchema2 = external_exports.enum(["on_done", "on_blocked", "scheduled"]);
35374
- var NotifyResponseSchema2 = external_exports.object({
35375
- notificationId: external_exports.string(),
35376
- workId: external_exports.string().uuid().optional(),
35377
- decisionId: external_exports.string().uuid().optional(),
35378
- status: NotifyStatusSchema2,
35379
- createdAt: external_exports.string().datetime(),
35380
- answer: UserAnswerSchema2.optional(),
35381
- answeredAt: external_exports.string().datetime().optional(),
35382
- /** Ride-alongs for THIS agent — pending work it should pick up when it's done with
35383
- * what it came for. Present on any reply, because an unwakeable agent's only
35384
- * reliable moment is one it initiated. Absent/empty = nothing owed. */
35385
- also: external_exports.array(RideAlongSchema2).optional()
35386
- });
35387
- var NotifyPlanUnitSchema2 = external_exports.object({
35388
- notificationId: external_exports.string(),
35389
- /** The unit's own heading, so the agent can tell which of its paragraphs this became. */
35390
- title: external_exports.string(),
35391
- /** How loudly this unit was arbitrated to arrive — per unit, which is the point of units. */
35392
- level: NotifyLevelSchema2,
35393
- /** Answered from something the user already decided: nobody is interrupted, and a trail card
35394
- * says so. The agent should not wait on this one. */
35395
- settled: external_exports.literal(true).optional(),
35396
- /** What this unit would need to be answerable and does not carry (#894). A PROPOSAL to the
35397
- * agent — nothing here changed the ask, and ignoring it costs nothing. */
35398
- needs: external_exports.array(external_exports.enum(["options", "visuals"])).optional(),
35399
- /** The SHAPE the broker would give this unit, for the agent to ratify (#886/#894). The
35400
- * split layer reads prose and can see that a paragraph is a yes/no or a pick-one — but a
35401
- * broker that DECIDES that destroys the only fact separating a statement from a real ask
35402
- * (#731), so it is offered, never applied: the unit is stored `text` until the agent
35403
- * confirms the shape (POST /notify/:id/confirm). Ignoring it costs nothing. */
35404
- proposal: external_exports.object({
35405
- select: SelectShapeSchema2,
35406
- options: external_exports.array(external_exports.object({ label: external_exports.string().min(1) })).optional()
35407
- }).optional(),
35408
- /** What the broker READ this unit as wanting from the human (#952 layer 2): a `decision`
35409
- * between alternatives, an `approval` the agent is blocked on, or `knowledge` it just
35410
- * needs to know. Reported so the agent can correct a misread the same way it ratifies a
35411
- * shape — the read RAISES (a decision always asks) and never silences a question the
35412
- * agent declared (#731, #923). */
35413
- wants: external_exports.enum(["decision", "approval", "knowledge"]).optional()
35414
- });
35415
- var NotifyPlanSchema2 = external_exports.object({
35416
- units: external_exports.array(NotifyPlanUnitSchema2),
35417
- /** Which unit is this arrival's ONE interruption (units-design.md D23). Absent means nobody
35418
- * was interrupted — every unit was either settled or quiet enough to sit in the inbox. */
35419
- speaks: external_exports.string().optional()
35420
- });
35421
- var UserResponseSchema2 = external_exports.object({
35422
- requestId: external_exports.string(),
35423
- answer: UserAnswerSchema2,
35424
- answeredAt: external_exports.string().datetime(),
35425
- transcript: external_exports.string().optional(),
35426
- /** E2EE: the sealed answer (opaque envelope + plaintext `ignored` hint) when the item was
35427
- * E2EE-sealed. Present → the server persists it opaquely and branches status on `ignored`;
35428
- * the plaintext `answer` is a placeholder (`{ kind: "ignored" }`) the server ignores for a
35429
- * sealed row. Absent = today's plaintext answer, unchanged. */
35430
- sealed: external_exports.lazy(() => SealedAnswerSchema2).optional(),
35431
- /** Coverage report (#396): which of the ask's declared `points` were addressed. */
35432
- covered: external_exports.array(external_exports.string()).optional()
35433
- });
35434
35240
  var VoiceKeySchema2 = external_exports.enum(["rachel", "george", "jessica", "brian", "lily"]);
35435
35241
  var AgendaTurnSchema2 = external_exports.object({
35436
35242
  /** THE TURN'S IDENTITY (the first-sentence stream, 2026-09-09): the brain call that wrote
@@ -35614,10 +35420,6 @@ var InboxItemSchema2 = external_exports.object({
35614
35420
  goalState: external_exports.string().optional()
35615
35421
  }).optional()
35616
35422
  });
35617
- var SnoozeRequestSchema2 = external_exports.object({
35618
- requestId: external_exports.string(),
35619
- until: external_exports.string().datetime()
35620
- });
35621
35423
  var APNS_TOKEN_RE2 = /^[0-9a-fA-F]{64}$/;
35622
35424
  var PushTokenSchema2 = external_exports.object({
35623
35425
  voipToken: external_exports.string().min(1).optional(),
@@ -35838,19 +35640,6 @@ var MoveSchema2 = external_exports.object({
35838
35640
  * distilled from a clarify ruling (those carry no agent) or one whose source rows are gone. */
35839
35641
  learnedFrom: external_exports.object({ id: external_exports.string(), name: external_exports.string() }).nullable()
35840
35642
  });
35841
- var CreateRequestSchema2 = external_exports.object({
35842
- /** The connection (token id) to send to, from GET /api/tokens. */
35843
- tokenId: external_exports.string(),
35844
- /** The user's message to the agent. */
35845
- text: external_exports.string().min(1),
35846
- /** Land the request on an existing conversation thread (History → "Continue")
35847
- * instead of minting a fresh one. Must belong to the requesting user. */
35848
- parentId: external_exports.string().optional(),
35849
- /** Point the agent at a past conversation (possibly with a different agent) as
35850
- * starting context (History → "New session from this"). A reference, not a copy —
35851
- * the agent reads it via get_thread. Must belong to the requesting user. */
35852
- contextParentId: external_exports.string().optional()
35853
- });
35854
35643
  var QueueQuestionSchema2 = external_exports.object({
35855
35644
  /** The decision need's id — what an answer is accepted against. */
35856
35645
  id: external_exports.string(),
@@ -35942,38 +35731,6 @@ var NoteSchema2 = external_exports.object({
35942
35731
  lastRideAt: external_exports.string().nullable().default(null),
35943
35732
  createdAt: external_exports.string()
35944
35733
  });
35945
- var CreateNoteSchema2 = external_exports.object({
35946
- /** The intent, in the user's own words. Stored verbatim; the broker only titles it. */
35947
- text: external_exports.string().min(1).max(4e3),
35948
- /** Capture it as a REMINDER — a note assigned to the user themselves, which rides
35949
- * their next call instead of being handed to an agent. Everything else about the
35950
- * note is identical; this is the one parameter that separates the two. */
35951
- forMe: external_exports.boolean().optional(),
35952
- /** The not-before, when the user already said one. Absent = the very next call. */
35953
- dueAt: external_exports.string().datetime().optional(),
35954
- repeat: NoteRepeatSchema2.optional()
35955
- });
35956
- var RecordDecisionSchema2 = external_exports.object({
35957
- /** An open decision (from /clarify) to answer. */
35958
- decisionId: external_exports.string().optional(),
35959
- /** For an ad-hoc decision: what was ambiguous. Required without `decisionId`. */
35960
- question: external_exports.string().min(1).max(500).optional(),
35961
- /** The ruling. */
35962
- answer: external_exports.string().min(1).max(2e3)
35963
- }).refine((d) => d.decisionId || d.question, { message: "decisionId or question required" });
35964
- var AssignNoteSchema2 = external_exports.object({
35965
- /** An EXISTING agent: token id or nickname. Omit when spawning fresh. */
35966
- target: external_exports.string().min(1).optional(),
35967
- /** Spawn a NEW session for this note (companion.md §2.2): the assignee doesn't
35968
- * exist yet — mint it on a live desktop that advertises the harness+workspace,
35969
- * named after the note. The brief arrives as its opening request. */
35970
- spawn: external_exports.object({
35971
- hostTokenId: external_exports.string().uuid(),
35972
- harness: external_exports.string().min(1),
35973
- workspace: external_exports.string().min(1)
35974
- }).optional()
35975
- }).refine((a) => !!a.target !== !!a.spawn, { message: "exactly one of target or spawn" });
35976
- var TriageVerdictSchema2 = external_exports.enum(["keep", "stale", "close", "assign"]);
35977
35734
  var TriageItemSchema2 = external_exports.object({
35978
35735
  noteId: external_exports.string(),
35979
35736
  /** The note's headline at run time. */
@@ -36107,20 +35864,6 @@ var PairingRevealSchema2 = external_exports.object({
36107
35864
  ed25519: external_exports.string(),
36108
35865
  nonce: external_exports.string()
36109
35866
  });
36110
- var DeviceCodeRequestSchema2 = external_exports.object({
36111
- /** The agent's suggested name for the pairing — the human sees it pre-filled at
36112
- * approval and can override. Optional; blank → a default silly name server-side. */
36113
- suggestedName: external_exports.string().optional(),
36114
- /** Legacy alias for suggestedName (older MCPs sent `agent`). Accepted for
36115
- * back-compat; `suggestedName` wins when both are present. ponytail: drop once no
36116
- * pre-`name` MCP is in the wild. */
36117
- agent: external_exports.union([external_exports.string(), external_exports.object({ name: external_exports.string().optional() })]).optional(),
36118
- device: external_exports.string().optional(),
36119
- proto: external_exports.string().optional(),
36120
- // compiled-in tag, e.g. "paigy-pair-v2|sas=24"
36121
- commitment: external_exports.string().optional()
36122
- // agent's Ca
36123
- });
36124
35867
  var DeviceCodeSchema2 = external_exports.object({
36125
35868
  device_code: external_exports.string(),
36126
35869
  user_code: external_exports.string(),
@@ -36154,11 +35897,6 @@ var DeviceInfoSchema2 = external_exports.object({
36154
35897
  phone_reveal: PairingRevealSchema2.nullable().optional(),
36155
35898
  uik_pub: external_exports.string().nullable().optional()
36156
35899
  });
36157
- var DeviceTokenRequestSchema2 = external_exports.object({
36158
- device_code: external_exports.string(),
36159
- reveal: PairingRevealSchema2.optional()
36160
- // agent's reveal {x25519, ed25519, nonce}
36161
- });
36162
35900
  var DeviceTokenSchema2 = external_exports.object({
36163
35901
  access_token: external_exports.string(),
36164
35902
  /** The pairing's single name (user-typed at approval, the agent's suggestion, or
@@ -36180,14 +35918,6 @@ var DeviceTokenSchema2 = external_exports.object({
36180
35918
  // present once the phone reveals
36181
35919
  uik_pub: external_exports.string().nullable().optional()
36182
35920
  });
36183
- var DeviceCommitRequestSchema2 = external_exports.object({
36184
- code: external_exports.string(),
36185
- commitment: external_exports.string()
36186
- // Cb
36187
- });
36188
- var DevicePeerCommitSchema2 = external_exports.object({
36189
- commitment: external_exports.string().nullable()
36190
- });
36191
35921
  var SupportRequestSchema2 = external_exports.object({
36192
35922
  email: external_exports.string().email().max(320),
36193
35923
  message: external_exports.string().trim().min(1).max(5e3),
@@ -36207,15 +35937,6 @@ var NotificationFeedbackKindSchema2 = external_exports.enum([
36207
35937
  "other"
36208
35938
  // anything else — the note carries it.
36209
35939
  ]);
36210
- var NotificationFeedbackSchema2 = external_exports.object({
36211
- notificationId: external_exports.string(),
36212
- kind: NotificationFeedbackKindSchema2,
36213
- /** Optional free-text elaboration for a preset; required (non-empty) for 'other'. */
36214
- note: external_exports.string().trim().max(2e3).optional()
36215
- }).superRefine((r, ctx) => {
36216
- if (r.kind === "other" && !r.note)
36217
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["note"], message: "note is required for 'other' feedback" });
36218
- });
36219
35940
  var FeedbackResolutionSchema2 = external_exports.enum(["broker_fixed", "sent_to_agent"]);
36220
35941
  var FeedbackOutcomeSchema2 = external_exports.object({
36221
35942
  resolution: FeedbackResolutionSchema2,
@@ -36938,11 +36659,35 @@ function bridgeLine(r) {
36938
36659
 
36939
36660
  // src/cli.ts
36940
36661
  var STATUS_MARK = { ready: "\u2713", login: "\u25D0", "adapter-missing": "\u25D0", missing: "\u2717" };
36941
- function printConnectLines(link, userCode) {
36662
+ function printConnectLines(link, userCode, enter) {
36942
36663
  console.log("Connect this computer from your phone");
36943
- console.log(` Open ${link}`);
36664
+ console.log(` Open ${link}${enter ? " (press Enter to open it here)" : ""}`);
36944
36665
  console.log(` or scan the QR above \xB7 or type ${userCode} in Paigy \u2192 Devices \u2192 Connect a computer`);
36945
36666
  }
36667
+ async function pairThisMachine() {
36668
+ const host = hostname().replace(/\.local$/, "");
36669
+ const code = await requestCode(host, void 0, host);
36670
+ const link = code.verification_uri_complete;
36671
+ console.log(await import_qrcode.default.toString(link, { type: "terminal", small: true }));
36672
+ printConnectLines(link, code.user_code, !!process.stdin.isTTY);
36673
+ const opener = process.platform === "darwin" ? "open" : "xdg-open";
36674
+ const stop2 = onEnter(process.stdin, () => execFile2(opener, [link], () => {
36675
+ }));
36676
+ try {
36677
+ const deadline = Date.now() + code.expires_in * 1e3;
36678
+ while (Date.now() < deadline) {
36679
+ const token = await pollToken(code.device_code).catch(() => null);
36680
+ if (token) {
36681
+ saveToken(token, "Desktop");
36682
+ return token.name;
36683
+ }
36684
+ await sleep(code.interval * 1e3);
36685
+ }
36686
+ return null;
36687
+ } finally {
36688
+ stop2();
36689
+ }
36690
+ }
36946
36691
  function forwardCodexThreadId() {
36947
36692
  const cfg = join6(process.env.CODEX_HOME || join6(homedir7(), ".codex"), "config.toml");
36948
36693
  if (!existsSync5(cfg)) return;
@@ -37030,23 +36775,12 @@ async function main() {
37030
36775
  const live = held ? await credentialWorks(held) : false;
37031
36776
  if (held && !live) console.log("\u26A0 this machine was logged out \u2014 reconnecting it now");
37032
36777
  if (!live) {
37033
- const code = await requestCode(hostname().replace(/\.local$/, ""), void 0, hostname().replace(/\.local$/, ""));
37034
- console.log(await import_qrcode.default.toString(code.verification_uri_complete, { type: "terminal", small: true }));
37035
- printConnectLines(code.verification_uri_complete, code.user_code);
37036
- const deadline = Date.now() + code.expires_in * 1e3;
37037
- let paired = false;
37038
- while (!paired && Date.now() < deadline) {
37039
- const token = await pollToken(code.device_code).catch(() => null);
37040
- if (token) {
37041
- saveToken(token, "Desktop");
37042
- console.log(`\u2713 paired as "${token.name}"`);
37043
- paired = true;
37044
- } else await sleep(code.interval * 1e3);
37045
- }
37046
- if (!paired) {
36778
+ const name = await pairThisMachine();
36779
+ if (name === null) {
37047
36780
  console.error("Pairing code expired \u2014 run `paigy-harness setup` again.");
37048
36781
  process.exit(1);
37049
36782
  }
36783
+ console.log(`\u2713 paired as "${name}"`);
37050
36784
  } else console.log("\u2713 already paired as this machine");
37051
36785
  for (const a of detected) {
37052
36786
  if (a.status === "adapter-missing" && a.install) continue;
@@ -37127,22 +36861,14 @@ async function main() {
37127
36861
  return;
37128
36862
  }
37129
36863
  if (existing) console.log("\u26A0 this machine was logged out \u2014 reconnecting it now");
37130
- const code = await requestCode(hostname().replace(/\.local$/, ""), void 0, hostname().replace(/\.local$/, ""));
37131
- console.log(await import_qrcode.default.toString(code.verification_uri_complete, { type: "terminal", small: true }));
37132
- printConnectLines(code.verification_uri_complete, code.user_code);
37133
- const deadline = Date.now() + code.expires_in * 1e3;
37134
- while (Date.now() < deadline) {
37135
- const token = await pollToken(code.device_code).catch(() => null);
37136
- if (token) {
37137
- saveToken(token, "Desktop");
37138
- console.log(`\u2713 paired as "${token.name}" \u2014 this machine is now launchable from your phone`);
37139
- console.log(" next: paigy-harness host --grant ~/your/projects (or: paigy-harness service)");
37140
- return;
37141
- }
37142
- await sleep(code.interval * 1e3);
36864
+ const name = await pairThisMachine();
36865
+ if (name === null) {
36866
+ console.error("Pairing code expired \u2014 run `paigy-harness pair` again.");
36867
+ process.exit(1);
37143
36868
  }
37144
- console.error("Pairing code expired \u2014 run `paigy-harness pair` again.");
37145
- process.exit(1);
36869
+ console.log(`\u2713 paired as "${name}" \u2014 this machine is now launchable from your phone`);
36870
+ console.log(" next: paigy-harness host --grant ~/your/projects (or: paigy-harness service)");
36871
+ return;
37146
36872
  }
37147
36873
  if (parsed.service) {
37148
36874
  if (process.platform !== "darwin") {
@@ -37314,10 +37040,11 @@ async function main() {
37314
37040
  void main();
37315
37041
  async function credentialWorks(token) {
37316
37042
  try {
37317
- const res = await fetch(`${process.env.PAIGY_API_URL ?? "https://paigy.ai"}/api/identity`, {
37043
+ const res = await fetch(`${process.env.PAIGY_API_URL ?? "https://paigy.ai"}/api/presence`, {
37044
+ method: "POST",
37318
37045
  headers: { authorization: `Bearer ${token}` }
37319
37046
  });
37320
- return res.ok;
37047
+ return res.status !== 401 && res.status !== 403;
37321
37048
  } catch {
37322
37049
  return true;
37323
37050
  }