pkg/tool: use $id instead of kind to identify task types

This clears the way for task definitions to own the full
space of "normal" names (not starting with a $). This
in turn is useful for defining flag and env variable task.

Change-Id: Ibb94746e58b8b4182d767199969bf87c469183a8
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/4381
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/custom.go b/cmd/cue/cmd/custom.go
index 7ac1b95..a8d5f82 100644
--- a/cmd/cue/cmd/custom.go
+++ b/cmd/cue/cmd/custom.go
@@ -357,11 +357,14 @@
 }
 
 func newTask(index int, name string, v cue.Value) (*task, error) {
-	// Lookup kind for backwards compatibility.
-	// TODO: consider at some point whether kind can be removed.
-	kind, err := v.Lookup("kind").String()
+	kind, err := v.Lookup("$id").String()
 	if err != nil {
-		return nil, err
+		// Lookup kind for backwards compatibility.
+		// TODO: consider at some point whether kind can be removed.
+		kind, err = v.Lookup("kind").String()
+		if err != nil {
+			return nil, err
+		}
 	}
 	if k, ok := legacyKinds[kind]; ok {
 		kind = k
diff --git a/cue/builtins.go b/cue/builtins.go
index 5c2a585..7c5dd8f 100644
--- a/cue/builtins.go
+++ b/cue/builtins.go
@@ -3484,7 +3484,8 @@
 		$long?:  string
 	}
 	Task: {
-		kind: =~"\\."
+		$type: "tool.Task"
+		$id:   =~"\\."
 	}
 }`,
 	},
@@ -3492,7 +3493,7 @@
 		native: []*builtin{{}},
 		cue: `{
 	Print: {
-		kind: *"tool/cli.Print" | "print"
+		$id:  *"tool/cli.Print" | "print"
 		text: string
 	}
 }`,
@@ -3501,11 +3502,11 @@
 		native: []*builtin{{}},
 		cue: `{
 	Run: {
-		kind:     *"tool/exec.Run" | "exec"
+		$id:      *"tool/exec.Run" | "exec"
 		cmd:      string | [string, ...string]
 		install?: string | [string, ...string]
 		env: {
-			[Key=string]: string
+			[string]: string
 		}
 		stdout:  *null | string | bytes
 		stderr:  *null | string | bytes
@@ -3518,24 +3519,24 @@
 		native: []*builtin{{}},
 		cue: `{
 	Read: {
-		kind:     "tool/file.Read"
+		$id:      "tool/file.Read"
 		filename: !=""
 		contents: *bytes | string
 	}
 	Create: {
-		kind:        "tool/file.Create"
+		$id:         "tool/file.Create"
 		filename:    !=""
 		contents:    bytes | string
 		permissions: int | *420
 	}
 	Append: {
-		kind:        "tool/file.Append"
+		$id:         "tool/file.Append"
 		filename:    !=""
 		contents:    bytes | string
 		permissions: int | *420
 	}
 	Glob: {
-		kind: "tool/file.Glob"
+		$id:  "tool/file.Glob"
 		glob: !=""
 		files: [...string]
 	}
@@ -3548,7 +3549,7 @@
 		method: "GET"
 	}
 	Do: {
-		kind:   *"tool/http.Do" | "http"
+		$id:    *"tool/http.Do" | "http"
 		method: string
 		response: {
 			body: *bytes | string
diff --git a/doc/tutorial/kubernetes/testdata/manual.out b/doc/tutorial/kubernetes/testdata/manual.out
index 7f4563d..8eaae10 100644
--- a/doc/tutorial/kubernetes/testdata/manual.out
+++ b/doc/tutorial/kubernetes/testdata/manual.out
@@ -248,7 +248,6 @@
 deployment: {
     bartender: {
         name: "bartender"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -268,6 +267,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/bartender:v0.1.34"
         expose: {
@@ -447,7 +447,6 @@
 deployment: {
     breaddispatcher: {
         name: "breaddispatcher"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -467,6 +466,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/breaddispatcher:v0.3.24"
         expose: {
@@ -648,7 +648,6 @@
 deployment: {
     host: {
         name: "host"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -668,6 +667,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 2
         image:    "gcr.io/myproj/host:v0.1.10"
         expose: {
@@ -847,7 +847,6 @@
 deployment: {
     maitred: {
         name: "maitred"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -867,6 +866,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/maitred:v0.0.4"
         expose: {
@@ -1046,7 +1046,6 @@
 deployment: {
     valeter: {
         name: "valeter"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -1066,6 +1065,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/valeter:v0.0.4"
         expose: {
@@ -1247,7 +1247,6 @@
 deployment: {
     waiter: {
         name: "waiter"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -1267,6 +1266,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 5
         image:    "gcr.io/myproj/waiter:v0.3.0"
         expose: {
@@ -1446,7 +1446,6 @@
 deployment: {
     waterdispatcher: {
         name: "waterdispatcher"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -1466,6 +1465,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/waterdispatcher:v0.0.48"
         expose: {
@@ -1725,7 +1725,6 @@
 deployment: {
     download: {
         name: "download"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -1735,6 +1734,7 @@
         }
         kubernetes: {
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/download:v0.0.2"
         expose: {
@@ -1987,7 +1987,6 @@
 deployment: {
     etcd: {
         name: "etcd"
-        kind: "stateful"
         env: {
             ETCDCTL_API:                    "3"
             ETCD_AUTO_COMPACTION_RETENTION: "4"
@@ -2057,6 +2056,7 @@
                 serviceName: "etcd"
             }
         }
+        kind:     "stateful"
         replicas: 3
         image:    "quay.io/coreos/etcd:v3.3.10"
         expose: {
@@ -2299,7 +2299,6 @@
 deployment: {
     events: {
         name: "events"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -2335,6 +2334,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 2
         image:    "gcr.io/myproj/events:v0.1.31"
         expose: {
@@ -2547,7 +2547,6 @@
 deployment: {
     tasks: {
         name: "tasks"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -2567,6 +2566,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/tasks:v0.2.6"
         expose: {
@@ -2771,7 +2771,6 @@
 deployment: {
     updater: {
         name: "updater"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -2781,6 +2780,7 @@
         }
         kubernetes: {
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/updater:v0.1.0"
         expose: {
@@ -2984,7 +2984,6 @@
 deployment: {
     watcher: {
         name: "watcher"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -2994,6 +2993,7 @@
         }
         kubernetes: {
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/watcher:v0.1.0"
         expose: {
@@ -3343,7 +3343,6 @@
 deployment: {
     caller: {
         name: "caller"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -3374,6 +3373,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 3
         image:    "gcr.io/myproj/caller:v0.20.14"
         expose: {
@@ -3664,7 +3664,6 @@
 deployment: {
     dishwasher: {
         name: "dishwasher"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -3695,6 +3694,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 5
         image:    "gcr.io/myproj/dishwasher:v0.2.13"
         expose: {
@@ -3973,7 +3973,6 @@
 deployment: {
     expiditer: {
         name: "expiditer"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -4004,6 +4003,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/expiditer:v0.5.34"
         expose: {
@@ -4269,7 +4269,6 @@
 deployment: {
     headchef: {
         name: "headchef"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -4300,6 +4299,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/headchef:v0.2.16"
         expose: {
@@ -4564,7 +4564,6 @@
 deployment: {
     linecook: {
         name: "linecook"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -4595,6 +4594,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/linecook:v0.1.42"
         expose: {
@@ -4863,7 +4863,6 @@
 deployment: {
     pastrychef: {
         name: "pastrychef"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -4894,6 +4893,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/pastrychef:v0.1.15"
         expose: {
@@ -5143,7 +5143,6 @@
 deployment: {
     souschef: {
         name: "souschef"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -5174,6 +5173,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/souschef:v0.5.3"
         expose: {
@@ -5517,7 +5517,6 @@
 deployment: {
     alertmanager: {
         name: "alertmanager"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -5534,6 +5533,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "prom/alertmanager:v0.15.2"
         expose: {
@@ -5792,7 +5792,6 @@
 deployment: {
     grafana: {
         name: "grafana"
-        kind: "deployment"
         env: {
             GF_AUTH_BASIC_ENABLED:      "false"
             GF_AUTH_ANONYMOUS_ENABLED:  "true"
@@ -5823,6 +5822,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "grafana/grafana:4.5.2"
         expose: {
@@ -6059,7 +6059,6 @@
 deployment: {
     "node-exporter": {
         name: "node-exporter"
-        kind: "daemon"
         env: {
         }
         label: {
@@ -6092,6 +6091,7 @@
                 }
             }
         }
+        kind:     "daemon"
         replicas: 1
         image:    "quay.io/prometheus/node-exporter:v0.16.0"
         expose: {
@@ -6573,7 +6573,6 @@
 deployment: {
     prometheus: {
         name: "prometheus"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -6604,6 +6603,7 @@
                 }
             }
         }
+        kind:     "deployment"
         replicas: 1
         image:    "prom/prometheus:v2.4.3"
         expose: {
@@ -7188,7 +7188,6 @@
 deployment: {
     authproxy: {
         name: "authproxy"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -7198,6 +7197,7 @@
         }
         kubernetes: {
         }
+        kind:     "deployment"
         replicas: 1
         image:    "skippy/oauth2_proxy:2.0.1"
         expose: {
@@ -7457,7 +7457,6 @@
 deployment: {
     goget: {
         name: "goget"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -7467,6 +7466,7 @@
         }
         kubernetes: {
         }
+        kind:     "deployment"
         replicas: 1
         image:    "gcr.io/myproj/goget:v0.5.1"
         expose: {
@@ -7897,7 +7897,6 @@
 deployment: {
     nginx: {
         name: "nginx"
-        kind: "deployment"
         env: {
         }
         label: {
@@ -7907,6 +7906,7 @@
         }
         kubernetes: {
         }
+        kind:     "deployment"
         replicas: 1
         image:    "nginx:1.11.10-alpine"
         expose: {
diff --git a/pkg/tool/cli/cli.cue b/pkg/tool/cli/cli.cue
index 0318ff0..6f581f3 100644
--- a/pkg/tool/cli/cli.cue
+++ b/pkg/tool/cli/cli.cue
@@ -16,7 +16,7 @@
 
 // Print sends text to the stdout of the current process.
 Print: {
-	kind: *"tool/cli.Print" | "print" // for backwards compatibility
+	$id: *"tool/cli.Print" | "print" // for backwards compatibility
 
 	// text is the text to be printed.
 	text: string
@@ -26,7 +26,7 @@
 // Ask prompts the current console with a message and waits for input.
 //
 // Example:
-//     task ask: cli.Ask({
+//     task: ask: cli.Ask({
 //         prompt:   "Are you okay?"
 //         repsonse: bool
 //     })
diff --git a/pkg/tool/cli/doc.go b/pkg/tool/cli/doc.go
index 27dee9a..e65ebcf 100644
--- a/pkg/tool/cli/doc.go
+++ b/pkg/tool/cli/doc.go
@@ -6,7 +6,7 @@
 //
 //     // Print sends text to the stdout of the current process.
 //     Print: {
-//     	kind: *"tool/cli.Print" | "print" // for backwards compatibility
+//     	$id: *"tool/cli.Print" | "print" // for backwards compatibility
 //
 //     	// text is the text to be printed.
 //     	text: string
@@ -16,7 +16,7 @@
 //     // Ask prompts the current console with a message and waits for input.
 //     //
 //     // Example:
-//     //     task ask: cli.Ask({
+//     //     task: ask: cli.Ask({
 //     //         prompt:   "Are you okay?"
 //     //         repsonse: bool
 //     //     })
diff --git a/pkg/tool/doc.go b/pkg/tool/doc.go
index 32ea0db..a220c93 100644
--- a/pkg/tool/doc.go
+++ b/pkg/tool/doc.go
@@ -52,14 +52,15 @@
 //     	// tasks specifies the list of things to do to run command. Tasks are
 //     	// typically underspecified and completed by the particular internal
 //     	// handler that is running them. Task de
-//     	tasks <name>: Task
+//     	tasks: [name=string]: Task
 //     }
 //
 //     // A Task defines a step in the execution of a command.
 //     Task: {
 //     	// kind indicates the operation to run. It must be of the form
 //     	// packagePath.Operation.
-//     	kind: =~#"\."#
+//     	$id:   =~#"\."#
+//     	$type: "tool.Task" // legacy field 'kind' still supported for now.
 //     }
 //
 package tool
diff --git a/pkg/tool/exec/doc.go b/pkg/tool/exec/doc.go
index 43087a3..484c361 100644
--- a/pkg/tool/exec/doc.go
+++ b/pkg/tool/exec/doc.go
@@ -6,7 +6,7 @@
 //
 //     // Run executes the given shell command.
 //     Run: {
-//     	kind: *"tool/exec.Run" | "exec" // exec for backwards compatibility
+//     	$id: *"tool/exec.Run" | "exec" // exec for backwards compatibility
 //
 //     	// cmd is the command to run.
 //     	cmd: string | [string, ...string]
@@ -16,7 +16,7 @@
 //     	install?: string | [string, ...string]
 //
 //     	// env defines the environment variables to use for this system.
-//     	env <Key>: string
+//     	env: [string]: string
 //
 //     	// stdout captures the output from stdout if it is of type bytes or string.
 //     	// The default value of null indicates it is redirected to the stdout of the
diff --git a/pkg/tool/exec/exec.cue b/pkg/tool/exec/exec.cue
index ede6634..7ab429a 100644
--- a/pkg/tool/exec/exec.cue
+++ b/pkg/tool/exec/exec.cue
@@ -16,7 +16,7 @@
 
 // Run executes the given shell command.
 Run: {
-	kind: *"tool/exec.Run" | "exec" // exec for backwards compatibility
+	$id: *"tool/exec.Run" | "exec" // exec for backwards compatibility
 
 	// cmd is the command to run.
 	cmd: string | [string, ...string]
@@ -26,7 +26,7 @@
 	install?: string | [string, ...string]
 
 	// env defines the environment variables to use for this system.
-	env <Key>: string
+	env: [string]: string
 
 	// stdout captures the output from stdout if it is of type bytes or string.
 	// The default value of null indicates it is redirected to the stdout of the
diff --git a/pkg/tool/file/doc.go b/pkg/tool/file/doc.go
index 6a86439..1bb0c1c 100644
--- a/pkg/tool/file/doc.go
+++ b/pkg/tool/file/doc.go
@@ -6,7 +6,7 @@
 //
 //     // Read reads the contents of a file.
 //     Read: {
-//     	kind: "tool/file.Read"
+//     	$id: "tool/file.Read"
 //
 //     	// filename names the file to read.
 //     	//
@@ -22,7 +22,7 @@
 //
 //     // Append writes contents to the given file.
 //     Append: {
-//     	kind: "tool/file.Append"
+//     	$id: "tool/file.Append"
 //
 //     	// filename names the file to append.
 //     	//
@@ -39,7 +39,7 @@
 //
 //     // Create writes contents to the given file.
 //     Create: {
-//     	kind: "tool/file.Create"
+//     	$id: "tool/file.Create"
 //
 //     	// filename names the file to write.
 //     	//
@@ -56,7 +56,7 @@
 //
 //     // Glob returns a list of files.
 //     Glob: {
-//     	kind: "tool/file.Glob"
+//     	$id: "tool/file.Glob"
 //
 //     	// glob specifies the pattern to match files with.
 //     	//
diff --git a/pkg/tool/file/file.cue b/pkg/tool/file/file.cue
index 23fe7f6..8c1767d 100644
--- a/pkg/tool/file/file.cue
+++ b/pkg/tool/file/file.cue
@@ -16,7 +16,7 @@
 
 // Read reads the contents of a file.
 Read: {
-	kind: "tool/file.Read"
+	$id: "tool/file.Read"
 
 	// filename names the file to read.
 	//
@@ -32,7 +32,7 @@
 
 // Append writes contents to the given file.
 Append: {
-	kind: "tool/file.Append"
+	$id: "tool/file.Append"
 
 	// filename names the file to append.
 	//
@@ -49,7 +49,7 @@
 
 // Create writes contents to the given file.
 Create: {
-	kind: "tool/file.Create"
+	$id: "tool/file.Create"
 
 	// filename names the file to write.
 	//
@@ -66,7 +66,7 @@
 
 // Glob returns a list of files.
 Glob: {
-	kind: "tool/file.Glob"
+	$id: "tool/file.Glob"
 
 	// glob specifies the pattern to match files with.
 	//
diff --git a/pkg/tool/http/doc.go b/pkg/tool/http/doc.go
index 2aa2260..01c33b3 100644
--- a/pkg/tool/http/doc.go
+++ b/pkg/tool/http/doc.go
@@ -10,7 +10,7 @@
 //     Delete: Do & {method: "DELETE"}
 //
 //     Do: {
-//     	kind: *"tool/http.Do" | "http" // http for backwards compatibility
+//     	$id: *"tool/http.Do" | "http" // http for backwards compatibility
 //
 //     	method: string
 //     	url:    string // TODO: make url.URL type
@@ -37,7 +37,7 @@
 //     //  cert: string
 //     //  key:  string
 //     //
-//     //  handle <Pattern>: Message & {
+//     //  handle: [Pattern=string]: Message & {
 //     //   pattern: Pattern
 //     //  }
 //     // }
diff --git a/pkg/tool/http/http.cue b/pkg/tool/http/http.cue
index f8a3a60..0ab1dd5 100644
--- a/pkg/tool/http/http.cue
+++ b/pkg/tool/http/http.cue
@@ -20,7 +20,7 @@
 Delete: Do & {method: "DELETE"}
 
 Do: {
-	kind: *"tool/http.Do" | "http" // http for backwards compatibility
+	$id: *"tool/http.Do" | "http" // http for backwards compatibility
 
 	method: string
 	url:    string // TODO: make url.URL type
@@ -47,7 +47,7 @@
 //  cert: string
 //  key:  string
 //
-//  handle <Pattern>: Message & {
+//  handle: [Pattern=string]: Message & {
 //   pattern: Pattern
 //  }
 // }
diff --git a/pkg/tool/tool.cue b/pkg/tool/tool.cue
index ba61cbb..298b233 100644
--- a/pkg/tool/tool.cue
+++ b/pkg/tool/tool.cue
@@ -47,12 +47,13 @@
 	// tasks specifies the list of things to do to run command. Tasks are
 	// typically underspecified and completed by the particular internal
 	// handler that is running them. Task de
-	tasks <name>: Task
+	tasks: [name=string]: Task
 }
 
 // A Task defines a step in the execution of a command.
 Task: {
 	// kind indicates the operation to run. It must be of the form
 	// packagePath.Operation.
-	kind: =~#"\."#
+	$id:   =~#"\."#
+	$type: "tool.Task" // legacy field 'kind' still supported for now.
 }