Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86bcbc48ad |
@@ -495,3 +495,22 @@ func TestALowerGenerationAfterTheManagerWasRebuiltIsStillApplied(t *testing.T) {
|
||||
t.Fatalf("asked %v, credentials %v: a lower generation was ignored", asked, creds(t, p))
|
||||
}
|
||||
}
|
||||
|
||||
// The tips preference reaches the managed settings as spinnerTipsEnabled, either way, and is left out when the
|
||||
// mesh filled none: set in one call through the controller, never at the terminal.
|
||||
func TestTheTipsPreferenceIsRenderedAsSpinnerTipsEnabled(t *testing.T) {
|
||||
off, on := false, true
|
||||
for _, c := range []struct {
|
||||
tips *bool
|
||||
want any
|
||||
}{{&off, false}, {&on, true}, {nil, nil}} {
|
||||
out := Render(Facts{Console: "x"}, Settings{Preferences: Preferences{Tips: c.tips}}, nil, "/h", nil, Config{})
|
||||
var managed map[string]any
|
||||
if err := json.Unmarshal([]byte(out["managed-settings.json"]), &managed); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got, has := managed["spinnerTipsEnabled"]; got != c.want || has != (c.want != nil) {
|
||||
t.Errorf("tips %v rendered spinnerTipsEnabled %v (present %v)", c.tips, got, has)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,7 @@ func HomeScopeRefused(p Paths, target string) string {
|
||||
func (p Paths) credentials() string { return filepath.Join(p.Home, ".claude", ".credentials.json") }
|
||||
func (p Paths) account() string { return filepath.Join(p.Home, ".claude.json") }
|
||||
func (p Paths) binding() string { return filepath.Join(p.State, "licence.json") }
|
||||
func (p Paths) preferences() string { return filepath.Join(p.State, "preferences.json") }
|
||||
func (p Paths) apiKey() string { return filepath.Join(p.keyDir(), "api-key") }
|
||||
func (p Paths) helper() string { return filepath.Join(p.keyDir(), "api-key-helper") }
|
||||
|
||||
@@ -218,6 +219,7 @@ func RenderNow(p Paths, write WriteManaged) ([]string, error) {
|
||||
}
|
||||
var settings Settings
|
||||
readJSON(p.Settings, &settings)
|
||||
readJSON(p.preferences(), &settings.Preferences)
|
||||
var binding *Binding
|
||||
var b Binding
|
||||
if readJSON(p.binding(), &b) {
|
||||
|
||||
@@ -42,6 +42,15 @@ type Settings struct {
|
||||
MCPServers map[string]map[string]any `json:"mcp_servers"`
|
||||
// ManagedSettings are keys of the agent's managed settings the operator sets, for the mesh or a node.
|
||||
ManagedSettings map[string]any `json:"managed_settings"`
|
||||
// Preferences are this module's own preferences, from its untrusted preferences file: set in one call
|
||||
// with the controller's `settings` verb, for the mesh or a node, like any module's preference (ADR 0262).
|
||||
Preferences Preferences `json:"-"`
|
||||
}
|
||||
|
||||
// Preferences are the module's preferences as the mesh filled them; nil is a value the file did not carry.
|
||||
type Preferences struct {
|
||||
// Tips is whether Claude Code shows a tip while it works (`spinnerTipsEnabled`).
|
||||
Tips *bool `json:"tips"`
|
||||
}
|
||||
|
||||
// Binding is the licence this node holds, as it was last applied.
|
||||
@@ -121,6 +130,11 @@ func RenderWithMesh(facts Facts, settings Settings, binding *Binding, helperPath
|
||||
// The operator's `managed_settings` (ADR 0213), set at the controller's terminal alone: nothing registered
|
||||
// through this module's tools is laid over it (novox/hq issue 340).
|
||||
managed := mergeSettings(map[string]any{}, settings.ManagedSettings)
|
||||
// The module's preferences: keys of how a session looks, never of what it may do, so they are set in one
|
||||
// call through the controller rather than at the terminal, and laid over the operator's keys of the same name.
|
||||
if settings.Preferences.Tips != nil {
|
||||
managed["spinnerTipsEnabled"] = *settings.Preferences.Tips
|
||||
}
|
||||
// The mesh's own keys are laid last: a setting never replaces them.
|
||||
managed["attribution"] = map[string]any{"commit": "", "pr": ""}
|
||||
managed["allowAllClaudeAiMcps"] = true
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
{
|
||||
"module": "claude-code",
|
||||
"version": "1",
|
||||
"settings": {
|
||||
"tips": {
|
||||
"kind": "preference",
|
||||
"default": true,
|
||||
"why": "Claude Code shows a tip while it works; false turns tips off in every session on the machine, written as spinnerTipsEnabled in its managed settings"
|
||||
}
|
||||
},
|
||||
"slug": "agent",
|
||||
"capabilities": [
|
||||
"package-manager"
|
||||
@@ -146,6 +153,15 @@
|
||||
"owner": "${machine:account}",
|
||||
"merge": "json",
|
||||
"content": "{\n \"role\": \"\",\n \"mcp_servers\": {},\n \"managed_settings\": {},\n \"instructions\": {},\n \"output_styles\": {},\n \"skills\": {},\n \"commands\": {},\n \"agents\": {}\n}\n"
|
||||
},
|
||||
{
|
||||
"id": "preferences",
|
||||
"trusted": false,
|
||||
"type": "file",
|
||||
"path": "${dir:state}/preferences.json",
|
||||
"mode": "0600",
|
||||
"owner": "${machine:account}",
|
||||
"content": "{\n \"tips\": ${setting:tips}\n}\n"
|
||||
}
|
||||
],
|
||||
"shell": [
|
||||
|
||||
Reference in New Issue
Block a user