diff --git a/modules/claude-code/cmd/claude-code/config.go b/modules/claude-code/cmd/claude-code/config.go index 13e1333..31a99d9 100644 --- a/modules/claude-code/cmd/claude-code/config.go +++ b/modules/claude-code/cmd/claude-code/config.go @@ -800,8 +800,10 @@ func Register(p Paths, it Item, nodes []string, unregister bool, state ConfigSta } } } + // Compared before and after rather than read from Take: this node's own watch may take the same change + // first, and then Take here finds nothing new although this call made it. + before, _ := json.Marshal(v.Items()) var keys []string - changed := false for _, n := range nodes { key := it.Key(n) keys = append(keys, key) @@ -819,7 +821,12 @@ func Register(p Paths, it Item, nodes []string, unregister bool, state ConfigSta op = "delete" } item := it - changed = v.Take(key, op, &item) || changed + v.Take(key, op, &item) + } + after, _ := json.Marshal(v.Items()) + here := string(before) != string(after) + for _, k := range keys { + here = here || v.Applies(k) } verb := map[bool]string{false: "registered", true: "unregistered"}[unregister] answer := map[string]any{verb: it.Kind + " " + it.Name, "keys": keys} @@ -835,15 +842,15 @@ func Register(p Paths, it Item, nodes []string, unregister bool, state ConfigSta answer["offered as"] = "/" + Plugin + ":" + it.Name } } - if changed { + if here { + // Rendered whenever it applies here, so the answer says what this node wrote, whichever of the + // watch and this call took the change. rendered, err := RenderNow(p, write) answer["rendered here"] = rendered if err != nil { answer["not written here"] = err.Error() // kept on the bus all the same; the next render tries again } answer["sessions"] = "a new session takes it; a running one at /reload-plugins" - } else if v.Applies(keys[0]) || len(keys) > 1 { - answer["here"] = "already so" } else { answer["here"] = "not this node: each node it is for takes it from the bus" } diff --git a/modules/claude-code/cmd/claude-code/config_test.go b/modules/claude-code/cmd/claude-code/config_test.go index 69036ed..0a1edf8 100644 --- a/modules/claude-code/cmd/claude-code/config_test.go +++ b/modules/claude-code/cmd/claude-code/config_test.go @@ -455,3 +455,16 @@ func TestOneFileThatCannotBeWrittenDoesNotStopTheOthers(t *testing.T) { t.Fatalf("the other files were not written: %v", w) } } + +// The answer says what this node wrote even when its own watch took the change first. +func TestTheAnswerSaysWhatWasWrittenWhenTheWatchWasFirst(t *testing.T) { + p, w := node(t, "laptop") + state, view := memConfig{}, NewConfigView(p) + it := Item{Kind: KindCommand, Name: "c", Scope: ScopeHome, Files: one("c", "x")} + first := it + view.Take(it.Key("laptop"), "put", &first) // the watch, first + answer, err := Register(p, it, nil, false, state, view, writer(w)) + if err != nil || answer["rendered here"] == nil || answer["here"] != nil { + t.Fatalf("%v %v", answer, err) + } +}