@piagent/platform 1.44.3 → 1.44.4

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 (83) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +1 -1
  3. package/README.vi.md +1 -1
  4. package/docs/command-reference-vietnamese.md +2 -2
  5. package/docs/distribution-standard.md +6 -6
  6. package/docs/en/windows.md +2 -0
  7. package/docs/herdr-workflow.md +13 -1
  8. package/docs/languages.json +4 -4
  9. package/docs/operator-manual-vietnamese.md +7 -7
  10. package/docs/publishing-for-teams.md +1 -0
  11. package/docs/quickstart-vietnamese.md +1 -1
  12. package/docs/release-install-policy.md +2 -2
  13. package/docs/team-onboarding.md +2 -2
  14. package/docs/vi/windows.md +2 -0
  15. package/docs-site/architecture.html +1 -1
  16. package/docs-site/assets/search-en.json +1 -1
  17. package/docs-site/assets/search-vi.json +1 -1
  18. package/docs-site/benchmark.html +1 -1
  19. package/docs-site/commands.html +1 -1
  20. package/docs-site/content/en/quickstart.html +1 -1
  21. package/docs-site/content/quickstart.html +1 -1
  22. package/docs-site/context-engine.html +1 -1
  23. package/docs-site/ecosystem.html +1 -1
  24. package/docs-site/en/architecture.html +1 -1
  25. package/docs-site/en/benchmark.html +1 -1
  26. package/docs-site/en/commands.html +1 -1
  27. package/docs-site/en/context-engine.html +1 -1
  28. package/docs-site/en/ecosystem.html +1 -1
  29. package/docs-site/en/index.html +9 -9
  30. package/docs-site/en/mcp-approval.html +1 -1
  31. package/docs-site/en/mcp-auth.html +1 -1
  32. package/docs-site/en/mcp-servers.html +1 -1
  33. package/docs-site/en/mcp.html +1 -1
  34. package/docs-site/en/permissions.html +1 -1
  35. package/docs-site/en/profiles.html +1 -1
  36. package/docs-site/en/quickstart.html +2 -2
  37. package/docs-site/en/runtime.html +1 -1
  38. package/docs-site/en/scope.html +1 -1
  39. package/docs-site/en/security.html +1 -1
  40. package/docs-site/en/team.html +1 -1
  41. package/docs-site/en/update.html +3 -3
  42. package/docs-site/en/whats-new.html +27 -16
  43. package/docs-site/en/windows.html +1 -1
  44. package/docs-site/en/workflows.html +1 -1
  45. package/docs-site/index.html +9 -9
  46. package/docs-site/mcp-approval.html +1 -1
  47. package/docs-site/mcp-auth.html +1 -1
  48. package/docs-site/mcp-servers.html +1 -1
  49. package/docs-site/mcp.html +1 -1
  50. package/docs-site/permissions.html +1 -1
  51. package/docs-site/profiles.html +1 -1
  52. package/docs-site/quickstart.html +2 -2
  53. package/docs-site/releases.json +31 -0
  54. package/docs-site/runtime.html +1 -1
  55. package/docs-site/scope.html +1 -1
  56. package/docs-site/security.html +1 -1
  57. package/docs-site/team.html +1 -1
  58. package/docs-site/update.html +3 -3
  59. package/docs-site/whats-new.html +27 -16
  60. package/docs-site/windows.html +1 -1
  61. package/docs-site/workflows.html +1 -1
  62. package/evals/private-holdout-v1/public-exposure.v2.json +2 -2
  63. package/package.json +1 -1
  64. package/packages/piagent-core/extensions/company-session-guard.ts +4 -2
  65. package/packages/piagent-core/managed/herdr-reporter.mjs +85 -0
  66. package/packages/piagent-core/managed/store.d.mts +1 -0
  67. package/packages/piagent-core/managed/store.mjs +13 -0
  68. package/packages/piagent-core/package.json +1 -1
  69. package/packages/piagent-webui/dist/client/assets/{App-DcaqK-_s.js → App-CiwY9VpU.js} +1 -1
  70. package/packages/piagent-webui/dist/client/assets/{GatewayApp-5DVdNIyr.js → GatewayApp-DrNJW3v_.js} +3 -3
  71. package/packages/piagent-webui/dist/client/assets/{InspectionApp-CBPHxuqj.js → InspectionApp-BBiwSaV0.js} +1 -1
  72. package/packages/piagent-webui/dist/client/assets/{SessionAgentWorkspace-DmD9Qt4f.js → SessionAgentWorkspace-DwyPebIX.js} +1 -1
  73. package/packages/piagent-webui/dist/client/assets/{SessionInspectorDrawer-CK5ujmH3.js → SessionInspectorDrawer-CpVzaf_G.js} +2 -2
  74. package/packages/piagent-webui/dist/client/assets/SettingsNavigation-C-tO5iXn.js +3 -0
  75. package/packages/piagent-webui/dist/client/assets/{SettingsPage-Dda8GW2a.js → SettingsPage-Ca-qRSZa.js} +1 -1
  76. package/packages/piagent-webui/dist/client/assets/{TerminalPanel-X2389XHl.js → TerminalPanel-B8j_r6-y.js} +1 -1
  77. package/packages/piagent-webui/dist/client/assets/{WorkspaceCodeEditor-Dt3dS_QG.js → WorkspaceCodeEditor-BDTPvq-0.js} +1 -1
  78. package/packages/piagent-webui/dist/client/assets/{WorkspaceExplorer-CBHwY4BN.js → WorkspaceExplorer-DVsNU0eu.js} +3 -3
  79. package/packages/piagent-webui/dist/client/assets/{index-BMQo9OEq.js → index-uhJMXxqD.js} +2 -2
  80. package/packages/piagent-webui/dist/client/index.html +1 -1
  81. package/packages/piagent-webui/shared/company-copy.ts +1 -0
  82. package/scripts/piagent-studio.mjs +16 -6
  83. package/packages/piagent-webui/dist/client/assets/SettingsNavigation-BnorH-l_.js +0 -3
