@kaoruisaac/pedelec 0.2.2 → 0.2.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.
package/README.md CHANGED
@@ -171,18 +171,22 @@ Pedelec creates missing `skills/`, `assets/`, `logs/`, and `tmp/` directories an
171
171
 
172
172
  ## Selecting an Application Workspace
173
173
 
174
- Use `directoryPicker()` when the application wants the user to choose a local workspace before creating a session:
174
+ Use `sandboxFolderPicker()` when the application wants the user to choose a local workspace before creating a session:
175
175
 
176
176
  ```ts
177
- const path = await pedelec.directoryPicker();
178
- if (path === null) return; // The user cancelled the native picker.
177
+ const folder = await pedelec.sandboxFolderPicker();
178
+ if (!folder) return; // The user cancelled the native picker.
179
+
180
+ if (!folder.isEmptyFolder && !folder.hasSandboxConfig) {
181
+ // The application decides whether to warn the user.
182
+ }
179
183
 
180
184
  const session = await pedelec.createSession({
181
- sandbox: { path },
185
+ sandbox: { path: folder.path },
182
186
  });
183
187
  ```
184
188
 
185
- `directoryPicker()` returns `Promise<string | null>` and does not validate or initialize the selected directory. It requires the same origin approval as other sensitive Desktop APIs. The selected path remains application-managed; existing Core sandbox rules are applied later by `createSession()`, which may return `SANDBOX_PATH_INVALID` for an unacceptable path.
189
+ `sandboxFolderPicker()` returns `Promise<SandboxFolderPickerResult | null>`. It is a read-only snapshot: it does not validate or initialize the selected folder, create workspace directories, or create the sandbox marker. `isEmptyFolder` only reports whether the selected folder root has any filesystem entry. `hasSandboxConfig` is true only when `.pedelec-sandbox.json` exists as a regular file; its JSON is not parsed. The picker requires the same origin approval as other sensitive Desktop APIs, and cancellation returns `null`. `createSession()` still applies the full sandbox rules and creates the marker after successful custom sandbox initialization. The marker currently records the SDK version and normalized caller origin but does not restrict reuse by origin or SDK version.
186
190
 
187
191
  ---
188
192
 
