env-manager: ui polish (#127)

* env-manager: migrate to pico 2.0.6

* env: option to hide children from ui

* introduce template hierarchy

* style: improve menu styling

* env: reorganize tasks, pull before install

---------

Co-authored-by: Giorgi Lekveishvili <lekva@gl-mbp-m1-max.local>
diff --git a/core/installer/tasks/infra.go b/core/installer/tasks/infra.go
index 0216f84..0685a6d 100644
--- a/core/installer/tasks/infra.go
+++ b/core/installer/tasks/infra.go
@@ -13,8 +13,8 @@
 
 var initGroups = []string{"admin"}
 
-func SetupInfra(env Env, startIP net.IP, st *state) []Task {
-	t := newLeafTask("Create client", func() error {
+func CreateRepoClient(env Env, st *state) Task {
+	t := newLeafTask("Create repo client", func() error {
 		repo, err := st.ssClient.GetRepo("config")
 		if err != nil {
 			return err
@@ -30,25 +30,25 @@
 		st.emptySuffixGen = installer.NewEmptySuffixGenerator()
 		return nil
 	})
-	return []Task{
-		CommitEnvironmentConfiguration(env, st),
-		ConfigureFirstAccount(env, st),
-		&t,
-		newConcurrentParentTask(
-			"Core services",
-			SetupNetwork(env, startIP, st),
-			SetupCertificateIssuers(env, st),
-			SetupAuth(env, st),
-			SetupGroupMemberships(env, st),
-			SetupHeadscale(env, startIP, st),
-			SetupWelcome(env, st),
-			SetupAppStore(env, st),
-		),
-	}
+	return &t
+}
+
+func SetupInfra(env Env, startIP net.IP, st *state) Task {
+	return newConcurrentParentTask(
+		"Setup core services",
+		true,
+		SetupNetwork(env, startIP, st),
+		SetupCertificateIssuers(env, st),
+		SetupAuth(env, st),
+		SetupGroupMemberships(env, st),
+		SetupHeadscale(env, startIP, st),
+		SetupWelcome(env, st),
+		SetupAppStore(env, st),
+	)
 }
 
 func CommitEnvironmentConfiguration(env Env, st *state) Task {
-	t := newLeafTask("Configure environment infrastructure", func() error {
+	t := newLeafTask("commit config", func() error {
 		repo, err := st.ssClient.GetRepo("config")
 		if err != nil {
 			return err
@@ -129,7 +129,7 @@
 }
 
 func SetupNetwork(env Env, startIP net.IP, st *state) Task {
-	t := newLeafTask("Setup network", func() error {
+	t := newLeafTask("Setup private and public networks", func() error {
 		startAddr, err := netip.ParseAddr(startIP.String())
 		if err != nil {
 			return err
@@ -232,7 +232,7 @@
 		}
 		return nil
 	})
-	return newSequentialParentTask("Configure TLS certificate issuers", &pub, &priv)
+	return newSequentialParentTask("Configure TLS certificate issuers", false, &pub, &priv)
 }
 
 func SetupAuth(env Env, st *state) Task {
@@ -250,6 +250,7 @@
 	})
 	return newSequentialParentTask(
 		"Authentication services",
+		false,
 		&t,
 		waitForAddr(fmt.Sprintf("https://accounts-ui.%s", env.Domain)),
 	)
@@ -269,7 +270,8 @@
 		return nil
 	})
 	return newSequentialParentTask(
-		"Group Membership",
+		"Group membership",
+		false,
 		&t,
 		waitForAddr(fmt.Sprintf("https://memberships.p.%s", env.Domain)),
 	)
@@ -290,7 +292,8 @@
 		return nil
 	})
 	return newSequentialParentTask(
-		"Headscale service",
+		"Setup mesh VPN",
+		false,
 		&t,
 		waitForAddr(fmt.Sprintf("https://headscale.%s/apple", env.Domain)),
 	)
@@ -323,6 +326,7 @@
 	})
 	return newSequentialParentTask(
 		"Welcome service",
+		false,
 		&t,
 		waitForAddr(fmt.Sprintf("https://welcome.%s", env.Domain)),
 	)