@@ -37,7 +37,7 @@
37
37
  <span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
38
38
  <span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
39
39
  </a>
40
- <a class="version-badge" href="/whats-new" data-docs-version="v1.44.3" title="v1.44.3 docs · VI"><span class="dot"></span>v1.44.3</a>
40
+ <a class="version-badge" href="/whats-new" data-docs-version="v1.44.4" title="v1.44.4 docs · VI"><span class="dot"></span>v1.44.4</a>
41
41
  <nav class="top-nav" aria-label="Tài liệu">
42
42
  <a href="/quickstart">Tài liệu</a>
43
43
  <a href="/whats-new">Changelog</a>
@@ -145,9 +145,9 @@
145
145
  <h2 id="pin-cho-team">Pin một bản cho cả team</h2>
146
146
  <p>Khi rollout cho team, cài đúng bản Pi host và đúng bản platform, rồi chạy installer ở chế độ stable. Bước <code>--dry-run</code> in ra những gì sẽ đổi.</p>
147
147
  <div class="command-card">
148
- <header><span>Cài pin theo bản</span><button class="clip-btn" data-clip="npm install -g --ignore-scripts @earendil-works/pi-coding-agent@1.3.0&#10;npm install -g --ignore-scripts @piagent/platform@1.44.3&#10;piagent-install --stable --dry-run&#10;piagent-install --stable">Lấy lệnh</button></header>
148
+ <header><span>Cài pin theo bản</span><button class="clip-btn" data-clip="npm install -g --ignore-scripts @earendil-works/pi-coding-agent@1.3.0&#10;npm install -g --ignore-scripts @piagent/platform@1.44.4&#10;piagent-install --stable --dry-run&#10;piagent-install --stable">Lấy lệnh</button></header>
149
149
  <pre><code>npm install -g --ignore-scripts @earendil-works/pi-coding-agent@1.3.0
150
- npm install -g --ignore-scripts @piagent/platform@1.44.3
150
+ npm install -g --ignore-scripts @piagent/platform@1.44.4
151
151
  piagent-install --stable --dry-run
152
152
  piagent-install --stable</code></pre>
153
153
  </div>
@@ -37,7 +37,7 @@
37
37
  <span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
38
38
  <span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
39
39
  </a>
40
- <a class="version-badge" href="/whats-new" data-docs-version="v1.44.3" title="v1.44.3 docs · VI"><span class="dot"></span>v1.44.3</a>
40
+ <a class="version-badge" href="/whats-new" data-docs-version="v1.44.4" title="v1.44.4 docs · VI"><span class="dot"></span>v1.44.4</a>
41
41
  <nav class="top-nav" aria-label="Tài liệu">
