pi-lean-dimension 0.3.2 → 0.3.3

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 (32) hide show
  1. package/README.md +22 -0
  2. package/node_modules/pi-lean-portal/README.md +42 -2
  3. package/node_modules/pi-lean-portal/__tests__/browser-toggle-migration.test.ts +145 -0
  4. package/node_modules/pi-lean-portal/__tests__/browser-toggle.test.ts +24 -0
  5. package/node_modules/pi-lean-portal/backends/python-base/pi_browser_bridge/__pycache__/playwright_base.cpython-312.pyc +0 -0
  6. package/node_modules/pi-lean-portal/backends/python-base/pi_browser_bridge/__pycache__/playwright_base.cpython-313.pyc +0 -0
  7. package/node_modules/pi-lean-portal/browser-toggle.ts +98 -10
  8. package/node_modules/pi-lean-portal/package.json +2 -2
  9. package/node_modules/pi-lean-search/__tests__/web-search.test.ts +22 -0
  10. package/node_modules/pi-lean-search/index.ts +21 -1
  11. package/node_modules/pi-lean-search/package.json +2 -2
  12. package/node_modules/pi-tool-masking/LICENSE +21 -661
  13. package/node_modules/pi-tool-masking/README.md +35 -4
  14. package/node_modules/pi-tool-masking/index.ts +37 -4
  15. package/node_modules/pi-tool-masking/package.json +6 -3
  16. package/node_modules/playwright/lib/common/index.js +3 -6
  17. package/node_modules/playwright/lib/common/index.js.txt +2 -2
  18. package/node_modules/playwright/lib/transform/esmLoader.js +3 -6
  19. package/node_modules/playwright/lib/transform/esmLoader.js.txt +2 -2
  20. package/node_modules/playwright/package.json +2 -2
  21. package/node_modules/playwright-core/lib/coreBundle.js +1 -1
  22. package/node_modules/playwright-core/lib/vite/traceViewer/assets/{codeMirrorModule-By56iMx7.js → codeMirrorModule-rXmQmLUY.js} +1 -1
  23. package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-B-dXF5JN.js +181 -0
  24. package/node_modules/playwright-core/lib/vite/traceViewer/assets/{xtermModule-COQkjINf.js → xtermModule-BuZfJS5v.js} +1 -1
  25. package/node_modules/playwright-core/lib/vite/traceViewer/{index.Dl36UVQT.js → index.KZ4wOW1K.js} +1 -1
  26. package/node_modules/playwright-core/lib/vite/traceViewer/index.html +2 -2
  27. package/node_modules/playwright-core/lib/vite/traceViewer/{uiMode.D962mr9b.js → uiMode.Dzuouizj.js} +2 -2
  28. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.html +2 -2
  29. package/node_modules/playwright-core/package.json +1 -1
  30. package/node_modules/playwright-core/types/structs.d.ts +8 -3
  31. package/package.json +3 -3
  32. package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-B34OrIms.js +0 -181
@@ -2,7 +2,7 @@
2
2
 
3
3
  A library for pi plugin developers that groups tools into toggleable **toolsets** with persistent state and cross-extension events — eliminating the boilerplate every pi extension repeats when it wants to let users disable tools cleanly.
4
4
 
5
- `pi-tool-masking` is **not** a pi extension itself. It is a peer dependency that your extension imports. It owns the toggle logic, the session-restore path, and the event bus. Your extension owns the commands, the status bar, and the user-facing surfaces.
5
+ `pi-tool-masking` is **not** a pi extension itself. It is a dependency that your extension imports. It owns the toggle logic, the session-restore path, and the event bus. Your extension owns the commands, the status bar, and the user-facing surfaces.
6
6
 
7
7
  ---
8
8
 
