Compare commits
4
Commits
fix/r4e-k1
...
fix/r4e-k2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fdfecfa29 | ||
|
|
97f0f4813c | ||
|
|
8f10d3192c | ||
|
|
1e3439429f |
@@ -3,7 +3,7 @@ module gitea
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021114014-66e8fdaa62e2
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261022190740-104533e8c0c9
|
||||||
github.com/nats-io/nats-server/v2 v2.11.17
|
github.com/nats-io/nats-server/v2 v2.11.17
|
||||||
github.com/nats-io/nats.go v1.54.0
|
github.com/nats-io/nats.go v1.54.0
|
||||||
golang.org/x/crypto v0.57.0
|
golang.org/x/crypto v0.57.0
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021114014-66e8fdaa62e2 h1:Cdl5N56QPfmFBoLHrDfvvyc5Q+PUnTjf3fgYD7imcco=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261022190740-104533e8c0c9 h1:Ufmd2cYEXICQ817IGflccP9bexABE4WhIO49HPbaoSo=
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021114014-66e8fdaa62e2/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261022190740-104533e8c0c9/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
||||||
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ func (m *Module) build(ctx context.Context, args map[string]any) (any, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("no module in %q of workspace %s: %w", module, workspace, err)
|
return nil, fmt.Errorf("no module in %q of workspace %s: %w", module, workspace, err)
|
||||||
}
|
}
|
||||||
manifest, err := catalogue.ParseManifest(raw)
|
manifest, err := catalogue.ParseManifestForInputs(raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("the manifest in %q: %w", module, err)
|
return nil, fmt.Errorf("the manifest in %q: %w", module, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -237,3 +237,21 @@ func TestABuildOutputDirectoryLinkedOutsideTheModuleIsRefused(t *testing.T) {
|
|||||||
t.Errorf("a file outside the module was touched: %q, %v", body, err)
|
t.Errorf("a file outside the module was touched: %q, %v", body, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 1751 (ADR 0514 §2, the review's K2): a manifest whose config value falls back to a predefined key builds. The
|
||||||
|
// builder holds no published list of the keys, so it reads the manifest for its inputs (ParseManifestForInputs), not
|
||||||
|
// as a judge of config values; claude-code's real manifest (capturedClaudeCodeManifest) is the fixture.
|
||||||
|
func TestAManifestFallingBackToAPredefinedKeyBuilds(t *testing.T) {
|
||||||
|
raw := []byte(capturedClaudeCodeManifest)
|
||||||
|
if !strings.Contains(string(raw), `"predefined": "agent-managed-settings"`) {
|
||||||
|
t.Fatal("the captured manifest no longer falls back to a predefined key")
|
||||||
|
}
|
||||||
|
m, states, _ := buildModule(t, string(raw), "binary")
|
||||||
|
res, st := runBuild(t, m, states, "tools")
|
||||||
|
if st.State != delivery.StepPassed {
|
||||||
|
t.Fatalf("the step ended %s: %s", st.State, st.Reason)
|
||||||
|
}
|
||||||
|
if res.Artifact != "tools" || res.Binary != "claude-code" || !strings.HasPrefix(res.Digest, "sha256:") {
|
||||||
|
t.Errorf("result = %+v", res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,257 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// capturedClaudeCodeManifest is modules/claude-code/module.json of this catalogue at 56c68be7, copied verbatim on
|
||||||
|
// 2026-10-22 for issue 1751 (the R4e review's finding K2): a real manifest whose config value managed_settings falls
|
||||||
|
// back to the predefined key agent-managed-settings (ADR 0348 §7), which the builder holds no published list for. It
|
||||||
|
// lives in a test file, not under testdata, because the catalogue's paths check (ADR 0260) reads every other file of a
|
||||||
|
// module and the manifest names claude-code's own paths.
|
||||||
|
const capturedClaudeCodeManifest = `{
|
||||||
|
"module": "claude-code",
|
||||||
|
"version": "1",
|
||||||
|
"moved": true,
|
||||||
|
"slug": "agent",
|
||||||
|
"capabilities": [
|
||||||
|
"package-manager"
|
||||||
|
],
|
||||||
|
"requires": [
|
||||||
|
"mcp-endpoint",
|
||||||
|
{
|
||||||
|
"name": "gitea-read",
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": {
|
||||||
|
"mcp-endpoint": "${dir:state}/mcp-endpoint.json"
|
||||||
|
},
|
||||||
|
"secrets": {
|
||||||
|
"gitea-read": "${dir:state}/gitea-read.secret"
|
||||||
|
},
|
||||||
|
"uses": [
|
||||||
|
"operator-channel"
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
"servers",
|
||||||
|
"holdings",
|
||||||
|
"config",
|
||||||
|
"proposals",
|
||||||
|
"questions",
|
||||||
|
"memory",
|
||||||
|
"waits"
|
||||||
|
],
|
||||||
|
"reads": [
|
||||||
|
"claude-licence-manager.bindings"
|
||||||
|
],
|
||||||
|
"tools": [
|
||||||
|
"claude_code_status",
|
||||||
|
"claude_code_render",
|
||||||
|
"claude_code_guard",
|
||||||
|
"claude_code_pull",
|
||||||
|
"claude_code_grant",
|
||||||
|
"claude_code_add_api_key",
|
||||||
|
"claude_code_registrations",
|
||||||
|
"claude_code_memory",
|
||||||
|
"claude_code_mcp_list",
|
||||||
|
"claude_code_mcp_register",
|
||||||
|
"claude_code_mcp_unregister",
|
||||||
|
"claude_code_skill_list",
|
||||||
|
"claude_code_skill_register",
|
||||||
|
"claude_code_skill_unregister",
|
||||||
|
"claude_code_agent_list",
|
||||||
|
"claude_code_agent_register",
|
||||||
|
"claude_code_agent_unregister",
|
||||||
|
"claude_code_command_list",
|
||||||
|
"claude_code_command_register",
|
||||||
|
"claude_code_command_unregister",
|
||||||
|
"claude_code_hook_list",
|
||||||
|
"claude_code_hook_register",
|
||||||
|
"claude_code_hook_unregister",
|
||||||
|
"claude_code_output_style_list",
|
||||||
|
"claude_code_output_style_register",
|
||||||
|
"claude_code_output_style_unregister",
|
||||||
|
"claude_code_instructions_list",
|
||||||
|
"claude_code_instructions_register",
|
||||||
|
"claude_code_instructions_unregister",
|
||||||
|
"claude_code_instructions_propose",
|
||||||
|
"claude_code_proposals",
|
||||||
|
"claude_code_ask",
|
||||||
|
"claude_code_answer",
|
||||||
|
"claude_code_wait",
|
||||||
|
"claude_code_settings_get",
|
||||||
|
"claude_code_settings_set",
|
||||||
|
"claude_code_settings_clear",
|
||||||
|
"claude_code_permission_add",
|
||||||
|
"claude_code_permission_remove",
|
||||||
|
"claude_code_config_list",
|
||||||
|
"claude_code_config_show",
|
||||||
|
"claude_code_config_status",
|
||||||
|
"claude_code_config_import",
|
||||||
|
"claude_code_home_show",
|
||||||
|
"claude_code_home_remove",
|
||||||
|
"claude_code_home_removed",
|
||||||
|
"claude_code_home_restore",
|
||||||
|
"claude_code_judge",
|
||||||
|
"claude_code_judged"
|
||||||
|
],
|
||||||
|
"data": {
|
||||||
|
"own": [
|
||||||
|
{
|
||||||
|
"id": "agent-home",
|
||||||
|
"path": "${dir:agent-home}",
|
||||||
|
"class": "valuable",
|
||||||
|
"why": "the operator's agent's own files: its memory, history and projects"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"role": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "What this machine is for, in a sentence, written into the instructions every Claude Code session on it reads; empty says nothing.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
"mcp_servers": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The tool servers every session on this machine is given beside the mesh's own, by name, each as Claude Code's managed MCP configuration takes it; empty adds none.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"managed_settings": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Keys of Claude Code's managed settings every session on this machine obeys, such as spinnerTipsEnabled, laid over the mesh's own; empty adds none. Falls back to agent-managed-settings, the mesh's or this node's.",
|
||||||
|
"trusted": true,
|
||||||
|
"predefined": "agent-managed-settings",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"instructions": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The instructions every session on this machine reads, by name, each a text as one line or a list of its lines; empty adds none.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"output_styles": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The output styles offered to every session on this machine, by name, each a text as one line or a list of its lines; empty adds none.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"skills": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The skills offered to every session on this machine, by name, each its files by path, a text as one line or a list of its lines; a skill without its SKILL.md is left out; empty adds none.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The slash commands offered to every session on this machine, by name, each a text as one line or a list of its lines; empty adds none.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"agents": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The agents offered to every session on this machine, by name, each a text as one line or a list of its lines; empty adds none.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"id": "package",
|
||||||
|
"type": "package",
|
||||||
|
"package": "claude-code"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "managed",
|
||||||
|
"type": "directory",
|
||||||
|
"path": "/etc/claude-code",
|
||||||
|
"mode": "0755",
|
||||||
|
"unknown": "program"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "start",
|
||||||
|
"type": "file",
|
||||||
|
"path": "/usr/local/bin/claude-agent",
|
||||||
|
"mode": "0755",
|
||||||
|
"template": "files/claude-agent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "agent-account-name",
|
||||||
|
"type": "file",
|
||||||
|
"path": "/etc/claude-code/agent-account",
|
||||||
|
"mode": "0644",
|
||||||
|
"template": "files/agent-account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "agent-account",
|
||||||
|
"type": "user",
|
||||||
|
"name": "${machine:agent-account}",
|
||||||
|
"home": "${machine:agent-home}",
|
||||||
|
"root": "${machine:agent-root}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "agent-home",
|
||||||
|
"type": "directory",
|
||||||
|
"path": "${machine:agent-home}/.claude",
|
||||||
|
"mode": "0700",
|
||||||
|
"owner": "${machine:agent-account}",
|
||||||
|
"unknown": "module"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "state",
|
||||||
|
"type": "directory",
|
||||||
|
"mode": "0700",
|
||||||
|
"owner": "${machine:account}",
|
||||||
|
"place": ".",
|
||||||
|
"unknown": "program"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "facts",
|
||||||
|
"type": "file",
|
||||||
|
"path": "${dir:state}/facts.json",
|
||||||
|
"mode": "0600",
|
||||||
|
"owner": "${machine:account}",
|
||||||
|
"template": "files/facts.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "settings",
|
||||||
|
"type": "file",
|
||||||
|
"path": "${dir:state}/settings.json",
|
||||||
|
"mode": "0600",
|
||||||
|
"owner": "${machine:account}",
|
||||||
|
"takes-config": ["role", "mcp_servers", "managed_settings", "instructions", "output_styles", "skills", "commands", "agents"],
|
||||||
|
"merge": "json",
|
||||||
|
"template": "files/settings.json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"collection": "shell:zsh:normal",
|
||||||
|
"template": "files/zsh-normal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"build": {
|
||||||
|
"artifacts": [
|
||||||
|
{
|
||||||
|
"name": "tools",
|
||||||
|
"kind": "bundle",
|
||||||
|
"language": "go",
|
||||||
|
"system": "arch",
|
||||||
|
"from": "cmd/claude-code",
|
||||||
|
"binary": "claude-code",
|
||||||
|
"loads": [
|
||||||
|
"claude-code"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"MESH_CLAUDE_CODE_STATE": "${dir:state}",
|
||||||
|
"MESH_CLAUDE_CODE_FACTS": "${dir:state}/facts.json",
|
||||||
|
"MESH_CLAUDE_CODE_SETTINGS": "${dir:state}/settings.json"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "files",
|
||||||
|
"kind": "archive",
|
||||||
|
"from": "files"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
@@ -126,7 +126,7 @@ func (m *Module) build(ctx context.Context, args map[string]any) (any, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("no module in %q of workspace %s: %w", module, workspace, err)
|
return nil, fmt.Errorf("no module in %q of workspace %s: %w", module, workspace, err)
|
||||||
}
|
}
|
||||||
manifest, err := catalogue.ParseManifest(raw)
|
manifest, err := catalogue.ParseManifestForInputs(raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("the manifest in %q: %w", module, err)
|
return nil, fmt.Errorf("the manifest in %q: %w", module, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,3 +198,53 @@ func TestBuildFailsForWhatIsNotAnImageOrNotThere(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 1751 (ADR 0514 §2, the review's K2): a manifest whose config value falls back to a predefined key builds. The
|
||||||
|
// builder holds no published list of the keys, so it reads the manifest for its inputs (ParseManifestForInputs), not
|
||||||
|
// as a judge of config values. The manifest is claude-code's real one (capturedClaudeCodeManifest) with the image fixture's
|
||||||
|
// base and artifact added to its build, since no image module of the catalogue falls back to a predefined key today.
|
||||||
|
func TestAManifestFallingBackToAPredefinedKeyBuilds(t *testing.T) {
|
||||||
|
raw := []byte(capturedClaudeCodeManifest)
|
||||||
|
if !strings.Contains(string(raw), `"predefined": "agent-managed-settings"`) {
|
||||||
|
t.Fatal("the captured manifest no longer falls back to a predefined key")
|
||||||
|
}
|
||||||
|
m, _, states := setup(t, func(fixture string) string {
|
||||||
|
var real, image map[string]json.RawMessage
|
||||||
|
if err := json.Unmarshal(raw, &real); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal([]byte(fixture), &image); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
// The image fixture's base and artifact join claude-code's own artifacts (its archive of files/ stays).
|
||||||
|
var realBuild, imageBuild struct {
|
||||||
|
On json.RawMessage `json:"on,omitempty"`
|
||||||
|
Artifacts []json.RawMessage `json:"artifacts"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(real["build"], &realBuild); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(image["build"], &imageBuild); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
realBuild.On = imageBuild.On
|
||||||
|
realBuild.Artifacts = append(realBuild.Artifacts, imageBuild.Artifacts...)
|
||||||
|
b, err := json.Marshal(realBuild)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
real["build"] = b
|
||||||
|
out, err := json.Marshal(real)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return string(out)
|
||||||
|
})
|
||||||
|
res, st := runBuild(t, m, states, nil)
|
||||||
|
if st.State != delivery.StepPassed {
|
||||||
|
t.Fatalf("step = %+v", st)
|
||||||
|
}
|
||||||
|
if res.Digest != imageDigest || res.Artifact != "server" {
|
||||||
|
t.Errorf("result = %+v", res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,257 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// capturedClaudeCodeManifest is modules/claude-code/module.json of this catalogue at 56c68be7, copied verbatim on
|
||||||
|
// 2026-10-22 for issue 1751 (the R4e review's finding K2): a real manifest whose config value managed_settings falls
|
||||||
|
// back to the predefined key agent-managed-settings (ADR 0348 §7), which the builder holds no published list for. It
|
||||||
|
// lives in a test file, not under testdata, because the catalogue's paths check (ADR 0260) reads every other file of a
|
||||||
|
// module and the manifest names claude-code's own paths.
|
||||||
|
const capturedClaudeCodeManifest = `{
|
||||||
|
"module": "claude-code",
|
||||||
|
"version": "1",
|
||||||
|
"moved": true,
|
||||||
|
"slug": "agent",
|
||||||
|
"capabilities": [
|
||||||
|
"package-manager"
|
||||||
|
],
|
||||||
|
"requires": [
|
||||||
|
"mcp-endpoint",
|
||||||
|
{
|
||||||
|
"name": "gitea-read",
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"binds": {
|
||||||
|
"mcp-endpoint": "${dir:state}/mcp-endpoint.json"
|
||||||
|
},
|
||||||
|
"secrets": {
|
||||||
|
"gitea-read": "${dir:state}/gitea-read.secret"
|
||||||
|
},
|
||||||
|
"uses": [
|
||||||
|
"operator-channel"
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
"servers",
|
||||||
|
"holdings",
|
||||||
|
"config",
|
||||||
|
"proposals",
|
||||||
|
"questions",
|
||||||
|
"memory",
|
||||||
|
"waits"
|
||||||
|
],
|
||||||
|
"reads": [
|
||||||
|
"claude-licence-manager.bindings"
|
||||||
|
],
|
||||||
|
"tools": [
|
||||||
|
"claude_code_status",
|
||||||
|
"claude_code_render",
|
||||||
|
"claude_code_guard",
|
||||||
|
"claude_code_pull",
|
||||||
|
"claude_code_grant",
|
||||||
|
"claude_code_add_api_key",
|
||||||
|
"claude_code_registrations",
|
||||||
|
"claude_code_memory",
|
||||||
|
"claude_code_mcp_list",
|
||||||
|
"claude_code_mcp_register",
|
||||||
|
"claude_code_mcp_unregister",
|
||||||
|
"claude_code_skill_list",
|
||||||
|
"claude_code_skill_register",
|
||||||
|
"claude_code_skill_unregister",
|
||||||
|
"claude_code_agent_list",
|
||||||
|
"claude_code_agent_register",
|
||||||
|
"claude_code_agent_unregister",
|
||||||
|
"claude_code_command_list",
|
||||||
|
"claude_code_command_register",
|
||||||
|
"claude_code_command_unregister",
|
||||||
|
"claude_code_hook_list",
|
||||||
|
"claude_code_hook_register",
|
||||||
|
"claude_code_hook_unregister",
|
||||||
|
"claude_code_output_style_list",
|
||||||
|
"claude_code_output_style_register",
|
||||||
|
"claude_code_output_style_unregister",
|
||||||
|
"claude_code_instructions_list",
|
||||||
|
"claude_code_instructions_register",
|
||||||
|
"claude_code_instructions_unregister",
|
||||||
|
"claude_code_instructions_propose",
|
||||||
|
"claude_code_proposals",
|
||||||
|
"claude_code_ask",
|
||||||
|
"claude_code_answer",
|
||||||
|
"claude_code_wait",
|
||||||
|
"claude_code_settings_get",
|
||||||
|
"claude_code_settings_set",
|
||||||
|
"claude_code_settings_clear",
|
||||||
|
"claude_code_permission_add",
|
||||||
|
"claude_code_permission_remove",
|
||||||
|
"claude_code_config_list",
|
||||||
|
"claude_code_config_show",
|
||||||
|
"claude_code_config_status",
|
||||||
|
"claude_code_config_import",
|
||||||
|
"claude_code_home_show",
|
||||||
|
"claude_code_home_remove",
|
||||||
|
"claude_code_home_removed",
|
||||||
|
"claude_code_home_restore",
|
||||||
|
"claude_code_judge",
|
||||||
|
"claude_code_judged"
|
||||||
|
],
|
||||||
|
"data": {
|
||||||
|
"own": [
|
||||||
|
{
|
||||||
|
"id": "agent-home",
|
||||||
|
"path": "${dir:agent-home}",
|
||||||
|
"class": "valuable",
|
||||||
|
"why": "the operator's agent's own files: its memory, history and projects"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"role": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "What this machine is for, in a sentence, written into the instructions every Claude Code session on it reads; empty says nothing.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
"mcp_servers": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The tool servers every session on this machine is given beside the mesh's own, by name, each as Claude Code's managed MCP configuration takes it; empty adds none.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"managed_settings": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Keys of Claude Code's managed settings every session on this machine obeys, such as spinnerTipsEnabled, laid over the mesh's own; empty adds none. Falls back to agent-managed-settings, the mesh's or this node's.",
|
||||||
|
"trusted": true,
|
||||||
|
"predefined": "agent-managed-settings",
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"instructions": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The instructions every session on this machine reads, by name, each a text as one line or a list of its lines; empty adds none.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"output_styles": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The output styles offered to every session on this machine, by name, each a text as one line or a list of its lines; empty adds none.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"skills": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The skills offered to every session on this machine, by name, each its files by path, a text as one line or a list of its lines; a skill without its SKILL.md is left out; empty adds none.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The slash commands offered to every session on this machine, by name, each a text as one line or a list of its lines; empty adds none.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": {}
|
||||||
|
},
|
||||||
|
"agents": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "The agents offered to every session on this machine, by name, each a text as one line or a list of its lines; empty adds none.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"id": "package",
|
||||||
|
"type": "package",
|
||||||
|
"package": "claude-code"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "managed",
|
||||||
|
"type": "directory",
|
||||||
|
"path": "/etc/claude-code",
|
||||||
|
"mode": "0755",
|
||||||
|
"unknown": "program"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "start",
|
||||||
|
"type": "file",
|
||||||
|
"path": "/usr/local/bin/claude-agent",
|
||||||
|
"mode": "0755",
|
||||||
|
"template": "files/claude-agent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "agent-account-name",
|
||||||
|
"type": "file",
|
||||||
|
"path": "/etc/claude-code/agent-account",
|
||||||
|
"mode": "0644",
|
||||||
|
"template": "files/agent-account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "agent-account",
|
||||||
|
"type": "user",
|
||||||
|
"name": "${machine:agent-account}",
|
||||||
|
"home": "${machine:agent-home}",
|
||||||
|
"root": "${machine:agent-root}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "agent-home",
|
||||||
|
"type": "directory",
|
||||||
|
"path": "${machine:agent-home}/.claude",
|
||||||
|
"mode": "0700",
|
||||||
|
"owner": "${machine:agent-account}",
|
||||||
|
"unknown": "module"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "state",
|
||||||
|
"type": "directory",
|
||||||
|
"mode": "0700",
|
||||||
|
"owner": "${machine:account}",
|
||||||
|
"place": ".",
|
||||||
|
"unknown": "program"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "facts",
|
||||||
|
"type": "file",
|
||||||
|
"path": "${dir:state}/facts.json",
|
||||||
|
"mode": "0600",
|
||||||
|
"owner": "${machine:account}",
|
||||||
|
"template": "files/facts.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "settings",
|
||||||
|
"type": "file",
|
||||||
|
"path": "${dir:state}/settings.json",
|
||||||
|
"mode": "0600",
|
||||||
|
"owner": "${machine:account}",
|
||||||
|
"takes-config": ["role", "mcp_servers", "managed_settings", "instructions", "output_styles", "skills", "commands", "agents"],
|
||||||
|
"merge": "json",
|
||||||
|
"template": "files/settings.json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"collection": "shell:zsh:normal",
|
||||||
|
"template": "files/zsh-normal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"build": {
|
||||||
|
"artifacts": [
|
||||||
|
{
|
||||||
|
"name": "tools",
|
||||||
|
"kind": "bundle",
|
||||||
|
"language": "go",
|
||||||
|
"system": "arch",
|
||||||
|
"from": "cmd/claude-code",
|
||||||
|
"binary": "claude-code",
|
||||||
|
"loads": [
|
||||||
|
"claude-code"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"MESH_CLAUDE_CODE_STATE": "${dir:state}",
|
||||||
|
"MESH_CLAUDE_CODE_FACTS": "${dir:state}/facts.json",
|
||||||
|
"MESH_CLAUDE_CODE_SETTINGS": "${dir:state}/settings.json"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "files",
|
||||||
|
"kind": "archive",
|
||||||
|
"from": "files"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
Reference in New Issue
Block a user