dorkos 0.81.0 → 0.82.0

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 (81) hide show
  1. package/dist/bin/cli.js +973 -467
  2. package/dist/client/assets/{AboutPage-CG2PlGB9.js → AboutPage-WmtNTKyp.js} +1 -1
  3. package/dist/client/assets/{AppearancePage-uc6vrPjQ.js → AppearancePage-D7ZHuThu.js} +1 -1
  4. package/dist/client/assets/{BaseTanStackRouterDevtoolsPanel-B-iktbLX-CZ9OxU7F.js → BaseTanStackRouterDevtoolsPanel-B-iktbLX-wUJCR3vL.js} +1 -1
  5. package/dist/client/assets/{BlintzCanvas-C0dWt42q.js → BlintzCanvas-BXKUjnNQ.js} +1 -1
  6. package/dist/client/assets/{CanvasCsvContent-DpTj502y.js → CanvasCsvContent-BLAtnhdQ.js} +1 -1
  7. package/dist/client/assets/{CanvasFileContent-BfbMK0ME.js → CanvasFileContent-VogEwZeM.js} +2 -2
  8. package/dist/client/assets/{CanvasModel3dContent-BjkWZBVq.js → CanvasModel3dContent-DCTC7eOc.js} +2 -2
  9. package/dist/client/assets/{CodeMirrorDiff-BtkeZDXX.js → CodeMirrorDiff-Cpi43Atp.js} +1 -1
  10. package/dist/client/assets/{CodeMirrorEditor-C2mjcn0M.js → CodeMirrorEditor-CviERH82.js} +1 -1
  11. package/dist/client/assets/{ConnectionAccessLists-CrvGcp6D.js → ConnectionAccessLists-Be1b30nn.js} +1 -1
  12. package/dist/client/assets/{ConnectionsPage-C2q7w1vY.js → ConnectionsPage-BVN7GiuC.js} +1 -1
  13. package/dist/client/assets/{ConventionPage-CGoZt1nC.js → ConventionPage-Coim_h2z.js} +1 -1
  14. package/dist/client/assets/{FloatingTanStackRouterDevtools-CqogiFob-Dl7G5M5j.js → FloatingTanStackRouterDevtools-CqogiFob-lqp1rgj8.js} +1 -1
  15. package/dist/client/assets/HandlePage-DnzPN8N_.js +1 -0
  16. package/dist/client/assets/{LexicalField-CCu1Ihg3.js → LexicalField-DPe-aAXb.js} +1 -1
  17. package/dist/client/assets/{ManagesPage-c1KIJkFC.js → ManagesPage-BZS2TdZL.js} +1 -1
  18. package/dist/client/assets/{Model3dViewer-BO0fwX9g.js → Model3dViewer-qs0tZlVU.js} +1 -1
  19. package/dist/client/assets/NamePage-DyWqRDIe.js +1 -0
  20. package/dist/client/assets/{NotificationsPage-BVSSDb9i.js → NotificationsPage-gmiItsT0.js} +1 -1
  21. package/dist/client/assets/{PersonalityPopover-CI9kf81k.js → PersonalityPopover-Dej6dI7y.js} +1 -1
  22. package/dist/client/assets/PhotoPage-GtCoB8dK.js +1 -0
  23. package/dist/client/assets/{RoomsPage-B7s1XM1i.js → RoomsPage-3_HuXajd.js} +1 -1
  24. package/dist/client/assets/{RunsOnPopover-LTrQIz4S.js → RunsOnPopover-DbSoBFaL.js} +1 -1
  25. package/dist/client/assets/{SessionsPage-FLHcXJLg.js → SessionsPage-Dc_lqBom.js} +1 -1
  26. package/dist/client/assets/{SkillsPage-loa1-bcL.js → SkillsPage-C0qMUkgs.js} +1 -1
  27. package/dist/client/assets/{TasksPage-CjTt9J5n.js → TasksPage-DvzTPDnw.js} +1 -1
  28. package/dist/client/assets/{ToolsPage-DMnjLq2L.js → ToolsPage-Cwc96TTa.js} +1 -1
  29. package/dist/client/assets/{TopologyGraph-CRAGEuPI.js → TopologyGraph-C-BTnRXU.js} +2 -2
  30. package/dist/client/assets/{agent-browser-DH-qe6tt.js → agent-browser-DT3ABR4l.js} +1 -1
  31. package/dist/client/assets/{highlighted-body-KPVGNVTW-CKyNuC2a.js → highlighted-body-KPVGNVTW-CVFODbIg.js} +1 -1
  32. package/dist/client/assets/{index-BHz_iLMm.js → index-B3P6TTvD.js} +3 -3
  33. package/dist/client/assets/{index-CCa_zFfO.js → index-B8oHvyN5.js} +1 -1
  34. package/dist/client/assets/{index-DRBI-tjH.js → index-BUxNND2H.js} +1 -1
  35. package/dist/client/assets/{index-CoJiX2o7.js → index-BZaMgVdg.js} +1 -1
  36. package/dist/client/assets/{index-CWuLOWsu.js → index-BrgOWbRQ.js} +2 -2
  37. package/dist/client/assets/{index-Z0979U-2.js → index-BuU7EEtP.js} +1 -1
  38. package/dist/client/assets/{index-9FBdK--F.js → index-ByCzVYkU.js} +1 -1
  39. package/dist/client/assets/index-C08DUVQ4.css +1 -0
  40. package/dist/client/assets/{index-BaITIF12.js → index-CGqPFWQw.js} +1 -1
  41. package/dist/client/assets/{index-Cn5LkLHK.js → index-CN1plkKF.js} +1 -1
  42. package/dist/client/assets/{index-Criu5f4m.js → index-CXWMnEDK.js} +1 -1
  43. package/dist/client/assets/{index-UTvS0wz6.js → index-CaZw0EC7.js} +1 -1
  44. package/dist/client/assets/{index-B0rpOocp.js → index-Cca_q1vW.js} +1 -1
  45. package/dist/client/assets/{index-BGLRcYYE.js → index-CgakJfik.js} +1 -1
  46. package/dist/client/assets/{index-CgTvuqsz.js → index-ClmokM0M.js} +1 -1
  47. package/dist/client/assets/{index-CGYDEGb1.js → index-ClnyhFUL.js} +1 -1
  48. package/dist/client/assets/index-DDXrdlj0.js +1648 -0
  49. package/dist/client/assets/{index-hnccffr-.js → index-DEA1uIWn.js} +1 -1
  50. package/dist/client/assets/{index-D2P8UWWS.js → index-DF5k9E7k.js} +1 -1
  51. package/dist/client/assets/{index-DBsoxmLK.js → index-DGr90Ygi.js} +1 -1
  52. package/dist/client/assets/{index-D-nXANER.js → index-DIkpB_1y.js} +1 -1
  53. package/dist/client/assets/{index-CugRpUpy.js → index-DN8DYUEX.js} +1 -1
  54. package/dist/client/assets/{index-BVkt7309.js → index-D_gnDrw3.js} +1 -1
  55. package/dist/client/assets/{index-O1R1Ir-o.js → index-DbsvSNI-.js} +1 -1
  56. package/dist/client/assets/{index-37p1_k_N.js → index-DgjZhEr3.js} +1 -1
  57. package/dist/client/assets/{index-BmHCO7JA.js → index-Dh-3NGE9.js} +1 -1
  58. package/dist/client/assets/{index-Bq1ocT_z.js → index-DiFG9bwF.js} +1 -1
  59. package/dist/client/assets/{index-_r_3OCOV.js → index-DiFc1nSZ.js} +1 -1
  60. package/dist/client/assets/{index-CPiL-M1V.js → index-DjY4p5H5.js} +1 -1
  61. package/dist/client/assets/{index-0R0NT72V.js → index-Dm6W0lml.js} +1 -1
  62. package/dist/client/assets/{index-CT4uhPjz.js → index-J8BMKg6y.js} +1 -1
  63. package/dist/client/assets/{index-C_H8Na06.js → index-PRwgIfzy.js} +2 -2
  64. package/dist/client/assets/{index-DN2SO8dj.js → index-PrqHZbD1.js} +1 -1
  65. package/dist/client/assets/{index-BPl8DTOI.js → index-W25uMuZA.js} +1 -1
  66. package/dist/client/assets/{index-C6itZC0I.js → index-kzr7_3di.js} +1 -1
  67. package/dist/client/assets/{index-BhMgFrop.js → index-lciid4H8.js} +1 -1
  68. package/dist/client/assets/{index-BL-LFVsO.js → index-nEQI8fB2.js} +1 -1
  69. package/dist/client/assets/{room-files-source-BmK7_zzB.js → room-files-source-CSKgcbkn.js} +1 -1
  70. package/dist/client/assets/{soul-file-0ee-EflV.js → soul-file-BHeAw6R9.js} +1 -1
  71. package/dist/client/assets/{use-mesh-update-D1KVLTOA.js → use-mesh-update-BP_UXq60.js} +1 -1
  72. package/dist/client/assets/{use-personality-commit-KFutjy9j.js → use-personality-commit-DyJAMzzb.js} +1 -1
  73. package/dist/client/index.html +2 -2
  74. package/dist/server/index.js +28630 -24454
  75. package/dist/server/index.js.map +2 -2
  76. package/package.json +3 -3
  77. package/dist/client/assets/HandlePage-DbVA5ABk.js +0 -1
  78. package/dist/client/assets/NamePage-Cvksm2Vr.js +0 -1
  79. package/dist/client/assets/PhotoPage-DOvne6fS.js +0 -1
  80. package/dist/client/assets/index-D9FWq0Sm.css +0 -1
  81. package/dist/client/assets/index-DyAjYNxU.js +0 -1636
package/dist/bin/cli.js CHANGED
@@ -21239,7 +21239,7 @@ function settleLegacyAccountAlias(merged, patch) {
21239
21239
  const block = merged?.runtimes?.claudeCode;
21240
21240
  if (block && typeof block === "object") delete block.activeAccount;
21241
21241
  }