@@ -228,8 +228,8 @@ for (const entry of getRegisteredToolsets()) {
228
228
  ### Dependent toolsets
229
229
 
230
230
  ```ts
231
- // Portal tools are on by default; learn tools depend on portal
232
- const portalSpec: ToolsetSpec = {
231
+ // Web tools are on by default; learn tools depend on web
232
+ const webSpec: ToolsetSpec = {
233
233
  id: "my-plugin.web",
234
234
  names: new Set(["web-fetch", "web-snapshot"]),
235
235
  persistKey: "toolset-state:my-plugin.web",
@@ -247,6 +247,37 @@ const learnSpec: ToolsetSpec = {
247
247
 
248
248
  ---
249
249
 
250
+ ## Toolset naming
251
+
252
+ `defineToolset` can't tell which extension is calling it — pi's `ExtensionAPI`
253
+ doesn't expose the caller — so error messages can't name the responsible
254
+ extension directly. The toolset id is the only traceability signal, which is
255
+ why a stable, attributable id convention matters.
256
+
257
+ ### Convention (recommended, not enforced)
258
+
259
+ Prefix toolset ids with a stable namespace: `<product-family>.<subset>`, e.g.
260
+ `my-plugin.web`. The family may span multiple npm packages, and nothing checks
261
+ that the prefix matches a real package — it's for human traceability in
262
+ `/tbox list` and collision errors, not verification.
263
+
264
+ ### Enforcement floor
265
+
266
+ `defineToolset` enforces one naming invariant: **no two toolsets may claim the
267
+ same tool name.** Overlap is essentially always an authoring mistake and throws
268
+ at load time:
269
+
270
+ ```
271
+ [pi-tool-masking] name overlap: toolset "foo.search" claims tools already
272
+ owned by another toolset:
273
+ - tool "x" already claimed by toolset "bar.web" (registered from
274
+ /home/u/.pi/.../bar/index.ts, source: bar)
275
+ Each tool may belong to only one toolset. Naming convention: prefix toolset
276
+ ids with a stable namespace (<product-family>.<subset>, e.g. "foo.web").
277
+ ```
278
+
279
+ ---
280
+
250
281
  ## How it works (for the curious)
251
282
 
252
283
  - **Registration:** `defineToolset` stores the spec and handle in a global registry (shared across module instances, so multiple extensions see the same toolsets).
@@ -267,4 +298,4 @@ This package is used by:
267
298
 
268
299
  ## License
269
300
 
270
- GNU Affero General Public License v3.0 (AGPL-3.0). See [LICENSE](./LICENSE).
301
+ MIT. See [LICENSE](./LICENSE).
@@ -8,7 +8,7 @@ import type {
8
8
  // ---------------------------------------------------------------------------
9
9
 
10
10
  export interface ToolsetSpec {
11
- /** Stable id, e.g. "portal.web". Used in persist keys and event payloads. */
11
+ /** Stable id, e.g. "my-plugin.web". Used in persist keys and event payloads. */
12
12
  id: string;
13
13
  /** Human-readable name for the group. Optional — presenters fall back to id. */
14
14
  label?: string;
@@ -16,7 +16,7 @@ export interface ToolsetSpec {
16
16
  description?: string;
17
17
  /** Tool names this toolset governs. */
18
18
  names: Set<string>;
19
- /** Primary persistence key the toolset writes, e.g. "toolset-state:portal.web". */
19
+ /** Primary persistence key the toolset writes, e.g. "toolset-state:my-plugin.web". */
20
20
  persistKey: string;
21
21
  /** Fresh-session fallback when no branch entry exists. */
22
22
  defaultEnabled?: boolean;
@@ -33,7 +33,7 @@ export interface Toolset {
33
33
  }
34
34
 
35
35
  export interface ToolsetChangedEvent {
36
- /** Toolset id (e.g. "portal.web"). Always set. */
36
+ /** Toolset id (e.g. "my-plugin.web"). Always set. */
37
37
  id: string;
38
38
  enabled: boolean;
39
39
  /** Present only when emitMemberEvents is on and this is a per-member fanout event. */
@@ -165,7 +165,7 @@ function ensureRestoreHandler(pi: ExtensionAPI): void {
165
165
  //
166
166
  // Re-read the branch per toolset (not once before the loop): a companion
167
167
  // mirror (§10.1) fires synchronously inside `_applyRestoreToolset` and may
168
- // `appendEntry` for a toolset later in iteration order (e.g. portal.web's
168
+ // `appendEntry` for a toolset later in iteration order (e.g. my-plugin.web's
169
169
  // default-false restore makes search.web disable itself). Snapshotting the
170
170
  // branch once would hide that write from the later toolset, so it would
171
171
  // fall back to its packaged default and desync from the companion — the
@@ -426,6 +426,39 @@ export function defineToolset(pi: ExtensionAPI, spec: ToolsetSpec): Toolset {
426
426
  }
427
427
  }
428
428
 
429
+ // Name-overlap guard: no two toolsets may claim the same tool name. Every
430
+ // downstream failure mode (isEnabled lying, restore order-dependence, enable
431
+ // no-op, skipped dependents, focus leaks, mis-attribution, double-counts)
432
+ // requires two toolsets claiming one name; with that unreachable, toolsets
433
+ // own disjoint name sets. Gather every collision in this registration into
434
+ // one error so the author sees the full scope in one pass. `getAllTools()` is
435
+ // deferred to the throw branch so a clean registration never pays for it.
436
+ const collisions: { name: string; owner: string }[] = [];
437
+ for (const [id, entry] of registry) {
438
+ if (id === spec.id) continue;
439
+ for (const name of spec.names) {
440
+ if (entry.spec.names.has(name)) collisions.push({ name, owner: id });
441
+ }
442
+ }
443
+ if (collisions.length > 0) {
444
+ const allTools = pi.getAllTools();
445
+ const lines = collisions.map(({ name, owner }) => {
446
+ const tool = allTools.find((t) => t.name === name);
447
+ const where = tool
448
+ ? ` (registered from ${tool.sourceInfo.path}, source: ${tool.sourceInfo.source})`
449
+ : "";
450
+ return ` - tool "${name}" already claimed by toolset "${owner}"${where}`;
451
+ });
452
+ throw new Error(
453
+ `[pi-tool-masking] name overlap: toolset "${spec.id}" claims tools ` +
454
+ `already owned by another toolset:\n` +
455
+ lines.join("\n") +
456
+ "\n" +
457
+ `Each tool may belong to only one toolset. Naming convention: prefix ` +
458
+ `toolset ids with a stable namespace (<product-family>.<subset>, e.g. "my-plugin.web").`,
459
+ );
460
+ }
461
+
429
462
  const toolset = new ToolsetImpl(spec);
430
463
  registry.set(spec.id, { spec, toolset });
431
464
 
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "pi-tool-masking",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Core library for grouping pi tools into toggleable toolsets with persistent state and cross-extension events.",
7
- "keywords": ["tool-masking", "pi-extension"],
8
- "license": "AGPL-3.0-or-later",
7
+ "keywords": [
8
+ "tool-masking",
9
+ "pi-extension"
10
+ ],
11
+ "license": "MIT",
9
12
  "author": "Corey Ryan Hanson",
10
13
  "repository": {
11
14
  "type": "git",
@@ -793,16 +793,13 @@ function loadTsConfig(configPath) {
793
793
  ${e.message}`);
