Skip to content

Commit c8a7197

Browse files
committed
feat(bsk): update skill to support drop
1 parent 10469a8 commit c8a7197

3 files changed

Lines changed: 28 additions & 11 deletions

File tree

crates/bsk-cli/skill/SKILL.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,22 +210,29 @@ Both capture from the moment the tab is attached and read a bounded per-tab buff
210210

211211
| Command | Summary |
212212
|---------|---------|
213-
| `bsk upload <ref-or-selector> --file <path>` | Attach a local file through a file-input trigger; use `--mode drop` only for an explicit drop zone (`--file` is repeatable) |
213+
| `bsk upload <ref-or-selector> --file <path>` | Attach a local file through a file-input trigger; use `--mode drop` for a reliably identified attachment-receiving area (`--file` is repeatable) |
214214
| `bsk download <ref-or-selector> --out <path>` | Click one download trigger and copy the single completed file to an exact local path (`--overwrite` is opt-in) |
215215

216216
The agent/harness decides whether a file transfer is appropriate and which local path belongs to the task. Treat upload as disclosure of that file to the current website, and download as accepting website-controlled bytes onto the local filesystem. Use only paths that are necessary for the user's bounded goal.
217217

218-
BrowserSkill enforces the mechanical boundary: files are staged under a session-scoped opaque transfer, only daemon-minted capabilities reach the extension, upload/download still obey Agent Window tab checks, and transfers are chunk/size bounded. The default upload mode intercepts one chooser transaction, locates the file input activated in the resolved target's document, and assigns only the staged paths. `--mode drop` does not click: it delivers the same staged files through one native browser drop bound to the explicitly resolved drop zone. These mechanisms never fall back to each other automatically. Download uniquely correlates one exact-target browser intent with one Chrome download in either event order, routes it through a daemon-minted relative directory, and lets the daemon validate and import it. Upload staging remains available for a later form submission and is removed when the session ends. Downloads cannot overwrite an existing destination unless `--overwrite` is explicit. BrowserSkill does not inspect file content or decide whether its meaning is sensitive.
218+
BrowserSkill enforces the mechanical boundary: files are staged under a session-scoped opaque transfer, only daemon-minted capabilities reach the extension, upload/download still obey Agent Window tab checks, and transfers are chunk/size bounded. The default upload mode intercepts one chooser transaction, locates the file input activated in the resolved target's document, and assigns only the staged paths. `--mode drop` does not click: it delivers the same staged files through one native browser drop bound to the explicitly resolved attachment target. These mechanisms never fall back to each other automatically. Download uniquely correlates one exact-target browser intent with one Chrome download in either event order, routes it through a daemon-minted relative directory, and lets the daemon validate and import it. Upload staging remains available for a later form submission and is removed when the session ends. Downloads cannot overwrite an existing destination unless `--overwrite` is explicit. BrowserSkill does not inspect file content or decide whether its meaning is sensitive.
219+
220+
Choose the upload mechanism explicitly:
221+
222+
- Use the default input mode for an upload button, file-input label, or “upload from computer” action.
223+
- Use `--mode drop` only when the attachment can be reliably attributed to the target business editor: an explicit drop zone, chat composer, email editor, or form attachment area. Do not target page whitespace, a generic container, or an area whose attachment ownership is ambiguous.
224+
- If input mode returns `reason=file_input_not_activated` with `effect_state=none`, re-observe. When a reliable attachment-receiving area is present, attempt drop once against that area; otherwise use `request-help` when available.
225+
- Never switch mechanisms or repeat an upload when `effect_state=unknown` or `committed`.
219226

220227
A successful drop command means Chrome dispatched the native file drop to the resolved zone; it does not prove that the site's application logic accepted the attachment. Observe the page once after the command, and do not repeat the drop when the attachment is already present.
221228

222229
Do not use `request-help` merely because a native file chooser or browser download is involved; try these commands first. For transfer failures, use the structured error instead of retrying blindly:
223230

