Repository: vscode
Issue: Allow extensions to specify the schema for arguments to contributed commands
Labels: feature-request,extensions

<!-- ⚠️⚠️ Do Not Delete This! feature_request_template ⚠️⚠️ -->
<!-- Please read our Rules of Conduct: https://opensource.microsoft.com/codeofconduct/ -->
<!-- Please search existing issues to avoid creating duplicates. -->

<!-- Describe the feature you'd like. -->

Creating a feature request based on feedback from @aeschli in the discussion here:
https://github.com/microsoft/vscode-discussions/discussions/541#discussioncomment-5451218

Some built-in commands such as `workbench.action.tasks.runTask` provide a schema for their args, which enables auto-completion when creating a keybinding to invoke that command.

https://github.com/microsoft/vscode/blob/0d5e948d863153807cfe07ecd20dc10374eea6d2/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts#L421-L446

However, extensions do not have a convenient way to do the same. One current workaround is to contribute an additional schema, but this is not terribly convenient.

<details>
<summary>package.json</summary>

```
"contributes": {
  "jsonValidation": [
    {
      "fileMatch": "%APP_SETTINGS_HOME%/keybindings.json",
      "url": "./src/commands.schema.jsonc"
    },
    {
      "fileMatch": "%APP_SETTINGS_HOME%/profiles/*/keybindings.json",
      "url": "./src/commands.schema.jsonc"
    }
  ],
}
```
</details>

<details>
<summary>custom.schema.json</summary>

```
{
  "$schema": "http://json-schema.org/draft-07/schema",
  "type": "array",
  "items": {
    "type": "object",
    "if": {
      "required": [ "command" ],
      "properties": { "command": { "const": "akbyrd.task.runWithArgs" } }
    },
    "then": {
      "required": [ "args" ],
      "properties": {
        "args": {
          "type": [ "string", "object" ]
        }
      },
      "if": {
        "properties": { "args": { "type": "object" } }
      },
      "then": {
        "properties": {
          "args": {
            "required": [ "task" ],
            "properties": {
              "task": {
                "description": "The standard arguments to workbench.action.tasks.runTask",
                "type": [ "string", "object" ]
              },
              "taskArgs": {
                "description": "An object filled task arguments. Keys are argument names and values are argument values.",
                "type": "object",
                "patternProperties": {
                  ".*": { "not": { "type": [ "object", "array" ] } }
                }
              }
            },
            "defaultSnippets": [
              { "bodyText": "{ \"task\": \"${1:taskName}\", \"taskArgs\": { \"${4:argName}\": \"${5:argValue}\" } }" }
            ],
            "if": {
              "properties": { "task": { "type": "object"} }
            },
            "then": {
              "properties": {
                "task": {
                  "properties": {
                    "task": { "type": "string" },
                    "type": { "type": "string" }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
```
</details>

Additional points worth considering:
* Auto-completion for built-in commands currently does not work in some locations. For example, there is no auto-completion when invoking a command with arguments with a command input variable in tasks.json or launch.json. This likely applies to other places as well, but I'm not sure of all the possible locations a command can be invoked and therefore haven't been able to test them.
* Is it possible to infer the schema from the function that is passed into `registerCommand` or `registerTextEditorCommand`? I don't know if typescript supports introspection, but that could be a nice way to get basic auto-completion for minimal effort on the part of extension authors.