MCPcopy Create free account
hub / github.com/diillson/chatcli / InitSessionWorkspace

Function InitSessionWorkspace

cli/agent/session_workspace.go:100–191  ·  view source on GitHub ↗

InitSessionWorkspace creates the per-session workspace and registers its subdirs with the engine + read validators. Idempotent: calling it twice returns the existing workspace. The returned workspace should have Cleanup() called at CLI shutdown.

(logger *zap.Logger)

Source from the content-addressed store, hash-verified

98//
99// The returned workspace should have Cleanup() called at CLI shutdown.
100func InitSessionWorkspace(logger *zap.Logger) (*SessionWorkspace, error) {
101 sessionWorkspaceMu.Lock()
102 defer sessionWorkspaceMu.Unlock()
103
104 if sessionWorkspace != nil {
105 return sessionWorkspace, nil
106 }
107
108 root, err := os.MkdirTemp("", "chatcli-agent-")
109 if err != nil {
110 return nil, fmt.Errorf("creating session tmpdir: %w", err)
111 }
112
113 scratch := filepath.Join(root, "scratch")
114 if err := os.MkdirAll(scratch, 0o700); err != nil {
115 _ = os.RemoveAll(root)
116 return nil, fmt.Errorf("creating scratch dir: %w", err)
117 }
118
119 toolResults := filepath.Join(root, "tool-results")
120 if err := os.MkdirAll(toolResults, 0o700); err != nil {
121 _ = os.RemoveAll(root)
122 return nil, fmt.Errorf("creating tool-results dir: %w", err)
123 }
124
125 keep := strings.EqualFold(os.Getenv("CHATCLI_AGENT_KEEP_TMPDIR"), "true")
126
127 ws := &SessionWorkspace{
128 Root: root,
129 ScratchDir: scratch,
130 ToolResultsDir: toolResults,
131 keep: keep,
132 logger: logger,
133 }
134
135 // Export env var so child processes (run_command, exec) can use it.
136 _ = os.Setenv("CHATCLI_AGENT_TMPDIR", scratch)
137
138 // Register with read validator (agent package).
139 RegisterAuxReadPath(root)
140
141 // Register with engine write/exec validator.
142 engine.RegisterAuxPath(root)
143
144 // System temp directories are allowlisted by default. Every major
145 // model defaults to writing throwaway scripts under /tmp ("cat >
146 // /tmp/check.sh && bash /tmp/check.sh"); blocking that forces the
147 // model to guess a safe path and usually fails. The risk is low —
148 // these dirs are user-owned on single-user machines. Users who
149 // need strict sandboxing can set CHATCLI_BLOCK_TMP_WRITES=true.
150 if !strings.EqualFold(os.Getenv("CHATCLI_BLOCK_TMP_WRITES"), "true") {
151 tmpPaths := []string{os.TempDir()}
152 // On macOS os.TempDir() returns a per-user /var/folders/... path,
153 // but models emit /tmp verbatim. On Linux they're the same. Add
154 // /tmp explicitly when it exists and differs.
155 if _, err := os.Stat("/tmp"); err == nil {
156 tmpPaths = append(tmpPaths, "/tmp")
157 }

Calls 9

RegisterAuxPathFunction · 0.92
RegisterAuxReadPathFunction · 0.85
SetBudgetResultDirFunction · 0.85
fireResultDirSettersFunction · 0.85
LockMethod · 0.80
UnlockMethod · 0.80
ErrorfMethod · 0.80
InfoMethod · 0.65
StringMethod · 0.45