21242
- var DEFAULT_TRUST_WINDOW_MINUTES, MIN_TRUST_WINDOW_MINUTES, MAX_TRUST_WINDOW_MINUTES, ROOM_TURN_LIMIT_BOUNDS, MAX_TOTAL_TURNS_PER_HOUR_BOUNDS, ROOM_TURN_LIMIT_DEFAULTS, RELAY_TURN_CEILING_BOUNDS, RELAY_TURN_CEILING_DEFAULTS, SENSITIVE_CONFIG_KEYS, CREDENTIAL_REF_PATTERN, CredentialReferenceSchema, ONBOARDING_STEPS, OnboardingStepSchema, OnboardingStateSchema, ToursStateSchema, TOURS_DEFAULTS, DisplayNameSourceSchema, UserProfileSchema, USER_PROFILE_DEFAULTS, SidebarDisplayFilterSchema, SidebarItemRefSchema, SmartGroupRulesSchema, SidebarGroupShapeSchema, SidebarGroupSchema, SidebarSectionIdSchema, SidebarSectionPrefsSchema, SIDEBAR_SECTION_IDS, SidebarSectionsSchema, SidebarPrefsSchema, SIDEBAR_PREFS_DEFAULTS, ShapeUserPrefsSchema, SHAPE_USER_PREFS_DEFAULTS, StatusBarPinSchema, STATUS_BAR_PIN_KEYS, StatusBarPrefsSchema, STATUS_BAR_PREFS_DEFAULTS, ComposerPrefsSchema, COMPOSER_PREFS_DEFAULTS, EscalationDelaySchema, NotificationPrefsSchema, NOTIFICATION_PREFS_DEFAULTS, DEFAULT_AGENTS_DIRECTORY, RawMcpServerConfigSchema, ClaudeCodeAccountSchema, ClaudeCodeAccountsSchema, DefaultModelSchema, DefaultEffortSchema, DefaultTrustStopSchema, ClaudeCodeSettingsSchema, LoggingConfigSchema, UserConfigSchema, LOG_LEVEL_MAP, USER_CONFIG_DEFAULTS;
21242
+ var CommunityNavigationRefSchema, CommunityInstallationPathSchema, CommunityInstallationSearchScalarSchema, CommunityInstallationSearchValueSchema, CommunityInstallationDestinationSchema, CommunityNavigationDestinationSchema, CommunityNavigationOwnerPrefsSchema, CommunityNavigationPrefsSchema, DEFAULT_TRUST_WINDOW_MINUTES, MIN_TRUST_WINDOW_MINUTES, MAX_TRUST_WINDOW_MINUTES, ROOM_TURN_LIMIT_BOUNDS, MAX_TOTAL_TURNS_PER_HOUR_BOUNDS, ROOM_TURN_LIMIT_DEFAULTS, RELAY_TURN_CEILING_BOUNDS, RELAY_TURN_CEILING_DEFAULTS, SENSITIVE_CONFIG_KEYS, CREDENTIAL_REF_PATTERN, CredentialReferenceSchema, ONBOARDING_STEPS, OnboardingStepSchema, OnboardingStateSchema, ToursStateSchema, TOURS_DEFAULTS, DisplayNameSourceSchema, UserProfileSchema, USER_PROFILE_DEFAULTS, SidebarDisplayFilterSchema, SidebarItemRefSchema, SmartGroupRulesSchema, SidebarGroupShapeSchema, SidebarGroupSchema, SidebarSectionIdSchema, SidebarSectionPrefsSchema, SIDEBAR_SECTION_IDS, SidebarSectionsSchema, SidebarPrefsSchema, SIDEBAR_PREFS_DEFAULTS, ShapeUserPrefsSchema, SHAPE_USER_PREFS_DEFAULTS, StatusBarPinSchema, STATUS_BAR_PIN_KEYS, StatusBarPrefsSchema, STATUS_BAR_PREFS_DEFAULTS, ComposerPrefsSchema, COMPOSER_PREFS_DEFAULTS, EscalationDelaySchema, NotificationPrefsSchema, NOTIFICATION_PREFS_DEFAULTS, DEFAULT_AGENTS_DIRECTORY, RawMcpServerConfigSchema, ClaudeCodeAccountSchema, ClaudeCodeAccountsSchema, DefaultModelSchema, DefaultEffortSchema, DefaultTrustStopSchema, ClaudeCodeSettingsSchema, LoggingConfigSchema, UserConfigSchema, LOG_LEVEL_MAP, USER_CONFIG_DEFAULTS;
21243
21243
  var init_config_schema = __esm({
21244
21244
  "../shared/src/config-schema.ts"() {
21245
21245
  init_zod();
@@ -21249,6 +21249,66 @@ var init_config_schema = __esm({
21249
21249
  init_room_repo();
21250
21250
  init_runtime_environment_schema();
21251
21251
  init_runtime_environment_schema();
21252
+ CommunityNavigationRefSchema = external_exports.string().regex(/^[0-9A-Za-z][0-9A-Za-z_-]*$/, "A community ref must be path-safe");
21253
+ CommunityInstallationPathSchema = external_exports.enum([
21254
+ "/",
21255
+ "/activity",
21256
+ "/team",
21257
+ "/session",
21258
+ "/tasks",
21259
+ "/channels",
21260
+ "/workspaces",
21261
+ "/connections",
21262
+ "/marketplace",
21263
+ "/marketplace/sources",
21264
+ "/feedback-requests"
21265
+ ]);
21266
+ CommunityInstallationSearchScalarSchema = external_exports.union([
21267
+ external_exports.string(),
21268
+ external_exports.number(),
21269
+ external_exports.boolean(),
21270
+ external_exports.null()
21271
+ ]);
21272
+ CommunityInstallationSearchValueSchema = external_exports.union([
21273
+ CommunityInstallationSearchScalarSchema,
21274
+ external_exports.array(CommunityInstallationSearchScalarSchema).max(100)
21275
+ ]);
21276
+ CommunityInstallationDestinationSchema = external_exports.strictObject({
21277
+ path: CommunityInstallationPathSchema,
21278
+ search: external_exports.record(external_exports.string(), CommunityInstallationSearchValueSchema).default({})
21279
+ }).superRefine(({ search }, context2) => {
21280
+ if ("community" in search)
21281
+ context2.addIssue({
21282
+ code: "custom",
21283
+ path: ["search"],
21284
+ message: "A local installation destination cannot select Community authority"
21285
+ });
21286
+ if (JSON.stringify(search).length > 4096)
21287
+ context2.addIssue({
21288
+ code: "custom",
21289
+ path: ["search"],
21290
+ message: "Local installation search state is too large"
21291
+ });
21292
+ });
21293
+ CommunityNavigationDestinationSchema = external_exports.object({
21294
+ ref: CommunityNavigationRefSchema,
21295
+ roomId: external_exports.string().min(1).max(256),
21296
+ threadId: external_exports.string().min(1).max(256).nullable().default(null),
21297
+ scrollAnchorEntryId: external_exports.string().min(1).max(256).nullable().default(null)
21298
+ });
21299
+ CommunityNavigationOwnerPrefsSchema = external_exports.object({
21300
+ ownerKey: external_exports.string().min(1).max(256),
21301
+ installationDestination: CommunityInstallationDestinationSchema.default({
21302
+ path: "/",
21303
+ search: {}
21304
+ }),
21305
+ order: external_exports.array(CommunityNavigationRefSchema).max(100).default(() => []),
21306
+ destinations: external_exports.array(CommunityNavigationDestinationSchema).max(100).default(() => [])
21307
+ });
21308
+ CommunityNavigationPrefsSchema = external_exports.object({
21309
+ version: external_exports.literal(1).default(1),
21310
+ owners: external_exports.array(CommunityNavigationOwnerPrefsSchema).max(16).default(() => [])
21311
+ });
21252
21312
  DEFAULT_TRUST_WINDOW_MINUTES = 480;
21253
21313
  MIN_TRUST_WINDOW_MINUTES = 5;
21254
21314
  MAX_TRUST_WINDOW_MINUTES = 1440;
@@ -21783,6 +21843,11 @@ var init_config_schema = __esm({
21783
21843
  statusBar: StatusBarPrefsSchema.default(() => ({ pins: [] })),
21784
21844
  /** Person-scoped message-box preferences (DOR-948). */
21785
21845
  composer: ComposerPrefsSchema.default(() => ({ richText: true })),
21846
+ /** Owner-qualified Community order and remembered destinations; never draft content. */
21847
+ communityNavigation: CommunityNavigationPrefsSchema.default(() => ({
21848
+ version: 1,
21849
+ owners: []
21850
+ })),
21786
21851
  /**
21787
21852
  * When this person last read what Full autonomy means and said "don't ask
21788
21853
  * me again", as an ISO 8601 UTC string. `null` until they do, which is the
@@ -21867,6 +21932,7 @@ var init_config_schema = __esm({
21867
21932
  },
21868
21933
  statusBar: { pins: [] },
21869
21934
  composer: { richText: true },
21935
+ communityNavigation: { version: 1, owners: [] },
21870
21936
  autonomyAcknowledgedAt: null,
21871
21937
  // Both halves of the power-door answer. Declared here as well as per-field
21872
21938
  // because `conf` merges top-level defaults SHALLOWLY: the per-field default
@@ -25473,7 +25539,7 @@ import path2 from "path";
25473
25539
  import { fileURLToPath } from "url";
25474
25540
  function resolveVersion() {
25475
25541
  if (env2.DORKOS_VERSION_OVERRIDE) return env2.DORKOS_VERSION_OVERRIDE;
25476
- if (true) return "0.81.0";
25542
+ if (true) return "0.82.0";
25477
25543
  const pkgPath = path2.join(path2.dirname(fileURLToPath(import.meta.url)), "../../package.json");
25478
25544
  return JSON.parse(readFileSync(pkgPath, "utf-8")).version;
25479
25545
  }
@@ -26217,6 +26283,7 @@ __export(config_manager_exports, {
26217
26283
  retireToolOnlyReplies: () => retireToolOnlyReplies,
26218
26284
  scrubRetiredOnboardingSteps: () => scrubRetiredOnboardingSteps,
26219
26285
  seedA2aDisabled: () => seedA2aDisabled,
26286
+ seedCommunityNavigationPrefs: () => seedCommunityNavigationPrefs,
26220
26287
  seedDisplayNameSourceDefault: () => seedDisplayNameSourceDefault,
26221
26288
  seedFullPowerDecision: () => seedFullPowerDecision,
26222
26289
  seedHarnessAutoAdopt: () => seedHarnessAutoAdopt,
@@ -27126,6 +27193,15 @@ function seedRoomCanvasOps(store) {
27126
27193
  maxCanvasOpsPerTurn: USER_CONFIG_DEFAULTS.rooms.maxCanvasOpsPerTurn
27127
27194
  });
27128
27195
  }
27196
+ function seedCommunityNavigationPrefs(store) {
27197
+ const ui = store.get("ui");
27198
+ if (!ui || typeof ui !== "object" || Array.isArray(ui)) return;
27199
+ if ("communityNavigation" in ui) return;
27200
+ store.set("ui", {
27201
+ ...ui,
27202
+ communityNavigation: { version: 1, owners: [] }
27203
+ });
27204
+ }
27129
27205
  function tolerateRetiredSidebarKeys(ctx) {
27130
27206
  if (ctx.zodSchema === SidebarPrefsSchema) {
27131
27207
  const properties = ctx.jsonSchema.properties;
@@ -27710,6 +27786,12 @@ and your settings stay in the file you renamed.`;
27710
27786
  // `maxCanvasOpsPerTurn`, all of which this body preserves.
27711
27787
  "0.81.0": (store) => {
27712
27788
  retireToolOnlyReplies(store);
27789
+ },
27790
+ // 0.81.0 has merged (the second graduated experiment), so 0.82.0 is the next
27791
+ // key. This adds one nested preference block under `ui`; every older sibling
27792
+ // is preserved, and repeated execution leaves an existing owner history intact.
27793
+ "0.82.0": (store) => {
27794
+ seedCommunityNavigationPrefs(store);
27713
27795
  }
27714
27796
  };
27715
27797
  jsonSchemaFull = external_exports.toJSONSchema(UserConfigSchema, {
@@ -27974,7 +28056,7 @@ and your settings stay in the file you renamed.`;
27974
28056
  const floorBefore = this.standingGrantVoidFloor();
27975
28057
  this.write(key, value);
27976
28058
  this.stampStandingGrantVoidFloor(licensedBefore, floorBefore);
27977
- this.emitChange([key]);
28059
+ this.emitChange([key], [key]);
27978
28060
  }
27979
28061
  /**
27980
28062
  * Write one path, keeping any settings underneath it that belong to another
@@ -28055,10 +28137,10 @@ and your settings stay in the file you renamed.`;
28055
28137
  this.listeners.delete(listener);
28056
28138
  };
28057
28139
  }
28058
- /** Notify subscribers that the named top-level sections were just written. */
28059
- emitChange(sections) {
28140
+ /** Notify subscribers that the named sections, at the named key paths, were just written. */
28141
+ emitChange(sections, paths2) {
28060
28142
  if (this.listeners.size === 0) return;
28061
- const change = { sections };
28143
+ const change = { sections, paths: paths2 };
28062
28144
  for (const listener of this.listeners) {
28063
28145
  try {
28064
28146
  listener(change);
@@ -28077,7 +28159,7 @@ and your settings stay in the file you renamed.`;
28077
28159
  const floorBefore = this.standingGrantVoidFloor();
28078
28160
  this.write(key, value);
28079
28161
  this.stampStandingGrantVoidFloor(licensedBefore, floorBefore);
28080
- this.emitChange([key.split(".")[0]]);
28162
+ this.emitChange([key.split(".")[0]], [key]);
28081
28163
  return result2;
28082
28164
  }
28083
28165
  /** Get the full config object. */
@@ -28126,7 +28208,8 @@ and your settings stay in the file you renamed.`;
28126
28208
  restoreProtectedState(this.store, stored, "Reset your config");
28127
28209
  }
28128
28210
  this.stampStandingGrantVoidFloor(licensedBefore, floorBefore);
28129
- this.emitChange(key ? [key] : Object.keys(this.store.store));
28211
+ const sections = key ? [key] : Object.keys(this.store.store);
28212
+ this.emitChange(sections, sections);
28130
28213
  }
28131
28214
  /**
28132
28215
  * Whether the two settings, as stored RIGHT NOW, license a standing permission
@@ -30117,6 +30200,7 @@ function requiresClaudePlugin(type) {
30117
30200
  var PackageTypeSchema;
30118
30201
  var init_package_types = __esm({
30119
30202
  "../marketplace/src/package-types.ts"() {
30203
+ "use strict";
30120
30204
  init_zod();
30121
30205
  PackageTypeSchema = external_exports.enum(["agent", "plugin", "skill-pack", "adapter", "shape"]);
30122
30206
  }
@@ -31361,6 +31445,13 @@ var init_source_resolver = __esm({
31361
31445
  }
31362
31446
  });
31363
31447
 
31448
+ // ../marketplace/src/package-version.ts
31449
+ var init_package_version = __esm({
31450
+ "../marketplace/src/package-version.ts"() {
31451
+ "use strict";
31452
+ }
31453
+ });
31454
+
31364
31455
  // ../marketplace/src/cc-validator.ts
31365
31456
  function validateAgainstCcSchema(raw) {
31366
31457
  const result2 = CcMarketplaceJsonSchema.safeParse(raw);
@@ -31546,6 +31637,7 @@ var init_src = __esm({
31546
31637
  init_dorkos_sidecar_schema();
31547
31638
  init_merge_marketplace();
31548
31639
  init_source_resolver();
31640
+ init_package_version();
31549
31641
  init_cc_validator();
31550
31642
  init_marketplace_json_parser();
31551
31643
  init_package_types();
@@ -31667,6 +31759,52 @@ var init_logger2 = __esm({
31667
31759
  }
31668
31760
  });
31669
31761
 
31762
+ // ../shared/src/marketplace-schemas.ts
31763
+ function describeSchedulePermissionMode(mode) {
31764
+ return SCHEDULE_PERMISSION_MODE_SUMMARY[mode] ?? `runs in "${mode}" mode, which this version of DorkOS does not recognise`;
31765
+ }
31766
+ function describeScheduleArrival(startsEnabled) {
31767
+ return startsEnabled ? "waits for your approval before its first run" : "arrives switched off, and would wait for your approval too";
31768
+ }
31769
+ function describeHookEvent(event, matcher) {
31770
+ const when = HOOK_EVENT_SUMMARY[event] ?? `on ${event}`;
31771
+ return matcher ? `${when} (${matcher})` : when;
31772
+ }
31773
+ function isInstallSiblingName(name) {
31774
+ return MARKETPLACE_INSTALL_SIBLING_MARKERS.some((marker) => name.includes(marker));
31775
+ }
31776
+ var SCHEDULE_PERMISSION_MODE_SUMMARY, HOOK_EVENT_SUMMARY, MARKETPLACE_BACKUP_DIR_MARKER, MARKETPLACE_INSTALL_SIBLING_MARKERS;
31777
+ var init_marketplace_schemas = __esm({
31778
+ "../shared/src/marketplace-schemas.ts"() {
31779
+ SCHEDULE_PERMISSION_MODE_SUMMARY = {
31780
+ default: "runs at the most careful setting its agent offers",
31781
+ plan: "can only read and plan, and cannot change anything",
31782
+ acceptEdits: "can change files on its own, and on some agents run commands too",
31783
+ dontAsk: "runs its tools without a permission prompt",
31784
+ bypassPermissions: "can run any command without a permission prompt",
31785
+ auto: "decides for itself which actions are safe to take"
31786
+ };
31787
+ HOOK_EVENT_SUMMARY = {
31788
+ SessionStart: "when a session starts",
31789
+ SessionEnd: "when a session ends",
31790
+ UserPromptSubmit: "when you send a message",
31791
+ PreToolUse: "before the agent uses a tool",
31792
+ PostToolUse: "after the agent uses a tool",
31793
+ PermissionRequest: "when the agent asks for permission",
31794
+ Notification: "when the agent sends a notification",
31795
+ SubagentStart: "when a subagent starts",
31796
+ SubagentStop: "when a subagent finishes",
31797
+ Stop: "when the agent finishes",
31798
+ PreCompact: "before the conversation is shortened",
31799
+ PostCompact: "after the conversation is shortened"
31800
+ };
31801
+ MARKETPLACE_BACKUP_DIR_MARKER = ".dorkos-bak-";
31802
+ MARKETPLACE_INSTALL_SIBLING_MARKERS = [
31803
+ MARKETPLACE_BACKUP_DIR_MARKER
31804
+ ];
31805
+ }
31806
+ });
31807
+
31670
31808
  // ../skills/src/constants.ts
31671
31809
  var SKILL_FILENAME, WIDGET_TEMPLATE_SUFFIX;
31672
31810
  var init_constants3 = __esm({
@@ -34174,7 +34312,8 @@ var init_additional_context = __esm({
34174
34312
  StagedContextDataSchema = external_exports.object({ text: external_exports.string().min(1) });
34175
34313
  AccountsAccessDataSchema = external_exports.object({
34176
34314
  accountCount: external_exports.number().int().nonnegative().nullable(),
34177
- changed: external_exports.boolean()
34315
+ changed: external_exports.boolean(),
34316
+ serviceCatalog: external_exports.boolean().optional()
34178
34317
  });
34179
34318
  ApprovalVerdictDataSchema = external_exports.object({
34180
34319
  approvalId: external_exports.string().min(1),
@@ -34458,7 +34597,6 @@ function isSafeSigninUrl(value) {
34458
34597
  var PermissionModeSchema, PermissionModeIdSchema, PermissionStopSchema, SessionTaskStatusSchema, StreamEventTypeSchema, QuestionOptionSchema, QuestionItemSchema, EffortLevelSchema, SessionOriginSchema, SessionSchema, SessionUpdateResponseSchema, SessionSettingsSchema, StoredSessionSettingsResponseSchema, UpdateSessionRequestSchema, ForkSessionRequestSchema, ReloadPluginsResultSchema, SEED_CONTEXT_MAX_LENGTH, MessageDispositionSchema, DispositionDowngradeReasonSchema, MessageDeliveryOutcomeSchema, InterruptOutcomeSchema, InterruptReasonSchema, InterruptReceiptSchema, QueuedMessageSchema, SendMessageRequestSchema, SendMessageResponseSchema, SessionTriggerResponseSchema, SessionQueueResponseSchema, QueueMoveTargetSchema, UpdateQueuedMessageRequestSchema, UpdateQueuedMessageResponseSchema, DENY_REASON_MAX_LENGTH, ApprovalRequestSchema, BatchApprovalRequestSchema, SubmitAnswersRequestSchema, UI_ACTION_ID_MAX_LENGTH, UI_ACTION_TITLE_MAX_LENGTH, UI_ACTION_PAYLOAD_MAX_LENGTH, UiActionRequestSchema, McpAppPermissionSchema, McpAppResourceRequestSchema, McpAppResourceResponseSchema, ElicitationModeSchema, ElicitationActionSchema, SubmitElicitationRequestSchema, ListSessionsQuerySchema, SessionListWarningSchema, SessionListResponseSchema, RecentSessionsQuerySchema, RecentSessionsResponseSchema, SessionDailyCountsQuerySchema, SessionDailyCountsResponseSchema, CommandsQuerySchema, TextDeltaSchema, ThinkingDeltaSchema, ToolCallStatusSchema, McpAppRefSchema, ToolCallEventSchema, ToolProgressEventSchema, AlwaysAllowScopeSchema, ApprovalEventSchema, QuestionPromptEventSchema, PendingInteractionDTOSchema, ErrorCategorySchema, ErrorEventSchema, ApiRetryEventSchema, DoneEventSchema, TerminalReasonSchema, UsageStateSchema, UsageStatusSchema, SessionStatusEventSchema, ContextUsageCategorySchema, ContextUsageSchema, TaskItemSchema, TaskUpdateEventSchema, RelayReceiptEventSchema, MessageDeliveredEventSchema, RelayMessageEventSchema, BackgroundTaskTypeSchema, BackgroundTaskStatusSchema, BackgroundTaskStartedEventSchema, BackgroundTaskProgressEventSchema, BackgroundTaskDoneEventSchema, SubagentTextDeltaEventSchema, SystemStatusEventSchema, OperationKindSchema, OperationStateSchema, OperationProgressEventShapeSchema, OperationProgressEventSchema, MemoryEntrySchema, MemoryRecallEventSchema, CompactBoundaryEventSchema, sessionImageShape, SessionImageEventSchema, deniedAgentShape, PermissionDeniedEventSchema, PromptSuggestionEventSchema, HookStartedEventSchema, HookProgressEventSchema, HookResponseEventSchema, SdkSessionStateSchema, SessionStateChangedEventSchema, ElicitationPromptEventSchema, ElicitationCompleteEventSchema, InteractionCancelledEventSchema, CapabilityApprovalRequiredEventSchema, CapabilityApprovalResolvedEventSchema, SigninUrlSchema, MCP_SIGNIN_OUTCOMES, McpSigninOutcomeSchema, McpSigninRequiredEventSchema, McpSigninResolvedEventSchema, StreamEventSchema, TextPartSchema, HookStatusSchema, HookPartSchema, ToolApprovalOutcomeSchema, QuestionOutcomeSchema, ToolCallPartSchema, BackgroundTaskPartSchema, ThinkingPartSchema, ErrorPartSchema, ElicitationPartSchema, CapabilityApprovalPartSchema, McpSigninPartSchema, MemoryRecallPartSchema, PermissionDeniedPartSchema, CompactBoundaryPartSchema, ImagePartSchema, MessagePartSchema, MessageTypeSchema, HistoryToolCallSchema, CompactMetadataSchema, HistoryMessageSchema, CommandEntrySchema, CommandRegistrySchema, FileListQuerySchema, RawFileQuerySchema, FileListResponseSchema, WriteFileRequestSchema, WriteFileResponseSchema, FileEntrySchema, FileTreeQuerySchema, FileTreeResponseSchema, FileContentQuerySchema, FileContentResponseSchema, CreateEntryRequestSchema, CreateEntryResponseSchema, DeleteEntryQuerySchema, RenameEntryRequestSchema, CopyEntryRequestSchema, RevealEntryRequestSchema, DiffBaselineOriginSchema, DiffBaselineQuerySchema, DiffBaselineResponseSchema, AdvanceDiffBaselineRequestSchema, DiffPendingQuerySchema, DiffPendingResponseSchema, DiffBaselineRawQuerySchema, RevertDiffBaselineRequestSchema, FileMutationResponseSchema, WorkbenchSignRequestSchema, WorkbenchSignResponseSchema, WorkbenchProbeRequestSchema, WorkbenchProbeResponseSchema, BrowseDirectoryQuerySchema, DirectoryEntrySchema, BrowseDirectoryResponseSchema, TunnelStatusSchema, HealthResponseSchema, ExecutionDefaultsSchema, ExperimentStateSchema, ServerConfigSchema, ModelTierSchema, ModelOptionSchema, SubagentInfoSchema, GitStatusResponseSchema, GitStatusErrorSchema, ErrorResponseSchema, SessionLockedErrorSchema, TaskStatusSchema, SettableTaskStatusSchema, TaskNameSchema, TaskRunStatusSchema, TaskRunTriggerSchema, TaskSchema, TaskRunSchema, CancelTaskRunResponseSchema, TaskTemplateSchema, TASK_DURATION_PATTERN, TASK_DURATION_MAX, TASK_DESCRIPTION_MAX, CreateTaskRequestSchema, SIDEBAR_TAB_ID_PATTERN, ShapeLiveLayoutCaptureSchema, ForkShapeRequestSchema, UpdateTaskRequestSchema, ListTaskRunsQuerySchema, ConfigPatchRequestSchema, ConfigPatchResponseSchema, UploadResultSchema, UploadResponseSchema, UploadProgressSchema, CanvasMediaSrcSchema, UiCanvasContentSchema, UiPanelIdSchema, UiSidebarTabSchema, UiToastLevelSchema, CELEBRATION_KINDS, CELEBRATION_KIND_SYNONYMS, CelebrationKindSchema, UiCommandTargetSchema, UiCommandSchema, UiCommandEventSchema, UiStateSchema, UiStateReportDocumentSchema, UiStateReportSchema, DevtoolsConsoleLevelSchema, DEVTOOLS_ARGS_MAX_CHARS, DevtoolsConsoleEntrySchema, DevtoolsNetworkEntrySchema, DEVTOOLS_CONSOLE_BATCH_MAX, DEVTOOLS_NETWORK_BATCH_MAX, DEVTOOLS_SCREENSHOT_MAX_CHARS, DevtoolsScreenshotResultSchema, DevtoolsIngestSchema, BrowserTargetSchema, BrowserActCommandSchema, BrowserPageSummarySchema, DEVTOOLS_OUTLINE_MAX_CHARS, DevtoolsActionResultSchema, DevtoolsRecordingUploadSchema;
34459
34598
  var init_schemas3 = __esm({
34460
34599
  "../shared/src/schemas.ts"() {
34461
- "use strict";
34462
34600
  init_zod();
34463
34601
  init_zod_openapi();
34464
34602
  init_additional_context();
@@ -38299,6 +38437,7 @@ async function scanSkillDirectory(dir, schema2, options) {
38299
38437
  for (const entry of entries) {
38300
38438
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
38301
38439
  if (ignoreDirs.has(entry.name)) continue;
38440
+ if (isInstallSiblingName(entry.name)) continue;
38302
38441
  const skillPath = path12.join(dir, entry.name, SKILL_FILENAME);
38303
38442
  let content;
38304
38443
  try {
@@ -38345,6 +38484,7 @@ var UI_TEMPLATES_DIRNAME;
38345
38484
  var init_scanner = __esm({
38346
38485
  "../skills/src/scanner.ts"() {
38347
38486
  init_logger2();
38487
+ init_marketplace_schemas();
38348
38488
  init_constants3();
38349
38489
  init_parser();
38350
38490
  init_ui_template();
@@ -38401,8 +38541,22 @@ var init_validator = __esm({
38401
38541
  // ../marketplace/src/package-validator.ts
38402
38542
  import { promises as fs7 } from "node:fs";
38403
38543
  import path14 from "node:path";
38544
+ async function readDeclaredVersion(packagePath) {
38545
+ return await readVersionField(path14.join(packagePath, CLAUDE_PLUGIN_MANIFEST_PATH)) ?? await readVersionField(path14.join(packagePath, PACKAGE_MANIFEST_PATH));
38546
+ }
38547
+ async function readVersionField(filePath) {
38548
+ try {
38549
+ const parsed = JSON.parse(await fs7.readFile(filePath, "utf-8"));
38550
+ if (parsed === null || typeof parsed !== "object") return void 0;
38551
+ const version4 = parsed.version;
38552
+ return typeof version4 === "string" && version4 !== "" ? version4 : void 0;
38553
+ } catch {
38554
+ return void 0;
38555
+ }
38556
+ }
38404
38557
  async function validatePackage(packagePath) {
38405
38558
  const issues = [];
38559
+ const declaredVersion = await readDeclaredVersion(packagePath);
38406
38560
  let manifestRaw;
38407
38561
  let manifestSource;
38408
38562
  const dorkManifestPath2 = path14.join(packagePath, PACKAGE_MANIFEST_PATH);
@@ -38421,7 +38575,7 @@ async function validatePackage(packagePath) {
38421
38575
  message: `Invalid JSON in manifest: ${err instanceof Error ? err.message : String(err)}`,
38422
38576
  path: PACKAGE_MANIFEST_PATH
38423
38577
  });
38424
- return { ok: false, issues };
38578
+ return { ok: false, issues, declaredVersion };
38425
38579
  }
38426
38580
  manifestSource = PACKAGE_MANIFEST_PATH;
38427
38581
  } else {
@@ -38433,7 +38587,7 @@ async function validatePackage(packagePath) {
38433
38587
  message: `Required file missing: ${PACKAGE_MANIFEST_PATH} (no ${CLAUDE_PLUGIN_MANIFEST_PATH} fallback found either)`,
38434
38588
  path: PACKAGE_MANIFEST_PATH
38435
38589
  });
38436
- return { ok: false, issues };
38590
+ return { ok: false, issues, declaredVersion };
38437
38591
  }
38438
38592
  manifestRaw = synthesized;
38439
38593
  manifestSource = CLAUDE_PLUGIN_MANIFEST_PATH;
@@ -38448,7 +38602,7 @@ async function validatePackage(packagePath) {
38448
38602
  path: manifestSource
38449
38603
  });
38450
38604
  }
38451
- return { ok: false, issues };
38605
+ return { ok: false, issues, declaredVersion };
38452
38606
  }
38453
38607
  const manifest = parseResult.data;
38454
38608
  if (!manifest.category && !manifest.categories?.length) {
@@ -38471,6 +38625,9 @@ async function validatePackage(packagePath) {
38471
38625
  });
38472
38626
  }
38473
38627
  }
38628
+ if (manifestSource === PACKAGE_MANIFEST_PATH) {
38629
+ await checkVersionAgreement(packagePath, manifest.version, issues);
38630
+ }
38474
38631
  for (const dir of SKILL_SOURCE_DIRS) {
38475
38632
  const fullDir = path14.join(packagePath, dir);
38476
38633
  try {
@@ -38491,7 +38648,35 @@ async function validatePackage(packagePath) {
38491
38648
  await checkPackagedMcpServers(packagePath, issues);
38492
38649
  await checkScheduleSkillRefs(packagePath, manifest, issues);
38493
38650
  const hasErrors = issues.some((i2) => i2.level === "error");
38494
- return { ok: !hasErrors, issues, manifest };
38651
+ return { ok: !hasErrors, issues, manifest, declaredVersion };
38652
+ }
38653
+ async function checkVersionAgreement(packagePath, manifestVersion, issues) {
38654
+ let plugin;
38655
+ try {
38656
+ plugin = JSON.parse(
38657
+ await fs7.readFile(path14.join(packagePath, CLAUDE_PLUGIN_MANIFEST_PATH), "utf-8")
38658
+ );
38659
+ } catch {
38660
+ return;
38661
+ }
38662
+ if (plugin === null || typeof plugin !== "object") return;
38663
+ const pluginVersion = plugin.version;
38664
+ if (typeof pluginVersion === "string" && pluginVersion !== "") {
38665
+ if (pluginVersion === manifestVersion) return;
38666
+ issues.push({
38667
+ level: "error",
38668
+ code: "VERSION_MISMATCH",
38669
+ message: `${PACKAGE_MANIFEST_PATH} says version ${manifestVersion} but ${CLAUDE_PLUGIN_MANIFEST_PATH} says ${pluginVersion}. Set both to the same version: Claude Code loads ${pluginVersion}, DorkOS would report ${manifestVersion}.`,
38670
+ path: CLAUDE_PLUGIN_MANIFEST_PATH
38671
+ });
38672
+ return;
38673
+ }
38674
+ issues.push({
38675
+ level: "error",
38676
+ code: "VERSION_MISMATCH",
38677
+ message: `${PACKAGE_MANIFEST_PATH} says version ${manifestVersion} but ${CLAUDE_PLUGIN_MANIFEST_PATH} has no version. Add "version": "${manifestVersion}" to plugin.json so Claude Code and DorkOS agree.`,
38678
+ path: CLAUDE_PLUGIN_MANIFEST_PATH
38679
+ });
38495
38680
  }
38496
38681
  async function checkScheduleSkillRefs(packagePath, manifest, issues) {
38497
38682
  if (manifest.type === "adapter") return;
@@ -38722,12 +38907,24 @@ async function checkSourcePaths(marketplace, probe, buildCandidate, marketplaceR
38722
38907
  return { name: entry.name, status: "skipped-object-source" };
38723
38908
  }
38724
38909
  const candidate = buildCandidate(resolved.path);
38725
- const reachable = await probe(candidate);
38726
- return reachable ? { name: entry.name, status: "ok", candidate } : { name: entry.name, status: "not-found", candidate, sourceInput };
38910
+ const probed = await probe(candidate);
38911
+ if (!probed.reachable) {
38912
+ return { name: entry.name, status: "not-found", candidate, sourceInput };
38913
+ }
38914
+ if (entry.version && probed.version && entry.version !== probed.version) {
38915
+ return {
38916
+ name: entry.name,
38917
+ status: "version-mismatch",
38918
+ candidate,
38919
+ entryVersion: entry.version,
38920
+ pluginVersion: probed.version
38921
+ };
38922
+ }
38923
+ return { name: entry.name, status: "ok", candidate };
38727
38924
  });
38728
38925
  const results = await Promise.all(tasks);
38729
38926
  const checkedCount = results.filter((r3) => r3.status !== "skipped-object-source").length;
38730
- const ok2 = results.every((r3) => r3.status !== "not-found");
38927
+ const ok2 = results.every((r3) => r3.status === "ok" || r3.status === "skipped-object-source");
38731
38928
  return { ok: ok2, results, checkedCount, totalCount: marketplace.plugins.length };
38732
38929
  }
38733
38930
  function makeLocalCandidateBuilder(marketplaceRoot) {
@@ -38738,26 +38935,42 @@ function makeRemoteCandidateBuilder(rawBase) {
38738
38935
  return (resolvedPath) => `${normalized}/${resolvedPath}/.claude-plugin/plugin.json`;
38739
38936
  }
38740
38937
  async function localProbe(candidate) {
38741
- const { stat: stat3 } = await import("node:fs/promises");
38938
+ const { readFile: readFile7, stat: stat3 } = await import("node:fs/promises");
38742
38939
  try {
38743
- const s2 = await stat3(candidate);
38744
- return s2.isFile();
38940
+ if (!(await stat3(candidate)).isFile()) return { reachable: false };
38745
38941
  } catch {
38746
- return false;
38942
+ return { reachable: false };
38943
+ }
38944
+ try {
38945
+ return withVersion(JSON.parse(await readFile7(candidate, "utf-8")));
38946
+ } catch {
38947
+ return { reachable: true };
38747
38948
  }
38748
38949
  }
38749
38950
  async function remoteProbe(candidate) {
38951
+ let res;
38750
38952
  try {
38751
- const res = await fetch(candidate);
38752
- return res.ok;
38953
+ res = await fetch(candidate);
38753
38954
  } catch {
38754
- return false;
38955
+ return { reachable: false };
38755
38956
  }
38957
+ if (!res.ok) return { reachable: false };
38958
+ try {
38959
+ return withVersion(await res.json());
38960
+ } catch {
38961
+ return { reachable: true };
38962
+ }
38963
+ }
38964
+ function withVersion(plugin) {
38965
+ const version4 = plugin !== null && typeof plugin === "object" ? plugin.version : void 0;
38966
+ return typeof version4 === "string" && version4 !== "" ? { reachable: true, version: version4 } : { reachable: true };
38756
38967
  }
38757
38968
  function renderSourcePathResults(report2, marketplace) {
38758
38969
  const { results, checkedCount, totalCount } = report2;
38759
38970
  const skippedCount = totalCount - checkedCount;
38760
- const okCount = results.filter((r3) => r3.status === "ok").length;
38971
+ const okCount = results.filter(
38972
+ (r3) => r3.status === "ok" || r3.status === "version-mismatch"
38973
+ ).length;
38761
38974
  if (report2.ok) {
38762
38975
  let suffix;
38763
38976
  if (checkedCount === 0) {
@@ -38770,17 +38983,33 @@ function renderSourcePathResults(report2, marketplace) {
38770
38983
  return { okLine: `[OK] Plugin sources reachable${suffix}
38771
38984
  `, failBlock: "" };
38772
38985
  }
38773
- const lines = [`[FAIL] Plugin sources reachable (${okCount}/${checkedCount})
38774
- `];
38775
- for (const r3 of results) {
38776
- if (r3.status !== "not-found") continue;
38777
- lines.push(` - ${r3.name}: "${r3.sourceInput}" \u2192 not found at ${r3.candidate}
38986
+ const lines = [];
38987
+ const notFound = results.filter(
38988
+ (r3) => r3.status === "not-found"
38989
+ );
38990
+ if (notFound.length > 0) {
38991
+ lines.push(`[FAIL] Plugin sources reachable (${okCount}/${checkedCount})
38992
+ `);
38993
+ for (const r3 of notFound) {
38994
+ lines.push(` - ${r3.name}: "${r3.sourceInput}" \u2192 not found at ${r3.candidate}
38995
+ `);
38996
+ }
38997
+ }
38998
+ const mismatched = results.filter(
38999
+ (r3) => r3.status === "version-mismatch"
39000
+ );
39001
+ if (mismatched.length > 0) {
39002
+ lines.push(`[FAIL] Entry versions match plugin.json
38778
39003
  `);
39004
+ for (const r3 of mismatched) {
39005
+ lines.push(
39006
+ ` - ${r3.name}: ENTRY_VERSION_MISMATCH: marketplace.json says version ${r3.entryVersion} but ${r3.candidate} says ${r3.pluginVersion}. Claude Code silently uses plugin.json's version, so the entry's is never seen. Remove "version" from the entry, or make them match.
39007
+ `
39008
+ );
39009
+ }
38779
39010
  }
38780
39011
  const pluginRoot = marketplace.metadata?.pluginRoot;
38781
- const failingWithExplicitDotSlash = results.some(
38782
- (r3) => r3.status === "not-found" && r3.sourceInput.startsWith("./")
38783
- );
39012
+ const failingWithExplicitDotSlash = notFound.some((r3) => r3.sourceInput.startsWith("./"));
38784
39013
  if (pluginRoot !== void 0 && failingWithExplicitDotSlash) {
38785
39014
  const normalizedRoot = pluginRoot.replace(/^\.\//, "").replace(/\/+$/, "");
38786
39015
  lines.push(
@@ -39224,6 +39453,17 @@ var init_config_disclosure = __esm({
39224
39453
  "ui.shapes.autoFollowAgent": "expose",
39225
39454
  "ui.statusBar.pins": "expose",
39226
39455
  "ui.composer.richText": "expose",
39456
+ // Owner and tenant-qualified navigation history is local UI state. Withhold
39457
+ // the whole shape so a tokenless config read cannot enumerate private room IDs.
39458
+ "ui.communityNavigation.version": "withhold",
39459
+ "ui.communityNavigation.owners[].ownerKey": "withhold",
39460
+ "ui.communityNavigation.owners[].order": "withhold",
39461
+ "ui.communityNavigation.owners[].destinations[].ref": "withhold",
39462
+ "ui.communityNavigation.owners[].destinations[].roomId": "withhold",
39463
+ "ui.communityNavigation.owners[].destinations[].threadId": "withhold",
39464
+ "ui.communityNavigation.owners[].destinations[].scrollAnchorEntryId": "withhold",
39465
+ "ui.communityNavigation.owners[].installationDestination.path": "withhold",
39466
+ "ui.communityNavigation.owners[].installationDestination.search": "withhold",
39227
39467
  // A timestamp saying the person read what Full autonomy means. Names nothing
39228
39468
  // and unlocks nothing on being read — an agent that learns the date is no
39229
39469
  // closer to anything than one that does not.
@@ -39614,6 +39854,20 @@ var init_config_write_policy = __esm({
39614
39854
  "ui.shapes.autoFollowAgent": "agent-writable",
39615
39855
  "ui.statusBar.pins": "agent-writable",
39616
39856
  "ui.composer.richText": "agent-writable",
39857
+ // Preferences only: restoring a room always reauthorizes it server-side, so
39858
+ // changing an ID cannot widen access or disclose the remembered destination.
39859
+ "ui.communityNavigation.version": "agent-writable",
39860
+ // Operator-only: which owner a namespace belongs to, and where the owner's
39861
+ // next "This DorkOS" click lands. An agent that could write either could
39862
+ // plant another owner's state or steer the operator to a route of its choice.
39863
+ "ui.communityNavigation.owners[].ownerKey": "operator-only",
39864
+ "ui.communityNavigation.owners[].order": "agent-writable",
39865
+ "ui.communityNavigation.owners[].destinations[].ref": "agent-writable",
39866
+ "ui.communityNavigation.owners[].destinations[].roomId": "agent-writable",
39867
+ "ui.communityNavigation.owners[].destinations[].threadId": "agent-writable",
39868
+ "ui.communityNavigation.owners[].destinations[].scrollAnchorEntryId": "agent-writable",
39869
+ "ui.communityNavigation.owners[].installationDestination.path": "operator-only",
39870
+ "ui.communityNavigation.owners[].installationDestination.search": "operator-only",
39617
39871
  // Which promo cards are hidden. A preference about what the sidebar's bottom
39618
39872
  // slot offers, exactly like `ui.sidebar.gettingStarted.retired` above; nothing
39619
39873
  // it gates is a security control.
@@ -40295,6 +40549,19 @@ var init_config_write_policy = __esm({
40295
40549
  description: "Whether a name on your roster is shown as your own or as an agent\u2019s suggestion",
40296
40550
  paths: ["profile.displayNameSource.kind", "profile.displayNameSource.agentName"]
40297
40551
  },
40552
+ {
40553
+ stake: "navigation",
40554
+ // Not `reach` (nobody gets in) and not `authorship` (no name is shown as
40555
+ // anyone's). An agent able to write the owner key could file its own state
40556
+ // under the person's namespace, and one able to write the saved route could
40557
+ // choose where the person lands on their next "switch back" click.
40558
+ description: "Where the app takes you when you switch back to this DorkOS, and whose saved places those are",
40559
+ paths: [
40560
+ "ui.communityNavigation.owners[].ownerKey",
40561
+ "ui.communityNavigation.owners[].installationDestination.path",
40562
+ "ui.communityNavigation.owners[].installationDestination.search"
40563
+ ]
40564
+ },
40298
40565
  {
40299
40566
  stake: "attention",
40300
40567
  description: "Whether you are told that something is waiting on you",
@@ -42387,7 +42654,7 @@ var init_sql = __esm({
42387
42654
  return new SQL([new StringChunk(str)]);
42388
42655
  }
42389
42656
  sql22.raw = raw;
42390
- function join53(chunks, separator) {
42657
+ function join54(chunks, separator) {
42391
42658
  const result2 = [];
42392
42659
  for (const [i2, chunk] of chunks.entries()) {
42393
42660
  if (i2 > 0 && separator !== void 0) {
@@ -42397,7 +42664,7 @@ var init_sql = __esm({
42397
42664
  }
42398
42665
  return new SQL(result2);
42399
42666
  }
42400
- sql22.join = join53;
42667
+ sql22.join = join54;
42401
42668
  function identifier(value) {
42402
42669
  return new Name(value);
42403
42670
  }
@@ -45317,7 +45584,7 @@ var init_select2 = __esm({
45317
45584
  const baseTableName = this.tableName;
45318
45585
  const tableName = getTableLikeName(table2);
45319
45586
  for (const item of extractUsedTable(table2)) this.usedTables.add(item);
45320
- if (typeof tableName === "string" && this.config.joins?.some((join53) => join53.alias === tableName)) {
45587
+ if (typeof tableName === "string" && this.config.joins?.some((join54) => join54.alias === tableName)) {
45321
45588
  throw new Error(`Alias "${tableName}" is already used in this query`);
45322
45589
  }
45323
45590
  if (!this.isPartialSelect) {
@@ -46203,7 +46470,7 @@ var init_update = __esm({
46203
46470
  createJoin(joinType) {
46204
46471
  return (table2, on) => {
46205
46472
  const tableName = getTableLikeName(table2);
46206
- if (typeof tableName === "string" && this.config.joins.some((join53) => join53.alias === tableName)) {
46473
+ if (typeof tableName === "string" && this.config.joins.some((join54) => join54.alias === tableName)) {
46207
46474
  throw new Error(`Alias "${tableName}" is already used in this query`);
46208
46475
  }
46209
46476
  if (typeof on === "function") {
@@ -57420,6 +57687,7 @@ function listSkillDirs(absRoot, relPrefix, options = {}) {
57420
57687
  if (isLink && options.followSymlinks === false) continue;
57421
57688
  const isManagedProjection2 = isLink && entry.name.includes(INSTALLED_PROJECTION_MARKER);
57422
57689
  if (isManagedProjection2 && !options.includeManagedProjections) continue;
57690
+ if (isInstallSiblingName(entry.name)) continue;
57423
57691
  const absEntry = join10(absRoot, entry.name);
57424
57692
  if (!resolvesToDirectory(absEntry, entry)) continue;
57425
57693
  const sourceDir = `${relPrefix}/${entry.name}`;
@@ -57457,6 +57725,7 @@ var INSTALLED_PROJECTION_MARKER, AGENTS_SKILLS_DIR, CLAUDE_PLUGIN_ROOT_TOKEN;
57457
57725
  var init_scanner2 = __esm({
57458
57726
  "../harness/src/scan/scanner.ts"() {
57459
57727
  "use strict";
57728
+ init_marketplace_schemas();
57460
57729
  INSTALLED_PROJECTION_MARKER = "__";
57461
57730
  AGENTS_SKILLS_DIR = ".agents/skills";
57462
57731
  CLAUDE_PLUGIN_ROOT_TOKEN = "${CLAUDE_PLUGIN_ROOT}";
@@ -58476,11 +58745,11 @@ function globalInstallDropReason(plugin, opts) {
58476
58745
  namedSkills(plugin.skills.map((skill) => skill.name)),
58477
58746
  shared
58478
58747
  );
58479
- const join53 = (into) => shared ? into : `${into}${into.endsWith(".") ? "" : "."} ${GLOBAL_INSTALL_SHARE_OFFER}`;
58748
+ const join54 = (into) => shared ? into : `${into}${into.endsWith(".") ? "" : "."} ${GLOBAL_INSTALL_SHARE_OFFER}`;
58480
58749
  const timed = plugin.skills.filter((skill) => skill.hasSchedule);
58481
- if (timed.length === 0) return join53(lead);
58750
+ if (timed.length === 0) return join54(lead);
58482
58751
  const allLinked = timed.every((skill) => skill.linkedInDorkHome === true);
58483
- return join53(`${lead}. ${allLinked ? GLOBAL_INSTALL_TIMERS_WORK : GLOBAL_INSTALL_TIMERS_PENDING}`);
58752
+ return join54(`${lead}. ${allLinked ? GLOBAL_INSTALL_TIMERS_WORK : GLOBAL_INSTALL_TIMERS_PENDING}`);
58484
58753
  }
58485
58754
  function planGlobalInstallDrops(input4) {
58486
58755
  const projectNames = new Set(
@@ -58701,7 +58970,7 @@ function scanPluginsRoot(pluginsRoot, scope, dorkHome) {
58701
58970
  const plugins = [];
58702
58971
  const unreadableManifests = [];
58703
58972
  for (const entry of readdirSync3(pluginsRoot, { withFileTypes: true })) {
58704
- if (!entry.isDirectory()) continue;
58973
+ if (!entry.isDirectory() || isInstallSiblingName(entry.name)) continue;
58705
58974
  const pluginDir = join12(pluginsRoot, entry.name);
58706
58975
  const location = scope === "global" ? { scope, absDir: pluginDir } : { scope, relDir: `${PROJECT_PLUGINS_DIR}/${entry.name}` };
58707
58976
  const sourcePrefix = location.scope === "global" ? location.absDir : location.relDir;
@@ -58761,6 +59030,7 @@ var init_installed = __esm({
58761
59030
  "../harness/src/sources/installed.ts"() {
58762
59031
  "use strict";
58763
59032
  init_src();
59033
+ init_marketplace_schemas();
58764
59034
  init_schedule_schema();
58765
59035
  init_parser();
58766
59036
  init_scanner2();
@@ -59599,6 +59869,7 @@ function lockedSkillFolders(absRoot, root, entries, found, options) {
59599
59869
  const records = [];
59600
59870
  for (const entry of entries) {
59601
59871
  if (found.has(entry.name)) continue;
59872
+ if (isInstallSiblingName(entry.name)) continue;
59602
59873
  const isLink = entry.isSymbolicLink();
59603
59874
  if (isLink && entry.name.includes(INSTALLED_PROJECTION_MARKER) && !options.includeManagedProjections)
59604
59875
  continue;
@@ -59636,6 +59907,7 @@ var init_skills = __esm({
59636
59907
  init_scanner2();
59637
59908
  init_installed_projector();
59638
59909
  init_parser();
59910
+ init_marketplace_schemas();
59639
59911
  init_constants3();
59640
59912
  init_read();
59641
59913
  init_types4();
@@ -62731,9 +63003,9 @@ rather not share, and press submit. Never report their issue as filed. If
62731
63003
  \`truncated\` comes back true the link could not hold the whole body, so hand them
62732
63004
  \`fullBody\` as well.
62733
63005
 
62734
- If they would rather do it themselves: **Send feedback** in the app goes straight
62735
- to the DorkOS team; **Help and feedback > Report on GitHub** opens this same
62736
- page; \`dorkos feedback\` does it from a terminal. Neither that command nor this
63006
+ If they would rather do it themselves: **Help and feedback > Send feedback** in
63007
+ the app goes straight to the DorkOS team, and its **Open one instead** link at
63008
+ the bottom opens this same page; \`dorkos feedback\` does it from a terminal. Neither that command nor this
62737
63009
  tool is off limits to you, so never say it is, and never file an issue on their
62738
63010
  behalf through some other tool.
62739
63011
 
@@ -66063,7 +66335,6 @@ function boundaryWasConfigured(env5, config3) {
66063
66335
  var BoundaryError, resolvedBoundary, MAX_DANGLING_SYMLINK_HOPS, cachedDorkHome;
66064
66336
  var init_boundary = __esm({
66065
66337
  "../../apps/server/src/lib/boundary.ts"() {
66066
- "use strict";
66067
66338
  init_dork_home();
66068
66339
  BoundaryError = class extends Error {
66069
66340
  code;
@@ -66219,7 +66490,6 @@ function writeGlobalSharing(harnesses, reason, now2 = /* @__PURE__ */ new Date()
66219
66490
  var NOTHING_SHARED;
66220
66491
  var init_global_scope = __esm({
66221
66492
  "../../apps/server/src/services/harness/global-scope.ts"() {
66222
- "use strict";
66223
66493
  init_src4();
66224
66494
  init_config_schema();
66225
66495
  init_boundary();
@@ -66858,18 +67128,119 @@ var init_package_paths = __esm({
66858
67128
  }
66859
67129
  });
66860
67130
 
66861
- // ../../apps/server/src/services/marketplace/marketplace-cache.ts
66862
- import { mkdir as mkdir3, mkdtemp, readFile as readFile3, rename, writeFile as writeFile3, readdir, rm, stat } from "node:fs/promises";
67131
+ // ../../apps/server/src/lib/git-safety.ts
67132
+ var init_git_safety = __esm({
67133
+ "../../apps/server/src/lib/git-safety.ts"() {
67134
+ "use strict";
67135
+ }
67136
+ });
67137
+
67138
+ // ../../apps/server/src/services/core/template-downloader.ts
67139
+ var init_template_downloader = __esm({
67140
+ "../../apps/server/src/services/core/template-downloader.ts"() {
67141
+ "use strict";
67142
+ init_src();
67143
+ init_logger();
67144
+ init_git_safety();
67145
+ init_env();
67146
+ }
67147
+ });
67148
+
67149
+ // ../../apps/server/src/services/marketplace/lib/git-tree.ts
67150
+ import { execFile } from "node:child_process";
67151
+ import { promisify } from "node:util";
67152
+ function isFullCommitSha(value) {
67153
+ return value !== void 0 && FULL_COMMIT_SHA_RE.test(value);
67154
+ }
67155
+ var execFileAsync, REMOTE, PARTIAL_CLONE_CONFIG, FULL_COMMIT_SHA_RE;
67156
+ var init_git_tree = __esm({
67157
+ "../../apps/server/src/services/marketplace/lib/git-tree.ts"() {
67158
+ "use strict";
67159
+ init_git_safety();
67160
+ init_template_downloader();
67161
+ execFileAsync = promisify(execFile);
67162
+ REMOTE = "origin";
67163
+ PARTIAL_CLONE_CONFIG = [
67164
+ ["core.repositoryformatversion", "1"],
67165
+ ["extensions.partialClone", REMOTE],
67166
+ [`remote.${REMOTE}.promisor`, "true"],
67167
+ [`remote.${REMOTE}.partialclonefilter`, "blob:none"]
67168
+ ];
67169
+ FULL_COMMIT_SHA_RE = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/;
67170
+ }
67171
+ });
67172
+
67173
+ // ../../apps/server/src/services/marketplace/lib/directory-size.ts
67174
+ import { lstat, readdir } from "node:fs/promises";
66863
67175
  import { join as join43 } from "node:path";
67176
+ async function directorySize(root) {
67177
+ let total = 0;
67178
+ const walk = async (dir, depth) => {
67179
+ if (depth > MAX_DEPTH2) return;
67180
+ let entries;
67181
+ try {
67182
+ entries = await readdir(dir, { withFileTypes: true });
67183
+ } catch {
67184
+ return;
67185
+ }
67186
+ for (const entry of entries) {
67187
+ const entryPath = join43(dir, entry.name);
67188
+ if (entry.isDirectory()) {
67189
+ await walk(entryPath, depth + 1);
67190
+ } else if (entry.isFile()) {
67191
+ try {
67192
+ total += (await lstat(entryPath)).size;
67193
+ } catch {
67194
+ }
67195
+ }
67196
+ }
67197
+ };
67198
+ await walk(root, 0);
67199
+ return total;
67200
+ }
67201
+ var MAX_DEPTH2;
67202
+ var init_directory_size = __esm({
67203
+ "../../apps/server/src/services/marketplace/lib/directory-size.ts"() {
67204
+ "use strict";
67205
+ MAX_DEPTH2 = 256;
67206
+ }
67207
+ });
67208
+
67209
+ // ../../apps/server/src/services/marketplace/marketplace-cache.ts
67210
+ import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
67211
+ import {
67212
+ mkdir as mkdir3,
67213
+ mkdtemp,
67214
+ readFile as readFile3,
67215
+ rename,
67216
+ writeFile as writeFile3,
67217
+ readdir as readdir2,
67218
+ rm,
67219
+ stat,
67220
+ utimes
67221
+ } from "node:fs/promises";
67222
+ import { join as join44 } from "node:path";
67223
+ function subpathDigest(subpath) {
67224
+ if (subpath === "") return "";
67225
+ return createHash3("sha256").update(subpath).digest("hex").slice(0, 12);
67226
+ }
67227
+ async function stampUsed(path43) {
67228
+ const now2 = /* @__PURE__ */ new Date();
67229
+ try {
67230
+ await utimes(path43, now2, now2);
67231
+ return now2;
67232
+ } catch {
67233
+ return (await stat(path43)).mtime;
67234
+ }
67235
+ }
66864
67236
  function parsePackageDirName(entry) {
66865
67237
  const at = entry.lastIndexOf("@");
66866
67238
  if (at <= 0 || at === entry.length - 1) {
66867
67239
  return null;
66868
67240
  }
66869
- return {
66870
- packageName: entry.slice(0, at),
66871
- commitSha: entry.slice(at + 1)
66872
- };
67241
+ const [commitSha = "", digest2 = ""] = entry.slice(at + 1).split(SUBPATH_SEPARATOR);
67242
+ if (commitSha === "") return null;
67243
+ return { packageName: entry.slice(0, at), commitSha, subpathDigest: digest2 };
66873
67244
  }
66874
67245
  async function isNonEmptyDir(dir) {
66875
67246
  try {
@@ -66877,30 +67248,29 @@ async function isNonEmptyDir(dir) {
66877
67248
  if (!info2.isDirectory()) {
66878
67249
  return false;
66879
67250
  }
66880
- const entries = await readdir(dir);
67251
+ const entries = await readdir2(dir);
66881
67252
  return entries.length > 0;
66882
67253
  } catch {
66883
67254
  return false;
66884
67255
  }
66885
67256
  }
66886
- function groupByPackageName(packages) {
66887
- const grouped = /* @__PURE__ */ new Map();
66888
- for (const pkg of packages) {
66889
- const list = grouped.get(pkg.packageName) ?? [];
66890
- list.push(pkg);
66891
- grouped.set(pkg.packageName, list);
66892
- }
66893
- return grouped;
66894
- }
66895
- var DEFAULT_TTL_MS, MARKETPLACE_FILENAME, LAST_FETCHED_FILENAME, MarketplaceCache;
67257
+ var DEFAULT_TTL_MS, MARKETPLACE_FILENAME, LAST_FETCHED_FILENAME, TREES_DIRNAME, LEGACY_PACKAGES_DIRNAME, TEMP_FETCH_PREFIX, TEMP_PRUNE_PREFIX, IN_USE_GRACE_MS, SUBPATH_SEPARATOR, MarketplaceCache;
66896
67258
  var init_marketplace_cache = __esm({
66897
67259
  "../../apps/server/src/services/marketplace/marketplace-cache.ts"() {
66898
67260
  "use strict";
66899
67261
  init_src();
66900
67262
  init_package_paths();
67263
+ init_git_tree();
67264
+ init_directory_size();
66901
67265
  DEFAULT_TTL_MS = 60 * 60 * 1e3;
66902
67266
  MARKETPLACE_FILENAME = "marketplace.json";
66903
67267
  LAST_FETCHED_FILENAME = ".last-fetched";
67268
+ TREES_DIRNAME = "trees";
67269
+ LEGACY_PACKAGES_DIRNAME = "packages";
67270
+ TEMP_FETCH_PREFIX = ".tmp-fetch-";
67271
+ TEMP_PRUNE_PREFIX = ".tmp-prune-";
67272
+ IN_USE_GRACE_MS = 15 * 60 * 1e3;
67273
+ SUBPATH_SEPARATOR = "~";
66904
67274
  MarketplaceCache = class {
66905
67275
  /**
66906
67276
  * Construct a cache rooted at `${dorkHome}/cache/marketplace`.
@@ -66916,17 +67286,25 @@ var init_marketplace_cache = __esm({
66916
67286
  dorkHome;
66917
67287
  ttlMs;
66918
67288
  /**
66919
- * In-flight materialization promises keyed by `${name}@${sha}`. Two
67289
+ * In-flight materialization promises keyed by `${name}@${expectedSha}`. Two
66920
67290
  * concurrent {@link MarketplaceCache.materializePackage} calls for the same
66921
- * cache key share a single clone: the first call performs the clone, every
67291
+ * expected commit share a single fetch: the first call performs it, every
66922
67292
  * subsequent caller awaits the same promise and reuses the result. This is
66923
67293
  * the in-process de-dup that stops a UI preview + install double-fetch from
66924
- * racing two `git clone` processes into the same directory.
67294
+ * racing two git processes into the same directory.
66925
67295
  */
66926
67296
  inFlight = /* @__PURE__ */ new Map();
67297
+ /**
67298
+ * Tail of the in-process lock ({@link MarketplaceCache.exclusive}). It
67299
+ * serialises only short critical sections: a reader's "exists? stamp it",
67300
+ * a fetch's landing, and a sweep's "still unused? rename it aside".
67301
+ */
67302
+ lockTail = Promise.resolve();
67303
+ /** Listeners told when a fetch lands a new entry ({@link onEntryWritten}). */
67304
+ entryWrittenListeners = /* @__PURE__ */ new Set();
66927
67305
  /** Compute the cache root path: `${dorkHome}/cache/marketplace`. */
66928
67306
  get cacheRoot() {
66929
- return join43(this.dorkHome, "cache", "marketplace");
67307
+ return join44(this.dorkHome, "cache", "marketplace");
66930
67308
  }
66931
67309
  /**
66932
67310
  * Read a cached marketplace.json document.
@@ -66951,8 +67329,8 @@ var init_marketplace_cache = __esm({
66951
67329
  */
66952
67330
  async readMarketplace(marketplaceName) {
66953
67331
  const dir = this.marketplaceDir(marketplaceName);
66954
- const jsonPath = join43(dir, MARKETPLACE_FILENAME);
66955
- const stampPath = join43(dir, LAST_FETCHED_FILENAME);
67332
+ const jsonPath = join44(dir, MARKETPLACE_FILENAME);
67333
+ const stampPath = join44(dir, LAST_FETCHED_FILENAME);
66956
67334
  let raw;
66957
67335
  let stamp2;
66958
67336
  try {
@@ -66987,138 +67365,262 @@ var init_marketplace_cache = __esm({
66987
67365
  async writeMarketplace(marketplaceName, json2) {
66988
67366
  const dir = this.marketplaceDir(marketplaceName);
66989
67367
  await mkdir3(dir, { recursive: true });
66990
- await writeFile3(join43(dir, MARKETPLACE_FILENAME), `${JSON.stringify(json2, null, 2)}
67368
+ await writeFile3(join44(dir, MARKETPLACE_FILENAME), `${JSON.stringify(json2, null, 2)}
66991
67369
  `);
66992
- await writeFile3(join43(dir, LAST_FETCHED_FILENAME), (/* @__PURE__ */ new Date()).toISOString());
67370
+ await writeFile3(join44(dir, LAST_FETCHED_FILENAME), (/* @__PURE__ */ new Date()).toISOString());
66993
67371
  }
66994
67372
  /**
66995
- * Get a cached package by name and commit SHA.
67373
+ * Get a cached package tree by name, commit and subfolder, and stamp it as
67374
+ * used so a sweep leaves it alone while the caller reads it.
66996
67375
  *
66997
67376
  * @param packageName - Logical package name.
66998
- * @param commitSha - Commit SHA the package was cloned at.
66999
- * @returns A descriptor when present, `null` otherwise.
67000
- */
67001
- async getPackage(packageName, commitSha) {
67002
- const path43 = this.packageDir(packageName, commitSha);
67003
- try {
67004
- const info2 = await stat(path43);
67005
- if (!info2.isDirectory()) {
67006
- return null;
67007
- }
67008
- return {
67009
- packageName,
67010
- commitSha,
67011
- path: path43,
67012
- cachedAt: info2.mtime
67013
- };
67014
- } catch {
67015
- return null;
67016
- }
67377
+ * @param commitSha - The commit whose tree is wanted.
67378
+ * @param subpath - The subfolder a sparse entry holds; `''` for the whole
67379
+ * repository. Part of the key: a sparse checkout is a different tree.
67380
+ * @returns A descriptor when a non-empty entry is present, `null` otherwise.
67381
+ */
67382
+ async getPackage(packageName, commitSha, subpath) {
67383
+ const path43 = this.packageDir(packageName, commitSha, subpath);
67384
+ const usedAt = await this.stampIfPresent(path43);
67385
+ if (usedAt === null) return null;
67386
+ return {
67387
+ packageName,
67388
+ commitSha,
67389
+ subpathDigest: subpathDigest(subpath),
67390
+ path: path43,
67391
+ lastUsedAt: usedAt
67392
+ };
67017
67393
  }
67018
67394
  /**
67019
- * Reserve a package directory in the cache and return its absolute path.
67395
+ * The one way an entry is written. Fetches into a unique temp directory,
67396
+ * takes the entry's key from the commit the fetch REPORTS, refuses anything
67397
+ * that is not a full commit id, and atomically renames the tree onto
67398
+ * `${name}@${commit}` — `${name}@${commit}~${digest}` for a sparse entry,
67399
+ * where the digest is of the subfolder (DOR-2248). The caller's
67400
+ * `expectedSha` never names an
67401
+ * entry: it only short-circuits a tree already cached under it and
67402
+ * de-duplicates concurrent fetches of it. The two differ when a ref moved
67403
+ * between the caller's lookup and the fetch, and the entry then holds the
67404
+ * commit that actually arrived.
67020
67405
  *
67021
- * The caller is responsible for writing the package contents into the
67022
- * returned directory. The directory is created (idempotently) but left
67023
- * empty — `putPackage` does no other I/O.
67406
+ * Every entry it hands out is stamped as used, and a fetch that lands a new
67407
+ * entry tells the {@link onEntryWritten} listeners.
67024
67408
  *
67025
- * @param packageName - Logical package name.
67026
- * @param commitSha - Commit SHA the package will be cloned at.
67027
- * @returns Absolute path to the reserved directory.
67028
- */
67029
- async putPackage(packageName, commitSha) {
67030
- const path43 = this.packageDir(packageName, commitSha);
67031
- await mkdir3(path43, { recursive: true });
67032
- return path43;
67033
- }
67034
- /**
67035
- * Concurrency-safe, atomic package materialization. Guarantees that two
67036
- * concurrent fetches of the same `${name}@${sha}` never both clone into (and
67037
- * corrupt) the same directory. This is the bug behind the failing `flow`
67038
- * github-subdir install: a UI preview and install fire simultaneously and
67039
- * two `git clone` processes collide on git's template copy step.
67040
- *
67041
- * Algorithm:
67042
- * 1. If the final cache path already holds a valid (non-empty) package,
67043
- * reuse it immediately (no clone).
67044
- * 2. If a materialization for this key is already in flight, await it and
67045
- * reuse its result (in-process de-dup).
67046
- * 3. Otherwise clone into a unique sibling temp directory, then atomically
67047
- * `rename` it onto the final cache path. A partial/empty directory left
67048
- * by a prior crashed clone is removed before the rename so it can never
67049
- * shadow a clean result.
67050
- *
67051
- * The injected `clone` callback receives the temp directory to populate; any
67052
- * error it throws (e.g. a `GitSpawnError` carrying git stderr + exit code)
67053
- * propagates verbatim so callers surface the real fetch failure rather than
67054
- * a downstream "manifest missing" validation error.
67409
+ * Concurrency: two fetches of one entry key in this process
67410
+ * share one fetch (a UI preview and an install fire together, and two git
67411
+ * processes must never collide in one directory). A valid tree another
67412
+ * process landed first wins, and ours is discarded. A partial (empty)
67413
+ * directory left by a crash is replaced.
67414
+ *
67415
+ * The fetch's error (git's stderr, via `GitFetchError`) propagates
67416
+ * verbatim, so a caller sees the real failure rather than a later
67417
+ * "manifest missing".
67055
67418
  *
67056
67419
  * @param packageName - Logical package name.
67057
- * @param commitSha - Commit SHA the package is cloned at (the cache key).
67058
- * @param clone - Callback that clones/populates the given temp directory.
67059
- * @returns Absolute path to the final cache directory holding the package.
67060
- */
67061
- async materializePackage(packageName, commitSha, clone2) {
67062
- const finalPath = this.packageDir(packageName, commitSha);
67063
- if (await isNonEmptyDir(finalPath)) {
67064
- return finalPath;
67065
- }
67066
- const key = `${packageName}@${commitSha}`;
67420
+ * @param expectedSha - The commit the caller asked for.
67421
+ * @param subpath - The subfolder the fetch checks out; `''` for the whole
67422
+ * repository.
67423
+ * @param fetch - Populates the temp directory it is given and resolves to
67424
+ * the full commit id of what it put there.
67425
+ * @returns Where the tree is, and the commit it is.
67426
+ * @throws {Error} When the fetch reports anything but a full commit id.
67427
+ */
67428
+ async materializePackage(packageName, expectedSha, subpath, fetch2) {
67429
+ const expectedPath = this.packageDir(packageName, expectedSha, subpath);
67430
+ if (await this.stampIfPresent(expectedPath) !== null) {
67431
+ return { path: expectedPath, commitSha: expectedSha };
67432
+ }
67433
+ const key = expectedPath;
67067
67434
  const existing = this.inFlight.get(key);
67068
67435
  if (existing) {
67069
67436
  return existing;
67070
67437
  }
67071
- const work = this.cloneAndPromote(finalPath, clone2).finally(() => {
67438
+ const work = this.fetchAndPromote(packageName, subpath, fetch2).finally(() => {
67072
67439
  this.inFlight.delete(key);
67073
67440
  });
67074
67441
  this.inFlight.set(key, work);
67075
67442
  return work;
67076
67443
  }
67077
67444
  /**
67078
- * Clone into a unique temp directory and atomically promote it onto the
67079
- * final cache path. Cleans up the temp directory on clone failure and
67080
- * removes any partial directory occupying the final path before promoting.
67445
+ * Delete what no entry is ever read from, once, before any fetch runs (the
67446
+ * server calls it at startup):
67447
+ *
67448
+ * - the `packages/` root entries lived in before their keys were verified
67449
+ * (DOR-2248): a tree there may not be the commit its name says;
67450
+ * - temp fetch directories a crash left in `trees/`, whose `.git` may still
67451
+ * hold a half-fetched repository;
67452
+ * - entries a sweep renamed aside and a crash stopped it deleting.
67453
+ *
67454
+ * Idempotent. Not safe while a fetch is running in this cache.
67455
+ */
67456
+ async removeLeftovers() {
67457
+ await rm(join44(this.cacheRoot, LEGACY_PACKAGES_DIRNAME), { recursive: true, force: true });
67458
+ const treesRoot = join44(this.cacheRoot, TREES_DIRNAME);
67459
+ let entries;
67460
+ try {
67461
+ entries = await readdir2(treesRoot);
67462
+ } catch {
67463
+ return;
67464
+ }
67465
+ await Promise.all(
67466
+ entries.filter(
67467
+ (entry) => entry.startsWith(TEMP_FETCH_PREFIX) || entry.startsWith(TEMP_PRUNE_PREFIX)
67468
+ ).map((entry) => rm(join44(treesRoot, entry), { recursive: true, force: true }))
67469
+ );
67470
+ }
67471
+ /**
67472
+ * Fetch into a unique temp directory, key it by the reported commit, and
67473
+ * atomically promote it onto that entry. Cleans up the temp directory on
67474
+ * any failure.
67081
67475
  *
67082
67476
  * @internal
67083
67477
  */
67084
- async cloneAndPromote(finalPath, clone2) {
67085
- const packagesRoot = join43(this.cacheRoot, "packages");
67086
- await mkdir3(packagesRoot, { recursive: true });
67087
- const tempDir = await mkdtemp(join43(packagesRoot, ".tmp-clone-"));
67478
+ async fetchAndPromote(packageName, subpath, fetch2) {
67479
+ const treesRoot = join44(this.cacheRoot, TREES_DIRNAME);
67480
+ await mkdir3(treesRoot, { recursive: true });
67481
+ const tempDir = await mkdtemp(join44(treesRoot, TEMP_FETCH_PREFIX));
67482
+ let commitSha;
67483
+ let finalPath;
67088
67484
  try {
67089
- await clone2(tempDir);
67485
+ commitSha = await fetch2(tempDir);
67486
+ if (!isFullCommitSha(commitSha)) {
67487
+ throw new Error(
67488
+ `Refused to cache ${packageName}: the fetch reported "${commitSha}", which is not a full commit id`
67489
+ );
67490
+ }
67491
+ finalPath = this.packageDir(packageName, commitSha, subpath);
67090
67492
  } catch (err) {
67091
67493
  await rm(tempDir, { recursive: true, force: true });
67092
67494
  throw err;
67093
67495
  }
67094
- if (await isNonEmptyDir(finalPath)) {
67496
+ const landedOurs = await this.exclusive(async () => {
67497
+ if (await isNonEmptyDir(finalPath)) {
67498
+ await stampUsed(finalPath);
67499
+ return false;
67500
+ }
67501
+ await rm(finalPath, { recursive: true, force: true });
67502
+ await rename(tempDir, finalPath);
67503
+ await stampUsed(finalPath);
67504
+ return true;
67505
+ });
67506
+ if (landedOurs) {
67507
+ for (const listener of this.entryWrittenListeners) listener();
67508
+ } else {
67095
67509
  await rm(tempDir, { recursive: true, force: true });
67096
- return finalPath;
67097
67510
  }
67098
- await rm(finalPath, { recursive: true, force: true });
67099
- await rename(tempDir, finalPath);
67100
- return finalPath;
67511
+ return { path: finalPath, commitSha };
67512
+ }
67513
+ /**
67514
+ * Be told each time a fetch lands a new entry: the one way the cache grows,
67515
+ * so the one signal its retention owner needs. Not called for a cache hit,
67516
+ * a failed fetch, or a tree that was already there when the fetch landed.
67517
+ *
67518
+ * @param listener - Called synchronously after the entry is in place. It
67519
+ * must not throw; start any work it triggers in the background.
67520
+ * @returns A function that stops the notifications.
67521
+ */
67522
+ onEntryWritten(listener) {
67523
+ this.entryWrittenListeners.add(listener);
67524
+ return () => {
67525
+ this.entryWrittenListeners.delete(listener);
67526
+ };
67527
+ }
67528
+ /**
67529
+ * Remove every entry the caller's rule does not keep and that nobody has
67530
+ * used in the last {@link IN_USE_GRACE_MS}. The grace is not the caller's to
67531
+ * waive: it is this cache's promise to everyone it handed a path.
67532
+ *
67533
+ * Each removal re-checks the stamp and renames the entry aside to
67534
+ * `.tmp-prune-*` under the lock, then measures and deletes the renamed copy
67535
+ * outside it. A reader that stamps first keeps its entry; one that comes
67536
+ * after the rename sees a miss and fetches. In-progress fetches
67537
+ * (`.tmp-fetch-*`) are never entries, so never candidates.
67538
+ *
67539
+ * @param keep - Given every entry, returns the paths to keep. Called once,
67540
+ * with the listing this call works from.
67541
+ * @returns What was removed, the bytes freed, and any entry that could not be
67542
+ * removed (the others still are).
67543
+ */
67544
+ async removeUnused(keep) {
67545
+ const treesRoot = join44(this.cacheRoot, TREES_DIRNAME);
67546
+ const entries = await this.listPackages();
67547
+ const kept = keep(entries);
67548
+ const result2 = { removed: [], freedBytes: 0, failed: [] };
67549
+ for (const entry of entries) {
67550
+ if (kept.has(entry.path)) continue;
67551
+ try {
67552
+ const aside = await this.exclusive(async () => {
67553
+ let lastUsedMs;
67554
+ try {
67555
+ lastUsedMs = (await stat(entry.path)).mtimeMs;
67556
+ } catch {
67557
+ return null;
67558
+ }
67559
+ if (Date.now() - lastUsedMs < IN_USE_GRACE_MS) return null;
67560
+ const target = join44(treesRoot, `${TEMP_PRUNE_PREFIX}${randomUUID2()}`);
67561
+ await rename(entry.path, target);
67562
+ return target;
67563
+ });
67564
+ if (aside === null) continue;
67565
+ const bytes = await directorySize(aside);
67566
+ await rm(aside, { recursive: true, force: true });
67567
+ result2.removed.push(entry);
67568
+ result2.freedBytes += bytes;
67569
+ } catch (err) {
67570
+ result2.failed.push({ entry, error: err instanceof Error ? err.message : String(err) });
67571
+ }
67572
+ }
67573
+ return result2;
67574
+ }
67575
+ /**
67576
+ * Stamp `path` as used now if it holds a valid entry, as one step under the
67577
+ * lock.
67578
+ *
67579
+ * @returns When it was stamped, or `null` when there is no valid entry.
67580
+ * @internal
67581
+ */
67582
+ stampIfPresent(path43) {
67583
+ return this.exclusive(async () => {
67584
+ if (!await isNonEmptyDir(path43)) return null;
67585
+ return stampUsed(path43);
67586
+ });
67587
+ }
67588
+ /**
67589
+ * Run `fn` with no other critical section of this cache running. Sections
67590
+ * are a few system calls each, so a promise chain is all the lock needs.
67591
+ *
67592
+ * @internal
67593
+ */
67594
+ exclusive(fn) {
67595
+ const run = this.lockTail.then(fn);
67596
+ this.lockTail = run.then(
67597
+ () => void 0,
67598
+ () => void 0
67599
+ );
67600
+ return run;
67101
67601
  }
67102
67602
  /**
67103
67603
  * Enumerate every cached package across all names and SHAs. Entries whose
67104
- * directory name does not match the `${name}@${sha}` convention are
67105
- * silently skipped.
67604
+ * directory name does not match the `${name}@${sha}` convention (including
67605
+ * in-progress fetches and entries being removed) are silently skipped.
67606
+ * Listing is not use: it stamps nothing.
67106
67607
  */
67107
67608
  async listPackages() {
67108
- const root = join43(this.cacheRoot, "packages");
67609
+ const root = join44(this.cacheRoot, TREES_DIRNAME);
67109
67610
  let entries;
67110
67611
  try {
67111
- entries = await readdir(root);
67612
+ entries = await readdir2(root);
67112
67613
  } catch {
67113
67614
  return [];
67114
67615
  }
67115
67616
  const results = [];
67116
67617
  for (const entry of entries) {
67618
+ if (entry.startsWith(TEMP_FETCH_PREFIX) || entry.startsWith(TEMP_PRUNE_PREFIX)) continue;
67117
67619
  const parsed = parsePackageDirName(entry);
67118
67620
  if (!parsed) {
67119
67621
  continue;
67120
67622
  }
67121
- const path43 = join43(root, entry);
67623
+ const path43 = join44(root, entry);
67122
67624
  try {
67123
67625
  const info2 = await stat(path43);
67124
67626
  if (!info2.isDirectory()) {
@@ -67127,37 +67629,15 @@ var init_marketplace_cache = __esm({
67127
67629
  results.push({
67128
67630
  packageName: parsed.packageName,
67129
67631
  commitSha: parsed.commitSha,
67632
+ subpathDigest: parsed.subpathDigest,
67130
67633
  path: path43,
67131
- cachedAt: info2.mtime
67634
+ lastUsedAt: info2.mtime
67132
67635
  });
67133
67636
  } catch {
67134
67637
  }
67135
67638
  }
67136
67639
  return results;
67137
67640
  }
67138
- /**
67139
- * Garbage-collect cached packages. Groups every cached package by name,
67140
- * sorts each group by `cachedAt` descending, and removes everything past
67141
- * the `keepLastN`-th entry.
67142
- *
67143
- * @param opts - Pruning options. `keepLastN` defaults to `1` (keep only
67144
- * the most recently cached SHA per package name).
67145
- * @returns The list of removed package descriptors.
67146
- */
67147
- async prune(opts) {
67148
- const keepLastN = opts?.keepLastN ?? 1;
67149
- const grouped = groupByPackageName(await this.listPackages());
67150
- const removed = [];
67151
- for (const group of grouped.values()) {
67152
- group.sort((a2, b2) => b2.cachedAt.getTime() - a2.cachedAt.getTime());
67153
- const toRemove = group.slice(keepLastN);
67154
- for (const pkg of toRemove) {
67155
- await rm(pkg.path, { recursive: true, force: true });
67156
- removed.push(pkg);
67157
- }
67158
- }
67159
- return { removed };
67160
- }
67161
67641
  /** Wipe the entire cache directory. No-op when the directory does not exist. */
67162
67642
  async clear() {
67163
67643
  await rm(this.cacheRoot, { recursive: true, force: true });
@@ -67169,11 +67649,15 @@ var init_marketplace_cache = __esm({
67169
67649
  * the cache.
67170
67650
  */
67171
67651
  marketplaceDir(marketplaceName) {
67172
- const root = join43(this.cacheRoot, "marketplaces");
67173
- return assertContainedIn(root, join43(root, marketplaceName));
67652
+ const root = join44(this.cacheRoot, "marketplaces");
67653
+ return assertContainedIn(root, join44(root, marketplaceName));
67174
67654
  }
67175
67655
  /**
67176
- * Compute the directory path for a content-addressable package clone.
67656
+ * Compute the directory path for a content-addressable package tree:
67657
+ * `${name}@${sha}` for a whole repository, `${name}@${sha}~${digest}` for a
67658
+ * sparse checkout of `subpath`, the digest being the first 12 hex digits of
67659
+ * the subfolder's SHA-256 (a path may hold characters a directory name
67660
+ * cannot, and its length is unbounded).
67177
67661
  *
67178
67662
  * The containment assertion is the belt to the resolver's braces. Both halves
67179
67663
  * of this key are caller-influenced — the package name comes from the install
@@ -67185,9 +67669,11 @@ var init_marketplace_cache = __esm({
67185
67669
  * @throws {PathEscapeError} When the key would place the directory outside
67186
67670
  * the cache.
67187
67671
  */
67188
- packageDir(packageName, commitSha) {
67189
- const root = join43(this.cacheRoot, "packages");
67190
- return assertContainedIn(root, join43(root, `${packageName}@${commitSha}`));
67672
+ packageDir(packageName, commitSha, subpath) {
67673
+ const root = join44(this.cacheRoot, TREES_DIRNAME);
67674
+ const digest2 = subpathDigest(subpath);
67675
+ const tree = digest2 === "" ? "" : `${SUBPATH_SEPARATOR}${digest2}`;
67676
+ return assertContainedIn(root, join44(root, `${packageName}@${commitSha}${tree}`));
67191
67677
  }
67192
67678
  };
67193
67679
  }
@@ -67195,13 +67681,13 @@ var init_marketplace_cache = __esm({
67195
67681
 
67196
67682
  // ../shared/src/atomic-write.ts
67197
67683
  import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
67198
- import { randomUUID as randomUUID2 } from "node:crypto";
67684
+ import { randomUUID as randomUUID3 } from "node:crypto";
67199
67685
  import { chmod, mkdir as mkdir4, rename as rename2, rm as rm2, writeFile as writeFile4 } from "node:fs/promises";
67200
- import { basename as basename6, dirname as dirname11, join as join44, resolve as resolve9 } from "node:path";
67686
+ import { basename as basename6, dirname as dirname11, join as join45, resolve as resolve9 } from "node:path";
67201
67687
  async function writeUnlocked(filePath, data, options) {
67202
67688
  const dir = dirname11(filePath);
67203
67689
  await mkdir4(dir, { recursive: true });
67204
- const tempPath = join44(dir, `.${basename6(filePath)}.${process.pid}.${randomUUID2()}.tmp`);
67690
+ const tempPath = join45(dir, `.${basename6(filePath)}.${process.pid}.${randomUUID3()}.tmp`);
67205
67691
  try {
67206
67692
  await writeFile4(tempPath, data, {
67207
67693
  encoding: "utf-8",
@@ -67305,7 +67791,7 @@ var init_source_url_policy = __esm({
67305
67791
 
67306
67792
  // ../../apps/server/src/services/marketplace/marketplace-source-manager.ts
67307
67793
  import { readFile as readFile4 } from "node:fs/promises";
67308
- import { join as join45 } from "node:path";
67794
+ import { join as join46 } from "node:path";
67309
67795
  function buildDefaultSources() {
67310
67796
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
67311
67797
  return [
@@ -67365,7 +67851,7 @@ var init_marketplace_source_manager = __esm({
67365
67851
  */
67366
67852
  constructor(dorkHome) {
67367
67853
  this.dorkHome = dorkHome;
67368
- this.filePath = join45(dorkHome, MARKETPLACES_FILENAME);
67854
+ this.filePath = join46(dorkHome, MARKETPLACES_FILENAME);
67369
67855
  }
67370
67856
  dorkHome;
67371
67857
  filePath;
@@ -67800,7 +68286,7 @@ __export(harness_sync_command_exports, {
67800
68286
  runHarnessSync: () => runHarnessSync
67801
68287
  });
67802
68288
  import { existsSync as existsSync17, readFileSync as readFileSync20 } from "node:fs";
67803
- import { join as join46 } from "node:path";
68289
+ import { join as join47 } from "node:path";
67804
68290
  import { parseArgs as parseArgs3 } from "node:util";
67805
68291
  function parseHarnessSyncArgs(rawArgs) {
67806
68292
  let parsed;
@@ -67927,7 +68413,7 @@ function reportCodexTrust(before, after) {
67927
68413
  }
67928
68414
  function reportClaudeSkillsRestart(existedBefore, repoRoot) {
67929
68415
  if (existedBefore) return;
67930
- if (!existsSync17(join46(repoRoot, CLAUDE_SKILLS_DIR))) return;
68416
+ if (!existsSync17(join47(repoRoot, CLAUDE_SKILLS_DIR))) return;
67931
68417
  const facts = skillsFactsFor("claude-code");
67932
68418
  console.log("");
67933
68419
  console.log(`Created ${CLAUDE_SKILLS_DIR}/, which is where Claude Code reads skills.`);
@@ -67938,7 +68424,7 @@ function reportClaudeSkillsRestart(existedBefore, repoRoot) {
67938
68424
  }
67939
68425
  function readIfPresent(repoRoot, rel) {
67940
68426
  try {
67941
- return readFileSync20(join46(repoRoot, rel), "utf8");
68427
+ return readFileSync20(join47(repoRoot, rel), "utf8");
67942
68428
  } catch {
67943
68429
  return void 0;
67944
68430
  }
@@ -68265,7 +68751,7 @@ async function runHarnessSync(args) {
68265
68751
  }
68266
68752
  const repoRoot = process.cwd();
68267
68753
  const ourHarness = await readDorkosHarness(resolveDorkHome2());
68268
- if (!existsSync17(join46(repoRoot, HARNESS_MANIFEST_PATH))) {
68754
+ if (!existsSync17(join47(repoRoot, HARNESS_MANIFEST_PATH))) {
68269
68755
  if (!args.fix) {
68270
68756
  console.error(`No harness manifest in ${repoRoot}`);
68271
68757
  console.error(` looked for: ${HARNESS_MANIFEST_PATH}`);
@@ -68345,7 +68831,7 @@ async function runHarnessSync(args) {
68345
68831
  return { exitCode: strictExit(exitCode2, withheld, args.strict) };
68346
68832
  }
68347
68833
  const codexHooksBefore = readIfPresent(repoRoot, CODEX_HOOKS_TARGET);
68348
- const claudeSkillsExistedBefore = existsSync17(join46(repoRoot, CLAUDE_SKILLS_DIR));
68834
+ const claudeSkillsExistedBefore = existsSync17(join47(repoRoot, CLAUDE_SKILLS_DIR));
68349
68835
  const result2 = projectWithConsent2(repoRoot, {
68350
68836
  ...consentOpts,
68351
68837
  sweepOrphans: harnessFilter === void 0
@@ -68403,7 +68889,7 @@ __export(harness_adopt_command_exports, {
68403
68889
  runHarnessAdopt: () => runHarnessAdopt
68404
68890
  });
68405
68891
  import { existsSync as existsSync18 } from "node:fs";
68406
- import { join as join47, resolve as resolve10 } from "node:path";
68892
+ import { join as join48, resolve as resolve10 } from "node:path";
68407
68893
  import { parseArgs as parseArgs4 } from "node:util";
68408
68894
  function parseHarnessAdoptArgs(rawArgs) {
68409
68895
  let parsed;
@@ -68444,7 +68930,7 @@ ${USAGE_LINE6}`
68444
68930
  }
68445
68931
  async function runHarnessAdopt(args) {
68446
68932
  const repoRoot = args.project === void 0 ? process.cwd() : resolve10(process.cwd(), args.project);
68447
- if (!existsSync18(join47(repoRoot, HARNESS_MANIFEST_PATH))) {
68933
+ if (!existsSync18(join48(repoRoot, HARNESS_MANIFEST_PATH))) {
68448
68934
  console.error(`No harness manifest in ${repoRoot}`);
68449
68935
  console.error(` looked for: ${HARNESS_MANIFEST_PATH}`);
68450
68936
  console.error("");
@@ -68969,31 +69455,16 @@ function parseCacheListArgs(rawArgs) {
68969
69455
  }
68970
69456
  }
68971
69457
  function parseCachePruneArgs(rawArgs) {
68972
- let parsed;
68973
69458
  try {
68974
- parsed = parseArgs6({
69459
+ parseArgs6({
68975
69460
  args: rawArgs,
68976
- options: {
68977
- "keep-last-n": { type: "string" }
68978
- },
69461
+ options: {},
68979
69462
  allowPositionals: false,
68980
69463
  strict: true
68981
69464
  });
68982
69465
  } catch (err) {
68983
69466
  rethrowUnknownOption(err, "cache prune", PRUNE_USAGE);
68984
69467
  }
68985
- const raw = parsed.values["keep-last-n"];
68986
- if (raw === void 0) {
68987
- return {};
68988
- }
68989
- const parsedNumber = Number(raw);
68990
- if (!Number.isInteger(parsedNumber) || parsedNumber < 0) {
68991
- throw new Error(
68992
- `Invalid value for --keep-last-n: '${String(raw)}' (expected a non-negative integer).
68993
- ${PRUNE_USAGE}`
68994
- );
68995
- }
68996
- return { keepLastN: parsedNumber };
68997
69468
  }
68998
69469
  function parseCacheClearArgs(rawArgs) {
68999
69470
  let parsed;
@@ -69019,11 +69490,17 @@ function renderCacheStatus(status) {
69019
69490
  ];
69020
69491
  const labelWidth = Math.max(...rows.map((r3) => r3[0].length));
69021
69492
  const valueWidth = Math.max(...rows.map((r3) => r3[1].length));
69022
- return rows.map(([label, value]) => {
69493
+ const lines = rows.map(([label, value]) => {
69023
69494
  const paddedLabel = label + " ".repeat(labelWidth - label.length);
69024
69495
  const paddedValue = " ".repeat(valueWidth - value.length) + value;
69025
69496
  return `${paddedLabel} ${paddedValue}`;
69026
- }).join("\n");
69497
+ });
69498
+ if (status.cleanup?.paused) {
69499
+ lines.push(
69500
+ `Automatic cleanup is paused: ${status.cleanup.reason ?? "the server log says why"}`
69501
+ );
69502
+ }
69503
+ return lines.join("\n");
69027
69504
  }
69028
69505
  async function runCacheList() {
69029
69506
  try {
@@ -69039,17 +69516,18 @@ async function runCacheList() {
69039
69516
  return 1;
69040
69517
  }
69041
69518
  }
69042
- async function runCachePrune(args) {
69519
+ async function runCachePrune() {
69043
69520
  try {
69044
- const body = args.keepLastN !== void 0 ? { keepLastN: args.keepLastN } : {};
69045
- const result2 = await apiCall("POST", "/api/marketplace/cache/prune", body);
69521
+ const result2 = await apiCall("POST", "/api/marketplace/cache/prune", {});
69046
69522
  const count2 = result2.removed.length;
69047
69523
  if (count2 === 0) {
69048
- console.log("Nothing to prune \u2014 cache is already minimal.");
69524
+ console.log(
69525
+ "Nothing to remove. Everything cached belongs to an installed package or was used in the last 15 minutes."
69526
+ );
69049
69527
  return 0;
69050
69528
  }
69051
69529
  const noun = count2 === 1 ? "package" : "packages";
69052
- console.log(`Pruned ${count2} cached ${noun}, freed ${formatBytes(result2.freedBytes)}.`);
69530
+ console.log(`Removed ${count2} cached ${noun}, freed ${formatBytes(result2.freedBytes)}.`);
69053
69531
  return 0;
69054
69532
  } catch (err) {
69055
69533
  if (err instanceof ApiError) {
@@ -69093,7 +69571,7 @@ var init_cache_commands = __esm({
69093
69571
  init_confirm_prompt();
69094
69572
  init_parse_args_error();
69095
69573
  LIST_USAGE = "Usage: dorkos cache list";
69096
- PRUNE_USAGE = "Usage: dorkos cache prune [--keep-last-n <N>]";
69574
+ PRUNE_USAGE = "Usage: dorkos cache prune";
69097
69575
  CLEAR_USAGE = "Usage: dorkos cache clear [-y|--yes]";
69098
69576
  }
69099
69577
  });
@@ -69122,7 +69600,8 @@ async function runCacheDispatcher(subcommand2, subArgs) {
69122
69600
  return await runCacheList2();
69123
69601
  }
69124
69602
  if (subcommand2 === "prune") {
69125
- return await runCachePrune2(parseCachePruneArgs2(subArgs));
69603
+ parseCachePruneArgs2(subArgs);
69604
+ return await runCachePrune2();
69126
69605
  }
69127
69606
  if (subcommand2 === "clear") {
69128
69607
  return await runCacheClear2(parseCacheClearArgs2(subArgs));
@@ -69146,13 +69625,13 @@ Inspect and manage the marketplace package cache on the running DorkOS server.
69146
69625
 
69147
69626
  Subcommands:
69148
69627
  list Show cache counts and total size
69149
- prune [--keep-last-n <N>] Remove older cached package SHAs (default: keep 1)
69628
+ prune Remove cached packages no install needs
69629
+ (DorkOS also does this on its own)
69150
69630
  clear [-y|--yes] Wipe the entire cache (requires confirmation)
69151
69631
 
69152
69632
  Examples:
69153
69633
  dorkos cache list
69154
69634
  dorkos cache prune
69155
- dorkos cache prune --keep-last-n 3
69156
69635
  dorkos cache clear --yes
69157
69636
  `;
69158
69637
  }
@@ -70349,45 +70828,6 @@ https://dorkos.ai/docs/guides/agent-browser
70349
70828
  }
70350
70829
  });
70351
70830
 
70352
- // ../shared/src/marketplace-schemas.ts
70353
- function describeSchedulePermissionMode(mode) {
70354
- return SCHEDULE_PERMISSION_MODE_SUMMARY[mode] ?? `runs in "${mode}" mode, which this version of DorkOS does not recognise`;
70355
- }
70356
- function describeScheduleArrival(startsEnabled) {
70357
- return startsEnabled ? "waits for your approval before its first run" : "arrives switched off, and would wait for your approval too";
70358
- }
70359
- function describeHookEvent(event, matcher) {
70360
- const when = HOOK_EVENT_SUMMARY[event] ?? `on ${event}`;
70361
- return matcher ? `${when} (${matcher})` : when;
70362
- }
70363
- var SCHEDULE_PERMISSION_MODE_SUMMARY, HOOK_EVENT_SUMMARY;
70364
- var init_marketplace_schemas = __esm({
70365
- "../shared/src/marketplace-schemas.ts"() {
70366
- SCHEDULE_PERMISSION_MODE_SUMMARY = {
70367
- default: "runs at the most careful setting its agent offers",
70368
- plan: "can only read and plan, and cannot change anything",
70369
- acceptEdits: "can change files on its own, and on some agents run commands too",
70370
- dontAsk: "runs its tools without a permission prompt",
70371
- bypassPermissions: "can run any command without a permission prompt",
70372
- auto: "decides for itself which actions are safe to take"
70373
- };
70374
- HOOK_EVENT_SUMMARY = {
70375
- SessionStart: "when a session starts",
70376
- SessionEnd: "when a session ends",
70377
- UserPromptSubmit: "when you send a message",
70378
- PreToolUse: "before the agent uses a tool",
70379
- PostToolUse: "after the agent uses a tool",
70380
- PermissionRequest: "when the agent asks for permission",
70381
- Notification: "when the agent sends a notification",
70382
- SubagentStart: "when a subagent starts",
70383
- SubagentStop: "when a subagent finishes",
70384
- Stop: "when the agent finishes",
70385
- PreCompact: "before the conversation is shortened",
70386
- PostCompact: "after the conversation is shortened"
70387
- };
70388
- }
70389
- });
70390
-
70391
70831
  // src/lib/preview-render.ts
70392
70832
  function renderPreview(packageName, version4, preview) {
70393
70833
  const lines = [];
@@ -70738,62 +71178,112 @@ function parseUpdateArgs(rawArgs) {
70738
71178
  }
70739
71179
  async function runUpdate(args) {
70740
71180
  try {
70741
- const targets = args.name ? [args.name] : await listInstalledPackageNames();
70742
- if (targets.length === 0) {
70743
- console.log("No installed packages to check.");
70744
- return 0;
70745
- }
70746
- const allChecks = [];
70747
- const allApplied = [];
70748
- for (const name of targets) {
70749
- const body = { apply: Boolean(args.apply) };
70750
- if (args.projectPath) body.projectPath = args.projectPath;
70751
- const result2 = await apiCall(
70752
- "POST",
70753
- `/api/marketplace/packages/${encodeURIComponent(name)}/update`,
70754
- body
70755
- );
70756
- allChecks.push(...result2.checks);
70757
- allApplied.push(...result2.applied);
70758
- }
70759
- renderUpdateChecks(allChecks, Boolean(args.apply));
70760
- if (args.apply && allApplied.length > 0) {
70761
- console.log("");
70762
- console.log("Applied:");
70763
- for (const a2 of allApplied) {
70764
- console.log(` ${a2.packageName}@${a2.version} \u2192 ${a2.installPath}`);
70765
- }
70766
- }
70767
- return 0;
71181
+ return args.name ? await updateOne(args.name, args) : await updateAll(args);
70768
71182
  } catch (err) {
70769
- if (err instanceof ApiError) {
70770
- console.error(`Error: ${err.message}`);
70771
- } else {
70772
- console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
70773
- }
71183
+ console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
70774
71184
  return 1;
70775
71185
  }
70776
71186
  }
70777
- async function listInstalledPackageNames() {
70778
- const installed = await apiCall("GET", "/api/marketplace/installed");
70779
- return installed.packages.map((p) => p.name);
71187
+ async function updateOne(name, args) {
71188
+ const body = { apply: Boolean(args.apply) };
71189
+ if (args.projectPath) body.projectPath = args.projectPath;
71190
+ let result2;
71191
+ try {
71192
+ result2 = await apiCall(
71193
+ "POST",
71194
+ `/api/marketplace/packages/${encodeURIComponent(name)}/update`,
71195
+ body
71196
+ );
71197
+ } catch (err) {
71198
+ if (!(err instanceof ApiError)) throw err;
71199
+ renderUpdateChecks([couldNotCheck(name, err.message)], Boolean(args.apply));
71200
+ return err.status === 404 || args.apply ? 1 : 0;
71201
+ }
71202
+ renderUpdateChecks(result2.checks, Boolean(args.apply));
71203
+ if (args.apply && result2.applied.length > 0) {
71204
+ console.log("");
71205
+ console.log("Applied:");
71206
+ for (const a2 of result2.applied)
71207
+ console.log(` ${a2.packageName}@${a2.version} \u2192 ${a2.installPath}`);
71208
+ }
71209
+ return 0;
70780
71210
  }
70781
- function renderUpdateChecks(checks, apply) {
70782
- const pending = checks.filter((c3) => c3.hasUpdate);
70783
- const upToDate = checks.length - pending.length;
70784
- if (pending.length === 0) {
70785
- console.log(`All ${checks.length} package(s) up to date.`);
70786
- return;
71211
+ async function updateAll(args) {
71212
+ const result2 = args.apply ? await apiCall("POST", "/api/marketplace/updates", {
71213
+ apply: true,
71214
+ ...args.projectPath && { projectPath: args.projectPath }
71215
+ }) : await apiCall(
71216
+ "GET",
71217
+ `/api/marketplace/updates${args.projectPath ? `?projectPath=${encodeURIComponent(args.projectPath)}` : ""}`
71218
+ );
71219
+ if (result2.checks.length === 0) {
71220
+ console.log("No installed packages to check.");
71221
+ return 0;
70787
71222
  }
70788
- for (const check4 of pending) {
70789
- const suffix = apply ? "" : " (run with --apply to update)";
70790
- console.log(
70791
- `${check4.packageName}: ${check4.installedVersion} \u2192 ${check4.latestVersion}${suffix}`
70792
- );
71223
+ renderUpdateChecks(result2.checks, Boolean(args.apply));
71224
+ const applied = result2.checks.flatMap(
71225
+ (c3) => c3.applied ? [{ check: c3, result: c3.applied }] : []
71226
+ );
71227
+ if (applied.length > 0) {
71228
+ console.log("");
71229
+ console.log("Applied:");
71230
+ for (const { check: check4, result: a2 } of applied) {
71231
+ console.log(` ${labelOf(check4)}@${a2.version} \u2192 ${a2.installPath}`);
71232
+ }
71233
+ }
71234
+ const failed = result2.checks.filter((c3) => c3.applyError !== void 0);
71235
+ if (failed.length > 0) {
71236
+ console.log("");
71237
+ console.log("Could not update:");
71238
+ for (const c3 of failed) console.log(` ${labelOf(c3)}: ${c3.applyError}`);
70793
71239
  }
70794
- if (upToDate > 0) {
70795
- console.log(`${upToDate} package(s) already up to date.`);
71240
+ return failed.length > 0 ? 1 : 0;
71241
+ }
71242
+ function couldNotCheck(packageName, reason) {
71243
+ return {
71244
+ packageName,
71245
+ installedVersion: "",
71246
+ latestVersion: "",
71247
+ hasUpdate: false,
71248
+ marketplace: "",
71249
+ status: "unknown",
71250
+ note: reason
71251
+ };
71252
+ }
71253
+ function labelOf(check4) {
71254
+ const place2 = check4.agentName ?? check4.agentPath;
71255
+ return place2 ? `${check4.packageName} [${place2}]` : check4.packageName;
71256
+ }
71257
+ function formatVersion(version4, source) {
71258
+ return source === "commit" ? `commit ${version4.slice(0, 7)}` : version4;
71259
+ }
71260
+ function renderUpdateChecks(checks, apply) {
71261
+ for (const check4 of checks) {
71262
+ const label = labelOf(check4);
71263
+ const installed = formatVersion(check4.installedVersion, check4.installedVersionSource);
71264
+ if (check4.status === "unknown") {
71265
+ console.log(`${label} could not check: ${check4.note ?? "no reason given"}`);
71266
+ continue;
71267
+ }
71268
+ if (check4.status === "update-available") {
71269
+ const latest = formatVersion(check4.latestVersion, check4.latestVersionSource);
71270
+ const from = check4.marketplace ? ` (${check4.marketplace})` : "";
71271
+ console.log(`${label} ${installed} \u2192 ${latest}${from}`);
71272
+ } else {
71273
+ console.log(`${label} up to date (${installed})`);
71274
+ }
71275
+ if (check4.note) console.log(` ${check4.note}`);
70796
71276
  }
71277
+ const updates = checks.filter((c3) => c3.status === "update-available").length;
71278
+ const current = checks.filter((c3) => c3.status === "current").length;
71279
+ const unknown2 = checks.filter((c3) => c3.status === "unknown").length;
71280
+ const parts = [
71281
+ updates > 0 && `${updates} ${updates === 1 ? "update" : "updates"} available`,
71282
+ current > 0 && `${current} up to date`,
71283
+ unknown2 > 0 && `${unknown2} could not be checked`
71284
+ ].filter(Boolean);
71285
+ const hint = !apply && updates > 0 ? ` Run again with --apply to install ${updates === 1 ? "it" : "them"}.` : "";
71286
+ console.log(`${parts.join(", ")}.${hint}`);
70797
71287
  }
70798
71288
  var USAGE_LINE10;
70799
71289
  var init_update2 = __esm({
@@ -71498,7 +71988,7 @@ var init_provider_process = __esm({
71498
71988
  // src/commands/community-deploy/runtime/github-release-source.ts
71499
71989
  import { mkdtemp as mkdtemp2, rm as rm3, writeFile as writeFile5 } from "node:fs/promises";
71500
71990
  import { tmpdir as tmpdir2 } from "node:os";
71501
- import { join as join48 } from "node:path";
71991
+ import { join as join49 } from "node:path";
71502
71992
  function createGitHubCommunityReleaseSource(options) {
71503
71993
  const verify = async (subject, trusted) => {
71504
71994
  await runProviderCommand({
@@ -71544,8 +72034,8 @@ function createGitHubCommunityReleaseSource(options) {
71544
72034
  return result2.value;
71545
72035
  },
71546
72036
  verifyManifest: async (bytes, trusted) => {
71547
- const directory = await mkdtemp2(join48(tmpdir2(), "dorkos-community-manifest-"));
71548
- const path43 = join48(directory, "manifest.json");
72037
+ const directory = await mkdtemp2(join49(tmpdir2(), "dorkos-community-manifest-"));
72038
+ const path43 = join49(directory, "manifest.json");
71549
72039
  try {
71550
72040
  await writeFile5(path43, bytes, { mode: 384, flag: "wx" });
71551
72041
  return await verify(path43, trusted);
@@ -71564,7 +72054,7 @@ var init_github_release_source = __esm({
71564
72054
  });
71565
72055
 
71566
72056
  // src/commands/community-deploy/plan.ts
71567
- import { createHash as createHash3 } from "node:crypto";
72057
+ import { createHash as createHash4 } from "node:crypto";
71568
72058
  function createLaunchPlan(input4) {
71569
72059
  const parsed = LaunchPlanInputSchema.parse(input4);
71570
72060
  Object.freeze(parsed.fly);
@@ -71594,7 +72084,7 @@ function hashLaunchPlan(plan) {
71594
72084
  private: plan.tigris.private
71595
72085
  }
71596
72086
  });
71597
- return createHash3("sha256").update(canonical, "utf8").digest("hex");
72087
+ return createHash4("sha256").update(canonical, "utf8").digest("hex");
71598
72088
  }
71599
72089
  var SafeIdentifierSchema, DisplayNameSchema, RegionSchema, Sha256DigestSchema, LaunchPlanInputSchema;
71600
72090
  var init_plan2 = __esm({
@@ -71845,13 +72335,21 @@ async function readFlyRegions(options) {
71845
72335
  deprecated: region.deprecated
71846
72336
  }));
71847
72337
  }
72338
+ function toFlyAppIdentity(app) {
72339
+ return {
72340
+ id: app.ID,
72341
+ name: app.Name,
72342
+ organizationSlug: app.Organization.Slug,
72343
+ status: app.Status
72344
+ };
72345
+ }
71848
72346
  async function readFlyApps(options, organizationSlug) {
71849
72347
  const slug = ExternalIdentifierSchema.parse(organizationSlug);
71850
72348
  const apps = (await runProviderCommand({
71851
72349
  ...options,
71852
72350
  args: ["apps", "list", "--org", slug, "--json"],
71853
72351
  parse: (stdout3) => {
71854
- const parsed = external_exports.array(FlyAppSchema).parse(parseExternalJson(stdout3));
72352
+ const parsed = external_exports.array(FlyAppResponseSchema).parse(parseExternalJson(stdout3));
71855
72353
  requireUniqueExternalIds(parsed, (app) => app.ID);
71856
72354
  if (parsed.some((app) => app.Organization.Slug !== slug)) {
71857
72355
  throw new Error("ORGANIZATION_BINDING_MISMATCH");
@@ -71859,14 +72357,19 @@ async function readFlyApps(options, organizationSlug) {
71859
72357
  return parsed;
71860
72358
  }
71861
72359
  })).value;
71862
- return apps.map((app) => ({
71863
- id: app.ID,
71864
- name: app.Name,
71865
- organizationId: app.Organization.ID,
71866
- organizationSlug: app.Organization.Slug,
71867
- organizationName: app.Organization.Name,
71868
- status: app.Status
71869
- }));
72360
+ return apps.map(toFlyAppIdentity);
72361
+ }
72362
+ async function readFlyOrganizationId(options, organizationSlug) {
72363
+ const slug = ExternalIdentifierSchema.parse(organizationSlug);
72364
+ return (await runProviderCommand({
72365
+ ...options,
72366
+ args: ["orgs", "show", slug, "--json"],
72367
+ parse: (stdout3) => {
72368
+ const parsed = FlyOrganizationDetailSchema.parse(parseExternalJson(stdout3));
72369
+ if (parsed.Slug !== slug) throw new Error("ORGANIZATION_BINDING_MISMATCH");
72370
+ return parsed.ID;
72371
+ }
72372
+ })).value;
71870
72373
  }
71871
72374
  async function readFlyRuntimeInventory(options, appName) {
71872
72375
  const app = ExternalIdentifierSchema.parse(appName);
@@ -71927,7 +72430,7 @@ async function readFlyRuntimeInventory(options, appName) {
71927
72430
  }))
71928
72431
  };
71929
72432
  }
71930
- var FlyIdentitySchema, FlyOrganizationsSchema, FlyRegionSchema, FlyAppSchema, FlyImageDigestSchema, FlyImageComponentSchema, FlyMachineSchema, FlyReleaseSchema, FlyIpSchema;
72433
+ var FlyIdentitySchema, FlyOrganizationsSchema, FlyRegionSchema, FlyAppResponseSchema, FlyOrganizationDetailSchema, FlyImageDigestSchema, FlyImageComponentSchema, FlyMachineSchema, FlyReleaseSchema, FlyIpSchema;
71931
72434
  var init_fly_read = __esm({
71932
72435
  "src/commands/community-deploy/fly-read.ts"() {
71933
72436
  "use strict";
@@ -71945,16 +72448,13 @@ var init_fly_read = __esm({
71945
72448
  requires_paid_plan: external_exports.boolean(),
71946
72449
  deprecated: external_exports.boolean()
71947
72450
  }).passthrough();
71948
- FlyAppSchema = external_exports.object({
72451
+ FlyAppResponseSchema = external_exports.object({
71949
72452
  ID: ExternalIdentifierSchema,
71950
72453
  Name: ExternalIdentifierSchema,
71951
- Organization: external_exports.object({
71952
- ID: ExternalIdentifierSchema,
71953
- Slug: ExternalIdentifierSchema,
71954
- Name: ExternalLabelSchema
71955
- }).passthrough(),
71956
- Status: ExternalLabelSchema
72454
+ Organization: external_exports.object({ Slug: ExternalIdentifierSchema }).passthrough(),
72455
+ Status: external_exports.union([external_exports.literal(""), ExternalLabelSchema])
71957
72456
  }).passthrough();
72457
+ FlyOrganizationDetailSchema = external_exports.object({ ID: ExternalIdentifierSchema, Slug: ExternalIdentifierSchema }).passthrough();
71958
72458
  FlyImageDigestSchema = external_exports.string().regex(/^sha256:[0-9a-f]{64}$/u);
71959
72459
  FlyImageComponentSchema = external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9._/-]{0,511}$/u);
71960
72460
  FlyMachineSchema = external_exports.object({
@@ -72029,21 +72529,27 @@ async function createFlyApp(options, appName, organizationSlug) {
72029
72529
  ...options,
72030
72530
  args: ["apps", "create", app, "--org", organization2, "--json", "--yes"],
72031
72531
  parse: (stdout3) => {
72032
- const parsed = FlyCreatedAppSchema.parse(parseExternalJson(stdout3));
72033
- if (parsed.Name !== app || parsed.Organization.Slug !== organization2) {
72532
+ let document;
72533
+ try {
72534
+ document = parseExternalJson(stdout3);
72535
+ } catch {
72536
+ return null;
72537
+ }
72538
+ const parsed = FlyAppResponseSchema.safeParse(document);
72539
+ if (!parsed.success) return null;
72540
+ if (parsed.data.Name !== app || parsed.data.Organization.Slug !== organization2) {
72034
72541
  throw new Error("APP_BINDING_MISMATCH");
72035
72542
  }
72036
- return parsed;
72543
+ return toFlyAppIdentity(parsed.data);
72037
72544
  }
72038
72545
  });
72039
- return {
72040
- id: created.ID,
72041
- name: created.Name,
72042
- organizationId: created.Organization.ID,
72043
- organizationSlug: created.Organization.Slug,
72044
- organizationName: created.Organization.Name,
72045
- status: created.Status
72046
- };
72546
+ if (created) return created;
72547
+ const matches = await readFlyApps(options, organization2).catch(() => {
72548
+ throw new ProviderMutationError("CREATION_OUTCOME_UNCERTAIN");
72549
+ });
72550
+ const exact = matches.filter((candidate) => candidate.name === app);
72551
+ if (exact.length !== 1) throw new ProviderMutationError("CREATION_OUTCOME_UNCERTAIN");
72552
+ return exact[0];
72047
72553
  }
72048
72554
  async function stageFlySecrets(options, appName, secrets) {
72049
72555
  const app = parseInput(ExternalIdentifierSchema, appName);
@@ -72114,23 +72620,14 @@ function verifyExistingFlyDeployment(inventory, expectedRepository, expectedDige
72114
72620
  }
72115
72621
  return inventory;
72116
72622
  }
72117
- var FlyCreatedAppSchema, SecretNameSchema, ImageReferenceSchema;
72623
+ var SecretNameSchema, ImageReferenceSchema;
72118
72624
  var init_fly_mutate = __esm({
72119
72625
  "src/commands/community-deploy/fly-mutate.ts"() {
72120
72626
  "use strict";
72121
72627
  init_zod();
72122
72628
  init_provider_contract();
72123
72629
  init_provider_mutation();
72124
- FlyCreatedAppSchema = external_exports.object({
72125
- ID: ExternalIdentifierSchema,
72126
- Name: ExternalIdentifierSchema,
72127
- Status: ExternalLabelSchema,
72128
- Organization: external_exports.object({
72129
- ID: ExternalIdentifierSchema,
72130
- Slug: ExternalIdentifierSchema,
72131
- Name: ExternalLabelSchema
72132
- }).passthrough()
72133
- }).passthrough();
72630
+ init_fly_read();
72134
72631
  SecretNameSchema = external_exports.string().regex(/^[A-Za-z_][A-Za-z0-9_]{0,127}$/u);
72135
72632
  ImageReferenceSchema = external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9._/-]{0,511}@sha256:[0-9a-f]{64}$/u);
72136
72633
  }
@@ -73199,6 +73696,7 @@ function createDefaultCommunityCreationDependencies(input4) {
73199
73696
  if (!id) throw new ProviderMutationError("INVALID_RESPONSE");
73200
73697
  return exactFlyApp(input4.options, input4.plan.fly.organizationId, id, input4.plan.fly.appName);
73201
73698
  };
73699
+ let flyOrganizationId;
73202
73700
  return {
73203
73701
  persist: input4.persist,
73204
73702
  now: input4.now,
@@ -73258,15 +73756,23 @@ function createDefaultCommunityCreationDependencies(input4) {
73258
73756
  );
73259
73757
  if (!confirmed) throw new FlyGraphqlClientError("TERMS_NOT_ACCEPTED");
73260
73758
  }
73759
+ flyOrganizationId = await readFlyOrganizationId(
73760
+ input4.options.fly,
73761
+ input4.plan.fly.organizationId
73762
+ );
73261
73763
  },
73262
73764
  create: async () => {
73263
73765
  const exactApp = await app();
73766
+ const organizationId = flyOrganizationId ??= await readFlyOrganizationId(
73767
+ input4.options.fly,
73768
+ input4.plan.fly.organizationId
73769
+ );
73264
73770
  const created = await useTigrisClient(
73265
73771
  input4.options,
73266
73772
  (client2) => client2.createTigris({
73267
73773
  clientMutationId: input4.latestJournal().runId,
73268
73774
  name: input4.plan.tigris.bucketName,
73269
- organizationId: input4.plan.fly.organizationId,
73775
+ organizationId,
73270
73776
  appId: exactApp.id,
73271
73777
  primaryRegion: input4.plan.fly.region
73272
73778
  })
@@ -73304,7 +73810,7 @@ var init_default_services = __esm({
73304
73810
  // src/commands/community-deploy/fly-config.ts
73305
73811
  import { mkdtemp as mkdtemp3, rm as rm4, writeFile as writeFile6 } from "node:fs/promises";
73306
73812
  import { tmpdir as tmpdir3 } from "node:os";
73307
- import { join as join49 } from "node:path";
73813
+ import { join as join50 } from "node:path";
73308
73814
  function tomlString(value) {
73309
73815
  return JSON.stringify(value);
73310
73816
  }
@@ -73357,8 +73863,8 @@ kill_timeout = "30s"
73357
73863
  `;
73358
73864
  }
73359
73865
  async function withCommunityFlyConfig(plan, consumer) {
73360
- const directory = await mkdtemp3(join49(tmpdir3(), "dorkos-community-fly-"));
73361
- const path43 = join49(directory, "fly.toml");
73866
+ const directory = await mkdtemp3(join50(tmpdir3(), "dorkos-community-fly-"));
73867
+ const path43 = join50(directory, "fly.toml");
73362
73868
  try {
73363
73869
  await writeFile6(path43, renderCommunityFlyConfig(plan), { mode: 384, flag: "wx" });
73364
73870
  return await consumer(path43);
@@ -73506,7 +74012,7 @@ var init_default_deploy = __esm({
73506
74012
  // src/commands/community-deploy/runtime/default-owner.ts
73507
74013
  import { access, constants as constants4, stat as stat2 } from "node:fs/promises";
73508
74014
  import { platform as platform2 } from "node:os";
73509
- import { delimiter, join as join50 } from "node:path";
74015
+ import { delimiter, join as join51 } from "node:path";
73510
74016
  import { createInterface as createInterface4 } from "node:readline/promises";
73511
74017
  import { stdin as stdin2, stdout as stdout2 } from "node:process";
73512
74018
  async function ask(question, signal) {
@@ -73539,7 +74045,7 @@ function handoffCommands(system) {
73539
74045
  async function executableOnPath(executable, path43) {
73540
74046
  for (const directory of path43.split(delimiter).filter(Boolean)) {
73541
74047
  try {
73542
- await access(join50(directory, executable), constants4.X_OK);
74048
+ await access(join51(directory, executable), constants4.X_OK);
73543
74049
  return true;
73544
74050
  } catch {
73545
74051
  }
@@ -73573,7 +74079,7 @@ async function assertOwnerHandoffPrerequisites(env5, system = platform2()) {
73573
74079
  "Owner handoff needs an active Wayland clipboard session before setup can create resources. See https://github.com/dork-labs/dorkos/blob/main/apps/community/FLY.md"
73574
74080
  );
73575
74081
  }
73576
- const socketAvailable = await stat2(join50(runtimeDirectory, display)).then(
74082
+ const socketAvailable = await stat2(join51(runtimeDirectory, display)).then(
73577
74083
  (value) => value.isSocket(),
73578
74084
  () => false
73579
74085
  );
@@ -74198,28 +74704,28 @@ var init_owner = __esm({
74198
74704
  });
74199
74705
 
74200
74706
  // src/commands/community-deploy/journal.ts
74201
- import { randomUUID as randomUUID3 } from "node:crypto";
74707
+ import { randomUUID as randomUUID4 } from "node:crypto";
74202
74708
  import { constants as constants5 } from "node:fs";
74203
74709
  import {
74204
74710
  chmod as chmod2,
74205
74711
  link as link2,
74206
- lstat,
74712
+ lstat as lstat2,
74207
74713
  mkdir as mkdir5,
74208
74714
  open as open2,
74209
74715
  readFile as readFile6,
74210
- readdir as readdir2,
74716
+ readdir as readdir3,
74211
74717
  rename as rename3,
74212
74718
  rm as rm5,
74213
74719
  unlink
74214
74720
  } from "node:fs/promises";
74215
- import { basename as basename7, dirname as dirname12, join as join51 } from "node:path";
74721
+ import { basename as basename7, dirname as dirname12, join as join52 } from "node:path";
74216
74722
  function launchJournalPath(dorkHome, runId) {
74217
74723
  const safeRunId = external_exports.uuid().parse(runId);
74218
- return join51(dorkHome, "launches", "community", `${safeRunId}.json`);
74724
+ return join52(dorkHome, "launches", "community", `${safeRunId}.json`);
74219
74725
  }
74220
74726
  async function rejectSymlink(path43) {
74221
74727
  try {
74222
- if ((await lstat(path43)).isSymbolicLink()) throw new Error(`Refusing symbolic link: ${path43}`);
74728
+ if ((await lstat2(path43)).isSymbolicLink()) throw new Error(`Refusing symbolic link: ${path43}`);
74223
74729
  } catch (error63) {
74224
74730
  if (error63.code !== "ENOENT") throw error63;
74225
74731
  }
@@ -74243,7 +74749,7 @@ async function prepareDirectory(filePath) {
74243
74749
  }
74244
74750
  async function exists2(path43) {
74245
74751
  try {
74246
- await lstat(path43);
74752
+ await lstat2(path43);
74247
74753
  return true;
74248
74754
  } catch (error63) {
74249
74755
  if (error63.code === "ENOENT") return false;
@@ -74252,9 +74758,9 @@ async function exists2(path43) {
74252
74758
  }
74253
74759
  async function writeDurably(filePath, data) {
74254
74760
  const directory = dirname12(filePath);
74255
- const temporary = join51(
74761
+ const temporary = join52(
74256
74762
  directory,
74257
- `.${basename7(filePath)}.${process.pid}.${randomUUID3()}.durable`
74763
+ `.${basename7(filePath)}.${process.pid}.${randomUUID4()}.durable`
74258
74764
  );
74259
74765
  let handle;
74260
74766
  try {
@@ -74294,7 +74800,7 @@ function processIsAlive(pid) {
74294
74800
  }
74295
74801
  async function sameFile(first, second) {
74296
74802
  try {
74297
- const [left, right] = await Promise.all([lstat(first), lstat(second)]);
74803
+ const [left, right] = await Promise.all([lstat2(first), lstat2(second)]);
74298
74804
  return left.dev === right.dev && left.ino === right.ino;
74299
74805
  } catch {
74300
74806
  return false;
@@ -74305,7 +74811,7 @@ async function releaseOwnedLock(candidate, lockPath) {
74305
74811
  await rm5(candidate, { force: true });
74306
74812
  }
74307
74813
  async function createLockCandidate(lockPath) {
74308
- const record2 = { ownerId: randomUUID3(), pid: process.pid, createdAt: (/* @__PURE__ */ new Date()).toISOString() };
74814
+ const record2 = { ownerId: randomUUID4(), pid: process.pid, createdAt: (/* @__PURE__ */ new Date()).toISOString() };
74309
74815
  const candidate = `${lockPath}.${record2.ownerId}.candidate`;
74310
74816
  await writeDurably(candidate, `${JSON.stringify(record2)}
74311
74817
  `);
@@ -74349,12 +74855,12 @@ async function readLaunchJournal(filePath) {
74349
74855
  }
74350
74856
  }
74351
74857
  async function listIncompleteLaunchJournals(dorkHome) {
74352
- const directory = join51(dorkHome, "launches", "community");
74858
+ const directory = join52(dorkHome, "launches", "community");
74353
74859
  await rejectSymlink(dirname12(directory));
74354
74860
  await rejectSymlink(directory);
74355
74861
  let filenames;
74356
74862
  try {
74357
- filenames = await readdir2(directory);
74863
+ filenames = await readdir3(directory);
74358
74864
  } catch (error63) {
74359
74865
  if (error63.code === "ENOENT") return [];
74360
74866
  throw error63;
@@ -74625,7 +75131,7 @@ __export(community_dispatcher_exports, {
74625
75131
  formatIncompleteLaunches: () => formatIncompleteLaunches,
74626
75132
  runCommunityDispatcher: () => runCommunityDispatcher
74627
75133
  });
74628
- import { randomUUID as randomUUID4 } from "node:crypto";
75134
+ import { randomUUID as randomUUID5 } from "node:crypto";
74629
75135
  import { parseArgs as parseArgs16 } from "node:util";
74630
75136
  function required2(value, flag) {
74631
75137
  if (!value) throw new Error(`${flag} is required`);
@@ -74728,7 +75234,7 @@ async function runCommunityDispatcher(args, context2) {
74728
75234
  return 0;
74729
75235
  }
74730
75236
  const version4 = parsed.values.version ?? context2.cliVersion;
74731
- const runId = parsed.values.resume ?? randomUUID4();
75237
+ const runId = parsed.values.resume ?? randomUUID5();
74732
75238
  const journalPath = launchJournalPath(context2.dorkHome, runId);
74733
75239
  const resumeJournal = parsed.values.resume ? await readLaunchJournal(journalPath) : null;
74734
75240
  if (parsed.values.resume && !resumeJournal) {
@@ -75738,7 +76244,7 @@ __export(feedback_exports, {
75738
76244
  runFeedback: () => runFeedback
75739
76245
  });
75740
76246
  import os7 from "node:os";
75741
- import { execFile } from "node:child_process";
76247
+ import { execFile as execFile2 } from "node:child_process";
75742
76248
  function gatherCliReport(kind, version4, store) {
75743
76249
  return gatherFeedbackReport({
75744
76250
  kind,
@@ -75757,11 +76263,11 @@ function parseArgs17(args) {
75757
76263
  function defaultOpenUrl(url2) {
75758
76264
  if (!/^https?:\/\//i.test(url2)) return false;
75759
76265
  try {
75760
- if (process.platform === "darwin") execFile("open", [url2], () => {
76266
+ if (process.platform === "darwin") execFile2("open", [url2], () => {
75761
76267
  });
75762
- else if (process.platform === "win32") execFile("cmd", ["/c", "start", "", url2], () => {
76268
+ else if (process.platform === "win32") execFile2("cmd", ["/c", "start", "", url2], () => {
75763
76269
  });
75764
- else execFile("xdg-open", [url2], () => {
76270
+ else execFile2("xdg-open", [url2], () => {
75765
76271
  });
75766
76272
  return true;
75767
76273
  } catch {
@@ -79631,7 +80137,7 @@ var init_base64 = __esm({
79631
80137
  });
79632
80138
 
79633
80139
  // ../../node_modules/.pnpm/@better-auth+utils@0.5.0/node_modules/@better-auth/utils/dist/hash.mjs
79634
- function createHash4(algorithm2, encoding) {
80140
+ function createHash5(algorithm2, encoding) {
79635
80141
  return { digest: async (input4) => {
79636
80142
  const data = toBufferSource(input4);
79637
80143
  const hashBuffer = await getWebcryptoSubtle().digest(algorithm2, data);
@@ -80575,12 +81081,12 @@ function formatEnvelope(version4, ciphertext) {
80575
81081
  return `${ENVELOPE_PREFIX}${version4}$${ciphertext}`;
80576
81082
  }
80577
81083
  async function rawEncrypt(secret, data) {
80578
- const keyAsBytes = await createHash4("SHA-256").digest(secret);
81084
+ const keyAsBytes = await createHash5("SHA-256").digest(secret);
80579
81085
  const dataAsBytes = utf8ToBytes(data);
80580
81086
  return bytesToHex(managedNonce(xchacha20poly1305)(new Uint8Array(keyAsBytes)).encrypt(dataAsBytes));
80581
81087
  }
80582
81088
  async function rawDecrypt(secret, hex4) {
80583
- const keyAsBytes = await createHash4("SHA-256").digest(secret);
81089
+ const keyAsBytes = await createHash5("SHA-256").digest(secret);
80584
81090
  const dataAsBytes = hexToBytes2(hex4);
80585
81091
  const chacha = managedNonce(xchacha20poly1305)(new Uint8Array(keyAsBytes));
80586
81092
  return new TextDecoder().decode(chacha.decrypt(dataAsBytes));
@@ -85273,7 +85779,7 @@ var init_verification_token_storage = __esm({
85273
85779
  init_base64();
85274
85780
  init_hash();
85275
85781
  defaultKeyHasher = async (identifier) => {
85276
- const hash2 = await createHash4("SHA-256").digest(new TextEncoder().encode(identifier));
85782
+ const hash2 = await createHash5("SHA-256").digest(new TextEncoder().encode(identifier));
85277
85783
  return base64Url.encode(new Uint8Array(hash2), { padding: false });
85278
85784
  };
85279
85785
  }
@@ -86607,7 +87113,7 @@ var init_internal_adapter = __esm({
86607
87113
  * is best-effort there (it is intended for development and tests).
86608
87114
  */
86609
87115
  reserveVerificationValue: async (data) => {
86610
- const reservationId = base64Url.encode(new Uint8Array(await createHash4("SHA-256").digest(new TextEncoder().encode("reserve:" + data.identifier))), { padding: false });
87116
+ const reservationId = base64Url.encode(new Uint8Array(await createHash5("SHA-256").digest(new TextEncoder().encode("reserve:" + data.identifier))), { padding: false });
86611
87117
  const storageOption = getStorageOption(data.identifier, options.verification?.storeIdentifier);
86612
87118
  const storedIdentifier = await processIdentifier(data.identifier, storageOption);
86613
87119
  if (secondaryStorage && !options.verification?.storeInDatabase) throw new BetterAuthError("reserveVerificationValue requires database-backed verification storage. Set verification.storeInDatabase to true for flows that reserve verification values.");
@@ -95826,7 +96332,7 @@ var init_factory = __esm({
95826
96332
  }
95827
96333
  return transformedData;
95828
96334
  };
95829
- const transformOutput = async (data, unsafe_model, select2 = [], join53) => {
96335
+ const transformOutput = async (data, unsafe_model, select2 = [], join54) => {
95830
96336
  const transformSingleOutput = async (data2, unsafe_model2, select3 = []) => {
95831
96337
  if (!data2) return null;
95832
96338
  const newMappedKeys = config3.mapKeysTransformOutput ?? {};
@@ -95862,10 +96368,10 @@ var init_factory = __esm({
95862
96368
  }
95863
96369
  return transformedData2;
95864
96370
  };
95865
- if (!join53 || Object.keys(join53).length === 0) return await transformSingleOutput(data, unsafe_model, select2);
96371
+ if (!join54 || Object.keys(join54).length === 0) return await transformSingleOutput(data, unsafe_model, select2);
95866
96372
  unsafe_model = getDefaultModelName(unsafe_model);
95867
96373
  const transformedData = await transformSingleOutput(data, unsafe_model, select2);
95868
- const requiredModels = Object.entries(join53).map(([model, joinConfig]) => ({
96374
+ const requiredModels = Object.entries(join54).map(([model, joinConfig]) => ({
95869
96375
  modelName: getModelName(model),
95870
96376
  defaultModelName: getDefaultModelName(model),
95871
96377
  joinConfig
@@ -95964,8 +96470,8 @@ var init_factory = __esm({
95964
96470
  if (!unsanitizedJoin) return void 0;
95965
96471
  if (Object.keys(unsanitizedJoin).length === 0) return void 0;
95966
96472
  const transformedJoin = {};
95967
- for (const [model, join53] of Object.entries(unsanitizedJoin)) {
95968
- if (!join53) continue;
96473
+ for (const [model, join54] of Object.entries(unsanitizedJoin)) {
96474
+ if (!join54) continue;
95969
96475
  const defaultModelName = getDefaultModelName(model);
95970
96476
  const defaultBaseModelName = getDefaultModelName(baseModel);
95971
96477
  let foreignKeys = Object.entries(schema2[defaultModelName].fields).filter(([field, fieldAttributes]) => fieldAttributes.references && getDefaultModelName(fieldAttributes.references.model) === defaultBaseModelName);
@@ -96006,7 +96512,7 @@ var init_factory = __esm({
96006
96512
  const isUnique = to === "id" ? true : foreignKeyAttributes.unique ?? false;
96007
96513
  let limit = options.advanced?.database?.defaultFindManyLimit ?? 100;
96008
96514
  if (isUnique) limit = 1;
96009
- else if (typeof join53 === "object" && typeof join53.limit === "number") limit = join53.limit;
96515
+ else if (typeof join54 === "object" && typeof join54.limit === "number") limit = join54.limit;
96010
96516
  transformedJoin[getModelName(model)] = {
96011
96517
  on: {
96012
96518
  from,
@@ -96223,21 +96729,21 @@ var init_factory = __esm({
96223
96729
  action: "findOne"
96224
96730
  });
96225
96731
  unsafeModel = getDefaultModelName(unsafeModel);
96226
- let join53;
96732
+ let join54;
96227
96733
  let passJoinToAdapter = true;
96228
96734
  if (!config3.disableTransformJoin) {
96229
96735
  const result2 = transformJoinClause(unsafeModel, unsafeJoin, select2);
96230
96736
  if (result2) {
96231
- join53 = result2.join;
96737
+ join54 = result2.join;
96232
96738
  select2 = result2.select;
96233
96739
  }
96234
- if (!options.advanced?.database?.joins && join53 && Object.keys(join53).length > 0) passJoinToAdapter = false;
96235
- } else join53 = unsafeJoin;
96740
+ if (!options.advanced?.database?.joins && join54 && Object.keys(join54).length > 0) passJoinToAdapter = false;
96741
+ } else join54 = unsafeJoin;
96236
96742
  debugLog({ method: "findOne" }, `${formatTransactionId(thisTransactionId)} ${formatStep(1, 3)}`, `${formatMethod("findOne")}:`, {
96237
96743
  model,
96238
96744
  where,
96239
96745
  select: select2,
96240
- join: join53
96746
+ join: join54
96241
96747
  });
96242
96748
  const res = await withSpan2(`db findOne ${model}`, {
96243
96749
  [ATTR_DB_OPERATION_NAME]: "findOne",
@@ -96246,14 +96752,14 @@ var init_factory = __esm({
96246
96752
  model,
96247
96753
  where,
96248
96754
  select: select2,
96249
- join: passJoinToAdapter ? join53 : void 0
96755
+ join: passJoinToAdapter ? join54 : void 0
96250
96756
  }));
96251
96757
  debugLog({ method: "findOne" }, `${formatTransactionId(thisTransactionId)} ${formatStep(2, 3)}`, `${formatMethod("findOne")} ${formatAction2("DB Result")}:`, {
96252
96758
  model,
96253
96759
  data: res
96254
96760
  });
96255
96761
  let transformed = res;
96256
- if (!config3.disableTransformOutput) transformed = await transformOutput(res, unsafeModel, select2, join53);
96762
+ if (!config3.disableTransformOutput) transformed = await transformOutput(res, unsafeModel, select2, join54);
96257
96763
  debugLog({ method: "findOne" }, `${formatTransactionId(thisTransactionId)} ${formatStep(3, 3)}`, `${formatMethod("findOne")} ${formatAction2("Parsed Result")}:`, {
96258
96764
  model,
96259
96765
  data: transformed
@@ -96271,23 +96777,23 @@ var init_factory = __esm({
96271
96777
  action: "findMany"
96272
96778
  });
96273
96779
  unsafeModel = getDefaultModelName(unsafeModel);
96274
- let join53;
96780
+ let join54;
96275
96781
  let passJoinToAdapter = true;
96276
96782
  if (!config3.disableTransformJoin) {
96277
96783
  const result2 = transformJoinClause(unsafeModel, unsafeJoin, select2);
96278
96784
  if (result2) {
96279
- join53 = result2.join;
96785
+ join54 = result2.join;
96280
96786
  select2 = result2.select;
96281
96787
  }
96282
- if (!options.advanced?.database?.joins && join53 && Object.keys(join53).length > 0) passJoinToAdapter = false;
96283
- } else join53 = unsafeJoin;
96788
+ if (!options.advanced?.database?.joins && join54 && Object.keys(join54).length > 0) passJoinToAdapter = false;
96789
+ } else join54 = unsafeJoin;
96284
96790
  debugLog({ method: "findMany" }, `${formatTransactionId(thisTransactionId)} ${formatStep(1, 3)}`, `${formatMethod("findMany")}:`, {
96285
96791
  model,
96286
96792
  where,
96287
96793
  limit,
96288
96794
  sortBy,
96289
96795
  offset,
96290
- join: join53
96796
+ join: join54
96291
96797
  });
96292
96798
  const res = await withSpan2(`db findMany ${model}`, {
96293
96799
  [ATTR_DB_OPERATION_NAME]: "findMany",
@@ -96299,7 +96805,7 @@ var init_factory = __esm({
96299
96805
  select: select2,
96300
96806
  sortBy,
96301
96807
  offset,
96302
- join: passJoinToAdapter ? join53 : void 0
96808
+ join: passJoinToAdapter ? join54 : void 0
96303
96809
  }));
96304
96810
  debugLog({ method: "findMany" }, `${formatTransactionId(thisTransactionId)} ${formatStep(2, 3)}`, `${formatMethod("findMany")} ${formatAction2("DB Result")}:`, {
96305
96811
  model,
@@ -96307,7 +96813,7 @@ var init_factory = __esm({
96307
96813
  });
96308
96814
  let transformed = res;
96309
96815
  if (!config3.disableTransformOutput) transformed = await Promise.all(res.map(async (r3) => {
96310
- return await transformOutput(r3, unsafeModel, void 0, join53);
96816
+ return await transformOutput(r3, unsafeModel, void 0, join54);
96311
96817
  }));
96312
96818
  debugLog({ method: "findMany" }, `${formatTransactionId(thisTransactionId)} ${formatStep(3, 3)}`, `${formatMethod("findMany")} ${formatAction2("Parsed Result")}:`, {
96313
96819
  model,
@@ -96649,7 +97155,7 @@ var init_dist7 = __esm({
96649
97155
  return sortBy.direction === "asc" ? comparison : -comparison;
96650
97156
  });
96651
97157
  };
96652
- function convertWhereClause(where, model, join53, select2) {
97158
+ function convertWhereClause(where, model, join54, select2) {
96653
97159
  const baseRecords = (() => {
96654
97160
  const table2 = activeDb[model];
96655
97161
  if (!table2) {
@@ -96709,14 +97215,14 @@ var init_dist7 = __esm({
96709
97215
  })))));
96710
97216
  return records;
96711
97217
  })();
96712
- if (!join53) return baseRecords;
97218
+ if (!join54) return baseRecords;
96713
97219
  const grouped = /* @__PURE__ */ new Map();
96714
97220
  const seenIds = /* @__PURE__ */ new Map();
96715
97221
  for (const baseRecord of baseRecords) {
96716
97222
  const baseId = String(baseRecord.id);
96717
97223
  if (!grouped.has(baseId)) {
96718
97224
  const nested = { ...baseRecord };
96719
- for (const [joinModel, joinAttr] of Object.entries(join53)) {
97225
+ for (const [joinModel, joinAttr] of Object.entries(join54)) {
96720
97226
  const joinModelName = getModelName(joinModel);
96721
97227
  if (joinAttr.relation === "one-to-one") nested[joinModelName] = null;
96722
97228
  else {
@@ -96727,7 +97233,7 @@ var init_dist7 = __esm({
96727
97233
  grouped.set(baseId, nested);
96728
97234
  }
96729
97235
  const nestedEntry = grouped.get(baseId);
96730
- for (const [joinModel, joinAttr] of Object.entries(join53)) {
97236
+ for (const [joinModel, joinAttr] of Object.entries(join54)) {
96731
97237
  const joinModelName = getModelName(joinModel);
96732
97238
  const joinTable = activeDb[joinModelName];
96733
97239
  if (!joinTable) {
@@ -96760,18 +97266,18 @@ var init_dist7 = __esm({
96760
97266
  activeDb[model].push(data);
96761
97267
  return data;
96762
97268
  },
96763
- findOne: async ({ model, where, select: select2, join: join53 }) => {
96764
- const res = convertWhereClause(where, model, join53, select2);
96765
- if (join53) {
97269
+ findOne: async ({ model, where, select: select2, join: join54 }) => {
97270
+ const res = convertWhereClause(where, model, join54, select2);
97271
+ if (join54) {
96766
97272
  const resArray = res;
96767
97273
  if (!resArray.length) return null;
96768
97274
  return resArray[0];
96769
97275
  }
96770
97276
  return res[0] || null;
96771
97277
  },
96772
- findMany: async ({ model, where, sortBy, limit, select: select2, offset, join: join53 }) => {
96773
- const res = convertWhereClause(where || [], model, join53, select2);
96774
- if (join53) {
97278
+ findMany: async ({ model, where, sortBy, limit, select: select2, offset, join: join54 }) => {
97279
+ const res = convertWhereClause(where || [], model, join54, select2);
97280
+ if (join54) {
96775
97281
  const resArray = res;
96776
97282
  if (!resArray.length) return [];
96777
97283
  applySortToRecords(resArray, sortBy, model);
@@ -98769,10 +99275,10 @@ var init_query_node = __esm({
98769
99275
  where: node2.where ? WhereNode.cloneWithOperation(node2.where, "And", operation) : WhereNode.create(operation)
98770
99276
  });
98771
99277
  },
98772
- cloneWithJoin(node2, join53) {
99278
+ cloneWithJoin(node2, join54) {
98773
99279
  return freeze({
98774
99280
  ...node2,
98775
- joins: node2.joins ? freeze([...node2.joins, join53]) : freeze([join53])
99281
+ joins: node2.joins ? freeze([...node2.joins, join54]) : freeze([join54])
98776
99282
  });
98777
99283
  },
98778
99284
  cloneWithReturning(node2, selections) {
@@ -103283,8 +103789,8 @@ var init_with_schema_transformer = __esm({
103283
103789
  this.#collectSchemableIdsFromTableExpr(node2.table, schemableIds);
103284
103790
  }
103285
103791
  if ("joins" in node2 && node2.joins) {
103286
- for (const join53 of node2.joins) {
103287
- this.#collectSchemableIdsFromTableExpr(join53.table, schemableIds);
103792
+ for (const join54 of node2.joins) {
103793
+ this.#collectSchemableIdsFromTableExpr(join54.table, schemableIds);
103288
103794
  }
103289
103795
  }
103290
103796
  if ("using" in node2 && node2.using) {
@@ -115456,7 +115962,7 @@ var init_mssql_introspector = __esm({
115456
115962
  return await this.#db.selectFrom("sys.schemas").select("name").execute();
115457
115963
  }
115458
115964
  async getTables(options = { withInternalKyselyTables: false }) {
115459
- const rawColumns = await this.#db.selectFrom("sys.tables as tables").leftJoin("sys.schemas as table_schemas", "table_schemas.schema_id", "tables.schema_id").innerJoin("sys.columns as columns", "columns.object_id", "tables.object_id").innerJoin("sys.types as types", "types.user_type_id", "columns.user_type_id").leftJoin("sys.schemas as type_schemas", "type_schemas.schema_id", "types.schema_id").leftJoin("sys.extended_properties as comments", (join53) => join53.onRef("comments.major_id", "=", "tables.object_id").onRef("comments.minor_id", "=", "columns.column_id").on("comments.name", "=", "MS_Description")).$if(!options.withInternalKyselyTables, (qb) => qb.where("tables.name", "!=", DEFAULT_MIGRATION_TABLE).where("tables.name", "!=", DEFAULT_MIGRATION_LOCK_TABLE)).select([
115965
+ const rawColumns = await this.#db.selectFrom("sys.tables as tables").leftJoin("sys.schemas as table_schemas", "table_schemas.schema_id", "tables.schema_id").innerJoin("sys.columns as columns", "columns.object_id", "tables.object_id").innerJoin("sys.types as types", "types.user_type_id", "columns.user_type_id").leftJoin("sys.schemas as type_schemas", "type_schemas.schema_id", "types.schema_id").leftJoin("sys.extended_properties as comments", (join54) => join54.onRef("comments.major_id", "=", "tables.object_id").onRef("comments.minor_id", "=", "columns.column_id").on("comments.name", "=", "MS_Description")).$if(!options.withInternalKyselyTables, (qb) => qb.where("tables.name", "!=", DEFAULT_MIGRATION_TABLE).where("tables.name", "!=", DEFAULT_MIGRATION_LOCK_TABLE)).select([
115460
115966
  "tables.name as table_name",
115461
115967
  (eb) => eb.ref("tables.type").$castTo().as("table_type"),
115462
115968
  "table_schemas.name as table_schema_name",
@@ -115471,7 +115977,7 @@ var init_mssql_introspector = __esm({
115471
115977
  "types.name as type_name",
115472
115978
  "type_schemas.name as type_schema_name",
115473
115979
  "comments.value as column_comment"
115474
- ]).unionAll(this.#db.selectFrom("sys.views as views").leftJoin("sys.schemas as view_schemas", "view_schemas.schema_id", "views.schema_id").innerJoin("sys.columns as columns", "columns.object_id", "views.object_id").innerJoin("sys.types as types", "types.user_type_id", "columns.user_type_id").leftJoin("sys.schemas as type_schemas", "type_schemas.schema_id", "types.schema_id").leftJoin("sys.extended_properties as comments", (join53) => join53.onRef("comments.major_id", "=", "views.object_id").onRef("comments.minor_id", "=", "columns.column_id").on("comments.name", "=", "MS_Description")).select([
115980
+ ]).unionAll(this.#db.selectFrom("sys.views as views").leftJoin("sys.schemas as view_schemas", "view_schemas.schema_id", "views.schema_id").innerJoin("sys.columns as columns", "columns.object_id", "views.object_id").innerJoin("sys.types as types", "types.user_type_id", "columns.user_type_id").leftJoin("sys.schemas as type_schemas", "type_schemas.schema_id", "types.schema_id").leftJoin("sys.extended_properties as comments", (join54) => join54.onRef("comments.major_id", "=", "views.object_id").onRef("comments.minor_id", "=", "columns.column_id").on("comments.name", "=", "MS_Description")).select([
115475
115981
  "views.name as table_name",
115476
115982
  "views.type as table_type",
115477
115983
  "view_schemas.name as table_schema_name",
@@ -116611,10 +117117,10 @@ var init_dist9 = __esm({
116611
117117
  mysqlNoIdWarned = true;
116612
117118
  logger2.warn(`[Kysely Adapter] MySQL does not support INSERT...RETURNING. With generateId set to false, the adapter uses best-effort fallback strategies (unique columns, full-field match) to retrieve inserted rows. For reliable behavior, use Better Auth's default ID generation, a custom generateId function, or generateId: "serial" for auto-increment.`);
116613
117119
  }
116614
- const selectAllJoins = (join53) => {
117120
+ const selectAllJoins = (join54) => {
116615
117121
  const allSelects = [];
116616
117122
  const allSelectsStr = [];
116617
- if (join53) for (const [joinModel, _3] of Object.entries(join53)) {
117123
+ if (join54) for (const [joinModel, _3] of Object.entries(join54)) {
116618
117124
  const fields = schema2[getDefaultModelName(joinModel)]?.fields;
116619
117125
  const [_joinModelSchema, joinModelName] = joinModel.includes(".") ? joinModel.split(".") : [void 0, joinModel];
116620
117126
  if (!fields) continue;
@@ -116839,7 +117345,7 @@ var init_dist9 = __esm({
116839
117345
  async create({ data, model }) {
116840
117346
  return await withReturning(data, db2.insertInto(model).values(data), model, []);
116841
117347
  },
116842
- async findOne({ model, where, select: select2, join: join53 }) {
117348
+ async findOne({ model, where, select: select2, join: join54 }) {
116843
117349
  const { and: and2, or: or2 } = convertWhereClause(model, where);
116844
117350
  let query = db2.selectFrom((eb) => {
116845
117351
  let b2 = eb.selectFrom(model);
@@ -116852,19 +117358,19 @@ var init_dist9 = __esm({
116852
117358
  else b2 = b2.selectAll();
116853
117359
  return b2.as("primary");
116854
117360
  }).selectAll("primary");
116855
- if (join53) for (const [joinModel, joinAttr] of Object.entries(join53)) {
117361
+ if (join54) for (const [joinModel, joinAttr] of Object.entries(join54)) {
116856
117362
  const [_joinModelSchema, joinModelName] = joinModel.includes(".") ? joinModel.split(".") : [void 0, joinModel];
116857
- query = query.leftJoin(`${joinModel} as join_${joinModelName}`, (join54) => join54.onRef(`join_${joinModelName}.${joinAttr.on.to}`, "=", `primary.${joinAttr.on.from}`));
117363
+ query = query.leftJoin(`${joinModel} as join_${joinModelName}`, (join55) => join55.onRef(`join_${joinModelName}.${joinAttr.on.to}`, "=", `primary.${joinAttr.on.from}`));
116858
117364
  }
116859
- const { allSelectsStr, allSelects } = selectAllJoins(join53);
117365
+ const { allSelectsStr, allSelects } = selectAllJoins(join54);
116860
117366
  query = query.select(allSelects);
116861
117367
  const res = await query.execute();
116862
117368
  if (!res || !Array.isArray(res) || res.length === 0) return null;
116863
117369
  const row = res[0];
116864
- if (join53) return processJoinedResults(res, join53, allSelectsStr)[0];
117370
+ if (join54) return processJoinedResults(res, join54, allSelectsStr)[0];
116865
117371
  return row;
116866
117372
  },
116867
- async findMany({ model, where, limit, select: select2, offset, sortBy, join: join53 }) {
117373
+ async findMany({ model, where, limit, select: select2, offset, sortBy, join: join54 }) {
116868
117374
  const { and: and2, or: or2 } = convertWhereClause(model, where);
116869
117375
  let query = db2.selectFrom((eb) => {
116870
117376
  let b2 = eb.selectFrom(model);
@@ -116893,11 +117399,11 @@ var init_dist9 = __esm({
116893
117399
  else b2 = b2.selectAll();
116894
117400
  return b2.as("primary");
116895
117401
  }).selectAll("primary");
116896
- if (join53) for (const [joinModel, joinAttr] of Object.entries(join53)) {
117402
+ if (join54) for (const [joinModel, joinAttr] of Object.entries(join54)) {
116897
117403
  const [_joinModelSchema, joinModelName] = joinModel.includes(".") ? joinModel.split(".") : [void 0, joinModel];
116898
- query = query.leftJoin(`${joinModel} as join_${joinModelName}`, (join54) => join54.onRef(`join_${joinModelName}.${joinAttr.on.to}`, "=", `primary.${joinAttr.on.from}`));
117404
+ query = query.leftJoin(`${joinModel} as join_${joinModelName}`, (join55) => join55.onRef(`join_${joinModelName}.${joinAttr.on.to}`, "=", `primary.${joinAttr.on.from}`));
116899
117405
  }
116900
- const { allSelectsStr, allSelects } = selectAllJoins(join53);
117406
+ const { allSelectsStr, allSelects } = selectAllJoins(join54);
116901
117407
  query = query.select(allSelects);
116902
117408
  if (sortBy?.field) query = query.orderBy(`${getFieldName({
116903
117409
  model,
@@ -116905,7 +117411,7 @@ var init_dist9 = __esm({
116905
117411
  })}`, sortBy.direction);
116906
117412
  const res = await query.execute();
116907
117413
  if (!res) return [];
116908
- if (join53) return processJoinedResults(res, join53, allSelectsStr);
117414
+ if (join54) return processJoinedResults(res, join54, allSelectsStr);
116909
117415
  return res;
116910
117416
  },
116911
117417
  async update({ model, where, update: values2 }) {
@@ -118093,7 +118599,7 @@ function detectEnvironment() {
118093
118599
  return getEnvVar("NODE_ENV") === "production" ? "production" : isCI2() ? "ci" : isTest() ? "test" : "development";
118094
118600
  }
118095
118601
  async function hashToBase64(data) {
118096
- const buffer = await createHash4("SHA-256").digest(data);
118602
+ const buffer = await createHash5("SHA-256").digest(data);
118097
118603
  return base643.encode(buffer);
118098
118604
  }
118099
118605
  async function readRootPackageJson() {
@@ -119011,10 +119517,10 @@ var init_dist12 = __esm({
119011
119517
  checkMissingFields(schemaModel, model, values2);
119012
119518
  return await withReturning(model, db2.insert(schemaModel).values(values2), values2);
119013
119519
  },
119014
- async findOne({ model, where, select: select2, join: join53 }) {
119520
+ async findOne({ model, where, select: select2, join: join54 }) {
119015
119521
  const schemaModel = getSchema2(model);
119016
119522
  const clause = convertWhereClause(where, model);
119017
- if (join53) {
119523
+ if (join54) {
119018
119524
  const queryModel = getQueryModel(model);
119019
119525
  if (!db2.query || !queryModel) {
119020
119526
  logger2.error(`[# Drizzle Adapter]: The model "${model}" was not found in the query object. Please update your Drizzle schema to include relations or re-generate using "npx auth@latest generate".`);
@@ -119024,7 +119530,7 @@ var init_dist12 = __esm({
119024
119530
  const renamedJoinResults = [];
119025
119531
  const relationKeys = relationKeysByModel.get(queryModel);
119026
119532
  includes = {};
119027
- const joinEntries = Object.entries(join53);
119533
+ const joinEntries = Object.entries(join54);
119028
119534
  for (const [joinModel, joinAttr] of joinEntries) {
119029
119535
  const limit = joinAttr.limit ?? options.advanced?.database?.defaultFindManyLimit ?? 100;
119030
119536
  const isUnique = joinAttr.relation === "one-to-one";
@@ -119066,11 +119572,11 @@ var init_dist12 = __esm({
119066
119572
  if (!res.length) return null;
119067
119573
  return res[0];
119068
119574
  },
119069
- async findMany({ model, where, sortBy, limit, select: select2, offset, join: join53 }) {
119575
+ async findMany({ model, where, sortBy, limit, select: select2, offset, join: join54 }) {
119070
119576
  const schemaModel = getSchema2(model);
119071
119577
  const clause = where ? convertWhereClause(where, model) : [];
119072
119578
  const sortFn = sortBy?.direction === "desc" ? desc : asc;
119073
- if (join53) {
119579
+ if (join54) {
119074
119580
  const queryModel = getQueryModel(model);
119075
119581
  if (!db2.query || !queryModel) {
119076
119582
  logger2.error(`[# Drizzle Adapter]: The model "${model}" was not found in the query object. Please update your Drizzle schema to include relations or re-generate using "npx auth@latest generate".`);
@@ -119080,7 +119586,7 @@ var init_dist12 = __esm({
119080
119586
  const renamedJoinResults = [];
119081
119587
  const relationKeys = relationKeysByModel.get(queryModel);
119082
119588
  includes = {};
119083
- const joinEntries = Object.entries(join53);
119589
+ const joinEntries = Object.entries(join54);
119084
119590
  for (const [joinModel, joinAttr] of joinEntries) {
119085
119591
  const isUnique = joinAttr.relation === "one-to-one";
119086
119592
  const limit2 = joinAttr.limit ?? options.advanced?.database?.defaultFindManyLimit ?? 100;
@@ -119710,7 +120216,7 @@ var init_client = __esm({
119710
120216
 
119711
120217
  // ../../node_modules/.pnpm/better-auth@1.7.2_@opentelemetry+api@1.9.1_@prisma+client@5.22.0_better-sqlite3@12.11.1_2a8e047da398d63c3579f222674b33b1/node_modules/better-auth/dist/plugins/organization/adapter.mjs
119712
120218
  async function computeTeamMembershipKey(data) {
119713
- const digest2 = await createHash4("SHA-256").digest(new TextEncoder().encode(JSON.stringify([data.teamId, data.userId])));
120219
+ const digest2 = await createHash5("SHA-256").digest(new TextEncoder().encode(JSON.stringify([data.teamId, data.userId])));
119714
120220
  return base64Url.encode(new Uint8Array(digest2), { padding: false });
119715
120221
  }
119716
120222
  async function findTeamMemberByKeyOrPair(adapter, data) {
@@ -127144,7 +127650,7 @@ var init_dist13 = __esm({
127144
127650
  }
127145
127651
  } } });
127146
127652
  defaultKeyHasher2 = async (key) => {
127147
- const hash2 = await createHash4("SHA-256").digest(new TextEncoder().encode(key));
127653
+ const hash2 = await createHash5("SHA-256").digest(new TextEncoder().encode(key));
127148
127654
  return base64Url.encode(new Uint8Array(hash2), { padding: false });
127149
127655
  };
127150
127656
  API_KEY_TABLE_NAME = "apikey";
@@ -127211,7 +127717,7 @@ var init_auth_instance = __esm({
127211
127717
  });
127212
127718
 
127213
127719
  // ../shared/src/secret-file.ts
127214
- import { randomUUID as randomUUID5 } from "node:crypto";
127720
+ import { randomUUID as randomUUID6 } from "node:crypto";
127215
127721
  import {
127216
127722
  chmodSync as chmodSync2,
127217
127723
  linkSync,
@@ -127221,9 +127727,9 @@ import {
127221
127727
  rmSync as rmSync7,
127222
127728
  writeFileSync as writeFileSync2
127223
127729
  } from "node:fs";
127224
- import { basename as basename8, dirname as dirname13, join as join52 } from "node:path";
127730
+ import { basename as basename8, dirname as dirname13, join as join53 } from "node:path";
127225
127731
  function tempPathFor(filePath) {
127226
- return join52(dirname13(filePath), `.${basename8(filePath)}.${process.pid}.${randomUUID5()}.tmp`);
127732
+ return join53(dirname13(filePath), `.${basename8(filePath)}.${process.pid}.${randomUUID6()}.tmp`);
127227
127733
  }
127228
127734
  function unusableSecretError(filePath, detail) {
127229
127735
  return new Error(
@@ -128912,7 +129418,7 @@ var init_cloud_link_client = __esm({
128912
129418
  });
128913
129419
 
128914
129420
  // ../../apps/server/src/lib/instance-id.ts
128915
- import { randomUUID as randomUUID6 } from "node:crypto";
129421
+ import { randomUUID as randomUUID7 } from "node:crypto";
128916
129422
  import fs21 from "node:fs/promises";
128917
129423
  import path36 from "node:path";
128918
129424
  async function getOrCreateInstanceId(dorkHome) {
@@ -128923,7 +129429,7 @@ async function getOrCreateInstanceId(dorkHome) {
128923
129429
  if (trimmed) return trimmed;
128924
129430
  } catch {
128925
129431
  }
128926
- const id = randomUUID6();
129432
+ const id = randomUUID7();
128927
129433
  await fs21.mkdir(dorkHome, { recursive: true });
128928
129434
  await fs21.writeFile(filePath, id, "utf8");
128929
129435
  return id;
@@ -128954,15 +129460,15 @@ __export(cloud_dispatcher_exports, {
128954
129460
  HELP_TEXT: () => HELP_TEXT8,
128955
129461
  runCloudDispatcher: () => runCloudDispatcher
128956
129462
  });
128957
- import { execFile as execFile2 } from "node:child_process";
129463
+ import { execFile as execFile3 } from "node:child_process";
128958
129464
  function defaultOpenUrl2(url2) {
128959
129465
  if (!/^https?:\/\//i.test(url2)) return;
128960
129466
  try {
128961
- if (process.platform === "darwin") execFile2("open", [url2], () => {
129467
+ if (process.platform === "darwin") execFile3("open", [url2], () => {
128962
129468
  });
128963
- else if (process.platform === "win32") execFile2("cmd", ["/c", "start", "", url2], () => {
129469
+ else if (process.platform === "win32") execFile3("cmd", ["/c", "start", "", url2], () => {
128964
129470
  });
128965
- else execFile2("xdg-open", [url2], () => {
129471
+ else execFile3("xdg-open", [url2], () => {
128966
129472
  });
128967
129473
  } catch {
128968
129474
  }
@@ -130215,7 +130721,7 @@ var init_connections_subscriptions = __esm({
130215
130721
  });
130216
130722
 
130217
130723
  // src/commands/connections-review.ts
130218
- import { execFile as execFile3 } from "node:child_process";
130724
+ import { execFile as execFile4 } from "node:child_process";
130219
130725
  import { parseArgs as parseArgs23 } from "node:util";
130220
130726
  function connectorReviewErrorExitCode(error63) {
130221
130727
  return error63 instanceof ConnectorReviewStatusError ? error63.exitCode : void 0;
@@ -130224,11 +130730,11 @@ function defaultOpenUrl3(url2) {
130224
130730
  const parsed = new URL(url2);
130225
130731
  if (parsed.protocol !== "http:" || parsed.hostname !== "localhost") return false;
130226
130732
  try {
130227
- if (process.platform === "darwin") execFile3("open", [url2], () => {
130733
+ if (process.platform === "darwin") execFile4("open", [url2], () => {
130228
130734
  });
130229
- else if (process.platform === "win32") execFile3("cmd", ["/c", "start", "", url2], () => {
130735
+ else if (process.platform === "win32") execFile4("cmd", ["/c", "start", "", url2], () => {
130230
130736
  });
130231
- else execFile3("xdg-open", [url2], () => {
130737
+ else execFile4("xdg-open", [url2], () => {
130232
130738
  });
130233
130739
  return true;
130234
130740
  } catch {
@@ -132599,7 +133105,7 @@ if (process.argv[2] === "community") {
132599
133105
  })
132600
133106
  );
132601
133107
  const exitCode = await dispatcher.runCommunityDispatcher(process.argv.slice(3), {
132602
- cliVersion: "0.81.0",
133108
+ cliVersion: "0.82.0",
132603
133109
  dorkHome: DORK_HOME,
132604
133110
  processEnv: childEnv,
132605
133111
  parseRelease: (bytes) => releaseContract.parseCompatibleCommunityReleaseManifest(
@@ -132607,7 +133113,7 @@ if (process.argv[2] === "community") {
132607
133113
  {
132608
133114
  platform: { os: "linux", architecture: "amd64" },
132609
133115
  configSchemaVersion: releaseContract.COMMUNITY_CONFIG_SCHEMA_VERSION,
132610
- migrationCompatibilityId: "sha256:94aafbb08157408c74d3262a744ebe4b4a44e42cd5b3a2a4ae764eb9224fb5bf"
133116
+ migrationCompatibilityId: "sha256:3cd56d9a5458634b4e1c77fd6c2fbdc5f0d14ec2145cd18d241447e6329a4c6e"
132611
133117
  }
132612
133118
  )
132613
133119
  });
@@ -132617,7 +133123,7 @@ if (process.argv[2] === "community") {
132617
133123
  process.exit(1);
132618
133124
  }
132619
133125
  }
132620
- var cliErrorReporter = initCliErrorReporting({ dorkHome: DORK_HOME, version: "0.81.0" });
133126
+ var cliErrorReporter = initCliErrorReporting({ dorkHome: DORK_HOME, version: "0.82.0" });
132621
133127
  var uninstallCliErrorHandlers = cliErrorReporter ? installCliErrorHandlers(cliErrorReporter) : void 0;
132622
133128
  if (process.argv[2] === "doctor") {
132623
133129
  process.env.DORK_HOME = DORK_HOME;
@@ -132627,7 +133133,7 @@ if (process.argv[2] === "doctor") {
132627
133133
  if (process.argv[2] === "feedback") {
132628
133134
  process.env.DORK_HOME = DORK_HOME;
132629
133135
  const { runFeedback: runFeedback2 } = await Promise.resolve().then(() => (init_feedback2(), feedback_exports));
132630
- process.exit(await runFeedback2(DORK_HOME, "0.81.0", process.argv.slice(3)));
133136
+ process.exit(await runFeedback2(DORK_HOME, "0.82.0", process.argv.slice(3)));
132631
133137
  }
132632
133138
  if (process.argv[2] === "auth") {
132633
133139
  process.env.DORK_HOME = DORK_HOME;
@@ -132722,7 +133228,7 @@ if (process.argv[2] === "agent" || process.argv[2] === "task" || process.argv[2]
132722
133228
  }
132723
133229
  }
132724
133230
  const { runVersionDispatcher: runVersionDispatcher2 } = await Promise.resolve().then(() => (init_version5(), version_exports));
132725
- process.exit(await runVersionDispatcher2("0.81.0", DORK_HOME, subArgs));
133231
+ process.exit(await runVersionDispatcher2("0.82.0", DORK_HOME, subArgs));
132726
133232
  }
132727
133233
  function parseCliArgs() {
132728
133234
  try {
@@ -132845,14 +133351,14 @@ Examples:
132845
133351
  process.exit(0);
132846
133352
  }
132847
133353
  if (values.version) {
132848
- console.log("0.81.0");
133354
+ console.log("0.82.0");
132849
133355
  process.exit(0);
132850
133356
  }
132851
133357
  if (values["post-install-check"]) {
132852
133358
  const claudeFound = checkClaude();
132853
133359
  const coreExtensionsFound = checkCoreExtensions();
132854
133360
  const extensionsCompile = await checkExtensionCompilation();
132855
- console.log(`dorkos ${"0.81.0"}`);
133361
+ console.log(`dorkos ${"0.82.0"}`);
132856
133362
  if (!coreExtensionsFound) {
132857
133363
  console.log("Installation incomplete \u2014 bundled core extensions are missing.");
132858
133364
  }
@@ -133009,7 +133515,7 @@ if (fs28.existsSync(envPath)) {
133009
133515
  }
133010
133516
  uninstallCliErrorHandlers?.();
133011
133517
  process.env.DORKOS_CLI_ENTRYPOINT = fileURLToPath6(import.meta.url);
133012
- process.env.DORKOS_CLI_VERSION = "0.81.0";
133518
+ process.env.DORKOS_CLI_VERSION = "0.82.0";
133013
133519
  var server;
133014
133520
  try {
133015
133521
  server = await import("../server/index.js");
@@ -133034,7 +133540,7 @@ var ansiReset = "\x1B[0m";
133034
133540
  console.log("");
133035
133541
  console.log(`${purple}${logo}${ansiReset}`);
133036
133542
  console.log("");
133037
- console.log(` DorkOS v${"0.81.0"}`);
133543
+ console.log(` DorkOS v${"0.82.0"}`);
133038
133544
  console.log(` Local: ${link(localUrl, localUrl)}`);
133039
133545
  var nets = networkInterfaces();
133040
133546
  var networkUrl = null;
@@ -133057,9 +133563,9 @@ if (shouldOpenBrowser && process.stdin.isTTY) {
133057
133563
  const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
133058
133564
  exec(`${openCmd} ${localUrl}`);
133059
133565
  }
133060
- checkForUpdate("0.81.0").then((latestVersion) => {
133566
+ checkForUpdate("0.82.0").then((latestVersion) => {
133061
133567
  if (latestVersion) {
133062
- const msg = `Update available: ${"0.81.0"} \u2192 ${latestVersion}`;
133568
+ const msg = `Update available: ${"0.82.0"} \u2192 ${latestVersion}`;
133063
133569
  const cmd = "Run npm install -g dorkos@latest to update";
133064
133570
  const width = Math.max(msg.length, cmd.length) + 6;
133065
133571
  const pad2 = (s2) => `\u2502 ${s2}${" ".repeat(width - s2.length - 6)} \u2502`;