pinomad 0.13.0 → 0.14.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.
Files changed (41) hide show
  1. package/dist/{chunk-kmzzjv53.js → chunk-1mjbt2z2.js} +143 -10
  2. package/dist/{chunk-90g1cg9n.js → chunk-3hfaejdx.js} +1 -1
  3. package/dist/{chunk-d9mq5d46.js → chunk-5ayqca95.js} +10 -8
  4. package/dist/{chunk-7mn38n4f.js → chunk-63ymn5c9.js} +2 -2
  5. package/dist/{chunk-563fnad9.js → chunk-6j6hkfbj.js} +8 -4
  6. package/dist/{chunk-pqe7q1s7.js → chunk-6vbp1vva.js} +2 -1
  7. package/dist/chunk-8g2e77gf.js +46 -0
  8. package/dist/{chunk-6th9xv39.js → chunk-97ssw1c0.js} +9 -7
  9. package/dist/{chunk-g3ahp7b9.js → chunk-9trbbz4r.js} +1 -1
  10. package/dist/{chunk-4fferbxw.js → chunk-e59k3bmz.js} +213 -30
  11. package/dist/{chunk-s0h7c7da.js → chunk-ega1wnkg.js} +1 -1
  12. package/dist/{chunk-maqv34cs.js → chunk-evbv1fkn.js} +3 -3
  13. package/dist/{chunk-d4tq62yr.js → chunk-f6741a5q.js} +12 -11
  14. package/dist/{chunk-m51mq8vh.js → chunk-fdhbzwxj.js} +12 -10
  15. package/dist/{chunk-aapsc9g0.js → chunk-hfwa1vt5.js} +1952 -295
  16. package/dist/{chunk-t91zt5f0.js → chunk-hg9gs396.js} +1 -1
  17. package/dist/chunk-mdjk0s0t.js +23 -0
  18. package/dist/{chunk-wd7aracm.js → chunk-mxwcnnkg.js} +1 -303
  19. package/dist/chunk-pte4peaf.js +315 -0
  20. package/dist/{chunk-53xv3fny.js → chunk-s66evzar.js} +2446 -416
  21. package/dist/chunk-vedqqhbd.js +240 -0
  22. package/dist/{chunk-ra86wjp5.js → chunk-w9zpff3n.js} +11 -6
  23. package/dist/pinomad.js +12 -12
  24. package/package.json +5 -1
  25. package/web/assets/{core-BHm2gdHL.js → core-BWHGsFpV.js} +1 -1
  26. package/web/assets/{highlighted-diff-DrHvSLK9.js → highlighted-diff-DJ7KZCpS.js} +2 -2
  27. package/web/assets/{highlights-1aLwssz-.js → highlights-CyEmo6OI.js} +1 -1
  28. package/web/assets/{highlights-themes-C1p4pFYS.js → highlights-themes-CSNkBojy.js} +1 -1
  29. package/web/assets/index-C_qkbyL7.css +1 -0
  30. package/web/assets/index-DefQtCI2.js +396 -0
  31. package/web/assets/{shiki-BwyCm3kZ.js → shiki-BzCmRG-v.js} +2 -2
  32. package/web/assets/{shiki-langs-CMlALLSg.js → shiki-langs-DOkjyV4d.js} +1 -1
  33. package/web/assets/{stream-tokenizer-BlgIhw0y.js → stream-tokenizer-CBPqFe4Z.js} +1 -1
  34. package/web/assets/{theming-themes-DDvoqEqT.js → theming-themes-wKVca0aB.js} +1 -1
  35. package/web/assets/{xterm-view-BnKOnF3C.js → xterm-view-CKa1-QCM.js} +12 -12
  36. package/web/index.html +3 -2
  37. package/web/theme-boot.js +11 -0
  38. package/dist/chunk-sd640dt7.js +0 -22
  39. package/dist/chunk-t6fw0wa9.js +0 -96
  40. package/web/assets/index-A_AUJoO6.css +0 -1
  41. package/web/assets/index-BafYMKiN.js +0 -396
@@ -2,7 +2,7 @@ import {
2
2
  HOST_SETTING_KEYS,
3
3
  isQueueMode,
4
4
  isThinkingLevel
5
- } from "./chunk-pqe7q1s7.js";
5
+ } from "./chunk-6vbp1vva.js";
6
6
 
7
7
  // packages/protocol/src/rtc.ts