224-
- `reason=file_input_not_activated` means the requested click did not activate exactly one `<input type="file">`; the page may use a non-input picker such as `window.showOpenFilePicker()`. Do not retry blindly. If human help is available, call `request-help` and tell the user the exact original local path to choose. The staged daemon path is internal and must not be shown to the user.
231+
- `reason=file_input_not_activated` means the requested click did not activate exactly one `<input type="file">`; the page may use a non-input picker such as `window.showOpenFilePicker()`. Follow the explicit mechanism-selection rule above. If no reliable attachment-receiving area exists, call `request-help` when available and tell the user the exact original local path to choose. The staged daemon path is internal and must not be shown to the user.
225232
- `reason=file_input_probe_failed` means BrowserSkill could not safely establish the browser-side upload transaction. Do not repeat the same action; use `request-help` when available.
226233
- `reason=set_file_input_failed` means BrowserSkill found the activated file input but Chrome rejected the staged path or assignment. Check the extension's file-URL access permission; otherwise use `request-help`.
227234
- `reason=upload_mechanism_unsupported` means the browser cannot perform a native file drop. Do not retry the same drop; use a standard file-input trigger or `request-help`.
228-
- `reason=file_drop_target_unavailable` means the specified point is no longer owned by the resolved drop zone. When `effect_state=none`, re-observe and select the visible drop zone itself; do not guess another target.
235+
- `reason=file_drop_target_unavailable` means the specified point is no longer owned by the resolved attachment target. When `effect_state=none`, re-observe and select the attachment-receiving editor or drop zone itself; do not guess another target.
229236
- `reason=file_drop_failed` means the native drop command failed. Do not retry when `effect_state=unknown`; first observe whether the page already received the file.
230237
- `reason=download_capture_failed` means BrowserSkill could not attribute exactly one completed download to the requested target. Do not retry blindly or accept an unrelated browser download; use `request-help` when available.
231238
- `effect_state=none` means BrowserSkill confirmed that no file-transfer effect was committed. Follow the accompanying reason; a corrected target or explicit human fallback may be attempted.

crates/bsk-cli/src/cli/render_error.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ pub fn info_for_error(code: ErrorCode, data: Option<&serde_json::Value>) -> Rend
295295
(ErrorCode::Unsupported, reason::FILE_INPUT_NOT_ACTIVATED) => RenderInfo {
296296
summary: "the upload trigger did not activate a file input",
297297
hint: Some(
298-
"the page may use a non-input picker such as showOpenFilePicker(); do not retry blindly — use `bsk request-help` with the exact original local path, or stop if human help is disabled",
298+
"the page may use a non-input picker such as showOpenFilePicker(); when effect_state is none, re-observe and use `--mode drop` once only for a reliably identified attachment-receiving area — otherwise use `bsk request-help` with the exact original local path",
299299
),
300300
exit_code: base.exit_code,
301301
},
@@ -328,7 +328,7 @@ pub fn info_for_error(code: ErrorCode, data: Option<&serde_json::Value>) -> Rend
328328
) => RenderInfo {
329329
summary: "the file-drop target could not be safely resolved",
330330
hint: Some(
331-
"rerun observe and select the visible drop zone itself; no file was delivered when effect_state is none",
331+
"rerun observe and select the attachment-receiving editor or drop zone itself; do not guess another target — no file was delivered when effect_state is none",
332332
),
333333
exit_code: base.exit_code,
334334
},
@@ -477,7 +477,10 @@ mod tests {
477477
info.summary,
478478
"the upload trigger did not activate a file input"
479479
);
480-
assert!(info.hint.unwrap().contains("exact original local path"));
480+
let hint = info.hint.unwrap();
481+
assert!(hint.contains("--mode drop"));
482+
assert!(hint.contains("reliably identified attachment-receiving area"));
483+
assert!(hint.contains("exact original local path"));
481484

482485
let control = serde_json::json!({ "reason": reason::FILE_INPUT_PROBE_FAILED });
483486
let info = info_for_error(ErrorCode::Timeout, Some(&control));

skill/SKILL.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,22 +210,29 @@ Both capture from the moment the tab is attached and read a bounded per-tab buff
210210

211211
| Command | Summary |
212212
|---------|---------|
213-
| `bsk upload <ref-or-selector> --file <path>` | Attach a local file through a file-input trigger; use `--mode drop` only for an explicit drop zone (`--file` is repeatable) |
213+
| `bsk upload <ref-or-selector> --file <path>` | Attach a local file through a file-input trigger; use `--mode drop` for a reliably identified attachment-receiving area (`--file` is repeatable) |
214214
| `bsk download <ref-or-selector> --out <path>` | Click one download trigger and copy the single completed file to an exact local path (`--overwrite` is opt-in) |
215215

216216
The agent/harness decides whether a file transfer is appropriate and which local path belongs to the task. Treat upload as disclosure of that file to the current website, and download as accepting website-controlled bytes onto the local filesystem. Use only paths that are necessary for the user's bounded goal.
217217