42
42
  <a href="/quickstart">Tài liệu</a>
43
43
  <a href="/whats-new" aria-current="page">Changelog</a>
@@ -108,7 +108,19 @@
108
108
  <div class="release-filter" role="toolbar" aria-label="Lọc theo loại thay đổi"><button type="button" data-filter-kind="all" aria-pressed="true">Tất cả</button><button type="button" data-filter-kind="new" aria-pressed="false">Mới</button><button type="button" data-filter-kind="improved" aria-pressed="false">Cải thiện</button><button type="button" data-filter-kind="fixed" aria-pressed="false">Sửa lỗi</button><button type="button" data-filter-kind="security" aria-pressed="false">Bảo mật</button></div>
109
109
  <section class="section releases" data-releases>
110
110
  <h2 id="latest" class="sr-only">Mới nhất</h2>
111
- <article class="release latest" id="v1-44-3" data-release>
111
+ <article class="release latest" id="v1-44-4" data-release>
112
+ <div class="release-meta"><a class="release-version" href="#v1-44-4">v1.44.4</a><time class="release-date" datetime="2026-10-28">28/10/2026</time></div>
113
+ <div class="release-body">
114
+ <h3 data-toc-skip id="v1-44-4-title">Conversation công ty trở lại trong pane Herdr</h3>
115
+ <p>Trong Herdr (Windows: cài trong WSL), pane công ty báo trạng thái và mở lại đúng conversation sau khi Herdr khởi động lại, bằng piagent studio --session.</p>
116
+ <ul class="release-items">
117
+ <li data-kind="new"><span class="kind kind-new">Mới</span><span>piagent studio --session &lt;file&gt; mở lại một conversation công ty; chỉ nhận file trong kho của chính member (ngoài kho báo managed-session-outside-store).</span></li>
118
+ <li data-kind="new"><span class="kind kind-new">Mới</span><span>Conversation công ty trong pane Herdr báo đang chạy, chờ hay rảnh cho Herdr, và Herdr resume bằng piagent studio, không phải pi cá nhân. Cần Herdr 0.9.2+.</span></li>
119
+ <li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>WSL/Linux: Pi cá nhân không còn mở được conversation công ty chưa có lượt nào, và piagent studio --web mở được trình duyệt (wslview/explorer.exe).</span></li>
120
+ </ul>
121
+ </div>
122
+ </article>
123
+ <article class="release" id="v1-44-3" data-release>
112
124
  <div class="release-meta"><a class="release-version" href="#v1-44-3">v1.44.3</a><time class="release-date" datetime="2026-10-28">28/10/2026</time></div>
113
125
  <div class="release-body">
114
126
  <h3 data-toc-skip id="v1-44-3-title">Prompt injection không lặng lẽ đọc được hệ thống</h3>
@@ -414,25 +426,24 @@
414
426
  <p class="release-requires"><strong>Cần:</strong> Agent Watch 0.15.11 (Windows 0.1.16)</p>
415
427
  </div>
416
428
  </article>
417
- <article class="release" id="v1-37-0" data-release>
418
- <div class="release-meta"><a class="release-version" href="#v1-37-0">v1.37.0</a><time class="release-date" datetime="2026-10-22">22/10/2026</time></div>
419
- <div class="release-body">
420
- <h3 data-toc-skip id="v1-37-0-title">Câu trả lời bị cắt không còn làm dừng task dài</h3>
421
- <p>Câu trả lời bị cắt giữa chừng phía sau Studio được hỏi lại và task tự làm tiếp; <code>piagent studio --rpc</code> cho script điều khiển cuộc trò chuyện công ty.</p>
422
- <ul class="release-items">
423
- <li data-kind="new"><span class="kind kind-new">Mới</span><span>Lệnh mới <code>piagent studio --rpc</code> chạy một cuộc trò chuyện công ty qua giao thức RPC của Pi trên stdin/stdout, nhiều tin nhắn và có <code>ask_user</code>.</span></li>
424
- <li data-kind="new"><span class="kind kind-new">Mới</span><span>Repository có lane soak cho task dài: một member giả lập điều khiển agent công ty thật qua các task 45–150 phút.</span></li>
425
- <li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Câu trả lời bị cắt giữa chừng từng hiện &quot;không gửi được yêu cầu&quot; và dừng task dài; giờ Piagent hỏi lại và task tự làm tiếp.</span></li>
426
- <li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Terminal công ty không còn thoát với lỗi khi cuộc trò chuyện đóng ngay sau một lượt trong lúc Git vẫn đang trả trạng thái branch.</span></li>
427
- </ul>
428
- </div>
429
- </article>
430
429
  </section>
