@pimote/sdk 0.15.0-rc.5 → 0.15.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/README.md CHANGED
@@ -102,7 +102,7 @@ interface BodySection {
102
102
  - **`body`** — Optional content sections, each with a style (`text`, `code`, or `secondary`).
103
103
  - **`footer`** — Optional array of short strings displayed at the bottom.
104
104
  - **`href`** — Optional same-origin URL. When set, the client renders the
105
- entire card as a clickable link (same-tab navigation). Use for cards
105
+ entire card as a clickable link that opens in a new tab. Use for cards
106
106
  that point at a hosted resource — e.g. a bundle served by pimote's
107
107
  static-host tool.
108
108
 
@@ -162,7 +162,7 @@ The discovery seam. `list()` is called on cache miss and must return the current
162
162
 
163
163
  ### `FolderCreator`
164
164
 
165
- The creation seam. `describe()` returns the human-readable form for the creation UI — a `label` plus a `paramSchema` mapping param names to `'string' | 'string[]'`. `create(params)` receives the user-supplied params, makes the folder, and returns its `{ path }`.
165
+ The creation seam. `describe()` returns the human-readable form for the creation UI — a `label` plus a `paramSchema` mapping param names to `'string' | 'string[]'`. `create(params)` receives the user-supplied params, makes the folder, and returns its `{ path }`. Pimote resolves that path to the folder's canonical filesystem identity before seeding, broadcasting, or opening a session, so a creator can return the lexical path it used to reach the folder. The path must name the successfully created folder.
166
166
 
167
167
  ### Entry shapes
168
168
 
@@ -7,7 +7,7 @@ import type { EventBus } from '@earendil-works/pi-coding-agent';
7
7
  * for sessions already past the idle-reap threshold — the poll is invisible
8
8
  * until it matters.
9
9
  *
10
- * Fails open: no responder, or any responder answering `active: false`, means
10
+ * Fails open: no responder, or no responder answering `active: true`, means
11
11
  * no background work and the caller may reap. When several extensions answer,
12
12
  * responses are OR-ed — any assertion of live work holds the session.
13
13
  */
@@ -6,7 +6,7 @@
6
6
  * for sessions already past the idle-reap threshold — the poll is invisible
7
7
  * until it matters.
8
8
  *
9
- * Fails open: no responder, or any responder answering `active: false`, means
9
+ * Fails open: no responder, or no responder answering `active: true`, means
10
10
  * no background work and the caller may reap. When several extensions answer,
11
11
  * responses are OR-ed — any assertion of live work holds the session.
12
12
  */
@@ -71,6 +71,12 @@ export interface FolderCreator {
71
71
  readonly id: string;
72
72
  /** Human-readable description for the creation UI. */
73
73
  describe(): FolderCreatorDescriptor;
74
+ /**
75
+ * Make the folder and return its path. Pimote resolves the path to its
76
+ * canonical filesystem identity before seeding, broadcasting, or opening a
77
+ * session, so a creator can return the lexical path it used to reach the
78
+ * folder. The path must name the successfully created folder.
79
+ */
74
80
  create(params: Record<string, unknown>): Promise<{
75
81
  path: string;
76
82
  }>;
@@ -1,7 +1,3 @@
1
- /** Tracks active state per key so re-detection deactivates the old handle.
2
- * Scoped per ExtensionAPI instance (one per pi session) via a WeakMap, so two
3
- * sessions in the same process that detect() the same key don't deactivate
4
- * each other's handles. */
5
1
  const handlesByApi = new WeakMap();
6
2
  /**
7
3
  * Detect whether running inside pimote. Returns a scoped handle for pushing
@@ -12,7 +8,6 @@ const handlesByApi = new WeakMap();
12
8
  * previous handle (its methods become no-ops) and returns a new one.
13
9
  */
14
10
  export function detect(pi, key) {
15
- // Synchronous detection round-trip
16
11
  let detected = false;
17
12
  const unsub = pi.events.on('pimote:detect:response', () => {
18
13
  detected = true;
@@ -21,7 +16,6 @@ export function detect(pi, key) {
21
16
  unsub();
22
17
  if (!detected)
23
18
  return null;
24
- // Deactivate previous handle for this key (scoped to this pi instance)
25
19
  let handles = handlesByApi.get(pi);
26
20
  if (!handles) {
27
21
  handles = new Map();
@@ -30,7 +24,6 @@ export function detect(pi, key) {
30
24
  const prev = handles.get(key);
31
25
  if (prev)
32
26
  prev.active = false;
33
- // Create new handle state
34
27
  const state = { active: true };
35
28
  handles.set(key, state);
36
29
  return {
@@ -15,7 +15,7 @@ export interface Card {
15
15
  footer?: string[];
16
16
  /**
17
17
  * Optional same-origin URL. When present, the client renders the entire
18
- * card as a clickable link (same-tab navigation). Kept in lock-step with
18
+ * card as a clickable link that opens in a new tab. Kept in lock-step with
19
19
  * the protocol `Card` type in `shared/src/protocol.ts`.
20
20
  */
21
21
  href?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pimote/sdk",
3
- "version": "0.15.0-rc.5",
3
+ "version": "0.15.0",
4
4
  "description": "Pimote extensibility SDK: panel cards, background-activity reap guard, and folder discovery/creation seams for pi extensions",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -49,7 +49,7 @@
49
49
  }
50
50
  },
51
51
  "devDependencies": {
52
- "@earendil-works/pi-coding-agent": "1.3.0",
52
+ "@earendil-works/pi-coding-agent": "1.4.0",
53
53
  "typescript": "^6.0.2",
54
54
  "vitest": "^4.1.2"
55
55
  }