package/dist/index.d.ts CHANGED
@@ -86,6 +86,11 @@ export type SerializableSkillsManifest = {
86
86
  export type CreateSessionSandboxInput = {
87
87
  path: string;
88
88
  };
89
+ export interface SandboxFolderPickerResult {
90
+ path: string;
91
+ isEmptyFolder: boolean;
92
+ hasSandboxConfig: boolean;
93
+ }
89
94
  type CreateSessionInputWithProvider<TTools extends readonly ToolDefinition[] = readonly ToolDefinition[]> = {
90
95
  provider: ProviderCode;
91
96
  effortLevel?: EffortLevel;
@@ -233,7 +238,7 @@ export declare class Pedelec {
233
238
  constructor(options?: PedelecOptions);
234
239
  createSession(): Promise<PedelecSession<string>>;
235
240
  createSession<const TTools extends readonly ToolDefinition[]>(input: CreateSessionInput<TTools>): Promise<PedelecSession<ToolNameOf<TTools>>>;
236
- directoryPicker(): Promise<string | null>;
241
+ sandboxFolderPicker(): Promise<SandboxFolderPickerResult | null>;
237
242
  listProviders(): Promise<ProviderInfo[]>;
238
243
  getSettings(): Promise<PedelecSettings>;
239
244
  getApprovalStatus(): Promise<ApprovalStatus>;
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { PEDELEC_EXTENSION_ID } from "./extension-id.js";
2
+ import { SDK_VERSION } from "./version.generated.js";
2
3
  const SDK_EXTERNAL_PORT_NAME = "pedelec-sdk-external";
3
4
  const DEFAULT_BRIDGE_TIMEOUT_MS = 30_000;
4
5
  function normalizeListAssetsResponse(response) {
@@ -149,9 +150,9 @@ export class Pedelec {
149
150
  }
150
151
  return this.registerSession(result.sessionId, resolvedInput.provider, resolvedInput.effortLevel, resolvedInput.inlineToolHandlers);
151
152
  }
152
- async directoryPicker() {
153
- const result = await this.requestWithOptions("pick_directory", {}, { timeoutMs: null });
154
- return normalizeDirectoryPickerResponse(result);
153
+ async sandboxFolderPicker() {
154
+ const result = await this.requestWithOptions("pick_sandbox_folder", {}, { timeoutMs: null });
155
+ return normalizeSandboxFolderPickerResponse(result);
155
156
  }
156
157
  async listProviders() {
157
158
  return normalizeProviderInfoList(await this.request("list_providers"));
@@ -201,7 +202,13 @@ export class Pedelec {
201
202
  return Promise.reject(normalizeError(err, "EXTENSION_UNAVAILABLE", "Pedelec extension is unavailable."));
202
203
  }
203
204
  const requestId = `sdk_${Date.now()}_${this.nextRequestNumber++}`;
204
- const message = { channelId: this.channelId, type, requestId, ...payload };
205
+ const message = {
206
+ channelId: this.channelId,
207
+ type,
208
+ requestId,
209
+ ...payload,
210
+ ...(type === "create_session" ? { callerSdkVersion: SDK_VERSION } : {}),
211
+ };
205
212
  return new Promise((resolve, reject) => {
206
213
  const timeoutMs = options.timeoutMs === undefined ? this.bridgeTimeoutMs : options.timeoutMs;
207
214
  const timeoutId = timeoutMs === null
@@ -1026,15 +1033,22 @@ function normalizePedelecSettings(value) {
1026
1033
  }
1027
1034
  return { defaultProvider: value.defaultProvider };
1028
1035
  }
1029
- function normalizeDirectoryPickerResponse(value) {
1036
+ function normalizeSandboxFolderPickerResponse(value) {
1030
1037
  if (!isPlainObject(value) || !("path" in value)) {
1031
- throw makeError("SDK_PROTOCOL_ERROR", "pick_directory response had an invalid shape");
1038
+ throw makeError("SDK_PROTOCOL_ERROR", "pick_sandbox_folder response had an invalid shape");
1032
1039
  }
1033
1040
  const path = value.path;
1034
- if (path !== null && (typeof path !== "string" || path.length === 0)) {
1035
- throw makeError("SDK_PROTOCOL_ERROR", "pick_directory response had an invalid shape");
1041
+ if (path === null)
1042
+ return null;
1043
+ if (typeof path !== "string" || path.length === 0 ||
1044
+ typeof value.isEmptyFolder !== "boolean" || typeof value.hasSandboxConfig !== "boolean") {
1045
+ throw makeError("SDK_PROTOCOL_ERROR", "pick_sandbox_folder response had an invalid shape");
1036
1046
  }
1037
- return path;
1047
+ return {
1048
+ path,
1049
+ isEmptyFolder: value.isEmptyFolder,
1050
+ hasSandboxConfig: value.hasSandboxConfig,
1051
+ };
1038
1052
  }
1039
1053
  function normalizeProviderInfoList(value) {
1040
1054
  if (!Array.isArray(value))
@@ -136,10 +136,15 @@ async function availabilityHasPublicType() {
136
136
  void availability;
137
137
  void promise;
138
138
  }
139
- async function directoryPickerHasPublicType() {
139
+ async function sandboxFolderPickerHasPublicType() {
140
140
  const pedelec = new Pedelec();
141
- const path = pedelec.directoryPicker();
142
- void path;
141
+ const result = pedelec.sandboxFolderPicker();
142
+ void result;
143
+ }
144
+ function directoryPickerIsRemoved() {
145
+ const pedelec = new Pedelec();
146
+ // @ts-expect-error directoryPicker was removed in favor of sandboxFolderPicker
147
+ pedelec.directoryPicker();
143
148
  }
144
149
  function publicSecurityTypesAreRestricted() {
145
150
  const status = {
@@ -159,7 +164,8 @@ void noSkillsFallsBackToString;
159
164
  void effortLevelPublicTypeContract;
160
165
  void listAssetsHasPublicTypes;
161
166
  void availabilityHasPublicType;
162
- void directoryPickerHasPublicType;
167
+ void sandboxFolderPickerHasPublicType;
168
+ void directoryPickerIsRemoved;
163
169
  void publicSecurityTypesAreRestricted;
164
170
  const baseContext = {
165
171
  sessionId: "thread_1",
@@ -0,0 +1 @@
1
+ export declare const SDK_VERSION = "0.2.4";
@@ -0,0 +1,2 @@
1
+ // Generated from sdk/package.json. Do not edit manually.
2
+ export const SDK_VERSION = "0.2.4";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaoruisaac/pedelec",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -24,8 +24,11 @@
24
24
  "directory": "sdk"
25
25
  },
26
26
  "scripts": {
27
+ "prebuild": "node scripts/generate-version.mjs",
27
28
  "build": "tsc -p tsconfig.json",
29
+ "pretest": "node scripts/generate-version.mjs",
28
30
  "test": "vitest run",
31
+ "pretype-test": "node scripts/generate-version.mjs",
29
32
  "type-test": "tsc -p tsconfig.type-test.json",
30
33
  "prepublishOnly": "npm run test && npm run type-test && npm run build"
31
34
  },