431
430
  <section class="section archive">
432
431
  <h2 id="archive">Các bản trước</h2>
433
432
  <p class="section-lead">Bản cũ hơn, gom theo tháng. Mở một tháng để xem từng thay đổi.</p>
434
433
  <details class="release-archive">
435
- <summary><span>Tháng 10/2026</span><span class="archive-count">54</span></summary>
434
+ <summary><span>Tháng 10/2026</span><span class="archive-count">55</span></summary>
435
+ <div class="archive-row" id="v1-37-0">
436
+ <div class="archive-head"><a class="release-version" href="#v1-37-0">v1.37.0</a> <span class="release-date">22/10/2026</span></div>
437
+ <div class="archive-body">
438
+ <p><strong>Câu trả lời bị cắt không còn làm dừng task dài</strong> — Câu trả lời bị cắt giữa chừng phía sau Studio được hỏi lại và task tự làm tiếp; <code>piagent studio --rpc</code> cho script điều khiển cuộc trò chuyện công ty.</p>
439
+ <ul class="release-items">
440
+ <li data-kind="new"><span class="kind kind-new">Mới</span><span>Lệnh mới <code>piagent studio --rpc</code> chạy một cuộc trò chuyện công ty qua giao thức RPC của Pi trên stdin/stdout, nhiều tin nhắn và có <code>ask_user</code>.</span></li>
441
+ <li data-kind="new"><span class="kind kind-new">Mới</span><span>Repository có lane soak cho task dài: một member giả lập điều khiển agent công ty thật qua các task 45–150 phút.</span></li>
442
+ <li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Câu trả lời bị cắt giữa chừng từng hiện &quot;không gửi được yêu cầu&quot; và dừng task dài; giờ Piagent hỏi lại và task tự làm tiếp.</span></li>
443
+ <li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Terminal công ty không còn thoát với lỗi khi cuộc trò chuyện đóng ngay sau một lượt trong lúc Git vẫn đang trả trạng thái branch.</span></li>
444
+ </ul>
445
+ </div>
446
+ </div>
436
447
  <div class="archive-row" id="v1-36-1">
437
448
  <div class="archive-head"><a class="release-version" href="#v1-36-1">v1.36.1</a> <span class="release-date">22/10/2026</span></div>
438
449
  <div class="archive-body">
@@ -37,7 +37,7 @@
37
37
  <span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
38
38
  <span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
39
39
  </a>
40
- <a class="version-badge" href="/whats-new" data-docs-version="v1.44.3" title="v1.44.3 docs · VI"><span class="dot"></span>v1.44.3</a>
40
+ <a class="version-badge" href="/whats-new" data-docs-version="v1.44.4" title="v1.44.4 docs · VI"><span class="dot"></span>v1.44.4</a>
41
41
  <nav class="top-nav" aria-label="Tài liệu">
42
42
  <a href="/quickstart">Tài liệu</a>
43
43
  <a href="/whats-new">Changelog</a>
@@ -37,7 +37,7 @@
37
37
  <span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
38
38
  <span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
39
39
  </a>
40
- <a class="version-badge" href="/whats-new" data-docs-version="v1.44.3" title="v1.44.3 docs · VI"><span class="dot"></span>v1.44.3</a>
40
+ <a class="version-badge" href="/whats-new" data-docs-version="v1.44.4" title="v1.44.4 docs · VI"><span class="dot"></span>v1.44.4</a>
41
41
  <nav class="top-nav" aria-label="Tài liệu">
42
42
  <a href="/quickstart">Tài liệu</a>
43
43
  <a href="/whats-new">Changelog</a>
@@ -256,8 +256,8 @@
256
256
  },
257
257
  {
258
258
  "path": "tests",
259
- "fileCount": 631,
260
- "sha256": "37750935b5a593d52607baf8fa6b3faba03105501289fa83f4677504ed05e3d3"
259
+ "fileCount": 632,
260
+ "sha256": "32e1a1de9bc5896285ea16a4ad1d0c817e036f1b1877da60b11f406579b5356a"
261
261
  }
