pwragent 1.3.11 → 1.3.12

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.
@@ -9187,6 +9187,152 @@ var import_websocket = __toESM(require_websocket(), 1);
9187
9187
  var import_websocket_server = __toESM(require_websocket_server(), 1);
9188
9188
  var wrapper_default = import_websocket.default;
9189
9189
 
9190
+ // ../shared/src/contracts/navigation.ts
9191
+ var WORKTREE_IMAGE_MAX_BYTES = 16 * 1024 * 1024;
9192
+ function buildThreadIdentityKey(backend, threadId) {
9193
+ return `${backend}:${threadId}`;
9194
+ }
9195
+ var NAVIGATION_QUERY_PROTOCOL_VERSION = 2;
9196
+ var NAVIGATION_QUERY_MAX_PAGE_ROWS = 100;
9197
+ var NAVIGATION_QUERY_MAX_RESULT_BYTES = 252 * 1024;
9198
+
9199
+ // ../shared/src/thread-pins.ts
9200
+ var KEEP_AT_TOP_RANK_BOUNDARY = -(2 ** 39);
9201
+ var KEEP_AT_TOP_RANK_BASE = -(2 ** 40);
9202
+ function comparePinnedThreads(left, right) {
9203
+ const rankComparison = comparePinRanks(left.pinnedRank, right.pinnedRank);
9204
+ if (rankComparison !== 0) return rankComparison;
9205
+ const updatedComparison = (right.updatedAt ?? 0) - (left.updatedAt ?? 0);
9206
+ if (updatedComparison !== 0) return updatedComparison;
9207
+ return left.id.localeCompare(right.id);
9208
+ }
9209
+ function comparePinRanks(left, right) {
9210
+ const leftNumber = parsePinRank(left);
9211
+ const rightNumber = parsePinRank(right);
9212
+ if (leftNumber !== rightNumber) return leftNumber - rightNumber;
9213
+ return (left ?? "").localeCompare(right ?? "");
9214
+ }
9215
+ function parsePinRank(rank) {
9216
+ if (!rank?.trim()) return Number.POSITIVE_INFINITY;
9217
+ const parsed = Number(rank);
9218
+ return Number.isFinite(parsed) ? parsed : Number.POSITIVE_INFINITY;
9219
+ }
9220
+
9221
+ // ../shared/src/directory-navigation.ts
9222
+ function pathBaseName(value) {
9223
+ if (!value) {
9224
+ return value ?? "";
9225
+ }
9226
+ const normalized = value.replace(/[\\/]+$/, "");
9227
+ const parts = normalized.split(/[\\/]/).filter(Boolean);
9228
+ return parts.at(-1) ?? normalized;
9229
+ }
9230
+ function canonicalizeNavigationPath(value) {
9231
+ return value.replace(/\\/g, "/").replace(/\/+$/, "");
9232
+ }
9233
+ function normalizeGitOriginUrl(value) {
9234
+ const trimmed = value?.trim();
9235
+ if (!trimmed) {
9236
+ return void 0;
9237
+ }
9238
+ const sshMatch = trimmed.match(/^git@([^:]+):(.+)$/i);
9239
+ let candidate = sshMatch ? `${sshMatch[1]}/${sshMatch[2]}` : trimmed.replace(/^[a-z]+:\/\//i, "");
9240
+ if (!sshMatch && /^[a-z]+:\/\//i.test(trimmed) && !/^file:/i.test(trimmed)) {
9241
+ const url = trimmed.match(/^[a-z]+:\/\/(?:[^/?#]*@)?([^/?#]+)(\/[^?#]*)/i);
9242
+ if (!url) {
9243
+ return void 0;
9244
+ }
9245
+ candidate = `${url[1]}${url[2]}`;
9246
+ }
9247
+ const normalized = candidate.replace(/\.git$/i, "").replace(/^ssh\//i, "").replace(/^\/+/, "").replace(/\/+$/, "").toLowerCase();
9248
+ return normalized || void 0;
9249
+ }
9250
+ function isInternalDirectoryLabel(value) {
9251
+ return Boolean(value?.startsWith("directory:") || value?.startsWith("workspace:"));
9252
+ }
9253
+ function displayDirectoryLabel(params) {
9254
+ const label = params.label?.trim();
9255
+ if (label && !isInternalDirectoryLabel(label)) {
9256
+ return label;
9257
+ }
9258
+ if (params.kind === "workspace") {
9259
+ return "Workspaces";
9260
+ }
9261
+ return pathBaseName(params.path) || label || "Directory";
9262
+ }
9263
+ function matchScratchProjectsRoot(value) {
9264
+ const scratchWorkspaceRootMatch = value.match(
9265
+ /^(.*[\\/]\.pwrag(?:ent|nt)(?:[\\/]profiles[\\/][^\\/]+)?[\\/]projects)$/
9266
+ );
9267
+ if (scratchWorkspaceRootMatch) {
9268
+ return scratchWorkspaceRootMatch[1];
9269
+ }
9270
+ const scratchWorkspaceMatch = value.match(
9271
+ /^(.*[\\/]\.pwrag(?:ent|nt)(?:[\\/]profiles[\\/][^\\/]+)?[\\/]projects)[\\/][^\\/]+$/
9272
+ );
9273
+ return scratchWorkspaceMatch?.[1];
9274
+ }
9275
+ function matchCodexChatsRoot(value) {
9276
+ const codexChatsRootMatch = value.match(
9277
+ /^(.*[\\/]Documents[\\/]Codex)(?:[\\/]\d{4}-\d{2}-\d{2}(?:[\\/].*)?)?$/
9278
+ );
9279
+ return codexChatsRootMatch?.[1];
9280
+ }
9281
+ function classifyDirectory(directory) {
9282
+ const path11 = canonicalizeNavigationPath(directory.path);
9283
+ const scratchProjectsRoot = matchScratchProjectsRoot(path11);
9284
+ if (scratchProjectsRoot) {
9285
+ return {
9286
+ key: `workspace:${scratchProjectsRoot}`,
9287
+ kind: "workspace",
9288
+ label: "Workspaces",
9289
+ path: scratchProjectsRoot
9290
+ };
9291
+ }
9292
+ const codexChatsRoot = matchCodexChatsRoot(path11);
9293
+ if (codexChatsRoot) {
9294
+ return {
9295
+ key: `directory:${codexChatsRoot}`,
9296
+ kind: "directory",
9297
+ label: "Codex Chats",
9298
+ path: codexChatsRoot
9299
+ };
9300
+ }
9301
+ const repoWorktreeMatch = path11.match(
9302
+ /^(.*)[\\/]\.worktrees[\\/][^\\/]+(?:[\\/].*)?$/
9303
+ );
9304
+ if (directory.kind === "worktree" && repoWorktreeMatch) {
9305
+ const canonicalPath = repoWorktreeMatch[1];
9306
+ return {
9307
+ key: `directory:${canonicalPath}`,
9308
+ kind: "directory",
9309
+ label: pathBaseName(canonicalPath),
9310
+ path: canonicalPath
9311
+ };
9312
+ }
9313
+ const codexWorktreeMatch = path11.match(
9314
+ /^(?:[A-Za-z]:)?[\\/].*[\\/]\.codex(?:[\\/]profiles[\\/][^\\/]+)?[\\/]worktrees[\\/][^\\/]+[\\/]([^\\/]+)(?:[\\/].*)?$/
9315
+ );
9316
+ if (codexWorktreeMatch) {
9317
+ return {
9318
+ key: `directory:${path11}`,
9319
+ kind: "directory",
9320
+ label: codexWorktreeMatch[1],
9321
+ path: path11
9322
+ };
9323
+ }
9324
+ return {
9325
+ key: `directory:${path11}`,
9326
+ kind: "directory",
9327
+ label: displayDirectoryLabel({
9328
+ kind: "directory",
9329
+ label: directory.label,
9330
+ path: path11
9331
+ }),
9332
+ path: path11
9333
+ };
9334
+ }
9335
+
9190
9336
  // ../shared/src/contracts/agent-tools.ts
9191
9337
  var PWRAGENT_TOOL_NAMESPACE = "pwragent";
9192
9338
 
@@ -9381,15 +9527,6 @@ var PWRAGENT_MESSAGING_CALLABLE_OPERATION_NAMES = [
9381
9527
  ...PWRAGENT_MESSAGING_LEGACY_OPERATION_NAMES
9382
9528
  ];
9383
9529
 
9384
- // ../shared/src/contracts/navigation.ts
9385
- var WORKTREE_IMAGE_MAX_BYTES = 16 * 1024 * 1024;
9386
- function buildThreadIdentityKey(backend, threadId) {
9387
- return `${backend}:${threadId}`;
9388
- }
9389
- var NAVIGATION_QUERY_PROTOCOL_VERSION = 2;
9390
- var NAVIGATION_QUERY_MAX_PAGE_ROWS = 100;
9391
- var NAVIGATION_QUERY_MAX_RESULT_BYTES = 252 * 1024;
9392
-
9393
9530
  // ../shared/src/navigation-star-map-filters.ts
9394
9531
  var NAVIGATION_STAR_MAP_FACETS = {
9395
9532
  attention: ["attention", "approval", "pr", "unpushed"],
@@ -9444,143 +9581,6 @@ function threadTodoMessageOriginFromUnknown(value) {
9444
9581
  return { id, ...title ? { title } : {} };
9445
9582
  }
9446
9583
 
9447
- // ../shared/src/thread-pins.ts
9448
- var KEEP_AT_TOP_RANK_BOUNDARY = -(2 ** 39);
9449
- var KEEP_AT_TOP_RANK_BASE = -(2 ** 40);
9450
- function comparePinnedThreads(left, right) {
9451
- const rankComparison = comparePinRanks(left.pinnedRank, right.pinnedRank);
9452
- if (rankComparison !== 0) return rankComparison;
9453
- const updatedComparison = (right.updatedAt ?? 0) - (left.updatedAt ?? 0);
9454
- if (updatedComparison !== 0) return updatedComparison;
9455
- return left.id.localeCompare(right.id);
9456
- }
9457
- function comparePinRanks(left, right) {
9458
- const leftNumber = parsePinRank(left);
9459
- const rightNumber = parsePinRank(right);
9460
- if (leftNumber !== rightNumber) return leftNumber - rightNumber;
9461
- return (left ?? "").localeCompare(right ?? "");
9462
- }
9463
- function parsePinRank(rank) {
9464
- if (!rank?.trim()) return Number.POSITIVE_INFINITY;
9465
- const parsed = Number(rank);
9466
- return Number.isFinite(parsed) ? parsed : Number.POSITIVE_INFINITY;
9467
- }
9468
-
9469
- // ../shared/src/directory-navigation.ts
9470
- function pathBaseName(value) {
9471
- if (!value) {
9472
- return value ?? "";
9473
- }
9474
- const normalized = value.replace(/[\\/]+$/, "");
9475
- const parts = normalized.split(/[\\/]/).filter(Boolean);
9476
- return parts.at(-1) ?? normalized;
9477
- }
9478
- function canonicalizeNavigationPath(value) {
9479
- return value.replace(/\\/g, "/").replace(/\/+$/, "");
9480
- }
9481
- function normalizeGitOriginUrl(value) {
9482
- const trimmed = value?.trim();
9483
- if (!trimmed) {
9484
- return void 0;
9485
- }
9486
- const sshMatch = trimmed.match(/^git@([^:]+):(.+)$/i);
9487
- let candidate = sshMatch ? `${sshMatch[1]}/${sshMatch[2]}` : trimmed.replace(/^[a-z]+:\/\//i, "");
9488
- if (!sshMatch && /^[a-z]+:\/\//i.test(trimmed) && !/^file:/i.test(trimmed)) {
9489
- const url = trimmed.match(/^[a-z]+:\/\/(?:[^/?#]*@)?([^/?#]+)(\/[^?#]*)/i);
9490
- if (!url) {
9491
- return void 0;
9492
- }
9493
- candidate = `${url[1]}${url[2]}`;
9494
- }
9495
- const normalized = candidate.replace(/\.git$/i, "").replace(/^ssh\//i, "").replace(/^\/+/, "").replace(/\/+$/, "").toLowerCase();
9496
- return normalized || void 0;
9497
- }
9498
- function isInternalDirectoryLabel(value) {
9499
- return Boolean(value?.startsWith("directory:") || value?.startsWith("workspace:"));
9500
- }
9501
- function displayDirectoryLabel(params) {
9502
- const label = params.label?.trim();
9503
- if (label && !isInternalDirectoryLabel(label)) {
9504
- return label;
9505
- }
9506
- if (params.kind === "workspace") {
9507
- return "Workspaces";
9508
- }
9509
- return pathBaseName(params.path) || label || "Directory";
9510
- }
9511
- function matchScratchProjectsRoot(value) {
9512
- const scratchWorkspaceRootMatch = value.match(
9513
- /^(.*[\\/]\.pwrag(?:ent|nt)(?:[\\/]profiles[\\/][^\\/]+)?[\\/]projects)$/
9514
- );
9515
- if (scratchWorkspaceRootMatch) {
9516
- return scratchWorkspaceRootMatch[1];
9517
- }
9518
- const scratchWorkspaceMatch = value.match(
9519
- /^(.*[\\/]\.pwrag(?:ent|nt)(?:[\\/]profiles[\\/][^\\/]+)?[\\/]projects)[\\/][^\\/]+$/
9520
- );
9521
- return scratchWorkspaceMatch?.[1];
9522
- }
9523
- function matchCodexChatsRoot(value) {
9524
- const codexChatsRootMatch = value.match(
9525
- /^(.*[\\/]Documents[\\/]Codex)(?:[\\/]\d{4}-\d{2}-\d{2}(?:[\\/].*)?)?$/
9526
- );
9527
- return codexChatsRootMatch?.[1];
9528
- }
9529
- function classifyDirectory(directory) {
9530
- const path11 = canonicalizeNavigationPath(directory.path);
9531
- const scratchProjectsRoot = matchScratchProjectsRoot(path11);
9532
- if (scratchProjectsRoot) {
9533
- return {
9534
- key: `workspace:${scratchProjectsRoot}`,
9535
- kind: "workspace",
9536
- label: "Workspaces",
9537
- path: scratchProjectsRoot
9538
- };
9539
- }
9540
- const codexChatsRoot = matchCodexChatsRoot(path11);
9541
- if (codexChatsRoot) {
9542
- return {
9543
- key: `directory:${codexChatsRoot}`,
9544
- kind: "directory",
9545
- label: "Codex Chats",
9546
- path: codexChatsRoot
9547
- };
9548
- }
9549
- const repoWorktreeMatch = path11.match(
9550
- /^(.*)[\\/]\.worktrees[\\/][^\\/]+(?:[\\/].*)?$/
9551
- );
9552
- if (directory.kind === "worktree" && repoWorktreeMatch) {
9553
- const canonicalPath = repoWorktreeMatch[1];
9554
- return {
9555
- key: `directory:${canonicalPath}`,
9556
- kind: "directory",
9557
- label: pathBaseName(canonicalPath),
9558
- path: canonicalPath
9559
- };
9560
- }
9561
- const codexWorktreeMatch = path11.match(
9562
- /^(?:[A-Za-z]:)?[\\/].*[\\/]\.codex(?:[\\/]profiles[\\/][^\\/]+)?[\\/]worktrees[\\/][^\\/]+[\\/]([^\\/]+)(?:[\\/].*)?$/
9563
- );
9564
- if (codexWorktreeMatch) {
9565
- return {
9566
- key: `directory:${path11}`,
9567
- kind: "directory",
9568
- label: codexWorktreeMatch[1],
9569
- path: path11
9570
- };
9571
- }
9572
- return {
9573
- key: `directory:${path11}`,
9574
- kind: "directory",
9575
- label: displayDirectoryLabel({
9576
- kind: "directory",
9577
- label: directory.label,
9578
- path: path11
9579
- }),
9580
- path: path11
9581
- };
9582
- }
9583
-
9584
9584
  // ../shared/src/nested-worktree-pathspec.ts
9585
9585
  var EXCLUDE_MAGIC = ":(exclude,top,literal)";
9586
9586
  function normalizeWorktreePath(value) {
@@ -9843,6 +9843,32 @@ function sortThreadJumpMatches(threads, query) {
9843
9843
  });
9844
9844
  }
9845
9845
 
9846
+ // ../shared/src/text-graphemes.ts
9847
+ var segmenter;
9848
+ function* clusters(value) {
9849
+ if (typeof Intl.Segmenter !== "function") {
9850
+ yield* value;
9851
+ return;
9852
+ }
9853
+ segmenter ??= new Intl.Segmenter("en", { granularity: "grapheme" });
9854
+ for (const { segment } of segmenter.segment(value)) {
9855
+ yield segment;
9856
+ }
9857
+ }
9858
+ function graphemePrefix(value, maxLength) {
9859
+ if (value.length <= maxLength) {
9860
+ return value;
9861
+ }
9862
+ let end = 0;
9863
+ for (const cluster of clusters(value)) {
9864
+ if (end + cluster.length > maxLength) {
9865
+ break;
9866
+ }
9867
+ end += cluster.length;
9868
+ }
9869
+ return value.slice(0, end);
9870
+ }
9871
+
9846
9872
  // ../shared/src/thread-titles.ts
9847
9873
  var MAX_DERIVED_THREAD_TITLE_LENGTH = 72;
9848
9874
  var MIN_PREFERRED_BREAK_INDEX = 36;
@@ -9895,7 +9921,7 @@ function shortenDerivedThreadTitle(value) {
9895
9921
  if (wordBreak >= MIN_PREFERRED_BREAK_INDEX) {
9896
9922
  return `${trimTrailingPunctuation(candidate.slice(0, wordBreak))}...`;
9897
9923
  }
9898
- return `${trimTrailingPunctuation(candidate.slice(0, MAX_DERIVED_THREAD_TITLE_LENGTH))}...`;
9924
+ return `${trimTrailingPunctuation(graphemePrefix(candidate, MAX_DERIVED_THREAD_TITLE_LENGTH))}...`;
9899
9925
  }
9900
9926
 
9901
9927
  // ../shared/src/messaging-causal-context.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pwragent",
3
- "version": "1.3.11",
3
+ "version": "1.3.12",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Experimental headless PwrAgent daemon and command-line client.",
@@ -64,7 +64,7 @@
64
64
  "node-pty"
65
65
  ],
66
66
  "pwragentRelease": {
67
- "tag": "v1.3.11",
68
- "commit": "7b787f4a90bfff4811f1d41b04ae025f0cfe6ebf"
67
+ "tag": "v1.3.12",
68
+ "commit": "7654f26215b4b5e47f70cc3fe682fd6e3d39c7f8"
69
69
  }
70
70
  }