@@ -4,11 +4,9 @@ import (
44 _ "embed"
55 "encoding/json"
66 "fmt"
7- "io/fs"
87 "net"
98 "os"
109 "path/filepath"
11- "runtime"
1210 "strings"
1311
1412 "csgclaw/internal/config"
@@ -22,24 +20,6 @@ var defaultManagerPicoClawConfig []byte
2220//go:embed defaults/manager-security.yml
2321var defaultManagerSecurityConfig string
2422
25- var managerSkillSourceDirResolver = bundledManagerSkillSourceDir
26-
27- const managerMemoryContents = `# Manager Memory
28-
29- When an admin asks you to arrange or reuse workers such as ux, dev, and qa:
30-
31- - Do not do the implementation work yourself.
32- - Do not use message for status chatter or request restatement.
33- - Use the bundled manager-worker-dispatch workflow directly from ~/.picoclaw/workspace/skills/manager-worker-dispatch.
34- - Fast path:
35- 1. python scripts/manager_worker_api.py list-workers
36- 2. join the chosen workers to the room
37- 3. write todo.json under ~/.picoclaw/workspace/projects/<slug>/
38- 4. python scripts/manager_worker_api.py start-tracking --room-id <room> --todo-path <todo.json>
39- - Only open SKILL.md if the workflow must change or a required command is unclear.
40- - After tracking starts, send one concise assignment summary.
41- `
42-
4323func ensureManagerPicoClawConfig (server config.ServerConfig , model config.ModelConfig ) (string , error ) {
4424 return ensureAgentPicoClawConfig (ManagerName , "u-manager" , server , model )
4525}
@@ -52,9 +32,6 @@ func ensureAgentPicoClawConfig(agentName, botID string, server config.ServerConf
5232 if err := os .MkdirAll (filepath .Join (hostRoot , hostPicoClawLogs ), 0o755 ); err != nil {
5333 return "" , fmt .Errorf ("create manager picoclaw logs dir: %w" , err )
5434 }
55- if err := ensureAgentWorkspace (hostRoot , agentName ); err != nil {
56- return "" , err
57- }
5835
5936 data , err := renderAgentPicoClawConfig (botID , server , model )
6037 if err != nil {
@@ -247,118 +224,3 @@ func renderManagerSecurityConfig(server config.ServerConfig, model config.ModelC
247224 }
248225 return content
249226}
250-
251- func ensureAgentWorkspace (hostRoot , agentName string ) error {
252- workspaceRoot := filepath .Join (hostRoot , "workspace" )
253- for _ , dir := range []string {
254- filepath .Join (workspaceRoot , "memory" ),
255- filepath .Join (workspaceRoot , "projects" ),
256- filepath .Join (workspaceRoot , "sessions" ),
257- filepath .Join (workspaceRoot , "state" ),
258- filepath .Join (workspaceRoot , "skills" ),
259- } {
260- if err := os .MkdirAll (dir , 0o755 ); err != nil {
261- return fmt .Errorf ("create agent workspace dir %q: %w" , dir , err )
262- }
263- }
264- if ! strings .EqualFold (strings .TrimSpace (agentName ), ManagerName ) {
265- return nil
266- }
267-
268- dstRoot := filepath .Join (workspaceRoot , "skills" , "manager-worker-dispatch" )
269- srcRoot , err := managerSkillSourceDirResolver ()
270- if err != nil {
271- return fmt .Errorf ("resolve bundled manager skill: %w" , err )
272- }
273- if err := copyDirTree (srcRoot , dstRoot ); err != nil {
274- return fmt .Errorf ("seed bundled manager skill: %w" , err )
275- }
276- memoryPath := filepath .Join (workspaceRoot , "memory" , "MEMORY.md" )
277- if err := os .WriteFile (memoryPath , []byte (managerMemoryContents ), 0o644 ); err != nil {
278- return fmt .Errorf ("write manager memory: %w" , err )
279- }
280- return nil
281- }
282-
283- func bundledManagerSkillSourceDir () (string , error ) {
284- candidates := make ([]string , 0 , 4 )
285- if wd , err := os .Getwd (); err == nil {
286- candidates = append (candidates , wd )
287- }
288- if exe , err := os .Executable (); err == nil {
289- candidates = append (candidates , filepath .Dir (exe ), filepath .Dir (filepath .Dir (exe )))
290- }
291- if _ , file , _ , ok := runtime .Caller (0 ); ok {
292- candidates = append (candidates , filepath .Dir (file ), filepath .Dir (filepath .Dir (filepath .Dir (file ))))
293- }
294-
295- for _ , base := range candidates {
296- if found := findManagerSkillUnder (base ); found != "" {
297- return found , nil
298- }
299- }
300- return "" , os .ErrNotExist
301- }
302-
303- func findManagerSkillUnder (base string ) string {
304- base = strings .TrimSpace (base )
305- if base == "" {
306- return ""
307- }
308- for current := base ; ; current = filepath .Dir (current ) {
309- candidate := filepath .Join (current , "skills" , "manager-worker-dispatch" )
310- if info , err := os .Stat (filepath .Join (candidate , "SKILL.md" )); err == nil && ! info .IsDir () {
311- return candidate
312- }
313- parent := filepath .Dir (current )
314- if parent == current {
315- return ""
316- }
317- }
318- }
319-
320- func copyDirTree (srcRoot , dstRoot string ) error {
321- srcRoot = filepath .Clean (srcRoot )
322- dstRoot = filepath .Clean (dstRoot )
323- if err := os .RemoveAll (dstRoot ); err != nil {
324- return err
325- }
326-
327- return filepath .WalkDir (srcRoot , func (path string , d fs.DirEntry , walkErr error ) error {
328- if walkErr != nil {
329- return walkErr
330- }
331- rel , err := filepath .Rel (srcRoot , path )
332- if err != nil {
333- return err
334- }
335- target := dstRoot
336- if rel != "." {
337- target = filepath .Join (dstRoot , rel )
338- }
339-
340- info , err := d .Info ()
341- if err != nil {
342- return err
343- }
344- if d .IsDir () {
345- return os .MkdirAll (target , info .Mode ().Perm ())
346- }
347-
348- data , err := os .ReadFile (path )
349- if err != nil {
350- return err
351- }
352- if err := os .MkdirAll (filepath .Dir (target ), 0o755 ); err != nil {
353- return err
354- }
355- mode := info .Mode ().Perm ()
356- if mode == 0 {
357- mode = 0o644
358- }
359- if err := os .WriteFile (target , data , mode ); err != nil {
360- return err
361- }
362- return nil
363- })
364- }
0 commit comments