@lazyingart/agintiflow 0.20.92 → 0.20.94

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
@@ -155,7 +155,7 @@ aginti --resume <session-id> \
155
155
  "Take a fresh screenshot of the running app in the emulator, save it with a durable filename in this project, and keep git status clean."
156
156
  ```
157
157
 
158
- Permission behavior is intentionally consistent: writes inside the current project are allowed through file tools, network/setup runs are normal in approved Docker workspace mode, and outside-project or trusted-host actions stop with a clear blocker plus a suggested rerun command. See [runtime modes and autonomy](docs/runtime-modes-and-autonomy.md) for the full contract.
158
+ Permission behavior is intentionally consistent: writes inside the current project are allowed through file tools, workspace-local toolchain builds/probes can run when their command is narrowly classified, network/setup runs are normal in approved Docker workspace mode, and outside-project or trusted-host actions stop with a clear blocker plus a suggested rerun command. See [runtime modes and autonomy](docs/runtime-modes-and-autonomy.md) for the full contract.
159
159
 
160
160
  Tmux follows the same rule. In Docker sandbox mode, `tmux_start_session` and `tmux_send_keys` are durable host tools, but their commands must stay workspace-bound. In host mode, tmux startup/send command text follows the same host shell policy as `run_command`; broad host shell work needs explicit `--allow-destructive`. Use `--sandbox-mode host --allow-destructive` only when a tmux task really needs trusted whole-host execution.
161
161
 
@@ -167,7 +167,7 @@ Use these when you want explicit control instead of the default interactive poli
167
167
  | --- | --- | --- |
168
168
  | Strict inspection | `aginti --sandbox-mode docker-readonly --package-install-policy block --allow-shell --no-file-tools --no-web-search "inspect this project without edits"` | Enforced read-only project inspection through shell commands such as `ls`, `rg`, `cat`, and test commands that do not write. No file-tool writes, web calls, workspace writes, or installs. |
169
169
  | Full write in current folder | `aginti --sandbox-mode docker-workspace --package-install-policy allow --approve-package-installs --allow-shell --allow-file-tools "build and test this project"` | Read/write inside the current project folder, run network/setup commands in Docker, keep host safer. |
170
- | Full host computer access | `aginti --sandbox-mode host --package-install-policy allow --approve-package-installs --allow-shell --allow-file-tools --allow-destructive "perform the trusted host maintenance task"` | Direct host shell and destructive actions. Use only when you trust the task and want whole-host access. |
170
+ | Full host computer access | `aginti --sandbox-mode host --package-install-policy allow --approve-package-installs --allow-shell --allow-file-tools --allow-destructive "perform the trusted host maintenance task"` | Direct host shell and destructive actions. Use only when you trust the task and want whole-host access. Android emulator/device work often needs this because the SDK and emulator live on the host. |
171
171
 
172
172
  For resume:
173
173
 
@@ -13,7 +13,7 @@ The failed task was expected under the current Docker design, but the agent shou
13
13
 
14
14
  The fix is guidance plus guardrails: raw `tmux` shell commands are blocked inside Docker `run_command`, and the model is told to use host tmux tools for durable sessions.
15
15
 
16
- Important boundary: host tmux tools are durable, but they are not a permission escape hatch. In `docker-readonly` and `docker-workspace` modes, `tmux_start_session` and `tmux_send_keys` are still workspace-bound. Startup commands and sent shell text must use relative paths under the project, not absolute host paths outside the project. In `host` mode, tmux startup/send command text follows the same host shell policy as `run_command`, so broad host shell work requires `--allow-destructive`. If a task really needs `/home/...`, `/etc/...`, an emulator outside the project, or whole-host maintenance, rerun explicitly with `--sandbox-mode host --allow-destructive`.
16
+ Important boundary: host tmux tools are durable, but they are not a permission escape hatch. In `docker-readonly` and `docker-workspace` modes, `tmux_start_session` and `tmux_send_keys` are still workspace-bound. Startup commands and sent shell text must use relative paths under the project, not absolute host paths outside the project. In `host` mode, tmux startup/send command text follows the same host shell policy as `run_command`, so broad host shell work requires `--allow-destructive`. Narrow workspace-local probes/builds can run without full-host trust, but if a task really needs `/home/...`, `/etc/...`, an emulator outside the project, or whole-host maintenance, rerun explicitly with `--sandbox-mode host --allow-destructive`.
17
17
 
18
18
  ## Execution Modes
19
19
 
@@ -51,11 +51,13 @@ The runtime must be consistent when an action is not permitted. A blocked action
51
51
  Current contract:
52
52
 
53
53
  - Workspace file tools may read and write inside the configured project folder when file tools are enabled.
54
+ - Narrow workspace-local shell actions such as safe probes, Gradle/TeX builds, and `chmod +x` on a project script may run when the command policy can classify them precisely.
54
55
  - Workspace writes outside that folder, secret paths, `.git` internals, and dependency folders such as `node_modules` are blocked.
55
56
  - `git clone`, `git fetch`, `git pull --ff-only`, `git push`, `curl`, and `wget` are classified as network operations.
56
57
  - Network/setup commands are allowed in `docker-workspace` only when package installs are approved.
57
58
  - Host `sudo` and host OS package installs are not automatic. The agent should ask the user to run a manual command or switch to a safer Docker setup.
58
59
  - Destructive host shell/git operations need explicit trusted host mode.
60
+ - Android SDK/emulator work commonly needs host mode because `adb`, emulator images, and device state live outside Docker; use trusted host mode for install/launch/screenshot steps when the user approves that host access.
59
61
 
60
62
  When a tool is blocked, the tool result includes `permissionAdvice` with three choices: refuse/stop, approve a safer rerun, or switch to a trusted host run. The model prompt requires the agent to present that blocker and avoid retrying variants until the user approves a path.
61
63
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.20.92",
3
+ "version": "0.20.94",
4
4
  "type": "module",
5
5
  "description": "Low-cost, project-aware Web and CLI agents with DeepSeek/Venice/OpenAI routing, visible tool calls, durable sessions, scouts, AAPS, SCS, and guarded local execution.",
6
6
  "license": "Apache-2.0",
@@ -270,6 +270,14 @@ try {
270
270
  ...dockerWorkspacePolicy,
271
271
  packageInstallPolicy: "block",
272
272
  };
273
+ const hostWorkspacePolicy = {
274
+ allowShellTool: true,
275
+ useDockerSandbox: false,
276
+ sandboxMode: "host",
277
+ packageInstallPolicy: "allow",
278
+ allowDestructive: false,
279
+ commandCwd: workspace,
280
+ };
273
281
  const readonlyProbePolicy = evaluateCommandPolicy(
274
282
  'which pdflatex 2>&1; which latexmk 2>&1; echo "---"; find /workspace -name \'*.tex\' -maxdepth 3 2>/dev/null; echo "exit: $?"',
275
283
  dockerWorkspaceNoInstallsPolicy
@@ -326,6 +334,21 @@ try {
326
334
  assert(safeChmodAndRunPolicy.allowed, "safe workspace chmod + script run sequence should be allowed in docker-workspace allow mode");
327
335
  const unsafeChmodPolicy = evaluateCommandPolicy("chmod +x /etc/passwd", dockerWorkspacePolicy);
328
336
  assert(!unsafeChmodPolicy.allowed, "chmod outside the workspace should be blocked");
337
+ const hostWorkspaceChmodPolicy = evaluateCommandPolicy("chmod +x android-app/gradlew && echo \"CHMOD_OK\"", hostWorkspacePolicy);
338
+ assert(hostWorkspaceChmodPolicy.allowed, "host mode should allow workspace-local chmod without full-host destructive access");
339
+ assert(
340
+ hostWorkspaceChmodPolicy.category === "permission-change",
341
+ "host workspace chmod sequence should remain categorized as permission-change"
342
+ );
343
+ const androidReadonlyProbePolicy = evaluateCommandPolicy(
344
+ 'test -x /usr/bin/gradle && echo "GRADLE_OK" ; test -x /usr/bin/java && /usr/bin/java -version 2>&1 | head -1; adb devices; emulator -list-avds; find android-app -type f | sort',
345
+ hostWorkspacePolicy
346
+ );
347
+ assert(androidReadonlyProbePolicy.allowed, "Android host read-only probes should not require full-host destructive access");
348
+ assert(androidReadonlyProbePolicy.category === "read-only", "Android host probes should remain read-only");
349
+ const androidGradleBuildPolicy = evaluateCommandPolicy("cd android-app && ./gradlew :app:assembleDebug", hostWorkspacePolicy);
350
+ assert(androidGradleBuildPolicy.allowed, "workspace-local Gradle Android build should be allowed in host workspace mode");
351
+ assert(androidGradleBuildPolicy.category === "toolchain", "workspace-local Gradle Android build should be toolchain");
329
352
  const cdWorkspacePolicy = evaluateCommandPolicy("cd /workspace && git status --short 2>&1 | head -20", dockerWorkspacePolicy);
330
353
  assert(cdWorkspacePolicy.allowed, "cd /workspace should be allowed in docker-workspace mode");
331
354
  const gitCleanDryRunPolicy = evaluateCommandPolicy("git clean -nd reports", dockerWorkspacePolicy);
@@ -338,8 +361,21 @@ try {
338
361
  assert(localGitCommitPolicy.category === "git-workflow", "local git commit should be classified as git-workflow");
339
362
  const localGitSwitchPolicy = evaluateCommandPolicy("git switch -c feature-a", dockerWorkspaceNoInstallsPolicy);
340
363
  assert(localGitSwitchPolicy.allowed, "local git switch -c should be allowed without package installs");
364
+ const localGitCheckoutExistingPolicy = evaluateCommandPolicy("git checkout main", dockerWorkspaceNoInstallsPolicy);
365
+ assert(localGitCheckoutExistingPolicy.allowed, "local git checkout existing branch should be allowed without package installs");
341
366
  const localGitMergePolicy = evaluateCommandPolicy("git merge --ff-only feature-a", dockerWorkspaceNoInstallsPolicy);
342
367
  assert(localGitMergePolicy.allowed, "local git fast-forward merge should be allowed without package installs");
368
+ const localGitNoFfMergePolicy = evaluateCommandPolicy("git merge --no-ff --no-edit feature-b", dockerWorkspaceNoInstallsPolicy);
369
+ assert(localGitNoFfMergePolicy.allowed, "local git explicit no-ff merge should be allowed without package installs");
370
+ const localGitNoFfMergeAltPolicy = evaluateCommandPolicy("git merge --no-ff feature-b --no-edit", dockerWorkspaceNoInstallsPolicy);
371
+ assert(localGitNoFfMergeAltPolicy.allowed, "local git explicit no-ff merge alternate arg order should be allowed");
372
+ const localGitWorkflowSequencePolicy = evaluateCommandPolicy(
373
+ "cd /workspace/git-practice && git checkout main && git merge --ff-only feature-a",
374
+ dockerWorkspaceNoInstallsPolicy
375
+ );
376
+ assert(localGitWorkflowSequencePolicy.allowed, "local git checkout + ff-only merge sequence should be allowed without package installs");
377
+ const plainGitMergePolicy = evaluateCommandPolicy("git merge feature-a", dockerWorkspaceNoInstallsPolicy);
378
+ assert(!plainGitMergePolicy.allowed, "plain git merge should stay guarded because it can hang or make an ambiguous merge");
343
379
  const unsafeRebasePolicy = evaluateCommandPolicy("git rebase main", dockerWorkspaceNoInstallsPolicy);
344
380
  assert(!unsafeRebasePolicy.allowed, "git rebase should still require stronger permission because it rewrites history");
345
381
  const unsafeCloneTarget = evaluateCommandPolicy("git clone https://github.com/lazyingart/AgInTiFlow.git ../AgInTiFlow", dockerWorkspacePolicy);
@@ -780,6 +816,9 @@ try {
780
816
  "command_policy_git_rebase_still_guarded",
781
817
  "command_policy_git_clone_network",
782
818
  "command_policy_safe_chmod_sequence",
819
+ "command_policy_host_workspace_chmod",
820
+ "command_policy_android_host_probes",
821
+ "command_policy_android_gradle_build",
783
822
  "command_policy_cd_workspace",
784
823
  "command_policy_git_clean_dry_run",
785
824
  "permission_recovery_advice",
@@ -126,6 +126,25 @@ try {
126
126
  });
127
127
  assert.equal(dockerTmuxRelativeStart.allowed, true, "Docker-mode tmux_start_session should allow workspace-relative paths");
128
128
 
129
+ const dockerTmuxGitFfMergeStart = checkToolUse({
130
+ toolName: "tmux_start_session",
131
+ args: {
132
+ name: `${session}-docker-git-ff`,
133
+ cwd: ".",
134
+ command: "git checkout main && git merge --ff-only feature-a",
135
+ },
136
+ config: dockerNoInstallsConfig,
137
+ });
138
+ assert.equal(dockerTmuxGitFfMergeStart.allowed, true, "Docker-mode tmux should allow explicit local checkout + ff-only merge workflow");
139
+
140
+ const dockerTmuxGitPlainMergeStart = checkToolUse({
141
+ toolName: "tmux_start_session",
142
+ args: { name: `${session}-docker-git-plain-merge`, cwd: ".", command: "git merge feature-a" },
143
+ config: dockerNoInstallsConfig,
144
+ });
145
+ assert.equal(dockerTmuxGitPlainMergeStart.allowed, false, "Docker-mode tmux should keep plain git merge guarded");
146
+ assert.equal(dockerTmuxGitPlainMergeStart.category, "destructive", "plain git merge should keep destructive category");
147
+
129
148
  const dockerTmuxRebaseStart = checkToolUse({
130
149
  toolName: "tmux_start_session",
131
150
  args: { name: `${session}-docker-rebase`, cwd: ".", command: "git rebase main" },
@@ -235,6 +254,8 @@ try {
235
254
  "docker-tmux-start-project-path-allowed",
236
255
  "docker-tmux-start-relative-path-allowed",
237
256
  "docker-tmux-start-command-policy-guardrail",
257
+ "docker-tmux-start-git-ff-merge-allowed",
258
+ "docker-tmux-start-plain-git-merge-guarded",
238
259
  "docker-tmux-send-command-policy-guardrail",
239
260
  "docker-tmux-send-readonly-command-allowed",
240
261
  "host-tmux-start-shell-policy-guardrail",
@@ -22,12 +22,13 @@ tools:
22
22
 
23
23
  1. Inspect before editing: `git status --short`, project tree, Gradle/settings files, AndroidManifest, package names, modules, Java/Kotlin versions, `ANDROID_HOME`/`ANDROID_SDK_ROOT`, likely SDK folders, `adb devices`, and emulator/AVD availability.
24
24
  2. Do not use host `sudo`, `apt`, `dnf`, `yum`, `brew`, `winget`, or global host installs for Android app work. These can hang on password prompts or mutate the user's machine. Prefer existing Android SDK tools, project-local Gradle wrapper setup, user-writable caches, or a clear setup report with the exact manual command.
25
- 3. If a Gradle wrapper is needed, create `gradle/wrapper/` before downloading files. Prefer a valid project-local wrapper or an already-installed Gradle. Do not loop on the same failed install/download.
26
- 4. Patch source-set-aware files only: manifests, Gradle scripts, Kotlin/Java sources, XML resources, and project docs. Keep generated build outputs out of patches and commits.
27
- 5. Build with the narrowest useful task first, usually `./gradlew :app:assembleDebug` or `./gradlew assembleDebug`. Repair build failures from the actual error text.
28
- 6. Install and launch on an available device/emulator with `adb install` and `adb shell am start`. Verify with `adb shell pidof`, `adb logcat -d`, `adb shell screencap`, or similar evidence when available.
29
- 7. Save screenshots and APK references in durable workspace paths with descriptive names when the user did not specify paths, for example `artifacts/screenshots/<app>-<timestamp>.png` and `app/build/outputs/apk/debug/app-debug.apk`. Do not rely only on a temporary screenshot that is deleted after canvas preview.
30
- 8. Commit only after build/install/launch verification, with a clear message. Before final summary, run `git status --short`; leave source changes committed and generated/session artifacts ignored or explicitly reported. If no device/emulator exists, finish with a concrete external blocker and the generated APK path.
25
+ 3. Android SDK and emulator tooling usually lives on the host, not inside Docker. If a permission block appears while using a host SDK/emulator, prefer the exact trusted host resume command from `permissionAdvice.trustedHostCommand` over a Docker rerun unless the SDK is explicitly mounted in Docker.
26
+ 4. If a Gradle wrapper is needed, create `gradle/wrapper/` before downloading files. Prefer a valid project-local wrapper or an already-installed Gradle. Do not loop on the same failed install/download.
27
+ 5. Patch source-set-aware files only: manifests, Gradle scripts, Kotlin/Java sources, XML resources, and project docs. Keep generated build outputs out of patches and commits.
28
+ 6. Build with the narrowest useful task first, usually `./gradlew :app:assembleDebug` or `./gradlew assembleDebug`. Repair build failures from the actual error text.
29
+ 7. Install and launch on an available device/emulator with `adb install` and `adb shell am start`. Verify with `adb shell pidof`, `adb logcat -d`, `adb shell screencap`, or similar evidence when available.
30
+ 8. Save screenshots and APK references in durable workspace paths with descriptive names when the user did not specify paths, for example `artifacts/screenshots/<app>-<timestamp>.png` and `app/build/outputs/apk/debug/app-debug.apk`. Do not rely only on a temporary screenshot that is deleted after canvas preview.
31
+ 9. Commit only after build/install/launch verification, with a clear message. Before final summary, run `git status --short`; leave source changes committed and generated/session artifacts ignored or explicitly reported. If no device/emulator exists, finish with a concrete external blocker and the generated APK path.
31
32
 
32
33
  ## Missing Tooling
33
34
 
@@ -20,6 +20,6 @@ tools:
20
20
 
21
21
  Always inspect `git status --short` and relevant diffs before committing or pushing. Keep commits scoped and stop on conflicts, divergence, or unrelated dirty work.
22
22
 
23
- For local workflow practice or repository setup, prefer a disposable subdirectory if the user did not clearly target the current repository. Configure only local git identity (`git config user.name`, `git config user.email`) inside that repo; never change global git config. Use accurate git scenarios: a fast-forward merge means the target branch has not diverged; a non-fast-forward merge intentionally creates a merge commit after both branches diverge; a rebase rewrites local branch commits and should be used only in an explicitly disposable/local branch or after user approval.
23
+ For local workflow practice or repository setup, prefer a disposable subdirectory if the user did not clearly target the current repository. Configure only local git identity (`git config user.name`, `git config user.email`) inside that repo; never change global git config. Use policy-friendly local commands: `git switch <branch>` or `git checkout <branch>` for existing branches, `git switch -c <branch>` or `git checkout -b <branch>` for new branches, `git merge --ff-only <branch>` for fast-forward evidence, and `git merge --no-ff --no-edit <branch>` for explicit merge-commit evidence. Avoid plain `git merge <branch>` because it can hang on an editor or make an ambiguous merge. Use accurate git scenarios: a fast-forward merge means the target branch has not diverged; a non-fast-forward merge intentionally creates a merge commit after both branches diverge; a rebase rewrites local branch commits and should be used only in an explicitly disposable/local branch or after user approval.
24
24
 
25
25
  Use `gh` for PR/release/status workflows when authenticated. Fold long command output but preserve key errors, URLs, branch names, and commit hashes.
@@ -15,6 +15,7 @@ const READ_ONLY_PATTERNS = [
15
15
  /^cat(?:\s+[-\w./~*]+)+$/,
16
16
  /^head(?:\s+.+)?$/,
17
17
  /^tail(?:\s+.+)?$/,
18
+ /^sort(?:\s+[-\w./~*]+)*$/,
18
19
  /^wc(?:\s+.+)?$/,
19
20
  /^sed\s+-n\s+['"0-9,:p\s-]+\s+[-\w./~*]+$/,
20
21
  /^git\s+(status|branch|log|show|diff(?:\s+--stat)?|remote\s+-v)(?:\s+.+)?$/,
@@ -23,6 +24,11 @@ const READ_ONLY_PATTERNS = [
23
24
  /^python(?:3)?\s+--version$/,
24
25
  /^pip(?:3)?\s+--version$/,
25
26
  /^conda\s+--version$/,
27
+ /^(?:[-/\w.]+\/)?java\s+-version$/,
28
+ /^(?:[-/\w.]+\/)?gradle\s+--version$/,
29
+ /^(?:[-/\w.]+\/)?adb\s+devices(?:\s+-l)?$/,
30
+ /^(?:[-/\w.]+\/)?emulator\s+-list-avds$/,
31
+ /^(?:[-/\w.]+\/)?sdkmanager\s+--list(?:\s+[-\w./:=]+)*$/,
26
32
  /^(?:pdflatex|latexmk)\s+--version$/,
27
33
  /^test\s+-[efdx]\s+[-\w./~]+$/,
28
34
  /^true$/,
@@ -81,9 +87,13 @@ const GIT_WORKFLOW_PATTERNS = [
81
87
  /^git\s+branch\s+[A-Za-z0-9][-\w./]*$/,
82
88
  /^git\s+switch\s+(?:-c\s+)?[A-Za-z0-9][-\w./]*$/,
83
89
  /^git\s+checkout\s+-b\s+[A-Za-z0-9][-\w./]*$/,
90
+ /^git\s+checkout\s+[A-Za-z0-9][-\w./]*$/,
84
91
  /^git\s+merge\s+--ff-only\s+[A-Za-z0-9][-\w./]*$/,
85
92
  /^git\s+merge\s+--no-ff\s+--no-edit\s+[A-Za-z0-9][-\w./]*$/,
93
+ /^git\s+merge\s+--no-ff\s+[A-Za-z0-9][-\w./]*\s+--no-edit$/,
94
+ /^git\s+merge\s+--no-edit\s+--no-ff\s+[A-Za-z0-9][-\w./]*$/,
86
95
  /^git\s+merge\s+[A-Za-z0-9][-\w./]*\s+--no-ff\s+--no-edit$/,
96
+ /^git\s+merge\s+[A-Za-z0-9][-\w./]*\s+--no-edit\s+--no-ff$/,
87
97
  /^git\s+fetch(?:\s+[-\w./:=]+)*$/,
88
98
  /^git\s+pull\s+--ff-only(?:\s+[-\w./:=]+)*$/,
89
99
  /^git\s+push(?:\s+[-\w./:=]+)*$/,
@@ -96,6 +106,7 @@ const UNSAFE_GIT_PATTERNS = [
96
106
 
97
107
  const TOOLCHAIN_PATTERNS = [
98
108
  /^python(?:3)?\s+[-\w./]+\.py(?:\s+[-\w./:=]+)*$/,
109
+ /^\.\/gradlew\s+(?:(?::[-\w]+:)?(?:assembleDebug|assembleRelease|bundleDebug|bundleRelease|compileDebugKotlin|compileReleaseKotlin|testDebugUnitTest|lintDebug|lint|check|build))(?:\s+[-\w./:=]+)*$/,
99
110
  /^latexmk\s+(?=[-\w./=\s]*-pdf\b)(?:(?:-cd|-pdf|-interaction=nonstopmode|-halt-on-error|-output-directory=[-\w./]+)\s+)+[-\w./]+\.tex$/,
100
111
  /^pdflatex\s+(?:(?:-interaction=nonstopmode|-halt-on-error|-output-directory=[-\w./]+|-jobname\s+[-\w./]+)\s+)*[-\w./]+\.tex$/,
101
112
  ];
@@ -647,7 +658,7 @@ export function evaluateCommandPolicy(command, config) {
647
658
  };
648
659
  }
649
660
 
650
- if (classification.category === "permission-change" && !trustedDockerShell && !trustedHostShell) {
661
+ if (classification.category === "permission-change" && sandboxMode !== "host" && !trustedDockerShell && !trustedHostShell) {
651
662
  return {
652
663
  allowed: false,
653
664
  ...classification,
@@ -227,7 +227,7 @@ export const TASK_PROFILES = {
227
227
  id: "android",
228
228
  label: "Android",
229
229
  prompt:
230
- "Bias toward end-to-end Android app delivery while still handling normal project work. Inspect git status, existing Gradle files, AndroidManifest, SDK paths, Java/Kotlin versions, adb devices, and emulator/AVD availability before editing. Do not use host sudo, apt, dnf, yum, brew, winget, or global host installs during Android tasks; prefer the existing Android SDK, project-local Gradle wrapper, user-writable caches, or a clear setup report. Create missing wrapper directories before downloads, avoid repeated failing install attempts, build with focused Gradle tasks, install and launch with adb when a device/emulator exists, verify with am/logcat/screencap when possible, save screenshots under durable workspace paths, and commit the finished app only after checks.",
230
+ "Bias toward end-to-end Android app delivery while still handling normal project work. Inspect git status, existing Gradle files, AndroidManifest, SDK paths, Java/Kotlin versions, adb devices, and emulator/AVD availability before editing. Do not use host sudo, apt, dnf, yum, brew, winget, or global host installs during Android tasks; prefer the existing Android SDK, project-local Gradle wrapper, user-writable caches, or a clear setup report. Android SDK/emulator work usually needs host mode because device tools live outside Docker; if host policy blocks a required project-local build/probe, present the exact trusted host resume command from permissionAdvice rather than suggesting Docker as the primary route. Create missing wrapper directories before downloads, avoid repeated failing install attempts, build with focused Gradle tasks, install and launch with adb when a device/emulator exists, verify with am/logcat/screencap when possible, save screenshots under durable workspace paths, and commit the finished app only after checks.",
231
231
  tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "sandbox", "canvas"],
232
232
  },
233
233
  website: {
@@ -255,7 +255,7 @@ export const TASK_PROFILES = {
255
255
  id: "github",
256
256
  label: "GitHub maintenance",
257
257
  prompt:
258
- "Bias toward safe git and GitHub maintenance while still fixing code/docs when asked. Always inspect git status and remotes first, separate unrelated changes, run relevant checks before commits, use gh when available for PR/issues/releases, prefer fast-forward pulls, and stop on conflicts or ambiguous history. For local workflow practice, use a disposable subdirectory, set only local git identity, avoid real remotes unless explicitly requested, and describe fast-forward, non-fast-forward merge, and rebase evidence accurately.",
258
+ "Bias toward safe git and GitHub maintenance while still fixing code/docs when asked. Always inspect git status and remotes first, separate unrelated changes, run relevant checks before commits, use gh when available for PR/issues/releases, prefer fast-forward pulls, and stop on conflicts or ambiguous history. For local workflow practice, use a disposable subdirectory, set only local git identity, avoid real remotes unless explicitly requested, prefer `git switch <branch>`/`git checkout <branch>` for branch changes, use `git merge --ff-only <branch>` for fast-forward evidence, use `git merge --no-ff --no-edit <branch>` for intentional merge commits, avoid plain `git merge <branch>`, and describe fast-forward, non-fast-forward merge, and rebase evidence accurately.",
259
259
  tools: ["shell", "files", "web_search", "inspect_project"],
260
260
  },
261
261
  word: {