Dax Raad hai 3 meses
pai
achega
a7f920d83b

+ 0 - 2
package.json

@@ -78,8 +78,6 @@
     "url": "https://github.com/sst/opencode"
   },
   "license": "MIT",
-  "randomField": "hello from claude",
-  "anotherRandomField": "xkcd-927-compliance-level",
   "prettier": {
     "semi": false,
     "printWidth": 120

+ 12 - 12
packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx

@@ -130,24 +130,24 @@ export function PermissionPrompt(props: { request: PermissionRequest }) {
               <Match when={true}>
                 <box paddingLeft={1} gap={1}>
                   <text fg={theme.textMuted}>This will allow the following patterns until OpenCode is restarted</text>
-                  <For each={props.request.always}>
-                    {(pattern) => (
-                      <text fg={theme.text}>
-                        {"- "}
-                        {pattern}
-                      </text>
-                    )}
-                  </For>
+                  <box>
+                    <For each={props.request.always}>
+                      {(pattern) => (
+                        <text fg={theme.text}>
+                          {"- "}
+                          {pattern}
+                        </text>
+                      )}
+                    </For>
+                  </box>
                 </box>
               </Match>
             </Switch>
           }
           options={{ confirm: "Confirm", cancel: "Cancel" }}
           onSelect={(option) => {
-            if (option === "cancel") {
-              setStore("always", false)
-              return
-            }
+            setStore("always", false)
+            if (option === "cancel") return
             sdk.client.permission.reply({
               reply: "always",
               requestID: props.request.id,

+ 14 - 5
packages/opencode/src/config/config.ts

@@ -123,13 +123,22 @@ export namespace Config {
       result.permission = mergeDeep(result.permission ?? {}, JSON.parse(Flag.OPENCODE_PERMISSION))
     }
 
-    if (!result.username) result.username = os.userInfo().username
-
-    // Handle migration from autoshare to share field
-    if (result.autoshare === true && !result.share) {
-      result.share = "auto"
+    // Backwards compatibility: legacy top-level `tools` config
+    if (result.tools) {
+      const perms: Record<string, Config.PermissionAction> = {}
+      for (const [tool, enabled] of Object.entries(result.tools)) {
+        const action: Config.PermissionAction = enabled ? "allow" : "deny"
+        if (tool === "write" || tool === "edit" || tool === "patch" || tool === "multiedit") {
+          perms.edit = action
+          continue
+        }
+        perms[tool] = action
+      }
+      result.permission = mergeDeep(perms, result.permission ?? {})
     }
 
+    if (!result.username) result.username = os.userInfo().username
+
     // Handle migration from autoshare to share field
     if (result.autoshare === true && !result.share) {
       result.share = "auto"

+ 2 - 1
packages/opencode/src/permission/arity.ts

@@ -5,7 +5,8 @@ export namespace BashArity {
       const arity = ARITY[prefix]
       if (arity !== undefined) return tokens.slice(0, arity)
     }
-    return tokens
+    if (tokens.length === 0) return []
+    return tokens.slice(0, 1)
   }
 
   /* Generated with following prompt:

+ 20 - 3
packages/opencode/src/permission/next.ts

@@ -181,7 +181,6 @@ export namespace PermissionNext {
         return
       }
       if (input.reply === "always") {
-        const projectID = Instance.project.id
         for (const pattern of existing.info.always) {
           s.approved.push({
             permission: existing.info.permission,
@@ -189,10 +188,28 @@ export namespace PermissionNext {
             action: "allow",
           })
         }
+
+        existing.resolve()
+
+        const sessionID = existing.info.sessionID
+        for (const [id, pending] of Object.entries(s.pending)) {
+          if (pending.info.sessionID !== sessionID) continue
+          const ok = pending.info.patterns.every(
+            (pattern) => evaluate(pending.info.permission, pattern, s.approved) === "allow",
+          )
+          if (!ok) continue
+          delete s.pending[id]
+          Bus.publish(Event.Replied, {
+            sessionID: pending.info.sessionID,
+            requestID: pending.info.id,
+            reply: "always",
+          })
+          pending.resolve()
+        }
+
         // TODO: we don't save the permission ruleset to disk yet until there's
         // UI to manage it
-        // await Storage.write(["permission", projectID], s.approved)
-        existing.resolve()
+        // await Storage.write(["permission", Instance.project.id], s.approved)
         return
       }
     },