218-
BrowserSkill enforces the mechanical boundary: files are staged under a session-scoped opaque transfer, only daemon-minted capabilities reach the extension, upload/download still obey Agent Window tab checks, and transfers are chunk/size bounded. The default upload mode intercepts one chooser transaction, locates the file input activated in the resolved target's document, and assigns only the staged paths. `--mode drop` does not click: it delivers the same staged files through one native browser drop bound to the explicitly resolved drop zone. These mechanisms never fall back to each other automatically. Download uniquely correlates one exact-target browser intent with one Chrome download in either event order, routes it through a daemon-minted relative directory, and lets the daemon validate and import it. Upload staging remains available for a later form submission and is removed when the session ends. Downloads cannot overwrite an existing destination unless `--overwrite` is explicit. BrowserSkill does not inspect file content or decide whether its meaning is sensitive.
218+
BrowserSkill enforces the mechanical boundary: files are staged under a session-scoped opaque transfer, only daemon-minted capabilities reach the extension, upload/download still obey Agent Window tab checks, and transfers are chunk/size bounded. The default upload mode intercepts one chooser transaction, locates the file input activated in the resolved target's document, and assigns only the staged paths. `--mode drop` does not click: it delivers the same staged files through one native browser drop bound to the explicitly resolved attachment target. These mechanisms never fall back to each other automatically. Download uniquely correlates one exact-target browser intent with one Chrome download in either event order, routes it through a daemon-minted relative directory, and lets the daemon validate and import it. Upload staging remains available for a later form submission and is removed when the session ends. Downloads cannot overwrite an existing destination unless `--overwrite` is explicit. BrowserSkill does not inspect file content or decide whether its meaning is sensitive.
219+
220+
Choose the upload mechanism explicitly:
221+
222+
- Use the default input mode for an upload button, file-input label, or “upload from computer” action.
223+
- Use `--mode drop` only when the attachment can be reliably attributed to the target business editor: an explicit drop zone, chat composer, email editor, or form attachment area. Do not target page whitespace, a generic container, or an area whose attachment ownership is ambiguous.
224+
- If input mode returns `reason=file_input_not_activated` with `effect_state=none`, re-observe. When a reliable attachment-receiving area is present, attempt drop once against that area; otherwise use `request-help` when available.
225+
- Never switch mechanisms or repeat an upload when `effect_state=unknown` or `committed`.
219226

220227
A successful drop command means Chrome dispatched the native file drop to the resolved zone; it does not prove that the site's application logic accepted the attachment. Observe the page once after the command, and do not repeat the drop when the attachment is already present.
221228

222229
Do not use `request-help` merely because a native file chooser or browser download is involved; try these commands first. For transfer failures, use the structured error instead of retrying blindly:
223230

224-
- `reason=file_input_not_activated` means the requested click did not activate exactly one `<input type="file">`; the page may use a non-input picker such as `window.showOpenFilePicker()`. Do not retry blindly. If human help is available, call `request-help` and tell the user the exact original local path to choose. The staged daemon path is internal and must not be shown to the user.
231+
- `reason=file_input_not_activated` means the requested click did not activate exactly one `<input type="file">`; the page may use a non-input picker such as `window.showOpenFilePicker()`. Follow the explicit mechanism-selection rule above. If no reliable attachment-receiving area exists, call `request-help` when available and tell the user the exact original local path to choose. The staged daemon path is internal and must not be shown to the user.
225232
- `reason=file_input_probe_failed` means BrowserSkill could not safely establish the browser-side upload transaction. Do not repeat the same action; use `request-help` when available.
226233
- `reason=set_file_input_failed` means BrowserSkill found the activated file input but Chrome rejected the staged path or assignment. Check the extension's file-URL access permission; otherwise use `request-help`.
227234
- `reason=upload_mechanism_unsupported` means the browser cannot perform a native file drop. Do not retry the same drop; use a standard file-input trigger or `request-help`.
228-
- `reason=file_drop_target_unavailable` means the specified point is no longer owned by the resolved drop zone. When `effect_state=none`, re-observe and select the visible drop zone itself; do not guess another target.
235+
- `reason=file_drop_target_unavailable` means the specified point is no longer owned by the resolved attachment target. When `effect_state=none`, re-observe and select the attachment-receiving editor or drop zone itself; do not guess another target.
229236
- `reason=file_drop_failed` means the native drop command failed. Do not retry when `effect_state=unknown`; first observe whether the page already received the file.
230237
- `reason=download_capture_failed` means BrowserSkill could not attribute exactly one completed download to the requested target. Do not retry blindly or accept an unrelated browser download; use `request-help` when available.
231238
- `effect_state=none` means BrowserSkill confirmed that no file-transfer effect was committed. Follow the accompanying reason; a corrected target or explicit human fallback may be attempted.

0 commit comments

Comments
 (0)