The control node is to run its agents under an account that cannot become root (hq ADR 0266). Declare it as a user the node-engine judges root: never, put the agent's directory in its home, and place claude-agent so the operator starts a session there through their own sudo. Where no agent account is named, both name the operator's account, as before.
153 lines
4.5 KiB
JSON
153 lines
4.5 KiB
JSON
{
|
|
"module": "claude-code",
|
|
"version": "1",
|
|
"slug": "agent",
|
|
"capabilities": [
|
|
"package-manager"
|
|
],
|
|
"requires": [
|
|
"mcp-endpoint"
|
|
],
|
|
"binds": {
|
|
"mcp-endpoint": "${dir:state}/mcp-endpoint.json"
|
|
},
|
|
"state": [
|
|
"servers",
|
|
"holdings",
|
|
"config"
|
|
],
|
|
"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_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_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"
|
|
],
|
|
"data": {
|
|
"own": [
|
|
{
|
|
"id": "agent-home",
|
|
"path": "${dir:agent-home}",
|
|
"class": "valuable",
|
|
"why": "the operator's agent's own files: its memory, history and projects"
|
|
}
|
|
]
|
|
},
|
|
"resources": [
|
|
{
|
|
"id": "package",
|
|
"type": "package",
|
|
"package": "claude-code"
|
|
},
|
|
{
|
|
"id": "managed",
|
|
"type": "directory",
|
|
"path": "/etc/claude-code",
|
|
"mode": "0755"
|
|
},
|
|
{
|
|
"id": "start",
|
|
"type": "file",
|
|
"path": "/usr/local/bin/claude-agent",
|
|
"mode": "0755",
|
|
"content": "#!/bin/sh\n# The mesh's (module claude-code, novox/hq ADR 0266): start the agent as the account agents run as on this\n# machine. Written whole at every push: an edit here is overwritten.\nagent='${machine:agent-account}'\nif [ \"$(id -un)\" = \"$agent\" ]; then\n\texec claude \"$@\"\nfi\n# Another account, the operator's, becomes the agent's through its own sudo: the person is the authority. The\n# operator's override of the guard travels only when it is set in this shell, as it would reach claude.\nif [ -n \"$MESH_GUARD_OVERRIDE\" ]; then\n\texec sudo -iu \"$agent\" env MESH_GUARD_OVERRIDE=\"$MESH_GUARD_OVERRIDE\" claude \"$@\"\nfi\nexec sudo -iu \"$agent\" claude \"$@\"\n"
|
|
},
|
|
{
|
|
"id": "agent-account",
|
|
"type": "user",
|
|
"name": "${machine:agent-account}",
|
|
"root": "${machine:agent-root}"
|
|
},
|
|
{
|
|
"id": "agent-home",
|
|
"type": "directory",
|
|
"path": "${machine:agent-home}/.claude",
|
|
"mode": "0700",
|
|
"owner": "${machine:agent-account}"
|
|
},
|
|
{
|
|
"id": "state",
|
|
"type": "directory",
|
|
"mode": "0700",
|
|
"owner": "${machine:account}",
|
|
"place": "."
|
|
},
|
|
{
|
|
"id": "facts",
|
|
"type": "file",
|
|
"path": "${dir:state}/facts.json",
|
|
"mode": "0600",
|
|
"owner": "${machine:account}",
|
|
"content": "{\n \"node\": \"${machine:name}\",\n \"console\": \"http://127.0.0.1:${bound:mcp-endpoint:port}/mcp\"\n}\n"
|
|
},
|
|
{
|
|
"id": "settings",
|
|
"type": "file",
|
|
"path": "${dir:state}/settings.json",
|
|
"mode": "0600",
|
|
"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"
|
|
}
|
|
],
|
|
"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"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|