8
8
  function rtcAddressScope(address) {
@@ -173,12 +173,17 @@ function parseRtcMaxMessageSize(sdp) {
173
173
  return { kind: "bounded", bytes };
174
174
  }
175
175
 
176
+ // packages/protocol/src/upgrade.ts
177
+ var AUTO_UPGRADE_MODES = ["off", "notify", "auto"];
178
+ var isAutoUpgradeMode = (value) => AUTO_UPGRADE_MODES.includes(value);
179
+ var HOST_UPGRADING_ERROR = "Host is upgrading";
180
+
176
181
  // packages/protocol/src/auth.ts
177
182
  var CUSTOM_PROVIDER_APIS = ["openai-completions", "openai-responses", "anthropic-messages", "google-generative-ai"];
178
183
  var isCustomProviderApi = (value) => CUSTOM_PROVIDER_APIS.includes(value);
179
184
 
180
185
  // packages/protocol/src/frames.ts
181
- var HOST_STREAMS = { conversations: 0, index: 0, devices: 0, mcp: 0, models: 1, auth: 1, settings: 2, agents: 6, providers: 21 };
186
+ var HOST_STREAMS = { conversations: 0, index: 0, devices: 0, mcp: 0, models: 1, auth: 1, settings: 2, agents: 6, providers: 21, upgrade: 30 };
182
187
  var HOST_STREAM_NAMES = Object.keys(HOST_STREAMS);
183
188
  function hostStreams(hostMinor) {
184
189
  return HOST_STREAM_NAMES.filter((name) => HOST_STREAMS[name] <= hostMinor);
@@ -187,7 +192,7 @@ var conversationStream = (id) => `conversation:${id}`;
187
192
  var docStream = (kind, id) => `doc:${kind}:${id}`;
188
193
  var UNAUTHORIZED_CLOSE_CODE = 4401;
189
194
  var INVALID_FRAME_CLOSE_CODE = 4400;
190
- var PROTOCOL = { major: 5, minor: 29 };
195
+ var PROTOCOL = { major: 5, minor: 33 };
191
196
  var CALL_SINCE = {
192
197
  addProject: 0,
193
198
  removeProject: 0,
@@ -237,7 +242,11 @@ var CALL_SINCE = {
237
242
  resizeTerminal: 27,
238
243
  renameTerminal: 27,
239
244
  restartTerminal: 27,
240
- closeTerminal: 27
245
+ closeTerminal: 27,
246
+ stopProcess: 32,
247
+ startUpgrade: 30,
248
+ cancelUpgrade: 30,
249
+ checkUpgrade: 30
241
250
  };
242
251
  function hostSupportsCall(hostMinor, method) {
243
252
  return hostMinor >= CALL_SINCE[method];
@@ -256,7 +265,10 @@ var FEATURE_SINCE = {
256
265
  rtc: 23,
257
266
  submitEntry: 25,
258
267
  terminals: 27,
259
- transcriptPaging: 28
268
+ transcriptPaging: 28,
269
+ autoUpgrade: 30,
270
+ processes: 32,
271
+ subagentStop: 33
260
272
  };
261
273
  function hostSupportsFeature(hostMinor, feature) {
262
274
  return hostMinor >= FEATURE_SINCE[feature];
@@ -271,7 +283,7 @@ function parseClientFrame(value) {
271
283
  if (isStreamName(stream)) {
272
284
  if (value.type === "unsubscribe")
273
285
  return { kind: "frame", frame: { type: "unsubscribe", stream } };
274
- if (stream.startsWith("terminal:") && value.since !== undefined) {
286
+ if ((stream.startsWith("terminal:") || stream.startsWith("process:")) && value.since !== undefined) {
275
287
  const since = value.since;
276
288
  if (typeof since !== "number" || !Number.isSafeInteger(since) || since < 0)
277
289
  return { kind: "malformed" };
@@ -306,9 +318,9 @@ function parseClientFrame(value) {
306
318
  return { kind: "unsupportedCall", id, method };
307
319
  return validCallArgs(method, args) ? { kind: "frame", frame: { type: "call", id, method, args } } : { kind: "malformed" };
308
320
  }
309
- var STREAM_KINDS = new Set(["conversation", "doc", "tasks", "terminals", "terminal", ...HOST_STREAM_NAMES]);
321
+ var STREAM_KINDS = new Set(["conversation", "doc", "tasks", "terminals", "terminal", "process", ...HOST_STREAM_NAMES]);
310
322
  function isStreamName(stream) {
311
- return stream === "tasks" || HOST_STREAM_NAMES.includes(stream) || /^(?:conversation:|doc:.+:|terminals:)[1-9]\d*$/.test(stream) || /^terminal:[\w-]+$/.test(stream);
323
+ return stream === "tasks" || HOST_STREAM_NAMES.includes(stream) || /^(?:conversation:|doc:.+:|terminals:)[1-9]\d*$/.test(stream) || /^terminal:[\w-]+$/.test(stream) || /^process:[\w-]+$/.test(stream);
312
324
  }
313
325
  var isCallMethod = (method) => CALL_METHODS.includes(method);
314
326
  var CALL_METHODS = Object.keys(CALL_SINCE);
@@ -319,7 +331,8 @@ var SETTING_VALIDATORS = {
319
331
  followUpMode: (value) => value === null || isQueueMode(value),
320
332
  acceptAccountDevices: (value) => value === null || typeof value === "boolean",
321
333
  rtcStun: (value) => value === null || Array.isArray(value) && value.every(nonempty),
322
- hostName: (value) => value === null || typeof value === "string"
334
+ hostName: (value) => value === null || typeof value === "string",
335
+ autoUpgrade: (value) => value === null || isAutoUpgradeMode(value)
323
336
  };
324
337
  function validCallArgs(method, args) {
325
338
  const conversationId = () => typeof args.conversationId === "number" && Number.isSafeInteger(args.conversationId) && args.conversationId >= 1;
@@ -342,6 +355,8 @@ function validCallArgs(method, args) {
342
355
  return terminalId() && (args.name === null || typeof args.name === "string");
343
356
  case "closeTerminal":
344
357
  return terminalId();
358
+ case "stopProcess":
359
+ return conversationId() && nonempty(args.id);
345
360
  case "submit":
346
361
  return conversationId() && typeof args.text === "string" && (args.whenBusy === "steer" || args.whenBusy === "followUp") && nonempty(args.requestId) && images() && skills() && attachments();
347
362
  case "submission":
@@ -395,7 +410,11 @@ function validCallArgs(method, args) {
395
410
  case "renameConversation":
396
411
  return conversationId() && typeof args.title === "string";
397
412
  case "createPairing":
413
+ case "cancelUpgrade":
414
+ case "checkUpgrade":
398
415
  return Object.keys(args).length === 0;
416
+ case "startUpgrade":
417
+ return args.when === "idle" || args.when === "now";
399
418
  case "rtcOffer":
400
419
  return nonempty(args.attempt) && nonempty(args.sdp);
401
420
  case "ping":
@@ -668,6 +687,120 @@ function homeOf(index, summaries, id) {
668
687
  return;
669
688
  }
670
689
 
690
+ // packages/protocol/src/presentation.ts
691
+ import { Type } from "typebox";
692
+ import { Value } from "typebox/value";
693
+ var TodoItemSchema = Type.Object({
694
+ text: Type.String({ minLength: 1 }),
695
+ status: Type.Union([Type.Literal("pending"), Type.Literal("in_progress"), Type.Literal("completed")])
696
+ });
697
+ var TodoSchema = Type.Object({ items: Type.Array(TodoItemSchema) });
698
+ var QuestionOptionSchema = Type.Object({
699
+ label: Type.String({ minLength: 1 }),
700
+ description: Type.Optional(Type.String())
701
+ });
702
+ var QuestionItemSchema = Type.Object({
703
+ question: Type.String({ minLength: 1 }),
704
+ header: Type.String({ minLength: 1, maxLength: 16 }),
705
+ options: Type.Array(QuestionOptionSchema, { minItems: 2, maxItems: 4 }),
706
+ multiSelect: Type.Optional(Type.Boolean())
707
+ });
708
+ var QuestionAnswerSchema = Type.Object({
709
+ selected: Type.Array(Type.String()),
710
+ other: Type.Optional(Type.String())
711
+ });
712
+ var QuestionResolutionSchema = Type.Union([
713
+ Type.Object({ outcome: Type.Literal("answered"), answers: Type.Array(QuestionAnswerSchema), at: Type.Number() }),
714
+ Type.Object({ outcome: Type.Literal("dismissed"), at: Type.Number() }),
715
+ Type.Object({ outcome: Type.Literal("cancelled"), at: Type.Number() })
716
+ ]);
717
+ var QuestionRequestSchema = Type.Object({
718
+ id: Type.String({ minLength: 1 }),
719
+ questions: Type.Array(QuestionItemSchema, { minItems: 1, maxItems: 4 }),
720
+ askedAt: Type.Number(),
721
+ resolution: Type.Optional(QuestionResolutionSchema)
722
+ });
723
+ var QuestionSchema = Type.Object({ requests: Type.Array(QuestionRequestSchema) });
724
+ var DiffSchema = Type.Object({ patch: Type.String() });
725
+ var CodemodeCallSchema = Type.Object({
726
+ id: Type.Optional(Type.Number()),
727
+ name: Type.String(),
728
+ args: Type.String(),
729
+ status: Type.Union([Type.Literal("running"), Type.Literal("ok"), Type.Literal("error"), Type.Literal("cancelled")]),
730
+ durationMs: Type.Optional(Type.Number()),
731
+ error: Type.Optional(Type.String()),
732
+ details: Type.Optional(Type.Unknown())
733
+ });
734
+ var CodemodeSchema = Type.Object({ code: Type.Optional(Type.String()), calls: Type.Array(CodemodeCallSchema) });
735
+ var TokenCount = Type.Integer({ minimum: 0 });
736
+ var ContextBreakdownSchema = Type.Object({
737
+ used: TokenCount,
738
+ system: TokenCount,
739
+ skills: TokenCount,
740
+ tools: TokenCount,
741
+ mcp: TokenCount,
742
+ messages: TokenCount
743
+ });
744
+ var ProcessStateSchema = Type.Union([
745
+ Type.Literal("starting"),
746
+ Type.Literal("running"),
747
+ Type.Object({
748
+ exited: Type.Union([Type.Number(), Type.Null()]),
749
+ signal: Type.Optional(Type.String())
750
+ }),
751
+ Type.Object({
752
+ stopped: Type.Union([
753
+ Type.Literal("agent"),
754
+ Type.Literal("user"),
755
+ Type.Literal("archive"),
756
+ Type.Literal("shutdown")
757
+ ])
758
+ }),
759
+ Type.Object({ failed: Type.String() }),
760
+ Type.Literal("lost")
761
+ ]);
762
+ var ProcessInfoSchema = Type.Object({
763
+ id: Type.String({ minLength: 1 }),
764
+ owner: Type.Number(),
765
+ name: Type.String(),
766
+ command: Type.String(),
767
+ pid: Type.Optional(Type.Number()),
768
+ startedAt: Type.Number(),
769
+ endedAt: Type.Optional(Type.Number()),
770
+ state: ProcessStateSchema
771
+ });
772
+ var ProcessesSchema = Type.Object({ processes: Type.Array(ProcessInfoSchema) });
773
+ function classify(presentation, value) {
774
+ if (presentation === "pinomad.todo" && Value.Check(TodoSchema, value)) {
775
+ return { type: "pinomad.todo", value };
776
+ }
777
+ if (presentation === "pinomad.question" && Value.Check(QuestionSchema, value)) {
778
+ return { type: "pinomad.question", value };
779
+ }
780
+ if (presentation === "pinomad.diff" && Value.Check(DiffSchema, value)) {
781
+ return { type: "pinomad.diff", value };
782
+ }
783
+ if (presentation === "pinomad.codemode" && Value.Check(CodemodeSchema, value)) {
784
+ return { type: "pinomad.codemode", value };
785
+ }
786
+ if (presentation === "pinomad.context" && Value.Check(ContextBreakdownSchema, value)) {
787
+ return { type: "pinomad.context", value };
788
+ }
789
+ if (presentation === "pinomad.processes" && Value.Check(ProcessesSchema, value)) {
790
+ return { type: "pinomad.processes", value };
791
+ }
792
+ return { type: "fallback", value };
793
+ }
794
+
795
+ // packages/protocol/src/processes.ts
796
+ function isProcessesHello(value) {
797
+ return value !== null && typeof value === "object" && typeof value.limit === "number";
798
+ }
799
+ function isProcessActive(state) {
800
+ return state === "starting" || state === "running";
801
+ }
802
+ var processStream = (id) => `process:${id}`;
803
+
671
804
  // packages/protocol/src/transcript.ts
672
805
  var TRANSCRIPT_PAGE = 50;
673
806
  var MAX_TRANSCRIPT_PAGE = 500;
@@ -694,4 +827,4 @@ function isBusy(view) {
694
827
  return live?.run !== undefined;
695
828
  }
696
829
 
697
- export { rtcSelectedPair, RTC_DEFAULT_STUN, RTC_DATA_CHANNEL_LABEL, RTC_MAX_RECORD_BYTES, isRtcHello, rtcCandidateType, sdpCandidates, withRtcCandidates, parseRtcMaxMessageSize, isCustomProviderApi, HOST_STREAM_NAMES, hostStreams, conversationStream, docStream, UNAUTHORIZED_CLOSE_CODE, INVALID_FRAME_CLOSE_CODE, PROTOCOL, hostSupportsCall, hostSupportsFeature, parseClientFrame, MAX_ATTACHMENTS_PER_MESSAGE, MAX_PENDING_ATTACHMENTS, MAX_PENDING_ATTACHMENT_BYTES, ATTACHMENT_TTL_MS, MAX_ATTACHMENT_NAME_LENGTH, isAttachmentId, base64DecodedLength, attachmentBeginProblem, attachmentChunkProblem, attachmentBlock, parseAttachmentBlock, organize, checkoutOf, homeOf, TRANSCRIPT_PAGE, MAX_TRANSCRIPT_PAGE, withEarlier, addEarlier, isBusy };
830
+ export { rtcSelectedPair, RTC_DEFAULT_STUN, RTC_DATA_CHANNEL_LABEL, RTC_MAX_RECORD_BYTES, isRtcHello, rtcCandidateType, sdpCandidates, withRtcCandidates, parseRtcMaxMessageSize, isAutoUpgradeMode, HOST_UPGRADING_ERROR, isCustomProviderApi, HOST_STREAM_NAMES, hostStreams, conversationStream, docStream, UNAUTHORIZED_CLOSE_CODE, INVALID_FRAME_CLOSE_CODE, PROTOCOL, hostSupportsCall, hostSupportsFeature, parseClientFrame, MAX_ATTACHMENTS_PER_MESSAGE, MAX_PENDING_ATTACHMENTS, MAX_PENDING_ATTACHMENT_BYTES, ATTACHMENT_TTL_MS, MAX_ATTACHMENT_NAME_LENGTH, isAttachmentId, base64DecodedLength, attachmentBeginProblem, attachmentChunkProblem, attachmentBlock, parseAttachmentBlock, organize, checkoutOf, homeOf, TodoItemSchema, QuestionItemSchema, QuestionSchema, classify, isProcessesHello, isProcessActive, processStream, TRANSCRIPT_PAGE, MAX_TRANSCRIPT_PAGE, withEarlier, addEarlier, isBusy };
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-ngf1zatm.js";
4
4
  import {
5
5
  packagedVersion
6
- } from "./chunk-s0h7c7da.js";
6
+ } from "./chunk-ega1wnkg.js";
7
7
  import"./chunk-df32avw6.js";
8
8
 
9
9
  // apps/host/src/cli/web-link.ts
@@ -3,39 +3,41 @@ import {
3
3
  isSecureServerOrigin,
4
4
  probeServerAccounts,
5
5
  runServerOperation
6
- } from "./chunk-7mn38n4f.js";
6
+ } from "./chunk-63ymn5c9.js";
7
7
  import {
8
8
  constantValue,
9
9
  openHostSettings
10
- } from "./chunk-563fnad9.js";
10
+ } from "./chunk-6j6hkfbj.js";
11
11
  import {
12
12
  loadHostKey,
13
13
  loadRelayKey
14
- } from "./chunk-t91zt5f0.js";
14
+ } from "./chunk-hg9gs396.js";
15
15
  import {
16
16
  writeServerConfig
17
17
  } from "./chunk-nq57fdnq.js";
18
18
  import {
19
19
  relayHostId
20
- } from "./chunk-g3ahp7b9.js";
20
+ } from "./chunk-9trbbz4r.js";
21
+ import {
22
+ restartService
23
+ } from "./chunk-pte4peaf.js";
21
24
  import {
22
25
  argValue,
23
26
  installSpec,
24
- restartService,
25
27
  serviceManager,
26
28
  withoutRelayArgs
27
- } from "./chunk-wd7aracm.js";
29
+ } from "./chunk-mxwcnnkg.js";
28
30
  import {
29
31
  cleanHostName,
30
32
  normalizeHostName
31
- } from "./chunk-pqe7q1s7.js";
33
+ } from "./chunk-6vbp1vva.js";
32
34
  import {
33
35
  DEFAULT_DATA_DIR
34
36
  } from "./chunk-ngf1zatm.js";
35
37
  import {
36
38
  commandHint,
37
39
  hostEntry
38
- } from "./chunk-s0h7c7da.js";
40
+ } from "./chunk-ega1wnkg.js";
39
41
 
40
42
  // apps/host/src/cli/join.ts
41
43
  import { mkdir } from "node:fs/promises";
@@ -6,10 +6,10 @@ import {
6
6
  relayWsBase,
7
7
  signRelayChallenge,
8
8
  signRelayChallengeV2
9
- } from "./chunk-g3ahp7b9.js";
9
+ } from "./chunk-9trbbz4r.js";
10
10
  import {
11
11
  toBase64Url
12
- } from "./chunk-pqe7q1s7.js";
12
+ } from "./chunk-6vbp1vva.js";
13
13
 
14
14
  // apps/host/src/cli/server-ops.ts
15
15
  import { WebSocket } from "ws";
@@ -1,13 +1,14 @@
1
1
  import {
2
- RTC_DEFAULT_STUN
3
- } from "./chunk-kmzzjv53.js";
2
+ RTC_DEFAULT_STUN,
3
+ isAutoUpgradeMode
4
+ } from "./chunk-1mjbt2z2.js";
4
5
  import {
5
6
  HOST_SETTING_KEYS,
6
7
  cleanHostName,
7
8
  isQueueMode,
8
9
  isThinkingLevel,
9
10
  normalizeHostName
10
- } from "./chunk-pqe7q1s7.js";
11
+ } from "./chunk-6vbp1vva.js";
11
12
 