262
262
  ],
263
263
  "custodianComparisonRules": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piagent/platform",
3
- "version": "1.44.3",
3
+ "version": "1.44.4",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -7,11 +7,13 @@ import path from "node:path";
7
7
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
8
8
 
9
9
  const COMPANY_PROVIDER = "agent_watch_managed";
10
- const STORE = "/AgentWatch/ManagedSessions/";
10
+ // Agent Watch's store: the macOS app's support folder, or the XDG data folder
11
+ // on Linux and WSL (managed/store.mjs).
12
+ const STORE = /\/(AgentWatch|agentwatch)\/ManagedSessions\//;
11
13
 
12
14
  export function isCompanySession(ctx: Pick<ExtensionContext, "sessionManager">): boolean {
13
15
  const file = String(ctx.sessionManager?.getSessionFile?.() ?? "").split(path.sep).join("/");
14
- if (file.includes(STORE)) return true;
16
+ if (STORE.test(file)) return true;
15
17
  try {
16
18
  return ctx.sessionManager.getEntries().some((entry: any) => typeof entry?.customType === "string" && entry.customType.startsWith("agent-watch-run"));
17
19
  } catch {
@@ -0,0 +1,85 @@
1
+ import net from 'node:net';
2
+
3
+ // Herdr (herdr.dev) keeps panes of agents and resumes each one's session after
4
+ // its server restarts. Its own Pi extension lives in ~/.pi/agent/extensions,
5
+ // which a company conversation never loads, and `piagent studio` starts from a
6
+ // clean environment, so Herdr would see no state and resume nothing. This is
7
+ // the company Terminal's own reporter: the same socket requests (newline JSON,
8
+ // pane.report_agent), with the command that reopens this conversation in
9
+ // `piagent studio` instead of personal Pi.
10
+ const SOURCE = 'custom:piagent-studio', AGENT = 'piagent';
11
+
12
+ // What a Herdr pane gives its processes, read before the environment is
13
+ // cleared; null outside Herdr. Nothing else of it reaches the conversation.
14
+ export function herdrEnvironment(environment = process.env) {
15
+ const socket = environment.HERDR_SOCKET_PATH, pane = environment.HERDR_PANE_ID;
16
+ if (environment.HERDR_ENV !== '1' || !socket || !pane) return null;
17
+ return { socket: process.platform === 'win32' ? `\\\\.\\pipe\\${socket}` : socket, pane };
18
+ }
19
+
20
+ // Herdr types this into the restored pane's shell. It refuses apostrophes and
21
+ // control characters (its POSIX quoting), so such a path is not offered.
22
+ export function herdrResumeArgv(cwd, sessionFile) {
23
+ const argv = ['piagent', 'studio', '--project', cwd, ...(sessionFile ? ['--session', sessionFile] : [])];
24
+ return argv.every(part => typeof part === 'string' && part && !part.includes("'") && !/\p{Cc}/u.test(part)) ? argv : null;
25
+ }
26
+
27
+ // One request, delivered when Herdr answers; a second, longer try when the
28
+ // first is lost. A Herdr that is gone costs the conversation nothing.
29
+ function sendOnce(socketPath, request, timeoutMs) {
30
+ return new Promise(resolve => {
31
+ let done = false;
32
+ const socket = net.createConnection(socketPath);
33
+ const finish = delivered => { if (done) return; done = true; clearTimeout(timer); socket.destroy(); resolve(delivered); };
34
+ const timer = setTimeout(() => finish(false), timeoutMs); timer.unref?.();
35
+ socket.on('error', () => finish(false));
36
+ socket.on('connect', () => socket.write(`${JSON.stringify(request)}\n`));
37
+ socket.on('data', () => finish(true));
38
+ socket.on('end', () => finish(false));
39
+ });
40
+ }
41
+ export async function sendHerdrRequest(socketPath, request) {
42
+ if (!await sendOnce(socketPath, request, 500)) await sendOnce(socketPath, request, 1500);
43
+ }
44
+
45
+ // working while a turn runs, blocked while the conversation waits for the
46
+ // member (Pi's `herdr:blocked` events), idle otherwise. Reports go out one at a
47
+ // time, the newest state winning.
48
+ export function companyHerdrExtension(herdr, { send = sendHerdrRequest } = {}) {
49
+ return (pi) => {
50
+ let seq = Date.now() * 1000, active = false, blocked = 0, label, last, resumeArgv, queued, sending = false;
51
+ const desired = () => blocked > 0 ? { state: 'blocked', message: label } : { state: active ? 'working' : 'idle', message: undefined };
52
+ const drain = async () => {
53
+ if (sending) return;
54
+ sending = true;
55
+ try {
56
+ while (queued) {
57
+ const next = queued; queued = undefined;
58
+ await send(herdr.socket, { id: `${SOURCE}:${next.seq}`, method: 'pane.report_agent',
59
+ params: { pane_id: herdr.pane, source: SOURCE, agent: AGENT, state: next.state, message: next.message, seq: next.seq, ...(resumeArgv ? { resume_argv: resumeArgv } : {}) } });
60
+ }
61
+ } finally { sending = false; if (queued) void drain(); }
62
+ };
63
+ const publish = (force = false) => {
64
+ const next = desired();
65
+ if (!force && next.state === last?.state && next.message === last?.message) return;
66
+ last = next; queued = { ...next, seq: ++seq }; void drain();
67
+ };
68
+ const follow = ctx => {
69
+ let file;
70
+ try { file = ctx?.sessionManager?.getSessionFile?.(); } catch { file = undefined; }
71
+ const argv = herdrResumeArgv(ctx?.cwd, typeof file === 'string' && file ? file : undefined);
72
+ const changed = JSON.stringify(argv) !== JSON.stringify(resumeArgv);
73
+ resumeArgv = argv ?? undefined;
74
+ return changed;
75
+ };
76
+ pi.events?.on?.('herdr:blocked', data => {
77
+ if (data?.active) { blocked += 1; label = data.label; } else { blocked = Math.max(0, blocked - 1); if (!blocked) label = undefined; }
78
+ publish();
79
+ });
80
+ // /new, /resume and /fork start another session: Herdr follows it.
81
+ pi.on('session_start', async (_event, ctx) => { follow(ctx); active = ctx?.isIdle?.() === false; publish(true); });
82
+ pi.on('agent_start', (_event, ctx) => { const changed = follow(ctx); active = true; publish(changed); });
83
+ pi.on('agent_settled', (_event, ctx) => { if (ctx?.isIdle?.() !== true) return; active = false; publish(); });
84
+ };
85
+ }
@@ -3,3 +3,4 @@ export function storedSlot(root: string, slot: string): string | null;
3
3
  export function resolveStore(root: string, slot: string, identity: { origin: unknown; userId: unknown }): string;
4
4
  export function agentWatchDataDirectory(home: string, environment?: Readonly<Record<string, string | undefined>>): string;
5
5
  export function interopEnvironment(environment?: Readonly<Record<string, string | undefined>>): Record<string, string>;
6
+ export function companySessionFile(sessionsDir: string, file: string): string | null;
@@ -74,3 +74,16 @@ export function resolveStore(root, slot, { origin, userId }) {
74
74
  for (const name of new Set([slot, store])) { write(path.join(root, name, 'member'), member); write(path.join(root, name, 'store'), store); }
75
75
  return store;
76
76
  }
77
+
78
+ // A conversation `piagent studio --session` reopens (Herdr's restore names
79
+ // one): only a file of this store's sessions folder. Null when the file was
80
+ // never written (a conversation with no message yet): a new one starts.
81
+ export function companySessionFile(sessionsDir, file) {
82
+ const target = path.resolve(String(file));
83
+ if (!target.endsWith('.jsonl')) throw Error('managed-session-outside-store');
84
+ const real = candidate => { try { return fs.realpathSync(candidate); } catch { return null; } };
85
+ const found = real(target), root = real(sessionsDir) ?? path.resolve(sessionsDir);
86
+ const resolved = found ?? path.join(real(path.dirname(target)) ?? path.dirname(target), path.basename(target));
87
+ if (!resolved.startsWith(root + path.sep)) throw Error('managed-session-outside-store');
88
+ return found && fs.statSync(found).isFile() ? found : null;
89
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piagent/core",
3
- "version": "1.44.3",
3
+ "version": "1.44.4",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "license": "MIT",