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))
|
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) 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) account() string { return filepath.Join(p.Home, ".claude.json") }
|
||||||
func (p Paths) binding() string { return filepath.Join(p.State, "licence.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) apiKey() string { return filepath.Join(p.keyDir(), "api-key") }
|
||||||
func (p Paths) helper() string { return filepath.Join(p.keyDir(), "api-key-helper") }
|
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
|
var settings Settings
|
||||||
readJSON(p.Settings, &settings)
|
readJSON(p.Settings, &settings)
|
||||||
|
readJSON(p.preferences(), &settings.Preferences)
|
||||||
var binding *Binding
|
var binding *Binding
|
||||||
var b Binding
|
var b Binding
|
||||||
if readJSON(p.binding(), &b) {
|
if readJSON(p.binding(), &b) {
|
||||||
|
|||||||
@@ -42,6 +42,15 @@ type Settings struct {
|
|||||||
MCPServers map[string]map[string]any `json:"mcp_servers"`
|
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 are keys of the agent's managed settings the operator sets, for the mesh or a node.
|
||||||
ManagedSettings map[string]any `json:"managed_settings"`
|
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.
|
// 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
|
// 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).
|
// through this module's tools is laid over it (novox/hq issue 340).
|
||||||
managed := mergeSettings(map[string]any{}, settings.ManagedSettings)
|
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.
|
// The mesh's own keys are laid last: a setting never replaces them.
|
||||||
managed["attribution"] = map[string]any{"commit": "", "pr": ""}
|
managed["attribution"] = map[string]any{"commit": "", "pr": ""}
|
||||||
managed["allowAllClaudeAiMcps"] = true
|
managed["allowAllClaudeAiMcps"] = true
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
{
|
{
|
||||||
"module": "claude-code",
|
"module": "claude-code",
|
||||||
"version": "1",
|
"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",
|
"slug": "agent",
|
||||||
"capabilities": [
|
"capabilities": [
|
||||||
"package-manager"
|
"package-manager"
|
||||||
@@ -146,6 +153,15 @@
|
|||||||
"owner": "${machine:account}",
|
"owner": "${machine:account}",
|
||||||
"merge": "json",
|
"merge": "json",
|
||||||
"content": "{\n \"role\": \"\",\n \"mcp_servers\": {},\n \"managed_settings\": {},\n \"instructions\": {},\n \"output_styles\": {},\n \"skills\": {},\n \"commands\": {},\n \"agents\": {}\n}\n"
|
"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": [
|
"shell": [
|
||||||
|
|||||||
Reference in New Issue
Block a user