@p4code/cli 0.1.18 → 0.1.19

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 (85) hide show
  1. package/dist/bin.mjs +628 -141
  2. package/dist/client/assets/{DiffPanel-CP_cM9m0.js → DiffPanel-CseUmWvE.js} +2 -2
  3. package/dist/client/assets/{FilePreviewPanel-CLho0PPu.js → FilePreviewPanel-Dm7l5FFh.js} +2 -2
  4. package/dist/client/assets/{PreviewPanel-DvnUpMQv.js → PreviewPanel-DOyykNL9.js} +2 -2
  5. package/dist/client/assets/{angular-html-CEMakyzJ.js → angular-html-YobKPLun.js} +2 -2
  6. package/dist/client/assets/{angular-ts-YXZHq2uz.js → angular-ts-Ac3I6TFV.js} +2 -2
  7. package/dist/client/assets/{apl-BTa85Bsd.js → apl-Dwl73GTS.js} +2 -2
  8. package/dist/client/assets/arrow-right-BqDszij1.js +2 -0
  9. package/dist/client/assets/{astro-DIbti84c.js → astro-KBgldnxZ.js} +2 -2
  10. package/dist/client/assets/{blade-CKAdvdwG.js → blade-DTU2NGhh.js} +2 -2
  11. package/dist/client/assets/{c-DW17xzCK.js → c-COF4kWCp.js} +2 -2
  12. package/dist/client/assets/{cobol-DXiicIcZ.js → cobol-BA7JsdNr.js} +2 -2
  13. package/dist/client/assets/{coffee-9Pdmmdn2.js → coffee-PFN_w4qL.js} +2 -2
  14. package/dist/client/assets/{cpp-bm3vFVmW.js → cpp-CpT6w-g5.js} +2 -2
  15. package/dist/client/assets/{crystal-DbxZDZf9.js → crystal-BrlaRT0B.js} +2 -2
  16. package/dist/client/assets/{css-BEBnbxDe.js → css-C2LMO3MX.js} +2 -2
  17. package/dist/client/assets/{edge-K97wVEy_.js → edge-DBkQ-Ajd.js} +2 -2
  18. package/dist/client/assets/{elixir-Rc2JDLLD.js → elixir-EbSNDEx0.js} +2 -2
  19. package/dist/client/assets/{elm-QsA8aREL.js → elm-CSs0Wzy2.js} +2 -2
  20. package/dist/client/assets/{erb-CliRJz4v.js → erb-BBmMQG9b.js} +2 -2
  21. package/dist/client/assets/{fileCommentAnnotations-DtIPA0Fm.js → fileCommentAnnotations-CifvTzWP.js} +2 -2
  22. package/dist/client/assets/{git-rebase-Da_Wuhd_.js → git-rebase-C09BpZDw.js} +2 -2
  23. package/dist/client/assets/{glimmer-js-XPbTw3tC.js → glimmer-js-D4Bqn6Yg.js} +2 -2
  24. package/dist/client/assets/{glimmer-ts-BtK3NOkH.js → glimmer-ts-fLCHL8o6.js} +2 -2
  25. package/dist/client/assets/{glsl-DqEtJptk.js → glsl-17sV9oGm.js} +2 -2
  26. package/dist/client/assets/{graphql-BSRTeXs0.js → graphql-BqFquulN.js} +2 -2
  27. package/dist/client/assets/{hack-Dw9HaNHZ.js → hack-D6Jpv-j9.js} +2 -2
  28. package/dist/client/assets/{haml-BBNabTlb.js → haml-D0eo8PEJ.js} +2 -2
  29. package/dist/client/assets/{handlebars-BgXzhWSj.js → handlebars-HG0XNkEg.js} +2 -2
  30. package/dist/client/assets/{html-wBdSHoow.js → html-Bh3padJ5.js} +2 -2
  31. package/dist/client/assets/{html-derivative-CANLUZ-z.js → html-derivative-DVHw4MNX.js} +2 -2
  32. package/dist/client/assets/{http-BY44QKMy.js → http-CYCXaOA5.js} +2 -2
  33. package/dist/client/assets/{hurl-EMZQkkjM.js → hurl-D4oK46oh.js} +2 -2
  34. package/dist/client/assets/index-CV_dK79d.js +783 -0
  35. package/dist/client/assets/{java-ByjPbT42.js → java-nvFYZOCN.js} +2 -2
  36. package/dist/client/assets/{javascript-C9vbUEcm.js → javascript-CMBxjf-M.js} +2 -2
  37. package/dist/client/assets/{jinja-DH-AbsBN.js → jinja-vsPdkFFj.js} +2 -2
  38. package/dist/client/assets/{jison-Bef1Ntr_.js → jison-uky2pPNE.js} +2 -2
  39. package/dist/client/assets/{json-Gk_oM0bP.js → json-DOSqa2F1.js} +2 -2
  40. package/dist/client/assets/{jsx-Ds7YHLou.js → jsx-Ci7CVNQe.js} +2 -2
  41. package/dist/client/assets/{julia-Dm-6xpIK.js → julia-J2m7N3_R.js} +2 -2
  42. package/dist/client/assets/{just-BXY93QN4.js → just-BDy3oM_N.js} +2 -2
  43. package/dist/client/assets/{latex-B3-eYkFA.js → latex-CMD49F7D.js} +2 -2
  44. package/dist/client/assets/{liquid-C10OBLnm.js → liquid-Dq6k2YW6.js} +2 -2
  45. package/dist/client/assets/{lua-BUR8bsxC.js → lua-CohtP6J8.js} +2 -2
  46. package/dist/client/assets/{marko-COPLM_fz.js → marko-C4V2zw1t.js} +2 -2
  47. package/dist/client/assets/{mdc-CTAUTBsz.js → mdc-q1ZKjwYt.js} +2 -2
  48. package/dist/client/assets/{nginx-D1BLqLRM.js → nginx-D2TdEIZ3.js} +2 -2
  49. package/dist/client/assets/{nim-Xs8VbhdY.js → nim-BtWKpYQs.js} +2 -2
  50. package/dist/client/assets/{perl-D7-zmFa1.js → perl-Ci4Pso9h.js} +2 -2
  51. package/dist/client/assets/{php-BiTVgoaL.js → php-CMzpcAju.js} +2 -2
  52. package/dist/client/assets/{pug-DphfHoFa.js → pug-D0sbFhP6.js} +2 -2
  53. package/dist/client/assets/{qml-CYcNnFOd.js → qml-BfWXHzNc.js} +2 -2
  54. package/dist/client/assets/{r-BrJ-p0TS.js → r-BN4rQDnz.js} +2 -2
  55. package/dist/client/assets/{razor-1gio6m_g.js → razor-D5iw68yr.js} +2 -2
  56. package/dist/client/assets/{regexp-CNiuKup7.js → regexp-Ba0WieCb.js} +2 -2
  57. package/dist/client/assets/{rst-BPOsO8_U.js → rst-DQqlRfnq.js} +2 -2
  58. package/dist/client/assets/{ruby-CpfKHKDc.js → ruby-CReh9Gta.js} +2 -2
  59. package/dist/client/assets/{sas-CngX1we2.js → sas-CJ-Cpd8L.js} +2 -2
  60. package/dist/client/assets/{scss-B2remLQX.js → scss-CZp-cH6d.js} +2 -2
  61. package/dist/client/assets/{shellscript-CQmxALRY.js → shellscript-hCSuhhJZ.js} +2 -2
  62. package/dist/client/assets/{shellsession-BB-5CB_r.js → shellsession-BnDNcCDQ.js} +2 -2
  63. package/dist/client/assets/{soy-kYUnX51I.js → soy-BXarcWJY.js} +2 -2
  64. package/dist/client/assets/{sql-Cq9fRkwr.js → sql-ADQCXhYd.js} +2 -2
  65. package/dist/client/assets/{stata-17nboilR.js → stata-DSS4IpqF.js} +2 -2
  66. package/dist/client/assets/{surrealql-D1hrcsSn.js → surrealql-DuYcftNm.js} +2 -2
  67. package/dist/client/assets/{svelte-GmGi3eK8.js → svelte-CAXOFInl.js} +2 -2
  68. package/dist/client/assets/{templ-DySdTLEs.js → templ-BvTIEIah.js} +2 -2
  69. package/dist/client/assets/{tex-CblcFqPi.js → tex-DpnVRTMM.js} +2 -2
  70. package/dist/client/assets/textarea-etKSOtDN.js +46 -0
  71. package/dist/client/assets/{ts-tags-BQC5pzJI.js → ts-tags-4wlHlovT.js} +2 -2
  72. package/dist/client/assets/{tsx-1bNjXgiV.js → tsx-CHDgELdy.js} +2 -2
  73. package/dist/client/assets/{twig-CNwthYXl.js → twig-DPmx2UHF.js} +2 -2
  74. package/dist/client/assets/{typescript-BTKoaKmx.js → typescript-CHO8bW-H.js} +2 -2
  75. package/dist/client/assets/{vue-B4XpWxge.js → vue-CM19I03n.js} +2 -2
  76. package/dist/client/assets/{vue-html-CcUSqexV.js → vue-html-ginfkxGQ.js} +2 -2
  77. package/dist/client/assets/{vue-vine-JDMd26pY.js → vue-vine-CGdZxUwf.js} +2 -2
  78. package/dist/client/assets/{xml-DRuNSJP8.js → xml-B8CY16OL.js} +2 -2
  79. package/dist/client/assets/{xsl-BIJJg1B0.js → xsl-COHh7n8v.js} +2 -2
  80. package/dist/client/assets/{yaml-BNEnOsJI.js → yaml-DXx-djat.js} +2 -2
  81. package/dist/client/index.html +2 -2
  82. package/package.json +1 -1
  83. package/dist/client/assets/arrow-right-Bi8kADrV.js +0 -2
  84. package/dist/client/assets/index-kwzTYbVb.js +0 -775
  85. package/dist/client/assets/textarea-Cf56oU_6.js +0 -46