12
13
  // apps/host/src/host-value.ts
13
14
  function constantValue(value) {
@@ -70,10 +71,12 @@ var fileValueError = (key, value, models) => {
70
71
  return Array.isArray(value) && value.every((entry) => typeof entry === "string" && entry !== "") ? undefined : "malformed";
71
72
  case "hostName":
72
73
  return typeof value === "string" ? undefined : "malformed";
74
+ case "autoUpgrade":
75
+ return isAutoUpgradeMode(value) ? undefined : "malformed";
73
76
  }
74
77
  };
75
78
  var sameModel = (a, b) => a === b || a !== null && b !== null && a.provider === b.provider && a.modelId === b.modelId;
76
- var sameSettings = (a, b) => a.steeringMode === b.steeringMode && a.followUpMode === b.followUpMode && a.acceptAccountDevices === b.acceptAccountDevices && a.defaultThinkingLevel === b.defaultThinkingLevel && sameModel(a.defaultModel, b.defaultModel) && (a.rtcStun === undefined || b.rtcStun === undefined ? a.rtcStun === b.rtcStun : sameList(a.rtcStun, b.rtcStun, (x, y) => x === y)) && a.hostName === b.hostName && sameList(a.custom, b.custom, (x, y) => x === y);
79
+ var sameSettings = (a, b) => a.steeringMode === b.steeringMode && a.followUpMode === b.followUpMode && a.acceptAccountDevices === b.acceptAccountDevices && a.defaultThinkingLevel === b.defaultThinkingLevel && sameModel(a.defaultModel, b.defaultModel) && (a.rtcStun === undefined || b.rtcStun === undefined ? a.rtcStun === b.rtcStun : sameList(a.rtcStun, b.rtcStun, (x, y) => x === y)) && a.hostName === b.hostName && a.autoUpgrade === b.autoUpgrade && sameList(a.custom, b.custom, (x, y) => x === y);
77
80
  var parse = (path, text) => {
78
81
  let parsed;
79
82
  try {
@@ -120,6 +123,7 @@ async function openHostSettings(options) {
120
123
  acceptAccountDevices: fileValues.acceptAccountDevices ?? true,
121
124
  rtcStun: fileValues.rtcStun ?? RTC_DEFAULT_STUN,
122
125
  hostName: normalizeHostName(fileValues.hostName ?? hostname()),
126
+ autoUpgrade: fileValues.autoUpgrade ?? "notify",
123
127
  custom
124
128
  };
125
129
  };
@@ -82,7 +82,8 @@ var HOST_SETTING_KEY_SET = {
82
82
  followUpMode: true,
83
83
  acceptAccountDevices: true,
84
84
  rtcStun: true,
85
- hostName: true
85
+ hostName: true,
86
+ autoUpgrade: true
86
87
  };
87
88
  var HOST_SETTING_KEYS = Object.keys(HOST_SETTING_KEY_SET);
88
89
  var THINKING_LEVEL_KEYS = { off: true, minimal: true, low: true, medium: true, high: true, xhigh: true, max: true };
@@ -0,0 +1,46 @@
1
+ import {
2
+ globalPrefixOf,
3
+ packageDir
4
+ } from "./chunk-ega1wnkg.js";
5
+
6
+ // apps/host/src/upgrade/npm.ts
7
+ import { existsSync } from "node:fs";
8
+ import { dirname, join } from "node:path";
9
+ function npmBeside(execPath) {
10
+ const binDir = dirname(execPath);
11
+ const cli = join(binDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js");
12
+ return existsSync(cli) ? { command: execPath, args: [cli], binDir } : { command: "npm", args: [] };
13
+ }
14
+ var packagePrefix = () => globalPrefixOf(packageDir);
15
+ function installCommand(npm, prefix, spec) {
16
+ return { ...npm, args: [...npm.args, "install", "-g", "--prefix", prefix, spec] };
17
+ }
18
+ function viewCommand(npm) {
19
+ return { ...npm, args: [...npm.args, "view", "pinomad@latest", "version", "time", "pinomad", "--json"] };
20
+ }
21
+ function parseRelease(stdout) {
22
+ const parsed = JSON.parse(stdout);
23
+ const value = Array.isArray(parsed) ? parsed.at(-1) : parsed;
24
+ if (value === undefined || value === null)
25
+ throw new Error("npm view returned no version");
26
+ if (typeof value.version !== "string")
27
+ throw new Error("npm view returned no version");
28
+ const time = value.time;
29
+ const published = typeof time?.[value.version] === "string" ? Date.parse(time[value.version]) : Number.NaN;
30
+ if (Number.isNaN(published))
31
+ throw new Error(`npm view returned no publish time for ${value.version}`);
32
+ const field = value.pinomad;
33
+ const major = field?.protocolMajor;
34
+ return {
35
+ version: value.version,
36
+ publishedAt: published,
37
+ ...typeof major === "number" && Number.isSafeInteger(major) ? { protocolMajor: major } : {}
38
+ };
39
+ }
40
+ function outputTail(output, lines = 12) {
41
+ return output.split(`
42
+ `).filter((line) => line.trim() !== "").slice(-lines).join(`
43
+ `);
44
+ }
45
+
46
+ export { npmBeside, packagePrefix, installCommand, viewCommand, parseRelease, outputTail };
@@ -4,21 +4,23 @@ import {
4
4
  readServerConfig
5
5
  } from "./chunk-nq57fdnq.js";
6
6
  import {
7
- argValue,
8
7
  reachabilityLine,
9
- serviceManager,
10
8
  versionLine
11
- } from "./chunk-wd7aracm.js";
12
- import"./chunk-4fferbxw.js";
9
+ } from "./chunk-pte4peaf.js";
10
+ import"./chunk-e59k3bmz.js";
13
11
  import"./chunk-kzbzacz9.js";
14
- import"./chunk-kmzzjv53.js";
15
- import"./chunk-pqe7q1s7.js";
12
+ import {
13
+ argValue,
14
+ serviceManager
15
+ } from "./chunk-mxwcnnkg.js";
16
+ import"./chunk-1mjbt2z2.js";
17
+ import"./chunk-6vbp1vva.js";
16
18
  import {
17
19
  DEFAULT_DATA_DIR
18
20
  } from "./chunk-ngf1zatm.js";
19
21
  import {
20
22
  commandHint
21
- } from "./chunk-s0h7c7da.js";
23
+ } from "./chunk-ega1wnkg.js";
22
24
  import"./chunk-df32avw6.js";
23
25
 
24
26
  // apps/host/src/cli/status.ts
@@ -3,7 +3,7 @@ import {
3
3
  fromBase64Url,
4
4
  parseEndpointSet,
5
5
  toBase64Url
6
- } from "./chunk-pqe7q1s7.js";
6
+ } from "./chunk-6vbp1vva.js";
7
7
 
8
8
  // packages/protocol/src/relay.ts
9
9
  import { ed25519 } from "@noble/curves/ed25519.js";