@porte/cli 0.1.2 → 0.1.3

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.
@@ -5058,7 +5058,13 @@ const ConversationFailurePayloadSchema = discriminatedUnion("_tag", [
5058
5058
  message: string().min(1)
5059
5059
  })
5060
5060
  ]);
5061
- uuidv7().brand();
5061
+ //#endregion
5062
+ //#region ../../packages/core/src/identity/identity.ts
5063
+ /**
5064
+ * These schemas define identifiers that cross Porte process boundaries.
5065
+ * Each brand prevents accidental use of a different identifier.
5066
+ */
5067
+ const HostIdSchema = uuidv7().brand();
5062
5068
  uuidv7().brand();
5063
5069
  uuidv7().brand();
5064
5070
  uuidv7().brand();
@@ -5796,7 +5802,11 @@ const HostPlatformSchema = _enum([
5796
5802
  const PairedHostSchema = object({
5797
5803
  name: string().min(1),
5798
5804
  platform: HostPlatformSchema
5799
- }).extend({ lastSeenAt: IsoDateTimeSchema.nullable() });
5805
+ }).extend({
5806
+ /** Names the pairing's relay object; a re-pair after unpair gets a new one. */
5807
+ id: HostIdSchema,
5808
+ lastSeenAt: IsoDateTimeSchema.nullable()
5809
+ });
5800
5810
  discriminatedUnion("state", [
5801
5811
  object({ state: literal("unpaired") }),
5802
5812
  object({
@@ -6155,6 +6165,8 @@ const PORTE_CLI_CLIENT_ID = "porte-cli";
6155
6165
  * serves it cannot drift; the route asserts it against the generated tree.
6156
6166
  */
6157
6167
  const PAIRING_CODE_PATH = "/api/pair/code";
6168
+ /** Where the daemon ends its own pairing: DELETE with its bearer token. */
6169
+ const HOST_PAIRING_PATH = "/api/host/pairing";
6158
6170
  /** RFC 8628 fixes this value; the token request is invalid without it. */
6159
6171
  const DEVICE_CODE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
6160
6172
  /**
@@ -6705,4 +6717,4 @@ async function sendJsonRpcFrame(write) {
6705
6717
  if (sent.isErr()) throw sent.error;
6706
6718
  }
6707
6719
  //#endregion
6708
- export { INTERNAL_SERVER_ERROR as $, ProblemDetailsSchema as A, PermissionNotFoundError as B, DeviceTokenErrorSchema as C, PORTE_CLI_CLIENT_ID as D, PAIRING_CODE_PATH as E, AgentUnresponsiveError as F, makeConversationSummary as G, ConversationEventSchema as H, ConfigurationNotFoundError as I, IsoDateTimeSchema as J, ConversationIdSchema as K, ConversationBusyError as L, isClassifiedError as M, isDomainError as N, createLogger as O, WorkspaceNotAllowedError as P, turnIdFor as Q, ConversationNotFoundError as R, DeviceCodeResponseSchema as S, DeviceTokenResponseSchema as T, ToolViewSchema as U, TurnNotFoundError as V, ConversationCursorSchema as W, PermissionIdSchema as X, MessageIdSchema as Y, ToolCallIdSchema as Z, readJsonRpcIncoming as _, url as _t, HOST_APPLICATION_ERROR_CODE as a, _enum as at, DEVICE_CODE_GRANT_TYPE as b, HOST_CONVERSATION_SUBPROTOCOL as c, email as ct, JSON_RPC_ERROR_CODES as d, literal as dt, InternalServerError as et, JsonRpcReadError as f, number as ft, jsonRpcNotification as g, unknown as gt, jsonRpcError as h, string as ht, HostControlMethods as i, h as it, HostPlatformSchema as j, setLogSink as k, HostRequestIdSchema as l, httpUrl as lt, handleJsonRpcRequest as m, record as mt, sendJsonRpcFrame as n, CODING_AGENT_UNAVAILABLE_ERROR as nt, HOST_APPLICATION_ERROR_MESSAGE as o, array as ot, JsonRpcTextSchema as p, object as pt, ElicitationIdSchema as q, HostConversationMethods as r, CodingAgentUnavailableError as rt, HOST_CONTROL_SUBPROTOCOL as s, discriminatedUnion as st, JsonRpcSendError as t, ServiceUnavailableError as tt, SequenceNumberSchema as u, json as ut, readJsonRpcTextFrame as v, DeviceTokenRequestSchema as w, DeviceCodeRequestSchema as x, formatPairingCode as y, ElicitationNotFoundError as z };
6720
+ export { turnIdFor as $, setLogSink as A, ElicitationNotFoundError as B, DeviceTokenErrorSchema as C, PAIRING_CODE_PATH as D, HOST_PAIRING_PATH as E, WorkspaceNotAllowedError as F, ConversationCursorSchema as G, TurnNotFoundError as H, AgentUnresponsiveError as I, ElicitationIdSchema as J, makeConversationSummary as K, ConfigurationNotFoundError as L, HostPlatformSchema as M, isClassifiedError as N, PORTE_CLI_CLIENT_ID as O, isDomainError as P, ToolCallIdSchema as Q, ConversationBusyError as R, DeviceCodeResponseSchema as S, DeviceTokenResponseSchema as T, ConversationEventSchema as U, PermissionNotFoundError as V, ToolViewSchema as W, MessageIdSchema as X, IsoDateTimeSchema as Y, PermissionIdSchema as Z, readJsonRpcIncoming as _, unknown as _t, HOST_APPLICATION_ERROR_CODE as a, h as at, DEVICE_CODE_GRANT_TYPE as b, HOST_CONVERSATION_SUBPROTOCOL as c, discriminatedUnion as ct, JSON_RPC_ERROR_CODES as d, json as dt, INTERNAL_SERVER_ERROR as et, JsonRpcReadError as f, literal as ft, jsonRpcNotification as g, string as gt, jsonRpcError as h, record as ht, HostControlMethods as i, CodingAgentUnavailableError as it, ProblemDetailsSchema as j, createLogger as k, HostRequestIdSchema as l, email as lt, handleJsonRpcRequest as m, object as mt, sendJsonRpcFrame as n, ServiceUnavailableError as nt, HOST_APPLICATION_ERROR_MESSAGE as o, _enum as ot, JsonRpcTextSchema as p, number as pt, ConversationIdSchema as q, HostConversationMethods as r, CODING_AGENT_UNAVAILABLE_ERROR as rt, HOST_CONTROL_SUBPROTOCOL as s, array as st, JsonRpcSendError as t, InternalServerError as tt, SequenceNumberSchema as u, httpUrl as ut, readJsonRpcTextFrame as v, url as vt, DeviceTokenRequestSchema as w, DeviceCodeRequestSchema as x, formatPairingCode as y, ConversationNotFoundError as z };
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { k as setLogSink } from "./client-Cvulvd-1.js";
2
+ import { A as setLogSink } from "./client-BwrMf7hy.js";
3
3
  //#region src/main.ts
4
4
  const major = Number(process.versions.node.split(".")[0]);
5
5
  if (Number.isNaN(major) || major < 22) {
@@ -11,7 +11,7 @@ setLogSink((_level, line) => {
11
11
  });
12
12
  const verbose = process.argv.includes("--verbose") || process.argv.includes("-v");
13
13
  process.env.LOG_LEVEL ??= verbose ? "DEBUG" : "WARN";
14
- const { run } = await import("./run-cli-CoetNCwK.js");
14
+ const { run } = await import("./run-cli-CEPB1b8j.js");
15
15
  const code = await run(process.argv.slice(2), {
16
16
  stdout: process.stdout,
17
17
  stderr: process.stderr,
@@ -1,4 +1,4 @@
1
- import { $ as INTERNAL_SERVER_ERROR, A as ProblemDetailsSchema, B as PermissionNotFoundError, C as DeviceTokenErrorSchema, D as PORTE_CLI_CLIENT_ID, E as PAIRING_CODE_PATH, F as AgentUnresponsiveError, G as makeConversationSummary, H as ConversationEventSchema, I as ConfigurationNotFoundError, J as IsoDateTimeSchema, K as ConversationIdSchema, L as ConversationBusyError, M as isClassifiedError, N as isDomainError, O as createLogger, P as WorkspaceNotAllowedError, Q as turnIdFor, R as ConversationNotFoundError, S as DeviceCodeResponseSchema, T as DeviceTokenResponseSchema, U as ToolViewSchema, V as TurnNotFoundError, W as ConversationCursorSchema, X as PermissionIdSchema, Y as MessageIdSchema, Z as ToolCallIdSchema, _ as readJsonRpcIncoming, _t as url, a as HOST_APPLICATION_ERROR_CODE, at as _enum, b as DEVICE_CODE_GRANT_TYPE, c as HOST_CONVERSATION_SUBPROTOCOL, ct as email, d as JSON_RPC_ERROR_CODES, dt as literal, et as InternalServerError, f as JsonRpcReadError, ft as number, g as jsonRpcNotification, gt as unknown, h as jsonRpcError, ht as string, i as HostControlMethods, it as h, j as HostPlatformSchema, l as HostRequestIdSchema, lt as httpUrl, m as handleJsonRpcRequest, mt as record, n as sendJsonRpcFrame, nt as CODING_AGENT_UNAVAILABLE_ERROR, o as HOST_APPLICATION_ERROR_MESSAGE, ot as array, p as JsonRpcTextSchema, pt as object, q as ElicitationIdSchema, r as HostConversationMethods, rt as CodingAgentUnavailableError, s as HOST_CONTROL_SUBPROTOCOL, st as discriminatedUnion, t as JsonRpcSendError, tt as ServiceUnavailableError, u as SequenceNumberSchema, ut as json, v as readJsonRpcTextFrame, w as DeviceTokenRequestSchema, x as DeviceCodeRequestSchema, y as formatPairingCode, z as ElicitationNotFoundError } from "./client-Cvulvd-1.js";
1
+ import { $ as turnIdFor, B as ElicitationNotFoundError, C as DeviceTokenErrorSchema, D as PAIRING_CODE_PATH, E as HOST_PAIRING_PATH, F as WorkspaceNotAllowedError, G as ConversationCursorSchema, H as TurnNotFoundError, I as AgentUnresponsiveError, J as ElicitationIdSchema, K as makeConversationSummary, L as ConfigurationNotFoundError, M as HostPlatformSchema, N as isClassifiedError, O as PORTE_CLI_CLIENT_ID, P as isDomainError, Q as ToolCallIdSchema, R as ConversationBusyError, S as DeviceCodeResponseSchema, T as DeviceTokenResponseSchema, U as ConversationEventSchema, V as PermissionNotFoundError, W as ToolViewSchema, X as MessageIdSchema, Y as IsoDateTimeSchema, Z as PermissionIdSchema, _ as readJsonRpcIncoming, _t as unknown, a as HOST_APPLICATION_ERROR_CODE, at as h, b as DEVICE_CODE_GRANT_TYPE, c as HOST_CONVERSATION_SUBPROTOCOL, ct as discriminatedUnion, d as JSON_RPC_ERROR_CODES, dt as json, et as INTERNAL_SERVER_ERROR, f as JsonRpcReadError, ft as literal, g as jsonRpcNotification, gt as string, h as jsonRpcError, ht as record, i as HostControlMethods, it as CodingAgentUnavailableError, j as ProblemDetailsSchema, k as createLogger, l as HostRequestIdSchema, lt as email, m as handleJsonRpcRequest, mt as object, n as sendJsonRpcFrame, nt as ServiceUnavailableError, o as HOST_APPLICATION_ERROR_MESSAGE, ot as _enum, p as JsonRpcTextSchema, pt as number, q as ConversationIdSchema, r as HostConversationMethods, rt as CODING_AGENT_UNAVAILABLE_ERROR, s as HOST_CONTROL_SUBPROTOCOL, st as array, t as JsonRpcSendError, tt as InternalServerError, u as SequenceNumberSchema, ut as httpUrl, v as readJsonRpcTextFrame, vt as url, w as DeviceTokenRequestSchema, x as DeviceCodeRequestSchema, y as formatPairingCode, z as ConversationNotFoundError } from "./client-BwrMf7hy.js";
2
2
  import { homedir, hostname } from "node:os";
3
3
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
4
4
  import { execFileSync, spawn } from "node:child_process";
@@ -168,7 +168,7 @@ var WebSocketHandlerError = class extends h("WebSocketHandlerError") {
168
168
  //#endregion
169
169
  //#region src/entrypoints/cli/version.ts
170
170
  /** Package version. Source is `package.json`. */
171
- const VERSION = "0.1.2";
171
+ const VERSION = "0.1.3";
172
172
  //#endregion
173
173
  //#region src/entrypoints/cli/cli-error.ts
174
174
  /** Bad arguments or missing required flags. */
@@ -538,13 +538,30 @@ var DeviceAuthorizationClient = class {
538
538
  return fromRefusal(refusal.data.error);
539
539
  }
540
540
  /**
541
- * End the pairing.
541
+ * End the pairing on the server, before the credential is dropped locally.
542
542
  *
543
- * Stubbed: the route it needs does not exist yet, so unpairing currently only
544
- * clears the local credential. Wiring the request is a change to this method.
543
+ * A refused token means the browser already ended it, which is the state
544
+ * asked for. Anything else stays an error, so the caller keeps the credential
545
+ * and can try again: a pairing the server still holds is what nothing else can clean up.
545
546
  */
546
- revoke(_token) {
547
- return Promise.resolve();
547
+ async revoke(token) {
548
+ let response;
549
+ try {
550
+ response = await fetch(new URL(HOST_PAIRING_PATH, this.baseUrl), {
551
+ method: "DELETE",
552
+ headers: { Authorization: `Bearer ${token}` }
553
+ });
554
+ } catch (cause) {
555
+ throw new PairingError({
556
+ reason: "unreachable",
557
+ cause
558
+ });
559
+ }
560
+ if (response.ok || response.status === 401 || response.status === 403) return;
561
+ throw new PairingError({
562
+ reason: "unexpected",
563
+ cause: response.status
564
+ });
548
565
  }
549
566
  /**
550
567
  * Ask who the new token belongs to.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://www.schemastore.org/package.json",
3
3
  "name": "@porte/cli",
4
- "version": "0.1.2",
4
+ "version": "0.1.3",
5
5
  "description": "Run your local Grok sessions from your phone. The daemon that pairs a machine with useporte.dev.",
6
6
  "keywords": [
7
7
  "acp",
@@ -51,6 +51,9 @@
51
51
  },
52
52
  "scripts": {
53
53
  "dev": "tsx src/main.ts",
54
+ "dev:pair": "PORTE_URL=https://tunnel.useporte.dev PORTE_DATA_DIRECTORY=$HOME/.porte-dev tsx src/main.ts pair",
55
+ "dev:up": "PORTE_URL=https://tunnel.useporte.dev PORTE_DATA_DIRECTORY=$HOME/.porte-dev tsx src/main.ts up",
56
+ "dev:unpair": "PORTE_URL=https://tunnel.useporte.dev PORTE_DATA_DIRECTORY=$HOME/.porte-dev tsx src/main.ts unpair",
54
57
  "build": "tsdown",
55
58
  "typecheck": "tsc --noEmit",
56
59
  "lint": "oxlint .",