794
794
  }
795
795
  }
796
- function resolveConfigFile(baseConfigFile, referencedConfigFile, kind) {
797
- const originalReferencedConfigFile = referencedConfigFile;
796
+ function resolveConfigFile(baseConfigFile, referencedConfigFile) {
798
797
  if (!referencedConfigFile.endsWith(".json"))
799
798
  referencedConfigFile += ".json";
800
799
  const currentDir = import_path4.default.dirname(baseConfigFile);
801
800
  let resolvedConfigFile = import_path4.default.resolve(currentDir, referencedConfigFile);
802
801
  if (referencedConfigFile.includes("/") && referencedConfigFile.includes(".") && !import_fs4.default.existsSync(resolvedConfigFile))
803
802
  resolvedConfigFile = import_path4.default.join(currentDir, "node_modules", referencedConfigFile);
804
- if (!import_fs4.default.existsSync(resolvedConfigFile))
805
- throw new Error(`Failed to resolve "${kind}" path "${originalReferencedConfigFile}" referenced from ${baseConfigFile}`);
806
803
  return resolvedConfigFile;
807
804
  }
808
805
  function innerLoadTsConfig(configFilePath, references, visited = /* @__PURE__ */ new Map()) {
@@ -819,7 +816,7 @@ function innerLoadTsConfig(configFilePath, references, visited = /* @__PURE__ */
819
816
  const parsedConfig = json5.parse(cleanedJson);
820
817
  const extendsArray = Array.isArray(parsedConfig.extends) ? parsedConfig.extends : parsedConfig.extends ? [parsedConfig.extends] : [];
821
818
  for (const extendedConfig of extendsArray) {
822
- const extendedConfigPath = resolveConfigFile(configFilePath, extendedConfig, "extends");
819
+ const extendedConfigPath = resolveConfigFile(configFilePath, extendedConfig);
823
820
  const base = innerLoadTsConfig(extendedConfigPath, references, visited);
824
821
  Object.assign(result2, base, { tsConfigPath: configFilePath });
825
822
  }
@@ -835,7 +832,7 @@ function innerLoadTsConfig(configFilePath, references, visited = /* @__PURE__ */
835
832
  result2.absoluteBaseUrl = import_path4.default.resolve(import_path4.default.dirname(configFilePath), parsedConfig.compilerOptions.baseUrl);
836
833
  }
837
834
  for (const ref of parsedConfig.references || [])
838
- references.push(innerLoadTsConfig(resolveConfigFile(configFilePath, ref.path, "references"), references, visited));
835
+ references.push(innerLoadTsConfig(resolveConfigFile(configFilePath, ref.path), references, visited));
839
836
  if (import_path4.default.basename(configFilePath) === "jsconfig.json" && result2.allowJs === void 0)
840
837
  result2.allowJs = true;
841
838
  return result2;
@@ -1,5 +1,5 @@
1
1
  # packages/playwright/lib/common/index.js
2
- # total: 114.4 KB
2
+ # total: 114.2 KB
3
3
 
4
4
  ## Inlined (20)
5
5
  12.0 KB packages/playwright/src/common/config.ts
@@ -20,7 +20,7 @@
20
20
  1.1 KB packages/playwright/src/transform/pirates.ts
21
21
  1.1 KB packages/playwright/src/transform/portTransport.ts
22
22
  12.3 KB packages/playwright/src/transform/transform.ts
23
- 3.2 KB packages/playwright/src/transform/tsconfig-loader.ts
23
+ 2.9 KB packages/playwright/src/transform/tsconfig-loader.ts
24
24
  7.0 KB packages/playwright/src/util.ts
25
25
 
26
26
  ## External (8)
@@ -4414,16 +4414,13 @@ function loadTsConfig(configPath) {
4414
4414
  ${e.message}`);
4415
4415
  }
4416
4416
  }
4417
- function resolveConfigFile(baseConfigFile, referencedConfigFile, kind) {
4418
- const originalReferencedConfigFile = referencedConfigFile;
4417
+ function resolveConfigFile(baseConfigFile, referencedConfigFile) {
4419
4418
  if (!referencedConfigFile.endsWith(".json"))
4420
4419
  referencedConfigFile += ".json";
4421
4420
  const currentDir = import_path2.default.dirname(baseConfigFile);
4422
4421
  let resolvedConfigFile = import_path2.default.resolve(currentDir, referencedConfigFile);
4423
4422
  if (referencedConfigFile.includes("/") && referencedConfigFile.includes(".") && !import_fs2.default.existsSync(resolvedConfigFile))
4424
4423
  resolvedConfigFile = import_path2.default.join(currentDir, "node_modules", referencedConfigFile);
4425
- if (!import_fs2.default.existsSync(resolvedConfigFile))
4426
- throw new Error(`Failed to resolve "${kind}" path "${originalReferencedConfigFile}" referenced from ${baseConfigFile}`);
4427
4424
  return resolvedConfigFile;
4428
4425
  }
4429
4426
  function innerLoadTsConfig(configFilePath, references, visited = /* @__PURE__ */ new Map()) {
@@ -4440,7 +4437,7 @@ function innerLoadTsConfig(configFilePath, references, visited = /* @__PURE__ */
4440
4437
  const parsedConfig = import_json5.default.parse(cleanedJson);
4441
4438
  const extendsArray = Array.isArray(parsedConfig.extends) ? parsedConfig.extends : parsedConfig.extends ? [parsedConfig.extends] : [];
4442
4439
  for (const extendedConfig of extendsArray) {
4443
- const extendedConfigPath = resolveConfigFile(configFilePath, extendedConfig, "extends");
4440
+ const extendedConfigPath = resolveConfigFile(configFilePath, extendedConfig);
4444
4441
  const base = innerLoadTsConfig(extendedConfigPath, references, visited);
4445
4442
  Object.assign(result2, base, { tsConfigPath: configFilePath });
4446
4443
  }
@@ -4456,7 +4453,7 @@ function innerLoadTsConfig(configFilePath, references, visited = /* @__PURE__ */
4456
4453
  result2.absoluteBaseUrl = import_path2.default.resolve(import_path2.default.dirname(configFilePath), parsedConfig.compilerOptions.baseUrl);
4457
4454
  }
4458
4455
  for (const ref of parsedConfig.references || [])
4459
- references.push(innerLoadTsConfig(resolveConfigFile(configFilePath, ref.path, "references"), references, visited));
4456
+ references.push(innerLoadTsConfig(resolveConfigFile(configFilePath, ref.path), references, visited));
4460
4457
  if (import_path2.default.basename(configFilePath) === "jsconfig.json" && result2.allowJs === void 0)
4461
4458
  result2.allowJs = true;
4462
4459
  return result2;
@@ -1,5 +1,5 @@
1
1
  # packages/playwright/lib/transform/esmLoader.js
2
- # total: 283.9 KB
2
+ # total: 283.6 KB
3
3
 
4
4
  ## Inlined (51)
5
5
  1.3 KB node_modules/balanced-match/dist/esm/index.js
@@ -47,7 +47,7 @@
47
47
  1.1 KB packages/playwright/src/transform/pirates.ts
48
48
  1.1 KB packages/playwright/src/transform/portTransport.ts
49
49
  11.7 KB packages/playwright/src/transform/transform.ts
50
- 3.2 KB packages/playwright/src/transform/tsconfig-loader.ts
50
+ 2.9 KB packages/playwright/src/transform/tsconfig-loader.ts
51
51
  4.7 KB packages/playwright/src/util.ts
52
52
  0.2 KB packages/utils/crypto.ts
53
53
  0.1 KB packages/utils/debug.ts
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playwright",
3
- "version": "1.62.0",
3
+ "version": "1.62.1",
4
4
  "description": "A high-level API to automate web browsers",
5
5
  "repository": {
6
6
  "type": "git",
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "license": "Apache-2.0",
52
52
  "dependencies": {
53
- "playwright-core": "1.62.0"
53
+ "playwright-core": "1.62.1"
54
54
  },
55
55
  "optionalDependencies": {
56
56
  "fsevents": "2.3.2"