package/dist/bin.mjs CHANGED
@@ -121,7 +121,7 @@ const closeServer = (server) => {
121
121
  * NetService - Service tag for startup networking helpers.
122
122
  */
123
123
  var NetService = class extends Context.Service()("@p4code/shared/Net/NetService") {};
124
- const make$75 = () => {
124
+ const make$76 = () => {
125
125
  /**
126
126
  * Returns true when a TCP server can bind to {host, port}.
127
127
  * `EADDRNOTAVAIL` is treated as available so IPv6-absent hosts don't fail
@@ -230,10 +230,10 @@ const make$75 = () => {
230
230
  })
231
231
  };
232
232
  };
233
- const layer$71 = Layer.sync(NetService, make$75);
233
+ const layer$72 = Layer.sync(NetService, make$76);
234
234
  //#endregion
235
235
  //#region package.json
236
- var version = "0.1.18";
236
+ var version = "0.1.19";
237
237
  //#endregion
238
238
  //#region src/config.ts
239
239
  /**
@@ -254,8 +254,8 @@ var ServerConfig$1 = class extends Context.Service()("@p4code/cli/config/ServerC
254
254
  /** @deprecated Import and use `layerTest` from this module. */
255
255
  static layerTest = (cwd, baseDirOrPrefix) => layerTest$2(cwd, baseDirOrPrefix);
256
256
  };
257
- const make$74 = (config) => ServerConfig$1.of(config);
258
- const layer$70 = (config) => Layer.succeed(ServerConfig$1, make$74(config));
257
+ const make$75 = (config) => ServerConfig$1.of(config);
258
+ const layer$71 = (config) => Layer.succeed(ServerConfig$1, make$75(config));
259
259
  const deriveServerPaths = Effect.fn(function* (baseDir, devUrl, options = {}) {
260
260
  const { join } = yield* Path.Path;
261
261
  const stateDir = join(baseDir, devUrl !== void 0 && !options.baseDirIsExplicit ? "dev" : "userdata");
@@ -3430,6 +3430,36 @@ const PreviewAutomationNetworkEntry = Schema.Struct({
3430
3430
  errorText: Schema.optional(Schema.String),
3431
3431
  timestamp: Schema.String
3432
3432
  });
3433
+ /** Value of an accessibility state such as `expanded`, `checked` or `level`. */
3434
+ const PreviewAccessibilityState = Schema.Union([
3435
+ Schema.String,
3436
+ Schema.Number,
3437
+ Schema.Boolean
3438
+ ]);
3439
+ /**
3440
+ * A node of the compacted accessibility tree. `parentId` points at the nearest
3441
+ * emitted ancestor, so the hierarchy is reconstructible without child lists.
3442
+ */
3443
+ const PreviewAccessibilityNode = Schema.Struct({
3444
+ id: Schema.String,
3445
+ parentId: Schema.optional(Schema.String),
3446
+ role: Schema.String,
3447
+ name: Schema.optional(Schema.String),
3448
+ description: Schema.optional(Schema.String),
3449
+ value: Schema.optional(Schema.String),
3450
+ states: Schema.optional(Schema.Record(Schema.String, PreviewAccessibilityState))
3451
+ });
3452
+ /**
3453
+ * Semantic nodes only: ignored nodes, raw text nodes and unnamed layout
3454
+ * wrappers are dropped, and the node list is capped. `totalNodes` counts the
3455
+ * nodes that survived filtering, so `truncated` distinguishes a clipped tree
3456
+ * from a small page.
3457
+ */
3458
+ const PreviewAccessibilitySnapshot = Schema.Struct({
3459
+ nodes: Schema.Array(PreviewAccessibilityNode),
3460
+ totalNodes: Schema.Int,
3461
+ truncated: Schema.Boolean
3462
+ });
3433
3463
  const PreviewAutomationActionEvent = Schema.Struct({
3434
3464
  id: Schema.String,
3435
3465
  action: Schema.String,
@@ -3449,7 +3479,7 @@ const PreviewAutomationSnapshot = Schema.Struct({
3449
3479
  loading: Schema.Boolean,
3450
3480
  visibleText: Schema.String,
3451
3481
  interactiveElements: Schema.Array(PreviewAutomationElement),
3452
- accessibilityTree: Schema.Unknown,
3482
+ accessibilityTree: PreviewAccessibilitySnapshot,
3453
3483
  consoleEntries: Schema.Array(PreviewAutomationConsoleEntry),
3454
3484
  networkEntries: Schema.Array(PreviewAutomationNetworkEntry),
3455
3485
  actionTimeline: Schema.Array(PreviewAutomationActionEvent),
@@ -7218,6 +7248,21 @@ const RepositoryKeyField = TrimmedNonEmptyString.pipe(Schema$1.annotateEncoded({
7218
7248
  * placed by hand and falls back to the priority/recency order.
7219
7249
  */
7220
7250
  const OrderKeyField = TrimmedNonEmptyString.pipe(Schema$1.annotateEncoded({ description: "Manual board position key. Lexicographic: smaller sorts higher in the column. Null means no manual position." }));
7251
+ /**
7252
+ * Where a task came from when it did not originate on this board.
7253
+ *
7254
+ * The identifier is the tracker's own, not ours: `MOBILE-12262` reads the same
7255
+ * in p4code as it does in Linear, in a commit message, and in conversation,
7256
+ * which is the whole point of carrying it. `url` is what the tracker itself
7257
+ * reported, never a guess assembled from the identifier - a Linear URL embeds
7258
+ * the workspace slug, so a constructed one would 404.
7259
+ */
7260
+ const TaskExternalRef = Schema$1.Struct({
7261
+ source: Schema$1.Literals(["linear"]),
7262
+ identifier: TrimmedNonEmptyString,
7263
+ url: TrimmedNonEmptyString
7264
+ });
7265
+ const ExternalRefField = TaskExternalRef.pipe(Schema$1.annotateEncoded({ description: "The tracker issue this task mirrors, e.g. a Linear ticket. Null for a task that originated on this board." }));
7221
7266
  const LabelsField = Schema$1.Array(TaskLabel).check(Schema$1.isMaxLength(TASK_LABELS_MAX_COUNT)).pipe(Schema$1.annotateEncoded({ description: "Free-form tags used to group and filter tasks." }));
7222
7267
  const TaskIdField = TaskId.pipe(Schema$1.annotateEncoded({ description: "Id of the task to act on - the UUID or the readable id (e.g. P4-12)." }));
7223
7268
  const Task = Schema$1.Struct({
@@ -7259,6 +7304,13 @@ const Task = Schema$1.Struct({
7259
7304
  * to a history.
7260
7305
  */
7261
7306
  threadId: Schema$1.NullOr(ThreadId),
7307
+ /**
7308
+ * The tracker issue this task mirrors, or `null` for a task that was filed
7309
+ * here. Nullable-with-default for the same version-skew reason as
7310
+ * `readableId` above: a row from a store without the migration decodes to
7311
+ * `null` rather than failing the whole board.
7312
+ */
7313
+ externalRef: Schema$1.NullOr(TaskExternalRef).pipe(Schema$1.withDecodingDefault(Effect.succeed(null))),
7262
7314
  title: TrimmedNonEmptyString.check(Schema$1.isMaxLength(TASK_TITLE_MAX_LENGTH)),
7263
7315
  body: Schema$1.String,
7264
7316
  status: StoredStatusField,
@@ -7272,6 +7324,7 @@ const TaskCreateInput = Schema$1.Struct({
7272
7324
  projectId: Schema$1.optional(ProjectIdField),
7273
7325
  repositoryKey: Schema$1.optional(RepositoryKeyField),
7274
7326
  threadId: Schema$1.optional(ThreadIdField),
7327
+ externalRef: Schema$1.optional(ExternalRefField),
7275
7328
  title: TitleField,
7276
7329
  body: Schema$1.optional(BodyField),
7277
7330
  status: Schema$1.optional(StatusField),
@@ -7310,6 +7363,7 @@ const TaskUpdateInput = Schema$1.Struct({
7310
7363
  projectId: Schema$1.optional(Schema$1.NullOr(ProjectIdField)),
7311
7364
  repositoryKey: Schema$1.optional(Schema$1.NullOr(RepositoryKeyField)),
7312
7365
  threadId: Schema$1.optional(Schema$1.NullOr(ThreadIdField)),
7366
+ externalRef: Schema$1.optional(Schema$1.NullOr(ExternalRefField)),
7313
7367
  title: Schema$1.optional(TitleField),
7314
7368
  body: Schema$1.optional(BodyField),
7315
7369
  status: Schema$1.optional(StatusField),
@@ -7675,6 +7729,58 @@ var ProjectWriteFileError = class extends Schema$1.TaggedErrorClass()("ProjectWr
7675
7729
  }
7676
7730
  };
7677
7731
  //#endregion
7732
+ //#region ../../packages/contracts/src/ticket.ts
7733
+ /**
7734
+ * Reading an issue out of an external tracker.
7735
+ *
7736
+ * One call, deliberately: p4code does not sync trackers, it recognizes a ticket
7737
+ * somebody pasted and asks the tracker what it is called. Everything durable
7738
+ * that comes back is stored on a task as its {@link TaskExternalRef}.
7739
+ *
7740
+ * The tracker is reached through the MCP server the user already registered for
7741
+ * it, so there is no second place to configure credentials and no p4code-owned
7742
+ * API key. That also bounds what this can ever answer: a tracker with no MCP
7743
+ * server registered, or one never signed in to on this machine, is reported as
7744
+ * unconfigured rather than silently returning nothing.
7745
+ *
7746
+ * @module contracts/ticket
7747
+ */
7748
+ /**
7749
+ * A tracker reference as it was typed, before anything has confirmed it exists.
7750
+ *
7751
+ * Deliberately not the parsed `{ source, identifier }` pair: what a user pastes
7752
+ * is a URL as often as an id, and which tracker a bare `MOBILE-12262` belongs
7753
+ * to is a question only the resolver can answer.
7754
+ */
7755
+ const TicketResolveInput = Schema$1.Struct({ reference: TrimmedNonEmptyString });
7756
+ const TicketResolveResult = Schema$1.Struct({
7757
+ externalRef: TaskExternalRef,
7758
+ /** The issue title as the tracker reports it, for the task that mirrors it. */
7759
+ title: TrimmedNonEmptyString
7760
+ });
7761
+ /**
7762
+ * Why a reference could not be turned into a ticket.
7763
+ *
7764
+ * The reason is separate from the detail because the client acts on it: an
7765
+ * unconfigured tracker is a thing the user can fix in Settings and is worth
7766
+ * saying so about, while `unavailable` is a retry and `not_found` usually means
7767
+ * a typo. `detail` is the sentence to show; the reason decides the shape.
7768
+ */
7769
+ const TicketResolveFailureReason = Schema$1.Literals([
7770
+ "not_configured",
7771
+ "not_authorized",
7772
+ "not_found",
7773
+ "unavailable"
7774
+ ]);
7775
+ var TicketResolveError = class extends Schema$1.TaggedErrorClass()("TicketResolveError", {
7776
+ reason: TicketResolveFailureReason,
7777
+ detail: Schema$1.String
7778
+ }) {
7779
+ get message() {
7780
+ return this.detail;
7781
+ }
7782
+ };
7783
+ //#endregion
7678
7784
  //#region ../../packages/contracts/src/threadControl.ts
7679
7785
  /**
7680
7786
  * Thread control over MCP - the self-scoped toolkit an agent uses to act on
@@ -8726,6 +8832,7 @@ const WS_METHODS = {
8726
8832
  tasksUpdate: "tasks.update",
8727
8833
  tasksDelete: "tasks.delete",
8728
8834
  tasksStartThread: "tasks.startThread",
8835
+ ticketsResolve: "tickets.resolve",
8729
8836
  hubGetSyncStatus: "hub.getSyncStatus",
8730
8837
  hubConnect: "hub.connect",
8731
8838
  hubDisconnect: "hub.disconnect",
@@ -9033,6 +9140,17 @@ const WsMcpOAuthDisconnectRpc = Rpc.make(WS_METHODS.mcpOAuthDisconnect, {
9033
9140
  error: Schema$1.Union([McpRegistryError, EnvironmentAuthorizationError])
9034
9141
  });
9035
9142
  /**
9143
+ * Asks the tracker what a pasted reference is, without writing anything.
9144
+ *
9145
+ * Read-only on purpose: the caller decides whether the answer becomes a task.
9146
+ * A resolve that filed a row would make an accidental paste a board entry.
9147
+ */
9148
+ const WsTicketsResolveRpc = Rpc.make(WS_METHODS.ticketsResolve, {
9149
+ payload: TicketResolveInput,
9150
+ success: TicketResolveResult,
9151
+ error: Schema$1.Union([TicketResolveError, EnvironmentAuthorizationError])
9152
+ });
9153
+ /**
9036
9154
  * The board, then every change to it, for as long as the client stays
9037
9155
  * subscribed. The leading snapshot is what makes this sufficient on its own —
9038
9156
  * a client does not list first, so there is no window between the two in which
@@ -9410,7 +9528,7 @@ const WsSubscribeAuthAccessRpc = Rpc.make(WS_METHODS.subscribeAuthAccess, {
9410
9528
  error: Schema$1.Union([AuthAccessStreamError, EnvironmentAuthorizationError]),
9411
9529
  stream: true
9412
9530
  });
9413
- const WsRpcGroup = RpcGroup.make(WsServerProbeRpc, WsServerGetConfigRpc, WsServerRefreshProvidersRpc, WsServerUpdateProviderRpc, WsServerUpdateServerRpc, WsServerUpsertKeybindingRpc, WsServerRemoveKeybindingRpc, WsServerGetSettingsRpc, WsServerUpdateSettingsRpc, WsServerDiscoverSourceControlRpc, WsServerGetProviderUsageRpc, WsServerGetTraceDiagnosticsRpc, WsServerGetProcessDiagnosticsRpc, WsServerGetProcessResourceHistoryRpc, WsServerSignalProcessRpc, WsSourceControlLookupRepositoryRpc, WsSourceControlCloneRepositoryRpc, WsSourceControlPublishRepositoryRpc, WsProjectsListEntriesRpc, WsProjectsReadFileRpc, WsProjectsSearchEntriesRpc, WsProjectsWriteFileRpc, WsShellOpenInEditorRpc, WsFilesystemBrowseRpc, WsAssetsCreateUrlRpc, WsSubscribeVcsStatusRpc, WsVcsPullRpc, WsVcsRefreshStatusRpc, WsGitRunStackedActionRpc, WsGitResolvePullRequestRpc, WsGitPreparePullRequestThreadRpc, WsVcsListRefsRpc, WsVcsCreateWorktreeRpc, WsVcsRemoveWorktreeRpc, WsVcsCreateRefRpc, WsVcsSwitchRefRpc, WsVcsInitRpc, WsReviewGetDiffPreviewRpc, WsTerminalOpenRpc, WsTerminalAttachRpc, WsTerminalWriteRpc, WsTerminalResizeRpc, WsTerminalClearRpc, WsTerminalRestartRpc, WsTerminalCloseRpc, WsSubscribeTerminalEventsRpc, WsSubscribeTerminalMetadataRpc, WsPreviewOpenRpc, WsPreviewNavigateRpc, WsPreviewResizeRpc, WsPreviewRefreshRpc, WsPreviewCloseRpc, WsPreviewListRpc, WsPreviewReportStatusRpc, WsPreviewAutomationConnectRpc, WsPreviewAutomationRespondRpc, WsPreviewAutomationFocusHostRpc, WsSubscribePreviewEventsRpc, WsSubscribeDiscoveredLocalServersRpc, WsSubscribeServerConfigRpc, WsSubscribeServerLifecycleRpc, WsSubscribeAuthAccessRpc, WsTasksListRpc, WsTasksGetRpc, WsTasksCreateRpc, WsTasksUpdateRpc, WsTasksDeleteRpc, WsTasksStartThreadRpc, WsSubscribeTasksRpc, WsHubGetSyncStatusRpc, WsHubConnectRpc, WsHubDisconnectRpc, WsHubSetSyncModeRpc, WsHubSetShareModeRpc, WsHubMintTokenRpc, WsSkillsSyncRpc, WsSkillsPublishRpc, WsSkillsPublishAllRpc, WsSkillsUnpublishRpc, WsAssetsReadRpc, WsAssetsSaveRpc, WsAssetsDeleteRpc, WsAssetsCreateLocalRpc, WsAssetsRemoveLocalRpc, WsSkillRegistrySearchRpc, WsSkillRegistryFetchRpc, WsMcpListRpc, WsMcpSaveRpc, WsMcpRemoveRpc, WsMcpSetSecretRpc, WsMcpOAuthBeginRpc, WsMcpOAuthDisconnectRpc, WsOrchestrationDispatchCommandRpc, WsOrchestrationGetTurnDiffRpc, WsOrchestrationGetFullThreadDiffRpc, WsOrchestrationGetArchivedShellSnapshotRpc, WsOrchestrationSubscribeShellRpc, WsOrchestrationSubscribeThreadRpc);
9531
+ const WsRpcGroup = RpcGroup.make(WsServerProbeRpc, WsServerGetConfigRpc, WsServerRefreshProvidersRpc, WsServerUpdateProviderRpc, WsServerUpdateServerRpc, WsServerUpsertKeybindingRpc, WsServerRemoveKeybindingRpc, WsServerGetSettingsRpc, WsServerUpdateSettingsRpc, WsServerDiscoverSourceControlRpc, WsServerGetProviderUsageRpc, WsServerGetTraceDiagnosticsRpc, WsServerGetProcessDiagnosticsRpc, WsServerGetProcessResourceHistoryRpc, WsServerSignalProcessRpc, WsSourceControlLookupRepositoryRpc, WsSourceControlCloneRepositoryRpc, WsSourceControlPublishRepositoryRpc, WsProjectsListEntriesRpc, WsProjectsReadFileRpc, WsProjectsSearchEntriesRpc, WsProjectsWriteFileRpc, WsShellOpenInEditorRpc, WsFilesystemBrowseRpc, WsAssetsCreateUrlRpc, WsSubscribeVcsStatusRpc, WsVcsPullRpc, WsVcsRefreshStatusRpc, WsGitRunStackedActionRpc, WsGitResolvePullRequestRpc, WsGitPreparePullRequestThreadRpc, WsVcsListRefsRpc, WsVcsCreateWorktreeRpc, WsVcsRemoveWorktreeRpc, WsVcsCreateRefRpc, WsVcsSwitchRefRpc, WsVcsInitRpc, WsReviewGetDiffPreviewRpc, WsTerminalOpenRpc, WsTerminalAttachRpc, WsTerminalWriteRpc, WsTerminalResizeRpc, WsTerminalClearRpc, WsTerminalRestartRpc, WsTerminalCloseRpc, WsSubscribeTerminalEventsRpc, WsSubscribeTerminalMetadataRpc, WsPreviewOpenRpc, WsPreviewNavigateRpc, WsPreviewResizeRpc, WsPreviewRefreshRpc, WsPreviewCloseRpc, WsPreviewListRpc, WsPreviewReportStatusRpc, WsPreviewAutomationConnectRpc, WsPreviewAutomationRespondRpc, WsPreviewAutomationFocusHostRpc, WsSubscribePreviewEventsRpc, WsSubscribeDiscoveredLocalServersRpc, WsSubscribeServerConfigRpc, WsSubscribeServerLifecycleRpc, WsSubscribeAuthAccessRpc, WsTasksListRpc, WsTasksGetRpc, WsTasksCreateRpc, WsTasksUpdateRpc, WsTasksDeleteRpc, WsTasksStartThreadRpc, WsSubscribeTasksRpc, WsHubGetSyncStatusRpc, WsHubConnectRpc, WsHubDisconnectRpc, WsHubSetSyncModeRpc, WsHubSetShareModeRpc, WsHubMintTokenRpc, WsSkillsSyncRpc, WsSkillsPublishRpc, WsSkillsPublishAllRpc, WsSkillsUnpublishRpc, WsAssetsReadRpc, WsAssetsSaveRpc, WsAssetsDeleteRpc, WsAssetsCreateLocalRpc, WsAssetsRemoveLocalRpc, WsSkillRegistrySearchRpc, WsSkillRegistryFetchRpc, WsMcpListRpc, WsMcpSaveRpc, WsMcpRemoveRpc, WsMcpSetSecretRpc, WsMcpOAuthBeginRpc, WsMcpOAuthDisconnectRpc, WsTicketsResolveRpc, WsOrchestrationDispatchCommandRpc, WsOrchestrationGetTurnDiffRpc, WsOrchestrationGetFullThreadDiffRpc, WsOrchestrationGetArchivedShellSnapshotRpc, WsOrchestrationSubscribeShellRpc, WsOrchestrationSubscribeThreadRpc);
9414
9532
  //#endregion
9415
9533
  //#region ../../packages/shared/src/oauthScope.ts
9416
9534
  const OAUTH_SCOPE_TOKEN = /^[\u0021\u0023-\u005b\u005d-\u007e]+$/u;
@@ -9556,7 +9674,7 @@ function deriveAuthClientMetadata(input) {
9556
9674
  //#endregion
9557
9675
  //#region src/auth/EnvironmentAuthPolicy.ts
9558
9676
  var EnvironmentAuthPolicy = class extends Context.Service()("@p4code/cli/auth/EnvironmentAuthPolicy") {};
9559
- const make$73 = Effect.gen(function* () {
9677
+ const make$74 = Effect.gen(function* () {
9560
9678
  const config = yield* ServerConfig$1;
9561
9679
  const isRemoteReachable = isRemoteReachableHost(config.host);
9562
9680
  const policy = config.mode === "desktop" ? isRemoteReachable ? "remote-reachable" : "desktop-managed-local" : isRemoteReachable ? "remote-reachable" : "loopback-browser";
@@ -9574,7 +9692,7 @@ const make$73 = Effect.gen(function* () {
9574
9692
  };
9575
9693
  return EnvironmentAuthPolicy.of({ getDescriptor: () => Effect.succeed(descriptor).pipe(Effect.withSpan("EnvironmentAuthPolicy.getDescriptor")) });
9576
9694
  });
9577
- const layer$69 = Layer.effect(EnvironmentAuthPolicy, make$73);
9695
+ const layer$70 = Layer.effect(EnvironmentAuthPolicy, make$74);
9578
9696
  //#endregion
9579
9697
  //#region src/persistence/Errors.ts
9580
9698
  function summarizeSchemaIssue(issue) {
@@ -9755,7 +9873,7 @@ function toPersistenceSqlOrDecodeError$6(sqlOperation, decodeOperation, correlat
9755
9873
  cause
9756
9874
  });
9757
9875
  }
9758
- const make$72 = Effect.gen(function* () {
9876
+ const make$73 = Effect.gen(function* () {
9759
9877
  const sql = yield* SqlClient.SqlClient;
9760
9878
  const createSessionRow = SqlSchema.void({
9761
9879
  Request: CreateAuthSessionInput,
@@ -9889,7 +10007,7 @@ const make$72 = Effect.gen(function* () {
9889
10007
  setLastConnectedAt
9890
10008
  };
9891
10009
  });
9892
- const layer$68 = Layer.effect(AuthSessionRepository, make$72);
10010
+ const layer$69 = Layer.effect(AuthSessionRepository, make$73);
9893
10011
  //#endregion
9894
10012
  //#region src/auth/ServerSecretStore.ts
9895
10013
  const secretStoreErrorContext = {
@@ -9956,7 +10074,7 @@ const isSecretStoreError = Schema$1.is(SecretStoreError);
9956
10074
  const isPlatformError = (value) => Predicate.isTagged(value, "PlatformError");
9957
10075
  const isSecretAlreadyExistsError = (error) => "cause" in error && isPlatformError(error.cause) && error.cause.reason._tag === "AlreadyExists";
9958
10076
  var ServerSecretStore = class extends Context.Service()("@p4code/cli/auth/ServerSecretStore") {};
9959
- const make$71 = Effect.gen(function* () {
10077
+ const make$72 = Effect.gen(function* () {
9960
10078
  const crypto = yield* Crypto.Crypto;
9961
10079
  const fileSystem = yield* FileSystem.FileSystem;
9962
10080
  const path = yield* Path.Path;
@@ -10026,7 +10144,7 @@ const make$71 = Effect.gen(function* () {
10026
10144
  remove
10027
10145
  });
10028
10146
  });
10029
- const layer$67 = Layer.effect(ServerSecretStore, make$71);
10147
+ const layer$68 = Layer.effect(ServerSecretStore, make$72);
10030
10148
  //#endregion
10031
10149
  //#region src/auth/SessionStore.ts
10032
10150
  var MalformedSessionTokenError = class extends Schema$1.TaggedErrorClass()("MalformedSessionTokenError", {}) {
@@ -10264,7 +10382,7 @@ function toAuthClientSession(input) {
10264
10382
  current: false
10265
10383
  };
10266
10384
  }
10267
- const make$70 = Effect.gen(function* () {
10385
+ const make$71 = Effect.gen(function* () {
10268
10386
  const crypto = yield* Crypto.Crypto;
10269
10387
  const serverConfig = yield* ServerConfig$1;
10270
10388
  const secretStore = yield* ServerSecretStore;
@@ -10578,7 +10696,7 @@ const make$70 = Effect.gen(function* () {
10578
10696
  markDisconnected
10579
10697
  });
10580
10698
  });
10581
- const layer$66 = Layer.effect(SessionStore, make$70).pipe(Layer.provideMerge(layer$68));
10699
+ const layer$67 = Layer.effect(SessionStore, make$71).pipe(Layer.provideMerge(layer$69));
10582
10700
  //#endregion
10583
10701
  //#region src/persistence/AuthPairingLinks.ts
10584
10702
  const AuthPairingLinkRecord = Schema$1.Struct({
@@ -10639,7 +10757,7 @@ function toPersistenceSqlOrDecodeError$5(sqlOperation, decodeOperation, correlat
10639
10757
  cause
10640
10758
  });
10641
10759
  }
10642
- const make$69 = Effect.gen(function* () {
10760
+ const make$70 = Effect.gen(function* () {
10643
10761
  const sql = yield* SqlClient.SqlClient;
10644
10762
  const createPairingLinkRow = SqlSchema.void({
10645
10763
  Request: CreateAuthPairingLinkInput,
@@ -10774,7 +10892,7 @@ const make$69 = Effect.gen(function* () {
10774
10892
  getByCredential
10775
10893
  };
10776
10894
  });
10777
- const layer$65 = Layer.effect(AuthPairingLinkRepository, make$69);
10895
+ const layer$66 = Layer.effect(AuthPairingLinkRepository, make$70);
10778
10896
  //#endregion
10779
10897
  //#region src/auth/PairingGrantStore.ts
10780
10898
  var UnknownBootstrapCredentialError = class extends Schema$1.TaggedErrorClass()("UnknownBootstrapCredentialError", {}) {
@@ -10869,7 +10987,7 @@ const DEV_STARTUP_TTL_HOURS = Duration.hours(24);
10869
10987
  const PAIRING_TOKEN_ALPHABET = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
10870
10988
  const PAIRING_TOKEN_LENGTH = 12;
10871
10989
  const PAIRING_TOKEN_REJECTION_LIMIT = Math.floor(256 / 32) * 32;
10872
- const make$68 = Effect.gen(function* () {
10990
+ const make$69 = Effect.gen(function* () {
10873
10991
  const crypto = yield* Crypto.Crypto;
10874
10992
  const config = yield* ServerConfig$1;
10875
10993
  const pairingLinks = yield* AuthPairingLinkRepository;
@@ -11067,7 +11185,7 @@ const make$68 = Effect.gen(function* () {
11067
11185
  consume
11068
11186
  });
11069
11187
  });
11070
- const layer$64 = Layer.effect(PairingGrantStore, make$68).pipe(Layer.provideMerge(layer$65));
11188
+ const layer$65 = Layer.effect(PairingGrantStore, make$69).pipe(Layer.provideMerge(layer$66));
11071
11189
  //#endregion
11072
11190
  //#region src/persistence/Migrations/001_OrchestrationEvents.ts
11073
11191
  var _001_OrchestrationEvents_default = Effect.gen(function* () {
@@ -12520,6 +12638,28 @@ var _039_ProjectionThreadsCompressMode_default = Effect.gen(function* () {
12520
12638
  `;
12521
12639
  });
12522
12640
  //#endregion
12641
+ //#region src/persistence/Migrations/040_TaskExternalRef.ts
12642
+ /**
12643
+ * The tracker issue a task mirrors, for tasks that did not start on this board.
12644
+ *
12645
+ * Stored as one JSON blob rather than three columns because nothing queries
12646
+ * inside it except the uniqueness check below, and a tracker's shape is not
12647
+ * ours to normalize - a second source will bring fields Linear does not have.
12648
+ *
12649
+ * The unique index is over the identifier alone, extracted from the JSON: it is
12650
+ * what stops a second paste of the same ticket from filing a duplicate task.
12651
+ * Partial, so the many rows with no external ref do not collide on NULL.
12652
+ */
12653
+ var _040_TaskExternalRef_default = Effect.gen(function* () {
12654
+ const sql = yield* SqlClient.SqlClient;
12655
+ yield* sql`ALTER TABLE tasks ADD COLUMN external_ref_json TEXT`;
12656
+ yield* sql`
12657
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_external_ref_identifier
12658
+ ON tasks(json_extract(external_ref_json, '$.identifier'))
12659
+ WHERE external_ref_json IS NOT NULL
12660
+ `;
12661
+ });
12662
+ //#endregion
12523
12663
  //#region src/persistence/Migrations.ts
12524
12664
  /**
12525
12665
  * MigrationsLive - Migration runner with inline loader
@@ -12735,6 +12875,11 @@ const migrationEntries = [
12735
12875
  39,
12736
12876
  "ProjectionThreadsCompressMode",
12737
12877
  _039_ProjectionThreadsCompressMode_default
12878
+ ],
12879
+ [
12880
+ 40,
12881
+ "TaskExternalRef",
12882
+ _040_TaskExternalRef_default
12738
12883
  ]
12739
12884
  ];
12740
12885
  const makeMigrationLoader = (throughId) => Migrator.fromRecord(Object.fromEntries(migrationEntries.filter(([id]) => throughId === void 0 || id <= throughId).map(([id, name, migration]) => [`${id}_${name}`, migration])));
@@ -12922,7 +13067,7 @@ function parseBearerToken(request) {
12922
13067
  const token = header.slice(7).trim();
12923
13068
  return token.length > 0 ? token : null;
12924
13069
  }
12925
- const make$67 = Effect.gen(function* () {
13070
+ const make$68 = Effect.gen(function* () {
12926
13071
  const policy = yield* EnvironmentAuthPolicy;
12927
13072
  const bootstrapCredentials = yield* PairingGrantStore;
12928
13073
  const sessions = yield* SessionStore;
@@ -13117,9 +13262,9 @@ const make$67 = Effect.gen(function* () {
13117
13262
  issueStartupPairingUrl
13118
13263
  });
13119
13264
  });
13120
- const layer$63 = Layer.effect(EnvironmentAuth, make$67).pipe(Layer.provideMerge(layer$64), Layer.provideMerge(layer$66), Layer.provideMerge(layer$69));
13121
- const storageLayer = Layer.mergeAll(layer$67, layerConfig);
13122
- const runtimeLayer = layer$63.pipe(Layer.provideMerge(storageLayer));
13265
+ const layer$64 = Layer.effect(EnvironmentAuth, make$68).pipe(Layer.provideMerge(layer$65), Layer.provideMerge(layer$67), Layer.provideMerge(layer$70));
13266
+ const storageLayer = Layer.mergeAll(layer$68, layerConfig);
13267
+ const runtimeLayer = layer$64.pipe(Layer.provideMerge(storageLayer));
13123
13268
  //#endregion
13124
13269
  //#region src/cliAuthFormat.ts
13125
13270
  const newline = "\n";
@@ -13874,7 +14019,7 @@ const runWithEnvironmentAuth = (flags, run, options) => Effect.gen(function* ()
13874
14019
  }
13875
14020
  return yield* Effect.gen(function* () {
13876
14021
  return yield* run(yield* EnvironmentAuth);
13877
- }).pipe(Effect.provide(Layer.mergeAll(runtimeLayer).pipe(Layer.provide(layer$70(config)), Layer.provide(Layer.succeed(References.MinimumLogLevel, minimumLogLevel)))));
14022
+ }).pipe(Effect.provide(Layer.mergeAll(runtimeLayer).pipe(Layer.provide(layer$71(config)), Layer.provide(Layer.succeed(References.MinimumLogLevel, minimumLogLevel)))));
13878
14023
  });
13879
14024
  const ttlFlag = Flag.string("ttl").pipe(Flag.withSchema(DurationFromString), Flag.withDescription("TTL, for example `5m`, `1h`, `30d`, or `15 minutes`."), Flag.optional);
13880
14025
  const jsonFlag = Flag.boolean("json").pipe(Flag.withDescription("Emit JSON instead of human-readable output."), Flag.withDefault(false));
@@ -14014,7 +14159,7 @@ const DEFAULT_LIMITS = {
14014
14159
  windowMillis: FAILURE_WINDOW_MS,
14015
14160
  blockMillis: BLOCK_DURATION_MS
14016
14161
  };
14017
- const make$66 = Effect.fn("HubAuthThrottle.make")(function* (limits = DEFAULT_LIMITS) {
14162
+ const make$67 = Effect.fn("HubAuthThrottle.make")(function* (limits = DEFAULT_LIMITS) {
14018
14163
  const state = yield* Ref.make(initialThrottleState);
14019
14164
  return HubAuthThrottle.of({
14020
14165
  shouldRefuse: Effect.gen(function* () {
@@ -14028,7 +14173,7 @@ const make$66 = Effect.fn("HubAuthThrottle.make")(function* (limits = DEFAULT_LI
14028
14173
  })
14029
14174
  });
14030
14175
  });
14031
- const layer$62 = Layer.effect(HubAuthThrottle, make$66());
14176
+ const layer$63 = Layer.effect(HubAuthThrottle, make$67());
14032
14177
  //#endregion
14033
14178
  //#region src/hub/HubAuth.ts
14034
14179
  /**
@@ -14342,7 +14487,10 @@ const DeleteTaskInput = Schema$1.Struct({ taskId: TaskId });
14342
14487
  var TaskRepository = class extends Context.Service()("@p4code/cli/persistence/Services/Tasks/TaskRepository") {};
14343
14488
  //#endregion
14344
14489
  //#region src/persistence/Layers/Tasks.ts
14345
- const TaskDbRow = Task.mapFields(Struct.assign({ labels: Schema$1.fromJsonString(Schema$1.Array(TaskLabel)) }));
14490
+ const TaskDbRow = Task.mapFields(Struct.assign({
14491
+ labels: Schema$1.fromJsonString(Schema$1.Array(TaskLabel)),
14492
+ externalRef: Schema$1.NullOr(Schema$1.fromJsonString(TaskExternalRef))
14493
+ }));
14346
14494
  /**
14347
14495
  * The `list` filter with every field normalized to a bound `null` rather than
14348
14496
  * an absent key. Each predicate is then `(:param IS NULL OR column = :param)`,
@@ -14362,6 +14510,7 @@ const TASK_COLUMNS = `
14362
14510
  project_id AS "projectId",
14363
14511
  repository_key AS "repositoryKey",
14364
14512
  thread_id AS "threadId",
14513
+ external_ref_json AS "externalRef",
14365
14514
  title,
14366
14515
  body,
14367
14516
  status,
@@ -14385,6 +14534,7 @@ const makeTaskRepository = Effect.gen(function* () {
14385
14534
  project_id,
14386
14535
  repository_key,
14387
14536
  thread_id,
14537
+ external_ref_json,
14388
14538
  title,
14389
14539
  body,
14390
14540
  status,
@@ -14401,6 +14551,7 @@ const makeTaskRepository = Effect.gen(function* () {
14401
14551
  ${row.projectId},
14402
14552
  ${row.repositoryKey},
14403
14553
  ${row.threadId},
14554
+ ${row.externalRef === null ? null : JSON.stringify(row.externalRef)},
14404
14555
  ${row.title},
14405
14556
  ${row.body},
14406
14557
  ${row.status},
@@ -14417,6 +14568,7 @@ const makeTaskRepository = Effect.gen(function* () {
14417
14568
  project_id = excluded.project_id,
14418
14569
  repository_key = excluded.repository_key,
14419
14570
  thread_id = excluded.thread_id,
14571
+ external_ref_json = excluded.external_ref_json,
14420
14572
  title = excluded.title,
14421
14573
  body = excluded.body,
14422
14574
  status = excluded.status,
@@ -14515,6 +14667,7 @@ const makeTaskRepository = Effect.gen(function* () {
14515
14667
  ...input.projectId !== void 0 ? { projectId: input.projectId } : {},
14516
14668
  ...input.repositoryKey !== void 0 ? { repositoryKey: input.repositoryKey } : {},
14517
14669
  ...input.threadId !== void 0 ? { threadId: input.threadId } : {},
14670
+ ...input.externalRef !== void 0 ? { externalRef: input.externalRef } : {},
14518
14671
  ...input.title !== void 0 ? { title: input.title } : {},
14519
14672
  ...input.body !== void 0 ? { body: input.body } : {},
14520
14673
  ...input.status !== void 0 ? { status: input.status } : {},
@@ -14686,6 +14839,7 @@ const createTaskRoute = HttpRouter.add("POST", "/tasks", respondToHubFailures(Ef
14686
14839
  projectId: input.projectId ?? null,
14687
14840
  repositoryKey: input.repositoryKey ?? null,
14688
14841
  threadId: input.threadId ?? null,
14842
+ externalRef: input.externalRef ?? null,
14689
14843
  title: input.title,
14690
14844
  body: input.body ?? "",
14691
14845
  status: input.status ?? "backlog",
@@ -14827,7 +14981,7 @@ const deleteAssetRoute = HttpRouter.add("DELETE", "/assets/:kind/:name", respond
14827
14981
  const outcome = yield* (yield* AgentAssetRepository).deleteByName(requested);
14828
14982
  return outcome._tag === "conflict" ? assetConflict(Option.getOrNull(outcome.current)) : HttpServerResponse.empty({ status: 204 });
14829
14983
  })));
14830
- const layer$61 = Layer.mergeAll(healthRoute, listTasksRoute, getTaskRoute, createTaskRoute, updateTaskRoute, deleteTaskRoute, listAssetsRoute, getAssetRoute, putAssetRoute, deleteAssetRoute);
14984
+ const layer$62 = Layer.mergeAll(healthRoute, listTasksRoute, getTaskRoute, createTaskRoute, updateTaskRoute, deleteTaskRoute, listAssetsRoute, getAssetRoute, putAssetRoute, deleteAssetRoute);
14831
14985
  //#endregion
14832
14986
  //#region src/hub/Migrations/001_Tasks.ts
14833
14987
  /**
@@ -14989,6 +15143,22 @@ var _005_TaskOrderKeys_default = Effect.gen(function* () {
14989
15143
  yield* (yield* SqlClient.SqlClient)`ALTER TABLE tasks ADD COLUMN order_key TEXT`;
14990
15144
  });
14991
15145
  //#endregion
15146
+ //#region src/hub/Migrations/006_TaskExternalRef.ts
15147
+ /**
15148
+ * The tracker issue a task mirrors, mirroring the environment server's
15149
+ * migration 040. The hub carries the column so a task filed against a Linear
15150
+ * ticket on one machine still reads as that ticket on another.
15151
+ */
15152
+ var _006_TaskExternalRef_default = Effect.gen(function* () {
15153
+ const sql = yield* SqlClient.SqlClient;
15154
+ yield* sql`ALTER TABLE tasks ADD COLUMN external_ref_json TEXT`;
15155
+ yield* sql`
15156
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_external_ref_identifier
15157
+ ON tasks(json_extract(external_ref_json, '$.identifier'))
15158
+ WHERE external_ref_json IS NOT NULL
15159
+ `;
15160
+ });
15161
+ //#endregion
14992
15162
  //#region src/hub/Migrations.ts
14993
15163
  /**
14994
15164
  * Hub migrations.
@@ -15024,6 +15194,11 @@ const hubMigrationEntries = [
15024
15194
  5,
15025
15195
  "TaskOrderKeys",
15026
15196
  _005_TaskOrderKeys_default
15197
+ ],
15198
+ [
15199
+ 6,
15200
+ "TaskExternalRef",
15201
+ _006_TaskExternalRef_default
15027
15202
  ]
15028
15203
  ];
15029
15204
  const hubMigrationLoader = Migrator.fromRecord(Object.fromEntries(hubMigrationEntries.map(([id, name, migration]) => [`${id}_${name}`, migration])));
@@ -15106,7 +15281,7 @@ const announce = Layer.effectDiscard(Effect.gen(function* () {
15106
15281
  });
15107
15282
  if (isRemoteReachableHost(config.host)) yield* Effect.logWarning("Hub is reachable beyond loopback. The bearer token is the only control — repeated auth failures are not rate limited.", { host: config.host });
15108
15283
  }));
15109
- const makeHubLayer = HttpRouter.serve(layer$61).pipe(Layer.provideMerge(announce), Layer.provideMerge(HubHttpServerLive), Layer.provideMerge(layer$62), Layer.provideMerge(TaskRepositoryLive), Layer.provideMerge(AgentAssetRepositoryLive), Layer.provideMerge(HubPersistenceLive));
15284
+ const makeHubLayer = HttpRouter.serve(layer$62).pipe(Layer.provideMerge(announce), Layer.provideMerge(HubHttpServerLive), Layer.provideMerge(layer$63), Layer.provideMerge(TaskRepositoryLive), Layer.provideMerge(AgentAssetRepositoryLive), Layer.provideMerge(HubPersistenceLive));
15110
15285
  const runHub = Layer.launch(makeHubLayer);
15111
15286
  //#endregion
15112
15287
  //#region src/atomicWrite.ts
@@ -15230,7 +15405,7 @@ function stripDefaultServerSettings(current, defaults) {
15230
15405
  }
15231
15406
  return Object.is(current, defaults) ? void 0 : current;
15232
15407
  }
15233
- const make$65 = Effect.gen(function* () {
15408
+ const make$66 = Effect.gen(function* () {
15234
15409
  const { settingsPath } = yield* ServerConfig$1;
15235
15410
  const fs = yield* FileSystem.FileSystem;
15236
15411
  const pathService = yield* Path.Path;
@@ -15451,7 +15626,7 @@ const make$65 = Effect.gen(function* () {
15451
15626
  }
15452
15627
  };
15453
15628
  });
15454
- const layer$60 = Layer.effect(ServerSettingsService, make$65);
15629
+ const layer$61 = Layer.effect(ServerSettingsService, make$66);
15455
15630
  //#endregion
15456
15631
  //#region src/pathExpansion.ts
15457
15632
  /**
@@ -15793,7 +15968,7 @@ function claudeEntryFromRegistration(registration) {
15793
15968
  };
15794
15969
  }
15795
15970
  var ClaudeMcpFiles = class extends Context.Service()("@p4code/cli/mcp/ClaudeMcpFiles") {};
15796
- const make$64 = Effect.gen(function* () {
15971
+ const make$65 = Effect.gen(function* () {
15797
15972
  const fileSystem = yield* FileSystem.FileSystem;
15798
15973
  const path = yield* Path.Path;
15799
15974
  const services = yield* Effect.context();
@@ -15858,7 +16033,7 @@ const make$64 = Effect.gen(function* () {
15858
16033
  removeProject: (projectDir, name) => removeAt(Effect.succeed(projectFile(projectDir)))(name)
15859
16034
  };
15860
16035
  });
15861
- const layer$59 = Layer.effect(ClaudeMcpFiles, make$64);
16036
+ const layer$60 = Layer.effect(ClaudeMcpFiles, make$65);
15862
16037
  Layer.succeed(ClaudeMcpFiles, {
15863
16038
  readUser: Effect.succeed([]),
15864
16039
  upsertUser: () => Effect.fail(new McpRegistryError({ detail: "No Claude config in tests." })),
@@ -15994,7 +16169,7 @@ const decodeClientRegistration = Schema$1.decodeUnknownExit(ClientRegistrationRe
15994
16169
  const decodeTokenResponse = Schema$1.decodeUnknownExit(TokenResponse);
15995
16170
  var McpOAuth = class extends Context.Service()("@p4code/cli/mcp/McpOAuth") {};
15996
16171
  const registryError = (detail) => new McpRegistryError({ detail });
15997
- const make$63 = Effect.gen(function* () {
16172
+ const make$64 = Effect.gen(function* () {
15998
16173
  const config = yield* ServerConfig$1;
15999
16174
  const secrets = yield* ServerSecretStore;
16000
16175
  const http = yield* HttpClient.HttpClient;
@@ -16314,7 +16489,7 @@ const make$63 = Effect.gen(function* () {
16314
16489
  accessTokenFor
16315
16490
  };
16316
16491
  });
16317
- const layer$58 = Layer.effect(McpOAuth, make$63);
16492
+ const layer$59 = Layer.effect(McpOAuth, make$64);
16318
16493
  Layer.succeed(McpOAuth, {
16319
16494
  statusFor: () => Effect.succeed(Option.none()),
16320
16495
  begin: () => Effect.fail(new McpRegistryError({ detail: "OAuth sign-in is not available." })),
@@ -16332,7 +16507,7 @@ const decodeRegistration$1 = Schema$1.decodeUnknownExit(RegistrationFromJson$1);
16332
16507
  const encodeRegistration = Schema$1.encodeSync(RegistrationFromJson$1);
16333
16508
  var McpRegistry = class extends Context.Service()("@p4code/cli/mcp/McpRegistry") {};
16334
16509
  const slotsOf = (registration) => registration.secrets ?? [];
16335
- const make$62 = Effect.gen(function* () {
16510
+ const make$63 = Effect.gen(function* () {
16336
16511
  const config = yield* ServerConfig$1;
16337
16512
  const secrets = yield* ServerSecretStore;
16338
16513
  const oauth = yield* McpOAuth;
@@ -16483,7 +16658,7 @@ const make$62 = Effect.gen(function* () {
16483
16658
  }).pipe(Effect.provide(services), Effect.catchCause((cause) => Effect.logWarning("mcp registry resolve failed", { cause }).pipe(Effect.as({}))))
16484
16659
  };
16485
16660
  });
16486
- const layer$57 = Layer.effect(McpRegistry, make$62);
16661
+ const layer$58 = Layer.effect(McpRegistry, make$63);
16487
16662
  //#endregion
16488
16663
  //#region src/sync/skillDirectory.ts
16489
16664
  /**
@@ -16862,7 +17037,7 @@ const formatHubLink = (input) => encodeStoredHubLink({
16862
17037
  shareMode: input.shareMode
16863
17038
  });
16864
17039
  const fromEnvironment = (environment) => validateHubLink(environment.P4CODE_HUB_URL ?? "", environment.P4CODE_HUB_TOKEN ?? "");
16865
- const make$61 = Effect.fn("HubLink.make")(function* (environment) {
17040
+ const make$62 = Effect.fn("HubLink.make")(function* (environment) {
16866
17041
  const secrets = yield* ServerSecretStore;
16867
17042
  const env = environment ?? process.env;
16868
17043
  const fromEnv = fromEnvironment(env);
@@ -16928,7 +17103,7 @@ const make$61 = Effect.fn("HubLink.make")(function* (environment) {
16928
17103
  })
16929
17104
  };
16930
17105
  });
16931
- const layer$56 = Layer.effect(HubLink, make$61());
17106
+ const layer$57 = Layer.effect(HubLink, make$62());
16932
17107
  //#endregion
16933
17108
  //#region src/sync/HubAssetClient.ts
16934
17109
  /**
@@ -16961,7 +17136,7 @@ const decodeAssetListPage = Schema$1.decodeUnknownEffect(AssetListPage);
16961
17136
  const decodeConflictBody$1 = Schema$1.decodeUnknownEffect(ConflictBody$1);
16962
17137
  const decodeAsset = Schema$1.decodeUnknownEffect(AgentAsset);
16963
17138
  var HubAssetClient = class extends Context.Service()("@p4code/cli/sync/HubAssetClient") {};
16964
- const make$60 = Effect.gen(function* () {
17139
+ const make$61 = Effect.gen(function* () {
16965
17140
  const http = yield* HttpClient.HttpClient;
16966
17141
  const link = yield* HubLink;
16967
17142
  const requireSettings = Effect.gen(function* () {
@@ -17043,7 +17218,7 @@ const make$60 = Effect.gen(function* () {
17043
17218
  remove
17044
17219
  };
17045
17220
  });
17046
- const layer$55 = Layer.effect(HubAssetClient, make$60);
17221
+ const layer$56 = Layer.effect(HubAssetClient, make$61);
17047
17222
  //#endregion
17048
17223
  //#region src/sync/mcpRegistrationFiles.ts
17049
17224
  /**
@@ -17618,7 +17793,7 @@ const EMPTY_REPORT = {
17618
17793
  unavailable: null
17619
17794
  };
17620
17795
  var AssetSync = class extends Context.Service()("@p4code/cli/sync/AssetSync") {};
17621
- const make$59 = Effect.gen(function* () {
17796
+ const make$60 = Effect.gen(function* () {
17622
17797
  const client = yield* HubAssetClient;
17623
17798
  const link = yield* HubLink;
17624
17799
  const settingsStore = yield* ServerSettingsService;
@@ -18331,7 +18506,7 @@ const make$59 = Effect.gen(function* () {
18331
18506
  removeLocal
18332
18507
  };
18333
18508
  });
18334
- const layer$54 = Layer.effect(AssetSync, make$59);
18509
+ const layer$55 = Layer.effect(AssetSync, make$60);
18335
18510
  //#endregion
18336
18511
  //#region src/provider/CompressPrompts.ts
18337
18512
  /**
@@ -18590,7 +18765,7 @@ const findAgentPreset = (requested) => {
18590
18765
  };
18591
18766
  //#endregion
18592
18767
  //#region src/cli/assets.ts
18593
- const SyncServicesLive = layer$54.pipe(Layer.provideMerge(layer$55), Layer.provideMerge(layer$56), Layer.provideMerge(layer$60.pipe(Layer.provide(layer$67))), Layer.provideMerge(layer$67), Layer.provideMerge(FetchHttpClient.layer));
18768
+ const SyncServicesLive = layer$55.pipe(Layer.provideMerge(layer$56), Layer.provideMerge(layer$57), Layer.provideMerge(layer$61.pipe(Layer.provide(layer$68))), Layer.provideMerge(layer$68), Layer.provideMerge(FetchHttpClient.layer));
18594
18769
  const runWithSync = (flags, run) => Effect.gen(function* () {
18595
18770
  const config = yield* resolveCliAuthConfig(flags, yield* GlobalFlag.LogLevel);
18596
18771
  return yield* Effect.gen(function* () {
@@ -18598,7 +18773,7 @@ const runWithSync = (flags, run) => Effect.gen(function* () {
18598
18773
  sync: yield* AssetSync,
18599
18774
  link: yield* HubLink
18600
18775
  });
18601
- }).pipe(Effect.provide(SyncServicesLive.pipe(Layer.provide(layer$70(config)), Layer.provide(Layer.succeed(References.MinimumLogLevel, "Error")))));
18776
+ }).pipe(Effect.provide(SyncServicesLive.pipe(Layer.provide(layer$71(config)), Layer.provide(Layer.succeed(References.MinimumLogLevel, "Error")))));
18602
18777
  });
18603
18778
  const STATE_LABEL = {
18604
18779
  synced: "synced",
@@ -23950,12 +24125,12 @@ const runProcessCore = Effect.fn("processRunner.runProcessCore")(function* (spaw
23950
24125
  stderrTruncated: stderr.truncated
23951
24126
  };
23952
24127
  });
23953
- const make$58 = Effect.fn("ProcessRunner.make")(function* () {
24128
+ const make$59 = Effect.fn("ProcessRunner.make")(function* () {
23954
24129
  const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
23955
24130
  const run = (input) => finalizeRunProcess(runProcessCore(spawner, input), input);
23956
24131
  return ProcessRunner.of({ run });
23957
24132
  });
23958
- const layer$53 = Layer.effect(ProcessRunner, make$58());
24133
+ const layer$54 = Layer.effect(ProcessRunner, make$59());
23959
24134
  //#endregion
23960
24135
  //#region src/project/RepositoryIdentityResolver.ts
23961
24136
  const DEFAULT_REPOSITORY_IDENTITY_CACHE_CAPACITY = 512;
@@ -24046,7 +24221,7 @@ const resolveRepositoryIdentityFromCacheKey = Effect.fn("RepositoryIdentityResol
24046
24221
  rootPath: cacheKey
24047
24222
  }) : null;
24048
24223
  });
24049
- const make$57 = Effect.fn("RepositoryIdentityResolver.make")(function* (options = {}) {
24224
+ const make$58 = Effect.fn("RepositoryIdentityResolver.make")(function* (options = {}) {
24050
24225
  const processRunner = yield* ProcessRunner;
24051
24226
  const repositoryIdentityCache = yield* Cache.makeWith((cacheKey) => resolveRepositoryIdentityFromCacheKey(cacheKey).pipe(Effect.provideService(ProcessRunner, processRunner)), {
24052
24227
  capacity: options.cacheCapacity ?? DEFAULT_REPOSITORY_IDENTITY_CACHE_CAPACITY,
@@ -24061,7 +24236,7 @@ const make$57 = Effect.fn("RepositoryIdentityResolver.make")(function* (options
24061
24236
  });
24062
24237
  return RepositoryIdentityResolver.of({ resolve });
24063
24238
  });
24064
- const layer$52 = Layer.effect(RepositoryIdentityResolver, make$57()).pipe(Layer.provide(layer$53));
24239
+ const layer$53 = Layer.effect(RepositoryIdentityResolver, make$58()).pipe(Layer.provide(layer$54));
24065
24240
  //#endregion
24066
24241
  //#region src/orchestration/Layers/ProjectionSnapshotQuery.ts
24067
24242
  const decodeReadModel = Schema$1.decodeUnknownEffect(OrchestrationReadModel);
@@ -25881,7 +26056,7 @@ function mergeWithDefaultKeybindings(custom) {
25881
26056
  * Keybindings - Service tag for keybinding configuration operations.
25882
26057
  */
25883
26058
  var Keybindings = class extends Context.Service()("@p4code/cli/keybindings") {};
25884
- const make$56 = Effect.gen(function* () {
26059
+ const make$57 = Effect.gen(function* () {
25885
26060
  const { keybindingsConfigPath } = yield* ServerConfig$1;
25886
26061
  const fs = yield* FileSystem.FileSystem;
25887
26062
  const path = yield* Path.Path;
@@ -26142,7 +26317,7 @@ const make$56 = Effect.gen(function* () {
26142
26317
  }))
26143
26318
  };
26144
26319
  });
26145
- const layer$51 = Layer.effect(Keybindings, make$56);
26320
+ const layer$52 = Layer.effect(Keybindings, make$57);
26146
26321
  //#endregion
26147
26322
  //#region src/process/externalLauncher.ts
26148
26323
  /**
@@ -26369,7 +26544,7 @@ const launchEditorProcess = Effect.fn("externalLauncher.launchEditorProcess")(fu
26369
26544
  cause
26370
26545
  }));
26371
26546
  });
26372
- const make$55 = Effect.gen(function* () {
26547
+ const make$56 = Effect.gen(function* () {
26373
26548
  const spawner = yield* ChildProcessSpawner$1.ChildProcessSpawner;
26374
26549
  const fileSystem = yield* FileSystem.FileSystem;
26375
26550
  const path = yield* Path.Path;
@@ -26380,7 +26555,7 @@ const make$55 = Effect.gen(function* () {
26380
26555
  launchEditor: (input) => provideCommandResolutionServices(Effect.flatMap(resolveEditorLaunch(input), (launch) => launchEditorProcess(launch).pipe(Effect.provideService(ChildProcessSpawner$1.ChildProcessSpawner, spawner))))
26381
26556
  });
26382
26557
  });
26383
- const layer$50 = Layer.effect(ExternalLauncher, make$55);
26558
+ const layer$51 = Layer.effect(ExternalLauncher, make$56);
26384
26559
  //#endregion
26385
26560
  //#region src/orchestration/Services/OrchestrationReactor.ts
26386
26561
  /**
@@ -26398,7 +26573,7 @@ var OrchestrationReactor = class extends Context.Service()("@p4code/cli/orchestr
26398
26573
  //#endregion
26399
26574
  //#region src/serverLifecycleEvents.ts
26400
26575
  var ServerLifecycleEvents = class extends Context.Service()("@p4code/cli/serverLifecycleEvents") {};
26401
- const make$54 = Effect.gen(function* () {
26576
+ const make$55 = Effect.gen(function* () {
26402
26577
  const pubsub = yield* PubSub.unbounded();
26403
26578
  const state = yield* Ref.make({
26404
26579
  sequence: 0,
@@ -26422,7 +26597,7 @@ const make$54 = Effect.gen(function* () {
26422
26597
  }
26423
26598
  };
26424
26599
  });
26425
- const layer$49 = Layer.effect(ServerLifecycleEvents, make$54);
26600
+ const layer$50 = Layer.effect(ServerLifecycleEvents, make$55);
26426
26601
  //#endregion
26427
26602
  //#region src/telemetry/Identify.ts
26428
26603
  const CodexAuthJsonSchema = Schema$1.Struct({ tokens: Schema$1.Struct({ account_id: Schema$1.String }) });
@@ -26595,7 +26770,7 @@ var AnalyticsService = class AnalyticsService extends Context.Service()("@p4code
26595
26770
  /** No-op layer for callers that intentionally disable telemetry. */
26596
26771
  static layerTest = Layer.succeed(AnalyticsService, inert);
26597
26772
  };
26598
- const make$53 = Effect.gen(function* () {
26773
+ const make$54 = Effect.gen(function* () {
26599
26774
  const telemetryConfig = yield* TelemetryEnvConfig;
26600
26775
  const posthogKey = telemetryConfig.posthogKey.trim();
26601
26776
  if (!telemetryConfig.enabled || posthogKey === "") return inert;
@@ -26665,7 +26840,7 @@ const make$53 = Effect.gen(function* () {
26665
26840
  flush
26666
26841
  });
26667
26842
  });
26668
- const layer$48 = Layer.effect(AnalyticsService, make$53);
26843
+ const layer$49 = Layer.effect(AnalyticsService, make$54);
26669
26844
  AnalyticsService.layerTest;
26670
26845
  //#endregion
26671
26846
  //#region src/service/pinnedRuntime.ts
@@ -27012,7 +27187,7 @@ var BootServiceInstallError = class extends Schema$1.TaggedErrorClass()("BootSer
27012
27187
  }
27013
27188
  };
27014
27189
  var BootService = class extends Context.Service()("@p4code/cli/service/bootService") {};
27015
- const make$52 = Effect.fn("cloud.boot_service.make")(function* (input) {
27190
+ const make$53 = Effect.fn("cloud.boot_service.make")(function* (input) {
27016
27191
  const hostExecPath = yield* HostProcessExecutablePath;
27017
27192
  const hostArguments = yield* HostProcessArguments;
27018
27193
  const host = input.host ?? {
@@ -27231,7 +27406,7 @@ const make$52 = Effect.fn("cloud.boot_service.make")(function* (input) {
27231
27406
  logPath
27232
27407
  });
27233
27408
  });
27234
- const layer$47 = (input) => Layer.effect(BootService, make$52(input));
27409
+ const layer$48 = (input) => Layer.effect(BootService, make$53(input));
27235
27410
  //#endregion
27236
27411
  //#region src/service/selfUpdate.ts
27237
27412
  /**
@@ -27306,7 +27481,7 @@ const resolveServerSelfUpdateCapability = Effect.fn("cloud.server_self_update.re
27306
27481
  return null;
27307
27482
  });
27308
27483
  var ServerSelfUpdate = class extends Context.Service()("@p4code/cli/service/selfUpdate/ServerSelfUpdate") {};
27309
- const make$51 = Effect.fn("cloud.server_self_update.make")(function* (options) {
27484
+ const make$52 = Effect.fn("cloud.server_self_update.make")(function* (options) {
27310
27485
  const serverConfig = yield* ServerConfig$1;
27311
27486
  const fs = yield* FileSystem.FileSystem;
27312
27487
  const path = yield* Path.Path;
@@ -27456,7 +27631,7 @@ const make$51 = Effect.fn("cloud.server_self_update.make")(function* (options) {
27456
27631
  });
27457
27632
  return ServerSelfUpdate.of({ update });
27458
27633
  });
27459
- const layer$46 = Layer.effect(ServerSelfUpdate, make$51()).pipe(Layer.provide(layer$53));
27634
+ const layer$47 = Layer.effect(ServerSelfUpdate, make$52()).pipe(Layer.provide(layer$54));
27460
27635
  //#endregion
27461
27636
  //#region src/environment/ServerEnvironmentLabel.ts
27462
27637
  const ServerEnvironmentLabelCommandProbe = Schema$1.Literals(["macos-computer-name", "linux-pretty-hostname"]);
@@ -27588,7 +27763,7 @@ function platformArch(architecture) {
27588
27763
  default: return "other";
27589
27764
  }
27590
27765
  }
27591
- const make$50 = Effect.gen(function* () {
27766
+ const make$51 = Effect.gen(function* () {
27592
27767
  const fileSystem = yield* FileSystem.FileSystem;
27593
27768
  const path = yield* Path.Path;
27594
27769
  const serverConfig = yield* ServerConfig$1;
@@ -27651,7 +27826,7 @@ const make$50 = Effect.gen(function* () {
27651
27826
  * state. It intentionally has no fallback Layer.succeed value: callers must
27652
27827
  * provide the external platform services and a ServerConfig.
27653
27828
  */
27654
- const layer$45 = Layer.effect(ServerEnvironment, make$50).pipe(Layer.provide(layer$53));
27829
+ const layer$46 = Layer.effect(ServerEnvironment, make$51).pipe(Layer.provide(layer$54));
27655
27830
  //#endregion
27656
27831
  //#region src/provider/Services/ProviderSessionReaper.ts
27657
27832
  var ProviderSessionReaper = class extends Context.Service()("@p4code/cli/provider/Services/ProviderSessionReaper") {};
@@ -28728,7 +28903,7 @@ const maybeOpenBrowser = (target) => Effect.gen(function* () {
28728
28903
  yield* (yield* ExternalLauncher).launchBrowser(target).pipe(Effect.catch(() => Effect.logInfo("browser auto-open unavailable", { hint: `Open ${target} in your browser.` })));
28729
28904
  });
28730
28905
  const runStartupPhase = (phase, effect) => effect.pipe(Effect.annotateSpans({ "startup.phase": phase }), Effect.withSpan(`server.startup.${phase}`));
28731
- const make$49 = Effect.gen(function* () {
28906
+ const make$50 = Effect.gen(function* () {
28732
28907
  const serverConfig = yield* ServerConfig$1;
28733
28908
  const keybindings = yield* Keybindings;
28734
28909
  const orchestrationReactor = yield* OrchestrationReactor;
@@ -28869,7 +29044,7 @@ const make$49 = Effect.gen(function* () {
28869
29044
  enqueueCommand: commandGate.enqueueCommand
28870
29045
  };
28871
29046
  });
28872
- const layer$44 = Layer.effect(ServerRuntimeStartup, make$49);
29047
+ const layer$45 = Layer.effect(ServerRuntimeStartup, make$50);
28873
29048
  //#endregion
28874
29049
  //#region src/serverRuntimeState.ts
28875
29050
  const PersistedServerRuntimeState = Schema$1.Struct({
@@ -29017,7 +29192,7 @@ function expandHomePath$2(input, path) {
29017
29192
  if (input.startsWith("~/") || input.startsWith("~\\")) return path.join(NodeOS.homedir(), input.slice(2));
29018
29193
  return input;
29019
29194
  }
29020
- const make$48 = Effect.gen(function* () {
29195
+ const make$49 = Effect.gen(function* () {
29021
29196
  const fileSystem = yield* FileSystem.FileSystem;
29022
29197
  const path = yield* Path.Path;
29023
29198
  const statWorkspaceRoot = Effect.fn("WorkspacePaths.statWorkspaceRoot")(function* (workspaceRoot, normalizedWorkspaceRoot, phase) {
@@ -29074,7 +29249,7 @@ const make$48 = Effect.gen(function* () {
29074
29249
  resolveRelativePathWithinRoot
29075
29250
  });
29076
29251
  });
29077
- const layer$43 = Layer.effect(WorkspacePaths, make$48);
29252
+ const layer$44 = Layer.effect(WorkspacePaths, make$49);
29078
29253
  //#endregion
29079
29254
  //#region src/cli/project.ts
29080
29255
  const isEnvironmentHttpCommonError = Schema$1.is(EnvironmentHttpCommonError);
@@ -29180,7 +29355,7 @@ const projectCommandUuid = Crypto.Crypto.pipe(Effect.flatMap((crypto) => crypto.
29180
29355
  operation: "generateProjectCommandId",
29181
29356
  cause
29182
29357
  })));
29183
- const ProjectCliRuntimeLive = Layer.mergeAll(layer$43, OrchestrationLayerLive.pipe(Layer.provideMerge(layer$52), Layer.provideMerge(layerConfig)));
29358
+ const ProjectCliRuntimeLive = Layer.mergeAll(layer$44, OrchestrationLayerLive.pipe(Layer.provideMerge(layer$53), Layer.provideMerge(layerConfig)));
29184
29359
  const PROJECT_CLI_LIVE_SERVER_TIMEOUT = Duration.seconds(1);
29185
29360
  const withProjectCliSessionToken = (environmentAuth, run) => Effect.acquireUseRelease(environmentAuth.issueSession({
29186
29361
  scopes: AuthAdministrativeScopes,
@@ -29271,7 +29446,7 @@ const runProjectMutation = Effect.fn("runProjectMutation")(function* (flags, run
29271
29446
  });
29272
29447
  yield* Console.log(output);
29273
29448
  }));
29274
- const offlineRuntimeLayer = ProjectCliRuntimeLive.pipe(Layer.provide(layer$70(config)), Layer.provide(Layer.succeed(References.MinimumLogLevel, minimumLogLevel)));
29449
+ const offlineRuntimeLayer = ProjectCliRuntimeLive.pipe(Layer.provide(layer$71(config)), Layer.provide(Layer.succeed(References.MinimumLogLevel, minimumLogLevel)));
29275
29450
  return yield* Effect.gen(function* () {
29276
29451
  const snapshot = yield* getOfflineSnapshot();
29277
29452
  const orchestrationEngine = yield* OrchestrationEngineService;
@@ -29282,7 +29457,7 @@ const runProjectMutation = Effect.fn("runProjectMutation")(function* (flags, run
29282
29457
  });
29283
29458
  yield* Console.log(output);
29284
29459
  }).pipe(Effect.provide(offlineRuntimeLayer));
29285
- }).pipe(Effect.provide(Layer.mergeAll(runtimeLayer, layer$43).pipe(Layer.provideMerge(FetchHttpClient.layer), Layer.provide(layer$70(config)), Layer.provide(Layer.succeed(References.MinimumLogLevel, minimumLogLevel)))));
29460
+ }).pipe(Effect.provide(Layer.mergeAll(runtimeLayer, layer$44).pipe(Layer.provideMerge(FetchHttpClient.layer), Layer.provide(layer$71(config)), Layer.provide(Layer.succeed(References.MinimumLogLevel, minimumLogLevel)))));
29286
29461
  });
29287
29462
  const projectAddCommand = Command.make("add", {
29288
29463
  ...projectLocationFlags,
@@ -29889,7 +30064,7 @@ const logP4ProjectFileLoadError = (error) => Effect.logWarning(error).pipe(Effec
29889
30064
  filePath: error.filePath,
29890
30065
  errorTag: error._tag
29891
30066
  }));
29892
- const make$47 = Effect.gen(function* () {
30067
+ const make$48 = Effect.gen(function* () {
29893
30068
  const fileSystem = yield* FileSystem.FileSystem;
29894
30069
  const path = yield* Path.Path;
29895
30070
  const load = Effect.fn("P4ProjectFileLoader.load")(function* (workspaceRoot) {
@@ -29910,7 +30085,7 @@ const make$47 = Effect.gen(function* () {
29910
30085
  });
29911
30086
  return P4ProjectFileLoader.of({ load });
29912
30087
  });
29913
- const layer$42 = Layer.effect(P4ProjectFileLoader, make$47);
30088
+ const layer$43 = Layer.effect(P4ProjectFileLoader, make$48);
29914
30089
  //#endregion
29915
30090
  //#region src/project/ProjectFaviconResolver.ts
29916
30091
  /**
@@ -29981,7 +30156,7 @@ function extractIconHref(source) {
29981
30156
  return null;
29982
30157
  }
29983
30158
  const optionOnNotFound$1 = (effect) => effect.pipe(Effect.map(Option.some), Effect.catchTags({ PlatformError: (error) => error.reason._tag === "NotFound" ? Effect.succeed(Option.none()) : Effect.fail(error) }));
29984
- const make$46 = Effect.gen(function* () {
30159
+ const make$47 = Effect.gen(function* () {
29985
30160
  const fileSystem = yield* FileSystem.FileSystem;
29986
30161
  const path = yield* Path.Path;
29987
30162
  const workspacePaths = yield* WorkspacePaths;
@@ -30050,7 +30225,7 @@ const make$46 = Effect.gen(function* () {
30050
30225
  });
30051
30226
  return ProjectFaviconResolver.of({ resolvePath });
30052
30227
  });
30053
- const layer$41 = Layer.effect(ProjectFaviconResolver, make$46);
30228
+ const layer$42 = Layer.effect(ProjectFaviconResolver, make$47);
30054
30229
  //#endregion
30055
30230
  //#region src/assets/AssetAccess.ts
30056
30231
  const ASSET_ROUTE_PREFIX = "/api/assets";
@@ -30303,10 +30478,10 @@ const resolveAsset = Effect.fn("AssetAccess.resolveAsset")(function* (token, rel
30303
30478
  //#endregion
30304
30479
  //#region src/observability/BrowserTraceCollector.ts
30305
30480
  var BrowserTraceCollector = class extends Context.Service()("@p4code/cli/observability/BrowserTraceCollector") {};
30306
- const make$45 = (sink) => BrowserTraceCollector.of({ record: (records) => Effect.sync(() => {
30481
+ const make$46 = (sink) => BrowserTraceCollector.of({ record: (records) => Effect.sync(() => {
30307
30482
  for (const record of records) sink.push(record);
30308
30483
  }) });
30309
- const layer$40 = (sink) => Layer.succeed(BrowserTraceCollector, make$45(sink));
30484
+ const layer$41 = (sink) => Layer.succeed(BrowserTraceCollector, make$46(sink));
30310
30485
  //#endregion
30311
30486
  //#region src/auth/http.ts
30312
30487
  const CREDENTIAL_RESPONSE_HEADERS = {
@@ -31269,7 +31444,7 @@ const NESTED_PAYLOAD_KEYS = [
31269
31444
  "operations"
31270
31445
  ];
31271
31446
  const MAX_COLLECT_DEPTH = 4;
31272
- function asRecord$3(value) {
31447
+ function asRecord$4(value) {
31273
31448
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
31274
31449
  }
31275
31450
  function pushChangedFilePath(target, value) {
@@ -31284,7 +31459,7 @@ function collectChangedFilePaths(value, target, depth) {
31284
31459
  for (const entry of value) collectChangedFilePaths(entry, target, depth + 1);
31285
31460
  return;
31286
31461
  }
31287
- const record = asRecord$3(value);
31462
+ const record = asRecord$4(value);
31288
31463
  if (!record) return;
31289
31464
  for (const field of CHANGED_FILE_FIELDS) pushChangedFilePath(target, record[field]);
31290
31465
  for (const nestedKey of NESTED_PAYLOAD_KEYS) if (nestedKey in record) collectChangedFilePaths(record[nestedKey], target, depth + 1);
@@ -31295,7 +31470,7 @@ function collectChangedFilePaths(value, target, depth) {
31295
31470
  */
31296
31471
  function collectActivityChangedFilePaths(payload) {
31297
31472
  const target = /* @__PURE__ */ new Set();
31298
- collectChangedFilePaths(asRecord$3(asRecord$3(payload)?.data), target, 0);
31473
+ collectChangedFilePaths(asRecord$4(asRecord$4(payload)?.data), target, 0);
31299
31474
  return target;
31300
31475
  }
31301
31476
  /**
@@ -33200,7 +33375,7 @@ const classifyNonZeroExit = (command, stderr) => {
33200
33375
  if (command === "gh" && (normalized.includes("could not resolve to a pullrequest") || normalized.includes("repository.pullrequest") || normalized.includes("no pull requests found for branch") || normalized.includes("pull request not found")) || command === "glab" && (normalized.includes("merge request not found") || normalized.includes("not found") || normalized.includes("404")) || command === "az" && normalized.includes("pull request") && (normalized.includes("not found") || normalized.includes("does not exist"))) return "not-found";
33201
33376
  return "command-failed";
33202
33377
  };
33203
- const make$44 = Effect.gen(function* () {
33378
+ const make$45 = Effect.gen(function* () {
33204
33379
  const processRunner = yield* ProcessRunner;
33205
33380
  const run = Effect.fn("VcsProcess.run")(function* (input) {
33206
33381
  const baseError = {
@@ -33257,7 +33432,7 @@ const make$44 = Effect.gen(function* () {
33257
33432
  });
33258
33433
  return VcsProcess.of({ run });
33259
33434
  });
33260
- const layer$39 = Layer.effect(VcsProcess, make$44).pipe(Layer.provide(layer$53));
33435
+ const layer$40 = Layer.effect(VcsProcess, make$45).pipe(Layer.provide(layer$54));
33261
33436
  //#endregion
33262
33437
  //#region src/vcs/VcsDriver.ts
33263
33438
  var VcsDriver = class extends Context.Service()("@p4code/cli/vcs/VcsDriver") {};
@@ -33708,12 +33883,12 @@ const makeVcsDriver = Effect.gen(function* () {
33708
33883
  const driver = yield* makeVcsDriverShape();
33709
33884
  return VcsDriver.of(driver);
33710
33885
  });
33711
- const make$43 = Effect.gen(function* () {
33886
+ const make$44 = Effect.gen(function* () {
33712
33887
  const git = yield* makeGitVcsDriverCore();
33713
33888
  return GitVcsDriver.of(git);
33714
33889
  });
33715
33890
  Layer.effect(VcsDriver, makeVcsDriver);
33716
- const layer$38 = Layer.effect(GitVcsDriver, make$43);
33891
+ const layer$39 = Layer.effect(GitVcsDriver, make$44);
33717
33892
  //#endregion
33718
33893
  //#region src/vcs/VcsProjectConfig.ts
33719
33894
  const ProjectVcsConfigJson = fromLenientJson(Schema$1.Struct({
@@ -33745,7 +33920,7 @@ const logVcsProjectConfigError = (error) => Effect.logWarning(error).pipe(Effect
33745
33920
  configPath: error.configPath,
33746
33921
  errorTag: error._tag
33747
33922
  }));
33748
- const make$42 = Effect.gen(function* () {
33923
+ const make$43 = Effect.gen(function* () {
33749
33924
  const fileSystem = yield* FileSystem.FileSystem;
33750
33925
  const path = yield* Path.Path;
33751
33926
  const findConfigPath = Effect.fn("VcsProjectConfig.findConfigPath")(function* (cwd) {
@@ -33786,7 +33961,7 @@ const make$42 = Effect.gen(function* () {
33786
33961
  });
33787
33962
  return VcsProjectConfig.of({ resolveKind });
33788
33963
  });
33789
- const layer$37 = Layer.effect(VcsProjectConfig, make$42);
33964
+ const layer$38 = Layer.effect(VcsProjectConfig, make$43);
33790
33965
  //#endregion
33791
33966
  //#region src/vcs/VcsDriverRegistry.ts
33792
33967
  const DETECTION_CACHE_CAPACITY = 2048;
@@ -33806,7 +33981,7 @@ function parseDetectionCacheKey(key) {
33806
33981
  cwd: key.slice(separatorIndex + 1)
33807
33982
  };
33808
33983
  }
33809
- const make$41 = Effect.gen(function* () {
33984
+ const make$42 = Effect.gen(function* () {
33810
33985
  const projectConfig = yield* VcsProjectConfig;
33811
33986
  const git = yield* makeVcsDriver;
33812
33987
  const drivers = { git };
@@ -33863,7 +34038,7 @@ const make$41 = Effect.gen(function* () {
33863
34038
  resolve
33864
34039
  });
33865
34040
  });
33866
- const layer$36 = Layer.effect(VcsDriverRegistry, make$41).pipe(Layer.provide(layer$37));
34041
+ const layer$37 = Layer.effect(VcsDriverRegistry, make$42).pipe(Layer.provide(layer$38));
33867
34042
  //#endregion
33868
34043
  //#region src/checkpointing/CheckpointStore.ts
33869
34044
  /**
@@ -33883,7 +34058,7 @@ const layer$36 = Layer.effect(VcsDriverRegistry, make$41).pipe(Layer.provide(lay
33883
34058
  */
33884
34059
  /** Service tag for checkpoint persistence and restore operations. */
33885
34060
  var CheckpointStore = class extends Context.Service()("@p4code/cli/checkpointing/CheckpointStore") {};
33886
- const make$40 = Effect.gen(function* () {
34061
+ const make$41 = Effect.gen(function* () {
33887
34062
  const vcsRegistry = yield* VcsDriverRegistry;
33888
34063
  const resolveCheckpoints = Effect.fn("CheckpointStore.resolveCheckpoints")(function* (operation, cwd) {
33889
34064
  const handle = yield* vcsRegistry.resolve({ cwd });
@@ -33922,7 +34097,7 @@ const make$40 = Effect.gen(function* () {
33922
34097
  deleteCheckpointRefs
33923
34098
  });
33924
34099
  });
33925
- const layer$35 = Layer.effect(CheckpointStore, make$40);
34100
+ const layer$36 = Layer.effect(CheckpointStore, make$41);
33926
34101
  //#endregion
33927
34102
  //#region src/checkpointing/CheckpointDiffQuery.ts
33928
34103
  /**
@@ -33944,7 +34119,7 @@ function buildTurnDiffResult(input, diff) {
33944
34119
  diff
33945
34120
  };
33946
34121
  }
33947
- const make$39 = Effect.gen(function* () {
34122
+ const make$40 = Effect.gen(function* () {
33948
34123
  const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
33949
34124
  const checkpointStore = yield* CheckpointStore;
33950
34125
  const threadActivities = yield* ProjectionThreadActivityRepository;
@@ -34110,7 +34285,7 @@ const make$39 = Effect.gen(function* () {
34110
34285
  getFullThreadDiff
34111
34286
  });
34112
34287
  });
34113
- const layer$34 = Layer.effect(CheckpointDiffQuery, make$39);
34288
+ const layer$35 = Layer.effect(CheckpointDiffQuery, make$40);
34114
34289
  //#endregion
34115
34290
  //#region ../../packages/shared/src/toolCategory.ts
34116
34291
  const TOOL_CATEGORY_TITLES = {
@@ -34379,22 +34554,22 @@ function classifyToolCategory(input) {
34379
34554
  if (normalized.includes("image")) return "image_view";
34380
34555
  return "tool";
34381
34556
  }
34382
- function asRecord$2(value) {
34557
+ function asRecord$3(value) {
34383
34558
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
34384
34559
  }
34385
34560
  /** Classify from a runtime item payload's `data` (`{ toolName, input }`). */
34386
34561
  function classifyToolCategoryFromToolData(data) {
34387
- const record = asRecord$2(data);
34562
+ const record = asRecord$3(data);
34388
34563
  const toolName = record?.toolName;
34389
34564
  if (typeof toolName !== "string" || toolName.trim().length === 0) return;
34390
34565
  return classifyToolCategory({
34391
34566
  toolName,
34392
- toolInput: asRecord$2(record?.input)
34567
+ toolInput: asRecord$3(record?.input)
34393
34568
  });
34394
34569
  }
34395
34570
  //#endregion
34396
34571
  //#region src/orchestration/ActivityPayloadProjection.ts
34397
- function asRecord$1(value) {
34572
+ function asRecord$2(value) {
34398
34573
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
34399
34574
  }
34400
34575
  function asTrimmedString$1(value) {
@@ -34417,7 +34592,7 @@ function collectChangedFiles(value, target, seen, depth) {
34417
34592
  }
34418
34593
  return;
34419
34594
  }
34420
- const record = asRecord$1(value);
34595
+ const record = asRecord$2(value);
34421
34596
  if (!record) return;
34422
34597
  pushChangedFile(target, seen, record.path);
34423
34598
  pushChangedFile(target, seen, record.filePath);
@@ -34443,13 +34618,13 @@ function collectChangedFiles(value, target, seen, depth) {
34443
34618
  }
34444
34619
  }
34445
34620
  function projectCommandData(data) {
34446
- const item = asRecord$1(data.item);
34621
+ const item = asRecord$2(data.item);
34447
34622
  if (!item) return;
34448
34623
  const projectedItem = {};
34449
34624
  if ("command" in item) projectedItem.command = item.command;
34450
- const input = asRecord$1(item.input);
34625
+ const input = asRecord$2(item.input);
34451
34626
  if (input && "command" in input) projectedItem.input = { command: input.command };
34452
- const result = asRecord$1(item.result);
34627
+ const result = asRecord$2(item.result);
34453
34628
  if (result && "command" in result) projectedItem.result = { command: result.command };
34454
34629
  return Object.keys(projectedItem).length > 0 ? projectedItem : void 0;
34455
34630
  }
@@ -34465,7 +34640,7 @@ function summarizeToolTextOutput(value) {
34465
34640
  return null;
34466
34641
  }
34467
34642
  function projectRawOutput(value) {
34468
- const rawOutput = asRecord$1(value);
34643
+ const rawOutput = asRecord$2(value);
34469
34644
  if (!rawOutput) return;
34470
34645
  if (typeof rawOutput.totalFiles === "number" && Number.isFinite(rawOutput.totalFiles)) return {
34471
34646
  totalFiles: rawOutput.totalFiles,
@@ -34487,14 +34662,14 @@ function projectRawOutput(value) {
34487
34662
  * the full payload in persistence and the event store.
34488
34663
  */
34489
34664
  function projectActivityPayload(activity) {
34490
- const payload = asRecord$1(activity.payload);
34491
- const data = asRecord$1(payload?.data);
34665
+ const payload = asRecord$2(activity.payload);
34666
+ const data = asRecord$2(payload?.data);
34492
34667
  if (!payload || !data || payload.itemType === "mcp_tool_call") return activity;
34493
34668
  const projectedData = {};
34494
34669
  const item = projectCommandData(data);
34495
34670
  if (item) projectedData.item = item;
34496
34671
  if ("command" in data) projectedData.command = data.command;
34497
- const input = asRecord$1(data.input);
34672
+ const input = asRecord$2(data.input);
34498
34673
  if (input && "command" in input) projectedData.input = { command: input.command };
34499
34674
  const changedFiles = [];
34500
34675
  collectChangedFiles(data, changedFiles, /* @__PURE__ */ new Set(), 0);
@@ -34521,7 +34696,7 @@ function projectActivityPayload(activity) {
34521
34696
  */
34522
34697
  function isResolvableContextWindowActivity(activity) {
34523
34698
  if (activity.kind !== "context-window.updated") return false;
34524
- const usedTokens = asRecord$1(activity.payload)?.usedTokens;
34699
+ const usedTokens = asRecord$2(activity.payload)?.usedTokens;
34525
34700
  return typeof usedTokens === "number" && Number.isFinite(usedTokens) && usedTokens >= 0;
34526
34701
  }
34527
34702
  /**
@@ -34537,7 +34712,7 @@ function isResolvableContextWindowActivity(activity) {
34537
34712
  * client.
34538
34713
  */
34539
34714
  function withoutContextWindowBreakdown$1(activity) {
34540
- const payload = asRecord$1(activity.payload);
34715
+ const payload = asRecord$2(activity.payload);
34541
34716
  if (!payload || payload.breakdown === void 0) return activity;
34542
34717
  const { breakdown: _breakdown, ...rest } = payload;
34543
34718
  return {
@@ -34552,7 +34727,7 @@ function dropStaleContextWindowActivities(activities) {
34552
34727
  const retainedIndexes = new Set(latestIndexByTurn.values());
34553
34728
  let breakdownIndex = null;
34554
34729
  for (const index of retainedIndexes) {
34555
- if (asRecord$1(activities[index].payload)?.breakdown === void 0) continue;
34730
+ if (asRecord$2(activities[index].payload)?.breakdown === void 0) continue;
34556
34731
  if (breakdownIndex === null || index > breakdownIndex) breakdownIndex = index;
34557
34732
  }
34558
34733
  return activities.flatMap((activity, index) => {
@@ -34680,6 +34855,7 @@ const buildTaskRow = (input, taskId, timestamp, repositoryKey = null) => ({
34680
34855
  projectId: input.projectId ?? null,
34681
34856
  repositoryKey: repositoryKey ?? input.repositoryKey ?? null,
34682
34857
  threadId: input.threadId ?? null,
34858
+ externalRef: input.externalRef ?? null,
34683
34859
  title: input.title,
34684
34860
  body: input.body ?? "",
34685
34861
  status: input.status ?? "backlog",
@@ -35272,7 +35448,7 @@ function makeUpdateState(input) {
35272
35448
  output: input.output ?? null
35273
35449
  };
35274
35450
  }
35275
- const make$38 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
35451
+ const make$39 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
35276
35452
  const providerRegistry = yield* ProviderRegistry;
35277
35453
  const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
35278
35454
  const httpClient = yield* HttpClient.HttpClient;
@@ -35387,7 +35563,7 @@ const make$38 = Effect.fn("ProviderMaintenanceRunner.make")(function* () {
35387
35563
  });
35388
35564
  return ProviderMaintenanceRunner.of({ updateProvider });
35389
35565
  });
35390
- const layer$33 = Layer.effect(ProviderMaintenanceRunner, make$38());
35566
+ const layer$34 = Layer.effect(ProviderMaintenanceRunner, make$39());
35391
35567
  //#endregion
35392
35568
  //#region src/provider/Services/ProviderInstanceRegistry.ts
35393
35569
  var ProviderInstanceRegistry = class extends Context.Service()("@p4code/cli/provider/Services/ProviderInstanceRegistry") {};
@@ -35411,11 +35587,11 @@ const makeTextGenerationFromRegistry = (registry) => TextGeneration.of({
35411
35587
  detail: "This provider does not report account usage."
35412
35588
  }))))
35413
35589
  });
35414
- const make$37 = Effect.gen(function* () {
35590
+ const make$38 = Effect.gen(function* () {
35415
35591
  const registry = yield* ProviderInstanceRegistry;
35416
35592
  return makeTextGenerationFromRegistry(registry);
35417
35593
  });
35418
- const layer$32 = Layer.effect(TextGeneration, make$37);
35594
+ const layer$33 = Layer.effect(TextGeneration, make$38);
35419
35595
  const SKILL_MANIFEST_FILENAME = "SKILL.md";
35420
35596
  /**
35421
35597
  * Split a catalogue id (`owner/repo/skill-name`) into its parts.
@@ -35524,7 +35700,7 @@ function toAssetFilePath(repositoryPath, root) {
35524
35700
  const REGISTRY_SEARCH_URL = "https://www.skills.sh/api/search";
35525
35701
  const GITHUB_API_URL = "https://api.github.com";
35526
35702
  const GITHUB_RAW_URL = "https://raw.githubusercontent.com";
35527
- const REQUEST_TIMEOUT_MS = 15e3;
35703
+ const REQUEST_TIMEOUT_MS$1 = 15e3;
35528
35704
  /** More than a person reads, few enough that the panel is a list and not a feed. */
35529
35705
  const MAX_SEARCH_RESULTS = 25;
35530
35706
  /**
@@ -35561,10 +35737,10 @@ const emptyFetch = (id, unavailable) => ({
35561
35737
  skipped: [],
35562
35738
  unavailable
35563
35739
  });
35564
- const make$36 = Effect.gen(function* () {
35740
+ const make$37 = Effect.gen(function* () {
35565
35741
  const http = yield* HttpClient.HttpClient;
35566
35742
  const request = Effect.fn("SkillRegistry.request")(function* (url) {
35567
- return yield* http.execute(HttpClientRequest.get(url).pipe(HttpClientRequest.setHeader("accept", "application/json"), HttpClientRequest.setHeader("user-agent", "p4code"))).pipe(Effect.timeout(REQUEST_TIMEOUT_MS));
35743
+ return yield* http.execute(HttpClientRequest.get(url).pipe(HttpClientRequest.setHeader("accept", "application/json"), HttpClientRequest.setHeader("user-agent", "p4code"))).pipe(Effect.timeout(REQUEST_TIMEOUT_MS$1));
35568
35744
  });
35569
35745
  const search = (query) => Effect.gen(function* () {
35570
35746
  const response = yield* request(`${REGISTRY_SEARCH_URL}?q=${encodeURIComponent(query)}`).pipe(Effect.orElseSucceed(() => null));
@@ -35632,7 +35808,309 @@ const make$36 = Effect.gen(function* () {
35632
35808
  fetch
35633
35809
  };
35634
35810
  });
35635
- const layer$31 = Layer.effect(SkillRegistry, make$36);
35811
+ const layer$32 = Layer.effect(SkillRegistry, make$37);
35812
+ //#endregion
35813
+ //#region ../../packages/shared/src/ticketReference.ts
35814
+ /**
35815
+ * Recognizing a tracker reference in text somebody pasted.
35816
+ *
35817
+ * Shared because both ends need the same answer: the composer decides whether a
35818
+ * paste is worth a round trip, and the server decides what to ask the tracker.
35819
+ * Two copies of this rule would differ, and the difference would read as "it
35820
+ * works on my machine but the paste does nothing".
35821
+ *
35822
+ * @module ticketReference
35823
+ */
35824
+ /**
35825
+ * A Linear issue URL, e.g.
35826
+ * `https://linear.app/omnicasa/issue/MOBILE-12262/haptic-feedback`.
35827
+ *
35828
+ * The workspace slug is what makes the URL unguessable from the identifier
35829
+ * alone, which is why a resolved ticket keeps the tracker's own URL rather than
35830
+ * rebuilding one.
35831
+ */
35832
+ const LINEAR_ISSUE_URL_PATTERN = /https?:\/\/(?:www\.)?linear\.app\/[^/\s]+\/issue\/([A-Za-z][A-Za-z0-9]*-\d+)/;
35833
+ /**
35834
+ * A bare identifier, e.g. `MOBILE-12262`.
35835
+ *
35836
+ * Anchored: only a paste that is *nothing but* an identifier counts. Scanning
35837
+ * prose for this shape would claim things that are not tickets - a date range,
35838
+ * a version, a p4code readable id like `P4-40` - and each false positive costs
35839
+ * a request and, worse, a wrong link.
35840
+ */
35841
+ const BARE_IDENTIFIER_PATTERN = /^([A-Za-z][A-Za-z0-9]*-\d+)$/;
35842
+ /**
35843
+ * The issue identifier a paste refers to, or `null` when it refers to none.
35844
+ *
35845
+ * Case is normalized up, the way every tracker prints it, so the same ticket
35846
+ * pasted two ways compares equal.
35847
+ */
35848
+ function parseTicketReference(text) {
35849
+ const trimmed = text.trim();
35850
+ if (trimmed.length === 0) return null;
35851
+ const url = LINEAR_ISSUE_URL_PATTERN.exec(trimmed);
35852
+ if (url?.[1] !== void 0) return url[1].toUpperCase();
35853
+ const bare = BARE_IDENTIFIER_PATTERN.exec(trimmed);
35854
+ if (bare?.[1] !== void 0) return bare[1].toUpperCase();
35855
+ return null;
35856
+ }
35857
+ //#endregion
35858
+ //#region src/mcp/McpToolClient.ts
35859
+ /**
35860
+ * Calling a tool on somebody else's MCP server.
35861
+ *
35862
+ * The rest of `apps/server/src/mcp` points the other way: it *exposes* p4code's
35863
+ * toolkit to an agent. This is the only place p4code is the client, and it
35864
+ * exists because one feature - recognizing a pasted ticket - needs an answer
35865
+ * before any agent turn runs, from a server the user has already registered.
35866
+ *
35867
+ * Deliberately not a general MCP client. There is no session reuse, no tool
35868
+ * listing, no notifications, no SSE stream held open: one request/response pair
35869
+ * per call, which is all streamable HTTP requires for a plain `tools/call`. A
35870
+ * real client belongs here only once something needs one.
35871
+ *
35872
+ * @module mcp/McpToolClient
35873
+ */
35874
+ /**
35875
+ * The version p4code speaks. Sent on `initialize` and echoed back as a header
35876
+ * on the follow-up calls, which is what the spec asks of a client that has
35877
+ * already negotiated.
35878
+ */
35879
+ const MCP_PROTOCOL_VERSION = "2025-06-18";
35880
+ const REQUEST_TIMEOUT_MS = 15e3;
35881
+ var McpToolCallError = class extends Schema$1.TaggedErrorClass()("McpToolCallError", {
35882
+ detail: Schema$1.String,
35883
+ status: Schema$1.NullOr(Schema$1.Number)
35884
+ }) {
35885
+ get message() {
35886
+ return this.detail;
35887
+ }
35888
+ };
35889
+ const unauthorized$1 = (status) => status === 401 || status === 403;
35890
+ /**
35891
+ * Read a JSON-RPC envelope out of a response that may be either JSON or SSE.
35892
+ *
35893
+ * A streamable-http server picks the encoding, and both are legal answers to a
35894
+ * single call. The SSE branch keeps the last `data:` payload that parses: a
35895
+ * server is free to emit progress notifications ahead of the result, and the
35896
+ * result is what a caller of this asked for.
35897
+ */
35898
+ const readEnvelope = (body) => {
35899
+ const direct = parseJsonObject(body);
35900
+ if (direct !== void 0) return direct;
35901
+ let latest;
35902
+ for (const line of body.split("\n")) {
35903
+ const trimmed = line.trim();
35904
+ if (!trimmed.startsWith("data:")) continue;
35905
+ const parsed = parseJsonObject(trimmed.slice(5).trim());
35906
+ if (parsed !== void 0) latest = parsed;
35907
+ }
35908
+ return latest;
35909
+ };
35910
+ const parseJsonObject = (text) => {
35911
+ if (text.length === 0) return void 0;
35912
+ try {
35913
+ const parsed = JSON.parse(text);
35914
+ return typeof parsed === "object" && parsed !== null ? parsed : void 0;
35915
+ } catch {
35916
+ return;
35917
+ }
35918
+ };
35919
+ const textOf = (content) => {
35920
+ if (!Array.isArray(content)) return "";
35921
+ const parts = [];
35922
+ for (const block of content) {
35923
+ if (typeof block !== "object" || block === null) continue;
35924
+ const record = block;
35925
+ if (record["type"] === "text" && typeof record["text"] === "string") parts.push(record["text"]);
35926
+ }
35927
+ return parts.join("\n");
35928
+ };
35929
+ /**
35930
+ * One `tools/call`, preceded by the `initialize` handshake the transport
35931
+ * requires.
35932
+ *
35933
+ * The handshake is not optional and not cacheable here: a server may hand out a
35934
+ * session id, and this holds no session state between calls. Two round trips
35935
+ * for one answer is the price of not keeping a connection open for a feature
35936
+ * that fires when somebody pastes something.
35937
+ */
35938
+ const callMcpTool = Effect.fn("McpToolClient.callMcpTool")(function* (input) {
35939
+ const http = yield* HttpClient$1.HttpClient;
35940
+ const post = (body, extraHeaders) => http.execute(HttpClientRequest$1.bodyJsonUnsafe(HttpClientRequest$1.setHeaders(HttpClientRequest$1.post(input.url), {
35941
+ ...input.headers,
35942
+ ...extraHeaders,
35943
+ accept: "application/json, text/event-stream"
35944
+ }), body)).pipe(Effect.timeout(REQUEST_TIMEOUT_MS), Effect.catchCause((cause) => Effect.fail(new McpToolCallError({
35945
+ detail: `Could not reach ${input.url}: ${String(cause)}`,
35946
+ status: null
35947
+ }))));
35948
+ const initialize = yield* post({
35949
+ jsonrpc: "2.0",
35950
+ id: 1,
35951
+ method: "initialize",
35952
+ params: {
35953
+ protocolVersion: MCP_PROTOCOL_VERSION,
35954
+ capabilities: {},
35955
+ clientInfo: {
35956
+ name: "p4code",
35957
+ version: "0.0.0"
35958
+ }
35959
+ }
35960
+ }, {});
35961
+ if (initialize.status >= 400) return yield* new McpToolCallError({
35962
+ detail: unauthorized$1(initialize.status) ? "The server rejected p4code's credentials." : `The server answered ${initialize.status} to initialize.`,
35963
+ status: initialize.status
35964
+ });
35965
+ const sessionId = initialize.headers["mcp-session-id"];
35966
+ const sessionHeaders = {
35967
+ "mcp-protocol-version": MCP_PROTOCOL_VERSION,
35968
+ ...sessionId === void 0 ? {} : { "mcp-session-id": sessionId }
35969
+ };
35970
+ yield* post({
35971
+ jsonrpc: "2.0",
35972
+ method: "notifications/initialized"
35973
+ }, sessionHeaders).pipe(Effect.ignore);
35974
+ const response = yield* post({
35975
+ jsonrpc: "2.0",
35976
+ id: 2,
35977
+ method: "tools/call",
35978
+ params: {
35979
+ name: input.toolName,
35980
+ arguments: input.arguments
35981
+ }
35982
+ }, sessionHeaders);
35983
+ const body = yield* response.text.pipe(Effect.catchCause(() => Effect.succeed("")));
35984
+ if (response.status >= 400) return yield* new McpToolCallError({
35985
+ detail: unauthorized$1(response.status) ? "The server rejected p4code's credentials." : `The server answered ${response.status} to ${input.toolName}.`,
35986
+ status: response.status
35987
+ });
35988
+ const envelope = readEnvelope(body);
35989
+ if (envelope === void 0) return yield* new McpToolCallError({
35990
+ detail: `The server's answer to ${input.toolName} was not JSON-RPC.`,
35991
+ status: response.status
35992
+ });
35993
+ const error = envelope["error"];
35994
+ if (typeof error === "object" && error !== null) {
35995
+ const detail = error["message"];
35996
+ return yield* new McpToolCallError({
35997
+ detail: typeof detail === "string" ? detail : `${input.toolName} failed.`,
35998
+ status: response.status
35999
+ });
36000
+ }
36001
+ const result = envelope["result"];
36002
+ if (typeof result !== "object" || result === null) return yield* new McpToolCallError({
36003
+ detail: `${input.toolName} returned no result.`,
36004
+ status: response.status
36005
+ });
36006
+ const resultRecord = result;
36007
+ const text = textOf(resultRecord["content"]);
36008
+ if (resultRecord["isError"] === true) return yield* new McpToolCallError({
36009
+ detail: text.length > 0 ? text : `${input.toolName} reported an error.`,
36010
+ status: response.status
36011
+ });
36012
+ return {
36013
+ structuredContent: resultRecord["structuredContent"],
36014
+ text
36015
+ };
36016
+ });
36017
+ //#endregion
36018
+ //#region src/mcp/TicketResolver.ts
36019
+ /**
36020
+ * The registered server name a Linear ticket is resolved through.
36021
+ *
36022
+ * Matched by name rather than by URL: the name is what the user typed in
36023
+ * Settings and what every other surface calls it, and a workspace may reach
36024
+ * Linear through a proxy URL that no pattern here would recognize.
36025
+ */
36026
+ const LINEAR_SERVER_NAME = "linear";
36027
+ /** Linear's own tool for reading one issue. */
36028
+ const LINEAR_GET_ISSUE_TOOL = "get_issue";
36029
+ var TicketResolver = class extends Context.Service()("@p4code/cli/mcp/TicketResolver") {};
36030
+ const stringField$1 = (record, key) => {
36031
+ const value = record[key];
36032
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
36033
+ };
36034
+ const asRecord$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
36035
+ /**
36036
+ * Find the issue inside whatever the tool returned.
36037
+ *
36038
+ * MCP leaves the shape of a tool result to the tool, so this accepts the three
36039
+ * arrangements in the wild - the structured payload itself, that payload with
36040
+ * the issue nested one level down, or a text block that happens to be JSON -
36041
+ * rather than assuming the one Linear happens to send today.
36042
+ */
36043
+ const readIssue = (result) => {
36044
+ const structured = asRecord$1(result.structuredContent);
36045
+ if (structured !== void 0) {
36046
+ const nested = asRecord$1(structured["issue"]);
36047
+ if (nested !== void 0) return nested;
36048
+ if (stringField$1(structured, "url") !== void 0) return structured;
36049
+ }
36050
+ try {
36051
+ const parsed = JSON.parse(result.text);
36052
+ const record = asRecord$1(parsed);
36053
+ if (record === void 0) return structured;
36054
+ return asRecord$1(record["issue"]) ?? record;
36055
+ } catch {
36056
+ return structured;
36057
+ }
36058
+ };
36059
+ const make$36 = Effect.gen(function* () {
36060
+ const registry = yield* McpRegistry;
36061
+ const oauth = yield* McpOAuth;
36062
+ const http = yield* HttpClient$1.HttpClient;
36063
+ return { resolve: Effect.fn("TicketResolver.resolve")(function* (reference) {
36064
+ const identifier = parseTicketReference(reference);
36065
+ if (identifier === null) return yield* new TicketResolveError({
36066
+ reason: "not_found",
36067
+ detail: `"${reference}" does not look like a ticket reference.`
36068
+ });
36069
+ const server = (yield* registry.list).find((candidate) => candidate.registration.name.toLowerCase() === LINEAR_SERVER_NAME && candidate.registration.enabled);
36070
+ if (server === void 0 || server.registration.transport === "stdio") return yield* new TicketResolveError({
36071
+ reason: "not_configured",
36072
+ detail: "No Linear MCP server is registered on this machine. Add it in Settings to link tickets."
36073
+ });
36074
+ const registration = server.registration;
36075
+ const token = yield* oauth.accessTokenFor(registration);
36076
+ const headers = {
36077
+ ...registration.headers,
36078
+ ...Option.isSome(token) ? { authorization: `Bearer ${token.value}` } : {}
36079
+ };
36080
+ if (Option.isNone(token) && Object.keys(registration.headers ?? {}).length === 0) return yield* new TicketResolveError({
36081
+ reason: "not_authorized",
36082
+ detail: "Linear is registered but not signed in on this machine. Sign in from Settings."
36083
+ });
36084
+ const result = yield* callMcpTool({
36085
+ url: registration.url,
36086
+ headers,
36087
+ toolName: LINEAR_GET_ISSUE_TOOL,
36088
+ arguments: { id: identifier }
36089
+ }).pipe(Effect.provideService(HttpClient$1.HttpClient, http), Effect.mapError((error) => error.status === 401 || error.status === 403 ? new TicketResolveError({
36090
+ reason: "not_authorized",
36091
+ detail: "Linear rejected p4code's sign-in. Sign in again from Settings."
36092
+ }) : new TicketResolveError({
36093
+ reason: "unavailable",
36094
+ detail: error.detail
36095
+ })));
36096
+ const issue = readIssue(result);
36097
+ const url = issue === void 0 ? void 0 : stringField$1(issue, "url");
36098
+ const title = issue === void 0 ? void 0 : stringField$1(issue, "title");
36099
+ if (issue === void 0 || url === void 0 || title === void 0) return yield* new TicketResolveError({
36100
+ reason: "not_found",
36101
+ detail: `Linear returned nothing usable for ${identifier}.`
36102
+ });
36103
+ return {
36104
+ externalRef: {
36105
+ source: "linear",
36106
+ identifier: stringField$1(issue, "identifier") ?? identifier,
36107
+ url
36108
+ },
36109
+ title
36110
+ };
36111
+ }) };
36112
+ });
36113
+ const layer$31 = Layer.effect(TicketResolver, make$36);
35636
36114
  //#endregion
35637
36115
  //#region ../../packages/shared/src/KeyedCoalescingWorker.ts
35638
36116
  const makeKeyedCoalescingWorker = (options) => Effect.gen(function* () {
@@ -37722,7 +38200,7 @@ const makeWithOptions$1 = Effect.fn("TerminalManager.makeWithOptions")(function*
37722
38200
  subscribeMetadata
37723
38201
  });
37724
38202
  });
37725
- const layer$29 = Layer.effect(TerminalManager, make$34()).pipe(Layer.provide(layer$53));
38203
+ const layer$29 = Layer.effect(TerminalManager, make$34()).pipe(Layer.provide(layer$54));
37726
38204
  //#endregion
37727
38205
  //#region src/mcp/McpInvocationContext.ts
37728
38206
  var McpInvocationContext = class extends Context.Service()("@p4code/cli/mcp/McpInvocationContext") {};
@@ -44802,6 +45280,7 @@ const RPC_REQUIRED_SCOPE = /* @__PURE__ */ new Map([
44802
45280
  [WS_METHODS.tasksUpdate, AuthOrchestrationOperateScope],
44803
45281
  [WS_METHODS.tasksDelete, AuthOrchestrationOperateScope],
44804
45282
  [WS_METHODS.tasksStartThread, AuthOrchestrationOperateScope],
45283
+ [WS_METHODS.ticketsResolve, AuthOrchestrationReadScope],
44805
45284
  [WS_METHODS.subscribeTasks, AuthOrchestrationReadScope],
44806
45285
  [WS_METHODS.hubGetSyncStatus, AuthOrchestrationReadScope],
44807
45286
  [WS_METHODS.hubConnect, AuthOrchestrationOperateScope],
@@ -44956,6 +45435,7 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker) => WsRpcGroup.t
44956
45435
  const mcpOAuth = yield* McpOAuth;
44957
45436
  const claudeMcpFiles = yield* ClaudeMcpFiles;
44958
45437
  const skillRegistry = yield* SkillRegistry;
45438
+ const ticketResolver = yield* TicketResolver;
44959
45439
  const listMcpServersEverywhere = Effect.gen(function* () {
44960
45440
  const servers = [...yield* mcpRegistry.list];
44961
45441
  const projectRows = yield* projectionProjects.listAll().pipe(Effect.map((rows) => rows.filter((row) => row.deletedAt === null)), Effect.orElseSucceed(() => []));
@@ -45502,6 +45982,13 @@ const makeWsRpcLayer = (currentSession, previewAutomationBroker) => WsRpcGroup.t
45502
45982
  threadId
45503
45983
  };
45504
45984
  }), { "rpc.aggregate": "tasks" }),
45985
+ /**
45986
+ * What a pasted reference is, straight from the tracker.
45987
+ *
45988
+ * Nothing is written here: the client decides whether the answer
45989
+ * becomes a task, so an accidental paste costs one request and no row.
45990
+ */
45991
+ [WS_METHODS.ticketsResolve]: ({ reference }) => observeRpcEffect$1(WS_METHODS.ticketsResolve, ticketResolver.resolve(reference), { "rpc.aggregate": "tickets" }),
45505
45992
  [WS_METHODS.subscribeTasks]: (_input) => observeRpcStreamEffect$1(WS_METHODS.subscribeTasks, Effect.succeed(taskRepository.streamWithSnapshot.pipe(Stream.catch((cause) => Stream.fromEffect(toTaskStoreError("tasks.subscribe")(cause))))), { "rpc.aggregate": "tasks" }),
45506
45993
  [WS_METHODS.hubGetSyncStatus]: (_input) => observeRpcEffect$1(WS_METHODS.hubGetSyncStatus, assetSync.status, { "rpc.aggregate": "hub" }),
45507
45994
  [WS_METHODS.hubConnect]: (input) => observeRpcEffect$1(WS_METHODS.hubConnect, hubLink.connect(input).pipe(Effect.mapError((cause) => new HubLinkError({ detail: cause.message })), Effect.andThen(assetSync.status)), { "rpc.aggregate": "hub" }),
@@ -45769,7 +46256,7 @@ const websocketRpcRouteLayer = Layer.unwrap(Effect.gen(function* () {
45769
46256
  const serverAuth = yield* EnvironmentAuth;
45770
46257
  const sessions = yield* SessionStore;
45771
46258
  const session = yield* serverAuth.authenticateWebSocketUpgrade(request).pipe(Effect.catchIf(isServerAuthCredentialError, (error) => failEnvironmentAuthInvalid(serverAuthCredentialReason(error))), Effect.catchIf(isServerAuthInternalError, (error) => failEnvironmentInternal("internal_error", error)));
45772
- const rpcWebSocketHttpEffect = yield* RpcServer.toHttpEffectWebsocket(WsRpcGroup, { disableTracing: true }).pipe(Effect.provide(makeWsRpcLayer(session, previewAutomationBroker).pipe(Layer.provideMerge(RpcSerialization.layerJson), Layer.provide(layer$33), Layer.provide(Layer.succeed(ServerSelfUpdate, serverSelfUpdate)), Layer.provide(Layer.succeed(TaskRepository, taskRepository)), Layer.provide(Layer.succeed(ProjectionProjectRepository, projectionProjects)), Layer.provide(Layer.succeed(P4ProjectFileLoader, p4ProjectFileLoader)), Layer.provide(layer$5.pipe(Layer.provide(layer$14.pipe(Layer.provide(Layer.mergeAll(layer$22, layer$20, layer$18, layer$16)), Layer.provideMerge(layer$38), Layer.provide(layer$36.pipe(Layer.provide(layer$37))))), Layer.provide(layer$39))))));
46259
+ const rpcWebSocketHttpEffect = yield* RpcServer.toHttpEffectWebsocket(WsRpcGroup, { disableTracing: true }).pipe(Effect.provide(makeWsRpcLayer(session, previewAutomationBroker).pipe(Layer.provideMerge(RpcSerialization.layerJson), Layer.provide(layer$34), Layer.provide(Layer.succeed(ServerSelfUpdate, serverSelfUpdate)), Layer.provide(Layer.succeed(TaskRepository, taskRepository)), Layer.provide(Layer.succeed(ProjectionProjectRepository, projectionProjects)), Layer.provide(Layer.succeed(P4ProjectFileLoader, p4ProjectFileLoader)), Layer.provide(layer$5.pipe(Layer.provide(layer$14.pipe(Layer.provide(Layer.mergeAll(layer$22, layer$20, layer$18, layer$16)), Layer.provideMerge(layer$39), Layer.provide(layer$37.pipe(Layer.provide(layer$38))))), Layer.provide(layer$40))))));
45773
46260
  return yield* Effect.acquireUseRelease(sessions.markConnected(session.sessionId), () => rpcWebSocketHttpEffect, () => sessions.markDisconnected(session.sessionId));
45774
46261
  }).pipe(Effect.catchTags({
45775
46262
  EnvironmentAuthInvalidError: HttpServerRespondable.toResponse,
@@ -48093,7 +48580,7 @@ const makeOpenCodeRuntime = Effect.gen(function* () {
48093
48580
  };
48094
48581
  });
48095
48582
  var OpenCodeRuntime = class extends Context.Service()("@p4code/cli/provider/opencodeRuntime") {};
48096
- const OpenCodeRuntimeLive = Layer.effect(OpenCodeRuntime, makeOpenCodeRuntime).pipe(Layer.provide(layer$71));
48583
+ const OpenCodeRuntimeLive = Layer.effect(OpenCodeRuntime, makeOpenCodeRuntime).pipe(Layer.provide(layer$72));
48097
48584
  //#endregion
48098
48585
  //#region src/textGeneration/TextGenerationUtils.ts
48099
48586
  const isTextGenerationError$3 = Schema$1.is(TextGenerationError);
@@ -88537,7 +89024,7 @@ const ObservabilityLive = Layer.unwrap(Effect.gen(function* () {
88537
89024
  sink,
88538
89025
  ...delegate ? { delegate } : {}
88539
89026
  });
88540
- return Layer.mergeAll(Layer.succeed(Tracer.Tracer, tracer), layer$40(sink));
89027
+ return Layer.mergeAll(Layer.succeed(Tracer.Tracer, tracer), layer$41(sink));
88541
89028
  })).pipe(Layer.provide(OtlpExporter.layerFlusher), Layer.provideMerge(otlpSerializationLayer));
88542
89029
  const metricsLayer = config.otlpMetricsUrl === void 0 ? Layer.empty : OtlpMetrics.layer({
88543
89030
  url: config.otlpMetricsUrl,
@@ -88816,25 +89303,25 @@ const ReactorLayerLive = Layer.empty.pipe(Layer.provideMerge(OrchestrationReacto
88816
89303
  const ProviderSessionDirectoryLayerLive = ProviderSessionDirectoryLive.pipe(Layer.provide(layer$3));
88817
89304
  const ProviderLayerLive = ProviderServiceLive.pipe(Layer.provide(ProviderAdapterRegistryLive), Layer.provideMerge(ProviderSessionDirectoryLayerLive));
88818
89305
  const PersistenceLayerLive = Layer.empty.pipe(Layer.provideMerge(layerConfig));
88819
- const VcsDriverRegistryLayerLive = layer$36.pipe(Layer.provide(layer$37));
88820
- const SourceControlProviderRegistryLayerLive = layer$14.pipe(Layer.provide(Layer.mergeAll(layer$22, layer$20, layer$18, layer$16)), Layer.provideMerge(layer$38), Layer.provideMerge(VcsDriverRegistryLayerLive));
88821
- const GitManagerLayerLive = layer$13.pipe(Layer.provideMerge(layer$23), Layer.provideMerge(layer$38), Layer.provideMerge(SourceControlProviderRegistryLayerLive), Layer.provideMerge(layer$32));
88822
- const GitLayerLive = Layer.empty.pipe(Layer.provideMerge(GitManagerLayerLive), Layer.provideMerge(layer$38));
89306
+ const VcsDriverRegistryLayerLive = layer$37.pipe(Layer.provide(layer$38));
89307
+ const SourceControlProviderRegistryLayerLive = layer$14.pipe(Layer.provide(Layer.mergeAll(layer$22, layer$20, layer$18, layer$16)), Layer.provideMerge(layer$39), Layer.provideMerge(VcsDriverRegistryLayerLive));
89308
+ const GitManagerLayerLive = layer$13.pipe(Layer.provideMerge(layer$23), Layer.provideMerge(layer$39), Layer.provideMerge(SourceControlProviderRegistryLayerLive), Layer.provideMerge(layer$33));
89309
+ const GitLayerLive = Layer.empty.pipe(Layer.provideMerge(GitManagerLayerLive), Layer.provideMerge(layer$39));
88823
89310
  const GitWorkflowLayerLive = layer$12.pipe(Layer.provideMerge(VcsDriverRegistryLayerLive), Layer.provideMerge(GitLayerLive));
88824
- const SourceControlRepositoryServiceLayerLive = layer$4.pipe(Layer.provideMerge(layer$38), Layer.provideMerge(SourceControlProviderRegistryLayerLive));
88825
- const ReviewLayerLive = layer$9.pipe(Layer.provideMerge(layer$38), Layer.provideMerge(VcsDriverRegistryLayerLive));
88826
- const VcsLayerLive = Layer.empty.pipe(Layer.provideMerge(layer$37), Layer.provideMerge(VcsDriverRegistryLayerLive), Layer.provideMerge(layer$10.pipe(Layer.provide(VcsDriverRegistryLayerLive))), Layer.provideMerge(GitWorkflowLayerLive), Layer.provideMerge(ReviewLayerLive), Layer.provideMerge(SourceControlRepositoryServiceLayerLive), Layer.provideMerge(layer$11.pipe(Layer.provide(GitWorkflowLayerLive))));
88827
- const CheckpointingLayerLive = Layer.empty.pipe(Layer.provideMerge(layer$34), Layer.provideMerge(layer$35.pipe(Layer.provide(VcsDriverRegistryLayerLive))));
88828
- const PortScannerLayerLive = layer$30.pipe(Layer.provide(layer$53));
89311
+ const SourceControlRepositoryServiceLayerLive = layer$4.pipe(Layer.provideMerge(layer$39), Layer.provideMerge(SourceControlProviderRegistryLayerLive));
89312
+ const ReviewLayerLive = layer$9.pipe(Layer.provideMerge(layer$39), Layer.provideMerge(VcsDriverRegistryLayerLive));
89313
+ const VcsLayerLive = Layer.empty.pipe(Layer.provideMerge(layer$38), Layer.provideMerge(VcsDriverRegistryLayerLive), Layer.provideMerge(layer$10.pipe(Layer.provide(VcsDriverRegistryLayerLive))), Layer.provideMerge(GitWorkflowLayerLive), Layer.provideMerge(ReviewLayerLive), Layer.provideMerge(SourceControlRepositoryServiceLayerLive), Layer.provideMerge(layer$11.pipe(Layer.provide(GitWorkflowLayerLive))));
89314
+ const CheckpointingLayerLive = Layer.empty.pipe(Layer.provideMerge(layer$35), Layer.provideMerge(layer$36.pipe(Layer.provide(VcsDriverRegistryLayerLive))));
89315
+ const PortScannerLayerLive = layer$30.pipe(Layer.provide(layer$54));
88829
89316
  const TerminalLayerLive = layer$29.pipe(Layer.provide(PtyAdapterLive), Layer.provide(PortScannerLayerLive));
88830
89317
  const PreviewLayerLive = Layer.empty.pipe(Layer.provideMerge(layer$27), Layer.provideMerge(PortScannerLayerLive));
88831
- const WorkspaceEntriesLayerLive = layer$25.pipe(Layer.provide(layer$43));
88832
- const WorkspaceFileSystemLayerLive = layer$24.pipe(Layer.provide(layer$43), Layer.provide(WorkspaceEntriesLayerLive));
88833
- const WorkspaceLayerLive = Layer.mergeAll(layer$43, WorkspaceEntriesLayerLive, WorkspaceFileSystemLayerLive);
88834
- const ProjectFaviconResolverLayerLive = layer$41.pipe(Layer.provide(layer$43), Layer.provide(layer$42));
88835
- const AuthLayerLive = layer$63.pipe(Layer.provideMerge(PersistenceLayerLive), Layer.provide(layer$67));
89318
+ const WorkspaceEntriesLayerLive = layer$25.pipe(Layer.provide(layer$44));
89319
+ const WorkspaceFileSystemLayerLive = layer$24.pipe(Layer.provide(layer$44), Layer.provide(WorkspaceEntriesLayerLive));
89320
+ const WorkspaceLayerLive = Layer.mergeAll(layer$44, WorkspaceEntriesLayerLive, WorkspaceFileSystemLayerLive);
89321
+ const ProjectFaviconResolverLayerLive = layer$42.pipe(Layer.provide(layer$44), Layer.provide(layer$43));
89322
+ const AuthLayerLive = layer$64.pipe(Layer.provideMerge(PersistenceLayerLive), Layer.provide(layer$68));
88836
89323
  const ProviderRuntimeLayerLive = ProviderSessionReaperLive.pipe(Layer.provideMerge(ProviderLayerLive), Layer.provideMerge(OrchestrationLayerLive));
88837
- const RuntimeDependenciesLive = ReactorLayerLive.pipe(Layer.provideMerge(CheckpointingLayerLive), Layer.provideMerge(SourceControlProviderRegistryLayerLive), Layer.provideMerge(GitLayerLive), Layer.provideMerge(VcsLayerLive), Layer.provideMerge(ProviderRuntimeLayerLive), Layer.provideMerge(Layer.mergeAll(TerminalLayerLive, PreviewLayerLive)), Layer.provideMerge(PersistenceLayerLive), Layer.provideMerge(layer$51), Layer.provideMerge(ProviderRegistryLive), Layer.provideMerge(ProviderInstanceRegistryHydrationLive), Layer.provideMerge(ProviderEventLoggersLive), Layer.provideMerge(OpenCodeRuntimeLive), Layer.provideMerge(layer$60.pipe(Layer.provide(layer$67))), Layer.provideMerge(WorkspaceLayerLive), Layer.provideMerge(ProjectFaviconResolverLayerLive), Layer.provideMerge(layer$52), Layer.provideMerge(layer$45), Layer.provideMerge(AuthLayerLive), Layer.provideMerge(Layer.mergeAll(layer$57, layer$31).pipe(Layer.provideMerge(layer$58), Layer.provideMerge(layer$59))), Layer.provideMerge(layer$67)).pipe(Layer.provideMerge(layer$8), Layer.provideMerge(layer$7), Layer.provideMerge(layer$6), Layer.provideMerge(layer$48), Layer.provideMerge(layer$50), Layer.provideMerge(layer$49), Layer.provide(layer$71));
89324
+ const RuntimeDependenciesLive = ReactorLayerLive.pipe(Layer.provideMerge(CheckpointingLayerLive), Layer.provideMerge(SourceControlProviderRegistryLayerLive), Layer.provideMerge(GitLayerLive), Layer.provideMerge(VcsLayerLive), Layer.provideMerge(ProviderRuntimeLayerLive), Layer.provideMerge(Layer.mergeAll(TerminalLayerLive, PreviewLayerLive)), Layer.provideMerge(PersistenceLayerLive), Layer.provideMerge(layer$52), Layer.provideMerge(ProviderRegistryLive), Layer.provideMerge(ProviderInstanceRegistryHydrationLive), Layer.provideMerge(ProviderEventLoggersLive), Layer.provideMerge(OpenCodeRuntimeLive), Layer.provideMerge(layer$61.pipe(Layer.provide(layer$68))), Layer.provideMerge(WorkspaceLayerLive), Layer.provideMerge(ProjectFaviconResolverLayerLive), Layer.provideMerge(layer$53), Layer.provideMerge(layer$46), Layer.provideMerge(AuthLayerLive), Layer.provideMerge(layer$31.pipe(Layer.provideMerge(Layer.mergeAll(layer$58, layer$32).pipe(Layer.provideMerge(layer$59), Layer.provideMerge(layer$60))))), Layer.provideMerge(layer$68)).pipe(Layer.provideMerge(layer$8), Layer.provideMerge(layer$7), Layer.provideMerge(layer$6), Layer.provideMerge(layer$49), Layer.provideMerge(layer$51), Layer.provideMerge(layer$50), Layer.provide(layer$72));
88838
89325
  /**
88839
89326
  * Hub asset sync.
88840
89327
  *
@@ -88842,9 +89329,9 @@ const RuntimeDependenciesLive = ReactorLayerLive.pipe(Layer.provideMerge(Checkpo
88842
89329
  * not-configured shape, and every call reports that rather than failing — so
88843
89330
  * this costs a server with no hub nothing but a layer.
88844
89331
  */
88845
- const AssetSyncLive = layer$54.pipe(Layer.provideMerge(layer$55), Layer.provideMerge(layer$56));
88846
- const RuntimeServicesLive = layer$44.pipe(Layer.provideMerge(AssetSyncLive), Layer.provideMerge(RuntimeDependenciesLive));
88847
- const makeRoutesLayer = Layer.mergeAll(Layer.mergeAll(HttpApiBuilder.layer(EnvironmentHttpApi).pipe(Layer.provide(authHttpApiLayer), Layer.provide(orchestrationHttpApiLayer), Layer.provide(serverEnvironmentHttpApiLayer), Layer.provide(environmentAuthenticatedAuthLayer)), otlpTracesProxyRouteLayer, assetRouteLayer, mcpOAuthCallbackRouteLayer, staticAndDevRouteLayer, websocketRpcRouteLayer), layer.pipe(Layer.provide(layer$2))).pipe(Layer.provide(RoutedTaskRepositoryLive.pipe(Layer.provide(PersistenceLayerLive))), Layer.provide(ProjectionProjectRepositoryLive.pipe(Layer.provide(PersistenceLayerLive))), Layer.provide(layer$42), Layer.provide(layer$28), Layer.provide(layer$46), Layer.provide(browserApiCorsLayer), Layer.provide(httpCompressionLayer));
89332
+ const AssetSyncLive = layer$55.pipe(Layer.provideMerge(layer$56), Layer.provideMerge(layer$57));
89333
+ const RuntimeServicesLive = layer$45.pipe(Layer.provideMerge(AssetSyncLive), Layer.provideMerge(RuntimeDependenciesLive));
89334
+ const makeRoutesLayer = Layer.mergeAll(Layer.mergeAll(HttpApiBuilder.layer(EnvironmentHttpApi).pipe(Layer.provide(authHttpApiLayer), Layer.provide(orchestrationHttpApiLayer), Layer.provide(serverEnvironmentHttpApiLayer), Layer.provide(environmentAuthenticatedAuthLayer)), otlpTracesProxyRouteLayer, assetRouteLayer, mcpOAuthCallbackRouteLayer, staticAndDevRouteLayer, websocketRpcRouteLayer), layer.pipe(Layer.provide(layer$2))).pipe(Layer.provide(RoutedTaskRepositoryLive.pipe(Layer.provide(PersistenceLayerLive))), Layer.provide(ProjectionProjectRepositoryLive.pipe(Layer.provide(PersistenceLayerLive))), Layer.provide(layer$43), Layer.provide(layer$28), Layer.provide(layer$47), Layer.provide(browserApiCorsLayer), Layer.provide(httpCompressionLayer));
88848
89335
  const makeServerLayer = Layer.unwrap(Effect.gen(function* () {
88849
89336
  const config = yield* ServerConfig$1;
88850
89337
  yield* fixPath();
@@ -88887,7 +89374,7 @@ const makeServerLayer = Layer.unwrap(Effect.gen(function* () {
88887
89374
  cause,
88888
89375
  servePort: configured.servePort
88889
89376
  }))) : Effect.void)) : Layer.empty;
88890
- return Layer.mergeAll(HttpRouter.serve(makeRoutesLayer, { disableLogger: !config.logWebSocketEvents }), httpListeningLayer, runtimeStateLayer, tailscaleServeLayer).pipe(Layer.provideMerge(RuntimeServicesLive), Layer.provideMerge(HttpResponseCompressionLive), Layer.provideMerge(HttpServerLive), Layer.provide(ObservabilityLive), Layer.provideMerge(FetchHttpClient.layer), Layer.provideMerge(layer$39), Layer.provideMerge(PlatformServicesLive));
89377
+ return Layer.mergeAll(HttpRouter.serve(makeRoutesLayer, { disableLogger: !config.logWebSocketEvents }), httpListeningLayer, runtimeStateLayer, tailscaleServeLayer).pipe(Layer.provideMerge(RuntimeServicesLive), Layer.provideMerge(HttpResponseCompressionLive), Layer.provideMerge(HttpServerLive), Layer.provide(ObservabilityLive), Layer.provideMerge(FetchHttpClient.layer), Layer.provideMerge(layer$40), Layer.provideMerge(PlatformServicesLive));
88891
89378
  }));
88892
89379
  const runServer = Layer.launch(makeServerLayer);
88893
89380
  //#endregion
@@ -89049,11 +89536,11 @@ const reconcileWithNewBinary = Effect.fn("cli.selfUpdate.reconcileWithNewBinary"
89049
89536
  //#endregion
89050
89537
  //#region src/cli/service.ts
89051
89538
  const isBootServiceCommandError = Schema$1.is(BootServiceCommandError);
89052
- const bootServiceLayer = (config) => layer$47({
89539
+ const bootServiceLayer = (config) => layer$48({
89053
89540
  baseDir: config.baseDir,
89054
89541
  logsDir: config.logsDir,
89055
89542
  cliVersion: version
89056
- }).pipe(Layer.provide(layer$53));
89543
+ }).pipe(Layer.provide(layer$54));
89057
89544
  /** Install, update, or repair the service using the CLI version running this command. */
89058
89545
  const reconcileService = Effect.fn("cli.service.reconcile")(function* () {
89059
89546
  const service = yield* BootService;
@@ -89100,7 +89587,7 @@ const runServiceCommand = Effect.fn("cli.service.run")(function* (flags, run, pr
89100
89587
  const baseDirNotice = yield* describeNonDefaultBaseDir(config.baseDir);
89101
89588
  if (baseDirNotice !== null) yield* Console.error(baseDirNotice);
89102
89589
  if (prepare !== void 0) yield* prepare(config);
89103
- return yield* run.pipe(Effect.tapError((error) => isBootServiceCommandError(error) ? BootService.pipe(Effect.flatMap((service) => Console.error(`Details: ${service.logPath}`))) : Effect.void), Effect.provide(Layer.mergeAll(bootServiceLayer(config), layer$53)));
89590
+ return yield* run.pipe(Effect.tapError((error) => isBootServiceCommandError(error) ? BootService.pipe(Effect.flatMap((service) => Console.error(`Details: ${service.logPath}`))) : Effect.void), Effect.provide(Layer.mergeAll(bootServiceLayer(config), layer$54)));
89104
89591
  });
89105
89592
  /**
89106
89593
  * Options the installed unit carries, rather than ones this command consumes.
@@ -89254,7 +89741,7 @@ const serviceCommand = Command.make("service").pipe(Command.withDescription("Man
89254
89741
  ]));
89255
89742
  //#endregion
89256
89743
  //#region src/bin.ts
89257
- const CliRuntimeLayer = Layer.mergeAll(NodeServices.layer, layer$71, FetchHttpClient.layer);
89744
+ const CliRuntimeLayer = Layer.mergeAll(NodeServices.layer, layer$72, FetchHttpClient.layer);
89258
89745
  /**
89259
89746
  * Prints an update reminder before dispatching, at most once a day.
89260
89747
  *