b75b82e676
LaunchOpts.Agent (string) and WorkspaceEntryOptions.Agent (string) are replaced by *agent.Resolved, carrying Command, Args, and Env. The five entry commands (new, resume, last, open, attach) each construct an AgentSpec from the workspace metadata, apply --agent as a one-shot agent.command override (Open Q 1 — keeps muscle memory for users passing executable paths), call agent.Resolve, and pass the result through. resolveEntryAgent centralises the resume/last/open/attach path. shell.ExecAgent and shell.ExecTmuxAgent gain an args parameter; agent.env is merged into the env map at the session.Run launch switch, AFTER ctask's exported CTASK_* vars (per spec §5: agent.env wins on collision). mergeAgentEnv is the centralised merge. Lease, manifest, write lock, heartbeat, summary, and provisional cleanup are unchanged. The Agent string fields on Lease, SessionSummary, and SessionInfo continue to record the launched command for diagnostics.
66 lines
1.9 KiB
Go
66 lines
1.9 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/spf13/cobra"
|
|
"github.com/warrenronsiek/ctask/internal/config"
|
|
"github.com/warrenronsiek/ctask/internal/workspace"
|
|
)
|
|
|
|
var openCmd = &cobra.Command{
|
|
Use: "open <query>",
|
|
Short: "Open a workspace directory without launching the agent",
|
|
Args: cobra.ExactArgs(1),
|
|
SilenceUsage: true,
|
|
RunE: runOpen,
|
|
}
|
|
|
|
var (
|
|
openAll bool
|
|
openForce bool
|
|
openDirect bool
|
|
)
|
|
|
|
func init() {
|
|
openCmd.Flags().BoolVarP(&openAll, "all", "a", false, "Include archived workspaces in query resolution")
|
|
openCmd.Flags().BoolVar(&openForce, "force", false, "Skip active-session and stale-workspace warnings")
|
|
openCmd.Flags().BoolVar(&openDirect, "direct", false, "Bypass persistent session mode for this command")
|
|
openCmd.ValidArgsFunction = completeWorkspaces(completionActive)
|
|
rootCmd.AddCommand(openCmd)
|
|
}
|
|
|
|
func runOpen(cmd *cobra.Command, args []string) error {
|
|
roots := config.SearchRoots()
|
|
// PRESERVED v0.5.2 behavior: open's archive resolution is opt-in via --all.
|
|
// resolveOne(roots, query, includeArchived) — distinct from resume's
|
|
// archived-inclusive-with-restore-hint behavior.
|
|
ws := resolveOne(roots, args[0], openAll)
|
|
|
|
// updated_at bump (existing v0.4 behavior).
|
|
now := time.Now().UTC().Truncate(time.Second)
|
|
ws.Meta.UpdatedAt = now
|
|
metaPath := filepath.Join(ws.Path, "task.yaml")
|
|
if err := workspace.WriteMetaLocked(metaPath, ws.Meta); err != nil {
|
|
return fmt.Errorf("updating metadata: %w", err)
|
|
}
|
|
|
|
resolved, err := resolveEntryAgent(ws.Meta.Agent, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return runWorkspaceEntry(WorkspaceEntryOptions{
|
|
WsPath: ws.Path,
|
|
WsRoot: ws.Root,
|
|
WsMeta: ws.Meta,
|
|
ResolvedAgent: resolved,
|
|
Shell: true, // open always launches a shell
|
|
Force: openForce,
|
|
Direct: openDirect,
|
|
CommandName: "open",
|
|
})
|
|
}
|