@piagent/platform 1.12.0 → 1.13.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.
- package/CHANGELOG.md +39 -0
- package/README.md +3 -3
- package/README.vi.md +5 -1
- package/docs/command-reference-vietnamese.md +2 -2
- package/docs/distribution-standard.md +6 -6
- package/docs/en/README.md +1 -0
- package/docs/en/windows.md +66 -0
- package/docs/languages.json +13 -4
- package/docs/operator-manual-vietnamese.md +7 -7
- package/docs/publishing-for-teams.md +2 -0
- package/docs/release-install-policy.md +2 -2
- package/docs/team-onboarding.md +2 -2
- package/docs/vi/README.md +1 -0
- package/docs/vi/windows.md +66 -0
- package/docs-site/architecture.html +1 -1
- package/docs-site/benchmark.html +1 -1
- package/docs-site/commands.html +1 -1
- package/docs-site/content/en/index.html +4 -4
- package/docs-site/content/en/whats-new.html +19 -0
- package/docs-site/content/index.html +4 -4
- package/docs-site/content/whats-new.html +19 -0
- package/docs-site/context-engine.html +1 -1
- package/docs-site/ecosystem.html +1 -1
- package/docs-site/en/architecture.html +1 -1
- package/docs-site/en/benchmark.html +1 -1
- package/docs-site/en/commands.html +1 -1
- package/docs-site/en/context-engine.html +1 -1
- package/docs-site/en/ecosystem.html +1 -1
- package/docs-site/en/index.html +5 -5
- package/docs-site/en/mcp-approval.html +1 -1
- package/docs-site/en/mcp-auth.html +1 -1
- package/docs-site/en/mcp-servers.html +1 -1
- package/docs-site/en/mcp.html +1 -1
- package/docs-site/en/permissions.html +1 -1
- package/docs-site/en/profiles.html +1 -1
- package/docs-site/en/quickstart.html +1 -1
- package/docs-site/en/runtime.html +1 -1
- package/docs-site/en/scope.html +1 -1
- package/docs-site/en/security.html +1 -1
- package/docs-site/en/team.html +1 -1
- package/docs-site/en/whats-new.html +20 -1
- package/docs-site/en/workflows.html +1 -1
- package/docs-site/index.html +5 -5
- package/docs-site/mcp-approval.html +1 -1
- package/docs-site/mcp-auth.html +1 -1
- package/docs-site/mcp-servers.html +1 -1
- package/docs-site/mcp.html +1 -1
- package/docs-site/permissions.html +1 -1
- package/docs-site/profiles.html +1 -1
- package/docs-site/quickstart.html +1 -1
- package/docs-site/runtime.html +1 -1
- package/docs-site/scope.html +1 -1
- package/docs-site/security.html +1 -1
- package/docs-site/team.html +1 -1
- package/docs-site/whats-new.html +20 -1
- package/docs-site/workflows.html +1 -1
- package/evals/private-holdout-v1/public-exposure.v2.json +2 -2
- package/package.json +1 -1
- package/packages/piagent-core/extensions/piagent-guard.ts +3 -1
- package/packages/piagent-core/extensions/shell-write-targets.js +2 -1
- package/packages/piagent-core/extensions/source-checkout-paths.ts +4 -3
- package/packages/piagent-core/extensions/task-journal.js +2 -1
- package/packages/piagent-core/extensions/task-state.js +3 -3
- package/packages/piagent-core/managed/broker-client.mjs +2 -1
- package/packages/piagent-core/managed/doctor.mjs +5 -3
- package/packages/piagent-core/managed/language-environment.mjs +16 -6
- package/packages/piagent-core/managed/linux-sandbox.mjs +81 -0
- package/packages/piagent-core/managed/session.mjs +4 -1
- package/packages/piagent-core/managed/store.d.mts +2 -0
- package/packages/piagent-core/managed/store.mjs +12 -0
- package/packages/piagent-core/managed/tool-boundary.mjs +41 -14
- package/packages/piagent-core/managed/toolchain.mjs +5 -2
- package/packages/piagent-core/package.json +1 -1
- package/packages/piagent-core/runtime/host/browser-opener.d.mts +2 -0
- package/packages/piagent-core/runtime/host/browser-opener.mjs +20 -0
- package/packages/piagent-core/runtime/input/chat-images.ts +11 -4
- package/packages/piagent-core/runtime/resources/agent-resources.mjs +4 -4
- package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-FWfOWZjV.js → MarkdownMessage-D8wcWkJg.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{index-DFKHLVYk.js → index-DWL_wVw7.js} +3 -3
- package/packages/piagent-webui/dist/client/index.html +1 -1
- package/packages/piagent-webui/extension/piagent-webui.ts +6 -5
- package/packages/piagent-webui/gateway/control-socket.ts +14 -2
- package/packages/piagent-webui/gateway/managed-launch.ts +8 -6
- package/packages/piagent-webui/gateway/native-project-picker.ts +28 -3
- package/packages/piagent-webui/gateway/path-suggestions.ts +9 -3
- package/packages/piagent-webui/gateway/pi-host.ts +11 -3
- package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +3 -1
- package/scripts/dashboard-update-job.mjs +3 -2
- package/scripts/piagent-cli.mjs +2 -2
- package/scripts/piagent-dashboard.mjs +7 -7
- package/scripts/piagent-studio.mjs +4 -4
- package/scripts/piagent-webui-launcher.mjs +4 -3
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/commands" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/commands" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/context-engine" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/context-engine" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/ecosystem" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/ecosystem" hreflang="en" lang="en" aria-current="true">EN</a>
|
package/docs-site/en/index.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
<main>
|
|
94
94
|
<div class="content-shell" data-article>
|
|
95
95
|
<section class="hero">
|
|
96
|
-
<p class="eyebrow">Piagent 1.
|
|
96
|
+
<p class="eyebrow">Piagent 1.13.0</p>
|
|
97
97
|
<h1>A coding agent for the whole team, checked at every step.</h1>
|
|
98
98
|
<p>
|
|
99
99
|
One dashboard for Terminal and the browser. Use models with your own account, or the company's models through Agent Watch and Agent Studio. The guard checks every tool call; in company mode the team's Harness asks for checks, has a subagent review the change and reports the outcome right under the answer.
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
<div class="hero-actions">
|
|
108
108
|
<a class="button primary" href="/en/quickstart">Get started</a>
|
|
109
109
|
<a class="button" href="/en/ecosystem">Ecosystem</a>
|
|
110
|
-
<a class="button" href="/en/whats-new">What’s new in 1.
|
|
110
|
+
<a class="button" href="/en/whats-new">What’s new in 1.13.0</a>
|
|
111
111
|
<a class="button" href="/en/commands">View commands</a>
|
|
112
112
|
</div>
|
|
113
113
|
</section>
|
|
@@ -183,9 +183,9 @@ piagent-setup</code></pre>
|
|
|
183
183
|
<h2 id="where-to-start">Where to start</h2>
|
|
184
184
|
<div class="card-grid">
|
|
185
185
|
<a class="doc-card" href="/en/whats-new">
|
|
186
|
-
<span class="card-kicker">Release 1.
|
|
186
|
+
<span class="card-kicker">Release 1.13.0</span>
|
|
187
187
|
<h3>What’s new</h3>
|
|
188
|
-
<p
|
|
188
|
+
<p>Piagent on Windows through WSL2: a bubblewrap sandbox for company conversations and Agent Watch for Windows; in 1.12: @ picks files and folders on the Mac, skills and commands run from /, and forked company conversations take messages.</p>
|
|
189
189
|
</a>
|
|
190
190
|
<a class="doc-card" href="/en/ecosystem">
|
|
191
191
|
<span class="card-kicker">Get started</span>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/mcp-approval" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/mcp-approval" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/mcp-auth" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/mcp-auth" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/mcp-servers" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/mcp-servers" hreflang="en" lang="en" aria-current="true">EN</a>
|
package/docs-site/en/mcp.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/mcp" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/mcp" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/permissions" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/permissions" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/profiles" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/profiles" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/quickstart" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/quickstart" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/runtime" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/runtime" hreflang="en" lang="en" aria-current="true">EN</a>
|
package/docs-site/en/scope.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/scope" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/scope" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/security" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/security" hreflang="en" lang="en" aria-current="true">EN</a>
|
package/docs-site/en/team.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/team" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/team" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/whats-new" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/whats-new" hreflang="en" lang="en" aria-current="true">EN</a>
|
|
@@ -103,6 +103,25 @@
|
|
|
103
103
|
<h1>1.9.0: ask in plain language, the team's Harness checks</h1>
|
|
104
104
|
<p>The task contract and workflow commands are gone. Company mode asks for checks and a review on its own; Stop, network commands on approval and clearer approval cards.</p>
|
|
105
105
|
</div>
|
|
106
|
+
<section class="section">
|
|
107
|
+
<p class="section-kicker">v1.13.0 · 2026-10-06</p>
|
|
108
|
+
<h2 id="v1-13-0">Piagent on Windows through WSL2</h2>
|
|
109
|
+
<p class="section-lead">Members on Windows run Piagent in WSL2 (Ubuntu), for company and personal conversations alike. Company conversations get a bubblewrap sandbox that keeps the macOS sandbox’s promises, and Agent Watch for Windows holds the company key. Setup: <a href="https://github.com/Vt-mmm/piagent/blob/main/docs/en/windows.md">Piagent on Windows</a>.</p>
|
|
110
|
+
<ul>
|
|
111
|
+
<li>The project, its package cache and a private temporary folder are writable; other home folders are read-only for reference; hidden home entries are not in the sandbox; credential files read as empty.</li>
|
|
112
|
+
<li>A command without network approval reaches only the servers it starts; processes it leaves behind end with it.</li>
|
|
113
|
+
<li>From WSL, the folder picker is Windows’ dialog and links open in the Windows browser.</li>
|
|
114
|
+
<li>Running on Windows itself is a preview of personal mode; <code>piagent-update</code> does not run there yet.</li>
|
|
115
|
+
</ul>
|
|
116
|
+
<p>After updating, each member imports the Piagent configuration again in Agent Watch (macOS: Studio → Apply for Piagent; Windows: Connect Piagent in WSL).</p>
|
|
117
|
+
</section>
|
|
118
|
+
|
|
119
|
+
<section class="section">
|
|
120
|
+
<p class="section-kicker">v1.12.1 · 2026-10-06</p>
|
|
121
|
+
<h2 id="v1-12-1">Forked company conversations take messages</h2>
|
|
122
|
+
<p class="section-lead">A fork of a company conversation, made to keep its context, now takes messages. Before, the fork was listed but every message to it said “The message was not sent”. Forks made with an earlier release need to be made again after updating.</p>
|
|
123
|
+
</section>
|
|
124
|
+
|
|
106
125
|
<section class="section">
|
|
107
126
|
<p class="section-kicker">v1.12.0 · 2026-10-06</p>
|
|
108
127
|
<h2 id="v1-12-0">@ any folder, skills from /, and tests in the company sandbox</h2>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · EN</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Language">
|
|
35
35
|
<a class="language-option" href="/workflows" hreflang="vi" lang="vi">VI</a>
|
|
36
36
|
<a class="language-option current" href="/en/workflows" hreflang="en" lang="en" aria-current="true">EN</a>
|
package/docs-site/index.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/" hreflang="en" lang="en">EN</a>
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
<main>
|
|
94
94
|
<div class="content-shell" data-article>
|
|
95
95
|
<section class="hero">
|
|
96
|
-
<p class="eyebrow">Piagent 1.
|
|
96
|
+
<p class="eyebrow">Piagent 1.13.0</p>
|
|
97
97
|
<h1>Coding agent cho cả team, kiểm tra từng bước.</h1>
|
|
98
98
|
<p>
|
|
99
99
|
Một dashboard cho Terminal và trình duyệt. Dùng model bằng tài khoản của bạn, hoặc model của công ty qua Agent Watch và Agent Studio. Guard kiểm tra từng tool call; ở chế độ công ty, Harness của team tự yêu cầu chạy check, cho subagent review và báo kết quả ngay dưới câu trả lời.
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
<div class="hero-actions">
|
|
108
108
|
<a class="button primary" href="/quickstart">Bắt đầu</a>
|
|
109
109
|
<a class="button" href="/ecosystem">Hệ sinh thái</a>
|
|
110
|
-
<a class="button" href="/whats-new">Có gì mới trong 1.
|
|
110
|
+
<a class="button" href="/whats-new">Có gì mới trong 1.13.0</a>
|
|
111
111
|
<a class="button" href="/commands">Xem command</a>
|
|
112
112
|
</div>
|
|
113
113
|
</section>
|
|
@@ -183,9 +183,9 @@ piagent-setup</code></pre>
|
|
|
183
183
|
<h2 id="bat-dau-tu-dau">Bắt đầu từ đâu</h2>
|
|
184
184
|
<div class="card-grid">
|
|
185
185
|
<a class="doc-card" href="/whats-new">
|
|
186
|
-
<span class="card-kicker">Bản 1.
|
|
186
|
+
<span class="card-kicker">Bản 1.13.0</span>
|
|
187
187
|
<h3>Có gì mới</h3>
|
|
188
|
-
<p
|
|
188
|
+
<p>Piagent trên Windows qua WSL2: sandbox công ty bằng bubblewrap và Agent Watch cho Windows; ở 1.12: @ chọn file và folder trên máy, skill và command dùng bằng /, nhánh cuộc trò chuyện công ty gửi được tin nhắn.</p>
|
|
189
189
|
</a>
|
|
190
190
|
<a class="doc-card" href="/ecosystem">
|
|
191
191
|
<span class="card-kicker">Get started</span>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/mcp-approval" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/mcp-approval" hreflang="en" lang="en">EN</a>
|
package/docs-site/mcp-auth.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/mcp-auth" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/mcp-auth" hreflang="en" lang="en">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/mcp-servers" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/mcp-servers" hreflang="en" lang="en">EN</a>
|
package/docs-site/mcp.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/mcp" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/mcp" hreflang="en" lang="en">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/permissions" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/permissions" hreflang="en" lang="en">EN</a>
|
package/docs-site/profiles.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/profiles" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/profiles" hreflang="en" lang="en">EN</a>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/quickstart" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/quickstart" hreflang="en" lang="en">EN</a>
|
package/docs-site/runtime.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/runtime" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/runtime" hreflang="en" lang="en">EN</a>
|
package/docs-site/scope.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/scope" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/scope" hreflang="en" lang="en">EN</a>
|
package/docs-site/security.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/security" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/security" hreflang="en" lang="en">EN</a>
|
package/docs-site/team.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/team" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/team" hreflang="en" lang="en">EN</a>
|
package/docs-site/whats-new.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/whats-new" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/whats-new" hreflang="en" lang="en">EN</a>
|
|
@@ -103,6 +103,25 @@
|
|
|
103
103
|
<h1>Bản 1.9.0: nói việc bằng lời, Harness của team kiểm tra</h1>
|
|
104
104
|
<p>Bỏ task contract và lệnh workflow. Chế độ công ty tự yêu cầu check và review; nút Dừng, lệnh có mạng theo lần duyệt và thẻ duyệt dễ đọc hơn.</p>
|
|
105
105
|
</div>
|
|
106
|
+
<section class="section">
|
|
107
|
+
<p class="section-kicker">v1.13.0 · 2026-10-06</p>
|
|
108
|
+
<h2 id="v1-13-0">Piagent trên Windows qua WSL2</h2>
|
|
109
|
+
<p class="section-lead">Thành viên dùng Windows chạy Piagent trong WSL2 (Ubuntu), cả cuộc trò chuyện công ty lẫn cá nhân. Cuộc trò chuyện công ty có sandbox bubblewrap giữ đúng những gì sandbox macOS bảo đảm, và Agent Watch cho Windows giữ key công ty. Hướng dẫn cài đặt: <a href="https://github.com/Vt-mmm/piagent/blob/main/docs/vi/windows.md">Piagent trên Windows</a>.</p>
|
|
110
|
+
<ul>
|
|
111
|
+
<li>Project, cache package của project và thư mục tạm riêng ghi được; folder khác trong home chỉ đọc để tham chiếu; mục ẩn trong home không có trong sandbox; file credential đọc ra rỗng.</li>
|
|
112
|
+
<li>Lệnh chưa được duyệt mạng chỉ tới được server do chính nó mở; tiến trình lệnh để lại kết thúc cùng lệnh.</li>
|
|
113
|
+
<li>Từ WSL, hộp chọn folder là hộp thoại của Windows và link mở trong trình duyệt Windows.</li>
|
|
114
|
+
<li>Chạy thẳng trên Windows là bản xem trước cho chế độ cá nhân; <code>piagent-update</code> chưa chạy ở đó.</li>
|
|
115
|
+
</ul>
|
|
116
|
+
<p>Sau khi cập nhật, mỗi thành viên nhập lại cấu hình Piagent trong Agent Watch (macOS: Studio → Áp dụng cho Piagent; Windows: Kết nối Piagent trong WSL).</p>
|
|
117
|
+
</section>
|
|
118
|
+
|
|
119
|
+
<section class="section">
|
|
120
|
+
<p class="section-kicker">v1.12.1 · 2026-10-06</p>
|
|
121
|
+
<h2 id="v1-12-1">Nhánh cuộc trò chuyện công ty gửi được tin nhắn</h2>
|
|
122
|
+
<p class="section-lead">Tạo nhánh (fork) một cuộc trò chuyện công ty để giữ context giờ gửi tin nhắn bình thường. Trước đây nhánh vẫn hiện trong danh sách nhưng mọi tin nhắn đều báo “Tin nhắn chưa được gửi”. Nhánh tạo bằng bản cũ cần tạo lại sau khi cập nhật.</p>
|
|
123
|
+
</section>
|
|
124
|
+
|
|
106
125
|
<section class="section">
|
|
107
126
|
<p class="section-kicker">v1.12.0 · 2026-10-06</p>
|
|
108
127
|
<h2 id="v1-12-0">@ tới mọi folder, skill dùng bằng /, và test chạy được trong sandbox công ty</h2>
|
package/docs-site/workflows.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span>Pi Agent Platform</span>
|
|
31
31
|
</a>
|
|
32
32
|
<div class="top-actions">
|
|
33
|
-
<span class="pill"><span class="pill-dot"></span>v1.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.13.0 docs · VI</span>
|
|
34
34
|
<nav class="language-switch" aria-label="Ngôn ngữ">
|
|
35
35
|
<a class="language-option current" href="/workflows" hreflang="vi" lang="vi" aria-current="true">VI</a>
|
|
36
36
|
<a class="language-option" href="/en/workflows" hreflang="en" lang="en">EN</a>
|
|
@@ -256,8 +256,8 @@
|
|
|
256
256
|
},
|
|
257
257
|
{
|
|
258
258
|
"path": "tests",
|
|
259
|
-
"fileCount":
|
|
260
|
-
"sha256": "
|
|
259
|
+
"fileCount": 522,
|
|
260
|
+
"sha256": "b791eef3eafef91608219d5b57e853b4351c7a04a99e0cedbd5a8234da9eb692"
|
|
261
261
|
}
|
|
262
262
|
],
|
|
263
263
|
"custodianComparisonRules": {
|
package/package.json
CHANGED
|
@@ -732,7 +732,9 @@ function usesFilesystemContentFields(toolName: string, allowAmbiguousSource = tr
|
|
|
732
732
|
|
|
733
733
|
function inspectRepositoryPathBoundary(cwd: string, candidate: string): { reason?: string } {
|
|
734
734
|
const normalized = normalizePathCandidate(candidate);
|
|
735
|
-
|
|
735
|
+
// On Windows a path on another drive stays absolute after path.relative
|
|
736
|
+
// (D:\x becomes D:/x): a drive letter is never a project path.
|
|
737
|
+
if (normalized === ".." || normalized.startsWith("../") || path.posix.isAbsolute(normalized) || /^[A-Za-z]:/.test(normalized)) {
|
|
736
738
|
return { reason: `path resolves outside the project: ${candidate}` };
|
|
737
739
|
}
|
|
738
740
|
let current = cwd;
|
|
@@ -18,7 +18,8 @@ const FIND_FILE_OUTPUT_ACTIONS = new Set(["-fprint", "-fprint0", "-fprintf", "-f
|
|
|
18
18
|
function isNullDeviceRedirectionTarget(value) {
|
|
19
19
|
const candidate = String(value ?? "");
|
|
20
20
|
if (process.platform !== "win32") return candidate === "/dev/null";
|
|
21
|
-
|
|
21
|
+
// Git Bash, which runs the bash tool on Windows, has /dev/null as well.
|
|
22
|
+
return candidate === "/dev/null" || candidate.replace(/\\/g, "/").toLowerCase() === "//./nul";
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
function commandName(value) {
|
|
@@ -29,7 +29,8 @@ export function grantedSourceCheckoutRootForPath(cwd: string, candidate: string,
|
|
|
29
29
|
// ~/Documents/old-shop"): their own files, external drives and the shared
|
|
30
30
|
// folder, read with read, grep, find or ls. Hidden entries of the home folder
|
|
31
31
|
// (shell files, histories, tool configs) and ~/Library (app data, mail,
|
|
32
|
-
// browser profiles) stay closed; a link is judged
|
|
32
|
+
// browser profiles) stay closed, as does AppData on Windows; a link is judged
|
|
33
|
+
// by where it leads.
|
|
33
34
|
export function referenceReadRootForPath(cwd: string, candidate: string): string | undefined {
|
|
34
35
|
let target: string, home: string;
|
|
35
36
|
try {
|
|
@@ -40,7 +41,7 @@ export function referenceReadRootForPath(cwd: string, candidate: string): string
|
|
|
40
41
|
}
|
|
41
42
|
if (inside(home, target)) {
|
|
42
43
|
const first = path.relative(home, target).split(path.sep)[0];
|
|
43
|
-
return first.startsWith(".") || first === "Library" ? undefined : home;
|
|
44
|
+
return first.startsWith(".") || first === "Library" || first === "AppData" ? undefined : home;
|
|
44
45
|
}
|
|
45
46
|
return ["/Volumes", "/Users/Shared", "/private/tmp"].find((root) => inside(root, target));
|
|
46
47
|
}
|
|
@@ -51,7 +52,7 @@ export function piToolPathInput(input: Record<string, unknown>): Record<string,
|
|
|
51
52
|
const value = input.path;
|
|
52
53
|
if (typeof value !== "string") return input;
|
|
53
54
|
const bare = value.startsWith("@") ? value.slice(1) : value;
|
|
54
|
-
const opened = bare === "~" ? os.homedir() : bare
|
|
55
|
+
const opened = bare === "~" ? os.homedir() : /^~[/\\]/.test(bare) ? path.join(os.homedir(), bare.slice(2)) : bare;
|
|
55
56
|
return opened === value ? input : { ...input, path: opened };
|
|
56
57
|
}
|
|
57
58
|
|
|
@@ -256,7 +256,8 @@ function appendJournalRecord(safePaths, journal, event, recordedAt) {
|
|
|
256
256
|
const previousBytes = fs.existsSync(safePaths.events) ? fs.statSync(safePaths.events).size : 0;
|
|
257
257
|
try {
|
|
258
258
|
fs.appendFileSync(safePaths.events, `${JSON.stringify(record)}\n`, { mode: 0o600 });
|
|
259
|
-
|
|
259
|
+
// Windows flushes only a handle opened for writing.
|
|
260
|
+
const descriptor = fs.openSync(safePaths.events, process.platform === "win32" ? fs.constants.O_RDWR : fs.constants.O_RDONLY);
|
|
260
261
|
try { fs.fsyncSync(descriptor); } finally { fs.closeSync(descriptor); }
|
|
261
262
|
} catch (error) {
|
|
262
263
|
try { fs.truncateSync(safePaths.events, previousBytes); } catch { /* A later read fails closed if rollback itself is impossible. */ }
|
|
@@ -127,8 +127,8 @@ function writeJsonAtomic(cwd, filePath, value) {
|
|
|
127
127
|
fs.renameSync(temporary, safePath);
|
|
128
128
|
fs.chmodSync(parent, 0o700);
|
|
129
129
|
fs.chmodSync(safePath, 0o600);
|
|
130
|
-
const directory = fs.openSync(parent, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
|
|
131
|
-
try { fs.fsyncSync(directory); } finally { fs.closeSync(directory); }
|
|
130
|
+
const directory = process.platform === "win32" ? undefined : fs.openSync(parent, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
|
|
131
|
+
if (directory !== undefined) try { fs.fsyncSync(directory); } finally { fs.closeSync(directory); } // Windows flushes no directory.
|
|
132
132
|
} catch {
|
|
133
133
|
try { fs.unlinkSync(temporary); } catch {}
|
|
134
134
|
throw new Error("Task state atomic persistence failed");
|
|
@@ -537,7 +537,7 @@ export function durableTaskContractMatches(cwd, expected) {
|
|
|
537
537
|
const safePath = resolveLocalStatePath(cwd, taskRunPath(cwd, normalized.taskRunId), {
|
|
538
538
|
label: "Task state", kind: "file"
|
|
539
539
|
});
|
|
540
|
-
const descriptor = fs.openSync(safePath, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
|
|
540
|
+
const descriptor = fs.openSync(safePath, (process.platform === "win32" ? fs.constants.O_RDWR : fs.constants.O_RDONLY) | (fs.constants.O_NOFOLLOW ?? 0)); // Windows flushes writable handles only.
|
|
541
541
|
try {
|
|
542
542
|
fs.fsyncSync(descriptor);
|
|
543
543
|
const before = fs.fstatSync(descriptor, { bigint: true });
|
|
@@ -3,13 +3,14 @@ import { randomUUID } from 'node:crypto';
|
|
|
3
3
|
import { StringDecoder } from 'node:string_decoder';
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import path from 'node:path';
|
|
6
|
+
import { interopEnvironment } from './store.mjs';
|
|
6
7
|
|
|
7
8
|
export class ManagedBrokerClient {
|
|
8
9
|
#child; #pending = new Map(); #tail = Promise.resolve(); #closed = false;
|
|
9
10
|
constructor({ executable, profileID }) {
|
|
10
11
|
if (!path.isAbsolute(executable) || fs.realpathSync(executable) !== executable || !/^[a-f0-9]{64}$/.test(profileID)) throw Error('managed-broker-binding-invalid');
|
|
11
12
|
this.#child = spawn(executable, ['managed-broker', '--profile', profileID], {
|
|
12
|
-
stdio: ['pipe', 'pipe', 'pipe'], env: { PATH: '/usr/bin:/bin', LANG: 'en_US.UTF-8' },
|
|
13
|
+
stdio: ['pipe', 'pipe', 'pipe'], env: { PATH: '/usr/bin:/bin', LANG: 'en_US.UTF-8', ...interopEnvironment() },
|
|
13
14
|
});
|
|
14
15
|
let pending = ''; const decoder = new StringDecoder('utf8');
|
|
15
16
|
const fail = () => { this.#closed = true; for (const item of this.#pending.values()) { clearTimeout(item.timer); item.reject(Error('managed-broker-disconnected')); } this.#pending.clear(); };
|
|
@@ -54,8 +54,10 @@ export async function runDoctor({ sdkRoot, origin, broker, network = true }) {
|
|
|
54
54
|
if (await bash("cat 'Dự án mới/ghi chú.md'") !== 'ổn') throw Error('content changed'); return 'ok';
|
|
55
55
|
});
|
|
56
56
|
await check('folders outside the project are read-only', true, async () => {
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
// Refused, or (Linux) kept in the sandbox's own /tmp: never on this machine.
|
|
58
|
+
const outside = path.join(path.dirname(project), 'piagent-doctor-outside.txt');
|
|
59
|
+
try { await boundary.invoke('write', { path: '../piagent-doctor-outside.txt', content: 'x' }); } catch { /* refused */ }
|
|
60
|
+
if (fs.existsSync(outside)) { fs.rmSync(outside, { force: true }); throw Error('a write outside the project was allowed'); }
|
|
59
61
|
// A folder the member points to for reference (@~/…) is readable.
|
|
60
62
|
await boundary.invoke('ls', { path: '~' });
|
|
61
63
|
return 'read, write refused';
|
|
@@ -79,7 +81,7 @@ export async function runDoctor({ sdkRoot, origin, broker, network = true }) {
|
|
|
79
81
|
});
|
|
80
82
|
await check('make', false, () => bash('make --version'));
|
|
81
83
|
// Tests that start a server or use a local database (tool-boundary.mjs).
|
|
82
|
-
await check('tests reach
|
|
84
|
+
await check('tests reach their own servers (localhost)', false, async () => {
|
|
83
85
|
await boundary.invoke('write', { path: 'loopback.mjs', content: "import http from 'node:http'; const s = http.createServer((q, r) => r.end('ok')); s.listen(0, '127.0.0.1', async () => { console.log(await (await fetch(`http://127.0.0.1:${s.address().port}/`)).text()); s.close(); });\n" });
|
|
84
86
|
try { return await bash('node loopback.mjs'); }
|
|
85
87
|
catch (error) { throw Error(/loopback-blocked/.test(String(error?.message)) ? 'a local proxy listens on this Mac: tests that use localhost need run_with_network' : first(String(error?.message))); }
|