Deprecate hook files, use pinned beads for propulsion (gt-rgd9x)
Replace hook file mechanism with discovery-based pinned beads: - gt hook: now runs bd update <bead> --status=pinned - gt sling: same, plus nudge to target - gt handoff: same when bead ID provided - gt prime: checks pinned beads instead of hook files - gt mol status: no longer checks hook files Key changes: - outputAttachmentStatus: extended to all roles (was Crew/Polecat only) - checkSlungWork: now queries pinned beads instead of reading hook files - wisp/io.go functions: marked deprecated with migration notes This follows Gas Town discovery over explicit state principle. Hook files are kept for backward compatibility but no longer written. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/steveyegge/gastown/internal/style"
|
||||
"github.com/steveyegge/gastown/internal/tmux"
|
||||
"github.com/steveyegge/gastown/internal/wisp"
|
||||
"github.com/steveyegge/gastown/internal/workspace"
|
||||
)
|
||||
|
||||
@@ -504,29 +503,26 @@ func hookBeadForHandoff(beadID string) error {
|
||||
return fmt.Errorf("bead '%s' not found", beadID)
|
||||
}
|
||||
|
||||
// Determine agent identity and clone root
|
||||
agentID, _, cloneRoot, err := resolveSelfTarget()
|
||||
// Determine agent identity
|
||||
agentID, _, _, err := resolveSelfTarget()
|
||||
if err != nil {
|
||||
return fmt.Errorf("detecting agent identity: %w", err)
|
||||
}
|
||||
|
||||
// Create the slung work wisp
|
||||
sw := wisp.NewSlungWork(beadID, agentID)
|
||||
sw.Subject = handoffSubject
|
||||
sw.Context = handoffMessage
|
||||
|
||||
fmt.Printf("%s Hooking %s...\n", style.Bold.Render("🪝"), beadID)
|
||||
|
||||
if handoffDryRun {
|
||||
fmt.Printf("Would create wisp: %s\n", wisp.HookPath(cloneRoot, agentID))
|
||||
fmt.Printf("Would run: bd update %s --status=pinned --assignee=%s\n", beadID, agentID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write the wisp to the hook
|
||||
if err := wisp.WriteSlungWork(cloneRoot, agentID, sw); err != nil {
|
||||
return fmt.Errorf("writing wisp: %w", err)
|
||||
// Pin the bead using bd update (discovery-based approach)
|
||||
pinCmd := exec.Command("bd", "update", beadID, "--status=pinned", "--assignee="+agentID)
|
||||
pinCmd.Stderr = os.Stderr
|
||||
if err := pinCmd.Run(); err != nil {
|
||||
return fmt.Errorf("pinning bead: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("%s Work attached to hook\n", style.Bold.Render("✓"))
|
||||
fmt.Printf("%s Work attached to hook (pinned bead)\n", style.Bold.Render("✓"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/steveyegge/gastown/internal/style"
|
||||
"github.com/steveyegge/gastown/internal/wisp"
|
||||
)
|
||||
|
||||
var hookCmd = &cobra.Command{
|
||||
@@ -64,38 +63,33 @@ func runHook(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Determine agent identity and clone root
|
||||
agentID, _, cloneRoot, err := resolveSelfTarget()
|
||||
// Determine agent identity
|
||||
agentID, _, _, err := resolveSelfTarget()
|
||||
if err != nil {
|
||||
return fmt.Errorf("detecting agent identity: %w", err)
|
||||
}
|
||||
|
||||
// Create the slung work wisp
|
||||
sw := wisp.NewSlungWork(beadID, agentID)
|
||||
sw.Subject = hookSubject
|
||||
sw.Context = hookMessage
|
||||
|
||||
fmt.Printf("%s Hooking %s...\n", style.Bold.Render("🪝"), beadID)
|
||||
|
||||
if hookDryRun {
|
||||
fmt.Printf("Would create wisp: %s\n", wisp.HookPath(cloneRoot, agentID))
|
||||
fmt.Printf(" bead_id: %s\n", beadID)
|
||||
fmt.Printf(" agent: %s\n", agentID)
|
||||
fmt.Printf("Would run: bd update %s --status=pinned --assignee=%s\n", beadID, agentID)
|
||||
if hookSubject != "" {
|
||||
fmt.Printf(" subject: %s\n", hookSubject)
|
||||
fmt.Printf(" subject (for handoff mail): %s\n", hookSubject)
|
||||
}
|
||||
if hookMessage != "" {
|
||||
fmt.Printf(" context: %s\n", hookMessage)
|
||||
fmt.Printf(" context (for handoff mail): %s\n", hookMessage)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write the wisp to the hook
|
||||
if err := wisp.WriteSlungWork(cloneRoot, agentID, sw); err != nil {
|
||||
return fmt.Errorf("writing wisp: %w", err)
|
||||
// Pin the bead using bd update (discovery-based approach)
|
||||
pinCmd := exec.Command("bd", "update", beadID, "--status=pinned", "--assignee="+agentID)
|
||||
pinCmd.Stderr = os.Stderr
|
||||
if err := pinCmd.Run(); err != nil {
|
||||
return fmt.Errorf("pinning bead: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("%s Work attached to hook\n", style.Bold.Render("✓"))
|
||||
fmt.Printf("%s Work attached to hook (pinned bead)\n", style.Bold.Render("✓"))
|
||||
fmt.Printf(" Use 'gt handoff' to restart with this work\n")
|
||||
fmt.Printf(" Use 'gt mol status' to see hook status\n")
|
||||
|
||||
|
||||
@@ -258,16 +258,8 @@ func runMoleculeStatus(cmd *cobra.Command, args []string) error {
|
||||
HasWork: len(pinnedBeads) > 0,
|
||||
}
|
||||
|
||||
// Also check for wisp hook files (from gt hook/sling/handoff)
|
||||
// These are stored at the git clone root, not the beads dir
|
||||
gitRoot, _ := getGitRootForMolStatus()
|
||||
if gitRoot != "" {
|
||||
sw, err := wisp.ReadHook(gitRoot, target)
|
||||
if err == nil && sw != nil {
|
||||
status.SlungWork = sw
|
||||
status.HasWork = true
|
||||
}
|
||||
}
|
||||
// Note: Hook files are deprecated. Work is now tracked via pinned beads only.
|
||||
// The SlungWork field is kept for backward compatibility but will be nil.
|
||||
|
||||
if len(pinnedBeads) > 0 {
|
||||
// Take the first pinned bead (agents typically have one pinned bead)
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
"github.com/steveyegge/gastown/internal/lock"
|
||||
"github.com/steveyegge/gastown/internal/style"
|
||||
"github.com/steveyegge/gastown/internal/templates"
|
||||
"github.com/steveyegge/gastown/internal/wisp"
|
||||
"github.com/steveyegge/gastown/internal/workspace"
|
||||
)
|
||||
|
||||
@@ -533,20 +532,18 @@ func runMailCheckInject(workDir string) {
|
||||
// This is key for the autonomous overnight work pattern.
|
||||
// The Propulsion Principle: "If you find something on your hook, YOU RUN IT."
|
||||
func outputAttachmentStatus(ctx RoleContext) {
|
||||
if ctx.Role != RoleCrew && ctx.Role != RolePolecat {
|
||||
// Skip only unknown roles - all valid roles can have pinned work
|
||||
if ctx.Role == RoleUnknown {
|
||||
return
|
||||
}
|
||||
|
||||
// Check for pinned beads with attachments
|
||||
b := beads.New(ctx.WorkDir)
|
||||
|
||||
// Build assignee string based on role
|
||||
var assignee string
|
||||
switch ctx.Role {
|
||||
case RoleCrew:
|
||||
assignee = fmt.Sprintf("%s/crew/%s", ctx.Rig, ctx.Polecat)
|
||||
case RolePolecat:
|
||||
assignee = fmt.Sprintf("%s/%s", ctx.Rig, ctx.Polecat)
|
||||
// Build assignee string based on role (same as getAgentIdentity)
|
||||
assignee := getAgentIdentity(ctx)
|
||||
if assignee == "" {
|
||||
return
|
||||
}
|
||||
|
||||
// Find pinned beads for this agent
|
||||
@@ -1271,78 +1268,41 @@ func outputRefineryPatrolContext(ctx RoleContext) {
|
||||
}
|
||||
}
|
||||
|
||||
// checkSlungWork checks for slung work on the agent's hook.
|
||||
// checkSlungWork checks for pinned work on the agent's hook.
|
||||
// If found, displays it prominently and tells the agent to execute it.
|
||||
// The wisp is burned after the agent acknowledges it.
|
||||
// Returns true if slung work was found (caller should skip normal startup directive).
|
||||
// Returns true if pinned work was found (caller should skip normal startup directive).
|
||||
func checkSlungWork(ctx RoleContext) bool {
|
||||
// Determine agent identity for hook lookup
|
||||
// Determine agent identity
|
||||
agentID := getAgentIdentity(ctx)
|
||||
if agentID == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// Get the git clone root (hooks are stored at clone root, not cwd)
|
||||
cloneRoot, err := getGitRoot()
|
||||
if err != nil {
|
||||
// Not in a git repo - can't have hooks
|
||||
// Check for pinned beads (the discovery-based hook)
|
||||
b := beads.New(ctx.WorkDir)
|
||||
pinnedBeads, err := b.List(beads.ListOptions{
|
||||
Status: beads.StatusPinned,
|
||||
Assignee: agentID,
|
||||
Priority: -1,
|
||||
})
|
||||
if err != nil || len(pinnedBeads) == 0 {
|
||||
// No pinned beads - no slung work
|
||||
return false
|
||||
}
|
||||
|
||||
sw, err := wisp.ReadHook(cloneRoot, agentID)
|
||||
if err != nil {
|
||||
if errors.Is(err, wisp.ErrNoHook) {
|
||||
// No hook - normal case, nothing to do
|
||||
return false
|
||||
}
|
||||
// Log other errors (permission, corruption) but continue
|
||||
fmt.Printf("%s Warning: error reading hook: %v\n", style.Dim.Render("⚠"), err)
|
||||
return false
|
||||
}
|
||||
|
||||
// Verify bead exists before showing autonomous mode
|
||||
// Try multiple beads locations: cwd, clone root, and rig's beads dir
|
||||
var stdout bytes.Buffer
|
||||
beadExists := false
|
||||
beadSearchDirs := []string{ctx.WorkDir, cloneRoot}
|
||||
// For Mayor, also try the gastown rig's beads location
|
||||
if ctx.Role == RoleMayor {
|
||||
beadSearchDirs = append(beadSearchDirs, filepath.Join(ctx.TownRoot, "gastown", "mayor", "rig"))
|
||||
}
|
||||
for _, dir := range beadSearchDirs {
|
||||
cmd := exec.Command("bd", "show", sw.BeadID)
|
||||
cmd.Dir = dir
|
||||
stdout.Reset()
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = nil
|
||||
if cmd.Run() == nil {
|
||||
beadExists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !beadExists {
|
||||
fmt.Println()
|
||||
fmt.Printf("%s\n\n", style.Bold.Render("## 🎯 SLUNG WORK ON HOOK"))
|
||||
fmt.Printf(" Bead ID: %s\n", style.Bold.Render(sw.BeadID))
|
||||
fmt.Printf(" %s Bead %s not found! It may have been deleted.\n",
|
||||
style.Bold.Render("⚠ WARNING:"), sw.BeadID)
|
||||
fmt.Println(" The hook will NOT be burned. Investigate this issue.")
|
||||
fmt.Println()
|
||||
// Don't burn - leave hook for debugging
|
||||
return false
|
||||
}
|
||||
// Use the first pinned bead (agents typically have one)
|
||||
pinnedBead := pinnedBeads[0]
|
||||
|
||||
// Build the role announcement string
|
||||
roleAnnounce := buildRoleAnnouncement(ctx)
|
||||
|
||||
// Found slung work! Display AUTONOMOUS MODE prominently
|
||||
// Found pinned work! Display AUTONOMOUS MODE prominently
|
||||
fmt.Println()
|
||||
fmt.Printf("%s\n\n", style.Bold.Render("## 🚨 AUTONOMOUS WORK MODE 🚨"))
|
||||
fmt.Println("Work is slung on your hook. After announcing your role, begin IMMEDIATELY.")
|
||||
fmt.Println("Work is pinned to your hook. After announcing your role, begin IMMEDIATELY.")
|
||||
fmt.Println()
|
||||
fmt.Println("1. Announce: \"" + roleAnnounce + "\" (ONE line, no elaboration)")
|
||||
fmt.Printf("2. Then IMMEDIATELY run: `bd show %s`\n", sw.BeadID)
|
||||
fmt.Printf("2. Then IMMEDIATELY run: `bd show %s`\n", pinnedBead.ID)
|
||||
fmt.Println("3. Begin execution - no waiting for user input")
|
||||
fmt.Println()
|
||||
fmt.Println("**DO NOT:**")
|
||||
@@ -1351,40 +1311,43 @@ func checkSlungWork(ctx RoleContext) bool {
|
||||
fmt.Println("- Describe what you're going to do")
|
||||
fmt.Println()
|
||||
|
||||
// Show the slung work details
|
||||
fmt.Printf("%s\n\n", style.Bold.Render("## Slung Work"))
|
||||
fmt.Printf(" Bead ID: %s\n", style.Bold.Render(sw.BeadID))
|
||||
if sw.Subject != "" {
|
||||
fmt.Printf(" Subject: %s\n", sw.Subject)
|
||||
}
|
||||
if sw.Context != "" {
|
||||
fmt.Printf(" Context: %s\n", sw.Context)
|
||||
}
|
||||
if sw.Args != "" {
|
||||
fmt.Printf(" Args: %s\n", style.Bold.Render(sw.Args))
|
||||
fmt.Println()
|
||||
fmt.Printf(" %s Use these args to guide your execution.\n", style.Bold.Render("→"))
|
||||
}
|
||||
fmt.Printf(" Slung by: %s at %s\n", sw.CreatedBy, sw.CreatedAt.Format("2006-01-02 15:04:05"))
|
||||
fmt.Println()
|
||||
|
||||
// Show bead preview (first 15 lines)
|
||||
lines := strings.Split(stdout.String(), "\n")
|
||||
maxLines := 15
|
||||
if len(lines) > maxLines {
|
||||
lines = lines[:maxLines]
|
||||
lines = append(lines, "...")
|
||||
}
|
||||
fmt.Println("**Bead preview:**")
|
||||
for _, line := range lines {
|
||||
fmt.Printf(" %s\n", line)
|
||||
// Show the pinned work details
|
||||
fmt.Printf("%s\n\n", style.Bold.Render("## Pinned Work"))
|
||||
fmt.Printf(" Bead ID: %s\n", style.Bold.Render(pinnedBead.ID))
|
||||
fmt.Printf(" Title: %s\n", pinnedBead.Title)
|
||||
if pinnedBead.Description != "" {
|
||||
// Show first few lines of description
|
||||
lines := strings.Split(pinnedBead.Description, "\n")
|
||||
maxLines := 5
|
||||
if len(lines) > maxLines {
|
||||
lines = lines[:maxLines]
|
||||
lines = append(lines, "...")
|
||||
}
|
||||
fmt.Println(" Description:")
|
||||
for _, line := range lines {
|
||||
fmt.Printf(" %s\n", line)
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
// Burn the hook now that it's been read and verified
|
||||
if err := wisp.BurnHook(cloneRoot, agentID); err != nil {
|
||||
fmt.Printf("%s Warning: could not burn hook: %v\n", style.Dim.Render("⚠"), err)
|
||||
// Show bead preview using bd show
|
||||
fmt.Println("**Bead details:**")
|
||||
cmd := exec.Command("bd", "show", pinnedBead.ID)
|
||||
var stdout bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = nil
|
||||
if cmd.Run() == nil {
|
||||
lines := strings.Split(stdout.String(), "\n")
|
||||
maxLines := 15
|
||||
if len(lines) > maxLines {
|
||||
lines = lines[:maxLines]
|
||||
lines = append(lines, "...")
|
||||
}
|
||||
for _, line := range lines {
|
||||
fmt.Printf(" %s\n", line)
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/steveyegge/gastown/internal/style"
|
||||
"github.com/steveyegge/gastown/internal/tmux"
|
||||
"github.com/steveyegge/gastown/internal/wisp"
|
||||
)
|
||||
|
||||
var slingCmd = &cobra.Command{
|
||||
@@ -144,7 +143,6 @@ func runSling(cmd *cobra.Command, args []string) error {
|
||||
// Determine target agent (self or specified)
|
||||
var targetAgent string
|
||||
var targetPane string
|
||||
var hookRoot string // Where to store the hook (role's home)
|
||||
var err error
|
||||
|
||||
if len(args) > 1 {
|
||||
@@ -157,7 +155,6 @@ func runSling(cmd *cobra.Command, args []string) error {
|
||||
fmt.Printf("Would spawn fresh polecat in rig '%s'\n", rigName)
|
||||
targetAgent = fmt.Sprintf("%s/polecats/<new>", rigName)
|
||||
targetPane = "<new-pane>"
|
||||
hookRoot = fmt.Sprintf("<polecat-worktree-in-%s>", rigName)
|
||||
} else {
|
||||
// Spawn a fresh polecat in the rig
|
||||
fmt.Printf("Target is rig '%s', spawning fresh polecat...\n", rigName)
|
||||
@@ -167,30 +164,22 @@ func runSling(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
targetAgent = spawnInfo.AgentID()
|
||||
targetPane = spawnInfo.Pane
|
||||
hookRoot = spawnInfo.ClonePath
|
||||
}
|
||||
} else {
|
||||
// Slinging to an existing agent
|
||||
targetAgent, targetPane, hookRoot, err = resolveTargetAgent(target)
|
||||
targetAgent, targetPane, _, err = resolveTargetAgent(target)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving target: %w", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Slinging to self
|
||||
targetAgent, targetPane, hookRoot, err = resolveSelfTarget()
|
||||
targetAgent, targetPane, _, err = resolveSelfTarget()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Create the slung work wisp
|
||||
sw := wisp.NewSlungWork(beadID, targetAgent)
|
||||
sw.Subject = slingSubject
|
||||
sw.Context = slingMessage
|
||||
sw.Formula = formulaName
|
||||
sw.Args = slingArgs
|
||||
|
||||
// Display what we're doing
|
||||
if formulaName != "" {
|
||||
fmt.Printf("%s Slinging formula %s on %s to %s...\n", style.Bold.Render("🎯"), formulaName, beadID, targetAgent)
|
||||
@@ -199,32 +188,31 @@ func runSling(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if slingDryRun {
|
||||
fmt.Printf("Would create wisp: %s\n", wisp.HookPath(hookRoot, targetAgent))
|
||||
fmt.Printf(" bead_id: %s\n", beadID)
|
||||
fmt.Printf("Would run: bd update %s --status=pinned --assignee=%s\n", beadID, targetAgent)
|
||||
if formulaName != "" {
|
||||
fmt.Printf(" formula: %s\n", formulaName)
|
||||
}
|
||||
fmt.Printf(" agent: %s\n", targetAgent)
|
||||
fmt.Printf(" hook_root: %s\n", hookRoot)
|
||||
if slingSubject != "" {
|
||||
fmt.Printf(" subject: %s\n", slingSubject)
|
||||
fmt.Printf(" subject (in nudge): %s\n", slingSubject)
|
||||
}
|
||||
if slingMessage != "" {
|
||||
fmt.Printf(" context: %s\n", slingMessage)
|
||||
}
|
||||
if slingArgs != "" {
|
||||
fmt.Printf(" args: %s\n", slingArgs)
|
||||
fmt.Printf(" args (in nudge): %s\n", slingArgs)
|
||||
}
|
||||
fmt.Printf("Would inject start prompt to pane: %s\n", targetPane)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write the wisp to the hook
|
||||
if err := wisp.WriteSlungWork(hookRoot, targetAgent, sw); err != nil {
|
||||
return fmt.Errorf("writing wisp: %w", err)
|
||||
// Pin the bead using bd update (discovery-based approach)
|
||||
pinCmd := exec.Command("bd", "update", beadID, "--status=pinned", "--assignee="+targetAgent)
|
||||
pinCmd.Stderr = os.Stderr
|
||||
if err := pinCmd.Run(); err != nil {
|
||||
return fmt.Errorf("pinning bead: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("%s Work attached to hook\n", style.Bold.Render("✓"))
|
||||
fmt.Printf("%s Work attached to hook (pinned bead)\n", style.Bold.Render("✓"))
|
||||
|
||||
// Inject the "start now" prompt
|
||||
if err := injectStartPrompt(targetPane, beadID, slingSubject, slingArgs); err != nil {
|
||||
@@ -406,7 +394,6 @@ func runSlingFormula(args []string) error {
|
||||
// Resolve target agent and pane
|
||||
var targetAgent string
|
||||
var targetPane string
|
||||
var hookRoot string
|
||||
var err error
|
||||
|
||||
if target != "" {
|
||||
@@ -417,7 +404,6 @@ func runSlingFormula(args []string) error {
|
||||
fmt.Printf("Would spawn fresh polecat in rig '%s'\n", rigName)
|
||||
targetAgent = fmt.Sprintf("%s/polecats/<new>", rigName)
|
||||
targetPane = "<new-pane>"
|
||||
hookRoot = fmt.Sprintf("<polecat-worktree-in-%s>", rigName)
|
||||
} else {
|
||||
// Spawn a fresh polecat in the rig
|
||||
fmt.Printf("Target is rig '%s', spawning fresh polecat...\n", rigName)
|
||||
@@ -427,18 +413,17 @@ func runSlingFormula(args []string) error {
|
||||
}
|
||||
targetAgent = spawnInfo.AgentID()
|
||||
targetPane = spawnInfo.Pane
|
||||
hookRoot = spawnInfo.ClonePath
|
||||
}
|
||||
} else {
|
||||
// Slinging to an existing agent
|
||||
targetAgent, targetPane, hookRoot, err = resolveTargetAgent(target)
|
||||
targetAgent, targetPane, _, err = resolveTargetAgent(target)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving target: %w", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Slinging to self
|
||||
targetAgent, targetPane, hookRoot, err = resolveSelfTarget()
|
||||
targetAgent, targetPane, _, err = resolveSelfTarget()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -448,7 +433,7 @@ func runSlingFormula(args []string) error {
|
||||
|
||||
if slingDryRun {
|
||||
fmt.Printf("Would cook formula: %s\n", formulaName)
|
||||
fmt.Printf("Would create wisp and attach to hook: %s\n", wisp.HookPath(hookRoot, targetAgent))
|
||||
fmt.Printf("Would create wisp and pin to: %s\n", targetAgent)
|
||||
for _, v := range slingVars {
|
||||
fmt.Printf(" --var %s\n", v)
|
||||
}
|
||||
@@ -492,20 +477,13 @@ func runSlingFormula(args []string) error {
|
||||
|
||||
fmt.Printf("%s Wisp created: %s\n", style.Bold.Render("✓"), wispResult.RootID)
|
||||
|
||||
// Step 3: Attach to hook
|
||||
sw := wisp.NewSlungWork(wispResult.RootID, targetAgent)
|
||||
sw.Subject = slingSubject
|
||||
if sw.Subject == "" {
|
||||
sw.Subject = fmt.Sprintf("Formula: %s", formulaName)
|
||||
// Step 3: Pin the wisp bead using bd update (discovery-based approach)
|
||||
pinCmd := exec.Command("bd", "update", wispResult.RootID, "--status=pinned", "--assignee="+targetAgent)
|
||||
pinCmd.Stderr = os.Stderr
|
||||
if err := pinCmd.Run(); err != nil {
|
||||
return fmt.Errorf("pinning wisp bead: %w", err)
|
||||
}
|
||||
sw.Context = slingMessage
|
||||
sw.Formula = formulaName
|
||||
sw.Args = slingArgs
|
||||
|
||||
if err := wisp.WriteSlungWork(hookRoot, targetAgent, sw); err != nil {
|
||||
return fmt.Errorf("writing to hook: %w", err)
|
||||
}
|
||||
fmt.Printf("%s Attached to hook\n", style.Bold.Render("✓"))
|
||||
fmt.Printf("%s Attached to hook (pinned bead)\n", style.Bold.Render("✓"))
|
||||
|
||||
// Step 4: Nudge to start
|
||||
if targetPane == "" {
|
||||
|
||||
Reference in New Issue
Block a user